github.com/tacshi/go-ethereum@v0.0.0-20230616113857-84a434e20921/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/tacshi/go-ethereum/common" 25 "github.com/tacshi/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 this 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 } 149 150 // errIteratorEnd is stored in nodeIterator.err when iteration is done. 151 var errIteratorEnd = errors.New("end of iteration") 152 153 // seekError is stored in nodeIterator.err if the initial seek has failed. 154 type seekError struct { 155 key []byte 156 err error 157 } 158 159 func (e seekError) Error() string { 160 return "seek error: " + e.err.Error() 161 } 162 163 func newNodeIterator(trie *Trie, start []byte) NodeIterator { 164 if trie.Hash() == types.EmptyRootHash { 165 return &nodeIterator{ 166 trie: trie, 167 err: errIteratorEnd, 168 } 169 } 170 it := &nodeIterator{trie: trie} 171 it.err = it.seek(start) 172 return it 173 } 174 175 func (it *nodeIterator) AddResolver(resolver NodeResolver) { 176 it.resolver = resolver 177 } 178 179 func (it *nodeIterator) Hash() common.Hash { 180 if len(it.stack) == 0 { 181 return common.Hash{} 182 } 183 return it.stack[len(it.stack)-1].hash 184 } 185 186 func (it *nodeIterator) Parent() common.Hash { 187 if len(it.stack) == 0 { 188 return common.Hash{} 189 } 190 return it.stack[len(it.stack)-1].parent 191 } 192 193 func (it *nodeIterator) Leaf() bool { 194 return hasTerm(it.path) 195 } 196 197 func (it *nodeIterator) LeafKey() []byte { 198 if len(it.stack) > 0 { 199 if _, ok := it.stack[len(it.stack)-1].node.(valueNode); ok { 200 return hexToKeybytes(it.path) 201 } 202 } 203 panic("not at leaf") 204 } 205 206 func (it *nodeIterator) LeafBlob() []byte { 207 if len(it.stack) > 0 { 208 if node, ok := it.stack[len(it.stack)-1].node.(valueNode); ok { 209 return node 210 } 211 } 212 panic("not at leaf") 213 } 214 215 func (it *nodeIterator) LeafProof() [][]byte { 216 if len(it.stack) > 0 { 217 if _, ok := it.stack[len(it.stack)-1].node.(valueNode); ok { 218 hasher := newHasher(false) 219 defer returnHasherToPool(hasher) 220 proofs := make([][]byte, 0, len(it.stack)) 221 222 for i, item := range it.stack[:len(it.stack)-1] { 223 // Gather nodes that end up as hash nodes (or the root) 224 node, hashed := hasher.proofHash(item.node) 225 if _, ok := hashed.(hashNode); ok || i == 0 { 226 proofs = append(proofs, nodeToBytes(node)) 227 } 228 } 229 return proofs 230 } 231 } 232 panic("not at leaf") 233 } 234 235 func (it *nodeIterator) Path() []byte { 236 return it.path 237 } 238 239 func (it *nodeIterator) NodeBlob() []byte { 240 if it.Hash() == (common.Hash{}) { 241 return nil // skip the non-standalone node 242 } 243 blob, err := it.resolveBlob(it.Hash().Bytes(), it.Path()) 244 if err != nil { 245 it.err = err 246 return nil 247 } 248 return blob 249 } 250 251 func (it *nodeIterator) Error() error { 252 if it.err == errIteratorEnd { 253 return nil 254 } 255 if seek, ok := it.err.(seekError); ok { 256 return seek.err 257 } 258 return it.err 259 } 260 261 // Next moves the iterator to the next node, returning whether there are any 262 // further nodes. In case of an internal error this method returns false and 263 // sets the Error field to the encountered failure. If `descend` is false, 264 // skips iterating over any subnodes of the current node. 265 func (it *nodeIterator) Next(descend bool) bool { 266 if it.err == errIteratorEnd { 267 return false 268 } 269 if seek, ok := it.err.(seekError); ok { 270 if it.err = it.seek(seek.key); it.err != nil { 271 return false 272 } 273 } 274 // Otherwise step forward with the iterator and report any errors. 275 state, parentIndex, path, err := it.peek(descend) 276 it.err = err 277 if it.err != nil { 278 return false 279 } 280 it.push(state, parentIndex, path) 281 return true 282 } 283 284 func (it *nodeIterator) seek(prefix []byte) error { 285 // The path we're looking for is the hex encoded key without terminator. 286 key := keybytesToHex(prefix) 287 key = key[:len(key)-1] 288 // Move forward until we're just before the closest match to key. 289 for { 290 state, parentIndex, path, err := it.peekSeek(key) 291 if err == errIteratorEnd { 292 return errIteratorEnd 293 } else if err != nil { 294 return seekError{prefix, err} 295 } else if bytes.Compare(path, key) >= 0 { 296 return nil 297 } 298 it.push(state, parentIndex, path) 299 } 300 } 301 302 // init initializes the iterator. 303 func (it *nodeIterator) init() (*nodeIteratorState, error) { 304 root := it.trie.Hash() 305 state := &nodeIteratorState{node: it.trie.root, index: -1} 306 if root != types.EmptyRootHash { 307 state.hash = root 308 } 309 return state, state.resolve(it, nil) 310 } 311 312 // peek creates the next state of the iterator. 313 func (it *nodeIterator) peek(descend bool) (*nodeIteratorState, *int, []byte, error) { 314 // Initialize the iterator if we've just started. 315 if len(it.stack) == 0 { 316 state, err := it.init() 317 return state, nil, nil, err 318 } 319 if !descend { 320 // If we're skipping children, pop the current node first 321 it.pop() 322 } 323 324 // Continue iteration to the next child 325 for len(it.stack) > 0 { 326 parent := it.stack[len(it.stack)-1] 327 ancestor := parent.hash 328 if (ancestor == common.Hash{}) { 329 ancestor = parent.parent 330 } 331 state, path, ok := it.nextChild(parent, ancestor) 332 if ok { 333 if err := state.resolve(it, path); err != nil { 334 return parent, &parent.index, path, err 335 } 336 return state, &parent.index, path, nil 337 } 338 // No more child nodes, move back up. 339 it.pop() 340 } 341 return nil, nil, nil, errIteratorEnd 342 } 343 344 // peekSeek is like peek, but it also tries to skip resolving hashes by skipping 345 // over the siblings that do not lead towards the desired seek position. 346 func (it *nodeIterator) peekSeek(seekKey []byte) (*nodeIteratorState, *int, []byte, error) { 347 // Initialize the iterator if we've just started. 348 if len(it.stack) == 0 { 349 state, err := it.init() 350 return state, nil, nil, err 351 } 352 if !bytes.HasPrefix(seekKey, it.path) { 353 // If we're skipping children, pop the current node first 354 it.pop() 355 } 356 357 // Continue iteration to the next child 358 for len(it.stack) > 0 { 359 parent := it.stack[len(it.stack)-1] 360 ancestor := parent.hash 361 if (ancestor == common.Hash{}) { 362 ancestor = parent.parent 363 } 364 state, path, ok := it.nextChildAt(parent, ancestor, seekKey) 365 if ok { 366 if err := state.resolve(it, path); err != nil { 367 return parent, &parent.index, path, err 368 } 369 return state, &parent.index, path, nil 370 } 371 // No more child nodes, move back up. 372 it.pop() 373 } 374 return nil, nil, nil, errIteratorEnd 375 } 376 377 func (it *nodeIterator) resolveHash(hash hashNode, path []byte) (node, error) { 378 if it.resolver != nil { 379 if blob := it.resolver(it.trie.owner, path, common.BytesToHash(hash)); len(blob) > 0 { 380 if resolved, err := decodeNode(hash, blob); err == nil { 381 return resolved, nil 382 } 383 } 384 } 385 // Retrieve the specified node from the underlying node reader. 386 // it.trie.resolveAndTrack is not used since in that function the 387 // loaded blob will be tracked, while it's not required here since 388 // all loaded nodes won't be linked to trie at all and track nodes 389 // may lead to out-of-memory issue. 390 return it.trie.reader.node(path, common.BytesToHash(hash)) 391 } 392 393 func (it *nodeIterator) resolveBlob(hash hashNode, path []byte) ([]byte, error) { 394 if it.resolver != nil { 395 if blob := it.resolver(it.trie.owner, path, common.BytesToHash(hash)); len(blob) > 0 { 396 return blob, nil 397 } 398 } 399 // Retrieve the specified node from the underlying node reader. 400 // it.trie.resolveAndTrack is not used since in that function the 401 // loaded blob will be tracked, while it's not required here since 402 // all loaded nodes won't be linked to trie at all and track nodes 403 // may lead to out-of-memory issue. 404 return it.trie.reader.nodeBlob(path, common.BytesToHash(hash)) 405 } 406 407 func (st *nodeIteratorState) resolve(it *nodeIterator, path []byte) error { 408 if hash, ok := st.node.(hashNode); ok { 409 resolved, err := it.resolveHash(hash, path) 410 if err != nil { 411 return err 412 } 413 st.node = resolved 414 st.hash = common.BytesToHash(hash) 415 } 416 return nil 417 } 418 419 func findChild(n *fullNode, index int, path []byte, ancestor common.Hash) (node, *nodeIteratorState, []byte, int) { 420 var ( 421 child node 422 state *nodeIteratorState 423 childPath []byte 424 ) 425 for ; index < len(n.Children); index++ { 426 if n.Children[index] != nil { 427 child = n.Children[index] 428 hash, _ := child.cache() 429 state = &nodeIteratorState{ 430 hash: common.BytesToHash(hash), 431 node: child, 432 parent: ancestor, 433 index: -1, 434 pathlen: len(path), 435 } 436 childPath = append(childPath, path...) 437 childPath = append(childPath, byte(index)) 438 return child, state, childPath, index 439 } 440 } 441 return nil, nil, nil, 0 442 } 443 444 func (it *nodeIterator) nextChild(parent *nodeIteratorState, ancestor common.Hash) (*nodeIteratorState, []byte, bool) { 445 switch node := parent.node.(type) { 446 case *fullNode: 447 // Full node, move to the first non-nil child. 448 if child, state, path, index := findChild(node, parent.index+1, it.path, ancestor); child != nil { 449 parent.index = index - 1 450 return state, path, true 451 } 452 case *shortNode: 453 // Short node, return the pointer singleton child 454 if parent.index < 0 { 455 hash, _ := node.Val.cache() 456 state := &nodeIteratorState{ 457 hash: common.BytesToHash(hash), 458 node: node.Val, 459 parent: ancestor, 460 index: -1, 461 pathlen: len(it.path), 462 } 463 path := append(it.path, node.Key...) 464 return state, path, true 465 } 466 } 467 return parent, it.path, false 468 } 469 470 // nextChildAt is similar to nextChild, except that it targets a child as close to the 471 // target key as possible, thus skipping siblings. 472 func (it *nodeIterator) nextChildAt(parent *nodeIteratorState, ancestor common.Hash, key []byte) (*nodeIteratorState, []byte, bool) { 473 switch n := parent.node.(type) { 474 case *fullNode: 475 // Full node, move to the first non-nil child before the desired key position 476 child, state, path, index := findChild(n, parent.index+1, it.path, ancestor) 477 if child == nil { 478 // No more children in this fullnode 479 return parent, it.path, false 480 } 481 // If the child we found is already past the seek position, just return it. 482 if bytes.Compare(path, key) >= 0 { 483 parent.index = index - 1 484 return state, path, true 485 } 486 // The child is before the seek position. Try advancing 487 for { 488 nextChild, nextState, nextPath, nextIndex := findChild(n, index+1, it.path, ancestor) 489 // If we run out of children, or skipped past the target, return the 490 // previous one 491 if nextChild == nil || bytes.Compare(nextPath, key) >= 0 { 492 parent.index = index - 1 493 return state, path, true 494 } 495 // We found a better child closer to the target 496 state, path, index = nextState, nextPath, nextIndex 497 } 498 case *shortNode: 499 // Short node, return the pointer singleton child 500 if parent.index < 0 { 501 hash, _ := n.Val.cache() 502 state := &nodeIteratorState{ 503 hash: common.BytesToHash(hash), 504 node: n.Val, 505 parent: ancestor, 506 index: -1, 507 pathlen: len(it.path), 508 } 509 path := append(it.path, n.Key...) 510 return state, path, true 511 } 512 } 513 return parent, it.path, false 514 } 515 516 func (it *nodeIterator) push(state *nodeIteratorState, parentIndex *int, path []byte) { 517 it.path = path 518 it.stack = append(it.stack, state) 519 if parentIndex != nil { 520 *parentIndex++ 521 } 522 } 523 524 func (it *nodeIterator) pop() { 525 last := it.stack[len(it.stack)-1] 526 it.path = it.path[:last.pathlen] 527 it.stack[len(it.stack)-1] = nil 528 it.stack = it.stack[:len(it.stack)-1] 529 } 530 531 func compareNodes(a, b NodeIterator) int { 532 if cmp := bytes.Compare(a.Path(), b.Path()); cmp != 0 { 533 return cmp 534 } 535 if a.Leaf() && !b.Leaf() { 536 return -1 537 } else if b.Leaf() && !a.Leaf() { 538 return 1 539 } 540 if cmp := bytes.Compare(a.Hash().Bytes(), b.Hash().Bytes()); cmp != 0 { 541 return cmp 542 } 543 if a.Leaf() && b.Leaf() { 544 return bytes.Compare(a.LeafBlob(), b.LeafBlob()) 545 } 546 return 0 547 } 548 549 type differenceIterator struct { 550 a, b NodeIterator // Nodes returned are those in b - a. 551 eof bool // Indicates a has run out of elements 552 count int // Number of nodes scanned on either trie 553 } 554 555 // NewDifferenceIterator constructs a NodeIterator that iterates over elements in b that 556 // are not in a. Returns the iterator, and a pointer to an integer recording the number 557 // of nodes seen. 558 func NewDifferenceIterator(a, b NodeIterator) (NodeIterator, *int) { 559 a.Next(true) 560 it := &differenceIterator{ 561 a: a, 562 b: b, 563 } 564 return it, &it.count 565 } 566 567 func (it *differenceIterator) Hash() common.Hash { 568 return it.b.Hash() 569 } 570 571 func (it *differenceIterator) Parent() common.Hash { 572 return it.b.Parent() 573 } 574 575 func (it *differenceIterator) Leaf() bool { 576 return it.b.Leaf() 577 } 578 579 func (it *differenceIterator) LeafKey() []byte { 580 return it.b.LeafKey() 581 } 582 583 func (it *differenceIterator) LeafBlob() []byte { 584 return it.b.LeafBlob() 585 } 586 587 func (it *differenceIterator) LeafProof() [][]byte { 588 return it.b.LeafProof() 589 } 590 591 func (it *differenceIterator) Path() []byte { 592 return it.b.Path() 593 } 594 595 func (it *differenceIterator) NodeBlob() []byte { 596 return it.b.NodeBlob() 597 } 598 599 func (it *differenceIterator) AddResolver(resolver NodeResolver) { 600 panic("not implemented") 601 } 602 603 func (it *differenceIterator) Next(bool) bool { 604 // Invariants: 605 // - We always advance at least one element in b. 606 // - At the start of this function, a's path is lexically greater than b's. 607 if !it.b.Next(true) { 608 return false 609 } 610 it.count++ 611 612 if it.eof { 613 // a has reached eof, so we just return all elements from b 614 return true 615 } 616 617 for { 618 switch compareNodes(it.a, it.b) { 619 case -1: 620 // b jumped past a; advance a 621 if !it.a.Next(true) { 622 it.eof = true 623 return true 624 } 625 it.count++ 626 case 1: 627 // b is before a 628 return true 629 case 0: 630 // a and b are identical; skip this whole subtree if the nodes have hashes 631 hasHash := it.a.Hash() == common.Hash{} 632 if !it.b.Next(hasHash) { 633 return false 634 } 635 it.count++ 636 if !it.a.Next(hasHash) { 637 it.eof = true 638 return true 639 } 640 it.count++ 641 } 642 } 643 } 644 645 func (it *differenceIterator) Error() error { 646 if err := it.a.Error(); err != nil { 647 return err 648 } 649 return it.b.Error() 650 } 651 652 type nodeIteratorHeap []NodeIterator 653 654 func (h nodeIteratorHeap) Len() int { return len(h) } 655 func (h nodeIteratorHeap) Less(i, j int) bool { return compareNodes(h[i], h[j]) < 0 } 656 func (h nodeIteratorHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } 657 func (h *nodeIteratorHeap) Push(x interface{}) { *h = append(*h, x.(NodeIterator)) } 658 func (h *nodeIteratorHeap) Pop() interface{} { 659 n := len(*h) 660 x := (*h)[n-1] 661 *h = (*h)[0 : n-1] 662 return x 663 } 664 665 type unionIterator struct { 666 items *nodeIteratorHeap // Nodes returned are the union of the ones in these iterators 667 count int // Number of nodes scanned across all tries 668 } 669 670 // NewUnionIterator constructs a NodeIterator that iterates over elements in the union 671 // of the provided NodeIterators. Returns the iterator, and a pointer to an integer 672 // recording the number of nodes visited. 673 func NewUnionIterator(iters []NodeIterator) (NodeIterator, *int) { 674 h := make(nodeIteratorHeap, len(iters)) 675 copy(h, iters) 676 heap.Init(&h) 677 678 ui := &unionIterator{items: &h} 679 return ui, &ui.count 680 } 681 682 func (it *unionIterator) Hash() common.Hash { 683 return (*it.items)[0].Hash() 684 } 685 686 func (it *unionIterator) Parent() common.Hash { 687 return (*it.items)[0].Parent() 688 } 689 690 func (it *unionIterator) Leaf() bool { 691 return (*it.items)[0].Leaf() 692 } 693 694 func (it *unionIterator) LeafKey() []byte { 695 return (*it.items)[0].LeafKey() 696 } 697 698 func (it *unionIterator) LeafBlob() []byte { 699 return (*it.items)[0].LeafBlob() 700 } 701 702 func (it *unionIterator) LeafProof() [][]byte { 703 return (*it.items)[0].LeafProof() 704 } 705 706 func (it *unionIterator) Path() []byte { 707 return (*it.items)[0].Path() 708 } 709 710 func (it *unionIterator) NodeBlob() []byte { 711 return (*it.items)[0].NodeBlob() 712 } 713 714 func (it *unionIterator) AddResolver(resolver NodeResolver) { 715 panic("not implemented") 716 } 717 718 // Next returns the next node in the union of tries being iterated over. 719 // 720 // It does this by maintaining a heap of iterators, sorted by the iteration 721 // order of their next elements, with one entry for each source trie. Each 722 // time Next() is called, it takes the least element from the heap to return, 723 // advancing any other iterators that also point to that same element. These 724 // iterators are called with descend=false, since we know that any nodes under 725 // these nodes will also be duplicates, found in the currently selected iterator. 726 // Whenever an iterator is advanced, it is pushed back into the heap if it still 727 // has elements remaining. 728 // 729 // In the case that descend=false - eg, we're asked to ignore all subnodes of the 730 // current node - we also advance any iterators in the heap that have the current 731 // path as a prefix. 732 func (it *unionIterator) Next(descend bool) bool { 733 if len(*it.items) == 0 { 734 return false 735 } 736 737 // Get the next key from the union 738 least := heap.Pop(it.items).(NodeIterator) 739 740 // Skip over other nodes as long as they're identical, or, if we're not descending, as 741 // long as they have the same prefix as the current node. 742 for len(*it.items) > 0 && ((!descend && bytes.HasPrefix((*it.items)[0].Path(), least.Path())) || compareNodes(least, (*it.items)[0]) == 0) { 743 skipped := heap.Pop(it.items).(NodeIterator) 744 // Skip the whole subtree if the nodes have hashes; otherwise just skip this node 745 if skipped.Next(skipped.Hash() == common.Hash{}) { 746 it.count++ 747 // If there are more elements, push the iterator back on the heap 748 heap.Push(it.items, skipped) 749 } 750 } 751 if least.Next(descend) { 752 it.count++ 753 heap.Push(it.items, least) 754 } 755 return len(*it.items) > 0 756 } 757 758 func (it *unionIterator) Error() error { 759 for i := 0; i < len(*it.items); i++ { 760 if err := (*it.items)[i].Error(); err != nil { 761 return err 762 } 763 } 764 return nil 765 }