github.com/koko1123/flow-go-1@v0.29.6/storage/merkle/node.go (about) 1 // (c) 2019 Dapper Labs - ALL RIGHTS RESERVED 2 3 package merkle 4 5 import ( 6 "golang.org/x/crypto/blake2b" 7 ) 8 9 // The node represents a generic vertex in the sparse Merkle trie. 10 // CONVENTION: 11 // - This implementation guarantees that within the trie there are 12 // _never_ nil-references to descendants. We completely avoid this by 13 // utilizing `short nodes` that represent any path-segment without branching. 14 type node interface { 15 // Hash computes recursively the hash of this respective sub trie. 16 // To simplify enforcing cryptographic security, we introduce the convention 17 // that hashing a nil node is an illegal operation, which panics. 18 // If cacheEnabled is set the node stores the computed hash value for future 19 // calls to the Hash function. Note that the cached value is only returned 20 // when cacheEnabled is also set for the future calls. 21 Hash(cacheEnabled bool) []byte 22 23 // MaxDepthOfDescendants returns the length of the longest path from this node to any of the decedent leaf nodes, 24 // i.e. it returns the maximum depth of the subtree under this node. 25 MaxDepthOfDescendants() uint 26 } 27 28 // NodeTags encodes the type of node when hashing it. Required for cryptographic 29 // safety to prevent collision attacks (replacing a full node with a short node 30 // that has identical hash would otherwise be possible). 31 // Values are intended to be global constants and must be unique. 32 var ( 33 leafNodeTag = []byte{0} 34 fullNodeTag = []byte{1} 35 shortNodeTag = []byte{2} 36 ) 37 38 // Short Node 39 // Per convention a Short node has always _one child_, which is either 40 // a full node or a leaf. 41 42 type short struct { 43 count int // holds the count of bits in the path 44 path []byte // holds the common path to the next node 45 child node // holds the child after the common path; never nil 46 cachedHashValue []byte // cached hash value 47 } 48 49 var _ node = &short{} 50 51 func computeShortHash(count int, path []byte, childHash []byte) []byte { 52 c := serializedPathSegmentLength(count) 53 h, _ := blake2b.New256(shortNodeTag) // blake2b.New256(..) never errors for given MAC (verified in tests) 54 _, _ = h.Write(c[:]) // blake2b.Write(..) never errors for _any_ input 55 _, _ = h.Write(path) // blake2b.Write(..) never errors for _any_ input 56 _, _ = h.Write(childHash) // blake2b.Write(..) never errors for _any_ input 57 return h.Sum(nil) 58 } 59 60 func (n *short) Hash(cacheEnabled bool) []byte { 61 if !cacheEnabled { 62 return computeShortHash(n.count, n.path, n.child.Hash(cacheEnabled)) 63 } 64 if len(n.cachedHashValue) == 0 { 65 n.cachedHashValue = computeShortHash(n.count, n.path, n.child.Hash(cacheEnabled)) 66 } 67 return n.cachedHashValue 68 } 69 70 func (n *short) MaxDepthOfDescendants() uint { 71 return n.child.MaxDepthOfDescendants() + 1 72 } 73 74 // serializedPathSegmentLength serializes the bitCount into two bytes. 75 // We are able to represent key length of up to 65528 bits 76 func serializedPathSegmentLength(bitCount int) [2]byte { 77 var byteCount [2]byte 78 byteCount[0] = byte(bitCount >> 8) 79 byteCount[1] = byte(bitCount) 80 return byteCount 81 } 82 83 //Full Node 84 // Per convention a Full Node has always _two children_. Nil values not allowed. 85 86 type full struct { 87 left node // holds the left path node (bit 0); never nil 88 right node // holds the right path node (bit 1); never nil 89 cachedHashValue []byte // cached hash value 90 } 91 92 var _ node = &full{} 93 94 func computeFullHash(leftChildHash, rightChildHash []byte) []byte { 95 h, _ := blake2b.New256(fullNodeTag) // blake2b.New256(..) never errors for given MAC (verified in tests) 96 _, _ = h.Write(leftChildHash) // blake2b.Write(..) never errors for _any_ input 97 _, _ = h.Write(rightChildHash) // blake2b.Write(..) never errors for _any_ input 98 return h.Sum(nil) 99 } 100 101 func (n *full) Hash(cacheEnabled bool) []byte { 102 if !cacheEnabled { 103 return computeFullHash(n.left.Hash(cacheEnabled), n.right.Hash(cacheEnabled)) 104 } 105 if len(n.cachedHashValue) == 0 { 106 n.cachedHashValue = computeFullHash(n.left.Hash(cacheEnabled), n.right.Hash(cacheEnabled)) 107 } 108 return n.cachedHashValue 109 } 110 111 func (n *full) MaxDepthOfDescendants() uint { 112 left := n.left.MaxDepthOfDescendants() 113 right := n.right.MaxDepthOfDescendants() 114 if left < right { 115 return right + 1 116 } 117 return left + 1 118 } 119 120 // Leaf Node 121 // Leaf represents a key-value pair. We only store the value, because the 122 // key is implicitly stored as the merkle path through the tree. 123 124 type leaf struct { 125 val []byte 126 cachedHashValue []byte // cached hash value 127 } 128 129 var _ node = &leaf{} 130 131 func computeLeafHash(value []byte) []byte { 132 h, _ := blake2b.New256(leafNodeTag) // blake2b.New256(..) never errors for given MAC (verified in tests) 133 _, _ = h.Write(value) // blake2b.Write(..) never errors for _any_ input 134 return h.Sum(nil) 135 } 136 137 func (n *leaf) Hash(cacheEnabled bool) []byte { 138 if !cacheEnabled { 139 return computeLeafHash(n.val) 140 } 141 if len(n.cachedHashValue) == 0 { 142 n.cachedHashValue = computeLeafHash(n.val) 143 } 144 return n.cachedHashValue 145 } 146 147 func (n *leaf) MaxDepthOfDescendants() uint { 148 return 0 149 } 150 151 // Dummy Node 152 // Dummy node type as substitute for `nil`. Not used in the trie, but as zero 153 // value for auxiliary variables during trie update operations. This reduces 154 // complexity of the business logic, as we can then also apply the convention of 155 // "nodes are never nil" to the auxiliary variables. 156 157 type dummy struct{} 158 159 var _ node = &dummy{} 160 161 func (n *dummy) Hash(_ bool) []byte { 162 // Per convention, Hash should never be called by the business logic but 163 // is required to implement the node interface 164 panic("dummy node has no hash") 165 } 166 167 func (n *dummy) MaxDepthOfDescendants() uint { 168 return 0 169 }