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