diff --git a/miner/taiko_payload_building.go b/miner/taiko_payload_building.go index c3f2fc830ec2..7458ee1ae2cb 100644 --- a/miner/taiko_payload_building.go +++ b/miner/taiko_payload_building.go @@ -13,17 +13,7 @@ func (payload *Payload) SetFullBlock(block *types.Block, fees *big.Int) { payload.lock.Lock() defer payload.lock.Unlock() - go func() { - payload.lock.Lock() - defer payload.lock.Unlock() - - select { - case <-payload.done: - log.Info("SetFullBlock payload done received", "id", payload.id) - case payload.stop <- struct{}{}: - default: - } - }() + go payload.afterSetFullBlock() payload.full = block payload.fullFees = fees @@ -35,3 +25,20 @@ func (payload *Payload) SetFullBlock(block *types.Block, fees *big.Int) { payload.cond.Broadcast() // fire signal for notifying full block } + +func (payload *Payload) afterSetFullBlock() { + payload.lock.Lock() + defer payload.lock.Unlock() + + select { + case <-payload.done: + log.Info("SetFullBlock payload done received", "id", payload.id) + return + default: + } + + select { + case payload.stop <- struct{}{}: + default: + } +} diff --git a/miner/taiko_payload_building_test.go b/miner/taiko_payload_building_test.go index c64286936586..a00581a05a60 100644 --- a/miner/taiko_payload_building_test.go +++ b/miner/taiko_payload_building_test.go @@ -53,6 +53,63 @@ func Test_SetFullBlock_AvoidPanic(t *testing.T) { payload.SetFullBlock(block, fees) } +func Test_AfterSetFullBlock_Panic_DoneChannelNotSent(t *testing.T) { + var ( + db = rawdb.NewMemoryDatabase() + recipient = common.HexToAddress("0xdeadbeef") + ) + w, b := newTestWorker(t, params.TestChainConfig, ethash.NewFaker(), db, 0) + defer w.close() + + timestamp := uint64(time.Now().Unix()) + args := &BuildPayloadArgs{ + Parent: b.chain.CurrentBlock().Hash(), + Timestamp: timestamp, + Random: common.Hash{}, + FeeRecipient: recipient, + } + payload, err := w.buildPayload(args) + if err != nil { + t.Fatalf("Failed to build payload %v", err) + } + + // dont send on done channel, but close stop channel. + // should panic when sent on. + close(payload.stop) + + assert.Panics(t, func() { + payload.afterSetFullBlock() + }) +} + +func Test_AfterSetFullBlock_AvoidPanic_DoneChannelSent(t *testing.T) { + var ( + db = rawdb.NewMemoryDatabase() + recipient = common.HexToAddress("0xdeadbeef") + ) + w, b := newTestWorker(t, params.TestChainConfig, ethash.NewFaker(), db, 0) + defer w.close() + + timestamp := uint64(time.Now().Unix()) + args := &BuildPayloadArgs{ + Parent: b.chain.CurrentBlock().Hash(), + Timestamp: timestamp, + Random: common.Hash{}, + FeeRecipient: recipient, + } + payload, err := w.buildPayload(args) + if err != nil { + t.Fatalf("Failed to build payload %v", err) + } + + payload.done <- struct{}{} + close(payload.stop) + + assert.NotPanics(t, func() { + payload.afterSetFullBlock() + }) +} + func Test_SetFullBlock(t *testing.T) { var ( db = rawdb.NewMemoryDatabase()