Skip to content

Commit d320d83

Browse files
committed
Fix deadlock in SimulatedBeacon.loop
1 parent 7aafad2 commit d320d83

File tree

1 file changed

+17
-3
lines changed

1 file changed

+17
-3
lines changed

eth/catalyst/simulated_beacon_api.go

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package catalyst
1818

1919
import (
2020
"context"
21+
"sync/atomic"
2122
"time"
2223

2324
"github.com/ethereum/go-ethereum/common"
@@ -32,8 +33,9 @@ type api struct {
3233

3334
func (a *api) loop() {
3435
var (
35-
newTxs = make(chan core.NewTxsEvent)
36-
sub = a.sim.eth.TxPool().SubscribeTransactions(newTxs, true)
36+
committing atomic.Bool
37+
newTxs = make(chan core.NewTxsEvent)
38+
sub = a.sim.eth.TxPool().SubscribeTransactions(newTxs, true)
3739
)
3840
defer sub.Unsubscribe()
3941

@@ -42,12 +44,24 @@ func (a *api) loop() {
4244
case <-a.sim.shutdownCh:
4345
return
4446
case w := <-a.sim.withdrawals.pending:
47+
// FIXME: `sealBlock` will block the loop and `newTxs` won't be
48+
// read. If new TX will be submitted to the pool while we're
49+
// sealing the block, deadlock will occur.
4550
withdrawals := append(a.sim.withdrawals.gatherPending(9), w)
4651
if err := a.sim.sealBlock(withdrawals, uint64(time.Now().Unix())); err != nil {
4752
log.Warn("Error performing sealing work", "err", err)
4853
}
4954
case <-newTxs:
50-
a.sim.Commit()
55+
go func() {
56+
if committing.Swap(true) {
57+
return
58+
}
59+
a.sim.Commit()
60+
// FIXME: This is race-y, if `newTxs` arrive after we
61+
// `Commit`ted but before we unset `committing`, `newTxs` will
62+
// be skipped. Needs redesign.
63+
committing.Store(false)
64+
}()
5165
}
5266
}
5367
}

0 commit comments

Comments
 (0)