github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/evm/types/genesis.go (about)

     1  package types
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"fmt"
     7  
     8  	ethcmn "github.com/ethereum/go-ethereum/common"
     9  	"github.com/ethereum/go-ethereum/common/hexutil"
    10  )
    11  
    12  type (
    13  	// GenesisState defines the evm module genesis state
    14  	GenesisState struct {
    15  		Accounts                    []GenesisAccount    `json:"accounts"`
    16  		TxsLogs                     []TransactionLogs   `json:"txs_logs"`
    17  		ContractDeploymentWhitelist AddressList         `json:"contract_deployment_whitelist"`
    18  		ContractBlockedList         AddressList         `json:"contract_blocked_list"`
    19  		ContractMethodBlockedList   BlockedContractList `json:"contract_method_blocked_list,omitempty"`
    20  		ChainConfig                 ChainConfig         `json:"chain_config"`
    21  		Params                      Params              `json:"params"`
    22  	}
    23  
    24  	// GenesisAccount defines an account to be initialized in the genesis state.
    25  	// Its main difference between with Geth's GenesisAccount is that it uses a custom
    26  	// storage type and that it doesn't contain the private key field.
    27  	// NOTE: balance is omitted as it is imported from the auth account balance.
    28  	GenesisAccount struct {
    29  		Address string        `json:"address"`
    30  		Code    hexutil.Bytes `json:"code,omitempty"`
    31  		Storage Storage       `json:"storage,omitempty"`
    32  	}
    33  )
    34  
    35  // Validate performs a basic validation of a GenesisAccount fields.
    36  func (ga GenesisAccount) Validate() error {
    37  	if ga.Address == (ethcmn.Address{}.String()) {
    38  		return fmt.Errorf("address cannot be the zero address %s", ga.Address)
    39  	}
    40  	if len(ga.Code) == 0 {
    41  		return errors.New("code bytes cannot be empty")
    42  	}
    43  
    44  	return ga.Storage.Validate()
    45  }
    46  
    47  func (ga GenesisAccount) MarshalJSON() ([]byte, error) {
    48  	formatState := &struct {
    49  		Address string  `json:"address"`
    50  		Code    string  `json:"code,omitempty"`
    51  		Storage Storage `json:"storage,omitempty"`
    52  	}{
    53  		Address: ga.Address,
    54  		Code:    ga.Code.String(),
    55  		Storage: ga.Storage,
    56  	}
    57  
    58  	if ga.Code == nil {
    59  		formatState.Code = ""
    60  	}
    61  	return json.Marshal(formatState)
    62  }
    63  
    64  func (ga *GenesisAccount) UnmarshalJSON(input []byte) error {
    65  	formatState := &struct {
    66  		Address string  `json:"address"`
    67  		Code    string  `json:"code,omitempty"`
    68  		Storage Storage `json:"storage,omitempty"`
    69  	}{}
    70  	if err := json.Unmarshal(input, &formatState); err != nil {
    71  		return err
    72  	}
    73  
    74  	ga.Address = formatState.Address
    75  	if formatState.Code == "" {
    76  		ga.Code = nil
    77  	} else {
    78  		ga.Code = hexutil.MustDecode(formatState.Code)
    79  	}
    80  	ga.Storage = formatState.Storage
    81  	return nil
    82  }
    83  
    84  // DefaultGenesisState sets default evm genesis state with empty accounts and default params and
    85  // chain config values.
    86  func DefaultGenesisState() GenesisState {
    87  	return GenesisState{
    88  		Accounts:                    []GenesisAccount{},
    89  		TxsLogs:                     []TransactionLogs{},
    90  		ContractDeploymentWhitelist: AddressList{},
    91  		ContractBlockedList:         AddressList{},
    92  		ChainConfig:                 DefaultChainConfig(),
    93  		Params:                      DefaultParams(),
    94  	}
    95  }
    96  
    97  // Validate performs basic genesis state validation returning an error upon any
    98  // failure.
    99  func (gs GenesisState) Validate() error {
   100  	seenAccounts := make(map[string]bool)
   101  	seenTxs := make(map[string]bool)
   102  	for _, acc := range gs.Accounts {
   103  		if seenAccounts[acc.Address] {
   104  			return fmt.Errorf("duplicated genesis account %s", acc.Address)
   105  		}
   106  		if err := acc.Validate(); err != nil {
   107  			return fmt.Errorf("invalid genesis account %s: %w", acc.Address, err)
   108  		}
   109  		seenAccounts[acc.Address] = true
   110  	}
   111  
   112  	for _, tx := range gs.TxsLogs {
   113  		if seenTxs[tx.Hash.String()] {
   114  			return fmt.Errorf("duplicated logs from transaction %s", tx.Hash.String())
   115  		}
   116  
   117  		if err := tx.Validate(); err != nil {
   118  			return fmt.Errorf("invalid logs from transaction %s: %w", tx.Hash.String(), err)
   119  		}
   120  
   121  		seenTxs[tx.Hash.String()] = true
   122  	}
   123  
   124  	if err := gs.ChainConfig.Validate(); err != nil {
   125  		return err
   126  	}
   127  
   128  	return gs.Params.Validate()
   129  }