From a6378e0607deb727a0b57686c70443531fcf681c Mon Sep 17 00:00:00 2001 From: itsdevbear Date: Wed, 31 Jan 2024 15:26:03 -0500 Subject: [PATCH] based --- cosmos/config/config.go | 9 +++++ cosmos/config/flags/flags.go | 8 +++-- cosmos/config/template.go | 3 ++ cosmos/runtime/ante/ante.go | 7 +++- cosmos/runtime/runtime.go | 9 +++-- cosmos/runtime/txpool/handler.go | 28 ++++++++++----- cosmos/runtime/txpool/handler_test.go | 2 +- cosmos/runtime/txpool/mempool.go | 49 ++++++++++++++++++++++----- eth/polar/config.go | 3 ++ 9 files changed, 94 insertions(+), 24 deletions(-) diff --git a/cosmos/config/config.go b/cosmos/config/config.go index 1c3859f44..f98679b78 100644 --- a/cosmos/config/config.go +++ b/cosmos/config/config.go @@ -94,6 +94,15 @@ func readConfigFromAppOptsParser(parser AppOptionsParser) (*Config, error) { return nil, err } + if conf.Polar.IsValidator, err = parser.GetBool(flags.IsValidator); err != nil { + return nil, err + } + + if conf.Polar.ValidatorJSONRPCEndpoint, err = + parser.GetString(flags.ValidatorJSONRPCEndpoint); 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 90ae84edc..02fc271b9 100644 --- a/cosmos/config/flags/flags.go +++ b/cosmos/config/flags/flags.go @@ -24,9 +24,11 @@ const ( OptimisticExecution = "polaris.optimistic-execution" // Polar Root. - RPCEvmTimeout = "polaris.polar.rpc-evm-timeout" - RPCTxFeeCap = "polaris.polar.rpc-tx-fee-cap" - RPCGasCap = "polaris.polar.rpc-gas-cap" + RPCEvmTimeout = "polaris.polar.rpc-evm-timeout" + RPCTxFeeCap = "polaris.polar.rpc-tx-fee-cap" + RPCGasCap = "polaris.polar.rpc-gas-cap" + IsValidator = "polaris.polar.is-validator" + ValidatorJSONRPCEndpoint = "polaris.polar.validator-jsonrpc-endpoint" // Miner. MinerEtherbase = "polaris.polar.miner.etherbase" diff --git a/cosmos/config/template.go b/cosmos/config/template.go index 9a04dae72..8e188ee95 100644 --- a/cosmos/config/template.go +++ b/cosmos/config/template.go @@ -40,6 +40,9 @@ rpc-evm-timeout = "{{ .Polaris.Polar.RPCEVMTimeout }}" # Transaction fee cap for RPC requests rpc-tx-fee-cap = "{{ .Polaris.Polar.RPCTxFeeCap }}" +validator-json-rpc-endpoint = "{{ .Polaris.Polar.ValidatorJSONRPCEndpoint }}" +is-validator = {{ .Polaris.Polar.IsValidator }} + # Chain config [polaris.polar.chain] chain-id = "{{ .Polaris.Polar.Chain.ChainID }}" diff --git a/cosmos/runtime/ante/ante.go b/cosmos/runtime/ante/ante.go index 05c4de043..f27c336c4 100644 --- a/cosmos/runtime/ante/ante.go +++ b/cosmos/runtime/ante/ante.go @@ -39,12 +39,13 @@ import ( type Provider struct { evmAnteHandler sdk.AnteHandler // Ante handler for EVM transactions cosmosAnteHandler sdk.AnteHandler // Ante handler for Cosmos transactions + isValidator bool } // NewAnteHandler creates a new Provider with a mempool and Cosmos ante handler. // It sets up the EVM ante handler with the necessary decorators. func NewAnteHandler( - mempool *txpool.Mempool, cosmosAnteHandler sdk.AnteHandler, + mempool *txpool.Mempool, cosmosAnteHandler sdk.AnteHandler, isValidator bool, ) *Provider { evmAnteDecorators := []sdk.AnteDecorator{ ante.NewSetUpContextDecorator(), // Set up the context decorator for the EVM ante handler @@ -55,6 +56,7 @@ func NewAnteHandler( return &Provider{ evmAnteHandler: sdk.ChainAnteDecorators(evmAnteDecorators...), cosmosAnteHandler: cosmosAnteHandler, + isValidator: isValidator, } } @@ -67,6 +69,9 @@ func (ah *Provider) AnteHandler() func( // If the transaction contains a single EVM transaction, use the EVM ante handler if len(tx.GetMsgs()) == 1 { if _, ok := tx.GetMsgs()[0].(*evmtypes.WrappedEthereumTransaction); ok { + if ah.isValidator { + return ctx, errors.New("validator cannot accept EVM from comet") + } return ah.evmAnteHandler(ctx, tx, simulate) } else if _, ok = tx.GetMsgs()[0].(*evmtypes.WrappedPayloadEnvelope); ok { if ctx.ExecMode() != sdk.ExecModeCheck { diff --git a/cosmos/runtime/runtime.go b/cosmos/runtime/runtime.go index 880ccaf84..4b4e91586 100644 --- a/cosmos/runtime/runtime.go +++ b/cosmos/runtime/runtime.go @@ -92,6 +92,8 @@ type Polaris struct { // into the txpool are happening during this process. The mempool object then read locks for // adding transactions into the txpool. blockBuilderMu sync.RWMutex + + cfg *eth.Config } // New creates a new Polaris runtime from the provided dependencies. @@ -105,6 +107,7 @@ func New( var err error p := &Polaris{ logger: logger, + cfg: cfg, } ctx := sdk.Context{}. @@ -129,6 +132,8 @@ func New( int64(cfg.Polar.LegacyTxPool.Lifetime), &p.blockBuilderMu, priceLimit, + p.cfg.Polar.IsValidator, + p.cfg.Polar.ValidatorJSONRPCEndpoint, ) return p @@ -163,7 +168,7 @@ func (p *Polaris) Build( } app.SetAnteHandler( - antelib.NewAnteHandler(p.WrappedTxPool, cosmHandler).AnteHandler(), + antelib.NewAnteHandler(p.WrappedTxPool, cosmHandler, p.cfg.Polar.IsValidator).AnteHandler(), ) return nil @@ -178,7 +183,7 @@ func (p *Polaris) SetupServices(clientCtx client.Context) error { // Initialize the txpool with a new transaction serializer. p.WrappedTxPool.Init(p.logger, clientCtx, libtx.NewSerializer[*ethtypes.Transaction]( - clientCtx.TxConfig, evmtypes.WrapTx)) + clientCtx.TxConfig, evmtypes.WrapTx), p.cfg.Polar.IsValidator) // Register services with Polaris. p.RegisterLifecycles([]node.Lifecycle{ diff --git a/cosmos/runtime/txpool/handler.go b/cosmos/runtime/txpool/handler.go index 069003b68..a3ae8afd2 100644 --- a/cosmos/runtime/txpool/handler.go +++ b/cosmos/runtime/txpool/handler.go @@ -96,28 +96,35 @@ type handler struct { // Queue for failed transactions failedTxs chan *failedTx + + isValidator bool } // newHandler creates a new handler. func newHandler( clientCtx TxBroadcaster, txPool TxSubProvider, serializer TxSerializer, - crc CometRemoteCache, logger log.Logger, + crc CometRemoteCache, logger log.Logger, isValidator bool, ) *handler { h := &handler{ - logger: logger, - clientCtx: clientCtx, - serializer: serializer, - crc: crc, - txPool: txPool, - txsCh: make(chan core.NewTxsEvent, txChanSize), - stopCh: make(chan struct{}), - failedTxs: make(chan *failedTx, txChanSize), + logger: logger, + clientCtx: clientCtx, + serializer: serializer, + crc: crc, + txPool: txPool, + txsCh: make(chan core.NewTxsEvent, txChanSize), + stopCh: make(chan struct{}), + failedTxs: make(chan *failedTx, txChanSize), + isValidator: isValidator, } return h } // Start starts the handler. func (h *handler) Start() error { + if h.isValidator { + return nil + } + if h.running.Load() { return errors.New("handler already started") } @@ -129,6 +136,9 @@ func (h *handler) Start() error { // Stop stops the handler. func (h *handler) Stop() error { + if h.isValidator { + return nil + } if !h.Running() { return errors.New("handler already stopped") } diff --git a/cosmos/runtime/txpool/handler_test.go b/cosmos/runtime/txpool/handler_test.go index a99202a26..f0f8172cc 100644 --- a/cosmos/runtime/txpool/handler_test.go +++ b/cosmos/runtime/txpool/handler_test.go @@ -60,7 +60,7 @@ var _ = Describe("", func() { subprovider = mocks.NewTxSubProvider(t) subprovider.On("SubscribeTransactions", mock.Anything, mock.Anything).Return(subscription) serializer = mocks.NewTxSerializer(t) - h = newHandler(broadcaster, subprovider, serializer, newCometRemoteCache(), log.NewTestLogger(t)) + h = newHandler(broadcaster, subprovider, serializer, newCometRemoteCache(), log.NewTestLogger(t), false) err := h.Start() Expect(err).NotTo(HaveOccurred()) for !h.Running() { diff --git a/cosmos/runtime/txpool/mempool.go b/cosmos/runtime/txpool/mempool.go index 0d58c8b2a..cedf4a31d 100644 --- a/cosmos/runtime/txpool/mempool.go +++ b/cosmos/runtime/txpool/mempool.go @@ -39,6 +39,7 @@ import ( ethtxpool "github.com/ethereum/go-ethereum/core/txpool" ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethclient" ) // Mempool implements the mempool.Mempool & Lifecycle interfaces. @@ -70,20 +71,40 @@ type Mempool struct { crc CometRemoteCache blockBuilderMu *sync.RWMutex priceLimit *big.Int + + isValidator bool + validatorJsonRPC string + ethclient *ethclient.Client } // New creates a new Mempool. func New( chain core.ChainReader, txpool eth.TxPool, lifetime int64, - blockBuilderMu *sync.RWMutex, priceLimit *big.Int, + blockBuilderMu *sync.RWMutex, priceLimit *big.Int, isValidator bool, + validatorJsonRPC string, ) *Mempool { + var ( + ec *ethclient.Client + err error + ) + + if !isValidator && validatorJsonRPC == "" { + ec, err = ethclient.Dial(validatorJsonRPC) + if err != nil { + panic(err) + } + } + return &Mempool{ - TxPool: txpool, - chain: chain, - lifetime: lifetime, - crc: newCometRemoteCache(), - blockBuilderMu: blockBuilderMu, - priceLimit: priceLimit, + TxPool: txpool, + chain: chain, + lifetime: lifetime, + crc: newCometRemoteCache(), + blockBuilderMu: blockBuilderMu, + priceLimit: priceLimit, + isValidator: isValidator, + validatorJsonRPC: validatorJsonRPC, + ethclient: ec, } } @@ -92,8 +113,9 @@ func (m *Mempool) Init( logger log.Logger, txBroadcaster TxBroadcaster, txSerializer TxSerializer, + isValidator bool, ) { - m.handler = newHandler(txBroadcaster, m.TxPool, txSerializer, m.crc, logger) + m.handler = newHandler(txBroadcaster, m.TxPool, txSerializer, m.crc, logger, isValidator) } // Start starts the Mempool TxHandler. @@ -108,6 +130,10 @@ func (m *Mempool) Stop() error { // Insert attempts to insert a Tx into the app-side mempool returning an error upon failure. func (m *Mempool) Insert(ctx context.Context, sdkTx sdk.Tx) error { + if m.isValidator { + return errors.New("validator cannot insert transactions into the mempool from comet") + } + sCtx := sdk.UnwrapSDKContext(ctx) msgs := sdkTx.GetMsgs() if len(msgs) != 1 { @@ -123,6 +149,13 @@ 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.isValidator && m.ethclient != nil { + // Broadcast the transaction to the validator. + // Note: we don't care about the response here. + _ = m.ethclient.SendTransaction(context.Background(), ethTx) + } + // Insert the tx into the txpool as a remote. m.blockBuilderMu.RLock() errs := m.TxPool.Add([]*ethtypes.Transaction{ethTx}, false, false) diff --git a/eth/polar/config.go b/eth/polar/config.go index 1de919bc6..0ec70fcab 100644 --- a/eth/polar/config.go +++ b/eth/polar/config.go @@ -102,4 +102,7 @@ type Config struct { // RPCTxFeeCap is the global transaction fee(price * gaslimit) cap for // send-transaction variants. The unit is ether. RPCTxFeeCap float64 + + ValidatorJSONRPCEndpoint string + IsValidator bool }