diff --git a/core/txpool/blobpool/cache.go b/core/txpool/blobpool/cache.go index 23f53f0fc1..a6632ddb6c 100644 --- a/core/txpool/blobpool/cache.go +++ b/core/txpool/blobpool/cache.go @@ -81,11 +81,11 @@ type Cache struct { needCell bool // channels into loop - quit chan struct{} - topkRequest chan struct{} - topkTimer mclock.Timer - hasBlobsCh chan []common.Hash // list of tx hashes that should be pinned - enableCellCh chan struct{} // signals the loop to switch to cell mode + quit chan struct{} + topkRequest chan struct{} + topkTimer mclock.Timer + hasBlobsCh chan []common.Hash // list of tx hashes that should be pinned + cellModeCh chan bool // signals the loop to switch cell mode on/offo step func() // test hook fired after each loop iteration @@ -103,14 +103,14 @@ func NewCache(p *BlobPool) *Cache { // It allows injecting a clock and a step hook. func newCache(p *BlobPool, clock mclock.Clock, step func()) *Cache { c := &Cache{ - entries: make(map[common.Hash]*cachedBlob), - blobpool: p, - hasBlobsCh: make(chan []common.Hash, 1), - clock: clock, - step: step, - quit: make(chan struct{}), - topkRequest: make(chan struct{}, 1), - enableCellCh: make(chan struct{}, 1), + entries: make(map[common.Hash]*cachedBlob), + blobpool: p, + hasBlobsCh: make(chan []common.Hash, 1), + clock: clock, + step: step, + quit: make(chan struct{}), + topkRequest: make(chan struct{}, 1), + cellModeCh: make(chan bool, 1), } c.wg.Add(1) @@ -311,9 +311,9 @@ func (c *Cache) GetCells(vhashes []common.Hash, mask types.CustodyBitmap) ([][]* // blobs. This means we can also cache cells that lack enough blobs to // recover. It signals the loop to switch to cell mode and re-select // transactions from this wider pool. -func (c *Cache) EnableCell() { +func (c *Cache) SetCellMode(on bool) { select { - case c.enableCellCh <- struct{}{}: + case c.cellModeCh <- on: case <-c.quit: } } @@ -335,13 +335,11 @@ func (c *Cache) loop() { c.update(want) c.triggerTopKAfter(topKTimeout) - case <-c.enableCellCh: - // CL supports cell-based blob retrieval; switch to cell mode and - // re-select immediately over the now-wider pool. needCell is only - // touched here in the loop, so a fresh selection and update observe - // a consistent value. - if !c.needCell { - c.needCell = true + case on := <-c.cellModeCh: + // This runs when the CL signals (non-)support for cell proofs. Enable/disable + // cell mode and re-select immediately to force an update. + if c.needCell != on { + c.needCell = on c.triggerTopK() } diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go index f485633f0a..ba153b196d 100644 --- a/eth/catalyst/api.go +++ b/eth/catalyst/api.go @@ -22,6 +22,7 @@ import ( "errors" "fmt" "reflect" + "slices" "strconv" "sync" "sync/atomic" @@ -1198,17 +1199,13 @@ func (api *ConsensusAPI) checkFork(timestamp uint64, forks ...forks.Fork) bool { func (api *ConsensusAPI) ExchangeCapabilities(caps []string) []string { valueT := reflect.TypeOf(api) - for _, cap := range caps { - if cap == "engine_getBlobsV4" { - // If the CL supports getBlobsV4, we call EnableCell() on the - // blob cache to skip the blob recovery process. This is a - // one-directional toggle, which assumes that once the CL - // supports getBlobsV4, it will not fall back to getBlobsV3 - // again. - api.eth.BlobCache().EnableCell() - break - } - } + // If the CL supports getBlobsV4, we call EnableCell() on the + // blob cache to skip the blob recovery process. This is a + // one-directional toggle, which assumes that once the CL + // supports getBlobsV4, it will not fall back to getBlobsV3 + // again. + cellmode := slices.Contains(caps, "engine_getBlobsV4") + api.eth.BlobCache().SetCellMode(cellmode) ourCaps := make([]string, 0, valueT.NumMethod()) for i := 0; i < valueT.NumMethod(); i++ {