Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge export genesis #455

Merged
merged 4 commits into from
Nov 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ require (
github.com/btcsuite/btcd v0.21.0-beta
github.com/btcsuite/btcutil v1.0.2
github.com/cespare/cp v1.1.1 // indirect
github.com/cosmos/cosmos-sdk v0.39.1
github.com/cosmos/cosmos-sdk v0.39.2
github.com/deckarep/golang-set v1.7.1 // indirect
github.com/ethereum/go-ethereum v1.9.24
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect
Expand Down
58 changes: 46 additions & 12 deletions x/evm/genesis.go
Original file line number Diff line number Diff line change
@@ -1,29 +1,61 @@
package evm

import (
"fmt"

sdk "github.com/cosmos/cosmos-sdk/types"

emint "github.com/okex/okexchain/app/types"
ethcmn "github.com/ethereum/go-ethereum/common"

ethermint "github.com/okex/okexchain/app/types"
"github.com/okex/okexchain/x/evm/types"

abci "github.com/tendermint/tendermint/abci/types"
)

// InitGenesis initializes genesis state based on exported genesis
func InitGenesis(ctx sdk.Context, k Keeper, data GenesisState) []abci.ValidatorUpdate {
func InitGenesis(ctx sdk.Context, k Keeper, accountKeeper types.AccountKeeper, data GenesisState) []abci.ValidatorUpdate { // nolint: interfacer
evmDenom := data.Params.EvmDenom

for _, account := range data.Accounts {
// FIXME: this will override bank InitGenesis balance!
k.SetBalance(ctx, account.Address, account.Balance)
k.SetCode(ctx, account.Address, account.Code)
address := ethcmn.HexToAddress(account.Address)
accAddress := sdk.AccAddress(address.Bytes())

// check that the EVM balance the matches the account balance
acc := accountKeeper.GetAccount(ctx, accAddress)
if acc == nil {
panic(fmt.Errorf("account not found for address %s", account.Address))
}

_, ok := acc.(*ethermint.EthAccount)
if !ok {
panic(
fmt.Errorf("account %s must be an %T type, got %T",
account.Address, &ethermint.EthAccount{}, acc,
),
)
}

evmBalance := acc.GetCoins().AmountOf(evmDenom)
if !evmBalance.Equal(account.Balance) {
panic(
fmt.Errorf(
"balance mismatch for account %s, expected %s%s, got %s%s",
account.Address, evmBalance, evmDenom, account.Balance, evmDenom,
),
)
}

k.SetBalance(ctx, address, account.Balance.BigInt())
k.SetCode(ctx, address, account.Code)
for _, storage := range account.Storage {
k.SetState(ctx, account.Address, storage.Key, storage.Value)
k.SetState(ctx, address, storage.Key, storage.Value)
}
}

var err error
for _, txLog := range data.TxsLogs {
err = k.SetLogs(ctx, txLog.Hash, txLog.Logs)
if err != nil {
if err = k.SetLogs(ctx, txLog.Hash, txLog.Logs); err != nil {
panic(err)
}
}
Expand Down Expand Up @@ -54,8 +86,7 @@ func ExportGenesis(ctx sdk.Context, k Keeper, ak types.AccountKeeper) GenesisSta
accounts := ak.GetAllAccounts(ctx)

for _, account := range accounts {

ethAccount, ok := account.(*emint.EthAccount)
ethAccount, ok := account.(*ethermint.EthAccount)
if !ok {
continue
}
Expand All @@ -67,9 +98,12 @@ func ExportGenesis(ctx sdk.Context, k Keeper, ak types.AccountKeeper) GenesisSta
panic(err)
}

balanceInt := k.GetBalance(ctx, addr)
balance := sdk.NewDecFromBigIntWithPrec(balanceInt, sdk.Precision)

genAccount := types.GenesisAccount{
Address: addr,
Balance: k.GetBalance(ctx, addr),
Address: addr.String(),
Balance: balance,
Code: k.GetCode(ctx, addr),
Storage: storage,
}
Expand Down
151 changes: 112 additions & 39 deletions x/evm/genesis_test.go

Large diffs are not rendered by default.

10 changes: 7 additions & 3 deletions x/evm/keeper/querier.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ func queryAccount(ctx sdk.Context, path []string, keeper Keeper) ([]byte, error)
}

func queryExportAccount(ctx sdk.Context, path []string, keeper Keeper) ([]byte, error) {
addr := ethcmn.HexToAddress(path[1])
hexAddress := path[1]
addr := ethcmn.HexToAddress(hexAddress)

var storage types.Storage
err := keeper.ForEachStorage(ctx, addr, func(key, value ethcmn.Hash) bool {
Expand All @@ -211,9 +212,12 @@ func queryExportAccount(ctx sdk.Context, path []string, keeper Keeper) ([]byte,
return nil, err
}

balanceInt := keeper.GetBalance(ctx, addr)
balance := sdk.NewDecFromBigIntWithPrec(balanceInt, sdk.Precision)

res := types.GenesisAccount{
Address: addr,
Balance: keeper.GetBalance(ctx, addr),
Address: hexAddress,
Balance: balance,
Code: keeper.GetCode(ctx, addr),
Storage: storage,
}
Expand Down
2 changes: 1 addition & 1 deletion x/evm/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.V
func (am AppModule) InitGenesis(ctx sdk.Context, data json.RawMessage) []abci.ValidatorUpdate {
var genesisState types.GenesisState
types.ModuleCdc.MustUnmarshalJSON(data, &genesisState)
return InitGenesis(ctx, am.keeper, genesisState)
return InitGenesis(ctx, am.keeper, am.ak, genesisState)
}

// ExportGenesis exports the genesis state to be used by daemon
Expand Down
38 changes: 0 additions & 38 deletions x/evm/module_test.go

This file was deleted.

29 changes: 15 additions & 14 deletions x/evm/types/genesis.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package types

import (
"bytes"
"errors"
"fmt"
"math/big"

sdk "github.com/cosmos/cosmos-sdk/types"

ethcmn "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
Expand All @@ -23,22 +23,22 @@ type (
// Its main difference between with Geth's GenesisAccount is that it uses a custom
// storage type and that it doesn't contain the private key field.
GenesisAccount struct {
Address ethcmn.Address `json:"address"`
Balance *big.Int `json:"balance"`
Code hexutil.Bytes `json:"code,omitempty"`
Storage Storage `json:"storage,omitempty"`
Address string `json:"address"`
Balance sdk.Dec `json:"balance"`
Code hexutil.Bytes `json:"code,omitempty"`
Storage Storage `json:"storage,omitempty"`
}
)

// Validate performs a basic validation of a GenesisAccount fields.
func (ga GenesisAccount) Validate() error {
if bytes.Equal(ga.Address.Bytes(), ethcmn.Address{}.Bytes()) {
return fmt.Errorf("address cannot be the zero address %s", ga.Address.String())
if ga.Address == (ethcmn.Address{}.String()) {
return fmt.Errorf("address cannot be the zero address %s", ga.Address)
}
if ga.Balance == nil {
if ga.Balance.IsNil() {
return errors.New("balance cannot be nil")
}
if ga.Balance.Sign() == -1 {
if ga.Balance.IsNegative() {
return errors.New("balance cannot be negative")
}
if ga.Code != nil && len(ga.Code) == 0 {
Expand All @@ -65,14 +65,15 @@ func (gs GenesisState) Validate() error {
seenAccounts := make(map[string]bool)
seenTxs := make(map[string]bool)
for _, acc := range gs.Accounts {
if seenAccounts[acc.Address.String()] {
return fmt.Errorf("duplicated genesis account %s", acc.Address.String())
if seenAccounts[acc.Address] {
return fmt.Errorf("duplicated genesis account %s", acc.Address)
}
if err := acc.Validate(); err != nil {
return fmt.Errorf("invalid genesis account %s: %w", acc.Address.String(), err)
return fmt.Errorf("invalid genesis account %s: %w", acc.Address, err)
}
seenAccounts[acc.Address.String()] = true
seenAccounts[acc.Address] = true
}

for _, tx := range gs.TxsLogs {
if seenTxs[tx.Hash.String()] {
return fmt.Errorf("duplicated logs from transaction %s", tx.Hash.String())
Expand Down
47 changes: 25 additions & 22 deletions x/evm/types/genesis_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package types

import (
"math/big"
"testing"

"github.com/stretchr/testify/require"
Expand All @@ -10,9 +9,13 @@ import (
ethtypes "github.com/ethereum/go-ethereum/core/types"
ethcrypto "github.com/ethereum/go-ethereum/crypto"

sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/okex/okexchain/app/crypto/ethsecp256k1"
)

var address = ethcmn.BytesToAddress([]byte{1, 2, 3, 4, 5})

func TestValidateGenesisAccount(t *testing.T) {
testCases := []struct {
name string
Expand All @@ -22,8 +25,8 @@ func TestValidateGenesisAccount(t *testing.T) {
{
"valid genesis account",
GenesisAccount{
Address: ethcmn.BytesToAddress([]byte{1, 2, 3, 4, 5}),
Balance: big.NewInt(1),
Address: address.String(),
Balance: sdk.NewDec(1),
Code: []byte{1, 2, 3},
Storage: Storage{
NewState(ethcmn.BytesToHash([]byte{1, 2, 3}), ethcmn.BytesToHash([]byte{1, 2, 3})),
Expand All @@ -34,32 +37,32 @@ func TestValidateGenesisAccount(t *testing.T) {
{
"empty account address bytes",
GenesisAccount{
Address: ethcmn.Address{},
Balance: big.NewInt(1),
Address: ethcmn.Address{}.String(),
Balance: sdk.NewDec(1),
},
false,
},
{
"nil account balance",
GenesisAccount{
Address: ethcmn.BytesToAddress([]byte{1, 2, 3, 4, 5}),
Balance: nil,
Address: address.String(),
Balance: sdk.Dec{},
},
false,
},
{
"nil account balance",
GenesisAccount{
Address: ethcmn.BytesToAddress([]byte{1, 2, 3, 4, 5}),
Balance: big.NewInt(-1),
Address: address.String(),
Balance: sdk.NewDec(-1),
},
false,
},
{
"empty code bytes",
GenesisAccount{
Address: ethcmn.BytesToAddress([]byte{1, 2, 3, 4, 5}),
Balance: big.NewInt(1),
Address: address.String(),
Balance: sdk.NewDec(1),
Code: []byte{},
},
false,
Expand Down Expand Up @@ -97,8 +100,8 @@ func TestValidateGenesis(t *testing.T) {
genState: GenesisState{
Accounts: []GenesisAccount{
{
Address: ethcmn.BytesToAddress([]byte{1, 2, 3, 4, 5}),
Balance: big.NewInt(1),
Address: address.String(),
Balance: sdk.NewDec(1),
Code: []byte{1, 2, 3},
Storage: Storage{
{Key: ethcmn.BytesToHash([]byte{1, 2, 3})},
Expand Down Expand Up @@ -138,7 +141,7 @@ func TestValidateGenesis(t *testing.T) {
genState: GenesisState{
Accounts: []GenesisAccount{
{
Address: ethcmn.Address{},
Address: ethcmn.Address{}.String(),
},
},
},
Expand All @@ -149,16 +152,16 @@ func TestValidateGenesis(t *testing.T) {
genState: GenesisState{
Accounts: []GenesisAccount{
{
Address: ethcmn.BytesToAddress([]byte{1, 2, 3, 4, 5}),
Balance: big.NewInt(1),
Address: address.String(),
Balance: sdk.NewDec(1),
Code: []byte{1, 2, 3},
Storage: Storage{
NewState(ethcmn.BytesToHash([]byte{1, 2, 3}), ethcmn.BytesToHash([]byte{1, 2, 3})),
},
},
{
Address: ethcmn.BytesToAddress([]byte{1, 2, 3, 4, 5}),
Balance: big.NewInt(1),
Address: address.String(),
Balance: sdk.NewDec(1),
Code: []byte{1, 2, 3},
Storage: Storage{
NewState(ethcmn.BytesToHash([]byte{1, 2, 3}), ethcmn.BytesToHash([]byte{1, 2, 3})),
Expand All @@ -173,8 +176,8 @@ func TestValidateGenesis(t *testing.T) {
genState: GenesisState{
Accounts: []GenesisAccount{
{
Address: ethcmn.BytesToAddress([]byte{1, 2, 3, 4, 5}),
Balance: big.NewInt(1),
Address: address.String(),
Balance: sdk.NewDec(1),
Code: []byte{1, 2, 3},
Storage: Storage{
{Key: ethcmn.BytesToHash([]byte{1, 2, 3})},
Expand Down Expand Up @@ -223,8 +226,8 @@ func TestValidateGenesis(t *testing.T) {
genState: GenesisState{
Accounts: []GenesisAccount{
{
Address: ethcmn.BytesToAddress([]byte{1, 2, 3, 4, 5}),
Balance: big.NewInt(1),
Address: address.String(),
Balance: sdk.NewDec(1),
Code: []byte{1, 2, 3},
Storage: Storage{
{Key: ethcmn.BytesToHash([]byte{1, 2, 3})},
Expand Down