diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index 19da48d1dac..1edfcad2098 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -18,7 +18,8 @@ on: jobs: golangci: - if: ${{ github.event_name == 'pull_request' || github.event_name == 'schedule' }} + # We don't directly merge dependabot PRs, so let's not waste the resources + if: ${{ github.event_name == 'pull_request' || github.event_name == 'schedule' && github.actor != 'dependabot[bot]'}} name: lint runs-on: ubuntu20.04-8cores-32GB steps: @@ -44,6 +45,8 @@ jobs: matrix: cmd: ["go_core_tests", "go_core_race_tests", "go_core_fuzz"] name: Core Tests (${{ matrix.cmd }}) + # We don't directly merge dependabot PRs, so let's not waste the resources + if: github.actor != 'dependabot[bot]' runs-on: ubuntu20.04-64cores-256GB env: CL_DATABASE_URL: postgresql://postgres:postgres@localhost:5432/chainlink_test?sslmode=disable diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 95b58c43200..f57aedc5c97 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -60,6 +60,8 @@ jobs: enforce-ctf-version: name: Enforce CTF Version runs-on: ubuntu-latest + # We don't directly merge dependabot PRs, so let's not waste the resources + if: github.actor != 'dependabot[bot]' steps: - run: echo "${{github.event_name}}" - name: Checkout the repo @@ -93,6 +95,8 @@ jobs: environment: integration name: Check Paths That Require Tests To Run runs-on: ubuntu-latest + # We don't directly merge dependabot PRs, so let's not waste the resources + if: github.actor != 'dependabot[bot]' steps: - name: Checkout the repo uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 @@ -127,6 +131,8 @@ jobs: build-lint-integration-tests: name: Build and Lint integration-tests runs-on: ubuntu20.04-16cores-64GB + # We don't directly merge dependabot PRs, so let's not waste the resources + if: github.actor != 'dependabot[bot]' strategy: matrix: project: @@ -853,6 +859,8 @@ jobs: name: Get Solana Sha From Go Mod environment: Integration runs-on: ubuntu-latest + # We don't directly merge dependabot PRs, so let's not waste the resources + if: github.actor != 'dependabot[bot]' outputs: sha: ${{ steps.getsha.outputs.sha }} steps: diff --git a/.gitignore b/.gitignore index e56774fbefc..e10b07b9106 100644 --- a/.gitignore +++ b/.gitignore @@ -91,7 +91,7 @@ tools/flakeytests/coverage.txt **/testdata/fuzz/* # Runtime test configuration that might contain secrets -overrides.toml +override*.toml # Pythin venv .venv/ diff --git a/common/fee/utils.go b/common/fee/utils.go index eeb2c966719..26323e11e26 100644 --- a/common/fee/utils.go +++ b/common/fee/utils.go @@ -8,13 +8,13 @@ import ( "github.com/shopspring/decimal" ) -func ApplyMultiplier(feeLimit uint32, multiplier float32) (uint32, error) { - result := decimal.NewFromBigInt(big.NewInt(0).SetUint64(uint64(feeLimit)), 0).Mul(decimal.NewFromFloat32(multiplier)).IntPart() +func ApplyMultiplier(feeLimit uint64, multiplier float32) (uint64, error) { + result := decimal.NewFromBigInt(big.NewInt(0).SetUint64(feeLimit), 0).Mul(decimal.NewFromFloat32(multiplier)) - if result > math.MaxUint32 { + if result.GreaterThan(decimal.NewFromBigInt(big.NewInt(0).SetUint64(math.MaxUint64), 0)) { return 0, fmt.Errorf("integer overflow when applying multiplier of %f to fee limit of %d", multiplier, feeLimit) } - return uint32(result), nil + return result.BigInt().Uint64(), nil } // Returns the input value increased by the given percentage. diff --git a/common/txmgr/broadcaster.go b/common/txmgr/broadcaster.go index 3e7520aff1a..f56e6b0368c 100644 --- a/common/txmgr/broadcaster.go +++ b/common/txmgr/broadcaster.go @@ -760,7 +760,7 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) tryA return eb.saveTryAgainAttempt(ctx, lgr, etx, attempt, replacementAttempt, initialBroadcastAt, fee, feeLimit) } -func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) saveTryAgainAttempt(ctx context.Context, lgr logger.Logger, etx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], attempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], replacementAttempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], initialBroadcastAt time.Time, newFee FEE, newFeeLimit uint32) (err error, retyrable bool) { +func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) saveTryAgainAttempt(ctx context.Context, lgr logger.Logger, etx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], attempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], replacementAttempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], initialBroadcastAt time.Time, newFee FEE, newFeeLimit uint64) (err error, retyrable bool) { if err = eb.txStore.SaveReplacementInProgressAttempt(ctx, attempt, &replacementAttempt); err != nil { return fmt.Errorf("tryAgainWithNewFee failed: %w", err), true } diff --git a/common/txmgr/confirmer.go b/common/txmgr/confirmer.go index 073a6b90fa4..d76e70d9707 100644 --- a/common/txmgr/confirmer.go +++ b/common/txmgr/confirmer.go @@ -793,7 +793,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) bum logFields := ec.logFieldsPreviousAttempt(previousAttempt) var bumpedFee FEE - var bumpedFeeLimit uint32 + var bumpedFeeLimit uint64 bumpedAttempt, bumpedFee, bumpedFeeLimit, _, err = ec.NewBumpTxAttempt(ctx, etx, previousAttempt, previousAttempts, ec.lggr) // if no error, return attempt @@ -1039,7 +1039,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) mar // This operates completely orthogonal to the normal Confirmer and can result in untracked attempts! // Only for emergency usage. // This is in case of some unforeseen scenario where the node is refusing to release the lock. KISS. -func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) ForceRebroadcast(ctx context.Context, seqs []SEQ, fee FEE, address ADDR, overrideGasLimit uint32) error { +func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) ForceRebroadcast(ctx context.Context, seqs []SEQ, fee FEE, address ADDR, overrideGasLimit uint64) error { if len(seqs) == 0 { ec.lggr.Infof("ForceRebroadcast: No sequences provided. Skipping") return nil @@ -1082,7 +1082,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) For return nil } -func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) sendEmptyTransaction(ctx context.Context, fromAddress ADDR, seq SEQ, overrideGasLimit uint32, fee FEE) (string, error) { +func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) sendEmptyTransaction(ctx context.Context, fromAddress ADDR, seq SEQ, overrideGasLimit uint64, fee FEE) (string, error) { gasLimit := overrideGasLimit if gasLimit == 0 { gasLimit = ec.feeConfig.LimitDefault() diff --git a/common/txmgr/txmgr.go b/common/txmgr/txmgr.go index d0b33ad7e30..2bd9ed4d2d2 100644 --- a/common/txmgr/txmgr.go +++ b/common/txmgr/txmgr.go @@ -561,7 +561,7 @@ func (b *Txm[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) SendNative ToAddress: to, EncodedPayload: []byte{}, Value: value, - FeeLimit: gasLimit, + FeeLimit: uint64(gasLimit), Strategy: NewSendEveryStrategy(), } etx, err = b.pruneQueueAndCreateTxn(ctx, txRequest, chainID) diff --git a/common/txmgr/types/client.go b/common/txmgr/types/client.go index 32527e5896e..759b15d6162 100644 --- a/common/txmgr/types/client.go +++ b/common/txmgr/types/client.go @@ -62,9 +62,9 @@ type TransactionClient[ ) (client.SendTxReturnCode, error) SendEmptyTransaction( ctx context.Context, - newTxAttempt func(ctx context.Context, seq SEQ, feeLimit uint32, fee FEE, fromAddress ADDR) (attempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error), + newTxAttempt func(ctx context.Context, seq SEQ, feeLimit uint64, fee FEE, fromAddress ADDR) (attempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error), seq SEQ, - gasLimit uint32, + gasLimit uint64, fee FEE, fromAddress ADDR, ) (txhash string, err error) diff --git a/common/txmgr/types/config.go b/common/txmgr/types/config.go index 502a7f42d5c..53e35cd4b6e 100644 --- a/common/txmgr/types/config.go +++ b/common/txmgr/types/config.go @@ -42,7 +42,7 @@ type BroadcasterListenerConfig interface { type ConfirmerFeeConfig interface { BumpTxDepth() uint32 - LimitDefault() uint32 + LimitDefault() uint64 // from gas.Config BumpThreshold() uint64 diff --git a/common/txmgr/types/mocks/tx_attempt_builder.go b/common/txmgr/types/mocks/tx_attempt_builder.go index 5b9b3e505ad..20ecbde0945 100644 --- a/common/txmgr/types/mocks/tx_attempt_builder.go +++ b/common/txmgr/types/mocks/tx_attempt_builder.go @@ -77,7 +77,7 @@ func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) } // NewBumpTxAttempt provides a mock function with given fields: ctx, tx, previousAttempt, priorAttempts, lggr -func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) NewBumpTxAttempt(ctx context.Context, tx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], previousAttempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], priorAttempts []txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], lggr logger.Logger) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint32, bool, error) { +func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) NewBumpTxAttempt(ctx context.Context, tx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], previousAttempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], priorAttempts []txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], lggr logger.Logger) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint64, bool, error) { ret := _m.Called(ctx, tx, previousAttempt, priorAttempts, lggr) if len(ret) == 0 { @@ -86,10 +86,10 @@ func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) var r0 txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE] var r1 FEE - var r2 uint32 + var r2 uint64 var r3 bool var r4 error - if rf, ok := ret.Get(0).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], []txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint32, bool, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], []txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint64, bool, error)); ok { return rf(ctx, tx, previousAttempt, priorAttempts, lggr) } if rf, ok := ret.Get(0).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], []txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger) txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]); ok { @@ -104,10 +104,10 @@ func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) r1 = ret.Get(1).(FEE) } - if rf, ok := ret.Get(2).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], []txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger) uint32); ok { + if rf, ok := ret.Get(2).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], []txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger) uint64); ok { r2 = rf(ctx, tx, previousAttempt, priorAttempts, lggr) } else { - r2 = ret.Get(2).(uint32) + r2 = ret.Get(2).(uint64) } if rf, ok := ret.Get(3).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], []txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger) bool); ok { @@ -126,7 +126,7 @@ func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) } // NewCustomTxAttempt provides a mock function with given fields: ctx, tx, fee, gasLimit, txType, lggr -func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) NewCustomTxAttempt(ctx context.Context, tx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], fee FEE, gasLimit uint32, txType int, lggr logger.Logger) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], bool, error) { +func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) NewCustomTxAttempt(ctx context.Context, tx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], fee FEE, gasLimit uint64, txType int, lggr logger.Logger) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], bool, error) { ret := _m.Called(ctx, tx, fee, gasLimit, txType, lggr) if len(ret) == 0 { @@ -136,22 +136,22 @@ func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) var r0 txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE] var r1 bool var r2 error - if rf, ok := ret.Get(0).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint32, int, logger.Logger) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], bool, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint64, int, logger.Logger) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], bool, error)); ok { return rf(ctx, tx, fee, gasLimit, txType, lggr) } - if rf, ok := ret.Get(0).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint32, int, logger.Logger) txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]); ok { + if rf, ok := ret.Get(0).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint64, int, logger.Logger) txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]); ok { r0 = rf(ctx, tx, fee, gasLimit, txType, lggr) } else { r0 = ret.Get(0).(txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) } - if rf, ok := ret.Get(1).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint32, int, logger.Logger) bool); ok { + if rf, ok := ret.Get(1).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint64, int, logger.Logger) bool); ok { r1 = rf(ctx, tx, fee, gasLimit, txType, lggr) } else { r1 = ret.Get(1).(bool) } - if rf, ok := ret.Get(2).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint32, int, logger.Logger) error); ok { + if rf, ok := ret.Get(2).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint64, int, logger.Logger) error); ok { r2 = rf(ctx, tx, fee, gasLimit, txType, lggr) } else { r2 = ret.Error(2) @@ -161,7 +161,7 @@ func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) } // NewEmptyTxAttempt provides a mock function with given fields: ctx, seq, feeLimit, fee, fromAddress -func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) NewEmptyTxAttempt(ctx context.Context, seq SEQ, feeLimit uint32, fee FEE, fromAddress ADDR) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error) { +func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) NewEmptyTxAttempt(ctx context.Context, seq SEQ, feeLimit uint64, fee FEE, fromAddress ADDR) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error) { ret := _m.Called(ctx, seq, feeLimit, fee, fromAddress) if len(ret) == 0 { @@ -170,16 +170,16 @@ func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) var r0 txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE] var r1 error - if rf, ok := ret.Get(0).(func(context.Context, SEQ, uint32, FEE, ADDR) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, SEQ, uint64, FEE, ADDR) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error)); ok { return rf(ctx, seq, feeLimit, fee, fromAddress) } - if rf, ok := ret.Get(0).(func(context.Context, SEQ, uint32, FEE, ADDR) txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]); ok { + if rf, ok := ret.Get(0).(func(context.Context, SEQ, uint64, FEE, ADDR) txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]); ok { r0 = rf(ctx, seq, feeLimit, fee, fromAddress) } else { r0 = ret.Get(0).(txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) } - if rf, ok := ret.Get(1).(func(context.Context, SEQ, uint32, FEE, ADDR) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, SEQ, uint64, FEE, ADDR) error); ok { r1 = rf(ctx, seq, feeLimit, fee, fromAddress) } else { r1 = ret.Error(1) @@ -189,7 +189,7 @@ func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) } // NewTxAttempt provides a mock function with given fields: ctx, tx, lggr, opts -func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) NewTxAttempt(ctx context.Context, tx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], lggr logger.Logger, opts ...feetypes.Opt) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint32, bool, error) { +func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) NewTxAttempt(ctx context.Context, tx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], lggr logger.Logger, opts ...feetypes.Opt) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint64, bool, error) { _va := make([]interface{}, len(opts)) for _i := range opts { _va[_i] = opts[_i] @@ -205,10 +205,10 @@ func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) var r0 txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE] var r1 FEE - var r2 uint32 + var r2 uint64 var r3 bool var r4 error - if rf, ok := ret.Get(0).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger, ...feetypes.Opt) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint32, bool, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger, ...feetypes.Opt) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint64, bool, error)); ok { return rf(ctx, tx, lggr, opts...) } if rf, ok := ret.Get(0).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger, ...feetypes.Opt) txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]); ok { @@ -223,10 +223,10 @@ func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) r1 = ret.Get(1).(FEE) } - if rf, ok := ret.Get(2).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger, ...feetypes.Opt) uint32); ok { + if rf, ok := ret.Get(2).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger, ...feetypes.Opt) uint64); ok { r2 = rf(ctx, tx, lggr, opts...) } else { - r2 = ret.Get(2).(uint32) + r2 = ret.Get(2).(uint64) } if rf, ok := ret.Get(3).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger, ...feetypes.Opt) bool); ok { @@ -245,7 +245,7 @@ func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) } // NewTxAttemptWithType provides a mock function with given fields: ctx, tx, lggr, txType, opts -func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) NewTxAttemptWithType(ctx context.Context, tx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], lggr logger.Logger, txType int, opts ...feetypes.Opt) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint32, bool, error) { +func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) NewTxAttemptWithType(ctx context.Context, tx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], lggr logger.Logger, txType int, opts ...feetypes.Opt) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint64, bool, error) { _va := make([]interface{}, len(opts)) for _i := range opts { _va[_i] = opts[_i] @@ -261,10 +261,10 @@ func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) var r0 txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE] var r1 FEE - var r2 uint32 + var r2 uint64 var r3 bool var r4 error - if rf, ok := ret.Get(0).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger, int, ...feetypes.Opt) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint32, bool, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger, int, ...feetypes.Opt) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint64, bool, error)); ok { return rf(ctx, tx, lggr, txType, opts...) } if rf, ok := ret.Get(0).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger, int, ...feetypes.Opt) txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]); ok { @@ -279,10 +279,10 @@ func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) r1 = ret.Get(1).(FEE) } - if rf, ok := ret.Get(2).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger, int, ...feetypes.Opt) uint32); ok { + if rf, ok := ret.Get(2).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger, int, ...feetypes.Opt) uint64); ok { r2 = rf(ctx, tx, lggr, txType, opts...) } else { - r2 = ret.Get(2).(uint32) + r2 = ret.Get(2).(uint64) } if rf, ok := ret.Get(3).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger, int, ...feetypes.Opt) bool); ok { diff --git a/common/txmgr/types/tx.go b/common/txmgr/types/tx.go index 3b294adcd07..76fd7f4b3ab 100644 --- a/common/txmgr/types/tx.go +++ b/common/txmgr/types/tx.go @@ -79,7 +79,7 @@ type TxRequest[ADDR types.Hashable, TX_HASH types.Hashable] struct { ToAddress ADDR EncodedPayload []byte Value big.Int - FeeLimit uint32 + FeeLimit uint64 Meta *TxMeta[ADDR, TX_HASH] ForwarderAddress ADDR @@ -175,7 +175,7 @@ type TxAttempt[ Tx Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE] TxFee FEE // ChainSpecificFeeLimit on the TxAttempt is always the same as the on-chain encoded value for fee limit - ChainSpecificFeeLimit uint32 + ChainSpecificFeeLimit uint64 SignedRawTx []byte Hash TX_HASH CreatedAt time.Time @@ -205,7 +205,7 @@ type Tx[ Value big.Int // FeeLimit on the Tx is always the conceptual gas limit, which is not // necessarily the same as the on-chain encoded value (i.e. Optimism) - FeeLimit uint32 + FeeLimit uint64 Error null.String // BroadcastAt is updated every time an attempt for this tx is re-sent // In almost all cases it will be within a second or so of the actual send time. diff --git a/common/txmgr/types/tx_attempt_builder.go b/common/txmgr/types/tx_attempt_builder.go index 47c71abea35..b242f73e6fc 100644 --- a/common/txmgr/types/tx_attempt_builder.go +++ b/common/txmgr/types/tx_attempt_builder.go @@ -27,18 +27,18 @@ type TxAttemptBuilder[ types.HeadTrackable[HEAD, BLOCK_HASH] // NewTxAttempt builds a transaction using the configured transaction type and fee estimator (new estimation) - NewTxAttempt(ctx context.Context, tx Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], lggr logger.Logger, opts ...feetypes.Opt) (attempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], fee FEE, feeLimit uint32, retryable bool, err error) + NewTxAttempt(ctx context.Context, tx Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], lggr logger.Logger, opts ...feetypes.Opt) (attempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], fee FEE, feeLimit uint64, retryable bool, err error) // NewTxAttemptWithType builds a transaction using the configured fee estimator (new estimation) + passed in tx type - NewTxAttemptWithType(ctx context.Context, tx Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], lggr logger.Logger, txType int, opts ...feetypes.Opt) (attempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], fee FEE, feeLimit uint32, retryable bool, err error) + NewTxAttemptWithType(ctx context.Context, tx Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], lggr logger.Logger, txType int, opts ...feetypes.Opt) (attempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], fee FEE, feeLimit uint64, retryable bool, err error) // NewBumpTxAttempt builds a transaction using the configured fee estimator (bumping) + tx type from previous attempt // this should only be used after an initial attempt has been broadcast and the underlying gas estimator only needs to bump the fee - NewBumpTxAttempt(ctx context.Context, tx Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], previousAttempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], priorAttempts []TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], lggr logger.Logger) (attempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], bumpedFee FEE, bumpedFeeLimit uint32, retryable bool, err error) + NewBumpTxAttempt(ctx context.Context, tx Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], previousAttempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], priorAttempts []TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], lggr logger.Logger) (attempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], bumpedFee FEE, bumpedFeeLimit uint64, retryable bool, err error) // NewCustomTxAttempt builds a transaction using the passed in fee + tx type - NewCustomTxAttempt(ctx context.Context, tx Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], fee FEE, gasLimit uint32, txType int, lggr logger.Logger) (attempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], retryable bool, err error) + NewCustomTxAttempt(ctx context.Context, tx Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], fee FEE, gasLimit uint64, txType int, lggr logger.Logger) (attempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], retryable bool, err error) // NewEmptyTxAttempt is used in ForceRebroadcast to create a signed tx with zero value sent to the zero address - NewEmptyTxAttempt(ctx context.Context, seq SEQ, feeLimit uint32, fee FEE, fromAddress ADDR) (attempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error) + NewEmptyTxAttempt(ctx context.Context, seq SEQ, feeLimit uint64, fee FEE, fromAddress ADDR) (attempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error) } diff --git a/contracts/scripts/generate-automation-master-interface.ts b/contracts/scripts/generate-automation-master-interface.ts index 78c09cf2836..18866b2e695 100644 --- a/contracts/scripts/generate-automation-master-interface.ts +++ b/contracts/scripts/generate-automation-master-interface.ts @@ -9,7 +9,7 @@ import { utils } from 'ethers' import fs from 'fs' import { exec } from 'child_process' -const dest = 'src/v0.8/automation/dev/interfaces/v2_2' +const dest = 'src/v0.8/automation/interfaces/v2_2' const srcDest = `${dest}/IAutomationRegistryMaster.sol` const tmpDest = `${dest}/tmp.txt` diff --git a/contracts/scripts/native_solc_compile_all_automation b/contracts/scripts/native_solc_compile_all_automation index 248462f421a..fda0bc90fc1 100755 --- a/contracts/scripts/native_solc_compile_all_automation +++ b/contracts/scripts/native_solc_compile_all_automation @@ -86,18 +86,17 @@ solc-select use $SOLC_VERSION export SOLC_VERSION=$SOLC_VERSION # v0.8.19 -compileContract automation/dev/v2_2/AutomationRegistrar2_2.sol -compileContract automation/dev/v2_2/AutomationRegistry2_2.sol -compileContract automation/dev/v2_2/AutomationRegistryLogicA2_2.sol -compileContract automation/dev/v2_2/AutomationRegistryLogicB2_2.sol -compileContract automation/dev/v2_2/AutomationUtils2_2.sol -compileContract automation/dev/interfaces/v2_2/IAutomationRegistryMaster.sol -compileContract automation/dev/chains/ArbitrumModule.sol -compileContract automation/dev/chains/ChainModuleBase.sol -compileContract automation/dev/chains/OptimismModule.sol -compileContract automation/dev/chains/ScrollModule.sol - -compileContract automation/dev/interfaces/IChainModule.sol +compileContract automation/v2_2/AutomationRegistry2_2.sol +compileContract automation/v2_2/AutomationRegistryLogicA2_2.sol +compileContract automation/v2_2/AutomationRegistryLogicB2_2.sol +compileContract automation/v2_2/AutomationUtils2_2.sol +compileContract automation/interfaces/v2_2/IAutomationRegistryMaster.sol +compileContract automation/chains/ArbitrumModule.sol +compileContract automation/chains/ChainModuleBase.sol +compileContract automation/chains/OptimismModule.sol +compileContract automation/chains/ScrollModule.sol +compileContract automation/interfaces/IChainModule.sol + compileContract automation/dev/v2_3/AutomationRegistrar2_3.sol compileContract automation/dev/v2_3/AutomationRegistry2_3.sol compileContract automation/dev/v2_3/AutomationRegistryLogicA2_3.sol diff --git a/contracts/src/v0.8/automation/dev/chains/ArbitrumModule.sol b/contracts/src/v0.8/automation/chains/ArbitrumModule.sol similarity index 90% rename from contracts/src/v0.8/automation/dev/chains/ArbitrumModule.sol rename to contracts/src/v0.8/automation/chains/ArbitrumModule.sol index fad7e459c63..e27a0809b7e 100644 --- a/contracts/src/v0.8/automation/dev/chains/ArbitrumModule.sol +++ b/contracts/src/v0.8/automation/chains/ArbitrumModule.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; -import {ArbSys} from "../../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol"; -import {ArbGasInfo} from "../../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbGasInfo.sol"; +import {ArbSys} from "../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol"; +import {ArbGasInfo} from "../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbGasInfo.sol"; import {ChainModuleBase} from "./ChainModuleBase.sol"; contract ArbitrumModule is ChainModuleBase { diff --git a/contracts/src/v0.8/automation/dev/chains/ChainModuleBase.sol b/contracts/src/v0.8/automation/chains/ChainModuleBase.sol similarity index 100% rename from contracts/src/v0.8/automation/dev/chains/ChainModuleBase.sol rename to contracts/src/v0.8/automation/chains/ChainModuleBase.sol diff --git a/contracts/src/v0.8/automation/dev/chains/OptimismModule.sol b/contracts/src/v0.8/automation/chains/OptimismModule.sol similarity index 93% rename from contracts/src/v0.8/automation/dev/chains/OptimismModule.sol rename to contracts/src/v0.8/automation/chains/OptimismModule.sol index 1c5a3f33d1f..91c1c0ed968 100644 --- a/contracts/src/v0.8/automation/dev/chains/OptimismModule.sol +++ b/contracts/src/v0.8/automation/chains/OptimismModule.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; -import {OVM_GasPriceOracle} from "../../../vendor/@eth-optimism/contracts/v0.8.9/contracts/L2/predeploys/OVM_GasPriceOracle.sol"; +import {OVM_GasPriceOracle} from "../../vendor/@eth-optimism/contracts/v0.8.9/contracts/L2/predeploys/OVM_GasPriceOracle.sol"; import {ChainModuleBase} from "./ChainModuleBase.sol"; contract OptimismModule is ChainModuleBase { diff --git a/contracts/src/v0.8/automation/dev/chains/ScrollModule.sol b/contracts/src/v0.8/automation/chains/ScrollModule.sol similarity index 94% rename from contracts/src/v0.8/automation/dev/chains/ScrollModule.sol rename to contracts/src/v0.8/automation/chains/ScrollModule.sol index f01a2b537c3..1e41ed3805f 100644 --- a/contracts/src/v0.8/automation/dev/chains/ScrollModule.sol +++ b/contracts/src/v0.8/automation/chains/ScrollModule.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; -import {IScrollL1GasPriceOracle} from "../../../vendor/@scroll-tech/contracts/src/L2/predeploys/IScrollL1GasPriceOracle.sol"; +import {IScrollL1GasPriceOracle} from "../../vendor/@scroll-tech/contracts/src/L2/predeploys/IScrollL1GasPriceOracle.sol"; import {ChainModuleBase} from "./ChainModuleBase.sol"; contract ScrollModule is ChainModuleBase { diff --git a/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol b/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol index 89bea70af86..99d9202b5e8 100644 --- a/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol +++ b/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol @@ -8,7 +8,7 @@ import {AutomationRegistryBase2_3} from "../v2_3/AutomationRegistryBase2_3.sol"; import {AutomationRegistryLogicA2_3} from "../v2_3/AutomationRegistryLogicA2_3.sol"; import {AutomationRegistryLogicB2_3} from "../v2_3/AutomationRegistryLogicB2_3.sol"; import {IAutomationRegistryMaster} from "../interfaces/v2_3/IAutomationRegistryMaster2_3.sol"; -import {ChainModuleBase} from "../chains/ChainModuleBase.sol"; +import {ChainModuleBase} from "../../chains/ChainModuleBase.sol"; contract AutomationRegistry2_3_SetUp is BaseTest { address internal constant LINK_ETH_FEED = 0x1111111111111111111111111111111111111110; diff --git a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistrar2_2.sol b/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistrar2_2.sol deleted file mode 100644 index 8d2fe775ee8..00000000000 --- a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistrar2_2.sol +++ /dev/null @@ -1,535 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.19; - -import {LinkTokenInterface} from "../../../shared/interfaces/LinkTokenInterface.sol"; -import {IAutomationRegistryMaster} from "../interfaces/v2_2/IAutomationRegistryMaster.sol"; -import {TypeAndVersionInterface} from "../../../interfaces/TypeAndVersionInterface.sol"; -import {ConfirmedOwner} from "../../../shared/access/ConfirmedOwner.sol"; -import {IERC677Receiver} from "../../../shared/interfaces/IERC677Receiver.sol"; - -/** - * @notice Contract to accept requests for upkeep registrations - * @dev There are 2 registration workflows in this contract - * Flow 1. auto approve OFF / manual registration - UI calls `register` function on this contract, this contract owner at a later time then manually - * calls `approve` to register upkeep and emit events to inform UI and others interested. - * Flow 2. auto approve ON / real time registration - UI calls `register` function as before, which calls the `registerUpkeep` function directly on - * keeper registry and then emits approved event to finish the flow automatically without manual intervention. - * The idea is to have same interface(functions,events) for UI or anyone using this contract irrespective of auto approve being enabled or not. - * they can just listen to `RegistrationRequested` & `RegistrationApproved` events and know the status on registrations. - */ -contract AutomationRegistrar2_2 is TypeAndVersionInterface, ConfirmedOwner, IERC677Receiver { - /** - * DISABLED: No auto approvals, all new upkeeps should be approved manually. - * ENABLED_SENDER_ALLOWLIST: Auto approvals for allowed senders subject to max allowed. Manual for rest. - * ENABLED_ALL: Auto approvals for all new upkeeps subject to max allowed. - */ - enum AutoApproveType { - DISABLED, - ENABLED_SENDER_ALLOWLIST, - ENABLED_ALL - } - - bytes4 private constant REGISTER_REQUEST_SELECTOR = this.register.selector; - - mapping(bytes32 => PendingRequest) private s_pendingRequests; - mapping(uint8 => TriggerRegistrationStorage) private s_triggerRegistrations; - - LinkTokenInterface public immutable LINK; - - /** - * @notice versions: - * - KeeperRegistrar 2.1.0: Update for compatability with registry 2.1.0 - * Add auto approval levels by type - * - KeeperRegistrar 2.0.0: Remove source from register - * Breaks our example of "Register an Upkeep using your own deployed contract" - * - KeeperRegistrar 1.1.0: Add functionality for sender allowlist in auto approve - * : Remove rate limit and add max allowed for auto approve - * - KeeperRegistrar 1.0.0: initial release - */ - string public constant override typeAndVersion = "AutomationRegistrar 2.1.0"; - - /** - * @notice TriggerRegistrationStorage stores the auto-approval levels for upkeeps by type - * @member autoApproveType the auto approval setting (see enum) - * @member autoApproveMaxAllowed the max number of upkeeps that can be auto approved of this type - * @member approvedCount the count of upkeeps auto approved of this type - */ - struct TriggerRegistrationStorage { - AutoApproveType autoApproveType; - uint32 autoApproveMaxAllowed; - uint32 approvedCount; - } - - /** - * @notice InitialTriggerConfig configures the auto-approval levels for upkeeps by trigger type - * @dev this struct is only used in the constructor to set the initial values for various trigger configs - * @member triggerType the upkeep type to configure - * @member autoApproveType the auto approval setting (see enum) - * @member autoApproveMaxAllowed the max number of upkeeps that can be auto approved of this type - */ - struct InitialTriggerConfig { - uint8 triggerType; - AutoApproveType autoApproveType; - uint32 autoApproveMaxAllowed; - } - - struct RegistrarConfig { - IAutomationRegistryMaster AutomationRegistry; - uint96 minLINKJuels; - } - - struct PendingRequest { - address admin; - uint96 balance; - } - - struct RegistrationParams { - string name; - bytes encryptedEmail; - address upkeepContract; - uint32 gasLimit; - address adminAddress; - uint8 triggerType; - bytes checkData; - bytes triggerConfig; - bytes offchainConfig; - uint96 amount; - } - - RegistrarConfig private s_config; - // Only applicable if s_config.configType is ENABLED_SENDER_ALLOWLIST - mapping(address => bool) private s_autoApproveAllowedSenders; - - event RegistrationRequested( - bytes32 indexed hash, - string name, - bytes encryptedEmail, - address indexed upkeepContract, - uint32 gasLimit, - address adminAddress, - uint8 triggerType, - bytes triggerConfig, - bytes offchainConfig, - bytes checkData, - uint96 amount - ); - - event RegistrationApproved(bytes32 indexed hash, string displayName, uint256 indexed upkeepId); - - event RegistrationRejected(bytes32 indexed hash); - - event AutoApproveAllowedSenderSet(address indexed senderAddress, bool allowed); - - event ConfigChanged(address AutomationRegistry, uint96 minLINKJuels); - - event TriggerConfigSet(uint8 triggerType, AutoApproveType autoApproveType, uint32 autoApproveMaxAllowed); - - error InvalidAdminAddress(); - error RequestNotFound(); - error HashMismatch(); - error OnlyAdminOrOwner(); - error InsufficientPayment(); - error RegistrationRequestFailed(); - error OnlyLink(); - error AmountMismatch(); - error SenderMismatch(); - error FunctionNotPermitted(); - error LinkTransferFailed(address to); - error InvalidDataLength(); - - /** - * @param LINKAddress Address of Link token - * @param AutomationRegistry keeper registry address - * @param minLINKJuels minimum LINK that new registrations should fund their upkeep with - * @param triggerConfigs the initial config for individual triggers - */ - constructor( - address LINKAddress, - address AutomationRegistry, - uint96 minLINKJuels, - InitialTriggerConfig[] memory triggerConfigs - ) ConfirmedOwner(msg.sender) { - LINK = LinkTokenInterface(LINKAddress); - setConfig(AutomationRegistry, minLINKJuels); - for (uint256 idx = 0; idx < triggerConfigs.length; idx++) { - setTriggerConfig( - triggerConfigs[idx].triggerType, - triggerConfigs[idx].autoApproveType, - triggerConfigs[idx].autoApproveMaxAllowed - ); - } - } - - //EXTERNAL - - /** - * @notice register can only be called through transferAndCall on LINK contract - * @param name string of the upkeep to be registered - * @param encryptedEmail email address of upkeep contact - * @param upkeepContract address to perform upkeep on - * @param gasLimit amount of gas to provide the target contract when performing upkeep - * @param adminAddress address to cancel upkeep and withdraw remaining funds - * @param triggerType the type of trigger for the upkeep - * @param checkData data passed to the contract when checking for upkeep - * @param triggerConfig the config for the trigger - * @param offchainConfig offchainConfig for upkeep in bytes - * @param amount quantity of LINK upkeep is funded with (specified in Juels) - * @param sender address of the sender making the request - */ - function register( - string memory name, - bytes calldata encryptedEmail, - address upkeepContract, - uint32 gasLimit, - address adminAddress, - uint8 triggerType, - bytes memory checkData, - bytes memory triggerConfig, - bytes memory offchainConfig, - uint96 amount, - address sender - ) external onlyLINK { - _register( - RegistrationParams({ - name: name, - encryptedEmail: encryptedEmail, - upkeepContract: upkeepContract, - gasLimit: gasLimit, - adminAddress: adminAddress, - triggerType: triggerType, - checkData: checkData, - triggerConfig: triggerConfig, - offchainConfig: offchainConfig, - amount: amount - }), - sender - ); - } - - /** - * @notice Allows external users to register upkeeps; assumes amount is approved for transfer by the contract - * @param requestParams struct of all possible registration parameters - */ - function registerUpkeep(RegistrationParams calldata requestParams) external returns (uint256) { - if (requestParams.amount < s_config.minLINKJuels) { - revert InsufficientPayment(); - } - - LINK.transferFrom(msg.sender, address(this), requestParams.amount); - - return _register(requestParams, msg.sender); - } - - /** - * @dev register upkeep on AutomationRegistry contract and emit RegistrationApproved event - */ - function approve( - string memory name, - address upkeepContract, - uint32 gasLimit, - address adminAddress, - uint8 triggerType, - bytes calldata checkData, - bytes memory triggerConfig, - bytes calldata offchainConfig, - bytes32 hash - ) external onlyOwner { - PendingRequest memory request = s_pendingRequests[hash]; - if (request.admin == address(0)) { - revert RequestNotFound(); - } - bytes32 expectedHash = keccak256( - abi.encode(upkeepContract, gasLimit, adminAddress, triggerType, checkData, triggerConfig, offchainConfig) - ); - if (hash != expectedHash) { - revert HashMismatch(); - } - delete s_pendingRequests[hash]; - _approve( - RegistrationParams({ - name: name, - encryptedEmail: "", - upkeepContract: upkeepContract, - gasLimit: gasLimit, - adminAddress: adminAddress, - triggerType: triggerType, - checkData: checkData, - triggerConfig: triggerConfig, - offchainConfig: offchainConfig, - amount: request.balance - }), - expectedHash - ); - } - - /** - * @notice cancel will remove a registration request and return the refunds to the request.admin - * @param hash the request hash - */ - function cancel(bytes32 hash) external { - PendingRequest memory request = s_pendingRequests[hash]; - if (!(msg.sender == request.admin || msg.sender == owner())) { - revert OnlyAdminOrOwner(); - } - if (request.admin == address(0)) { - revert RequestNotFound(); - } - delete s_pendingRequests[hash]; - bool success = LINK.transfer(request.admin, request.balance); - if (!success) { - revert LinkTransferFailed(request.admin); - } - emit RegistrationRejected(hash); - } - - /** - * @notice owner calls this function to set contract config - * @param AutomationRegistry new keeper registry address - * @param minLINKJuels minimum LINK that new registrations should fund their upkeep with - */ - function setConfig(address AutomationRegistry, uint96 minLINKJuels) public onlyOwner { - s_config = RegistrarConfig({ - minLINKJuels: minLINKJuels, - AutomationRegistry: IAutomationRegistryMaster(AutomationRegistry) - }); - emit ConfigChanged(AutomationRegistry, minLINKJuels); - } - - /** - * @notice owner calls to set the config for this upkeep type - * @param triggerType the upkeep type to configure - * @param autoApproveType the auto approval setting (see enum) - * @param autoApproveMaxAllowed the max number of upkeeps that can be auto approved of this type - */ - function setTriggerConfig( - uint8 triggerType, - AutoApproveType autoApproveType, - uint32 autoApproveMaxAllowed - ) public onlyOwner { - s_triggerRegistrations[triggerType].autoApproveType = autoApproveType; - s_triggerRegistrations[triggerType].autoApproveMaxAllowed = autoApproveMaxAllowed; - emit TriggerConfigSet(triggerType, autoApproveType, autoApproveMaxAllowed); - } - - /** - * @notice owner calls this function to set allowlist status for senderAddress - * @param senderAddress senderAddress to set the allowlist status for - * @param allowed true if senderAddress needs to be added to allowlist, false if needs to be removed - */ - function setAutoApproveAllowedSender(address senderAddress, bool allowed) external onlyOwner { - s_autoApproveAllowedSenders[senderAddress] = allowed; - - emit AutoApproveAllowedSenderSet(senderAddress, allowed); - } - - /** - * @notice read the allowlist status of senderAddress - * @param senderAddress address to read the allowlist status for - */ - function getAutoApproveAllowedSender(address senderAddress) external view returns (bool) { - return s_autoApproveAllowedSenders[senderAddress]; - } - - /** - * @notice read the current registration configuration - */ - function getConfig() external view returns (address AutomationRegistry, uint256 minLINKJuels) { - RegistrarConfig memory config = s_config; - return (address(config.AutomationRegistry), config.minLINKJuels); - } - - /** - * @notice read the config for this upkeep type - * @param triggerType upkeep type to read config for - */ - function getTriggerRegistrationDetails(uint8 triggerType) external view returns (TriggerRegistrationStorage memory) { - return s_triggerRegistrations[triggerType]; - } - - /** - * @notice gets the admin address and the current balance of a registration request - */ - function getPendingRequest(bytes32 hash) external view returns (address, uint96) { - PendingRequest memory request = s_pendingRequests[hash]; - return (request.admin, request.balance); - } - - /** - * @notice Called when LINK is sent to the contract via `transferAndCall` - * @param sender Address of the sender transfering LINK - * @param amount Amount of LINK sent (specified in Juels) - * @param data Payload of the transaction - */ - function onTokenTransfer( - address sender, - uint256 amount, - bytes calldata data - ) - external - override - onlyLINK - permittedFunctionsForLINK(data) - isActualAmount(amount, data) - isActualSender(sender, data) - { - if (amount < s_config.minLINKJuels) { - revert InsufficientPayment(); - } - (bool success, ) = address(this).delegatecall(data); - // calls register - if (!success) { - revert RegistrationRequestFailed(); - } - } - - // ================================================================ - // | PRIVATE | - // ================================================================ - - /** - * @dev verify registration request and emit RegistrationRequested event - */ - function _register(RegistrationParams memory params, address sender) private returns (uint256) { - if (params.adminAddress == address(0)) { - revert InvalidAdminAddress(); - } - bytes32 hash = keccak256( - abi.encode( - params.upkeepContract, - params.gasLimit, - params.adminAddress, - params.triggerType, - params.checkData, - params.triggerConfig, - params.offchainConfig - ) - ); - - emit RegistrationRequested( - hash, - params.name, - params.encryptedEmail, - params.upkeepContract, - params.gasLimit, - params.adminAddress, - params.triggerType, - params.triggerConfig, - params.offchainConfig, - params.checkData, - params.amount - ); - - uint256 upkeepId; - if (_shouldAutoApprove(s_triggerRegistrations[params.triggerType], sender)) { - s_triggerRegistrations[params.triggerType].approvedCount++; - upkeepId = _approve(params, hash); - } else { - uint96 newBalance = s_pendingRequests[hash].balance + params.amount; - s_pendingRequests[hash] = PendingRequest({admin: params.adminAddress, balance: newBalance}); - } - - return upkeepId; - } - - /** - * @dev register upkeep on AutomationRegistry contract and emit RegistrationApproved event - */ - function _approve(RegistrationParams memory params, bytes32 hash) private returns (uint256) { - IAutomationRegistryMaster AutomationRegistry = s_config.AutomationRegistry; - uint256 upkeepId = AutomationRegistry.registerUpkeep( - params.upkeepContract, - params.gasLimit, - params.adminAddress, - params.triggerType, - params.checkData, - params.triggerConfig, - params.offchainConfig - ); - bool success = LINK.transferAndCall(address(AutomationRegistry), params.amount, abi.encode(upkeepId)); - if (!success) { - revert LinkTransferFailed(address(AutomationRegistry)); - } - emit RegistrationApproved(hash, params.name, upkeepId); - return upkeepId; - } - - /** - * @dev verify sender allowlist if needed and check max limit - */ - function _shouldAutoApprove(TriggerRegistrationStorage memory config, address sender) private view returns (bool) { - if (config.autoApproveType == AutoApproveType.DISABLED) { - return false; - } - if (config.autoApproveType == AutoApproveType.ENABLED_SENDER_ALLOWLIST && (!s_autoApproveAllowedSenders[sender])) { - return false; - } - if (config.approvedCount < config.autoApproveMaxAllowed) { - return true; - } - return false; - } - - // ================================================================ - // | MODIFIERS | - // ================================================================ - - /** - * @dev Reverts if not sent from the LINK token - */ - modifier onlyLINK() { - if (msg.sender != address(LINK)) { - revert OnlyLink(); - } - _; - } - - /** - * @dev Reverts if the given data does not begin with the `register` function selector - * @param _data The data payload of the request - */ - modifier permittedFunctionsForLINK(bytes memory _data) { - bytes4 funcSelector; - assembly { - // solhint-disable-next-line avoid-low-level-calls - funcSelector := mload(add(_data, 32)) // First 32 bytes contain length of data - } - if (funcSelector != REGISTER_REQUEST_SELECTOR) { - revert FunctionNotPermitted(); - } - _; - } - - /** - * @dev Reverts if the actual amount passed does not match the expected amount - * @param expected amount that should match the actual amount - * @param data bytes - */ - modifier isActualAmount(uint256 expected, bytes calldata data) { - // decode register function arguments to get actual amount - (, , , , , , , , , uint96 amount, ) = abi.decode( - data[4:], - (string, bytes, address, uint32, address, uint8, bytes, bytes, bytes, uint96, address) - ); - if (expected != amount) { - revert AmountMismatch(); - } - _; - } - - /** - * @dev Reverts if the actual sender address does not match the expected sender address - * @param expected address that should match the actual sender address - * @param data bytes - */ - modifier isActualSender(address expected, bytes calldata data) { - // decode register function arguments to get actual sender - (, , , , , , , , , , address sender) = abi.decode( - data[4:], - (string, bytes, address, uint32, address, uint8, bytes, bytes, bytes, uint96, address) - ); - if (expected != sender) { - revert SenderMismatch(); - } - _; - } -} diff --git a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryBase2_3.sol b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryBase2_3.sol index 4874bbcb948..764eb5eac09 100644 --- a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryBase2_3.sol +++ b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryBase2_3.sol @@ -11,7 +11,7 @@ import {AggregatorV3Interface} from "../../../shared/interfaces/AggregatorV3Inte import {LinkTokenInterface} from "../../../shared/interfaces/LinkTokenInterface.sol"; import {KeeperCompatibleInterface} from "../../interfaces/KeeperCompatibleInterface.sol"; import {UpkeepFormat} from "../../interfaces/UpkeepTranscoderInterface.sol"; -import {IChainModule} from "../interfaces/IChainModule.sol"; +import {IChainModule} from "../../interfaces/IChainModule.sol"; /** * @notice Base Keeper Registry contract, contains shared logic between diff --git a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicB2_3.sol b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicB2_3.sol index 1f8655967cf..b0a1aa27fd6 100644 --- a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicB2_3.sol +++ b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicB2_3.sol @@ -6,7 +6,7 @@ import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.7.3/contra import {Address} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; import {UpkeepFormat} from "../../interfaces/UpkeepTranscoderInterface.sol"; import {IAutomationForwarder} from "../../interfaces/IAutomationForwarder.sol"; -import {IChainModule} from "../interfaces/IChainModule.sol"; +import {IChainModule} from "../../interfaces/IChainModule.sol"; contract AutomationRegistryLogicB2_3 is AutomationRegistryBase2_3 { using Address for address; diff --git a/contracts/src/v0.8/automation/dev/interfaces/IChainModule.sol b/contracts/src/v0.8/automation/interfaces/IChainModule.sol similarity index 100% rename from contracts/src/v0.8/automation/dev/interfaces/IChainModule.sol rename to contracts/src/v0.8/automation/interfaces/IChainModule.sol diff --git a/contracts/src/v0.8/automation/dev/interfaces/v2_2/IAutomationRegistryMaster.sol b/contracts/src/v0.8/automation/interfaces/v2_2/IAutomationRegistryMaster.sol similarity index 100% rename from contracts/src/v0.8/automation/dev/interfaces/v2_2/IAutomationRegistryMaster.sol rename to contracts/src/v0.8/automation/interfaces/v2_2/IAutomationRegistryMaster.sol diff --git a/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_2.t.sol b/contracts/src/v0.8/automation/test/AutomationRegistry2_2.t.sol similarity index 98% rename from contracts/src/v0.8/automation/dev/test/AutomationRegistry2_2.t.sol rename to contracts/src/v0.8/automation/test/AutomationRegistry2_2.t.sol index 6b05e4f6465..f3eafc0d9a5 100644 --- a/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_2.t.sol +++ b/contracts/src/v0.8/automation/test/AutomationRegistry2_2.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; -import {AutomationForwarderLogic} from "../../AutomationForwarderLogic.sol"; +import {AutomationForwarderLogic} from "../AutomationForwarderLogic.sol"; import {BaseTest} from "./BaseTest.t.sol"; import {AutomationRegistry2_2} from "../v2_2/AutomationRegistry2_2.sol"; import {AutomationRegistryBase2_2} from "../v2_2/AutomationRegistryBase2_2.sol"; diff --git a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistry2_2.sol b/contracts/src/v0.8/automation/v2_2/AutomationRegistry2_2.sol similarity index 97% rename from contracts/src/v0.8/automation/dev/v2_2/AutomationRegistry2_2.sol rename to contracts/src/v0.8/automation/v2_2/AutomationRegistry2_2.sol index 7b37a5eba2c..8add9568d26 100644 --- a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistry2_2.sol +++ b/contracts/src/v0.8/automation/v2_2/AutomationRegistry2_2.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; -import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; -import {Address} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; +import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; +import {Address} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; import {AutomationRegistryBase2_2} from "./AutomationRegistryBase2_2.sol"; import {AutomationRegistryLogicB2_2} from "./AutomationRegistryLogicB2_2.sol"; -import {Chainable} from "../../Chainable.sol"; -import {IERC677Receiver} from "../../../shared/interfaces/IERC677Receiver.sol"; -import {OCR2Abstract} from "../../../shared/ocr2/OCR2Abstract.sol"; +import {Chainable} from "../Chainable.sol"; +import {IERC677Receiver} from "../../shared/interfaces/IERC677Receiver.sol"; +import {OCR2Abstract} from "../../shared/ocr2/OCR2Abstract.sol"; /** * @notice Registry for adding work for Chainlink nodes to perform on client diff --git a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryBase2_2.sol b/contracts/src/v0.8/automation/v2_2/AutomationRegistryBase2_2.sol similarity index 97% rename from contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryBase2_2.sol rename to contracts/src/v0.8/automation/v2_2/AutomationRegistryBase2_2.sol index d415e0e3e1f..546b6e34a91 100644 --- a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryBase2_2.sol +++ b/contracts/src/v0.8/automation/v2_2/AutomationRegistryBase2_2.sol @@ -1,16 +1,16 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; -import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; -import {Address} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; -import {StreamsLookupCompatibleInterface} from "../../interfaces/StreamsLookupCompatibleInterface.sol"; -import {ILogAutomation, Log} from "../../interfaces/ILogAutomation.sol"; -import {IAutomationForwarder} from "../../interfaces/IAutomationForwarder.sol"; -import {ConfirmedOwner} from "../../../shared/access/ConfirmedOwner.sol"; -import {AggregatorV3Interface} from "../../../shared/interfaces/AggregatorV3Interface.sol"; -import {LinkTokenInterface} from "../../../shared/interfaces/LinkTokenInterface.sol"; -import {KeeperCompatibleInterface} from "../../interfaces/KeeperCompatibleInterface.sol"; -import {UpkeepFormat} from "../../interfaces/UpkeepTranscoderInterface.sol"; +import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; +import {Address} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; +import {StreamsLookupCompatibleInterface} from "../interfaces/StreamsLookupCompatibleInterface.sol"; +import {ILogAutomation, Log} from "../interfaces/ILogAutomation.sol"; +import {IAutomationForwarder} from "../interfaces/IAutomationForwarder.sol"; +import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; +import {AggregatorV3Interface} from "../../shared/interfaces/AggregatorV3Interface.sol"; +import {LinkTokenInterface} from "../../shared/interfaces/LinkTokenInterface.sol"; +import {KeeperCompatibleInterface} from "../interfaces/KeeperCompatibleInterface.sol"; +import {UpkeepFormat} from "../interfaces/UpkeepTranscoderInterface.sol"; import {IChainModule} from "../interfaces/IChainModule.sol"; /** diff --git a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicA2_2.sol b/contracts/src/v0.8/automation/v2_2/AutomationRegistryLogicA2_2.sol similarity index 96% rename from contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicA2_2.sol rename to contracts/src/v0.8/automation/v2_2/AutomationRegistryLogicA2_2.sol index b5269fcb63a..dfe78c9db6f 100644 --- a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicA2_2.sol +++ b/contracts/src/v0.8/automation/v2_2/AutomationRegistryLogicA2_2.sol @@ -1,15 +1,15 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; -import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; -import {Address} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; +import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; +import {Address} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; import {AutomationRegistryBase2_2} from "./AutomationRegistryBase2_2.sol"; import {AutomationRegistryLogicB2_2} from "./AutomationRegistryLogicB2_2.sol"; -import {Chainable} from "../../Chainable.sol"; -import {AutomationForwarder} from "../../AutomationForwarder.sol"; -import {IAutomationForwarder} from "../../interfaces/IAutomationForwarder.sol"; -import {UpkeepTranscoderInterfaceV2} from "../../interfaces/UpkeepTranscoderInterfaceV2.sol"; -import {MigratableKeeperRegistryInterfaceV2} from "../../interfaces/MigratableKeeperRegistryInterfaceV2.sol"; +import {Chainable} from "../Chainable.sol"; +import {AutomationForwarder} from "../AutomationForwarder.sol"; +import {IAutomationForwarder} from "../interfaces/IAutomationForwarder.sol"; +import {UpkeepTranscoderInterfaceV2} from "../interfaces/UpkeepTranscoderInterfaceV2.sol"; +import {MigratableKeeperRegistryInterfaceV2} from "../interfaces/MigratableKeeperRegistryInterfaceV2.sol"; /** * @notice Logic contract, works in tandem with AutomationRegistry as a proxy diff --git a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicB2_2.sol b/contracts/src/v0.8/automation/v2_2/AutomationRegistryLogicB2_2.sol similarity index 98% rename from contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicB2_2.sol rename to contracts/src/v0.8/automation/v2_2/AutomationRegistryLogicB2_2.sol index 6ce56577819..3b5354c7be4 100644 --- a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicB2_2.sol +++ b/contracts/src/v0.8/automation/v2_2/AutomationRegistryLogicB2_2.sol @@ -2,10 +2,10 @@ pragma solidity 0.8.19; import {AutomationRegistryBase2_2} from "./AutomationRegistryBase2_2.sol"; -import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; -import {Address} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; -import {UpkeepFormat} from "../../interfaces/UpkeepTranscoderInterface.sol"; -import {IAutomationForwarder} from "../../interfaces/IAutomationForwarder.sol"; +import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; +import {Address} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; +import {UpkeepFormat} from "../interfaces/UpkeepTranscoderInterface.sol"; +import {IAutomationForwarder} from "../interfaces/IAutomationForwarder.sol"; import {IChainModule} from "../interfaces/IChainModule.sol"; contract AutomationRegistryLogicB2_2 is AutomationRegistryBase2_2 { diff --git a/contracts/src/v0.8/automation/dev/v2_2/AutomationUtils2_2.sol b/contracts/src/v0.8/automation/v2_2/AutomationUtils2_2.sol similarity index 95% rename from contracts/src/v0.8/automation/dev/v2_2/AutomationUtils2_2.sol rename to contracts/src/v0.8/automation/v2_2/AutomationUtils2_2.sol index 2558937233a..bcd61ab9510 100644 --- a/contracts/src/v0.8/automation/dev/v2_2/AutomationUtils2_2.sol +++ b/contracts/src/v0.8/automation/v2_2/AutomationUtils2_2.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.19; import {AutomationRegistryBase2_2} from "./AutomationRegistryBase2_2.sol"; -import {Log} from "../../interfaces/ILogAutomation.sol"; +import {Log} from "../interfaces/ILogAutomation.sol"; /** * @notice this file exposes structs that are otherwise internal to the automation registry diff --git a/contracts/src/v0.8/automation/dev/v2_2/LICENSE b/contracts/src/v0.8/automation/v2_2/LICENSE similarity index 100% rename from contracts/src/v0.8/automation/dev/v2_2/LICENSE rename to contracts/src/v0.8/automation/v2_2/LICENSE diff --git a/contracts/src/v0.8/automation/dev/v2_2/README.md b/contracts/src/v0.8/automation/v2_2/README.md similarity index 100% rename from contracts/src/v0.8/automation/dev/v2_2/README.md rename to contracts/src/v0.8/automation/v2_2/README.md diff --git a/contracts/test/v0.8/automation/AutomationRegistrar2_2.test.ts b/contracts/test/v0.8/automation/AutomationRegistrar2_2.test.ts deleted file mode 100644 index b7585462067..00000000000 --- a/contracts/test/v0.8/automation/AutomationRegistrar2_2.test.ts +++ /dev/null @@ -1,1013 +0,0 @@ -import { ethers } from 'hardhat' -import { ContractFactory, Contract } from 'ethers' -import { assert, expect } from 'chai' -import { evmRevert } from '../../test-helpers/matchers' -import { getUsers, Personas } from '../../test-helpers/setup' -import { BigNumber, Signer } from 'ethers' -import { MockV3Aggregator__factory as MockV3AggregatorFactory } from '../../../typechain/factories/MockV3Aggregator__factory' -import { UpkeepMock__factory as UpkeepMockFactory } from '../../../typechain/factories/UpkeepMock__factory' -import { MockV3Aggregator } from '../../../typechain/MockV3Aggregator' -import { UpkeepMock } from '../../../typechain/UpkeepMock' -import { toWei } from '../../test-helpers/helpers' -import { IKeeperRegistryMaster as IKeeperRegistry } from '../../../typechain/IKeeperRegistryMaster' -import { AutomationRegistrar2_2 as Registrar } from '../../../typechain/AutomationRegistrar2_2' -import { deployRegistry21 } from './helpers' - -// copied from KeeperRegistryBase2_2.sol -enum Trigger { - CONDITION, - LOG, -} - -let linkTokenFactory: ContractFactory -let mockV3AggregatorFactory: MockV3AggregatorFactory -let upkeepMockFactory: UpkeepMockFactory - -let personas: Personas - -before(async () => { - personas = (await getUsers()).personas - - linkTokenFactory = await ethers.getContractFactory( - 'src/v0.4/LinkToken.sol:LinkToken', - ) - mockV3AggregatorFactory = (await ethers.getContractFactory( - 'src/v0.8/tests/MockV3Aggregator.sol:MockV3Aggregator', - )) as unknown as MockV3AggregatorFactory - upkeepMockFactory = await ethers.getContractFactory('UpkeepMock') -}) - -const errorMsgs = { - onlyOwner: 'revert Only callable by owner', - onlyAdmin: 'OnlyAdminOrOwner()', - hashPayload: 'HashMismatch()', - requestNotFound: 'RequestNotFound()', -} - -describe('AutomationRegistrar2_2', () => { - const upkeepName = 'SampleUpkeep' - - const linkEth = BigNumber.from(300000000) - const gasWei = BigNumber.from(100) - const performGas = BigNumber.from(100000) - const paymentPremiumPPB = BigNumber.from(250000000) - const flatFeeMicroLink = BigNumber.from(0) - const maxAllowedAutoApprove = 5 - const trigger = '0xdeadbeef' - const offchainConfig = '0x01234567' - - const emptyBytes = '0x00' - const stalenessSeconds = BigNumber.from(43820) - const gasCeilingMultiplier = BigNumber.from(1) - const checkGasLimit = BigNumber.from(20000000) - const fallbackGasPrice = BigNumber.from(200) - const fallbackLinkPrice = BigNumber.from(200000000) - const maxCheckDataSize = BigNumber.from(10000) - const maxPerformDataSize = BigNumber.from(10000) - const maxRevertDataSize = BigNumber.from(1000) - const maxPerformGas = BigNumber.from(5000000) - const minUpkeepSpend = BigNumber.from('1000000000000000000') - const amount = BigNumber.from('5000000000000000000') - const amount1 = BigNumber.from('6000000000000000000') - const transcoder = ethers.constants.AddressZero - const upkeepManager = ethers.Wallet.createRandom().address - - // Enum values are not auto exported in ABI so have to manually declare - const autoApproveType_DISABLED = 0 - const autoApproveType_ENABLED_SENDER_ALLOWLIST = 1 - const autoApproveType_ENABLED_ALL = 2 - - let owner: Signer - let admin: Signer - let someAddress: Signer - let registrarOwner: Signer - let stranger: Signer - let requestSender: Signer - - let linkToken: Contract - let linkEthFeed: MockV3Aggregator - let gasPriceFeed: MockV3Aggregator - let mock: UpkeepMock - let registry: IKeeperRegistry - let registrar: Registrar - - beforeEach(async () => { - owner = personas.Default - admin = personas.Neil - someAddress = personas.Ned - registrarOwner = personas.Nelly - stranger = personas.Nancy - requestSender = personas.Norbert - - linkToken = await linkTokenFactory.connect(owner).deploy() - gasPriceFeed = await mockV3AggregatorFactory - .connect(owner) - .deploy(0, gasWei) - linkEthFeed = await mockV3AggregatorFactory - .connect(owner) - .deploy(9, linkEth) - - registry = await deployRegistry21( - owner, - 0, - linkToken.address, - linkEthFeed.address, - gasPriceFeed.address, - ) - - mock = await upkeepMockFactory.deploy() - - const registrarFactory = await ethers.getContractFactory( - 'AutomationRegistrar2_2', - ) - registrar = await registrarFactory - .connect(registrarOwner) - .deploy(linkToken.address, registry.address, minUpkeepSpend, [ - { - triggerType: Trigger.CONDITION, - autoApproveType: autoApproveType_DISABLED, - autoApproveMaxAllowed: 0, - }, - { - triggerType: Trigger.LOG, - autoApproveType: autoApproveType_DISABLED, - autoApproveMaxAllowed: 0, - }, - ]) - - await linkToken - .connect(owner) - .transfer(await requestSender.getAddress(), toWei('1000')) - - const keepers = [ - await personas.Carol.getAddress(), - await personas.Nancy.getAddress(), - await personas.Ned.getAddress(), - await personas.Neil.getAddress(), - ] - const onchainConfig = { - paymentPremiumPPB, - flatFeeMicroLink, - checkGasLimit, - stalenessSeconds, - gasCeilingMultiplier, - minUpkeepSpend, - maxCheckDataSize, - maxPerformDataSize, - maxRevertDataSize, - maxPerformGas, - fallbackGasPrice, - fallbackLinkPrice, - transcoder, - registrars: [registrar.address], - upkeepPrivilegeManager: upkeepManager, - } - await registry - .connect(owner) - .setConfigTypeSafe(keepers, keepers, 1, onchainConfig, 1, '0x') - }) - - describe('#typeAndVersion', () => { - it('uses the correct type and version', async () => { - const typeAndVersion = await registrar.typeAndVersion() - assert.equal(typeAndVersion, 'AutomationRegistrar 2.1.0') - }) - }) - - describe('#register', () => { - it('reverts if not called by the LINK token', async () => { - await evmRevert( - registrar - .connect(someAddress) - .register( - upkeepName, - emptyBytes, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - amount, - await requestSender.getAddress(), - ), - 'OnlyLink()', - ) - }) - - it('reverts if the amount passed in data mismatches actual amount sent', async () => { - await registrar - .connect(registrarOwner) - .setTriggerConfig( - Trigger.CONDITION, - autoApproveType_ENABLED_ALL, - maxAllowedAutoApprove, - ) - - const abiEncodedBytes = registrar.interface.encodeFunctionData( - 'register', - [ - upkeepName, - emptyBytes, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - amount1, - await requestSender.getAddress(), - ], - ) - - await evmRevert( - linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes), - 'AmountMismatch()', - ) - }) - - it('reverts if the sender passed in data mismatches actual sender', async () => { - const abiEncodedBytes = registrar.interface.encodeFunctionData( - 'register', - [ - upkeepName, - emptyBytes, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - amount, - await admin.getAddress(), // Should have been requestSender.getAddress() - ], - ) - await evmRevert( - linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes), - 'SenderMismatch()', - ) - }) - - it('reverts if the admin address is 0x0000...', async () => { - const abiEncodedBytes = registrar.interface.encodeFunctionData( - 'register', - [ - upkeepName, - emptyBytes, - mock.address, - performGas, - '0x0000000000000000000000000000000000000000', - 0, - emptyBytes, - trigger, - offchainConfig, - amount, - await requestSender.getAddress(), - ], - ) - - await evmRevert( - linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes), - 'RegistrationRequestFailed()', - ) - }) - - it('Auto Approve ON - registers an upkeep on KeeperRegistry instantly and emits both RegistrationRequested and RegistrationApproved events', async () => { - //set auto approve ON with high threshold limits - await registrar - .connect(registrarOwner) - .setTriggerConfig( - Trigger.CONDITION, - autoApproveType_ENABLED_ALL, - maxAllowedAutoApprove, - ) - - //register with auto approve ON - const abiEncodedBytes = registrar.interface.encodeFunctionData( - 'register', - [ - upkeepName, - emptyBytes, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - amount, - await requestSender.getAddress(), - ], - ) - const tx = await linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes) - - const [id] = await registry.getActiveUpkeepIDs(0, 1) - - //confirm if a new upkeep has been registered and the details are the same as the one just registered - const newupkeep = await registry.getUpkeep(id) - assert.equal(newupkeep.target, mock.address) - assert.equal(newupkeep.admin, await admin.getAddress()) - assert.equal(newupkeep.checkData, emptyBytes) - assert.equal(newupkeep.balance.toString(), amount.toString()) - assert.equal(newupkeep.performGas, performGas.toNumber()) - assert.equal(newupkeep.offchainConfig, offchainConfig) - - await expect(tx).to.emit(registrar, 'RegistrationRequested') - await expect(tx).to.emit(registrar, 'RegistrationApproved') - }) - - it('Auto Approve OFF - does not registers an upkeep on KeeperRegistry, emits only RegistrationRequested event', async () => { - //get upkeep count before attempting registration - const beforeCount = (await registry.getState()).state.numUpkeeps - - //set auto approve OFF, threshold limits dont matter in this case - await registrar - .connect(registrarOwner) - .setTriggerConfig( - Trigger.CONDITION, - autoApproveType_DISABLED, - maxAllowedAutoApprove, - ) - - //register with auto approve OFF - const abiEncodedBytes = registrar.interface.encodeFunctionData( - 'register', - [ - upkeepName, - emptyBytes, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - amount, - await requestSender.getAddress(), - ], - ) - const tx = await linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes) - const receipt = await tx.wait() - - //get upkeep count after attempting registration - const afterCount = (await registry.getState()).state.numUpkeeps - //confirm that a new upkeep has NOT been registered and upkeep count is still the same - assert.deepEqual(beforeCount, afterCount) - - //confirm that only RegistrationRequested event is emitted and RegistrationApproved event is not - await expect(tx).to.emit(registrar, 'RegistrationRequested') - await expect(tx).not.to.emit(registrar, 'RegistrationApproved') - - const hash = receipt.logs[2].topics[1] - const pendingRequest = await registrar.getPendingRequest(hash) - assert.equal(await admin.getAddress(), pendingRequest[0]) - assert.ok(amount.eq(pendingRequest[1])) - }) - - it('Auto Approve ON - Throttle max approvals - does not register an upkeep on KeeperRegistry beyond the max limit, emits only RegistrationRequested event after limit is hit', async () => { - assert.equal((await registry.getState()).state.numUpkeeps.toNumber(), 0) - - //set auto approve on, with max 1 allowed - await registrar - .connect(registrarOwner) - .setTriggerConfig(Trigger.CONDITION, autoApproveType_ENABLED_ALL, 1) - - //set auto approve on, with max 1 allowed - await registrar - .connect(registrarOwner) - .setTriggerConfig(Trigger.LOG, autoApproveType_ENABLED_ALL, 1) - - // register within threshold, new upkeep should be registered - let abiEncodedBytes = registrar.interface.encodeFunctionData('register', [ - upkeepName, - emptyBytes, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - amount, - await requestSender.getAddress(), - ]) - await linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes) - assert.equal((await registry.getState()).state.numUpkeeps.toNumber(), 1) // 0 -> 1 - - // try registering another one, new upkeep should not be registered - abiEncodedBytes = registrar.interface.encodeFunctionData('register', [ - upkeepName, - emptyBytes, - mock.address, - performGas.toNumber() + 1, // make unique hash - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - amount, - await requestSender.getAddress(), - ]) - await linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes) - assert.equal((await registry.getState()).state.numUpkeeps.toNumber(), 1) // Still 1 - - // register a second type of upkeep, different limit - abiEncodedBytes = registrar.interface.encodeFunctionData('register', [ - upkeepName, - emptyBytes, - mock.address, - performGas, - await admin.getAddress(), - Trigger.LOG, - emptyBytes, - trigger, - offchainConfig, - amount, - await requestSender.getAddress(), - ]) - await linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes) - assert.equal((await registry.getState()).state.numUpkeeps.toNumber(), 2) // 1 -> 2 - - // Now set new max limit to 2. One more upkeep should get auto approved - await registrar - .connect(registrarOwner) - .setTriggerConfig(Trigger.CONDITION, autoApproveType_ENABLED_ALL, 2) - - abiEncodedBytes = registrar.interface.encodeFunctionData('register', [ - upkeepName, - emptyBytes, - mock.address, - performGas.toNumber() + 2, // make unique hash - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - amount, - await requestSender.getAddress(), - ]) - await linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes) - assert.equal((await registry.getState()).state.numUpkeeps.toNumber(), 3) // 2 -> 3 - - // One more upkeep should not get registered - abiEncodedBytes = registrar.interface.encodeFunctionData('register', [ - upkeepName, - emptyBytes, - mock.address, - performGas.toNumber() + 3, // make unique hash - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - amount, - await requestSender.getAddress(), - ]) - await linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes) - assert.equal((await registry.getState()).state.numUpkeeps.toNumber(), 3) // Still 3 - }) - - it('Auto Approve Sender Allowlist - sender in allowlist - registers an upkeep on KeeperRegistry instantly and emits both RegistrationRequested and RegistrationApproved events', async () => { - const senderAddress = await requestSender.getAddress() - - //set auto approve to ENABLED_SENDER_ALLOWLIST type with high threshold limits - await registrar - .connect(registrarOwner) - .setTriggerConfig( - Trigger.CONDITION, - autoApproveType_ENABLED_SENDER_ALLOWLIST, - maxAllowedAutoApprove, - ) - - // Add sender to allowlist - await registrar - .connect(registrarOwner) - .setAutoApproveAllowedSender(senderAddress, true) - - //register with auto approve ON - const abiEncodedBytes = registrar.interface.encodeFunctionData( - 'register', - [ - upkeepName, - emptyBytes, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - amount, - await requestSender.getAddress(), - ], - ) - const tx = await linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes) - - const [id] = await registry.getActiveUpkeepIDs(0, 1) - - //confirm if a new upkeep has been registered and the details are the same as the one just registered - const newupkeep = await registry.getUpkeep(id) - assert.equal(newupkeep.target, mock.address) - assert.equal(newupkeep.admin, await admin.getAddress()) - assert.equal(newupkeep.checkData, emptyBytes) - assert.equal(newupkeep.balance.toString(), amount.toString()) - assert.equal(newupkeep.performGas, performGas.toNumber()) - - await expect(tx).to.emit(registrar, 'RegistrationRequested') - await expect(tx).to.emit(registrar, 'RegistrationApproved') - }) - - it('Auto Approve Sender Allowlist - sender NOT in allowlist - does not registers an upkeep on KeeperRegistry, emits only RegistrationRequested event', async () => { - const beforeCount = (await registry.getState()).state.numUpkeeps - const senderAddress = await requestSender.getAddress() - - //set auto approve to ENABLED_SENDER_ALLOWLIST type with high threshold limits - await registrar - .connect(registrarOwner) - .setTriggerConfig( - Trigger.CONDITION, - autoApproveType_ENABLED_SENDER_ALLOWLIST, - maxAllowedAutoApprove, - ) - - // Explicitly remove sender from allowlist - await registrar - .connect(registrarOwner) - .setAutoApproveAllowedSender(senderAddress, false) - - //register. auto approve shouldn't happen - const abiEncodedBytes = registrar.interface.encodeFunctionData( - 'register', - [ - upkeepName, - emptyBytes, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - amount, - await requestSender.getAddress(), - ], - ) - const tx = await linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes) - const receipt = await tx.wait() - - //get upkeep count after attempting registration - const afterCount = (await registry.getState()).state.numUpkeeps - //confirm that a new upkeep has NOT been registered and upkeep count is still the same - assert.deepEqual(beforeCount, afterCount) - - //confirm that only RegistrationRequested event is emitted and RegistrationApproved event is not - await expect(tx).to.emit(registrar, 'RegistrationRequested') - await expect(tx).not.to.emit(registrar, 'RegistrationApproved') - - const hash = receipt.logs[2].topics[1] - const pendingRequest = await registrar.getPendingRequest(hash) - assert.equal(await admin.getAddress(), pendingRequest[0]) - assert.ok(amount.eq(pendingRequest[1])) - }) - }) - - describe('#registerUpkeep', () => { - it('reverts with empty message if amount sent is not available in LINK allowance', async () => { - await evmRevert( - registrar.connect(someAddress).registerUpkeep({ - name: upkeepName, - upkeepContract: mock.address, - gasLimit: performGas, - adminAddress: await admin.getAddress(), - triggerType: 0, - checkData: emptyBytes, - triggerConfig: trigger, - offchainConfig: emptyBytes, - amount, - encryptedEmail: emptyBytes, - }), - '', - ) - }) - - it('reverts if the amount passed in data is less than configured minimum', async () => { - await registrar - .connect(registrarOwner) - .setTriggerConfig( - Trigger.CONDITION, - autoApproveType_ENABLED_ALL, - maxAllowedAutoApprove, - ) - - // amt is one order of magnitude less than minUpkeepSpend - const amt = BigNumber.from('100000000000000000') - - await evmRevert( - registrar.connect(someAddress).registerUpkeep({ - name: upkeepName, - upkeepContract: mock.address, - gasLimit: performGas, - adminAddress: await admin.getAddress(), - triggerType: 0, - checkData: emptyBytes, - triggerConfig: trigger, - offchainConfig: emptyBytes, - amount: amt, - encryptedEmail: emptyBytes, - }), - 'InsufficientPayment()', - ) - }) - - it('Auto Approve ON - registers an upkeep on KeeperRegistry instantly and emits both RegistrationRequested and RegistrationApproved events', async () => { - //set auto approve ON with high threshold limits - await registrar - .connect(registrarOwner) - .setTriggerConfig( - Trigger.CONDITION, - autoApproveType_ENABLED_ALL, - maxAllowedAutoApprove, - ) - - await linkToken.connect(requestSender).approve(registrar.address, amount) - - const tx = await registrar.connect(requestSender).registerUpkeep({ - name: upkeepName, - upkeepContract: mock.address, - gasLimit: performGas, - adminAddress: await admin.getAddress(), - triggerType: 0, - checkData: emptyBytes, - triggerConfig: trigger, - offchainConfig, - amount, - encryptedEmail: emptyBytes, - }) - assert.equal((await registry.getState()).state.numUpkeeps.toNumber(), 1) // 0 -> 1 - - //confirm if a new upkeep has been registered and the details are the same as the one just registered - const [id] = await registry.getActiveUpkeepIDs(0, 1) - const newupkeep = await registry.getUpkeep(id) - assert.equal(newupkeep.target, mock.address) - assert.equal(newupkeep.admin, await admin.getAddress()) - assert.equal(newupkeep.checkData, emptyBytes) - assert.equal(newupkeep.balance.toString(), amount.toString()) - assert.equal(newupkeep.performGas, performGas.toNumber()) - assert.equal(newupkeep.offchainConfig, offchainConfig) - - await expect(tx).to.emit(registrar, 'RegistrationRequested') - await expect(tx).to.emit(registrar, 'RegistrationApproved') - }) - }) - - describe('#setAutoApproveAllowedSender', () => { - it('reverts if not called by the owner', async () => { - const tx = registrar - .connect(stranger) - .setAutoApproveAllowedSender(await admin.getAddress(), false) - await evmRevert(tx, 'Only callable by owner') - }) - - it('sets the allowed status correctly and emits log', async () => { - const senderAddress = await stranger.getAddress() - let tx = await registrar - .connect(registrarOwner) - .setAutoApproveAllowedSender(senderAddress, true) - await expect(tx) - .to.emit(registrar, 'AutoApproveAllowedSenderSet') - .withArgs(senderAddress, true) - - let senderAllowedStatus = await registrar - .connect(owner) - .getAutoApproveAllowedSender(senderAddress) - assert.isTrue(senderAllowedStatus) - - tx = await registrar - .connect(registrarOwner) - .setAutoApproveAllowedSender(senderAddress, false) - await expect(tx) - .to.emit(registrar, 'AutoApproveAllowedSenderSet') - .withArgs(senderAddress, false) - - senderAllowedStatus = await registrar - .connect(owner) - .getAutoApproveAllowedSender(senderAddress) - assert.isFalse(senderAllowedStatus) - }) - }) - - describe('#setTriggerConfig', () => { - it('reverts if not called by the owner', async () => { - const tx = registrar - .connect(stranger) - .setTriggerConfig(Trigger.LOG, autoApproveType_ENABLED_ALL, 100) - await evmRevert(tx, 'Only callable by owner') - }) - - it('changes the config', async () => { - const tx = await registrar - .connect(registrarOwner) - .setTriggerConfig(Trigger.LOG, autoApproveType_ENABLED_ALL, 100) - await registrar.getTriggerRegistrationDetails(Trigger.LOG) - await expect(tx) - .to.emit(registrar, 'TriggerConfigSet') - .withArgs(Trigger.LOG, autoApproveType_ENABLED_ALL, 100) - }) - }) - - describe('#approve', () => { - let hash: string - - beforeEach(async () => { - await registrar - .connect(registrarOwner) - .setTriggerConfig( - Trigger.CONDITION, - autoApproveType_DISABLED, - maxAllowedAutoApprove, - ) - - //register with auto approve OFF - const abiEncodedBytes = registrar.interface.encodeFunctionData( - 'register', - [ - upkeepName, - emptyBytes, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - amount, - await requestSender.getAddress(), - ], - ) - - const tx = await linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes) - const receipt = await tx.wait() - hash = receipt.logs[2].topics[1] - }) - - it('reverts if not called by the owner', async () => { - const tx = registrar - .connect(stranger) - .approve( - upkeepName, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - emptyBytes, - hash, - ) - await evmRevert(tx, 'Only callable by owner') - }) - - it('reverts if the hash does not exist', async () => { - const tx = registrar - .connect(registrarOwner) - .approve( - upkeepName, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - emptyBytes, - '0x000000000000000000000000322813fd9a801c5507c9de605d63cea4f2ce6c44', - ) - await evmRevert(tx, errorMsgs.requestNotFound) - }) - - it('reverts if any member of the payload changes', async () => { - let tx = registrar - .connect(registrarOwner) - .approve( - upkeepName, - ethers.Wallet.createRandom().address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - emptyBytes, - hash, - ) - await evmRevert(tx, errorMsgs.hashPayload) - tx = registrar - .connect(registrarOwner) - .approve( - upkeepName, - mock.address, - 10000, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - emptyBytes, - hash, - ) - await evmRevert(tx, errorMsgs.hashPayload) - tx = registrar - .connect(registrarOwner) - .approve( - upkeepName, - mock.address, - performGas, - ethers.Wallet.createRandom().address, - 0, - emptyBytes, - trigger, - emptyBytes, - hash, - ) - await evmRevert(tx, errorMsgs.hashPayload) - tx = registrar - .connect(registrarOwner) - .approve( - upkeepName, - mock.address, - performGas, - await admin.getAddress(), - 0, - '0x1234', - trigger, - emptyBytes, - hash, - ) - await evmRevert(tx, errorMsgs.hashPayload) - }) - - it('approves an existing registration request', async () => { - const tx = await registrar - .connect(registrarOwner) - .approve( - upkeepName, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - hash, - ) - await expect(tx).to.emit(registrar, 'RegistrationApproved') - }) - - it('deletes the request afterwards / reverts if the request DNE', async () => { - await registrar - .connect(registrarOwner) - .approve( - upkeepName, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - hash, - ) - const tx = registrar - .connect(registrarOwner) - .approve( - upkeepName, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - hash, - ) - await evmRevert(tx, errorMsgs.requestNotFound) - }) - }) - - describe('#cancel', () => { - let hash: string - - beforeEach(async () => { - await registrar - .connect(registrarOwner) - .setTriggerConfig( - Trigger.CONDITION, - autoApproveType_DISABLED, - maxAllowedAutoApprove, - ) - - //register with auto approve OFF - const abiEncodedBytes = registrar.interface.encodeFunctionData( - 'register', - [ - upkeepName, - emptyBytes, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - amount, - await requestSender.getAddress(), - ], - ) - const tx = await linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes) - const receipt = await tx.wait() - hash = receipt.logs[2].topics[1] - // submit duplicate request (increase balance) - await linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes) - }) - - it('reverts if not called by the admin / owner', async () => { - const tx = registrar.connect(stranger).cancel(hash) - await evmRevert(tx, errorMsgs.onlyAdmin) - }) - - it('reverts if the hash does not exist', async () => { - const tx = registrar - .connect(registrarOwner) - .cancel( - '0x000000000000000000000000322813fd9a801c5507c9de605d63cea4f2ce6c44', - ) - await evmRevert(tx, errorMsgs.requestNotFound) - }) - - it('refunds the total request balance to the admin address if owner cancels', async () => { - const before = await linkToken.balanceOf(await admin.getAddress()) - const tx = await registrar.connect(registrarOwner).cancel(hash) - const after = await linkToken.balanceOf(await admin.getAddress()) - assert.isTrue(after.sub(before).eq(amount.mul(BigNumber.from(2)))) - await expect(tx).to.emit(registrar, 'RegistrationRejected') - }) - - it('refunds the total request balance to the admin address if admin cancels', async () => { - const before = await linkToken.balanceOf(await admin.getAddress()) - const tx = await registrar.connect(admin).cancel(hash) - const after = await linkToken.balanceOf(await admin.getAddress()) - assert.isTrue(after.sub(before).eq(amount.mul(BigNumber.from(2)))) - await expect(tx).to.emit(registrar, 'RegistrationRejected') - }) - - it('deletes the request hash', async () => { - await registrar.connect(registrarOwner).cancel(hash) - let tx = registrar.connect(registrarOwner).cancel(hash) - await evmRevert(tx, errorMsgs.requestNotFound) - tx = registrar - .connect(registrarOwner) - .approve( - upkeepName, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - emptyBytes, - hash, - ) - await evmRevert(tx, errorMsgs.requestNotFound) - }) - }) -}) diff --git a/core/capabilities/targets/write_target.go b/core/capabilities/targets/write_target.go index 531730cc089..a7452be7fc8 100644 --- a/core/capabilities/targets/write_target.go +++ b/core/capabilities/targets/write_target.go @@ -212,7 +212,7 @@ func (cap *EvmWrite) Execute(ctx context.Context, callback chan<- capabilities.C FromAddress: config.FromAddress().Address(), ToAddress: config.ForwarderAddress().Address(), EncodedPayload: calldata, - FeeLimit: uint32(defaultGasLimit), + FeeLimit: uint64(defaultGasLimit), Meta: txMeta, Strategy: strategy, Checker: checker, diff --git a/core/chains/evm/client/errors.go b/core/chains/evm/client/errors.go index cedeb37d2e4..8095c122508 100644 --- a/core/chains/evm/client/errors.go +++ b/core/chains/evm/client/errors.go @@ -140,6 +140,7 @@ var arbitrum = ClientErrors{ Fatal: arbitrumFatal, L2FeeTooLow: regexp.MustCompile(`(: |^)max fee per gas less than block base fee(:|$)`), L2Full: regexp.MustCompile(`(: |^)(queue full|sequencer pending tx pool full, please try again)(:|$)`), + ServiceUnavailable: regexp.MustCompile(`(: |^)502 Bad Gateway: [\s\S]*$`), } var celo = ClientErrors{ diff --git a/core/chains/evm/client/errors_test.go b/core/chains/evm/client/errors_test.go index 21b4981ff17..a59d3fbf719 100644 --- a/core/chains/evm/client/errors_test.go +++ b/core/chains/evm/client/errors_test.go @@ -213,6 +213,7 @@ func Test_Eth_Errors(t *testing.T) { t.Run("IsServiceUnavailable", func(t *testing.T) { tests := []errorCase{ {"call failed: 503 Service Unavailable: \r\n503 Service Temporarily Unavailable\r\n\r\n

