NOLINTNEXTLINE(misc-no-recursion)
| 2772 | |
| 2773 | // NOLINTNEXTLINE(misc-no-recursion) |
| 2774 | std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptContext ctx, const SigningProvider& provider) |
| 2775 | { |
| 2776 | if (ctx == ParseScriptContext::P2TR && script.size() == 34 && script[0] == 32 && script[33] == OP_CHECKSIG) { |
| 2777 | XOnlyPubKey key{std::span{script}.subspan(1, 32)}; |
| 2778 | return std::make_unique<PKDescriptor>(InferXOnlyPubkey(key, ctx, provider), true); |
| 2779 | } |
| 2780 | |
| 2781 | if (ctx == ParseScriptContext::P2TR) { |
| 2782 | auto ret = InferMultiA(script, ctx, provider); |
| 2783 | if (ret) return ret; |
| 2784 | } |
| 2785 | |
| 2786 | std::vector<std::vector<unsigned char>> data; |
| 2787 | TxoutType txntype = Solver(script, data); |
| 2788 | |
| 2789 | if (txntype == TxoutType::PUBKEY && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) { |
| 2790 | CPubKey pubkey(data[0]); |
| 2791 | if (auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) { |
| 2792 | return std::make_unique<PKDescriptor>(std::move(pubkey_provider)); |
| 2793 | } |
| 2794 | } |
| 2795 | if (txntype == TxoutType::PUBKEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) { |
| 2796 | uint160 hash(data[0]); |
| 2797 | CKeyID keyid(hash); |
| 2798 | CPubKey pubkey; |
| 2799 | if (provider.GetPubKey(keyid, pubkey)) { |
| 2800 | if (auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) { |
| 2801 | return std::make_unique<PKHDescriptor>(std::move(pubkey_provider)); |
| 2802 | } |
| 2803 | } |
| 2804 | } |
| 2805 | if (txntype == TxoutType::WITNESS_V0_KEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH)) { |
| 2806 | uint160 hash(data[0]); |
| 2807 | CKeyID keyid(hash); |
| 2808 | CPubKey pubkey; |
| 2809 | if (provider.GetPubKey(keyid, pubkey)) { |
| 2810 | if (auto pubkey_provider = InferPubkey(pubkey, ParseScriptContext::P2WPKH, provider)) { |
| 2811 | return std::make_unique<WPKHDescriptor>(std::move(pubkey_provider)); |
| 2812 | } |
| 2813 | } |
| 2814 | } |
| 2815 | if (txntype == TxoutType::MULTISIG && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) { |
| 2816 | bool ok = true; |
| 2817 | std::vector<std::unique_ptr<PubkeyProvider>> providers; |
| 2818 | for (size_t i = 1; i + 1 < data.size(); ++i) { |
| 2819 | CPubKey pubkey(data[i]); |
| 2820 | if (auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) { |
| 2821 | providers.push_back(std::move(pubkey_provider)); |
| 2822 | } else { |
| 2823 | ok = false; |
| 2824 | break; |
| 2825 | } |
| 2826 | } |
| 2827 | if (ok) return std::make_unique<MultisigDescriptor>((int)data[0][0], std::move(providers)); |
| 2828 | } |
| 2829 | if (txntype == TxoutType::SCRIPTHASH && ctx == ParseScriptContext::TOP) { |
| 2830 | uint160 hash(data[0]); |
| 2831 | CScriptID scriptid(hash); |
no test coverage detected