Skip to content

Commit

Permalink
Initial implementation of IBC Precompile
Browse files Browse the repository at this point in the history
  • Loading branch information
evgeniy-scherbina committed Feb 22, 2024
1 parent 3100ab6 commit bc891ae
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 4 deletions.
2 changes: 1 addition & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ func NewEthermintApp(
app.EvmKeeper = evmkeeper.NewKeeper(
appCodec, keys[evmtypes.StoreKey], tkeys[evmtypes.TransientKey],
authtypes.NewModuleAddress(govtypes.ModuleName),
app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.FeeMarketKeeper,
app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.FeeMarketKeeper, nil,
nil, geth.NewEVM, tracer, evmSs,
)

Expand Down
2 changes: 1 addition & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -901,6 +901,7 @@ github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6So
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
Expand Down Expand Up @@ -978,7 +979,6 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
Expand Down
8 changes: 8 additions & 0 deletions x/evm/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ type Keeper struct {
// fetch EIP1559 base fee and parameters
feeMarketKeeper types.FeeMarketKeeper

ibcTransferKeeper statedb.IBCTransferKeeper

// chain ID number obtained from the context's chain id
eip155ChainID *big.Int

Expand Down Expand Up @@ -91,6 +93,7 @@ func NewKeeper(
bankKeeper types.BankKeeper,
sk types.StakingKeeper,
fmk types.FeeMarketKeeper,
ibcTransferKeeper statedb.IBCTransferKeeper,
customPrecompiles evm.PrecompiledContracts,
evmConstructor evm.Constructor,
tracer string,
Expand Down Expand Up @@ -118,6 +121,7 @@ func NewKeeper(
bankKeeper: bankKeeper,
stakingKeeper: sk,
feeMarketKeeper: fmk,
ibcTransferKeeper: ibcTransferKeeper,
storeKey: storeKey,
transientKey: transientKey,
customPrecompiles: customPrecompiles,
Expand Down Expand Up @@ -400,3 +404,7 @@ func (k Keeper) AddTransientGasUsed(ctx sdk.Context, gasUsed uint64) (uint64, er
k.SetTransientGasUsed(ctx, result)
return result, nil
}

func (k Keeper) IBCTransferKeeper() statedb.IBCTransferKeeper {
return k.ibcTransferKeeper
}
4 changes: 3 additions & 1 deletion x/evm/keeper/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ func (k *Keeper) NewEVM(
tracer vm.EVMLogger,
stateDB vm.StateDB,
) evm.EVM {
goCtx := sdk.WrapSDKContext(ctx)

Check failure on line 55 in x/evm/keeper/state_transition.go

View workflow job for this annotation

GitHub Actions / Run golangci-lint

goCtx declared and not used (typecheck)

blockCtx := vm.BlockContext{

Check failure on line 57 in x/evm/keeper/state_transition.go

View workflow job for this annotation

GitHub Actions / Run golangci-lint

blockCtx declared and not used (typecheck)
CanTransfer: core.CanTransfer,
Transfer: core.Transfer,
Expand All @@ -70,7 +72,7 @@ func (k *Keeper) NewEVM(
tracer = k.Tracer(ctx, msg, cfg.ChainConfig)
}
vmConfig := k.VMConfig(ctx, msg, cfg, tracer)

Check failure on line 74 in x/evm/keeper/state_transition.go

View workflow job for this annotation

GitHub Actions / Run golangci-lint

vmConfig declared and not used (typecheck)
return k.evmConstructor(blockCtx, txCtx, stateDB, cfg.ChainConfig, vmConfig, k.customPrecompiles)
return k.evmConstructor(goCtx, blockCtx, txCtx, stateDB, cfg.ChainConfig, vmConfig, k.customPrecompiles)
}

// GetHashFn implements vm.GetHashFunc for Ethermint. It handles 3 cases:
Expand Down
8 changes: 8 additions & 0 deletions x/evm/statedb/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
package statedb

import (
"context"
"math/big"

sdk "github.com/cosmos/cosmos-sdk/types"
ibctransfertypes "github.com/cosmos/ibc-go/v6/modules/apps/transfer/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"
)
Expand All @@ -33,6 +35,10 @@ type ExtStateDB interface {
AppendJournalEntry(JournalEntry)
}

type IBCTransferKeeper interface {
Transfer(goCtx context.Context, msg *ibctransfertypes.MsgTransfer) (*ibctransfertypes.MsgTransferResponse, error)
}

// Keeper provide underlying storage of StateDB
type Keeper interface {
// Read methods
Expand All @@ -48,4 +54,6 @@ type Keeper interface {
SetCode(ctx sdk.Context, codeHash []byte, code []byte)
SetBalance(ctx sdk.Context, addr common.Address, amount *big.Int) error
DeleteAccount(ctx sdk.Context, addr common.Address) error

IBCTransferKeeper() IBCTransferKeeper
}
53 changes: 53 additions & 0 deletions x/evm/statedb/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,19 @@ package statedb

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

"github.com/cosmos/cosmos-sdk/types"
sdk "github.com/cosmos/cosmos-sdk/types"
ibctransfertypes "github.com/cosmos/ibc-go/v6/modules/apps/transfer/types"
ibcclienttypes "github.com/cosmos/ibc-go/v6/modules/core/02-client/types"
"github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/precompile/contract"
)

var _ vm.StateDB = &StateDB{}
Expand Down Expand Up @@ -71,6 +76,12 @@ func (s *StateDB) Keeper() Keeper {
return s.keeper
}

func (s *StateDB) Context() context.Context {
// s.ctx.CurrentCtx() replaced s.ctx after rebasing
// TODO(yevhenii): is it correct?
return s.ctx.CurrentCtx()
}

// AddLog adds a log, called by evm.
func (s *StateDB) AddLog(log *ethtypes.Log) {
log.TxHash = s.txConfig.TxHash
Expand Down Expand Up @@ -464,3 +475,45 @@ func (s *StateDB) SetError(err error) {

s.sdkError = err
}

func (s *StateDB) IBCTransfer(goCtx context.Context, msg *contract.MsgTransfer) (*contract.MsgTransferResponse, error) {
resp, err := s.keeper.IBCTransferKeeper().Transfer(goCtx, newMsgTransfer(msg))
if err != nil {
return nil, err
}

return newMsgTransferResponse(resp), nil
}

func newMsgTransfer(m *contract.MsgTransfer) *ibctransfertypes.MsgTransfer {
return &ibctransfertypes.MsgTransfer{
SourcePort: m.SourcePort,
SourceChannel: m.SourceChannel,
Token: newCoin(m.Token),
Sender: m.Sender,
Receiver: m.Receiver,
TimeoutHeight: newHeight(m.TimeoutHeight),
TimeoutTimestamp: m.TimeoutTimestamp,
Memo: m.Memo,
}
}

func newCoin(c contract.Coin) types.Coin {
return types.Coin{
Denom: c.Denom,
Amount: c.Amount,
}
}

func newHeight(h contract.Height) ibcclienttypes.Height {
return ibcclienttypes.Height{
RevisionNumber: h.RevisionNumber,
RevisionHeight: h.RevisionHeight,
}
}

func newMsgTransferResponse(r *ibctransfertypes.MsgTransferResponse) *contract.MsgTransferResponse {
return &contract.MsgTransferResponse{
Sequence: r.Sequence,
}
}
4 changes: 3 additions & 1 deletion x/evm/vm/geth/geth.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package geth

import (
"context"
"math/big"

"github.com/ethereum/go-ethereum/common"
Expand All @@ -40,6 +41,7 @@ type EVM struct {
// the default precompiled contracts and the EVM concrete implementation from
// geth.
func NewEVM(
goCtx context.Context,
blockCtx vm.BlockContext,
txCtx vm.TxContext,
stateDB vm.StateDB,
Expand All @@ -48,7 +50,7 @@ func NewEVM(
_ evm.PrecompiledContracts, // unused
) evm.EVM {
return &EVM{
EVM: vm.NewEVM(blockCtx, txCtx, stateDB, chainConfig, config),
EVM: vm.NewEVMWithContext(goCtx, blockCtx, txCtx, stateDB, chainConfig, config),
}
}

Expand Down
2 changes: 2 additions & 0 deletions x/evm/vm/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package vm

import (
"context"
"math/big"

"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -75,6 +76,7 @@ type EVM interface {
// Constructor defines the function used to instantiate the EVM on
// each state transition.
type Constructor func(
goCtx context.Context,
blockCtx vm.BlockContext,
txCtx vm.TxContext,
stateDB vm.StateDB,
Expand Down

0 comments on commit bc891ae

Please sign in to comment.