github.com/amazechain/amc@v0.1.3/modules/state/plain_readonly.go (about) 1 // Copyright 2023 The AmazeChain Authors 2 // This file is part of the AmazeChain library. 3 // 4 // The AmazeChain 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 AmazeChain 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 AmazeChain library. If not, see <http://www.gnu.org/licenses/>. 16 17 package state 18 19 import ( 20 "bytes" 21 "encoding/binary" 22 "fmt" 23 "github.com/amazechain/amc/common/account" 24 "github.com/amazechain/amc/common/types" 25 "github.com/amazechain/amc/log" 26 "github.com/amazechain/amc/modules" 27 "github.com/google/btree" 28 "github.com/holiman/uint256" 29 "github.com/ledgerwatch/erigon-lib/kv" 30 ) 31 32 type storageItem struct { 33 key, seckey types.Hash 34 value uint256.Int 35 } 36 37 func (a *storageItem) Less(b btree.Item) bool { 38 bi := b.(*storageItem) 39 return bytes.Compare(a.key[:], bi.key[:]) < 0 40 } 41 42 // State at the beginning of blockNr 43 type PlainState struct { 44 accHistoryC, storageHistoryC kv.Cursor 45 accChangesC, storageChangesC kv.CursorDupSort 46 tx kv.Tx 47 blockNr uint64 48 storage map[types.Address]*btree.BTree 49 trace bool 50 } 51 52 func NewPlainState(tx kv.Tx, blockNr uint64) *PlainState { 53 c1, _ := tx.Cursor(modules.AccountsHistory) 54 c2, _ := tx.Cursor(modules.StorageHistory) 55 c3, _ := tx.CursorDupSort(modules.AccountChangeSet) 56 c4, _ := tx.CursorDupSort(modules.StorageChangeSet) 57 58 return &PlainState{ 59 tx: tx, 60 blockNr: blockNr, 61 storage: make(map[types.Address]*btree.BTree), 62 accHistoryC: c1, storageHistoryC: c2, accChangesC: c3, storageChangesC: c4, 63 } 64 } 65 66 func (s *PlainState) SetTrace(trace bool) { 67 s.trace = trace 68 } 69 70 func (s *PlainState) SetBlockNr(blockNr uint64) { 71 s.blockNr = blockNr 72 } 73 74 func (s *PlainState) GetBlockNr() uint64 { 75 return s.blockNr 76 } 77 78 func (s *PlainState) ForEachStorage(addr types.Address, startLocation types.Hash, cb func(key, seckey types.Hash, value uint256.Int) bool, maxResults int) error { 79 st := btree.New(16) 80 var k [types.AddressLength + types.IncarnationLength + types.HashLength]byte 81 copy(k[:], addr[:]) 82 accData, err := GetAsOf(s.tx, s.accHistoryC, s.accChangesC, false /* storage */, addr[:], s.blockNr) 83 if err != nil { 84 return err 85 } 86 var acc account.StateAccount 87 if err := acc.DecodeForStorage(accData); err != nil { 88 log.Error("Error decoding account", "err", err) 89 return err 90 } 91 binary.BigEndian.PutUint16(k[types.AddressLength:], acc.Incarnation) 92 copy(k[types.AddressLength+types.IncarnationLength:], startLocation[:]) 93 var lastKey types.Hash 94 overrideCounter := 0 95 min := &storageItem{key: startLocation} 96 if t, ok := s.storage[addr]; ok { 97 t.AscendGreaterOrEqual(min, func(i btree.Item) bool { 98 item := i.(*storageItem) 99 st.ReplaceOrInsert(item) 100 if !item.value.IsZero() { 101 copy(lastKey[:], item.key[:]) 102 // Only count non-zero items 103 overrideCounter++ 104 } 105 return overrideCounter < maxResults 106 }) 107 } 108 numDeletes := st.Len() - overrideCounter 109 if err := WalkAsOfStorage(s.tx, addr, acc.Incarnation, startLocation, s.blockNr, func(kAddr, kLoc, vs []byte) (bool, error) { 110 if !bytes.Equal(kAddr, addr[:]) { 111 return false, nil 112 } 113 if len(vs) == 0 { 114 // Skip deleted entries 115 return true, nil 116 } 117 keyHash, err1 := types.HashData(kLoc) 118 if err1 != nil { 119 return false, err1 120 } 121 //fmt.Printf("seckey: %x\n", seckey) 122 si := storageItem{} 123 copy(si.key[:], kLoc) 124 copy(si.seckey[:], keyHash[:]) 125 if st.Has(&si) { 126 return true, nil 127 } 128 si.value.SetBytes(vs) 129 st.ReplaceOrInsert(&si) 130 if bytes.Compare(kLoc, lastKey[:]) > 0 { 131 // Beyond overrides 132 return st.Len() < maxResults+numDeletes, nil 133 } 134 return st.Len() < maxResults+overrideCounter+numDeletes, nil 135 }); err != nil { 136 log.Error("ForEachStorage walk error", "err", err) 137 return err 138 } 139 results := 0 140 var innerErr error 141 st.AscendGreaterOrEqual(min, func(i btree.Item) bool { 142 item := i.(*storageItem) 143 if !item.value.IsZero() { 144 // Skip if value == 0 145 cb(item.key, item.seckey, item.value) 146 results++ 147 } 148 return results < maxResults 149 }) 150 return innerErr 151 } 152 153 func (s *PlainState) ReadAccountData(address types.Address) (*account.StateAccount, error) { 154 enc, err := GetAsOf(s.tx, s.accHistoryC, s.accChangesC, false /* storage */, address[:], s.blockNr) 155 if err != nil { 156 return nil, err 157 } 158 if len(enc) == 0 { 159 if s.trace { 160 fmt.Printf("ReadAccountData [%x] => []\n", address) 161 } 162 return nil, nil 163 } 164 var a account.StateAccount 165 if err = a.DecodeForStorage(enc); err != nil { 166 return nil, err 167 } 168 //restore codehash 169 if a.Incarnation > 0 && a.IsEmptyCodeHash() { 170 if codeHash, err1 := s.tx.GetOne(modules.PlainContractCode, modules.PlainGenerateStoragePrefix(address[:], a.Incarnation)); err1 == nil { 171 if len(codeHash) > 0 { 172 a.CodeHash = types.BytesToHash(codeHash) 173 } 174 } else { 175 return nil, err1 176 } 177 } 178 if s.trace { 179 fmt.Printf("ReadAccountData [%x] => [nonce: %d, balance: %d, codeHash: %x]\n", address, a.Nonce, &a.Balance, a.CodeHash) 180 } 181 return &a, nil 182 } 183 184 func (s *PlainState) ReadAccountStorage(address types.Address, incarnation uint16, key *types.Hash) ([]byte, error) { 185 compositeKey := modules.PlainGenerateCompositeStorageKey(address.Bytes(), incarnation, key.Bytes()) 186 enc, err := GetAsOf(s.tx, s.storageHistoryC, s.storageChangesC, true /* storage */, compositeKey, s.blockNr) 187 if err != nil { 188 return nil, err 189 } 190 if s.trace { 191 fmt.Printf("ReadAccountStorage [%x] [%x] => [%x]\n", address, *key, enc) 192 } 193 if len(enc) == 0 { 194 return nil, nil 195 } 196 return enc, nil 197 } 198 199 func (s *PlainState) ReadAccountCode(address types.Address, incarnation uint16, codeHash types.Hash) ([]byte, error) { 200 if bytes.Equal(codeHash[:], emptyCodeHash) { 201 return nil, nil 202 } 203 code, err := s.tx.GetOne(modules.Code, codeHash[:]) 204 if s.trace { 205 fmt.Printf("ReadAccountCode [%x %x] => [%x]\n", address, codeHash, code) 206 } 207 if len(code) == 0 { 208 return nil, nil 209 } 210 return code, err 211 } 212 213 func (s *PlainState) ReadAccountCodeSize(address types.Address, incarnation uint16, codeHash types.Hash) (int, error) { 214 code, err := s.ReadAccountCode(address, incarnation, codeHash) 215 return len(code), err 216 } 217 218 func (s *PlainState) ReadAccountIncarnation(address types.Address) (uint16, error) { 219 enc, err := GetAsOf(s.tx, s.accHistoryC, s.accChangesC, false /* storage */, address[:], s.blockNr+1) 220 if err != nil { 221 return 0, err 222 } 223 if len(enc) == 0 { 224 return 0, nil 225 } 226 var acc account.StateAccount 227 if err = acc.DecodeForStorage(enc); err != nil { 228 return 0, err 229 } 230 if acc.Incarnation == 0 { 231 return 0, nil 232 } 233 return acc.Incarnation - 1, nil 234 } 235 236 func (s *PlainState) UpdateAccountData(address types.Address, original, account *account.StateAccount) error { 237 return nil 238 } 239 240 func (s *PlainState) DeleteAccount(address types.Address, original *account.StateAccount) error { 241 return nil 242 } 243 244 func (s *PlainState) UpdateAccountCode(address types.Address, incarnation uint16, codeHash types.Hash, code []byte) error { 245 return nil 246 } 247 248 func (s *PlainState) WriteAccountStorage(address types.Address, incarnation uint16, key *types.Hash, original, value *uint256.Int) error { 249 t, ok := s.storage[address] 250 if !ok { 251 t = btree.New(16) 252 s.storage[address] = t 253 } 254 h := types.NewHasher() 255 defer types.ReturnHasherToPool(h) 256 h.Sha.Reset() 257 _, err := h.Sha.Write(key[:]) 258 if err != nil { 259 return err 260 } 261 i := &storageItem{key: *key, value: *value} 262 _, err = h.Sha.Read(i.seckey[:]) 263 if err != nil { 264 return err 265 } 266 267 t.ReplaceOrInsert(i) 268 return nil 269 } 270 271 func (s *PlainState) CreateContract(address types.Address) error { 272 delete(s.storage, address) 273 return nil 274 }