14template<
typename M,
typename K,
typename V>
17 auto it = map.find(key);
18 if (it != map.end()) {
60 std::pair<CPubKey, KeyOriginInfo> out;
62 if (
ret) info = std::move(out.second);
109 mapScripts[id] = std::move(
script);
116 if (!
GetKey(address, key)) {
126 mapKeys[pubkey.
GetID()] = key;
134 return mapKeys.count(address) > 0;
140 std::set<CKeyID> set_address;
141 for (
const auto& mi : mapKeys) {
142 set_address.insert(mi.first);
150 KeyMap::const_iterator mi = mapKeys.find(address);
151 if (mi != mapKeys.end()) {
166 mapScripts[
CScriptID(redeemScript)] = redeemScript;
173 return mapScripts.count(hash) > 0;
179 std::set<CScriptID> set_script;
180 for (
const auto& mi : mapScripts) {
181 set_script.insert(mi.first);
189 ScriptMap::const_iterator mi = mapScripts.find(hash);
190 if (mi != mapScripts.end())
192 redeemScriptOut = (*mi).second;
202 if (
auto id = std::get_if<PKHash>(&dest)) {
205 if (
auto witness_id = std::get_if<WitnessV0KeyHash>(&dest)) {
208 if (
auto script_hash = std::get_if<ScriptHash>(&dest)) {
213 if (
auto inner_witness_id = std::get_if<WitnessV0KeyHash>(&inner_dest)) {
214 return ToKeyID(*inner_witness_id);
218 if (
auto output_key = std::get_if<WitnessV1Taproot>(&dest)) {
239 if (provider->GetCScript(scriptid,
script))
return true;
247 if (provider->GetPubKey(keyid, pubkey))
return true;
256 if (provider->GetKeyOrigin(keyid, info))
return true;
264 if (provider->GetKey(keyid, key))
return true;
272 if (provider->GetTaprootSpendData(output_key, spenddata))
return true;
280 if (provider->GetTaprootBuilder(output_key, builder))
return true;
289 for (
auto& leaf : a.leaves) {
290 leaf.merkle_branch.push_back(b.hash);
291 ret.leaves.emplace_back(std::move(leaf));
294 for (
auto& leaf : b.leaves) {
295 leaf.merkle_branch.push_back(a.hash);
296 ret.leaves.emplace_back(std::move(leaf));
312 for (
auto& [key, control_blocks] : other.
scripts) {
313 scripts[key].merge(std::move(control_blocks));
323 if ((
size_t)depth + 1 <
m_branch.size()) {
332 if (depth == 0)
m_valid =
false;
345 std::vector<bool> branch;
346 for (
int depth : depths) {
352 if ((
size_t)depth + 1 < branch.size())
return false;
353 while (branch.size() > (
size_t)depth && branch[depth]) {
355 if (depth == 0)
return false;
358 if (branch.size() <= (
size_t)depth) branch.resize((
size_t)depth + 1);
360 branch[depth] =
true;
363 return branch.size() == 0 || (branch.size() == 1 && branch[0]);
373 if (track)
node.leaves.emplace_back(
LeafInfo{std::vector<unsigned char>(
script.begin(),
script.end()), leaf_version, {}});
413 for (
const auto& leaf :
m_branch[0]->leaves) {
414 std::vector<unsigned char> control_block;
416 control_block[0] = leaf.leaf_version | (
m_parity ? 1 : 0);
418 if (leaf.merkle_branch.size()) {
419 std::copy(leaf.merkle_branch[0].begin(),
423 spd.
scripts[{leaf.script, leaf.leaf_version}].insert(std::move(control_block));
433 if (!tweak || tweak->first != output)
return std::nullopt;
435 std::vector<std::tuple<int, std::vector<unsigned char>,
int>>
ret;
443 std::unique_ptr<TreeNode> sub[2];
446 const std::pair<std::vector<unsigned char>,
int>* leaf =
nullptr;
448 bool explored =
false;
458 for (
const auto& [key, control_blocks] : spenddata.
scripts) {
459 const auto& [
script, leaf_ver] = key;
460 for (
const auto& control : control_blocks) {
462 if (leaf_ver < 0 || leaf_ver >= 0x100 || leaf_ver & 1)
continue;
471 if (merkle_root != spenddata.
merkle_root)
continue;
473 TreeNode*
node = &root;
475 for (
size_t depth = 0; depth < levels; ++depth) {
477 if (
node->explored && !
node->inner)
return std::nullopt;
488 for (
int i = 0; i < 2; ++i) {
489 if (
node->sub[i]->hash == hash || (
node->sub[i]->hash.IsNull() &&
node->sub[1-i]->hash != hash)) {
490 node->sub[i]->hash = hash;
496 if (!desc)
return std::nullopt;
499 node->explored =
true;
501 node->sub[0] = std::make_unique<TreeNode>();
502 node->sub[1] = std::make_unique<TreeNode>();
503 node->sub[1]->hash = hash;
508 if (
node->sub[0])
return std::nullopt;
509 node->explored =
true;
512 node->hash = leaf_hash;
518 std::vector<TreeNode*> stack{&root};
519 while (!stack.empty()) {
520 TreeNode&
node = *stack.back();
521 if (!
node.explored) {
524 }
else if (!
node.inner) {
526 ret.emplace_back(stack.size() - 1,
node.leaf->first,
node.leaf->second);
529 }
else if (
node.sub[0]->done && !
node.sub[1]->done && !
node.sub[1]->explored && !
node.sub[1]->hash.IsNull() &&
544 node.sub[0]->done =
false;
545 node.sub[1]->done =
true;
546 }
else if (
node.sub[0]->done &&
node.sub[1]->done) {
548 node.sub[0]->done =
false;
549 node.sub[1]->done =
false;
552 }
else if (!
node.sub[0]->done) {
554 stack.push_back(&*
node.sub[0]);
555 }
else if (!
node.sub[1]->done) {
557 stack.push_back(&*
node.sub[1]);
567 std::vector<std::tuple<uint8_t, uint8_t, std::vector<unsigned char>>> tuples;
569 const auto& leaves =
m_branch[0]->leaves;
570 for (
const auto& leaf : leaves) {
572 uint8_t depth = (uint8_t)leaf.merkle_branch.size();
573 uint8_t leaf_ver = (uint8_t)leaf.leaf_version;
574 tuples.emplace_back(depth, leaf_ver, leaf.script);
CScriptID ToScriptID(const ScriptHash &script_hash)
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a scriptPubKey for the destination.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
CKeyID ToKeyID(const PKHash &key_hash)
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
An encapsulated private key.
CPubKey GetPubKey() const
Compute the public key from a private key.
A reference to a CKey: the Hash160 of its serialized public key.
An encapsulated public key.
bool IsCompressed() const
Check whether this is a compressed public key.
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Serialized script, used inside transaction inputs and outputs.
A reference to a CScript: the Hash160 of its serialization.
virtual bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey)
virtual bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const override
virtual bool GetCScript(const CScriptID &hash, CScript &redeemScriptOut) const override
virtual bool GetKey(const CKeyID &address, CKey &keyOut) const override
virtual bool AddCScript(const CScript &redeemScript)
void ImplicitlyLearnRelatedKeyScripts(const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
virtual std::set< CKeyID > GetKeys() const
virtual std::set< CScriptID > GetCScripts() const
virtual bool HaveCScript(const CScriptID &hash) const override
RecursiveMutex cs_KeyStore
virtual bool HaveKey(const CKeyID &address) const override
bool GetTaprootSpendData(const XOnlyPubKey &output_key, TaprootSpendData &spenddata) const override
bool GetKey(const CKeyID &keyid, CKey &key) const override
bool GetKeyOrigin(const CKeyID &keyid, KeyOriginInfo &info) const override
const SigningProvider * m_provider
bool GetPubKey(const CKeyID &keyid, CPubKey &pubkey) const override
bool GetTaprootBuilder(const XOnlyPubKey &output_key, TaprootBuilder &builder) const override
bool GetCScript(const CScriptID &scriptid, CScript &script) const override
bool GetKey(const CKeyID &keyid, CKey &key) const override
bool GetKeyOrigin(const CKeyID &keyid, KeyOriginInfo &info) const override
bool GetTaprootSpendData(const XOnlyPubKey &output_key, TaprootSpendData &spenddata) const override
std::vector< std::unique_ptr< SigningProvider > > m_providers
bool GetPubKey(const CKeyID &keyid, CPubKey &pubkey) const override
bool GetTaprootBuilder(const XOnlyPubKey &output_key, TaprootBuilder &builder) const override
void AddProvider(std::unique_ptr< SigningProvider > provider)
bool GetCScript(const CScriptID &scriptid, CScript &script) const override
An interface to be implemented by keystores that support signing.
virtual bool GetCScript(const CScriptID &scriptid, CScript &script) const
virtual bool GetTaprootSpendData(const XOnlyPubKey &output_key, TaprootSpendData &spenddata) const
virtual bool GetPubKey(const CKeyID &address, CPubKey &pubkey) const
virtual bool GetTaprootBuilder(const XOnlyPubKey &output_key, TaprootBuilder &builder) const
virtual bool GetKey(const CKeyID &address, CKey &key) const
virtual bool GetKeyOrigin(const CKeyID &keyid, KeyOriginInfo &info) const
bool GetPubKeyByXOnly(const XOnlyPubKey &pubkey, CPubKey &out) const
A Span is an object that can refer to a contiguous sequence of objects.
Utility class to construct Taproot outputs from internal key and script tree.
WitnessV1Taproot GetOutput()
Compute scriptPubKey (after Finalize()).
static NodeInfo Combine(NodeInfo &&a, NodeInfo &&b)
Combine information about a parent Merkle tree node from its child nodes.
TaprootSpendData GetSpendData() const
Compute spending data (after Finalize()).
bool IsComplete() const
Return whether there were either no leaves, or the leaves form a Huffman tree.
static bool ValidDepths(const std::vector< int > &depths)
Check if a list of depths is legal (will lead to IsComplete()).
void Insert(NodeInfo &&node, int depth)
Insert information about a node at a certain depth, and propagate information up.
XOnlyPubKey m_internal_key
The internal key, set when finalizing.
XOnlyPubKey m_output_key
The output key, computed when finalizing.
bool IsValid() const
Return true if so far all input was valid.
TaprootBuilder & Add(int depth, Span< const unsigned char > script, int leaf_version, bool track=true)
Add a new script at a certain depth in the tree.
std::vector< std::optional< NodeInfo > > m_branch
The current state of the builder.
TaprootBuilder & AddOmitted(int depth, const uint256 &hash)
Like Add(), but for a Merkle node with a given hash to the tree.
TaprootBuilder & Finalize(const XOnlyPubKey &internal_key)
Finalize the construction.
bool m_parity
The tweak parity, computed when finalizing.
std::vector< std::tuple< uint8_t, uint8_t, std::vector< unsigned char > > > GetTreeTuples() const
Returns a vector of tuples representing the depth, leaf version, and script.
bool m_valid
Whether the builder is in a valid state so far.
const unsigned char * end() const
bool IsNull() const
Test whether this is the 0 key (the result of default construction).
const unsigned char * begin() const
std::optional< std::pair< XOnlyPubKey, bool > > CreateTapTweak(const uint256 *merkle_root) const
Construct a Taproot tweaked output point with this point as internal key.
bool IsFullyValid() const
Determine if this pubkey is fully valid.
constexpr bool IsNull() const
static constexpr unsigned int size()
constexpr unsigned char * begin()
uint256 ComputeTaprootMerkleRoot(Span< const unsigned char > control, const uint256 &tapleaf_hash)
Compute the BIP341 taproot script tree Merkle root from control block and leaf hash.
uint256 ComputeTapleafHash(uint8_t leaf_version, Span< const unsigned char > script)
Compute the BIP341 tapleaf hash from leaf version & script.
uint256 ComputeTapbranchHash(Span< const unsigned char > a, Span< const unsigned char > b)
Compute the BIP341 tapbranch hash from two branches.
static constexpr uint8_t TAPROOT_LEAF_MASK
static constexpr size_t TAPROOT_CONTROL_NODE_SIZE
static constexpr size_t TAPROOT_CONTROL_MAX_NODE_COUNT
static constexpr size_t TAPROOT_CONTROL_MAX_SIZE
static constexpr size_t TAPROOT_CONTROL_BASE_SIZE
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE
std::optional< std::vector< std::tuple< int, std::vector< unsigned char >, int > > > InferTaprootTree(const TaprootSpendData &spenddata, const XOnlyPubKey &output)
Given a TaprootSpendData and the output key, reconstruct its script tree.
const SigningProvider & DUMMY_SIGNING_PROVIDER
bool LookupHelper(const M &map, const K &key, V &value)
CKeyID GetKeyForDestination(const SigningProvider &store, const CTxDestination &dest)
Return the CKeyID of the key involved in a script (if there is a unique one).
bool GetPubKey(const CKeyID &keyid, CPubKey &pubkey) const override
FlatSigningProvider & Merge(FlatSigningProvider &&b) LIFETIMEBOUND
std::map< CKeyID, std::pair< CPubKey, KeyOriginInfo > > origins
bool GetTaprootBuilder(const XOnlyPubKey &output_key, TaprootBuilder &builder) const override
bool GetKey(const CKeyID &keyid, CKey &key) const override
std::map< CKeyID, CPubKey > pubkeys
std::map< CKeyID, CKey > keys
bool GetKeyOrigin(const CKeyID &keyid, KeyOriginInfo &info) const override
std::map< CScriptID, CScript > scripts
std::map< XOnlyPubKey, TaprootBuilder > tr_trees
bool GetCScript(const CScriptID &scriptid, CScript &script) const override
Map from output key to Taproot tree (which can then make the TaprootSpendData.
bool GetTaprootSpendData(const XOnlyPubKey &output_key, TaprootSpendData &spenddata) const override
Information about a tracked leaf in the Merkle tree.
Information associated with a node in the Merkle tree.
uint256 hash
Merkle hash of this node.
uint256 merkle_root
The Merkle root of the script tree (0 if no scripts).
std::map< std::pair< std::vector< unsigned char >, int >, std::set< std::vector< unsigned char >, ShortestVectorFirstComparator > > scripts
Map from (script, leaf_version) to (sets of) control blocks.
void Merge(TaprootSpendData other)
Merge other TaprootSpendData (for the same scriptPubKey) into this.
XOnlyPubKey internal_key
The BIP341 internal key.
#define AssertLockHeld(cs)