github.com/ethereum/go-ethereum@v1.16.1/trie/iterator.go (about) 1 // Copyright 2014 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 "bytes" 21 "container/heap" 22 "errors" 23 24 "github.com/ethereum/go-ethereum/common" 25 "github.com/ethereum/go-ethereum/core/types" 26 ) 27 28 // NodeResolver is used for looking up trie nodes before reaching into the real 29 // persistent layer. This is not mandatory, rather is an optimization for cases 30 // where trie nodes can be recovered from some external mechanism without reading 31 // from disk. In those cases, this resolver allows short circuiting accesses and 32 // returning them from memory. 33 type NodeResolver func(owner common.Hash, path []byte, hash common.Hash) []byte 34 35 // Iterator is a key-value trie iterator that traverses a Trie. 36 type Iterator struct { 37 nodeIt NodeIterator 38 39 Key []byte // Current data key on which the iterator is positioned on 40 Value []byte // Current data value on which the iterator is positioned on 41 Err error 42 } 43 44 // NewIterator creates a new key-value iterator from a node iterator. 45 // Note that the value returned by the iterator is raw. If the content is encoded 46 // (e.g. storage value is RLP-encoded), it's caller's duty to decode it. 47 func NewIterator(it NodeIterator) *Iterator { 48 return &Iterator{ 49 nodeIt: it, 50 } 51 } 52 53 // Next moves the iterator forward one key-value entry. 54 func (it *Iterator) Next() bool { 55 for it.nodeIt.Next(true) { 56 if it.nodeIt.Leaf() { 57 it.Key = it.nodeIt.LeafKey() 58 it.Value = it.nodeIt.LeafBlob() 59 return true 60 } 61 } 62 it.Key = nil 63 it.Value = nil 64 it.Err = it.nodeIt.Error() 65 return false 66 } 67 68 // Prove generates the Merkle proof for the leaf node the iterator is currently 69 // positioned on. 70 func (it *Iterator) Prove() [][]byte { 71 return it.nodeIt.LeafProof() 72 } 73 74 // NodeIterator is an iterator to traverse the trie pre-order. 75 type NodeIterator interface { 76 // Next moves the iterator to the next node. If the parameter is false, any child 77 // nodes will be skipped. 78 Next(bool) bool 79 80 // Error returns the error status of the iterator. 81 Error() error 82 83 // Hash returns the hash of the current node. 84 Hash() common.Hash 85 86 // Parent returns the hash of the parent of the current node. The hash may be the one 87 // grandparent if the immediate parent is an internal node with no hash. 88 Parent() common.Hash 89 90 // Path returns the hex-encoded path to the current node. 91 // Callers must not retain references to the return value after calling Next. 92 // For leaf nodes, the last element of the path is the 'terminator symbol' 0x10. 93 Path() []byte 94 95 // NodeBlob returns the rlp-encoded value of the current iterated node. 96 // If the node is an embedded node in its parent, nil is returned then. 97 NodeBlob() []byte 98 99 // Leaf returns true iff the current node is a leaf node. 100 Leaf() bool 101 102 // LeafKey returns the key of the leaf. The method panics if the iterator is not 103 // positioned at a leaf. Callers must not retain references to the value after 104 // calling Next. 105 LeafKey() []byte 106 107 // LeafBlob returns the content of the leaf. The method panics if the iterator 108 // is not positioned at a leaf. Callers must not retain references to the value 109 // after calling Next. 110 LeafBlob() []byte 111 112 // LeafProof returns the Merkle proof of the leaf. The method panics if the 113 // iterator is not positioned at a leaf. Callers must not retain references 114 // to the value after calling Next. 115 LeafProof() [][]byte 116 117 // AddResolver sets a node resolver to use for looking up trie nodes before 118 // reaching into the real persistent layer. 119 // 120 // This is not required for normal operation, rather is an optimization for 121 // cases where trie nodes can be recovered from some external mechanism without 122 // reading from disk. In those cases, this resolver allows short circuiting 123 // accesses and returning them from memory. 124 // 125 // Before adding a similar mechanism to any other place in Geth, consider 126 // making trie.Database an interface and wrapping at that level. It's a huge 127 // refactor, but it could be worth it if another occurrence arises. 128 AddResolver(NodeResolver) 129 } 130 131 // nodeIteratorState represents the iteration state at one particular node of the 132 // trie, which can be resumed at a later invocation. 133 type nodeIteratorState struct { 134 hash common.Hash // Hash of the node being iterated (nil if not standalone) 135 node node // Trie node being iterated 136 parent common.Hash // Hash of the first full ancestor node (nil if current is the root) 137 index int // Child to be processed next 138 pathlen int // Length of the path to the parent node 139 } 140 141 type nodeIterator struct { 142 trie *Trie // Trie being iterated 143 stack []*nodeIteratorState // Hierarchy of trie nodes persisting the iteration state 144 path []byte // Path to the current node 145 err error // Failure set in case of an internal error in the iterator 146 147 resolver NodeResolver // optional node resolver for avoiding disk hits 148 pool []*nodeIteratorState // local pool for iterator states 149 } 150 151 // errIteratorEnd is stored in nodeIterator.err when iteration is done. 152 var errIteratorEnd = errors.New("end of iteration") 153 154 // seekError is stored in nodeIterator.err if the initial seek has failed. 155 type seekError struct { 156 key []byte 157 err error 158 } 159 160 func (e seekError) Error() string { 161 return "seek error: " + e.err.Error() 162 } 163 164 func newNodeIterator(trie *Trie, start []byte) NodeIterator { 165 if trie.Hash() == types.EmptyRootHash { 166 return &nodeIterator{ 167 trie: trie, 168 err: errIteratorEnd, 169 } 170 } 171 it := &nodeIterator{trie: trie} 172 it.err = it.seek(start) 173 return it 174 } 175 176 func (it *nodeIterator) putInPool(item *nodeIteratorState) { 177 if len(it.pool) < 40 { 178 item.node = nil 179 it.pool = append(it.pool, item) 180 } 181 } 182 183 func (it *nodeIterator) getFromPool() *nodeIteratorState { 184 idx := len(it.pool) - 1 185 if idx < 0 { 186 return new(nodeIteratorState) 187 } 188 el := it.pool[idx] 189 it.pool[idx] = nil 190 it.pool = it.pool[:idx] 191 return el 192 } 193 194 func (it *nodeIterator) AddResolver(resolver NodeResolver) { 195 it.resolver = resolver 196 } 197 198 func (it *nodeIterator) Hash() common.Hash { 199 if len(it.stack) == 0 { 200 return common.Hash{} 201 } 202 return it.stack[len(it.stack)-1].hash 203 } 204 205 func (it *nodeIterator) Parent() common.Hash { 206 if len(it.stack) == 0 { 207 return common.Hash{} 208 } 209 return it.stack[len(it.stack)-1].parent 210 } 211 212 func (it *nodeIterator) Leaf() bool { 213 return hasTerm(it.path) 214 } 215 216 func (it *nodeIterator) LeafKey() []byte { 217 if len(it.stack) > 0 { 218 if _, ok := it.stack[len(it.stack)-1].node.(valueNode); ok { 219 return hexToKeybytes(it.path) 220 } 221 } 222 panic("not at leaf") 223 } 224 225 func (it *nodeIterator) LeafBlob() []byte { 226 if len(it.stack) > 0 { 227 if node, ok := it.stack[len(it.stack)-1].node.(valueNode); ok { 228 return node 229 } 230 } 231 panic("not at leaf") 232 } 233 234 func (it *nodeIterator) LeafProof() [][]byte { 235 if len(it.stack) > 0 { 236 if _, ok := it.stack[len(it.stack)-1].node.(valueNode); ok { 237 hasher := newHasher(false) 238 defer returnHasherToPool(hasher) 239 proofs := make([][]byte, 0, len(it.stack)) 240 241 for i, item := range it.stack[:len(it.stack)-1] { 242 // Gather nodes that end up as hash nodes (or the root) 243 node, hashed := hasher.proofHash(item.node) 244 if _, ok := hashed.(hashNode); ok || i == 0 { 245 proofs = append(proofs, nodeToBytes(node)) 246 } 247 } 248 return proofs 249 } 250 } 251 panic("not at leaf") 252 } 253 254 func (it *nodeIterator) Path() []byte { 255 return it.path 256 } 257 258 func (it *nodeIterator) NodeBlob() []byte { 259 if it.Hash() == (common.Hash{}) { 260 return nil // skip the non-standalone node 261 } 262 blob, err := it.resolveBlob(it.Hash().Bytes(), it.Path()) 263 if err != nil { 264 it.err = err 265 return nil 266 } 267 return blob 268 } 269 270 func (it *nodeIterator) Error() error { 271 if it.err == errIteratorEnd { 272 return nil 273 } 274 if seek, ok := it.err.(seekError); ok { 275 return seek.err 276 } 277 return it.err 278 } 279 280 // Next moves the iterator to the next node, returning whether there are any 281 // further nodes. In case of an internal error this method returns false and 282 // sets the Error field to the encountered failure. If `descend` is false, 283 // skips iterating over any subnodes of the current node. 284 func (it *nodeIterator) Next(descend bool) bool { 285 if it.err == errIteratorEnd { 286 return false 287 } 288 if seek, ok := it.err.(seekError); ok { 289 if it.err = it.seek(seek.key); it.err != nil { 290 return false 291 } 292 } 293 // Otherwise step forward with the iterator and report any errors. 294 state, parentIndex, path, err := it.peek(descend) 295 it.err = err 296 if it.err != nil { 297 return false 298 } 299 it.push(state, parentIndex, path) 300 return true 301 } 302 303 func (it *nodeIterator) seek(prefix []byte) error { 304 // The path we're looking for is the hex encoded key without terminator. 305 key := keybytesToHex(prefix) 306 key = key[:len(key)-1] 307 308 // Move forward until we're just before the closest match to key. 309 for { 310 state, parentIndex, path, err := it.peekSeek(key) 311 if err == errIteratorEnd { 312 return errIteratorEnd 313 } else if err != nil { 314 return seekError{prefix, err} 315 } else if reachedPath(path, key) { 316 return nil 317 } 318 it.push(state, parentIndex, path) 319 } 320 } 321 322 // init initializes the iterator. 323 func (it *nodeIterator) init() (*nodeIteratorState, error) { 324 root := it.trie.Hash() 325 state := &nodeIteratorState{node: it.trie.root, index: -1} 326 if root != types.EmptyRootHash { 327 state.hash = root 328 } 329 return state, state.resolve(it, nil) 330 } 331 332 // peek creates the next state of the iterator. 333 func (it *nodeIterator) peek(descend bool) (*nodeIteratorState, *int, []byte, error) { 334 // Initialize the iterator if we've just started. 335 if len(it.stack) == 0 { 336 state, err := it.init() 337 return state, nil, nil, err 338 } 339 if !descend { 340 // If we're skipping children, pop the current node first 341 it.pop() 342 } 343 // Continue iteration to the next child 344 for len(it.stack) > 0 { 345 parent := it.stack[len(it.stack)-1] 346 ancestor := parent.hash 347 if (ancestor == common.Hash{}) { 348 ancestor = parent.parent 349 } 350 state, path, ok := it.nextChild(parent, ancestor) 351 if ok { 352 if err := state.resolve(it, path); err != nil { 353 return parent, &parent.index, path, err 354 } 355 return state, &parent.index, path, nil 356 } 357 // No more child nodes, move back up. 358 it.pop() 359 } 360 return nil, nil, nil, errIteratorEnd 361 } 362 363 // peekSeek is like peek, but it also tries to skip resolving hashes by skipping 364 // over the siblings that do not lead towards the desired seek position. 365 func (it *nodeIterator) peekSeek(seekKey []byte) (*nodeIteratorState, *int, []byte, error) { 366 // Initialize the iterator if we've just started. 367 if len(it.stack) == 0 { 368 state, err := it.init() 369 return state, nil, nil, err 370 } 371 if !bytes.HasPrefix(seekKey, it.path) { 372 // If we're skipping children, pop the current node first 373 it.pop() 374 } 375 // Continue iteration to the next child 376 for len(it.stack) > 0 { 377 parent := it.stack[len(it.stack)-1] 378 ancestor := parent.hash 379 if (ancestor == common.Hash{}) { 380 ancestor = parent.parent 381 } 382 state, path, ok := it.nextChildAt(parent, ancestor, seekKey) 383 if ok { 384 if err := state.resolve(it, path); err != nil { 385 return parent, &parent.index, path, err 386 } 387 return state, &parent.index, path, nil 388 } 389 // No more child nodes, move back up. 390 it.pop() 391 } 392 return nil, nil, nil, errIteratorEnd 393 } 394 395 func (it *nodeIterator) resolveHash(hash hashNode, path []byte) (node, error) { 396 if it.resolver != nil { 397 if blob := it.resolver(it.trie.owner, path, common.BytesToHash(hash)); len(blob) > 0 { 398 if resolved, err := decodeNode(hash, blob); err == nil { 399 return resolved, nil 400 } 401 } 402 } 403 // Retrieve the specified node from the underlying node reader. 404 // it.trie.resolveAndTrack is not used since in that function the 405 // loaded blob will be tracked, while it's not required here since 406 // all loaded nodes won't be linked to trie at all and track nodes 407 // may lead to out-of-memory issue. 408 blob, err := it.trie.reader.node(path, common.BytesToHash(hash)) 409 if err != nil { 410 return nil, err 411 } 412 // The raw-blob format nodes are loaded either from the 413 // clean cache or the database, they are all in their own 414 // copy and safe to use unsafe decoder. 415 return mustDecodeNodeUnsafe(hash, blob), nil 416 } 417 418 func (it *nodeIterator) resolveBlob(hash hashNode, path []byte) ([]byte, error) { 419 if it.resolver != nil { 420 if blob := it.resolver(it.trie.owner, path, common.BytesToHash(hash)); len(blob) > 0 { 421 return blob, nil 422 } 423 } 424 // Retrieve the specified node from the underlying node reader. 425 // it.trie.resolveAndTrack is not used since in that function the 426 // loaded blob will be tracked, while it's not required here since 427 // all loaded nodes won't be linked to trie at all and track nodes 428 // may lead to out-of-memory issue. 429 return it.trie.reader.node(path, common.BytesToHash(hash)) 430 } 431 432 func (st *nodeIteratorState) resolve(it *nodeIterator, path []byte) error { 433 if hash, ok := st.node.(hashNode); ok { 434 resolved, err := it.resolveHash(hash, path) 435 if err != nil { 436 return err 437 } 438 st.node = resolved 439 st.hash = common.BytesToHash(hash) 440 } 441 return nil 442 } 443 444 func (it *nodeIterator) findChild(n *fullNode, index int, ancestor common.Hash) (node, *nodeIteratorState, []byte, int) { 445 var ( 446 path = it.path 447 child node 448 state *nodeIteratorState 449 childPath []byte 450 ) 451 for ; index < len(n.Children); index = nextChildIndex(index) { 452 if n.Children[index] != nil { 453 child = n.Children[index] 454 hash, _ := child.cache() 455 456 state = it.getFromPool() 457 state.hash = common.BytesToHash(hash) 458 state.node = child 459 state.parent = ancestor 460 state.index = -1 461 state.pathlen = len(path) 462 463 childPath = append(childPath, path...) 464 childPath = append(childPath, byte(index)) 465 return child, state, childPath, index 466 } 467 } 468 return nil, nil, nil, 0 469 } 470 471 func (it *nodeIterator) nextChild(parent *nodeIteratorState, ancestor common.Hash) (*nodeIteratorState, []byte, bool) { 472 switch node := parent.node.(type) { 473 case *fullNode: 474 // Full node, move to the first non-nil child. 475 if child, state, path, index := it.findChild(node, nextChildIndex(parent.index), ancestor); child != nil { 476 parent.index = prevChildIndex(index) 477 return state, path, true 478 } 479 case *shortNode: 480 // Short node, return the pointer singleton child 481 if parent.index < 0 { 482 hash, _ := node.Val.cache() 483 state := it.getFromPool() 484 state.hash = common.BytesToHash(hash) 485 state.node = node.Val 486 state.parent = ancestor 487 state.index = -1 488 state.pathlen = len(it.path) 489 path := append(it.path, node.Key...) 490 return state, path, true 491 } 492 } 493 return parent, it.path, false 494 } 495 496 // nextChildAt is similar to nextChild, except that it targets a child as close to the 497 // target key as possible, thus skipping siblings. 498 func (it *nodeIterator) nextChildAt(parent *nodeIteratorState, ancestor common.Hash, key []byte) (*nodeIteratorState, []byte, bool) { 499 switch n := parent.node.(type) { 500 case *fullNode: 501 // Full node, move to the first non-nil child before the desired key position 502 child, state, path, index := it.findChild(n, nextChildIndex(parent.index), ancestor) 503 if child == nil { 504 // No more children in this fullnode 505 return parent, it.path, false 506 } 507 // If the child we found is already past the seek position, just return it. 508 if reachedPath(path, key) { 509 parent.index = prevChildIndex(index) 510 return state, path, true 511 } 512 // The child is before the seek position. Try advancing 513 for { 514 nextChild, nextState, nextPath, nextIndex := it.findChild(n, nextChildIndex(index), ancestor) 515 // If we run out of children, or skipped past the target, return the 516 // previous one 517 if nextChild == nil || reachedPath(nextPath, key) { 518 parent.index = prevChildIndex(index) 519 return state, path, true 520 } 521 // We found a better child closer to the target 522 state, path, index = nextState, nextPath, nextIndex 523 } 524 case *shortNode: 525 // Short node, return the pointer singleton child 526 if parent.index < 0 { 527 hash, _ := n.Val.cache() 528 state := it.getFromPool() 529 state.hash = common.BytesToHash(hash) 530 state.node = n.Val 531 state.parent = ancestor 532 state.index = -1 533 state.pathlen = len(it.path) 534 path := append(it.path, n.Key...) 535 return state, path, true 536 } 537 } 538 return parent, it.path, false 539 } 540 541 func (it *nodeIterator) push(state *nodeIteratorState, parentIndex *int, path []byte) { 542 it.path = path 543 it.stack = append(it.stack, state) 544 if parentIndex != nil { 545 *parentIndex = nextChildIndex(*parentIndex) 546 } 547 } 548 549 func (it *nodeIterator) pop() { 550 last := it.stack[len(it.stack)-1] 551 it.path = it.path[:last.pathlen] 552 it.stack[len(it.stack)-1] = nil 553 it.stack = it.stack[:len(it.stack)-1] 554 555 it.putInPool(last) // last is now unused 556 } 557 558 // reachedPath normalizes a path by truncating a terminator if present, and 559 // returns true if it is greater than or equal to the target. Using this, 560 // the path of a value node embedded a full node will compare less than the 561 // full node's children. 562 func reachedPath(path, target []byte) bool { 563 if hasTerm(path) { 564 path = path[:len(path)-1] 565 } 566 return bytes.Compare(path, target) >= 0 567 } 568 569 // A value embedded in a full node occupies the last slot (16) of the array of 570 // children. In order to produce a pre-order traversal when iterating children, 571 // we jump to this last slot first, then go back iterate the child nodes (and 572 // skip the last slot at the end): 573 574 // prevChildIndex returns the index of a child in a full node which precedes 575 // the given index when performing a pre-order traversal. 576 func prevChildIndex(index int) int { 577 switch index { 578 case 0: // We jumped back to iterate the children, from the value slot 579 return 16 580 case 16: // We jumped to the embedded value slot at the end, from the placeholder index 581 return -1 582 case 17: // We skipped the value slot after iterating all the children 583 return 15 584 default: // We are iterating the children in sequence 585 return index - 1 586 } 587 } 588 589 // nextChildIndex returns the index of a child in a full node which follows 590 // the given index when performing a pre-order traversal. 591 func nextChildIndex(index int) int { 592 switch index { 593 case -1: // Jump from the placeholder index to the embedded value slot 594 return 16 595 case 15: // Skip the value slot after iterating the children 596 return 17 597 case 16: // From the embedded value slot, jump back to iterate the children 598 return 0 599 default: // Iterate children in sequence 600 return index + 1 601 } 602 } 603 604 func compareNodes(a, b NodeIterator) int { 605 if cmp := bytes.Compare(a.Path(), b.Path()); cmp != 0 { 606 return cmp 607 } 608 if a.Leaf() && !b.Leaf() { 609 return -1 610 } else if b.Leaf() && !a.Leaf() { 611 return 1 612 } 613 if cmp := bytes.Compare(a.Hash().Bytes(), b.Hash().Bytes()); cmp != 0 { 614 return cmp 615 } 616 if a.Leaf() && b.Leaf() { 617 return bytes.Compare(a.LeafBlob(), b.LeafBlob()) 618 } 619 return 0 620 } 621 622 type differenceIterator struct { 623 a, b NodeIterator // Nodes returned are those in b - a. 624 eof bool // Indicates a has run out of elements 625 count int // Number of nodes scanned on either trie 626 } 627 628 // NewDifferenceIterator constructs a NodeIterator that iterates over elements in b that 629 // are not in a. Returns the iterator, and a pointer to an integer recording the number 630 // of nodes seen. 631 func NewDifferenceIterator(a, b NodeIterator) (NodeIterator, *int) { 632 a.Next(true) 633 it := &differenceIterator{ 634 a: a, 635 b: b, 636 } 637 return it, &it.count 638 } 639 640 func (it *differenceIterator) Hash() common.Hash { 641 return it.b.Hash() 642 } 643 644 func (it *differenceIterator) Parent() common.Hash { 645 return it.b.Parent() 646 } 647 648 func (it *differenceIterator) Leaf() bool { 649 return it.b.Leaf() 650 } 651 652 func (it *differenceIterator) LeafKey() []byte { 653 return it.b.LeafKey() 654 } 655 656 func (it *differenceIterator) LeafBlob() []byte { 657 return it.b.LeafBlob() 658 } 659 660 func (it *differenceIterator) LeafProof() [][]byte { 661 return it.b.LeafProof() 662 } 663 664 func (it *differenceIterator) Path() []byte { 665 return it.b.Path() 666 } 667 668 func (it *differenceIterator) NodeBlob() []byte { 669 return it.b.NodeBlob() 670 } 671 672 func (it *differenceIterator) AddResolver(resolver NodeResolver) { 673 panic("not implemented") 674 } 675 676 func (it *differenceIterator) Next(bool) bool { 677 // Invariants: 678 // - We always advance at least one element in b. 679 // - At the start of this function, a's path is lexically greater than b's. 680 if !it.b.Next(true) { 681 return false 682 } 683 it.count++ 684 685 if it.eof { 686 // a has reached eof, so we just return all elements from b 687 return true 688 } 689 690 for { 691 switch compareNodes(it.a, it.b) { 692 case -1: 693 // b jumped past a; advance a 694 if !it.a.Next(true) { 695 it.eof = true 696 return true 697 } 698 it.count++ 699 case 1: 700 // b is before a 701 return true 702 case 0: 703 // a and b are identical; skip this whole subtree if the nodes have hashes 704 hasHash := it.a.Hash() == common.Hash{} 705 if !it.b.Next(hasHash) { 706 return false 707 } 708 it.count++ 709 if !it.a.Next(hasHash) { 710 it.eof = true 711 return true 712 } 713 it.count++ 714 } 715 } 716 } 717 718 func (it *differenceIterator) Error() error { 719 if err := it.a.Error(); err != nil { 720 return err 721 } 722 return it.b.Error() 723 } 724 725 type nodeIteratorHeap []NodeIterator 726 727 func (h nodeIteratorHeap) Len() int { return len(h) } 728 func (h nodeIteratorHeap) Less(i, j int) bool { return compareNodes(h[i], h[j]) < 0 } 729 func (h nodeIteratorHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } 730 func (h *nodeIteratorHeap) Push(x interface{}) { *h = append(*h, x.(NodeIterator)) } 731 func (h *nodeIteratorHeap) Pop() interface{} { 732 n := len(*h) 733 x := (*h)[n-1] 734 *h = (*h)[0 : n-1] 735 return x 736 } 737 738 type unionIterator struct { 739 items *nodeIteratorHeap // Nodes returned are the union of the ones in these iterators 740 count int // Number of nodes scanned across all tries 741 } 742 743 // NewUnionIterator constructs a NodeIterator that iterates over elements in the union 744 // of the provided NodeIterators. Returns the iterator, and a pointer to an integer 745 // recording the number of nodes visited. 746 func NewUnionIterator(iters []NodeIterator) (NodeIterator, *int) { 747 h := make(nodeIteratorHeap, len(iters)) 748 copy(h, iters) 749 heap.Init(&h) 750 751 ui := &unionIterator{items: &h} 752 return ui, &ui.count 753 } 754 755 func (it *unionIterator) Hash() common.Hash { 756 return (*it.items)[0].Hash() 757 } 758 759 func (it *unionIterator) Parent() common.Hash { 760 return (*it.items)[0].Parent() 761 } 762 763 func (it *unionIterator) Leaf() bool { 764 return (*it.items)[0].Leaf() 765 } 766 767 func (it *unionIterator) LeafKey() []byte { 768 return (*it.items)[0].LeafKey() 769 } 770 771 func (it *unionIterator) LeafBlob() []byte { 772 return (*it.items)[0].LeafBlob() 773 } 774 775 func (it *unionIterator) LeafProof() [][]byte { 776 return (*it.items)[0].LeafProof() 777 } 778 779 func (it *unionIterator) Path() []byte { 780 return (*it.items)[0].Path() 781 } 782 783 func (it *unionIterator) NodeBlob() []byte { 784 return (*it.items)[0].NodeBlob() 785 } 786 787 func (it *unionIterator) AddResolver(resolver NodeResolver) { 788 panic("not implemented") 789 } 790 791 // Next returns the next node in the union of tries being iterated over. 792 // 793 // It does this by maintaining a heap of iterators, sorted by the iteration 794 // order of their next elements, with one entry for each source trie. Each 795 // time Next() is called, it takes the least element from the heap to return, 796 // advancing any other iterators that also point to that same element. These 797 // iterators are called with descend=false, since we know that any nodes under 798 // these nodes will also be duplicates, found in the currently selected iterator. 799 // Whenever an iterator is advanced, it is pushed back into the heap if it still 800 // has elements remaining. 801 // 802 // In the case that descend=false - eg, we're asked to ignore all subnodes of the 803 // current node - we also advance any iterators in the heap that have the current 804 // path as a prefix. 805 func (it *unionIterator) Next(descend bool) bool { 806 if len(*it.items) == 0 { 807 return false 808 } 809 810 // Get the next key from the union 811 least := heap.Pop(it.items).(NodeIterator) 812 813 // Skip over other nodes as long as they're identical, or, if we're not descending, as 814 // long as they have the same prefix as the current node. 815 for len(*it.items) > 0 && ((!descend && bytes.HasPrefix((*it.items)[0].Path(), least.Path())) || compareNodes(least, (*it.items)[0]) == 0) { 816 skipped := heap.Pop(it.items).(NodeIterator) 817 // Skip the whole subtree if the nodes have hashes; otherwise just skip this node 818 if skipped.Next(skipped.Hash() == common.Hash{}) { 819 it.count++ 820 // If there are more elements, push the iterator back on the heap 821 heap.Push(it.items, skipped) 822 } 823 } 824 if least.Next(descend) { 825 it.count++ 826 heap.Push(it.items, least) 827 } 828 return len(*it.items) > 0 829 } 830 831 func (it *unionIterator) Error() error { 832 for i := 0; i < len(*it.items); i++ { 833 if err := (*it.items)[i].Error(); err != nil { 834 return err 835 } 836 } 837 return nil 838 }