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 @@ -83,6 +83,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
- (rpc) [#135](https://github.com/EscanBE/evermint/pull/135) Build tx receipt to response for txs aborted due to block gas limit
- (evm) [#136](https://github.com/EscanBE/evermint/pull/136) Correct block bloom, receipt bloom computation and some other minor issues of transient data
- (rpc+indexer) [#137](https://github.com/EscanBE/evermint/pull/137) Exclude txs dropped pre-AnteHandle due to gas limit from RPC results
- (rpc) [#145](https://github.com/EscanBE/evermint/pull/145) Fix broken tests caused by `--allow-insecure-unlock` and minor refactor RPC backend

### Client Breaking

Expand Down
4 changes: 3 additions & 1 deletion integration_test_util/chain_suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ func (suite *ChainIntegrationTestSuite) RpcBackendAt(height int64) *rpcbackend.B
queryClients := suite.QueryClientsAt(height)
rpcServerCtx := server.NewDefaultContext()

rpcBackend := rpcbackend.NewBackend(rpcServerCtx, rpcServerCtx.Logger, queryClients.ClientQueryCtx, false, suite.EvmTxIndexer)
rpcBackend := rpcbackend.NewBackend(rpcServerCtx, rpcServerCtx.Logger, queryClients.ClientQueryCtx, suite.EvmTxIndexer)

// override the query client with the mock query client, for changing query context
getFieldQueryClient := func() reflect.Value {
Expand All @@ -480,6 +480,8 @@ func (suite *ChainIntegrationTestSuite) RpcBackendAt(height int64) *rpcbackend.B
Elem().
Set(reflect.ValueOf(queryClients.Rpc))

rpcBackend.AllowInsecureUnlock(true)

return rpcBackend
}

Expand Down
22 changes: 8 additions & 14 deletions rpc/apis.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ type APICreator = func(
ctx *server.Context,
clientCtx client.Context,
tendermintWebsocketClient *rpcclient.WSClient,
allowUnprotectedTxs bool,
indexer types.EVMTxIndexer,
) []rpc.API

Expand All @@ -58,10 +57,9 @@ func init() {
EthNamespace: func(ctx *server.Context,
clientCtx client.Context,
tmWSClient *rpcclient.WSClient,
allowUnprotectedTxs bool,
indexer types.EVMTxIndexer,
) []rpc.API {
evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer)
evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, indexer)
return []rpc.API{
{
Namespace: EthNamespace,
Expand All @@ -77,7 +75,7 @@ func init() {
},
}
},
Web3Namespace: func(*server.Context, client.Context, *rpcclient.WSClient, bool, types.EVMTxIndexer) []rpc.API {
Web3Namespace: func(*server.Context, client.Context, *rpcclient.WSClient, types.EVMTxIndexer) []rpc.API {
return []rpc.API{
{
Namespace: Web3Namespace,
Expand All @@ -87,7 +85,7 @@ func init() {
},
}
},
NetNamespace: func(_ *server.Context, clientCtx client.Context, _ *rpcclient.WSClient, _ bool, _ types.EVMTxIndexer) []rpc.API {
NetNamespace: func(_ *server.Context, clientCtx client.Context, _ *rpcclient.WSClient, _ types.EVMTxIndexer) []rpc.API {
return []rpc.API{
{
Namespace: NetNamespace,
Expand All @@ -100,10 +98,9 @@ func init() {
PersonalNamespace: func(ctx *server.Context,
clientCtx client.Context,
_ *rpcclient.WSClient,
allowUnprotectedTxs bool,
indexer types.EVMTxIndexer,
) []rpc.API {
evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer)
evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, indexer)
return []rpc.API{
{
Namespace: PersonalNamespace,
Expand All @@ -113,7 +110,7 @@ func init() {
},
}
},
TxPoolNamespace: func(ctx *server.Context, _ client.Context, _ *rpcclient.WSClient, _ bool, _ types.EVMTxIndexer) []rpc.API {
TxPoolNamespace: func(ctx *server.Context, _ client.Context, _ *rpcclient.WSClient, _ types.EVMTxIndexer) []rpc.API {
return []rpc.API{
{
Namespace: TxPoolNamespace,
Expand All @@ -126,10 +123,9 @@ func init() {
DebugNamespace: func(ctx *server.Context,
clientCtx client.Context,
_ *rpcclient.WSClient,
allowUnprotectedTxs bool,
indexer types.EVMTxIndexer,
) []rpc.API {
evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer)
evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, indexer)
return []rpc.API{
{
Namespace: DebugNamespace,
Expand All @@ -142,10 +138,9 @@ func init() {
MinerNamespace: func(ctx *server.Context,
clientCtx client.Context,
_ *rpcclient.WSClient,
allowUnprotectedTxs bool,
indexer types.EVMTxIndexer,
) []rpc.API {
evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer)
evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, indexer)
return []rpc.API{
{
Namespace: MinerNamespace,
Expand All @@ -162,15 +157,14 @@ func init() {
func GetRPCAPIs(ctx *server.Context,
clientCtx client.Context,
tmWSClient *rpcclient.WSClient,
allowUnprotectedTxs bool,
indexer types.EVMTxIndexer,
selectedAPIs []string,
) []rpc.API {
var apis []rpc.API

for _, ns := range selectedAPIs {
if creator, ok := apiCreators[ns]; ok {
apis = append(apis, creator(ctx, clientCtx, tmWSClient, allowUnprotectedTxs, indexer)...)
apis = append(apis, creator(ctx, clientCtx, tmWSClient, indexer)...)
} else {
ctx.Logger.Error("invalid namespace value", "namespace", ns)
}
Expand Down
34 changes: 16 additions & 18 deletions rpc/backend/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ type EVMBackend interface {
ImportRawKey(privkey, password string) (common.Address, error)
ListAccounts() ([]common.Address, error)
NewMnemonic(uid string, language keyring.Language, hdPath, bip39Passphrase string, algo keyring.SignatureAlgo) (*keyring.Record, error)
UnprotectedAllowed() bool
AllowUnprotectedTxs(allow bool)
AllowInsecureUnlock(allow bool)
RPCGasCap() uint64 // global gas cap for eth_call over rpc: DoS protection
RPCEVMTimeout() time.Duration // global timeout for eth_call over rpc: DoS protection
RPCTxFeeCap() float64 // RPCTxFeeCap is the global transaction fee(price * gaslimit) cap for send-transaction variants. The unit is ether.
Expand Down Expand Up @@ -129,22 +130,20 @@ var _ BackendI = (*Backend)(nil)

// Backend implements the BackendI interface
type Backend struct {
ctx context.Context
clientCtx client.Context
queryClient *rpctypes.QueryClient // gRPC query client
logger log.Logger
chainID *big.Int
cfg config.Config
allowUnprotectedTxs bool
indexer evertypes.EVMTxIndexer
ctx context.Context
clientCtx client.Context
queryClient *rpctypes.QueryClient // gRPC query client
logger log.Logger
chainID *big.Int
cfg config.Config
indexer evertypes.EVMTxIndexer
}

// NewBackend creates a new Backend instance for cosmos and ethereum namespaces
func NewBackend(
ctx *server.Context,
logger log.Logger,
clientCtx client.Context,
allowUnprotectedTxs bool,
indexer evertypes.EVMTxIndexer,
) *Backend {
chainID, err := evertypes.ParseChainID(clientCtx.ChainID)
Expand All @@ -162,13 +161,12 @@ func NewBackend(
}

return &Backend{
ctx: context.Background(),
clientCtx: clientCtx,
queryClient: rpctypes.NewQueryClient(clientCtx),
logger: logger.With("module", "backend"),
chainID: chainID,
cfg: appConf,
allowUnprotectedTxs: allowUnprotectedTxs,
indexer: indexer,
ctx: context.Background(),
clientCtx: clientCtx,
queryClient: rpctypes.NewQueryClient(clientCtx),
logger: logger.With("module", "backend"),
chainID: chainID,
cfg: appConf,
indexer: indexer,
}
}
4 changes: 2 additions & 2 deletions rpc/backend/backend_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,15 @@ func (suite *BackendTestSuite) SetupTest() {
WithKeyring(keyRing).
WithAccountRetriever(client.TestAccountRetriever{Accounts: accounts})

allowUnprotectedTxs := false
idxer := indexer.NewKVIndexer(dbm.NewMemDB(), ctx.Logger, clientCtx)

suite.backend = NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, idxer)
suite.backend = NewBackend(ctx, ctx.Logger, clientCtx, idxer)
suite.backend.queryClient.QueryClient = mocks.NewEVMQueryClient(suite.T())
suite.backend.clientCtx.Client = mocks.NewClient(suite.T())
suite.backend.queryClient.FeeMarket = mocks.NewFeeMarketQueryClient(suite.T())
suite.backend.ctx = rpctypes.ContextWithHeight(1)
suite.backend.indexer = mocks.NewEVMTxIndexer(suite.T())
suite.backend.AllowInsecureUnlock(true)

// Add codec
encCfg := encoding.MakeConfig(app.ModuleBasics)
Expand Down
2 changes: 1 addition & 1 deletion rpc/backend/call_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ func (b *Backend) SendRawTransaction(data hexutil.Bytes) (common.Hash, error) {
}

// check the local node config in case unprotected txs are disabled
if !b.UnprotectedAllowed() && !tx.Protected() {
if !b.cfg.JSONRPC.AllowUnprotectedTxs && !tx.Protected() {
// Ensure only eip155 signed transactions are submitted if EIP155Required is set.
return common.Hash{}, errors.New("only replay-protected (EIP-155) transactions allowed over RPC")
}
Expand Down
8 changes: 4 additions & 4 deletions rpc/backend/call_tx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ func (suite *BackendTestSuite) TestSendRawTransaction() {
"fail - unprotected transactions",
func() {
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
suite.backend.allowUnprotectedTxs = false
suite.backend.AllowUnprotectedTxs(false)
RegisterParamsWithoutHeaderError(queryClient, 1)
},
rlpEncodedBz,
Expand All @@ -360,7 +360,7 @@ func (suite *BackendTestSuite) TestSendRawTransaction() {
"fail - failed to get evm params",
func() {
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
suite.backend.allowUnprotectedTxs = true
suite.backend.AllowUnprotectedTxs(true)
RegisterParamsWithoutHeaderError(queryClient, 1)
},
rlpEncodedBz,
Expand All @@ -372,7 +372,7 @@ func (suite *BackendTestSuite) TestSendRawTransaction() {
func() {
client := suite.backend.clientCtx.Client.(*mocks.Client)
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
suite.backend.allowUnprotectedTxs = true
suite.backend.AllowUnprotectedTxs(true)
RegisterParamsWithoutHeader(queryClient, 1)
RegisterBroadcastTxError(client, txBytes)
},
Expand All @@ -385,7 +385,7 @@ func (suite *BackendTestSuite) TestSendRawTransaction() {
func() {
client := suite.backend.clientCtx.Client.(*mocks.Client)
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
suite.backend.allowUnprotectedTxs = true
suite.backend.AllowUnprotectedTxs(true)
RegisterParamsWithoutHeader(queryClient, 1)
RegisterBroadcastTx(client, txBytes)
},
Expand Down
22 changes: 18 additions & 4 deletions rpc/backend/node_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,10 +295,24 @@ func (b *Backend) SetGasPrice(gasPrice hexutil.Big) bool {
return true
}

// UnprotectedAllowed returns the node configuration value for allowing
// unprotected transactions (i.e not replay-protected)
func (b Backend) UnprotectedAllowed() bool {
return b.allowUnprotectedTxs
// AllowUnprotectedTxs should be used for testing purpose only.
func (b *Backend) AllowUnprotectedTxs(allow bool) {
if b.cfg.JSONRPC.AllowUnprotectedTxs == allow {
return
}

jsonRpc := &b.cfg.JSONRPC
jsonRpc.AllowUnprotectedTxs = allow
}

// AllowInsecureUnlock should be used for testing purpose only.
func (b *Backend) AllowInsecureUnlock(allow bool) {
if b.cfg.JSONRPC.AllowInsecureUnlock == allow {
return
}

jsonRpc := &b.cfg.JSONRPC
jsonRpc.AllowInsecureUnlock = allow
}

// RPCGasCap is the global gas cap for eth-call variants.
Expand Down
2 changes: 1 addition & 1 deletion rpc/backend/sign_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func (b *Backend) SendTransaction(args evmtypes.TransactionArgs) (common.Hash, e
ethTx := msg.AsTransaction()

// check the local node config in case unprotected txs are disabled
if !b.UnprotectedAllowed() && !ethTx.Protected() {
if !b.cfg.JSONRPC.AllowUnprotectedTxs && !ethTx.Protected() {
// Ensure only eip155 signed transactions are submitted if EIP155Required is set.
return common.Hash{}, errors.New("only replay-protected (EIP-155) transactions allowed over RPC")
}
Expand Down
3 changes: 1 addition & 2 deletions server/json_rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,9 @@ func StartJSONRPC(ctx *server.Context,

rpcServer := ethrpc.NewServer()

allowUnprotectedTxs := config.JSONRPC.AllowUnprotectedTxs
rpcAPIArr := config.JSONRPC.API

apis := rpc.GetRPCAPIs(ctx, clientCtx, tmWsClient, allowUnprotectedTxs, indexer, rpcAPIArr)
apis := rpc.GetRPCAPIs(ctx, clientCtx, tmWsClient, indexer, rpcAPIArr)

for _, api := range apis {
if err := rpcServer.RegisterName(api.Namespace, api.Service); err != nil {
Expand Down