From 5ea40b1247bb4bce37961a601aaa553c7cdfb08f Mon Sep 17 00:00:00 2001 From: lei shi Date: Thu, 27 Jun 2024 13:40:30 -0700 Subject: [PATCH 1/2] support native token --- .changeset/shaggy-bananas-do.md | 5 + integration-tests/actions/actions.go | 2 +- .../actions/automation_ocr_helpers.go | 15 ++- .../actions/automationv2/actions.go | 11 +- integration-tests/actions/keeper_helpers.go | 113 +++++++++++------- .../chaos/automation_chaos_test.go | 4 +- .../ethereum_contracts_automation.go | 83 +++++++++++++ .../contracts/ethereum_keeper_contracts.go | 2 + .../reorg/automation_reorg_test.go | 2 + integration-tests/smoke/automation_test.go | 28 ++++- .../smoke/automation_test.go_test_list.json | 7 +- integration-tests/smoke/log_poller_test.go | 2 + .../testsetups/keeper_benchmark.go | 2 +- 13 files changed, 214 insertions(+), 62 deletions(-) create mode 100644 .changeset/shaggy-bananas-do.md diff --git a/.changeset/shaggy-bananas-do.md b/.changeset/shaggy-bananas-do.md new file mode 100644 index 00000000000..b4b8b00e372 --- /dev/null +++ b/.changeset/shaggy-bananas-do.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +add native billing in smoke test #added diff --git a/integration-tests/actions/actions.go b/integration-tests/actions/actions.go index bdca411c1d8..2763141a899 100644 --- a/integration-tests/actions/actions.go +++ b/integration-tests/actions/actions.go @@ -5,6 +5,7 @@ import ( "context" "crypto/ecdsa" "fmt" + "math" "math/big" "strings" "sync" @@ -40,7 +41,6 @@ import ( gethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/pkg/errors" "github.com/test-go/testify/require" - "math" ctfconfig "github.com/smartcontractkit/chainlink-testing-framework/config" "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" diff --git a/integration-tests/actions/automation_ocr_helpers.go b/integration-tests/actions/automation_ocr_helpers.go index 22220af9d63..9aa96040250 100644 --- a/integration-tests/actions/automation_ocr_helpers.go +++ b/integration-tests/actions/automation_ocr_helpers.go @@ -274,9 +274,12 @@ func DeployAutoOCRRegistryAndRegistrar( // DeployConsumers deploys and registers keeper consumers. If ephemeral addresses are enabled, it will deploy and register the consumers from ephemeral addresses, but each upkpeep will be registered with root key address as the admin. Which means // that functions like setting upkeep configuration, pausing, unpausing, etc. will be done by the root key address. It deploys multicall contract and sends link funds to each deployment address. -func DeployConsumers(t *testing.T, chainClient *seth.Client, registry contracts.KeeperRegistry, registrar contracts.KeeperRegistrar, linkToken contracts.LinkToken, numberOfUpkeeps int, linkFundsForEachUpkeep *big.Int, upkeepGasLimit uint32, isLogTrigger bool, isMercury bool) ([]contracts.KeeperConsumer, []*big.Int) { - err := DeployMultiCallAndFundDeploymentAddresses(chainClient, linkToken, numberOfUpkeeps, linkFundsForEachUpkeep) - require.NoError(t, err, "Sending link funds to deployment addresses shouldn't fail") +func DeployConsumers(t *testing.T, chainClient *seth.Client, registry contracts.KeeperRegistry, registrar contracts.KeeperRegistrar, linkToken contracts.LinkToken, numberOfUpkeeps int, linkFundsForEachUpkeep *big.Int, upkeepGasLimit uint32, isLogTrigger bool, isMercury bool, isBillingTokenNative bool, wethToken contracts.WETHToken) ([]contracts.KeeperConsumer, []*big.Int) { + // Fund deployers with LINK, no need to do this for Native token + if !isBillingTokenNative { + err := DeployMultiCallAndFundDeploymentAddresses(chainClient, linkToken, numberOfUpkeeps, linkFundsForEachUpkeep) + require.NoError(t, err, "Sending link funds to deployment addresses shouldn't fail") + } upkeeps := DeployKeeperConsumers(t, chainClient, numberOfUpkeeps, isLogTrigger, isMercury) require.Equal(t, numberOfUpkeeps, len(upkeeps), "Number of upkeeps should match") @@ -285,7 +288,7 @@ func DeployConsumers(t *testing.T, chainClient *seth.Client, registry contracts. upkeepsAddresses = append(upkeepsAddresses, upkeep.Address()) } upkeepIds := RegisterUpkeepContracts( - t, chainClient, linkToken, linkFundsForEachUpkeep, upkeepGasLimit, registry, registrar, numberOfUpkeeps, upkeepsAddresses, isLogTrigger, isMercury, + t, chainClient, linkToken, linkFundsForEachUpkeep, upkeepGasLimit, registry, registrar, numberOfUpkeeps, upkeepsAddresses, isLogTrigger, isMercury, isBillingTokenNative, wethToken, ) require.Equal(t, numberOfUpkeeps, len(upkeepIds), "Number of upkeepIds should match") return upkeeps, upkeepIds @@ -318,7 +321,7 @@ func DeployPerformanceConsumers( for _, upkeep := range upkeeps { upkeepsAddresses = append(upkeepsAddresses, upkeep.Address()) } - upkeepIds := RegisterUpkeepContracts(t, chainClient, linkToken, linkFundsForEachUpkeep, upkeepGasLimit, registry, registrar, numberOfUpkeeps, upkeepsAddresses, false, false) + upkeepIds := RegisterUpkeepContracts(t, chainClient, linkToken, linkFundsForEachUpkeep, upkeepGasLimit, registry, registrar, numberOfUpkeeps, upkeepsAddresses, false, false, false, nil) return upkeeps, upkeepIds } @@ -344,7 +347,7 @@ func DeployPerformDataCheckerConsumers( for _, upkeep := range upkeeps { upkeepsAddresses = append(upkeepsAddresses, upkeep.Address()) } - upkeepIds := RegisterUpkeepContracts(t, chainClient, linkToken, linkFundsForEachUpkeep, upkeepGasLimit, registry, registrar, numberOfUpkeeps, upkeepsAddresses, false, false) + upkeepIds := RegisterUpkeepContracts(t, chainClient, linkToken, linkFundsForEachUpkeep, upkeepGasLimit, registry, registrar, numberOfUpkeeps, upkeepsAddresses, false, false, false, nil) return upkeeps, upkeepIds } diff --git a/integration-tests/actions/automationv2/actions.go b/integration-tests/actions/automationv2/actions.go index 1ed4bef1414..f7d495bda5a 100644 --- a/integration-tests/actions/automationv2/actions.go +++ b/integration-tests/actions/automationv2/actions.go @@ -565,7 +565,8 @@ func (a *AutomationTest) SetConfigOnRegistry() error { } else if a.RegistrySettings.RegistryVersion == ethereum.RegistryVersion_2_3 { ocrConfig.TypedOnchainConfig23 = a.RegistrySettings.Create23OnchainConfig(a.Registrar.Address(), a.UpkeepPrivilegeManager, a.Registry.ChainModuleAddress(), a.Registry.ReorgProtectionEnabled()) ocrConfig.BillingTokens = []common.Address{ - common.HexToAddress(a.LinkToken.Address()), // TODO add more billing tokens + common.HexToAddress(a.LinkToken.Address()), + common.HexToAddress(a.WETHToken.Address()), } ocrConfig.BillingConfigs = []i_automation_registry_master_wrapper_2_3.AutomationRegistryBase23BillingConfig{ @@ -577,6 +578,14 @@ func (a *AutomationTest) SetConfigOnRegistry() error { FallbackPrice: big.NewInt(1000), MinSpend: big.NewInt(200), }, + { + GasFeePPB: 100, + FlatFeeMilliCents: big.NewInt(500), + PriceFeed: common.HexToAddress(a.EthUSDFeed.Address()), // ETH/USD feed and LINK/USD feed are the same + Decimals: 18, + FallbackPrice: big.NewInt(1000), + MinSpend: big.NewInt(200), + }, } } err = a.Registry.SetConfigTypeSafe(ocrConfig) diff --git a/integration-tests/actions/keeper_helpers.go b/integration-tests/actions/keeper_helpers.go index 7f02f54c751..ee1662cc180 100644 --- a/integration-tests/actions/keeper_helpers.go +++ b/integration-tests/actions/keeper_helpers.go @@ -8,6 +8,7 @@ import ( "strconv" "testing" + "github.com/ethereum/go-ethereum/core/types" "github.com/google/uuid" "github.com/pkg/errors" "github.com/smartcontractkit/seth" @@ -115,7 +116,7 @@ func DeployKeeperContracts( } registrar := DeployKeeperRegistrar(t, client, registryVersion, linkToken, registrarSettings, registry) - upkeeps, upkeepIds := DeployConsumers(t, client, registry, registrar, linkToken, numberOfUpkeeps, linkFundsForEachUpkeep, upkeepGasLimit, false, false) + upkeeps, upkeepIds := DeployConsumers(t, client, registry, registrar, linkToken, numberOfUpkeeps, linkFundsForEachUpkeep, upkeepGasLimit, false, false, false, nil) return registry, registrar, upkeeps, upkeepIds } @@ -178,7 +179,7 @@ func DeployPerformanceKeeperContracts( upkeepsAddresses = append(upkeepsAddresses, upkeep.Address()) } - upkeepIds := RegisterUpkeepContracts(t, chainClient, linkToken, linkFundsForEachUpkeep, upkeepGasLimit, registry, registrar, numberOfContracts, upkeepsAddresses, false, false) + upkeepIds := RegisterUpkeepContracts(t, chainClient, linkToken, linkFundsForEachUpkeep, upkeepGasLimit, registry, registrar, numberOfContracts, upkeepsAddresses, false, false, false, nil) return registry, registrar, upkeeps, upkeepIds } @@ -236,7 +237,7 @@ func DeployPerformDataCheckerContracts( upkeepsAddresses = append(upkeepsAddresses, upkeep.Address()) } - upkeepIds := RegisterUpkeepContracts(t, chainClient, linkToken, linkFundsForEachUpkeep, upkeepGasLimit, registry, registrar, numberOfContracts, upkeepsAddresses, false, false) + upkeepIds := RegisterUpkeepContracts(t, chainClient, linkToken, linkFundsForEachUpkeep, upkeepGasLimit, registry, registrar, numberOfContracts, upkeepsAddresses, false, false, false, nil) return registry, registrar, upkeeps, upkeepIds } @@ -259,14 +260,14 @@ func DeployKeeperRegistrar( return registrar } -func RegisterUpkeepContracts(t *testing.T, client *seth.Client, linkToken contracts.LinkToken, linkFunds *big.Int, upkeepGasLimit uint32, registry contracts.KeeperRegistry, registrar contracts.KeeperRegistrar, numberOfContracts int, upkeepAddresses []string, isLogTrigger bool, isMercury bool) []*big.Int { +func RegisterUpkeepContracts(t *testing.T, client *seth.Client, linkToken contracts.LinkToken, fundsForEachUpkeep *big.Int, upkeepGasLimit uint32, registry contracts.KeeperRegistry, registrar contracts.KeeperRegistrar, numberOfContracts int, upkeepAddresses []string, isLogTrigger bool, isMercury bool, isBillingTokenNative bool, wethToken contracts.WETHToken) []*big.Int { checkData := make([][]byte, 0) for i := 0; i < numberOfContracts; i++ { checkData = append(checkData, []byte("0")) } return RegisterUpkeepContractsWithCheckData( - t, client, linkToken, linkFunds, upkeepGasLimit, registry, registrar, - numberOfContracts, upkeepAddresses, checkData, isLogTrigger, isMercury) + t, client, linkToken, fundsForEachUpkeep, upkeepGasLimit, registry, registrar, + numberOfContracts, upkeepAddresses, checkData, isLogTrigger, isMercury, isBillingTokenNative, wethToken) } type upkeepRegistrationResult struct { @@ -284,7 +285,7 @@ type upkeepConfig struct { type UpkeepId = *big.Int -func RegisterUpkeepContractsWithCheckData(t *testing.T, client *seth.Client, linkToken contracts.LinkToken, linkFunds *big.Int, upkeepGasLimit uint32, registry contracts.KeeperRegistry, registrar contracts.KeeperRegistrar, numberOfContracts int, upkeepAddresses []string, checkData [][]byte, isLogTrigger bool, isMercury bool) []*big.Int { +func RegisterUpkeepContractsWithCheckData(t *testing.T, client *seth.Client, linkToken contracts.LinkToken, fundsForEachUpkeep *big.Int, upkeepGasLimit uint32, registry contracts.KeeperRegistry, registrar contracts.KeeperRegistrar, numberOfContracts int, upkeepAddresses []string, checkData [][]byte, isLogTrigger bool, isMercury bool, isBillingTokenNative bool, wethToken contracts.WETHToken) []*big.Int { l := logging.GetTestLogger(t) concurrency, err := GetAndAssertCorrectConcurrency(client, 1) @@ -300,45 +301,69 @@ func RegisterUpkeepContractsWithCheckData(t *testing.T, client *seth.Client, lin var registerUpkeepFn = func(resultCh chan upkeepRegistrationResult, errorCh chan error, executorNum int, config upkeepConfig) { id := uuid.New().String() keyNum := executorNum + 1 // key 0 is the root key + var tx *types.Transaction + + if isBillingTokenNative { + // register upkeep with native token + tx, err = registrar.RegisterUpkeepFromKey( + keyNum, + fmt.Sprintf("upkeep_%s", id), + []byte("test@mail.com"), + config.address, + upkeepGasLimit, + client.MustGetRootKeyAddress().Hex(), // upkeep Admin + config.data, + fundsForEachUpkeep, + wethToken.Address(), + isLogTrigger, + isMercury, + ) + if err != nil { + errorCh <- errors.Wrapf(err, "[id: %s] Failed to register upkeep at %s", id, config.address) + return + } + } else { + // register upkeep with LINK + req, err := registrar.EncodeRegisterRequest( + fmt.Sprintf("upkeep_%s", id), + []byte("test@mail.com"), + config.address, + upkeepGasLimit, + client.MustGetRootKeyAddress().Hex(), // upkeep Admin + config.data, + fundsForEachUpkeep, + 0, + client.Addresses[keyNum].Hex(), + isLogTrigger, + isMercury, + linkToken.Address(), + ) + + if err != nil { + errorCh <- errors.Wrapf(err, "[id: %s] Failed to encode register request for upkeep at %s", id, config.address) + return + } - req, err := registrar.EncodeRegisterRequest( - fmt.Sprintf("upkeep_%s", id), - []byte("test@mail.com"), - config.address, - upkeepGasLimit, - client.MustGetRootKeyAddress().Hex(), // upkeep Admin - config.data, - linkFunds, - 0, - client.Addresses[keyNum].Hex(), - isLogTrigger, - isMercury, - linkToken.Address(), - ) - - if err != nil { - errorCh <- errors.Wrapf(err, "[id: %s] Failed to encode register request for upkeep at %s", id, config.address) - return - } - - balance, err := linkToken.BalanceOf(context.Background(), client.Addresses[keyNum].Hex()) - if err != nil { - errorCh <- errors.Wrapf(err, "[id: %s]Failed to get LINK balance of %s", id, client.Addresses[keyNum].Hex()) - return - } + balance, err := linkToken.BalanceOf(context.Background(), client.Addresses[keyNum].Hex()) + if err != nil { + errorCh <- errors.Wrapf(err, "[id: %s]Failed to get LINK balance of %s", id, client.Addresses[keyNum].Hex()) + return + } - // not stricly necessary, but helps us to avoid an errorless revert if there is not enough LINK - if balance.Cmp(linkFunds) < 0 { - errorCh <- fmt.Errorf("[id: %s] Not enough LINK balance for %s. Has: %s. Needs: %s", id, client.Addresses[keyNum].Hex(), balance.String(), linkFunds.String()) - return - } + // not strictly necessary, but helps us to avoid an errorless revert if there is not enough LINK + if balance.Cmp(fundsForEachUpkeep) < 0 { + errorCh <- fmt.Errorf("[id: %s] Not enough LINK balance for %s. Has: %s. Needs: %s", id, client.Addresses[keyNum].Hex(), balance.String(), fundsForEachUpkeep.String()) + return + } - tx, err := linkToken.TransferAndCallFromKey(registrar.Address(), linkFunds, req, keyNum) - if err != nil { - errorCh <- errors.Wrapf(err, "[id: %s] Failed to register upkeep at %s", id, config.address) - return + tx, err = linkToken.TransferAndCallFromKey(registrar.Address(), fundsForEachUpkeep, req, keyNum) + if err != nil { + errorCh <- errors.Wrapf(err, "[id: %s] Failed to register upkeep at %s", id, config.address) + return + } } + // parse txn to get upkeep ID receipt, err := client.Client.TransactionReceipt(context.Background(), tx.Hash()) if err != nil { errorCh <- errors.Wrapf(err, "[id: %s] Failed to get receipt for upkeep at %s and tx hash %s", id, config.address, tx.Hash()) @@ -405,10 +430,10 @@ func DeployKeeperConsumers(t *testing.T, client *seth.Client, numberOfContracts // v2.1 only: Conditional based contract with Mercury enabled keeperConsumerInstance, err = contracts.DeployAutomationStreamsLookupUpkeepConsumerFromKey(client, keyNum, big.NewInt(1000), big.NewInt(5), false, true, false) // 1000 block test range } else if isLogTrigger { - // v2.1 only: Log triggered based contract without Mercury + // v2.1+: Log triggered based contract without Mercury keeperConsumerInstance, err = contracts.DeployAutomationLogTriggerConsumerFromKey(client, keyNum, big.NewInt(1000)) // 1000 block test range } else { - // v2.0 and v2.1: Conditional based contract without Mercury + // v2.0+: Conditional based contract without Mercury keeperConsumerInstance, err = contracts.DeployUpkeepCounterFromKey(client, keyNum, big.NewInt(999999), big.NewInt(5)) } @@ -580,7 +605,7 @@ func RegisterNewUpkeeps( err = SendLinkFundsToDeploymentAddresses(chainClient, concurrency, numberOfNewUpkeeps, operationsPerAddress, multicallAddress, linkFundsForEachUpkeep, linkToken) require.NoError(t, err, "Sending link funds to deployment addresses shouldn't fail") - newUpkeepIDs := RegisterUpkeepContracts(t, chainClient, linkToken, linkFundsForEachUpkeep, upkeepGasLimit, registry, registrar, numberOfNewUpkeeps, addressesOfNewUpkeeps, false, false) + newUpkeepIDs := RegisterUpkeepContracts(t, chainClient, linkToken, linkFundsForEachUpkeep, upkeepGasLimit, registry, registrar, numberOfNewUpkeeps, addressesOfNewUpkeeps, false, false, false, nil) return newlyDeployedUpkeeps, newUpkeepIDs } diff --git a/integration-tests/chaos/automation_chaos_test.go b/integration-tests/chaos/automation_chaos_test.go index d091522c2cf..e14c35ed17b 100644 --- a/integration-tests/chaos/automation_chaos_test.go +++ b/integration-tests/chaos/automation_chaos_test.go @@ -286,8 +286,8 @@ func TestAutomationChaos(t *testing.T) { } require.NoError(t, err, "Error setting OCR config") - consumersConditional, upkeepidsConditional := actions.DeployConsumers(t, chainClient, registry, registrar, linkToken, numberOfUpkeeps, big.NewInt(defaultLinkFunds), defaultUpkeepGasLimit, false, false) - consumersLogtrigger, upkeepidsLogtrigger := actions.DeployConsumers(t, chainClient, registry, registrar, linkToken, numberOfUpkeeps, big.NewInt(defaultLinkFunds), defaultUpkeepGasLimit, true, false) + consumersConditional, upkeepidsConditional := actions.DeployConsumers(t, chainClient, registry, registrar, linkToken, numberOfUpkeeps, big.NewInt(defaultLinkFunds), defaultUpkeepGasLimit, false, false, false, nil) + consumersLogtrigger, upkeepidsLogtrigger := actions.DeployConsumers(t, chainClient, registry, registrar, linkToken, numberOfUpkeeps, big.NewInt(defaultLinkFunds), defaultUpkeepGasLimit, true, false, false, nil) consumers := append(consumersConditional, consumersLogtrigger...) upkeepIDs := append(upkeepidsConditional, upkeepidsLogtrigger...) diff --git a/integration-tests/contracts/ethereum_contracts_automation.go b/integration-tests/contracts/ethereum_contracts_automation.go index c2c7576e0f0..bd0e1aafc82 100644 --- a/integration-tests/contracts/ethereum_contracts_automation.go +++ b/integration-tests/contracts/ethereum_contracts_automation.go @@ -1799,6 +1799,87 @@ func (v *EthereumKeeperRegistrar) Fund(_ *big.Float) error { panic("do not use this function, use actions.SendFunds instead") } +// register Upkeep with native token, only available from v2.3 +func (v *EthereumKeeperRegistrar) RegisterUpkeepFromKey(keyNum int, name string, email []byte, upkeepAddr string, gasLimit uint32, adminAddr string, checkData []byte, amount *big.Int, wethTokenAddr string, isLogTrigger bool, isMercury bool) (*types.Transaction, error) { + if v.registrar23 == nil { + return nil, fmt.Errorf("RegisterUpkeepFromKey with native token is only supported in registrar version v2.3") + } + + registrarABI = cltypes.MustGetABI(registrar23.AutomationRegistrarABI) + txOpts := v.client.NewTXKeyOpts(keyNum, seth.WithValue(amount)) + + if isLogTrigger { + var topic0InBytes [32]byte + // bytes representation of 0x0000000000000000000000000000000000000000000000000000000000000000 + bytes0 := [32]byte{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + } + if isMercury { + // bytes representation of 0xd1ffe9e45581c11d7d9f2ed5f75217cd4be9f8b7eee6af0f6d03f46de53956cd + topic0InBytes = [32]byte{209, 255, 233, 228, 85, 129, 193, 29, 125, 159, 46, 213, 247, 82, 23, 205, 75, 233, 248, 183, 238, 230, 175, 15, 109, 3, 244, 109, 229, 57, 86, 205} + } else { + // bytes representation of 0x3d53a39550e04688065827f3bb86584cb007ab9ebca7ebd528e7301c9c31eb5d + topic0InBytes = [32]byte{ + 61, 83, 163, 149, 80, 224, 70, 136, + 6, 88, 39, 243, 187, 134, 88, 76, + 176, 7, 171, 158, 188, 167, 235, + 213, 40, 231, 48, 28, 156, 49, 235, 93, + } + } + + logTriggerConfigStruct := acutils.IAutomationV21PlusCommonLogTriggerConfig{ + ContractAddress: common.HexToAddress(upkeepAddr), + FilterSelector: 0, + Topic0: topic0InBytes, + Topic1: bytes0, + Topic2: bytes0, + Topic3: bytes0, + } + encodedLogTriggerConfig, err := compatibleUtils.Methods["_logTriggerConfig"].Inputs.Pack(&logTriggerConfigStruct) + if err != nil { + return nil, err + } + + params := registrar23.AutomationRegistrar23RegistrationParams{ + UpkeepContract: common.HexToAddress(upkeepAddr), + Amount: amount, + AdminAddress: common.HexToAddress(adminAddr), + GasLimit: gasLimit, + TriggerType: uint8(1), // trigger type + BillingToken: common.HexToAddress(wethTokenAddr), // native + Name: name, + EncryptedEmail: email, + CheckData: checkData, + TriggerConfig: encodedLogTriggerConfig, // log trigger upkeep + OffchainConfig: []byte{}, + } + + decodedTx, err := v.client.Decode(v.registrar23.RegisterUpkeep(txOpts, + params, + )) + return decodedTx.Transaction, err + } + + params := registrar23.AutomationRegistrar23RegistrationParams{ + UpkeepContract: common.HexToAddress(upkeepAddr), + Amount: amount, + AdminAddress: common.HexToAddress(adminAddr), + GasLimit: gasLimit, + TriggerType: uint8(0), // trigger type + BillingToken: common.HexToAddress(wethTokenAddr), // native + Name: name, + EncryptedEmail: email, + CheckData: checkData, + TriggerConfig: []byte{}, // conditional upkeep + OffchainConfig: []byte{}, + } + + decodedTx, err := v.client.Decode(v.registrar23.RegisterUpkeep(txOpts, + params, + )) + return decodedTx.Transaction, err +} + // EncodeRegisterRequest encodes register request to call it through link token TransferAndCall func (v *EthereumKeeperRegistrar) EncodeRegisterRequest(name string, email []byte, upkeepAddr string, gasLimit uint32, adminAddr string, checkData []byte, amount *big.Int, source uint8, senderAddr string, isLogTrigger bool, isMercury bool, linkTokenAddr string) ([]byte, error) { if v.registrar20 != nil { @@ -2056,9 +2137,11 @@ func DeployKeeperRegistrar(client *seth.Client, registryVersion eth_contracts.Ke billingTokens := []common.Address{ common.HexToAddress(linkAddr), + common.HexToAddress(registrarSettings.WETHTokenAddr), } minRegistrationFees := []*big.Int{ big.NewInt(10), + big.NewInt(10), } data, err := client.DeployContract(client.NewTXOpts(), "KeeperRegistrar2_3", *abi, common.FromHex(registrar23.AutomationRegistrarMetaData.Bin), diff --git a/integration-tests/contracts/ethereum_keeper_contracts.go b/integration-tests/contracts/ethereum_keeper_contracts.go index 84543627d49..34c78b3fc60 100644 --- a/integration-tests/contracts/ethereum_keeper_contracts.go +++ b/integration-tests/contracts/ethereum_keeper_contracts.go @@ -27,6 +27,8 @@ type KeeperRegistrar interface { EncodeRegisterRequest(name string, email []byte, upkeepAddr string, gasLimit uint32, adminAddr string, checkData []byte, amount *big.Int, source uint8, senderAddr string, isLogTrigger bool, isMercury bool, linkTokenAddr string) ([]byte, error) Fund(ethAmount *big.Float) error + + RegisterUpkeepFromKey(keyNum int, name string, email []byte, upkeepAddr string, gasLimit uint32, adminAddr string, checkData []byte, amount *big.Int, wethTokenAddr string, isLogTrigger bool, isMercury bool) (*types.Transaction, error) } type UpkeepTranscoder interface { diff --git a/integration-tests/reorg/automation_reorg_test.go b/integration-tests/reorg/automation_reorg_test.go index 5a18bb17c9b..2a2350e1956 100644 --- a/integration-tests/reorg/automation_reorg_test.go +++ b/integration-tests/reorg/automation_reorg_test.go @@ -229,6 +229,8 @@ func TestAutomationReorg(t *testing.T) { defaultUpkeepGasLimit, isLogTrigger, false, + false, + nil, ) if isLogTrigger { diff --git a/integration-tests/smoke/automation_test.go b/integration-tests/smoke/automation_test.go index 20240351c5d..0f9040d94ed 100644 --- a/integration-tests/smoke/automation_test.go +++ b/integration-tests/smoke/automation_test.go @@ -110,7 +110,10 @@ func SetupAutomationBasic(t *testing.T, nodeUpgrade bool) { "registry_2_2_with_mercury_v02": ethereum.RegistryVersion_2_2, "registry_2_2_with_mercury_v03": ethereum.RegistryVersion_2_2, "registry_2_2_with_logtrigger_and_mercury_v02": ethereum.RegistryVersion_2_2, - "registry_2_3_conditional": ethereum.RegistryVersion_2_3, + "registry_2_3_conditional_native": ethereum.RegistryVersion_2_3, + "registry_2_3_conditional_link": ethereum.RegistryVersion_2_3, + "registry_2_3_logtrigger_native": ethereum.RegistryVersion_2_3, + "registry_2_3_logtrigger_link": ethereum.RegistryVersion_2_3, } for n, rv := range registryVersions { @@ -129,8 +132,9 @@ func SetupAutomationBasic(t *testing.T, nodeUpgrade bool) { } } - // Use the name to determine if this is a log trigger or mercury - isLogTrigger := name == "registry_2_1_logtrigger" || name == "registry_2_1_with_logtrigger_and_mercury_v02" || name == "registry_2_2_logtrigger" || name == "registry_2_2_with_logtrigger_and_mercury_v02" + // Use the name to determine if this is a log trigger or mercury or billing token is LINK + isBillingTokenNative := name == "registry_2_3_conditional_native" || name == "registry_2_3_logtrigger_native" + isLogTrigger := name == "registry_2_1_logtrigger" || name == "registry_2_1_with_logtrigger_and_mercury_v02" || name == "registry_2_2_logtrigger" || name == "registry_2_2_with_logtrigger_and_mercury_v02" || name == "registry_2_3_logtrigger_native" || name == "registry_2_3_logtrigger_link" isMercuryV02 := name == "registry_2_1_with_mercury_v02" || name == "registry_2_1_with_logtrigger_and_mercury_v02" || name == "registry_2_2_with_mercury_v02" || name == "registry_2_2_with_logtrigger_and_mercury_v02" isMercuryV03 := name == "registry_2_1_with_mercury_v03" || name == "registry_2_2_with_mercury_v03" isMercury := isMercuryV02 || isMercuryV03 @@ -153,6 +157,8 @@ func SetupAutomationBasic(t *testing.T, nodeUpgrade bool) { automationDefaultUpkeepGasLimit, isLogTrigger, isMercury, + isBillingTokenNative, + a.WETHToken, ) // Do it in two separate loops, so we don't end up setting up one upkeep, but starting the consumer for another one @@ -189,8 +195,6 @@ func SetupAutomationBasic(t *testing.T, nodeUpgrade bool) { actions.GetStalenessReportCleanupFn(t, a.Logger, a.ChainClient, sb, a.Registry, registryVersion)() }) - // TODO Tune this timeout window after stress testing - l.Info().Msg("Waiting 10m for all upkeeps to perform at least 1 upkeep") gom.Eventually(func(g gomega.Gomega) { // Check if the upkeeps are performing multiple times by analyzing their counters for i := 0; i < len(upkeepIDs); i++ { @@ -292,6 +296,8 @@ func TestSetUpkeepTriggerConfig(t *testing.T) { automationDefaultUpkeepGasLimit, true, false, + false, + nil, ) // Start log trigger based upkeeps for all consumers @@ -473,6 +479,8 @@ func TestAutomationAddFunds(t *testing.T) { automationDefaultUpkeepGasLimit, false, false, + false, + nil, ) t.Cleanup(func() { @@ -551,6 +559,8 @@ func TestAutomationPauseUnPause(t *testing.T) { automationDefaultUpkeepGasLimit, false, false, + false, + nil, ) t.Cleanup(func() { @@ -650,6 +660,8 @@ func TestAutomationRegisterUpkeep(t *testing.T) { automationDefaultUpkeepGasLimit, false, false, + false, + nil, ) t.Cleanup(func() { @@ -744,6 +756,8 @@ func TestAutomationPauseRegistry(t *testing.T) { automationDefaultUpkeepGasLimit, false, false, + false, + nil, ) t.Cleanup(func() { @@ -822,6 +836,8 @@ func TestAutomationKeeperNodesDown(t *testing.T) { automationDefaultUpkeepGasLimit, false, false, + false, + nil, ) t.Cleanup(func() { @@ -1235,6 +1251,8 @@ func TestSetOffchainConfigWithMaxGasPrice(t *testing.T) { automationDefaultUpkeepGasLimit, false, false, + false, + nil, ) t.Cleanup(func() { diff --git a/integration-tests/smoke/automation_test.go_test_list.json b/integration-tests/smoke/automation_test.go_test_list.json index f0b8a1cb603..8245f31ca62 100644 --- a/integration-tests/smoke/automation_test.go_test_list.json +++ b/integration-tests/smoke/automation_test.go_test_list.json @@ -37,9 +37,12 @@ }, { "name": "TestAutomationBasic", - "nodes": 1, + "nodes": 4, "run":[ - {"name":"registry_2_3_conditional"} + {"name":"registry_2_3_conditional_native"}, + {"name":"registry_2_3_conditional_link"}, + {"name":"registry_2_3_logtrigger_native"}, + {"name":"registry_2_3_logtrigger_link"} ] }, { diff --git a/integration-tests/smoke/log_poller_test.go b/integration-tests/smoke/log_poller_test.go index d02daec2114..f1a257552a2 100644 --- a/integration-tests/smoke/log_poller_test.go +++ b/integration-tests/smoke/log_poller_test.go @@ -317,6 +317,8 @@ func prepareEnvironment(l zerolog.Logger, t *testing.T, testConfig *tc.TestConfi uint32(2500000), true, false, + false, + nil, ) err = logpoller.AssertUpkeepIdsUniqueness(upkeepIDs) diff --git a/integration-tests/testsetups/keeper_benchmark.go b/integration-tests/testsetups/keeper_benchmark.go index 81f2ce0edf4..d50355f39b6 100644 --- a/integration-tests/testsetups/keeper_benchmark.go +++ b/integration-tests/testsetups/keeper_benchmark.go @@ -801,7 +801,7 @@ func (k *KeeperBenchmarkTest) DeployBenchmarkKeeperContracts(index int) { err = actions.DeployMultiCallAndFundDeploymentAddresses(k.chainClient, k.linkToken, upkeep.NumberOfUpkeeps, linkFunds) require.NoError(k.t, err, "Sending link funds to deployment addresses shouldn't fail") - upkeepIds := actions.RegisterUpkeepContractsWithCheckData(k.t, k.chainClient, k.linkToken, linkFunds, uint32(upkeep.UpkeepGasLimit), registry, registrar, upkeep.NumberOfUpkeeps, upkeepAddresses, checkData, false, false) + upkeepIds := actions.RegisterUpkeepContractsWithCheckData(k.t, k.chainClient, k.linkToken, linkFunds, uint32(upkeep.UpkeepGasLimit), registry, registrar, upkeep.NumberOfUpkeeps, upkeepAddresses, checkData, false, false, false, nil) k.keeperRegistries[index] = registry k.keeperRegistrars[index] = registrar From c28c33f5944618822aac30ba4e8d4be02fa8501b Mon Sep 17 00:00:00 2001 From: lei shi Date: Fri, 28 Jun 2024 12:24:24 -0700 Subject: [PATCH 2/2] split the tests and add mercury related tests --- integration-tests/smoke/automation_test.go | 44 ++++++++++--------- .../smoke/automation_test.go_test_list.json | 18 +++++++- 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/integration-tests/smoke/automation_test.go b/integration-tests/smoke/automation_test.go index 0f9040d94ed..62462d641a8 100644 --- a/integration-tests/smoke/automation_test.go +++ b/integration-tests/smoke/automation_test.go @@ -8,6 +8,7 @@ import ( "net/http" "os" "strconv" + "strings" "testing" "time" @@ -98,22 +99,25 @@ func TestAutomationBasic(t *testing.T) { func SetupAutomationBasic(t *testing.T, nodeUpgrade bool) { t.Parallel() + // native, mercury_v02, mercury_v03 and logtrigger are reserved keywords, use them with caution registryVersions := map[string]ethereum.KeeperRegistryVersion{ - "registry_2_0": ethereum.RegistryVersion_2_0, - "registry_2_1_conditional": ethereum.RegistryVersion_2_1, - "registry_2_1_logtrigger": ethereum.RegistryVersion_2_1, - "registry_2_1_with_mercury_v02": ethereum.RegistryVersion_2_1, - "registry_2_1_with_mercury_v03": ethereum.RegistryVersion_2_1, - "registry_2_1_with_logtrigger_and_mercury_v02": ethereum.RegistryVersion_2_1, - "registry_2_2_conditional": ethereum.RegistryVersion_2_2, - "registry_2_2_logtrigger": ethereum.RegistryVersion_2_2, - "registry_2_2_with_mercury_v02": ethereum.RegistryVersion_2_2, - "registry_2_2_with_mercury_v03": ethereum.RegistryVersion_2_2, - "registry_2_2_with_logtrigger_and_mercury_v02": ethereum.RegistryVersion_2_2, - "registry_2_3_conditional_native": ethereum.RegistryVersion_2_3, - "registry_2_3_conditional_link": ethereum.RegistryVersion_2_3, - "registry_2_3_logtrigger_native": ethereum.RegistryVersion_2_3, - "registry_2_3_logtrigger_link": ethereum.RegistryVersion_2_3, + "registry_2_0": ethereum.RegistryVersion_2_0, + "registry_2_1_conditional": ethereum.RegistryVersion_2_1, + "registry_2_1_logtrigger": ethereum.RegistryVersion_2_1, + "registry_2_1_with_mercury_v02": ethereum.RegistryVersion_2_1, + "registry_2_1_with_mercury_v03": ethereum.RegistryVersion_2_1, + "registry_2_1_with_logtrigger_and_mercury_v02": ethereum.RegistryVersion_2_1, + "registry_2_2_conditional": ethereum.RegistryVersion_2_2, + "registry_2_2_logtrigger": ethereum.RegistryVersion_2_2, + "registry_2_2_with_mercury_v02": ethereum.RegistryVersion_2_2, + "registry_2_2_with_mercury_v03": ethereum.RegistryVersion_2_2, + "registry_2_2_with_logtrigger_and_mercury_v02": ethereum.RegistryVersion_2_2, + "registry_2_3_conditional_native": ethereum.RegistryVersion_2_3, + "registry_2_3_conditional_link": ethereum.RegistryVersion_2_3, + "registry_2_3_logtrigger_native": ethereum.RegistryVersion_2_3, + "registry_2_3_logtrigger_link": ethereum.RegistryVersion_2_3, + "registry_2_3_with_mercury_v03_link": ethereum.RegistryVersion_2_3, + "registry_2_3_with_logtrigger_and_mercury_v02_link": ethereum.RegistryVersion_2_3, } for n, rv := range registryVersions { @@ -132,11 +136,11 @@ func SetupAutomationBasic(t *testing.T, nodeUpgrade bool) { } } - // Use the name to determine if this is a log trigger or mercury or billing token is LINK - isBillingTokenNative := name == "registry_2_3_conditional_native" || name == "registry_2_3_logtrigger_native" - isLogTrigger := name == "registry_2_1_logtrigger" || name == "registry_2_1_with_logtrigger_and_mercury_v02" || name == "registry_2_2_logtrigger" || name == "registry_2_2_with_logtrigger_and_mercury_v02" || name == "registry_2_3_logtrigger_native" || name == "registry_2_3_logtrigger_link" - isMercuryV02 := name == "registry_2_1_with_mercury_v02" || name == "registry_2_1_with_logtrigger_and_mercury_v02" || name == "registry_2_2_with_mercury_v02" || name == "registry_2_2_with_logtrigger_and_mercury_v02" - isMercuryV03 := name == "registry_2_1_with_mercury_v03" || name == "registry_2_2_with_mercury_v03" + // Use the name to determine if this is a log trigger or mercury or billing token is native + isBillingTokenNative := strings.Contains(name, "native") + isLogTrigger := strings.Contains(name, "logtrigger") + isMercuryV02 := strings.Contains(name, "mercury_v02") + isMercuryV03 := strings.Contains(name, "mercury_v03") isMercury := isMercuryV02 || isMercuryV03 a := setupAutomationTestDocker( diff --git a/integration-tests/smoke/automation_test.go_test_list.json b/integration-tests/smoke/automation_test.go_test_list.json index 8245f31ca62..1b8477ca289 100644 --- a/integration-tests/smoke/automation_test.go_test_list.json +++ b/integration-tests/smoke/automation_test.go_test_list.json @@ -37,14 +37,28 @@ }, { "name": "TestAutomationBasic", - "nodes": 4, + "nodes": 2, "run":[ {"name":"registry_2_3_conditional_native"}, - {"name":"registry_2_3_conditional_link"}, + {"name":"registry_2_3_conditional_link"} + ] + }, + { + "name": "TestAutomationBasic", + "nodes": 2, + "run":[ {"name":"registry_2_3_logtrigger_native"}, {"name":"registry_2_3_logtrigger_link"} ] }, + { + "name": "TestAutomationBasic", + "nodes": 2, + "run":[ + {"name":"registry_2_3_with_mercury_v03_link"}, + {"name":"registry_2_3_with_logtrigger_and_mercury_v02_link"} + ] + }, { "name": "TestSetUpkeepTriggerConfig", "nodes": 2