MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / ConsumeNodeSmart

Function ConsumeNodeSmart

src/test/fuzz/miniscript.cpp:771–843  ·  view source on GitHub ↗

* Consume a Miniscript node from the fuzzer's output. * * This is similar to ConsumeNodeStable, but uses a precomputed table with permitted * fragments/subnode type for each required type. It is intended to more quickly explore * interesting miniscripts, at the cost of higher implementation complexity (which could * cause it miss things if incorrect), and with less regard for stability of the

Source from the content-addressed store, hash-verified

769 * everything).
770 */
771std::optional<NodeInfo> ConsumeNodeSmart(MsCtx script_ctx, FuzzedDataProvider& provider, Type type_needed) {
772 /** Table entry for the requested type. */
773 const auto& table{IsTapscript(script_ctx) ? SMARTINFO.tap_table : SMARTINFO.wsh_table};
774 auto recipes_it = table.find(type_needed);
775 assert(recipes_it != table.end());
776 /** Pick one recipe from the available ones for that type. */
777 const auto& [frag, subt] = PickValue(provider, recipes_it->second);
778
779 // Based on the fragment the recipe uses, fill in other data (k, keys, data).
780 switch (frag) {
781 case Fragment::PK_K:
782 case Fragment::PK_H:
783 return {{frag, ConsumePubKey(provider)}};
784 case Fragment::MULTI: {
785 const auto n_keys = provider.ConsumeIntegralInRange<uint8_t>(1, 20);
786 const auto k = provider.ConsumeIntegralInRange<uint8_t>(1, n_keys);
787 std::vector<CPubKey> keys{n_keys};
788 for (auto& key: keys) key = ConsumePubKey(provider);
789 return {{frag, k, std::move(keys)}};
790 }
791 case Fragment::MULTI_A: {
792 const auto n_keys = provider.ConsumeIntegralInRange<uint16_t>(1, 999);
793 const auto k = provider.ConsumeIntegralInRange<uint16_t>(1, n_keys);
794 std::vector<CPubKey> keys{n_keys};
795 for (auto& key: keys) key = ConsumePubKey(provider);
796 return {{frag, k, std::move(keys)}};
797 }
798 case Fragment::OLDER:
799 case Fragment::AFTER:
800 return {{frag, provider.ConsumeIntegralInRange<uint32_t>(1, 0x7FFFFFF)}};
801 case Fragment::SHA256:
802 return {{frag, PickValue(provider, TEST_DATA.sha256)}};
803 case Fragment::HASH256:
804 return {{frag, PickValue(provider, TEST_DATA.hash256)}};
805 case Fragment::RIPEMD160:
806 return {{frag, PickValue(provider, TEST_DATA.ripemd160)}};
807 case Fragment::HASH160:
808 return {{frag, PickValue(provider, TEST_DATA.hash160)}};
809 case Fragment::JUST_0:
810 case Fragment::JUST_1:
811 case Fragment::WRAP_A:
812 case Fragment::WRAP_S:
813 case Fragment::WRAP_C:
814 case Fragment::WRAP_D:
815 case Fragment::WRAP_V:
816 case Fragment::WRAP_J:
817 case Fragment::WRAP_N:
818 case Fragment::AND_V:
819 case Fragment::AND_B:
820 case Fragment::OR_B:
821 case Fragment::OR_C:
822 case Fragment::OR_D:
823 case Fragment::OR_I:
824 case Fragment::ANDOR:
825 return {{subt, frag}};
826 case Fragment::THRESH: {
827 uint32_t children;
828 if (subt.size() < 2) {

Callers 1

miniscript.cppFile · 0.85

Calls 7

IsTapscriptFunction · 0.85
ConsumePubKeyFunction · 0.85
findMethod · 0.80
endMethod · 0.45
sizeMethod · 0.45
push_backMethod · 0.45
backMethod · 0.45

Tested by

no test coverage detected