@@ -11,7 +11,7 @@ import {Panic} from "../Panic.sol";
11
11
*
12
12
* Each tree is a complete binary tree with the ability to sequentially insert leaves, changing them from a zero to a
13
13
* non-zero value and updating its root. This structure allows inserting commitments (or other entries) that are not
14
- * stored, but can be proven to be part of the tree at a later time. See {MerkleProof}.
14
+ * stored, but can be proven to be part of the tree at a later time if the root is kept . See {MerkleProof}.
15
15
*
16
16
* A tree is defined by the following parameters:
17
17
*
@@ -34,13 +34,13 @@ library MerkleTree {
34
34
* directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and
35
35
* lead to unexpected behavior.
36
36
*
37
- * NOTE: The `root` is kept up to date after each insertion without keeping track of its history. Consider
38
- * using a secondary structure to store a list of historical roots (e.g. a mapping, {BitMaps} or {Checkpoints}).
37
+ * NOTE: The `root` and the updates history is not stored within the tree. Consider using a secondary structure to
38
+ * store a list of historical roots from the values returned from {setup} and {push} (e.g. a mapping, {BitMaps} or
39
+ * {Checkpoints}).
39
40
*
40
41
* WARNING: Updating any of the tree's parameters after the first insertion will result in a corrupted tree.
41
42
*/
42
43
struct Bytes32PushTree {
43
- bytes32 _root;
44
44
uint256 _nextLeafIndex;
45
45
bytes32 [] _sides;
46
46
bytes32 [] _zeros;
@@ -56,7 +56,7 @@ library MerkleTree {
56
56
* IMPORTANT: The zero value should be carefully chosen since it will be stored in the tree representing
57
57
* empty leaves. It should be a value that is not expected to be part of the tree.
58
58
*/
59
- function setup (Bytes32PushTree storage self , uint8 levels , bytes32 zero ) internal {
59
+ function setup (Bytes32PushTree storage self , uint8 levels , bytes32 zero ) internal returns ( bytes32 initialRoot ) {
60
60
return setup (self, levels, zero, Hashes.commutativeKeccak256);
61
61
}
62
62
@@ -71,7 +71,7 @@ library MerkleTree {
71
71
uint8 levels ,
72
72
bytes32 zero ,
73
73
function (bytes32 , bytes32 ) view returns (bytes32 ) fnHash
74
- ) internal {
74
+ ) internal returns ( bytes32 initialRoot ) {
75
75
// Store depth in the dynamic array
76
76
Arrays.unsafeSetLength (self._sides, levels);
77
77
Arrays.unsafeSetLength (self._zeros, levels);
@@ -84,9 +84,10 @@ library MerkleTree {
84
84
}
85
85
86
86
// Set the first root
87
- self._root = currentZero;
88
87
self._nextLeafIndex = 0 ;
89
88
self._fnHash = fnHash;
89
+
90
+ return currentZero;
90
91
}
91
92
92
93
/**
@@ -102,15 +103,15 @@ library MerkleTree {
102
103
function (bytes32 , bytes32 ) view returns (bytes32 ) fnHash = self._fnHash;
103
104
104
105
// Get leaf index
105
- uint256 leafIndex = self._nextLeafIndex++ ;
106
+ index = self._nextLeafIndex++ ;
106
107
107
108
// Check if tree is full.
108
- if (leafIndex >= 1 << levels) {
109
+ if (index >= 1 << levels) {
109
110
Panic.panic (Panic.RESOURCE_ERROR);
110
111
}
111
112
112
113
// Rebuild branch from leaf to root
113
- uint256 currentIndex = leafIndex ;
114
+ uint256 currentIndex = index ;
114
115
bytes32 currentLevelHash = leaf;
115
116
for (uint32 i = 0 ; i < levels; i++ ) {
116
117
// Reaching the parent node, is currentLevelHash the left child?
@@ -132,17 +133,7 @@ library MerkleTree {
132
133
currentIndex >>= 1 ;
133
134
}
134
135
135
- // Record new root
136
- self._root = currentLevelHash;
137
-
138
- return (leafIndex, currentLevelHash);
139
- }
140
-
141
- /**
142
- * @dev Tree's current root
143
- */
144
- function root (Bytes32PushTree storage self ) internal view returns (bytes32 ) {
145
- return self._root;
136
+ return (index, currentLevelHash);
146
137
}
147
138
148
139
/**
0 commit comments