Changeset View
Changeset View
Standalone View
Standalone View
src/script/descriptor.cpp
Show First 20 Lines • Show All 247 Lines • ▼ Show 20 Lines | |||||
}; | }; | ||||
/** Base class for all Descriptor implementations. */ | /** Base class for all Descriptor implementations. */ | ||||
class DescriptorImpl : public Descriptor { | class DescriptorImpl : public Descriptor { | ||||
//! Public key arguments for this descriptor (size 1 for PK, PKH; any size | //! Public key arguments for this descriptor (size 1 for PK, PKH; any size | ||||
//! of Multisig). | //! of Multisig). | ||||
const std::vector<std::unique_ptr<PubkeyProvider>> m_pubkey_args; | const std::vector<std::unique_ptr<PubkeyProvider>> m_pubkey_args; | ||||
//! The sub-descriptor argument (nullptr for everything but SH). | //! The sub-descriptor argument (nullptr for everything but SH). | ||||
const std::unique_ptr<Descriptor> m_script_arg; | const std::unique_ptr<DescriptorImpl> m_script_arg; | ||||
//! The string name of the descriptor function. | //! The string name of the descriptor function. | ||||
const std::string m_name; | const std::string m_name; | ||||
protected: | protected: | ||||
//! Return a serialization of anything except pubkey and script arguments, | //! Return a serialization of anything except pubkey and script arguments, | ||||
//! to be prepended to those. | //! to be prepended to those. | ||||
virtual std::string ToStringExtra() const { return ""; } | virtual std::string ToStringExtra() const { return ""; } | ||||
Show All 13 Lines | protected: | ||||
* @return A vector with scriptPubKeys for this descriptor. | * @return A vector with scriptPubKeys for this descriptor. | ||||
*/ | */ | ||||
virtual std::vector<CScript> | virtual std::vector<CScript> | ||||
MakeScripts(const std::vector<CPubKey> &pubkeys, const CScript *script, | MakeScripts(const std::vector<CPubKey> &pubkeys, const CScript *script, | ||||
FlatSigningProvider &out) const = 0; | FlatSigningProvider &out) const = 0; | ||||
public: | public: | ||||
DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, | DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, | ||||
std::unique_ptr<Descriptor> script, const std::string &name) | std::unique_ptr<DescriptorImpl> script, | ||||
const std::string &name) | |||||
: m_pubkey_args(std::move(pubkeys)), m_script_arg(std::move(script)), | : m_pubkey_args(std::move(pubkeys)), m_script_arg(std::move(script)), | ||||
m_name(name) {} | m_name(name) {} | ||||
bool IsSolvable() const override { | bool IsSolvable() const override { | ||||
if (m_script_arg) { | if (m_script_arg) { | ||||
if (!m_script_arg->IsSolvable()) { | if (!m_script_arg->IsSolvable()) { | ||||
return false; | return false; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 232 Lines • ▼ Show 20 Lines | |||||
protected: | protected: | ||||
std::vector<CScript> MakeScripts(const std::vector<CPubKey> &, | std::vector<CScript> MakeScripts(const std::vector<CPubKey> &, | ||||
const CScript *script, | const CScript *script, | ||||
FlatSigningProvider &) const override { | FlatSigningProvider &) const override { | ||||
return Singleton(GetScriptForDestination(CScriptID(*script))); | return Singleton(GetScriptForDestination(CScriptID(*script))); | ||||
} | } | ||||
public: | public: | ||||
SHDescriptor(std::unique_ptr<Descriptor> desc) | SHDescriptor(std::unique_ptr<DescriptorImpl> desc) | ||||
: DescriptorImpl({}, std::move(desc), "sh") {} | : DescriptorImpl({}, std::move(desc), "sh") {} | ||||
}; | }; | ||||
//////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////// | ||||
// Parser // | // Parser // | ||||
//////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////// | ||||
enum class ParseScriptContext { | enum class ParseScriptContext { | ||||
▲ Show 20 Lines • Show All 167 Lines • ▼ Show 20 Lines | std::unique_ptr<PubkeyProvider> ParsePubkey(const Span<const char> &sp, | ||||
if (!provider) { | if (!provider) { | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
return std::make_unique<OriginPubkeyProvider>(std::move(info), | return std::make_unique<OriginPubkeyProvider>(std::move(info), | ||||
std::move(provider)); | std::move(provider)); | ||||
} | } | ||||
/** Parse a script in a particular context. */ | /** Parse a script in a particular context. */ | ||||
std::unique_ptr<Descriptor> ParseScript(Span<const char> &sp, | std::unique_ptr<DescriptorImpl> ParseScript(Span<const char> &sp, | ||||
ParseScriptContext ctx, | ParseScriptContext ctx, | ||||
FlatSigningProvider &out) { | FlatSigningProvider &out) { | ||||
auto expr = Expr(sp); | auto expr = Expr(sp); | ||||
if (Func("pk", expr)) { | if (Func("pk", expr)) { | ||||
auto pubkey = ParsePubkey(expr, out); | auto pubkey = ParsePubkey(expr, out); | ||||
if (!pubkey) { | if (!pubkey) { | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
return std::make_unique<PKDescriptor>(std::move(pubkey)); | return std::make_unique<PKDescriptor>(std::move(pubkey)); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | InferPubkey(const CPubKey &pubkey, ParseScriptContext, | ||||
KeyOriginInfo info; | KeyOriginInfo info; | ||||
if (provider.GetKeyOrigin(pubkey.GetID(), info)) { | if (provider.GetKeyOrigin(pubkey.GetID(), info)) { | ||||
return std::make_unique<OriginPubkeyProvider>(std::move(info), | return std::make_unique<OriginPubkeyProvider>(std::move(info), | ||||
std::move(key_provider)); | std::move(key_provider)); | ||||
} | } | ||||
return key_provider; | return key_provider; | ||||
} | } | ||||
std::unique_ptr<Descriptor> InferScript(const CScript &script, | std::unique_ptr<DescriptorImpl> InferScript(const CScript &script, | ||||
ParseScriptContext ctx, | ParseScriptContext ctx, | ||||
const SigningProvider &provider) { | const SigningProvider &provider) { | ||||
std::vector<std::vector<uint8_t>> data; | std::vector<std::vector<uint8_t>> data; | ||||
txnouttype txntype = Solver(script, data); | txnouttype txntype = Solver(script, data); | ||||
if (txntype == TX_PUBKEY) { | if (txntype == TX_PUBKEY) { | ||||
CPubKey pubkey(data[0].begin(), data[0].end()); | CPubKey pubkey(data[0].begin(), data[0].end()); | ||||
if (pubkey.IsValid()) { | if (pubkey.IsValid()) { | ||||
return std::make_unique<PKDescriptor>( | return std::make_unique<PKDescriptor>( | ||||
InferPubkey(pubkey, ctx, provider)); | InferPubkey(pubkey, ctx, provider)); | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | |||||
} // namespace | } // namespace | ||||
std::unique_ptr<Descriptor> Parse(const std::string &descriptor, | std::unique_ptr<Descriptor> Parse(const std::string &descriptor, | ||||
FlatSigningProvider &out) { | FlatSigningProvider &out) { | ||||
Span<const char> sp(descriptor.data(), descriptor.size()); | Span<const char> sp(descriptor.data(), descriptor.size()); | ||||
auto ret = ParseScript(sp, ParseScriptContext::TOP, out); | auto ret = ParseScript(sp, ParseScriptContext::TOP, out); | ||||
if (sp.size() == 0 && ret) { | if (sp.size() == 0 && ret) { | ||||
return ret; | return std::unique_ptr<Descriptor>(std::move(ret)); | ||||
} | } | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
std::unique_ptr<Descriptor> InferDescriptor(const CScript &script, | std::unique_ptr<Descriptor> InferDescriptor(const CScript &script, | ||||
const SigningProvider &provider) { | const SigningProvider &provider) { | ||||
return InferScript(script, ParseScriptContext::TOP, provider); | return InferScript(script, ParseScriptContext::TOP, provider); | ||||
} | } |