github.com/cryptotooltop/go-ethereum@v0.0.0-20231103184714-151d1922f3e5/core/state/snapshot/account.go (about) 1 // Copyright 2019 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 snapshot 18 19 import ( 20 "bytes" 21 "math/big" 22 23 "github.com/scroll-tech/go-ethereum/common" 24 "github.com/scroll-tech/go-ethereum/rlp" 25 ) 26 27 // Account is a modified version of a state.Account, where the root is replaced 28 // with a byte slice. This format can be used to represent full-consensus format 29 // or slim-snapshot format which replaces the empty root and code hash as nil 30 // byte slice. 31 type Account struct { 32 Nonce uint64 33 Balance *big.Int 34 Root []byte 35 KeccakCodeHash []byte 36 PoseidonCodeHash []byte 37 CodeSize uint64 38 } 39 40 // SlimAccount converts a state.Account content into a slim snapshot account 41 func SlimAccount(nonce uint64, balance *big.Int, root common.Hash, keccakcodehash []byte, poseidoncodehash []byte, codesize uint64) Account { 42 slim := Account{ 43 Nonce: nonce, 44 Balance: balance, 45 } 46 if root != emptyRoot { 47 slim.Root = root[:] 48 } 49 if !bytes.Equal(keccakcodehash, emptyKeccakCode[:]) { 50 slim.KeccakCodeHash = keccakcodehash 51 slim.PoseidonCodeHash = poseidoncodehash 52 slim.CodeSize = codesize 53 } 54 return slim 55 } 56 57 // SlimAccountRLP converts a state.Account content into a slim snapshot 58 // version RLP encoded. 59 func SlimAccountRLP(nonce uint64, balance *big.Int, root common.Hash, keccakcodehash []byte, poseidoncodehash []byte, codesize uint64) []byte { 60 data, err := rlp.EncodeToBytes(SlimAccount(nonce, balance, root, keccakcodehash, poseidoncodehash, codesize)) 61 if err != nil { 62 panic(err) 63 } 64 return data 65 } 66 67 // FullAccount decodes the data on the 'slim RLP' format and return 68 // the consensus format account. 69 func FullAccount(data []byte) (Account, error) { 70 var account Account 71 if err := rlp.DecodeBytes(data, &account); err != nil { 72 return Account{}, err 73 } 74 if len(account.Root) == 0 { 75 account.Root = emptyRoot[:] 76 } 77 if len(account.KeccakCodeHash) == 0 { 78 account.KeccakCodeHash = emptyKeccakCode[:] 79 account.PoseidonCodeHash = emptyPoseidonCode[:] 80 account.CodeSize = 0 81 } 82 return account, nil 83 } 84 85 // FullAccountRLP converts data on the 'slim RLP' format into the full RLP-format. 86 func FullAccountRLP(data []byte) ([]byte, error) { 87 account, err := FullAccount(data) 88 if err != nil { 89 return nil, err 90 } 91 return rlp.EncodeToBytes(account) 92 }