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

     1  package types
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  
     8  	ethcmn "github.com/ethereum/go-ethereum/common"
     9  	sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors"
    10  )
    11  
    12  // Storage represents the account Storage map as a slice of single key value
    13  // State pairs. This is to prevent non determinism at genesis initialization or export.
    14  type Storage []State
    15  
    16  // Validate performs a basic validation of the Storage fields.
    17  func (s Storage) Validate() error {
    18  	seenStorage := make(map[string]bool)
    19  	for i, state := range s {
    20  		if seenStorage[state.Key.String()] {
    21  			return sdkerrors.Wrapf(ErrInvalidState, "duplicate state key %d", i)
    22  		}
    23  
    24  		if err := state.Validate(); err != nil {
    25  			return err
    26  		}
    27  
    28  		seenStorage[state.Key.String()] = true
    29  	}
    30  	return nil
    31  }
    32  
    33  // String implements the stringer interface
    34  func (s Storage) String() string {
    35  	var str string
    36  	for _, state := range s {
    37  		str += fmt.Sprintf("%s: %s\n", state.Key.String(), state.Value.String())
    38  	}
    39  
    40  	return str
    41  }
    42  
    43  // Copy returns a copy of storage.
    44  func (s Storage) Copy() Storage {
    45  	cpy := make(Storage, len(s))
    46  	copy(cpy, s)
    47  
    48  	return cpy
    49  }
    50  
    51  // State represents a single Storage key value pair item.
    52  type State struct {
    53  	Key   ethcmn.Hash `json:"key"`
    54  	Value ethcmn.Hash `json:"value"`
    55  }
    56  
    57  // Validate performs a basic validation of the State fields.
    58  func (s State) Validate() error {
    59  	if bytes.Equal(s.Key.Bytes(), ethcmn.Hash{}.Bytes()) {
    60  		return sdkerrors.Wrap(ErrInvalidState, "state key hash cannot be empty")
    61  	}
    62  	// NOTE: state value can be empty
    63  	return nil
    64  }
    65  
    66  // NewState creates a new State instance
    67  func NewState(key, value ethcmn.Hash) State {
    68  	return State{
    69  		Key:   key,
    70  		Value: value,
    71  	}
    72  }
    73  
    74  func (s State) MarshalJSON() ([]byte, error) {
    75  	formatState := &struct {
    76  		Key   string `json:"key"`
    77  		Value string `json:"value"`
    78  	}{
    79  		Key:   s.Key.Hex(),
    80  		Value: s.Value.Hex(),
    81  	}
    82  
    83  	return json.Marshal(formatState)
    84  }
    85  
    86  func (s *State) UnmarshalJSON(input []byte) error {
    87  	formatState := &struct {
    88  		Key   string `json:"key"`
    89  		Value string `json:"value"`
    90  	}{}
    91  	if err := json.Unmarshal(input, &formatState); err != nil {
    92  		return err
    93  	}
    94  
    95  	s.Key = ethcmn.HexToHash(formatState.Key)
    96  	s.Value = ethcmn.HexToHash(formatState.Value)
    97  	return nil
    98  }