github.com/dim4egster/coreth@v0.10.2/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  	IsMultiCoin bool
    47  }
    48  
    49  // SlimAccount converts a state.Account content into a slim snapshot account
    50  func SlimAccount(nonce uint64, balance *big.Int, root common.Hash, codehash []byte, isMultiCoin bool) Account {
    51  	slim := Account{
    52  		Nonce:       nonce,
    53  		Balance:     balance,
    54  		IsMultiCoin: isMultiCoin,
    55  	}
    56  	if root != emptyRoot {
    57  		slim.Root = root[:]
    58  	}
    59  	if !bytes.Equal(codehash, emptyCode[:]) {
    60  		slim.CodeHash = codehash
    61  	}
    62  	return slim
    63  }
    64  
    65  // SlimAccountRLP converts a state.Account content into a slim snapshot
    66  // version RLP encoded.
    67  func SlimAccountRLP(nonce uint64, balance *big.Int, root common.Hash, codehash []byte, isMultiCoin bool) []byte {
    68  	data, err := rlp.EncodeToBytes(SlimAccount(nonce, balance, root, codehash, isMultiCoin))
    69  	if err != nil {
    70  		panic(err)
    71  	}
    72  	return data
    73  }
    74  
    75  // FullAccount decodes the data on the 'slim RLP' format and return
    76  // the consensus format account.
    77  func FullAccount(data []byte) (Account, error) {
    78  	var account Account
    79  	if err := rlp.DecodeBytes(data, &account); err != nil {
    80  		return Account{}, err
    81  	}
    82  	if len(account.Root) == 0 {
    83  		account.Root = emptyRoot[:]
    84  	}
    85  	if len(account.CodeHash) == 0 {
    86  		account.CodeHash = emptyCode[:]
    87  	}
    88  	return account, nil
    89  }
    90  
    91  // FullAccountRLP converts data on the 'slim RLP' format into the full RLP-format.
    92  func FullAccountRLP(data []byte) ([]byte, error) {
    93  	account, err := FullAccount(data)
    94  	if err != nil {
    95  		return nil, err
    96  	}
    97  	return rlp.EncodeToBytes(account)
    98  }