nodeset.go 3.2 KB

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