Skip to content
This repository was archived by the owner on Dec 12, 2024. It is now read-only.

refactor: RPC server with evmID (ethermint side) #5

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 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
65 changes: 65 additions & 0 deletions server/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@

import (
"context"
"errors"
"fmt"
"io"
"net"
"net/http"
"net/rpc"
"os"
"path/filepath"
"runtime/pprof"
Expand Down Expand Up @@ -69,8 +71,14 @@
"github.com/evmos/ethermint/server/config"
srvflags "github.com/evmos/ethermint/server/flags"
ethermint "github.com/evmos/ethermint/types"
evmKeeper "github.com/evmos/ethermint/x/evm/keeper"
)

type IncoApp interface {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
type IncoApp interface {
// incoApp is a local interface to get the EVM keeper from the Inco chain app,
// without introducing any circular dependencies.
type incoApp interface {

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

// Return evm keeper which is used in ethermint side to get evm keeper access

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Return evm keeper which is used in ethermint side to get evm keeper access
// GetEvmKeeper returns evm keeper which is used in ethermint side to get evm keeper access

Use go-style godocs

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

GetEvmKeeper() *evmKeeper.Keeper
}

// DBOpener is a function to open `application.db`, potentially with customized options.
type DBOpener func(opts types.AppOptions, rootDir string, backend dbm.BackendType) (dbm.DB, error)

Expand Down Expand Up @@ -488,9 +496,66 @@
return err
}

// Start running rpc server for sgx binary access on the evm Keeper statedb
listener, err := startRpcServer(svrCtx, g, app)
if err != nil {
return err
}

defer func() {
// TODO: Graceful stop
listener.Close()
}()

return g.Wait()
}

func startRpcServer(
svrCtx *server.Context,
g *errgroup.Group,
app types.Application,
) (listener net.Listener, err error) {
ethApp := app.(IncoApp)
evmKeeper := ethApp.GetEvmKeeper()
if evmKeeper == nil {
return nil, errors.New("evm keeper is invalid")
}

g.Go(func() error {
listener, err = runRPCServer(svrCtx, evmKeeper)
return err
})

return
}

func runRPCServer(svrCtx *server.Context, keeper *evmKeeper.Keeper) (net.Listener, error) {
defer func() {
if r := recover(); r != nil {
svrCtx.Logger.Error("recovered from panic", "error", r)
}
}()

// Run a persistent RPC server for sgx binary can access to evm keeper statedb
srv := &evmKeeper.EthmRpcServer{Keeper: keeper}
err := rpc.Register(srv)
if err != nil {
return nil, err
}

rpc.HandleHTTP()

// TODO handle port customization
l, err := net.Listen("tcp", ":9093")
if err != nil {
return nil, err
}

go http.Serve(l, nil)

Check failure on line 554 in server/start.go

View workflow job for this annotation

GitHub Actions / Run golangci-lint

Error return value of `http.Serve` is not checked (errcheck)

return l, nil
}

func openDB(_ types.AppOptions, rootDir string, backendType dbm.BackendType) (dbm.DB, error) {
dataDir := filepath.Join(rootDir, "data")
return dbm.NewDB("application", backendType, dataDir)
Expand Down
10 changes: 10 additions & 0 deletions x/evm/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@
// a set of store keys that should cover all the precompile use cases,
// or ideally just pass the application's all stores.
keys map[string]storetypes.StoreKey

// sdkCtxs maps a unique evmID to a sdk.Context. It is used to track
// requests coming from the SGX binary, and handle them using the correct sdk.Context.
// Each evmID is mapped to a unique EVM instance on the TEE side.
sdkCtxs map[uint64]*sdk.Context
}

// NewKeeper generates new evm module keeper
Expand Down Expand Up @@ -118,6 +123,7 @@
tracer: tracer,
customContractFns: customContractFns,
keys: keys,
sdkCtxs: make(map[uint64]*sdk.Context),
}
}

Expand Down Expand Up @@ -391,3 +397,7 @@
k.SetTransientGasUsed(ctx, result)
return result, nil
}

