forked from cerc-io/plugeth
core, eth, miner: start propagating and consuming blob txs (#28243)
* core, eth, miner: start propagating and consuming blob txs * eth/protocols/eth: disable eth/67 if Cancun is enabled * core/txpool, eth, miner: pass gas limit infos in lazy tx for mienr filtering * core/txpool, miner: add lazy resolver for pending txs too * core, eth: fix review noticed bugs * eth, miner: minor polishes in the mining and announcing logs * core/expool: unsubscribe the event scope
This commit is contained in:
+1
-1
@@ -334,7 +334,7 @@ func (b *EthAPIBackend) TxPool() *txpool.TxPool {
|
||||
}
|
||||
|
||||
func (b *EthAPIBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription {
|
||||
return b.eth.txPool.SubscribeNewTxsEvent(ch)
|
||||
return b.eth.txPool.SubscribeTransactions(ch, true)
|
||||
}
|
||||
|
||||
func (b *EthAPIBackend) SyncProgress() ethereum.SyncProgress {
|
||||
|
||||
@@ -199,7 +199,7 @@ func (c *SimulatedBeacon) sealBlock(withdrawals []*types.Withdrawal) error {
|
||||
func (c *SimulatedBeacon) loopOnDemand() {
|
||||
var (
|
||||
newTxs = make(chan core.NewTxsEvent)
|
||||
sub = c.eth.TxPool().SubscribeNewTxsEvent(newTxs)
|
||||
sub = c.eth.TxPool().SubscribeTransactions(newTxs, true)
|
||||
)
|
||||
defer sub.Unsubscribe()
|
||||
|
||||
|
||||
+24
-17
@@ -75,9 +75,10 @@ type txPool interface {
|
||||
// The slice should be modifiable by the caller.
|
||||
Pending(enforceTips bool) map[common.Address][]*txpool.LazyTransaction
|
||||
|
||||
// SubscribeNewTxsEvent should return an event subscription of
|
||||
// NewTxsEvent and send events to the given channel.
|
||||
SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription
|
||||
// SubscribeTransactions subscribes to new transaction events. The subscriber
|
||||
// can decide whether to receive notifications only for newly seen transactions
|
||||
// or also for reorged out ones.
|
||||
SubscribeTransactions(ch chan<- core.NewTxsEvent, reorgs bool) event.Subscription
|
||||
}
|
||||
|
||||
// handlerConfig is the collection of initialization parameters to create a full
|
||||
@@ -509,10 +510,10 @@ func (h *handler) unregisterPeer(id string) {
|
||||
func (h *handler) Start(maxPeers int) {
|
||||
h.maxPeers = maxPeers
|
||||
|
||||
// broadcast transactions
|
||||
// broadcast and announce transactions (only new ones, not resurrected ones)
|
||||
h.wg.Add(1)
|
||||
h.txsCh = make(chan core.NewTxsEvent, txChanSize)
|
||||
h.txsSub = h.txpool.SubscribeNewTxsEvent(h.txsCh)
|
||||
h.txsSub = h.txpool.SubscribeTransactions(h.txsCh, false)
|
||||
go h.txBroadcastLoop()
|
||||
|
||||
// broadcast mined blocks
|
||||
@@ -592,26 +593,33 @@ func (h *handler) BroadcastBlock(block *types.Block, propagate bool) {
|
||||
}
|
||||
|
||||
// BroadcastTransactions will propagate a batch of transactions
|
||||
// - To a square root of all peers
|
||||
// - To a square root of all peers for non-blob transactions
|
||||
// - And, separately, as announcements to all peers which are not known to
|
||||
// already have the given transaction.
|
||||
func (h *handler) BroadcastTransactions(txs types.Transactions) {
|
||||
var (
|
||||
annoCount int // Count of announcements made
|
||||
annoPeers int
|
||||
directCount int // Count of the txs sent directly to peers
|
||||
directPeers int // Count of the peers that were sent transactions directly
|
||||
blobTxs int // Number of blob transactions to announce only
|
||||
largeTxs int // Number of large transactions to announce only
|
||||
|
||||
directCount int // Number of transactions sent directly to peers (duplicates included)
|
||||
directPeers int // Number of peers that were sent transactions directly
|
||||
annCount int // Number of transactions announced across all peers (duplicates included)
|
||||
annPeers int // Number of peers announced about transactions
|
||||
|
||||
txset = make(map[*ethPeer][]common.Hash) // Set peer->hash to transfer directly
|
||||
annos = make(map[*ethPeer][]common.Hash) // Set peer->hash to announce
|
||||
|
||||
)
|
||||
// Broadcast transactions to a batch of peers not knowing about it
|
||||
for _, tx := range txs {
|
||||
peers := h.peers.peersWithoutTransaction(tx.Hash())
|
||||
|
||||
var numDirect int
|
||||
if tx.Size() <= txMaxBroadcastSize {
|
||||
switch {
|
||||
case tx.Type() == types.BlobTxType:
|
||||
blobTxs++
|
||||
case tx.Size() > txMaxBroadcastSize:
|
||||
largeTxs++
|
||||
default:
|
||||
numDirect = int(math.Sqrt(float64(len(peers))))
|
||||
}
|
||||
// Send the tx unconditionally to a subset of our peers
|
||||
@@ -629,13 +637,12 @@ func (h *handler) BroadcastTransactions(txs types.Transactions) {
|
||||
peer.AsyncSendTransactions(hashes)
|
||||
}
|
||||
for peer, hashes := range annos {
|
||||
annoPeers++
|
||||
annoCount += len(hashes)
|
||||
annPeers++
|
||||
annCount += len(hashes)
|
||||
peer.AsyncSendPooledTransactionHashes(hashes)
|
||||
}
|
||||
log.Debug("Transaction broadcast", "txs", len(txs),
|
||||
"announce packs", annoPeers, "announced hashes", annoCount,
|
||||
"tx packs", directPeers, "broadcast txs", directCount)
|
||||
log.Debug("Distributed transactions", "plaintxs", len(txs)-blobTxs-largeTxs, "blobtxs", blobTxs, "largetxs", largeTxs,
|
||||
"bcastpeers", directPeers, "bcastcount", directCount, "annpeers", annPeers, "anncount", annCount)
|
||||
}
|
||||
|
||||
// minedBroadcastLoop sends mined blocks to connected peers.
|
||||
|
||||
+8
-6
@@ -17,6 +17,7 @@
|
||||
package eth
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"time"
|
||||
@@ -73,6 +74,11 @@ func (h *ethHandler) Handle(peer *eth.Peer, packet eth.Packet) error {
|
||||
return h.txFetcher.Notify(peer.ID(), packet.Hashes)
|
||||
|
||||
case *eth.TransactionsPacket:
|
||||
for _, tx := range *packet {
|
||||
if tx.Type() == types.BlobTxType {
|
||||
return errors.New("disallowed broadcast blob transaction")
|
||||
}
|
||||
}
|
||||
return h.txFetcher.Enqueue(peer.ID(), *packet, false)
|
||||
|
||||
case *eth.PooledTransactionsResponse:
|
||||
@@ -90,9 +96,7 @@ func (h *ethHandler) handleBlockAnnounces(peer *eth.Peer, hashes []common.Hash,
|
||||
// the chain already entered the pos stage and disconnect the
|
||||
// remote peer.
|
||||
if h.merger.PoSFinalized() {
|
||||
// TODO (MariusVanDerWijden) drop non-updated peers after the merge
|
||||
return nil
|
||||
// return errors.New("unexpected block announces")
|
||||
return errors.New("disallowed block announcement")
|
||||
}
|
||||
// Schedule all the unknown hashes for retrieval
|
||||
var (
|
||||
@@ -118,9 +122,7 @@ func (h *ethHandler) handleBlockBroadcast(peer *eth.Peer, block *types.Block, td
|
||||
// the chain already entered the pos stage and disconnect the
|
||||
// remote peer.
|
||||
if h.merger.PoSFinalized() {
|
||||
// TODO (MariusVanDerWijden) drop non-updated peers after the merge
|
||||
return nil
|
||||
// return errors.New("unexpected block announces")
|
||||
return errors.New("disallowed block broadcast")
|
||||
}
|
||||
// Schedule the block for import
|
||||
h.blockFetcher.Enqueue(peer.ID(), block)
|
||||
|
||||
@@ -249,7 +249,7 @@ func testRecvTransactions(t *testing.T, protocol uint) {
|
||||
handler.handler.synced.Store(true) // mark synced to accept transactions
|
||||
|
||||
txs := make(chan core.NewTxsEvent)
|
||||
sub := handler.txpool.SubscribeNewTxsEvent(txs)
|
||||
sub := handler.txpool.SubscribeTransactions(txs, false)
|
||||
defer sub.Unsubscribe()
|
||||
|
||||
// Create a source peer to send messages through and a sink handler to receive them
|
||||
@@ -424,7 +424,7 @@ func testTransactionPropagation(t *testing.T, protocol uint) {
|
||||
for i := 0; i < len(sinks); i++ {
|
||||
txChs[i] = make(chan core.NewTxsEvent, 1024)
|
||||
|
||||
sub := sinks[i].txpool.SubscribeNewTxsEvent(txChs[i])
|
||||
sub := sinks[i].txpool.SubscribeTransactions(txChs[i], false)
|
||||
defer sub.Unsubscribe()
|
||||
}
|
||||
// Fill the source pool with transactions and wait for them at the sinks
|
||||
|
||||
+4
-2
@@ -113,15 +113,17 @@ func (p *testTxPool) Pending(enforceTips bool) map[common.Address][]*txpool.Lazy
|
||||
Time: tx.Time(),
|
||||
GasFeeCap: tx.GasFeeCap(),
|
||||
GasTipCap: tx.GasTipCap(),
|
||||
Gas: tx.Gas(),
|
||||
BlobGas: tx.BlobGas(),
|
||||
})
|
||||
}
|
||||
}
|
||||
return pending
|
||||
}
|
||||
|
||||
// SubscribeNewTxsEvent should return an event subscription of NewTxsEvent and
|
||||
// SubscribeTransactions should return an event subscription of NewTxsEvent and
|
||||
// send events to the given channel.
|
||||
func (p *testTxPool) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription {
|
||||
func (p *testTxPool) SubscribeTransactions(ch chan<- core.NewTxsEvent, reorgs bool) event.Subscription {
|
||||
return p.txFeed.Subscribe(ch)
|
||||
}
|
||||
|
||||
|
||||
@@ -93,6 +93,10 @@ type TxPool interface {
|
||||
func MakeProtocols(backend Backend, network uint64, dnsdisc enode.Iterator) []p2p.Protocol {
|
||||
protocols := make([]p2p.Protocol, 0, len(ProtocolVersions))
|
||||
for _, version := range ProtocolVersions {
|
||||
// Blob transactions require eth/68 announcements, disable everything else
|
||||
if version <= ETH67 && backend.Chain().Config().CancunTime != nil {
|
||||
continue
|
||||
}
|
||||
version := version // Closure
|
||||
|
||||
protocols = append(protocols, p2p.Protocol{
|
||||
|
||||
@@ -426,11 +426,11 @@ func handleGetPooledTransactions(backend Backend, msg Decoder, peer *Peer) error
|
||||
if err := msg.Decode(&query); err != nil {
|
||||
return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
|
||||
}
|
||||
hashes, txs := answerGetPooledTransactions(backend, query.GetPooledTransactionsRequest, peer)
|
||||
hashes, txs := answerGetPooledTransactions(backend, query.GetPooledTransactionsRequest)
|
||||
return peer.ReplyPooledTransactionsRLP(query.RequestId, hashes, txs)
|
||||
}
|
||||
|
||||
func answerGetPooledTransactions(backend Backend, query GetPooledTransactionsRequest, peer *Peer) ([]common.Hash, []rlp.RawValue) {
|
||||
func answerGetPooledTransactions(backend Backend, query GetPooledTransactionsRequest) ([]common.Hash, []rlp.RawValue) {
|
||||
// Gather transactions until the fetch or network limits is reached
|
||||
var (
|
||||
bytes int
|
||||
|
||||
Reference in New Issue
Block a user