Skip to content

Commit 6eddab6

Browse files
committed
Add Script::Tree note about prehashed merkle root, update tests
1 parent fe2f398 commit 6eddab6

2 files changed

Lines changed: 58 additions & 43 deletions

File tree

lib/Bitcoin/Crypto/Script/Tree.pm

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,11 @@ instead:
300300
hash => bytestring with prehashed leaf,
301301
}
302302
303+
Same logic can be applied if only the merkle root of the tree is known - simply
304+
introduce a prehashed structure as the only element of the tree. This can be
305+
useful in places where a script tree object is required for its root hash, but
306+
you don't have the full tree - for example in PSBTs.
307+
303308
=head1 INTERFACE
304309
305310
=head2 Attributes

t/Script/Tree.t

Lines changed: 53 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,53 +2,53 @@ use Test2::V0;
22
use Bitcoin::Crypto qw(btc_script_tree);
33
use Bitcoin::Crypto::Util qw(to_format);
44

5-
# this example is a modified test case from BIP341
6-
my $tree = btc_script_tree->new(
7-
tree => [
8-
{
9-
id => 0,
10-
leaf_version => 192,
11-
script => [hex => '2071981521ad9fc9036687364118fb6ccd2035b96a423c59c5430e98310a11abe2ac']
12-
},
13-
[
14-
{
15-
id => 1,
16-
leaf_version => 192,
17-
script => [hex => '20d5094d2dbe9b76e2c245a2b89b6006888952e2faa6a149ae318d69e520617748ac']
18-
},
19-
{
20-
id => 2,
21-
leaf_version => 192,
22-
script => [hex => '20c440b462ad48c7a77f94cd4532d8f2119dcebbd7c9764557e62726419b08ad4cac']
23-
}
24-
]
25-
]
26-
);
5+
subtest 'should calculate tree root' => sub {
276

28-
my $tree_prehashed = btc_script_tree->new(
29-
tree => [
30-
{hash => [hex => 'f154e8e8e17c31d3462d7132589ed29353c6fafdb884c5a6e04ea938834f0d9d']},
31-
[
7+
# this example is a modified test case from BIP341
8+
my $tree = btc_script_tree->new(
9+
tree => [
3210
{
11+
id => 0,
3312
leaf_version => 192,
34-
script => [hex => '20d5094d2dbe9b76e2c245a2b89b6006888952e2faa6a149ae318d69e520617748ac']
13+
script => [hex => '2071981521ad9fc9036687364118fb6ccd2035b96a423c59c5430e98310a11abe2ac']
3514
},
36-
{hash => [hex => 'd7485025fceb78b9ed667db36ed8b8dc7b1f0b307ac167fa516fe4352b9f4ef7']},
15+
[
16+
{
17+
id => 1,
18+
leaf_version => 192,
19+
script => [hex => '20d5094d2dbe9b76e2c245a2b89b6006888952e2faa6a149ae318d69e520617748ac']
20+
},
21+
{
22+
id => 2,
23+
leaf_version => 192,
24+
script => [hex => '20c440b462ad48c7a77f94cd4532d8f2119dcebbd7c9764557e62726419b08ad4cac']
25+
}
26+
]
3727
]
38-
]
39-
);
28+
);
4029

41-
my $tree_from_path = btc_script_tree->from_path(
42-
{
43-
leaf_version => 192,
44-
script => [hex => '20d5094d2dbe9b76e2c245a2b89b6006888952e2faa6a149ae318d69e520617748ac']
45-
}, [
46-
[hex => 'd7485025fceb78b9ed667db36ed8b8dc7b1f0b307ac167fa516fe4352b9f4ef7'],
47-
[hex => 'f154e8e8e17c31d3462d7132589ed29353c6fafdb884c5a6e04ea938834f0d9d'],
48-
]
49-
);
30+
my $tree_prehashed = btc_script_tree->new(
31+
tree => [
32+
{hash => [hex => 'f154e8e8e17c31d3462d7132589ed29353c6fafdb884c5a6e04ea938834f0d9d']},
33+
[
34+
{
35+
leaf_version => 192,
36+
script => [hex => '20d5094d2dbe9b76e2c245a2b89b6006888952e2faa6a149ae318d69e520617748ac']
37+
},
38+
{hash => [hex => 'd7485025fceb78b9ed667db36ed8b8dc7b1f0b307ac167fa516fe4352b9f4ef7']},
39+
]
40+
]
41+
);
5042

51-
subtest 'testing merkle_root' => sub {
43+
my $tree_from_path = btc_script_tree->from_path(
44+
{
45+
leaf_version => 192,
46+
script => [hex => '20d5094d2dbe9b76e2c245a2b89b6006888952e2faa6a149ae318d69e520617748ac']
47+
}, [
48+
[hex => 'd7485025fceb78b9ed667db36ed8b8dc7b1f0b307ac167fa516fe4352b9f4ef7'],
49+
[hex => 'f154e8e8e17c31d3462d7132589ed29353c6fafdb884c5a6e04ea938834f0d9d'],
50+
]
51+
);
5252
is(
5353
to_format [hex => $tree->get_merkle_root],
5454
'2f6b2c5397b6d68ca18e09a3f05161668ffe93a988582d55c6f07bd5b3329def',
@@ -68,10 +68,20 @@ subtest 'testing merkle_root' => sub {
6868
);
6969
};
7070

71-
subtest 'testing from_path with empty path' => sub {
72-
my $tree;
71+
subtest 'tree merkle root should be equal to the hash of the single tree element' => sub {
72+
my $root = '2f6b2c5397b6d68ca18e09a3f05161668ffe93a988582d55c6f07bd5b3329def';
73+
my $tree_root_only = btc_script_tree->new(tree => [{hash => [hex => $root]}]);
74+
75+
is(
76+
to_format [hex => $tree_root_only->get_merkle_root],
77+
$root,
78+
'precalculated merkle root ok'
79+
);
80+
};
81+
82+
subtest 'should create a tree using from_path with empty path' => sub {
7383
ok lives {
74-
$tree = btc_script_tree->from_path(
84+
btc_script_tree->from_path(
7585
{
7686
leaf_version => 192,
7787
script => [hex => '20d5094d2dbe9b76e2c245a2b89b6006888952e2faa6a149ae318d69e520617748ac']

0 commit comments

Comments
 (0)