diff --git a/ethergo/listener/listener.go b/ethergo/listener/listener.go index 8e8befd582..8c02dba98f 100644 --- a/ethergo/listener/listener.go +++ b/ethergo/listener/listener.go @@ -12,6 +12,7 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rpc" "github.com/ipfs/go-log" "github.com/jpillora/backoff" "github.com/synapsecns/sanguine/core/metrics" @@ -48,6 +49,8 @@ type chainListener struct { pollInterval, pollIntervalSetting time.Duration // newBlockHandler is an optional handler that is called when a new block is detected. newBlockHandler NewBlockHandler + finalityMode rpc.BlockNumber + blockWait uint64 } var ( @@ -66,6 +69,8 @@ func NewChainListener(omnirpcClient client.EVM, store listenerDB.ChainListenerDB client: omnirpcClient, backoff: newBackoffConfig(), pollIntervalSetting: time.Millisecond * 50, + finalityMode: FinalityModeLatest, + blockWait: 0, } for _, option := range options { @@ -183,6 +188,25 @@ func (c *chainListener) doPoll(parentCtx context.Context, handler HandleLog) (er return nil } +func (c chainListener) getBlockNumber(ctx context.Context) (uint64, error) { + var block *types.Block + var err error + + block, err = c.client.BlockByNumber(ctx, big.NewInt(c.finalityMode.Int64())) + + if err != nil { + return 0, err + } + + blockNumber := block.Number() + + if c.blockWait > 0 { + blockNumber.Sub(blockNumber, big.NewInt(int64(c.blockWait))) + } + + return blockNumber.Uint64(), nil +} + func (c chainListener) getMetadata(parentCtx context.Context) (startBlock, chainID uint64, err error) { var lastIndexed uint64 ctx, span := c.handler.Tracer().Start(parentCtx, "getMetadata") diff --git a/ethergo/listener/options.go b/ethergo/listener/options.go index 89c45c759d..c0e976efcf 100644 --- a/ethergo/listener/options.go +++ b/ethergo/listener/options.go @@ -3,6 +3,8 @@ package listener import ( "context" "time" + + "github.com/ethereum/go-ethereum/rpc" ) // Option is a functional option for chainListener. @@ -24,3 +26,25 @@ func WithPollInterval(interval time.Duration) Option { c.pollIntervalSetting = interval } } + +// FinalityMode represents the finality mode for block queries. + +const ( + FinalityModeSafe rpc.BlockNumber = rpc.SafeBlockNumber + FinalityModeFinalized rpc.BlockNumber = rpc.FinalizedBlockNumber + FinalityModeLatest rpc.BlockNumber = rpc.FinalizedBlockNumber +) + +// WithFinalityMode sets the finality mode. +func WithFinalityMode(mode rpc.BlockNumber) Option { + return func(c *chainListener) { + c.finalityMode = mode + } +} + +// WithBlockWait sets the block wait. +func WithBlockWait(wait uint64) Option { + return func(c *chainListener) { + c.blockWait = wait + } +}