@@ -67,7 +67,7 @@ func TestIsGasRetryableError(t *testing.T) {
6767 require .True (t , isGasRetryableError (fmt .Errorf ("deploy failed: %w" , core .ErrFeeCapTooLow )))
6868}
6969
70- func TestDeployTransactOpts (t * testing.T ) {
70+ func TestTransactOptsWithGasOverrides (t * testing.T ) {
7171 t .Parallel ()
7272
7373 base := & bind.TransactOpts {
@@ -77,21 +77,21 @@ func TestDeployTransactOpts(t *testing.T) {
7777 GasTipCap : big .NewInt (2 ),
7878 }
7979
80- require .Nil (t , deployTransactOpts (nil , 1 , 1 ))
81- require .Same (t , base , deployTransactOpts (base , 0 , 0 ))
80+ require .Nil (t , transactOptsWithGasOverrides (nil , 1 , 1 ))
81+ require .Same (t , base , transactOptsWithGasOverrides (base , 0 , 0 ))
8282
83- limitOnly := deployTransactOpts (base , 500_000 , 0 )
83+ limitOnly := transactOptsWithGasOverrides (base , 500_000 , 0 )
8484 require .Equal (t , uint64 (500_000 ), limitOnly .GasLimit )
8585 require .Equal (t , big .NewInt (1 ), limitOnly .GasPrice )
8686 require .Equal (t , big .NewInt (100 ), limitOnly .GasFeeCap )
8787
88- priceOnly := deployTransactOpts (base , 0 , 30_000_000_000 )
88+ priceOnly := transactOptsWithGasOverrides (base , 0 , 30_000_000_000 )
8989 require .Equal (t , uint64 (21_000 ), priceOnly .GasLimit )
9090 require .Equal (t , uint64 (30_000_000_000 ), priceOnly .GasPrice .Uint64 ())
9191 require .Nil (t , priceOnly .GasFeeCap )
9292 require .Nil (t , priceOnly .GasTipCap )
9393
94- withGas := deployTransactOpts (base , 500_000 , 30_000_000_000 )
94+ withGas := transactOptsWithGasOverrides (base , 500_000 , 30_000_000_000 )
9595 require .Equal (t , uint64 (500_000 ), withGas .GasLimit )
9696 require .Equal (t , uint64 (30_000_000_000 ), withGas .GasPrice .Uint64 ())
9797 require .Nil (t , withGas .GasFeeCap )
@@ -236,3 +236,133 @@ func TestRetryDeployWithGasBoostSkipsZkSync(t *testing.T) {
236236func ptrUint64 (v uint64 ) * uint64 {
237237 return & v
238238}
239+
240+ func TestRetryWriteWithGasBoostRetriesOnGasError (t * testing.T ) {
241+ t .Parallel ()
242+
243+ failures := 2
244+ var gasLimits []uint64
245+ op := operations .NewOperation (
246+ "write-gas-boost-retry" ,
247+ semver .MustParse ("1.0.0" ),
248+ "test" ,
249+ func (_ operations.Bundle , _ evm.Chain , input FunctionInput [struct {}]) (struct {}, error ) {
250+ gasLimits = append (gasLimits , input .GasLimit )
251+ if failures > 0 {
252+ failures --
253+ return struct {}{}, errors .New ("out of gas: gas required exceeds allowance" )
254+ }
255+
256+ return struct {}{}, nil
257+ },
258+ )
259+
260+ cfg := & GasBoostConfig {
261+ InitialGasLimit : 1_000_000 ,
262+ GasLimitIncrement : ptrUint64 (100_000 ),
263+ }
264+ bundle := optest .NewBundle (t )
265+ _ , err := operations .ExecuteOperation (
266+ bundle ,
267+ op ,
268+ evm.Chain {Selector : 1 },
269+ FunctionInput [struct {}]{},
270+ RetryWriteWithGasBoost [struct {}](cfg ),
271+ )
272+ require .NoError (t , err )
273+ require .Equal (t , []uint64 {0 , 1_000_000 , 1_100_000 }, gasLimits )
274+ }
275+
276+ func TestRetryWriteWithGasBoostNilConfig (t * testing.T ) {
277+ t .Parallel ()
278+
279+ failures := 2
280+ calls := 0
281+ op := operations .NewOperation (
282+ "write-gas-boost-nil" ,
283+ semver .MustParse ("1.0.0" ),
284+ "test" ,
285+ func (_ operations.Bundle , _ evm.Chain , _ FunctionInput [struct {}]) (struct {}, error ) {
286+ calls ++
287+ if failures > 0 {
288+ failures --
289+ return struct {}{}, errors .New ("out of gas" )
290+ }
291+
292+ return struct {}{}, nil
293+ },
294+ )
295+
296+ bundle := optest .NewBundle (t )
297+ _ , err := operations .ExecuteOperation (
298+ bundle ,
299+ op ,
300+ evm.Chain {Selector : 1 },
301+ FunctionInput [struct {}]{},
302+ RetryWriteWithGasBoost [struct {}](nil ),
303+ )
304+ require .Error (t , err )
305+ require .Equal (t , 1 , calls )
306+ }
307+
308+ func TestRetryWriteWithGasBoostSkipsNonGasErrors (t * testing.T ) {
309+ t .Parallel ()
310+
311+ var gasLimits []uint64
312+ op := operations .NewOperation (
313+ "write-gas-boost-skip" ,
314+ semver .MustParse ("1.0.0" ),
315+ "test" ,
316+ func (_ operations.Bundle , _ evm.Chain , input FunctionInput [struct {}]) (struct {}, error ) {
317+ gasLimits = append (gasLimits , input .GasLimit )
318+ return struct {}{}, errors .New ("revert: unauthorized" )
319+ },
320+ )
321+
322+ bundle := optest .NewBundle (t )
323+ _ , err := operations .ExecuteOperation (
324+ bundle ,
325+ op ,
326+ evm.Chain {Selector : 1 },
327+ FunctionInput [struct {}]{},
328+ RetryWriteWithGasBoost [struct {}](& GasBoostConfig {}),
329+ )
330+ require .Error (t , err )
331+ for _ , limit := range gasLimits {
332+ require .Equal (t , uint64 (0 ), limit )
333+ }
334+ }
335+
336+ func TestRetryWriteWithGasBoostSkipsZkSync (t * testing.T ) {
337+ t .Parallel ()
338+
339+ failures := 2
340+ var gasLimits []uint64
341+ op := operations .NewOperation (
342+ "write-gas-boost-zksync" ,
343+ semver .MustParse ("1.0.0" ),
344+ "test" ,
345+ func (_ operations.Bundle , _ evm.Chain , input FunctionInput [struct {}]) (struct {}, error ) {
346+ gasLimits = append (gasLimits , input .GasLimit )
347+ if failures > 0 {
348+ failures --
349+ return struct {}{}, errors .New ("out of gas" )
350+ }
351+
352+ return struct {}{}, nil
353+ },
354+ )
355+
356+ bundle := optest .NewBundle (t )
357+ _ , err := operations .ExecuteOperation (
358+ bundle ,
359+ op ,
360+ evm.Chain {Selector : 1 , IsZkSyncVM : true },
361+ FunctionInput [struct {}]{},
362+ RetryWriteWithGasBoost [struct {}](& GasBoostConfig {}),
363+ )
364+ require .NoError (t , err )
365+ for _ , limit := range gasLimits {
366+ require .Equal (t , uint64 (0 ), limit )
367+ }
368+ }
0 commit comments