Try using a custom error type

This way, we only break the spinloop when it is definitely because the
transaction pool has already been terminated.
This commit is contained in:
Pepper Lebeck-Jobe 2025-03-07 17:48:23 +01:00
parent f6d5b76b2c
commit 71d4441981
No known key found for this signature in database
2 changed files with 20 additions and 5 deletions

View file

@ -80,6 +80,17 @@ func (w *withdrawalQueue) subscribe(ch chan<- newWithdrawalsEvent) event.Subscri
return w.subs.Track(sub) return w.subs.Track(sub)
} }
// txPoolTerminatedError is returned when the txpool is already terminated when
// trying to seal a block.
type txPoolTerminatedError struct {
error
}
// Error returns the message from the wrapped error.
func (t *txPoolTerminatedError) Error() string {
return t.error.Error()
}
// SimulatedBeacon drives an Ethereum instance as if it were a real beacon // SimulatedBeacon drives an Ethereum instance as if it were a real beacon
// client. It can run in period mode where it mines a new block every period // client. It can run in period mode where it mines a new block every period
// (seconds) or on every transaction via Commit, Fork and AdjustTime. // (seconds) or on every transaction via Commit, Fork and AdjustTime.
@ -181,7 +192,7 @@ func (c *SimulatedBeacon) sealBlock(withdrawals []*types.Withdrawal, timestamp u
// behavior, the pool will be explicitly blocked on its reset before // behavior, the pool will be explicitly blocked on its reset before
// continuing to the block production below. // continuing to the block production below.
if err := c.eth.APIBackend.TxPool().Sync(); err != nil { if err := c.eth.APIBackend.TxPool().Sync(); err != nil {
return fmt.Errorf("failed to sync txpool: %w", err) return &txPoolTerminatedError{fmt.Errorf("failed to sync txpool: %w", err)}
} }
version := payloadVersion(c.eth.BlockChain().Config(), timestamp) version := payloadVersion(c.eth.BlockChain().Config(), timestamp)
@ -302,12 +313,12 @@ func (c *SimulatedBeacon) setCurrentState(headHash, finalizedHash common.Hash) {
// Commit seals a block on demand. // Commit seals a block on demand.
func (c *SimulatedBeacon) Commit() common.Hash { func (c *SimulatedBeacon) Commit() common.Hash {
hash, _ := c.fallibleCommit() hash, _ := c.commit()
return hash return hash
} }
// fallibleCommit attempts to seal a block on demand, but may return an error. // fallibleCommit attempts to seal a block on demand, but may return an error.
func (c *SimulatedBeacon) fallibleCommit() (common.Hash, error) { func (c *SimulatedBeacon) commit() (common.Hash, error) {
withdrawals := c.withdrawals.pop(10) withdrawals := c.withdrawals.pop(10)
if err := c.sealBlock(withdrawals, uint64(time.Now().Unix())); err != nil { if err := c.sealBlock(withdrawals, uint64(time.Now().Unix())); err != nil {
log.Warn("Error performing sealing work", "err", err) log.Warn("Error performing sealing work", "err", err)

View file

@ -18,6 +18,7 @@ package catalyst
import ( import (
"context" "context"
"errors"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
@ -71,8 +72,11 @@ func (a *simulatedBeaconAPI) loop() {
break break
} }
// Avoids spinlooping if the txPool is alredy terminated. // Avoids spinlooping if the txPool is alredy terminated.
if _, err := a.sim.fallibleCommit(); err != nil { if _, err := a.sim.commit(); err != nil {
break var txpTermErr *txPoolTerminatedError
if errors.As(err, &txpTermErr) {
break
}
} }
} }
} }