github.com/MetalBlockchain/subnet-evm@v0.4.9/trie/nodeset.go (about)

     1  // (c) 2022, 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 2022 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  	"fmt"
    31  
    32  	"github.com/ethereum/go-ethereum/common"
    33  )
    34  
    35  // memoryNode is all the information we know about a single cached trie node
    36  // in the memory.
    37  type memoryNode struct {
    38  	hash common.Hash // Node hash, computed by hashing rlp value
    39  	size uint16      // Byte size of the useful cached data
    40  	node node        // Cached collapsed trie node, or raw rlp data
    41  }
    42  
    43  // NodeSet contains all dirty nodes collected during the commit operation.
    44  // Each node is keyed by path. It's not thread-safe to use.
    45  type NodeSet struct {
    46  	owner  common.Hash            // the identifier of the trie
    47  	paths  []string               // the path of dirty nodes, sort by insertion order
    48  	nodes  map[string]*memoryNode // the map of dirty nodes, keyed by node path
    49  	leaves []*leaf                // the list of dirty leaves
    50  }
    51  
    52  // NewNodeSet initializes an empty node set to be used for tracking dirty nodes
    53  // from a specific account or storage trie. The owner is zero for the account
    54  // trie and the owning account address hash for storage tries.
    55  func NewNodeSet(owner common.Hash) *NodeSet {
    56  	return &NodeSet{
    57  		owner: owner,
    58  		nodes: make(map[string]*memoryNode),
    59  	}
    60  }
    61  
    62  // add caches node with provided path and node object.
    63  func (set *NodeSet) add(path string, node *memoryNode) {
    64  	set.paths = append(set.paths, path)
    65  	set.nodes[path] = node
    66  }
    67  
    68  // addLeaf caches the provided leaf node.
    69  func (set *NodeSet) addLeaf(node *leaf) {
    70  	set.leaves = append(set.leaves, node)
    71  }
    72  
    73  // Len returns the number of dirty nodes contained in the set.
    74  func (set *NodeSet) Len() int {
    75  	return len(set.nodes)
    76  }
    77  
    78  // MergedNodeSet represents a merged dirty node set for a group of tries.
    79  type MergedNodeSet struct {
    80  	sets map[common.Hash]*NodeSet
    81  }
    82  
    83  // NewMergedNodeSet initializes an empty merged set.
    84  func NewMergedNodeSet() *MergedNodeSet {
    85  	return &MergedNodeSet{sets: make(map[common.Hash]*NodeSet)}
    86  }
    87  
    88  // NewWithNodeSet constructs a merged nodeset with the provided single set.
    89  func NewWithNodeSet(set *NodeSet) *MergedNodeSet {
    90  	merged := NewMergedNodeSet()
    91  	merged.Merge(set)
    92  	return merged
    93  }
    94  
    95  // Merge merges the provided dirty nodes of a trie into the set. The assumption
    96  // is held that no duplicated set belonging to the same trie will be merged twice.
    97  func (set *MergedNodeSet) Merge(other *NodeSet) error {
    98  	_, present := set.sets[other.owner]
    99  	if present {
   100  		return fmt.Errorf("duplicate trie for owner %#x", other.owner)
   101  	}
   102  	set.sets[other.owner] = other
   103  	return nil
   104  }