github.com/MetalBlockchain/subnet-evm@v0.4.9/core/state/snapshot/account.go (about)

     1  // (c) 2019-2020, Ava Labs, Inc.
     2  //
     3  // This file is a derived work, based on the go-ethereum library whose original
     4  // notices appear below.
     5  //
     6  // It is distributed under a license compatible with the licensing terms of the
     7  // original code from which it is derived.
     8  //
     9  // Much love to the original authors for their work.
    10  // **********
    11  // Copyright 2019 The go-ethereum Authors
    12  // This file is part of the go-ethereum library.
    13  //
    14  // The go-ethereum library is free software: you can redistribute it and/or modify
    15  // it under the terms of the GNU Lesser General Public License as published by
    16  // the Free Software Foundation, either version 3 of the License, or
    17  // (at your option) any later version.
    18  //
    19  // The go-ethereum library is distributed in the hope that it will be useful,
    20  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    21  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    22  // GNU Lesser General Public License for more details.
    23  //
    24  // You should have received a copy of the GNU Lesser General Public License
    25  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    26  
    27  package snapshot
    28  
    29  import (
    30  	"bytes"
    31  	"math/big"
    32  
    33  	"github.com/ethereum/go-ethereum/common"
    34  	"github.com/ethereum/go-ethereum/rlp"
    35  )
    36  
    37  // Account is a modified version of a state.Account, where the root is replaced
    38  // with a byte slice. This format can be used to represent full-consensus format
    39  // or slim-snapshot format which replaces the empty root and code hash as nil
    40  // byte slice.
    41  type Account struct {
    42  	Nonce    uint64
    43  	Balance  *big.Int
    44  	Root     []byte
    45  	CodeHash []byte
    46  }
    47  
    48  // SlimAccount converts a state.Account content into a slim snapshot account
    49  func SlimAccount(nonce uint64, balance *big.Int, root common.Hash, codehash []byte) Account {
    50  	slim := Account{
    51  		Nonce:   nonce,
    52  		Balance: balance,
    53  	}
    54  	if root != emptyRoot {
    55  		slim.Root = root[:]
    56  	}
    57  	if !bytes.Equal(codehash, emptyCode[:]) {
    58  		slim.CodeHash = codehash
    59  	}
    60  	return slim
    61  }
    62  
    63  // SlimAccountRLP converts a state.Account content into a slim snapshot
    64  // version RLP encoded.
    65  func SlimAccountRLP(nonce uint64, balance *big.Int, root common.Hash, codehash []byte) []byte {
    66  	data, err := rlp.EncodeToBytes(SlimAccount(nonce, balance, root, codehash))
    67  	if err != nil {
    68  		panic(err)
    69  	}
    70  	return data
    71  }
    72  
    73  // FullAccount decodes the data on the 'slim RLP' format and return
    74  // the consensus format account.
    75  func FullAccount(data []byte) (Account, error) {
    76  	var account Account
    77  	if err := rlp.DecodeBytes(data, &account); err != nil {
    78  		return Account{}, err
    79  	}
    80  	if len(account.Root) == 0 {
    81  		account.Root = emptyRoot[:]
    82  	}
    83  	if len(account.CodeHash) == 0 {
    84  		account.CodeHash = emptyCode[:]
    85  	}
    86  	return account, nil
    87  }
    88  
    89  // FullAccountRLP converts data on the 'slim RLP' format into the full RLP-format.
    90  func FullAccountRLP(data []byte) ([]byte, error) {
    91  	account, err := FullAccount(data)
    92  	if err != nil {
    93  		return nil, err
    94  	}
    95  	return rlp.EncodeToBytes(account)
    96  }