@@ -30,7 +30,7 @@ pragma solidity ^0.8.4;
30
30
*
31
31
* uintTreaple.getRoot();
32
32
*
33
- * CartesianMerkleTree.Proof memory proof = uintTreaple.getProof(100);
33
+ * CartesianMerkleTree.Proof memory proof = uintTreaple.getProof(100, 0 );
34
34
*
35
35
* uintTreaple.getNodeByKey(100);
36
36
*
@@ -590,6 +590,7 @@ library CartesianMerkleTree {
590
590
* @param root The root hash of the Cartesian Merkle tree.
591
591
* @param siblings An array of sibling hashes can be used to get the Cartesian Merkle Root.
592
592
* @param siblingsLength The number of siblings to be used for evidence.
593
+ * @param directionBits A path from the root to the node.
593
594
* @param existence Indicates the presence (true) or absence (false) of the node.
594
595
* @param key The key associated with the node.
595
596
* @param nonExistenceKey The non-existence key of the auxiliary node in case when existence is false.
@@ -598,6 +599,7 @@ library CartesianMerkleTree {
598
599
bytes32 root;
599
600
bytes32 [] siblings;
600
601
uint256 siblingsLength;
602
+ uint256 directionBits;
601
603
bool existence;
602
604
bytes32 key;
603
605
bytes32 nonExistenceKey;
@@ -775,6 +777,7 @@ library CartesianMerkleTree {
775
777
root: _rootMerkleHash (treaple),
776
778
siblings: new bytes32 [](desiredProofSize_),
777
779
siblingsLength: 0 ,
780
+ directionBits: 0 ,
778
781
existence: false ,
779
782
key: key_,
780
783
nonExistenceKey: ZERO_HASH
@@ -787,20 +790,23 @@ library CartesianMerkleTree {
787
790
Node storage node;
788
791
uint256 currentSiblingsIndex_;
789
792
uint256 nextNodeId_ = treaple.merkleRootId;
793
+ uint256 directionBits_;
790
794
791
795
while (true ) {
792
796
node = treaple.nodes[uint64 (nextNodeId_)];
793
797
794
798
if (node.key == key_) {
795
- _addProofSibling (
796
- proof_,
797
- currentSiblingsIndex_++ ,
798
- treaple.nodes[node.childLeft].merkleHash
799
- );
800
- _addProofSibling (
801
- proof_,
802
- currentSiblingsIndex_++ ,
803
- treaple.nodes[node.childRight].merkleHash
799
+ bytes32 leftHash_ = treaple.nodes[node.childLeft].merkleHash;
800
+ bytes32 rightHash_ = treaple.nodes[node.childRight].merkleHash;
801
+
802
+ _addProofSibling (proof_, currentSiblingsIndex_++ , leftHash_);
803
+ _addProofSibling (proof_, currentSiblingsIndex_++ , rightHash_);
804
+
805
+ proof_.directionBits = _calculateDirectionBit (
806
+ directionBits_,
807
+ currentSiblingsIndex_,
808
+ leftHash_,
809
+ rightHash_
804
810
);
805
811
806
812
proof_.existence = true ;
@@ -820,15 +826,17 @@ library CartesianMerkleTree {
820
826
}
821
827
822
828
if (nextNodeId_ == 0 ) {
823
- _addProofSibling (
824
- proof_,
825
- currentSiblingsIndex_++ ,
826
- treaple.nodes[node.childLeft].merkleHash
827
- );
828
- _addProofSibling (
829
- proof_,
830
- currentSiblingsIndex_++ ,
831
- treaple.nodes[node.childRight].merkleHash
829
+ bytes32 leftHash_ = treaple.nodes[node.childLeft].merkleHash;
830
+ bytes32 rightHash_ = treaple.nodes[node.childRight].merkleHash;
831
+
832
+ _addProofSibling (proof_, currentSiblingsIndex_++ , leftHash_);
833
+ _addProofSibling (proof_, currentSiblingsIndex_++ , rightHash_);
834
+
835
+ proof_.directionBits = _calculateDirectionBit (
836
+ directionBits_,
837
+ currentSiblingsIndex_,
838
+ leftHash_,
839
+ rightHash_
832
840
);
833
841
834
842
proof_.nonExistenceKey = node.key;
@@ -843,6 +851,13 @@ library CartesianMerkleTree {
843
851
currentSiblingsIndex_++ ,
844
852
treaple.nodes[otherNodeId_].merkleHash
845
853
);
854
+
855
+ directionBits_ = _calculateDirectionBit (
856
+ directionBits_,
857
+ currentSiblingsIndex_,
858
+ treaple.nodes[uint64 (nextNodeId_)].merkleHash,
859
+ treaple.nodes[otherNodeId_].merkleHash
860
+ );
846
861
}
847
862
848
863
return proof_;
@@ -875,6 +890,23 @@ library CartesianMerkleTree {
875
890
proof_.siblings[currentSiblingsIndex_] = siblingToAdd_;
876
891
}
877
892
893
+ function _calculateDirectionBit (
894
+ uint256 directionBits_ ,
895
+ uint256 currentSiblingsIndex_ ,
896
+ bytes32 leftHash_ ,
897
+ bytes32 rightHash_
898
+ ) private pure returns (uint256 ) {
899
+ if (currentSiblingsIndex_ != 2 ) {
900
+ directionBits_ <<= 1 ;
901
+ }
902
+
903
+ if (leftHash_ > rightHash_) {
904
+ directionBits_ |= 1 ;
905
+ }
906
+
907
+ return directionBits_;
908
+ }
909
+
878
910
function _hashNodes (CMT storage treaple , uint256 nodeId_ ) private view returns (bytes32 ) {
879
911
Node storage node = treaple.nodes[uint64 (nodeId_)];
880
912
0 commit comments