func (k Keeper) getSdkCtx(evmId uint64) *sdk.Context {

Check warning on line 401 in x/evm/keeper/keeper.go

View workflow job for this annotation

GitHub Actions / Run golangci-lint

var-naming: method parameter evmId should be evmID (revive)
return k.sdkCtxs[evmId]
}
59 changes: 47 additions & 12 deletions x/evm/keeper/rpc_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,12 @@
return err
}

func (c *sgxRPCClient) PrepareTx(args PrepareTxArgs, reply *PrepareTxReply) error {
return c.doCall("SgxRpcServer.PrepareTx", args, reply)
func (c *sgxRPCClient) StartEVM(args StartEVMArgs, reply *StartEVMReply) error {
return c.doCall("SgxRpcServer.StartEVM", args, reply)
}

func (c *sgxRPCClient) InitFhevm(args InitFhevmArgs, reply *InitFhevmReply) error {
return c.doCall("SgxRpcServer.InitFhevm", args, reply)
}

func (c *sgxRPCClient) Call(args CallArgs, reply *CallReply) error {
Expand Down Expand Up @@ -85,15 +89,19 @@
return c.doCall("SgxRpcServer.StateDBGetLogs", args, reply)
}

// PrepareTxEVMConfig only contains the fields from EVMConfig that are needed
func (c *sgxRPCClient) StopEVM(args StopEVMArgs, reply *StopEVMReply) error {
return c.doCall("SgxRpcServer.StopEVM", args, reply)
}

// StartEVMTxEVMConfig only contains the fields from EVMConfig that are needed
// to create a new EVM instance. This is used to pass the EVM configuration
// over RPC to the SGX binary.
type PrepareTxEVMConfig struct {
type StartEVMTxEVMConfig struct {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
type StartEVMTxEVMConfig struct {
type StartEVMConfig struct {

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

// ChainConfig is the EVM chain configuration in JSON format. Since the
// underlying params.ChainConfig struct contains pointer fields, they are
// not serializable over RPC with gob. Instead, the JSON representation is
// used.
ChainConfigJson []byte

Check warning on line 104 in x/evm/keeper/rpc_client.go

View workflow job for this annotation

GitHub Actions / Run golangci-lint

var-naming: struct field ChainConfigJson should be ChainConfigJSON (revive)

// Fields from EVMConfig
CoinBase common.Address
Expand All @@ -111,24 +119,35 @@
Overrides string
}

// PrepareTxArgs is the argument struct for the SgxRpcServer.PrepareTx RPC method.
type PrepareTxArgs struct {
// StartEVMArgs is the argument struct for the SgxRpcServer.StartEVM RPC method.
type StartEVMArgs struct {
TxHash []byte
// Header is the Tendermint header of the block in which the transaction
// will be executed.
Header cmtproto.Header
// Msg is the EVM transaction message to run on the EVM.
Msg core.Message
// EvmConfig is the EVM configuration to set.
EvmConfig PrepareTxEVMConfig
EvmConfig StartEVMTxEVMConfig
}

// StartEVMReply is the reply struct for the SgxRpcServer.StartEVM RPC method.
type StartEVMReply struct {
EvmId uint64

Check warning on line 136 in x/evm/keeper/rpc_client.go

View workflow job for this annotation

GitHub Actions / Run golangci-lint

var-naming: struct field EvmId should be EvmID (revive)
}

// PrepareTxArgs is the reply struct for the SgxRpcServer.PrepareTx RPC method.
type PrepareTxReply struct {
// InitFhevmArgs is the arg struct for the SgxRpcServer.InitFhevm RPC method.
type InitFhevmArgs struct {
EvmId uint64

Check warning on line 141 in x/evm/keeper/rpc_client.go

View workflow job for this annotation

GitHub Actions / Run golangci-lint

var-naming: struct field EvmId should be EvmID (revive)
}

// InitFhevmReply is the reply struct for the SgxRpcServer.InitFhevm RPC method.
type InitFhevmReply struct {

Check failure on line 145 in x/evm/keeper/rpc_client.go

View workflow job for this annotation

GitHub Actions / Run golangci-lint

File is not `gofumpt`-ed (gofumpt)
}

// CallArgs is the argument struct for the SgxRpcServer.Call RPC method.
type CallArgs struct {
EvmId uint64
Caller vm.AccountRef
Addr common.Address
Input []byte
Expand All @@ -144,6 +163,7 @@

// CreateArgs is the argument struct for the SgxRpcServer.Create RPC method.
type CreateArgs struct {
EvmId uint64
Caller vm.AccountRef
Code []byte
Gas uint64
Expand All @@ -159,72 +179,87 @@

// CommitArgs is the argument struct for the SgxRpcServer.Commit RPC method.
type CommitArgs struct {
Commit bool
EvmId uint64
}

// CommitReply is the reply struct for the SgxRpcServer.Commit RPC method.
type CommitReply struct {

Check failure on line 186 in x/evm/keeper/rpc_client.go

View workflow job for this annotation

GitHub Actions / Run golangci-lint

File is not `gofumpt`-ed (gofumpt)
}

// CommitArgs is the argument struct for the SgxRpcServer.StateDBSubBalance RPC method.
type StateDBSubBalanceArgs struct {
EvmId uint64
Caller vm.AccountRef
Msg core.Message
}

// CommitReply is the reply struct for the SgxRpcServer.StateDBSubBalance RPC method.
type StateDBSubBalanceReply struct {

Check failure on line 197 in x/evm/keeper/rpc_client.go

View workflow job for this annotation

GitHub Actions / Run golangci-lint

File is not `gofumpt`-ed (gofumpt)
}

// CommitArgs is the argument struct for the SgxRpcServer.StateDSetNonce RPC method.
type StateDBSetNonceArgs struct {
EvmId uint64
Caller vm.AccountRef
Nonce uint64
}

// CommitReply is the reply struct for the SgxRpcServer.StateDSetNonce RPC method.
type StateDBSetNonceReply struct {

Check failure on line 208 in x/evm/keeper/rpc_client.go

View workflow job for this annotation

GitHub Actions / Run golangci-lint

File is not `gofumpt`-ed (gofumpt)
}

// StateDBAddBalanceArgs is the argument struct for the SgxRpcServer.StateDBAddBalance RPC method.
type StateDBAddBalanceArgs struct {
EvmId uint64
Caller vm.AccountRef
Msg core.Message
LeftoverGas uint64
}

// StateDBAddBalanceReply is the reply struct for the SgxRpcServer.StateDBAddBalance RPC method.
type StateDBAddBalanceReply struct {

Check failure on line 220 in x/evm/keeper/rpc_client.go

View workflow job for this annotation

GitHub Actions / Run golangci-lint

File is not `gofumpt`-ed (gofumpt)
}

type StateDBPrepareArgs struct {
Msg core.Message
Rules params.Rules
EvmId uint64
Msg core.Message
Rules params.Rules
CoinBase common.Address
}

type StateDBPrepareReply struct {

Check failure on line 230 in x/evm/keeper/rpc_client.go

View workflow job for this annotation

GitHub Actions / Run golangci-lint

File is not `gofumpt`-ed (gofumpt)
}

// StateDBIncreaseNonceArgs is the argument struct for the SgxRpcServer.StateDBIncreaseNonce RPC method.
type StateDBIncreaseNonceArgs struct {
EvmId uint64
Caller vm.AccountRef
Msg core.Message
}

// StateDBIncreaseNonceReply is the reply struct for the SgxRpcServer.StateDBIncreaseNonce RPC method.
type StateDBIncreaseNonceReply struct {

Check failure on line 241 in x/evm/keeper/rpc_client.go

View workflow job for this annotation

GitHub Actions / Run golangci-lint

File is not `gofumpt`-ed (gofumpt)
}

type StateDBGetRefundArgs struct {
EvmId uint64
}

type StateDBGetRefundReply struct {
Refund uint64
}

type StateDBGetLogsArgs struct {
EvmId uint64
}

type StateDBGetLogsReply struct {
Logs []*ethtypes.Log
}

type StopEVMArgs struct {
EvmId uint64
}

type StopEVMReply struct {

Check failure on line 264 in x/evm/keeper/rpc_client.go

View workflow job for this annotation

GitHub Actions / Run golangci-lint

File is not `gofumpt`-ed (gofumpt)
}
Loading
Loading