Skip to content

Commit 0577d42

Browse files
committed
psbt: Change m_tap_tree to store just the tuples
Instead of having an entire TaprootBuilder which may or may not be complete, and could potentially have future changes that interact oddly with taproot tree tuples, have m_tap_tree be just the tuples. When needed in other a TaprootBuilder for actual use, the tuples will be added to a a TaprootBuilder that, in the future, can take in whatever other data is needed as well.
1 parent 22c051c commit 0577d42

File tree

3 files changed

+19
-25
lines changed

3 files changed

+19
-25
lines changed

src/psbt.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,14 @@ void PSBTOutput::FillSignatureData(SignatureData& sigdata) const
218218
for (const auto& key_pair : hd_keypaths) {
219219
sigdata.misc_pubkeys.emplace(key_pair.first.GetID(), key_pair);
220220
}
221-
if (m_tap_tree.has_value() && m_tap_internal_key.IsFullyValid()) {
222-
TaprootSpendData spenddata = m_tap_tree->GetSpendData();
221+
if (!m_tap_tree.empty() && m_tap_internal_key.IsFullyValid()) {
222+
TaprootBuilder builder;
223+
for (const auto& [depth, leaf_ver, script] : m_tap_tree) {
224+
builder.Add((int)depth, script, (int)leaf_ver, /*track=*/true);
225+
}
226+
assert(builder.IsComplete());
227+
builder.Finalize(m_tap_internal_key);
228+
TaprootSpendData spenddata = builder.GetSpendData();
223229

224230
sigdata.tr_spenddata.internal_key = m_tap_internal_key;
225231
sigdata.tr_spenddata.Merge(spenddata);
@@ -244,7 +250,7 @@ void PSBTOutput::FromSignatureData(const SignatureData& sigdata)
244250
m_tap_internal_key = sigdata.tr_spenddata.internal_key;
245251
}
246252
if (sigdata.tr_builder.has_value()) {
247-
m_tap_tree = sigdata.tr_builder;
253+
m_tap_tree = sigdata.tr_builder->GetTreeTuples();
248254
}
249255
for (const auto& [pubkey, leaf_origin] : sigdata.taproot_misc_pubkeys) {
250256
m_tap_bip32_paths.emplace(pubkey, leaf_origin);
@@ -265,7 +271,7 @@ void PSBTOutput::Merge(const PSBTOutput& output)
265271
if (redeem_script.empty() && !output.redeem_script.empty()) redeem_script = output.redeem_script;
266272
if (witness_script.empty() && !output.witness_script.empty()) witness_script = output.witness_script;
267273
if (m_tap_internal_key.IsNull() && !output.m_tap_internal_key.IsNull()) m_tap_internal_key = output.m_tap_internal_key;
268-
if (!m_tap_tree.has_value() && output.m_tap_tree.has_value()) m_tap_tree = output.m_tap_tree;
274+
if (m_tap_tree.empty() && !output.m_tap_tree.empty()) m_tap_tree = output.m_tap_tree;
269275
}
270276
bool PSBTInputSigned(const PSBTInput& input)
271277
{

src/psbt.h

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,7 @@ struct PSBTOutput
713713
CScript witness_script;
714714
std::map<CPubKey, KeyOriginInfo> hd_keypaths;
715715
XOnlyPubKey m_tap_internal_key;
716-
std::optional<TaprootBuilder> m_tap_tree;
716+
std::vector<std::tuple<uint8_t, uint8_t, CScript>> m_tap_tree;
717717
std::map<XOnlyPubKey, std::pair<std::set<uint256>, KeyOriginInfo>> m_tap_bip32_paths;
718718
std::map<std::vector<unsigned char>, std::vector<unsigned char>> unknown;
719719
std::set<PSBTProprietary> m_proprietary;
@@ -754,15 +754,11 @@ struct PSBTOutput
754754
}
755755

756756
// Write taproot tree
757-
if (m_tap_tree.has_value()) {
757+
if (!m_tap_tree.empty()) {
758758
SerializeToVector(s, PSBT_OUT_TAP_TREE);
759759
std::vector<unsigned char> value;
760760
CVectorWriter s_value(s.GetType(), s.GetVersion(), value, 0);
761-
const auto& tuples = m_tap_tree->GetTreeTuples();
762-
for (const auto& tuple : tuples) {
763-
uint8_t depth = std::get<0>(tuple);
764-
uint8_t leaf_ver = std::get<1>(tuple);
765-
CScript script = std::get<2>(tuple);
761+
for (const auto& [depth, leaf_ver, script] : m_tap_tree) {
766762
s_value << depth;
767763
s_value << leaf_ver;
768764
s_value << script;
@@ -858,13 +854,13 @@ struct PSBTOutput
858854
} else if (key.size() != 1) {
859855
throw std::ios_base::failure("Output Taproot tree key is more than one byte type");
860856
}
861-
m_tap_tree.emplace();
862857
std::vector<unsigned char> tree_v;
863858
s >> tree_v;
864859
SpanReader s_tree(s.GetType(), s.GetVersion(), tree_v);
865860
if (s_tree.empty()) {
866861
throw std::ios_base::failure("Output Taproot tree must not be empty");
867862
}
863+
TaprootBuilder builder;
868864
while (!s_tree.empty()) {
869865
uint8_t depth;
870866
uint8_t leaf_ver;
@@ -878,9 +874,10 @@ struct PSBTOutput
878874
if ((leaf_ver & ~TAPROOT_LEAF_MASK) != 0) {
879875
throw std::ios_base::failure("Output Taproot tree has a leaf with an invalid leaf version");
880876
}
881-
m_tap_tree->Add((int)depth, script, (int)leaf_ver, true /* track */);
877+
m_tap_tree.push_back(std::make_tuple(depth, leaf_ver, script));
878+
builder.Add((int)depth, script, (int)leaf_ver, true /* track */);
882879
}
883-
if (!m_tap_tree->IsComplete()) {
880+
if (!builder.IsComplete()) {
884881
throw std::ios_base::failure("Output Taproot tree is malformed");
885882
}
886883
break;
@@ -934,11 +931,6 @@ struct PSBTOutput
934931
}
935932
}
936933

937-
// Finalize m_tap_tree so that all of the computed things are computed
938-
if (m_tap_tree.has_value() && m_tap_tree->IsComplete() && m_tap_internal_key.IsFullyValid()) {
939-
m_tap_tree->Finalize(m_tap_internal_key);
940-
}
941-
942934
if (!found_sep) {
943935
throw std::ios_base::failure("Separator is missing at the end of an output map");
944936
}

src/rpc/rawtransaction.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,13 +1241,9 @@ static RPCHelpMan decodepsbt()
12411241
}
12421242

12431243
// Taproot tree
1244-
if (output.m_tap_tree.has_value()) {
1244+
if (!output.m_tap_tree.empty()) {
12451245
UniValue tree(UniValue::VARR);
1246-
const auto& tuples = output.m_tap_tree->GetTreeTuples();
1247-
for (const auto& tuple : tuples) {
1248-
uint8_t depth = std::get<0>(tuple);
1249-
uint8_t leaf_ver = std::get<1>(tuple);
1250-
CScript script = std::get<2>(tuple);
1246+
for (const auto& [depth, leaf_ver, script] : output.m_tap_tree) {
12511247
UniValue elem(UniValue::VOBJ);
12521248
elem.pushKV("depth", (int)depth);
12531249
elem.pushKV("leaf_ver", (int)leaf_ver);

0 commit comments

Comments
 (0)