github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/state/stateutil/trie_helpers.go (about) 1 package stateutil 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 7 "github.com/pkg/errors" 8 "github.com/prysmaticlabs/prysm/shared/hashutil" 9 "github.com/prysmaticlabs/prysm/shared/htrutils" 10 "github.com/prysmaticlabs/prysm/shared/trieutil" 11 ) 12 13 // ReturnTrieLayer returns the representation of a merkle trie when 14 // provided with the elements of a fixed sized trie and the corresponding depth of 15 // it. 16 func ReturnTrieLayer(elements [][32]byte, length uint64) [][]*[32]byte { 17 hasher := hashutil.CustomSHA256Hasher() 18 leaves := elements 19 20 if len(leaves) == 1 { 21 return [][]*[32]byte{{&leaves[0]}} 22 } 23 hashLayer := leaves 24 layers := make([][][32]byte, htrutils.Depth(length)+1) 25 layers[0] = hashLayer 26 layers, _ = merkleizeTrieLeaves(layers, hashLayer, hasher) 27 refLayers := make([][]*[32]byte, len(layers)) 28 for i, val := range layers { 29 refLayers[i] = make([]*[32]byte, len(val)) 30 for j, innerVal := range val { 31 newVal := innerVal 32 refLayers[i][j] = &newVal 33 } 34 } 35 return refLayers 36 } 37 38 func merkleizeTrieLeaves(layers [][][32]byte, hashLayer [][32]byte, 39 hasher func([]byte) [32]byte) ([][][32]byte, [][32]byte) { 40 // We keep track of the hash layers of a Merkle trie until we reach 41 // the top layer of length 1, which contains the single root element. 42 // [Root] -> Top layer has length 1. 43 // [E] [F] -> This layer has length 2. 44 // [A] [B] [C] [D] -> The bottom layer has length 4 (needs to be a power of two). 45 i := 1 46 chunkBuffer := bytes.NewBuffer([]byte{}) 47 chunkBuffer.Grow(64) 48 for len(hashLayer) > 1 && i < len(layers) { 49 layer := make([][32]byte, len(hashLayer)/2) 50 for j := 0; j < len(hashLayer); j += 2 { 51 chunkBuffer.Write(hashLayer[j][:]) 52 chunkBuffer.Write(hashLayer[j+1][:]) 53 hashedChunk := hasher(chunkBuffer.Bytes()) 54 layer[j/2] = hashedChunk 55 chunkBuffer.Reset() 56 } 57 hashLayer = layer 58 layers[i] = hashLayer 59 i++ 60 } 61 return layers, hashLayer 62 } 63 64 // ReturnTrieLayerVariable returns the representation of a merkle trie when 65 // provided with the elements of a variable sized trie and the corresponding depth of 66 // it. 67 func ReturnTrieLayerVariable(elements [][32]byte, length uint64) [][]*[32]byte { 68 hasher := hashutil.CustomSHA256Hasher() 69 depth := htrutils.Depth(length) 70 layers := make([][]*[32]byte, depth+1) 71 // Return zerohash at depth 72 if len(elements) == 0 { 73 zerohash := trieutil.ZeroHashes[depth] 74 layers[len(layers)-1] = []*[32]byte{&zerohash} 75 return layers 76 } 77 transformedLeaves := make([]*[32]byte, len(elements)) 78 for i := range elements { 79 arr := elements[i] 80 transformedLeaves[i] = &arr 81 } 82 layers[0] = transformedLeaves 83 buffer := bytes.NewBuffer([]byte{}) 84 buffer.Grow(64) 85 for i := 0; i < int(depth); i++ { 86 oddNodeLength := len(layers[i])%2 == 1 87 if oddNodeLength { 88 zerohash := trieutil.ZeroHashes[i] 89 layers[i] = append(layers[i], &zerohash) 90 } 91 updatedValues := make([]*[32]byte, 0, len(layers[i])/2) 92 for j := 0; j < len(layers[i]); j += 2 { 93 buffer.Write(layers[i][j][:]) 94 buffer.Write(layers[i][j+1][:]) 95 concat := hasher(buffer.Bytes()) 96 updatedValues = append(updatedValues, &concat) 97 buffer.Reset() 98 } 99 // remove zerohash node from tree 100 if oddNodeLength { 101 layers[i] = layers[i][:len(layers[i])-1] 102 } 103 layers[i+1] = updatedValues 104 } 105 return layers 106 } 107 108 // RecomputeFromLayer recomputes specific branches of a fixed sized trie depending on the provided changed indexes. 109 func RecomputeFromLayer(changedLeaves [][32]byte, changedIdx []uint64, layer [][]*[32]byte) ([32]byte, [][]*[32]byte, error) { 110 hasher := hashutil.CustomSHA256Hasher() 111 for i, idx := range changedIdx { 112 layer[0][idx] = &changedLeaves[i] 113 } 114 115 if len(changedIdx) == 0 { 116 return *layer[0][0], layer, nil 117 } 118 119 leaves := layer[0] 120 121 // We need to ensure we recompute indices of the Merkle tree which 122 // changed in-between calls to this function. This check adds an offset 123 // to the recomputed indices to ensure we do so evenly. 124 maxChangedIndex := changedIdx[len(changedIdx)-1] 125 if int(maxChangedIndex+2) == len(leaves) && maxChangedIndex%2 != 0 { 126 changedIdx = append(changedIdx, maxChangedIndex+1) 127 } 128 129 root := *layer[0][0] 130 var err error 131 132 for _, idx := range changedIdx { 133 root, layer, err = recomputeRootFromLayer(int(idx), layer, leaves, hasher) 134 if err != nil { 135 return [32]byte{}, nil, err 136 } 137 } 138 return root, layer, nil 139 } 140 141 // RecomputeFromLayerVariable recomputes specific branches of a variable sized trie depending on the provided changed indexes. 142 func RecomputeFromLayerVariable(changedLeaves [][32]byte, changedIdx []uint64, layer [][]*[32]byte) ([32]byte, [][]*[32]byte, error) { 143 hasher := hashutil.CustomSHA256Hasher() 144 if len(changedIdx) == 0 { 145 return *layer[0][0], layer, nil 146 } 147 root := *layer[len(layer)-1][0] 148 var err error 149 150 for i, idx := range changedIdx { 151 root, layer, err = recomputeRootFromLayerVariable(int(idx), changedLeaves[i], layer, hasher) 152 if err != nil { 153 return [32]byte{}, nil, err 154 } 155 } 156 return root, layer, nil 157 } 158 159 // this method assumes that the provided trie already has all its elements included 160 // in the base depth. 161 func recomputeRootFromLayer(idx int, layers [][]*[32]byte, chunks []*[32]byte, 162 hasher func([]byte) [32]byte) ([32]byte, [][]*[32]byte, error) { 163 root := *chunks[idx] 164 layers[0] = chunks 165 // The merkle tree structure looks as follows: 166 // [[r1, r2, r3, r4], [parent1, parent2], [root]] 167 // Using information about the index which changed, idx, we recompute 168 // only its branch up the tree. 169 currentIndex := idx 170 for i := 0; i < len(layers)-1; i++ { 171 isLeft := currentIndex%2 == 0 172 neighborIdx := currentIndex ^ 1 173 174 neighbor := [32]byte{} 175 if layers[i] != nil && len(layers[i]) != 0 && neighborIdx < len(layers[i]) { 176 neighbor = *layers[i][neighborIdx] 177 } 178 if isLeft { 179 parentHash := hasher(append(root[:], neighbor[:]...)) 180 root = parentHash 181 } else { 182 parentHash := hasher(append(neighbor[:], root[:]...)) 183 root = parentHash 184 } 185 parentIdx := currentIndex / 2 186 // Update the cached layers at the parent index. 187 rootVal := root 188 if len(layers[i+1]) == 0 { 189 layers[i+1] = append(layers[i+1], &rootVal) 190 } else { 191 layers[i+1][parentIdx] = &rootVal 192 } 193 currentIndex = parentIdx 194 } 195 // If there is only a single leaf, we return it (the identity element). 196 if len(layers[0]) == 1 { 197 return *layers[0][0], layers, nil 198 } 199 return root, layers, nil 200 } 201 202 // this method assumes that the base branch does not consist of all leaves of the 203 // trie. Instead missing leaves are assumed to be zerohashes, following the structure 204 // of a sparse merkle trie. 205 func recomputeRootFromLayerVariable(idx int, item [32]byte, layers [][]*[32]byte, 206 hasher func([]byte) [32]byte) ([32]byte, [][]*[32]byte, error) { 207 for idx >= len(layers[0]) { 208 zerohash := trieutil.ZeroHashes[0] 209 layers[0] = append(layers[0], &zerohash) 210 } 211 layers[0][idx] = &item 212 213 currentIndex := idx 214 root := item 215 for i := 0; i < len(layers)-1; i++ { 216 isLeft := currentIndex%2 == 0 217 neighborIdx := currentIndex ^ 1 218 219 neighbor := [32]byte{} 220 if neighborIdx >= len(layers[i]) { 221 neighbor = trieutil.ZeroHashes[i] 222 } else { 223 neighbor = *layers[i][neighborIdx] 224 } 225 if isLeft { 226 parentHash := hasher(append(root[:], neighbor[:]...)) 227 root = parentHash 228 } else { 229 parentHash := hasher(append(neighbor[:], root[:]...)) 230 root = parentHash 231 } 232 parentIdx := currentIndex / 2 233 if len(layers[i+1]) == 0 || parentIdx >= len(layers[i+1]) { 234 newItem := root 235 layers[i+1] = append(layers[i+1], &newItem) 236 } else { 237 newItem := root 238 layers[i+1][parentIdx] = &newItem 239 } 240 currentIndex = parentIdx 241 } 242 return root, layers, nil 243 } 244 245 // AddInMixin describes a method from which a lenth mixin is added to the 246 // provided root. 247 func AddInMixin(root [32]byte, length uint64) ([32]byte, error) { 248 rootBuf := new(bytes.Buffer) 249 if err := binary.Write(rootBuf, binary.LittleEndian, length); err != nil { 250 return [32]byte{}, errors.Wrap(err, "could not marshal eth1data votes length") 251 } 252 // We need to mix in the length of the slice. 253 rootBufRoot := make([]byte, 32) 254 copy(rootBufRoot, rootBuf.Bytes()) 255 return htrutils.MixInLength(root, rootBufRoot), nil 256 } 257 258 // Merkleize 32-byte leaves into a Merkle trie for its adequate depth, returning 259 // the resulting layers of the trie based on the appropriate depth. This function 260 // pads the leaves to a length of 32. 261 func Merkleize(leaves [][]byte) [][][]byte { 262 hashFunc := hashutil.CustomSHA256Hasher() 263 layers := make([][][]byte, htrutils.Depth(uint64(len(leaves)))+1) 264 for len(leaves) != 32 { 265 leaves = append(leaves, make([]byte, 32)) 266 } 267 currentLayer := leaves 268 layers[0] = currentLayer 269 270 // We keep track of the hash layers of a Merkle trie until we reach 271 // the top layer of length 1, which contains the single root element. 272 // [Root] -> Top layer has length 1. 273 // [E] [F] -> This layer has length 2. 274 // [A] [B] [C] [D] -> The bottom layer has length 4 (needs to be a power of two). 275 i := 1 276 for len(currentLayer) > 1 && i < len(layers) { 277 layer := make([][]byte, 0) 278 for i := 0; i < len(currentLayer); i += 2 { 279 hashedChunk := hashFunc(append(currentLayer[i], currentLayer[i+1]...)) 280 layer = append(layer, hashedChunk[:]) 281 } 282 currentLayer = layer 283 layers[i] = currentLayer 284 i++ 285 } 286 return layers 287 } 288 289 // MerkleizeTrieLeaves merkleize the trie leaves. 290 func MerkleizeTrieLeaves(layers [][][32]byte, hashLayer [][32]byte, 291 hasher func([]byte) [32]byte) ([][][32]byte, [][32]byte) { 292 // We keep track of the hash layers of a Merkle trie until we reach 293 // the top layer of length 1, which contains the single root element. 294 // [Root] -> Top layer has length 1. 295 // [E] [F] -> This layer has length 2. 296 // [A] [B] [C] [D] -> The bottom layer has length 4 (needs to be a power of two). 297 i := 1 298 chunkBuffer := bytes.NewBuffer([]byte{}) 299 chunkBuffer.Grow(64) 300 for len(hashLayer) > 1 && i < len(layers) { 301 layer := make([][32]byte, len(hashLayer)/2) 302 for j := 0; j < len(hashLayer); j += 2 { 303 chunkBuffer.Write(hashLayer[j][:]) 304 chunkBuffer.Write(hashLayer[j+1][:]) 305 hashedChunk := hasher(chunkBuffer.Bytes()) 306 layer[j/2] = hashedChunk 307 chunkBuffer.Reset() 308 } 309 hashLayer = layer 310 layers[i] = hashLayer 311 i++ 312 } 313 return layers, hashLayer 314 }