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

update development #3

Merged
merged 2 commits into from
Jan 7, 2021
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
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ Ref: https://keepachangelog.com/en/1.0.0/

### API Breaking

* (evm) [\#670](https://github.com/cosmos/ethermint/pull/670) Migrate types to the ones defined by the protobuf messages, which are required for the stargate release.

### Bug Fixes

* (evm) [\#674](https://github.com/cosmos/ethermint/issues/674) Reset all cache after account data has been committed in `EndBlock` to make sure every node state consistent

## [v0.4.0] - 2020-12-15

### API Breaking

* (evm) [\#661](https://github.com/cosmos/ethermint/pull/661) `Balance` field has been removed from the evm module's `GenesisState`.

### Features
Expand All @@ -60,7 +70,6 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Bug Fixes

* (evm) [\#674](https://github.com/cosmos/ethermint/issues/674) Reset all cache after account data has been committed in `EndBlock` to make sure every node state consistent
* (evm) [\#661](https://github.com/cosmos/ethermint/pull/661) Set nonce to the EVM account on genesis initialization.
* (rpc) [\#648](https://github.com/cosmos/ethermint/issues/648) Fix block cumulative gas used value.
* (evm) [\#621](https://github.com/cosmos/ethermint/issues/621) EVM `GenesisAccount` fields now share the same format as the auth module `Account`.
Expand Down
2 changes: 1 addition & 1 deletion app/ante/eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ func (egcd EthGasConsumeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula
// Charge sender for gas up to limit
if gasLimit != 0 {
// Cost calculates the fees paid to validators based on gas limit and price
cost := new(big.Int).Mul(msgEthTx.Data.Price, new(big.Int).SetUint64(gasLimit))
cost := new(big.Int).Mul(msgEthTx.Data.Price.BigInt(), new(big.Int).SetUint64(gasLimit))

evmDenom := egcd.evmKeeper.GetParams(ctx).EvmDenom

Expand Down
10 changes: 5 additions & 5 deletions rpc/types/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,15 @@ func NewTransaction(tx *evmtypes.MsgEthereumTx, txHash, blockHash common.Hash, b
rpcTx := &Transaction{
From: from,
Gas: hexutil.Uint64(tx.Data.GasLimit),
GasPrice: (*hexutil.Big)(tx.Data.Price),
GasPrice: (*hexutil.Big)(tx.Data.Price.BigInt()),
Hash: txHash,
Input: hexutil.Bytes(tx.Data.Payload),
Nonce: hexutil.Uint64(tx.Data.AccountNonce),
To: tx.To(),
Value: (*hexutil.Big)(tx.Data.Amount),
V: (*hexutil.Big)(tx.Data.V),
R: (*hexutil.Big)(tx.Data.R),
S: (*hexutil.Big)(tx.Data.S),
Value: (*hexutil.Big)(tx.Data.Amount.BigInt()),
V: (*hexutil.Big)(new(big.Int).SetBytes(tx.Data.V)),
R: (*hexutil.Big)(new(big.Int).SetBytes(tx.Data.R)),
S: (*hexutil.Big)(new(big.Int).SetBytes(tx.Data.S)),
}

if blockHash != (common.Hash{}) {
Expand Down
23 changes: 0 additions & 23 deletions types/types.proto

This file was deleted.

17 changes: 17 additions & 0 deletions types/validation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package types

import (
"bytes"

ethcmn "github.com/ethereum/go-ethereum/common"
)

// IsEmptyHash returns true if the hash corresponds to an empty ethereum hex hash.
func IsEmptyHash(hash string) bool {
return bytes.Equal(ethcmn.HexToHash(hash).Bytes(), ethcmn.Hash{}.Bytes())
}

// IsZeroAddress returns true if the address corresponds to an empty ethereum hex address.
func IsZeroAddress(address string) bool {
return bytes.Equal(ethcmn.HexToAddress(address).Bytes(), ethcmn.Address{}.Bytes())
}
55 changes: 55 additions & 0 deletions types/validation_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package types

import (
"testing"

"github.com/stretchr/testify/require"

ethcmn "github.com/ethereum/go-ethereum/common"
)

func TestIsEmptyHash(t *testing.T) {
testCases := []struct {
name string
hash string
expEmpty bool
}{
{
"empty string", "", true,
},
{
"zero hash", ethcmn.Hash{}.String(), true,
},

{
"non-empty hash", ethcmn.BytesToHash([]byte{1, 2, 3, 4}).String(), false,
},
}

for _, tc := range testCases {
require.Equal(t, tc.expEmpty, IsEmptyHash(tc.hash), tc.name)
}
}

func TestIsZeroAddress(t *testing.T) {
testCases := []struct {
name string
address string
expEmpty bool
}{
{
"empty string", "", true,
},
{
"zero address", ethcmn.Address{}.String(), true,
},

{
"non-empty address", ethcmn.BytesToAddress([]byte{1, 2, 3, 4}).String(), false,
},
}

for _, tc := range testCases {
require.Equal(t, tc.expEmpty, IsZeroAddress(tc.address), tc.name)
}
}
21 changes: 14 additions & 7 deletions x/evm/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,21 @@ import (
ethcmn "github.com/ethereum/go-ethereum/common"

ethermint "github.com/cosmos/ethermint/types"
"github.com/cosmos/ethermint/x/evm/keeper"
"github.com/cosmos/ethermint/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, accountKeeper types.AccountKeeper, data GenesisState) []abci.ValidatorUpdate { // nolint: interfacer
func InitGenesis(
ctx sdk.Context,
k keeper.Keeper,
accountKeeper types.AccountKeeper, // nolint: interfacer
data GenesisState,
) []abci.ValidatorUpdate {

k.SetParams(ctx, data.Params)
evmDenom := data.Params.EvmDenom

for _, account := range data.Accounts {
Expand All @@ -40,22 +48,21 @@ func InitGenesis(ctx sdk.Context, k Keeper, accountKeeper types.AccountKeeper, d

k.SetNonce(ctx, address, acc.GetSequence())
k.SetBalance(ctx, address, evmBalance.BigInt())
k.SetCode(ctx, address, account.Code)
k.SetCode(ctx, address, ethcmn.Hex2Bytes(account.Code))

for _, storage := range account.Storage {
k.SetState(ctx, address, storage.Key, storage.Value)
k.SetState(ctx, address, ethcmn.HexToHash(storage.Key), ethcmn.HexToHash(storage.Value))
}
}

var err error
for _, txLog := range data.TxsLogs {
if err = k.SetLogs(ctx, txLog.Hash, txLog.Logs); err != nil {
if err = k.SetLogs(ctx, ethcmn.HexToHash(txLog.Hash), txLog.Logs); err != nil {
panic(err)
}
}

k.SetChainConfig(ctx, data.ChainConfig)
k.SetParams(ctx, data.Params)

// set state objects and code to store
_, err = k.Commit(ctx, false)
Expand All @@ -74,7 +81,7 @@ func InitGenesis(ctx sdk.Context, k Keeper, accountKeeper types.AccountKeeper, d
}

// ExportGenesis exports genesis state of the EVM module
func ExportGenesis(ctx sdk.Context, k Keeper, ak types.AccountKeeper) GenesisState {
func ExportGenesis(ctx sdk.Context, k keeper.Keeper, ak types.AccountKeeper) GenesisState {
// nolint: prealloc
var ethGenAccounts []types.GenesisAccount
ak.IterateAccounts(ctx, func(account authexported.Account) bool {
Expand All @@ -93,7 +100,7 @@ func ExportGenesis(ctx sdk.Context, k Keeper, ak types.AccountKeeper) GenesisSta

genAccount := types.GenesisAccount{
Address: addr.String(),
Code: k.GetCode(ctx, addr),
Code: ethcmn.Bytes2Hex(k.GetCode(ctx, addr)),
Storage: storage,
}

Expand Down
2 changes: 1 addition & 1 deletion x/evm/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func (suite *EvmTestSuite) TestInitGenesis() {
{
Address: address.String(),
Storage: types.Storage{
{Key: common.BytesToHash([]byte("key")), Value: common.BytesToHash([]byte("value"))},
{Key: common.BytesToHash([]byte("key")).String(), Value: common.BytesToHash([]byte("value")).String()},
},
},
},
Expand Down
87 changes: 5 additions & 82 deletions x/evm/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,93 +29,16 @@ func NewHandler(k Keeper) sdk.Handler {

// handleMsgEthereumTx handles an Ethereum specific tx
func handleMsgEthereumTx(ctx sdk.Context, k Keeper, msg types.MsgEthereumTx) (*sdk.Result, error) {
// parse the chainID from a string to a base-10 integer
chainIDEpoch, err := ethermint.ParseChainID(ctx.ChainID())
if err != nil {
return nil, err
}

// Verify signature and retrieve sender address
sender, err := msg.VerifySig(chainIDEpoch)
// execute state transition
res, err := k.EthereumTx(ctx, msg)
if err != nil {
return nil, err
}

txHash := tmtypes.Tx(ctx.TxBytes()).Hash()
ethHash := common.BytesToHash(txHash)

st := types.StateTransition{
AccountNonce: msg.Data.AccountNonce,
Price: msg.Data.Price,
GasLimit: msg.Data.GasLimit,
Recipient: msg.Data.Recipient,
Amount: msg.Data.Amount,
Payload: msg.Data.Payload,
Csdb: k.CommitStateDB.WithContext(ctx),
ChainID: chainIDEpoch,
TxHash: &ethHash,
Sender: sender,
Simulate: ctx.IsCheckTx(),
}

// since the txCount is used by the stateDB, and a simulated tx is run only on the node it's submitted to,
// then this will cause the txCount/stateDB of the node that ran the simulated tx to be different than the
// other nodes, causing a consensus error
if !st.Simulate {
// Prepare db for logs
blockHash := types.HashFromContext(ctx)
k.CommitStateDB.Prepare(ethHash, blockHash, k.TxCount)
k.TxCount++
}

config, found := k.GetChainConfig(ctx)
if !found {
return nil, types.ErrChainConfigNotFound
}

executionResult, err := st.TransitionDb(ctx, config)
if err != nil {
return nil, err
}
// log state transition result
k.Logger(ctx).Info(res.Log)

if !st.Simulate {
// update block bloom filter
k.Bloom.Or(k.Bloom, executionResult.Bloom)

// update transaction logs in KVStore
err = k.SetLogs(ctx, common.BytesToHash(txHash), executionResult.Logs)
if err != nil {
panic(err)
}
}

// log successful execution
k.Logger(ctx).Info(executionResult.Result.Log)

ctx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(
types.EventTypeEthereumTx,
sdk.NewAttribute(sdk.AttributeKeyAmount, msg.Data.Amount.String()),
),
sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
sdk.NewAttribute(sdk.AttributeKeySender, sender.String()),
),
})

if msg.Data.Recipient != nil {
ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeEthereumTx,
sdk.NewAttribute(types.AttributeKeyRecipient, msg.Data.Recipient.String()),
),
)
}

// set the events to the result
executionResult.Result.Events = ctx.EventManager().Events()
return executionResult.Result, nil
return res, nil
}

// handleMsgEthermint handles an sdk.StdTx for an Ethereum state transition
Expand Down
12 changes: 6 additions & 6 deletions x/evm/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ func (k Keeper) GetAllTxLogs(ctx sdk.Context) []types.TransactionLogs {
// GetAccountStorage return state storage associated with an account
func (k Keeper) GetAccountStorage(ctx sdk.Context, address common.Address) (types.Storage, error) {
storage := types.Storage{}

err := k.ForEachStorage(ctx, address, func(key, value common.Hash) bool {
storage = append(storage, types.NewState(key, value))
return false
Expand All @@ -164,9 +165,9 @@ func (k Keeper) GetAccountStorage(ctx sdk.Context, address common.Address) (type

// GetChainConfig gets block height from block consensus hash
func (k Keeper) GetChainConfig(ctx sdk.Context) (types.ChainConfig, bool) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChainConfig)
// get from an empty key that's already prefixed by KeyPrefixChainConfig
bz := store.Get([]byte{})
store := ctx.KVStore(k.storeKey)

bz := store.Get(types.KeyPrefixChainConfig)
if len(bz) == 0 {
return types.ChainConfig{}, false
}
Expand All @@ -178,8 +179,7 @@ func (k Keeper) GetChainConfig(ctx sdk.Context) (types.ChainConfig, bool) {

// SetChainConfig sets the mapping from block consensus hash to block height
func (k Keeper) SetChainConfig(ctx sdk.Context, config types.ChainConfig) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixChainConfig)
store := ctx.KVStore(k.storeKey)
bz := k.cdc.MustMarshalBinaryBare(config)
// get to an empty key that's already prefixed by KeyPrefixChainConfig
store.Set([]byte{}, bz)
store.Set(types.KeyPrefixChainConfig, bz)
}
4 changes: 2 additions & 2 deletions x/evm/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,10 @@ func (suite *KeeperTestSuite) TestTransactionLogs() {
txLogs := suite.app.EvmKeeper.GetAllTxLogs(suite.ctx)
suite.Require().Equal(2, len(txLogs))

suite.Require().Equal(ethcmn.Hash{}.String(), txLogs[0].Hash.String())
suite.Require().Equal(ethcmn.Hash{}.String(), txLogs[0].Hash)
suite.Require().Equal([]*ethtypes.Log{log2, log3}, txLogs[0].Logs)

suite.Require().Equal(ethHash.String(), txLogs[1].Hash.String())
suite.Require().Equal(ethHash.String(), txLogs[1].Hash)
suite.Require().Equal([]*ethtypes.Log{log}, txLogs[1].Logs)
}

Expand Down
Loading