Changeset View
Changeset View
Standalone View
Standalone View
src/script/descriptor.cpp
Show First 20 Lines • Show All 194 Lines • ▼ Show 20 Lines | struct PubkeyProvider { | ||||
virtual std::string ToString() const = 0; | virtual std::string ToString() const = 0; | ||||
/** | /** | ||||
* Get the descriptor string form including private data (if available in | * Get the descriptor string form including private data (if available in | ||||
* arg). | * arg). | ||||
*/ | */ | ||||
virtual bool ToPrivateString(const SigningProvider &arg, | virtual bool ToPrivateString(const SigningProvider &arg, | ||||
std::string &out) const = 0; | std::string &out) const = 0; | ||||
/** Derive a private key, if private data is available in arg. */ | |||||
virtual bool GetPrivKey(int pos, const SigningProvider &arg, | |||||
CKey &key) const = 0; | |||||
}; | }; | ||||
class OriginPubkeyProvider final : public PubkeyProvider { | class OriginPubkeyProvider final : public PubkeyProvider { | ||||
KeyOriginInfo m_origin; | KeyOriginInfo m_origin; | ||||
std::unique_ptr<PubkeyProvider> m_provider; | std::unique_ptr<PubkeyProvider> m_provider; | ||||
std::string OriginString() const { | std::string OriginString() const { | ||||
return HexStr(std::begin(m_origin.fingerprint), | return HexStr(std::begin(m_origin.fingerprint), | ||||
Show All 25 Lines | bool ToPrivateString(const SigningProvider &arg, | ||||
std::string &ret) const override { | std::string &ret) const override { | ||||
std::string sub; | std::string sub; | ||||
if (!m_provider->ToPrivateString(arg, sub)) { | if (!m_provider->ToPrivateString(arg, sub)) { | ||||
return false; | return false; | ||||
} | } | ||||
ret = "[" + OriginString() + "]" + std::move(sub); | ret = "[" + OriginString() + "]" + std::move(sub); | ||||
return true; | return true; | ||||
} | } | ||||
bool GetPrivKey(int pos, const SigningProvider &arg, | |||||
CKey &key) const override { | |||||
return m_provider->GetPrivKey(pos, arg, key); | |||||
} | |||||
}; | }; | ||||
/** An object representing a parsed constant public key in a descriptor. */ | /** An object representing a parsed constant public key in a descriptor. */ | ||||
class ConstPubkeyProvider final : public PubkeyProvider { | class ConstPubkeyProvider final : public PubkeyProvider { | ||||
CPubKey m_pubkey; | CPubKey m_pubkey; | ||||
public: | public: | ||||
ConstPubkeyProvider(const CPubKey &pubkey) : m_pubkey(pubkey) {} | ConstPubkeyProvider(const CPubKey &pubkey) : m_pubkey(pubkey) {} | ||||
Show All 17 Lines | bool ToPrivateString(const SigningProvider &arg, | ||||
std::string &ret) const override { | std::string &ret) const override { | ||||
CKey key; | CKey key; | ||||
if (!arg.GetKey(m_pubkey.GetID(), key)) { | if (!arg.GetKey(m_pubkey.GetID(), key)) { | ||||
return false; | return false; | ||||
} | } | ||||
ret = EncodeSecret(key); | ret = EncodeSecret(key); | ||||
return true; | return true; | ||||
} | } | ||||
bool GetPrivKey(int pos, const SigningProvider &arg, | |||||
CKey &key) const override { | |||||
return arg.GetKey(m_pubkey.GetID(), key); | |||||
} | |||||
}; | }; | ||||
enum class DeriveType { | enum class DeriveType { | ||||
NO, | NO, | ||||
UNHARDENED, | UNHARDENED, | ||||
HARDENED, | HARDENED, | ||||
}; | }; | ||||
Show All 35 Lines | BIP32PubkeyProvider(const CExtPubKey &extkey, KeyPath path, | ||||
DeriveType derive) | DeriveType derive) | ||||
: m_extkey(extkey), m_path(std::move(path)), m_derive(derive) {} | : m_extkey(extkey), m_path(std::move(path)), m_derive(derive) {} | ||||
bool IsRange() const override { return m_derive != DeriveType::NO; } | bool IsRange() const override { return m_derive != DeriveType::NO; } | ||||
size_t GetSize() const override { return 33; } | size_t GetSize() const override { return 33; } | ||||
bool GetPubKey(int pos, const SigningProvider &arg, CPubKey *key, | bool GetPubKey(int pos, const SigningProvider &arg, CPubKey *key, | ||||
KeyOriginInfo &info) const override { | KeyOriginInfo &info) const override { | ||||
if (key) { | if (key) { | ||||
if (IsHardened()) { | if (IsHardened()) { | ||||
CExtKey extkey; | CKey priv_key; | ||||
if (!GetExtKey(arg, extkey)) { | if (!GetPrivKey(pos, arg, priv_key)) { | ||||
return false; | return false; | ||||
} | } | ||||
for (auto entry : m_path) { | *key = priv_key.GetPubKey(); | ||||
extkey.Derive(extkey, entry); | |||||
} | |||||
if (m_derive == DeriveType::UNHARDENED) { | |||||
extkey.Derive(extkey, pos); | |||||
} | |||||
if (m_derive == DeriveType::HARDENED) { | |||||
extkey.Derive(extkey, pos | 0x80000000UL); | |||||
} | |||||
*key = extkey.Neuter().pubkey; | |||||
} else { | } else { | ||||
// TODO: optimize by caching | // TODO: optimize by caching | ||||
CExtPubKey extkey = m_extkey; | CExtPubKey extkey = m_extkey; | ||||
for (auto entry : m_path) { | for (auto entry : m_path) { | ||||
extkey.Derive(extkey, entry); | extkey.Derive(extkey, entry); | ||||
} | } | ||||
if (m_derive == DeriveType::UNHARDENED) { | if (m_derive == DeriveType::UNHARDENED) { | ||||
extkey.Derive(extkey, pos); | extkey.Derive(extkey, pos); | ||||
Show All 34 Lines | bool ToPrivateString(const SigningProvider &arg, | ||||
if (IsRange()) { | if (IsRange()) { | ||||
out += "/*"; | out += "/*"; | ||||
if (m_derive == DeriveType::HARDENED) { | if (m_derive == DeriveType::HARDENED) { | ||||
out += '\''; | out += '\''; | ||||
} | } | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool GetPrivKey(int pos, const SigningProvider &arg, | |||||
CKey &key) const override { | |||||
CExtKey extkey; | |||||
if (!GetExtKey(arg, extkey)) { | |||||
return false; | |||||
} | |||||
for (auto entry : m_path) { | |||||
extkey.Derive(extkey, entry); | |||||
} | |||||
if (m_derive == DeriveType::UNHARDENED) { | |||||
extkey.Derive(extkey, pos); | |||||
} | |||||
if (m_derive == DeriveType::HARDENED) { | |||||
extkey.Derive(extkey, pos | 0x80000000UL); | |||||
} | |||||
key = extkey.key; | |||||
return true; | |||||
} | |||||
}; | }; | ||||
/** 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 | ||||
//! for Multisig). | //! for 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). | ||||
▲ Show 20 Lines • Show All 191 Lines • ▼ Show 20 Lines | public: | ||||
bool ExpandFromCache(int pos, const std::vector<uint8_t> &cache, | bool ExpandFromCache(int pos, const std::vector<uint8_t> &cache, | ||||
std::vector<CScript> &output_scripts, | std::vector<CScript> &output_scripts, | ||||
FlatSigningProvider &out) const final { | FlatSigningProvider &out) const final { | ||||
Span<const uint8_t> span = MakeSpan(cache); | Span<const uint8_t> span = MakeSpan(cache); | ||||
return ExpandHelper(pos, DUMMY_SIGNING_PROVIDER, &span, output_scripts, | return ExpandHelper(pos, DUMMY_SIGNING_PROVIDER, &span, output_scripts, | ||||
out, nullptr) && | out, nullptr) && | ||||
span.size() == 0; | span.size() == 0; | ||||
} | } | ||||
void ExpandPrivate(int pos, const SigningProvider &provider, | |||||
FlatSigningProvider &out) const final { | |||||
for (const auto &p : m_pubkey_args) { | |||||
CKey key; | |||||
if (!p->GetPrivKey(pos, provider, key)) { | |||||
continue; | |||||
} | |||||
out.keys.emplace(key.GetPubKey().GetID(), key); | |||||
} | |||||
if (m_subdescriptor_arg) { | |||||
FlatSigningProvider subprovider; | |||||
m_subdescriptor_arg->ExpandPrivate(pos, provider, subprovider); | |||||
out = Merge(out, subprovider); | |||||
} | |||||
} | |||||
}; | }; | ||||
/** A parsed addr(A) descriptor. */ | /** A parsed addr(A) descriptor. */ | ||||
class AddressDescriptor final : public DescriptorImpl { | class AddressDescriptor final : public DescriptorImpl { | ||||
const CTxDestination m_destination; | const CTxDestination m_destination; | ||||
protected: | protected: | ||||
std::string ToStringExtra() const override { | std::string ToStringExtra() const override { | ||||
▲ Show 20 Lines • Show All 544 Lines • Show Last 20 Lines |