calculate tx lifecycle duration (#986)

* init

* draft
This commit is contained in:
HAOYUatHZ 2024-08-15 10:21:07 +08:00 committed by GitHub
parent 763bc05eba
commit 1d331572b6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -101,6 +101,8 @@ var (
slotsGauge = metrics.NewRegisteredGauge("txpool/slots", nil) slotsGauge = metrics.NewRegisteredGauge("txpool/slots", nil)
reheapTimer = metrics.NewRegisteredTimer("txpool/reheap", nil) reheapTimer = metrics.NewRegisteredTimer("txpool/reheap", nil)
txLifecycleTimer = metrics.NewRegisteredTimer("txpool/txfifecycle", nil)
) )
// BlockChain defines the minimal set of methods needed to back a tx pool with // BlockChain defines the minimal set of methods needed to back a tx pool with
@ -817,6 +819,7 @@ func (pool *LegacyPool) add(tx *types.Transaction, local bool) (replaced bool, e
// New transaction is better, replace old one // New transaction is better, replace old one
if old != nil { if old != nil {
pool.all.Remove(old.Hash()) pool.all.Remove(old.Hash())
pool.calculateTxsLifecycle(types.Transactions{old}, time.Now())
pool.priced.Removed(1) pool.priced.Removed(1)
pendingReplaceMeter.Mark(1) pendingReplaceMeter.Mark(1)
} }
@ -892,6 +895,7 @@ func (pool *LegacyPool) enqueueTx(hash common.Hash, tx *types.Transaction, local
// Discard any previous transaction and mark this // Discard any previous transaction and mark this
if old != nil { if old != nil {
pool.all.Remove(old.Hash()) pool.all.Remove(old.Hash())
pool.calculateTxsLifecycle(types.Transactions{old}, time.Now())
pool.priced.Removed(1) pool.priced.Removed(1)
queuedReplaceMeter.Mark(1) queuedReplaceMeter.Mark(1)
} else { } else {
@ -941,6 +945,7 @@ func (pool *LegacyPool) promoteTx(addr common.Address, hash common.Hash, tx *typ
if !inserted { if !inserted {
// An older transaction was better, discard this // An older transaction was better, discard this
pool.all.Remove(hash) pool.all.Remove(hash)
pool.calculateTxsLifecycle(types.Transactions{tx}, time.Now())
pool.priced.Removed(1) pool.priced.Removed(1)
pendingDiscardMeter.Mark(1) pendingDiscardMeter.Mark(1)
return false return false
@ -948,6 +953,7 @@ func (pool *LegacyPool) promoteTx(addr common.Address, hash common.Hash, tx *typ
// Otherwise discard any previous transaction and mark this // Otherwise discard any previous transaction and mark this
if old != nil { if old != nil {
pool.all.Remove(old.Hash()) pool.all.Remove(old.Hash())
pool.calculateTxsLifecycle(types.Transactions{old}, time.Now())
pool.priced.Removed(1) pool.priced.Removed(1)
pendingReplaceMeter.Mark(1) pendingReplaceMeter.Mark(1)
} else { } else {
@ -1156,6 +1162,7 @@ func (pool *LegacyPool) removeTx(hash common.Hash, outofbound bool, unreserve bo
} }
// Remove it from the list of known transactions // Remove it from the list of known transactions
pool.all.Remove(hash) pool.all.Remove(hash)
pool.calculateTxsLifecycle(types.Transactions{tx}, time.Now())
if outofbound { if outofbound {
pool.priced.Removed(1) pool.priced.Removed(1)
} }
@ -1499,6 +1506,7 @@ func (pool *LegacyPool) promoteExecutables(accounts []common.Address) []*types.T
for _, tx := range forwards { for _, tx := range forwards {
hash := tx.Hash() hash := tx.Hash()
pool.all.Remove(hash) pool.all.Remove(hash)
pool.calculateTxsLifecycle(types.Transactions{tx}, time.Now())
} }
log.Trace("Removed old queued transactions", "count", len(forwards)) log.Trace("Removed old queued transactions", "count", len(forwards))
@ -1508,6 +1516,7 @@ func (pool *LegacyPool) promoteExecutables(accounts []common.Address) []*types.T
for _, tx := range drops { for _, tx := range drops {
hash := tx.Hash() hash := tx.Hash()
pool.all.Remove(hash) pool.all.Remove(hash)
pool.calculateTxsLifecycle(types.Transactions{tx}, time.Now())
} }
log.Trace("Removed unpayable queued transactions", "count", len(drops)) log.Trace("Removed unpayable queued transactions", "count", len(drops))
queuedNofundsMeter.Mark(int64(len(drops))) queuedNofundsMeter.Mark(int64(len(drops)))
@ -1530,6 +1539,7 @@ func (pool *LegacyPool) promoteExecutables(accounts []common.Address) []*types.T
for _, tx := range caps { for _, tx := range caps {
hash := tx.Hash() hash := tx.Hash()
pool.all.Remove(hash) pool.all.Remove(hash)
pool.calculateTxsLifecycle(types.Transactions{tx}, time.Now())
log.Trace("Removed cap-exceeding queued transaction", "hash", hash) log.Trace("Removed cap-exceeding queued transaction", "hash", hash)
} }
queuedRateLimitMeter.Mark(int64(len(caps))) queuedRateLimitMeter.Mark(int64(len(caps)))
@ -1615,6 +1625,7 @@ func (pool *LegacyPool) truncatePending() {
// Drop the transaction from the global pools too // Drop the transaction from the global pools too
hash := tx.Hash() hash := tx.Hash()
pool.all.Remove(hash) pool.all.Remove(hash)
pool.calculateTxsLifecycle(types.Transactions{tx}, time.Now())
// Update the account nonce to the dropped transaction // Update the account nonce to the dropped transaction
pool.pendingNonces.setIfLower(offenders[i], tx.Nonce()) pool.pendingNonces.setIfLower(offenders[i], tx.Nonce())
@ -1642,6 +1653,7 @@ func (pool *LegacyPool) truncatePending() {
// Drop the transaction from the global pools too // Drop the transaction from the global pools too
hash := tx.Hash() hash := tx.Hash()
pool.all.Remove(hash) pool.all.Remove(hash)
pool.calculateTxsLifecycle(types.Transactions{tx}, time.Now())
// Update the account nonce to the dropped transaction // Update the account nonce to the dropped transaction
pool.pendingNonces.setIfLower(addr, tx.Nonce()) pool.pendingNonces.setIfLower(addr, tx.Nonce())
@ -1722,6 +1734,7 @@ func (pool *LegacyPool) demoteUnexecutables() {
for _, tx := range olds { for _, tx := range olds {
hash := tx.Hash() hash := tx.Hash()
pool.all.Remove(hash) pool.all.Remove(hash)
pool.calculateTxsLifecycle(types.Transactions{tx}, time.Now())
log.Trace("Removed old pending transaction", "hash", hash) log.Trace("Removed old pending transaction", "hash", hash)
} }
// Drop all transactions that are too costly (low balance or out of gas), and queue any invalids back for later // Drop all transactions that are too costly (low balance or out of gas), and queue any invalids back for later
@ -1731,6 +1744,7 @@ func (pool *LegacyPool) demoteUnexecutables() {
hash := tx.Hash() hash := tx.Hash()
log.Trace("Removed unpayable pending transaction", "hash", hash) log.Trace("Removed unpayable pending transaction", "hash", hash)
pool.all.Remove(hash) pool.all.Remove(hash)
pool.calculateTxsLifecycle(types.Transactions{tx}, time.Now())
} }
pendingNofundsMeter.Mark(int64(len(drops))) pendingNofundsMeter.Mark(int64(len(drops)))
@ -1785,6 +1799,16 @@ func (pool *LegacyPool) ResumeReorgs() {
} }
} }
// calculateTxsLifecycle calculates the lifecycle of given txs
func (pool *LegacyPool) calculateTxsLifecycle(txs types.Transactions, t time.Time) {
for _, tx := range txs {
if tx.Time().Before(t) {
txLifecycle := t.Sub(tx.Time())
txLifecycleTimer.Update(txLifecycle)
}
}
}
// addressByHeartbeat is an account address tagged with its last activity timestamp. // addressByHeartbeat is an account address tagged with its last activity timestamp.
type addressByHeartbeat struct { type addressByHeartbeat struct {
address common.Address address common.Address