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