|
|
@@ -456,44 +456,51 @@ func (h *handler) BroadcastBlock(block *types.Block, propagate bool) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// BroadcastTransactions will propagate a batch of transactions to all peers which are not known to
|
|
|
+// BroadcastTransactions will propagate a batch of transactions
|
|
|
+// - To a square root of all peers
|
|
|
+// - And, separately, as announcements to all peers which are not known to
|
|
|
// already have the given transaction.
|
|
|
-func (h *handler) BroadcastTransactions(txs types.Transactions, propagate bool) {
|
|
|
+func (h *handler) BroadcastTransactions(txs types.Transactions) {
|
|
|
var (
|
|
|
- txset = make(map[*ethPeer][]common.Hash)
|
|
|
- annos = make(map[*ethPeer][]common.Hash)
|
|
|
+ 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
|
|
|
+
|
|
|
+ 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
|
|
|
- if propagate {
|
|
|
- for _, tx := range txs {
|
|
|
- peers := h.peers.peersWithoutTransaction(tx.Hash())
|
|
|
-
|
|
|
- // Send the block to a subset of our peers
|
|
|
- transfer := peers[:int(math.Sqrt(float64(len(peers))))]
|
|
|
- for _, peer := range transfer {
|
|
|
- txset[peer] = append(txset[peer], tx.Hash())
|
|
|
- }
|
|
|
- log.Trace("Broadcast transaction", "hash", tx.Hash(), "recipients", len(transfer))
|
|
|
- }
|
|
|
- for peer, hashes := range txset {
|
|
|
- peer.AsyncSendTransactions(hashes)
|
|
|
- }
|
|
|
- return
|
|
|
- }
|
|
|
- // Otherwise only broadcast the announcement to peers
|
|
|
for _, tx := range txs {
|
|
|
peers := h.peers.peersWithoutTransaction(tx.Hash())
|
|
|
- for _, peer := range peers {
|
|
|
+ // Send the tx unconditionally to a subset of our peers
|
|
|
+ numDirect := int(math.Sqrt(float64(len(peers))))
|
|
|
+ for _, peer := range peers[:numDirect] {
|
|
|
+ txset[peer] = append(txset[peer], tx.Hash())
|
|
|
+ }
|
|
|
+ // For the remaining peers, send announcement only
|
|
|
+ for _, peer := range peers[numDirect:] {
|
|
|
annos[peer] = append(annos[peer], tx.Hash())
|
|
|
}
|
|
|
}
|
|
|
+ for peer, hashes := range txset {
|
|
|
+ directPeers++
|
|
|
+ directCount += len(hashes)
|
|
|
+ peer.AsyncSendTransactions(hashes)
|
|
|
+ }
|
|
|
for peer, hashes := range annos {
|
|
|
+ annoPeers++
|
|
|
+ annoCount += len(hashes)
|
|
|
if peer.Version() >= eth.ETH65 {
|
|
|
peer.AsyncSendPooledTransactionHashes(hashes)
|
|
|
} else {
|
|
|
peer.AsyncSendTransactions(hashes)
|
|
|
}
|
|
|
}
|
|
|
+ log.Debug("Transaction broadcast", "txs", len(txs),
|
|
|
+ "announce packs", annoPeers, "announced hashes", annoCount,
|
|
|
+ "tx packs", directPeers, "broadcast txs", directCount)
|
|
|
}
|
|
|
|
|
|
// minedBroadcastLoop sends mined blocks to connected peers.
|
|
|
@@ -511,13 +518,10 @@ func (h *handler) minedBroadcastLoop() {
|
|
|
// txBroadcastLoop announces new transactions to connected peers.
|
|
|
func (h *handler) txBroadcastLoop() {
|
|
|
defer h.wg.Done()
|
|
|
-
|
|
|
for {
|
|
|
select {
|
|
|
case event := <-h.txsCh:
|
|
|
- h.BroadcastTransactions(event.Txs, true) // First propagate transactions to peers
|
|
|
- h.BroadcastTransactions(event.Txs, false) // Only then announce to the rest
|
|
|
-
|
|
|
+ h.BroadcastTransactions(event.Txs)
|
|
|
case <-h.txsSub.Err():
|
|
|
return
|
|
|
}
|