github.com/klaytn/klaytn@v1.12.1/storage/statedb/iterator.go (about) 1 // Modifications Copyright 2018 The klaytn Authors 2 // Copyright 2015 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 // 18 // This file is derived from trie/iterator.go (2018/06/04). 19 // Modified and improved for the klaytn development. 20 21 package statedb 22 23 import ( 24 "bytes" 25 "container/heap" 26 "errors" 27 28 "github.com/klaytn/klaytn/storage/database" 29 30 "github.com/klaytn/klaytn/common" 31 "github.com/klaytn/klaytn/rlp" 32 ) 33 34 // Iterator is a key-value trie iterator that traverses a Trie. 35 type Iterator struct { 36 nodeIt NodeIterator 37 38 Key []byte // Current data key on which the iterator is positioned on 39 Value []byte // Current data value on which the iterator is positioned on 40 Err error 41 } 42 43 // NewIterator creates a new key-value iterator from a node iterator 44 func NewIterator(it NodeIterator) *Iterator { 45 return &Iterator{ 46 nodeIt: it, 47 } 48 } 49 50 // Next moves the iterator forward one key-value entry. 51 func (it *Iterator) Next() bool { 52 for it.nodeIt.Next(true) { 53 if it.nodeIt.Leaf() { 54 it.Key = it.nodeIt.LeafKey() 55 it.Value = it.nodeIt.LeafBlob() 56 return true 57 } 58 } 59 it.Key = nil 60 it.Value = nil 61 it.Err = it.nodeIt.Error() 62 return false 63 } 64 65 // NodeIterator is an iterator to traverse the trie pre-order. 66 type NodeIterator interface { 67 // Next moves the iterator to the next node. If the parameter is false, any child 68 // nodes will be skipped. 69 Next(bool) bool 70 // Error returns the error status of the iterator. 71 Error() error 72 73 // Hash returns the hash of the current node. 74 Hash() common.Hash 75 // Parent returns the hash of the parent of the current node. The hash may be the one 76 // grandparent if the immediate parent is an internal node with no hash. 77 Parent() common.Hash 78 // Path returns the hex-encoded path to the current node. 79 // Callers must not retain references to the return value after calling Next. 80 // For leaf nodes, the last element of the path is the 'terminator symbol' 0x10. 81 Path() []byte 82 83 // Leaf returns true iff the current node is a leaf node. 84 // LeafBlob, LeafKey return the contents and key of the leaf node. These 85 // method panic if the iterator is not positioned at a leaf. 86 // Callers must not retain references to their return value after calling Next 87 Leaf() bool 88 89 // LeafKey returns the key of the leaf. The method panics if the iterator is not 90 // positioned at a leaf. Callers must not retain references to the value after 91 // calling Next. 92 LeafKey() []byte 93 94 // LeafBlob returns the content of the leaf. The method panics if the iterator 95 // is not positioned at a leaf. Callers must not retain references to the value 96 // after calling Next. 97 LeafBlob() []byte 98 99 // LeafProof returns the Merkle proof of the leaf. The method panics if the 100 // iterator is not positioned at a leaf. Callers must not retain references 101 // to the value after calling Next. 102 LeafProof() [][]byte 103 104 // AddResolver sets an intermediate database to use for looking up trie nodes 105 // before reaching into the real persistent layer. 106 // 107 // This is not required for normal operation, rather is an optimization for 108 // cases where trie nodes can be recovered from some external mechanism without 109 // reading from disk. In those cases, this resolver allows short circuiting 110 // accesses and returning them from memory. 111 // 112 // Before adding a similar mechanism to any other place in Geth, consider 113 // making trie.Database an interface and wrapping at that level. It's a huge 114 // refactor, but it could be worth it if another occurrence arises. 115 AddResolver(database.DBManager) 116 } 117 118 // nodeIteratorState represents the iteration state at one particular node of the 119 // trie, which can be resumed at a later invocation. 120 type nodeIteratorState struct { 121 hash common.Hash // Hash of the node being iterated (nil if not standalone) 122 node node // Trie node being iterated 123 parent common.Hash // Hash of the first full ancestor node (nil if current is the root) 124 index int // Child to be processed next 125 pathlen int // Length of the path to this node 126 } 127 128 type nodeIterator struct { 129 trie *Trie // Trie being iterated 130 stack []*nodeIteratorState // Hierarchy of trie nodes persisting the iteration state 131 path []byte // Path to the current node 132 err error // Failure set in case of an internal error in the iterator 133 134 resolver database.DBManager // Optional intermediate resolver above the disk layer 135 } 136 137 // iteratorEnd is stored in nodeIterator.err when iteration is done. 138 var iteratorEnd = errors.New("end of iteration") 139 140 // seekError is stored in nodeIterator.err if the initial seek has failed. 141 type seekError struct { 142 key []byte 143 err error 144 } 145 146 func (e seekError) Error() string { 147 return "seek error: " + e.err.Error() 148 } 149 150 func newNodeIterator(trie *Trie, start []byte) NodeIterator { 151 if trie.Hash() == emptyState { 152 return new(nodeIterator) 153 } 154 it := &nodeIterator{trie: trie} 155 it.err = it.seek(start) 156 return it 157 } 158 159 func (it *nodeIterator) Hash() common.Hash { 160 if len(it.stack) == 0 { 161 return common.Hash{} 162 } 163 return it.stack[len(it.stack)-1].hash 164 } 165 166 func (it *nodeIterator) Parent() common.Hash { 167 if len(it.stack) == 0 { 168 return common.Hash{} 169 } 170 return it.stack[len(it.stack)-1].parent 171 } 172 173 func (it *nodeIterator) Leaf() bool { 174 return hasTerm(it.path) 175 } 176 177 func (it *nodeIterator) LeafBlob() []byte { 178 if len(it.stack) > 0 { 179 if node, ok := it.stack[len(it.stack)-1].node.(valueNode); ok { 180 return []byte(node) 181 } 182 } 183 panic("not at leaf") 184 } 185 186 func (it *nodeIterator) LeafKey() []byte { 187 if len(it.stack) > 0 { 188 if _, ok := it.stack[len(it.stack)-1].node.(valueNode); ok { 189 return hexToKeybytes(it.path) 190 } 191 } 192 panic("not at leaf") 193 } 194 195 func (it *nodeIterator) LeafProof() [][]byte { 196 if len(it.stack) > 0 { 197 if _, ok := it.stack[len(it.stack)-1].node.(valueNode); ok { 198 hasher := newHasher(nil) 199 defer returnHasherToPool(hasher) 200 201 proofs := make([][]byte, 0, len(it.stack)) 202 203 for i, item := range it.stack[:len(it.stack)-1] { 204 // Gather nodes that end up as hash nodes (or the root) 205 node, _ := hasher.hashChildren(item.node, nil, false) 206 hashed, _ := hasher.store(node, nil, false, false) 207 if _, ok := hashed.(hashNode); ok || i == 0 { 208 enc, _ := rlp.EncodeToBytes(node) 209 proofs = append(proofs, enc) 210 } 211 } 212 return proofs 213 } 214 } 215 panic("not at leaf") 216 } 217 218 func (it *nodeIterator) AddResolver(resolver database.DBManager) { 219 it.resolver = resolver 220 } 221 222 func (it *nodeIterator) Path() []byte { 223 return it.path 224 } 225 226 func (it *nodeIterator) Error() error { 227 if it.err == iteratorEnd { 228 return nil 229 } 230 if seek, ok := it.err.(seekError); ok { 231 return seek.err 232 } 233 return it.err 234 } 235 236 // Next moves the iterator to the next node, returning whether there are any 237 // further nodes. In case of an internal error this method returns false and 238 // sets the Error field to the encountered failure. If `descend` is false, 239 // skips iterating over any subnodes of the current node. 240 func (it *nodeIterator) Next(descend bool) bool { 241 if it.err == iteratorEnd { 242 return false 243 } 244 if seek, ok := it.err.(seekError); ok { 245 if it.err = it.seek(seek.key); it.err != nil { 246 return false 247 } 248 } 249 // Otherwise step forward with the iterator and report any errors. 250 state, parentIndex, path, err := it.peek(descend) 251 it.err = err 252 if it.err != nil { 253 return false 254 } 255 it.push(state, parentIndex, path) 256 return true 257 } 258 259 func (it *nodeIterator) seek(prefix []byte) error { 260 // The path we're looking for is the hex encoded key without terminator. 261 key := keybytesToHex(prefix) 262 key = key[:len(key)-1] 263 // Move forward until we're just before the closest match to key. 264 for { 265 state, parentIndex, path, err := it.peek(bytes.HasPrefix(key, it.path)) 266 if err == iteratorEnd { 267 return iteratorEnd 268 } else if err != nil { 269 return seekError{prefix, err} 270 } else if bytes.Compare(path, key) >= 0 { 271 return nil 272 } 273 it.push(state, parentIndex, path) 274 } 275 } 276 277 // peek creates the next state of the iterator. 278 func (it *nodeIterator) peek(descend bool) (*nodeIteratorState, *int, []byte, error) { 279 if len(it.stack) == 0 { 280 // Initialize the iterator if we've just started. 281 root := it.trie.Hash() 282 state := &nodeIteratorState{node: it.trie.root, index: -1} 283 if root != emptyRoot { 284 state.hash = root 285 } 286 err := state.resolve(it, nil) 287 return state, nil, nil, err 288 } 289 if !descend { 290 // If we're skipping children, pop the current node first 291 it.pop() 292 } 293 294 // Continue iteration to the next child 295 for len(it.stack) > 0 { 296 parent := it.stack[len(it.stack)-1] 297 ancestor := parent.hash 298 if (ancestor == common.Hash{}) { 299 ancestor = parent.parent 300 } 301 state, path, ok := it.nextChild(parent, ancestor) 302 if ok { 303 if err := state.resolve(it, path); err != nil { 304 return parent, &parent.index, path, err 305 } 306 return state, &parent.index, path, nil 307 } 308 // No more child nodes, move back up. 309 it.pop() 310 } 311 return nil, nil, nil, iteratorEnd 312 } 313 314 func (it *nodeIterator) resolveHash(hash hashNode, path []byte) (node, error) { 315 if it.resolver != nil { 316 hash := common.BytesToExtHash(hash) 317 enc, _ := it.resolver.ReadTrieNode(hash) 318 if enc != nil { 319 if resolved, err := decodeNode(hash[:], enc); err == nil { 320 return resolved, nil 321 } 322 } 323 } 324 return it.trie.resolveHash(hash, path) 325 } 326 327 func (st *nodeIteratorState) resolve(it *nodeIterator, path []byte) error { 328 if hash, ok := st.node.(hashNode); ok { 329 resolved, err := it.resolveHash(hash, path) 330 if err != nil { 331 return err 332 } 333 st.node = resolved 334 st.hash = common.BytesToExtHash(hash).Unextend() 335 } 336 return nil 337 } 338 339 func (it *nodeIterator) nextChild(parent *nodeIteratorState, ancestor common.Hash) (*nodeIteratorState, []byte, bool) { 340 switch node := parent.node.(type) { 341 case *fullNode: 342 // Full node, move to the first non-nil child. 343 for i := parent.index + 1; i < len(node.Children); i++ { 344 child := node.Children[i] 345 if child != nil { 346 hash, _ := child.cache() 347 state := &nodeIteratorState{ 348 hash: common.BytesToExtHash(hash).Unextend(), 349 node: child, 350 parent: ancestor, 351 index: -1, 352 pathlen: len(it.path), 353 } 354 path := append(it.path, byte(i)) 355 parent.index = i - 1 356 return state, path, true 357 } 358 } 359 case *shortNode: 360 // Short node, return the pointer singleton child 361 if parent.index < 0 { 362 hash, _ := node.Val.cache() 363 state := &nodeIteratorState{ 364 hash: common.BytesToExtHash(hash).Unextend(), 365 node: node.Val, 366 parent: ancestor, 367 index: -1, 368 pathlen: len(it.path), 369 } 370 path := append(it.path, node.Key...) 371 return state, path, true 372 } 373 } 374 return parent, it.path, false 375 } 376 377 func (it *nodeIterator) push(state *nodeIteratorState, parentIndex *int, path []byte) { 378 it.path = path 379 it.stack = append(it.stack, state) 380 if parentIndex != nil { 381 *parentIndex++ 382 } 383 } 384 385 func (it *nodeIterator) pop() { 386 parent := it.stack[len(it.stack)-1] 387 it.path = it.path[:parent.pathlen] 388 it.stack = it.stack[:len(it.stack)-1] 389 } 390 391 func compareNodes(a, b NodeIterator) int { 392 if cmp := bytes.Compare(a.Path(), b.Path()); cmp != 0 { 393 return cmp 394 } 395 if a.Leaf() && !b.Leaf() { 396 return -1 397 } else if b.Leaf() && !a.Leaf() { 398 return 1 399 } 400 if cmp := bytes.Compare(a.Hash().Bytes(), b.Hash().Bytes()); cmp != 0 { 401 return cmp 402 } 403 if a.Leaf() && b.Leaf() { 404 return bytes.Compare(a.LeafBlob(), b.LeafBlob()) 405 } 406 return 0 407 } 408 409 type differenceIterator struct { 410 a, b NodeIterator // Nodes returned are those in b - a. 411 eof bool // Indicates a has run out of elements 412 count int // Number of nodes scanned on either trie 413 } 414 415 // NewDifferenceIterator constructs a NodeIterator that iterates over elements in b that 416 // are not in a. Returns the iterator, and a pointer to an integer recording the number 417 // of nodes seen. 418 func NewDifferenceIterator(a, b NodeIterator) (NodeIterator, *int) { 419 a.Next(true) 420 it := &differenceIterator{ 421 a: a, 422 b: b, 423 } 424 return it, &it.count 425 } 426 427 func (it *differenceIterator) Hash() common.Hash { 428 return it.b.Hash() 429 } 430 431 func (it *differenceIterator) Parent() common.Hash { 432 return it.b.Parent() 433 } 434 435 func (it *differenceIterator) Leaf() bool { 436 return it.b.Leaf() 437 } 438 439 func (it *differenceIterator) LeafBlob() []byte { 440 return it.b.LeafBlob() 441 } 442 443 func (it *differenceIterator) LeafKey() []byte { 444 return it.b.LeafKey() 445 } 446 447 func (it *differenceIterator) LeafProof() [][]byte { 448 return it.b.LeafProof() 449 } 450 451 func (it *differenceIterator) AddResolver(database.DBManager) { 452 panic("implement me") 453 } 454 455 func (it *differenceIterator) Path() []byte { 456 return it.b.Path() 457 } 458 459 func (it *differenceIterator) Next(bool) bool { 460 // Invariants: 461 // - We always advance at least one element in b. 462 // - At the start of this function, a's path is lexically greater than b's. 463 if !it.b.Next(true) { 464 return false 465 } 466 it.count++ 467 468 if it.eof { 469 // a has reached eof, so we just return all elements from b 470 return true 471 } 472 473 for { 474 switch compareNodes(it.a, it.b) { 475 case -1: 476 // b jumped past a; advance a 477 if !it.a.Next(true) { 478 it.eof = true 479 return true 480 } 481 it.count++ 482 case 1: 483 // b is before a 484 return true 485 case 0: 486 // a and b are identical; skip this whole subtree if the nodes have hashes 487 hasHash := it.a.Hash() == common.Hash{} 488 if !it.b.Next(hasHash) { 489 return false 490 } 491 it.count++ 492 if !it.a.Next(hasHash) { 493 it.eof = true 494 return true 495 } 496 it.count++ 497 } 498 } 499 } 500 501 func (it *differenceIterator) Error() error { 502 if err := it.a.Error(); err != nil { 503 return err 504 } 505 return it.b.Error() 506 } 507 508 type nodeIteratorHeap []NodeIterator 509 510 func (h nodeIteratorHeap) Len() int { return len(h) } 511 func (h nodeIteratorHeap) Less(i, j int) bool { return compareNodes(h[i], h[j]) < 0 } 512 func (h nodeIteratorHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } 513 func (h *nodeIteratorHeap) Push(x interface{}) { *h = append(*h, x.(NodeIterator)) } 514 func (h *nodeIteratorHeap) Pop() interface{} { 515 n := len(*h) 516 x := (*h)[n-1] 517 *h = (*h)[0 : n-1] 518 return x 519 } 520 521 type unionIterator struct { 522 items *nodeIteratorHeap // Nodes returned are the union of the ones in these iterators 523 count int // Number of nodes scanned across all tries 524 } 525 526 // NewUnionIterator constructs a NodeIterator that iterates over elements in the union 527 // of the provided NodeIterators. Returns the iterator, and a pointer to an integer 528 // recording the number of nodes visited. 529 func NewUnionIterator(iters []NodeIterator) (NodeIterator, *int) { 530 h := make(nodeIteratorHeap, len(iters)) 531 copy(h, iters) 532 heap.Init(&h) 533 534 ui := &unionIterator{items: &h} 535 return ui, &ui.count 536 } 537 538 func (it *unionIterator) Hash() common.Hash { 539 return (*it.items)[0].Hash() 540 } 541 542 func (it *unionIterator) Parent() common.Hash { 543 return (*it.items)[0].Parent() 544 } 545 546 func (it *unionIterator) Leaf() bool { 547 return (*it.items)[0].Leaf() 548 } 549 550 func (it *unionIterator) LeafBlob() []byte { 551 return (*it.items)[0].LeafBlob() 552 } 553 554 func (it *unionIterator) LeafProof() [][]byte { 555 return (*it.items)[0].LeafProof() 556 } 557 558 func (it *unionIterator) AddResolver(database.DBManager) { 559 panic("implement me") 560 } 561 562 func (it *unionIterator) LeafKey() []byte { 563 return (*it.items)[0].LeafKey() 564 } 565 566 func (it *unionIterator) Path() []byte { 567 return (*it.items)[0].Path() 568 } 569 570 // Next returns the next node in the union of tries being iterated over. 571 // 572 // It does this by maintaining a heap of iterators, sorted by the iteration 573 // order of their next elements, with one entry for each source trie. Each 574 // time Next() is called, it takes the least element from the heap to return, 575 // advancing any other iterators that also point to that same element. These 576 // iterators are called with descend=false, since we know that any nodes under 577 // these nodes will also be duplicates, found in the currently selected iterator. 578 // Whenever an iterator is advanced, it is pushed back into the heap if it still 579 // has elements remaining. 580 // 581 // In the case that descend=false - eg, we're asked to ignore all subnodes of the 582 // current node - we also advance any iterators in the heap that have the current 583 // path as a prefix. 584 func (it *unionIterator) Next(descend bool) bool { 585 if len(*it.items) == 0 { 586 return false 587 } 588 589 // Get the next key from the union 590 least := heap.Pop(it.items).(NodeIterator) 591 592 // Skip over other nodes as long as they're identical, or, if we're not descending, as 593 // long as they have the same prefix as the current node. 594 for len(*it.items) > 0 && ((!descend && bytes.HasPrefix((*it.items)[0].Path(), least.Path())) || compareNodes(least, (*it.items)[0]) == 0) { 595 skipped := heap.Pop(it.items).(NodeIterator) 596 // Skip the whole subtree if the nodes have hashes; otherwise just skip this node 597 if skipped.Next(skipped.Hash() == common.Hash{}) { 598 it.count += 1 599 // If there are more elements, push the iterator back on the heap 600 heap.Push(it.items, skipped) 601 } 602 } 603 604 if least.Next(descend) { 605 it.count++ 606 heap.Push(it.items, least) 607 } 608 609 return len(*it.items) > 0 610 } 611 612 func (it *unionIterator) Error() error { 613 for i := 0; i < len(*it.items); i++ { 614 if err := (*it.items)[i].Error(); err != nil { 615 return err 616 } 617 } 618 return nil 619 }