From 2cdce538f45244c29dc409e4bac56f42dde10921 Mon Sep 17 00:00:00 2001 From: Lee Bousfield Date: Wed, 18 Sep 2024 14:02:39 -0500 Subject: [PATCH 1/3] Improve stability of getNodeCreationBlock for L3s --- staker/rollup_watcher.go | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/staker/rollup_watcher.go b/staker/rollup_watcher.go index 5ef28a49dc..cd7e5d059d 100644 --- a/staker/rollup_watcher.go +++ b/staker/rollup_watcher.go @@ -4,16 +4,19 @@ package staker import ( + "bytes" "context" "encoding/binary" "errors" "fmt" "math/big" + "strings" "sync/atomic" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rpc" "github.com/offchainlabs/nitro/arbutil" "github.com/offchainlabs/nitro/solgen/go/rollupgen" "github.com/offchainlabs/nitro/util/headerreader" @@ -51,6 +54,7 @@ type RollupWatcher struct { client arbutil.L1Interface baseCallOpts bind.CallOpts unSupportedL3Method atomic.Bool + supportedL3Method atomic.Bool } func NewRollupWatcher(address common.Address, client arbutil.L1Interface, callOpts bind.CallOpts) (*RollupWatcher, error) { @@ -73,15 +77,40 @@ func (r *RollupWatcher) getCallOpts(ctx context.Context) *bind.CallOpts { return &opts } +const noNodeErr string = "NO_NODE" + +func looksLikeNoNodeError(err error) bool { + if err == nil { + return false + } + if strings.Contains(err.Error(), noNodeErr) { + return true + } + errWithData, ok := err.(rpc.DataError) + if !ok { + return false + } + dataString, ok := errWithData.ErrorData().(string) + if !ok { + return false + } + data := common.FromHex(dataString) + return bytes.Contains(data, []byte(noNodeErr)) +} + func (r *RollupWatcher) getNodeCreationBlock(ctx context.Context, nodeNum uint64) (*big.Int, error) { callOpts := r.getCallOpts(ctx) if !r.unSupportedL3Method.Load() { createdAtBlock, err := r.GetNodeCreationBlockForLogLookup(callOpts, nodeNum) if err == nil { + r.supportedL3Method.Store(true) return createdAtBlock, nil } - log.Trace("failed to call getNodeCreationBlockForLogLookup, falling back on node CreatedAtBlock field", "err", err) - if headerreader.ExecutionRevertedRegexp.MatchString(err.Error()) { + if headerreader.ExecutionRevertedRegexp.MatchString(err.Error()) && !looksLikeNoNodeError(err) { + if r.supportedL3Method.Load() { + return nil, fmt.Errorf("getNodeCreationBlockForLogLookup failed despite previously succeeding: %w", err) + } + log.Trace("failed to call getNodeCreationBlockForLogLookup, falling back on node CreatedAtBlock field", "err", err) r.unSupportedL3Method.Store(true) } else { return nil, err From 32a601ccc8ab957c285ac573b03cea8b0b6c5acc Mon Sep 17 00:00:00 2001 From: Lee Bousfield Date: Wed, 18 Sep 2024 14:05:07 -0500 Subject: [PATCH 2/3] Fix linter --- staker/rollup_watcher.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/staker/rollup_watcher.go b/staker/rollup_watcher.go index cd7e5d059d..3219566549 100644 --- a/staker/rollup_watcher.go +++ b/staker/rollup_watcher.go @@ -86,7 +86,8 @@ func looksLikeNoNodeError(err error) bool { if strings.Contains(err.Error(), noNodeErr) { return true } - errWithData, ok := err.(rpc.DataError) + var errWithData rpc.DataError + ok := errors.As(err, &errWithData) if !ok { return false } From 0b40afb6eb5ff02376cd5ea307cd02a74d42e353 Mon Sep 17 00:00:00 2001 From: Lee Bousfield Date: Mon, 30 Sep 2024 21:45:52 -0500 Subject: [PATCH 3/3] Upgrade getNodeCreationBlockForLogLookup log to Info --- staker/rollup_watcher.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/staker/rollup_watcher.go b/staker/rollup_watcher.go index 3219566549..324ec23ab9 100644 --- a/staker/rollup_watcher.go +++ b/staker/rollup_watcher.go @@ -111,7 +111,7 @@ func (r *RollupWatcher) getNodeCreationBlock(ctx context.Context, nodeNum uint64 if r.supportedL3Method.Load() { return nil, fmt.Errorf("getNodeCreationBlockForLogLookup failed despite previously succeeding: %w", err) } - log.Trace("failed to call getNodeCreationBlockForLogLookup, falling back on node CreatedAtBlock field", "err", err) + log.Info("getNodeCreationBlockForLogLookup does not seem to exist, falling back on node CreatedAtBlock field", "err", err) r.unSupportedL3Method.Store(true) } else { return nil, err