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  }