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  }