From 1f5b8120571f592bbf1193f9c89a72c0b77d1084 Mon Sep 17 00:00:00 2001 From: itsdevbear Date: Wed, 31 Jan 2024 19:37:23 -0500 Subject: [PATCH] force recheck --- cosmos/config/config.go | 5 +++ cosmos/config/flags/flags.go | 1 + cosmos/config/template.go | 6 ++++ cosmos/runtime/runtime.go | 1 + cosmos/runtime/txpool/ante.go | 5 +-- cosmos/runtime/txpool/mempool.go | 56 ++++++++++++++++++-------------- eth/polar/config.go | 10 +++++- 7 files changed, 56 insertions(+), 28 deletions(-) diff --git a/cosmos/config/config.go b/cosmos/config/config.go index f98679b78..79da5b9d9 100644 --- a/cosmos/config/config.go +++ b/cosmos/config/config.go @@ -103,6 +103,11 @@ func readConfigFromAppOptsParser(parser AppOptionsParser) (*Config, error) { return nil, err } + if conf.Polar.ForceForwardReCheckTxs, err = parser.GetBool( + flags.ForceForwardReCheckTxs); err != nil { + return nil, err + } + // Polar Miner settings if conf.Polar.Miner.Etherbase, err = parser.GetCommonAddress(flags.MinerEtherbase); err != nil { diff --git a/cosmos/config/flags/flags.go b/cosmos/config/flags/flags.go index 02fc271b9..8627aae9f 100644 --- a/cosmos/config/flags/flags.go +++ b/cosmos/config/flags/flags.go @@ -29,6 +29,7 @@ const ( RPCGasCap = "polaris.polar.rpc-gas-cap" IsValidator = "polaris.polar.is-validator" ValidatorJSONRPCEndpoint = "polaris.polar.validator-jsonrpc-endpoint" + ForceForwardReCheckTxs = "polaris.polar.force-forward-recheck-txs" // Miner. MinerEtherbase = "polaris.polar.miner.etherbase" diff --git a/cosmos/config/template.go b/cosmos/config/template.go index 6401dba12..a4ec9ee17 100644 --- a/cosmos/config/template.go +++ b/cosmos/config/template.go @@ -40,9 +40,15 @@ rpc-evm-timeout = "{{ .Polaris.Polar.RPCEVMTimeout }}" # Transaction fee cap for RPC requests rpc-tx-fee-cap = "{{ .Polaris.Polar.RPCTxFeeCap }}" +# JSON-RPC endpoint for forwarding ethereum transactions directly to validators. validator-jsonrpc-endpoint = "{{ .Polaris.Polar.ValidatorJSONRPCEndpoint }}" + +# Whether the node is a validator is-validator = {{ .Polaris.Polar.IsValidator }} +# If we want to force forwarding on ReCheckTxs +force-forward-recheck-txs = {{ .Polaris.Polar.ForceForwardReCheckTxs }} + # Chain config [polaris.polar.chain] chain-id = "{{ .Polaris.Polar.Chain.ChainID }}" diff --git a/cosmos/runtime/runtime.go b/cosmos/runtime/runtime.go index 077a16259..79d80d3aa 100644 --- a/cosmos/runtime/runtime.go +++ b/cosmos/runtime/runtime.go @@ -134,6 +134,7 @@ func New( &p.blockBuilderMu, priceLimit, p.cfg.Polar.IsValidator, + p.cfg.Polar.ForceForwardReCheckTxs, p.cfg.Polar.ValidatorJSONRPCEndpoint, ) diff --git a/cosmos/runtime/txpool/ante.go b/cosmos/runtime/txpool/ante.go index 00215f04b..dc5fee89a 100644 --- a/cosmos/runtime/txpool/ante.go +++ b/cosmos/runtime/txpool/ante.go @@ -44,8 +44,6 @@ func (m *Mempool) AnteHandle( telemetry.IncrCounter(float32(1), MetricKeyCometPoolTxs) msgs := tx.GetMsgs() - // TODO: Record the time it takes to build a payload. - // We only want to eject transactions from comet on recheck. if ctx.ExecMode() == sdk.ExecModeCheck || ctx.ExecMode() == sdk.ExecModeReCheck { if wet, ok := utils.GetAs[*types.WrappedEthereumTransaction](msgs[0]); ok { @@ -55,6 +53,9 @@ func (m *Mempool) AnteHandle( ); shouldEject { telemetry.IncrCounter(float32(1), MetricKeyAnteEjectedTxs) return ctx, errors.New("eject from comet mempool") + } else if ctx.ExecMode() == sdk.ExecModeReCheck && m.forceBroadcastOnRecheck { + // We optionally force a re-broadcast. + m.ForwardToValidator(ethTx) } } } diff --git a/cosmos/runtime/txpool/mempool.go b/cosmos/runtime/txpool/mempool.go index 961dc7809..e267ee175 100644 --- a/cosmos/runtime/txpool/mempool.go +++ b/cosmos/runtime/txpool/mempool.go @@ -79,16 +79,18 @@ type Mempool struct { blockBuilderMu *sync.RWMutex priceLimit *big.Int - isValidator bool - validatorJSONRPC string - ethclient *ethclient.Client + isValidator bool + validatorJSONRPC string + forceBroadcastOnRecheck bool + ethclient *ethclient.Client } // New creates a new Mempool. func New( logger log.Logger, chain core.ChainReader, txpool eth.TxPool, lifetime int64, - blockBuilderMu *sync.RWMutex, priceLimit *big.Int, isValidator bool, + blockBuilderMu *sync.RWMutex, priceLimit *big.Int, isValidator, + forceBroadcastOnRecheck bool, validatorJSONRPC string, ) *Mempool { var ( @@ -118,16 +120,17 @@ func New( } return &Mempool{ - logger: logger, - TxPool: txpool, - chain: chain, - lifetime: lifetime, - crc: newCometRemoteCache(), - blockBuilderMu: blockBuilderMu, - priceLimit: priceLimit, - isValidator: isValidator, - validatorJSONRPC: validatorJSONRPC, - ethclient: ec, + logger: logger, + TxPool: txpool, + chain: chain, + lifetime: lifetime, + crc: newCometRemoteCache(), + blockBuilderMu: blockBuilderMu, + priceLimit: priceLimit, + isValidator: isValidator, + forceBroadcastOnRecheck: forceBroadcastOnRecheck, + validatorJSONRPC: validatorJSONRPC, + ethclient: ec, } } @@ -170,17 +173,8 @@ func (m *Mempool) Insert(ctx context.Context, sdkTx sdk.Tx) error { // Add the eth tx to the Geth txpool. ethTx := wet.Unwrap() - // Optmistically send to the validator. - if m.ethclient != nil { - // Broadcast the transaction to the validator. - // Note: we don't care about the response here. - go func() { - sCtx.Logger().Info("broadcasting transaction to validator", "hash", ethTx.Hash().Hex()) - if err := m.ethclient.SendTransaction(context.Background(), ethTx); err != nil { - sCtx.Logger().Error("failed to broadcast transaction to validator", "error", err) - } - }() - } + // Fowrad to a validator if we have one. + m.ForwardToValidator(ethTx) // Insert the tx into the txpool as a remote. m.blockBuilderMu.RLock() @@ -204,6 +198,18 @@ func (m *Mempool) Insert(ctx context.Context, sdkTx sdk.Tx) error { return nil } +func (m *Mempool) ForwardToValidator(ethTx *ethtypes.Transaction) { + if m.ethclient != nil { + // Broadcast the transaction to the validator. + // Note: we don't care about the response here. + go func() { + if err := m.ethclient.SendTransaction(context.Background(), ethTx); err != nil { + m.logger.Error("failed to broadcast transaction to validator", "error", err) + } + }() + } +} + // CountTx returns the number of transactions currently in the mempool. func (m *Mempool) CountTx() int { runnable, blocked := m.TxPool.Stats() diff --git a/eth/polar/config.go b/eth/polar/config.go index 0ec70fcab..8c7fc1bf4 100644 --- a/eth/polar/config.go +++ b/eth/polar/config.go @@ -103,6 +103,14 @@ type Config struct { // send-transaction variants. The unit is ether. RPCTxFeeCap float64 + // ValidatorJSONRPCEndpoint is the JSON-RPC endpoint of a validator, you + // want to forward transactions to. ValidatorJSONRPCEndpoint string - IsValidator bool + + // IsValidator is a flag to indicate if the node is a validator. + IsValidator bool + + // ForceForwardReCheckTxs is a flag to indicate if the node should forward + // transactions on recheck. + ForceForwardReCheckTxs bool }