Changeset View
Changeset View
Standalone View
Standalone View
src/script/descriptor.cpp
// Copyright (c) 2018 The Bitcoin Core developers | // Copyright (c) 2018 The Bitcoin Core developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include <script/descriptor.h> | #include <script/descriptor.h> | ||||
#include <chainparams.h> // For Params() | #include <chainparams.h> // For Params() | ||||
#include <config.h> | #include <config.h> | ||||
#include <key_io.h> | #include <key_io.h> | ||||
#include <pubkey.h> | #include <pubkey.h> | ||||
#include <script/standard.h> | #include <script/standard.h> | ||||
#include <span.h> | #include <span.h> | ||||
#include <util/bip32.h> | #include <util/bip32.h> | ||||
#include <util/spanparsing.h> | #include <util/spanparsing.h> | ||||
#include <util/strencodings.h> | #include <util/strencodings.h> | ||||
#include <util/system.h> | #include <util/system.h> | ||||
#include <util/vector.h> | |||||
#include <memory> | #include <memory> | ||||
#include <string> | #include <string> | ||||
namespace { | namespace { | ||||
//////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////// | ||||
// Checksum // | // Checksum // | ||||
▲ Show 20 Lines • Show All 561 Lines • ▼ Show 20 Lines | bool ExpandFromCache(int pos, const std::vector<uint8_t> &cache, | ||||
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; | ||||
} | } | ||||
}; | }; | ||||
/** Construct a vector with one element, which is moved into it. */ | |||||
template <typename T> std::vector<T> Singleton(T elem) { | |||||
std::vector<T> ret; | |||||
ret.emplace_back(std::move(elem)); | |||||
return ret; | |||||
} | |||||
/** 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 { | ||||
return EncodeDestination(m_destination, GetConfig()); | return EncodeDestination(m_destination, GetConfig()); | ||||
} | } | ||||
std::vector<CScript> MakeScripts(const std::vector<CPubKey> &, | std::vector<CScript> MakeScripts(const std::vector<CPubKey> &, | ||||
const CScript *, | const CScript *, | ||||
FlatSigningProvider &) const override { | FlatSigningProvider &) const override { | ||||
return Singleton(GetScriptForDestination(m_destination)); | return Vector(GetScriptForDestination(m_destination)); | ||||
} | } | ||||
public: | public: | ||||
AddressDescriptor(CTxDestination destination) | AddressDescriptor(CTxDestination destination) | ||||
: DescriptorImpl({}, {}, "addr"), | : DescriptorImpl({}, {}, "addr"), | ||||
m_destination(std::move(destination)) {} | m_destination(std::move(destination)) {} | ||||
bool IsSolvable() const final { return false; } | bool IsSolvable() const final { return false; } | ||||
}; | }; | ||||
/** A parsed raw(H) descriptor. */ | /** A parsed raw(H) descriptor. */ | ||||
class RawDescriptor final : public DescriptorImpl { | class RawDescriptor final : public DescriptorImpl { | ||||
const CScript m_script; | const CScript m_script; | ||||
protected: | protected: | ||||
std::string ToStringExtra() const override { | std::string ToStringExtra() const override { | ||||
return HexStr(m_script.begin(), m_script.end()); | return HexStr(m_script.begin(), m_script.end()); | ||||
} | } | ||||
std::vector<CScript> MakeScripts(const std::vector<CPubKey> &, | std::vector<CScript> MakeScripts(const std::vector<CPubKey> &, | ||||
const CScript *, | const CScript *, | ||||
FlatSigningProvider &) const override { | FlatSigningProvider &) const override { | ||||
return Singleton(m_script); | return Vector(m_script); | ||||
} | } | ||||
public: | public: | ||||
RawDescriptor(CScript script) | RawDescriptor(CScript script) | ||||
: DescriptorImpl({}, {}, "raw"), m_script(std::move(script)) {} | : DescriptorImpl({}, {}, "raw"), m_script(std::move(script)) {} | ||||
bool IsSolvable() const final { return false; } | bool IsSolvable() const final { return false; } | ||||
}; | }; | ||||
/** A parsed pk(P) descriptor. */ | /** A parsed pk(P) descriptor. */ | ||||
class PKDescriptor final : public DescriptorImpl { | class PKDescriptor final : public DescriptorImpl { | ||||
protected: | protected: | ||||
std::vector<CScript> MakeScripts(const std::vector<CPubKey> &keys, | std::vector<CScript> MakeScripts(const std::vector<CPubKey> &keys, | ||||
const CScript *, | const CScript *, | ||||
FlatSigningProvider &) const override { | FlatSigningProvider &) const override { | ||||
return Singleton(GetScriptForRawPubKey(keys[0])); | return Vector(GetScriptForRawPubKey(keys[0])); | ||||
} | } | ||||
public: | public: | ||||
PKDescriptor(std::unique_ptr<PubkeyProvider> prov) | PKDescriptor(std::unique_ptr<PubkeyProvider> prov) | ||||
: DescriptorImpl(Singleton(std::move(prov)), {}, "pk") {} | : DescriptorImpl(Vector(std::move(prov)), {}, "pk") {} | ||||
}; | }; | ||||
/** A parsed pkh(P) descriptor. */ | /** A parsed pkh(P) descriptor. */ | ||||
class PKHDescriptor final : public DescriptorImpl { | class PKHDescriptor final : public DescriptorImpl { | ||||
protected: | protected: | ||||
std::vector<CScript> MakeScripts(const std::vector<CPubKey> &keys, | std::vector<CScript> MakeScripts(const std::vector<CPubKey> &keys, | ||||
const CScript *, | const CScript *, | ||||
FlatSigningProvider &out) const override { | FlatSigningProvider &out) const override { | ||||
CKeyID id = keys[0].GetID(); | CKeyID id = keys[0].GetID(); | ||||
out.pubkeys.emplace(id, keys[0]); | out.pubkeys.emplace(id, keys[0]); | ||||
return Singleton(GetScriptForDestination(PKHash(id))); | return Vector(GetScriptForDestination(PKHash(id))); | ||||
} | } | ||||
public: | public: | ||||
PKHDescriptor(std::unique_ptr<PubkeyProvider> prov) | PKHDescriptor(std::unique_ptr<PubkeyProvider> prov) | ||||
: DescriptorImpl(Singleton(std::move(prov)), {}, "pkh") {} | : DescriptorImpl(Vector(std::move(prov)), {}, "pkh") {} | ||||
}; | }; | ||||
/** A parsed combo(P) descriptor. */ | /** A parsed combo(P) descriptor. */ | ||||
class ComboDescriptor final : public DescriptorImpl { | class ComboDescriptor final : public DescriptorImpl { | ||||
protected: | protected: | ||||
std::vector<CScript> MakeScripts(const std::vector<CPubKey> &keys, | std::vector<CScript> MakeScripts(const std::vector<CPubKey> &keys, | ||||
const CScript *, | const CScript *, | ||||
FlatSigningProvider &out) const override { | FlatSigningProvider &out) const override { | ||||
std::vector<CScript> ret; | std::vector<CScript> ret; | ||||
CKeyID id = keys[0].GetID(); | CKeyID id = keys[0].GetID(); | ||||
out.pubkeys.emplace(id, keys[0]); | out.pubkeys.emplace(id, keys[0]); | ||||
// P2PK | // P2PK | ||||
ret.emplace_back(GetScriptForRawPubKey(keys[0])); | ret.emplace_back(GetScriptForRawPubKey(keys[0])); | ||||
// P2PKH | // P2PKH | ||||
ret.emplace_back(GetScriptForDestination(PKHash(id))); | ret.emplace_back(GetScriptForDestination(PKHash(id))); | ||||
return ret; | return ret; | ||||
} | } | ||||
public: | public: | ||||
ComboDescriptor(std::unique_ptr<PubkeyProvider> prov) | ComboDescriptor(std::unique_ptr<PubkeyProvider> prov) | ||||
: DescriptorImpl(Singleton(std::move(prov)), {}, "combo") {} | : DescriptorImpl(Vector(std::move(prov)), {}, "combo") {} | ||||
}; | }; | ||||
/** A parsed multi(...) descriptor. */ | /** A parsed multi(...) descriptor. */ | ||||
class MultisigDescriptor final : public DescriptorImpl { | class MultisigDescriptor final : public DescriptorImpl { | ||||
const int m_threshold; | const int m_threshold; | ||||
protected: | protected: | ||||
std::string ToStringExtra() const override { | std::string ToStringExtra() const override { | ||||
return strprintf("%i", m_threshold); | return strprintf("%i", m_threshold); | ||||
} | } | ||||
std::vector<CScript> MakeScripts(const std::vector<CPubKey> &keys, | std::vector<CScript> MakeScripts(const std::vector<CPubKey> &keys, | ||||
const CScript *, | const CScript *, | ||||
FlatSigningProvider &) const override { | FlatSigningProvider &) const override { | ||||
return Singleton(GetScriptForMultisig(m_threshold, keys)); | return Vector(GetScriptForMultisig(m_threshold, keys)); | ||||
} | } | ||||
public: | public: | ||||
MultisigDescriptor(int threshold, | MultisigDescriptor(int threshold, | ||||
std::vector<std::unique_ptr<PubkeyProvider>> providers) | std::vector<std::unique_ptr<PubkeyProvider>> providers) | ||||
: DescriptorImpl(std::move(providers), {}, "multi"), | : DescriptorImpl(std::move(providers), {}, "multi"), | ||||
m_threshold(threshold) {} | m_threshold(threshold) {} | ||||
}; | }; | ||||
/** A parsed sh(...) descriptor. */ | /** A parsed sh(...) descriptor. */ | ||||
class SHDescriptor final : public DescriptorImpl { | class SHDescriptor final : public DescriptorImpl { | ||||
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(ScriptHash(*script))); | return Vector(GetScriptForDestination(ScriptHash(*script))); | ||||
} | } | ||||
public: | public: | ||||
SHDescriptor(std::unique_ptr<DescriptorImpl> desc) | SHDescriptor(std::unique_ptr<DescriptorImpl> desc) | ||||
: DescriptorImpl({}, std::move(desc), "sh") {} | : DescriptorImpl({}, std::move(desc), "sh") {} | ||||
}; | }; | ||||
//////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////// | ||||
▲ Show 20 Lines • Show All 413 Lines • Show Last 20 Lines |