@@ -10,8 +10,6 @@ import (
10
10
"sync"
11
11
"time"
12
12
13
- "github.com/prometheus/client_golang/prometheus"
14
- "github.com/prometheus/client_golang/prometheus/promauto"
15
13
"go.uber.org/multierr"
16
14
17
15
commonhex "github.com/smartcontractkit/chainlink-common/pkg/utils/hex"
@@ -33,48 +31,13 @@ const (
33
31
processHeadTimeout = 10 * time .Minute
34
32
)
35
33
36
- var (
37
- promNumGasBumps = promauto .NewCounterVec (prometheus.CounterOpts {
38
- Name : "tx_manager_num_gas_bumps" ,
39
- Help : "Number of gas bumps" ,
40
- }, []string {"chainID" })
41
-
42
- promGasBumpExceedsLimit = promauto .NewCounterVec (prometheus.CounterOpts {
43
- Name : "tx_manager_gas_bump_exceeds_limit" ,
44
- Help : "Number of times gas bumping failed from exceeding the configured limit. Any counts of this type indicate a serious problem." ,
45
- }, []string {"chainID" })
46
- promNumConfirmedTxs = promauto .NewCounterVec (prometheus.CounterOpts {
47
- Name : "tx_manager_num_confirmed_transactions" ,
48
- Help : "Total number of confirmed transactions. Note that this can err to be too high since transactions are counted on each confirmation, which can happen multiple times per transaction in the case of re-orgs" ,
49
- }, []string {"chainID" })
50
- promTimeUntilTxConfirmed = promauto .NewHistogramVec (prometheus.HistogramOpts {
51
- Name : "tx_manager_time_until_tx_confirmed" ,
52
- Help : "The amount of time elapsed from a transaction being broadcast to being included in a block." ,
53
- Buckets : []float64 {
54
- float64 (500 * time .Millisecond ),
55
- float64 (time .Second ),
56
- float64 (5 * time .Second ),
57
- float64 (15 * time .Second ),
58
- float64 (30 * time .Second ),
59
- float64 (time .Minute ),
60
- float64 (2 * time .Minute ),
61
- float64 (5 * time .Minute ),
62
- float64 (10 * time .Minute ),
63
- },
64
- }, []string {"chainID" })
65
- promBlocksUntilTxConfirmed = promauto .NewHistogramVec (prometheus.HistogramOpts {
66
- Name : "tx_manager_blocks_until_tx_confirmed" ,
67
- Help : "The amount of blocks that have been mined from a transaction being broadcast to being included in a block." ,
68
- Buckets : []float64 {
69
- float64 (1 ),
70
- float64 (5 ),
71
- float64 (10 ),
72
- float64 (20 ),
73
- float64 (50 ),
74
- float64 (100 ),
75
- },
76
- }, []string {"chainID" })
77
- )
34
+ type confimerMetrics interface {
35
+ IncrementNumGasBumps (ctx context.Context )
36
+ IncrementGasBumpExceedsLimit (ctx context.Context )
37
+ IncrementNumConfirmedTxs (ctx context.Context , confirmedTransactions int )
38
+ RecordTimeUntilTxConfirmed (ctx context.Context , duration float64 )
39
+ RecordBlocksUntilTxConfirmed (ctx context.Context , blocksElapsed float64 )
40
+ }
78
41
79
42
// Confirmer is a broad service which performs four different tasks in sequence on every new longest chain
80
43
// Step 1: Mark that all currently pending transaction attempts were broadcast before this block
@@ -95,6 +58,7 @@ type Confirmer[CID chains.ID, HEAD chains.Head[BHASH], ADDR chains.Hashable, THA
95
58
txConfig types.ConfirmerTransactionsConfig
96
59
dbConfig types.ConfirmerDatabaseConfig
97
60
chainID CID
61
+ metrics confimerMetrics
98
62
99
63
ks types.KeyStore [ADDR ]
100
64
enabledAddresses []ADDR
@@ -127,6 +91,7 @@ func NewConfirmer[
127
91
lggr logger.Logger ,
128
92
isReceiptNil func (R ) bool ,
129
93
stuckTxDetector types.StuckTxDetector [CHAIN_ID , ADDR , TX_HASH , BLOCK_HASH , SEQ , FEE ],
94
+ metrics confimerMetrics ,
130
95
) * Confirmer [CHAIN_ID , HEAD , ADDR , TX_HASH , BLOCK_HASH , R , SEQ , FEE ] {
131
96
lggr = logger .Named (lggr , "Confirmer" )
132
97
return & Confirmer [CHAIN_ID , HEAD , ADDR , TX_HASH , BLOCK_HASH , R , SEQ , FEE ]{
@@ -143,6 +108,7 @@ func NewConfirmer[
143
108
mb : mailbox .NewSingle [HEAD ](),
144
109
isReceiptNil : isReceiptNil ,
145
110
stuckTxDetector : stuckTxDetector ,
111
+ metrics : metrics ,
146
112
}
147
113
}
148
114
@@ -368,7 +334,7 @@ func (ec *Confirmer[CID, HEAD, ADDR, THASH, BHASH, R, SEQ, FEE]) ProcessIncluded
368
334
return nil
369
335
}
370
336
// Add newly confirmed transactions to the prom metric
371
- promNumConfirmedTxs . WithLabelValues ( ec .chainID . String ()). Add ( float64 ( len (includedTxs ) ))
337
+ ec .metrics . IncrementNumConfirmedTxs ( ctx , len (includedTxs ))
372
338
373
339
purgeTxIDs := make ([]int64 , 0 , len (includedTxs ))
374
340
confirmedTxIDs := make ([]int64 , 0 , len (includedTxs ))
@@ -381,7 +347,7 @@ func (ec *Confirmer[CID, HEAD, ADDR, THASH, BHASH, R, SEQ, FEE]) ProcessIncluded
381
347
continue
382
348
}
383
349
confirmedTxIDs = append (confirmedTxIDs , tx .ID )
384
- observeUntilTxConfirmed (ec .chainID , tx . TxAttempts , head )
350
+ observeUntilTxConfirmed (ctx , ec .metrics , tx , head )
385
351
}
386
352
// Mark the transactions included on-chain with a purge attempt as fatal error with the terminally stuck error message
387
353
if err := ec .txStore .UpdateTxFatalError (ctx , purgeTxIDs , ec .stuckTxDetector .StuckTxFatalError ()); err != nil {
@@ -667,13 +633,13 @@ func (ec *Confirmer[CID, HEAD, ADDR, THASH, BHASH, R, SEQ, FEE]) bumpGas(ctx con
667
633
// if no error, return attempt
668
634
// if err, continue below
669
635
if err == nil {
670
- promNumGasBumps . WithLabelValues ( ec .chainID . String ()). Inc ( )
636
+ ec .metrics . IncrementNumGasBumps ( ctx )
671
637
ec .lggr .Debugw ("Rebroadcast bumping fee for tx" , append (logFields , "bumpedFee" , bumpedFee .String (), "bumpedFeeLimit" , bumpedFeeLimit )... )
672
638
return bumpedAttempt , err
673
639
}
674
640
675
641
if errors .Is (err , fees .ErrBumpFeeExceedsLimit ) {
676
- promGasBumpExceedsLimit . WithLabelValues ( ec .chainID . String ()). Inc ( )
642
+ ec .metrics . IncrementGasBumpExceedsLimit ( ctx )
677
643
}
678
644
679
645
return bumpedAttempt , fmt .Errorf ("error bumping gas: %w" , err )
@@ -712,7 +678,7 @@ func (ec *Confirmer[CID, HEAD, ADDR, THASH, BHASH, R, SEQ, FEE]) handleInProgres
712
678
if err != nil {
713
679
return fmt .Errorf ("could not bump gas for terminally underpriced transaction: %w" , err )
714
680
}
715
- promNumGasBumps . WithLabelValues ( ec .chainID . String ()). Inc ( )
681
+ ec .metrics . IncrementNumGasBumps ( ctx )
716
682
lggr .With (
717
683
"sendError" , sendError ,
718
684
"maxGasPriceConfig" , ec .feeConfig .MaxFeePrice (),
@@ -853,38 +819,35 @@ func (ec *Confirmer[CID, HEAD, ADDR, THASH, BHASH, R, SEQ, FEE]) sendEmptyTransa
853
819
return txhash , nil
854
820
}
855
821
856
- // observeUntilTxConfirmed observes the promBlocksUntilTxConfirmed metric for each confirmed
857
- // transaction.
822
+ // observeUntilTxConfirmed observes the timeUntilTxConfirmed and blocksUntilTxConfirmed metrics for each confirmed transaction.
858
823
func observeUntilTxConfirmed [
859
824
CHAIN_ID chains.ID ,
860
825
ADDR chains.Hashable ,
861
826
TX_HASH , BLOCK_HASH chains.Hashable ,
862
827
SEQ chains.Sequence ,
863
828
FEE fees.Fee ,
864
- ](chainID CHAIN_ID , attempts []types.TxAttempt [CHAIN_ID , ADDR , TX_HASH , BLOCK_HASH , SEQ , FEE ], head chains.Head [BLOCK_HASH ]) {
865
- for _ , attempt := range attempts {
866
- // We estimate the time until confirmation by subtracting from the time the tx (not the attempt)
867
- // was created. We want to measure the amount of time taken from when a transaction is created
868
- // via e.g Txm.CreateTransaction to when it is confirmed on-chain, regardless of how many attempts
869
- // were needed to achieve this.
870
- duration := time .Since (attempt .Tx .CreatedAt )
871
- promTimeUntilTxConfirmed .
872
- WithLabelValues (chainID .String ()).
873
- Observe (float64 (duration ))
874
-
875
- // Since a tx can have many attempts, we take the number of blocks to confirm as the block number
876
- // of the receipt minus the block number of the first ever broadcast for this transaction.
877
- var minBroadcastBefore int64
878
- for _ , a := range attempt .Tx .TxAttempts {
879
- if b := a .BroadcastBeforeBlockNum ; b != nil && * b < minBroadcastBefore {
880
- minBroadcastBefore = * b
881
- }
882
- }
883
- if minBroadcastBefore > 0 {
884
- blocksElapsed := head .BlockNumber () - minBroadcastBefore
885
- promBlocksUntilTxConfirmed .
886
- WithLabelValues (chainID .String ()).
887
- Observe (float64 (blocksElapsed ))
829
+ ](ctx context.Context , metrics confimerMetrics , tx * types.Tx [CHAIN_ID , ADDR , TX_HASH , BLOCK_HASH , SEQ , FEE ], head chains.Head [BLOCK_HASH ]) {
830
+ if tx == nil {
831
+ return
832
+ }
833
+ // We estimate the time until confirmation by subtracting from the time the tx (not the attempt)
834
+ // was created. We want to measure the amount of time taken from when a transaction is created
835
+ // via e.g Txm.CreateTransaction to when it is confirmed on-chain, regardless of how many attempts
836
+ // were needed to achieve this.
837
+ duration := time .Since (tx .CreatedAt )
838
+ metrics .RecordTimeUntilTxConfirmed (ctx , float64 (duration ))
839
+
840
+ // Since a tx can have many attempts, we take the number of blocks to confirm as the current block number
841
+ // minus the block number of the first ever broadcast for this transaction.
842
+ var minBroadcastBefore int64
843
+ for _ , a := range tx .TxAttempts {
844
+ if b := a .BroadcastBeforeBlockNum ; b != nil && * b < minBroadcastBefore {
845
+ minBroadcastBefore = * b
888
846
}
889
847
}
848
+
849
+ if minBroadcastBefore > 0 {
850
+ blocksElapsed := head .BlockNumber () - minBroadcastBefore
851
+ metrics .RecordBlocksUntilTxConfirmed (ctx , float64 (blocksElapsed ))
852
+ }
890
853
}
0 commit comments