github.com/klaytn/klaytn@v1.12.1/node/cn/snap/nodeset.go (about) 1 // Modifications Copyright 2022 The klaytn Authors 2 // Copyright 2017 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 // 18 // This file is derived from light/nodeset.go (2022/06/29). 19 // Modified and improved for the klaytn development. 20 21 package snap 22 23 import ( 24 "errors" 25 "sync" 26 27 "github.com/klaytn/klaytn/common" 28 "github.com/klaytn/klaytn/crypto" 29 "github.com/klaytn/klaytn/rlp" 30 "github.com/klaytn/klaytn/storage/database" 31 ) 32 33 // NodeSet stores a set of trie nodes. It implements trie.Database and can also 34 // act as a cache for another trie.Database. 35 type NodeSet struct { 36 nodes map[string][]byte 37 order []string 38 39 dataSize int 40 lock sync.RWMutex 41 } 42 43 // NewNodeSet creates an empty node set 44 func NewNodeSet() *NodeSet { 45 return &NodeSet{ 46 nodes: make(map[string][]byte), 47 } 48 } 49 50 func (db *NodeSet) ReadTrieNode(hash common.ExtHash) ([]byte, error) { 51 return db.Get(database.TrieNodeKey(hash)) 52 } 53 54 func (db *NodeSet) WriteMerkleProof(key, value []byte) { 55 db.Put(key, value) 56 } 57 58 // Put stores a new node in the set 59 func (db *NodeSet) Put(key []byte, value []byte) error { 60 db.lock.Lock() 61 defer db.lock.Unlock() 62 63 keystr := string(key) 64 if _, ok := db.nodes[keystr]; ok { 65 return nil 66 } 67 68 db.nodes[keystr] = common.CopyBytes(value) 69 db.order = append(db.order, keystr) 70 db.dataSize += len(value) 71 72 return nil 73 } 74 75 // Delete removes a node from the set 76 func (db *NodeSet) Delete(key []byte) error { 77 db.lock.Lock() 78 defer db.lock.Unlock() 79 80 delete(db.nodes, string(key)) 81 return nil 82 } 83 84 // Get returns a stored node 85 func (db *NodeSet) Get(key []byte) ([]byte, error) { 86 db.lock.RLock() 87 defer db.lock.RUnlock() 88 89 if entry, ok := db.nodes[string(key)]; ok { 90 return entry, nil 91 } 92 return nil, errors.New("not found") 93 } 94 95 // Has returns true if the node set contains the given key 96 func (db *NodeSet) Has(key []byte) (bool, error) { 97 _, err := db.Get(key) 98 return err == nil, nil 99 } 100 101 // KeyCount returns the number of nodes in the set 102 func (db *NodeSet) KeyCount() int { 103 db.lock.RLock() 104 defer db.lock.RUnlock() 105 106 return len(db.nodes) 107 } 108 109 // DataSize returns the aggregated data size of nodes in the set 110 func (db *NodeSet) DataSize() int { 111 db.lock.RLock() 112 defer db.lock.RUnlock() 113 114 return db.dataSize 115 } 116 117 // NodeList converts the node set to a NodeList 118 func (db *NodeSet) NodeList() NodeList { 119 db.lock.RLock() 120 defer db.lock.RUnlock() 121 122 var values NodeList 123 for _, key := range db.order { 124 values = append(values, db.nodes[key]) 125 } 126 return values 127 } 128 129 // Store writes the contents of the set to the given database 130 func (db *NodeSet) Store(target database.KeyValueWriter) { 131 db.lock.RLock() 132 defer db.lock.RUnlock() 133 134 for key, value := range db.nodes { 135 target.Put([]byte(key), value) 136 } 137 } 138 139 // NodeList stores an ordered list of trie nodes. It implements ethdb.KeyValueWriter. 140 type NodeList []rlp.RawValue 141 142 // Store writes the contents of the list to the given database 143 func (n NodeList) Store(db database.KeyValueWriter) { 144 for _, node := range n { 145 db.Put(crypto.Keccak256(node), node) 146 } 147 } 148 149 // NodeSet converts the node list to a NodeSet 150 func (n NodeList) NodeSet() *NodeSet { 151 db := NewNodeSet() 152 n.Store(db) 153 return db 154 } 155 156 // Put stores a new node at the end of the list 157 func (n *NodeList) Put(key []byte, value []byte) error { 158 *n = append(*n, value) 159 return nil 160 } 161 162 // Delete panics as there's no reason to remove a node from the list. 163 func (n *NodeList) Delete(key []byte) error { 164 panic("not supported") 165 } 166 167 // DataSize returns the aggregated data size of nodes in the list 168 func (n NodeList) DataSize() int { 169 var size int 170 for _, node := range n { 171 size += len(node) 172 } 173 return size 174 }