mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 07:06:42 +00:00
attempt at making txpool Add sync param work
This commit is contained in:
parent
a7f24c26c0
commit
c5055a88b3
4 changed files with 66 additions and 14 deletions
|
|
@ -19,6 +19,7 @@ package legacypool
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"maps"
|
"maps"
|
||||||
"math"
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
@ -246,7 +247,7 @@ type LegacyPool struct {
|
||||||
priced *pricedList // All transactions sorted by price
|
priced *pricedList // All transactions sorted by price
|
||||||
|
|
||||||
reqResetCh chan *txpoolResetRequest
|
reqResetCh chan *txpoolResetRequest
|
||||||
reqPromoteCh chan *accountSet
|
reqPromoteCh chan *reqPromote
|
||||||
queueTxEventCh chan *types.Transaction
|
queueTxEventCh chan *types.Transaction
|
||||||
reorgDoneCh chan chan struct{}
|
reorgDoneCh chan chan struct{}
|
||||||
reorgShutdownCh chan struct{} // requests shutdown of scheduleReorgLoop
|
reorgShutdownCh chan struct{} // requests shutdown of scheduleReorgLoop
|
||||||
|
|
@ -258,6 +259,7 @@ type LegacyPool struct {
|
||||||
|
|
||||||
type txpoolResetRequest struct {
|
type txpoolResetRequest struct {
|
||||||
oldHead, newHead *types.Header
|
oldHead, newHead *types.Header
|
||||||
|
done chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new transaction pool to gather, sort and filter inbound
|
// New creates a new transaction pool to gather, sort and filter inbound
|
||||||
|
|
@ -277,7 +279,7 @@ func New(config Config, chain BlockChain) *LegacyPool {
|
||||||
beats: make(map[common.Address]time.Time),
|
beats: make(map[common.Address]time.Time),
|
||||||
all: newLookup(),
|
all: newLookup(),
|
||||||
reqResetCh: make(chan *txpoolResetRequest),
|
reqResetCh: make(chan *txpoolResetRequest),
|
||||||
reqPromoteCh: make(chan *accountSet),
|
reqPromoteCh: make(chan *reqPromote),
|
||||||
queueTxEventCh: make(chan *types.Transaction),
|
queueTxEventCh: make(chan *types.Transaction),
|
||||||
reorgDoneCh: make(chan chan struct{}),
|
reorgDoneCh: make(chan chan struct{}),
|
||||||
reorgShutdownCh: make(chan struct{}),
|
reorgShutdownCh: make(chan struct{}),
|
||||||
|
|
@ -962,6 +964,9 @@ func (pool *LegacyPool) Add(txs []*types.Transaction, sync bool) []error {
|
||||||
pool.mu.Lock()
|
pool.mu.Lock()
|
||||||
newErrs, dirtyAddrs := pool.addTxsLocked(news)
|
newErrs, dirtyAddrs := pool.addTxsLocked(news)
|
||||||
pool.mu.Unlock()
|
pool.mu.Unlock()
|
||||||
|
for _, new := range news {
|
||||||
|
fmt.Printf("prepare tx for queue %x\n", new.Hash())
|
||||||
|
}
|
||||||
|
|
||||||
var nilSlot = 0
|
var nilSlot = 0
|
||||||
for _, err := range newErrs {
|
for _, err := range newErrs {
|
||||||
|
|
@ -972,9 +977,11 @@ func (pool *LegacyPool) Add(txs []*types.Transaction, sync bool) []error {
|
||||||
nilSlot++
|
nilSlot++
|
||||||
}
|
}
|
||||||
// Reorg the pool internals if needed and return
|
// Reorg the pool internals if needed and return
|
||||||
done := pool.requestPromoteExecutables(dirtyAddrs)
|
req := &reqPromote{dirtyAddrs, make(chan struct{})}
|
||||||
|
pool.requestPromoteExecutables(req)
|
||||||
if sync {
|
if sync {
|
||||||
<-done
|
<-req.done
|
||||||
|
fmt.Printf("done adding txs %v\n", txs[0])
|
||||||
}
|
}
|
||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
|
|
@ -1140,9 +1147,10 @@ func (pool *LegacyPool) removeTx(hash common.Hash, outofbound bool, unreserve bo
|
||||||
// requestReset requests a pool reset to the new head block.
|
// requestReset requests a pool reset to the new head block.
|
||||||
// The returned channel is closed when the reset has occurred.
|
// The returned channel is closed when the reset has occurred.
|
||||||
func (pool *LegacyPool) requestReset(oldHead *types.Header, newHead *types.Header) chan struct{} {
|
func (pool *LegacyPool) requestReset(oldHead *types.Header, newHead *types.Header) chan struct{} {
|
||||||
|
req := &txpoolResetRequest{oldHead, newHead, make(chan struct{})}
|
||||||
select {
|
select {
|
||||||
case pool.reqResetCh <- &txpoolResetRequest{oldHead, newHead}:
|
case pool.reqResetCh <- req:
|
||||||
return <-pool.reorgDoneCh
|
return req.done
|
||||||
case <-pool.reorgShutdownCh:
|
case <-pool.reorgShutdownCh:
|
||||||
return pool.reorgShutdownCh
|
return pool.reorgShutdownCh
|
||||||
}
|
}
|
||||||
|
|
@ -1150,10 +1158,10 @@ func (pool *LegacyPool) requestReset(oldHead *types.Header, newHead *types.Heade
|
||||||
|
|
||||||
// requestPromoteExecutables requests transaction promotion checks for the given addresses.
|
// requestPromoteExecutables requests transaction promotion checks for the given addresses.
|
||||||
// The returned channel is closed when the promotion checks have occurred.
|
// The returned channel is closed when the promotion checks have occurred.
|
||||||
func (pool *LegacyPool) requestPromoteExecutables(set *accountSet) chan struct{} {
|
func (pool *LegacyPool) requestPromoteExecutables(req *reqPromote) chan struct{} {
|
||||||
select {
|
select {
|
||||||
case pool.reqPromoteCh <- set:
|
case pool.reqPromoteCh <- req:
|
||||||
return <-pool.reorgDoneCh
|
return req.done
|
||||||
case <-pool.reorgShutdownCh:
|
case <-pool.reorgShutdownCh:
|
||||||
return pool.reorgShutdownCh
|
return pool.reorgShutdownCh
|
||||||
}
|
}
|
||||||
|
|
@ -1174,6 +1182,8 @@ func (pool *LegacyPool) scheduleReorgLoop() {
|
||||||
defer pool.wg.Done()
|
defer pool.wg.Done()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
curDones []chan struct{}
|
||||||
|
nextDones []chan struct{}
|
||||||
curDone chan struct{} // non-nil while runReorg is active
|
curDone chan struct{} // non-nil while runReorg is active
|
||||||
nextDone = make(chan struct{})
|
nextDone = make(chan struct{})
|
||||||
launchNextRun bool
|
launchNextRun bool
|
||||||
|
|
@ -1184,11 +1194,15 @@ func (pool *LegacyPool) scheduleReorgLoop() {
|
||||||
for {
|
for {
|
||||||
// Launch next background reorg if needed
|
// Launch next background reorg if needed
|
||||||
if curDone == nil && launchNextRun {
|
if curDone == nil && launchNextRun {
|
||||||
|
fmt.Printf("initiating reorg with dones %v\n", nextDones)
|
||||||
|
fmt.Printf("initiating reorg with dirty accounts: %v\n", dirtyAccounts)
|
||||||
|
|
||||||
// Run the background reorg and announcements
|
// Run the background reorg and announcements
|
||||||
go pool.runReorg(nextDone, reset, dirtyAccounts, queuedEvents)
|
go pool.runReorg(nextDone, reset, dirtyAccounts, queuedEvents)
|
||||||
|
|
||||||
// Prepare everything for the next round of reorg
|
// Prepare everything for the next round of reorg
|
||||||
curDone, nextDone = nextDone, make(chan struct{})
|
curDone, nextDone = nextDone, make(chan struct{})
|
||||||
|
curDones, nextDones = nextDones, []chan struct{}{}
|
||||||
launchNextRun = false
|
launchNextRun = false
|
||||||
|
|
||||||
reset, dirtyAccounts = nil, nil
|
reset, dirtyAccounts = nil, nil
|
||||||
|
|
@ -1203,20 +1217,37 @@ func (pool *LegacyPool) scheduleReorgLoop() {
|
||||||
} else {
|
} else {
|
||||||
reset.newHead = req.newHead
|
reset.newHead = req.newHead
|
||||||
}
|
}
|
||||||
|
fmt.Printf("reset: appending to next dones %v\n", req.done)
|
||||||
|
nextDones = append(nextDones, req.done)
|
||||||
launchNextRun = true
|
launchNextRun = true
|
||||||
pool.reorgDoneCh <- nextDone
|
//pool.reorgDoneCh <- nextDone
|
||||||
|
|
||||||
case req := <-pool.reqPromoteCh:
|
case req := <-pool.reqPromoteCh:
|
||||||
|
select {
|
||||||
|
case tx := <-pool.queueTxEventCh:
|
||||||
|
fmt.Printf("queue tx %x\n", tx.Hash())
|
||||||
|
// Queue up the event, but don't schedule a reorg. It's up to the caller to
|
||||||
|
// request one later if they want the events sent.
|
||||||
|
addr, _ := types.Sender(pool.signer, tx)
|
||||||
|
if _, ok := queuedEvents[addr]; !ok {
|
||||||
|
queuedEvents[addr] = NewSortedMap()
|
||||||
|
}
|
||||||
|
queuedEvents[addr].Put(tx)
|
||||||
|
default:
|
||||||
|
}
|
||||||
// Promote request: update address set if request is already pending.
|
// Promote request: update address set if request is already pending.
|
||||||
if dirtyAccounts == nil {
|
if dirtyAccounts == nil {
|
||||||
dirtyAccounts = req
|
dirtyAccounts = req.set
|
||||||
} else {
|
} else {
|
||||||
dirtyAccounts.merge(req)
|
dirtyAccounts.merge(req.set)
|
||||||
}
|
}
|
||||||
|
fmt.Printf("promote executables: appending to next dones %v\n", req.done)
|
||||||
|
nextDones = append(nextDones, req.done)
|
||||||
launchNextRun = true
|
launchNextRun = true
|
||||||
pool.reorgDoneCh <- nextDone
|
//pool.reorgDoneCh <- nextDone
|
||||||
|
|
||||||
case tx := <-pool.queueTxEventCh:
|
case tx := <-pool.queueTxEventCh:
|
||||||
|
fmt.Printf("queue tx %x\n", tx.Hash())
|
||||||
// Queue up the event, but don't schedule a reorg. It's up to the caller to
|
// Queue up the event, but don't schedule a reorg. It's up to the caller to
|
||||||
// request one later if they want the events sent.
|
// request one later if they want the events sent.
|
||||||
addr, _ := types.Sender(pool.signer, tx)
|
addr, _ := types.Sender(pool.signer, tx)
|
||||||
|
|
@ -1226,12 +1257,24 @@ func (pool *LegacyPool) scheduleReorgLoop() {
|
||||||
queuedEvents[addr].Put(tx)
|
queuedEvents[addr].Put(tx)
|
||||||
|
|
||||||
case <-curDone:
|
case <-curDone:
|
||||||
|
fmt.Println("reorg done")
|
||||||
|
for _, ch := range curDones {
|
||||||
|
fmt.Println(ch)
|
||||||
|
close(ch)
|
||||||
|
}
|
||||||
|
fmt.Println("end reorg done")
|
||||||
curDone = nil
|
curDone = nil
|
||||||
|
|
||||||
case <-pool.reorgShutdownCh:
|
case <-pool.reorgShutdownCh:
|
||||||
// Wait for current run to finish.
|
// Wait for current run to finish.
|
||||||
if curDone != nil {
|
if curDone != nil {
|
||||||
|
fmt.Println("shutdown reorg done")
|
||||||
<-curDone
|
<-curDone
|
||||||
|
for _, ch := range curDones {
|
||||||
|
fmt.Println(ch)
|
||||||
|
close(ch)
|
||||||
|
}
|
||||||
|
fmt.Println("end reorg done")
|
||||||
}
|
}
|
||||||
close(nextDone)
|
close(nextDone)
|
||||||
return
|
return
|
||||||
|
|
@ -1309,6 +1352,7 @@ func (pool *LegacyPool) runReorg(done chan struct{}, reset *txpoolResetRequest,
|
||||||
if _, ok := events[addr]; !ok {
|
if _, ok := events[addr]; !ok {
|
||||||
events[addr] = NewSortedMap()
|
events[addr] = NewSortedMap()
|
||||||
}
|
}
|
||||||
|
fmt.Printf("promoted tx %v\n", tx.Hash())
|
||||||
events[addr].Put(tx)
|
events[addr].Put(tx)
|
||||||
}
|
}
|
||||||
if len(events) > 0 {
|
if len(events) > 0 {
|
||||||
|
|
@ -1429,6 +1473,7 @@ func (pool *LegacyPool) promoteExecutables(accounts []common.Address) []*types.T
|
||||||
// Iterate over all accounts and promote any executable transactions
|
// Iterate over all accounts and promote any executable transactions
|
||||||
gasLimit := pool.currentHead.Load().GasLimit
|
gasLimit := pool.currentHead.Load().GasLimit
|
||||||
for _, addr := range accounts {
|
for _, addr := range accounts {
|
||||||
|
fmt.Printf("promoteExecutables %x\n", addr)
|
||||||
list := pool.queue[addr]
|
list := pool.queue[addr]
|
||||||
if list == nil {
|
if list == nil {
|
||||||
continue // Just in case someone calls with a non existing account
|
continue // Just in case someone calls with a non existing account
|
||||||
|
|
@ -1687,6 +1732,11 @@ type accountSet struct {
|
||||||
cache []common.Address
|
cache []common.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type reqPromote struct {
|
||||||
|
set *accountSet
|
||||||
|
done chan struct{}
|
||||||
|
}
|
||||||
|
|
||||||
// newAccountSet creates a new address set with an associated signer for sender
|
// newAccountSet creates a new address set with an associated signer for sender
|
||||||
// derivations.
|
// derivations.
|
||||||
func newAccountSet(signer types.Signer, addrs ...common.Address) *accountSet {
|
func newAccountSet(signer types.Signer, addrs ...common.Address) *accountSet {
|
||||||
|
|
|
||||||
|
|
@ -361,6 +361,7 @@ func (p *TxPool) Add(txs []*types.Transaction, sync bool) []error {
|
||||||
splits := make([]int, len(txs))
|
splits := make([]int, len(txs))
|
||||||
|
|
||||||
for i, tx := range txs {
|
for i, tx := range txs {
|
||||||
|
fmt.Printf("txpool attempting to add %v\n", tx.Hash())
|
||||||
// Mark this transaction belonging to no-subpool
|
// Mark this transaction belonging to no-subpool
|
||||||
splits[i] = -1
|
splits[i] = -1
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@ func TestEth2AssembleBlock(t *testing.T) {
|
||||||
t.Fatalf("error signing transaction, err=%v", err)
|
t.Fatalf("error signing transaction, err=%v", err)
|
||||||
}
|
}
|
||||||
ethservice.TxPool().Add([]*types.Transaction{tx}, true)
|
ethservice.TxPool().Add([]*types.Transaction{tx}, true)
|
||||||
|
fmt.Println("in test: added txs")
|
||||||
blockParams := engine.PayloadAttributes{
|
blockParams := engine.PayloadAttributes{
|
||||||
Timestamp: blocks[9].Time() + 5,
|
Timestamp: blocks[9].Time() + 5,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 81862e4848585a438d64f911a19b3825f0f4cd95
|
Subproject commit faf33b471465d3c6cdc3d04fbd690895f78d33f2
|
||||||
Loading…
Reference in a new issue