Skip to content

Commit

Permalink
Problem: decode tx is unnecessary in tx listener (#491)
Browse files Browse the repository at this point in the history
* Problem: decode tx is unnecessary in tx listener

* cleanup
  • Loading branch information
mmsqe committed Jun 9, 2024
1 parent 97a30f8 commit 217e3af
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 35 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
more accurate.
* (app) [#483](https://github.com/crypto-org-chain/ethermint/pull/483) Make keyring-backend client config accessible in app.
* (deps) [#489](https://github.com/crypto-org-chain/ethermint/pull/489) Update cosmos-sdk to `v0.50.7`.
* (rpc) [#491](https://github.com/crypto-org-chain/ethermint/pull/491) Avoid unnecessary tx decode in tx listener.

## v0.21.x-cronos

Expand Down
10 changes: 7 additions & 3 deletions app/ante/handler_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ type HandlerOptions struct {
DynamicFeeChecker bool
DisabledAuthzMsgs []string
ExtraDecorators []sdk.AnteDecorator
PendingTxListener PendingTxListener
}

func (options HandlerOptions) validate() error {
Expand Down Expand Up @@ -131,10 +132,13 @@ func newEthAnteHandler(options HandlerOptions) sdk.AnteHandler {
return ctx, err
}

if len(options.ExtraDecorators) > 0 {
return sdk.ChainAnteDecorators(options.ExtraDecorators...)(ctx, tx, simulate)
extraDecorators := options.ExtraDecorators
if options.PendingTxListener != nil {
extraDecorators = append(extraDecorators, newTxListenerDecorator(options.PendingTxListener))
}
if len(extraDecorators) > 0 {
return sdk.ChainAnteDecorators(extraDecorators...)(ctx, tx, simulate)
}

return ctx, nil
}
}
Expand Down
33 changes: 33 additions & 0 deletions app/ante/tx_listener.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package ante

import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/common"
evmtypes "github.com/evmos/ethermint/x/evm/types"
)

type PendingTxListener func(common.Hash)

type TxListenerDecorator struct {
pendingTxListener PendingTxListener
}

// newTxListenerDecorator creates a new TxListenerDecorator with the provided PendingTxListener.
// CONTRACT: must be put at the last of the chained decorators
func newTxListenerDecorator(pendingTxListener PendingTxListener) TxListenerDecorator {
return TxListenerDecorator{pendingTxListener}
}

func (d TxListenerDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
if ctx.IsReCheckTx() {
return next(ctx, tx, simulate)
}
if ctx.IsCheckTx() && !simulate && d.pendingTxListener != nil {
for _, msg := range tx.GetMsgs() {
if ethTx, ok := msg.(*evmtypes.MsgEthereumTx); ok {
d.pendingTxListener(ethTx.Hash())
}
}
}
return next(ctx, tx, simulate)
}
26 changes: 11 additions & 15 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ import (

consensusparamkeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper"
consensusparamtypes "github.com/cosmos/cosmos-sdk/x/consensus/types"
"github.com/ethereum/go-ethereum/common"

// Force-load the tracer engines to trigger registration due to Go-Ethereum v1.10.15 changes
_ "github.com/ethereum/go-ethereum/eth/tracers/js"
Expand Down Expand Up @@ -189,8 +190,6 @@ var (

type GenesisState map[string]json.RawMessage

type PendingTxListener func([]byte)

// var _ server.Application (*EthermintApp)(nil)

// EthermintApp implements an extended ABCI application. It is an application
Expand All @@ -207,7 +206,7 @@ type EthermintApp struct {

invCheckPeriod uint

pendingTxListeners []PendingTxListener
pendingTxListeners []ante.PendingTxListener

// keys to access the substores
keys map[string]*storetypes.KVStoreKey
Expand Down Expand Up @@ -820,6 +819,7 @@ func (app *EthermintApp) setAnteHandler(txConfig client.TxConfig, maxGasWanted u
sdk.MsgTypeURL(&evmtypes.MsgEthereumTx{}),
sdk.MsgTypeURL(&vestingtypes.MsgCreateVestingAccount{}),
},
PendingTxListener: app.onPendingTx,
})
if err != nil {
panic(err)
Expand All @@ -828,6 +828,12 @@ func (app *EthermintApp) setAnteHandler(txConfig client.TxConfig, maxGasWanted u
app.SetAnteHandler(anteHandler)
}

func (app *EthermintApp) onPendingTx(hash common.Hash) {
for _, listener := range app.pendingTxListeners {
listener(hash)
}
}

func (app *EthermintApp) setPostHandler() {
postHandler, err := posthandler.NewPostHandler(
posthandler.HandlerOptions{},
Expand Down Expand Up @@ -1067,21 +1073,11 @@ func (app *EthermintApp) GetStoreKey(name string) storetypes.StoreKey {
return app.okeys[name]
}

// RegisterPendingTxListener is used by json-rpc server to listen to pending transactions in CheckTx.
func (app *EthermintApp) RegisterPendingTxListener(listener PendingTxListener) {
// RegisterPendingTxListener is used by json-rpc server to listen to pending transactions callback.
func (app *EthermintApp) RegisterPendingTxListener(listener ante.PendingTxListener) {
app.pendingTxListeners = append(app.pendingTxListeners, listener)
}

func (app *EthermintApp) CheckTx(req *abci.RequestCheckTx) (*abci.ResponseCheckTx, error) {
res, err := app.BaseApp.CheckTx(req)
if err == nil && res.Code == 0 && req.Type == abci.CheckTxType_New {
for _, listener := range app.pendingTxListeners {
listener(req.Tx)
}
}
return res, err
}

// RegisterSwaggerAPI registers swagger route with API Server
func RegisterSwaggerAPI(_ client.Context, rtr *mux.Router) {
root, err := fs.Sub(docs.SwaggerUI, "swagger-ui")
Expand Down
16 changes: 2 additions & 14 deletions rpc/stream/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,20 +113,8 @@ func (s *RPCStream) LogStream() *Stream[*ethtypes.Log] {
}

// ListenPendingTx is a callback passed to application to listen for pending transactions in CheckTx.
func (s *RPCStream) ListenPendingTx(bytes []byte) {
tx, err := s.txDecoder(bytes)
if err != nil {
s.logger.Error("fail to decode tx", "error", err.Error())
return
}

var hashes []common.Hash
for _, msg := range tx.GetMsgs() {
if ethTx, ok := msg.(*evmtypes.MsgEthereumTx); ok {
hashes = append(hashes, ethTx.AsTransaction().Hash())
}
}
s.pendingTxStream.Add(hashes...)
func (s *RPCStream) ListenPendingTx(hash common.Hash) {
s.pendingTxStream.Add(hash)
}

func (s *RPCStream) start(
Expand Down
5 changes: 2 additions & 3 deletions server/json_rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,9 @@ import (
"github.com/cosmos/cosmos-sdk/server"
ethlog "github.com/ethereum/go-ethereum/log"
ethrpc "github.com/ethereum/go-ethereum/rpc"
"github.com/evmos/ethermint/app"
"github.com/evmos/ethermint/app/ante"
"github.com/evmos/ethermint/rpc"
"github.com/evmos/ethermint/rpc/stream"

"github.com/evmos/ethermint/server/config"
ethermint "github.com/evmos/ethermint/types"
)
Expand All @@ -43,7 +42,7 @@ const (
)

type AppWithPendingTxStream interface {
RegisterPendingTxListener(listener app.PendingTxListener)
RegisterPendingTxListener(listener ante.PendingTxListener)
}

// StartJSONRPC starts the JSON-RPC server
Expand Down

0 comments on commit 217e3af

Please sign in to comment.