github.com/amazechain/amc@v0.1.3/modules/state/entire.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 "github.com/amazechain/amc/common/account" 22 "github.com/amazechain/amc/common/block" 23 "github.com/amazechain/amc/common/types" 24 "github.com/amazechain/amc/internal/avm/rlp" 25 types2 "github.com/amazechain/amc/internal/avm/types" 26 "github.com/amazechain/amc/modules" 27 "io" 28 "unsafe" 29 ) 30 31 type GetOneFun func(table string, key []byte) ([]byte, error) 32 33 type EntireCode struct { 34 CoinBase types.Address `json:"coinBase"` 35 Entire Entire `json:"entire"` 36 Codes []*HashCode `json:"codes"` 37 Headers []*block.Header `json:"headers"` 38 Rewards []*block.Reward `json:"rewards"` 39 } 40 41 type HashCode struct { 42 Hash types.Hash `json:"hash"` 43 Code []byte `json:"code"` 44 } 45 46 type HashCodes []*HashCode 47 48 func (s HashCodes) Len() int { return len(s) } 49 func (s HashCodes) Less(i, j int) bool { return bytes.Compare(s[i].Hash[:], s[j].Hash[:]) < 0 } 50 func (s HashCodes) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 51 52 type Entire struct { 53 Header *block.Header `json:"header"` 54 Uncles []*types2.Header `json:"uncles"` 55 Transactions [][]byte `json:"transactions"` 56 Snap *Snapshot `json:"snap"` 57 Proof types.Hash `json:"proof"` 58 Senders []types.Address `json:"senders"` 59 } 60 61 func (e Entire) Clone() Entire { 62 var c Entire 63 //c.Header = &types2.Header{ 64 // ParentHash: e.Header.ParentHash, 65 // UncleHash: e.Header.UncleHash, 66 // Coinbase: e.Header.Coinbase, 67 // Root: e.Header.Root, 68 // TxHash: e.Header.TxHash, 69 // ReceiptHash: e.Header.ReceiptHash, 70 // Bloom: e.Header.Bloom, 71 // Difficulty: e.Header.Difficulty, 72 // Number: e.Header.Number, 73 // GasLimit: e.Header.GasLimit, 74 // GasUsed: e.Header.GasUsed, 75 // Time: e.Header.Time, 76 // Extra: e.Header.Extra, 77 // MixDigest: e.Header.MixDigest, 78 // Nonce: e.Header.Nonce, 79 // BaseFee: e.Header.BaseFee, 80 //} 81 copyHeader := *e.Header 82 c.Header = ©Header 83 c.Uncles = e.Uncles 84 c.Transactions = e.Transactions 85 c.Proof = e.Proof 86 c.Senders = e.Senders 87 c.Snap = &Snapshot{ 88 Items: e.Snap.Items, 89 OutHash: e.Snap.OutHash, 90 accounts: e.Snap.accounts, 91 storage: e.Snap.storage, 92 written: e.Snap.written, 93 getOneFun: e.Snap.getOneFun, 94 } 95 return c 96 } 97 98 type Items []*Item 99 100 func (s Items) Len() int { return len(s) } 101 func (s Items) Less(i, j int) bool { return bytes.Compare(s[i].Key, s[j].Key) < 0 } 102 func (s Items) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 103 104 type Item struct { 105 Key []byte `json:"key"` 106 Value []byte `json:"value"` 107 } 108 109 type Snapshot struct { 110 Items Items `json:"items"` 111 OutHash types.Hash `json:"outHash"` 112 accounts map[string]int `json:"accounts"` 113 storage map[string]int `json:"storage"` 114 written bool `json:"written"` 115 getOneFun GetOneFun `json:"getOneFun"` 116 } 117 118 func NewWritableSnapshot() *Snapshot { 119 return &Snapshot{Items: make([]*Item, 0), written: true, OutHash: emptyCodeHashH, accounts: make(map[string]int), storage: make(map[string]int)} 120 } 121 122 func NewReadableSnapshot() *Snapshot { 123 return &Snapshot{Items: make([]*Item, 0), written: false, OutHash: emptyCodeHashH, accounts: make(map[string]int), storage: make(map[string]int)} 124 } 125 126 func (s *Snapshot) SetGetFun(f GetOneFun) { 127 s.getOneFun = f 128 } 129 130 func (s *Snapshot) ReadAccountStorage(address types.Address, incarnation uint16, key *types.Hash) ([]byte, error) { 131 if s.written { 132 return nil, nil 133 } 134 compositeKey := modules.PlainGenerateCompositeStorageKey(address.Bytes(), incarnation, key.Bytes()) 135 index, ok := s.storage[*(*string)(unsafe.Pointer(&compositeKey))] 136 if !ok { 137 if s.getOneFun != nil { 138 return s.getOneFun(modules.Storage, compositeKey) 139 } 140 return nil, nil 141 } 142 if s.Items[index] == nil { 143 return nil, nil 144 } 145 return s.Items[index].Value, nil 146 } 147 148 func (s *Snapshot) CanWrite() bool { 149 return s.written 150 } 151 152 func ReadSnapshotData(data []byte) (*Snapshot, error) { 153 snap := NewReadableSnapshot() 154 if len(data) == 0 { 155 return snap, nil 156 } 157 if err := rlp.DecodeBytes(data, &snap); err != nil { 158 return nil, err 159 } 160 for k, v := range snap.Items { 161 if len(v.Key) == types.AddressLength { 162 snap.accounts[*(*string)(unsafe.Pointer(&v.Key))] = k 163 } else { 164 snap.storage[*(*string)(unsafe.Pointer(&v.Key))] = k 165 } 166 } 167 return snap, nil 168 } 169 170 func (s *Snapshot) SetHash(hash types.Hash) { 171 if s.written { 172 return 173 } 174 s.OutHash = hash 175 } 176 177 func (s *Snapshot) ReadAccountData(address types.Address) (*account.StateAccount, error) { 178 if s.written { 179 return nil, nil 180 } 181 addr := address[:] 182 index, ok := s.accounts[*(*string)(unsafe.Pointer(&addr))] 183 if !ok { 184 if s.getOneFun != nil { 185 v, err := s.getOneFun(modules.Account, address[:]) 186 if err != nil { 187 return nil, err 188 } 189 if v == nil { 190 return nil, nil 191 } 192 var acc account.StateAccount 193 if err := acc.DecodeForStorage(v); err != nil { 194 return nil, err 195 } 196 return &acc, nil 197 } 198 return nil, nil 199 } 200 if s.Items[index] == nil { 201 return nil, nil 202 } 203 var acc account.StateAccount 204 if err := acc.DecodeForStorage(s.Items[index].Value); err != nil { 205 return nil, err 206 } 207 return &acc, nil 208 } 209 210 func (s *Snapshot) AddAccount(address types.Address, account *account.StateAccount) { 211 if !s.written || account == nil { 212 return 213 } 214 value := make([]byte, account.EncodingLengthForStorage()) 215 account.EncodeForStorage(value) 216 s.Items = append(s.Items, &Item{Key: address[:], Value: value}) 217 ss := address[:] 218 //fmt.Println("address", address.Hex()) 219 s.accounts[*(*string)(unsafe.Pointer(&ss))] = len(s.Items) 220 } 221 222 func (s *Snapshot) AddStorage(address types.Address, key *types.Hash, incarnation uint16, value []byte) { 223 if !s.written || len(value) == 0 { 224 return 225 } 226 compositeKey := modules.PlainGenerateCompositeStorageKey(address.Bytes(), incarnation, key.Bytes()) 227 s.Items = append(s.Items, &Item{Key: compositeKey, Value: value}) 228 //fmt.Println("address", address.Hex(), key.Hex()) 229 s.storage[*(*string)(unsafe.Pointer(&compositeKey))] = len(s.storage) 230 } 231 232 func EncodeBeforeState(w io.Writer, list Items, codeHash HashCodes) { 233 enc := make([]interface{}, 0, len(list)*2+len(codeHash)*2) 234 for _, i := range list { 235 enc = append(enc, i.Key, i.Value) 236 } 237 238 for _, h := range codeHash { 239 enc = append(enc, h.Hash, h.Code) 240 } 241 if err := rlp.Encode(w, enc); nil != err { 242 panic("before state encode failed:" + err.Error()) 243 } 244 }