503 Service Temporarily Unavailable

\r\n\r\n\r\n", true, "Nethermind"}, + {"call failed: 502 Bad Gateway: \r\n502 Bad Gateway\r\n\r\n

502 Bad Gateway

\r\n
", true, "Arbitrum"}, } for _, test := range tests { err = evmclient.NewSendErrorS(test.message) diff --git a/core/chains/evm/config/chain_scoped_gas_estimator.go b/core/chains/evm/config/chain_scoped_gas_estimator.go index 0c52cf0a468..9d7d10356f7 100644 --- a/core/chains/evm/config/chain_scoped_gas_estimator.go +++ b/core/chains/evm/config/chain_scoped_gas_estimator.go @@ -63,11 +63,11 @@ func (g *gasEstimatorConfig) FeeCapDefault() *assets.Wei { return g.c.FeeCapDefault } -func (g *gasEstimatorConfig) LimitDefault() uint32 { +func (g *gasEstimatorConfig) LimitDefault() uint64 { return *g.c.LimitDefault } -func (g *gasEstimatorConfig) LimitMax() uint32 { +func (g *gasEstimatorConfig) LimitMax() uint64 { return *g.c.LimitMax } diff --git a/core/chains/evm/config/config.go b/core/chains/evm/config/config.go index c878fea46e9..c9c3273f086 100644 --- a/core/chains/evm/config/config.go +++ b/core/chains/evm/config/config.go @@ -97,8 +97,8 @@ type GasEstimator interface { BumpTxDepth() uint32 BumpMin() *assets.Wei FeeCapDefault() *assets.Wei - LimitDefault() uint32 - LimitMax() uint32 + LimitDefault() uint64 + LimitMax() uint64 LimitMultiplier() float32 LimitTransfer() uint32 PriceDefault() *assets.Wei diff --git a/core/chains/evm/config/config_test.go b/core/chains/evm/config/config_test.go index f62f540dafc..07fe392b69c 100644 --- a/core/chains/evm/config/config_test.go +++ b/core/chains/evm/config/config_test.go @@ -277,8 +277,8 @@ func TestChainScopedConfig_GasEstimator(t *testing.T) { assert.Equal(t, assets.GWei(20), ge.PriceDefault()) assert.Equal(t, assets.GWei(500), ge.PriceMax()) assert.Equal(t, assets.GWei(1), ge.PriceMin()) - assert.Equal(t, uint32(500000), ge.LimitDefault()) - assert.Equal(t, uint32(500000), ge.LimitMax()) + assert.Equal(t, uint64(500000), ge.LimitDefault()) + assert.Equal(t, uint64(500000), ge.LimitMax()) assert.Equal(t, float32(1), ge.LimitMultiplier()) assert.Equal(t, uint32(21000), ge.LimitTransfer()) assert.Equal(t, assets.GWei(5), ge.BumpMin()) @@ -317,7 +317,7 @@ func TestChainScopedConfig_Profiles(t *testing.T) { tests := []struct { name string chainID int64 - expectedGasLimitDefault uint32 + expectedGasLimitDefault uint64 expectedMinimumContractPayment string }{ {"default", 0, 500000, "0.00001"}, diff --git a/core/chains/evm/config/mocks/gas_estimator.go b/core/chains/evm/config/mocks/gas_estimator.go index 69a2c852757..b1b25c0ee41 100644 --- a/core/chains/evm/config/mocks/gas_estimator.go +++ b/core/chains/evm/config/mocks/gas_estimator.go @@ -149,18 +149,18 @@ func (_m *GasEstimator) FeeCapDefault() *assets.Wei { } // LimitDefault provides a mock function with given fields: -func (_m *GasEstimator) LimitDefault() uint32 { +func (_m *GasEstimator) LimitDefault() uint64 { ret := _m.Called() if len(ret) == 0 { panic("no return value specified for LimitDefault") } - var r0 uint32 - if rf, ok := ret.Get(0).(func() uint32); ok { + var r0 uint64 + if rf, ok := ret.Get(0).(func() uint64); ok { r0 = rf() } else { - r0 = ret.Get(0).(uint32) + r0 = ret.Get(0).(uint64) } return r0 @@ -187,18 +187,18 @@ func (_m *GasEstimator) LimitJobType() config.LimitJobType { } // LimitMax provides a mock function with given fields: -func (_m *GasEstimator) LimitMax() uint32 { +func (_m *GasEstimator) LimitMax() uint64 { ret := _m.Called() if len(ret) == 0 { panic("no return value specified for LimitMax") } - var r0 uint32 - if rf, ok := ret.Get(0).(func() uint32); ok { + var r0 uint64 + if rf, ok := ret.Get(0).(func() uint64); ok { r0 = rf() } else { - r0 = ret.Get(0).(uint32) + r0 = ret.Get(0).(uint64) } return r0 diff --git a/core/chains/evm/config/toml/config.go b/core/chains/evm/config/toml/config.go index 1ab4aa20d01..b84993b28a6 100644 --- a/core/chains/evm/config/toml/config.go +++ b/core/chains/evm/config/toml/config.go @@ -481,8 +481,8 @@ type GasEstimator struct { PriceMax *assets.Wei PriceMin *assets.Wei - LimitDefault *uint32 - LimitMax *uint32 + LimitDefault *uint64 + LimitMax *uint64 LimitMultiplier *decimal.Decimal LimitTransfer *uint32 LimitJobType GasLimitJobType `toml:",omitempty"` diff --git a/core/chains/evm/config/toml/defaults/zkSync_Goerli.toml b/core/chains/evm/config/toml/defaults/zkSync_Goerli.toml index 04529a41b81..be3bc22b812 100644 --- a/core/chains/evm/config/toml/defaults/zkSync_Goerli.toml +++ b/core/chains/evm/config/toml/defaults/zkSync_Goerli.toml @@ -6,7 +6,7 @@ MinIncomingConfirmations = 1 NoNewHeadsThreshold = '1m' [GasEstimator] -LimitDefault = 3_500_000 +LimitDefault = 100_000_000 PriceMax = 18446744073709551615 PriceMin = 0 diff --git a/core/chains/evm/config/toml/defaults/zkSync_Mainnet.toml b/core/chains/evm/config/toml/defaults/zkSync_Mainnet.toml index d7808edd15f..84ddac91db3 100644 --- a/core/chains/evm/config/toml/defaults/zkSync_Mainnet.toml +++ b/core/chains/evm/config/toml/defaults/zkSync_Mainnet.toml @@ -6,7 +6,7 @@ MinIncomingConfirmations = 1 NoNewHeadsThreshold = '1m' [GasEstimator] -LimitDefault = 3_500_000 +LimitDefault = 100_000_000 PriceMax = 18446744073709551615 PriceMin = 0 diff --git a/core/chains/evm/config/toml/defaults/zkSync_Sepolia.toml b/core/chains/evm/config/toml/defaults/zkSync_Sepolia.toml new file mode 100644 index 00000000000..0801e54acc9 --- /dev/null +++ b/core/chains/evm/config/toml/defaults/zkSync_Sepolia.toml @@ -0,0 +1,14 @@ +ChainID = '300' +ChainType = 'zksync' +FinalityDepth = 1 +LogPollInterval = '5s' +MinIncomingConfirmations = 1 +NoNewHeadsThreshold = '1m' + +[GasEstimator] +LimitDefault = 100_000_000 +PriceMax = 18446744073709551615 +PriceMin = 0 + +[HeadTracker] +HistoryDepth = 5 diff --git a/core/chains/evm/gas/arbitrum_estimator.go b/core/chains/evm/gas/arbitrum_estimator.go index 525d439e3e4..40366c5b998 100644 --- a/core/chains/evm/gas/arbitrum_estimator.go +++ b/core/chains/evm/gas/arbitrum_estimator.go @@ -23,7 +23,7 @@ import ( ) type ArbConfig interface { - LimitMax() uint32 + LimitMax() uint64 BumpPercent() uint16 BumpMin() *assets.Wei } @@ -105,7 +105,7 @@ func (a *arbitrumEstimator) HealthReport() map[string]error { // - Limit is computed from the dynamic values perL2Tx and perL1CalldataUnit, provided by the getPricesInArbGas() method // of the precompilie contract at ArbGasInfoAddress. perL2Tx is a constant amount of gas, and perL1CalldataUnit is // multiplied by the length of the tx calldata. The sum of these two values plus the original l2GasLimit is returned. -func (a *arbitrumEstimator) GetLegacyGas(ctx context.Context, calldata []byte, l2GasLimit uint32, maxGasPriceWei *assets.Wei, opts ...feetypes.Opt) (gasPrice *assets.Wei, chainSpecificGasLimit uint32, err error) { +func (a *arbitrumEstimator) GetLegacyGas(ctx context.Context, calldata []byte, l2GasLimit uint64, maxGasPriceWei *assets.Wei, opts ...feetypes.Opt) (gasPrice *assets.Wei, chainSpecificGasLimit uint64, err error) { gasPrice, _, err = a.EvmEstimator.GetLegacyGas(ctx, calldata, l2GasLimit, maxGasPriceWei, opts...) if err != nil { return @@ -134,7 +134,7 @@ func (a *arbitrumEstimator) GetLegacyGas(ctx context.Context, calldata []byte, l } } perL2Tx, perL1CalldataUnit := a.getPricesInArbGas() - chainSpecificGasLimit = l2GasLimit + perL2Tx + uint32(len(calldata))*perL1CalldataUnit + chainSpecificGasLimit = l2GasLimit + uint64(perL2Tx) + uint64(len(calldata))*uint64(perL1CalldataUnit) a.logger.Debugw("GetLegacyGas", "l2GasLimit", l2GasLimit, "calldataLen", len(calldata), "perL2Tx", perL2Tx, "perL1CalldataUnit", perL1CalldataUnit, "chainSpecificGasLimit", chainSpecificGasLimit) }) diff --git a/core/chains/evm/gas/arbitrum_estimator_test.go b/core/chains/evm/gas/arbitrum_estimator_test.go index e5a5af8d4f8..afac9e03276 100644 --- a/core/chains/evm/gas/arbitrum_estimator_test.go +++ b/core/chains/evm/gas/arbitrum_estimator_test.go @@ -23,12 +23,12 @@ import ( ) type arbConfig struct { - v uint32 + v uint64 bumpPercent uint16 bumpMin *assets.Wei } -func (a *arbConfig) LimitMax() uint32 { +func (a *arbConfig) LimitMax() uint64 { return a.v } @@ -44,9 +44,9 @@ func TestArbitrumEstimator(t *testing.T) { t.Parallel() maxGasPrice := assets.NewWeiI(100) - const maxGasLimit uint32 = 500_000 + const maxGasLimit uint64 = 500_000 calldata := []byte{0x00, 0x00, 0x01, 0x02, 0x03} - const gasLimit uint32 = 80000 + const gasLimit uint64 = 80000 const gasPriceBufferPercentage = 50 const bumpPercent = 10 var bumpMin = assets.NewWei(big.NewInt(1)) @@ -109,7 +109,7 @@ func TestArbitrumEstimator(t *testing.T) { require.Error(t, err) assert.EqualError(t, err, "estimated gas price: 42 wei is greater than the maximum gas price configured: 40 wei") assert.Nil(t, gasPrice) - assert.Equal(t, uint32(0), chainSpecificGasLimit) + assert.Equal(t, uint64(0), chainSpecificGasLimit) }) t.Run("gas price is lower than global max gas price", func(t *testing.T) { @@ -133,7 +133,7 @@ func TestArbitrumEstimator(t *testing.T) { gasPrice, chainSpecificGasLimit, err := o.GetLegacyGas(testutils.Context(t), calldata, gasLimit, assets.NewWeiI(110)) assert.EqualError(t, err, "estimated gas price: 120 wei is greater than the maximum gas price configured: 110 wei") assert.Nil(t, gasPrice) - assert.Equal(t, uint32(0), chainSpecificGasLimit) + assert.Equal(t, uint64(0), chainSpecificGasLimit) }) t.Run("calling BumpLegacyGas on unstarted arbitrum estimator returns error", func(t *testing.T) { @@ -195,7 +195,7 @@ func TestArbitrumEstimator(t *testing.T) { perL2Tx = 50_000 perL1Calldata = 10_000 ) - var expLimit = gasLimit + perL2Tx + perL1Calldata*uint32(len(calldata)) + var expLimit = gasLimit + perL2Tx + perL1Calldata*uint64(len(calldata)) var b bytes.Buffer b.Write(common.BigToHash(big.NewInt(perL2Tx)).Bytes()) diff --git a/core/chains/evm/gas/block_history_estimator.go b/core/chains/evm/gas/block_history_estimator.go index 27e20931af8..fcd0d627063 100644 --- a/core/chains/evm/gas/block_history_estimator.go +++ b/core/chains/evm/gas/block_history_estimator.go @@ -248,7 +248,7 @@ func (b *BlockHistoryEstimator) HealthReport() map[string]error { return map[string]error{b.Name(): b.Healthy()} } -func (b *BlockHistoryEstimator) GetLegacyGas(_ context.Context, _ []byte, gasLimit uint32, maxGasPriceWei *assets.Wei, _ ...feetypes.Opt) (gasPrice *assets.Wei, chainSpecificGasLimit uint32, err error) { +func (b *BlockHistoryEstimator) GetLegacyGas(_ context.Context, _ []byte, gasLimit uint64, maxGasPriceWei *assets.Wei, _ ...feetypes.Opt) (gasPrice *assets.Wei, chainSpecificGasLimit uint64, err error) { ok := b.IfStarted(func() { gasPrice = b.getGasPrice() }) @@ -287,7 +287,7 @@ func (b *BlockHistoryEstimator) getTipCap() *assets.Wei { return b.tipCap } -func (b *BlockHistoryEstimator) BumpLegacyGas(_ context.Context, originalGasPrice *assets.Wei, gasLimit uint32, maxGasPriceWei *assets.Wei, attempts []EvmPriorAttempt) (bumpedGasPrice *assets.Wei, chainSpecificGasLimit uint32, err error) { +func (b *BlockHistoryEstimator) BumpLegacyGas(_ context.Context, originalGasPrice *assets.Wei, gasLimit uint64, maxGasPriceWei *assets.Wei, attempts []EvmPriorAttempt) (bumpedGasPrice *assets.Wei, chainSpecificGasLimit uint64, err error) { if b.bhConfig.CheckInclusionBlocks() > 0 { if err = b.checkConnectivity(attempts); err != nil { if pkgerrors.Is(err, commonfee.ErrConnectivity) { @@ -388,7 +388,7 @@ func (b *BlockHistoryEstimator) checkConnectivity(attempts []EvmPriorAttempt) er return nil } -func (b *BlockHistoryEstimator) GetDynamicFee(_ context.Context, gasLimit uint32, maxGasPriceWei *assets.Wei) (fee DynamicFee, chainSpecificGasLimit uint32, err error) { +func (b *BlockHistoryEstimator) GetDynamicFee(_ context.Context, gasLimit uint64, maxGasPriceWei *assets.Wei) (fee DynamicFee, chainSpecificGasLimit uint64, err error) { if !b.eConfig.EIP1559DynamicFees() { return fee, 0, pkgerrors.New("Can't get dynamic fee, EIP1559 is disabled") } @@ -461,7 +461,7 @@ func calcFeeCap(latestAvailableBaseFeePerGas *assets.Wei, bufferBlocks int, tipC return feeCap } -func (b *BlockHistoryEstimator) BumpDynamicFee(_ context.Context, originalFee DynamicFee, originalGasLimit uint32, maxGasPriceWei *assets.Wei, attempts []EvmPriorAttempt) (bumped DynamicFee, chainSpecificGasLimit uint32, err error) { +func (b *BlockHistoryEstimator) BumpDynamicFee(_ context.Context, originalFee DynamicFee, originalGasLimit uint64, maxGasPriceWei *assets.Wei, attempts []EvmPriorAttempt) (bumped DynamicFee, chainSpecificGasLimit uint64, err error) { if b.bhConfig.CheckInclusionBlocks() > 0 { if err = b.checkConnectivity(attempts); err != nil { if pkgerrors.Is(err, commonfee.ErrConnectivity) { @@ -864,7 +864,7 @@ func (b *BlockHistoryEstimator) EffectiveGasPrice(block evmtypes.Block, tx evmty case 0x2, 0x3: return b.getEffectiveGasPrice(block, tx) default: - b.logger.Warnw(fmt.Sprintf("Ignoring unknown transaction type %v", tx.Type), "block", block, "tx", tx) + b.logger.Debugw(fmt.Sprintf("Ignoring unknown transaction type %v", tx.Type), "block", block, "tx", tx) return nil } } @@ -916,7 +916,7 @@ func (b *BlockHistoryEstimator) EffectiveTipCap(block evmtypes.Block, tx evmtype } return effectiveTipCap default: - b.logger.Warnw(fmt.Sprintf("Ignoring unknown transaction type %v", tx.Type), "block", block, "tx", tx) + b.logger.Debugw(fmt.Sprintf("Ignoring unknown transaction type %v", tx.Type), "block", block, "tx", tx) return nil } } diff --git a/core/chains/evm/gas/cmd/arbgas/main.go b/core/chains/evm/gas/cmd/arbgas/main.go index c457b091c96..dc107a50b52 100644 --- a/core/chains/evm/gas/cmd/arbgas/main.go +++ b/core/chains/evm/gas/cmd/arbgas/main.go @@ -34,7 +34,7 @@ func main() { }) } -func printGetLegacyGas(ctx context.Context, e gas.EvmEstimator, calldata []byte, l2GasLimit uint32, maxGasPrice *assets.Wei, opts ...feetypes.Opt) { +func printGetLegacyGas(ctx context.Context, e gas.EvmEstimator, calldata []byte, l2GasLimit uint64, maxGasPrice *assets.Wei, opts ...feetypes.Opt) { price, limit, err := e.GetLegacyGas(ctx, calldata, l2GasLimit, maxGasPrice, opts...) if err != nil { log.Println("failed to get legacy gas:", err) @@ -67,12 +67,12 @@ func withEstimator(ctx context.Context, lggr logger.SugaredLogger, url string, f var _ gas.ArbConfig = &config{} type config struct { - max uint32 + max uint64 bumpPercent uint16 bumpMin *assets.Wei } -func (c *config) LimitMax() uint32 { +func (c *config) LimitMax() uint64 { return c.max } diff --git a/core/chains/evm/gas/fixed_price_estimator.go b/core/chains/evm/gas/fixed_price_estimator.go index a69be3b0d05..53b7e93a871 100644 --- a/core/chains/evm/gas/fixed_price_estimator.go +++ b/core/chains/evm/gas/fixed_price_estimator.go @@ -58,7 +58,7 @@ func (f *fixedPriceEstimator) Start(context.Context) error { return nil } -func (f *fixedPriceEstimator) GetLegacyGas(_ context.Context, _ []byte, gasLimit uint32, maxGasPriceWei *assets.Wei, _ ...feetypes.Opt) (*assets.Wei, uint32, error) { +func (f *fixedPriceEstimator) GetLegacyGas(_ context.Context, _ []byte, gasLimit uint64, maxGasPriceWei *assets.Wei, _ ...feetypes.Opt) (*assets.Wei, uint64, error) { gasPrice := commonfee.CalculateFee(f.config.PriceDefault().ToInt(), maxGasPriceWei.ToInt(), f.config.PriceMax().ToInt()) chainSpecificGasLimit, err := commonfee.ApplyMultiplier(gasLimit, f.config.LimitMultiplier()) if err != nil { @@ -70,10 +70,10 @@ func (f *fixedPriceEstimator) GetLegacyGas(_ context.Context, _ []byte, gasLimit func (f *fixedPriceEstimator) BumpLegacyGas( _ context.Context, originalGasPrice *assets.Wei, - originalGasLimit uint32, + originalGasLimit uint64, maxGasPriceWei *assets.Wei, _ []EvmPriorAttempt, -) (*assets.Wei, uint32, error) { +) (*assets.Wei, uint64, error) { gasPrice, err := commonfee.CalculateBumpedFee( f.lggr, f.config.PriceDefault().ToInt(), @@ -95,7 +95,7 @@ func (f *fixedPriceEstimator) BumpLegacyGas( return assets.NewWei(gasPrice), chainSpecificGasLimit, err } -func (f *fixedPriceEstimator) GetDynamicFee(_ context.Context, originalGasLimit uint32, maxGasPriceWei *assets.Wei) (d DynamicFee, chainSpecificGasLimit uint32, err error) { +func (f *fixedPriceEstimator) GetDynamicFee(_ context.Context, originalGasLimit uint64, maxGasPriceWei *assets.Wei) (d DynamicFee, chainSpecificGasLimit uint64, err error) { gasTipCap := f.config.TipCapDefault() if gasTipCap == nil { @@ -124,10 +124,10 @@ func (f *fixedPriceEstimator) GetDynamicFee(_ context.Context, originalGasLimit func (f *fixedPriceEstimator) BumpDynamicFee( _ context.Context, originalFee DynamicFee, - originalGasLimit uint32, + originalGasLimit uint64, maxGasPriceWei *assets.Wei, _ []EvmPriorAttempt, -) (bumped DynamicFee, chainSpecificGasLimit uint32, err error) { +) (bumped DynamicFee, chainSpecificGasLimit uint64, err error) { return BumpDynamicFeeOnly( f.config, diff --git a/core/chains/evm/gas/gas_test.go b/core/chains/evm/gas/gas_test.go index 355d39b6ce8..43a1506bc24 100644 --- a/core/chains/evm/gas/gas_test.go +++ b/core/chains/evm/gas/gas_test.go @@ -24,7 +24,7 @@ func Test_BumpLegacyGasPriceOnly(t *testing.T) { bumpMin *assets.Wei priceMax *assets.Wei expectedGasPrice *assets.Wei - originalLimit uint32 + originalLimit uint64 limitMultiplierPercent float32 expectedLimit uint64 }{ @@ -156,7 +156,7 @@ func Test_BumpDynamicFeeOnly(t *testing.T) { bumpMin *assets.Wei priceMax *assets.Wei expectedFee gas.DynamicFee - originalLimit uint32 + originalLimit uint64 limitMultiplierPercent float32 expectedLimit uint64 }{ diff --git a/core/chains/evm/gas/helpers_test.go b/core/chains/evm/gas/helpers_test.go index 9a5076be6d6..908674bbeeb 100644 --- a/core/chains/evm/gas/helpers_test.go +++ b/core/chains/evm/gas/helpers_test.go @@ -143,7 +143,7 @@ type MockGasEstimatorConfig struct { PriceMinF *assets.Wei PriceDefaultF *assets.Wei FeeCapDefaultF *assets.Wei - LimitMaxF uint32 + LimitMaxF uint64 ModeF string } @@ -191,7 +191,7 @@ func (m *MockGasEstimatorConfig) FeeCapDefault() *assets.Wei { return m.FeeCapDefaultF } -func (m *MockGasEstimatorConfig) LimitMax() uint32 { +func (m *MockGasEstimatorConfig) LimitMax() uint64 { return m.LimitMaxF } diff --git a/core/chains/evm/gas/mocks/evm_estimator.go b/core/chains/evm/gas/mocks/evm_estimator.go index 29705b2a5d9..f9ea34b830d 100644 --- a/core/chains/evm/gas/mocks/evm_estimator.go +++ b/core/chains/evm/gas/mocks/evm_estimator.go @@ -22,7 +22,7 @@ type EvmEstimator struct { } // BumpDynamicFee provides a mock function with given fields: ctx, original, gasLimit, maxGasPriceWei, attempts -func (_m *EvmEstimator) BumpDynamicFee(ctx context.Context, original gas.DynamicFee, gasLimit uint32, maxGasPriceWei *assets.Wei, attempts []gas.EvmPriorAttempt) (gas.DynamicFee, uint32, error) { +func (_m *EvmEstimator) BumpDynamicFee(ctx context.Context, original gas.DynamicFee, gasLimit uint64, maxGasPriceWei *assets.Wei, attempts []gas.EvmPriorAttempt) (gas.DynamicFee, uint64, error) { ret := _m.Called(ctx, original, gasLimit, maxGasPriceWei, attempts) if len(ret) == 0 { @@ -30,24 +30,24 @@ func (_m *EvmEstimator) BumpDynamicFee(ctx context.Context, original gas.Dynamic } var r0 gas.DynamicFee - var r1 uint32 + var r1 uint64 var r2 error - if rf, ok := ret.Get(0).(func(context.Context, gas.DynamicFee, uint32, *assets.Wei, []gas.EvmPriorAttempt) (gas.DynamicFee, uint32, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, gas.DynamicFee, uint64, *assets.Wei, []gas.EvmPriorAttempt) (gas.DynamicFee, uint64, error)); ok { return rf(ctx, original, gasLimit, maxGasPriceWei, attempts) } - if rf, ok := ret.Get(0).(func(context.Context, gas.DynamicFee, uint32, *assets.Wei, []gas.EvmPriorAttempt) gas.DynamicFee); ok { + if rf, ok := ret.Get(0).(func(context.Context, gas.DynamicFee, uint64, *assets.Wei, []gas.EvmPriorAttempt) gas.DynamicFee); ok { r0 = rf(ctx, original, gasLimit, maxGasPriceWei, attempts) } else { r0 = ret.Get(0).(gas.DynamicFee) } - if rf, ok := ret.Get(1).(func(context.Context, gas.DynamicFee, uint32, *assets.Wei, []gas.EvmPriorAttempt) uint32); ok { + if rf, ok := ret.Get(1).(func(context.Context, gas.DynamicFee, uint64, *assets.Wei, []gas.EvmPriorAttempt) uint64); ok { r1 = rf(ctx, original, gasLimit, maxGasPriceWei, attempts) } else { - r1 = ret.Get(1).(uint32) + r1 = ret.Get(1).(uint64) } - if rf, ok := ret.Get(2).(func(context.Context, gas.DynamicFee, uint32, *assets.Wei, []gas.EvmPriorAttempt) error); ok { + if rf, ok := ret.Get(2).(func(context.Context, gas.DynamicFee, uint64, *assets.Wei, []gas.EvmPriorAttempt) error); ok { r2 = rf(ctx, original, gasLimit, maxGasPriceWei, attempts) } else { r2 = ret.Error(2) @@ -57,7 +57,7 @@ func (_m *EvmEstimator) BumpDynamicFee(ctx context.Context, original gas.Dynamic } // BumpLegacyGas provides a mock function with given fields: ctx, originalGasPrice, gasLimit, maxGasPriceWei, attempts -func (_m *EvmEstimator) BumpLegacyGas(ctx context.Context, originalGasPrice *assets.Wei, gasLimit uint32, maxGasPriceWei *assets.Wei, attempts []gas.EvmPriorAttempt) (*assets.Wei, uint32, error) { +func (_m *EvmEstimator) BumpLegacyGas(ctx context.Context, originalGasPrice *assets.Wei, gasLimit uint64, maxGasPriceWei *assets.Wei, attempts []gas.EvmPriorAttempt) (*assets.Wei, uint64, error) { ret := _m.Called(ctx, originalGasPrice, gasLimit, maxGasPriceWei, attempts) if len(ret) == 0 { @@ -65,12 +65,12 @@ func (_m *EvmEstimator) BumpLegacyGas(ctx context.Context, originalGasPrice *ass } var r0 *assets.Wei - var r1 uint32 + var r1 uint64 var r2 error - if rf, ok := ret.Get(0).(func(context.Context, *assets.Wei, uint32, *assets.Wei, []gas.EvmPriorAttempt) (*assets.Wei, uint32, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, *assets.Wei, uint64, *assets.Wei, []gas.EvmPriorAttempt) (*assets.Wei, uint64, error)); ok { return rf(ctx, originalGasPrice, gasLimit, maxGasPriceWei, attempts) } - if rf, ok := ret.Get(0).(func(context.Context, *assets.Wei, uint32, *assets.Wei, []gas.EvmPriorAttempt) *assets.Wei); ok { + if rf, ok := ret.Get(0).(func(context.Context, *assets.Wei, uint64, *assets.Wei, []gas.EvmPriorAttempt) *assets.Wei); ok { r0 = rf(ctx, originalGasPrice, gasLimit, maxGasPriceWei, attempts) } else { if ret.Get(0) != nil { @@ -78,13 +78,13 @@ func (_m *EvmEstimator) BumpLegacyGas(ctx context.Context, originalGasPrice *ass } } - if rf, ok := ret.Get(1).(func(context.Context, *assets.Wei, uint32, *assets.Wei, []gas.EvmPriorAttempt) uint32); ok { + if rf, ok := ret.Get(1).(func(context.Context, *assets.Wei, uint64, *assets.Wei, []gas.EvmPriorAttempt) uint64); ok { r1 = rf(ctx, originalGasPrice, gasLimit, maxGasPriceWei, attempts) } else { - r1 = ret.Get(1).(uint32) + r1 = ret.Get(1).(uint64) } - if rf, ok := ret.Get(2).(func(context.Context, *assets.Wei, uint32, *assets.Wei, []gas.EvmPriorAttempt) error); ok { + if rf, ok := ret.Get(2).(func(context.Context, *assets.Wei, uint64, *assets.Wei, []gas.EvmPriorAttempt) error); ok { r2 = rf(ctx, originalGasPrice, gasLimit, maxGasPriceWei, attempts) } else { r2 = ret.Error(2) @@ -112,7 +112,7 @@ func (_m *EvmEstimator) Close() error { } // GetDynamicFee provides a mock function with given fields: ctx, gasLimit, maxGasPriceWei -func (_m *EvmEstimator) GetDynamicFee(ctx context.Context, gasLimit uint32, maxGasPriceWei *assets.Wei) (gas.DynamicFee, uint32, error) { +func (_m *EvmEstimator) GetDynamicFee(ctx context.Context, gasLimit uint64, maxGasPriceWei *assets.Wei) (gas.DynamicFee, uint64, error) { ret := _m.Called(ctx, gasLimit, maxGasPriceWei) if len(ret) == 0 { @@ -120,24 +120,24 @@ func (_m *EvmEstimator) GetDynamicFee(ctx context.Context, gasLimit uint32, maxG } var r0 gas.DynamicFee - var r1 uint32 + var r1 uint64 var r2 error - if rf, ok := ret.Get(0).(func(context.Context, uint32, *assets.Wei) (gas.DynamicFee, uint32, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, uint64, *assets.Wei) (gas.DynamicFee, uint64, error)); ok { return rf(ctx, gasLimit, maxGasPriceWei) } - if rf, ok := ret.Get(0).(func(context.Context, uint32, *assets.Wei) gas.DynamicFee); ok { + if rf, ok := ret.Get(0).(func(context.Context, uint64, *assets.Wei) gas.DynamicFee); ok { r0 = rf(ctx, gasLimit, maxGasPriceWei) } else { r0 = ret.Get(0).(gas.DynamicFee) } - if rf, ok := ret.Get(1).(func(context.Context, uint32, *assets.Wei) uint32); ok { + if rf, ok := ret.Get(1).(func(context.Context, uint64, *assets.Wei) uint64); ok { r1 = rf(ctx, gasLimit, maxGasPriceWei) } else { - r1 = ret.Get(1).(uint32) + r1 = ret.Get(1).(uint64) } - if rf, ok := ret.Get(2).(func(context.Context, uint32, *assets.Wei) error); ok { + if rf, ok := ret.Get(2).(func(context.Context, uint64, *assets.Wei) error); ok { r2 = rf(ctx, gasLimit, maxGasPriceWei) } else { r2 = ret.Error(2) @@ -147,7 +147,7 @@ func (_m *EvmEstimator) GetDynamicFee(ctx context.Context, gasLimit uint32, maxG } // GetLegacyGas provides a mock function with given fields: ctx, calldata, gasLimit, maxGasPriceWei, opts -func (_m *EvmEstimator) GetLegacyGas(ctx context.Context, calldata []byte, gasLimit uint32, maxGasPriceWei *assets.Wei, opts ...types.Opt) (*assets.Wei, uint32, error) { +func (_m *EvmEstimator) GetLegacyGas(ctx context.Context, calldata []byte, gasLimit uint64, maxGasPriceWei *assets.Wei, opts ...types.Opt) (*assets.Wei, uint64, error) { _va := make([]interface{}, len(opts)) for _i := range opts { _va[_i] = opts[_i] @@ -162,12 +162,12 @@ func (_m *EvmEstimator) GetLegacyGas(ctx context.Context, calldata []byte, gasLi } var r0 *assets.Wei - var r1 uint32 + var r1 uint64 var r2 error - if rf, ok := ret.Get(0).(func(context.Context, []byte, uint32, *assets.Wei, ...types.Opt) (*assets.Wei, uint32, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, []byte, uint64, *assets.Wei, ...types.Opt) (*assets.Wei, uint64, error)); ok { return rf(ctx, calldata, gasLimit, maxGasPriceWei, opts...) } - if rf, ok := ret.Get(0).(func(context.Context, []byte, uint32, *assets.Wei, ...types.Opt) *assets.Wei); ok { + if rf, ok := ret.Get(0).(func(context.Context, []byte, uint64, *assets.Wei, ...types.Opt) *assets.Wei); ok { r0 = rf(ctx, calldata, gasLimit, maxGasPriceWei, opts...) } else { if ret.Get(0) != nil { @@ -175,13 +175,13 @@ func (_m *EvmEstimator) GetLegacyGas(ctx context.Context, calldata []byte, gasLi } } - if rf, ok := ret.Get(1).(func(context.Context, []byte, uint32, *assets.Wei, ...types.Opt) uint32); ok { + if rf, ok := ret.Get(1).(func(context.Context, []byte, uint64, *assets.Wei, ...types.Opt) uint64); ok { r1 = rf(ctx, calldata, gasLimit, maxGasPriceWei, opts...) } else { - r1 = ret.Get(1).(uint32) + r1 = ret.Get(1).(uint64) } - if rf, ok := ret.Get(2).(func(context.Context, []byte, uint32, *assets.Wei, ...types.Opt) error); ok { + if rf, ok := ret.Get(2).(func(context.Context, []byte, uint64, *assets.Wei, ...types.Opt) error); ok { r2 = rf(ctx, calldata, gasLimit, maxGasPriceWei, opts...) } else { r2 = ret.Error(2) diff --git a/core/chains/evm/gas/mocks/evm_fee_estimator.go b/core/chains/evm/gas/mocks/evm_fee_estimator.go index 66acbdbf7ff..7ebde8bc0fd 100644 --- a/core/chains/evm/gas/mocks/evm_fee_estimator.go +++ b/core/chains/evm/gas/mocks/evm_fee_estimator.go @@ -26,7 +26,7 @@ type EvmFeeEstimator struct { } // BumpFee provides a mock function with given fields: ctx, originalFee, feeLimit, maxFeePrice, attempts -func (_m *EvmFeeEstimator) BumpFee(ctx context.Context, originalFee gas.EvmFee, feeLimit uint32, maxFeePrice *assets.Wei, attempts []gas.EvmPriorAttempt) (gas.EvmFee, uint32, error) { +func (_m *EvmFeeEstimator) BumpFee(ctx context.Context, originalFee gas.EvmFee, feeLimit uint64, maxFeePrice *assets.Wei, attempts []gas.EvmPriorAttempt) (gas.EvmFee, uint64, error) { ret := _m.Called(ctx, originalFee, feeLimit, maxFeePrice, attempts) if len(ret) == 0 { @@ -34,24 +34,24 @@ func (_m *EvmFeeEstimator) BumpFee(ctx context.Context, originalFee gas.EvmFee, } var r0 gas.EvmFee - var r1 uint32 + var r1 uint64 var r2 error - if rf, ok := ret.Get(0).(func(context.Context, gas.EvmFee, uint32, *assets.Wei, []gas.EvmPriorAttempt) (gas.EvmFee, uint32, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, gas.EvmFee, uint64, *assets.Wei, []gas.EvmPriorAttempt) (gas.EvmFee, uint64, error)); ok { return rf(ctx, originalFee, feeLimit, maxFeePrice, attempts) } - if rf, ok := ret.Get(0).(func(context.Context, gas.EvmFee, uint32, *assets.Wei, []gas.EvmPriorAttempt) gas.EvmFee); ok { + if rf, ok := ret.Get(0).(func(context.Context, gas.EvmFee, uint64, *assets.Wei, []gas.EvmPriorAttempt) gas.EvmFee); ok { r0 = rf(ctx, originalFee, feeLimit, maxFeePrice, attempts) } else { r0 = ret.Get(0).(gas.EvmFee) } - if rf, ok := ret.Get(1).(func(context.Context, gas.EvmFee, uint32, *assets.Wei, []gas.EvmPriorAttempt) uint32); ok { + if rf, ok := ret.Get(1).(func(context.Context, gas.EvmFee, uint64, *assets.Wei, []gas.EvmPriorAttempt) uint64); ok { r1 = rf(ctx, originalFee, feeLimit, maxFeePrice, attempts) } else { - r1 = ret.Get(1).(uint32) + r1 = ret.Get(1).(uint64) } - if rf, ok := ret.Get(2).(func(context.Context, gas.EvmFee, uint32, *assets.Wei, []gas.EvmPriorAttempt) error); ok { + if rf, ok := ret.Get(2).(func(context.Context, gas.EvmFee, uint64, *assets.Wei, []gas.EvmPriorAttempt) error); ok { r2 = rf(ctx, originalFee, feeLimit, maxFeePrice, attempts) } else { r2 = ret.Error(2) @@ -79,7 +79,7 @@ func (_m *EvmFeeEstimator) Close() error { } // GetFee provides a mock function with given fields: ctx, calldata, feeLimit, maxFeePrice, opts -func (_m *EvmFeeEstimator) GetFee(ctx context.Context, calldata []byte, feeLimit uint32, maxFeePrice *assets.Wei, opts ...types.Opt) (gas.EvmFee, uint32, error) { +func (_m *EvmFeeEstimator) GetFee(ctx context.Context, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, opts ...types.Opt) (gas.EvmFee, uint64, error) { _va := make([]interface{}, len(opts)) for _i := range opts { _va[_i] = opts[_i] @@ -94,24 +94,24 @@ func (_m *EvmFeeEstimator) GetFee(ctx context.Context, calldata []byte, feeLimit } var r0 gas.EvmFee - var r1 uint32 + var r1 uint64 var r2 error - if rf, ok := ret.Get(0).(func(context.Context, []byte, uint32, *assets.Wei, ...types.Opt) (gas.EvmFee, uint32, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, []byte, uint64, *assets.Wei, ...types.Opt) (gas.EvmFee, uint64, error)); ok { return rf(ctx, calldata, feeLimit, maxFeePrice, opts...) } - if rf, ok := ret.Get(0).(func(context.Context, []byte, uint32, *assets.Wei, ...types.Opt) gas.EvmFee); ok { + if rf, ok := ret.Get(0).(func(context.Context, []byte, uint64, *assets.Wei, ...types.Opt) gas.EvmFee); ok { r0 = rf(ctx, calldata, feeLimit, maxFeePrice, opts...) } else { r0 = ret.Get(0).(gas.EvmFee) } - if rf, ok := ret.Get(1).(func(context.Context, []byte, uint32, *assets.Wei, ...types.Opt) uint32); ok { + if rf, ok := ret.Get(1).(func(context.Context, []byte, uint64, *assets.Wei, ...types.Opt) uint64); ok { r1 = rf(ctx, calldata, feeLimit, maxFeePrice, opts...) } else { - r1 = ret.Get(1).(uint32) + r1 = ret.Get(1).(uint64) } - if rf, ok := ret.Get(2).(func(context.Context, []byte, uint32, *assets.Wei, ...types.Opt) error); ok { + if rf, ok := ret.Get(2).(func(context.Context, []byte, uint64, *assets.Wei, ...types.Opt) error); ok { r2 = rf(ctx, calldata, feeLimit, maxFeePrice, opts...) } else { r2 = ret.Error(2) @@ -121,7 +121,7 @@ func (_m *EvmFeeEstimator) GetFee(ctx context.Context, calldata []byte, feeLimit } // GetMaxCost provides a mock function with given fields: ctx, amount, calldata, feeLimit, maxFeePrice, opts -func (_m *EvmFeeEstimator) GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint32, maxFeePrice *assets.Wei, opts ...types.Opt) (*big.Int, error) { +func (_m *EvmFeeEstimator) GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, opts ...types.Opt) (*big.Int, error) { _va := make([]interface{}, len(opts)) for _i := range opts { _va[_i] = opts[_i] @@ -137,10 +137,10 @@ func (_m *EvmFeeEstimator) GetMaxCost(ctx context.Context, amount assets.Eth, ca var r0 *big.Int var r1 error - if rf, ok := ret.Get(0).(func(context.Context, assets.Eth, []byte, uint32, *assets.Wei, ...types.Opt) (*big.Int, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, assets.Eth, []byte, uint64, *assets.Wei, ...types.Opt) (*big.Int, error)); ok { return rf(ctx, amount, calldata, feeLimit, maxFeePrice, opts...) } - if rf, ok := ret.Get(0).(func(context.Context, assets.Eth, []byte, uint32, *assets.Wei, ...types.Opt) *big.Int); ok { + if rf, ok := ret.Get(0).(func(context.Context, assets.Eth, []byte, uint64, *assets.Wei, ...types.Opt) *big.Int); ok { r0 = rf(ctx, amount, calldata, feeLimit, maxFeePrice, opts...) } else { if ret.Get(0) != nil { @@ -148,7 +148,7 @@ func (_m *EvmFeeEstimator) GetMaxCost(ctx context.Context, amount assets.Eth, ca } } - if rf, ok := ret.Get(1).(func(context.Context, assets.Eth, []byte, uint32, *assets.Wei, ...types.Opt) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, assets.Eth, []byte, uint64, *assets.Wei, ...types.Opt) error); ok { r1 = rf(ctx, amount, calldata, feeLimit, maxFeePrice, opts...) } else { r1 = ret.Error(1) diff --git a/core/chains/evm/gas/models.go b/core/chains/evm/gas/models.go index 44e85af37ff..ae041615f53 100644 --- a/core/chains/evm/gas/models.go +++ b/core/chains/evm/gas/models.go @@ -34,11 +34,11 @@ type EvmFeeEstimator interface { // L1Oracle returns the L1 gas price oracle only if the chain has one, e.g. OP stack L2s and Arbitrum. L1Oracle() rollups.L1Oracle - GetFee(ctx context.Context, calldata []byte, feeLimit uint32, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (fee EvmFee, chainSpecificFeeLimit uint32, err error) - BumpFee(ctx context.Context, originalFee EvmFee, feeLimit uint32, maxFeePrice *assets.Wei, attempts []EvmPriorAttempt) (bumpedFee EvmFee, chainSpecificFeeLimit uint32, err error) + GetFee(ctx context.Context, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (fee EvmFee, chainSpecificFeeLimit uint64, err error) + BumpFee(ctx context.Context, originalFee EvmFee, feeLimit uint64, maxFeePrice *assets.Wei, attempts []EvmPriorAttempt) (bumpedFee EvmFee, chainSpecificFeeLimit uint64, err error) // GetMaxCost returns the total value = max price x fee units + transferred value - GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint32, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (*big.Int, error) + GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (*big.Int, error) } // NewEstimator returns the estimator for a given config @@ -105,7 +105,7 @@ type DynamicFee struct { } type EvmPriorAttempt struct { - ChainSpecificFeeLimit uint32 + ChainSpecificFeeLimit uint64 BroadcastBeforeBlockNum *int64 TxHash common.Hash TxType int @@ -122,22 +122,22 @@ type EvmEstimator interface { // GetLegacyGas Calculates initial gas fee for non-EIP1559 transaction // maxGasPriceWei parameter is the highest possible gas fee cap that the function will return - GetLegacyGas(ctx context.Context, calldata []byte, gasLimit uint32, maxGasPriceWei *assets.Wei, opts ...feetypes.Opt) (gasPrice *assets.Wei, chainSpecificGasLimit uint32, err error) + GetLegacyGas(ctx context.Context, calldata []byte, gasLimit uint64, maxGasPriceWei *assets.Wei, opts ...feetypes.Opt) (gasPrice *assets.Wei, chainSpecificGasLimit uint64, err error) // BumpLegacyGas Increases gas price and/or limit for non-EIP1559 transactions // if the bumped gas fee is greater than maxGasPriceWei, the method returns an error // attempts must: // - be sorted in order from highest price to lowest price // - all be of transaction type 0x0 or 0x1 - BumpLegacyGas(ctx context.Context, originalGasPrice *assets.Wei, gasLimit uint32, maxGasPriceWei *assets.Wei, attempts []EvmPriorAttempt) (bumpedGasPrice *assets.Wei, chainSpecificGasLimit uint32, err error) + BumpLegacyGas(ctx context.Context, originalGasPrice *assets.Wei, gasLimit uint64, maxGasPriceWei *assets.Wei, attempts []EvmPriorAttempt) (bumpedGasPrice *assets.Wei, chainSpecificGasLimit uint64, err error) // GetDynamicFee Calculates initial gas fee for gas for EIP1559 transactions // maxGasPriceWei parameter is the highest possible gas fee cap that the function will return - GetDynamicFee(ctx context.Context, gasLimit uint32, maxGasPriceWei *assets.Wei) (fee DynamicFee, chainSpecificGasLimit uint32, err error) + GetDynamicFee(ctx context.Context, gasLimit uint64, maxGasPriceWei *assets.Wei) (fee DynamicFee, chainSpecificGasLimit uint64, err error) // BumpDynamicFee Increases gas price and/or limit for non-EIP1559 transactions // if the bumped gas fee or tip caps are greater than maxGasPriceWei, the method returns an error // attempts must: // - be sorted in order from highest price to lowest price // - all be of transaction type 0x2 - BumpDynamicFee(ctx context.Context, original DynamicFee, gasLimit uint32, maxGasPriceWei *assets.Wei, attempts []EvmPriorAttempt) (bumped DynamicFee, chainSpecificGasLimit uint32, err error) + BumpDynamicFee(ctx context.Context, original DynamicFee, gasLimit uint64, maxGasPriceWei *assets.Wei, attempts []EvmPriorAttempt) (bumped DynamicFee, chainSpecificGasLimit uint64, err error) } var _ feetypes.Fee = (*EvmFee)(nil) @@ -241,7 +241,7 @@ func (e *WrappedEvmEstimator) L1Oracle() rollups.L1Oracle { return e.l1Oracle } -func (e *WrappedEvmEstimator) GetFee(ctx context.Context, calldata []byte, feeLimit uint32, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (fee EvmFee, chainSpecificFeeLimit uint32, err error) { +func (e *WrappedEvmEstimator) GetFee(ctx context.Context, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (fee EvmFee, chainSpecificFeeLimit uint64, err error) { // get dynamic fee if e.EIP1559Enabled { var dynamicFee DynamicFee @@ -256,7 +256,7 @@ func (e *WrappedEvmEstimator) GetFee(ctx context.Context, calldata []byte, feeLi return } -func (e *WrappedEvmEstimator) GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint32, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (*big.Int, error) { +func (e *WrappedEvmEstimator) GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (*big.Int, error) { fees, gasLimit, err := e.GetFee(ctx, calldata, feeLimit, maxFeePrice, opts...) if err != nil { return nil, err @@ -274,7 +274,7 @@ func (e *WrappedEvmEstimator) GetMaxCost(ctx context.Context, amount assets.Eth, return amountWithFees, nil } -func (e *WrappedEvmEstimator) BumpFee(ctx context.Context, originalFee EvmFee, feeLimit uint32, maxFeePrice *assets.Wei, attempts []EvmPriorAttempt) (bumpedFee EvmFee, chainSpecificFeeLimit uint32, err error) { +func (e *WrappedEvmEstimator) BumpFee(ctx context.Context, originalFee EvmFee, feeLimit uint64, maxFeePrice *assets.Wei, attempts []EvmPriorAttempt) (bumpedFee EvmFee, chainSpecificFeeLimit uint64, err error) { // validate only 1 fee type is present if (!originalFee.ValidDynamic() && originalFee.Legacy == nil) || (originalFee.ValidDynamic() && originalFee.Legacy != nil) { err = pkgerrors.New("only one dynamic or legacy fee can be defined") @@ -315,7 +315,7 @@ type GasEstimatorConfig interface { BumpThreshold() uint64 BumpMin() *assets.Wei FeeCapDefault() *assets.Wei - LimitMax() uint32 + LimitMax() uint64 LimitMultiplier() float32 PriceDefault() *assets.Wei TipCapDefault() *assets.Wei @@ -356,7 +356,7 @@ func HexToInt64(input interface{}) int64 { } // BumpLegacyGasPriceOnly will increase the price and apply multiplier to the gas limit -func BumpLegacyGasPriceOnly(cfg bumpConfig, lggr logger.SugaredLogger, currentGasPrice, originalGasPrice *assets.Wei, originalGasLimit uint32, maxGasPriceWei *assets.Wei) (gasPrice *assets.Wei, chainSpecificGasLimit uint32, err error) { +func BumpLegacyGasPriceOnly(cfg bumpConfig, lggr logger.SugaredLogger, currentGasPrice, originalGasPrice *assets.Wei, originalGasLimit uint64, maxGasPriceWei *assets.Wei) (gasPrice *assets.Wei, chainSpecificGasLimit uint64, err error) { gasPrice, err = bumpGasPrice(cfg, lggr, currentGasPrice, originalGasPrice, maxGasPriceWei) if err != nil { return nil, 0, err @@ -391,7 +391,7 @@ func bumpGasPrice(cfg bumpConfig, lggr logger.SugaredLogger, currentGasPrice, or } // BumpDynamicFeeOnly bumps the tip cap and max gas price if necessary -func BumpDynamicFeeOnly(config bumpConfig, feeCapBufferBlocks uint16, lggr logger.SugaredLogger, currentTipCap, currentBaseFee *assets.Wei, originalFee DynamicFee, originalGasLimit uint32, maxGasPriceWei *assets.Wei) (bumped DynamicFee, chainSpecificGasLimit uint32, err error) { +func BumpDynamicFeeOnly(config bumpConfig, feeCapBufferBlocks uint16, lggr logger.SugaredLogger, currentTipCap, currentBaseFee *assets.Wei, originalFee DynamicFee, originalGasLimit uint64, maxGasPriceWei *assets.Wei) (bumped DynamicFee, chainSpecificGasLimit uint64, err error) { bumped, err = bumpDynamicFee(config, feeCapBufferBlocks, lggr, currentTipCap, currentBaseFee, originalFee, maxGasPriceWei) if err != nil { return bumped, 0, err diff --git a/core/chains/evm/gas/models_test.go b/core/chains/evm/gas/models_test.go index 9c0e63a602b..76666143189 100644 --- a/core/chains/evm/gas/models_test.go +++ b/core/chains/evm/gas/models_test.go @@ -22,7 +22,7 @@ func TestWrappedEvmEstimator(t *testing.T) { ctx := testutils.Context(t) // fee values - gasLimit := uint32(10) + gasLimit := uint64(10) legacyFee := assets.NewWeiI(10) dynamicFee := gas.DynamicFee{ FeeCap: assets.NewWeiI(20), diff --git a/core/chains/evm/gas/suggested_price_estimator.go b/core/chains/evm/gas/suggested_price_estimator.go index d58a1155b91..89e497edbd3 100644 --- a/core/chains/evm/gas/suggested_price_estimator.go +++ b/core/chains/evm/gas/suggested_price_estimator.go @@ -154,17 +154,17 @@ func (o *SuggestedPriceEstimator) forceRefresh(ctx context.Context) (err error) func (o *SuggestedPriceEstimator) OnNewLongestChain(context.Context, *evmtypes.Head) {} -func (*SuggestedPriceEstimator) GetDynamicFee(_ context.Context, _ uint32, _ *assets.Wei) (fee DynamicFee, chainSpecificGasLimit uint32, err error) { +func (*SuggestedPriceEstimator) GetDynamicFee(_ context.Context, _ uint64, _ *assets.Wei) (fee DynamicFee, chainSpecificGasLimit uint64, err error) { err = pkgerrors.New("dynamic fees are not implemented for this estimator") return } -func (*SuggestedPriceEstimator) BumpDynamicFee(_ context.Context, _ DynamicFee, _ uint32, _ *assets.Wei, _ []EvmPriorAttempt) (bumped DynamicFee, chainSpecificGasLimit uint32, err error) { +func (*SuggestedPriceEstimator) BumpDynamicFee(_ context.Context, _ DynamicFee, _ uint64, _ *assets.Wei, _ []EvmPriorAttempt) (bumped DynamicFee, chainSpecificGasLimit uint64, err error) { err = pkgerrors.New("dynamic fees are not implemented for this estimator") return } -func (o *SuggestedPriceEstimator) GetLegacyGas(ctx context.Context, _ []byte, GasLimit uint32, maxGasPriceWei *assets.Wei, opts ...feetypes.Opt) (gasPrice *assets.Wei, chainSpecificGasLimit uint32, err error) { +func (o *SuggestedPriceEstimator) GetLegacyGas(ctx context.Context, _ []byte, GasLimit uint64, maxGasPriceWei *assets.Wei, opts ...feetypes.Opt) (gasPrice *assets.Wei, chainSpecificGasLimit uint64, err error) { chainSpecificGasLimit = GasLimit ok := o.IfStarted(func() { if slices.Contains(opts, feetypes.OptForceRefetch) { @@ -192,7 +192,7 @@ func (o *SuggestedPriceEstimator) GetLegacyGas(ctx context.Context, _ []byte, Ga // Adds the larger of BumpPercent and BumpMin configs as a buffer on top of the price returned from the RPC. // The only reason bumping logic would be called on the SuggestedPriceEstimator is if there was a significant price spike // between the last price update and when the tx was submitted. Refreshing the price helps ensure the latest market changes are accounted for. -func (o *SuggestedPriceEstimator) BumpLegacyGas(ctx context.Context, originalFee *assets.Wei, feeLimit uint32, maxGasPriceWei *assets.Wei, _ []EvmPriorAttempt) (newGasPrice *assets.Wei, chainSpecificGasLimit uint32, err error) { +func (o *SuggestedPriceEstimator) BumpLegacyGas(ctx context.Context, originalFee *assets.Wei, feeLimit uint64, maxGasPriceWei *assets.Wei, _ []EvmPriorAttempt) (newGasPrice *assets.Wei, chainSpecificGasLimit uint64, err error) { chainSpecificGasLimit = feeLimit ok := o.IfStarted(func() { // Immediately return error if original fee is greater than or equal to the max gas price diff --git a/core/chains/evm/gas/suggested_price_estimator_test.go b/core/chains/evm/gas/suggested_price_estimator_test.go index c09582774b8..ff5e004031b 100644 --- a/core/chains/evm/gas/suggested_price_estimator_test.go +++ b/core/chains/evm/gas/suggested_price_estimator_test.go @@ -24,7 +24,7 @@ func TestSuggestedPriceEstimator(t *testing.T) { maxGasPrice := assets.NewWeiI(100) calldata := []byte{0x00, 0x00, 0x01, 0x02, 0x03} - const gasLimit uint32 = 80000 + const gasLimit uint64 = 80000 cfg := &gas.MockGasEstimatorConfig{BumpPercentF: 10, BumpMinF: assets.NewWei(big.NewInt(1)), BumpThresholdF: 1} @@ -64,7 +64,7 @@ func TestSuggestedPriceEstimator(t *testing.T) { require.Error(t, err) assert.EqualError(t, err, "estimated gas price: 42 wei is greater than the maximum gas price configured: 40 wei") assert.Nil(t, gasPrice) - assert.Equal(t, uint32(0), chainSpecificGasLimit) + assert.Equal(t, uint64(0), chainSpecificGasLimit) }) t.Run("gas price is lower than global max gas price", func(t *testing.T) { @@ -80,7 +80,7 @@ func TestSuggestedPriceEstimator(t *testing.T) { gasPrice, chainSpecificGasLimit, err := o.GetLegacyGas(testutils.Context(t), calldata, gasLimit, assets.NewWeiI(110)) assert.EqualError(t, err, "estimated gas price: 120 wei is greater than the maximum gas price configured: 110 wei") assert.Nil(t, gasPrice) - assert.Equal(t, uint32(0), chainSpecificGasLimit) + assert.Equal(t, uint64(0), chainSpecificGasLimit) }) t.Run("calling GetLegacyGas on started estimator if initial call failed returns error", func(t *testing.T) { @@ -180,7 +180,7 @@ func TestSuggestedPriceEstimator(t *testing.T) { require.Error(t, err) assert.EqualError(t, err, "estimated gas price: 42 wei is greater than the maximum gas price configured: 40 wei") assert.Nil(t, gasPrice) - assert.Equal(t, uint32(0), chainSpecificGasLimit) + assert.Equal(t, uint64(0), chainSpecificGasLimit) }) t.Run("calling BumpLegacyGas on started estimator returns max gas price when suggested price under max but the buffer exceeds it", func(t *testing.T) { diff --git a/core/chains/evm/txmgr/attempts.go b/core/chains/evm/txmgr/attempts.go index 892920c0f67..aa1fa8cdeb2 100644 --- a/core/chains/evm/txmgr/attempts.go +++ b/core/chains/evm/txmgr/attempts.go @@ -45,7 +45,7 @@ func NewEvmTxAttemptBuilder(chainID big.Int, feeConfig evmTxAttemptBuilderFeeCon // NewTxAttempt builds an new attempt using the configured fee estimator + using the EIP1559 config to determine tx type // used for when a brand new transaction is being created in the txm -func (c *evmTxAttemptBuilder) NewTxAttempt(ctx context.Context, etx Tx, lggr logger.Logger, opts ...feetypes.Opt) (attempt TxAttempt, fee gas.EvmFee, feeLimit uint32, retryable bool, err error) { +func (c *evmTxAttemptBuilder) NewTxAttempt(ctx context.Context, etx Tx, lggr logger.Logger, opts ...feetypes.Opt) (attempt TxAttempt, fee gas.EvmFee, feeLimit uint64, retryable bool, err error) { txType := 0x0 if c.feeConfig.EIP1559DynamicFees() { txType = 0x2 @@ -55,7 +55,7 @@ func (c *evmTxAttemptBuilder) NewTxAttempt(ctx context.Context, etx Tx, lggr log // NewTxAttemptWithType builds a new attempt with a new fee estimation where the txType can be specified by the caller // used for L2 re-estimation on broadcasting (note EIP1559 must be disabled otherwise this will fail with mismatched fees + tx type) -func (c *evmTxAttemptBuilder) NewTxAttemptWithType(ctx context.Context, etx Tx, lggr logger.Logger, txType int, opts ...feetypes.Opt) (attempt TxAttempt, fee gas.EvmFee, feeLimit uint32, retryable bool, err error) { +func (c *evmTxAttemptBuilder) NewTxAttemptWithType(ctx context.Context, etx Tx, lggr logger.Logger, txType int, opts ...feetypes.Opt) (attempt TxAttempt, fee gas.EvmFee, feeLimit uint64, retryable bool, err error) { keySpecificMaxGasPriceWei := c.feeConfig.PriceMaxKey(etx.FromAddress) fee, feeLimit, err = c.EvmFeeEstimator.GetFee(ctx, etx.EncodedPayload, etx.FeeLimit, keySpecificMaxGasPriceWei, opts...) if err != nil { @@ -68,7 +68,7 @@ func (c *evmTxAttemptBuilder) NewTxAttemptWithType(ctx context.Context, etx Tx, // NewBumpTxAttempt builds a new attempt with a bumped fee - based on the previous attempt tx type // used in the txm broadcaster + confirmer when tx ix rejected for too low fee or is not included in a timely manner -func (c *evmTxAttemptBuilder) NewBumpTxAttempt(ctx context.Context, etx Tx, previousAttempt TxAttempt, priorAttempts []TxAttempt, lggr logger.Logger) (attempt TxAttempt, bumpedFee gas.EvmFee, bumpedFeeLimit uint32, retryable bool, err error) { +func (c *evmTxAttemptBuilder) NewBumpTxAttempt(ctx context.Context, etx Tx, previousAttempt TxAttempt, priorAttempts []TxAttempt, lggr logger.Logger) (attempt TxAttempt, bumpedFee gas.EvmFee, bumpedFeeLimit uint64, retryable bool, err error) { keySpecificMaxGasPriceWei := c.feeConfig.PriceMaxKey(etx.FromAddress) bumpedFee, bumpedFeeLimit, err = c.EvmFeeEstimator.BumpFee(ctx, previousAttempt.TxFee, etx.FeeLimit, keySpecificMaxGasPriceWei, newEvmPriorAttempts(priorAttempts)) @@ -82,7 +82,7 @@ func (c *evmTxAttemptBuilder) NewBumpTxAttempt(ctx context.Context, etx Tx, prev // NewCustomTxAttempt is the lowest level func where the fee parameters + tx type must be passed in // used in the txm for force rebroadcast where fees and tx type are pre-determined without an estimator -func (c *evmTxAttemptBuilder) NewCustomTxAttempt(ctx context.Context, etx Tx, fee gas.EvmFee, gasLimit uint32, txType int, lggr logger.Logger) (attempt TxAttempt, retryable bool, err error) { +func (c *evmTxAttemptBuilder) NewCustomTxAttempt(ctx context.Context, etx Tx, fee gas.EvmFee, gasLimit uint64, txType int, lggr logger.Logger) (attempt TxAttempt, retryable bool, err error) { switch txType { case 0x0: // legacy if fee.Legacy == nil { @@ -112,7 +112,7 @@ func (c *evmTxAttemptBuilder) NewCustomTxAttempt(ctx context.Context, etx Tx, fe } // NewEmptyTxAttempt is used in ForceRebroadcast to create a signed tx with zero value sent to the zero address -func (c *evmTxAttemptBuilder) NewEmptyTxAttempt(ctx context.Context, nonce evmtypes.Nonce, feeLimit uint32, fee gas.EvmFee, fromAddress common.Address) (attempt TxAttempt, err error) { +func (c *evmTxAttemptBuilder) NewEmptyTxAttempt(ctx context.Context, nonce evmtypes.Nonce, feeLimit uint64, fee gas.EvmFee, fromAddress common.Address) (attempt TxAttempt, err error) { value := big.NewInt(0) payload := []byte{} @@ -141,8 +141,8 @@ func (c *evmTxAttemptBuilder) NewEmptyTxAttempt(ctx context.Context, nonce evmty } -func (c *evmTxAttemptBuilder) newDynamicFeeAttempt(ctx context.Context, etx Tx, fee gas.DynamicFee, gasLimit uint32) (attempt TxAttempt, err error) { - if err = validateDynamicFeeGas(c.feeConfig, c.feeConfig.TipCapMin(), fee, gasLimit, etx); err != nil { +func (c *evmTxAttemptBuilder) newDynamicFeeAttempt(ctx context.Context, etx Tx, fee gas.DynamicFee, gasLimit uint64) (attempt TxAttempt, err error) { + if err = validateDynamicFeeGas(c.feeConfig, c.feeConfig.TipCapMin(), fee, etx); err != nil { return attempt, pkgerrors.Wrap(err, "error validating gas") } @@ -178,7 +178,7 @@ type keySpecificEstimator interface { // validateDynamicFeeGas is a sanity check - we have other checks elsewhere, but this // makes sure we _never_ create an invalid attempt -func validateDynamicFeeGas(kse keySpecificEstimator, tipCapMinimum *assets.Wei, fee gas.DynamicFee, gasLimit uint32, etx Tx) error { +func validateDynamicFeeGas(kse keySpecificEstimator, tipCapMinimum *assets.Wei, fee gas.DynamicFee, etx Tx) error { gasTipCap, gasFeeCap := fee.TipCap, fee.FeeCap if gasTipCap == nil { @@ -213,21 +213,21 @@ func validateDynamicFeeGas(kse keySpecificEstimator, tipCapMinimum *assets.Wei, return nil } -func newDynamicFeeTransaction(nonce uint64, to common.Address, value *big.Int, gasLimit uint32, chainID *big.Int, gasTipCap, gasFeeCap *assets.Wei, data []byte) types.DynamicFeeTx { +func newDynamicFeeTransaction(nonce uint64, to common.Address, value *big.Int, gasLimit uint64, chainID *big.Int, gasTipCap, gasFeeCap *assets.Wei, data []byte) types.DynamicFeeTx { return types.DynamicFeeTx{ ChainID: chainID, Nonce: nonce, GasTipCap: gasTipCap.ToInt(), GasFeeCap: gasFeeCap.ToInt(), - Gas: uint64(gasLimit), + Gas: gasLimit, To: &to, Value: value, Data: data, } } -func (c *evmTxAttemptBuilder) newLegacyAttempt(ctx context.Context, etx Tx, gasPrice *assets.Wei, gasLimit uint32) (attempt TxAttempt, err error) { - if err = validateLegacyGas(ctx, c.feeConfig, c.feeConfig.PriceMin(), gasPrice, gasLimit, etx); err != nil { +func (c *evmTxAttemptBuilder) newLegacyAttempt(ctx context.Context, etx Tx, gasPrice *assets.Wei, gasLimit uint64) (attempt TxAttempt, err error) { + if err = validateLegacyGas(c.feeConfig, c.feeConfig.PriceMin(), gasPrice, etx); err != nil { return attempt, pkgerrors.Wrap(err, "error validating gas") } @@ -260,7 +260,7 @@ func (c *evmTxAttemptBuilder) newLegacyAttempt(ctx context.Context, etx Tx, gasP // validateLegacyGas is a sanity check - we have other checks elsewhere, but this // makes sure we _never_ create an invalid attempt -func validateLegacyGas(ctx context.Context, kse keySpecificEstimator, minGasPriceWei, gasPrice *assets.Wei, gasLimit uint32, etx Tx) error { +func validateLegacyGas(kse keySpecificEstimator, minGasPriceWei, gasPrice *assets.Wei, etx Tx) error { if gasPrice == nil { panic("gas price missing") } @@ -290,12 +290,12 @@ func (c *evmTxAttemptBuilder) newSignedAttempt(ctx context.Context, etx Tx, tx * return attempt, nil } -func newLegacyTransaction(nonce uint64, to common.Address, value *big.Int, gasLimit uint32, gasPrice *assets.Wei, data []byte) types.LegacyTx { +func newLegacyTransaction(nonce uint64, to common.Address, value *big.Int, gasLimit uint64, gasPrice *assets.Wei, data []byte) types.LegacyTx { return types.LegacyTx{ Nonce: nonce, To: &to, Value: value, - Gas: uint64(gasLimit), + Gas: gasLimit, GasPrice: gasPrice.ToInt(), Data: data, } diff --git a/core/chains/evm/txmgr/attempts_test.go b/core/chains/evm/txmgr/attempts_test.go index b1e24984c37..ab8a5831b20 100644 --- a/core/chains/evm/txmgr/attempts_test.go +++ b/core/chains/evm/txmgr/attempts_test.go @@ -257,8 +257,8 @@ func TestTxm_NewCustomTxAttempt_NonRetryableErrors(t *testing.T) { func TestTxm_EvmTxAttemptBuilder_RetryableEstimatorError(t *testing.T) { est := gasmocks.NewEvmFeeEstimator(t) - est.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{}, uint32(0), pkgerrors.New("fail")) - est.On("BumpFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{}, uint32(0), pkgerrors.New("fail")) + est.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{}, uint64(0), pkgerrors.New("fail")) + est.On("BumpFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{}, uint64(0), pkgerrors.New("fail")) kst := ksmocks.NewEth(t) lggr := logger.Test(t) diff --git a/core/chains/evm/txmgr/broadcaster_test.go b/core/chains/evm/txmgr/broadcaster_test.go index 2af22d76a66..0b76f7fc6d1 100644 --- a/core/chains/evm/txmgr/broadcaster_test.go +++ b/core/chains/evm/txmgr/broadcaster_test.go @@ -36,7 +36,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" gasmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" @@ -188,7 +187,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Success(t *testing.T) { encodedPayload := []byte{1, 2, 3} value := big.Int(assets.NewEthValue(142)) - gasLimit := uint32(242) + gasLimit := uint64(242) checker := txmgr.TransmitCheckerSpec{ CheckerType: txmgr.TransmitCheckerTypeSimulate, } @@ -276,7 +275,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Success(t *testing.T) { return false } require.Equal(t, evmcfg.EVM().ChainID(), tx.ChainId()) - require.Equal(t, uint64(gasLimit), tx.Gas()) + require.Equal(t, gasLimit, tx.Gas()) require.Equal(t, evmcfg.EVM().GasEstimator().PriceDefault().ToInt(), tx.GasPrice()) require.Equal(t, toAddress, *tx.To()) require.Equal(t, value.String(), tx.Value().String()) @@ -299,7 +298,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Success(t *testing.T) { return false } require.Equal(t, evmcfg.EVM().ChainID(), tx.ChainId()) - require.Equal(t, uint64(gasLimit), tx.Gas()) + require.Equal(t, gasLimit, tx.Gas()) require.Equal(t, evmcfg.EVM().GasEstimator().PriceDefault().ToInt(), tx.GasPrice()) require.Equal(t, toAddress, *tx.To()) require.Equal(t, value.String(), tx.Value().String()) @@ -615,7 +614,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_OptimisticLockingOnEthTx(t *testi chStartEstimate := make(chan struct{}) chBlock := make(chan struct{}) - estimator.On("GetFee", mock.Anything, mock.Anything, mock.Anything, ccfg.EVM().GasEstimator().PriceMaxKey(fromAddress)).Return(gas.EvmFee{Legacy: assets.GWei(32)}, uint32(500), nil).Run(func(_ mock.Arguments) { + estimator.On("GetFee", mock.Anything, mock.Anything, mock.Anything, ccfg.EVM().GasEstimator().PriceMaxKey(fromAddress)).Return(gas.EvmFee{Legacy: assets.GWei(32)}, uint64(500), nil).Run(func(_ mock.Arguments) { close(chStartEstimate) <-chBlock }).Once() @@ -705,7 +704,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Success_WithMultiplier(t *testing func TestEthBroadcaster_ProcessUnstartedEthTxs_ResumingFromCrash(t *testing.T) { toAddress := gethCommon.HexToAddress("0x6C03DDA95a2AEd917EeCc6eddD4b9D16E6380411") value := big.Int(assets.NewEthValue(142)) - gasLimit := uint32(242) + gasLimit := uint64(242) encodedPayload := []byte{0, 1} nextNonce := evmtypes.Nonce(916714082576372851) firstNonce := nextNonce @@ -994,7 +993,7 @@ func getLocalNextNonce(t *testing.T, eb *txmgr.Broadcaster, fromAddress gethComm func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { toAddress := gethCommon.HexToAddress("0x6C03DDA95a2AEd917EeCc6eddD4b9D16E6380411") value := big.Int(assets.NewEthValue(142)) - gasLimit := uint32(242) + gasLimit := uint64(242) encodedPayload := []byte{0, 1} db := pgtest.NewSqlxDB(t) @@ -1632,7 +1631,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { func TestEthBroadcaster_ProcessUnstartedEthTxs_KeystoreErrors(t *testing.T) { toAddress := gethCommon.HexToAddress("0x6C03DDA95a2AEd917EeCc6eddD4b9D16E6380411") value := big.Int(assets.NewEthValue(142)) - gasLimit := uint32(242) + gasLimit := uint64(242) encodedPayload := []byte{0, 1} localNonce := 0 @@ -1679,7 +1678,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_KeystoreErrors(t *testing.T) { assert.Len(t, etx.TxAttempts, 0) // Check that the key did not have its nonce incremented - var nonce types.Nonce + var nonce evmtypes.Nonce nonce, err = eb.GetNextSequence(ctx, fromAddress) require.NoError(t, err) require.Equal(t, int64(localNonce), int64(nonce)) diff --git a/core/chains/evm/txmgr/client.go b/core/chains/evm/txmgr/client.go index e794f56ba31..89375e2d017 100644 --- a/core/chains/evm/txmgr/client.go +++ b/core/chains/evm/txmgr/client.go @@ -145,9 +145,9 @@ func (c *evmTxmClient) BatchGetReceipts(ctx context.Context, attempts []TxAttemp // May be useful for clearing stuck nonces func (c *evmTxmClient) SendEmptyTransaction( ctx context.Context, - newTxAttempt func(ctx context.Context, seq evmtypes.Nonce, feeLimit uint32, fee gas.EvmFee, fromAddress common.Address) (attempt TxAttempt, err error), + newTxAttempt func(ctx context.Context, seq evmtypes.Nonce, feeLimit uint64, fee gas.EvmFee, fromAddress common.Address) (attempt TxAttempt, err error), seq evmtypes.Nonce, - gasLimit uint32, + gasLimit uint64, fee gas.EvmFee, fromAddress common.Address, ) (txhash string, err error) { @@ -171,7 +171,7 @@ func (c *evmTxmClient) CallContract(ctx context.Context, a TxAttempt, blockNumbe _, errCall := c.client.CallContract(ctx, ethereum.CallMsg{ From: a.Tx.FromAddress, To: &a.Tx.ToAddress, - Gas: uint64(a.Tx.FeeLimit), + Gas: a.Tx.FeeLimit, GasPrice: a.TxFee.Legacy.ToInt(), GasFeeCap: a.TxFee.DynamicFeeCap.ToInt(), GasTipCap: a.TxFee.DynamicTipCap.ToInt(), diff --git a/core/chains/evm/txmgr/config.go b/core/chains/evm/txmgr/config.go index 8346a0d0551..b41753a070b 100644 --- a/core/chains/evm/txmgr/config.go +++ b/core/chains/evm/txmgr/config.go @@ -27,7 +27,7 @@ type FeeConfig interface { BumpPercent() uint16 BumpThreshold() uint64 BumpTxDepth() uint32 - LimitDefault() uint32 + LimitDefault() uint64 PriceDefault() *assets.Wei TipCapMin() *assets.Wei PriceMax() *assets.Wei diff --git a/core/chains/evm/txmgr/confirmer_test.go b/core/chains/evm/txmgr/confirmer_test.go index 1860b557335..ec09085bc44 100644 --- a/core/chains/evm/txmgr/confirmer_test.go +++ b/core/chains/evm/txmgr/confirmer_test.go @@ -1641,7 +1641,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WithConnectivityCheck(t *testing estimator := gasmocks.NewEvmEstimator(t) newEst := func(logger.Logger) gas.EvmEstimator { return estimator } - estimator.On("BumpLegacyGas", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, uint32(0), pkgerrors.Wrapf(commonfee.ErrConnectivity, "transaction...")) + estimator.On("BumpLegacyGas", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, uint64(0), pkgerrors.Wrapf(commonfee.ErrConnectivity, "transaction...")) ge := ccfg.EVM().GasEstimator() feeEstimator := gas.NewWrappedEvmEstimator(lggr, newEst, ge.EIP1559DynamicFees(), nil) txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, kst, feeEstimator) @@ -1686,7 +1686,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WithConnectivityCheck(t *testing kst := ksmocks.NewEth(t) estimator := gasmocks.NewEvmEstimator(t) - estimator.On("BumpDynamicFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.DynamicFee{}, uint32(0), pkgerrors.Wrapf(commonfee.ErrConnectivity, "transaction...")) + estimator.On("BumpDynamicFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.DynamicFee{}, uint64(0), pkgerrors.Wrapf(commonfee.ErrConnectivity, "transaction...")) newEst := func(logger.Logger) gas.EvmEstimator { return estimator } // Create confirmer with necessary state ge := ccfg.EVM().GasEstimator() @@ -2839,7 +2839,7 @@ func TestEthConfirmer_ForceRebroadcast(t *testing.T) { etx2 := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 2, fromAddress) gasPriceWei := gas.EvmFee{Legacy: assets.GWei(52)} - overrideGasLimit := uint32(20000) + overrideGasLimit := uint64(20000) t.Run("rebroadcasts one eth_tx if it falls within in nonce range", func(t *testing.T) { ethClient := evmtest.NewEthClientMockWithDefaultChain(t) @@ -2848,7 +2848,7 @@ func TestEthConfirmer_ForceRebroadcast(t *testing.T) { ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { return tx.Nonce() == uint64(*etx1.Sequence) && tx.GasPrice().Int64() == gasPriceWei.Legacy.Int64() && - tx.Gas() == uint64(overrideGasLimit) && + tx.Gas() == overrideGasLimit && reflect.DeepEqual(tx.Data(), etx1.EncodedPayload) && tx.To().String() == etx1.ToAddress.String() }), mock.Anything).Return(commonclient.Successful, nil).Once() @@ -2863,7 +2863,7 @@ func TestEthConfirmer_ForceRebroadcast(t *testing.T) { ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { return tx.Nonce() == uint64(*etx1.Sequence) && tx.GasPrice().Int64() == gasPriceWei.Legacy.Int64() && - tx.Gas() == uint64(etx1.FeeLimit) && + tx.Gas() == etx1.FeeLimit && reflect.DeepEqual(tx.Data(), etx1.EncodedPayload) && tx.To().String() == etx1.ToAddress.String() }), mock.Anything).Return(commonclient.Successful, nil).Once() @@ -2876,10 +2876,10 @@ func TestEthConfirmer_ForceRebroadcast(t *testing.T) { ec := newEthConfirmer(t, txStore, ethClient, config, ethKeyStore, nil) ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { - return tx.Nonce() == uint64(*etx1.Sequence) && tx.GasPrice().Int64() == gasPriceWei.Legacy.Int64() && tx.Gas() == uint64(overrideGasLimit) + return tx.Nonce() == uint64(*etx1.Sequence) && tx.GasPrice().Int64() == gasPriceWei.Legacy.Int64() && tx.Gas() == overrideGasLimit }), mock.Anything).Return(commonclient.Successful, nil).Once() ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { - return tx.Nonce() == uint64(*etx2.Sequence) && tx.GasPrice().Int64() == gasPriceWei.Legacy.Int64() && tx.Gas() == uint64(overrideGasLimit) + return tx.Nonce() == uint64(*etx2.Sequence) && tx.GasPrice().Int64() == gasPriceWei.Legacy.Int64() && tx.Gas() == overrideGasLimit }), mock.Anything).Return(commonclient.Successful, nil).Once() require.NoError(t, ec.ForceRebroadcast(testutils.Context(t), []evmtypes.Nonce{(1), (2)}, gasPriceWei, fromAddress, overrideGasLimit)) @@ -2900,7 +2900,7 @@ func TestEthConfirmer_ForceRebroadcast(t *testing.T) { ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { return tx.Nonce() == uint64(nonce) && tx.GasPrice().Int64() == gasPriceWei.Legacy.Int64() && - tx.Gas() == uint64(overrideGasLimit) && + tx.Gas() == overrideGasLimit && *tx.To() == fromAddress && tx.Value().Cmp(big.NewInt(0)) == 0 && len(tx.Data()) == 0 @@ -2916,7 +2916,7 @@ func TestEthConfirmer_ForceRebroadcast(t *testing.T) { ec := newEthConfirmer(t, txStore, ethClient, config, ethKeyStore, nil) ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { - return tx.Nonce() == uint64(0) && tx.GasPrice().Int64() == gasPriceWei.Legacy.Int64() && uint32(tx.Gas()) == config.EVM().GasEstimator().LimitDefault() + return tx.Nonce() == uint64(0) && tx.GasPrice().Int64() == gasPriceWei.Legacy.Int64() && tx.Gas() == config.EVM().GasEstimator().LimitDefault() }), mock.Anything).Return(commonclient.Successful, nil).Once() require.NoError(t, ec.ForceRebroadcast(testutils.Context(t), []evmtypes.Nonce{(0)}, gasPriceWei, fromAddress, 0)) diff --git a/core/chains/evm/txmgr/evm_tx_store.go b/core/chains/evm/txmgr/evm_tx_store.go index 364ee3f04d1..8187a390878 100644 --- a/core/chains/evm/txmgr/evm_tx_store.go +++ b/core/chains/evm/txmgr/evm_tx_store.go @@ -167,7 +167,7 @@ type DbEthTx struct { Value assets.Eth // GasLimit on the EthTx is always the conceptual gas limit, which is not // necessarily the same as the on-chain encoded value (i.e. Optimism) - GasLimit uint32 + GasLimit uint64 Error nullv4.String // BroadcastAt is updated every time an attempt for this eth_tx is re-sent // In almost all cases it will be within a second or so of the actual send time. @@ -276,7 +276,7 @@ type DbEthTxAttempt struct { BroadcastBeforeBlockNum *int64 State string CreatedAt time.Time - ChainSpecificGasLimit uint32 + ChainSpecificGasLimit uint64 TxType int GasTipCap *assets.Wei GasFeeCap *assets.Wei diff --git a/core/chains/evm/txmgr/evm_tx_store_test.go b/core/chains/evm/txmgr/evm_tx_store_test.go index 0994268037f..83d2381d007 100644 --- a/core/chains/evm/txmgr/evm_tx_store_test.go +++ b/core/chains/evm/txmgr/evm_tx_store_test.go @@ -1620,7 +1620,7 @@ func TestORM_CheckTxQueueCapacity(t *testing.T) { toAddress := testutils.NewAddress() encodedPayload := []byte{1, 2, 3} - feeLimit := uint32(1000000000) + feeLimit := uint64(1000000000) value := big.Int(assets.NewEthValue(142)) var maxUnconfirmedTransactions uint64 = 2 @@ -1713,7 +1713,7 @@ func TestORM_CreateTransaction(t *testing.T) { _, fromAddress := cltest.MustInsertRandomKey(t, kst.Eth()) toAddress := testutils.NewAddress() - gasLimit := uint32(1000) + gasLimit := uint64(1000) payload := []byte{1, 2, 3} ethClient := evmtest.NewEthClientMockWithDefaultChain(t) diff --git a/core/chains/evm/txmgr/test_helpers.go b/core/chains/evm/txmgr/test_helpers.go index e279dddf5fa..8cb771943b0 100644 --- a/core/chains/evm/txmgr/test_helpers.go +++ b/core/chains/evm/txmgr/test_helpers.go @@ -68,7 +68,7 @@ func (g *TestGasEstimatorConfig) BlockHistory() evmconfig.BlockHistory { } func (g *TestGasEstimatorConfig) EIP1559DynamicFees() bool { return false } -func (g *TestGasEstimatorConfig) LimitDefault() uint32 { return 42 } +func (g *TestGasEstimatorConfig) LimitDefault() uint64 { return 42 } func (g *TestGasEstimatorConfig) BumpPercent() uint16 { return 42 } func (g *TestGasEstimatorConfig) BumpThreshold() uint64 { return g.bumpThreshold } func (g *TestGasEstimatorConfig) BumpMin() *assets.Wei { return assets.NewWeiI(42) } @@ -76,7 +76,7 @@ func (g *TestGasEstimatorConfig) FeeCapDefault() *assets.Wei { return assets.New func (g *TestGasEstimatorConfig) PriceDefault() *assets.Wei { return assets.NewWeiI(42) } func (g *TestGasEstimatorConfig) TipCapDefault() *assets.Wei { return assets.NewWeiI(42) } func (g *TestGasEstimatorConfig) TipCapMin() *assets.Wei { return assets.NewWeiI(42) } -func (g *TestGasEstimatorConfig) LimitMax() uint32 { return 0 } +func (g *TestGasEstimatorConfig) LimitMax() uint64 { return 0 } func (g *TestGasEstimatorConfig) LimitMultiplier() float32 { return 0 } func (g *TestGasEstimatorConfig) BumpTxDepth() uint32 { return 42 } func (g *TestGasEstimatorConfig) LimitTransfer() uint32 { return 42 } diff --git a/core/chains/evm/txmgr/txmgr_test.go b/core/chains/evm/txmgr/txmgr_test.go index da18c592a55..0c812800f11 100644 --- a/core/chains/evm/txmgr/txmgr_test.go +++ b/core/chains/evm/txmgr/txmgr_test.go @@ -113,7 +113,7 @@ func TestTxm_CreateTransaction(t *testing.T) { _, fromAddress := cltest.MustInsertRandomKey(t, kst.Eth()) toAddress := testutils.NewAddress() - gasLimit := uint32(1000) + gasLimit := uint64(1000) payload := []byte{1, 2, 3} config, dbConfig, evmConfig := txmgr.MakeTestConfigs(t) @@ -396,7 +396,7 @@ func TestTxm_CreateTransaction_OutOfEth(t *testing.T) { fromAddress := thisKey.Address evmFromAddress := fromAddress - gasLimit := uint32(1000) + gasLimit := uint64(1000) toAddress := testutils.NewAddress() config, dbConfig, evmConfig := txmgr.MakeTestConfigs(t) @@ -784,13 +784,13 @@ func withDefaults() func(*txmgr.TxRequest) { tx.ToAddress = testutils.NewAddress() tx.EncodedPayload = []byte{1, 2, 3} tx.Value = big.Int(assets.NewEthValue(142)) - tx.FeeLimit = uint32(1000000000) + tx.FeeLimit = uint64(1000000000) tx.Strategy = txmgrcommon.NewSendEveryStrategy() // Set default values for other fields if needed } } -func mustCreateUnstartedTx(t testing.TB, txStore txmgr.EvmTxStore, fromAddress common.Address, toAddress common.Address, encodedPayload []byte, gasLimit uint32, value big.Int, chainID *big.Int, opts ...interface{}) (tx txmgr.Tx) { +func mustCreateUnstartedTx(t testing.TB, txStore txmgr.EvmTxStore, fromAddress common.Address, toAddress common.Address, encodedPayload []byte, gasLimit uint64, value big.Int, chainID *big.Int) (tx txmgr.Tx) { txRequest := txmgr.TxRequest{ FromAddress: fromAddress, ToAddress: toAddress, diff --git a/core/cmd/shell_local.go b/core/cmd/shell_local.go index 7e03fe719e1..8391e3bc70b 100644 --- a/core/cmd/shell_local.go +++ b/core/cmd/shell_local.go @@ -641,7 +641,7 @@ func (s *Shell) RebroadcastTransactions(c *cli.Context) (err error) { for i := int64(0); i < totalNonces; i++ { nonces[i] = evmtypes.Nonce(beginningNonce + i) } - err = ec.ForceRebroadcast(ctx, nonces, gas.EvmFee{Legacy: assets.NewWeiI(int64(gasPriceWei))}, address, uint32(overrideGasLimit)) + err = ec.ForceRebroadcast(ctx, nonces, gas.EvmFee{Legacy: assets.NewWeiI(int64(gasPriceWei))}, address, uint64(overrideGasLimit)) return s.errorOut(err) } diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 6bf2ad1b4b2..187589d8ee0 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -7,7 +7,6 @@ authorized_receiver: ../../contracts/solc/v0.8.19/AuthorizedReceiver/AuthorizedR automation_consumer_benchmark: ../../contracts/solc/v0.8.16/AutomationConsumerBenchmark/AutomationConsumerBenchmark.abi ../../contracts/solc/v0.8.16/AutomationConsumerBenchmark/AutomationConsumerBenchmark.bin f52c76f1aaed4be541d82d97189d70f5aa027fc9838037dd7a7d21910c8c488e automation_forwarder_logic: ../../contracts/solc/v0.8.16/AutomationForwarderLogic/AutomationForwarderLogic.abi ../../contracts/solc/v0.8.16/AutomationForwarderLogic/AutomationForwarderLogic.bin 15ae0c367297955fdab4b552dbb10e1f2be80a8fde0efec4a4d398693e9d72b5 automation_registrar_wrapper2_1: ../../contracts/solc/v0.8.16/AutomationRegistrar2_1/AutomationRegistrar2_1.abi ../../contracts/solc/v0.8.16/AutomationRegistrar2_1/AutomationRegistrar2_1.bin eb06d853aab39d3196c593b03e555851cbe8386e0fe54a74c2479f62d14b3c42 -automation_registrar_wrapper2_2: ../../contracts/solc/v0.8.19/AutomationRegistrar2_2/AutomationRegistrar2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistrar2_2/AutomationRegistrar2_2.bin 7c61908c1bb1bfd05a4da22bb73d62c0e2c05240f3f8fb5e06331603ff2246a9 automation_registrar_wrapper2_3: ../../contracts/solc/v0.8.19/AutomationRegistrar2_3/AutomationRegistrar2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistrar2_3/AutomationRegistrar2_3.bin 8e18d447009546ac8ad15d0d516ad4d663d0e1ca5f723300acb604b5571b63bf automation_registry_logic_a_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.bin 58d09c16be20a6d3f70be6d06299ed61415b7796c71f176d87ce015e1294e029 automation_registry_logic_a_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_3/AutomationRegistryLogicA2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_3/AutomationRegistryLogicA2_3.bin 56b9ed9923d0610fcc5c23c7e0d8f013195313138fbd2630b5148aced302582e diff --git a/core/gethwrappers/go_generate.go b/core/gethwrappers/go_generate.go index 2744f14c003..2b903ca9f50 100644 --- a/core/gethwrappers/go_generate.go +++ b/core/gethwrappers/go_generate.go @@ -56,7 +56,6 @@ package gethwrappers //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/KeeperRegistryLogicB2_1/KeeperRegistryLogicB2_1.abi ../../contracts/solc/v0.8.16/KeeperRegistryLogicB2_1/KeeperRegistryLogicB2_1.bin KeeperRegistryLogicB keeper_registry_logic_b_wrapper_2_1 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/IKeeperRegistryMaster/IKeeperRegistryMaster.abi ../../contracts/solc/v0.8.16/IKeeperRegistryMaster/IKeeperRegistryMaster.bin IKeeperRegistryMaster i_keeper_registry_master_wrapper_2_1 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/AutomationUtils2_1/AutomationUtils2_1.abi ../../contracts/solc/v0.8.16/AutomationUtils2_1/AutomationUtils2_1.bin AutomationUtils automation_utils_2_1 -//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/AutomationRegistrar2_2/AutomationRegistrar2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistrar2_2/AutomationRegistrar2_2.bin AutomationRegistrar automation_registrar_wrapper2_2 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.bin AutomationRegistry automation_registry_wrapper_2_2 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.bin AutomationRegistryLogicA automation_registry_logic_a_wrapper_2_2 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.bin AutomationRegistryLogicB automation_registry_logic_b_wrapper_2_2 diff --git a/core/internal/cltest/factories.go b/core/internal/cltest/factories.go index 2649cc47c6c..d192ce3d415 100644 --- a/core/internal/cltest/factories.go +++ b/core/internal/cltest/factories.go @@ -142,7 +142,7 @@ func NewEthTx(fromAddress common.Address) txmgr.Tx { ToAddress: testutils.NewAddress(), EncodedPayload: []byte{1, 2, 3}, Value: big.Int(assets.NewEthValue(142)), - FeeLimit: uint32(1000000000), + FeeLimit: uint64(1000000000), State: txmgrcommon.TxUnstarted, } } diff --git a/core/internal/features/features_test.go b/core/internal/features/features_test.go index d94452f2512..0b22d479da4 100644 --- a/core/internal/features/features_test.go +++ b/core/internal/features/features_test.go @@ -1334,7 +1334,7 @@ func TestIntegration_BlockHistoryEstimator(t *testing.T) { estimator := chain.GasEstimator() gasPrice, gasLimit, err := estimator.GetFee(testutils.Context(t), nil, 500_000, maxGasPrice) require.NoError(t, err) - assert.Equal(t, uint32(500000), gasLimit) + assert.Equal(t, uint64(500000), gasLimit) assert.Equal(t, "41.5 gwei", gasPrice.Legacy.String()) assert.Equal(t, initialDefaultGasPrice, chain.Config().EVM().GasEstimator().PriceDefault().Int64()) // unchanged diff --git a/core/services/blockhashstore/batch_bhs.go b/core/services/blockhashstore/batch_bhs.go index d8381ff6231..ffaa22b2463 100644 --- a/core/services/blockhashstore/batch_bhs.go +++ b/core/services/blockhashstore/batch_bhs.go @@ -18,7 +18,7 @@ import ( ) type batchBHSConfig interface { - LimitDefault() uint32 + LimitDefault() uint64 } type BatchBlockhashStore struct { diff --git a/core/services/blockhashstore/bhs.go b/core/services/blockhashstore/bhs.go index 0ca91c682e7..877e7b3dc25 100644 --- a/core/services/blockhashstore/bhs.go +++ b/core/services/blockhashstore/bhs.go @@ -25,7 +25,7 @@ import ( var _ BHS = &BulletproofBHS{} type bpBHSConfig interface { - LimitDefault() uint32 + LimitDefault() uint64 } type bpBHSDatabaseConfig interface { diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index 44c19aa257d..4d6ab0993e3 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -487,8 +487,8 @@ func TestConfig_Marshal(t *testing.T) { BumpTxDepth: ptr[uint32](6), BumpMin: assets.NewWeiI(100), FeeCapDefault: assets.NewWeiI(math.MaxInt64), - LimitDefault: ptr[uint32](12), - LimitMax: ptr[uint32](17), + LimitDefault: ptr[uint64](12), + LimitMax: ptr[uint64](17), LimitMultiplier: mustDecimal("1.234"), LimitTransfer: ptr[uint32](100), TipCapDefault: assets.NewWeiI(2), diff --git a/core/services/fluxmonitorv2/config.go b/core/services/fluxmonitorv2/config.go index 18fdf72798b..585c3f3f329 100644 --- a/core/services/fluxmonitorv2/config.go +++ b/core/services/fluxmonitorv2/config.go @@ -15,7 +15,7 @@ type Config interface { } type EvmFeeConfig interface { - LimitDefault() uint32 // Evm + LimitDefault() uint64 // Evm LimitJobType() config.LimitJobType } diff --git a/core/services/fluxmonitorv2/contract_submitter.go b/core/services/fluxmonitorv2/contract_submitter.go index c5a6e599f5d..c8d98a1a2f2 100644 --- a/core/services/fluxmonitorv2/contract_submitter.go +++ b/core/services/fluxmonitorv2/contract_submitter.go @@ -25,7 +25,7 @@ type FluxAggregatorContractSubmitter struct { flux_aggregator_wrapper.FluxAggregatorInterface orm ORM keyStore KeyStoreInterface - gasLimit uint32 + gasLimit uint64 forwardingAllowed bool chainID *big.Int } @@ -35,7 +35,7 @@ func NewFluxAggregatorContractSubmitter( contract flux_aggregator_wrapper.FluxAggregatorInterface, orm ORM, keyStore KeyStoreInterface, - gasLimit uint32, + gasLimit uint64, forwardingAllowed bool, chainID *big.Int, ) *FluxAggregatorContractSubmitter { diff --git a/core/services/fluxmonitorv2/contract_submitter_test.go b/core/services/fluxmonitorv2/contract_submitter_test.go index 4c8ce019bfd..238cf96e033 100644 --- a/core/services/fluxmonitorv2/contract_submitter_test.go +++ b/core/services/fluxmonitorv2/contract_submitter_test.go @@ -19,7 +19,7 @@ func TestFluxAggregatorContractSubmitter_Submit(t *testing.T) { fluxAggregator = mocks.NewFluxAggregator(t) orm = fmmocks.NewORM(t) keyStore = fmmocks.NewKeyStoreInterface(t) - gasLimit = uint32(2100) + gasLimit = uint64(2100) forwardingAllowed = false submitter = fluxmonitorv2.NewFluxAggregatorContractSubmitter(fluxAggregator, orm, keyStore, gasLimit, forwardingAllowed, testutils.FixtureChainID) diff --git a/core/services/fluxmonitorv2/flux_monitor.go b/core/services/fluxmonitorv2/flux_monitor.go index f21e56cbc80..724c03daa91 100644 --- a/core/services/fluxmonitorv2/flux_monitor.go +++ b/core/services/fluxmonitorv2/flux_monitor.go @@ -188,9 +188,9 @@ func NewFromJobSpec( gasLimit := fcfg.LimitDefault() fmLimit := fcfg.LimitJobType().FM() if jobSpec.GasLimit.Valid { - gasLimit = jobSpec.GasLimit.Uint32 + gasLimit = uint64(jobSpec.GasLimit.Uint32) } else if fmLimit != nil { - gasLimit = *fmLimit + gasLimit = uint64(*fmLimit) } contractSubmitter := NewFluxAggregatorContractSubmitter( diff --git a/core/services/fluxmonitorv2/mocks/orm.go b/core/services/fluxmonitorv2/mocks/orm.go index 8d277d61d2e..287c7ebb5fa 100644 --- a/core/services/fluxmonitorv2/mocks/orm.go +++ b/core/services/fluxmonitorv2/mocks/orm.go @@ -48,7 +48,7 @@ func (_m *ORM) CountFluxMonitorRoundStats() (int, error) { } // CreateEthTransaction provides a mock function with given fields: ctx, fromAddress, toAddress, payload, gasLimit, idempotencyKey -func (_m *ORM) CreateEthTransaction(ctx context.Context, fromAddress common.Address, toAddress common.Address, payload []byte, gasLimit uint32, idempotencyKey *string) error { +func (_m *ORM) CreateEthTransaction(ctx context.Context, fromAddress common.Address, toAddress common.Address, payload []byte, gasLimit uint64, idempotencyKey *string) error { ret := _m.Called(ctx, fromAddress, toAddress, payload, gasLimit, idempotencyKey) if len(ret) == 0 { @@ -56,7 +56,7 @@ func (_m *ORM) CreateEthTransaction(ctx context.Context, fromAddress common.Addr } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, common.Address, common.Address, []byte, uint32, *string) error); ok { + if rf, ok := ret.Get(0).(func(context.Context, common.Address, common.Address, []byte, uint64, *string) error); ok { r0 = rf(ctx, fromAddress, toAddress, payload, gasLimit, idempotencyKey) } else { r0 = ret.Error(0) diff --git a/core/services/fluxmonitorv2/orm.go b/core/services/fluxmonitorv2/orm.go index f85ab146c7e..91973387e32 100644 --- a/core/services/fluxmonitorv2/orm.go +++ b/core/services/fluxmonitorv2/orm.go @@ -27,7 +27,7 @@ type ORM interface { DeleteFluxMonitorRoundsBackThrough(aggregator common.Address, roundID uint32) error FindOrCreateFluxMonitorRoundStats(aggregator common.Address, roundID uint32, newRoundLogs uint) (FluxMonitorRoundStatsV2, error) UpdateFluxMonitorRoundStats(aggregator common.Address, roundID uint32, runID int64, newRoundLogsAddition uint, qopts ...pg.QOpt) error - CreateEthTransaction(ctx context.Context, fromAddress, toAddress common.Address, payload []byte, gasLimit uint32, idempotencyKey *string) error + CreateEthTransaction(ctx context.Context, fromAddress, toAddress common.Address, payload []byte, gasLimit uint64, idempotencyKey *string) error CountFluxMonitorRoundStats() (count int, err error) } @@ -119,7 +119,7 @@ func (o *orm) CreateEthTransaction( fromAddress common.Address, toAddress common.Address, payload []byte, - gasLimit uint32, + gasLimit uint64, idempotencyKey *string, ) (err error) { diff --git a/core/services/fluxmonitorv2/orm_test.go b/core/services/fluxmonitorv2/orm_test.go index bcbec4363e2..17e03a674f0 100644 --- a/core/services/fluxmonitorv2/orm_test.go +++ b/core/services/fluxmonitorv2/orm_test.go @@ -180,7 +180,7 @@ func TestORM_CreateEthTransaction(t *testing.T) { _, from = cltest.MustInsertRandomKey(t, ethKeyStore) to = testutils.NewAddress() payload = []byte{1, 0, 0} - gasLimit = uint32(21000) + gasLimit = uint64(21000) ) idempotencyKey := uuid.New().String() txm.On("CreateTransaction", mock.Anything, txmgr.TxRequest{ diff --git a/core/services/keeper/upkeep_executer_test.go b/core/services/keeper/upkeep_executer_test.go index 1018d5f2aab..9b6d64c2e20 100644 --- a/core/services/keeper/upkeep_executer_test.go +++ b/core/services/keeper/upkeep_executer_test.go @@ -132,7 +132,7 @@ func Test_UpkeepExecuter_PerformsUpkeep_Happy(t *testing.T) { c.EVM[0].ChainID = (*ubig.Big)(testutils.SimulatedChainID) }) - gasLimit := 5_000_000 + config.Keeper().Registry().PerformGasOverhead() + gasLimit := uint64(5_000_000 + config.Keeper().Registry().PerformGasOverhead()) ethTxCreated := cltest.NewAwaiter() txm.On("CreateTransaction", @@ -177,7 +177,7 @@ func Test_UpkeepExecuter_PerformsUpkeep_Happy(t *testing.T) { c.EVM[0].ChainID = (*ubig.Big)(testutils.SimulatedChainID) }) - gasLimit := 5_000_000 + config.Keeper().Registry().PerformGasOverhead() + gasLimit := uint64(5_000_000 + config.Keeper().Registry().PerformGasOverhead()) ethTxCreated := cltest.NewAwaiter() txm.On("CreateTransaction", @@ -287,7 +287,7 @@ func Test_UpkeepExecuter_PerformsUpkeep_Happy(t *testing.T) { cltest.NewAwaiter(), cltest.NewAwaiter(), } - gasLimit := 5_000_000 + config.Keeper().Registry().PerformGasOverhead() + gasLimit := uint64(5_000_000 + config.Keeper().Registry().PerformGasOverhead()) txm.On("CreateTransaction", mock.Anything, mock.MatchedBy(func(txRequest txmgr.TxRequest) bool { return txRequest.FeeLimit == gasLimit }), diff --git a/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go b/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go index 7f562c9adb3..1216eec0a63 100644 --- a/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go +++ b/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go @@ -337,7 +337,7 @@ func StartNewNode( c.EVM[0].LogPollInterval = commonconfig.MustNewDuration(1 * time.Second) c.EVM[0].Transactions.ForwardersEnabled = ptr(false) - c.EVM[0].GasEstimator.LimitDefault = ptr(maxGas) + c.EVM[0].GasEstimator.LimitDefault = ptr(uint64(maxGas)) c.EVM[0].GasEstimator.Mode = ptr("FixedPrice") c.EVM[0].GasEstimator.PriceDefault = assets.NewWei(big.NewInt(int64(DefaultGasPrice))) diff --git a/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go b/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go index 8d50b8076bb..8a496355c40 100644 --- a/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go +++ b/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go @@ -246,7 +246,7 @@ func setupNodeOCR2( c.OCR2.Enabled = ptr(true) c.EVM[0].LogPollInterval = commonconfig.MustNewDuration(500 * time.Millisecond) - c.EVM[0].GasEstimator.LimitDefault = ptr[uint32](3_500_000) + c.EVM[0].GasEstimator.LimitDefault = ptr[uint64](3_500_000) c.EVM[0].Transactions.ForwardersEnabled = &useForwarders c.OCR2.ContractPollInterval = commonconfig.MustNewDuration(10 * time.Second) }) diff --git a/core/services/ocrcommon/transmitter.go b/core/services/ocrcommon/transmitter.go index 1c4173798ea..423db2316a7 100644 --- a/core/services/ocrcommon/transmitter.go +++ b/core/services/ocrcommon/transmitter.go @@ -27,7 +27,7 @@ type Transmitter interface { type transmitter struct { txm txManager fromAddresses []common.Address - gasLimit uint32 + gasLimit uint64 effectiveTransmitterAddress common.Address strategy types.TxStrategy checker txmgr.TransmitCheckerSpec @@ -39,7 +39,7 @@ type transmitter struct { func NewTransmitter( txm txManager, fromAddresses []common.Address, - gasLimit uint32, + gasLimit uint64, effectiveTransmitterAddress common.Address, strategy types.TxStrategy, checker txmgr.TransmitCheckerSpec, diff --git a/core/services/ocrcommon/transmitter_test.go b/core/services/ocrcommon/transmitter_test.go index d954da869bc..c56896ab2b9 100644 --- a/core/services/ocrcommon/transmitter_test.go +++ b/core/services/ocrcommon/transmitter_test.go @@ -31,7 +31,7 @@ func Test_DefaultTransmitter_CreateEthTransaction(t *testing.T) { _, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore) - gasLimit := uint32(1000) + gasLimit := uint64(1000) chainID := big.NewInt(0) effectiveTransmitterAddress := fromAddress toAddress := testutils.NewAddress() @@ -73,7 +73,7 @@ func Test_DefaultTransmitter_Forwarding_Enabled_CreateEthTransaction(t *testing. _, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore) _, fromAddress2 := cltest.MustInsertRandomKey(t, ethKeyStore) - gasLimit := uint32(1000) + gasLimit := uint64(1000) chainID := big.NewInt(0) effectiveTransmitterAddress := common.Address{} toAddress := testutils.NewAddress() @@ -124,7 +124,7 @@ func Test_DefaultTransmitter_Forwarding_Enabled_CreateEthTransaction_Round_Robin fromAddress := common.Address{} - gasLimit := uint32(1000) + gasLimit := uint64(1000) chainID := big.NewInt(0) effectiveTransmitterAddress := common.Address{} toAddress := testutils.NewAddress() @@ -156,7 +156,7 @@ func Test_DefaultTransmitter_Forwarding_Enabled_CreateEthTransaction_No_Keystore _, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore) _, fromAddress2 := cltest.MustInsertRandomKey(t, ethKeyStore) - gasLimit := uint32(1000) + gasLimit := uint64(1000) chainID := big.NewInt(0) effectiveTransmitterAddress := common.Address{} txm := txmmocks.NewMockEvmTxManager(t) diff --git a/core/services/pipeline/common.go b/core/services/pipeline/common.go index 6e7ad1e7e4e..a07319643c3 100644 --- a/core/services/pipeline/common.go +++ b/core/services/pipeline/common.go @@ -560,9 +560,9 @@ func CheckInputs(inputs []Result, minLen, maxLen, maxErrors int) ([]interface{}, var ErrInvalidEVMChainID = errors.New("invalid EVM chain ID") -func SelectGasLimit(ge config.GasEstimator, jobType string, specGasLimit *uint32) uint32 { +func SelectGasLimit(ge config.GasEstimator, jobType string, specGasLimit *uint32) uint64 { if specGasLimit != nil { - return *specGasLimit + return uint64(*specGasLimit) } jt := ge.LimitJobType() @@ -583,7 +583,7 @@ func SelectGasLimit(ge config.GasEstimator, jobType string, specGasLimit *uint32 } if jobTypeGasLimit != nil { - return *jobTypeGasLimit + return uint64(*jobTypeGasLimit) } return ge.LimitDefault() } diff --git a/core/services/pipeline/common_test.go b/core/services/pipeline/common_test.go index 7da80d3af47..ea3f4d90c3b 100644 --- a/core/services/pipeline/common_test.go +++ b/core/services/pipeline/common_test.go @@ -324,7 +324,7 @@ func TestSelectGasLimit(t *testing.T) { t.Parallel() gcfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.EVM[0].GasEstimator.LimitDefault = ptr(uint32(999)) + c.EVM[0].GasEstimator.LimitDefault = ptr(uint64(999)) c.EVM[0].GasEstimator.LimitJobType = toml.GasLimitJobType{ DR: ptr(uint32(100)), VRF: ptr(uint32(101)), @@ -339,42 +339,42 @@ func TestSelectGasLimit(t *testing.T) { t.Run("spec defined gas limit", func(t *testing.T) { var specGasLimit uint32 = 1 gasLimit := pipeline.SelectGasLimit(cfg.EVM().GasEstimator(), pipeline.DirectRequestJobType, &specGasLimit) - assert.Equal(t, uint32(1), gasLimit) + assert.Equal(t, uint64(1), gasLimit) }) t.Run("direct request specific gas limit", func(t *testing.T) { gasLimit := pipeline.SelectGasLimit(cfg.EVM().GasEstimator(), pipeline.DirectRequestJobType, nil) - assert.Equal(t, uint32(100), gasLimit) + assert.Equal(t, uint64(100), gasLimit) }) t.Run("OCR specific gas limit", func(t *testing.T) { gasLimit := pipeline.SelectGasLimit(cfg.EVM().GasEstimator(), pipeline.OffchainReportingJobType, nil) - assert.Equal(t, uint32(103), gasLimit) + assert.Equal(t, uint64(103), gasLimit) }) t.Run("OCR2 specific gas limit", func(t *testing.T) { gasLimit := pipeline.SelectGasLimit(cfg.EVM().GasEstimator(), pipeline.OffchainReporting2JobType, nil) - assert.Equal(t, uint32(105), gasLimit) + assert.Equal(t, uint64(105), gasLimit) }) t.Run("VRF specific gas limit", func(t *testing.T) { gasLimit := pipeline.SelectGasLimit(cfg.EVM().GasEstimator(), pipeline.VRFJobType, nil) - assert.Equal(t, uint32(101), gasLimit) + assert.Equal(t, uint64(101), gasLimit) }) t.Run("flux monitor specific gas limit", func(t *testing.T) { gasLimit := pipeline.SelectGasLimit(cfg.EVM().GasEstimator(), pipeline.FluxMonitorJobType, nil) - assert.Equal(t, uint32(102), gasLimit) + assert.Equal(t, uint64(102), gasLimit) }) t.Run("keeper specific gas limit", func(t *testing.T) { gasLimit := pipeline.SelectGasLimit(cfg.EVM().GasEstimator(), pipeline.KeeperJobType, nil) - assert.Equal(t, uint32(104), gasLimit) + assert.Equal(t, uint64(104), gasLimit) }) t.Run("fallback to default gas limit", func(t *testing.T) { gasLimit := pipeline.SelectGasLimit(cfg.EVM().GasEstimator(), pipeline.WebhookJobType, nil) - assert.Equal(t, uint32(999), gasLimit) + assert.Equal(t, uint64(999), gasLimit) }) } func TestGetNextTaskOf(t *testing.T) { diff --git a/core/services/pipeline/task.estimategas.go b/core/services/pipeline/task.estimategas.go index 8fccc5e8eac..54be6273057 100644 --- a/core/services/pipeline/task.estimategas.go +++ b/core/services/pipeline/task.estimategas.go @@ -123,7 +123,7 @@ func (t *EstimateGasLimitTask) Run(ctx context.Context, lggr logger.Logger, vars if !gasLimitWithMultiplier.IsUint64() { return Result{Error: ErrInvalidMultiplier}, retryableRunInfo() } - gasLimitFinal := uint32(gasLimitWithMultiplier.Uint64()) + gasLimitFinal := gasLimitWithMultiplier.Uint64() if gasLimitFinal > maximumGasLimit { lggr.Warnw("EstimateGas: estimated amount is greater than configured limit, fallback to configured limit", "estimate", gasLimitFinal, diff --git a/core/services/pipeline/task.eth_call.go b/core/services/pipeline/task.eth_call.go index f011cd7a9b6..a3e95c3cfc1 100644 --- a/core/services/pipeline/task.eth_call.go +++ b/core/services/pipeline/task.eth_call.go @@ -106,14 +106,14 @@ func (t *ETHCallTask) Run(ctx context.Context, lggr logger.Logger, vars Vars, in return Result{Error: err}, runInfo } - var selectedGas uint32 + var selectedGas uint64 if gasUnlimited { if gas > 0 { return Result{Error: errors.Wrapf(ErrBadInput, "gas must be zero when gasUnlimited is true")}, runInfo } } else { if gas > 0 { - selectedGas = uint32(gas) + selectedGas = uint64(gas) } else { selectedGas = SelectGasLimit(chain.Config().EVM().GasEstimator(), t.jobType, t.specGasLimit) } @@ -123,7 +123,7 @@ func (t *ETHCallTask) Run(ctx context.Context, lggr logger.Logger, vars Vars, in To: (*common.Address)(&contractAddr), From: (common.Address)(from), Data: []byte(data), - Gas: uint64(selectedGas), + Gas: selectedGas, GasPrice: gasPrice.BigInt(), GasTipCap: gasTipCap.BigInt(), GasFeeCap: gasFeeCap.BigInt(), diff --git a/core/services/pipeline/task.eth_call_test.go b/core/services/pipeline/task.eth_call_test.go index 28af94ba25c..b21b3065f8c 100644 --- a/core/services/pipeline/task.eth_call_test.go +++ b/core/services/pipeline/task.eth_call_test.go @@ -33,7 +33,7 @@ func TestETHCallTask(t *testing.T) { testutils.SkipShortDB(t) var specGasLimit uint32 = 123 - const gasLimit uint32 = 500_000 + const gasLimit uint64 = 500_000 const drJobTypeGasLimit uint32 = 789 tests := []struct { diff --git a/core/services/pipeline/task.eth_tx.go b/core/services/pipeline/task.eth_tx.go index ffd496c486d..354651acbb4 100644 --- a/core/services/pipeline/task.eth_tx.go +++ b/core/services/pipeline/task.eth_tx.go @@ -150,7 +150,7 @@ func (t *ETHTxTask) Run(ctx context.Context, lggr logger.Logger, vars Vars, inpu FromAddress: fromAddr, ToAddress: common.Address(toAddr), EncodedPayload: []byte(data), - FeeLimit: uint32(gasLimit), + FeeLimit: uint64(gasLimit), Meta: txMeta, ForwarderAddress: forwarderAddress, Strategy: strategy, diff --git a/core/services/pipeline/task.eth_tx_test.go b/core/services/pipeline/task.eth_tx_test.go index d50949e120d..c38c338df20 100644 --- a/core/services/pipeline/task.eth_tx_test.go +++ b/core/services/pipeline/task.eth_tx_test.go @@ -31,7 +31,7 @@ func TestETHTxTask(t *testing.T) { reqID := common.HexToHash("0x5198616554d738d9485d1a7cf53b2f33e09c3bbc8fe9ac0020bd672cd2bc15d2") reqTxHash := common.HexToHash("0xc524fafafcaec40652b1f84fca09c231185437d008d195fccf2f51e64b7062f8") specGasLimit := uint32(123) - const defaultGasLimit uint32 = 999 + const defaultGasLimit uint64 = 999 const drJobTypeGasLimit uint32 = 789 from := common.HexToAddress("0x882969652440ccf14a5dbb9bd53eb21cb1e11e5c") @@ -74,7 +74,7 @@ func TestETHTxTask(t *testing.T) { func(keyStore *keystoremocks.Eth, txManager *txmmocks.MockEvmTxManager) { data := []byte("foobar") - gasLimit := uint32(12345) + gasLimit := uint64(12345) jobID := int32(321) addr := common.HexToAddress("0x2E396ecbc8223Ebc16EC45136228AE5EDB649943") txMeta := &txmgr.TxMeta{ @@ -124,7 +124,7 @@ func TestETHTxTask(t *testing.T) { nil, func(keyStore *keystoremocks.Eth, txManager *txmmocks.MockEvmTxManager) { data := []byte("foobar") - gasLimit := uint32(12345) + gasLimit := uint64(12345) txMeta := &txmgr.TxMeta{ JobID: &jid, RequestID: &reqID, @@ -202,7 +202,7 @@ func TestETHTxTask(t *testing.T) { nil, func(keyStore *keystoremocks.Eth, txManager *txmmocks.MockEvmTxManager) { data := []byte("foobar") - gasLimit := uint32(12345) + gasLimit := uint64(12345) txMeta := &txmgr.TxMeta{ JobID: &jid, RequestID: &reqID, @@ -248,7 +248,7 @@ func TestETHTxTask(t *testing.T) { nil, func(keyStore *keystoremocks.Eth, txManager *txmmocks.MockEvmTxManager) { data := []byte("foobar") - gasLimit := uint32(12345) + gasLimit := uint64(12345) txMeta := &txmgr.TxMeta{ JobID: &jid, RequestID: &reqID, @@ -284,7 +284,7 @@ func TestETHTxTask(t *testing.T) { nil, func(keyStore *keystoremocks.Eth, txManager *txmmocks.MockEvmTxManager) { data := []byte("foobar") - gasLimit := uint32(12345) + gasLimit := uint64(12345) txMeta := &txmgr.TxMeta{FailOnRevert: null.BoolFrom(false)} keyStore.On("GetRoundRobinAddress", mock.Anything, testutils.FixtureChainID, from).Return(from, nil) txManager.On("CreateTransaction", mock.Anything, txmgr.TxRequest{ @@ -326,7 +326,7 @@ func TestETHTxTask(t *testing.T) { FromAddress: from, ToAddress: to, EncodedPayload: data, - FeeLimit: drJobTypeGasLimit, + FeeLimit: uint64(drJobTypeGasLimit), Meta: txMeta, Strategy: txmgrcommon.NewSendEveryStrategy(), SignalCallback: true, @@ -361,7 +361,7 @@ func TestETHTxTask(t *testing.T) { FromAddress: from, ToAddress: to, EncodedPayload: data, - FeeLimit: specGasLimit, + FeeLimit: uint64(specGasLimit), Meta: txMeta, Strategy: txmgrcommon.NewSendEveryStrategy(), SignalCallback: true, @@ -415,7 +415,7 @@ func TestETHTxTask(t *testing.T) { nil, func(keyStore *keystoremocks.Eth, txManager *txmmocks.MockEvmTxManager) { data := []byte("foobar") - gasLimit := uint32(12345) + gasLimit := uint64(12345) txMeta := &txmgr.TxMeta{ JobID: &jid, RequestID: &reqID, diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index a02885cb556..3797e6633a6 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -10,6 +10,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" + "github.com/google/uuid" "github.com/jmoiron/sqlx" pkgerrors "github.com/pkg/errors" "golang.org/x/exp/maps" @@ -454,10 +455,13 @@ func (c *configWatcher) ContractConfigTracker() ocrtypes.ContractConfigTracker { } type configTransmitterOpts struct { - // override the gas limit default provided in the config watcher + // pluginGasLimit overrides the gas limit default provided in the config watcher. pluginGasLimit *uint32 + // subjectID overrides the queueing subject id (the job external id will be used by default). + subjectID *uuid.UUID } +// newOnChainContractTransmitter creates a new contract transmitter. func newOnChainContractTransmitter(ctx context.Context, lggr logger.Logger, rargs commontypes.RelayArgs, transmitterID string, ethKeystore keystore.Eth, configWatcher *configWatcher, opts configTransmitterOpts, transmissionContractABI abi.ABI) (*contractTransmitter, error) { var relayConfig types.RelayConfig if err := json.Unmarshal(rargs.RelayConfig, &relayConfig); err != nil { @@ -487,8 +491,12 @@ func newOnChainContractTransmitter(ctx context.Context, lggr logger.Logger, rarg fromAddresses = append(fromAddresses, common.HexToAddress(s)) } + subject := rargs.ExternalJobID + if opts.subjectID != nil { + subject = *opts.subjectID + } scoped := configWatcher.chain.Config() - strategy := txmgrcommon.NewQueueingTxStrategy(rargs.ExternalJobID, scoped.OCR2().DefaultTransactionQueueDepth(), scoped.Database().DefaultQueryTimeout()) + strategy := txmgrcommon.NewQueueingTxStrategy(subject, scoped.OCR2().DefaultTransactionQueueDepth(), scoped.Database().DefaultQueryTimeout()) var checker txm.TransmitCheckerSpec if configWatcher.chain.Config().OCR2().SimulateTransactions() { @@ -498,10 +506,10 @@ func newOnChainContractTransmitter(ctx context.Context, lggr logger.Logger, rarg gasLimit := configWatcher.chain.Config().EVM().GasEstimator().LimitDefault() ocr2Limit := configWatcher.chain.Config().EVM().GasEstimator().LimitJobType().OCR2() if ocr2Limit != nil { - gasLimit = *ocr2Limit + gasLimit = uint64(*ocr2Limit) } if opts.pluginGasLimit != nil { - gasLimit = *opts.pluginGasLimit + gasLimit = uint64(*opts.pluginGasLimit) } transmitter, err := ocrcommon.NewTransmitter( diff --git a/core/services/relay/evm/functions.go b/core/services/relay/evm/functions.go index c10134f3acc..41d9f93c5aa 100644 --- a/core/services/relay/evm/functions.go +++ b/core/services/relay/evm/functions.go @@ -194,7 +194,7 @@ func newFunctionsContractTransmitter(ctx context.Context, contractVersion uint32 gasLimit := configWatcher.chain.Config().EVM().GasEstimator().LimitDefault() ocr2Limit := configWatcher.chain.Config().EVM().GasEstimator().LimitJobType().OCR2() if ocr2Limit != nil { - gasLimit = *ocr2Limit + gasLimit = uint64(*ocr2Limit) } transmitter, err := ocrcommon.NewTransmitter( diff --git a/core/services/vrf/mocks/fee_config.go b/core/services/vrf/mocks/fee_config.go index 2f33415b338..ee7ea4e9a58 100644 --- a/core/services/vrf/mocks/fee_config.go +++ b/core/services/vrf/mocks/fee_config.go @@ -17,18 +17,18 @@ type FeeConfig struct { } // LimitDefault provides a mock function with given fields: -func (_m *FeeConfig) LimitDefault() uint32 { +func (_m *FeeConfig) LimitDefault() uint64 { ret := _m.Called() if len(ret) == 0 { panic("no return value specified for LimitDefault") } - var r0 uint32 - if rf, ok := ret.Get(0).(func() uint32); ok { + var r0 uint64 + if rf, ok := ret.Get(0).(func() uint64); ok { r0 = rf() } else { - r0 = ret.Get(0).(uint32) + r0 = ret.Get(0).(uint64) } return r0 diff --git a/core/services/vrf/v2/bhs_feeder_test.go b/core/services/vrf/v2/bhs_feeder_test.go index 6f857c80834..0ce674f5168 100644 --- a/core/services/vrf/v2/bhs_feeder_test.go +++ b/core/services/vrf/v2/bhs_feeder_test.go @@ -57,7 +57,7 @@ func TestStartHeartbeats(t *testing.T) { c.EVM[0].MinIncomingConfirmations = ptr[uint32](2) c.Feature.LogPoller = ptr(true) c.EVM[0].FinalityDepth = ptr[uint32](2) - c.EVM[0].GasEstimator.LimitDefault = ptr(uint32(gasLimit)) + c.EVM[0].GasEstimator.LimitDefault = ptr(uint64(gasLimit)) c.EVM[0].LogPollInterval = commonconfig.MustNewDuration(time.Second) }) diff --git a/core/services/vrf/v2/integration_helpers_test.go b/core/services/vrf/v2/integration_helpers_test.go index 6649b5972e0..71724b928c1 100644 --- a/core/services/vrf/v2/integration_helpers_test.go +++ b/core/services/vrf/v2/integration_helpers_test.go @@ -356,7 +356,7 @@ func testMultipleConsumersNeedTrustedBHS( config, db := heavyweight.FullTestDBV2(t, func(c *chainlink.Config, s *chainlink.Secrets) { simulatedOverrides(t, assets.GWei(10), keySpecificOverrides...)(c, s) c.EVM[0].MinIncomingConfirmations = ptr[uint32](2) - c.EVM[0].GasEstimator.LimitDefault = ptr(uint32(5_000_000)) + c.EVM[0].GasEstimator.LimitDefault = ptr(uint64(5_000_000)) c.Feature.LogPoller = ptr(true) c.EVM[0].LogPollInterval = commonconfig.MustNewDuration(1 * time.Second) c.EVM[0].FinalityDepth = ptr[uint32](2) @@ -541,7 +541,7 @@ func testSingleConsumerHappyPathBatchFulfillment( Key: ptr(key1.EIP55Address), GasEstimator: toml.KeySpecificGasEstimator{PriceMax: gasLanePriceWei}, })(c, s) - c.EVM[0].GasEstimator.LimitDefault = ptr[uint32](5_000_000) + c.EVM[0].GasEstimator.LimitDefault = ptr[uint64](5_000_000) c.EVM[0].MinIncomingConfirmations = ptr[uint32](2) c.EVM[0].ChainID = (*ubig.Big)(testutils.SimulatedChainID) c.Feature.LogPoller = ptr(true) @@ -1074,7 +1074,7 @@ func testSingleConsumerEIP150( Key: ptr(key1.EIP55Address), GasEstimator: v2.KeySpecificGasEstimator{PriceMax: gasLanePriceWei}, })(c, s) - c.EVM[0].GasEstimator.LimitDefault = ptr(uint32(3.5e6)) + c.EVM[0].GasEstimator.LimitDefault = ptr(uint64(3.5e6)) c.EVM[0].MinIncomingConfirmations = ptr[uint32](2) c.Feature.LogPoller = ptr(true) c.EVM[0].LogPollInterval = commonconfig.MustNewDuration(1 * time.Second) @@ -1144,7 +1144,7 @@ func testSingleConsumerEIP150Revert( Key: ptr(key1.EIP55Address), GasEstimator: v2.KeySpecificGasEstimator{PriceMax: gasLanePriceWei}, })(c, s) - c.EVM[0].GasEstimator.LimitDefault = ptr(uint32(gasLimit)) + c.EVM[0].GasEstimator.LimitDefault = ptr(uint64(gasLimit)) c.EVM[0].MinIncomingConfirmations = ptr[uint32](2) c.Feature.LogPoller = ptr(true) c.EVM[0].LogPollInterval = commonconfig.MustNewDuration(1 * time.Second) @@ -1209,7 +1209,7 @@ func testSingleConsumerBigGasCallbackSandwich( Key: ptr(key1.EIP55Address), GasEstimator: v2.KeySpecificGasEstimator{PriceMax: gasLanePriceWei}, })(c, s) - c.EVM[0].GasEstimator.LimitDefault = ptr[uint32](5_000_000) + c.EVM[0].GasEstimator.LimitDefault = ptr[uint64](5_000_000) c.EVM[0].MinIncomingConfirmations = ptr[uint32](2) c.Feature.LogPoller = ptr(true) c.EVM[0].LogPollInterval = commonconfig.MustNewDuration(1 * time.Second) @@ -1332,7 +1332,7 @@ func testSingleConsumerMultipleGasLanes( GasEstimator: v2.KeySpecificGasEstimator{PriceMax: expensiveGasLane}, })(c, s) c.EVM[0].MinIncomingConfirmations = ptr[uint32](2) - c.EVM[0].GasEstimator.LimitDefault = ptr[uint32](5_000_000) + c.EVM[0].GasEstimator.LimitDefault = ptr[uint64](5_000_000) c.Feature.LogPoller = ptr(true) c.EVM[0].LogPollInterval = commonconfig.MustNewDuration(1 * time.Second) }) @@ -1644,7 +1644,7 @@ func testMaliciousConsumer( vrfVersion vrfcommon.Version, ) { config, _ := heavyweight.FullTestDBV2(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.EVM[0].GasEstimator.LimitDefault = ptr[uint32](2_000_000) + c.EVM[0].GasEstimator.LimitDefault = ptr[uint64](2_000_000) c.EVM[0].GasEstimator.PriceMax = assets.GWei(1) c.EVM[0].GasEstimator.PriceDefault = assets.GWei(1) c.EVM[0].GasEstimator.FeeCapDefault = assets.GWei(1) diff --git a/core/services/vrf/v2/integration_v2_plus_test.go b/core/services/vrf/v2/integration_v2_plus_test.go index 9d89911f0f2..22b10b61c84 100644 --- a/core/services/vrf/v2/integration_v2_plus_test.go +++ b/core/services/vrf/v2/integration_v2_plus_test.go @@ -1151,7 +1151,7 @@ func TestVRFV2PlusIntegration_Migration(t *testing.T) { Key: ptr(key1.EIP55Address), GasEstimator: toml.KeySpecificGasEstimator{PriceMax: gasLanePriceWei}, })(c, s) - c.EVM[0].GasEstimator.LimitDefault = ptr[uint32](5_000_000) + c.EVM[0].GasEstimator.LimitDefault = ptr[uint64](5_000_000) c.EVM[0].MinIncomingConfirmations = ptr[uint32](2) c.Feature.LogPoller = ptr(true) c.EVM[0].LogPollInterval = commonconfig.MustNewDuration(1 * time.Second) diff --git a/core/services/vrf/v2/integration_v2_test.go b/core/services/vrf/v2/integration_v2_test.go index 18be6d8e408..3b7cdfa0a62 100644 --- a/core/services/vrf/v2/integration_v2_test.go +++ b/core/services/vrf/v2/integration_v2_test.go @@ -1012,7 +1012,7 @@ func testEoa( Key: ptr(key1.EIP55Address), GasEstimator: toml.KeySpecificGasEstimator{PriceMax: gasLanePriceWei}, })(c, s) - c.EVM[0].GasEstimator.LimitDefault = ptr(uint32(gasLimit)) + c.EVM[0].GasEstimator.LimitDefault = ptr(uint64(gasLimit)) c.EVM[0].MinIncomingConfirmations = ptr[uint32](2) c.EVM[0].FinalityDepth = ptr(finalityDepth) }) @@ -1173,7 +1173,7 @@ func TestVRFV2Integration_SingleConsumer_Wrapper(t *testing.T) { Key: ptr(key1.EIP55Address), GasEstimator: toml.KeySpecificGasEstimator{PriceMax: gasLanePriceWei}, })(c, s) - c.EVM[0].GasEstimator.LimitDefault = ptr[uint32](3_500_000) + c.EVM[0].GasEstimator.LimitDefault = ptr[uint64](3_500_000) c.EVM[0].MinIncomingConfirmations = ptr[uint32](2) }) ownerKey := cltest.MustGenerateRandomKey(t) @@ -1253,7 +1253,7 @@ func TestVRFV2Integration_Wrapper_High_Gas(t *testing.T) { Key: ptr(key1.EIP55Address), GasEstimator: toml.KeySpecificGasEstimator{PriceMax: gasLanePriceWei}, })(c, s) - c.EVM[0].GasEstimator.LimitDefault = ptr[uint32](3_500_000) + c.EVM[0].GasEstimator.LimitDefault = ptr[uint64](3_500_000) c.EVM[0].MinIncomingConfirmations = ptr[uint32](2) c.Feature.LogPoller = ptr(true) c.EVM[0].LogPollInterval = commonconfig.MustNewDuration(1 * time.Second) @@ -1492,7 +1492,7 @@ func simulatedOverrides(t *testing.T, defaultGasPrice *assets.Wei, ks ...toml.Ke if defaultGasPrice != nil { c.EVM[0].GasEstimator.PriceDefault = defaultGasPrice } - c.EVM[0].GasEstimator.LimitDefault = ptr[uint32](3_500_000) + c.EVM[0].GasEstimator.LimitDefault = ptr[uint64](3_500_000) c.Feature.LogPoller = ptr(true) c.EVM[0].LogPollInterval = commonconfig.MustNewDuration(1 * time.Second) @@ -2178,7 +2178,7 @@ func TestStartingCountsV1(t *testing.T) { BroadcastBeforeBlockNum: &broadcastBlock, State: txmgrtypes.TxAttemptBroadcast, CreatedAt: time.Now(), - ChainSpecificFeeLimit: uint32(100), + ChainSpecificFeeLimit: uint64(100), }) } // add tx attempt for unconfirmed @@ -2190,7 +2190,7 @@ func TestStartingCountsV1(t *testing.T) { Hash: evmutils.NewHash(), State: txmgrtypes.TxAttemptInProgress, CreatedAt: time.Now(), - ChainSpecificFeeLimit: uint32(100), + ChainSpecificFeeLimit: uint64(100), }) } for _, txAttempt := range txAttempts { diff --git a/core/services/vrf/v2/listener_v2.go b/core/services/vrf/v2/listener_v2.go index cb87921e86b..71c6e72a06f 100644 --- a/core/services/vrf/v2/listener_v2.go +++ b/core/services/vrf/v2/listener_v2.go @@ -170,11 +170,11 @@ func (lsn *listenerV2) Start(ctx context.Context) error { gasLimit := lsn.feeCfg.LimitDefault() vrfLimit := lsn.feeCfg.LimitJobType().VRF() if vrfLimit != nil { - gasLimit = *vrfLimit + gasLimit = uint64(*vrfLimit) } if err != nil { lsn.l.Criticalw("Error getting coordinator config for gas limit check, starting anyway.", "err", err) - } else if conf.MaxGasLimit()+(GasProofVerification*2) > gasLimit { + } else if uint64(conf.MaxGasLimit()+(GasProofVerification*2)) > gasLimit { lsn.l.Criticalw("Node gas limit setting may not be high enough to fulfill all requests; it should be increased. Starting anyway.", "currentGasLimit", gasLimit, "neededGasLimit", conf.MaxGasLimit()+(GasProofVerification*2), diff --git a/core/services/vrf/v2/listener_v2_log_processor.go b/core/services/vrf/v2/listener_v2_log_processor.go index 7f61dd4cf3e..db84fb47e3e 100644 --- a/core/services/vrf/v2/listener_v2_log_processor.go +++ b/core/services/vrf/v2/listener_v2_log_processor.go @@ -591,8 +591,8 @@ func (lsn *listenerV2) enqueueForceFulfillment( lsn.l.Infow("Estimated gas limit on force fulfillment", "estimateGasLimit", estimateGasLimit, "pipelineGasLimit", p.gasLimit) - if estimateGasLimit < uint64(p.gasLimit) { - estimateGasLimit = uint64(p.gasLimit) + if estimateGasLimit < p.gasLimit { + estimateGasLimit = p.gasLimit } requestID := common.BytesToHash(p.req.req.RequestID().Bytes()) @@ -602,7 +602,7 @@ func (lsn *listenerV2) enqueueForceFulfillment( FromAddress: fromAddress, ToAddress: lsn.vrfOwner.Address(), EncodedPayload: txData, - FeeLimit: uint32(estimateGasLimit), + FeeLimit: estimateGasLimit, Strategy: txmgrcommon.NewSendEveryStrategy(), Meta: &txmgr.TxMeta{ RequestID: &requestID, @@ -1205,7 +1205,7 @@ func (lsn *listenerV2) simulateFulfillment( } if trr.Task.Type() == pipeline.TaskTypeEstimateGasLimit { - res.gasLimit = trr.Result.Value.(uint32) + res.gasLimit = trr.Result.Value.(uint64) } } return res diff --git a/core/services/vrf/v2/listener_v2_types.go b/core/services/vrf/v2/listener_v2_types.go index b3cbbff4713..f10297f31a9 100644 --- a/core/services/vrf/v2/listener_v2_types.go +++ b/core/services/vrf/v2/listener_v2_types.go @@ -72,7 +72,7 @@ type vrfPipelineResult struct { fundsNeeded *big.Int run *pipeline.Run payload string - gasLimit uint32 + gasLimit uint64 req pendingRequest proof VRFProof reqCommitment RequestCommitment @@ -83,7 +83,7 @@ type vrfPipelineResult struct { type batchFulfillment struct { proofs []VRFProof commitments []RequestCommitment - totalGasLimit uint32 + totalGasLimit uint64 runs []*pipeline.Run reqIDs []*big.Int maxFees []*big.Int @@ -144,7 +144,7 @@ func (b *batchFulfillments) addRun(result vrfPipelineResult, fromAddress common. b.fulfillments = append(b.fulfillments, newBatchFulfillment(result, fromAddress, b.version)) } else { currBatch := b.fulfillments[b.currIndex] - if (currBatch.totalGasLimit + result.gasLimit) >= b.batchGasLimit { + if (currBatch.totalGasLimit + result.gasLimit) >= uint64(b.batchGasLimit) { // don't add to curr batch, add new batch and increment index b.fulfillments = append(b.fulfillments, newBatchFulfillment(result, fromAddress, b.version)) b.currIndex++ @@ -240,7 +240,7 @@ func (lsn *listenerV2) processBatch( FromAddress: fromAddress, ToAddress: lsn.batchCoordinator.Address(), EncodedPayload: payload, - FeeLimit: totalGasLimitBumped, + FeeLimit: uint64(totalGasLimitBumped), Strategy: txmgrcommon.NewSendEveryStrategy(), Meta: &txmgr.TxMeta{ RequestIDs: reqIDHashes, diff --git a/core/services/vrf/v2/listener_v2_types_test.go b/core/services/vrf/v2/listener_v2_types_test.go index c66270210b9..3ca76fb70d2 100644 --- a/core/services/vrf/v2/listener_v2_types_test.go +++ b/core/services/vrf/v2/listener_v2_types_test.go @@ -35,7 +35,7 @@ func Test_BatchFulfillments_AddRun(t *testing.T) { require.Len(t, bfs.fulfillments, 1) } - require.Equal(t, uint32(2000), bfs.fulfillments[0].totalGasLimit) + require.Equal(t, uint64(2000), bfs.fulfillments[0].totalGasLimit) // This addition should create and add a new batch bfs.addRun(vrfPipelineResult{ @@ -73,7 +73,7 @@ func Test_BatchFulfillments_AddRun_V2Plus(t *testing.T) { require.Len(t, bfs.fulfillments, 1) } - require.Equal(t, uint32(2000), bfs.fulfillments[0].totalGasLimit) + require.Equal(t, uint64(2000), bfs.fulfillments[0].totalGasLimit) // This addition should create and add a new batch bfs.addRun(vrfPipelineResult{ diff --git a/core/services/vrf/v2/reverted_txns.go b/core/services/vrf/v2/reverted_txns.go index be20738a8f5..d2f62fbf271 100644 --- a/core/services/vrf/v2/reverted_txns.go +++ b/core/services/vrf/v2/reverted_txns.go @@ -707,7 +707,7 @@ func (lsn *listenerV2) enqueueForceFulfillmentForRevertedTxn( FromAddress: fromAddress, ToAddress: lsn.vrfOwner.Address(), EncodedPayload: txData, - FeeLimit: uint32(estimateGasLimit), + FeeLimit: estimateGasLimit, Strategy: txmgrcommon.NewSendEveryStrategy(), Meta: &txmgr.TxMeta{ RequestID: &reqID, diff --git a/core/services/vrf/vrfcommon/types.go b/core/services/vrf/vrfcommon/types.go index 06988633e8e..a27fcd5beb8 100644 --- a/core/services/vrf/vrfcommon/types.go +++ b/core/services/vrf/vrfcommon/types.go @@ -22,7 +22,7 @@ type Config interface { //go:generate mockery --quiet --name FeeConfig --output ../mocks/ --case=underscore type FeeConfig interface { - LimitDefault() uint32 + LimitDefault() uint64 LimitJobType() config.LimitJobType PriceMaxKey(addr common.Address) *assets.Wei } diff --git a/core/web/eth_keys_controller_test.go b/core/web/eth_keys_controller_test.go index 545abefcd3e..94d92849887 100644 --- a/core/web/eth_keys_controller_test.go +++ b/core/web/eth_keys_controller_test.go @@ -409,7 +409,7 @@ func TestETHKeysController_ChainSuccess_ResetWithAbandon(t *testing.T) { FromAddress: addr, ToAddress: testutils.NewAddress(), EncodedPayload: []byte{1, 2, 3}, - FeeLimit: uint32(1000), + FeeLimit: uint64(1000), Meta: nil, Strategy: strategy, }) diff --git a/core/web/evm_transfer_controller.go b/core/web/evm_transfer_controller.go index 4a1bf46feea..26f199ed961 100644 --- a/core/web/evm_transfer_controller.go +++ b/core/web/evm_transfer_controller.go @@ -113,7 +113,7 @@ func ValidateEthBalanceForTransfer(c *gin.Context, chain legacyevm.Chain, fromAd return errors.Errorf("balance is too low for this transaction to be executed: %v", balance) } - gasLimit := chain.Config().EVM().GasEstimator().LimitTransfer() + gasLimit := uint64(chain.Config().EVM().GasEstimator().LimitTransfer()) estimator := chain.GasEstimator() amountWithFees, err := estimator.GetMaxCost(c, amount, nil, gasLimit, chain.Config().EVM().GasEstimator().PriceMaxKey(fromAddr)) diff --git a/core/web/presenters/eth_tx.go b/core/web/presenters/eth_tx.go index 65df01ef095..e1ba3664a8f 100644 --- a/core/web/presenters/eth_tx.go +++ b/core/web/presenters/eth_tx.go @@ -43,7 +43,7 @@ func NewEthTxResource(tx txmgr.Tx) EthTxResource { r := EthTxResource{ Data: hexutil.Bytes(tx.EncodedPayload), From: &tx.FromAddress, - GasLimit: strconv.FormatUint(uint64(tx.FeeLimit), 10), + GasLimit: strconv.FormatUint(tx.FeeLimit, 10), State: string(tx.State), To: &tx.ToAddress, Value: v.String(), diff --git a/core/web/presenters/eth_tx_test.go b/core/web/presenters/eth_tx_test.go index 193fa774ce9..3bcdab5edfb 100644 --- a/core/web/presenters/eth_tx_test.go +++ b/core/web/presenters/eth_tx_test.go @@ -26,7 +26,7 @@ func TestEthTxResource(t *testing.T) { EncodedPayload: []byte(`{"data": "is wilding out"}`), FromAddress: common.HexToAddress("0x1"), ToAddress: common.HexToAddress("0x2"), - FeeLimit: uint32(5000), + FeeLimit: uint64(5000), ChainID: chainID, State: txmgrcommon.TxConfirmed, Value: big.Int(assets.NewEthValue(1)), diff --git a/docs/CONFIG.md b/docs/CONFIG.md index 938c3de66b1..c91f7d0e23c 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -3058,7 +3058,91 @@ Mode = 'BlockHistory' PriceDefault = '20 gwei' PriceMax = '18.446744073709551615 ether' PriceMin = '0' -LimitDefault = 3500000 +LimitDefault = 100000000 +LimitMax = 500000 +LimitMultiplier = '1' +LimitTransfer = 21000 +BumpMin = '5 gwei' +BumpPercent = 20 +BumpThreshold = 3 +EIP1559DynamicFees = false +FeeCapDefault = '100 gwei' +TipCapDefault = '1 wei' +TipCapMin = '1 wei' + +[GasEstimator.BlockHistory] +BatchSize = 25 +BlockHistorySize = 8 +CheckInclusionBlocks = 12 +CheckInclusionPercentile = 90 +TransactionPercentile = 60 + +[HeadTracker] +HistoryDepth = 5 +MaxBufferSize = 3 +SamplingInterval = '1s' + +[NodePool] +PollFailureThreshold = 5 +PollInterval = '10s' +SelectionMode = 'HighestHead' +SyncThreshold = 5 +LeaseDuration = '0s' +NodeIsSyncingEnabled = false + +[OCR] +ContractConfirmations = 4 +ContractTransmitterTransmitTimeout = '10s' +DatabaseTimeout = '10s' +DeltaCOverride = '168h0m0s' +DeltaCJitterOverride = '1h0m0s' +ObservationGracePeriod = '1s' + +[OCR2] +[OCR2.Automation] +GasLimit = 5400000 +``` + +

+ +
zkSync Sepolia (300)

+ +```toml +AutoCreateKey = true +BlockBackfillDepth = 10 +BlockBackfillSkip = false +ChainType = 'zksync' +FinalityDepth = 1 +FinalityTagEnabled = false +LogBackfillBatchSize = 1000 +LogPollInterval = '5s' +LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 +BackupLogPollerBlockDelay = 100 +MinIncomingConfirmations = 1 +MinContractPayment = '0.00001 link' +NonceAutoSync = true +NoNewHeadsThreshold = '1m0s' +RPCDefaultBatchSize = 250 +RPCBlockQueryDelay = 1 + +[Transactions] +ForwardersEnabled = false +MaxInFlight = 16 +MaxQueued = 250 +ReaperInterval = '1h0m0s' +ReaperThreshold = '168h0m0s' +ResendAfterThreshold = '1m0s' + +[BalanceMonitor] +Enabled = true + +[GasEstimator] +Mode = 'BlockHistory' +PriceDefault = '20 gwei' +PriceMax = '18.446744073709551615 ether' +PriceMin = '0' +LimitDefault = 100000000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 @@ -3142,7 +3226,7 @@ Mode = 'BlockHistory' PriceDefault = '20 gwei' PriceMax = '18.446744073709551615 ether' PriceMin = '0' -LimitDefault = 3500000 +LimitDefault = 100000000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 diff --git a/integration-tests/README.md b/integration-tests/README.md index 1ea3609f11e..80154a6dd13 100644 --- a/integration-tests/README.md +++ b/integration-tests/README.md @@ -14,9 +14,9 @@ If you have previously run these smoke tests using GitHub Actions or some sort o ## Configure -We have finished first pass at moving the configuration from env vars to TOML files. Currently all product-related configuration is already in TOML files, but env vars still are used to control things like log level, Slack notifications and Kubernetes-related settings. See the [example.env](./example.env) file for environment variables. +We have finished the first pass at moving all test configuration from env vars to TOML files. All product-related configuration is already in TOML files, but env vars are still used to control the log level, Slack notifications, and Kubernetes-related settings. See the [example.env](./example.env) file for how to set these environment variables. -We have added what we think are sensible defaults for all products, you can find them in `./testconfig//.toml` files. Each product folder contains also an `example.toml` file with all possible TOML keys and some description. Detailed description of TOML configuration can be found in [README.md](./testconfig/README.md), but if you want to run some tests using default value all you need to do is provide Chainlink image and version: +We have defined some sensible defaults for all products, you can find them in `./testconfig//.toml` files. Each product folder contains an `example.toml` file that describes all options. If you wish to override these values, you can do so by creating a `./testconfig/overrides.toml`. A detailed description of TOML configuration can be found in the [testconfig README](./testconfig/README.md), but if you want to run some tests using default values all you need to do is provide the Chainlink image and version you want to run tests on: ```toml # ./testconfig/overrides.toml @@ -25,15 +25,7 @@ image = "your image name" version = "your tag" ``` -You could also think about that config this way: -```toml -# ./testconfig/overrides.toml -[ChainlinkImage] -image = "${CHAINLINK_IMAGE}" -version = "${CHAINLINK_VERSION}" -``` - -Of course above just and example, in real world no substitution will take place unless you use some templating tool, but it should give you an idea on how to move from env vars to TOML files. **Remember** your runtime configuration needs to be placed in `./testconfig/overrides.toml` file **that should never be committed**. +The `./testconfig/overrides.toml` file **should never be committed** and has been added to the [.gitignore](../.gitignore) file as it can often contain secrets like private keys and RPC URLs. ## Build @@ -47,7 +39,7 @@ e.g. ## Run -Make sure you have `./testconfig/overrides.toml` file with your Chainlink image and version. +Ensure you have created a `./testconfig/overrides.toml` file with your desired Chainlink image and version. `go test ./smoke/_test.go` diff --git a/integration-tests/types/config/node/core.go b/integration-tests/types/config/node/core.go index 3508f77555f..024a05f63e4 100644 --- a/integration-tests/types/config/node/core.go +++ b/integration-tests/types/config/node/core.go @@ -188,7 +188,7 @@ func WithPrivateEVMs(networks []blockchain.EVMNetwork) NodeConfigOpt { HistoryDepth: ptr.Ptr(uint32(100)), }, GasEstimator: evmcfg.GasEstimator{ - LimitDefault: ptr.Ptr(uint32(6000000)), + LimitDefault: ptr.Ptr(uint64(6000000)), PriceMax: assets.GWei(200), FeeCapDefault: assets.GWei(200), }, @@ -223,7 +223,7 @@ func WithVRFv2EVMEstimator(addresses []string, maxGasPriceGWei int64) NodeConfig return func(c *chainlink.Config) { c.EVM[0].KeySpecific = keySpecicifArr c.EVM[0].Chain.GasEstimator = evmcfg.GasEstimator{ - LimitDefault: ptr.Ptr[uint32](3500000), + LimitDefault: ptr.Ptr[uint64](3500000), } c.EVM[0].Chain.Transactions = evmcfg.Transactions{ MaxQueued: ptr.Ptr[uint32](10000),