mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-21 20:26:41 +00:00
eth/txtracker: rename txEntry to TxInfo, align field names with richer model
No functional change. Prepares the minimal model to mirror the field
naming of the richer txtracker variants on adjacent branches so that
upcoming cherry-picks (lastFinalNum seed, IncludedDeliverer freeze,
collectFinalization pivot to iterate t.txs) can apply with smaller
deltas.
Changes:
- txEntry -> TxInfo (exported, pointer in t.txs map)
- txEntry.peer -> TxInfo.Deliverer
- txEntry.addedAt -> TxInfo.AddedAt
- add TxStatus enum (StatusUnknown / StatusIncluded / StatusFinalized);
not yet assigned on any code path here
- add TxInfo.BlockNum and TxInfo.BlockHash; not yet assigned
This commit is contained in:
parent
905bc9d102
commit
1f77413959
2 changed files with 29 additions and 20 deletions
|
|
@ -68,20 +68,29 @@ type peerStats struct {
|
||||||
recentIncluded float64
|
recentIncluded float64
|
||||||
}
|
}
|
||||||
|
|
||||||
// txEntry tracks the deliverer of a transaction and when delivery was
|
// TxInfo records the per-transaction state the tracker maintains.
|
||||||
// recorded. addedAt is unix seconds; it is compared against block.Time()
|
//
|
||||||
// to suppress credit for txs delivered at or after the slot of their
|
// Deliverer is the peer that first handed us this tx via NotifyAccepted.
|
||||||
// inclusion block (e.g., re-broadcasts of just-mined txs).
|
// AddedAt is the unix-seconds wall-clock at that moment; it is compared
|
||||||
type txEntry struct {
|
// against block.Time() to suppress credit for txs delivered at or after
|
||||||
peer string
|
// the slot of their inclusion block (re-broadcasts of just-mined txs).
|
||||||
addedAt uint64
|
//
|
||||||
|
// BlockNum / BlockHash are populated when the tracker first sees the tx
|
||||||
|
// in a head block (BlockNum == 0 means not yet seen on chain). BlockHash
|
||||||
|
// is re-checked against canonical-at-height at finalization time so
|
||||||
|
// reorgs do not yield credit.
|
||||||
|
type TxInfo struct {
|
||||||
|
Deliverer string
|
||||||
|
AddedAt uint64
|
||||||
|
BlockNum uint64
|
||||||
|
BlockHash common.Hash
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tracker records which peer delivered each transaction and credits peers
|
// Tracker records which peer delivered each transaction and credits peers
|
||||||
// when their transactions appear on chain.
|
// when their transactions appear on chain.
|
||||||
type Tracker struct {
|
type Tracker struct {
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
txs map[common.Hash]txEntry // hash → deliverer + arrival time
|
txs map[common.Hash]*TxInfo // hash → per-tx state
|
||||||
peers map[string]*peerStats
|
peers map[string]*peerStats
|
||||||
order []common.Hash // insertion order for LRU eviction
|
order []common.Hash // insertion order for LRU eviction
|
||||||
|
|
||||||
|
|
@ -100,7 +109,7 @@ type Tracker struct {
|
||||||
// New creates a new tracker.
|
// New creates a new tracker.
|
||||||
func New() *Tracker {
|
func New() *Tracker {
|
||||||
return &Tracker{
|
return &Tracker{
|
||||||
txs: make(map[common.Hash]txEntry),
|
txs: make(map[common.Hash]*TxInfo),
|
||||||
peers: make(map[string]*peerStats),
|
peers: make(map[string]*peerStats),
|
||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
step: make(chan struct{}, 1),
|
step: make(chan struct{}, 1),
|
||||||
|
|
@ -153,7 +162,7 @@ func (t *Tracker) NotifyAccepted(peer string, hashes []common.Hash) {
|
||||||
if _, ok := t.txs[hash]; ok {
|
if _, ok := t.txs[hash]; ok {
|
||||||
continue // already tracked, keep first deliverer
|
continue // already tracked, keep first deliverer
|
||||||
}
|
}
|
||||||
t.txs[hash] = txEntry{peer: peer, addedAt: addedAt}
|
t.txs[hash] = &TxInfo{Deliverer: peer, AddedAt: addedAt}
|
||||||
t.order = append(t.order, hash)
|
t.order = append(t.order, hash)
|
||||||
}
|
}
|
||||||
// Ensure the delivering peer has a stats entry.
|
// Ensure the delivering peer has a stats entry.
|
||||||
|
|
@ -225,11 +234,11 @@ func (t *Tracker) handleChainHead(ev core.ChainHeadEvent) {
|
||||||
blockTime := block.Time()
|
blockTime := block.Time()
|
||||||
blockIncl := make(map[string]int)
|
blockIncl := make(map[string]int)
|
||||||
for _, tx := range block.Transactions() {
|
for _, tx := range block.Transactions() {
|
||||||
entry, ok := t.txs[tx.Hash()]
|
ti, ok := t.txs[tx.Hash()]
|
||||||
if !ok || entry.addedAt >= blockTime {
|
if !ok || ti.AddedAt >= blockTime {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
blockIncl[entry.peer]++
|
blockIncl[ti.Deliverer]++
|
||||||
}
|
}
|
||||||
// Accumulate per-peer finalization credits over the newly-finalized
|
// Accumulate per-peer finalization credits over the newly-finalized
|
||||||
// range (possibly zero blocks). Only counts peers still tracked.
|
// range (possibly zero blocks). Only counts peers still tracked.
|
||||||
|
|
@ -266,14 +275,14 @@ func (t *Tracker) collectFinalizationCredits() map[string]int {
|
||||||
}
|
}
|
||||||
blockTime := block.Time()
|
blockTime := block.Time()
|
||||||
for _, tx := range block.Transactions() {
|
for _, tx := range block.Transactions() {
|
||||||
entry, ok := t.txs[tx.Hash()]
|
ti, ok := t.txs[tx.Hash()]
|
||||||
if !ok || entry.addedAt >= blockTime {
|
if !ok || ti.AddedAt >= blockTime {
|
||||||
continue // unknown, or post-slot re-broadcast
|
continue // unknown, or post-slot re-broadcast
|
||||||
}
|
}
|
||||||
if _, ok := t.peers[entry.peer]; !ok {
|
if _, ok := t.peers[ti.Deliverer]; !ok {
|
||||||
continue // peer disconnected, skip credit
|
continue // peer disconnected, skip credit
|
||||||
}
|
}
|
||||||
credits[entry.peer]++
|
credits[ti.Deliverer]++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if total := sumCounts(credits); total > 0 {
|
if total := sumCounts(credits); total > 0 {
|
||||||
|
|
|
||||||
|
|
@ -197,8 +197,8 @@ func TestNotifyReceived(t *testing.T) {
|
||||||
t.Fatalf("expected order length 3, got %d", len(tr.order))
|
t.Fatalf("expected order length 3, got %d", len(tr.order))
|
||||||
}
|
}
|
||||||
for i, h := range hashes {
|
for i, h := range hashes {
|
||||||
if got := tr.txs[h]; got.peer != "peerA" {
|
if got := tr.txs[h]; got.Deliverer != "peerA" {
|
||||||
t.Fatalf("tx %d: expected deliverer=peerA, got %q", i, got.peer)
|
t.Fatalf("tx %d: expected deliverer=peerA, got %q", i, got.Deliverer)
|
||||||
}
|
}
|
||||||
if tr.order[i] != h {
|
if tr.order[i] != h {
|
||||||
t.Fatalf("order[%d] mismatch", i)
|
t.Fatalf("order[%d] mismatch", i)
|
||||||
|
|
@ -468,7 +468,7 @@ func TestRecentFinalizedDecays(t *testing.T) {
|
||||||
// post-block-propagation re-broadcast attribution attack: a peer that
|
// post-block-propagation re-broadcast attribution attack: a peer that
|
||||||
// learns a tx from the just-mined block and re-broadcasts it to our pool
|
// learns a tx from the just-mined block and re-broadcasts it to our pool
|
||||||
// should not gain credit when that block is processed. The finalization
|
// should not gain credit when that block is processed. The finalization
|
||||||
// path applies the same gate (entry.addedAt >= blockTime) and is exercised
|
// path applies the same gate (ti.AddedAt >= blockTime) and is exercised
|
||||||
// by the existing TestFinalization with the new clock semantics.
|
// by the existing TestFinalization with the new clock semantics.
|
||||||
func TestPreSlotGate(t *testing.T) {
|
func TestPreSlotGate(t *testing.T) {
|
||||||
tr := New()
|
tr := New()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue