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
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
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 int tweak(const secp256k1_context *ctx, secp256k1_xonly_pubkey *agg_pk, secp256k1_musig_keyagg_cache *cache)
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 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.