@@ -3,20 +3,18 @@ import { PendingBranch } from './PendingBranch.js';
33import { IDataHasher } from '../../crypto/hash/IDataHasher.js' ;
44import { IDataHasherFactory } from '../../crypto/hash/IDataHasherFactory.js' ;
55import { dedent } from '../../util/StringUtils.js' ;
6- import { bitsToString } from '../SparseMerkleTreePathUtils.js' ;
6+ import { bitsToString , commonPrefixLength } from '../SparseMerkleTreePathUtils.js' ;
77
88/**
99 * Pending interior node in a radix sparse Merkle tree, awaiting hashing.
1010 */
1111export class PendingNodeBranch {
12- public constructor (
12+ private constructor (
1313 private readonly _path : Uint8Array ,
1414 public readonly depth : number ,
1515 public readonly left : PendingBranch ,
1616 public readonly right : PendingBranch ,
17- ) {
18- this . _path = new Uint8Array ( _path ) ;
19- }
17+ ) { }
2018
2119 /**
2220 * @returns {Uint8Array } Copy of the node's committed region (its `depth`-bit prefix, suffix zeroed).
@@ -25,6 +23,29 @@ export class PendingNodeBranch {
2523 return this . _path . slice ( ) ;
2624 }
2725
26+ /**
27+ * Create a pending node, defensively copying the committed region.
28+ *
29+ * @param {Uint8Array } path Committed region (its `depth`-bit prefix, suffix zeroed).
30+ * @param {number } depth Node depth.
31+ * @param {PendingBranch } left Left child.
32+ * @param {PendingBranch } right Right child.
33+ * @returns {PendingNodeBranch } New pending node.
34+ */
35+ public static create ( path : Uint8Array , depth : number , left : PendingBranch , right : PendingBranch ) : PendingNodeBranch {
36+ return new PendingNodeBranch ( new Uint8Array ( path ) , depth , left , right ) ;
37+ }
38+
39+ /**
40+ * Depth at which `key` diverges from this node's committed region, capped at the node's own depth.
41+ *
42+ * @param {Uint8Array } key Key being inserted.
43+ * @returns {number } Common-prefix depth.
44+ */
45+ public calculateSplitDepth ( key : Uint8Array ) : number {
46+ return commonPrefixLength ( key , this . _path , this . depth ) ;
47+ }
48+
2849 /**
2950 * Hash this node (after finalizing children).
3051 *
@@ -44,4 +65,24 @@ export class PendingNodeBranch {
4465 Left: ${ this . left . toString ( ) }
4566 Right: ${ this . right . toString ( ) } ` ;
4667 }
68+
69+ /**
70+ * Derive a node with `left` as its left child, reusing this node's committed region without copying it.
71+ *
72+ * @param {PendingBranch } left Replacement left child.
73+ * @returns {PendingNodeBranch } New pending node.
74+ */
75+ public withLeftBranch ( left : PendingBranch ) : PendingNodeBranch {
76+ return new PendingNodeBranch ( this . _path , this . depth , left , this . right ) ;
77+ }
78+
79+ /**
80+ * Derive a node with `right` as its right child, reusing this node's committed region without copying it.
81+ *
82+ * @param {PendingBranch } right Replacement right child.
83+ * @returns {PendingNodeBranch } New pending node.
84+ */
85+ public withRightBranch ( right : PendingBranch ) : PendingNodeBranch {
86+ return new PendingNodeBranch ( this . _path , this . depth , this . left , right ) ;
87+ }
4788}
0 commit comments