mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-23 13:16:42 +00:00
core/txpool/blobpool: wait for billy conversion to exit
This commit is contained in:
parent
aefa3fc016
commit
e05bf5b320
2 changed files with 49 additions and 20 deletions
|
|
@ -904,7 +904,9 @@ func (p *BlobPool) Reset(oldHead, newHead *types.Header) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Initiate the background conversion thread.
|
// Initiate the background conversion thread.
|
||||||
go p.convertLegacySidecars(ids, txs)
|
p.cQueue.launchBillyConversion(func() {
|
||||||
|
p.convertLegacySidecars(ids, txs)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -913,7 +915,7 @@ func (p *BlobPool) Reset(oldHead, newHead *types.Header) {
|
||||||
// bulk conversion. If it fails for some reason, the subsequent txs won't be dropped
|
// bulk conversion. If it fails for some reason, the subsequent txs won't be dropped
|
||||||
// for simplicity which we assume it's very likely to happen.
|
// for simplicity which we assume it's very likely to happen.
|
||||||
//
|
//
|
||||||
// The returned flag indicates whether the replacement succeeds or not.
|
// The returned flag indicates whether the replacement succeeded.
|
||||||
func (p *BlobPool) compareAndSwap(address common.Address, hash common.Hash, blob []byte, oldID uint64, oldStorageSize uint32) bool {
|
func (p *BlobPool) compareAndSwap(address common.Address, hash common.Hash, blob []byte, oldID uint64, oldStorageSize uint32) bool {
|
||||||
p.lock.Lock()
|
p.lock.Lock()
|
||||||
defer p.lock.Unlock()
|
defer p.lock.Unlock()
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,8 @@ import (
|
||||||
// with 6 blobs each) would consume approximately 1.5GB of memory.
|
// with 6 blobs each) would consume approximately 1.5GB of memory.
|
||||||
const maxPendingConversionTasks = 2048
|
const maxPendingConversionTasks = 2048
|
||||||
|
|
||||||
// cTask represents a conversion task with an attached legacy blob transaction.
|
// txConvert represents a conversion task with an attached legacy blob transaction.
|
||||||
type cTask struct {
|
type txConvert struct {
|
||||||
tx *types.Transaction // Legacy blob transaction
|
tx *types.Transaction // Legacy blob transaction
|
||||||
done chan error // Channel for signaling back if the conversion succeeds
|
done chan error // Channel for signaling back if the conversion succeeds
|
||||||
}
|
}
|
||||||
|
|
@ -43,7 +43,8 @@ type cTask struct {
|
||||||
// it is performed in the background by a single thread, ensuring the main Geth
|
// it is performed in the background by a single thread, ensuring the main Geth
|
||||||
// process is not overloaded.
|
// process is not overloaded.
|
||||||
type conversionQueue struct {
|
type conversionQueue struct {
|
||||||
tasks chan *cTask
|
tasks chan *txConvert
|
||||||
|
billy chan func()
|
||||||
quit chan struct{}
|
quit chan struct{}
|
||||||
closed chan struct{}
|
closed chan struct{}
|
||||||
}
|
}
|
||||||
|
|
@ -51,7 +52,8 @@ type conversionQueue struct {
|
||||||
// newConversionQueue constructs the conversion queue.
|
// newConversionQueue constructs the conversion queue.
|
||||||
func newConversionQueue() *conversionQueue {
|
func newConversionQueue() *conversionQueue {
|
||||||
q := &conversionQueue{
|
q := &conversionQueue{
|
||||||
tasks: make(chan *cTask),
|
tasks: make(chan *txConvert),
|
||||||
|
billy: make(chan func()),
|
||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
closed: make(chan struct{}),
|
closed: make(chan struct{}),
|
||||||
}
|
}
|
||||||
|
|
@ -66,13 +68,23 @@ func newConversionQueue() *conversionQueue {
|
||||||
func (q *conversionQueue) convert(tx *types.Transaction) error {
|
func (q *conversionQueue) convert(tx *types.Transaction) error {
|
||||||
done := make(chan error, 1)
|
done := make(chan error, 1)
|
||||||
select {
|
select {
|
||||||
case q.tasks <- &cTask{tx: tx, done: done}:
|
case q.tasks <- &txConvert{tx: tx, done: done}:
|
||||||
return <-done
|
return <-done
|
||||||
case <-q.closed:
|
case <-q.closed:
|
||||||
return errors.New("conversion queue closed")
|
return errors.New("conversion queue closed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// launchBillyConversion starts a conversion task in the background.
|
||||||
|
func (q *conversionQueue) launchBillyConversion(fn func()) error {
|
||||||
|
select {
|
||||||
|
case q.billy <- fn:
|
||||||
|
return nil
|
||||||
|
case <-q.closed:
|
||||||
|
return errors.New("conversion queue closed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// close terminates the conversion queue.
|
// close terminates the conversion queue.
|
||||||
func (q *conversionQueue) close() {
|
func (q *conversionQueue) close() {
|
||||||
select {
|
select {
|
||||||
|
|
@ -85,7 +97,7 @@ func (q *conversionQueue) close() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// run converts a batch of legacy blob txs to the new cell proof format.
|
// run converts a batch of legacy blob txs to the new cell proof format.
|
||||||
func (q *conversionQueue) run(tasks []*cTask, done chan struct{}, interrupt *atomic.Int32) {
|
func (q *conversionQueue) run(tasks []*txConvert, done chan struct{}, interrupt *atomic.Int32) {
|
||||||
defer close(done)
|
defer close(done)
|
||||||
|
|
||||||
for _, t := range tasks {
|
for _, t := range tasks {
|
||||||
|
|
@ -110,42 +122,57 @@ func (q *conversionQueue) loop() {
|
||||||
defer close(q.closed)
|
defer close(q.closed)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
done chan struct{} // Non-nil if background routine is active
|
billyDone = make(chan struct{})
|
||||||
interrupt *atomic.Int32 // Flag to signal conversion interruption
|
billyTasks int // Count of running billy conversion tasks
|
||||||
|
done chan struct{} // Non-nil if background routine is active
|
||||||
|
interrupt *atomic.Int32 // Flag to signal conversion interruption
|
||||||
|
|
||||||
// The pending tasks for sidecar conversion. We assume the number of legacy
|
// The pending tasks for sidecar conversion. We assume the number of legacy
|
||||||
// blob transactions requiring conversion will not be excessive. However,
|
// blob transactions requiring conversion will not be excessive. However,
|
||||||
// a hard cap is applied as a protective measure.
|
// a hard cap is applied as a protective measure.
|
||||||
cTasks []*cTask
|
txTasks []*txConvert
|
||||||
)
|
)
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case t := <-q.tasks:
|
case t := <-q.tasks:
|
||||||
if len(cTasks) >= maxPendingConversionTasks {
|
if len(txTasks) >= maxPendingConversionTasks {
|
||||||
t.done <- errors.New("conversion queue is overloaded")
|
t.done <- errors.New("conversion queue is overloaded")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
cTasks = append(cTasks, t)
|
txTasks = append(txTasks, t)
|
||||||
|
|
||||||
// Launch the background conversion thread if it's idle
|
// Launch the background conversion thread if it's idle
|
||||||
if done == nil {
|
if done == nil {
|
||||||
done, interrupt = make(chan struct{}), new(atomic.Int32)
|
done, interrupt = make(chan struct{}), new(atomic.Int32)
|
||||||
|
|
||||||
tasks := slices.Clone(cTasks)
|
tasks := slices.Clone(txTasks)
|
||||||
cTasks = cTasks[:0]
|
txTasks = txTasks[:0]
|
||||||
go q.run(tasks, done, interrupt)
|
go q.run(tasks, done, interrupt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case fn := <-q.billy:
|
||||||
|
billyTasks++
|
||||||
|
go func() {
|
||||||
|
fn()
|
||||||
|
billyDone <- struct{}{}
|
||||||
|
}()
|
||||||
|
|
||||||
case <-done:
|
case <-done:
|
||||||
done, interrupt = nil, nil
|
done, interrupt = nil, nil
|
||||||
|
|
||||||
|
case <-billyDone:
|
||||||
|
billyTasks--
|
||||||
|
|
||||||
case <-q.quit:
|
case <-q.quit:
|
||||||
if done == nil {
|
if done != nil {
|
||||||
return
|
interrupt.Store(1)
|
||||||
|
log.Debug("Waiting for blob proof conversion to exit")
|
||||||
|
<-done
|
||||||
|
}
|
||||||
|
for billyTasks > 0 {
|
||||||
|
<-billyDone
|
||||||
|
billyTasks--
|
||||||
}
|
}
|
||||||
interrupt.Store(1)
|
|
||||||
log.Debug("Waiting for blob proof conversion to exit")
|
|
||||||
<-done
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue