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 }