Skip to content

Commit 74d9598

Browse files
committed
Merge bitcoin/bitcoin#32134: descriptors: Multipath/PR 22838 follow-ups
56f271e descriptors refactor: Clarify multipath data relationships through local struct (Hodlinator) 7e974f4 descriptors refactor: Use range-for and limit scope of seen_multipath (Hodlinator) 99a92ef descriptors doc: Correct Markdown format + wording (Hodlinator) Pull request description: Follows up on unresolved suggestions from #22838. In order of priority: 1. Fixes a couple of typos [^1][^2] and indentation to conform to Markdown. 2. Solves `for`-loop nit [^3] and also limits variable scope. 3. Clarifies data relationships [^4][^5] by introducing `struct` rather than comments. [^1]: bitcoin/bitcoin#22838 (comment) [^2]: bitcoin/bitcoin#22838 (comment) [^3]: bitcoin/bitcoin#22838 (comment) [^4]: bitcoin/bitcoin#22838 (comment) [^5]: bitcoin/bitcoin#22838 (comment) ACKs for top commit: Prabhat1308: re-ACK [`56f271e`](bitcoin/bitcoin@56f271e) mabu44: tACK 56f271e l0rinc: utACK 56f271e rkrux: crACK 56f271e Tree-SHA512: 75777c911640038a3e0ea48601c0f55463a5f8ff5b3462d81e8992d9fc8f988d5a240e2166befa67a2a246696b0863f8e2508524c14697c490d3b229fe048996
2 parents 3358b1d + 56f271e commit 74d9598

File tree

2 files changed

+19
-15
lines changed

2 files changed

+19
-15
lines changed

doc/descriptors.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -288,11 +288,11 @@ For example, a descriptor of the form:
288288

289289
multi(2,xpub.../<0;1;2>/0/*,xpub.../<2;3;4>/*)
290290

291-
will expand to the two descriptors
291+
will expand to the 3 descriptors
292292

293-
multi(2,xpub.../0/0/*,xpub.../2/*)
294-
multi(2,xpub.../1/0/*,xpub.../3/*)
295-
multi(2,xpub.../2/0/*,xpub.../4*)
293+
multi(2,xpub.../0/0/*,xpub.../2/*)
294+
multi(2,xpub.../1/0/*,xpub.../3/*)
295+
multi(2,xpub.../2/0/*,xpub.../4/*)
296296

297297
When this tuple contains only two elements, wallet implementations can use the
298298
first descriptor for receiving addresses and the second descriptor for change addresses.

src/script/descriptor.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,20 +1440,22 @@ std::optional<uint32_t> ParseKeyPathNum(std::span<const char> elem, bool& apostr
14401440
[[nodiscard]] bool ParseKeyPath(const std::vector<std::span<const char>>& split, std::vector<KeyPath>& out, bool& apostrophe, std::string& error, bool allow_multipath)
14411441
{
14421442
KeyPath path;
1443-
std::optional<size_t> multipath_segment_index;
1444-
std::vector<uint32_t> multipath_values;
1445-
std::unordered_set<uint32_t> seen_multipath;
1443+
struct MultipathSubstitutes {
1444+
size_t placeholder_index;
1445+
std::vector<uint32_t> values;
1446+
};
1447+
std::optional<MultipathSubstitutes> substitutes;
14461448

14471449
for (size_t i = 1; i < split.size(); ++i) {
14481450
const std::span<const char>& elem = split[i];
14491451

1450-
// Check if element contain multipath specifier
1452+
// Check if element contains multipath specifier
14511453
if (!elem.empty() && elem.front() == '<' && elem.back() == '>') {
14521454
if (!allow_multipath) {
14531455
error = strprintf("Key path value '%s' specifies multipath in a section where multipath is not allowed", std::string(elem.begin(), elem.end()));
14541456
return false;
14551457
}
1456-
if (multipath_segment_index) {
1458+
if (substitutes) {
14571459
error = "Multiple multipath key path specifiers found";
14581460
return false;
14591461
}
@@ -1465,33 +1467,35 @@ std::optional<uint32_t> ParseKeyPathNum(std::span<const char> elem, bool& apostr
14651467
return false;
14661468
}
14671469

1470+
substitutes.emplace();
1471+
std::unordered_set<uint32_t> seen_substitutes;
14681472
for (const auto& num : nums) {
14691473
const auto& op_num = ParseKeyPathNum(num, apostrophe, error);
14701474
if (!op_num) return false;
1471-
auto [_, inserted] = seen_multipath.insert(*op_num);
1475+
auto [_, inserted] = seen_substitutes.insert(*op_num);
14721476
if (!inserted) {
14731477
error = strprintf("Duplicated key path value %u in multipath specifier", *op_num);
14741478
return false;
14751479
}
1476-
multipath_values.emplace_back(*op_num);
1480+
substitutes->values.emplace_back(*op_num);
14771481
}
14781482

14791483
path.emplace_back(); // Placeholder for multipath segment
1480-
multipath_segment_index = path.size()-1;
1484+
substitutes->placeholder_index = path.size() - 1;
14811485
} else {
14821486
const auto& op_num = ParseKeyPathNum(elem, apostrophe, error);
14831487
if (!op_num) return false;
14841488
path.emplace_back(*op_num);
14851489
}
14861490
}
14871491

1488-
if (!multipath_segment_index) {
1492+
if (!substitutes) {
14891493
out.emplace_back(std::move(path));
14901494
} else {
14911495
// Replace the multipath placeholder with each value while generating paths
1492-
for (size_t i = 0; i < multipath_values.size(); i++) {
1496+
for (uint32_t substitute : substitutes->values) {
14931497
KeyPath branch_path = path;
1494-
branch_path[*multipath_segment_index] = multipath_values[i];
1498+
branch_path[substitutes->placeholder_index] = substitute;
14951499
out.emplace_back(std::move(branch_path));
14961500
}
14971501
}

0 commit comments

Comments
 (0)