77 "math"
88 "math/big"
99 "slices"
10- "strings"
1110 "sync"
1211 "time"
1312
@@ -37,17 +36,19 @@ const (
3736)
3837
3938var (
40- ZeroGasSuggestedErr = "either base fee or suggested tip is 0"
41- BlockFetchingErr = "failed to fetch enough block headers for congestion calculation"
39+ GasEstimationErr = errors . New ( "incorrect gas data received from node. Skipping gas estimation" )
40+ BlockFetchingErr = errors . New ( "failed to fetch enough block headers for congestion calculation" )
4241)
4342
4443// CalculateNetworkCongestionMetric calculates a simple congestion metric based on the last N blocks
4544// according to selected strategy.
4645func (m * Client ) CalculateNetworkCongestionMetric (blocksNumber uint64 , strategy string ) (float64 , error ) {
4746 if m .HeaderCache == nil {
48- return 0 , fmt .Errorf ("header cache is not initialized. " +
47+ err := fmt .Errorf ("header cache is not initialized. " +
4948 "This is an internal error that shouldn't happen. " +
5049 "If you see this, please open a GitHub issue at https://github.com/smartcontractkit/chainlink-testing-framework/issues with your configuration details" )
50+ err = fmt .Errorf ("%w: %v" , BlockFetchingErr , err )
51+ return 0 , err
5152 }
5253 var getHeaderData = func (bn * big.Int ) (* types.Header , error ) {
5354 if bn == nil {
@@ -80,13 +81,15 @@ func (m *Client) CalculateNetworkCongestionMetric(blocksNumber uint64, strategy
8081 defer cancel ()
8182 lastBlockNumber , err := m .Client .BlockNumber (ctx )
8283 if err != nil {
84+ err = fmt .Errorf ("%w: %v" , BlockFetchingErr , err )
8385 return 0 , err
8486 }
8587
8688 L .Trace ().Msgf ("Block range for gas calculation: %d - %d" , lastBlockNumber - blocksNumber , lastBlockNumber )
8789
8890 lastBlock , err := getHeaderData (big .NewInt (mustSafeInt64 (lastBlockNumber )))
8991 if err != nil {
92+ err = fmt .Errorf ("%w: %v" , BlockFetchingErr , err )
9093 return 0 , err
9194 }
9295
@@ -133,7 +136,7 @@ func (m *Client) CalculateNetworkCongestionMetric(blocksNumber uint64, strategy
133136
134137 minBlockCount := int (float64 (blocksNumber ) * 0.8 )
135138 if len (headers ) < minBlockCount {
136- return 0 , fmt .Errorf ("failed to fetch sufficient block headers for gas estimation. " +
139+ err := fmt .Errorf ("failed to fetch sufficient block headers for gas estimation. " +
137140 "Needed at least %d blocks, but only got %d (%.1f%% success rate).\n " +
138141 "This usually indicates:\n " +
139142 " 1. RPC node is experiencing high latency or load\n " +
@@ -145,6 +148,9 @@ func (m *Client) CalculateNetworkCongestionMetric(blocksNumber uint64, strategy
145148 " 3. Disable gas estimation: set gas_price_estimation_enabled = false\n " +
146149 " 4. Reduce gas_price_estimation_blocks to fetch fewer blocks" ,
147150 minBlockCount , len (headers ), float64 (len (headers ))/ float64 (blocksNumber )* 100 )
151+ err = fmt .Errorf ("%w: %v" , BlockFetchingErr , err )
152+
153+ return 0 , err
148154 }
149155
150156 switch strategy {
@@ -153,10 +159,12 @@ func (m *Client) CalculateNetworkCongestionMetric(blocksNumber uint64, strategy
153159 case CongestionStrategy_NewestFirst :
154160 return calculateNewestFirstNetworkCongestionMetric (headers ), nil
155161 default :
156- return 0 , fmt .Errorf ("unknown network congestion strategy '%s'. " +
162+ err := fmt .Errorf ("unknown network congestion strategy '%s'. " +
157163 "Valid strategies are: 'simple' (equal weight) or 'newest_first' (recent blocks weighted more).\n " +
158164 "This is likely a configuration error. Check your gas estimation settings" ,
159165 strategy )
166+ err = fmt .Errorf ("%w: %v" , BlockFetchingErr , err )
167+ return 0 , err
160168 }
161169}
162170
@@ -209,13 +217,15 @@ func (m *Client) GetSuggestedEIP1559Fees(ctx context.Context, priority string) (
209217 // fallback to current fees if historical fetching fails
210218 baseFee , currentGasTip , err = m .currentIP1559Fees (ctx )
211219 if err != nil {
220+ err = fmt .Errorf ("%w: %v" , GasEstimationErr , err )
212221 return
213222 }
214223 L .Debug ().Msg ("Falling back to current EIP-1559 fees for gas estimation" )
215224 }
216225 } else {
217226 baseFee , currentGasTip , err = m .currentIP1559Fees (ctx )
218227 if err != nil {
228+ err = fmt .Errorf ("%w: %v" , GasEstimationErr , err )
219229 return
220230 }
221231 }
@@ -227,6 +237,7 @@ func (m *Client) GetSuggestedEIP1559Fees(ctx context.Context, priority string) (
227237 " 1. Use a different RPC endpoint\n " +
228238 " 2. Disable gas estimation: set gas_price_estimation_enabled = false in config\n " +
229239 " 3. Set explicit gas values: gas_price, gas_fee_cap, and gas_tip_cap (in your config (seth.toml or ClientBuilder)" )
240+ err = fmt .Errorf ("%w: %v" , GasEstimationErr , err )
230241 return
231242 }
232243
@@ -267,6 +278,7 @@ func (m *Client) GetSuggestedEIP1559Fees(ctx context.Context, priority string) (
267278 Int64 ("SuggestedTip" , currentGasTip .Int64 ()).
268279 Msgf ("Incorrect gas data received from node: base fee was 0. Skipping gas estimation" )
269280 err = errors .New ("incorrect gas data received from node: base fee was 0. Skipping gas estimation" )
281+ err = fmt .Errorf ("%w: %v" , GasEstimationErr , err )
270282 return
271283 }
272284
@@ -283,6 +295,7 @@ func (m *Client) GetSuggestedEIP1559Fees(ctx context.Context, priority string) (
283295 var adjustmentFactor float64
284296 adjustmentFactor , err = getAdjustmentFactor (priority )
285297 if err != nil {
298+ err = fmt .Errorf ("%w: %v" , GasEstimationErr , err )
286299 return
287300 }
288301
@@ -315,6 +328,7 @@ func (m *Client) GetSuggestedEIP1559Fees(ctx context.Context, priority string) (
315328 var bufferAdjustment float64
316329 bufferAdjustment , err = getCongestionFactor (congestionClassification )
317330 if err != nil {
331+ err = fmt .Errorf ("%w: %v" , GasEstimationErr , err )
318332 return
319333 }
320334
@@ -325,7 +339,8 @@ func (m *Client) GetSuggestedEIP1559Fees(ctx context.Context, priority string) (
325339 // Apply buffer also to the tip
326340 bufferedTipCapFloat := new (big.Float ).Mul (new (big.Float ).SetInt (adjustedTipCap ), big .NewFloat (bufferAdjustment ))
327341 adjustedTipCap , _ = bufferedTipCapFloat .Int (nil )
328- } else if ! strings .Contains (err .Error (), BlockFetchingErr ) {
342+ } else if ! errors .Is (err , BlockFetchingErr ) {
343+ err = fmt .Errorf ("%w: %v" , GasEstimationErr , err )
329344 return
330345 } else {
331346 L .Debug ().
@@ -550,7 +565,7 @@ func (m *Client) GetSuggestedLegacyFees(ctx context.Context, priority string) (a
550565 }))
551566
552567 if retryErr != nil {
553- err = retryErr
568+ err = fmt . Errorf ( "%w: %v" , GasEstimationErr , retryErr )
554569 return
555570 }
556571
@@ -562,6 +577,7 @@ func (m *Client) GetSuggestedLegacyFees(ctx context.Context, priority string) (a
562577 var adjustmentFactor float64
563578 adjustmentFactor , err = getAdjustmentFactor (priority )
564579 if err != nil {
580+ err = fmt .Errorf ("%w: %v" , GasEstimationErr , err )
565581 return
566582 }
567583
@@ -589,13 +605,15 @@ func (m *Client) GetSuggestedLegacyFees(ctx context.Context, priority string) (a
589605 var bufferAdjustment float64
590606 bufferAdjustment , err = getCongestionFactor (congestionClassification )
591607 if err != nil {
608+ err = fmt .Errorf ("%w: %v" , GasEstimationErr , err )
592609 return
593610 }
594611
595612 // Calculate and apply the buffer.
596613 bufferedGasPriceFloat := new (big.Float ).Mul (new (big.Float ).SetInt (adjustedGasPrice ), big .NewFloat (bufferAdjustment ))
597614 adjustedGasPrice , _ = bufferedGasPriceFloat .Int (nil )
598- } else if ! strings .Contains (err .Error (), BlockFetchingErr ) {
615+ } else if ! errors .Is (err , BlockFetchingErr ) {
616+ err = fmt .Errorf ("%w: %v" , GasEstimationErr , err )
599617 return
600618 } else {
601619 L .Debug ().
0 commit comments