github.com/LampardNguyen234/go-ethereum@v1.10.16-0.20220117140830-b6a3b0260724/trie/stacktrie.go (about) 1 // Copyright 2020 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package trie 18 19 import ( 20 "bufio" 21 "bytes" 22 "encoding/gob" 23 "errors" 24 "fmt" 25 "io" 26 "sync" 27 28 "github.com/LampardNguyen234/go-ethereum/common" 29 "github.com/LampardNguyen234/go-ethereum/ethdb" 30 "github.com/LampardNguyen234/go-ethereum/log" 31 "github.com/LampardNguyen234/go-ethereum/rlp" 32 ) 33 34 var ErrCommitDisabled = errors.New("no database for committing") 35 36 var stPool = sync.Pool{ 37 New: func() interface{} { 38 return NewStackTrie(nil) 39 }, 40 } 41 42 func stackTrieFromPool(db ethdb.KeyValueWriter) *StackTrie { 43 st := stPool.Get().(*StackTrie) 44 st.db = db 45 return st 46 } 47 48 func returnToPool(st *StackTrie) { 49 st.Reset() 50 stPool.Put(st) 51 } 52 53 // StackTrie is a trie implementation that expects keys to be inserted 54 // in order. Once it determines that a subtree will no longer be inserted 55 // into, it will hash it and free up the memory it uses. 56 type StackTrie struct { 57 nodeType uint8 // node type (as in branch, ext, leaf) 58 val []byte // value contained by this node if it's a leaf 59 key []byte // key chunk covered by this (leaf|ext) node 60 children [16]*StackTrie // list of children (for branch and exts) 61 db ethdb.KeyValueWriter // Pointer to the commit db, can be nil 62 } 63 64 // NewStackTrie allocates and initializes an empty trie. 65 func NewStackTrie(db ethdb.KeyValueWriter) *StackTrie { 66 return &StackTrie{ 67 nodeType: emptyNode, 68 db: db, 69 } 70 } 71 72 // NewFromBinary initialises a serialized stacktrie with the given db. 73 func NewFromBinary(data []byte, db ethdb.KeyValueWriter) (*StackTrie, error) { 74 var st StackTrie 75 if err := st.UnmarshalBinary(data); err != nil { 76 return nil, err 77 } 78 // If a database is used, we need to recursively add it to every child 79 if db != nil { 80 st.setDb(db) 81 } 82 return &st, nil 83 } 84 85 // MarshalBinary implements encoding.BinaryMarshaler 86 func (st *StackTrie) MarshalBinary() (data []byte, err error) { 87 var ( 88 b bytes.Buffer 89 w = bufio.NewWriter(&b) 90 ) 91 if err := gob.NewEncoder(w).Encode(struct { 92 Nodetype uint8 93 Val []byte 94 Key []byte 95 }{ 96 st.nodeType, 97 st.val, 98 st.key, 99 }); err != nil { 100 return nil, err 101 } 102 for _, child := range st.children { 103 if child == nil { 104 w.WriteByte(0) 105 continue 106 } 107 w.WriteByte(1) 108 if childData, err := child.MarshalBinary(); err != nil { 109 return nil, err 110 } else { 111 w.Write(childData) 112 } 113 } 114 w.Flush() 115 return b.Bytes(), nil 116 } 117 118 // UnmarshalBinary implements encoding.BinaryUnmarshaler 119 func (st *StackTrie) UnmarshalBinary(data []byte) error { 120 r := bytes.NewReader(data) 121 return st.unmarshalBinary(r) 122 } 123 124 func (st *StackTrie) unmarshalBinary(r io.Reader) error { 125 var dec struct { 126 Nodetype uint8 127 Val []byte 128 Key []byte 129 } 130 gob.NewDecoder(r).Decode(&dec) 131 st.nodeType = dec.Nodetype 132 st.val = dec.Val 133 st.key = dec.Key 134 135 var hasChild = make([]byte, 1) 136 for i := range st.children { 137 if _, err := r.Read(hasChild); err != nil { 138 return err 139 } else if hasChild[0] == 0 { 140 continue 141 } 142 var child StackTrie 143 child.unmarshalBinary(r) 144 st.children[i] = &child 145 } 146 return nil 147 } 148 149 func (st *StackTrie) setDb(db ethdb.KeyValueWriter) { 150 st.db = db 151 for _, child := range st.children { 152 if child != nil { 153 child.setDb(db) 154 } 155 } 156 } 157 158 func newLeaf(key, val []byte, db ethdb.KeyValueWriter) *StackTrie { 159 st := stackTrieFromPool(db) 160 st.nodeType = leafNode 161 st.key = append(st.key, key...) 162 st.val = val 163 return st 164 } 165 166 func newExt(key []byte, child *StackTrie, db ethdb.KeyValueWriter) *StackTrie { 167 st := stackTrieFromPool(db) 168 st.nodeType = extNode 169 st.key = append(st.key, key...) 170 st.children[0] = child 171 return st 172 } 173 174 // List all values that StackTrie#nodeType can hold 175 const ( 176 emptyNode = iota 177 branchNode 178 extNode 179 leafNode 180 hashedNode 181 ) 182 183 // TryUpdate inserts a (key, value) pair into the stack trie 184 func (st *StackTrie) TryUpdate(key, value []byte) error { 185 k := keybytesToHex(key) 186 if len(value) == 0 { 187 panic("deletion not supported") 188 } 189 st.insert(k[:len(k)-1], value) 190 return nil 191 } 192 193 func (st *StackTrie) Update(key, value []byte) { 194 if err := st.TryUpdate(key, value); err != nil { 195 log.Error(fmt.Sprintf("Unhandled trie error: %v", err)) 196 } 197 } 198 199 func (st *StackTrie) Reset() { 200 st.db = nil 201 st.key = st.key[:0] 202 st.val = nil 203 for i := range st.children { 204 st.children[i] = nil 205 } 206 st.nodeType = emptyNode 207 } 208 209 // Helper function that, given a full key, determines the index 210 // at which the chunk pointed by st.keyOffset is different from 211 // the same chunk in the full key. 212 func (st *StackTrie) getDiffIndex(key []byte) int { 213 for idx, nibble := range st.key { 214 if nibble != key[idx] { 215 return idx 216 } 217 } 218 return len(st.key) 219 } 220 221 // Helper function to that inserts a (key, value) pair into 222 // the trie. 223 func (st *StackTrie) insert(key, value []byte) { 224 switch st.nodeType { 225 case branchNode: /* Branch */ 226 idx := int(key[0]) 227 // Unresolve elder siblings 228 for i := idx - 1; i >= 0; i-- { 229 if st.children[i] != nil { 230 if st.children[i].nodeType != hashedNode { 231 st.children[i].hash() 232 } 233 break 234 } 235 } 236 // Add new child 237 if st.children[idx] == nil { 238 st.children[idx] = newLeaf(key[1:], value, st.db) 239 } else { 240 st.children[idx].insert(key[1:], value) 241 } 242 case extNode: /* Ext */ 243 // Compare both key chunks and see where they differ 244 diffidx := st.getDiffIndex(key) 245 246 // Check if chunks are identical. If so, recurse into 247 // the child node. Otherwise, the key has to be split 248 // into 1) an optional common prefix, 2) the fullnode 249 // representing the two differing path, and 3) a leaf 250 // for each of the differentiated subtrees. 251 if diffidx == len(st.key) { 252 // Ext key and key segment are identical, recurse into 253 // the child node. 254 st.children[0].insert(key[diffidx:], value) 255 return 256 } 257 // Save the original part. Depending if the break is 258 // at the extension's last byte or not, create an 259 // intermediate extension or use the extension's child 260 // node directly. 261 var n *StackTrie 262 if diffidx < len(st.key)-1 { 263 n = newExt(st.key[diffidx+1:], st.children[0], st.db) 264 } else { 265 // Break on the last byte, no need to insert 266 // an extension node: reuse the current node 267 n = st.children[0] 268 } 269 // Convert to hash 270 n.hash() 271 var p *StackTrie 272 if diffidx == 0 { 273 // the break is on the first byte, so 274 // the current node is converted into 275 // a branch node. 276 st.children[0] = nil 277 p = st 278 st.nodeType = branchNode 279 } else { 280 // the common prefix is at least one byte 281 // long, insert a new intermediate branch 282 // node. 283 st.children[0] = stackTrieFromPool(st.db) 284 st.children[0].nodeType = branchNode 285 p = st.children[0] 286 } 287 // Create a leaf for the inserted part 288 o := newLeaf(key[diffidx+1:], value, st.db) 289 290 // Insert both child leaves where they belong: 291 origIdx := st.key[diffidx] 292 newIdx := key[diffidx] 293 p.children[origIdx] = n 294 p.children[newIdx] = o 295 st.key = st.key[:diffidx] 296 297 case leafNode: /* Leaf */ 298 // Compare both key chunks and see where they differ 299 diffidx := st.getDiffIndex(key) 300 301 // Overwriting a key isn't supported, which means that 302 // the current leaf is expected to be split into 1) an 303 // optional extension for the common prefix of these 2 304 // keys, 2) a fullnode selecting the path on which the 305 // keys differ, and 3) one leaf for the differentiated 306 // component of each key. 307 if diffidx >= len(st.key) { 308 panic("Trying to insert into existing key") 309 } 310 311 // Check if the split occurs at the first nibble of the 312 // chunk. In that case, no prefix extnode is necessary. 313 // Otherwise, create that 314 var p *StackTrie 315 if diffidx == 0 { 316 // Convert current leaf into a branch 317 st.nodeType = branchNode 318 p = st 319 st.children[0] = nil 320 } else { 321 // Convert current node into an ext, 322 // and insert a child branch node. 323 st.nodeType = extNode 324 st.children[0] = NewStackTrie(st.db) 325 st.children[0].nodeType = branchNode 326 p = st.children[0] 327 } 328 329 // Create the two child leaves: the one containing the 330 // original value and the one containing the new value 331 // The child leave will be hashed directly in order to 332 // free up some memory. 333 origIdx := st.key[diffidx] 334 p.children[origIdx] = newLeaf(st.key[diffidx+1:], st.val, st.db) 335 p.children[origIdx].hash() 336 337 newIdx := key[diffidx] 338 p.children[newIdx] = newLeaf(key[diffidx+1:], value, st.db) 339 340 // Finally, cut off the key part that has been passed 341 // over to the children. 342 st.key = st.key[:diffidx] 343 st.val = nil 344 case emptyNode: /* Empty */ 345 st.nodeType = leafNode 346 st.key = key 347 st.val = value 348 case hashedNode: 349 panic("trying to insert into hash") 350 default: 351 panic("invalid type") 352 } 353 } 354 355 // hash() hashes the node 'st' and converts it into 'hashedNode', if possible. 356 // Possible outcomes: 357 // 1. The rlp-encoded value was >= 32 bytes: 358 // - Then the 32-byte `hash` will be accessible in `st.val`. 359 // - And the 'st.type' will be 'hashedNode' 360 // 2. The rlp-encoded value was < 32 bytes 361 // - Then the <32 byte rlp-encoded value will be accessible in 'st.val'. 362 // - And the 'st.type' will be 'hashedNode' AGAIN 363 // 364 // This method will also: 365 // set 'st.type' to hashedNode 366 // clear 'st.key' 367 func (st *StackTrie) hash() { 368 /* Shortcut if node is already hashed */ 369 if st.nodeType == hashedNode { 370 return 371 } 372 // The 'hasher' is taken from a pool, but we don't actually 373 // claim an instance until all children are done with their hashing, 374 // and we actually need one 375 var h *hasher 376 377 switch st.nodeType { 378 case branchNode: 379 var nodes [17]node 380 for i, child := range st.children { 381 if child == nil { 382 nodes[i] = nilValueNode 383 continue 384 } 385 child.hash() 386 if len(child.val) < 32 { 387 nodes[i] = rawNode(child.val) 388 } else { 389 nodes[i] = hashNode(child.val) 390 } 391 st.children[i] = nil // Reclaim mem from subtree 392 returnToPool(child) 393 } 394 nodes[16] = nilValueNode 395 h = newHasher(false) 396 defer returnHasherToPool(h) 397 h.tmp.Reset() 398 if err := rlp.Encode(&h.tmp, nodes); err != nil { 399 panic(err) 400 } 401 case extNode: 402 st.children[0].hash() 403 h = newHasher(false) 404 defer returnHasherToPool(h) 405 h.tmp.Reset() 406 var valuenode node 407 if len(st.children[0].val) < 32 { 408 valuenode = rawNode(st.children[0].val) 409 } else { 410 valuenode = hashNode(st.children[0].val) 411 } 412 n := struct { 413 Key []byte 414 Val node 415 }{ 416 Key: hexToCompact(st.key), 417 Val: valuenode, 418 } 419 if err := rlp.Encode(&h.tmp, n); err != nil { 420 panic(err) 421 } 422 returnToPool(st.children[0]) 423 st.children[0] = nil // Reclaim mem from subtree 424 case leafNode: 425 h = newHasher(false) 426 defer returnHasherToPool(h) 427 h.tmp.Reset() 428 st.key = append(st.key, byte(16)) 429 sz := hexToCompactInPlace(st.key) 430 n := [][]byte{st.key[:sz], st.val} 431 if err := rlp.Encode(&h.tmp, n); err != nil { 432 panic(err) 433 } 434 case emptyNode: 435 st.val = emptyRoot.Bytes() 436 st.key = st.key[:0] 437 st.nodeType = hashedNode 438 return 439 default: 440 panic("Invalid node type") 441 } 442 st.key = st.key[:0] 443 st.nodeType = hashedNode 444 if len(h.tmp) < 32 { 445 st.val = common.CopyBytes(h.tmp) 446 return 447 } 448 // Write the hash to the 'val'. We allocate a new val here to not mutate 449 // input values 450 st.val = make([]byte, 32) 451 h.sha.Reset() 452 h.sha.Write(h.tmp) 453 h.sha.Read(st.val) 454 if st.db != nil { 455 // TODO! Is it safe to Put the slice here? 456 // Do all db implementations copy the value provided? 457 st.db.Put(st.val, h.tmp) 458 } 459 } 460 461 // Hash returns the hash of the current node 462 func (st *StackTrie) Hash() (h common.Hash) { 463 st.hash() 464 if len(st.val) != 32 { 465 // If the node's RLP isn't 32 bytes long, the node will not 466 // be hashed, and instead contain the rlp-encoding of the 467 // node. For the top level node, we need to force the hashing. 468 ret := make([]byte, 32) 469 h := newHasher(false) 470 defer returnHasherToPool(h) 471 h.sha.Reset() 472 h.sha.Write(st.val) 473 h.sha.Read(ret) 474 return common.BytesToHash(ret) 475 } 476 return common.BytesToHash(st.val) 477 } 478 479 // Commit will firstly hash the entrie trie if it's still not hashed 480 // and then commit all nodes to the associated database. Actually most 481 // of the trie nodes MAY have been committed already. The main purpose 482 // here is to commit the root node. 483 // 484 // The associated database is expected, otherwise the whole commit 485 // functionality should be disabled. 486 func (st *StackTrie) Commit() (common.Hash, error) { 487 if st.db == nil { 488 return common.Hash{}, ErrCommitDisabled 489 } 490 st.hash() 491 if len(st.val) != 32 { 492 // If the node's RLP isn't 32 bytes long, the node will not 493 // be hashed (and committed), and instead contain the rlp-encoding of the 494 // node. For the top level node, we need to force the hashing+commit. 495 ret := make([]byte, 32) 496 h := newHasher(false) 497 defer returnHasherToPool(h) 498 h.sha.Reset() 499 h.sha.Write(st.val) 500 h.sha.Read(ret) 501 st.db.Put(ret, st.val) 502 return common.BytesToHash(ret), nil 503 } 504 return common.BytesToHash(st.val), nil 505 }