Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add streams lookup load test (AUTO-9008) #12587

Merged
merged 16 commits into from
Mar 27, 2024
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
pragma solidity 0.8.6;

import {ILogAutomation, Log} from "../interfaces/ILogAutomation.sol";
import "../interfaces/StreamsLookupCompatibleInterface.sol";

struct CheckData {
uint256 checkBurnAmount;
uint256 performBurnAmount;
bytes32 eventSig;
string[] feeds;
}

contract SimpleLogUpkeepCounter is ILogAutomation {
contract SimpleLogUpkeepCounter is ILogAutomation, StreamsLookupCompatibleInterface {
event PerformingUpkeep(
address indexed from,
uint256 initialBlock,
Expand All @@ -27,36 +29,77 @@ contract SimpleLogUpkeepCounter is ILogAutomation {
uint256 public initialBlock;
uint256 public counter;
uint256 public timeToPerform;
bool public isRecovered;
bool internal isRecovered;
bool public isStreamsLookup;
bool public shouldRetryOnError;
string public feedParamKey = "feedIDs";
string public timeParamKey = "timestamp";

constructor() {
constructor(bool _isStreamsLookup) {
previousPerformBlock = 0;
lastBlock = block.number;
initialBlock = 0;
counter = 0;
isStreamsLookup = _isStreamsLookup;
}

function _checkDataConfig(CheckData memory) external {}

function setTimeParamKey(string memory timeParam) external {
timeParamKey = timeParam;
}

function setFeedParamKey(string memory feedParam) external {
feedParamKey = feedParam;
}

function setShouldRetryOnErrorBool(bool value) public {
shouldRetryOnError = value;
}

function checkLog(Log calldata log, bytes calldata checkData) external view override returns (bool, bytes memory) {
(uint256 checkBurnAmount, uint256 performBurnAmount, bytes32 eventSig) = abi.decode(
checkData,
(uint256, uint256, bytes32)
);
CheckData memory _checkData = abi.decode(checkData, (CheckData));
uint256 startGas = gasleft();
bytes32 dummyIndex = blockhash(block.number - 1);
bool dummy;
// burn gas
if (checkBurnAmount > 0) {
while (startGas - gasleft() < checkBurnAmount) {
if (_checkData.checkBurnAmount > 0) {
while (startGas - gasleft() < _checkData.checkBurnAmount) {
dummy = dummy && dummyMap[dummyIndex]; // arbitrary storage reads
dummyIndex = keccak256(abi.encode(dummyIndex, address(this)));
}
}
if (log.topics[2] == eventSig) {
return (true, abi.encode(log, block.number, checkData));
bytes[] memory values = new bytes[](2);
values[0] = abi.encode(0x00);
values[1] = abi.encode(0x00);
bytes memory extraData = abi.encode(log, block.number, checkData);
if (log.topics[2] == _checkData.eventSig) {
if (isStreamsLookup) {
revert StreamsLookup(feedParamKey, _checkData.feeds, timeParamKey, block.timestamp, extraData);
}
return (true, abi.encode(values, extraData));
}
return (false, abi.encode(log, block.number, checkData));
return (false, abi.encode(values, extraData));
}

function checkCallback(
bytes[] memory values,
bytes memory extraData
) external view override returns (bool, bytes memory) {
// do sth about the chainlinkBlob data in values and extraData
bytes memory performData = abi.encode(values, extraData);
return (true, performData);
}

function checkErrorHandler(
uint256 errCode,
bytes memory extraData
) external view override returns (bool upkeepNeeded, bytes memory performData) {
bytes[] memory values = new bytes[](2);
values[0] = abi.encode(errCode);
values[1] = abi.encode(extraData);
bytes memory returnData = abi.encode(values, extraData);
return (shouldRetryOnError, returnData);
}

function performUpkeep(bytes calldata performData) external override {
Expand All @@ -66,22 +109,23 @@ contract SimpleLogUpkeepCounter is ILogAutomation {
lastBlock = block.number;
counter = counter + 1;
previousPerformBlock = lastBlock;
(Log memory log, uint256 checkBlock, bytes memory extraData) = abi.decode(performData, (Log, uint256, bytes));
(, bytes memory extraData) = abi.decode(performData, (bytes[], bytes));
(Log memory log, uint256 checkBlock, bytes memory checkData) = abi.decode(extraData, (Log, uint256, bytes));
timeToPerform = block.timestamp - log.timestamp;
isRecovered = false;
if (checkBlock != log.blockNumber) {
isRecovered = true;
}
(uint256 checkBurnAmount, uint256 performBurnAmount, bytes32 eventSig) = abi.decode(
extraData,
(uint256, uint256, bytes32)
);
CheckData memory _checkData = abi.decode(checkData, (CheckData));
uint256 startGas = gasleft();
bytes32 dummyIndex = blockhash(block.number - 1);
bool dummy;
if (log.topics[2] != _checkData.eventSig) {
revert("Invalid event signature");
}
// burn gas
if (performBurnAmount > 0) {
while (startGas - gasleft() < performBurnAmount) {
if (_checkData.performBurnAmount > 0) {
while (startGas - gasleft() < _checkData.performBurnAmount) {
dummy = dummy && dummyMap[dummyIndex]; // arbitrary storage reads
dummyIndex = keccak256(abi.encode(dummyIndex, address(this)));
}
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ optimism_module: ../../contracts/solc/v0.8.19/OptimismModule/OptimismModule.abi
oracle_wrapper: ../../contracts/solc/v0.6/Oracle/Oracle.abi ../../contracts/solc/v0.6/Oracle/Oracle.bin 7af2fbac22a6e8c2847e8e685a5400cac5101d72ddf5365213beb79e4dede43a
perform_data_checker_wrapper: ../../contracts/solc/v0.8.16/PerformDataChecker/PerformDataChecker.abi ../../contracts/solc/v0.8.16/PerformDataChecker/PerformDataChecker.bin 48d8309c2117c29a24e1155917ab0b780956b2cd6a8a39ef06ae66a7f6d94f73
scroll_module: ../../contracts/solc/v0.8.19/ScrollModule/ScrollModule.abi ../../contracts/solc/v0.8.19/ScrollModule/ScrollModule.bin 8de157cb7e5bc78146548212803d60926c8483aca7e912d802b7c66dc5d2ab11
simple_log_upkeep_counter_wrapper: ../../contracts/solc/v0.8.6/SimpleLogUpkeepCounter/SimpleLogUpkeepCounter.abi ../../contracts/solc/v0.8.6/SimpleLogUpkeepCounter/SimpleLogUpkeepCounter.bin a2532ca73e227f846be39b52fa63cfa9d088116c3cfc311d972fe8db886fa915
simple_log_upkeep_counter_wrapper: ../../contracts/solc/v0.8.6/SimpleLogUpkeepCounter/SimpleLogUpkeepCounter.abi ../../contracts/solc/v0.8.6/SimpleLogUpkeepCounter/SimpleLogUpkeepCounter.bin 7557d117a066cd8cf35f635bc085ee11795442073c18f8610ede9037b74fd814
solidity_vrf_consumer_interface: ../../contracts/solc/v0.6/VRFConsumer/VRFConsumer.abi ../../contracts/solc/v0.6/VRFConsumer/VRFConsumer.bin ecc99378aa798014de9db42b2eb81320778b0663dbe208008dad75ccdc1d4366
solidity_vrf_consumer_interface_v08: ../../contracts/solc/v0.8.6/VRFConsumer/VRFConsumer.abi ../../contracts/solc/v0.8.6/VRFConsumer/VRFConsumer.bin b14f9136b15e3dc9d6154d5700f3ed4cf88ddc4f70f20c3bb57fc46050904c8f
solidity_vrf_coordinator_interface: ../../contracts/solc/v0.6/VRFCoordinator/VRFCoordinator.abi ../../contracts/solc/v0.6/VRFCoordinator/VRFCoordinator.bin a23d3c395156804788c7f6fbda2994e8f7184304c0f0c9f2c4ddeaf073d346d2
Expand Down
1 change: 1 addition & 0 deletions integration-tests/benchmark/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ func TestAutomationBenchmark(t *testing.T) {
FallbackLinkPrice: big.NewInt(2e18),
MaxCheckDataSize: uint32(5_000),
MaxPerformDataSize: uint32(5_000),
MaxRevertDataSize: uint32(5_000),
},
Upkeeps: &testsetups.UpkeepConfig{
NumberOfUpkeeps: *config.Keeper.Common.NumberOfUpkeeps,
Expand Down
1 change: 1 addition & 0 deletions integration-tests/chaos/automation_chaos_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ ListenAddresses = ["0.0.0.0:6690"]`
FallbackLinkPrice: big.NewInt(2e18),
MaxCheckDataSize: uint32(5000),
MaxPerformDataSize: uint32(5000),
MaxRevertDataSize: uint32(5000),
}
)

Expand Down
6 changes: 3 additions & 3 deletions integration-tests/contracts/contract_deployer.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ type ContractDeployer interface {
LoadKeeperRegistry(address common.Address, registryVersion eth_contracts.KeeperRegistryVersion) (KeeperRegistry, error)
DeployKeeperConsumer(updateInterval *big.Int) (KeeperConsumer, error)
DeployAutomationLogTriggerConsumer(testInterval *big.Int) (KeeperConsumer, error)
DeployAutomationSimpleLogTriggerConsumer() (KeeperConsumer, error)
DeployAutomationSimpleLogTriggerConsumer(isStreamsLookup bool) (KeeperConsumer, error)
DeployAutomationStreamsLookupUpkeepConsumer(testRange *big.Int, interval *big.Int, useArbBlock bool, staging bool, verify bool) (KeeperConsumer, error)
DeployAutomationLogTriggeredStreamsLookupUpkeepConsumer() (KeeperConsumer, error)
DeployKeeperConsumerPerformance(
Expand Down Expand Up @@ -1517,13 +1517,13 @@ func (e *EthereumContractDeployer) DeployAutomationLogTriggerConsumer(testInterv
}, err
}

func (e *EthereumContractDeployer) DeployAutomationSimpleLogTriggerConsumer() (KeeperConsumer, error) {
func (e *EthereumContractDeployer) DeployAutomationSimpleLogTriggerConsumer(isStreamsLookup bool) (KeeperConsumer, error) {
address, _, instance, err := e.client.DeployContract("SimpleLogUpkeepCounter", func(
auth *bind.TransactOpts,
backend bind.ContractBackend,
) (common.Address, *types.Transaction, interface{}, error) {
return simple_log_upkeep_counter_wrapper.DeploySimpleLogUpkeepCounter(
auth, backend,
auth, backend, isStreamsLookup,
)
})
if err != nil {
Expand Down
5 changes: 3 additions & 2 deletions integration-tests/contracts/ethereum_keeper_contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ type KeeperRegistrySettings struct {
FallbackLinkPrice *big.Int // LINK price used if the LINK price feed is stale
MaxCheckDataSize uint32
MaxPerformDataSize uint32
MaxRevertDataSize uint32
RegistryVersion ethereum.KeeperRegistryVersion
}

Expand Down Expand Up @@ -258,7 +259,7 @@ func (rcs *KeeperRegistrySettings) Create22OnchainConfig(registrar string, regis
MaxPerformGas: rcs.MaxPerformGas,
MaxCheckDataSize: rcs.MaxCheckDataSize,
MaxPerformDataSize: rcs.MaxPerformDataSize,
MaxRevertDataSize: uint32(1000),
MaxRevertDataSize: rcs.MaxRevertDataSize,
FallbackGasPrice: rcs.FallbackGasPrice,
FallbackLinkPrice: rcs.FallbackLinkPrice,
Transcoder: common.Address{},
Expand All @@ -280,7 +281,7 @@ func (rcs *KeeperRegistrySettings) Create21OnchainConfig(registrar string, regis
MaxPerformGas: rcs.MaxPerformGas,
MaxCheckDataSize: rcs.MaxCheckDataSize,
MaxPerformDataSize: rcs.MaxPerformDataSize,
MaxRevertDataSize: uint32(1000),
MaxRevertDataSize: rcs.MaxRevertDataSize,
FallbackGasPrice: rcs.FallbackGasPrice,
FallbackLinkPrice: rcs.FallbackLinkPrice,
Transcoder: common.Address{},
Expand Down
46 changes: 39 additions & 7 deletions integration-tests/load/automationv2_1/automationv2_1_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package automationv2_1

import (
"context"
"encoding/hex"
"fmt"
"math"
"math/big"
Expand Down Expand Up @@ -62,6 +63,11 @@ Enabled = true
Enabled = true
AnnounceAddresses = ["0.0.0.0:6690"]
ListenAddresses = ["0.0.0.0:6690"]`
secretsTOML = `[Mercury.Credentials.%s]
LegacyURL = '%s'
URL = '%s'
Username = '%s'
Password = '%s'`

minimumNodeSpec = map[string]interface{}{
"resources": map[string]interface{}{
Expand Down Expand Up @@ -177,6 +183,7 @@ Load Config:
FallbackLinkPrice: big.NewInt(2e18),
MaxCheckDataSize: uint32(5_000),
MaxPerformDataSize: uint32(5_000),
MaxRevertDataSize: uint32(5_000),
RegistryVersion: contractseth.RegistryVersion_2_1,
}

Expand Down Expand Up @@ -235,6 +242,16 @@ Load Config:
loadedTestConfig.Pyroscope.Environment = &testEnvironment.Cfg.Namespace
}

if *loadedTestConfig.Automation.DataStreams.Enabled {
secretsTOML = fmt.Sprintf(
secretsTOML, "cred1",
*loadedTestConfig.Automation.DataStreams.URL, *loadedTestConfig.Automation.DataStreams.URL,
*loadedTestConfig.Automation.DataStreams.Username, *loadedTestConfig.Automation.DataStreams.Password,
)
} else {
secretsTOML = ""
}

numberOfUpkeeps := *loadedTestConfig.Automation.General.NumberOfNodes

for i := 0; i < numberOfUpkeeps+1; i++ { // +1 for the OCR boot node
Expand All @@ -252,10 +269,11 @@ Load Config:
}

cd := chainlink.NewWithOverride(i, map[string]any{
"toml": nodeTOML,
"chainlink": nodeSpec,
"db": dbSpec,
"prometheus": *loadedTestConfig.Automation.General.UsePrometheus,
"toml": nodeTOML,
"chainlink": nodeSpec,
"db": dbSpec,
"prometheus": *loadedTestConfig.Automation.General.UsePrometheus,
"secretsToml": secretsTOML,
}, loadedTestConfig.ChainlinkImage, overrideFn)

testEnvironment.AddHelm(cd)
Expand Down Expand Up @@ -310,6 +328,10 @@ Load Config:
F: 1,
}

if *loadedTestConfig.Automation.DataStreams.Enabled {
a.MercuryCredentialName = "cred1"
}

startTimeTestSetup := time.Now()
l.Info().Str("START_TIME", startTimeTestSetup.String()).Msg("Test setup started")

Expand Down Expand Up @@ -344,7 +366,7 @@ Load Config:

for _, u := range loadedTestConfig.Automation.Load {
for i := 0; i < *u.NumberOfUpkeeps; i++ {
consumerContract, err := contractDeployer.DeployAutomationSimpleLogTriggerConsumer()
consumerContract, err := contractDeployer.DeployAutomationSimpleLogTriggerConsumer(*u.IsStreamsLookup)
require.NoError(t, err, "Error deploying automation consumer contract")
consumerContracts = append(consumerContracts, consumerContract)
l.Debug().
Expand All @@ -361,6 +383,11 @@ Load Config:
PerformBurnAmount: u.PerformBurnAmount,
UpkeepGasLimit: u.UpkeepGasLimit,
SharedTrigger: u.SharedTrigger,
Feeds: []string{},
}

if *u.IsStreamsLookup {
loadCfg.Feeds = u.Feeds
}

loadConfigs = append(loadConfigs, loadCfg)
Expand Down Expand Up @@ -394,17 +421,22 @@ Load Config:
}
encodedLogTriggerConfig, err := convenienceABI.Methods["_logTriggerConfig"].Inputs.Pack(&logTriggerConfigStruct)
require.NoError(t, err, "Error encoding log trigger config")
l.Debug().Bytes("Encoded Log Trigger Config", encodedLogTriggerConfig).Msg("Encoded Log Trigger Config")
l.Debug().
Interface("logTriggerConfigStruct", logTriggerConfigStruct).
Str("Encoded Log Trigger Config", hex.EncodeToString(encodedLogTriggerConfig)).Msg("Encoded Log Trigger Config")

checkDataStruct := simple_log_upkeep_counter_wrapper.CheckData{
CheckBurnAmount: loadConfigs[i].CheckBurnAmount,
PerformBurnAmount: loadConfigs[i].PerformBurnAmount,
EventSig: bytes1,
Feeds: loadConfigs[i].Feeds,
}

encodedCheckDataStruct, err := consumerABI.Methods["_checkDataConfig"].Inputs.Pack(&checkDataStruct)
require.NoError(t, err, "Error encoding check data struct")
l.Debug().Bytes("Encoded Check Data Struct", encodedCheckDataStruct).Msg("Encoded Check Data Struct")
l.Debug().
Interface("checkDataStruct", checkDataStruct).
Str("Encoded Check Data Struct", hex.EncodeToString(encodedCheckDataStruct)).Msg("Encoded Check Data Struct")

upkeepConfig := automationv2.UpkeepConfig{
UpkeepName: fmt.Sprintf("LogTriggerUpkeep-%d", i),
Expand Down
1 change: 1 addition & 0 deletions integration-tests/reorg/automation_reorg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ LimitDefault = 5_000_000`
FallbackLinkPrice: big.NewInt(2e18),
MaxCheckDataSize: uint32(5000),
MaxPerformDataSize: uint32(5000),
MaxRevertDataSize: uint32(5000),
}
)

Expand Down
1 change: 1 addition & 0 deletions integration-tests/smoke/automation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ var (
FallbackLinkPrice: big.NewInt(2e18),
MaxCheckDataSize: uint32(5000),
MaxPerformDataSize: uint32(5000),
MaxRevertDataSize: uint32(5000),
}
)

Expand Down
7 changes: 7 additions & 0 deletions integration-tests/testconfig/automation/automation.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ spec_type="minimum"
chainlink_node_log_level="info"
use_prometheus=false

[Load.Automation.DataStreams]
enabled=false

[[Load.Automation.Load]]
number_of_upkeeps=5
number_of_events = 1
Expand All @@ -34,6 +37,8 @@ check_burn_amount = 0
perform_burn_amount = 0
upkeep_gas_limit = 1000000
shared_trigger = false
is_streams_lookup = false
feeds = ["0x000200"]

[[Load.Automation.Load]]
number_of_upkeeps=5
Expand All @@ -44,6 +49,8 @@ check_burn_amount = 0
perform_burn_amount = 0
upkeep_gas_limit = 1000000
shared_trigger = true
is_streams_lookup = false
feeds = ["0x000200"]

[Load.Pyroscope]
enabled=false
Loading
Loading