Skip to content
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

- (ante) [#164](https://github.com/EscanBE/evermint/pull/164) Introduce Dual-Lane AnteHandler
- (ante) [#165](https://github.com/EscanBE/evermint/pull/165) Simulate EVM txs before accept mempool
- (evm) [#167](https://github.com/EscanBE/evermint/pull/167) Introduce Context-based StateDB

### Improvement

Expand Down
49 changes: 18 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ parent:
</a>
</div>

Requires [Go 1.22+](https://golang.org/dl/)

### Create your own fully customized EVM-enabled blockchain network in just 2 steps

[> Quick rename](https://github.com/EscanBE/evermint/blob/main/RENAME_CHAIN.md)
Expand All @@ -24,38 +26,16 @@ parent:

### About Evermint

Evermint is a fork of open source Evmos v12.1.6, maintained by Escan team with bug fixes, customization and enable developers to fork and transform to their chain, fully customized, in just 2 steps.

_Important Note: Evermint was born for development and research purpose so maintainers do not support migration for new upgrade/breaking changes._

### About Evmos

Evmos is a scalable, high-throughput Proof-of-Stake blockchain
that is fully compatible and interoperable with Ethereum.
It's built using the [Cosmos SDK](https://github.com/cosmos/cosmos-sdk/)
which runs on top of the [CometBFT](https://github.com/cometbft/cometbft) consensus engine.

### Different of Evermint & Evmos

- Evermint is for research and development purpose.
- Evermint is fork of open source Evmos v12.1.6 plus bug fixes.
- Evermint is [currently removing some modules](https://github.com/EscanBE/evermint/issues/41) from Evmos codebase and only keep `x/evm`, `x/erc20`, `x/feemarket`. The goal is to make it more simple for research and only focus on the skeleton of Evmos.
- After [upgraded to Cosmos-SDK v0.50](https://github.com/EscanBE/evermint/pull/148), Evermint is now has many breaking change to the Legacy Evmos v12.1.6. If you want to use the open-source libraries previously developed for Evmos v12.1.6, you might need to use [Evermint version which uses Cosmos-SDK v0.47 and below](https://github.com/EscanBE/evermint/tree/v12.3.0-cosmos47).
Evermint originally a fork of open source Evmos v12.1.6 plus lots of magic.

## Documentation
Many important pieces of code was replaced by Evermint, such as:
- Replaced legacy AnteHandler with [Dual-Lane AnteHandler](https://github.com/EscanBE/evermint/pull/164).
- Replaced legacy StateDB with [Context-based StateDB](https://github.com/EscanBE/evermint/pull/167).
- Used go-ethereum code for [state-transition](https://github.com/EscanBE/evermint/pull/156).
- Some project structure was replaced during upgrade to Cosmos-SDK v0.50, CometBFT v0.38, ibc-go v8.5.
- Data structure, code logic of `MsgEthereumTx` and some proto msgs were replaced.

Evermint does not maintain its own documentation site, user can refer to Evmos documentation hosted at [evmos/docs](https://github.com/evmos/docs) and can be found at [docs.evmos.org](https://docs.evmos.org).
Head over there and check it out.

**Note**: Requires [Go 1.22+](https://golang.org/dl/)

## Quick Start

To learn how the Evmos works from a high-level perspective,
go to the [Protocol Overview](https://docs.evmos.org/protocol) section from the documentation.
You can also check the instructions to [Run a Node](https://docs.evmos.org/protocol/evmos-cli#run-an-evmos-node).

### Additional feature provided by Evermint:
#### Some other features provided by Evermint:
1. Command convert between 0x address and bech32 address, or any custom bech32 HRP
```bash
evmd convert-address evm1sv9m0g7ycejwr3s369km58h5qe7xj77hxrsmsz evmos
Expand All @@ -66,4 +46,11 @@ evmd convert-address evm1sv9m0g7ycejwr3s369km58h5qe7xj77hxrsmsz evmos
4. [`snapshots` command](https://github.com/EscanBE/evermint/pull/12)
5. [`inspect` command](https://github.com/EscanBE/evermint/pull/14)
6. [Flag `--allow-insecure-unlock`](https://github.com/EscanBE/evermint/pull/142)
7. Dependencies updated: `Cosmos-SDK v0.50.9`, `CometBFT v0.38.12`, `ibc-go v8.5.0`, `go-ethereum v1.10.26`

### About Evmos
_v12.1.6_

Evmos is a scalable, high-throughput Proof-of-Stake blockchain
that is fully compatible and interoperable with Ethereum.
It's built using the [Cosmos SDK](https://github.com/cosmos/cosmos-sdk/)
which runs on top of the [Tendermint](https://github.com/tendermint/tendermint) consensus engine.
4 changes: 2 additions & 2 deletions app/antedl/ante.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ func NewAnteHandler(options HandlerOptions) sdk.AnteHandler {

// EVM-only lane
evmlane.NewEvmLaneSetupExecutionDecorator(*options.EvmKeeper),
evmlane.NewEvmLaneEmitEventDecorator(*options.EvmKeeper), // must be the last effective Ante
evmlane.NewEvmLaneExecWithoutErrorDecorator(*options.AccountKeeper, *options.EvmKeeper), // simulation ante
evmlane.NewEvmLaneEmitEventDecorator(*options.EvmKeeper), // must be the last effective Ante
evmlane.NewEvmLaneExecWithoutErrorDecorator(*options.AccountKeeper, options.BankKeeper, *options.EvmKeeper), // simulation ante

// Cosmos-only lane
cosmoslane.NewCosmosLaneRejectEthereumMsgsDecorator(),
Expand Down
18 changes: 10 additions & 8 deletions app/antedl/evmlane/993e_exec_without_error.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,37 @@ package evmlane
import (
"errors"

evmvm "github.com/EscanBE/evermint/v12/x/evm/vm"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"

errorsmod "cosmossdk.io/errors"

dlanteutils "github.com/EscanBE/evermint/v12/app/antedl/utils"
evmkeeper "github.com/EscanBE/evermint/v12/x/evm/keeper"
"github.com/EscanBE/evermint/v12/x/evm/statedb"
evmtypes "github.com/EscanBE/evermint/v12/x/evm/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
corevm "github.com/ethereum/go-ethereum/core/vm"
)

type ELExecWithoutErrorDecorator struct {
ak authkeeper.AccountKeeper
bk bankkeeper.Keeper
ek evmkeeper.Keeper
}

// NewEvmLaneExecWithoutErrorDecorator creates a new ELExecWithoutErrorDecorator.
// This decorator only executes in (re)check-tx and simulation mode.
// - If the input transaction is a Cosmos transaction, it calls next ante handler.
// - If the input transaction is an Ethereum transaction, it runs simulate the state transition to ensure tx can be executed.
func NewEvmLaneExecWithoutErrorDecorator(ak authkeeper.AccountKeeper, ek evmkeeper.Keeper) ELExecWithoutErrorDecorator {
func NewEvmLaneExecWithoutErrorDecorator(ak authkeeper.AccountKeeper, bk bankkeeper.Keeper, ek evmkeeper.Keeper) ELExecWithoutErrorDecorator {
return ELExecWithoutErrorDecorator{
ak: ak,
bk: bk,
ek: ek,
}
}
Expand Down Expand Up @@ -72,13 +76,11 @@ func (ed ELExecWithoutErrorDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, sim
ed.ek.SetFlagSenderNonceIncreasedByAnteHandle(simulationCtx, false)
}

var evm *vm.EVM
var evm *corevm.EVM
{ // initialize EVM
txConfig := statedb.NewEmptyTxConfig(common.BytesToHash(simulationCtx.HeaderHash()))
txConfig = txConfig.WithTxTypeFromMessage(ethCoreMsg)
stateDB := statedb.New(simulationCtx, &ed.ek, txConfig)
stateDB := evmvm.NewStateDB(simulationCtx, &ed.ek, ed.ak, ed.bk)
evmParams := ed.ek.GetParams(simulationCtx)
evmCfg := &statedb.EVMConfig{
evmCfg := &evmvm.EVMConfig{
Params: evmParams,
ChainConfig: evmParams.ChainConfig.EthereumConfig(ed.ek.ChainID()),
CoinBase: common.Address{},
Expand Down
4 changes: 3 additions & 1 deletion app/antedl/evmlane/993e_exec_without_error_it_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,9 @@ func (s *ELTestSuite) Test_ELExecWithoutErrorDecorator() {
cachedCtx, _ := s.Ctx().CacheContext()

tt.decoratorSpec.WithDecorator(
evmlane.NewEvmLaneExecWithoutErrorDecorator(*s.App().AccountKeeper(), *s.App().EvmKeeper()),
evmlane.NewEvmLaneExecWithoutErrorDecorator(
*s.App().AccountKeeper(), s.App().BankKeeper(), *s.App().EvmKeeper(),
),
)

if tt.reCheckTx {
Expand Down
2 changes: 1 addition & 1 deletion app/modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ var maccPerms = map[string][]string{
minttypes.ModuleName: {authtypes.Minter},
ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner},
icatypes.ModuleName: nil,
evmtypes.ModuleName: {authtypes.Minter, authtypes.Burner}, // used for secure addition and subtraction of balance using module account
evmtypes.ModuleName: {authtypes.Minter, authtypes.Burner}, // used for secure addition and subtraction of balance
erc20types.ModuleName: {authtypes.Minter, authtypes.Burner},
vauthtypes.ModuleName: {authtypes.Burner},
}
Expand Down
4 changes: 2 additions & 2 deletions rpc/backend/call_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
corevm "github.com/ethereum/go-ethereum/core/vm"
"github.com/pkg/errors"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
Expand Down Expand Up @@ -381,7 +381,7 @@ func (b *Backend) DoCall(
}

if res.Failed() {
if res.VmError != vm.ErrExecutionReverted.Error() {
if res.VmError != corevm.ErrExecutionReverted.Error() {
return nil, status.Error(codes.Internal, res.VmError)
}
return nil, evmtypes.NewExecErrorWithReason(res.Ret)
Expand Down
6 changes: 6 additions & 0 deletions testutil/tx/signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ func GenerateAddress() common.Address {
return addr
}

// GenerateHash generates an Ethereum hash.
func GenerateHash() common.Hash {
_, pk := NewAddrKey()
return common.BytesToHash(pk.Bytes())
}

var _ keyring.Signer = &Signer{}

// Signer defines a type that is used on testing for signing MsgEthereumTx
Expand Down
37 changes: 37 additions & 0 deletions types/noop_event_manager.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package types

import (
abci "github.com/cometbft/cometbft/abci/types"
sdk "github.com/cosmos/cosmos-sdk/types"
gogoproto "github.com/cosmos/gogoproto/proto"
)

var _ sdk.EventManagerI = &noOpEventManager{}

type noOpEventManager struct{}

func NewNoOpEventManager() sdk.EventManagerI {
return &noOpEventManager{}
}

func (n noOpEventManager) Events() sdk.Events {
return []sdk.Event{}
}

func (n noOpEventManager) ABCIEvents() []abci.Event {
return []abci.Event{}
}

func (n noOpEventManager) EmitTypedEvent(_ gogoproto.Message) error {
return nil
}

func (n noOpEventManager) EmitTypedEvents(_ ...gogoproto.Message) error {
return nil
}

func (n noOpEventManager) EmitEvent(_ sdk.Event) {
}

func (n noOpEventManager) EmitEvents(_ sdk.Events) {
}
12 changes: 4 additions & 8 deletions x/erc20/keeper/mock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@ import (
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"

erc20types "github.com/EscanBE/evermint/v12/x/erc20/types"
"github.com/EscanBE/evermint/v12/x/evm/statedb"
evmtypes "github.com/EscanBE/evermint/v12/x/evm/types"
sdk "github.com/cosmos/cosmos-sdk/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/vm"
corevm "github.com/ethereum/go-ethereum/core/vm"
"github.com/stretchr/testify/mock"
)

Expand All @@ -29,12 +28,9 @@ func (m *MockEVMKeeper) GetParams(_ sdk.Context) evmtypes.Params {
return args.Get(0).(evmtypes.Params)
}

func (m *MockEVMKeeper) GetAccountWithoutBalance(_ sdk.Context, _ common.Address) *statedb.Account {
func (m *MockEVMKeeper) IsEmptyAccount(_ sdk.Context, _ common.Address) bool {
args := m.Called(mock.Anything, mock.Anything)
if args.Get(0) == nil {
return nil
}
return args.Get(0).(*statedb.Account)
return args.Get(0).(bool)
}

func (m *MockEVMKeeper) EstimateGas(_ context.Context, _ *evmtypes.EthCallRequest) (*evmtypes.EstimateGasResponse, error) {
Expand All @@ -45,7 +41,7 @@ func (m *MockEVMKeeper) EstimateGas(_ context.Context, _ *evmtypes.EthCallReques
return args.Get(0).(*evmtypes.EstimateGasResponse), args.Error(1)
}

func (m *MockEVMKeeper) ApplyMessage(_ sdk.Context, _ core.Message, _ vm.EVMLogger, _ bool) (*evmtypes.MsgEthereumTxResponse, error) {
func (m *MockEVMKeeper) ApplyMessage(_ sdk.Context, _ core.Message, _ corevm.EVMLogger, _ bool) (*evmtypes.MsgEthereumTxResponse, error) {
args := m.Called(mock.Anything, mock.Anything, mock.Anything, mock.Anything)

if args.Get(0) == nil {
Expand Down
8 changes: 2 additions & 6 deletions x/erc20/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@ func (k Keeper) ConvertCoin(

// Remove token pair if contract is suicided
erc20 := common.HexToAddress(pair.Erc20Address)
acc := k.evmKeeper.GetAccountWithoutBalance(ctx, erc20)

if acc == nil || !acc.IsContract() {
if k.evmKeeper.IsEmptyAccount(ctx, erc20) {
k.DeleteTokenPair(ctx, pair)
k.Logger(ctx).Debug(
"deleting selfdestructed token pair from state",
Expand Down Expand Up @@ -79,9 +77,7 @@ func (k Keeper) ConvertERC20(

// Remove token pair if contract is suicided
erc20 := common.HexToAddress(pair.Erc20Address)
acc := k.evmKeeper.GetAccountWithoutBalance(ctx, erc20)

if acc == nil || !acc.IsContract() {
if k.evmKeeper.IsEmptyAccount(ctx, erc20) {
k.DeleteTokenPair(ctx, pair)
k.Logger(ctx).Debug(
"deleting selfdestructed token pair from state",
Expand Down
Loading