Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions eth/catalyst/simulated_beacon.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,17 @@ func (w *withdrawalQueue) subscribe(ch chan<- newWithdrawalsEvent) event.Subscri
return w.subs.Track(sub)
}

// errTxPoolTerminated is returned when the txpool is already terminated when
// trying to seal a block.
type errTxPoolTerminated struct {
error
}

// Error returns the message from the wrapped error.
func (t *errTxPoolTerminated) Error() string {
return fmt.Errorf("failed to sync txpool: %w", t.error).Error()
}

// 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
// (seconds) or on every transaction via Commit, Fork and AdjustTime.
Expand Down Expand Up @@ -181,7 +192,7 @@ func (c *SimulatedBeacon) sealBlock(withdrawals []*types.Withdrawal, timestamp u
// behavior, the pool will be explicitly blocked on its reset before
// continuing to the block production below.
if err := c.eth.APIBackend.TxPool().Sync(); err != nil {
return fmt.Errorf("failed to sync txpool: %w", err)
return &errTxPoolTerminated{err}
}

version := payloadVersion(c.eth.BlockChain().Config(), timestamp)
Expand Down Expand Up @@ -302,11 +313,18 @@ func (c *SimulatedBeacon) setCurrentState(headHash, finalizedHash common.Hash) {

// Commit seals a block on demand.
func (c *SimulatedBeacon) Commit() common.Hash {
hash, _ := c.commit()
return hash
}

// commit attempts to seal a block on demand, but may return an error.
func (c *SimulatedBeacon) commit() (common.Hash, error) {
withdrawals := c.withdrawals.pop(10)
if err := c.sealBlock(withdrawals, uint64(time.Now().Unix())); err != nil {
log.Warn("Error performing sealing work", "err", err)
return common.Hash{}, err
}
return c.eth.BlockChain().CurrentBlock().Hash()
return c.eth.BlockChain().CurrentBlock().Hash(), nil
}

// Rollback un-sends previously added transactions.
Expand Down
8 changes: 7 additions & 1 deletion eth/catalyst/simulated_beacon_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package catalyst

import (
"context"
"errors"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
Expand Down Expand Up @@ -70,7 +71,12 @@ func (a *simulatedBeaconAPI) loop() {
if executable, _ := a.sim.eth.TxPool().Stats(); executable == 0 {
break
}
a.sim.Commit()
// Avoids spinlooping if the txPool is alredy terminated.
if _, err := a.sim.commit(); err != nil {
if errors.Is(err, &errTxPoolTerminated{}) {
break
}
}
}
}
}()
Expand Down