github.com/theQRL/go-zond@v0.2.1/trie/secure_trie.go (about) 1 // Copyright 2015 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 17 package trie 18 19 import ( 20 "github.com/theQRL/go-zond/common" 21 "github.com/theQRL/go-zond/core/types" 22 "github.com/theQRL/go-zond/rlp" 23 "github.com/theQRL/go-zond/trie/trienode" 24 ) 25 26 // StateTrie wraps a trie with key hashing. In a stateTrie trie, all 27 // access operations hash the key using keccak256. This prevents 28 // calling code from creating long chains of nodes that 29 // increase the access time. 30 // 31 // Contrary to a regular trie, a StateTrie can only be created with 32 // New and must have an attached database. The database also stores 33 // the preimage of each key if preimage recording is enabled. 34 // 35 // StateTrie is not safe for concurrent use. 36 type StateTrie struct { 37 trie Trie 38 preimages *preimageStore 39 hashKeyBuf [common.HashLength]byte 40 secKeyCache map[string][]byte 41 secKeyCacheOwner *StateTrie // Pointer to self, replace the key cache on mismatch 42 } 43 44 // NewStateTrie creates a trie with an existing root node from a backing database. 45 // 46 // If root is the zero hash or the sha3 hash of an empty string, the 47 // trie is initially empty. Otherwise, New will panic if db is nil 48 // and returns MissingNodeError if the root node cannot be found. 49 func NewStateTrie(id *ID, db *Database) (*StateTrie, error) { 50 if db == nil { 51 panic("trie.NewStateTrie called without a database") 52 } 53 trie, err := New(id, db) 54 if err != nil { 55 return nil, err 56 } 57 return &StateTrie{trie: *trie, preimages: db.preimages}, nil 58 } 59 60 // MustGet returns the value for key stored in the trie. 61 // The value bytes must not be modified by the caller. 62 // 63 // This function will omit any encountered error but just 64 // print out an error message. 65 func (t *StateTrie) MustGet(key []byte) []byte { 66 return t.trie.MustGet(t.hashKey(key)) 67 } 68 69 // GetStorage attempts to retrieve a storage slot with provided account address 70 // and slot key. The value bytes must not be modified by the caller. 71 // If the specified storage slot is not in the trie, nil will be returned. 72 // If a trie node is not found in the database, a MissingNodeError is returned. 73 func (t *StateTrie) GetStorage(_ common.Address, key []byte) ([]byte, error) { 74 enc, err := t.trie.Get(t.hashKey(key)) 75 if err != nil || len(enc) == 0 { 76 return nil, err 77 } 78 _, content, _, err := rlp.Split(enc) 79 return content, err 80 } 81 82 // GetAccount attempts to retrieve an account with provided account address. 83 // If the specified account is not in the trie, nil will be returned. 84 // If a trie node is not found in the database, a MissingNodeError is returned. 85 func (t *StateTrie) GetAccount(address common.Address) (*types.StateAccount, error) { 86 res, err := t.trie.Get(t.hashKey(address.Bytes())) 87 if res == nil || err != nil { 88 return nil, err 89 } 90 ret := new(types.StateAccount) 91 err = rlp.DecodeBytes(res, ret) 92 return ret, err 93 } 94 95 // GetAccountByHash does the same thing as GetAccount, however it expects an 96 // account hash that is the hash of address. This constitutes an abstraction 97 // leak, since the client code needs to know the key format. 98 func (t *StateTrie) GetAccountByHash(addrHash common.Hash) (*types.StateAccount, error) { 99 res, err := t.trie.Get(addrHash.Bytes()) 100 if res == nil || err != nil { 101 return nil, err 102 } 103 ret := new(types.StateAccount) 104 err = rlp.DecodeBytes(res, ret) 105 return ret, err 106 } 107 108 // GetNode attempts to retrieve a trie node by compact-encoded path. It is not 109 // possible to use keybyte-encoding as the path might contain odd nibbles. 110 // If the specified trie node is not in the trie, nil will be returned. 111 // If a trie node is not found in the database, a MissingNodeError is returned. 112 func (t *StateTrie) GetNode(path []byte) ([]byte, int, error) { 113 return t.trie.GetNode(path) 114 } 115 116 // MustUpdate associates key with value in the trie. Subsequent calls to 117 // Get will return value. If value has length zero, any existing value 118 // is deleted from the trie and calls to Get will return nil. 119 // 120 // The value bytes must not be modified by the caller while they are 121 // stored in the trie. 122 // 123 // This function will omit any encountered error but just print out an 124 // error message. 125 func (t *StateTrie) MustUpdate(key, value []byte) { 126 hk := t.hashKey(key) 127 t.trie.MustUpdate(hk, value) 128 t.getSecKeyCache()[string(hk)] = common.CopyBytes(key) 129 } 130 131 // UpdateStorage associates key with value in the trie. Subsequent calls to 132 // Get will return value. If value has length zero, any existing value 133 // is deleted from the trie and calls to Get will return nil. 134 // 135 // The value bytes must not be modified by the caller while they are 136 // stored in the trie. 137 // 138 // If a node is not found in the database, a MissingNodeError is returned. 139 func (t *StateTrie) UpdateStorage(_ common.Address, key, value []byte) error { 140 hk := t.hashKey(key) 141 v, _ := rlp.EncodeToBytes(value) 142 err := t.trie.Update(hk, v) 143 if err != nil { 144 return err 145 } 146 t.getSecKeyCache()[string(hk)] = common.CopyBytes(key) 147 return nil 148 } 149 150 // UpdateAccount will abstract the write of an account to the secure trie. 151 func (t *StateTrie) UpdateAccount(address common.Address, acc *types.StateAccount) error { 152 hk := t.hashKey(address.Bytes()) 153 data, err := rlp.EncodeToBytes(acc) 154 if err != nil { 155 return err 156 } 157 if err := t.trie.Update(hk, data); err != nil { 158 return err 159 } 160 t.getSecKeyCache()[string(hk)] = address.Bytes() 161 return nil 162 } 163 164 func (t *StateTrie) UpdateContractCode(_ common.Address, _ common.Hash, _ []byte) error { 165 return nil 166 } 167 168 // MustDelete removes any existing value for key from the trie. This function 169 // will omit any encountered error but just print out an error message. 170 func (t *StateTrie) MustDelete(key []byte) { 171 hk := t.hashKey(key) 172 delete(t.getSecKeyCache(), string(hk)) 173 t.trie.MustDelete(hk) 174 } 175 176 // DeleteStorage removes any existing storage slot from the trie. 177 // If the specified trie node is not in the trie, nothing will be changed. 178 // If a node is not found in the database, a MissingNodeError is returned. 179 func (t *StateTrie) DeleteStorage(_ common.Address, key []byte) error { 180 hk := t.hashKey(key) 181 delete(t.getSecKeyCache(), string(hk)) 182 return t.trie.Delete(hk) 183 } 184 185 // DeleteAccount abstracts an account deletion from the trie. 186 func (t *StateTrie) DeleteAccount(address common.Address) error { 187 hk := t.hashKey(address.Bytes()) 188 delete(t.getSecKeyCache(), string(hk)) 189 return t.trie.Delete(hk) 190 } 191 192 // GetKey returns the sha3 preimage of a hashed key that was 193 // previously used to store a value. 194 func (t *StateTrie) GetKey(shaKey []byte) []byte { 195 if key, ok := t.getSecKeyCache()[string(shaKey)]; ok { 196 return key 197 } 198 if t.preimages == nil { 199 return nil 200 } 201 return t.preimages.preimage(common.BytesToHash(shaKey)) 202 } 203 204 // Commit collects all dirty nodes in the trie and replaces them with the 205 // corresponding node hash. All collected nodes (including dirty leaves if 206 // collectLeaf is true) will be encapsulated into a nodeset for return. 207 // The returned nodeset can be nil if the trie is clean (nothing to commit). 208 // All cached preimages will be also flushed if preimages recording is enabled. 209 // Once the trie is committed, it's not usable anymore. A new trie must 210 // be created with new root and updated trie database for following usage 211 func (t *StateTrie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet, error) { 212 // Write all the pre-images to the actual disk database 213 if len(t.getSecKeyCache()) > 0 { 214 if t.preimages != nil { 215 preimages := make(map[common.Hash][]byte) 216 for hk, key := range t.secKeyCache { 217 preimages[common.BytesToHash([]byte(hk))] = key 218 } 219 t.preimages.insertPreimage(preimages) 220 } 221 t.secKeyCache = make(map[string][]byte) 222 } 223 // Commit the trie and return its modified nodeset. 224 return t.trie.Commit(collectLeaf) 225 } 226 227 // Hash returns the root hash of StateTrie. It does not write to the 228 // database and can be used even if the trie doesn't have one. 229 func (t *StateTrie) Hash() common.Hash { 230 return t.trie.Hash() 231 } 232 233 // Copy returns a copy of StateTrie. 234 func (t *StateTrie) Copy() *StateTrie { 235 return &StateTrie{ 236 trie: *t.trie.Copy(), 237 preimages: t.preimages, 238 secKeyCache: t.secKeyCache, 239 } 240 } 241 242 // NodeIterator returns an iterator that returns nodes of the underlying trie. 243 // Iteration starts at the key after the given start key. 244 func (t *StateTrie) NodeIterator(start []byte) (NodeIterator, error) { 245 return t.trie.NodeIterator(start) 246 } 247 248 // MustNodeIterator is a wrapper of NodeIterator and will omit any encountered 249 // error but just print out an error message. 250 func (t *StateTrie) MustNodeIterator(start []byte) NodeIterator { 251 return t.trie.MustNodeIterator(start) 252 } 253 254 // hashKey returns the hash of key as an ephemeral buffer. 255 // The caller must not hold onto the return value because it will become 256 // invalid on the next call to hashKey or secKey. 257 func (t *StateTrie) hashKey(key []byte) []byte { 258 h := newHasher(false) 259 h.sha.Reset() 260 h.sha.Write(key) 261 h.sha.Read(t.hashKeyBuf[:]) 262 returnHasherToPool(h) 263 return t.hashKeyBuf[:] 264 } 265 266 // getSecKeyCache returns the current secure key cache, creating a new one if 267 // ownership changed (i.e. the current secure trie is a copy of another owning 268 // the actual cache). 269 func (t *StateTrie) getSecKeyCache() map[string][]byte { 270 if t != t.secKeyCacheOwner { 271 t.secKeyCacheOwner = t 272 t.secKeyCache = make(map[string][]byte) 273 } 274 return t.secKeyCache 275 }