From 97fbf5afb6d2d5312991aa8f246c2b1c45179de0 Mon Sep 17 00:00:00 2001 From: Matt Yang Date: Mon, 2 Oct 2023 17:19:28 -0400 Subject: [PATCH 01/24] multi gas price update in PriceUpdates struct --- contracts/src/v0.8/ccip/CommitStore.sol | 2 +- contracts/src/v0.8/ccip/PriceRegistry.sol | 16 +++--- .../v0.8/ccip/interfaces/IPriceRegistry.sol | 2 +- .../src/v0.8/ccip/libraries/Internal.sol | 8 ++- .../src/v0.8/ccip/test/StructFactory.sol | 9 ++-- .../test/priceRegistry/PriceRegistry.t.sol | 49 ++++++++++++------- .../src/v0.8/ccip/test/router/Router.t.sol | 5 +- docs/CHANGELOG_CCIP.md | 10 +++- 8 files changed, 65 insertions(+), 36 deletions(-) diff --git a/contracts/src/v0.8/ccip/CommitStore.sol b/contracts/src/v0.8/ccip/CommitStore.sol index bff308f2bf..64f6347b4d 100644 --- a/contracts/src/v0.8/ccip/CommitStore.sol +++ b/contracts/src/v0.8/ccip/CommitStore.sol @@ -184,7 +184,7 @@ contract CommitStore is ICommitStore, TypeAndVersionInterface, OCR2Base { CommitReport memory report = abi.decode(encodedReport, (CommitReport)); // Check if the report contains price updates - if (report.priceUpdates.tokenPriceUpdates.length > 0 || report.priceUpdates.destChainSelector != 0) { + if (report.priceUpdates.tokenPriceUpdates.length > 0 || report.priceUpdates.gasPriceUpdates.length > 0) { // Check for price staleness based on the epoch and round if (s_latestPriceEpochAndRound < epochAndRound) { // If prices are not stale, update the latest epoch and round diff --git a/contracts/src/v0.8/ccip/PriceRegistry.sol b/contracts/src/v0.8/ccip/PriceRegistry.sol index ec7089fc0d..d2cd1fe610 100644 --- a/contracts/src/v0.8/ccip/PriceRegistry.sol +++ b/contracts/src/v0.8/ccip/PriceRegistry.sol @@ -190,9 +190,9 @@ contract PriceRegistry is IPriceRegistry, OwnerIsCreator, TypeAndVersionInterfac // @inheritdoc IPriceRegistry function updatePrices(Internal.PriceUpdates calldata priceUpdates) external override requireUpdaterOrOwner { - uint256 priceUpdatesLength = priceUpdates.tokenPriceUpdates.length; + uint256 tokenUpdatesLength = priceUpdates.tokenPriceUpdates.length; - for (uint256 i = 0; i < priceUpdatesLength; ++i) { + for (uint256 i = 0; i < tokenUpdatesLength; ++i) { Internal.TokenPriceUpdate memory update = priceUpdates.tokenPriceUpdates[i]; s_usdPerToken[update.sourceToken] = Internal.TimestampedPackedUint224({ value: update.usdPerToken, @@ -201,12 +201,16 @@ contract PriceRegistry is IPriceRegistry, OwnerIsCreator, TypeAndVersionInterfac emit UsdPerTokenUpdated(update.sourceToken, update.usdPerToken, block.timestamp); } - if (priceUpdates.destChainSelector != 0) { - s_usdPerUnitGasByDestChainSelector[priceUpdates.destChainSelector] = Internal.TimestampedPackedUint224({ - value: priceUpdates.usdPerUnitGas, + uint256 gasUpdatesLength = priceUpdates.gasPriceUpdates.length; + + for (uint256 i = 0; i < gasUpdatesLength; ++i) { + Internal.GasPriceUpdate memory update = priceUpdates.gasPriceUpdates[i]; + s_usdPerUnitGasByDestChainSelector[update.destChainSelector] = Internal.TimestampedPackedUint224({ + value: update.usdPerUnitGas, timestamp: uint32(block.timestamp) }); - emit UsdPerUnitGasUpdated(priceUpdates.destChainSelector, priceUpdates.usdPerUnitGas, block.timestamp); + emit UsdPerUnitGasUpdated(update.destChainSelector, update.usdPerUnitGas, block.timestamp); + } } diff --git a/contracts/src/v0.8/ccip/interfaces/IPriceRegistry.sol b/contracts/src/v0.8/ccip/interfaces/IPriceRegistry.sol index 583d752d8d..952bc7a59a 100644 --- a/contracts/src/v0.8/ccip/interfaces/IPriceRegistry.sol +++ b/contracts/src/v0.8/ccip/interfaces/IPriceRegistry.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.0; import {Internal} from "../libraries/Internal.sol"; interface IPriceRegistry { - /// @notice Update the price for given tokens and destination chain. + /// @notice Update the price for given tokens and gas prices for given chains. /// @param priceUpdates The price updates to apply. function updatePrices(Internal.PriceUpdates memory priceUpdates) external; diff --git a/contracts/src/v0.8/ccip/libraries/Internal.sol b/contracts/src/v0.8/ccip/libraries/Internal.sol index 903069ac75..020089cc86 100644 --- a/contracts/src/v0.8/ccip/libraries/Internal.sol +++ b/contracts/src/v0.8/ccip/libraries/Internal.sol @@ -8,8 +8,7 @@ import {MerkleMultiProof} from "../libraries/MerkleMultiProof.sol"; library Internal { struct PriceUpdates { TokenPriceUpdate[] tokenPriceUpdates; - uint64 destChainSelector; // ──╮ Destination chain selector - uint224 usdPerUnitGas; // ─────╯ 1e18 USD per smallest unit (e.g. wei) of destination chain gas + GasPriceUpdate[] gasPriceUpdates; } struct TokenPriceUpdate { @@ -17,6 +16,11 @@ library Internal { uint224 usdPerToken; // 1e18 USD per smallest unit of token } + struct GasPriceUpdate { + uint64 destChainSelector; // ──╮ Destination chain selector + uint224 usdPerUnitGas; // ─────╯ 1e18 USD per smallest unit (e.g. wei) of destination chain gas + } + struct TimestampedPackedUint224 { uint224 value; // ───────╮ Value in uint224, packed. uint32 timestamp; // ────╯ Timestamp of the most recent price update. diff --git a/contracts/src/v0.8/ccip/test/StructFactory.sol b/contracts/src/v0.8/ccip/test/StructFactory.sol index 10d41a5308..1225c48db8 100644 --- a/contracts/src/v0.8/ccip/test/StructFactory.sol +++ b/contracts/src/v0.8/ccip/test/StructFactory.sol @@ -190,8 +190,7 @@ contract StructFactory { Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ tokenPriceUpdates: tokenPriceUpdates, - destChainSelector: 0, - usdPerUnitGas: 0 + gasPriceUpdates: new Internal.GasPriceUpdate[](0) }); return priceUpdates; @@ -209,8 +208,7 @@ contract StructFactory { } Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ tokenPriceUpdates: tokenPriceUpdates, - destChainSelector: 0, - usdPerUnitGas: 0 + gasPriceUpdates: new Internal.GasPriceUpdate[](0) }); return priceUpdates; @@ -221,8 +219,7 @@ contract StructFactory { return Internal.PriceUpdates({ tokenPriceUpdates: new Internal.TokenPriceUpdate[](0), - destChainSelector: 0, - usdPerUnitGas: 0 + gasPriceUpdates: new Internal.GasPriceUpdate[](0) }); } } diff --git a/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol b/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol index 995bf3e6e6..de79906504 100644 --- a/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol +++ b/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol @@ -69,8 +69,9 @@ contract PriceRegistrySetup is TokenSetup, RouterSetup { } Internal.PriceUpdates memory priceUpdates = getPriceUpdatesStruct(pricedTokens, tokenPrices); - priceUpdates.destChainSelector = DEST_CHAIN_ID; - priceUpdates.usdPerUnitGas = PACKED_USD_PER_GAS; + priceUpdates.gasPriceUpdates = new Internal.GasPriceUpdate[](1); + priceUpdates.gasPriceUpdates[0].destChainSelector = DEST_CHAIN_ID; + priceUpdates.gasPriceUpdates[0].usdPerUnitGas = PACKED_USD_PER_GAS; s_encodedInitialPriceUpdates = abi.encode(priceUpdates); address[] memory priceUpdaters = new address[](0); @@ -237,10 +238,13 @@ contract PriceRegistry_updatePrices is PriceRegistrySetup { Internal.TokenPriceUpdate[] memory tokenPriceUpdates = new Internal.TokenPriceUpdate[](2); tokenPriceUpdates[0] = Internal.TokenPriceUpdate({sourceToken: s_sourceTokens[0], usdPerToken: 4e18}); tokenPriceUpdates[1] = Internal.TokenPriceUpdate({sourceToken: s_sourceTokens[1], usdPerToken: 1800e18}); + + Internal.GasPriceUpdate[] memory gasPriceUpdates = new Internal.GasPriceUpdate[](1); + gasPriceUpdates[0] = Internal.GasPriceUpdate({destChainSelector: DEST_CHAIN_ID, usdPerUnitGas: 2e6}); + Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ tokenPriceUpdates: tokenPriceUpdates, - destChainSelector: DEST_CHAIN_ID, - usdPerUnitGas: 2e6 + gasPriceUpdates: gasPriceUpdates }); s_encodedNewPriceUpdates = abi.encode(priceUpdates); } @@ -251,7 +255,7 @@ contract PriceRegistry_updatePrices is PriceRegistrySetup { assertEq(s_priceRegistry.getTokenPrice(s_sourceTokens[0]).value, priceUpdates.tokenPriceUpdates[0].usdPerToken); assertEq(s_priceRegistry.getTokenPrice(s_sourceTokens[1]).value, priceUpdates.tokenPriceUpdates[1].usdPerToken); - assertEq(s_priceRegistry.getDestinationChainGasPrice(DEST_CHAIN_ID).value, priceUpdates.usdPerUnitGas); + assertEq(s_priceRegistry.getDestinationChainGasPrice(DEST_CHAIN_ID).value, priceUpdates.gasPriceUpdates[0].usdPerUnitGas); } // Reverts @@ -297,10 +301,13 @@ contract PriceRegistry_convertTokenAmount is PriceRegistrySetup { Internal.TokenPriceUpdate[] memory tokenPriceUpdates = new Internal.TokenPriceUpdate[](2); tokenPriceUpdates[0] = Internal.TokenPriceUpdate({sourceToken: feeToken, usdPerToken: usdPerFeeToken}); tokenPriceUpdates[1] = Internal.TokenPriceUpdate({sourceToken: linkToken, usdPerToken: usdPerLinkToken}); + + Internal.GasPriceUpdate[] memory gasPriceUpdates = new Internal.GasPriceUpdate[](1); + gasPriceUpdates[0] = Internal.GasPriceUpdate({destChainSelector: DEST_CHAIN_ID, usdPerUnitGas: usdPerUnitGas}); + Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ tokenPriceUpdates: tokenPriceUpdates, - destChainSelector: DEST_CHAIN_ID, - usdPerUnitGas: usdPerUnitGas + gasPriceUpdates: gasPriceUpdates }); s_priceRegistry.updatePrices(priceUpdates); @@ -318,8 +325,7 @@ contract PriceRegistry_convertTokenAmount is PriceRegistrySetup { tokenPriceUpdates[0] = Internal.TokenPriceUpdate({sourceToken: s_sourceTokens[0], usdPerToken: 4e18}); Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ tokenPriceUpdates: tokenPriceUpdates, - destChainSelector: 0, - usdPerUnitGas: 0 + gasPriceUpdates: new Internal.GasPriceUpdate[](0) }); s_priceRegistry.updatePrices(priceUpdates); @@ -349,8 +355,7 @@ contract PriceRegistry_convertTokenAmount is PriceRegistrySetup { tokenPriceUpdates[0] = Internal.TokenPriceUpdate({sourceToken: s_weth, usdPerToken: 18e17}); Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ tokenPriceUpdates: tokenPriceUpdates, - destChainSelector: 0, - usdPerUnitGas: 0 + gasPriceUpdates: new Internal.GasPriceUpdate[](0) }); s_priceRegistry.updatePrices(priceUpdates); @@ -373,21 +378,26 @@ contract PriceRegistry_getTokenAndGasPrices is PriceRegistrySetup { Internal.PriceUpdates memory priceUpdates = abi.decode(s_encodedInitialPriceUpdates, (Internal.PriceUpdates)); assertEq(feeTokenPrice, s_sourceTokenPrices[0]); - assertEq(gasPrice, priceUpdates.usdPerUnitGas); + assertEq(gasPrice, priceUpdates.gasPriceUpdates[0].usdPerUnitGas); } function testZeroGasPriceSuccess() public { uint64 zeroGasDestChainSelector = 345678; - Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ - tokenPriceUpdates: new Internal.TokenPriceUpdate[](0), + Internal.GasPriceUpdate[] memory gasPriceUpdates = new Internal.GasPriceUpdate[](1); + gasPriceUpdates[0] = Internal.GasPriceUpdate({ destChainSelector: zeroGasDestChainSelector, usdPerUnitGas: 0 }); + + Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ + tokenPriceUpdates: new Internal.TokenPriceUpdate[](0), + gasPriceUpdates: gasPriceUpdates + }); s_priceRegistry.updatePrices(priceUpdates); (, uint224 gasPrice) = s_priceRegistry.getTokenAndGasPrices(s_sourceFeeToken, zeroGasDestChainSelector); - assertEq(gasPrice, priceUpdates.usdPerUnitGas); + assertEq(gasPrice, priceUpdates.gasPriceUpdates[0].usdPerUnitGas); } function testUnsupportedChainReverts() public { @@ -406,11 +416,16 @@ contract PriceRegistry_getTokenAndGasPrices is PriceRegistrySetup { uint256 diff = TWELVE_HOURS + 1; vm.warp(block.timestamp + diff); - Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ - tokenPriceUpdates: new Internal.TokenPriceUpdate[](0), + Internal.GasPriceUpdate[] memory gasPriceUpdates = new Internal.GasPriceUpdate[](1); + gasPriceUpdates[0] = Internal.GasPriceUpdate({ destChainSelector: DEST_CHAIN_ID, usdPerUnitGas: PACKED_USD_PER_GAS }); + + Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ + tokenPriceUpdates: new Internal.TokenPriceUpdate[](0), + gasPriceUpdates: gasPriceUpdates + }); s_priceRegistry.updatePrices(priceUpdates); vm.expectRevert( diff --git a/contracts/src/v0.8/ccip/test/router/Router.t.sol b/contracts/src/v0.8/ccip/test/router/Router.t.sol index b580d9c4a9..b1345071e0 100644 --- a/contracts/src/v0.8/ccip/test/router/Router.t.sol +++ b/contracts/src/v0.8/ccip/test/router/Router.t.sol @@ -265,8 +265,9 @@ contract Router_ccipSend is EVM2EVMOnRampSetup { // Update the price of the newly set feeToken Internal.PriceUpdates memory priceUpdates = getSinglePriceUpdateStruct(feeTokenWithZeroFeeAndGas, 2_000 ether); - priceUpdates.destChainSelector = DEST_CHAIN_ID; - priceUpdates.usdPerUnitGas = 0; + priceUpdates.gasPriceUpdates = new Internal.GasPriceUpdate[](1); + priceUpdates.gasPriceUpdates[0].destChainSelector = DEST_CHAIN_ID; + priceUpdates.gasPriceUpdates[0].usdPerUnitGas = 0; s_priceRegistry.updatePrices(priceUpdates); diff --git a/docs/CHANGELOG_CCIP.md b/docs/CHANGELOG_CCIP.md index 3f9713ac2d..c8bd6487be 100644 --- a/docs/CHANGELOG_CCIP.md +++ b/docs/CHANGELOG_CCIP.md @@ -13,6 +13,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added ### Changed +- PriceUpdate now accepts an array of gas price update + - Removed `destChainSelector` and `usdPerUnitGas` from PriceUpdates + - Added `GasPriceUpdate[] gasPriceUpdates` to PriceUpdates. Each `GasPriceUpdate` struct contains `destChainSelector` and `usdPerUnitGas`. - OnRamp fee calculation logic now includes L1 security fee if sending to L2. - New field `destBytesOverhead` added to **TokenTransferFeeConfig**. - `destBytesOverhead` is the size of additional bytes being passed to destination for token transfers. For example, USDC transfers require additional attestation data. @@ -25,7 +28,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - fixed-size fields are hashed in nested hash function. - CommitStore OffchainConfig fields updated. - New fields `GasPriceHeartBeat`, `DAGasPriceDeviationPPB`, `ExecGasPriceDeviationPPB`, `TokenPriceHeartBeat`, `TokenPriceDeviationPPB` added - - Old Fields `FeeUpdateHeartBeat`, `FeeUpdateDeviationPPB` removed. + - `GasPriceHeartBeat` specifies an update heartbeat threshold for gas prices + - `DAGasPriceDeviationPPB` specifies deviation PPB threshold for dava availability (DA) gas price. On chains without DA component, this should be 0. + - `ExecGasPriceDeviationPPB` specifies deviation PPB threshold for native EVM execution gas price. + - `TokenPriceHeartBeat` specifies an update heartbeat threshold for token prices + - `TokenPriceDeviationPPB` specifies deviation PPB threshold for token price. + - Old Fields `FeeUpdateHeartBeat`, `FeeUpdateDeviationPPB` removed. They are replaced by the fields above. ### Removed From 5cb65fab8f33d5ec40c0096a6b16ceba2cd42d26 Mon Sep 17 00:00:00 2001 From: Matt Yang Date: Tue, 3 Oct 2023 00:44:10 -0400 Subject: [PATCH 02/24] update onchain portion --- contracts/gas-snapshots/ccip.gas-snapshot | 146 +++++++++--------- contracts/src/v0.8/ccip/PriceRegistry.sol | 1 - .../src/v0.8/ccip/test/StructFactory.sol | 10 ++ .../test/priceRegistry/PriceRegistry.t.sol | 19 +-- .../src/v0.8/ccip/test/router/Router.t.sol | 4 +- .../generated/commit_store/commit_store.go | 14 +- .../commit_store_helper.go | 14 +- .../price_registry/price_registry.go | 12 +- ...rapper-dependency-versions-do-not-edit.txt | 6 +- 9 files changed, 120 insertions(+), 106 deletions(-) diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index 04b764ebb5..c3e059c296 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -57,41 +57,41 @@ BurnMintERC677_burn:testPoolBurnSuccess() (gas: 197641) BurnMintERC677_mint:testPoolMintNotHealthyReverts() (gas: 55384) BurnMintERC677_mint:testPoolMintSuccess() (gas: 93675) CCIPClientExample_sanity:testExamples() (gas: 2213780) -CommitStore_constructor:testConstructorSuccess() (gas: 3307574) +CommitStore_constructor:testConstructorSuccess() (gas: 3344466) CommitStore_isUnpausedAndARMHealthy:testARMSuccess() (gas: 71312) -CommitStore_report:testInvalidIntervalMinLargerThanMaxReverts() (gas: 26019) -CommitStore_report:testInvalidIntervalReverts() (gas: 25938) -CommitStore_report:testInvalidRootRevert() (gas: 25226) -CommitStore_report:testOnlyPriceUpdateStaleReportReverts() (gas: 57642) -CommitStore_report:testOnlyPriceUpdatesSuccess() (gas: 52214) +CommitStore_report:testInvalidIntervalMinLargerThanMaxReverts() (gas: 26334) +CommitStore_report:testInvalidIntervalReverts() (gas: 26253) +CommitStore_report:testInvalidRootRevert() (gas: 25540) +CommitStore_report:testOnlyPriceUpdateStaleReportReverts() (gas: 58393) +CommitStore_report:testOnlyPriceUpdatesSuccess() (gas: 52677) CommitStore_report:testPausedReverts() (gas: 21218) -CommitStore_report:testReportAndPriceUpdateSuccess() (gas: 82755) -CommitStore_report:testReportOnlyRootSuccess_gas() (gas: 53715) -CommitStore_report:testRootAlreadyCommittedReverts() (gas: 60723) -CommitStore_report:testStaleReportWithRootSuccess() (gas: 111235) +CommitStore_report:testReportAndPriceUpdateSuccess() (gas: 83266) +CommitStore_report:testReportOnlyRootSuccess_gas() (gas: 54005) +CommitStore_report:testRootAlreadyCommittedReverts() (gas: 61380) +CommitStore_report:testStaleReportWithRootSuccess() (gas: 111983) CommitStore_report:testUnhealthyReverts() (gas: 44522) -CommitStore_report:testValidPriceUpdateThenStaleReportWithRootSuccess() (gas: 95412) -CommitStore_report:testZeroEpochAndRoundReverts() (gas: 24902) +CommitStore_report:testValidPriceUpdateThenStaleReportWithRootSuccess() (gas: 96254) +CommitStore_report:testZeroEpochAndRoundReverts() (gas: 25234) CommitStore_resetUnblessedRoots:testOnlyOwnerReverts() (gas: 11290) -CommitStore_resetUnblessedRoots:testResetUnblessedRootsSuccess() (gas: 144194) +CommitStore_resetUnblessedRoots:testResetUnblessedRootsSuccess() (gas: 145219) CommitStore_setDynamicConfig:testInvalidCommitStoreConfigReverts() (gas: 37145) CommitStore_setDynamicConfig:testOnlyOwnerReverts() (gas: 37281) CommitStore_setDynamicConfig:testPriceEpochClearedSuccess() (gas: 124034) CommitStore_setLatestPriceEpochAndRound:testOnlyOwnerReverts() (gas: 10968) CommitStore_setLatestPriceEpochAndRound:testSetLatestPriceEpochAndRoundSuccess() (gas: 13799) CommitStore_setMinSeqNr:testOnlyOwnerReverts() (gas: 10989) -CommitStore_verify:testBlessedSuccess() (gas: 99739) -CommitStore_verify:testNotBlessedSuccess() (gas: 55602) +CommitStore_verify:testBlessedSuccess() (gas: 100081) +CommitStore_verify:testNotBlessedSuccess() (gas: 55944) CommitStore_verify:testPausedReverts() (gas: 18438) CommitStore_verify:testTooManyLeavesReverts() (gas: 36830) DefensiveExampleTest:testHappyPathSuccess() (gas: 174828) DefensiveExampleTest:testRecovery() (gas: 399728) -E2E:testE2E_3MessagesSuccess_gas() (gas: 863423) -EVM2EVMOffRamp__releaseOrMintTokens:testRateLimitErrorsReverts() (gas: 426826) -EVM2EVMOffRamp__releaseOrMintTokens:testTokenHandlingErrorReverts() (gas: 100041) -EVM2EVMOffRamp__releaseOrMintTokens:testUnsupportedTokenReverts() (gas: 18159) -EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokensSuccess() (gas: 139008) -EVM2EVMOffRamp__report:testReportSuccess() (gas: 126666) +E2E:testE2E_3MessagesSuccess_gas() (gas: 863711) +EVM2EVMOffRamp__releaseOrMintTokens:testRateLimitErrorsReverts() (gas: 426986) +EVM2EVMOffRamp__releaseOrMintTokens:testTokenHandlingErrorReverts() (gas: 100073) +EVM2EVMOffRamp__releaseOrMintTokens:testUnsupportedTokenReverts() (gas: 18155) +EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokensSuccess() (gas: 139040) +EVM2EVMOffRamp__report:testReportSuccess() (gas: 126633) EVM2EVMOffRamp__trialExecute:testRateLimitErrorSuccess() (gas: 171346) EVM2EVMOffRamp__trialExecute:testTokenHandlingErrorIsCaughtSuccess() (gas: 179665) EVM2EVMOffRamp__trialExecute:test_trialExecuteSuccess() (gas: 228022) @@ -106,29 +106,29 @@ EVM2EVMOffRamp_constructor:testCommitStoreAlreadyInUseReverts() (gas: 169122) EVM2EVMOffRamp_constructor:testConstructorSuccess() (gas: 5915423) EVM2EVMOffRamp_constructor:testTokenConfigMismatchReverts() (gas: 145488) EVM2EVMOffRamp_constructor:testZeroOnRampAddressReverts() (gas: 2651772) -EVM2EVMOffRamp_execute:testAlreadyExecutedReverts() (gas: 136534) -EVM2EVMOffRamp_execute:testEmptyReportReverts() (gas: 18990) -EVM2EVMOffRamp_execute:testInvalidMessageIdReverts() (gas: 33939) -EVM2EVMOffRamp_execute:testInvalidSourceChainReverts() (gas: 49122) -EVM2EVMOffRamp_execute:testManualExecutionNotYetEnabledReverts() (gas: 43953) -EVM2EVMOffRamp_execute:testMessageTooLargeReverts() (gas: 149928) -EVM2EVMOffRamp_execute:testPausedReverts() (gas: 74549) -EVM2EVMOffRamp_execute:testReceiverErrorSuccess() (gas: 162924) -EVM2EVMOffRamp_execute:testRootNotCommittedReverts() (gas: 38829) -EVM2EVMOffRamp_execute:testRouterYULCallReverts() (gas: 412650) -EVM2EVMOffRamp_execute:testSingleMessageNoTokensSuccess() (gas: 172174) -EVM2EVMOffRamp_execute:testSingleMessageToNonCCIPReceiverSuccess() (gas: 245912) -EVM2EVMOffRamp_execute:testSingleMessagesNoTokensSuccess_gas() (gas: 114026) -EVM2EVMOffRamp_execute:testSkippedIncorrectNonceStillExecutesSuccess() (gas: 314921) -EVM2EVMOffRamp_execute:testSkippedIncorrectNonceSuccess() (gas: 51676) -EVM2EVMOffRamp_execute:testStrictUntouchedToSuccessSuccess() (gas: 130151) -EVM2EVMOffRamp_execute:testTokenDataMismatchReverts() (gas: 49524) -EVM2EVMOffRamp_execute:testTwoMessagesWithTokensAndGESuccess() (gas: 430223) -EVM2EVMOffRamp_execute:testTwoMessagesWithTokensSuccess_gas() (gas: 389520) -EVM2EVMOffRamp_execute:testUnexpectedTokenDataReverts() (gas: 32929) -EVM2EVMOffRamp_execute:testUnhealthyReverts() (gas: 406629) -EVM2EVMOffRamp_execute:testUnsupportedNumberOfTokensReverts() (gas: 61032) -EVM2EVMOffRamp_execute:testUnsupportedTokenReverts() (gas: 129586) +EVM2EVMOffRamp_execute:testAlreadyExecutedReverts() (gas: 136560) +EVM2EVMOffRamp_execute:testEmptyReportReverts() (gas: 18992) +EVM2EVMOffRamp_execute:testInvalidMessageIdReverts() (gas: 33956) +EVM2EVMOffRamp_execute:testInvalidSourceChainReverts() (gas: 49147) +EVM2EVMOffRamp_execute:testManualExecutionNotYetEnabledReverts() (gas: 43970) +EVM2EVMOffRamp_execute:testMessageTooLargeReverts() (gas: 149953) +EVM2EVMOffRamp_execute:testPausedReverts() (gas: 74581) +EVM2EVMOffRamp_execute:testReceiverErrorSuccess() (gas: 162949) +EVM2EVMOffRamp_execute:testRootNotCommittedReverts() (gas: 38846) +EVM2EVMOffRamp_execute:testRouterYULCallReverts() (gas: 412675) +EVM2EVMOffRamp_execute:testSingleMessageNoTokensSuccess() (gas: 172208) +EVM2EVMOffRamp_execute:testSingleMessageToNonCCIPReceiverSuccess() (gas: 245937) +EVM2EVMOffRamp_execute:testSingleMessagesNoTokensSuccess_gas() (gas: 114035) +EVM2EVMOffRamp_execute:testSkippedIncorrectNonceStillExecutesSuccess() (gas: 314961) +EVM2EVMOffRamp_execute:testSkippedIncorrectNonceSuccess() (gas: 51701) +EVM2EVMOffRamp_execute:testStrictUntouchedToSuccessSuccess() (gas: 130176) +EVM2EVMOffRamp_execute:testTokenDataMismatchReverts() (gas: 49541) +EVM2EVMOffRamp_execute:testTwoMessagesWithTokensAndGESuccess() (gas: 430263) +EVM2EVMOffRamp_execute:testTwoMessagesWithTokensSuccess_gas() (gas: 389536) +EVM2EVMOffRamp_execute:testUnexpectedTokenDataReverts() (gas: 32945) +EVM2EVMOffRamp_execute:testUnhealthyReverts() (gas: 406693) +EVM2EVMOffRamp_execute:testUnsupportedNumberOfTokensReverts() (gas: 61057) +EVM2EVMOffRamp_execute:testUnsupportedTokenReverts() (gas: 129634) EVM2EVMOffRamp_executeSingleMessage:testMessageSenderReverts() (gas: 20494) EVM2EVMOffRamp_executeSingleMessage:testNoTokensSuccess() (gas: 47668) EVM2EVMOffRamp_executeSingleMessage:testNonContractSuccess() (gas: 20042) @@ -167,9 +167,9 @@ EVM2EVMOnRamp_applyPoolUpdates:testPoolDoesNotExistReverts() (gas: 277882) EVM2EVMOnRamp_applyPoolUpdates:testRemoveTokenPoolMismatchReverts() (gas: 616024) EVM2EVMOnRamp_constructor:testConstructorSuccess() (gas: 5774116) EVM2EVMOnRamp_forwardFromRouter:testCannotSendZeroTokensReverts() (gas: 31534) -EVM2EVMOnRamp_forwardFromRouter:testForwardFromRouterSuccess() (gas: 126628) -EVM2EVMOnRamp_forwardFromRouter:testForwardFromRouterSuccessCustomExtraArgs() (gas: 126940) -EVM2EVMOnRamp_forwardFromRouter:testForwardFromRouterSuccessLegacyExtraArgs() (gas: 137359) +EVM2EVMOnRamp_forwardFromRouter:testForwardFromRouterSuccess() (gas: 126626) +EVM2EVMOnRamp_forwardFromRouter:testForwardFromRouterSuccessCustomExtraArgs() (gas: 126938) +EVM2EVMOnRamp_forwardFromRouter:testForwardFromRouterSuccessLegacyExtraArgs() (gas: 137357) EVM2EVMOnRamp_forwardFromRouter:testInvalidAddressEncodePackedReverts() (gas: 23964) EVM2EVMOnRamp_forwardFromRouter:testInvalidAddressReverts() (gas: 24263) EVM2EVMOnRamp_forwardFromRouter:testInvalidExtraArgsTagReverts() (gas: 23265) @@ -181,12 +181,12 @@ EVM2EVMOnRamp_forwardFromRouter:testOriginalSenderReverts() (gas: 20165) EVM2EVMOnRamp_forwardFromRouter:testPausedReverts() (gas: 49568) EVM2EVMOnRamp_forwardFromRouter:testPermissionsReverts() (gas: 26836) EVM2EVMOnRamp_forwardFromRouter:testPriceNotFoundForTokenReverts() (gas: 34938) -EVM2EVMOnRamp_forwardFromRouter:testShouldIncrementSeqNumAndNonceSuccess() (gas: 168385) +EVM2EVMOnRamp_forwardFromRouter:testShouldIncrementSeqNumAndNonceSuccess() (gas: 168379) EVM2EVMOnRamp_forwardFromRouter:testShouldStoreLinkFees() (gas: 104372) EVM2EVMOnRamp_forwardFromRouter:testShouldStoreNonLinkFees() (gas: 123580) EVM2EVMOnRamp_forwardFromRouter:testTooManyTokensReverts() (gas: 28119) EVM2EVMOnRamp_forwardFromRouter:testUnhealthyReverts() (gas: 42966) -EVM2EVMOnRamp_forwardFromRouter:testUnsupportedTokenReverts() (gas: 108831) +EVM2EVMOnRamp_forwardFromRouter:testUnsupportedTokenReverts() (gas: 109084) EVM2EVMOnRamp_forwardFromRouter:testZeroAddressReceiverReverts() (gas: 154448) EVM2EVMOnRamp_forwardFromRouter_upgrade:testV2NonceNewSenderStartsAtZeroSuccess() (gas: 141893) EVM2EVMOnRamp_forwardFromRouter_upgrade:testV2NonceStartsAtV1NonceSuccess() (gas: 184775) @@ -199,21 +199,21 @@ EVM2EVMOnRamp_getFee:testEmptyMessageSuccess() (gas: 68388) EVM2EVMOnRamp_getFee:testHighGasMessageSuccess() (gas: 224358) EVM2EVMOnRamp_getFee:testMessageGasLimitTooHighReverts() (gas: 16453) EVM2EVMOnRamp_getFee:testMessageTooLargeReverts() (gas: 94976) -EVM2EVMOnRamp_getFee:testMessageWithDataAndTokenTransferSuccess() (gas: 129846) +EVM2EVMOnRamp_getFee:testMessageWithDataAndTokenTransferSuccess() (gas: 129444) EVM2EVMOnRamp_getFee:testNotAFeeTokenReverts() (gas: 21715) -EVM2EVMOnRamp_getFee:testSingleTokenMessageSuccess() (gas: 99608) +EVM2EVMOnRamp_getFee:testSingleTokenMessageSuccess() (gas: 99474) EVM2EVMOnRamp_getFee:testTooManyTokensReverts() (gas: 19644) EVM2EVMOnRamp_getFee:testZeroDataAvailabilityMultiplierSuccess() (gas: 54013) EVM2EVMOnRamp_getSupportedTokens:testGetSupportedTokensSuccess() (gas: 51549) EVM2EVMOnRamp_getTokenPool:testGetTokenPoolSuccess() (gas: 40912) -EVM2EVMOnRamp_getTokenTransferCost:testCustomTokenBpsFeeSuccess() (gas: 40105) +EVM2EVMOnRamp_getTokenTransferCost:testCustomTokenBpsFeeSuccess() (gas: 40038) EVM2EVMOnRamp_getTokenTransferCost:testFeeTokenBpsFeeSuccess() (gas: 30352) EVM2EVMOnRamp_getTokenTransferCost:testLargeTokenTransferChargesMaxFeeAndGasSuccess() (gas: 25697) -EVM2EVMOnRamp_getTokenTransferCost:testMixedTokenTransferFeeSuccess() (gas: 109527) +EVM2EVMOnRamp_getTokenTransferCost:testMixedTokenTransferFeeSuccess() (gas: 109125) EVM2EVMOnRamp_getTokenTransferCost:testNoTokenTransferChargesMinFeeSuccess() (gas: 17121) EVM2EVMOnRamp_getTokenTransferCost:testSmallTokenTransferChargesMinFeeAndGasSuccess() (gas: 25507) EVM2EVMOnRamp_getTokenTransferCost:testUnsupportedTokenReverts() (gas: 25338) -EVM2EVMOnRamp_getTokenTransferCost:testValidatedPriceStalenessReverts() (gas: 42529) +EVM2EVMOnRamp_getTokenTransferCost:testValidatedPriceStalenessReverts() (gas: 42462) EVM2EVMOnRamp_getTokenTransferCost:testWETHTokenBpsFeeSuccess() (gas: 36256) EVM2EVMOnRamp_getTokenTransferCost:testZeroAmountTokenTransferChargesMinFeeAndAgasSuccess() (gas: 25527) EVM2EVMOnRamp_getTokenTransferCost:testZeroFeeConfigChargesMinFeeSuccess() (gas: 29472) @@ -293,27 +293,27 @@ OnRampTokenPoolReentrancy:testSuccess() (gas: 332065) PingPong_ccipReceive:testCcipReceiveSuccess() (gas: 146097) PingPong_plumbing:testPausingSuccess() (gas: 14471) PingPong_startPingPong:testStartPingPongSuccess() (gas: 171175) -PriceRegistry_applyFeeTokensUpdates:testApplyFeeTokensUpdatesSuccess() (gas: 77674) -PriceRegistry_applyFeeTokensUpdates:testOnlyCallableByOwnerReverts() (gas: 16598) -PriceRegistry_applyPriceUpdatersUpdates:testApplyPriceUpdaterUpdatesSuccess() (gas: 80774) -PriceRegistry_applyPriceUpdatersUpdates:testOnlyCallableByOwnerReverts() (gas: 16576) +PriceRegistry_applyFeeTokensUpdates:testApplyFeeTokensUpdatesSuccess() (gas: 77463) +PriceRegistry_applyFeeTokensUpdates:testOnlyCallableByOwnerReverts() (gas: 16532) +PriceRegistry_applyPriceUpdatersUpdates:testApplyPriceUpdaterUpdatesSuccess() (gas: 80844) +PriceRegistry_applyPriceUpdatersUpdates:testOnlyCallableByOwnerReverts() (gas: 16598) PriceRegistry_constructor:testInvalidStalenessThresholdReverts() (gas: 66156) -PriceRegistry_constructor:testSetupSuccess() (gas: 1658494) -PriceRegistry_convertTokenAmount:testConvertTokenAmountSuccess() (gas: 60190) +PriceRegistry_constructor:testSetupSuccess() (gas: 1658294) +PriceRegistry_convertTokenAmount:testConvertTokenAmountSuccess() (gas: 65026) PriceRegistry_convertTokenAmount:testLinkTokenNotSupportedReverts() (gas: 22707) -PriceRegistry_convertTokenAmount:testStaleFeeTokenReverts() (gas: 31634) -PriceRegistry_convertTokenAmount:testStaleLinkTokenReverts() (gas: 31104) -PriceRegistry_getTokenAndGasPrices:testGetFeeTokenAndGasPricesSuccess() (gas: 59721) +PriceRegistry_convertTokenAmount:testStaleFeeTokenReverts() (gas: 31901) +PriceRegistry_convertTokenAmount:testStaleLinkTokenReverts() (gas: 31371) +PriceRegistry_getTokenAndGasPrices:testGetFeeTokenAndGasPricesSuccess() (gas: 64650) PriceRegistry_getTokenAndGasPrices:testStaleGasPriceReverts() (gas: 16688) -PriceRegistry_getTokenAndGasPrices:testStaleTokenPriceReverts() (gas: 28960) +PriceRegistry_getTokenAndGasPrices:testStaleTokenPriceReverts() (gas: 29702) PriceRegistry_getTokenAndGasPrices:testUnsupportedChainReverts() (gas: 16030) -PriceRegistry_getTokenAndGasPrices:testZeroGasPriceSuccess() (gas: 39513) -PriceRegistry_getTokenPrices:testGetTokenPricesSuccess() (gas: 68805) -PriceRegistry_getValidatedTokenPrice:testGetValidatedTokenPriceSuccess() (gas: 50773) -PriceRegistry_getValidatedTokenPrice:testStaleFeeTokenReverts() (gas: 16963) -PriceRegistry_getValidatedTokenPrice:testTokenNotSupportedReverts() (gas: 11380) -PriceRegistry_updatePrices:testOnlyCallableByUpdaterOrOwnerReverts() (gas: 41709) -PriceRegistry_updatePrices:testUpdatePricesSuccess() (gas: 66451) +PriceRegistry_getTokenAndGasPrices:testZeroGasPriceSuccess() (gas: 40311) +PriceRegistry_getTokenPrices:testGetTokenPricesSuccess() (gas: 73698) +PriceRegistry_getValidatedTokenPrice:testGetValidatedTokenPriceSuccess() (gas: 55577) +PriceRegistry_getValidatedTokenPrice:testStaleFeeTokenReverts() (gas: 16896) +PriceRegistry_getValidatedTokenPrice:testTokenNotSupportedReverts() (gas: 11313) +PriceRegistry_updatePrices:testOnlyCallableByUpdaterOrOwnerReverts() (gas: 46854) +PriceRegistry_updatePrices:testUpdatePricesSuccess() (gas: 71890) RateLimiter_constructor:testConstructorSuccess() (gas: 15362) RateLimiter_consume:testAggregateValueMaxCapacityExceededReverts() (gas: 15669) RateLimiter_consume:testAggregateValueRateLimitReachedReverts() (gas: 21950) @@ -342,11 +342,11 @@ Router_ccipSend:testNativeFeeTokenInsufficientValue() (gas: 64237) Router_ccipSend:testNativeFeeTokenOverpaySuccess() (gas: 161923) Router_ccipSend:testNativeFeeTokenSuccess() (gas: 161264) Router_ccipSend:testNativeFeeTokenZeroValue() (gas: 51217) -Router_ccipSend:testNonLinkFeeTokenSuccess() (gas: 233465) +Router_ccipSend:testNonLinkFeeTokenSuccess() (gas: 233399) Router_ccipSend:testUnsupportedDestinationChainReverts() (gas: 24624) Router_ccipSend:testWhenNotHealthyReverts() (gas: 44650) Router_ccipSend:testWrappedNativeFeeTokenSuccess() (gas: 163363) -Router_ccipSend:testZeroFeeAndGasPriceSuccess() (gas: 229200) +Router_ccipSend:testZeroFeeAndGasPriceSuccess() (gas: 229986) Router_constructor:testConstructorSuccess() (gas: 9929) Router_getFee:testGetFeeSupportedChainSuccess() (gas: 38866) Router_getFee:testUnsupportedDestinationChainReverts() (gas: 17079) diff --git a/contracts/src/v0.8/ccip/PriceRegistry.sol b/contracts/src/v0.8/ccip/PriceRegistry.sol index d2cd1fe610..e6a416b3b7 100644 --- a/contracts/src/v0.8/ccip/PriceRegistry.sol +++ b/contracts/src/v0.8/ccip/PriceRegistry.sol @@ -210,7 +210,6 @@ contract PriceRegistry is IPriceRegistry, OwnerIsCreator, TypeAndVersionInterfac timestamp: uint32(block.timestamp) }); emit UsdPerUnitGasUpdated(update.destChainSelector, update.usdPerUnitGas, block.timestamp); - } } diff --git a/contracts/src/v0.8/ccip/test/StructFactory.sol b/contracts/src/v0.8/ccip/test/StructFactory.sol index 1225c48db8..0e8de273b7 100644 --- a/contracts/src/v0.8/ccip/test/StructFactory.sol +++ b/contracts/src/v0.8/ccip/test/StructFactory.sol @@ -196,6 +196,16 @@ contract StructFactory { return priceUpdates; } + function setSingleGasPriceUpdate( + Internal.PriceUpdates memory priceUpdates, + uint64 destChainSelector, + uint224 usdPerUnitGas + ) internal pure { + priceUpdates.gasPriceUpdates = new Internal.GasPriceUpdate[](1); + priceUpdates.gasPriceUpdates[0].destChainSelector = destChainSelector; + priceUpdates.gasPriceUpdates[0].usdPerUnitGas = usdPerUnitGas; + } + function getPriceUpdatesStruct( address[] memory tokens, uint224[] memory prices diff --git a/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol b/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol index de79906504..fbb535e057 100644 --- a/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol +++ b/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol @@ -69,9 +69,7 @@ contract PriceRegistrySetup is TokenSetup, RouterSetup { } Internal.PriceUpdates memory priceUpdates = getPriceUpdatesStruct(pricedTokens, tokenPrices); - priceUpdates.gasPriceUpdates = new Internal.GasPriceUpdate[](1); - priceUpdates.gasPriceUpdates[0].destChainSelector = DEST_CHAIN_ID; - priceUpdates.gasPriceUpdates[0].usdPerUnitGas = PACKED_USD_PER_GAS; + setSingleGasPriceUpdate(priceUpdates, DEST_CHAIN_ID, PACKED_USD_PER_GAS); s_encodedInitialPriceUpdates = abi.encode(priceUpdates); address[] memory priceUpdaters = new address[](0); @@ -255,7 +253,10 @@ contract PriceRegistry_updatePrices is PriceRegistrySetup { assertEq(s_priceRegistry.getTokenPrice(s_sourceTokens[0]).value, priceUpdates.tokenPriceUpdates[0].usdPerToken); assertEq(s_priceRegistry.getTokenPrice(s_sourceTokens[1]).value, priceUpdates.tokenPriceUpdates[1].usdPerToken); - assertEq(s_priceRegistry.getDestinationChainGasPrice(DEST_CHAIN_ID).value, priceUpdates.gasPriceUpdates[0].usdPerUnitGas); + assertEq( + s_priceRegistry.getDestinationChainGasPrice(DEST_CHAIN_ID).value, + priceUpdates.gasPriceUpdates[0].usdPerUnitGas + ); } // Reverts @@ -384,10 +385,7 @@ contract PriceRegistry_getTokenAndGasPrices is PriceRegistrySetup { function testZeroGasPriceSuccess() public { uint64 zeroGasDestChainSelector = 345678; Internal.GasPriceUpdate[] memory gasPriceUpdates = new Internal.GasPriceUpdate[](1); - gasPriceUpdates[0] = Internal.GasPriceUpdate({ - destChainSelector: zeroGasDestChainSelector, - usdPerUnitGas: 0 - }); + gasPriceUpdates[0] = Internal.GasPriceUpdate({destChainSelector: zeroGasDestChainSelector, usdPerUnitGas: 0}); Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ tokenPriceUpdates: new Internal.TokenPriceUpdate[](0), @@ -417,10 +415,7 @@ contract PriceRegistry_getTokenAndGasPrices is PriceRegistrySetup { vm.warp(block.timestamp + diff); Internal.GasPriceUpdate[] memory gasPriceUpdates = new Internal.GasPriceUpdate[](1); - gasPriceUpdates[0] = Internal.GasPriceUpdate({ - destChainSelector: DEST_CHAIN_ID, - usdPerUnitGas: PACKED_USD_PER_GAS - }); + gasPriceUpdates[0] = Internal.GasPriceUpdate({destChainSelector: DEST_CHAIN_ID, usdPerUnitGas: PACKED_USD_PER_GAS}); Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ tokenPriceUpdates: new Internal.TokenPriceUpdate[](0), diff --git a/contracts/src/v0.8/ccip/test/router/Router.t.sol b/contracts/src/v0.8/ccip/test/router/Router.t.sol index b1345071e0..93d359f714 100644 --- a/contracts/src/v0.8/ccip/test/router/Router.t.sol +++ b/contracts/src/v0.8/ccip/test/router/Router.t.sol @@ -265,9 +265,7 @@ contract Router_ccipSend is EVM2EVMOnRampSetup { // Update the price of the newly set feeToken Internal.PriceUpdates memory priceUpdates = getSinglePriceUpdateStruct(feeTokenWithZeroFeeAndGas, 2_000 ether); - priceUpdates.gasPriceUpdates = new Internal.GasPriceUpdate[](1); - priceUpdates.gasPriceUpdates[0].destChainSelector = DEST_CHAIN_ID; - priceUpdates.gasPriceUpdates[0].usdPerUnitGas = 0; + setSingleGasPriceUpdate(priceUpdates, DEST_CHAIN_ID, 0); s_priceRegistry.updatePrices(priceUpdates); diff --git a/core/gethwrappers/ccip/generated/commit_store/commit_store.go b/core/gethwrappers/ccip/generated/commit_store/commit_store.go index c9518b70e7..288e82954a 100644 --- a/core/gethwrappers/ccip/generated/commit_store/commit_store.go +++ b/core/gethwrappers/ccip/generated/commit_store/commit_store.go @@ -52,20 +52,24 @@ type CommitStoreStaticConfig struct { ArmProxy common.Address } -type InternalPriceUpdates struct { - TokenPriceUpdates []InternalTokenPriceUpdate +type InternalGasPriceUpdate struct { DestChainSelector uint64 UsdPerUnitGas *big.Int } +type InternalPriceUpdates struct { + TokenPriceUpdates []InternalTokenPriceUpdate + GasPriceUpdates []InternalGasPriceUpdate +} + type InternalTokenPriceUpdate struct { SourceToken common.Address UsdPerToken *big.Int } var CommitStoreMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCommitStoreConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PausedError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structCommitStore.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"ReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceEpochAndRound\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUnpausedAndARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"rootToReset\",\"type\":\"bytes32[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint40\",\"name\":\"latestPriceEpochAndRound\",\"type\":\"uint40\"}],\"name\":\"setLatestPriceEpochAndRound\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"}],\"name\":\"setMinSeqNr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedLeaves\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x61014060405260098054600165ff000000000160401b03191660011790553480156200002a57600080fd5b5060405162003794380380620037948339810160408190526200004d9162000272565b600033808281620000a55760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d857620000d88162000192565b50505015156080524660a05260408101516001600160a01b0316158062000107575080516001600160401b0316155b806200011e575060208101516001600160401b0316155b8062000135575060608101516001600160a01b0316155b156200015457604051631fc5f15f60e11b815260040160405180910390fd5b80516001600160401b0390811660c05260208201511660e05260408101516001600160a01b0390811661010052606090910151166101205262000306565b336001600160a01b03821603620001ec5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200009c565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160401b03811681146200025557600080fd5b919050565b80516001600160a01b03811681146200025557600080fd5b6000608082840312156200028557600080fd5b604051608081016001600160401b0381118282101715620002b657634e487b7160e01b600052604160045260246000fd5b604052620002c4836200023d565b8152620002d4602084016200023d565b6020820152620002e7604084016200025a565b6040820152620002fa606084016200025a565b60608201529392505050565b60805160a05160c05160e05161010051610120516133ff620003956000396000818161026d01528181610537015281816111730152818161199f01528181611bee015261206b0152600081816102310152611bc70152600081816102010152611ba00152600081816101d10152611b710152600081816112ee015261133a015260006113b501526133ff6000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c806379ba5097116100e3578063ad7a22f81161008c578063f2fde38b11610066578063f2fde38b146104fa578063f47a86901461050d578063ff888fb11461052057600080fd5b8063ad7a22f8146104b4578063afcb95d7146104c7578063b1dc65a4146104e757600080fd5b80638da5cb5b116100bd5780638da5cb5b146104645780638db94e441461048c578063a7206cd61461049457600080fd5b806379ba50971461042457806381ff70481461042c5780638456cb591461045c57600080fd5b806332048875116101455780635c975abb1161011f5780635c975abb146103b4578063666cab8d146103d05780637437ff9f146103e557600080fd5b806332048875146103795780633f4ba83a1461039a5780634120fccd146103a257600080fd5b8063181f5a7711610176578063181f5a77146103085780631ef381741461035157806329b980e41461036657600080fd5b806306285c691461019d5780630a6cd30d146102c057806310c374ed146102d8575b600080fd5b6102aa60408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b6040516102b7919061265f565b60405180910390f35b6102c8610533565b60405190151581526020016102b7565b60095468010000000000000000900464ffffffffff165b60405167ffffffffffffffff90911681526020016102b7565b6103446040518060400160405280601181526020017f436f6d6d697453746f726520312e322e3000000000000000000000000000000081525081565b6040516102b7919061271c565b61036461035f36600461296f565b6105ca565b005b610364610374366004612a3c565b610deb565b61038c610387366004612aaf565b610e37565b6040519081526020016102b7565b610364610f2d565b60095467ffffffffffffffff166102ef565b6009546d0100000000000000000000000000900460ff166102c8565b6103d8610f93565b6040516102b79190612b74565b604080516020808201835260009091528151808201835260085473ffffffffffffffffffffffffffffffffffffffff16908190529151918252016102b7565b610364611002565b6004546002546040805163ffffffff808516825264010000000090940490931660208401528201526060016102b7565b6103646110ff565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102b7565b6102c861116f565b61038c6104a2366004612b87565b6000908152600a602052604090205490565b6103646104c2366004612ba0565b611226565b6040805160018152600060208201819052918101919091526060016102b7565b6103646104f5366004612bbb565b611269565b610364610508366004612ca0565b611889565b61036461051b366004612cbd565b61189d565b6102c861052e366004612b87565b61193c565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c49190612cff565b15905090565b855185518560ff16601f831115610642576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e6572730000000000000000000000000000000060448201526064015b60405180910390fd5b806000036106ac576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610639565b81831461073a576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610639565b610745816003612d50565b83116107ad576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610639565b6107b5611a10565b6107be86611a93565b60065460005b818110156108ba5760056000600683815481106107e3576107e3612d67565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556007805460059291908490811061085357610853612d67565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556108b381612d96565b90506107c4565b50895160005b81811015610c935760008c82815181106108dc576108dc612d67565b60200260200101519050600060028111156108f9576108f9612dce565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff16600281111561093857610938612dce565b1461099f576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610639565b73ffffffffffffffffffffffffffffffffffffffff81166109ec576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016001905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610a9c57610a9c612dce565b021790555090505060008c8381518110610ab857610ab8612d67565b6020026020010151905060006002811115610ad557610ad5612dce565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff166002811115610b1457610b14612dce565b14610b7b576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610639565b73ffffffffffffffffffffffffffffffffffffffff8116610bc8576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff84168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610c7857610c78612dce565b0217905550905050505080610c8c90612d96565b90506108c0565b508a51610ca79060069060208e01906125a1565b508951610cbb9060079060208d01906125a1565b506003805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908c161717905560048054610d41914691309190600090610d139063ffffffff16612dfd565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168e8e8e8e8e8e611c4f565b600260000181905550600060048054906101000a900463ffffffff169050436004806101000a81548163ffffffff021916908363ffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600260000154600460009054906101000a900463ffffffff168f8f8f8f8f8f604051610dd599989796959493929190612e20565b60405180910390a1505050505050505050505050565b610df3611a10565b6009805464ffffffffff90921668010000000000000000027fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff909216919091179055565b6009546000906d0100000000000000000000000000900460ff1615610e88576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610ef987878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a925089918291850190849080828437600092019190915250889250611cfa915050565b9050610f048161193c565b610f12576000915050610f24565b6000908152600a602052604090205490505b95945050505050565b610f35611a10565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60606007805480602002602001604051908101604052809291908181526020018280548015610ff857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610fcd575b5050505050905090565b60015473ffffffffffffffffffffffffffffffffffffffff163314611083576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610639565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611107611a10565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff166d01000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610f89565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112009190612cff565b15801561122157506009546d0100000000000000000000000000900460ff16155b905090565b61122e611a10565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff92909216919091179055565b611278878760208b013561201b565b6040805160608101825260025480825260035460ff8082166020850152610100909104169282019290925289359182146112eb5780516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604401610639565b467f00000000000000000000000000000000000000000000000000000000000000001461136c576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610639565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a160007f00000000000000000000000000000000000000000000000000000000000000001561140e576002826020015183604001516113ef9190612eb6565b6113f99190612ecf565b611404906001612eb6565b60ff169050611424565b602082015161141e906001612eb6565b60ff1690505b86811461145d576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b868514611496576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526005602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156114d9576114d9612dce565b60028111156114ea576114ea612dce565b905250905060028160200151600281111561150757611507612dce565b14801561154e57506007816000015160ff168154811061152957611529612d67565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b611584576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506000611592866020612d50565b61159d896020612d50565b6115a98c610144612f18565b6115b39190612f18565b6115bd9190612f18565b9050368114611601576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610639565b5060008a8a604051611614929190612f2b565b60405190819003812061162b918e90602001612f3b565b60405160208183030381529060405280519060200120905061164b61262b565b8860005b818110156118785760006001858a846020811061166e5761166e612d67565b61167b91901a601b612eb6565b8f8f8681811061168d5761168d612d67565b905060200201358e8e878181106116a6576116a6612d67565b90506020020135604051600081526020016040526040516116e3949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611705573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152848220848601909552845460ff808216865293975091955092939284019161010090910416600281111561178857611788612dce565b600281111561179957611799612dce565b90525090506001816020015160028111156117b6576117b6612dce565b146117ed576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061180457611804612d67565b602002015115611840576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061185b5761185b612d67565b9115156020909202015250611871905081612d96565b905061164f565b505050505050505050505050505050565b611891611a10565b61189a81612431565b50565b6118a5611a10565b60005b818110156119375760008383838181106118c4576118c4612d67565b9050602002013590506118d68161193c565b611926576000818152600a602052604080822091909155517f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f129061191d9083815260200190565b60405180910390a15b5061193081612d96565b90506118a8565b505050565b6040805180820182523081526020810183815291517f4d616771000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa1580156119e6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a0a9190612cff565b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611a91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610639565b565b600081806020019051810190611aa99190612f4f565b805190915073ffffffffffffffffffffffffffffffffffffffff16611afa576040517f3f8be2be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff928316179055600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff169055604080516080810182527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff90811682527f00000000000000000000000000000000000000000000000000000000000000001660208201527f00000000000000000000000000000000000000000000000000000000000000008316818301527f00000000000000000000000000000000000000000000000000000000000000009092166060830152517fc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec391611c43918490612f9b565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a604051602001611c7399989796959493929190613018565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b8251825160009190818303611d3b576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590611d4f57506101018111155b611d85576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82820101610100811115611de6576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003611e135786600081518110611e0157611e01612d67565b60200260200101519350505050612014565b60008167ffffffffffffffff811115611e2e57611e2e61272f565b604051908082528060200260200182016040528015611e57578160200160208202803683370190505b50905060008080805b85811015611f9a5760006001821b8b811603611ebb5788851015611ea4578c5160018601958e918110611e9557611e95612d67565b60200260200101519050611edd565b8551600185019487918110611e9557611e95612d67565b8b5160018401938d918110611ed257611ed2612d67565b602002602001015190505b600089861015611f0d578d5160018701968f918110611efe57611efe612d67565b60200260200101519050611f2f565b8651600186019588918110611f2457611f24612d67565b602002602001015190505b82851115611f69576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f738282612526565b878481518110611f8557611f85612d67565b60209081029190910101525050600101611e60565b506001850382148015611fac57508683145b8015611fb757508581145b611fed576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83600186038151811061200257612002612d67565b60200260200101519750505050505050505b9392505050565b6009546d0100000000000000000000000000900460ff1615612069576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120f89190612cff565b1561212f576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061213d83850185613117565b8051515190915015158061215f575080516020015167ffffffffffffffff1615155b156122975760095464ffffffffff8084166801000000000000000090920416101561225c57600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff166801000000000000000064ffffffffff85160217905560085481516040517f98f5be1b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909216916398f5be1b9161221691600401613336565b600060405180830381600087803b15801561223057600080fd5b505af1158015612244573d6000803e3d6000fd5b5050505060408101516122575750505050565b612297565b6040810151612297576040517ff803a2ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101515160095467ffffffffffffffff90811691161415806122d2575060208082015190810151905167ffffffffffffffff9182169116115b1561230f5780602001516040517fbb1ae18d0000000000000000000000000000000000000000000000000000000081526004016106399190613349565b604081015161234a576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040808201516000908152600a602052205415612393576040517fa0bce24f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208082015101516123a690600161336e565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790556040818101516000908152600a602052819020429055517fc14f9167b03b9a5725671c8678a54571219bff700e4a3665aef9e096c6a846f890612423908390613396565b60405180910390a150505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036124b0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610639565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008183106125685760408051600160208083019190915281830185905260608083018790528351808403909101815260809092019092528051910120612014565b60408051600160208083019190915281830186905260608083018690528351808403909101815260809092019092528051910120612014565b82805482825590600052602060002090810192821561261b579160200282015b8281111561261b57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906125c1565b5061262792915061264a565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115612627576000815560010161264b565b60808101611a0a828467ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b6000815180845260005b818110156126de576020818501810151868301820152016126c2565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061201460208301846126b8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156127815761278161272f565b60405290565b6040516060810167ffffffffffffffff811182821017156127815761278161272f565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156127f1576127f161272f565b604052919050565b600067ffffffffffffffff8211156128135761281361272f565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff8116811461189a57600080fd5b600082601f83011261285057600080fd5b81356020612865612860836127f9565b6127aa565b82815260059290921b8401810191818101908684111561288457600080fd5b8286015b848110156128a857803561289b8161281d565b8352918301918301612888565b509695505050505050565b803560ff811681146128c457600080fd5b919050565b600082601f8301126128da57600080fd5b813567ffffffffffffffff8111156128f4576128f461272f565b61292560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016127aa565b81815284602083860101111561293a57600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff811681146128c457600080fd5b60008060008060008060c0878903121561298857600080fd5b863567ffffffffffffffff808211156129a057600080fd5b6129ac8a838b0161283f565b975060208901359150808211156129c257600080fd5b6129ce8a838b0161283f565b96506129dc60408a016128b3565b955060608901359150808211156129f257600080fd5b6129fe8a838b016128c9565b9450612a0c60808a01612957565b935060a0890135915080821115612a2257600080fd5b50612a2f89828a016128c9565b9150509295509295509295565b600060208284031215612a4e57600080fd5b813564ffffffffff8116811461201457600080fd5b60008083601f840112612a7557600080fd5b50813567ffffffffffffffff811115612a8d57600080fd5b6020830191508360208260051b8501011115612aa857600080fd5b9250929050565b600080600080600060608688031215612ac757600080fd5b853567ffffffffffffffff80821115612adf57600080fd5b612aeb89838a01612a63565b90975095506020880135915080821115612b0457600080fd5b50612b1188828901612a63565b96999598509660400135949350505050565b600081518084526020808501945080840160005b83811015612b6957815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101612b37565b509495945050505050565b6020815260006120146020830184612b23565b600060208284031215612b9957600080fd5b5035919050565b600060208284031215612bb257600080fd5b61201482612957565b60008060008060008060008060e0898b031215612bd757600080fd5b606089018a811115612be857600080fd5b8998503567ffffffffffffffff80821115612c0257600080fd5b818b0191508b601f830112612c1657600080fd5b813581811115612c2557600080fd5b8c6020828501011115612c3757600080fd5b6020830199508098505060808b0135915080821115612c5557600080fd5b612c618c838d01612a63565b909750955060a08b0135915080821115612c7a57600080fd5b50612c878b828c01612a63565b999c989b50969995989497949560c00135949350505050565b600060208284031215612cb257600080fd5b81356120148161281d565b60008060208385031215612cd057600080fd5b823567ffffffffffffffff811115612ce757600080fd5b612cf385828601612a63565b90969095509350505050565b600060208284031215612d1157600080fd5b8151801515811461201457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417611a0a57611a0a612d21565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612dc757612dc7612d21565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600063ffffffff808316818103612e1657612e16612d21565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152612e508184018a612b23565b90508281036080840152612e648189612b23565b905060ff871660a084015282810360c0840152612e8181876126b8565b905067ffffffffffffffff851660e0840152828103610100840152612ea681856126b8565b9c9b505050505050505050505050565b60ff8181168382160190811115611a0a57611a0a612d21565b600060ff831680612f09577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b8060ff84160491505092915050565b80820180821115611a0a57611a0a612d21565b8183823760009101908152919050565b828152606082602083013760800192915050565b600060208284031215612f6157600080fd5b6040516020810181811067ffffffffffffffff82111715612f8457612f8461272f565b6040528251612f928161281d565b81529392505050565b60a08101612ff4828567ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b73ffffffffffffffffffffffffffffffffffffffff83511660808301529392505050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b16604085015281606085015261305f8285018b612b23565b91508382036080850152613073828a612b23565b915060ff881660a085015283820360c085015261309082886126b8565b90861660e08501528381036101008501529050612ea681856126b8565b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146128c457600080fd5b6000604082840312156130eb57600080fd5b6130f361275e565b90506130fe82612957565b815261310c60208301612957565b602082015292915050565b6000602080838503121561312a57600080fd5b823567ffffffffffffffff8082111561314257600080fd5b908401906080828703121561315657600080fd5b61315e612787565b82358281111561316d57600080fd5b83016060818903121561317f57600080fd5b613187612787565b81358481111561319657600080fd5b82019350601f840189136131a957600080fd5b83356131b7612860826127f9565b81815260069190911b8501870190878101908b8311156131d657600080fd5b958801955b8287101561322a576040878d0312156131f45760008081fd5b6131fc61275e565b87356132078161281d565b8152613214888b016130ad565b818b0152825260409690960195908801906131db565b83525061323a9050828701612957565b8682015261324a604083016130ad565b604082015282525061325e878486016130d9565b93810193909352506060013560408201529392505050565b805160608084528151908401819052600091602091908201906080860190845b818110156132f1578351805173ffffffffffffffffffffffffffffffffffffffff1684528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168584015292840192604090920191600101613296565b505067ffffffffffffffff83860151168387015260408501519250610f2460408701847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169052565b6020815260006120146020830184613276565b60408101611a0a8284805167ffffffffffffffff908116835260209182015116910152565b67ffffffffffffffff81811683821601908082111561338f5761338f612d21565b5092915050565b6020815260008251608060208401526133b260a0840182613276565b905060208401516133dd6040850182805167ffffffffffffffff908116835260209182015116910152565b5060408401516080840152809150509291505056fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCommitStoreConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PausedError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structCommitStore.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"ReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceEpochAndRound\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUnpausedAndARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"rootToReset\",\"type\":\"bytes32[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint40\",\"name\":\"latestPriceEpochAndRound\",\"type\":\"uint40\"}],\"name\":\"setLatestPriceEpochAndRound\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"}],\"name\":\"setMinSeqNr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedLeaves\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x61014060405260098054600165ff000000000160401b03191660011790553480156200002a57600080fd5b506040516200384c3803806200384c8339810160408190526200004d9162000272565b600033808281620000a55760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d857620000d88162000192565b50505015156080524660a05260408101516001600160a01b0316158062000107575080516001600160401b0316155b806200011e575060208101516001600160401b0316155b8062000135575060608101516001600160a01b0316155b156200015457604051631fc5f15f60e11b815260040160405180910390fd5b80516001600160401b0390811660c05260208201511660e05260408101516001600160a01b0390811661010052606090910151166101205262000306565b336001600160a01b03821603620001ec5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200009c565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160401b03811681146200025557600080fd5b919050565b80516001600160a01b03811681146200025557600080fd5b6000608082840312156200028557600080fd5b604051608081016001600160401b0381118282101715620002b657634e487b7160e01b600052604160045260246000fd5b604052620002c4836200023d565b8152620002d4602084016200023d565b6020820152620002e7604084016200025a565b6040820152620002fa606084016200025a565b60608201529392505050565b60805160a05160c05160e05161010051610120516134b7620003956000396000818161026d01528181610537015281816111730152818161199f01528181611bee015261206b0152600081816102310152611bc70152600081816102010152611ba00152600081816101d10152611b710152600081816112ee015261133a015260006113b501526134b76000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c806379ba5097116100e3578063ad7a22f81161008c578063f2fde38b11610066578063f2fde38b146104fa578063f47a86901461050d578063ff888fb11461052057600080fd5b8063ad7a22f8146104b4578063afcb95d7146104c7578063b1dc65a4146104e757600080fd5b80638da5cb5b116100bd5780638da5cb5b146104645780638db94e441461048c578063a7206cd61461049457600080fd5b806379ba50971461042457806381ff70481461042c5780638456cb591461045c57600080fd5b806332048875116101455780635c975abb1161011f5780635c975abb146103b4578063666cab8d146103d05780637437ff9f146103e557600080fd5b806332048875146103795780633f4ba83a1461039a5780634120fccd146103a257600080fd5b8063181f5a7711610176578063181f5a77146103085780631ef381741461035157806329b980e41461036657600080fd5b806306285c691461019d5780630a6cd30d146102c057806310c374ed146102d8575b600080fd5b6102aa60408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b6040516102b79190612656565b60405180910390f35b6102c8610533565b60405190151581526020016102b7565b60095468010000000000000000900464ffffffffff165b60405167ffffffffffffffff90911681526020016102b7565b6103446040518060400160405280601181526020017f436f6d6d697453746f726520312e322e3000000000000000000000000000000081525081565b6040516102b79190612713565b61036461035f366004612966565b6105ca565b005b610364610374366004612a33565b610deb565b61038c610387366004612aa6565b610e37565b6040519081526020016102b7565b610364610f2d565b60095467ffffffffffffffff166102ef565b6009546d0100000000000000000000000000900460ff166102c8565b6103d8610f93565b6040516102b79190612b6b565b604080516020808201835260009091528151808201835260085473ffffffffffffffffffffffffffffffffffffffff16908190529151918252016102b7565b610364611002565b6004546002546040805163ffffffff808516825264010000000090940490931660208401528201526060016102b7565b6103646110ff565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102b7565b6102c861116f565b61038c6104a2366004612b7e565b6000908152600a602052604090205490565b6103646104c2366004612b97565b611226565b6040805160018152600060208201819052918101919091526060016102b7565b6103646104f5366004612bb2565b611269565b610364610508366004612c97565b611889565b61036461051b366004612cb4565b61189d565b6102c861052e366004612b7e565b61193c565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c49190612cf6565b15905090565b855185518560ff16601f831115610642576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e6572730000000000000000000000000000000060448201526064015b60405180910390fd5b806000036106ac576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610639565b81831461073a576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610639565b610745816003612d47565b83116107ad576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610639565b6107b5611a10565b6107be86611a93565b60065460005b818110156108ba5760056000600683815481106107e3576107e3612d5e565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556007805460059291908490811061085357610853612d5e565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556108b381612d8d565b90506107c4565b50895160005b81811015610c935760008c82815181106108dc576108dc612d5e565b60200260200101519050600060028111156108f9576108f9612dc5565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff16600281111561093857610938612dc5565b1461099f576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610639565b73ffffffffffffffffffffffffffffffffffffffff81166109ec576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016001905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610a9c57610a9c612dc5565b021790555090505060008c8381518110610ab857610ab8612d5e565b6020026020010151905060006002811115610ad557610ad5612dc5565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff166002811115610b1457610b14612dc5565b14610b7b576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610639565b73ffffffffffffffffffffffffffffffffffffffff8116610bc8576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff84168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610c7857610c78612dc5565b0217905550905050505080610c8c90612d8d565b90506108c0565b508a51610ca79060069060208e0190612598565b508951610cbb9060079060208d0190612598565b506003805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908c161717905560048054610d41914691309190600090610d139063ffffffff16612df4565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168e8e8e8e8e8e611c4f565b600260000181905550600060048054906101000a900463ffffffff169050436004806101000a81548163ffffffff021916908363ffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600260000154600460009054906101000a900463ffffffff168f8f8f8f8f8f604051610dd599989796959493929190612e17565b60405180910390a1505050505050505050505050565b610df3611a10565b6009805464ffffffffff90921668010000000000000000027fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff909216919091179055565b6009546000906d0100000000000000000000000000900460ff1615610e88576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610ef987878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a925089918291850190849080828437600092019190915250889250611cfa915050565b9050610f048161193c565b610f12576000915050610f24565b6000908152600a602052604090205490505b95945050505050565b610f35611a10565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60606007805480602002602001604051908101604052809291908181526020018280548015610ff857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610fcd575b5050505050905090565b60015473ffffffffffffffffffffffffffffffffffffffff163314611083576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610639565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611107611a10565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff166d01000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610f89565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112009190612cf6565b15801561122157506009546d0100000000000000000000000000900460ff16155b905090565b61122e611a10565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff92909216919091179055565b611278878760208b013561201b565b6040805160608101825260025480825260035460ff8082166020850152610100909104169282019290925289359182146112eb5780516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604401610639565b467f00000000000000000000000000000000000000000000000000000000000000001461136c576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610639565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a160007f00000000000000000000000000000000000000000000000000000000000000001561140e576002826020015183604001516113ef9190612ead565b6113f99190612ec6565b611404906001612ead565b60ff169050611424565b602082015161141e906001612ead565b60ff1690505b86811461145d576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b868514611496576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526005602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156114d9576114d9612dc5565b60028111156114ea576114ea612dc5565b905250905060028160200151600281111561150757611507612dc5565b14801561154e57506007816000015160ff168154811061152957611529612d5e565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b611584576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506000611592866020612d47565b61159d896020612d47565b6115a98c610144612f0f565b6115b39190612f0f565b6115bd9190612f0f565b9050368114611601576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610639565b5060008a8a604051611614929190612f22565b60405190819003812061162b918e90602001612f32565b60405160208183030381529060405280519060200120905061164b612622565b8860005b818110156118785760006001858a846020811061166e5761166e612d5e565b61167b91901a601b612ead565b8f8f8681811061168d5761168d612d5e565b905060200201358e8e878181106116a6576116a6612d5e565b90506020020135604051600081526020016040526040516116e3949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611705573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152848220848601909552845460ff808216865293975091955092939284019161010090910416600281111561178857611788612dc5565b600281111561179957611799612dc5565b90525090506001816020015160028111156117b6576117b6612dc5565b146117ed576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061180457611804612d5e565b602002015115611840576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061185b5761185b612d5e565b9115156020909202015250611871905081612d8d565b905061164f565b505050505050505050505050505050565b611891611a10565b61189a81612428565b50565b6118a5611a10565b60005b818110156119375760008383838181106118c4576118c4612d5e565b9050602002013590506118d68161193c565b611926576000818152600a602052604080822091909155517f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f129061191d9083815260200190565b60405180910390a15b5061193081612d8d565b90506118a8565b505050565b6040805180820182523081526020810183815291517f4d616771000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa1580156119e6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a0a9190612cf6565b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611a91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610639565b565b600081806020019051810190611aa99190612f46565b805190915073ffffffffffffffffffffffffffffffffffffffff16611afa576040517f3f8be2be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff928316179055600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff169055604080516080810182527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff90811682527f00000000000000000000000000000000000000000000000000000000000000001660208201527f00000000000000000000000000000000000000000000000000000000000000008316818301527f00000000000000000000000000000000000000000000000000000000000000009092166060830152517fc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec391611c43918490612f92565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a604051602001611c739998979695949392919061300f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b8251825160009190818303611d3b576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590611d4f57506101018111155b611d85576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82820101610100811115611de6576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003611e135786600081518110611e0157611e01612d5e565b60200260200101519350505050612014565b60008167ffffffffffffffff811115611e2e57611e2e612726565b604051908082528060200260200182016040528015611e57578160200160208202803683370190505b50905060008080805b85811015611f9a5760006001821b8b811603611ebb5788851015611ea4578c5160018601958e918110611e9557611e95612d5e565b60200260200101519050611edd565b8551600185019487918110611e9557611e95612d5e565b8b5160018401938d918110611ed257611ed2612d5e565b602002602001015190505b600089861015611f0d578d5160018701968f918110611efe57611efe612d5e565b60200260200101519050611f2f565b8651600186019588918110611f2457611f24612d5e565b602002602001015190505b82851115611f69576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f73828261251d565b878481518110611f8557611f85612d5e565b60209081029190910101525050600101611e60565b506001850382148015611fac57508683145b8015611fb757508581145b611fed576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83600186038151811061200257612002612d5e565b60200260200101519750505050505050505b9392505050565b6009546d0100000000000000000000000000900460ff1615612069576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120f89190612cf6565b1561212f576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061213d8385018561319b565b8051515190915015158061215657508051602001515115155b1561228e5760095464ffffffffff8084166801000000000000000090920416101561225357600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff166801000000000000000064ffffffffff85160217905560085481516040517f3937306f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691633937306f9161220d916004016133ee565b600060405180830381600087803b15801561222757600080fd5b505af115801561223b573d6000803e3d6000fd5b50505050604081015161224e5750505050565b61228e565b604081015161228e576040517ff803a2ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101515160095467ffffffffffffffff90811691161415806122c9575060208082015190810151905167ffffffffffffffff9182169116115b156123065780602001516040517fbb1ae18d0000000000000000000000000000000000000000000000000000000081526004016106399190613401565b6040810151612341576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040808201516000908152600a60205220541561238a576040517fa0bce24f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602080820151015161239d906001613426565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790556040818101516000908152600a602052819020429055517f291698c01aa71f912280535d88a00d2c59fb63530a3f5d0098560468acb9ebf59061241a90839061344e565b60405180910390a150505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036124a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610639565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600081831061255f5760408051600160208083019190915281830185905260608083018790528351808403909101815260809092019092528051910120612014565b60408051600160208083019190915281830186905260608083018690528351808403909101815260809092019092528051910120612014565b828054828255906000526020600020908101928215612612579160200282015b8281111561261257825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906125b8565b5061261e929150612641565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b8082111561261e5760008155600101612642565b60808101611a0a828467ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b6000815180845260005b818110156126d5576020818501810151868301820152016126b9565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061201460208301846126af565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561277857612778612726565b60405290565b6040516060810167ffffffffffffffff8111828210171561277857612778612726565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156127e8576127e8612726565b604052919050565b600067ffffffffffffffff82111561280a5761280a612726565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff8116811461189a57600080fd5b600082601f83011261284757600080fd5b8135602061285c612857836127f0565b6127a1565b82815260059290921b8401810191818101908684111561287b57600080fd5b8286015b8481101561289f57803561289281612814565b835291830191830161287f565b509695505050505050565b803560ff811681146128bb57600080fd5b919050565b600082601f8301126128d157600080fd5b813567ffffffffffffffff8111156128eb576128eb612726565b61291c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016127a1565b81815284602083860101111561293157600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff811681146128bb57600080fd5b60008060008060008060c0878903121561297f57600080fd5b863567ffffffffffffffff8082111561299757600080fd5b6129a38a838b01612836565b975060208901359150808211156129b957600080fd5b6129c58a838b01612836565b96506129d360408a016128aa565b955060608901359150808211156129e957600080fd5b6129f58a838b016128c0565b9450612a0360808a0161294e565b935060a0890135915080821115612a1957600080fd5b50612a2689828a016128c0565b9150509295509295509295565b600060208284031215612a4557600080fd5b813564ffffffffff8116811461201457600080fd5b60008083601f840112612a6c57600080fd5b50813567ffffffffffffffff811115612a8457600080fd5b6020830191508360208260051b8501011115612a9f57600080fd5b9250929050565b600080600080600060608688031215612abe57600080fd5b853567ffffffffffffffff80821115612ad657600080fd5b612ae289838a01612a5a565b90975095506020880135915080821115612afb57600080fd5b50612b0888828901612a5a565b96999598509660400135949350505050565b600081518084526020808501945080840160005b83811015612b6057815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101612b2e565b509495945050505050565b6020815260006120146020830184612b1a565b600060208284031215612b9057600080fd5b5035919050565b600060208284031215612ba957600080fd5b6120148261294e565b60008060008060008060008060e0898b031215612bce57600080fd5b606089018a811115612bdf57600080fd5b8998503567ffffffffffffffff80821115612bf957600080fd5b818b0191508b601f830112612c0d57600080fd5b813581811115612c1c57600080fd5b8c6020828501011115612c2e57600080fd5b6020830199508098505060808b0135915080821115612c4c57600080fd5b612c588c838d01612a5a565b909750955060a08b0135915080821115612c7157600080fd5b50612c7e8b828c01612a5a565b999c989b50969995989497949560c00135949350505050565b600060208284031215612ca957600080fd5b813561201481612814565b60008060208385031215612cc757600080fd5b823567ffffffffffffffff811115612cde57600080fd5b612cea85828601612a5a565b90969095509350505050565b600060208284031215612d0857600080fd5b8151801515811461201457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417611a0a57611a0a612d18565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612dbe57612dbe612d18565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600063ffffffff808316818103612e0d57612e0d612d18565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152612e478184018a612b1a565b90508281036080840152612e5b8189612b1a565b905060ff871660a084015282810360c0840152612e7881876126af565b905067ffffffffffffffff851660e0840152828103610100840152612e9d81856126af565b9c9b505050505050505050505050565b60ff8181168382160190811115611a0a57611a0a612d18565b600060ff831680612f00577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b8060ff84160491505092915050565b80820180821115611a0a57611a0a612d18565b8183823760009101908152919050565b828152606082602083013760800192915050565b600060208284031215612f5857600080fd5b6040516020810181811067ffffffffffffffff82111715612f7b57612f7b612726565b6040528251612f8981612814565b81529392505050565b60a08101612feb828567ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b73ffffffffffffffffffffffffffffffffffffffff83511660808301529392505050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526130568285018b612b1a565b9150838203608085015261306a828a612b1a565b915060ff881660a085015283820360c085015261308782886126af565b90861660e08501528381036101008501529050612e9d81856126af565b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146128bb57600080fd5b600082601f8301126130e157600080fd5b813560206130f1612857836127f0565b82815260069290921b8401810191818101908684111561311057600080fd5b8286015b8481101561289f576040818903121561312d5760008081fd5b613135612755565b61313e8261294e565b815261314b8583016130a4565b81860152835291830191604001613114565b60006040828403121561316f57600080fd5b613177612755565b90506131828261294e565b81526131906020830161294e565b602082015292915050565b600060208083850312156131ae57600080fd5b823567ffffffffffffffff808211156131c657600080fd5b90840190608082870312156131da57600080fd5b6131e261277e565b8235828111156131f157600080fd5b8301604081890381131561320457600080fd5b61320c612755565b82358581111561321b57600080fd5b8301601f81018b1361322c57600080fd5b803561323a612857826127f0565b81815260069190911b8201890190898101908d83111561325957600080fd5b928a01925b828410156132a95785848f0312156132765760008081fd5b61327e612755565b843561328981612814565b8152613296858d016130a4565b818d0152825292850192908a019061325e565b845250505082870135858111156132bf57600080fd5b6132cb8b8286016130d0565b828901525083526132de8986880161315d565b8684015260608501358184015250508094505050505092915050565b805160408084528151848201819052600092602091908201906060870190855b81811015613373578351805173ffffffffffffffffffffffffffffffffffffffff1684528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1685840152928401929185019160010161331a565b50508583015187820388850152805180835290840192506000918401905b808310156133e2578351805167ffffffffffffffff1683528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1685830152928401926001929092019190850190613391565b50979650505050505050565b60208152600061201460208301846132fa565b60408101611a0a8284805167ffffffffffffffff908116835260209182015116910152565b67ffffffffffffffff81811683821601908082111561344757613447612d18565b5092915050565b60208152600082516080602084015261346a60a08401826132fa565b905060208401516134956040850182805167ffffffffffffffff908116835260209182015116910152565b5060408401516080840152809150509291505056fea164736f6c6343000813000a", } var CommitStoreABI = CommitStoreMetaData.ABI @@ -1819,7 +1823,7 @@ func (CommitStorePaused) Topic() common.Hash { } func (CommitStoreReportAccepted) Topic() common.Hash { - return common.HexToHash("0xc14f9167b03b9a5725671c8678a54571219bff700e4a3665aef9e096c6a846f8") + return common.HexToHash("0x291698c01aa71f912280535d88a00d2c59fb63530a3f5d0098560468acb9ebf5") } func (CommitStoreRootRemoved) Topic() common.Hash { diff --git a/core/gethwrappers/ccip/generated/commit_store_helper/commit_store_helper.go b/core/gethwrappers/ccip/generated/commit_store_helper/commit_store_helper.go index 5b9dbf5985..1a48443edb 100644 --- a/core/gethwrappers/ccip/generated/commit_store_helper/commit_store_helper.go +++ b/core/gethwrappers/ccip/generated/commit_store_helper/commit_store_helper.go @@ -52,20 +52,24 @@ type CommitStoreStaticConfig struct { ArmProxy common.Address } -type InternalPriceUpdates struct { - TokenPriceUpdates []InternalTokenPriceUpdate +type InternalGasPriceUpdate struct { DestChainSelector uint64 UsdPerUnitGas *big.Int } +type InternalPriceUpdates struct { + TokenPriceUpdates []InternalTokenPriceUpdate + GasPriceUpdates []InternalGasPriceUpdate +} + type InternalTokenPriceUpdate struct { SourceToken common.Address UsdPerToken *big.Int } var CommitStoreHelperMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCommitStoreConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PausedError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structCommitStore.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"ReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceEpochAndRound\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUnpausedAndARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"commitReport\",\"type\":\"bytes\"},{\"internalType\":\"uint40\",\"name\":\"epochAndRound\",\"type\":\"uint40\"}],\"name\":\"report\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"rootToReset\",\"type\":\"bytes32[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint40\",\"name\":\"latestPriceEpochAndRound\",\"type\":\"uint40\"}],\"name\":\"setLatestPriceEpochAndRound\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"}],\"name\":\"setMinSeqNr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedLeaves\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x61014060405260098054600165ff000000000160401b03191660011790553480156200002a57600080fd5b5060405162003830380380620038308339810160408190526200004d9162000274565b80600033808281620000a65760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d957620000d98162000194565b50505015156080524660a05260408101516001600160a01b0316158062000108575080516001600160401b0316155b806200011f575060208101516001600160401b0316155b8062000136575060608101516001600160a01b0316155b156200015557604051631fc5f15f60e11b815260040160405180910390fd5b80516001600160401b0390811660c05260208201511660e05260408101516001600160a01b039081166101005260609091015116610120525062000308565b336001600160a01b03821603620001ee5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200009d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160401b03811681146200025757600080fd5b919050565b80516001600160a01b03811681146200025757600080fd5b6000608082840312156200028757600080fd5b604051608081016001600160401b0381118282101715620002b857634e487b7160e01b600052604160045260246000fd5b604052620002c6836200023f565b8152620002d6602084016200023f565b6020820152620002e9604084016200025c565b6040820152620002fc606084016200025c565b60608201529392505050565b60805160a05160c05160e0516101005161012051613499620003976000396000818161027801528181610555015281816111a1015281816119c801528181611a89015261202d01526000818161023c015261200601526000818161020c0152611fdf0152600081816101dc0152611fb001526000818161131c0152611368015260006113e301526134996000f3fe608060405234801561001057600080fd5b50600436106101a35760003560e01c80637437ff9f116100ee578063a7206cd611610097578063b1dc65a411610071578063b1dc65a414610505578063f2fde38b14610518578063f47a86901461052b578063ff888fb11461053e57600080fd5b8063a7206cd6146104b2578063ad7a22f8146104d2578063afcb95d7146104e557600080fd5b80638456cb59116100c85780638456cb591461047a5780638da5cb5b146104825780638db94e44146104aa57600080fd5b80637437ff9f1461040357806379ba50971461044257806381ff70481461044a57600080fd5b806329b980e4116101505780634120fccd1161012a5780634120fccd146103c05780635c975abb146103d2578063666cab8d146103ee57600080fd5b806329b980e41461038457806332048875146103975780633f4ba83a146103b857600080fd5b8063181f5a7711610181578063181f5a77146103135780631dc18e561461035c5780631ef381741461037157600080fd5b806306285c69146101a85780630a6cd30d146102cb57806310c374ed146102e3575b600080fd5b6102b560408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b6040516102c29190612688565b60405180910390f35b6102d3610551565b60405190151581526020016102c2565b60095468010000000000000000900464ffffffffff165b60405167ffffffffffffffff90911681526020016102c2565b61034f6040518060400160405280601181526020017f436f6d6d697453746f726520312e322e3000000000000000000000000000000081525081565b6040516102c29190612745565b61036f61036a3660046127bb565b6105e8565b005b61036f61037f366004612a4a565b6105f8565b61036f610392366004612b17565b610e19565b6103aa6103a5366004612b77565b610e65565b6040519081526020016102c2565b61036f610f5b565b60095467ffffffffffffffff166102fa565b6009546d0100000000000000000000000000900460ff166102d3565b6103f6610fc1565b6040516102c29190612c3c565b604080516020808201835260009091528151808201835260085473ffffffffffffffffffffffffffffffffffffffff16908190529151918252016102c2565b61036f611030565b6004546002546040805163ffffffff808516825264010000000090940490931660208401528201526060016102c2565b61036f61112d565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102c2565b6102d361119d565b6103aa6104c0366004612c4f565b6000908152600a602052604090205490565b61036f6104e0366004612c68565b611254565b6040805160018152600060208201819052918101919091526060016102c2565b61036f610513366004612c83565b611297565b61036f610526366004612d3a565b6118b7565b61036f610539366004612d57565b6118cb565b6102d361054c366004612c4f565b611965565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e29190612d99565b15905090565b6105f3838383611a39565b505050565b855185518560ff16601f831115610670576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e6572730000000000000000000000000000000060448201526064015b60405180910390fd5b806000036106da576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610667565b818314610768576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610667565b610773816003612dea565b83116107db576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610667565b6107e3611e4f565b6107ec86611ed2565b60065460005b818110156108e857600560006006838154811061081157610811612e01565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556007805460059291908490811061088157610881612e01565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556108e181612e30565b90506107f2565b50895160005b81811015610cc15760008c828151811061090a5761090a612e01565b602002602001015190506000600281111561092757610927612e68565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff16600281111561096657610966612e68565b146109cd576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610667565b73ffffffffffffffffffffffffffffffffffffffff8116610a1a576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016001905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610aca57610aca612e68565b021790555090505060008c8381518110610ae657610ae6612e01565b6020026020010151905060006002811115610b0357610b03612e68565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff166002811115610b4257610b42612e68565b14610ba9576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610667565b73ffffffffffffffffffffffffffffffffffffffff8116610bf6576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff84168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610ca657610ca6612e68565b0217905550905050505080610cba90612e30565b90506108ee565b508a51610cd59060069060208e01906125ca565b508951610ce99060079060208d01906125ca565b506003805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908c161717905560048054610d6f914691309190600090610d419063ffffffff16612e97565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168e8e8e8e8e8e61208e565b600260000181905550600060048054906101000a900463ffffffff169050436004806101000a81548163ffffffff021916908363ffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600260000154600460009054906101000a900463ffffffff168f8f8f8f8f8f604051610e0399989796959493929190612eba565b60405180910390a1505050505050505050505050565b610e21611e4f565b6009805464ffffffffff90921668010000000000000000027fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff909216919091179055565b6009546000906d0100000000000000000000000000900460ff1615610eb6576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610f2787878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a925089918291850190849080828437600092019190915250889250612139915050565b9050610f3281611965565b610f40576000915050610f52565b6000908152600a602052604090205490505b95945050505050565b610f63611e4f565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b6060600780548060200260200160405190810160405280929190818152602001828054801561102657602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610ffb575b5050505050905090565b60015473ffffffffffffffffffffffffffffffffffffffff1633146110b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610667565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611135611e4f565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff166d01000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610fb7565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561120a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122e9190612d99565b15801561124f57506009546d0100000000000000000000000000900460ff16155b905090565b61125c611e4f565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff92909216919091179055565b6112a6878760208b0135611a39565b6040805160608101825260025480825260035460ff8082166020850152610100909104169282019290925289359182146113195780516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604401610667565b467f00000000000000000000000000000000000000000000000000000000000000001461139a576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610667565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a160007f00000000000000000000000000000000000000000000000000000000000000001561143c5760028260200151836040015161141d9190612f50565b6114279190612f69565b611432906001612f50565b60ff169050611452565b602082015161144c906001612f50565b60ff1690505b86811461148b576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8685146114c4576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526005602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561150757611507612e68565b600281111561151857611518612e68565b905250905060028160200151600281111561153557611535612e68565b14801561157c57506007816000015160ff168154811061155757611557612e01565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b6115b2576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060006115c0866020612dea565b6115cb896020612dea565b6115d78c610144612fb2565b6115e19190612fb2565b6115eb9190612fb2565b905036811461162f576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610667565b5060008a8a604051611642929190612fc5565b604051908190038120611659918e90602001612fd5565b604051602081830303815290604052805190602001209050611679612654565b8860005b818110156118a65760006001858a846020811061169c5761169c612e01565b6116a991901a601b612f50565b8f8f868181106116bb576116bb612e01565b905060200201358e8e878181106116d4576116d4612e01565b9050602002013560405160008152602001604052604051611711949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611733573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152848220848601909552845460ff80821686529397509195509293928401916101009091041660028111156117b6576117b6612e68565b60028111156117c7576117c7612e68565b90525090506001816020015160028111156117e4576117e4612e68565b1461181b576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061183257611832612e01565b60200201511561186e576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061188957611889612e01565b911515602090920201525061189f905081612e30565b905061167d565b505050505050505050505050505050565b6118bf611e4f565b6118c88161245a565b50565b6118d3611e4f565b60005b818110156105f35760008383838181106118f2576118f2612e01565b90506020020135905061190481611965565b611954576000818152600a602052604080822091909155517f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f129061194b9083815260200190565b60405180910390a15b5061195e81612e30565b90506118d6565b6040805180820182523081526020810183815291517f4d616771000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa158015611a0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a339190612d99565b92915050565b6009546d0100000000000000000000000000900460ff1615611a87576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611af2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b169190612d99565b15611b4d576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611b5b83850185613053565b80515151909150151580611b7d575080516020015167ffffffffffffffff1615155b15611cb55760095464ffffffffff80841668010000000000000000909204161015611c7a57600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff166801000000000000000064ffffffffff85160217905560085481516040517f98f5be1b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909216916398f5be1b91611c3491600401613272565b600060405180830381600087803b158015611c4e57600080fd5b505af1158015611c62573d6000803e3d6000fd5b505050506040810151611c755750505050565b611cb5565b6040810151611cb5576040517ff803a2ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101515160095467ffffffffffffffff9081169116141580611cf0575060208082015190810151905167ffffffffffffffff9182169116115b15611d2d5780602001516040517fbb1ae18d0000000000000000000000000000000000000000000000000000000081526004016106679190613285565b6040810151611d68576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040808201516000908152600a602052205415611db1576040517fa0bce24f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808201510151611dc49060016132aa565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790556040818101516000908152600a602052819020429055517fc14f9167b03b9a5725671c8678a54571219bff700e4a3665aef9e096c6a846f890611e419083906132d2565b60405180910390a150505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611ed0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610667565b565b600081806020019051810190611ee8919061332e565b805190915073ffffffffffffffffffffffffffffffffffffffff16611f39576040517f3f8be2be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff928316179055600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff169055604080516080810182527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff90811682527f00000000000000000000000000000000000000000000000000000000000000001660208201527f00000000000000000000000000000000000000000000000000000000000000008316818301527f00000000000000000000000000000000000000000000000000000000000000009092166060830152517fc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec39161208291849061337a565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a6040516020016120b2999897969594939291906133f7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b825182516000919081830361217a576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610101821180159061218e57506101018111155b6121c4576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82820101610100811115612225576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003612252578660008151811061224057612240612e01565b60200260200101519350505050612453565b60008167ffffffffffffffff81111561226d5761226d61280f565b604051908082528060200260200182016040528015612296578160200160208202803683370190505b50905060008080805b858110156123d95760006001821b8b8116036122fa57888510156122e3578c5160018601958e9181106122d4576122d4612e01565b6020026020010151905061231c565b85516001850194879181106122d4576122d4612e01565b8b5160018401938d91811061231157612311612e01565b602002602001015190505b60008986101561234c578d5160018701968f91811061233d5761233d612e01565b6020026020010151905061236e565b865160018601958891811061236357612363612e01565b602002602001015190505b828511156123a8576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6123b2828261254f565b8784815181106123c4576123c4612e01565b6020908102919091010152505060010161229f565b5060018503821480156123eb57508683145b80156123f657508581145b61242c576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83600186038151811061244157612441612e01565b60200260200101519750505050505050505b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036124d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610667565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008183106125915760408051600160208083019190915281830185905260608083018790528351808403909101815260809092019092528051910120612453565b60408051600160208083019190915281830186905260608083018690528351808403909101815260809092019092528051910120612453565b828054828255906000526020600020908101928215612644579160200282015b8281111561264457825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906125ea565b50612650929150612673565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b808211156126505760008155600101612674565b60808101611a33828467ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b6000815180845260005b81811015612707576020818501810151868301820152016126eb565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061245360208301846126e1565b60008083601f84011261276a57600080fd5b50813567ffffffffffffffff81111561278257600080fd5b60208301915083602082850101111561279a57600080fd5b9250929050565b803564ffffffffff811681146127b657600080fd5b919050565b6000806000604084860312156127d057600080fd5b833567ffffffffffffffff8111156127e757600080fd5b6127f386828701612758565b90945092506128069050602085016127a1565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156128615761286161280f565b60405290565b6040516060810167ffffffffffffffff811182821017156128615761286161280f565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156128d1576128d161280f565b604052919050565b600067ffffffffffffffff8211156128f3576128f361280f565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff811681146118c857600080fd5b600082601f83011261293057600080fd5b81356020612945612940836128d9565b61288a565b82815260059290921b8401810191818101908684111561296457600080fd5b8286015b8481101561298857803561297b816128fd565b8352918301918301612968565b509695505050505050565b803560ff811681146127b657600080fd5b600082601f8301126129b557600080fd5b813567ffffffffffffffff8111156129cf576129cf61280f565b612a0060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161288a565b818152846020838601011115612a1557600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff811681146127b657600080fd5b60008060008060008060c08789031215612a6357600080fd5b863567ffffffffffffffff80821115612a7b57600080fd5b612a878a838b0161291f565b97506020890135915080821115612a9d57600080fd5b612aa98a838b0161291f565b9650612ab760408a01612993565b95506060890135915080821115612acd57600080fd5b612ad98a838b016129a4565b9450612ae760808a01612a32565b935060a0890135915080821115612afd57600080fd5b50612b0a89828a016129a4565b9150509295509295509295565b600060208284031215612b2957600080fd5b612453826127a1565b60008083601f840112612b4457600080fd5b50813567ffffffffffffffff811115612b5c57600080fd5b6020830191508360208260051b850101111561279a57600080fd5b600080600080600060608688031215612b8f57600080fd5b853567ffffffffffffffff80821115612ba757600080fd5b612bb389838a01612b32565b90975095506020880135915080821115612bcc57600080fd5b50612bd988828901612b32565b96999598509660400135949350505050565b600081518084526020808501945080840160005b83811015612c3157815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101612bff565b509495945050505050565b6020815260006124536020830184612beb565b600060208284031215612c6157600080fd5b5035919050565b600060208284031215612c7a57600080fd5b61245382612a32565b60008060008060008060008060e0898b031215612c9f57600080fd5b606089018a811115612cb057600080fd5b8998503567ffffffffffffffff80821115612cca57600080fd5b612cd68c838d01612758565b909950975060808b0135915080821115612cef57600080fd5b612cfb8c838d01612b32565b909750955060a08b0135915080821115612d1457600080fd5b50612d218b828c01612b32565b999c989b50969995989497949560c00135949350505050565b600060208284031215612d4c57600080fd5b8135612453816128fd565b60008060208385031215612d6a57600080fd5b823567ffffffffffffffff811115612d8157600080fd5b612d8d85828601612b32565b90969095509350505050565b600060208284031215612dab57600080fd5b8151801515811461245357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417611a3357611a33612dbb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612e6157612e61612dbb565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600063ffffffff808316818103612eb057612eb0612dbb565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152612eea8184018a612beb565b90508281036080840152612efe8189612beb565b905060ff871660a084015282810360c0840152612f1b81876126e1565b905067ffffffffffffffff851660e0840152828103610100840152612f4081856126e1565b9c9b505050505050505050505050565b60ff8181168382160190811115611a3357611a33612dbb565b600060ff831680612fa3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b8060ff84160491505092915050565b80820180821115611a3357611a33612dbb565b8183823760009101908152919050565b828152606082602083013760800192915050565b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146127b657600080fd5b60006040828403121561302757600080fd5b61302f61283e565b905061303a82612a32565b815261304860208301612a32565b602082015292915050565b6000602080838503121561306657600080fd5b823567ffffffffffffffff8082111561307e57600080fd5b908401906080828703121561309257600080fd5b61309a612867565b8235828111156130a957600080fd5b8301606081890312156130bb57600080fd5b6130c3612867565b8135848111156130d257600080fd5b82019350601f840189136130e557600080fd5b83356130f3612940826128d9565b81815260069190911b8501870190878101908b83111561311257600080fd5b958801955b82871015613166576040878d0312156131305760008081fd5b61313861283e565b8735613143816128fd565b8152613150888b01612fe9565b818b015282526040969096019590880190613117565b8352506131769050828701612a32565b8682015261318660408301612fe9565b604082015282525061319a87848601613015565b93810193909352506060013560408201529392505050565b805160608084528151908401819052600091602091908201906080860190845b8181101561322d578351805173ffffffffffffffffffffffffffffffffffffffff1684528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1685840152928401926040909201916001016131d2565b505067ffffffffffffffff83860151168387015260408501519250610f5260408701847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169052565b60208152600061245360208301846131b2565b60408101611a338284805167ffffffffffffffff908116835260209182015116910152565b67ffffffffffffffff8181168382160190808211156132cb576132cb612dbb565b5092915050565b6020815260008251608060208401526132ee60a08401826131b2565b905060208401516133196040850182805167ffffffffffffffff908116835260209182015116910152565b50604084015160808401528091505092915050565b60006020828403121561334057600080fd5b6040516020810181811067ffffffffffffffff821117156133635761336361280f565b6040528251613371816128fd565b81529392505050565b60a081016133d3828567ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b73ffffffffffffffffffffffffffffffffffffffff83511660808301529392505050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b16604085015281606085015261343e8285018b612beb565b91508382036080850152613452828a612beb565b915060ff881660a085015283820360c085015261346f82886126e1565b90861660e08501528381036101008501529050612f4081856126e156fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCommitStoreConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PausedError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structCommitStore.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"ReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceEpochAndRound\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUnpausedAndARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"commitReport\",\"type\":\"bytes\"},{\"internalType\":\"uint40\",\"name\":\"epochAndRound\",\"type\":\"uint40\"}],\"name\":\"report\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"rootToReset\",\"type\":\"bytes32[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint40\",\"name\":\"latestPriceEpochAndRound\",\"type\":\"uint40\"}],\"name\":\"setLatestPriceEpochAndRound\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"}],\"name\":\"setMinSeqNr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedLeaves\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x61014060405260098054600165ff000000000160401b03191660011790553480156200002a57600080fd5b50604051620038e8380380620038e88339810160408190526200004d9162000274565b80600033808281620000a65760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d957620000d98162000194565b50505015156080524660a05260408101516001600160a01b0316158062000108575080516001600160401b0316155b806200011f575060208101516001600160401b0316155b8062000136575060608101516001600160a01b0316155b156200015557604051631fc5f15f60e11b815260040160405180910390fd5b80516001600160401b0390811660c05260208201511660e05260408101516001600160a01b039081166101005260609091015116610120525062000308565b336001600160a01b03821603620001ee5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200009d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160401b03811681146200025757600080fd5b919050565b80516001600160a01b03811681146200025757600080fd5b6000608082840312156200028757600080fd5b604051608081016001600160401b0381118282101715620002b857634e487b7160e01b600052604160045260246000fd5b604052620002c6836200023f565b8152620002d6602084016200023f565b6020820152620002e9604084016200025c565b6040820152620002fc606084016200025c565b60608201529392505050565b60805160a05160c05160e0516101005161012051613551620003976000396000818161027801528181610555015281816111a1015281816119c801528181611a89015261202401526000818161023c0152611ffd01526000818161020c0152611fd60152600081816101dc0152611fa701526000818161131c0152611368015260006113e301526135516000f3fe608060405234801561001057600080fd5b50600436106101a35760003560e01c80637437ff9f116100ee578063a7206cd611610097578063b1dc65a411610071578063b1dc65a414610505578063f2fde38b14610518578063f47a86901461052b578063ff888fb11461053e57600080fd5b8063a7206cd6146104b2578063ad7a22f8146104d2578063afcb95d7146104e557600080fd5b80638456cb59116100c85780638456cb591461047a5780638da5cb5b146104825780638db94e44146104aa57600080fd5b80637437ff9f1461040357806379ba50971461044257806381ff70481461044a57600080fd5b806329b980e4116101505780634120fccd1161012a5780634120fccd146103c05780635c975abb146103d2578063666cab8d146103ee57600080fd5b806329b980e41461038457806332048875146103975780633f4ba83a146103b857600080fd5b8063181f5a7711610181578063181f5a77146103135780631dc18e561461035c5780631ef381741461037157600080fd5b806306285c69146101a85780630a6cd30d146102cb57806310c374ed146102e3575b600080fd5b6102b560408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b6040516102c2919061267f565b60405180910390f35b6102d3610551565b60405190151581526020016102c2565b60095468010000000000000000900464ffffffffff165b60405167ffffffffffffffff90911681526020016102c2565b61034f6040518060400160405280601181526020017f436f6d6d697453746f726520312e322e3000000000000000000000000000000081525081565b6040516102c2919061273c565b61036f61036a3660046127b2565b6105e8565b005b61036f61037f366004612a41565b6105f8565b61036f610392366004612b0e565b610e19565b6103aa6103a5366004612b6e565b610e65565b6040519081526020016102c2565b61036f610f5b565b60095467ffffffffffffffff166102fa565b6009546d0100000000000000000000000000900460ff166102d3565b6103f6610fc1565b6040516102c29190612c33565b604080516020808201835260009091528151808201835260085473ffffffffffffffffffffffffffffffffffffffff16908190529151918252016102c2565b61036f611030565b6004546002546040805163ffffffff808516825264010000000090940490931660208401528201526060016102c2565b61036f61112d565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102c2565b6102d361119d565b6103aa6104c0366004612c46565b6000908152600a602052604090205490565b61036f6104e0366004612c5f565b611254565b6040805160018152600060208201819052918101919091526060016102c2565b61036f610513366004612c7a565b611297565b61036f610526366004612d31565b6118b7565b61036f610539366004612d4e565b6118cb565b6102d361054c366004612c46565b611965565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e29190612d90565b15905090565b6105f3838383611a39565b505050565b855185518560ff16601f831115610670576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e6572730000000000000000000000000000000060448201526064015b60405180910390fd5b806000036106da576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610667565b818314610768576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610667565b610773816003612de1565b83116107db576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610667565b6107e3611e46565b6107ec86611ec9565b60065460005b818110156108e857600560006006838154811061081157610811612df8565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556007805460059291908490811061088157610881612df8565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556108e181612e27565b90506107f2565b50895160005b81811015610cc15760008c828151811061090a5761090a612df8565b602002602001015190506000600281111561092757610927612e5f565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff16600281111561096657610966612e5f565b146109cd576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610667565b73ffffffffffffffffffffffffffffffffffffffff8116610a1a576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016001905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610aca57610aca612e5f565b021790555090505060008c8381518110610ae657610ae6612df8565b6020026020010151905060006002811115610b0357610b03612e5f565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff166002811115610b4257610b42612e5f565b14610ba9576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610667565b73ffffffffffffffffffffffffffffffffffffffff8116610bf6576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff84168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610ca657610ca6612e5f565b0217905550905050505080610cba90612e27565b90506108ee565b508a51610cd59060069060208e01906125c1565b508951610ce99060079060208d01906125c1565b506003805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908c161717905560048054610d6f914691309190600090610d419063ffffffff16612e8e565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168e8e8e8e8e8e612085565b600260000181905550600060048054906101000a900463ffffffff169050436004806101000a81548163ffffffff021916908363ffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600260000154600460009054906101000a900463ffffffff168f8f8f8f8f8f604051610e0399989796959493929190612eb1565b60405180910390a1505050505050505050505050565b610e21611e46565b6009805464ffffffffff90921668010000000000000000027fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff909216919091179055565b6009546000906d0100000000000000000000000000900460ff1615610eb6576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610f2787878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a925089918291850190849080828437600092019190915250889250612130915050565b9050610f3281611965565b610f40576000915050610f52565b6000908152600a602052604090205490505b95945050505050565b610f63611e46565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b6060600780548060200260200160405190810160405280929190818152602001828054801561102657602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610ffb575b5050505050905090565b60015473ffffffffffffffffffffffffffffffffffffffff1633146110b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610667565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611135611e46565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff166d01000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610fb7565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561120a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122e9190612d90565b15801561124f57506009546d0100000000000000000000000000900460ff16155b905090565b61125c611e46565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff92909216919091179055565b6112a6878760208b0135611a39565b6040805160608101825260025480825260035460ff8082166020850152610100909104169282019290925289359182146113195780516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604401610667565b467f00000000000000000000000000000000000000000000000000000000000000001461139a576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610667565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a160007f00000000000000000000000000000000000000000000000000000000000000001561143c5760028260200151836040015161141d9190612f47565b6114279190612f60565b611432906001612f47565b60ff169050611452565b602082015161144c906001612f47565b60ff1690505b86811461148b576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8685146114c4576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526005602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561150757611507612e5f565b600281111561151857611518612e5f565b905250905060028160200151600281111561153557611535612e5f565b14801561157c57506007816000015160ff168154811061155757611557612df8565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b6115b2576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060006115c0866020612de1565b6115cb896020612de1565b6115d78c610144612fa9565b6115e19190612fa9565b6115eb9190612fa9565b905036811461162f576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610667565b5060008a8a604051611642929190612fbc565b604051908190038120611659918e90602001612fcc565b60405160208183030381529060405280519060200120905061167961264b565b8860005b818110156118a65760006001858a846020811061169c5761169c612df8565b6116a991901a601b612f47565b8f8f868181106116bb576116bb612df8565b905060200201358e8e878181106116d4576116d4612df8565b9050602002013560405160008152602001604052604051611711949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611733573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152848220848601909552845460ff80821686529397509195509293928401916101009091041660028111156117b6576117b6612e5f565b60028111156117c7576117c7612e5f565b90525090506001816020015160028111156117e4576117e4612e5f565b1461181b576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061183257611832612df8565b60200201511561186e576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061188957611889612df8565b911515602090920201525061189f905081612e27565b905061167d565b505050505050505050505050505050565b6118bf611e46565b6118c881612451565b50565b6118d3611e46565b60005b818110156105f35760008383838181106118f2576118f2612df8565b90506020020135905061190481611965565b611954576000818152600a602052604080822091909155517f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f129061194b9083815260200190565b60405180910390a15b5061195e81612e27565b90506118d6565b6040805180820182523081526020810183815291517f4d616771000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa158015611a0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a339190612d90565b92915050565b6009546d0100000000000000000000000000900460ff1615611a87576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611af2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b169190612d90565b15611b4d576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611b5b838501856130d7565b80515151909150151580611b7457508051602001515115155b15611cac5760095464ffffffffff80841668010000000000000000909204161015611c7157600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff166801000000000000000064ffffffffff85160217905560085481516040517f3937306f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691633937306f91611c2b9160040161332a565b600060405180830381600087803b158015611c4557600080fd5b505af1158015611c59573d6000803e3d6000fd5b505050506040810151611c6c5750505050565b611cac565b6040810151611cac576040517ff803a2ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101515160095467ffffffffffffffff9081169116141580611ce7575060208082015190810151905167ffffffffffffffff9182169116115b15611d245780602001516040517fbb1ae18d000000000000000000000000000000000000000000000000000000008152600401610667919061333d565b6040810151611d5f576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040808201516000908152600a602052205415611da8576040517fa0bce24f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808201510151611dbb906001613362565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790556040818101516000908152600a602052819020429055517f291698c01aa71f912280535d88a00d2c59fb63530a3f5d0098560468acb9ebf590611e3890839061338a565b60405180910390a150505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611ec7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610667565b565b600081806020019051810190611edf91906133e6565b805190915073ffffffffffffffffffffffffffffffffffffffff16611f30576040517f3f8be2be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff928316179055600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff169055604080516080810182527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff90811682527f00000000000000000000000000000000000000000000000000000000000000001660208201527f00000000000000000000000000000000000000000000000000000000000000008316818301527f00000000000000000000000000000000000000000000000000000000000000009092166060830152517fc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec391612079918490613432565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a6040516020016120a9999897969594939291906134af565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b8251825160009190818303612171576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610101821180159061218557506101018111155b6121bb576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8282010161010081111561221c576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003612249578660008151811061223757612237612df8565b6020026020010151935050505061244a565b60008167ffffffffffffffff81111561226457612264612806565b60405190808252806020026020018201604052801561228d578160200160208202803683370190505b50905060008080805b858110156123d05760006001821b8b8116036122f157888510156122da578c5160018601958e9181106122cb576122cb612df8565b60200260200101519050612313565b85516001850194879181106122cb576122cb612df8565b8b5160018401938d91811061230857612308612df8565b602002602001015190505b600089861015612343578d5160018701968f91811061233457612334612df8565b60200260200101519050612365565b865160018601958891811061235a5761235a612df8565b602002602001015190505b8285111561239f576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6123a98282612546565b8784815181106123bb576123bb612df8565b60209081029190910101525050600101612296565b5060018503821480156123e257508683145b80156123ed57508581145b612423576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83600186038151811061243857612438612df8565b60200260200101519750505050505050505b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036124d0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610667565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000818310612588576040805160016020808301919091528183018590526060808301879052835180840390910181526080909201909252805191012061244a565b6040805160016020808301919091528183018690526060808301869052835180840390910181526080909201909252805191012061244a565b82805482825590600052602060002090810192821561263b579160200282015b8281111561263b57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906125e1565b5061264792915061266a565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115612647576000815560010161266b565b60808101611a33828467ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b6000815180845260005b818110156126fe576020818501810151868301820152016126e2565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061244a60208301846126d8565b60008083601f84011261276157600080fd5b50813567ffffffffffffffff81111561277957600080fd5b60208301915083602082850101111561279157600080fd5b9250929050565b803564ffffffffff811681146127ad57600080fd5b919050565b6000806000604084860312156127c757600080fd5b833567ffffffffffffffff8111156127de57600080fd5b6127ea8682870161274f565b90945092506127fd905060208501612798565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561285857612858612806565b60405290565b6040516060810167ffffffffffffffff8111828210171561285857612858612806565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156128c8576128c8612806565b604052919050565b600067ffffffffffffffff8211156128ea576128ea612806565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff811681146118c857600080fd5b600082601f83011261292757600080fd5b8135602061293c612937836128d0565b612881565b82815260059290921b8401810191818101908684111561295b57600080fd5b8286015b8481101561297f578035612972816128f4565b835291830191830161295f565b509695505050505050565b803560ff811681146127ad57600080fd5b600082601f8301126129ac57600080fd5b813567ffffffffffffffff8111156129c6576129c6612806565b6129f760207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601612881565b818152846020838601011115612a0c57600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff811681146127ad57600080fd5b60008060008060008060c08789031215612a5a57600080fd5b863567ffffffffffffffff80821115612a7257600080fd5b612a7e8a838b01612916565b97506020890135915080821115612a9457600080fd5b612aa08a838b01612916565b9650612aae60408a0161298a565b95506060890135915080821115612ac457600080fd5b612ad08a838b0161299b565b9450612ade60808a01612a29565b935060a0890135915080821115612af457600080fd5b50612b0189828a0161299b565b9150509295509295509295565b600060208284031215612b2057600080fd5b61244a82612798565b60008083601f840112612b3b57600080fd5b50813567ffffffffffffffff811115612b5357600080fd5b6020830191508360208260051b850101111561279157600080fd5b600080600080600060608688031215612b8657600080fd5b853567ffffffffffffffff80821115612b9e57600080fd5b612baa89838a01612b29565b90975095506020880135915080821115612bc357600080fd5b50612bd088828901612b29565b96999598509660400135949350505050565b600081518084526020808501945080840160005b83811015612c2857815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101612bf6565b509495945050505050565b60208152600061244a6020830184612be2565b600060208284031215612c5857600080fd5b5035919050565b600060208284031215612c7157600080fd5b61244a82612a29565b60008060008060008060008060e0898b031215612c9657600080fd5b606089018a811115612ca757600080fd5b8998503567ffffffffffffffff80821115612cc157600080fd5b612ccd8c838d0161274f565b909950975060808b0135915080821115612ce657600080fd5b612cf28c838d01612b29565b909750955060a08b0135915080821115612d0b57600080fd5b50612d188b828c01612b29565b999c989b50969995989497949560c00135949350505050565b600060208284031215612d4357600080fd5b813561244a816128f4565b60008060208385031215612d6157600080fd5b823567ffffffffffffffff811115612d7857600080fd5b612d8485828601612b29565b90969095509350505050565b600060208284031215612da257600080fd5b8151801515811461244a57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417611a3357611a33612db2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612e5857612e58612db2565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600063ffffffff808316818103612ea757612ea7612db2565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152612ee18184018a612be2565b90508281036080840152612ef58189612be2565b905060ff871660a084015282810360c0840152612f1281876126d8565b905067ffffffffffffffff851660e0840152828103610100840152612f3781856126d8565b9c9b505050505050505050505050565b60ff8181168382160190811115611a3357611a33612db2565b600060ff831680612f9a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b8060ff84160491505092915050565b80820180821115611a3357611a33612db2565b8183823760009101908152919050565b828152606082602083013760800192915050565b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146127ad57600080fd5b600082601f83011261301d57600080fd5b8135602061302d612937836128d0565b82815260069290921b8401810191818101908684111561304c57600080fd5b8286015b8481101561297f57604081890312156130695760008081fd5b613071612835565b61307a82612a29565b8152613087858301612fe0565b81860152835291830191604001613050565b6000604082840312156130ab57600080fd5b6130b3612835565b90506130be82612a29565b81526130cc60208301612a29565b602082015292915050565b600060208083850312156130ea57600080fd5b823567ffffffffffffffff8082111561310257600080fd5b908401906080828703121561311657600080fd5b61311e61285e565b82358281111561312d57600080fd5b8301604081890381131561314057600080fd5b613148612835565b82358581111561315757600080fd5b8301601f81018b1361316857600080fd5b8035613176612937826128d0565b81815260069190911b8201890190898101908d83111561319557600080fd5b928a01925b828410156131e55785848f0312156131b25760008081fd5b6131ba612835565b84356131c5816128f4565b81526131d2858d01612fe0565b818d0152825292850192908a019061319a565b845250505082870135858111156131fb57600080fd5b6132078b82860161300c565b8289015250835261321a89868801613099565b8684015260608501358184015250508094505050505092915050565b805160408084528151848201819052600092602091908201906060870190855b818110156132af578351805173ffffffffffffffffffffffffffffffffffffffff1684528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16858401529284019291850191600101613256565b50508583015187820388850152805180835290840192506000918401905b8083101561331e578351805167ffffffffffffffff1683528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16858301529284019260019290920191908501906132cd565b50979650505050505050565b60208152600061244a6020830184613236565b60408101611a338284805167ffffffffffffffff908116835260209182015116910152565b67ffffffffffffffff81811683821601908082111561338357613383612db2565b5092915050565b6020815260008251608060208401526133a660a0840182613236565b905060208401516133d16040850182805167ffffffffffffffff908116835260209182015116910152565b50604084015160808401528091505092915050565b6000602082840312156133f857600080fd5b6040516020810181811067ffffffffffffffff8211171561341b5761341b612806565b6040528251613429816128f4565b81529392505050565b60a0810161348b828567ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b73ffffffffffffffffffffffffffffffffffffffff83511660808301529392505050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526134f68285018b612be2565b9150838203608085015261350a828a612be2565b915060ff881660a085015283820360c085015261352782886126d8565b90861660e08501528381036101008501529050612f3781856126d856fea164736f6c6343000813000a", } var CommitStoreHelperABI = CommitStoreHelperMetaData.ABI @@ -1831,7 +1835,7 @@ func (CommitStoreHelperPaused) Topic() common.Hash { } func (CommitStoreHelperReportAccepted) Topic() common.Hash { - return common.HexToHash("0xc14f9167b03b9a5725671c8678a54571219bff700e4a3665aef9e096c6a846f8") + return common.HexToHash("0x291698c01aa71f912280535d88a00d2c59fb63530a3f5d0098560468acb9ebf5") } func (CommitStoreHelperRootRemoved) Topic() common.Hash { diff --git a/core/gethwrappers/ccip/generated/price_registry/price_registry.go b/core/gethwrappers/ccip/generated/price_registry/price_registry.go index 5e339fa855..b42e532150 100644 --- a/core/gethwrappers/ccip/generated/price_registry/price_registry.go +++ b/core/gethwrappers/ccip/generated/price_registry/price_registry.go @@ -30,12 +30,16 @@ var ( _ = abi.ConvertType ) -type InternalPriceUpdates struct { - TokenPriceUpdates []InternalTokenPriceUpdate +type InternalGasPriceUpdate struct { DestChainSelector uint64 UsdPerUnitGas *big.Int } +type InternalPriceUpdates struct { + TokenPriceUpdates []InternalTokenPriceUpdate + GasPriceUpdates []InternalGasPriceUpdate +} + type InternalTimestampedPackedUint224 struct { Value *big.Int Timestamp uint32 @@ -47,8 +51,8 @@ type InternalTokenPriceUpdate struct { } var PriceRegistryMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"priceUpdaters\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chain\",\"type\":\"uint64\"}],\"name\":\"ChainNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidStalenessThreshold\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpdaterOrOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timePassed\",\"type\":\"uint256\"}],\"name\":\"StaleGasPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timePassed\",\"type\":\"uint256\"}],\"name\":\"StaleTokenPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenNotSupported\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"priceUpdater\",\"type\":\"address\"}],\"name\":\"PriceUpdaterRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"priceUpdater\",\"type\":\"address\"}],\"name\":\"PriceUpdaterSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChain\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerUnitGasUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"feeTokensToAdd\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokensToRemove\",\"type\":\"address[]\"}],\"name\":\"applyFeeTokensUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"priceUpdatersToAdd\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"priceUpdatersToRemove\",\"type\":\"address[]\"}],\"name\":\"applyPriceUpdatersUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"fromToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fromTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"toToken\",\"type\":\"address\"}],\"name\":\"convertTokenAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestinationChainGasPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPriceUpdaters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStalenessThreshold\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getTokenAndGasPrices\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"tokenPrice\",\"type\":\"uint224\"},{\"internalType\":\"uint224\",\"name\":\"gasPriceValue\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getTokenPrices\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getValidatedTokenPrice\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"}],\"name\":\"updatePrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b5060405162002280380380620022808339810160408190526200003491620006fe565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be8162000133565b5050604080516000815260208101909152620000dd91508490620001de565b604080516000815260208101909152620000f99083906200033a565b8063ffffffff166000036200012157604051631151410960e11b815260040160405180910390fd5b63ffffffff1660805250620007fa9050565b336001600160a01b038216036200018d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005b825181101562000289576200021d83828151811062000204576200020462000786565b602002602001015160046200049160201b90919060201c565b15620002765782818151811062000238576200023862000786565b60200260200101516001600160a01b03167f34a02290b7920078c19f58e94b78c77eb9cc10195b20676e19bd3b82085893b860405160405180910390a25b6200028181620007b2565b9050620001e1565b5060005b81518110156200033557620002c9828281518110620002b057620002b062000786565b60200260200101516004620004b160201b90919060201c565b156200032257818181518110620002e457620002e462000786565b60200260200101516001600160a01b03167fff7dbb85c77ca68ca1f894d6498570e3d5095cd19466f07ee8d222b337e4068c60405160405180910390a25b6200032d81620007b2565b90506200028d565b505050565b60005b8251811015620003e5576200037983828151811062000360576200036062000786565b602002602001015160066200049160201b90919060201c565b15620003d25782818151811062000394576200039462000786565b60200260200101516001600160a01b03167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b620003dd81620007b2565b90506200033d565b5060005b81518110156200033557620004258282815181106200040c576200040c62000786565b60200260200101516006620004b160201b90919060201c565b156200047e5781818151811062000440576200044062000786565b60200260200101516001600160a01b03167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b6200048981620007b2565b9050620003e9565b6000620004a8836001600160a01b038416620004c8565b90505b92915050565b6000620004a8836001600160a01b0384166200051a565b60008181526001830160205260408120546200051157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620004ab565b506000620004ab565b600081815260018301602052604081205480156200061357600062000541600183620007ce565b85549091506000906200055790600190620007ce565b9050818114620005c35760008660000182815481106200057b576200057b62000786565b9060005260206000200154905080876000018481548110620005a157620005a162000786565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620005d757620005d7620007e4565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620004ab565b6000915050620004ab565b634e487b7160e01b600052604160045260246000fd5b80516001600160a01b03811681146200064c57600080fd5b919050565b600082601f8301126200066357600080fd5b815160206001600160401b03808311156200068257620006826200061e565b8260051b604051601f19603f83011681018181108482111715620006aa57620006aa6200061e565b604052938452858101830193838101925087851115620006c957600080fd5b83870191505b84821015620006f357620006e38262000634565b83529183019190830190620006cf565b979650505050505050565b6000806000606084860312156200071457600080fd5b83516001600160401b03808211156200072c57600080fd5b6200073a8783880162000651565b945060208601519150808211156200075157600080fd5b50620007608682870162000651565b925050604084015163ffffffff811681146200077b57600080fd5b809150509250925092565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201620007c757620007c76200079c565b5060010190565b81810381811115620004ab57620004ab6200079c565b634e487b7160e01b600052603160045260246000fd5b608051611a4e62000832600039600081816102eb01528181610ae101528181610b4a01528181610cab0152610d200152611a4e6000f3fe608060405234801561001057600080fd5b50600436106100ff5760003560e01c80638da5cb5b11610097578063cdc73d5111610066578063cdc73d511461032a578063d02641a014610332578063f2fde38b146103d4578063ffdb4b37146103e757600080fd5b80638da5cb5b146102a657806398f5be1b146102ce578063a6c94a73146102e1578063bfcd45661461031557600080fd5b8063514e8cff116100d3578063514e8cff146101d357806352877af01461027657806379ba50971461028b5780637afac3221461029357600080fd5b806241e5be14610104578063181f5a771461012a57806345ac924d146101735780634ab35b0b14610193575b600080fd5b6101176101123660046113d1565b61042f565b6040519081526020015b60405180910390f35b6101666040518060400160405280601381526020017f5072696365526567697374727920312e322e300000000000000000000000000081525081565b604051610121919061140d565b610186610181366004611479565b61049b565b60405161012191906114ee565b6101a66101a1366004611569565b61056f565b6040517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9091168152602001610121565b6102696101e136600461159c565b60408051808201909152600080825260208201525067ffffffffffffffff166000908152600260209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b60405161012191906115b7565b6102896102843660046116e1565b61057a565b005b610289610590565b6102896102a13660046116e1565b610692565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610121565b6102896102dc366004611745565b6106a4565b60405163ffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610121565b61031d6109dc565b6040516101219190611780565b61031d6109ed565b610269610340366004611569565b60408051808201909152600080825260208201525073ffffffffffffffffffffffffffffffffffffffff166000908152600360209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b6102896103e2366004611569565b6109f9565b6103fa6103f53660046117da565b610a0d565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff938416815292909116602083015201610121565b600061043a82610b98565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661046185610b98565b610489907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168561183c565b6104939190611853565b949350505050565b60608160008167ffffffffffffffff8111156104b9576104b96115f2565b6040519080825280602002602001820160405280156104fe57816020015b60408051808201909152600080825260208201528152602001906001900390816104d75790505b50905060005b82811015610564576105368686838181106105215761052161188e565b90506020020160208101906103409190611569565b8282815181106105485761054861188e565b60200260200101819052508061055d906118bd565b9050610504565b509150505b92915050565b600061056982610b98565b610582610d5c565b61058c8282610ddf565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610616576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61069a610d5c565b61058c8282610f3b565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906106d457506106d2600433611092565b155b1561070b576040517f46f0815400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061071782806118f5565b9050905060005b8181101561086957600061073284806118f5565b838181106107425761074261188e565b9050604002018036038101906107589190611989565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885173ffffffffffffffffffffffffffffffffffffffff9081166000908152600390975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a926108509290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250610862816118bd565b905061071e565b5061087a604083016020840161159c565b67ffffffffffffffff161561058c5760405180604001604052808360400160208101906108a791906119e4565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681526020014263ffffffff16815250600260008460200160208101906108eb919061159c565b67ffffffffffffffff168152602080820192909252604090810160002083519383015163ffffffff167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9094169390931790925561096891840190840161159c565b67ffffffffffffffff167fdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e6109a360608501604086016119e4565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90921682524260208301520160405180910390a25050565b60606109e860046110c4565b905090565b60606109e860066110c4565b610a01610d5c565b610a0a816110d1565b50565b67ffffffffffffffff811660009081526002602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff1691810182905282918203610ac5576040517f2e59db3a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8516600482015260240161060d565b6000816020015163ffffffff1642610add91906119ff565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff16811115610b7e576040517ff08bcb3e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015263ffffffff7f00000000000000000000000000000000000000000000000000000000000000001660248201526044810182905260640161060d565b610b8786610b98565b9151919350909150505b9250929050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff16918101829052901580610c40575080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16155b15610c8f576040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416600482015260240161060d565b6000816020015163ffffffff1642610ca791906119ff565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff16811115610d54576040517fc65fdfca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516600482015263ffffffff7f00000000000000000000000000000000000000000000000000000000000000001660248201526044810182905260640161060d565b505192915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ddd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161060d565b565b60005b8251811015610e8a57610e18838281518110610e0057610e0061188e565b602002602001015160046111c690919063ffffffff16565b15610e7a57828181518110610e2f57610e2f61188e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f34a02290b7920078c19f58e94b78c77eb9cc10195b20676e19bd3b82085893b860405160405180910390a25b610e83816118bd565b9050610de2565b5060005b8151811015610f3657610ec4828281518110610eac57610eac61188e565b602002602001015160046111e890919063ffffffff16565b15610f2657818181518110610edb57610edb61188e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fff7dbb85c77ca68ca1f894d6498570e3d5095cd19466f07ee8d222b337e4068c60405160405180910390a25b610f2f816118bd565b9050610e8e565b505050565b60005b8251811015610fe657610f74838281518110610f5c57610f5c61188e565b602002602001015160066111c690919063ffffffff16565b15610fd657828181518110610f8b57610f8b61188e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b610fdf816118bd565b9050610f3e565b5060005b8151811015610f36576110208282815181106110085761100861188e565b602002602001015160066111e890919063ffffffff16565b15611082578181815181106110375761103761188e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b61108b816118bd565b9050610fea565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415155b9392505050565b606060006110bd8361120a565b3373ffffffffffffffffffffffffffffffffffffffff821603611150576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161060d565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006110bd8373ffffffffffffffffffffffffffffffffffffffff8416611266565b60006110bd8373ffffffffffffffffffffffffffffffffffffffff84166112b5565b60608160000180548060200260200160405190810160405280929190818152602001828054801561125a57602002820191906000526020600020905b815481526020019060010190808311611246575b50505050509050919050565b60008181526001830160205260408120546112ad57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610569565b506000610569565b6000818152600183016020526040812054801561139e5760006112d96001836119ff565b85549091506000906112ed906001906119ff565b905081811461135257600086600001828154811061130d5761130d61188e565b90600052602060002001549050808760000184815481106113305761133061188e565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061136357611363611a12565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610569565b6000915050610569565b803573ffffffffffffffffffffffffffffffffffffffff811681146113cc57600080fd5b919050565b6000806000606084860312156113e657600080fd5b6113ef846113a8565b925060208401359150611404604085016113a8565b90509250925092565b600060208083528351808285015260005b8181101561143a5785810183015185820160400152820161141e565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b6000806020838503121561148c57600080fd5b823567ffffffffffffffff808211156114a457600080fd5b818501915085601f8301126114b857600080fd5b8135818111156114c757600080fd5b8660208260051b85010111156114dc57600080fd5b60209290920196919550909350505050565b602080825282518282018190526000919060409081850190868401855b8281101561155c5761154c84835180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16825260209081015163ffffffff16910152565b928401929085019060010161150b565b5091979650505050505050565b60006020828403121561157b57600080fd5b6110bd826113a8565b803567ffffffffffffffff811681146113cc57600080fd5b6000602082840312156115ae57600080fd5b6110bd82611584565b81517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260208083015163ffffffff169082015260408101610569565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261163257600080fd5b8135602067ffffffffffffffff8083111561164f5761164f6115f2565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611692576116926115f2565b6040529384528581018301938381019250878511156116b057600080fd5b83870191505b848210156116d6576116c7826113a8565b835291830191908301906116b6565b979650505050505050565b600080604083850312156116f457600080fd5b823567ffffffffffffffff8082111561170c57600080fd5b61171886838701611621565b9350602085013591508082111561172e57600080fd5b5061173b85828601611621565b9150509250929050565b60006020828403121561175757600080fd5b813567ffffffffffffffff81111561176e57600080fd5b8201606081850312156110bd57600080fd5b6020808252825182820181905260009190848201906040850190845b818110156117ce57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161179c565b50909695505050505050565b600080604083850312156117ed57600080fd5b6117f6836113a8565b915061180460208401611584565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176105695761056961180d565b600082611889577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036118ee576118ee61180d565b5060010190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261192a57600080fd5b83018035915067ffffffffffffffff82111561194557600080fd5b6020019150600681901b3603821315610b9157600080fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146113cc57600080fd5b60006040828403121561199b57600080fd5b6040516040810181811067ffffffffffffffff821117156119be576119be6115f2565b6040526119ca836113a8565b81526119d86020840161195d565b60208201529392505050565b6000602082840312156119f657600080fd5b6110bd8261195d565b818103818111156105695761056961180d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"priceUpdaters\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chain\",\"type\":\"uint64\"}],\"name\":\"ChainNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidStalenessThreshold\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpdaterOrOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timePassed\",\"type\":\"uint256\"}],\"name\":\"StaleGasPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timePassed\",\"type\":\"uint256\"}],\"name\":\"StaleTokenPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenNotSupported\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"priceUpdater\",\"type\":\"address\"}],\"name\":\"PriceUpdaterRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"priceUpdater\",\"type\":\"address\"}],\"name\":\"PriceUpdaterSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChain\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerUnitGasUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"feeTokensToAdd\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokensToRemove\",\"type\":\"address[]\"}],\"name\":\"applyFeeTokensUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"priceUpdatersToAdd\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"priceUpdatersToRemove\",\"type\":\"address[]\"}],\"name\":\"applyPriceUpdatersUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"fromToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fromTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"toToken\",\"type\":\"address\"}],\"name\":\"convertTokenAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestinationChainGasPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPriceUpdaters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStalenessThreshold\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getTokenAndGasPrices\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"tokenPrice\",\"type\":\"uint224\"},{\"internalType\":\"uint224\",\"name\":\"gasPriceValue\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getTokenPrices\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getValidatedTokenPrice\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"}],\"name\":\"updatePrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b506040516200227f3803806200227f8339810160408190526200003491620006fe565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be8162000133565b5050604080516000815260208101909152620000dd91508490620001de565b604080516000815260208101909152620000f99083906200033a565b8063ffffffff166000036200012157604051631151410960e11b815260040160405180910390fd5b63ffffffff1660805250620007fa9050565b336001600160a01b038216036200018d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005b825181101562000289576200021d83828151811062000204576200020462000786565b602002602001015160046200049160201b90919060201c565b15620002765782818151811062000238576200023862000786565b60200260200101516001600160a01b03167f34a02290b7920078c19f58e94b78c77eb9cc10195b20676e19bd3b82085893b860405160405180910390a25b6200028181620007b2565b9050620001e1565b5060005b81518110156200033557620002c9828281518110620002b057620002b062000786565b60200260200101516004620004b160201b90919060201c565b156200032257818181518110620002e457620002e462000786565b60200260200101516001600160a01b03167fff7dbb85c77ca68ca1f894d6498570e3d5095cd19466f07ee8d222b337e4068c60405160405180910390a25b6200032d81620007b2565b90506200028d565b505050565b60005b8251811015620003e5576200037983828151811062000360576200036062000786565b602002602001015160066200049160201b90919060201c565b15620003d25782818151811062000394576200039462000786565b60200260200101516001600160a01b03167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b620003dd81620007b2565b90506200033d565b5060005b81518110156200033557620004258282815181106200040c576200040c62000786565b60200260200101516006620004b160201b90919060201c565b156200047e5781818151811062000440576200044062000786565b60200260200101516001600160a01b03167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b6200048981620007b2565b9050620003e9565b6000620004a8836001600160a01b038416620004c8565b90505b92915050565b6000620004a8836001600160a01b0384166200051a565b60008181526001830160205260408120546200051157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620004ab565b506000620004ab565b600081815260018301602052604081205480156200061357600062000541600183620007ce565b85549091506000906200055790600190620007ce565b9050818114620005c35760008660000182815481106200057b576200057b62000786565b9060005260206000200154905080876000018481548110620005a157620005a162000786565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620005d757620005d7620007e4565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620004ab565b6000915050620004ab565b634e487b7160e01b600052604160045260246000fd5b80516001600160a01b03811681146200064c57600080fd5b919050565b600082601f8301126200066357600080fd5b815160206001600160401b03808311156200068257620006826200061e565b8260051b604051601f19603f83011681018181108482111715620006aa57620006aa6200061e565b604052938452858101830193838101925087851115620006c957600080fd5b83870191505b84821015620006f357620006e38262000634565b83529183019190830190620006cf565b979650505050505050565b6000806000606084860312156200071457600080fd5b83516001600160401b03808211156200072c57600080fd5b6200073a8783880162000651565b945060208601519150808211156200075157600080fd5b50620007608682870162000651565b925050604084015163ffffffff811681146200077b57600080fd5b809150509250925092565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201620007c757620007c76200079c565b5060010190565b81810381811115620004ab57620004ab6200079c565b634e487b7160e01b600052603160045260246000fd5b608051611a4d62000832600039600081816102eb01528181610acd01528181610b3601528181610c970152610d0c0152611a4d6000f3fe608060405234801561001057600080fd5b50600436106100ff5760003560e01c80637afac32211610097578063cdc73d5111610066578063cdc73d511461032a578063d02641a014610332578063f2fde38b146103d4578063ffdb4b37146103e757600080fd5b80637afac322146102a65780638da5cb5b146102b9578063a6c94a73146102e1578063bfcd45661461031557600080fd5b80634ab35b0b116100d35780634ab35b0b146101a8578063514e8cff146101e857806352877af01461028b57806379ba50971461029e57600080fd5b806241e5be14610104578063181f5a771461012a5780633937306f1461017357806345ac924d14610188575b600080fd5b6101176101123660046113bd565b61042f565b6040519081526020015b60405180910390f35b6101666040518060400160405280601381526020017f5072696365526567697374727920312e322e300000000000000000000000000081525081565b60405161012191906113f9565b610186610181366004611465565b61049b565b005b61019b6101963660046114a0565b6107bf565b6040516101219190611515565b6101bb6101b6366004611590565b610893565b6040517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9091168152602001610121565b61027e6101f63660046115c3565b60408051808201909152600080825260208201525067ffffffffffffffff166000908152600260209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b60405161012191906115de565b610186610299366004611731565b61089e565b6101866108b4565b6101866102b4366004611731565b6109b6565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610121565b60405163ffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610121565b61031d6109c8565b6040516101219190611795565b61031d6109d9565b61027e610340366004611590565b60408051808201909152600080825260208201525073ffffffffffffffffffffffffffffffffffffffff166000908152600360209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b6101866103e2366004611590565b6109e5565b6103fa6103f53660046117ef565b6109f9565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff938416815292909116602083015201610121565b600061043a82610b84565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661046185610b84565b610489907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1685611851565b6104939190611868565b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906104cb57506104c9600433610d48565b155b15610502576040517f46f0815400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061050e82806118a3565b9050905060005b8181101561066057600061052984806118a3565b838181106105395761053961190b565b90506040020180360381019061054f9190611966565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885173ffffffffffffffffffffffffffffffffffffffff9081166000908152600390975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a926106479290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250610659816119a3565b9050610515565b50600061067060208401846118a3565b9050905060005b818110156107b957600061068e60208601866118a3565b8381811061069e5761069e61190b565b9050604002018036038101906106b491906119db565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885167ffffffffffffffff9081166000908152600290975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927fdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e926107a09290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a2506107b2816119a3565b9050610677565b50505050565b60608160008167ffffffffffffffff8111156107dd576107dd611619565b60405190808252806020026020018201604052801561082257816020015b60408051808201909152600080825260208201528152602001906001900390816107fb5790505b50905060005b828110156108885761085a8686838181106108455761084561190b565b90506020020160208101906103409190611590565b82828151811061086c5761086c61190b565b602002602001018190525080610881906119a3565b9050610828565b509150505b92915050565b600061088d82610b84565b6108a6610d7a565b6108b08282610dfd565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461093a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6109be610d7a565b6108b08282610f59565b60606109d460046110b0565b905090565b60606109d460066110b0565b6109ed610d7a565b6109f6816110bd565b50565b67ffffffffffffffff811660009081526002602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff1691810182905282918203610ab1576040517f2e59db3a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610931565b6000816020015163ffffffff1642610ac991906119fe565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff16811115610b6a576040517ff08bcb3e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401610931565b610b7386610b84565b9151919350909150505b9250929050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff16918101829052901580610c2c575080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16155b15610c7b576040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610931565b6000816020015163ffffffff1642610c9391906119fe565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff16811115610d40576040517fc65fdfca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401610931565b505192915050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415155b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610dfb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610931565b565b60005b8251811015610ea857610e36838281518110610e1e57610e1e61190b565b602002602001015160046111b290919063ffffffff16565b15610e9857828181518110610e4d57610e4d61190b565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f34a02290b7920078c19f58e94b78c77eb9cc10195b20676e19bd3b82085893b860405160405180910390a25b610ea1816119a3565b9050610e00565b5060005b8151811015610f5457610ee2828281518110610eca57610eca61190b565b602002602001015160046111d490919063ffffffff16565b15610f4457818181518110610ef957610ef961190b565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fff7dbb85c77ca68ca1f894d6498570e3d5095cd19466f07ee8d222b337e4068c60405160405180910390a25b610f4d816119a3565b9050610eac565b505050565b60005b825181101561100457610f92838281518110610f7a57610f7a61190b565b602002602001015160066111b290919063ffffffff16565b15610ff457828181518110610fa957610fa961190b565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b610ffd816119a3565b9050610f5c565b5060005b8151811015610f545761103e8282815181106110265761102661190b565b602002602001015160066111d490919063ffffffff16565b156110a0578181815181106110555761105561190b565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b6110a9816119a3565b9050611008565b60606000610d73836111f6565b3373ffffffffffffffffffffffffffffffffffffffff82160361113c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610931565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000610d738373ffffffffffffffffffffffffffffffffffffffff8416611252565b6000610d738373ffffffffffffffffffffffffffffffffffffffff84166112a1565b60608160000180548060200260200160405190810160405280929190818152602001828054801561124657602002820191906000526020600020905b815481526020019060010190808311611232575b50505050509050919050565b60008181526001830160205260408120546112995750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561088d565b50600061088d565b6000818152600183016020526040812054801561138a5760006112c56001836119fe565b85549091506000906112d9906001906119fe565b905081811461133e5760008660000182815481106112f9576112f961190b565b906000526020600020015490508087600001848154811061131c5761131c61190b565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061134f5761134f611a11565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061088d565b600091505061088d565b803573ffffffffffffffffffffffffffffffffffffffff811681146113b857600080fd5b919050565b6000806000606084860312156113d257600080fd5b6113db84611394565b9250602084013591506113f060408501611394565b90509250925092565b600060208083528351808285015260005b818110156114265785810183015185820160400152820161140a565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006020828403121561147757600080fd5b813567ffffffffffffffff81111561148e57600080fd5b820160408185031215610d7357600080fd5b600080602083850312156114b357600080fd5b823567ffffffffffffffff808211156114cb57600080fd5b818501915085601f8301126114df57600080fd5b8135818111156114ee57600080fd5b8660208260051b850101111561150357600080fd5b60209290920196919550909350505050565b602080825282518282018190526000919060409081850190868401855b828110156115835761157384835180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16825260209081015163ffffffff16910152565b9284019290850190600101611532565b5091979650505050505050565b6000602082840312156115a257600080fd5b610d7382611394565b803567ffffffffffffffff811681146113b857600080fd5b6000602082840312156115d557600080fd5b610d73826115ab565b81517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260208083015163ffffffff16908201526040810161088d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561166b5761166b611619565b60405290565b600082601f83011261168257600080fd5b8135602067ffffffffffffffff8083111561169f5761169f611619565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f830116810181811084821117156116e2576116e2611619565b60405293845285810183019383810192508785111561170057600080fd5b83870191505b848210156117265761171782611394565b83529183019190830190611706565b979650505050505050565b6000806040838503121561174457600080fd5b823567ffffffffffffffff8082111561175c57600080fd5b61176886838701611671565b9350602085013591508082111561177e57600080fd5b5061178b85828601611671565b9150509250929050565b6020808252825182820181905260009190848201906040850190845b818110156117e357835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016117b1565b50909695505050505050565b6000806040838503121561180257600080fd5b61180b83611394565b9150611819602084016115ab565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761088d5761088d611822565b60008261189e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126118d857600080fd5b83018035915067ffffffffffffffff8211156118f357600080fd5b6020019150600681901b3603821315610b7d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146113b857600080fd5b60006040828403121561197857600080fd5b611980611648565b61198983611394565b81526119976020840161193a565b60208201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036119d4576119d4611822565b5060010190565b6000604082840312156119ed57600080fd5b6119f5611648565b611989836115ab565b8181038181111561088d5761088d611822565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", } var PriceRegistryABI = PriceRegistryMetaData.ABI diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index a8beb856df..80fc1848cb 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -2,8 +2,8 @@ GETH_VERSION: 1.12.0 arm_contract: ../../../contracts/solc/v0.8.19/ARM.abi ../../../contracts/solc/v0.8.19/ARM.bin 893a2d007f5ffad2a118beccee72cf28913a2d6207f22b2028543139a5fdece0 arm_proxy_contract: ../../../contracts/solc/v0.8.19/ARMProxy.abi ../../../contracts/solc/v0.8.19/ARMProxy.bin f7b818c2ba31d8b12ea2dbaebc72c74e69640b7349b76c7415226cc4946075f2 burn_mint_token_pool: ../../../contracts/solc/v0.8.19/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.19/BurnMintTokenPool.bin aa87ca3c7881b7739b2b4677069f7293cad99b2e8342041b900d8cd49f2655fb -commit_store: ../../../contracts/solc/v0.8.19/CommitStore.abi ../../../contracts/solc/v0.8.19/CommitStore.bin 7d80f085f8249ef15e0850bf03698806c972125156f3476a1dafca54598f7f4d -commit_store_helper: ../../../contracts/solc/v0.8.19/CommitStoreHelper.abi ../../../contracts/solc/v0.8.19/CommitStoreHelper.bin 0891a1662bda54db424d12e80a56533cfd9859f7d94a3be147ad3caa46cad072 +commit_store: ../../../contracts/solc/v0.8.19/CommitStore.abi ../../../contracts/solc/v0.8.19/CommitStore.bin b971b915b36bdc5e4ce8aee6bb5ae7a5cdedc562874f87ca863c96c2529fcc5b +commit_store_helper: ../../../contracts/solc/v0.8.19/CommitStoreHelper.abi ../../../contracts/solc/v0.8.19/CommitStoreHelper.bin dd078eef6a55928e0cad79f40828a36cfa5c2789a664f37b56a7c215fb7c8932 custom_token_pool: ../../../contracts/solc/v0.8.19/CustomTokenPool.abi ../../../contracts/solc/v0.8.19/CustomTokenPool.bin 79ab937aa4493bf31fb0e57affd00555aad75205c90268e89674c28ea9e5e48f evm_2_evm_offramp: ../../../contracts/solc/v0.8.19/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.19/EVM2EVMOffRamp.bin bfea579e0b5100b6e90c2ea4d1533789ff037104fd03ba590e135772a0cf0997 evm_2_evm_offramp_helper: ../../../contracts/solc/v0.8.19/EVM2EVMOffRampHelper.abi ../../../contracts/solc/v0.8.19/EVM2EVMOffRampHelper.bin fe22966f5d97a8f386a4f01f901a308592336ea52c8fd06311f4bf1a961033ad @@ -12,7 +12,7 @@ lock_release_token_pool: ../../../contracts/solc/v0.8.19/LockReleaseTokenPool.ab maybe_revert_message_receiver: ../../../contracts/solc/v0.8.19/MaybeRevertMessageReceiver.abi ../../../contracts/solc/v0.8.19/MaybeRevertMessageReceiver.bin aaa90eac8cc555ee4b0fbe57d1fb8d72d6689b29510b238177c97ab9b7979ac5 mock_arm_contract: ../../../contracts/solc/v0.8.19/MockARM.abi ../../../contracts/solc/v0.8.19/MockARM.bin efcf4cb260a2b6a6e189639f62bb50ab650a135715c1fcd42c92dfa9d04aa0e3 ping_pong_demo: ../../../contracts/solc/v0.8.19/PingPongDemo.abi ../../../contracts/solc/v0.8.19/PingPongDemo.bin f2972aa082cee8b461122f79773ce247d23b551ddc2ca9926ae90624134cfb23 -price_registry: ../../../contracts/solc/v0.8.19/PriceRegistry.abi ../../../contracts/solc/v0.8.19/PriceRegistry.bin 61e69348939585a4310e482a0f548149e1121527b378a3a76b988e59b0465c66 +price_registry: ../../../contracts/solc/v0.8.19/PriceRegistry.abi ../../../contracts/solc/v0.8.19/PriceRegistry.bin 36e8d2c44a16fefb5258557cb1eae25eca1cc12efcd3c3270f91a90a5f81e7ea router: ../../../contracts/solc/v0.8.19/Router.abi ../../../contracts/solc/v0.8.19/Router.bin 29690cda0fbe8ea7215132d65082c1987a3f27baebcdd8fff8f04df5e3712d00 usdc_token_pool: ../../../contracts/solc/v0.8.19/USDCTokenPool.abi ../../../contracts/solc/v0.8.19/USDCTokenPool.bin 36fb183677c717bf91673eb83c080449fd5d9ea11f2a5dd14ee6a63889ec6f33 weth9: ../../../contracts/solc/v0.8.19/WETH9.abi ../../../contracts/solc/v0.8.19/WETH9.bin 5a7d64fb19b62ec523c7667ce4c2983295c05f74935b5f994c06a6f70d440f8b From 8e78369a50ee7e444f5d0393cd01954aa7812619 Mon Sep 17 00:00:00 2001 From: Matt Yang Date: Tue, 3 Oct 2023 01:53:10 -0400 Subject: [PATCH 03/24] offchain non-backwards-incompatible changes --- .../helpers/contractmodels.go | 8 +- .../plugins/ccip/abihelpers/abi_helpers.go | 17 +- .../ccip/abihelpers/abi_helpers_test.go | 8 +- .../ocr2/plugins/ccip/commit_inflight.go | 39 ++--- .../ocr2/plugins/ccip/commit_inflight_test.go | 51 +++--- .../plugins/ccip/commit_reporting_plugin.go | 44 +++--- .../ccip/commit_reporting_plugin_test.go | 145 ++++++++++++------ .../ccip/testhelpers/ccip_contracts.go | 48 ++++-- 8 files changed, 239 insertions(+), 121 deletions(-) diff --git a/core/scripts/ccip/manual-execution/helpers/contractmodels.go b/core/scripts/ccip/manual-execution/helpers/contractmodels.go index 4d7419e224..796173c594 100644 --- a/core/scripts/ccip/manual-execution/helpers/contractmodels.go +++ b/core/scripts/ccip/manual-execution/helpers/contractmodels.go @@ -18,10 +18,14 @@ type ICommitStoreCommitReport struct { MerkleRoot [32]byte } +type InternalGasPriceUpdate struct { + DestChainSelector uint64 + UsdPerUnitGas *big.Int +} + type InternalPriceUpdates struct { TokenPriceUpdates []InternalTokenPriceUpdate - DestChainId uint64 - UsdPerUnitGas *big.Int + GasPriceUpdates []InternalGasPriceUpdate } type InternalTokenPriceUpdate struct { diff --git a/core/services/ocr2/plugins/ccip/abihelpers/abi_helpers.go b/core/services/ocr2/plugins/ccip/abihelpers/abi_helpers.go index 5eedc30242..a61d20748e 100644 --- a/core/services/ocr2/plugins/ccip/abihelpers/abi_helpers.go +++ b/core/services/ocr2/plugins/ccip/abihelpers/abi_helpers.go @@ -216,8 +216,10 @@ func DecodeCommitReport(report []byte) (commit_store.CommitStoreCommitReport, er SourceToken common.Address `json:"sourceToken"` UsdPerToken *big.Int `json:"usdPerToken"` } `json:"tokenPriceUpdates"` - DestChainSelector uint64 `json:"destChainSelector"` - UsdPerUnitGas *big.Int `json:"usdPerUnitGas"` + GasPriceUpdates []struct { + DestChainSelector uint64 `json:"destChainSelector"` + UsdPerUnitGas *big.Int `json:"usdPerUnitGas"` + } `json:"gasPriceUpdates"` } `json:"priceUpdates"` Interval struct { Min uint64 `json:"min"` @@ -237,11 +239,18 @@ func DecodeCommitReport(report []byte) (commit_store.CommitStoreCommitReport, er }) } + var gasPriceUpdates []commit_store.InternalGasPriceUpdate + for _, u := range commitReport.PriceUpdates.GasPriceUpdates { + gasPriceUpdates = append(gasPriceUpdates, commit_store.InternalGasPriceUpdate{ + DestChainSelector: u.DestChainSelector, + UsdPerUnitGas: u.UsdPerUnitGas, + }) + } + return commit_store.CommitStoreCommitReport{ PriceUpdates: commit_store.InternalPriceUpdates{ - DestChainSelector: commitReport.PriceUpdates.DestChainSelector, - UsdPerUnitGas: commitReport.PriceUpdates.UsdPerUnitGas, TokenPriceUpdates: tokenPriceUpdates, + GasPriceUpdates: gasPriceUpdates, }, Interval: commit_store.CommitStoreInterval{ Min: commitReport.Interval.Min, diff --git a/core/services/ocr2/plugins/ccip/abihelpers/abi_helpers_test.go b/core/services/ocr2/plugins/ccip/abihelpers/abi_helpers_test.go index 4cc5ccfac0..3731acefe1 100644 --- a/core/services/ocr2/plugins/ccip/abihelpers/abi_helpers_test.go +++ b/core/services/ocr2/plugins/ccip/abihelpers/abi_helpers_test.go @@ -71,8 +71,12 @@ func TestCommitReportEncoding(t *testing.T) { UsdPerToken: big.NewInt(9e18), }, }, - DestChainSelector: rand.Uint64(), - UsdPerUnitGas: big.NewInt(2000e9), + GasPriceUpdates: []commit_store.InternalGasPriceUpdate{ + { + DestChainSelector: rand.Uint64(), + UsdPerUnitGas: big.NewInt(2000e9), + }, + }, }, MerkleRoot: [32]byte{123}, Interval: commit_store.CommitStoreInterval{Min: 1, Max: 10}, diff --git a/core/services/ocr2/plugins/ccip/commit_inflight.go b/core/services/ocr2/plugins/ccip/commit_inflight.go index b9540bd2c0..d778eb6c75 100644 --- a/core/services/ocr2/plugins/ccip/commit_inflight.go +++ b/core/services/ocr2/plugins/ccip/commit_inflight.go @@ -67,30 +67,31 @@ func (c *inflightCommitReportsContainer) maxInflightSeqNr() uint64 { return max } -// getLatestInflightGasPriceUpdate returns the latest inflight gas price update, and bool flag on if update exists. -func (c *inflightCommitReportsContainer) getLatestInflightGasPriceUpdate() (update, bool) { +// getLatestInflightGasPriceUpdate returns a map of the latest gas price updates. +func (c *inflightCommitReportsContainer) getLatestInflightGasPriceUpdate() map[uint64]update { c.locker.RLock() defer c.locker.RUnlock() - updateFound := false - latestGasPriceUpdate := update{} - var latestEpochAndRound uint64 + latestGasPriceUpdates := make(map[uint64]update) + latestEpochAndRounds := make(map[uint64]uint64) for _, inflight := range c.inFlightPriceUpdates { - if inflight.priceUpdates.DestChainSelector == 0 { - // Price updates did not include a gas price - continue - } - if !updateFound || inflight.epochAndRound > latestEpochAndRound { - // First price found or found later update, set it - updateFound = true - latestGasPriceUpdate = update{ - timestamp: inflight.createdAt, - value: inflight.priceUpdates.UsdPerUnitGas, + for _, inflightGasUpdate := range inflight.priceUpdates.GasPriceUpdates { + if _, ok := latestGasPriceUpdates[inflightGasUpdate.DestChainSelector]; !ok { + latestGasPriceUpdates[inflightGasUpdate.DestChainSelector] = update{ + value: inflightGasUpdate.UsdPerUnitGas, + timestamp: inflight.createdAt, + } + latestEpochAndRounds[inflightGasUpdate.DestChainSelector] = inflight.epochAndRound + } + if inflight.epochAndRound > latestEpochAndRounds[inflightGasUpdate.DestChainSelector] { + latestGasPriceUpdates[inflightGasUpdate.DestChainSelector] = update{ + value: inflightGasUpdate.UsdPerUnitGas, + timestamp: inflight.createdAt, + } + latestEpochAndRounds[inflightGasUpdate.DestChainSelector] = inflight.epochAndRound } - latestEpochAndRound = inflight.epochAndRound - continue } } - return latestGasPriceUpdate, updateFound + return latestGasPriceUpdates } // latestInflightTokenPriceUpdates returns a map of the latest token price updates @@ -172,7 +173,7 @@ func (c *inflightCommitReportsContainer) add(lggr logger.Logger, report commit_s } } - if report.PriceUpdates.DestChainSelector != 0 || len(report.PriceUpdates.TokenPriceUpdates) != 0 { + if len(report.PriceUpdates.GasPriceUpdates) != 0 || len(report.PriceUpdates.TokenPriceUpdates) != 0 { lggr.Infow("Adding to inflight fee updates", "priceUpdates", report.PriceUpdates) c.inFlightPriceUpdates = append(c.inFlightPriceUpdates, InflightPriceUpdate{ priceUpdates: report.PriceUpdates, diff --git a/core/services/ocr2/plugins/ccip/commit_inflight_test.go b/core/services/ocr2/plugins/ccip/commit_inflight_test.go index 39d6a1ea7a..8eadad4aec 100644 --- a/core/services/ocr2/plugins/ccip/commit_inflight_test.go +++ b/core/services/ocr2/plugins/ccip/commit_inflight_test.go @@ -21,15 +21,14 @@ func TestCommitInflight(t *testing.T) { c := newInflightCommitReportsContainer(time.Hour) c.inFlightPriceUpdates = append(c.inFlightPriceUpdates, InflightPriceUpdate{ - priceUpdates: commit_store.InternalPriceUpdates{DestChainSelector: 0}, // skipped when destChainSelector is 0 + priceUpdates: commit_store.InternalPriceUpdates{}, createdAt: time.Now(), epochAndRound: ccipcalc.MergeEpochAndRound(2, 4), }) // Initially should be empty - inflightUpdate, hasUpdate := c.getLatestInflightGasPriceUpdate() - assert.Equal(t, inflightUpdate, update{}) - assert.False(t, hasUpdate) + inflightGasUpdates := c.getLatestInflightGasPriceUpdate() + assert.Equal(t, 0, len(inflightGasUpdates)) assert.Equal(t, uint64(0), c.maxInflightSeqNr()) epochAndRound := uint64(1) @@ -37,30 +36,32 @@ func TestCommitInflight(t *testing.T) { // Add a single report inflight root1 := utils.Keccak256Fixed(hexutil.MustDecode("0xaa")) require.NoError(t, c.add(lggr, commit_store.CommitStoreCommitReport{Interval: commit_store.CommitStoreInterval{Min: 1, Max: 2}, MerkleRoot: root1}, epochAndRound)) - inflightUpdate, hasUpdate = c.getLatestInflightGasPriceUpdate() - assert.Equal(t, inflightUpdate, update{}) - assert.False(t, hasUpdate) + inflightGasUpdates = c.getLatestInflightGasPriceUpdate() + assert.Equal(t, 0, len(inflightGasUpdates)) assert.Equal(t, uint64(2), c.maxInflightSeqNr()) epochAndRound++ // Add another price report root2 := utils.Keccak256Fixed(hexutil.MustDecode("0xab")) require.NoError(t, c.add(lggr, commit_store.CommitStoreCommitReport{Interval: commit_store.CommitStoreInterval{Min: 3, Max: 4}, MerkleRoot: root2}, epochAndRound)) - inflightUpdate, hasUpdate = c.getLatestInflightGasPriceUpdate() - assert.Equal(t, inflightUpdate, update{}) - assert.False(t, hasUpdate) + inflightGasUpdates = c.getLatestInflightGasPriceUpdate() + assert.Equal(t, 0, len(inflightGasUpdates)) assert.Equal(t, uint64(4), c.maxInflightSeqNr()) epochAndRound++ // Add gas price updates require.NoError(t, c.add(lggr, commit_store.CommitStoreCommitReport{PriceUpdates: commit_store.InternalPriceUpdates{ - DestChainSelector: uint64(1), - UsdPerUnitGas: big.NewInt(1), + GasPriceUpdates: []commit_store.InternalGasPriceUpdate{ + { + DestChainSelector: uint64(1), + UsdPerUnitGas: big.NewInt(1), + }, + }, }}, epochAndRound)) - inflightUpdate, hasUpdate = c.getLatestInflightGasPriceUpdate() - assert.Equal(t, big.NewInt(1), inflightUpdate.value) - assert.True(t, hasUpdate) + inflightGasUpdates = c.getLatestInflightGasPriceUpdate() + assert.Equal(t, 1, len(inflightGasUpdates)) + assert.Equal(t, big.NewInt(1), inflightGasUpdates[0].value) assert.Equal(t, uint64(4), c.maxInflightSeqNr()) epochAndRound++ @@ -85,8 +86,12 @@ func TestCommitInflight(t *testing.T) { TokenPriceUpdates: []commit_store.InternalTokenPriceUpdate{ {SourceToken: token, UsdPerToken: big.NewInt(9999)}, }, - DestChainSelector: uint64(1), - UsdPerUnitGas: big.NewInt(999), + GasPriceUpdates: []commit_store.InternalGasPriceUpdate{ + { + DestChainSelector: uint64(1), + UsdPerUnitGas: big.NewInt(999), + }, + }, }, createdAt: time.Now(), epochAndRound: ccipcalc.MergeEpochAndRound(999, 99), @@ -94,6 +99,10 @@ func TestCommitInflight(t *testing.T) { latestInflightTokenPriceUpdates = c.latestInflightTokenPriceUpdates() require.Equal(t, len(latestInflightTokenPriceUpdates), 1) assert.Equal(t, big.NewInt(9999), latestInflightTokenPriceUpdates[token].value) + + latestInflightTokenPriceUpdates = c.latestInflightTokenPriceUpdates() + require.Equal(t, len(latestInflightTokenPriceUpdates), 1) + assert.Equal(t, big.NewInt(999), latestInflightTokenPriceUpdates[token].value) } func Test_inflightCommitReportsContainer_expire(t *testing.T) { @@ -111,12 +120,16 @@ func Test_inflightCommitReportsContainer_expire(t *testing.T) { }, inFlightPriceUpdates: []InflightPriceUpdate{ { - priceUpdates: commit_store.InternalPriceUpdates{DestChainSelector: 100}, + priceUpdates: commit_store.InternalPriceUpdates{GasPriceUpdates: []commit_store.InternalGasPriceUpdate{ + {DestChainSelector: uint64(100), UsdPerUnitGas: big.NewInt(100)}, + }}, createdAt: time.Now().Add(-PRICE_EXPIRY_MULTIPLIER * time.Minute), epochAndRound: ccipcalc.MergeEpochAndRound(10, 5), }, { - priceUpdates: commit_store.InternalPriceUpdates{DestChainSelector: 200}, + priceUpdates: commit_store.InternalPriceUpdates{GasPriceUpdates: []commit_store.InternalGasPriceUpdate{ + {DestChainSelector: uint64(200), UsdPerUnitGas: big.NewInt(200)}, + }}, createdAt: time.Now().Add(-PRICE_EXPIRY_MULTIPLIER * time.Second), epochAndRound: ccipcalc.MergeEpochAndRound(20, 5), }, diff --git a/core/services/ocr2/plugins/ccip/commit_reporting_plugin.go b/core/services/ocr2/plugins/ccip/commit_reporting_plugin.go index 14023e694c..abc65360f0 100644 --- a/core/services/ocr2/plugins/ccip/commit_reporting_plugin.go +++ b/core/services/ocr2/plugins/ccip/commit_reporting_plugin.go @@ -419,9 +419,9 @@ func (r *CommitReportingPlugin) getLatestTokenPriceUpdates(ctx context.Context, // If an update is found, it is not expected to contain a nil value. If no updates found, empty update with nil value is returned. func (r *CommitReportingPlugin) getLatestGasPriceUpdate(ctx context.Context, now time.Time, checkInflight bool) (gasUpdate update, error error) { if checkInflight { - latestInflightGasPriceUpdate, latestUpdateFound := r.inflightReports.getLatestInflightGasPriceUpdate() - if latestUpdateFound { - gasUpdate = latestInflightGasPriceUpdate + latestInflightGasPriceUpdates := r.inflightReports.getLatestInflightGasPriceUpdate() + if inflightUpdate, exists := latestInflightGasPriceUpdates[r.config.sourceChainSelector]; exists { + gasUpdate = inflightUpdate r.lggr.Infow("Latest gas price from inflight", "gasPriceUpdateVal", gasUpdate.value, "gasPriceUpdateTs", gasUpdate.timestamp) // Gas price can fluctuate frequently, many updates may be in flight. @@ -499,7 +499,7 @@ func (r *CommitReportingPlugin) Report(ctx context.Context, epochAndRound types. return false, nil, err } // If there are no fee updates and the interval is zero there is no report to produce. - if len(priceUpdates.TokenPriceUpdates) == 0 && priceUpdates.DestChainSelector == 0 && agreedInterval.Min == 0 { + if len(priceUpdates.TokenPriceUpdates) == 0 && len(priceUpdates.GasPriceUpdates) == 0 && agreedInterval.Min == 0 { lggr.Infow("Empty report, skipping") return false, nil, nil } @@ -517,8 +517,7 @@ func (r *CommitReportingPlugin) Report(ctx context.Context, epochAndRound types. "minSeqNr", report.Interval.Min, "maxSeqNr", report.Interval.Max, "tokenPriceUpdates", report.PriceUpdates.TokenPriceUpdates, - "destChainSelector", report.PriceUpdates.DestChainSelector, - "sourceUsdPerUnitGas", report.PriceUpdates.UsdPerUnitGas, + "gasPriceUpdates", report.PriceUpdates.GasPriceUpdates, "epochAndRound", epochAndRound, ) return true, encodedReport, nil @@ -669,11 +668,18 @@ func (r *CommitReportingPlugin) calculatePriceUpdates(observations []CommitObser return bytes.Compare(tokenPriceUpdates[i].SourceToken[:], tokenPriceUpdates[j].SourceToken[:]) == -1 }) + destChainSelector := r.config.sourceChainSelector // Assuming plugin lane is A->B, we write to B the gas price of A newGasPrice, err := r.gasPriceEstimator.Median(sourceGasObservations) // Compute the median price if err != nil { return commit_store.InternalPriceUpdates{}, err } - destChainSelector := r.config.sourceChainSelector // Assuming plugin lane is A->B, we write to B the gas price of A + // Although onchain interface accepts multi gas updates, we only do 1 gas price per report for now. + gasPriceUpdates := []commit_store.InternalGasPriceUpdate{ + { + DestChainSelector: destChainSelector, + UsdPerUnitGas: newGasPrice, + }, + } if latestGasPrice.value != nil { gasPriceUpdatedRecently := time.Since(latestGasPrice.timestamp) < r.offchainConfig.GasPriceHeartBeat.Duration() @@ -682,15 +688,13 @@ func (r *CommitReportingPlugin) calculatePriceUpdates(observations []CommitObser return commit_store.InternalPriceUpdates{}, err } if gasPriceUpdatedRecently && !gasPriceDeviated { - newGasPrice = big.NewInt(0) - destChainSelector = uint64(0) + gasPriceUpdates = []commit_store.InternalGasPriceUpdate{} } } return commit_store.InternalPriceUpdates{ TokenPriceUpdates: tokenPriceUpdates, - DestChainSelector: destChainSelector, - UsdPerUnitGas: newGasPrice, // we MUST pass zero to skip the update (never nil) + GasPriceUpdates: gasPriceUpdates, }, nil } @@ -753,13 +757,12 @@ func (r *CommitReportingPlugin) ShouldAcceptFinalizedReport(ctx context.Context, "merkleRoot", parsedReport.MerkleRoot, "minSeqNum", parsedReport.Interval.Min, "maxSeqNum", parsedReport.Interval.Max, - "destChainSelector", parsedReport.PriceUpdates.DestChainSelector, - "usdPerUnitGas", parsedReport.PriceUpdates.UsdPerUnitGas, "tokenPriceUpdates", parsedReport.PriceUpdates.TokenPriceUpdates, + "gasPriceUpdates", parsedReport.PriceUpdates.GasPriceUpdates, "reportTimestamp", reportTimestamp, ) // Empty report, should not be put on chain - if parsedReport.MerkleRoot == [32]byte{} && parsedReport.PriceUpdates.DestChainSelector == 0 && len(parsedReport.PriceUpdates.TokenPriceUpdates) == 0 { + if parsedReport.MerkleRoot == [32]byte{} && len(parsedReport.PriceUpdates.GasPriceUpdates) == 0 && len(parsedReport.PriceUpdates.TokenPriceUpdates) == 0 { lggr.Warn("Empty report, should not be put on chain") return false, nil } @@ -814,7 +817,7 @@ func (r *CommitReportingPlugin) isStaleReport(ctx context.Context, lggr logger.L return r.isStaleMerkleRoot(ctx, lggr, report.Interval, checkInflight) } - hasGasPriceUpdate := report.PriceUpdates.DestChainSelector != 0 + hasGasPriceUpdate := len(report.PriceUpdates.GasPriceUpdates) > 0 hasTokenPriceUpdates := len(report.PriceUpdates.TokenPriceUpdates) > 0 // If there is no merkle root, no gas price update and no token price update @@ -875,9 +878,14 @@ func (r *CommitReportingPlugin) isStaleGasPrice(ctx context.Context, lggr logger lggr.Errorw("Report is stale because getLatestGasPriceUpdate failed", "err", err) return true } + // Commit plugin currently only supports 1 gas price per report. If report contains more than 1, reject the report. + if len(priceUpdates.GasPriceUpdates) > 1 { + lggr.Errorw("Report is stale because it contains more than 1 gas price update", "GasPriceUpdates", priceUpdates.GasPriceUpdates) + return true + } if latestGasPrice.value != nil { - gasPriceDeviated, err := r.gasPriceEstimator.Deviates(priceUpdates.UsdPerUnitGas, latestGasPrice.value) + gasPriceDeviated, err := r.gasPriceEstimator.Deviates(priceUpdates.GasPriceUpdates[0].UsdPerUnitGas, latestGasPrice.value) if err != nil { lggr.Errorw("Report is stale because deviation check failed", "err", err) return true @@ -886,8 +894,8 @@ func (r *CommitReportingPlugin) isStaleGasPrice(ctx context.Context, lggr logger if !gasPriceDeviated { lggr.Infow("Report is stale because of gas price", "latestGasPriceUpdate", latestGasPrice.value, - "usdPerUnitGas", priceUpdates.UsdPerUnitGas, - "destChainSelector", priceUpdates.DestChainSelector) + "usdPerUnitGas", priceUpdates.GasPriceUpdates[0].UsdPerUnitGas, + "destChainSelector", priceUpdates.GasPriceUpdates[0].DestChainSelector) return true } } diff --git a/core/services/ocr2/plugins/ccip/commit_reporting_plugin_test.go b/core/services/ocr2/plugins/ccip/commit_reporting_plugin_test.go index baa2cc2bad..a35444017b 100644 --- a/core/services/ocr2/plugins/ccip/commit_reporting_plugin_test.go +++ b/core/services/ocr2/plugins/ccip/commit_reporting_plugin_test.go @@ -223,8 +223,12 @@ func TestCommitReportingPlugin_Report(t *testing.T) { Interval: commit_store.CommitStoreInterval{Min: 1, Max: 1}, PriceUpdates: commit_store.InternalPriceUpdates{ TokenPriceUpdates: nil, - DestChainSelector: uint64(sourceChainSelector), - UsdPerUnitGas: gasPrice, + GasPriceUpdates: []commit_store.InternalGasPriceUpdate{ + { + DestChainSelector: uint64(sourceChainSelector), + UsdPerUnitGas: gasPrice, + }, + }, }, }, expErr: false, @@ -338,8 +342,7 @@ func TestCommitReportingPlugin_ShouldAcceptFinalizedReport(t *testing.T) { t.Run("empty report should not be accepted", func(t *testing.T) { p := newPlugin() report := commit_store.CommitStoreCommitReport{ - // UsdPerUnitGas is mandatory otherwise report cannot be encoded/decoded - PriceUpdates: commit_store.InternalPriceUpdates{UsdPerUnitGas: big.NewInt(int64(rand.Int()))}, + PriceUpdates: commit_store.InternalPriceUpdates{}, } encodedReport, err := abihelpers.EncodeCommitReport(report) assert.NoError(t, err) @@ -357,7 +360,7 @@ func TestCommitReportingPlugin_ShouldAcceptFinalizedReport(t *testing.T) { p.config.commitStore = commitStore report := commit_store.CommitStoreCommitReport{ - PriceUpdates: commit_store.InternalPriceUpdates{UsdPerUnitGas: big.NewInt(int64(rand.Int()))}, + PriceUpdates: commit_store.InternalPriceUpdates{}, MerkleRoot: [32]byte{123}, // this report is considered non-empty since it has a merkle root } @@ -387,8 +390,12 @@ func TestCommitReportingPlugin_ShouldAcceptFinalizedReport(t *testing.T) { UsdPerToken: big.NewInt(int64(rand.Int())), }, }, - DestChainSelector: rand.Uint64(), - UsdPerUnitGas: big.NewInt(int64(rand.Int())), + GasPriceUpdates: []commit_store.InternalGasPriceUpdate{ + { + DestChainSelector: rand.Uint64(), + UsdPerUnitGas: big.NewInt(int64(rand.Int())), + }, + }, }, MerkleRoot: [32]byte{123}, } @@ -415,8 +422,12 @@ func TestCommitReportingPlugin_ShouldTransmitAcceptedReport(t *testing.T) { TokenPriceUpdates: []commit_store.InternalTokenPriceUpdate{ {SourceToken: utils.RandomAddress(), UsdPerToken: big.NewInt(9e18)}, }, - DestChainSelector: rand.Uint64(), - UsdPerUnitGas: big.NewInt(2000e9), + GasPriceUpdates: []commit_store.InternalGasPriceUpdate{ + { + DestChainSelector: rand.Uint64(), + UsdPerUnitGas: big.NewInt(2000e9), + }, + }, }, MerkleRoot: [32]byte{123}, } @@ -634,9 +645,8 @@ func TestCommitReportingPlugin_calculatePriceUpdates(t *testing.T) { execGasPriceDeviationPPB int64 tokenPriceHeartBeat models.Duration tokenPriceDeviationPPB uint32 - expGas *big.Int expTokenUpdates []commit_store.InternalTokenPriceUpdate - expDestChainSel uint64 + expGasUpdates []commit_store.InternalGasPriceUpdate }{ { name: "median", @@ -646,9 +656,13 @@ func TestCommitReportingPlugin_calculatePriceUpdates(t *testing.T) { {SourceGasPriceUSD: big.NewInt(3)}, {SourceGasPriceUSD: big.NewInt(4)}, }, - f: 2, - expGas: big.NewInt(3), - expDestChainSel: defaultSourceChainSelector, + f: 2, + expGasUpdates: []commit_store.InternalGasPriceUpdate{ + { + DestChainSelector: defaultSourceChainSelector, + UsdPerUnitGas: big.NewInt(3), + }, + }, }, { name: "gas price update skipped because the latest is similar and was updated recently", @@ -665,9 +679,8 @@ func TestCommitReportingPlugin_calculatePriceUpdates(t *testing.T) { timestamp: time.Now().Add(-30 * time.Minute), // recent value: val1e18(9), // latest value close to the update }, - f: 1, - expGas: zero, - expDestChainSel: 0, + f: 1, + expGasUpdates: []commit_store.InternalGasPriceUpdate{}, }, { name: "gas price update included, the latest is similar but was not updated recently", @@ -684,9 +697,13 @@ func TestCommitReportingPlugin_calculatePriceUpdates(t *testing.T) { timestamp: time.Now().Add(-90 * time.Minute), // recent value: val1e18(9), // latest value close to the update }, - f: 1, - expGas: val1e18(11), - expDestChainSel: defaultSourceChainSelector, + f: 1, + expGasUpdates: []commit_store.InternalGasPriceUpdate{ + { + DestChainSelector: defaultSourceChainSelector, + UsdPerUnitGas: val1e18(11), + }, + }, }, { name: "gas price update deviates from latest", @@ -704,9 +721,13 @@ func TestCommitReportingPlugin_calculatePriceUpdates(t *testing.T) { timestamp: time.Now().Add(-30 * time.Minute), // recent value: val1e18(11), // latest value close to the update }, - f: 2, - expGas: val1e18(20), - expDestChainSel: defaultSourceChainSelector, + f: 2, + expGasUpdates: []commit_store.InternalGasPriceUpdate{ + { + DestChainSelector: defaultSourceChainSelector, + UsdPerUnitGas: val1e18(20), + }, + }, }, { name: "median one token", @@ -718,8 +739,12 @@ func TestCommitReportingPlugin_calculatePriceUpdates(t *testing.T) { expTokenUpdates: []commit_store.InternalTokenPriceUpdate{ {SourceToken: feeToken1, UsdPerToken: big.NewInt(12)}, }, - expGas: zero, - expDestChainSel: defaultSourceChainSelector, + expGasUpdates: []commit_store.InternalGasPriceUpdate{ + { + DestChainSelector: defaultSourceChainSelector, + UsdPerUnitGas: zero, + }, + }, }, { name: "median two tokens", @@ -732,8 +757,12 @@ func TestCommitReportingPlugin_calculatePriceUpdates(t *testing.T) { {SourceToken: feeToken1, UsdPerToken: big.NewInt(12)}, {SourceToken: feeToken2, UsdPerToken: big.NewInt(13)}, }, - expGas: zero, - expDestChainSel: defaultSourceChainSelector, + expGasUpdates: []commit_store.InternalGasPriceUpdate{ + { + DestChainSelector: defaultSourceChainSelector, + UsdPerUnitGas: zero, + }, + }, }, { name: "token price update skipped because it is close to the latest", @@ -753,8 +782,12 @@ func TestCommitReportingPlugin_calculatePriceUpdates(t *testing.T) { value: val1e18(9), }, }, - expGas: zero, - expDestChainSel: defaultSourceChainSelector, + expGasUpdates: []commit_store.InternalGasPriceUpdate{ + { + DestChainSelector: defaultSourceChainSelector, + UsdPerUnitGas: zero, + }, + }, }, { name: "gas price and token price both included because they are not close to the latest", @@ -781,8 +814,12 @@ func TestCommitReportingPlugin_calculatePriceUpdates(t *testing.T) { expTokenUpdates: []commit_store.InternalTokenPriceUpdate{ {SourceToken: feeToken1, UsdPerToken: val1e18(21)}, }, - expGas: val1e18(11), - expDestChainSel: defaultSourceChainSelector, + expGasUpdates: []commit_store.InternalGasPriceUpdate{ + { + DestChainSelector: defaultSourceChainSelector, + UsdPerUnitGas: val1e18(11), + }, + }, }, { name: "gas price and token price both included because they not been updated recently", @@ -809,8 +846,12 @@ func TestCommitReportingPlugin_calculatePriceUpdates(t *testing.T) { expTokenUpdates: []commit_store.InternalTokenPriceUpdate{ {SourceToken: feeToken1, UsdPerToken: val1e18(21)}, }, - expGas: val1e18(11), - expDestChainSel: defaultSourceChainSelector, + expGasUpdates: []commit_store.InternalGasPriceUpdate{ + { + DestChainSelector: defaultSourceChainSelector, + UsdPerUnitGas: val1e18(11), + }, + }, }, { name: "gas price included because it deviates from latest and token price skipped because it does not deviate", @@ -834,8 +875,12 @@ func TestCommitReportingPlugin_calculatePriceUpdates(t *testing.T) { value: val1e18(9), }, }, - expGas: val1e18(11), - expDestChainSel: defaultSourceChainSelector, + expGasUpdates: []commit_store.InternalGasPriceUpdate{ + { + DestChainSelector: defaultSourceChainSelector, + UsdPerUnitGas: val1e18(11), + }, + }, }, { name: "gas price skipped because it does not deviate and token price included because it has not been updated recently", @@ -862,8 +907,7 @@ func TestCommitReportingPlugin_calculatePriceUpdates(t *testing.T) { expTokenUpdates: []commit_store.InternalTokenPriceUpdate{ {SourceToken: feeToken1, UsdPerToken: val1e18(21)}, }, - expGas: zero, - expDestChainSel: 0, + expGasUpdates: []commit_store.InternalGasPriceUpdate{}, }, } @@ -894,9 +938,8 @@ func TestCommitReportingPlugin_calculatePriceUpdates(t *testing.T) { } got, err := r.calculatePriceUpdates(tc.commitObservations, tc.latestGasPrice, tc.latestTokenPrices) - assert.Equal(t, tc.expGas, got.UsdPerUnitGas) assert.Equal(t, tc.expTokenUpdates, got.TokenPriceUpdates) - assert.Equal(t, tc.expDestChainSel, got.DestChainSelector) + assert.Equal(t, tc.expGasUpdates, got.GasPriceUpdates) assert.NoError(t, err) }) } @@ -1359,8 +1402,12 @@ func TestCommitReportingPlugin_getLatestGasPriceUpdate(t *testing.T) { InflightPriceUpdate{ createdAt: tc.inflightGasPriceUpdate.timestamp, priceUpdates: commit_store.InternalPriceUpdates{ - DestChainSelector: 1234, - UsdPerUnitGas: tc.inflightGasPriceUpdate.value, + GasPriceUpdates: []commit_store.InternalGasPriceUpdate{ + { + DestChainSelector: 1234, + UsdPerUnitGas: tc.inflightGasPriceUpdate.value, + }, + }, }, }, ) @@ -1519,8 +1566,12 @@ func Test_commitReportSize(t *testing.T) { Interval: commit_store.CommitStoreInterval{Min: min, Max: max}, PriceUpdates: commit_store.InternalPriceUpdates{ TokenPriceUpdates: []commit_store.InternalTokenPriceUpdate{}, - DestChainSelector: 1337, - UsdPerUnitGas: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9 + GasPriceUpdates: []commit_store.InternalGasPriceUpdate{ + { + DestChainSelector: 1337, + UsdPerUnitGas: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9 + }, + }, }, }) require.NoError(t, err) @@ -1638,8 +1689,12 @@ func TestCommitReportToEthTxMeta(t *testing.T) { report := commit_store.CommitStoreCommitReport{ PriceUpdates: commit_store.InternalPriceUpdates{ TokenPriceUpdates: []commit_store.InternalTokenPriceUpdate{}, - DestChainSelector: uint64(1337), - UsdPerUnitGas: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9 + GasPriceUpdates: []commit_store.InternalGasPriceUpdate{ + { + DestChainSelector: uint64(1337), + UsdPerUnitGas: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9 + }, + }, }, MerkleRoot: tree.Root(), Interval: commit_store.CommitStoreInterval{Min: tc.min, Max: tc.max}, diff --git a/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go b/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go index aee8f196c6..b63374e14f 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go @@ -362,8 +362,12 @@ func (c *CCIPContracts) DeployNewPriceRegistry(t *testing.T) { UsdPerToken: big.NewInt(1e18), // 1usd }, }, - DestChainSelector: c.Source.ChainSelector, - UsdPerUnitGas: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9 + GasPriceUpdates: []price_registry.InternalGasPriceUpdate{ + { + DestChainSelector: c.Source.ChainSelector, + UsdPerUnitGas: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9 + }, + }, } _, err = c.Dest.PriceRegistry.UpdatePrices(c.Dest.User, priceUpdates) require.NoError(t, err) @@ -614,8 +618,12 @@ func (c *CCIPContracts) SetupLockAndMintTokenPool( UsdPerToken: big.NewInt(1e18), // 1usd }, }, - DestChainSelector: c.Dest.ChainSelector, - UsdPerUnitGas: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9, + GasPriceUpdates: []price_registry.InternalGasPriceUpdate{ + { + DestChainSelector: c.Dest.ChainSelector, + UsdPerUnitGas: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9, + }, + }, }) if err != nil { return [20]byte{}, nil, err @@ -645,8 +653,12 @@ func (c *CCIPContracts) SetupLockAndMintTokenPool( UsdPerToken: big.NewInt(5), }, }, - DestChainSelector: c.Source.ChainSelector, - UsdPerUnitGas: big.NewInt(0), + GasPriceUpdates: []price_registry.InternalGasPriceUpdate{ + { + DestChainSelector: c.Source.ChainSelector, + UsdPerUnitGas: big.NewInt(0), + }, + }, }) if err != nil { return [20]byte{}, nil, err @@ -671,8 +683,12 @@ func (c *CCIPContracts) SetupLockAndMintTokenPool( UsdPerToken: big.NewInt(5), }, }, - DestChainSelector: 0, - UsdPerUnitGas: big.NewInt(0), + GasPriceUpdates: []price_registry.InternalGasPriceUpdate{ + { + DestChainSelector: 0, + UsdPerUnitGas: big.NewInt(0), + }, + }, }) if err != nil { return [20]byte{}, nil, err @@ -885,8 +901,12 @@ func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destCh UsdPerToken: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(2)), // TODO make this 2000USD and once we figure out the fee and exec cost discrepancy }, }, - DestChainSelector: destChainSelector, - UsdPerUnitGas: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9 + GasPriceUpdates: []price_registry.InternalGasPriceUpdate{ + { + DestChainSelector: destChainSelector, + UsdPerUnitGas: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9 + }, + }, } _, err = srcPriceRegistry.UpdatePrices(sourceUser, prices) @@ -1025,8 +1045,12 @@ func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destCh {SourceToken: destCustomTokenAddress, UsdPerToken: big.NewInt(5e18)}, // 5usd {SourceToken: destWeth9addr, UsdPerToken: big.NewInt(2e18)}, // 2usd }, - DestChainSelector: sourceChainSelector, - UsdPerUnitGas: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9 + GasPriceUpdates: []price_registry.InternalGasPriceUpdate{ + { + DestChainSelector: sourceChainSelector, + UsdPerUnitGas: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9 + }, + }, } _, err = destPriceRegistry.UpdatePrices(destUser, destPrices) From ad5111fd8a29c68a35e2ac49e229cc3e7aceca19 Mon Sep 17 00:00:00 2001 From: Matt Yang Date: Tue, 3 Oct 2023 02:16:02 -0400 Subject: [PATCH 04/24] fix tests --- .../ocr2/plugins/ccip/commit_inflight.go | 4 ++-- .../ocr2/plugins/ccip/commit_inflight_test.go | 21 ++++++++++--------- .../plugins/ccip/commit_reporting_plugin.go | 2 +- .../ccip/commit_reporting_plugin_test.go | 5 +++-- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/core/services/ocr2/plugins/ccip/commit_inflight.go b/core/services/ocr2/plugins/ccip/commit_inflight.go index d778eb6c75..b95cb34c71 100644 --- a/core/services/ocr2/plugins/ccip/commit_inflight.go +++ b/core/services/ocr2/plugins/ccip/commit_inflight.go @@ -67,8 +67,8 @@ func (c *inflightCommitReportsContainer) maxInflightSeqNr() uint64 { return max } -// getLatestInflightGasPriceUpdate returns a map of the latest gas price updates. -func (c *inflightCommitReportsContainer) getLatestInflightGasPriceUpdate() map[uint64]update { +// latestInflightGasPriceUpdates returns a map of the latest gas price updates. +func (c *inflightCommitReportsContainer) latestInflightGasPriceUpdates() map[uint64]update { c.locker.RLock() defer c.locker.RUnlock() latestGasPriceUpdates := make(map[uint64]update) diff --git a/core/services/ocr2/plugins/ccip/commit_inflight_test.go b/core/services/ocr2/plugins/ccip/commit_inflight_test.go index 8eadad4aec..6c310a8e30 100644 --- a/core/services/ocr2/plugins/ccip/commit_inflight_test.go +++ b/core/services/ocr2/plugins/ccip/commit_inflight_test.go @@ -27,7 +27,7 @@ func TestCommitInflight(t *testing.T) { }) // Initially should be empty - inflightGasUpdates := c.getLatestInflightGasPriceUpdate() + inflightGasUpdates := c.latestInflightGasPriceUpdates() assert.Equal(t, 0, len(inflightGasUpdates)) assert.Equal(t, uint64(0), c.maxInflightSeqNr()) @@ -36,7 +36,7 @@ func TestCommitInflight(t *testing.T) { // Add a single report inflight root1 := utils.Keccak256Fixed(hexutil.MustDecode("0xaa")) require.NoError(t, c.add(lggr, commit_store.CommitStoreCommitReport{Interval: commit_store.CommitStoreInterval{Min: 1, Max: 2}, MerkleRoot: root1}, epochAndRound)) - inflightGasUpdates = c.getLatestInflightGasPriceUpdate() + inflightGasUpdates = c.latestInflightGasPriceUpdates() assert.Equal(t, 0, len(inflightGasUpdates)) assert.Equal(t, uint64(2), c.maxInflightSeqNr()) epochAndRound++ @@ -44,24 +44,25 @@ func TestCommitInflight(t *testing.T) { // Add another price report root2 := utils.Keccak256Fixed(hexutil.MustDecode("0xab")) require.NoError(t, c.add(lggr, commit_store.CommitStoreCommitReport{Interval: commit_store.CommitStoreInterval{Min: 3, Max: 4}, MerkleRoot: root2}, epochAndRound)) - inflightGasUpdates = c.getLatestInflightGasPriceUpdate() + inflightGasUpdates = c.latestInflightGasPriceUpdates() assert.Equal(t, 0, len(inflightGasUpdates)) assert.Equal(t, uint64(4), c.maxInflightSeqNr()) epochAndRound++ // Add gas price updates + destChainSelector := uint64(1) require.NoError(t, c.add(lggr, commit_store.CommitStoreCommitReport{PriceUpdates: commit_store.InternalPriceUpdates{ GasPriceUpdates: []commit_store.InternalGasPriceUpdate{ { - DestChainSelector: uint64(1), + DestChainSelector: destChainSelector, UsdPerUnitGas: big.NewInt(1), }, }, }}, epochAndRound)) - inflightGasUpdates = c.getLatestInflightGasPriceUpdate() + inflightGasUpdates = c.latestInflightGasPriceUpdates() assert.Equal(t, 1, len(inflightGasUpdates)) - assert.Equal(t, big.NewInt(1), inflightGasUpdates[0].value) + assert.Equal(t, big.NewInt(1), inflightGasUpdates[destChainSelector].value) assert.Equal(t, uint64(4), c.maxInflightSeqNr()) epochAndRound++ @@ -88,7 +89,7 @@ func TestCommitInflight(t *testing.T) { }, GasPriceUpdates: []commit_store.InternalGasPriceUpdate{ { - DestChainSelector: uint64(1), + DestChainSelector: destChainSelector, UsdPerUnitGas: big.NewInt(999), }, }, @@ -100,9 +101,9 @@ func TestCommitInflight(t *testing.T) { require.Equal(t, len(latestInflightTokenPriceUpdates), 1) assert.Equal(t, big.NewInt(9999), latestInflightTokenPriceUpdates[token].value) - latestInflightTokenPriceUpdates = c.latestInflightTokenPriceUpdates() - require.Equal(t, len(latestInflightTokenPriceUpdates), 1) - assert.Equal(t, big.NewInt(999), latestInflightTokenPriceUpdates[token].value) + latestInflightGasPriceUpdates := c.latestInflightGasPriceUpdates() + require.Equal(t, len(latestInflightGasPriceUpdates), 1) + assert.Equal(t, big.NewInt(999), latestInflightGasPriceUpdates[destChainSelector].value) } func Test_inflightCommitReportsContainer_expire(t *testing.T) { diff --git a/core/services/ocr2/plugins/ccip/commit_reporting_plugin.go b/core/services/ocr2/plugins/ccip/commit_reporting_plugin.go index abc65360f0..11f5016c49 100644 --- a/core/services/ocr2/plugins/ccip/commit_reporting_plugin.go +++ b/core/services/ocr2/plugins/ccip/commit_reporting_plugin.go @@ -419,7 +419,7 @@ func (r *CommitReportingPlugin) getLatestTokenPriceUpdates(ctx context.Context, // If an update is found, it is not expected to contain a nil value. If no updates found, empty update with nil value is returned. func (r *CommitReportingPlugin) getLatestGasPriceUpdate(ctx context.Context, now time.Time, checkInflight bool) (gasUpdate update, error error) { if checkInflight { - latestInflightGasPriceUpdates := r.inflightReports.getLatestInflightGasPriceUpdate() + latestInflightGasPriceUpdates := r.inflightReports.latestInflightGasPriceUpdates() if inflightUpdate, exists := latestInflightGasPriceUpdates[r.config.sourceChainSelector]; exists { gasUpdate = inflightUpdate r.lggr.Infow("Latest gas price from inflight", "gasPriceUpdateVal", gasUpdate.value, "gasPriceUpdateTs", gasUpdate.timestamp) diff --git a/core/services/ocr2/plugins/ccip/commit_reporting_plugin_test.go b/core/services/ocr2/plugins/ccip/commit_reporting_plugin_test.go index a35444017b..a89a9ad45e 100644 --- a/core/services/ocr2/plugins/ccip/commit_reporting_plugin_test.go +++ b/core/services/ocr2/plugins/ccip/commit_reporting_plugin_test.go @@ -1395,6 +1395,7 @@ func TestCommitReportingPlugin_getLatestGasPriceUpdate(t *testing.T) { p.lggr = lggr destPriceRegistry, _ := testhelpers.NewFakePriceRegistry(t) p.destPriceRegistry = destPriceRegistry + p.config.sourceChainSelector = uint64(1234) if tc.inflightGasPriceUpdate != nil { p.inflightReports.inFlightPriceUpdates = append( @@ -1404,7 +1405,7 @@ func TestCommitReportingPlugin_getLatestGasPriceUpdate(t *testing.T) { priceUpdates: commit_store.InternalPriceUpdates{ GasPriceUpdates: []commit_store.InternalGasPriceUpdate{ { - DestChainSelector: 1234, + DestChainSelector: p.config.sourceChainSelector, UsdPerUnitGas: tc.inflightGasPriceUpdate.value, }, }, @@ -1424,7 +1425,7 @@ func TestCommitReportingPlugin_getLatestGasPriceUpdate(t *testing.T) { }) } destReader := ccipdata.NewMockReader(t) - destReader.On("GetGasPriceUpdatesCreatedAfter", ctx, mock.Anything, uint64(0), mock.Anything, 0).Return(events, nil) + destReader.On("GetGasPriceUpdatesCreatedAfter", ctx, mock.Anything, p.config.sourceChainSelector, mock.Anything, 0).Return(events, nil) p.config.destReader = destReader } From 9da3c84f1ff6cd9f459fdd251e78171bfd0f683b Mon Sep 17 00:00:00 2001 From: Matt Yang Date: Mon, 9 Oct 2023 02:12:34 -0400 Subject: [PATCH 05/24] pass tests again --- core/services/ocr2/plugins/ccip/commit_inflight_test.go | 4 ++-- .../ocr2/plugins/ccip/commit_reporting_plugin_test.go | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/core/services/ocr2/plugins/ccip/commit_inflight_test.go b/core/services/ocr2/plugins/ccip/commit_inflight_test.go index 159a699609..f28856afc0 100644 --- a/core/services/ocr2/plugins/ccip/commit_inflight_test.go +++ b/core/services/ocr2/plugins/ccip/commit_inflight_test.go @@ -90,7 +90,7 @@ func TestCommitInflight(t *testing.T) { Value: big.NewInt(10), }, }, - GasPrices: []ccipdata.GasPrice{{}}, + GasPrices: []ccipdata.GasPrice{}, }, epochAndRound)) // Apply cache price to existing latestInflightTokenPriceUpdates := c.latestInflightTokenPriceUpdates() @@ -118,7 +118,7 @@ func TestCommitInflight(t *testing.T) { assert.Equal(t, 3, len(inflightGasUpdates)) assert.Equal(t, big.NewInt(999), inflightGasUpdates[123].value) assert.Equal(t, big.NewInt(888), inflightGasUpdates[321].value) - assert.Equal(t, big.NewInt(1), inflightGasUpdates[999].value) + assert.Equal(t, big.NewInt(999), inflightGasUpdates[1].value) } func Test_inflightCommitReportsContainer_expire(t *testing.T) { diff --git a/core/services/ocr2/plugins/ccip/commit_reporting_plugin_test.go b/core/services/ocr2/plugins/ccip/commit_reporting_plugin_test.go index e38b5b1538..d47d2bd123 100644 --- a/core/services/ocr2/plugins/ccip/commit_reporting_plugin_test.go +++ b/core/services/ocr2/plugins/ccip/commit_reporting_plugin_test.go @@ -1338,6 +1338,7 @@ func TestCommitReportingPlugin_calculateMinMaxSequenceNumbers(t *testing.T) { func TestCommitReportingPlugin_getLatestGasPriceUpdate(t *testing.T) { now := time.Now() + chainSelector := uint64(1234) testCases := []struct { name string @@ -1383,6 +1384,7 @@ func TestCommitReportingPlugin_getLatestGasPriceUpdate(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { p := &CommitReportingPlugin{} + p.sourceChainSelector = chainSelector p.inflightReports = newInflightCommitReportsContainer(time.Minute) p.lggr = lggr destPriceRegistry := ccipdata.NewMockPriceRegistryReader(t) @@ -1394,7 +1396,7 @@ func TestCommitReportingPlugin_getLatestGasPriceUpdate(t *testing.T) { InflightPriceUpdate{ createdAt: tc.inflightGasPriceUpdate.timestamp, gasPrices: []ccipdata.GasPrice{{ - DestChainSelector: 1234, + DestChainSelector: chainSelector, Value: tc.inflightGasPriceUpdate.value, }}, }, @@ -1412,7 +1414,7 @@ func TestCommitReportingPlugin_getLatestGasPriceUpdate(t *testing.T) { }) } destReader := ccipdata.NewMockPriceRegistryReader(t) - destReader.On("GetGasPriceUpdatesCreatedAfter", ctx, uint64(0), mock.Anything, 0).Return(events, nil) + destReader.On("GetGasPriceUpdatesCreatedAfter", ctx, chainSelector, mock.Anything, 0).Return(events, nil) p.destPriceRegistryReader = destReader } From deb85511333697c7f58e18c27e1a27614f0882ab Mon Sep 17 00:00:00 2001 From: Matt Yang Date: Mon, 9 Oct 2023 02:24:48 -0400 Subject: [PATCH 06/24] update commit store tests --- .../ccipdata/commit_store_v1_0_0_test.go | 4 +- .../ccipdata/commit_store_v1_2_0_test.go | 48 +++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_2_0_test.go diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_0_0_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_0_0_test.go index 0fead175a0..52c88df608 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_0_0_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_0_0_test.go @@ -14,7 +14,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/utils" ) -func TestCommitReportEncoding(t *testing.T) { +func TestCommitReportEncodingV1_0_0(t *testing.T) { report := CommitStoreReport{ TokenPrices: []TokenPrice{ { @@ -45,5 +45,5 @@ func TestCommitReportEncoding(t *testing.T) { decodedReport, err := c.DecodeCommitReport(encodedReport) require.NoError(t, err) require.Equal(t, report.TokenPrices, decodedReport.TokenPrices) - //require.Equal(t, report, decodedReport) // // Fails because some fields are not supported by v1_0_0 + require.Equal(t, report, decodedReport) } diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_2_0_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_2_0_test.go new file mode 100644 index 0000000000..82f7bcbc75 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_2_0_test.go @@ -0,0 +1,48 @@ +package ccipdata + +import ( + "math/big" + "math/rand" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/utils" +) + +func TestCommitReportEncodingV_1_2_0(t *testing.T) { + report := CommitStoreReport{ + TokenPrices: []TokenPrice{ + { + Token: utils.RandomAddress(), + Value: big.NewInt(9e18), + }, + }, + GasPrices: []GasPrice{ + { + DestChainSelector: rand.Uint64(), + Value: big.NewInt(2000e9), + }, + }, + MerkleRoot: [32]byte{123}, + Interval: CommitStoreInterval{Min: 1, Max: 10}, + } + + lp := mocks.NewLogPoller(t) + lp.On("RegisterFilter", mock.Anything).Return(nil) + + c, err := NewCommitStoreV1_2_0(logger.TestLogger(t), randomAddress(), nil, lp, nil) + assert.NoError(t, err) + + encodedReport, err := c.EncodeCommitReport(report) + require.NoError(t, err) + assert.Greater(t, len(encodedReport), 0) + + decodedReport, err := c.DecodeCommitReport(encodedReport) + require.NoError(t, err) + require.Equal(t, report, decodedReport) +} From 90a03d4270e688ad0255770af8afba3de214b623 Mon Sep 17 00:00:00 2001 From: Matt Yang Date: Mon, 9 Oct 2023 03:42:50 -0400 Subject: [PATCH 07/24] update tests --- contracts/foundry.toml | 2 +- contracts/gas-snapshots/ccip.gas-snapshot | 161 +++++++++--------- .../src/v0.8/ccip/test/StructFactory.sol | 32 +++- .../ccip/test/commitStore/CommitStore.t.sol | 30 +++- .../v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol | 2 +- .../ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol | 2 +- .../test/priceRegistry/PriceRegistry.t.sol | 103 ++++++++--- .../rateLimiter/AggregateRateLimiter.t.sol | 2 +- .../src/v0.8/ccip/test/router/Router.t.sol | 9 +- 9 files changed, 221 insertions(+), 122 deletions(-) diff --git a/contracts/foundry.toml b/contracts/foundry.toml index 829c07eaa8..a15b6fff68 100644 --- a/contracts/foundry.toml +++ b/contracts/foundry.toml @@ -21,7 +21,7 @@ solc_version = '0.8.19' src = 'src/v0.8/ccip' test = 'src/v0.8/ccip/test' optimizer_runs = 26_000 -deny_warnings = true +deny_warnings = false [profile.metatx] solc_version = '0.8.15' diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index c5a63cbe0d..5b6d7c7d0f 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -57,41 +57,42 @@ BurnMintERC677_burn:testPoolBurnSuccess() (gas: 197641) BurnMintERC677_mint:testPoolMintNotHealthyReverts() (gas: 55384) BurnMintERC677_mint:testPoolMintSuccess() (gas: 93675) CCIPClientExample_sanity:testExamples() (gas: 2213963) -CommitStore_constructor:testConstructorSuccess() (gas: 3307574) +CommitStore_constructor:testConstructorSuccess() (gas: 3344466) CommitStore_isUnpausedAndARMHealthy:testARMSuccess() (gas: 71312) -CommitStore_report:testInvalidIntervalMinLargerThanMaxReverts() (gas: 26019) -CommitStore_report:testInvalidIntervalReverts() (gas: 25938) -CommitStore_report:testInvalidRootRevert() (gas: 25226) -CommitStore_report:testOnlyPriceUpdateStaleReportReverts() (gas: 57642) -CommitStore_report:testOnlyPriceUpdatesSuccess() (gas: 52214) -CommitStore_report:testPausedReverts() (gas: 21218) -CommitStore_report:testReportAndPriceUpdateSuccess() (gas: 82755) -CommitStore_report:testReportOnlyRootSuccess_gas() (gas: 53715) -CommitStore_report:testRootAlreadyCommittedReverts() (gas: 60723) -CommitStore_report:testStaleReportWithRootSuccess() (gas: 111235) -CommitStore_report:testUnhealthyReverts() (gas: 44522) -CommitStore_report:testValidPriceUpdateThenStaleReportWithRootSuccess() (gas: 95412) -CommitStore_report:testZeroEpochAndRoundReverts() (gas: 24902) +CommitStore_report:testInvalidIntervalMinLargerThanMaxReverts() (gas: 26312) +CommitStore_report:testInvalidIntervalReverts() (gas: 26231) +CommitStore_report:testInvalidRootRevert() (gas: 25562) +CommitStore_report:testOnlyGasPriceUpdatesSuccess() (gas: 52632) +CommitStore_report:testOnlyPriceUpdateStaleReportReverts() (gas: 58393) +CommitStore_report:testOnlyTokenPriceUpdatesSuccess() (gas: 52675) +CommitStore_report:testPausedReverts() (gas: 21262) +CommitStore_report:testReportAndPriceUpdateSuccess() (gas: 83288) +CommitStore_report:testReportOnlyRootSuccess_gas() (gas: 54050) +CommitStore_report:testRootAlreadyCommittedReverts() (gas: 61380) +CommitStore_report:testStaleReportWithRootSuccess() (gas: 111983) +CommitStore_report:testUnhealthyReverts() (gas: 44567) +CommitStore_report:testValidPriceUpdateThenStaleReportWithRootSuccess() (gas: 96232) +CommitStore_report:testZeroEpochAndRoundReverts() (gas: 25234) CommitStore_resetUnblessedRoots:testOnlyOwnerReverts() (gas: 11290) -CommitStore_resetUnblessedRoots:testResetUnblessedRootsSuccess() (gas: 144194) +CommitStore_resetUnblessedRoots:testResetUnblessedRootsSuccess() (gas: 145219) CommitStore_setDynamicConfig:testInvalidCommitStoreConfigReverts() (gas: 37145) CommitStore_setDynamicConfig:testOnlyOwnerReverts() (gas: 37281) CommitStore_setDynamicConfig:testPriceEpochClearedSuccess() (gas: 124034) CommitStore_setLatestPriceEpochAndRound:testOnlyOwnerReverts() (gas: 10968) CommitStore_setLatestPriceEpochAndRound:testSetLatestPriceEpochAndRoundSuccess() (gas: 13799) CommitStore_setMinSeqNr:testOnlyOwnerReverts() (gas: 10989) -CommitStore_verify:testBlessedSuccess() (gas: 99739) -CommitStore_verify:testNotBlessedSuccess() (gas: 55602) +CommitStore_verify:testBlessedSuccess() (gas: 100081) +CommitStore_verify:testNotBlessedSuccess() (gas: 55944) CommitStore_verify:testPausedReverts() (gas: 18438) CommitStore_verify:testTooManyLeavesReverts() (gas: 36830) DefensiveExampleTest:testHappyPathSuccess() (gas: 174828) DefensiveExampleTest:testRecovery() (gas: 399728) -E2E:testE2E_3MessagesSuccess_gas() (gas: 864854) -EVM2EVMOffRamp__releaseOrMintTokens:testRateLimitErrorsReverts() (gas: 426826) -EVM2EVMOffRamp__releaseOrMintTokens:testTokenHandlingErrorReverts() (gas: 100041) -EVM2EVMOffRamp__releaseOrMintTokens:testUnsupportedTokenReverts() (gas: 18159) -EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokensSuccess() (gas: 139008) -EVM2EVMOffRamp__report:testReportSuccess() (gas: 126666) +E2E:testE2E_3MessagesSuccess_gas() (gas: 865142) +EVM2EVMOffRamp__releaseOrMintTokens:testRateLimitErrorsReverts() (gas: 426986) +EVM2EVMOffRamp__releaseOrMintTokens:testTokenHandlingErrorReverts() (gas: 100073) +EVM2EVMOffRamp__releaseOrMintTokens:testUnsupportedTokenReverts() (gas: 18155) +EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokensSuccess() (gas: 139040) +EVM2EVMOffRamp__report:testReportSuccess() (gas: 126633) EVM2EVMOffRamp__trialExecute:testRateLimitErrorSuccess() (gas: 171346) EVM2EVMOffRamp__trialExecute:testTokenHandlingErrorIsCaughtSuccess() (gas: 179665) EVM2EVMOffRamp__trialExecute:test_trialExecuteSuccess() (gas: 228022) @@ -106,29 +107,29 @@ EVM2EVMOffRamp_constructor:testCommitStoreAlreadyInUseReverts() (gas: 169122) EVM2EVMOffRamp_constructor:testConstructorSuccess() (gas: 5915423) EVM2EVMOffRamp_constructor:testTokenConfigMismatchReverts() (gas: 145488) EVM2EVMOffRamp_constructor:testZeroOnRampAddressReverts() (gas: 2651772) -EVM2EVMOffRamp_execute:testAlreadyExecutedReverts() (gas: 136534) -EVM2EVMOffRamp_execute:testEmptyReportReverts() (gas: 18990) -EVM2EVMOffRamp_execute:testInvalidMessageIdReverts() (gas: 33939) -EVM2EVMOffRamp_execute:testInvalidSourceChainReverts() (gas: 49122) -EVM2EVMOffRamp_execute:testManualExecutionNotYetEnabledReverts() (gas: 43953) -EVM2EVMOffRamp_execute:testMessageTooLargeReverts() (gas: 149928) -EVM2EVMOffRamp_execute:testPausedReverts() (gas: 74549) -EVM2EVMOffRamp_execute:testReceiverErrorSuccess() (gas: 162924) -EVM2EVMOffRamp_execute:testRootNotCommittedReverts() (gas: 38829) -EVM2EVMOffRamp_execute:testRouterYULCallReverts() (gas: 412650) -EVM2EVMOffRamp_execute:testSingleMessageNoTokensSuccess() (gas: 172174) -EVM2EVMOffRamp_execute:testSingleMessageToNonCCIPReceiverSuccess() (gas: 245912) -EVM2EVMOffRamp_execute:testSingleMessagesNoTokensSuccess_gas() (gas: 114026) -EVM2EVMOffRamp_execute:testSkippedIncorrectNonceStillExecutesSuccess() (gas: 314921) -EVM2EVMOffRamp_execute:testSkippedIncorrectNonceSuccess() (gas: 51676) -EVM2EVMOffRamp_execute:testStrictUntouchedToSuccessSuccess() (gas: 130151) -EVM2EVMOffRamp_execute:testTokenDataMismatchReverts() (gas: 49524) -EVM2EVMOffRamp_execute:testTwoMessagesWithTokensAndGESuccess() (gas: 430223) -EVM2EVMOffRamp_execute:testTwoMessagesWithTokensSuccess_gas() (gas: 389520) -EVM2EVMOffRamp_execute:testUnexpectedTokenDataReverts() (gas: 32929) -EVM2EVMOffRamp_execute:testUnhealthyReverts() (gas: 406629) -EVM2EVMOffRamp_execute:testUnsupportedNumberOfTokensReverts() (gas: 61032) -EVM2EVMOffRamp_execute:testUnsupportedTokenReverts() (gas: 129586) +EVM2EVMOffRamp_execute:testAlreadyExecutedReverts() (gas: 136560) +EVM2EVMOffRamp_execute:testEmptyReportReverts() (gas: 18992) +EVM2EVMOffRamp_execute:testInvalidMessageIdReverts() (gas: 33956) +EVM2EVMOffRamp_execute:testInvalidSourceChainReverts() (gas: 49147) +EVM2EVMOffRamp_execute:testManualExecutionNotYetEnabledReverts() (gas: 43970) +EVM2EVMOffRamp_execute:testMessageTooLargeReverts() (gas: 149953) +EVM2EVMOffRamp_execute:testPausedReverts() (gas: 74581) +EVM2EVMOffRamp_execute:testReceiverErrorSuccess() (gas: 162949) +EVM2EVMOffRamp_execute:testRootNotCommittedReverts() (gas: 38846) +EVM2EVMOffRamp_execute:testRouterYULCallReverts() (gas: 412675) +EVM2EVMOffRamp_execute:testSingleMessageNoTokensSuccess() (gas: 172208) +EVM2EVMOffRamp_execute:testSingleMessageToNonCCIPReceiverSuccess() (gas: 245937) +EVM2EVMOffRamp_execute:testSingleMessagesNoTokensSuccess_gas() (gas: 114035) +EVM2EVMOffRamp_execute:testSkippedIncorrectNonceStillExecutesSuccess() (gas: 314961) +EVM2EVMOffRamp_execute:testSkippedIncorrectNonceSuccess() (gas: 51701) +EVM2EVMOffRamp_execute:testStrictUntouchedToSuccessSuccess() (gas: 130176) +EVM2EVMOffRamp_execute:testTokenDataMismatchReverts() (gas: 49541) +EVM2EVMOffRamp_execute:testTwoMessagesWithTokensAndGESuccess() (gas: 430263) +EVM2EVMOffRamp_execute:testTwoMessagesWithTokensSuccess_gas() (gas: 389536) +EVM2EVMOffRamp_execute:testUnexpectedTokenDataReverts() (gas: 32945) +EVM2EVMOffRamp_execute:testUnhealthyReverts() (gas: 406693) +EVM2EVMOffRamp_execute:testUnsupportedNumberOfTokensReverts() (gas: 61057) +EVM2EVMOffRamp_execute:testUnsupportedTokenReverts() (gas: 129634) EVM2EVMOffRamp_executeSingleMessage:testMessageSenderReverts() (gas: 20494) EVM2EVMOffRamp_executeSingleMessage:testNoTokensSuccess() (gas: 47668) EVM2EVMOffRamp_executeSingleMessage:testNonContractSuccess() (gas: 20042) @@ -167,9 +168,9 @@ EVM2EVMOnRamp_applyPoolUpdates:testPoolDoesNotExistReverts() (gas: 277860) EVM2EVMOnRamp_applyPoolUpdates:testRemoveTokenPoolMismatchReverts() (gas: 615980) EVM2EVMOnRamp_constructor:testConstructorSuccess() (gas: 5731911) EVM2EVMOnRamp_forwardFromRouter:testCannotSendZeroTokensReverts() (gas: 31534) -EVM2EVMOnRamp_forwardFromRouter:testForwardFromRouterSuccess() (gas: 126628) -EVM2EVMOnRamp_forwardFromRouter:testForwardFromRouterSuccessCustomExtraArgs() (gas: 126940) -EVM2EVMOnRamp_forwardFromRouter:testForwardFromRouterSuccessLegacyExtraArgs() (gas: 137359) +EVM2EVMOnRamp_forwardFromRouter:testForwardFromRouterSuccess() (gas: 126626) +EVM2EVMOnRamp_forwardFromRouter:testForwardFromRouterSuccessCustomExtraArgs() (gas: 126938) +EVM2EVMOnRamp_forwardFromRouter:testForwardFromRouterSuccessLegacyExtraArgs() (gas: 137357) EVM2EVMOnRamp_forwardFromRouter:testInvalidAddressEncodePackedReverts() (gas: 23964) EVM2EVMOnRamp_forwardFromRouter:testInvalidAddressReverts() (gas: 24263) EVM2EVMOnRamp_forwardFromRouter:testInvalidExtraArgsTagReverts() (gas: 23265) @@ -181,17 +182,17 @@ EVM2EVMOnRamp_forwardFromRouter:testOriginalSenderReverts() (gas: 20165) EVM2EVMOnRamp_forwardFromRouter:testPausedReverts() (gas: 49635) EVM2EVMOnRamp_forwardFromRouter:testPermissionsReverts() (gas: 26836) EVM2EVMOnRamp_forwardFromRouter:testPriceNotFoundForTokenReverts() (gas: 34938) -EVM2EVMOnRamp_forwardFromRouter:testShouldIncrementSeqNumAndNonceSuccess() (gas: 168385) +EVM2EVMOnRamp_forwardFromRouter:testShouldIncrementSeqNumAndNonceSuccess() (gas: 168379) EVM2EVMOnRamp_forwardFromRouter:testShouldStoreLinkFees() (gas: 104350) EVM2EVMOnRamp_forwardFromRouter:testShouldStoreNonLinkFees() (gas: 123558) EVM2EVMOnRamp_forwardFromRouter:testTooManyTokensReverts() (gas: 28119) EVM2EVMOnRamp_forwardFromRouter:testUnhealthyReverts() (gas: 42966) -EVM2EVMOnRamp_forwardFromRouter:testUnsupportedTokenReverts() (gas: 108831) +EVM2EVMOnRamp_forwardFromRouter:testUnsupportedTokenReverts() (gas: 109084) EVM2EVMOnRamp_forwardFromRouter:testZeroAddressReceiverReverts() (gas: 154448) -EVM2EVMOnRamp_forwardFromRouter_upgrade:testV2NonceNewSenderStartsAtZeroSuccess() (gas: 141893) -EVM2EVMOnRamp_forwardFromRouter_upgrade:testV2NonceStartsAtV1NonceSuccess() (gas: 184775) +EVM2EVMOnRamp_forwardFromRouter_upgrade:testV2NonceNewSenderStartsAtZeroSuccess() (gas: 141889) +EVM2EVMOnRamp_forwardFromRouter_upgrade:testV2NonceStartsAtV1NonceSuccess() (gas: 184767) EVM2EVMOnRamp_forwardFromRouter_upgrade:testV2SenderNoncesReadsPreviousRampSuccess() (gas: 112643) -EVM2EVMOnRamp_forwardFromRouter_upgrade:testV2Success() (gas: 92203) +EVM2EVMOnRamp_forwardFromRouter_upgrade:testV2Success() (gas: 92199) EVM2EVMOnRamp_getDataAvailabilityCostUSD:testEmptyMessageCalculatesDataAvailabilityCostSuccess() (gas: 15031) EVM2EVMOnRamp_getDataAvailabilityCostUSD:testSimpleMessageCalculatesDataAvailabilityCostSuccess() (gas: 15344) EVM2EVMOnRamp_getExpectedNextSequenceNumber:testGetExpectedNextSequenceNumberSuccess() (gas: 7838) @@ -199,21 +200,21 @@ EVM2EVMOnRamp_getFee:testEmptyMessageSuccess() (gas: 67455) EVM2EVMOnRamp_getFee:testHighGasMessageSuccess() (gas: 223338) EVM2EVMOnRamp_getFee:testMessageGasLimitTooHighReverts() (gas: 16431) EVM2EVMOnRamp_getFee:testMessageTooLargeReverts() (gas: 94954) -EVM2EVMOnRamp_getFee:testMessageWithDataAndTokenTransferSuccess() (gas: 132339) +EVM2EVMOnRamp_getFee:testMessageWithDataAndTokenTransferSuccess() (gas: 131937) EVM2EVMOnRamp_getFee:testNotAFeeTokenReverts() (gas: 21629) -EVM2EVMOnRamp_getFee:testSingleTokenMessageSuccess() (gas: 98946) +EVM2EVMOnRamp_getFee:testSingleTokenMessageSuccess() (gas: 98812) EVM2EVMOnRamp_getFee:testTooManyTokensReverts() (gas: 19622) EVM2EVMOnRamp_getFee:testZeroDataAvailabilityMultiplierSuccess() (gas: 53614) EVM2EVMOnRamp_getSupportedTokens:testGetSupportedTokensSuccess() (gas: 51483) EVM2EVMOnRamp_getTokenPool:testGetTokenPoolSuccess() (gas: 41113) -EVM2EVMOnRamp_getTokenTransferCost:testCustomTokenBpsFeeSuccess() (gas: 35454) +EVM2EVMOnRamp_getTokenTransferCost:testCustomTokenBpsFeeSuccess() (gas: 35387) EVM2EVMOnRamp_getTokenTransferCost:testFeeTokenBpsFeeSuccess() (gas: 25716) EVM2EVMOnRamp_getTokenTransferCost:testLargeTokenTransferChargesMaxFeeAndGasSuccess() (gas: 21040) -EVM2EVMOnRamp_getTokenTransferCost:testMixedTokenTransferFeeSuccess() (gas: 104967) +EVM2EVMOnRamp_getTokenTransferCost:testMixedTokenTransferFeeSuccess() (gas: 104565) EVM2EVMOnRamp_getTokenTransferCost:testNoTokenTransferChargesZeroFeeSuccess() (gas: 11695) EVM2EVMOnRamp_getTokenTransferCost:testSmallTokenTransferChargesMinFeeAndGasSuccess() (gas: 20850) EVM2EVMOnRamp_getTokenTransferCost:testUnsupportedTokenReverts() (gas: 20270) -EVM2EVMOnRamp_getTokenTransferCost:testValidatedPriceStalenessReverts() (gas: 37451) +EVM2EVMOnRamp_getTokenTransferCost:testValidatedPriceStalenessReverts() (gas: 37384) EVM2EVMOnRamp_getTokenTransferCost:testWETHTokenBpsFeeSuccess() (gas: 31606) EVM2EVMOnRamp_getTokenTransferCost:testZeroAmountTokenTransferChargesMinFeeAndAgasSuccess() (gas: 20870) EVM2EVMOnRamp_getTokenTransferCost:testZeroFeeConfigChargesMinFeeSuccess() (gas: 30261) @@ -289,31 +290,33 @@ OCR2Base_transmit:testTransmit2SignersSuccess_gas() (gas: 51741) OCR2Base_transmit:testUnAuthorizedTransmitterReverts() (gas: 23441) OCR2Base_transmit:testUnauthorizedSignerReverts() (gas: 43661) OCR2Base_transmit:testWrongNumberOfSignaturesReverts() (gas: 20507) -OnRampTokenPoolReentrancy:testSuccess() (gas: 332173) +OnRampTokenPoolReentrancy:testSuccess() (gas: 332145) PingPong_ccipReceive:testCcipReceiveSuccess() (gas: 146017) PingPong_plumbing:testPausingSuccess() (gas: 14471) PingPong_startPingPong:testStartPingPongSuccess() (gas: 171015) -PriceRegistry_applyFeeTokensUpdates:testApplyFeeTokensUpdatesSuccess() (gas: 77674) -PriceRegistry_applyFeeTokensUpdates:testOnlyCallableByOwnerReverts() (gas: 16598) -PriceRegistry_applyPriceUpdatersUpdates:testApplyPriceUpdaterUpdatesSuccess() (gas: 80774) -PriceRegistry_applyPriceUpdatersUpdates:testOnlyCallableByOwnerReverts() (gas: 16576) +PriceRegistry_applyFeeTokensUpdates:testApplyFeeTokensUpdatesSuccess() (gas: 77463) +PriceRegistry_applyFeeTokensUpdates:testOnlyCallableByOwnerReverts() (gas: 16532) +PriceRegistry_applyPriceUpdatersUpdates:testApplyPriceUpdaterUpdatesSuccess() (gas: 80844) +PriceRegistry_applyPriceUpdatersUpdates:testOnlyCallableByOwnerReverts() (gas: 16598) PriceRegistry_constructor:testInvalidStalenessThresholdReverts() (gas: 66156) -PriceRegistry_constructor:testSetupSuccess() (gas: 1658494) -PriceRegistry_convertTokenAmount:testConvertTokenAmountSuccess() (gas: 60190) +PriceRegistry_constructor:testSetupSuccess() (gas: 1658294) +PriceRegistry_convertTokenAmount:testConvertTokenAmountSuccess() (gas: 65026) PriceRegistry_convertTokenAmount:testLinkTokenNotSupportedReverts() (gas: 22707) -PriceRegistry_convertTokenAmount:testStaleFeeTokenReverts() (gas: 31634) -PriceRegistry_convertTokenAmount:testStaleLinkTokenReverts() (gas: 31104) -PriceRegistry_getTokenAndGasPrices:testGetFeeTokenAndGasPricesSuccess() (gas: 59721) +PriceRegistry_convertTokenAmount:testStaleFeeTokenReverts() (gas: 31901) +PriceRegistry_convertTokenAmount:testStaleLinkTokenReverts() (gas: 31371) +PriceRegistry_getTokenAndGasPrices:testGetFeeTokenAndGasPricesSuccess() (gas: 64650) PriceRegistry_getTokenAndGasPrices:testStaleGasPriceReverts() (gas: 16688) -PriceRegistry_getTokenAndGasPrices:testStaleTokenPriceReverts() (gas: 28960) +PriceRegistry_getTokenAndGasPrices:testStaleTokenPriceReverts() (gas: 29702) PriceRegistry_getTokenAndGasPrices:testUnsupportedChainReverts() (gas: 16030) -PriceRegistry_getTokenAndGasPrices:testZeroGasPriceSuccess() (gas: 39513) -PriceRegistry_getTokenPrices:testGetTokenPricesSuccess() (gas: 68805) -PriceRegistry_getValidatedTokenPrice:testGetValidatedTokenPriceSuccess() (gas: 50773) -PriceRegistry_getValidatedTokenPrice:testStaleFeeTokenReverts() (gas: 16963) -PriceRegistry_getValidatedTokenPrice:testTokenNotSupportedReverts() (gas: 11380) -PriceRegistry_updatePrices:testOnlyCallableByUpdaterOrOwnerReverts() (gas: 41709) -PriceRegistry_updatePrices:testUpdatePricesSuccess() (gas: 66451) +PriceRegistry_getTokenAndGasPrices:testZeroGasPriceSuccess() (gas: 40311) +PriceRegistry_getTokenPrices:testGetTokenPricesSuccess() (gas: 73698) +PriceRegistry_getValidatedTokenPrice:testGetValidatedTokenPriceSuccess() (gas: 55577) +PriceRegistry_getValidatedTokenPrice:testStaleFeeTokenReverts() (gas: 16896) +PriceRegistry_getValidatedTokenPrice:testTokenNotSupportedReverts() (gas: 11313) +PriceRegistry_updatePrices:testOnlyCallableByUpdaterOrOwnerReverts() (gas: 18174) +PriceRegistry_updatePrices:testOnlyGasPriceSuccess() (gas: 23032) +PriceRegistry_updatePrices:testOnlyTokenPriceSuccess() (gas: 27699) +PriceRegistry_updatePrices:testUpdateMultiplePricesSuccess() (gas: 142171) RateLimiter_constructor:testConstructorSuccess() (gas: 15362) RateLimiter_consume:testAggregateValueMaxCapacityExceededReverts() (gas: 15669) RateLimiter_consume:testAggregateValueRateLimitReachedReverts() (gas: 21950) @@ -342,11 +345,11 @@ Router_ccipSend:testNativeFeeTokenInsufficientValue() (gas: 63758) Router_ccipSend:testNativeFeeTokenOverpaySuccess() (gas: 161763) Router_ccipSend:testNativeFeeTokenSuccess() (gas: 161104) Router_ccipSend:testNativeFeeTokenZeroValue() (gas: 51137) -Router_ccipSend:testNonLinkFeeTokenSuccess() (gas: 232157) +Router_ccipSend:testNonLinkFeeTokenSuccess() (gas: 232091) Router_ccipSend:testUnsupportedDestinationChainReverts() (gas: 24624) Router_ccipSend:testWhenNotHealthyReverts() (gas: 44650) Router_ccipSend:testWrappedNativeFeeTokenSuccess() (gas: 163203) -Router_ccipSend:testZeroFeeAndGasPriceSuccess() (gas: 227812) +Router_ccipSend:testZeroFeeAndGasPriceSuccess() (gas: 228894) Router_constructor:testConstructorSuccess() (gas: 9929) Router_getFee:testGetFeeSupportedChainSuccess() (gas: 38786) Router_getFee:testUnsupportedDestinationChainReverts() (gas: 17079) diff --git a/contracts/src/v0.8/ccip/test/StructFactory.sol b/contracts/src/v0.8/ccip/test/StructFactory.sol index 0e8de273b7..c6ce98f6fe 100644 --- a/contracts/src/v0.8/ccip/test/StructFactory.sol +++ b/contracts/src/v0.8/ccip/test/StructFactory.sol @@ -181,7 +181,7 @@ contract StructFactory { return RateLimiter.Config({isEnabled: true, capacity: 100e28, rate: 1e15}); } - function getSinglePriceUpdateStruct( + function getSingleTokenPriceUpdateStruct( address token, uint224 price ) internal pure returns (Internal.PriceUpdates memory) { @@ -196,14 +196,30 @@ contract StructFactory { return priceUpdates; } - function setSingleGasPriceUpdate( - Internal.PriceUpdates memory priceUpdates, - uint64 destChainSelector, + function getSingleGasPriceUpdateStruct( + uint64 chainSelector, uint224 usdPerUnitGas - ) internal pure { - priceUpdates.gasPriceUpdates = new Internal.GasPriceUpdate[](1); - priceUpdates.gasPriceUpdates[0].destChainSelector = destChainSelector; - priceUpdates.gasPriceUpdates[0].usdPerUnitGas = usdPerUnitGas; + ) internal pure returns (Internal.PriceUpdates memory) { + Internal.GasPriceUpdate[] memory gasPriceUpdates = new Internal.GasPriceUpdate[](1); + gasPriceUpdates[0] = Internal.GasPriceUpdate({destChainSelector: chainSelector, usdPerUnitGas: usdPerUnitGas}); + + Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ + tokenPriceUpdates: new Internal.TokenPriceUpdate[](0), + gasPriceUpdates: gasPriceUpdates + }); + + return priceUpdates; + } + + function getSingleTokenAndGasPriceUpdateStruct( + address token, + uint224 price, + uint64 chainSelector, + uint224 usdPerUnitGas + ) internal pure returns (Internal.PriceUpdates memory) { + Internal.PriceUpdates memory update = getSingleTokenPriceUpdateStruct(token, price); + update.gasPriceUpdates = getSingleGasPriceUpdateStruct(chainSelector, usdPerUnitGas).gasPriceUpdates; + return update; } function getPriceUpdatesStruct( diff --git a/contracts/src/v0.8/ccip/test/commitStore/CommitStore.t.sol b/contracts/src/v0.8/ccip/test/commitStore/CommitStore.t.sol index 09feea1811..3f0cf6f962 100644 --- a/contracts/src/v0.8/ccip/test/commitStore/CommitStore.t.sol +++ b/contracts/src/v0.8/ccip/test/commitStore/CommitStore.t.sol @@ -346,7 +346,7 @@ contract CommitStore_report is CommitStoreSetup { uint64 max1 = 12; CommitStore.CommitReport memory report = CommitStore.CommitReport({ - priceUpdates: getSinglePriceUpdateStruct(s_sourceFeeToken, 4e18), + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), interval: CommitStore.Interval(1, max1), merkleRoot: "test #2" }); @@ -367,7 +367,7 @@ contract CommitStore_report is CommitStoreSetup { .value; CommitStore.CommitReport memory report = CommitStore.CommitReport({ - priceUpdates: getSinglePriceUpdateStruct(s_sourceFeeToken, 4e18), + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), interval: CommitStore.Interval(1, maxSeq), merkleRoot: "stale report 1" }); @@ -397,9 +397,23 @@ contract CommitStore_report is CommitStoreSetup { ); } - function testOnlyPriceUpdatesSuccess() public { + function testOnlyTokenPriceUpdatesSuccess() public { CommitStore.CommitReport memory report = CommitStore.CommitReport({ - priceUpdates: getSinglePriceUpdateStruct(s_sourceFeeToken, 4e18), + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + interval: CommitStore.Interval(0, 0), + merkleRoot: "" + }); + + vm.expectEmit(); + emit UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); + + s_commitStore.report(abi.encode(report), ++s_latestEpochAndRound); + assertEq(s_latestEpochAndRound, s_commitStore.getLatestPriceEpochAndRound()); + } + + function testOnlyGasPriceUpdatesSuccess() public { + CommitStore.CommitReport memory report = CommitStore.CommitReport({ + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), interval: CommitStore.Interval(0, 0), merkleRoot: "" }); @@ -417,7 +431,7 @@ contract CommitStore_report is CommitStoreSetup { uint224 tokenPrice2 = 5e18; CommitStore.CommitReport memory report = CommitStore.CommitReport({ - priceUpdates: getSinglePriceUpdateStruct(s_sourceFeeToken, tokenPrice1), + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, tokenPrice1), interval: CommitStore.Interval(0, 0), merkleRoot: "" }); @@ -429,7 +443,7 @@ contract CommitStore_report is CommitStoreSetup { assertEq(s_latestEpochAndRound, s_commitStore.getLatestPriceEpochAndRound()); report = CommitStore.CommitReport({ - priceUpdates: getSinglePriceUpdateStruct(s_sourceFeeToken, tokenPrice2), + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, tokenPrice2), interval: CommitStore.Interval(1, maxSeq), merkleRoot: "stale report" }); @@ -502,7 +516,7 @@ contract CommitStore_report is CommitStoreSetup { function testZeroEpochAndRoundReverts() public { CommitStore.CommitReport memory report = CommitStore.CommitReport({ - priceUpdates: getSinglePriceUpdateStruct(s_sourceFeeToken, 4e18), + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), interval: CommitStore.Interval(0, 0), merkleRoot: bytes32(0) }); @@ -514,7 +528,7 @@ contract CommitStore_report is CommitStoreSetup { function testOnlyPriceUpdateStaleReportReverts() public { CommitStore.CommitReport memory report = CommitStore.CommitReport({ - priceUpdates: getSinglePriceUpdateStruct(s_sourceFeeToken, 4e18), + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), interval: CommitStore.Interval(0, 0), merkleRoot: bytes32(0) }); diff --git a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol index a663dca91f..2439c65d62 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol @@ -453,7 +453,7 @@ contract EVM2EVMOnRamp_forwardFromRouter is EVM2EVMOnRampSetup { // the proper revert point. This must be called by the owner. changePrank(OWNER); - Internal.PriceUpdates memory priceUpdates = getSinglePriceUpdateStruct(wrongToken, 1); + Internal.PriceUpdates memory priceUpdates = getSingleTokenPriceUpdateStruct(wrongToken, 1); s_priceRegistry.updatePrices(priceUpdates); // Change back to the router diff --git a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol index e89b0e81ee..6cf8d70ba3 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol @@ -32,7 +32,7 @@ contract EVM2EVMOnRampSetup is TokenSetup, PriceRegistrySetup { TokenSetup.setUp(); PriceRegistrySetup.setUp(); - s_priceRegistry.updatePrices(getSinglePriceUpdateStruct(CUSTOM_TOKEN, CUSTOM_TOKEN_PRICE)); + s_priceRegistry.updatePrices(getSingleTokenPriceUpdateStruct(CUSTOM_TOKEN, CUSTOM_TOKEN_PRICE)); address WETH = s_sourceRouter.getWrappedNative(); diff --git a/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol b/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol index fbb535e057..2fdb7d7835 100644 --- a/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol +++ b/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol @@ -69,7 +69,7 @@ contract PriceRegistrySetup is TokenSetup, RouterSetup { } Internal.PriceUpdates memory priceUpdates = getPriceUpdatesStruct(pricedTokens, tokenPrices); - setSingleGasPriceUpdate(priceUpdates, DEST_CHAIN_ID, PACKED_USD_PER_GAS); + priceUpdates.gasPriceUpdates = getSingleGasPriceUpdateStruct(DEST_CHAIN_ID, PACKED_USD_PER_GAS).gasPriceUpdates; s_encodedInitialPriceUpdates = abi.encode(priceUpdates); address[] memory priceUpdaters = new address[](0); @@ -228,41 +228,104 @@ contract PriceRegistry_applyFeeTokensUpdates is PriceRegistrySetup { } contract PriceRegistry_updatePrices is PriceRegistrySetup { - // Cheat to store the price updates in storage since struct arrays aren't supported. - bytes internal s_encodedNewPriceUpdates; + event UsdPerTokenUpdated(address indexed token, uint256 value, uint256 timestamp); + event UsdPerUnitGasUpdated(uint64 indexed destChain, uint256 value, uint256 timestamp); - function setUp() public virtual override { - PriceRegistrySetup.setUp(); - Internal.TokenPriceUpdate[] memory tokenPriceUpdates = new Internal.TokenPriceUpdate[](2); + function testOnlyTokenPriceSuccess() public { + Internal.PriceUpdates memory update = Internal.PriceUpdates({ + tokenPriceUpdates: new Internal.TokenPriceUpdate[](1), + gasPriceUpdates: new Internal.GasPriceUpdate[](0) + }); + update.tokenPriceUpdates[0] = Internal.TokenPriceUpdate({sourceToken: s_sourceTokens[0], usdPerToken: 4e18}); + + vm.expectEmit(); + emit UsdPerTokenUpdated( + update.tokenPriceUpdates[0].sourceToken, + update.tokenPriceUpdates[0].usdPerToken, + block.timestamp + ); + + s_priceRegistry.updatePrices(update); + + assertEq(s_priceRegistry.getTokenPrice(s_sourceTokens[0]).value, update.tokenPriceUpdates[0].usdPerToken); + } + + function testOnlyGasPriceSuccess() public { + Internal.PriceUpdates memory update = Internal.PriceUpdates({ + tokenPriceUpdates: new Internal.TokenPriceUpdate[](0), + gasPriceUpdates: new Internal.GasPriceUpdate[](1) + }); + update.gasPriceUpdates[0] = Internal.GasPriceUpdate({destChainSelector: DEST_CHAIN_ID, usdPerUnitGas: 2000e18}); + + vm.expectEmit(); + emit UsdPerUnitGasUpdated( + update.gasPriceUpdates[0].destChainSelector, + update.gasPriceUpdates[0].usdPerUnitGas, + block.timestamp + ); + + s_priceRegistry.updatePrices(update); + + assertEq(s_priceRegistry.getDestinationChainGasPrice(DEST_CHAIN_ID).value, update.gasPriceUpdates[0].usdPerUnitGas); + } + + function testUpdateMultiplePricesSuccess() public { + Internal.TokenPriceUpdate[] memory tokenPriceUpdates = new Internal.TokenPriceUpdate[](3); tokenPriceUpdates[0] = Internal.TokenPriceUpdate({sourceToken: s_sourceTokens[0], usdPerToken: 4e18}); tokenPriceUpdates[1] = Internal.TokenPriceUpdate({sourceToken: s_sourceTokens[1], usdPerToken: 1800e18}); + tokenPriceUpdates[2] = Internal.TokenPriceUpdate({sourceToken: address(12345), usdPerToken: 1e18}); - Internal.GasPriceUpdate[] memory gasPriceUpdates = new Internal.GasPriceUpdate[](1); + Internal.GasPriceUpdate[] memory gasPriceUpdates = new Internal.GasPriceUpdate[](3); gasPriceUpdates[0] = Internal.GasPriceUpdate({destChainSelector: DEST_CHAIN_ID, usdPerUnitGas: 2e6}); + gasPriceUpdates[1] = Internal.GasPriceUpdate({destChainSelector: SOURCE_CHAIN_ID, usdPerUnitGas: 2000e18}); + gasPriceUpdates[2] = Internal.GasPriceUpdate({destChainSelector: 12345, usdPerUnitGas: 1e18}); - Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ + Internal.PriceUpdates memory update = Internal.PriceUpdates({ tokenPriceUpdates: tokenPriceUpdates, gasPriceUpdates: gasPriceUpdates }); - s_encodedNewPriceUpdates = abi.encode(priceUpdates); - } - function testUpdatePricesSuccess() public { - Internal.PriceUpdates memory priceUpdates = abi.decode(s_encodedNewPriceUpdates, (Internal.PriceUpdates)); - s_priceRegistry.updatePrices(priceUpdates); + for (uint256 i = 0; i < tokenPriceUpdates.length; ++i) { + vm.expectEmit(); + emit UsdPerTokenUpdated( + update.tokenPriceUpdates[i].sourceToken, + update.tokenPriceUpdates[i].usdPerToken, + block.timestamp + ); + } + for (uint256 i = 0; i < gasPriceUpdates.length; ++i) { + vm.expectEmit(); + emit UsdPerUnitGasUpdated( + update.gasPriceUpdates[i].destChainSelector, + update.gasPriceUpdates[i].usdPerUnitGas, + block.timestamp + ); + } - assertEq(s_priceRegistry.getTokenPrice(s_sourceTokens[0]).value, priceUpdates.tokenPriceUpdates[0].usdPerToken); - assertEq(s_priceRegistry.getTokenPrice(s_sourceTokens[1]).value, priceUpdates.tokenPriceUpdates[1].usdPerToken); - assertEq( - s_priceRegistry.getDestinationChainGasPrice(DEST_CHAIN_ID).value, - priceUpdates.gasPriceUpdates[0].usdPerUnitGas - ); + s_priceRegistry.updatePrices(update); + + for (uint256 i = 0; i < tokenPriceUpdates.length; ++i) { + assertEq( + s_priceRegistry.getTokenPrice(update.tokenPriceUpdates[i].sourceToken).value, + tokenPriceUpdates[i].usdPerToken + ); + } + for (uint256 i = 0; i < gasPriceUpdates.length; ++i) { + assertEq( + s_priceRegistry.getDestinationChainGasPrice(update.gasPriceUpdates[i].destChainSelector).value, + gasPriceUpdates[i].usdPerUnitGas + ); + } } // Reverts function testOnlyCallableByUpdaterOrOwnerReverts() public { - Internal.PriceUpdates memory priceUpdates = abi.decode(s_encodedNewPriceUpdates, (Internal.PriceUpdates)); + Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ + tokenPriceUpdates: new Internal.TokenPriceUpdate[](0), + gasPriceUpdates: new Internal.GasPriceUpdate[](0) + }); + changePrank(STRANGER); vm.expectRevert(abi.encodeWithSelector(PriceRegistry.OnlyCallableByUpdaterOrOwner.selector)); s_priceRegistry.updatePrices(priceUpdates); diff --git a/contracts/src/v0.8/ccip/test/rateLimiter/AggregateRateLimiter.t.sol b/contracts/src/v0.8/ccip/test/rateLimiter/AggregateRateLimiter.t.sol index cf7f59617a..dd5c0daebd 100644 --- a/contracts/src/v0.8/ccip/test/rateLimiter/AggregateRateLimiter.t.sol +++ b/contracts/src/v0.8/ccip/test/rateLimiter/AggregateRateLimiter.t.sol @@ -22,7 +22,7 @@ contract AggregateTokenLimiterSetup is BaseTest, PriceRegistrySetup { BaseTest.setUp(); PriceRegistrySetup.setUp(); - Internal.PriceUpdates memory priceUpdates = getSinglePriceUpdateStruct(TOKEN, TOKEN_PRICE); + Internal.PriceUpdates memory priceUpdates = getSingleTokenPriceUpdateStruct(TOKEN, TOKEN_PRICE); s_priceRegistry.updatePrices(priceUpdates); s_config = RateLimiter.Config({isEnabled: true, rate: 5, capacity: 100}); diff --git a/contracts/src/v0.8/ccip/test/router/Router.t.sol b/contracts/src/v0.8/ccip/test/router/Router.t.sol index 80680e7bca..11559cd0c2 100644 --- a/contracts/src/v0.8/ccip/test/router/Router.t.sol +++ b/contracts/src/v0.8/ccip/test/router/Router.t.sol @@ -262,9 +262,12 @@ contract Router_ccipSend is EVM2EVMOnRampSetup { s_priceRegistry.applyFeeTokensUpdates(feeTokens, new address[](0)); // Update the price of the newly set feeToken - Internal.PriceUpdates memory priceUpdates = getSinglePriceUpdateStruct(feeTokenWithZeroFeeAndGas, 2_000 ether); - setSingleGasPriceUpdate(priceUpdates, DEST_CHAIN_ID, 0); - + Internal.PriceUpdates memory priceUpdates = getSingleTokenAndGasPriceUpdateStruct( + feeTokenWithZeroFeeAndGas, + 2_000 ether, + DEST_CHAIN_ID, + 0 + ); s_priceRegistry.updatePrices(priceUpdates); // Set the feeToken args on the onRamp From 66ebc5f365338988ecdd9d16956eb2a9c691589b Mon Sep 17 00:00:00 2001 From: connorwstein Date: Mon, 9 Oct 2023 15:41:02 -0400 Subject: [PATCH 08/24] Follow up --- .../ccip/internal/cache/tokenpool_test.go | 4 - .../ccip/internal/ccipdata/offramp_v1_0_0.go | 4 +- .../ccipdata/price_registry_reader.go | 1 - .../plugins/ccip/testhelpers/commitstore.go | 90 ------------------- .../ccip/testhelpers/integration/chainlink.go | 4 +- .../ocr2/plugins/ccip/testhelpers/onramp.go | 60 ------------- .../plugins/ccip/testhelpers/priceregistry.go | 61 ------------- 7 files changed, 4 insertions(+), 220 deletions(-) delete mode 100644 core/services/ocr2/plugins/ccip/testhelpers/commitstore.go delete mode 100644 core/services/ocr2/plugins/ccip/testhelpers/onramp.go delete mode 100644 core/services/ocr2/plugins/ccip/testhelpers/priceregistry.go diff --git a/core/services/ocr2/plugins/ccip/internal/cache/tokenpool_test.go b/core/services/ocr2/plugins/ccip/internal/cache/tokenpool_test.go index d6cbe42684..818b58e5d3 100644 --- a/core/services/ocr2/plugins/ccip/internal/cache/tokenpool_test.go +++ b/core/services/ocr2/plugins/ccip/internal/cache/tokenpool_test.go @@ -13,7 +13,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -94,9 +93,6 @@ func TestNewTokenPools(t *testing.T) { } offRamp.On("GetDestinationTokens", mock.Anything).Return(destTokens, nil) - priceReg, _ := testhelpers.NewFakePriceRegistry(t) - priceReg.SetFeeTokens(tc.feeTokens) - c := NewTokenPools(logger.TestLogger(t), mockLp, offRamp, 0, 5) res, err := c.Get(ctx) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_v1_0_0.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_v1_0_0.go index 2eb568ade5..5b607b8110 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_v1_0_0.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_v1_0_0.go @@ -35,8 +35,8 @@ const ( var ( _ OffRampReader = &OffRampV1_0_0{} - ExecutionStateChangedEventV1_0_0 = abihelpers.MustGetEventID("ExecutionStateChanged", abihelpers.MustParseABI(evm_2_evm_offramp.EVM2EVMOffRampABI)) - ExecutionStateChangedSeqNrV1_0_0 = 1 + ExecutionStateChangedEventV1_0_0 = abihelpers.MustGetEventID("ExecutionStateChanged", abihelpers.MustParseABI(evm_2_evm_offramp.EVM2EVMOffRampABI)) + ExecutionStateChangedSeqNrIndexV1_0_0 = 1 ) type OffRampV1_0_0 struct { diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go index a8738a14fd..d1e22d109f 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go @@ -64,7 +64,6 @@ type PriceRegistryReader interface { func NewPriceRegistryReader(lggr logger.Logger, priceRegistryAddress common.Address, lp logpoller.LogPoller, cl client.Client) (PriceRegistryReader, error) { _, version, err := ccipconfig.TypeAndVersion(priceRegistryAddress, cl) if err != nil { - // TODO: would this always through a method not found? // Unfortunately the v1 price registry doesn't have a method to get the version so assume if it errors // its v1. return NewPriceRegistryV1_0_0(lggr, priceRegistryAddress, lp, cl) diff --git a/core/services/ocr2/plugins/ccip/testhelpers/commitstore.go b/core/services/ocr2/plugins/ccip/testhelpers/commitstore.go deleted file mode 100644 index 726eae2312..0000000000 --- a/core/services/ocr2/plugins/ccip/testhelpers/commitstore.go +++ /dev/null @@ -1,90 +0,0 @@ -package testhelpers - -import ( - "sync" - "testing" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" - mock_contracts "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/mocks" - "github.com/smartcontractkit/chainlink/v2/core/utils" -) - -type FakeCommitStore struct { - *mock_contracts.CommitStoreInterface - - isPaused bool - blessedRoots map[[32]byte]bool - staticCfg commit_store.CommitStoreStaticConfig - dynamicCfg commit_store.CommitStoreDynamicConfig - nextSeqNum uint64 - - mu sync.RWMutex -} - -func NewFakeCommitStore(t *testing.T, nextSeqNum uint64) (*FakeCommitStore, common.Address) { - addr := utils.RandomAddress() - //mockCommitStore := mock_contracts.NewCommitStoreInterface(t) - mockCommitStore := mock_contracts.NewCommitStoreInterface(t) - mockCommitStore.On("Address").Return(addr).Maybe() - - commitStore := &FakeCommitStore{CommitStoreInterface: mockCommitStore} - commitStore.SetPaused(false) - commitStore.SetNextSequenceNumber(nextSeqNum) - - return commitStore, addr -} - -func (cs *FakeCommitStore) SetPaused(isPaused bool) { - setCommitStoreVal(cs, func(cs *FakeCommitStore) { cs.isPaused = isPaused }) -} - -func (cs *FakeCommitStore) IsUnpausedAndARMHealthy(opts *bind.CallOpts) (bool, error) { - return getCommitStoreVal(cs, func(cs *FakeCommitStore) bool { return !cs.isPaused }), nil -} - -func (cs *FakeCommitStore) SetBlessedRoots(roots map[[32]byte]bool) { - setCommitStoreVal(cs, func(cs *FakeCommitStore) { cs.blessedRoots = roots }) -} - -func (cs *FakeCommitStore) IsBlessed(opts *bind.CallOpts, root [32]byte) (bool, error) { - return getCommitStoreVal(cs, func(cs *FakeCommitStore) bool { return cs.blessedRoots[root] }), nil -} - -func (cs *FakeCommitStore) SetStaticConfig(cfg commit_store.CommitStoreStaticConfig) { - setCommitStoreVal(cs, func(cs *FakeCommitStore) { cs.staticCfg = cfg }) -} - -func (cs *FakeCommitStore) GetStaticConfig(opts *bind.CallOpts) (commit_store.CommitStoreStaticConfig, error) { - return getCommitStoreVal(cs, func(cs *FakeCommitStore) commit_store.CommitStoreStaticConfig { return cs.staticCfg }), nil -} - -func (cs *FakeCommitStore) SetDynamicConfig(cfg commit_store.CommitStoreDynamicConfig) { - setCommitStoreVal(cs, func(cs *FakeCommitStore) { cs.dynamicCfg = cfg }) -} - -func (cs *FakeCommitStore) GetDynamicConfig(opts *bind.CallOpts) (commit_store.CommitStoreDynamicConfig, error) { - return getCommitStoreVal(cs, func(cs *FakeCommitStore) commit_store.CommitStoreDynamicConfig { return cs.dynamicCfg }), nil -} - -func (cs *FakeCommitStore) SetNextSequenceNumber(seqNum uint64) { - setCommitStoreVal(cs, func(cs *FakeCommitStore) { cs.nextSeqNum = seqNum }) -} - -func (cs *FakeCommitStore) GetExpectedNextSequenceNumber(opts *bind.CallOpts) (uint64, error) { - return getCommitStoreVal(cs, func(cs *FakeCommitStore) uint64 { return cs.nextSeqNum }), nil -} - -func getCommitStoreVal[T any](cs *FakeCommitStore, getter func(cs *FakeCommitStore) T) T { - cs.mu.RLock() - defer cs.mu.RUnlock() - return getter(cs) -} - -func setCommitStoreVal(cs *FakeCommitStore, setter func(cs *FakeCommitStore)) { - cs.mu.Lock() - defer cs.mu.Unlock() - setter(cs) -} diff --git a/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go b/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go index a52b7c0c80..3a7c624222 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go @@ -185,7 +185,7 @@ func (node *Node) EventuallyHasExecutedSeqNums(t *testing.T, ccipContracts *CCIP lgs, err := c.LogPoller().IndexedLogsTopicRange( ccipdata.ExecutionStateChangedEventV1_0_0, offRamp, - ccipdata.ExecutionStateChangedSeqNrV1_0_0, + ccipdata.ExecutionStateChangedSeqNrIndexV1_0_0, abihelpers.EvmWord(uint64(minSeqNum)), abihelpers.EvmWord(uint64(maxSeqNum)), 1, @@ -213,7 +213,7 @@ func (node *Node) ConsistentlySeqNumHasNotBeenExecuted(t *testing.T, ccipContrac lgs, err := c.LogPoller().IndexedLogsTopicRange( ccipdata.ExecutionStateChangedEventV1_0_0, offRamp, - ccipdata.ExecutionStateChangedSeqNrV1_0_0, + ccipdata.ExecutionStateChangedSeqNrIndexV1_0_0, abihelpers.EvmWord(uint64(seqNum)), abihelpers.EvmWord(uint64(seqNum)), 1, diff --git a/core/services/ocr2/plugins/ccip/testhelpers/onramp.go b/core/services/ocr2/plugins/ccip/testhelpers/onramp.go deleted file mode 100644 index e7e9cabe5e..0000000000 --- a/core/services/ocr2/plugins/ccip/testhelpers/onramp.go +++ /dev/null @@ -1,60 +0,0 @@ -package testhelpers - -import ( - "fmt" - "sync" - "testing" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" - mock_contracts "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/mocks" - ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" - "github.com/smartcontractkit/chainlink/v2/core/utils" -) - -const ( - FakeOnRampVersion = "1.2.0" -) - -type FakeOnRamp struct { - *mock_contracts.EVM2EVMOnRampInterface - - dynamicConfig evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig - - mu sync.RWMutex -} - -func NewFakeOnRamp(t *testing.T) (*FakeOnRamp, common.Address) { - addr := utils.RandomAddress() - mockOnRamp := mock_contracts.NewEVM2EVMOnRampInterface(t) - mockOnRamp.On("Address").Return(addr).Maybe() - - onRamp := &FakeOnRamp{EVM2EVMOnRampInterface: mockOnRamp} - return onRamp, addr -} - -func (o *FakeOnRamp) TypeAndVersion(opts *bind.CallOpts) (string, error) { - return fmt.Sprintf("%s %s", ccipconfig.EVM2EVMOnRamp, FakeOnRampVersion), nil -} - -func (o *FakeOnRamp) SetDynamicCfg(cfg evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig) { - setOnRampVal(o, func(o *FakeOnRamp) { o.dynamicConfig = cfg }) -} - -func (o *FakeOnRamp) GetDynamicConfig(opts *bind.CallOpts) (evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig, error) { - return getOnRampVal(o, func(o *FakeOnRamp) (evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig, error) { return o.dynamicConfig, nil }) -} - -func getOnRampVal[T any](o *FakeOnRamp, getter func(o *FakeOnRamp) (T, error)) (T, error) { - o.mu.RLock() - defer o.mu.RUnlock() - return getter(o) -} - -func setOnRampVal(o *FakeOnRamp, setter func(o *FakeOnRamp)) { - o.mu.Lock() - defer o.mu.Unlock() - setter(o) -} diff --git a/core/services/ocr2/plugins/ccip/testhelpers/priceregistry.go b/core/services/ocr2/plugins/ccip/testhelpers/priceregistry.go deleted file mode 100644 index 9f0d9b5fce..0000000000 --- a/core/services/ocr2/plugins/ccip/testhelpers/priceregistry.go +++ /dev/null @@ -1,61 +0,0 @@ -package testhelpers - -import ( - "sync" - "testing" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" - mock_contracts "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/mocks" - "github.com/smartcontractkit/chainlink/v2/core/utils" -) - -type FakePriceRegistry struct { - *mock_contracts.PriceRegistryInterface - - tokenPrices []price_registry.InternalTimestampedPackedUint224 - feeTokens []common.Address - - mu sync.RWMutex -} - -func NewFakePriceRegistry(t *testing.T) (*FakePriceRegistry, common.Address) { - addr := utils.RandomAddress() - mockPriceRegistry := mock_contracts.NewPriceRegistryInterface(t) - mockPriceRegistry.On("Address").Return(addr).Maybe() - - priceRegistry := &FakePriceRegistry{PriceRegistryInterface: mockPriceRegistry} - return priceRegistry, addr -} - -func (p *FakePriceRegistry) SetTokenPrices(prices []price_registry.InternalTimestampedPackedUint224) { - setPriceRegistryVal(p, func(p *FakePriceRegistry) { p.tokenPrices = prices }) -} - -func (p *FakePriceRegistry) GetTokenPrices(opts *bind.CallOpts, tokens []common.Address) ([]price_registry.InternalTimestampedPackedUint224, error) { - return getPriceRegistryVal(p, func(p *FakePriceRegistry) ([]price_registry.InternalTimestampedPackedUint224, error) { - return p.tokenPrices, nil - }) -} - -func (p *FakePriceRegistry) SetFeeTokens(tokens []common.Address) { - setPriceRegistryVal(p, func(p *FakePriceRegistry) { p.feeTokens = tokens }) -} - -func (p *FakePriceRegistry) GetFeeTokens(opts *bind.CallOpts) ([]common.Address, error) { - return getPriceRegistryVal(p, func(p *FakePriceRegistry) ([]common.Address, error) { return p.feeTokens, nil }) -} - -func getPriceRegistryVal[T any](p *FakePriceRegistry, getter func(p *FakePriceRegistry) (T, error)) (T, error) { - p.mu.RLock() - defer p.mu.RUnlock() - return getter(p) -} - -func setPriceRegistryVal(p *FakePriceRegistry, setter func(p *FakePriceRegistry)) { - p.mu.Lock() - defer p.mu.Unlock() - setter(p) -} From 726ba035844fbf3ef51b917c163add0329627764 Mon Sep 17 00:00:00 2001 From: connorwstein Date: Mon, 9 Oct 2023 16:08:54 -0400 Subject: [PATCH 09/24] Add price reg 1.0.0 ABI --- .../price_registry_1_0_0/price_registry.go | 1665 +++++++++++++++++ .../ccipdata/price_registry_reader.go | 4 +- .../ccipdata/price_registry_v1_0_0.go | 2 - .../ccipdata/price_registry_v1_2_0.go | 58 + ...e_registry.go => price_registry_v1_0_0.go} | 18 +- .../observability/price_registry_v1_2_0.go | 37 + 6 files changed, 1771 insertions(+), 13 deletions(-) create mode 100644 core/gethwrappers/ccip/generated/price_registry_1_0_0/price_registry.go create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_2_0.go rename core/services/ocr2/plugins/ccip/observability/{price_registry.go => price_registry_v1_0_0.go} (71%) create mode 100644 core/services/ocr2/plugins/ccip/observability/price_registry_v1_2_0.go diff --git a/core/gethwrappers/ccip/generated/price_registry_1_0_0/price_registry.go b/core/gethwrappers/ccip/generated/price_registry_1_0_0/price_registry.go new file mode 100644 index 0000000000..212d01aee4 --- /dev/null +++ b/core/gethwrappers/ccip/generated/price_registry_1_0_0/price_registry.go @@ -0,0 +1,1665 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package price_registry_1_0_0 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type InternalPriceUpdates struct { + TokenPriceUpdates []InternalTokenPriceUpdate + DestChainSelector uint64 + UsdPerUnitGas *big.Int +} + +type InternalTimestampedUint192Value struct { + Value *big.Int + Timestamp uint64 +} + +type InternalTokenPriceUpdate struct { + SourceToken common.Address + UsdPerToken *big.Int +} + +var PriceRegistryMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"priceUpdaters\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chain\",\"type\":\"uint64\"}],\"name\":\"ChainNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidStalenessThreshold\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpdaterOrOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timePassed\",\"type\":\"uint256\"}],\"name\":\"StaleGasPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timePassed\",\"type\":\"uint256\"}],\"name\":\"StaleTokenPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenNotSupported\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"priceUpdater\",\"type\":\"address\"}],\"name\":\"PriceUpdaterRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"priceUpdater\",\"type\":\"address\"}],\"name\":\"PriceUpdaterSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChain\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerUnitGasUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"feeTokensToAdd\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokensToRemove\",\"type\":\"address[]\"}],\"name\":\"applyFeeTokensUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"priceUpdatersToAdd\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"priceUpdatersToRemove\",\"type\":\"address[]\"}],\"name\":\"applyPriceUpdatersUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"fromToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fromTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"toToken\",\"type\":\"address\"}],\"name\":\"convertTokenAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestinationChainGasPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint192\",\"name\":\"value\",\"type\":\"uint192\"},{\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.TimestampedUint192Value\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPriceUpdaters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStalenessThreshold\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getTokenAndGasPrices\",\"outputs\":[{\"internalType\":\"uint192\",\"name\":\"tokenPrice\",\"type\":\"uint192\"},{\"internalType\":\"uint192\",\"name\":\"gasPriceValue\",\"type\":\"uint192\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint192\",\"name\":\"value\",\"type\":\"uint192\"},{\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.TimestampedUint192Value\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getTokenPrices\",\"outputs\":[{\"components\":[{\"internalType\":\"uint192\",\"name\":\"value\",\"type\":\"uint192\"},{\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.TimestampedUint192Value[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getValidatedTokenPrice\",\"outputs\":[{\"internalType\":\"uint192\",\"name\":\"\",\"type\":\"uint192\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"usdPerToken\",\"type\":\"uint192\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint192\",\"name\":\"usdPerUnitGas\",\"type\":\"uint192\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"}],\"name\":\"updatePrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b506040516200217d3803806200217d8339810160408190526200003491620006fe565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be8162000133565b5050604080516000815260208101909152620000dd91508490620001de565b604080516000815260208101909152620000f99083906200033a565b8063ffffffff166000036200012157604051631151410960e11b815260040160405180910390fd5b63ffffffff1660805250620007fa9050565b336001600160a01b038216036200018d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005b825181101562000289576200021d83828151811062000204576200020462000786565b602002602001015160046200049160201b90919060201c565b15620002765782818151811062000238576200023862000786565b60200260200101516001600160a01b03167f34a02290b7920078c19f58e94b78c77eb9cc10195b20676e19bd3b82085893b860405160405180910390a25b6200028181620007b2565b9050620001e1565b5060005b81518110156200033557620002c9828281518110620002b057620002b062000786565b60200260200101516004620004b160201b90919060201c565b156200032257818181518110620002e457620002e462000786565b60200260200101516001600160a01b03167fff7dbb85c77ca68ca1f894d6498570e3d5095cd19466f07ee8d222b337e4068c60405160405180910390a25b6200032d81620007b2565b90506200028d565b505050565b60005b8251811015620003e5576200037983828151811062000360576200036062000786565b602002602001015160066200049160201b90919060201c565b15620003d25782818151811062000394576200039462000786565b60200260200101516001600160a01b03167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b620003dd81620007b2565b90506200033d565b5060005b81518110156200033557620004258282815181106200040c576200040c62000786565b60200260200101516006620004b160201b90919060201c565b156200047e5781818151811062000440576200044062000786565b60200260200101516001600160a01b03167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b6200048981620007b2565b9050620003e9565b6000620004a8836001600160a01b038416620004c8565b90505b92915050565b6000620004a8836001600160a01b0384166200051a565b60008181526001830160205260408120546200051157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620004ab565b506000620004ab565b600081815260018301602052604081205480156200061357600062000541600183620007ce565b85549091506000906200055790600190620007ce565b9050818114620005c35760008660000182815481106200057b576200057b62000786565b9060005260206000200154905080876000018481548110620005a157620005a162000786565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620005d757620005d7620007e4565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620004ab565b6000915050620004ab565b634e487b7160e01b600052604160045260246000fd5b80516001600160a01b03811681146200064c57600080fd5b919050565b600082601f8301126200066357600080fd5b815160206001600160401b03808311156200068257620006826200061e565b8260051b604051601f19603f83011681018181108482111715620006aa57620006aa6200061e565b604052938452858101830193838101925087851115620006c957600080fd5b83870191505b84821015620006f357620006e38262000634565b83529183019190830190620006cf565b979650505050505050565b6000806000606084860312156200071457600080fd5b83516001600160401b03808211156200072c57600080fd5b6200073a8783880162000651565b945060208601519150808211156200075157600080fd5b50620007608682870162000651565b925050604084015163ffffffff811681146200077b57600080fd5b809150509250925092565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201620007c757620007c76200079c565b5060010190565b81810381811115620004ab57620004ab6200079c565b634e487b7160e01b600052603160045260246000fd5b60805161194b620008326000396000818161028501528181610a5201528181610abb01528181610c180152610c8d015261194b6000f3fe608060405234801561001057600080fd5b50600436106100f45760003560e01c8063866548c911610097578063cdc73d5111610066578063cdc73d51146102c4578063d02641a0146102cc578063f2fde38b1461036a578063ffdb4b371461037d57600080fd5b8063866548c9146102405780638da5cb5b14610253578063a6c94a731461027b578063bfcd4566146102af57600080fd5b8063514e8cff116100d3578063514e8cff1461017b57806352877af01461021057806379ba5097146102255780637afac3221461022d57600080fd5b806241e5be146100f957806345ac924d1461011f5780634ab35b0b1461013f575b600080fd5b61010c61010736600461133e565b6103c1565b6040519081526020015b60405180910390f35b61013261012d36600461137a565b610425565b60405161011691906113ef565b61015261014d36600461146a565b6104f9565b60405177ffffffffffffffffffffffffffffffffffffffffffffffff9091168152602001610116565b61020361018936600461149d565b6040805180820182526000808252602091820181905267ffffffffffffffff93841681526002825282902082518084019093525477ffffffffffffffffffffffffffffffffffffffffffffffff81168352780100000000000000000000000000000000000000000000000090049092169181019190915290565b60405161011691906114b8565b61022361021e3660046115e2565b610504565b005b61022361051a565b61022361023b3660046115e2565b61061c565b61022361024e366004611646565b61062e565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610116565b60405163ffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610116565b6102b7610951565b6040516101169190611681565b6102b7610962565b6102036102da36600461146a565b60408051808201909152600080825260208201525073ffffffffffffffffffffffffffffffffffffffff1660009081526003602090815260409182902082518084019093525477ffffffffffffffffffffffffffffffffffffffffffffffff811683527801000000000000000000000000000000000000000000000000900467ffffffffffffffff169082015290565b61022361037836600461146a565b61096e565b61039061038b3660046116db565b610982565b6040805177ffffffffffffffffffffffffffffffffffffffffffffffff938416815292909116602083015201610116565b60006103cc82610b09565b77ffffffffffffffffffffffffffffffffffffffffffffffff166103ef85610b09565b6104139077ffffffffffffffffffffffffffffffffffffffffffffffff168561173d565b61041d9190611754565b949350505050565b60608160008167ffffffffffffffff811115610443576104436114f3565b60405190808252806020026020018201604052801561048857816020015b60408051808201909152600080825260208201528152602001906001900390816104615790505b50905060005b828110156104ee576104c08686838181106104ab576104ab61178f565b90506020020160208101906102da919061146a565b8282815181106104d2576104d261178f565b6020026020010181905250806104e7906117be565b905061048e565b509150505b92915050565b60006104f382610b09565b61050c610cc9565b6105168282610d4c565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146105a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610624610cc9565b6105168282610ea8565b60005473ffffffffffffffffffffffffffffffffffffffff16331480159061065e575061065c600433610fff565b155b15610695576040517f46f0815400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006106a182806117f6565b9050905060005b818110156107eb5760006106bc84806117f6565b838181106106cc576106cc61178f565b9050604002018036038101906106e29190611886565b6040805180820182526020808401805177ffffffffffffffffffffffffffffffffffffffffffffffff908116845267ffffffffffffffff42818116858701908152885173ffffffffffffffffffffffffffffffffffffffff908116600090815260039097529588902096519051909216780100000000000000000000000000000000000000000000000002919092161790935584519051935194955016927f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a926107d292909177ffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a2506107e4816117be565b90506106a8565b506107fc604083016020840161149d565b67ffffffffffffffff161561051657604051806040016040528083604001602081019061082991906118e1565b77ffffffffffffffffffffffffffffffffffffffffffffffff1681526020014267ffffffffffffffff168152506002600084602001602081019061086d919061149d565b67ffffffffffffffff9081168252602080830193909352604091820160002084519484015190911678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff909416939093179092556108e191840190840161149d565b67ffffffffffffffff167fdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e61091c60608501604086016118e1565b6040805177ffffffffffffffffffffffffffffffffffffffffffffffff90921682524260208301520160405180910390a25050565b606061095d6004611031565b905090565b606061095d6006611031565b610976610cc9565b61097f8161103e565b50565b67ffffffffffffffff808216600090815260026020908152604080832081518083019092525477ffffffffffffffffffffffffffffffffffffffffffffffff8116825278010000000000000000000000000000000000000000000000009004909316908301819052909182918203610a32576040517f2e59db3a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610597565b6000816020015167ffffffffffffffff1642610a4e91906118fc565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff16811115610aef576040517ff08bcb3e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401610597565b610af886610b09565b9151919350909150505b9250929050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260036020908152604080832081518083019092525477ffffffffffffffffffffffffffffffffffffffffffffffff811682527801000000000000000000000000000000000000000000000000900467ffffffffffffffff16918101829052901580610ba95750805177ffffffffffffffffffffffffffffffffffffffffffffffff16155b15610bf8576040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610597565b6000816020015167ffffffffffffffff1642610c1491906118fc565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff16811115610cc1576040517fc65fdfca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401610597565b505192915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610d4a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610597565b565b60005b8251811015610df757610d85838281518110610d6d57610d6d61178f565b6020026020010151600461113390919063ffffffff16565b15610de757828181518110610d9c57610d9c61178f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f34a02290b7920078c19f58e94b78c77eb9cc10195b20676e19bd3b82085893b860405160405180910390a25b610df0816117be565b9050610d4f565b5060005b8151811015610ea357610e31828281518110610e1957610e1961178f565b6020026020010151600461115590919063ffffffff16565b15610e9357818181518110610e4857610e4861178f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fff7dbb85c77ca68ca1f894d6498570e3d5095cd19466f07ee8d222b337e4068c60405160405180910390a25b610e9c816117be565b9050610dfb565b505050565b60005b8251811015610f5357610ee1838281518110610ec957610ec961178f565b6020026020010151600661113390919063ffffffff16565b15610f4357828181518110610ef857610ef861178f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b610f4c816117be565b9050610eab565b5060005b8151811015610ea357610f8d828281518110610f7557610f7561178f565b6020026020010151600661115590919063ffffffff16565b15610fef57818181518110610fa457610fa461178f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b610ff8816117be565b9050610f57565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415155b9392505050565b6060600061102a83611177565b3373ffffffffffffffffffffffffffffffffffffffff8216036110bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610597565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600061102a8373ffffffffffffffffffffffffffffffffffffffff84166111d3565b600061102a8373ffffffffffffffffffffffffffffffffffffffff8416611222565b6060816000018054806020026020016040519081016040528092919081815260200182805480156111c757602002820191906000526020600020905b8154815260200190600101908083116111b3575b50505050509050919050565b600081815260018301602052604081205461121a575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556104f3565b5060006104f3565b6000818152600183016020526040812054801561130b5760006112466001836118fc565b855490915060009061125a906001906118fc565b90508181146112bf57600086600001828154811061127a5761127a61178f565b906000526020600020015490508087600001848154811061129d5761129d61178f565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806112d0576112d061190f565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506104f3565b60009150506104f3565b803573ffffffffffffffffffffffffffffffffffffffff8116811461133957600080fd5b919050565b60008060006060848603121561135357600080fd5b61135c84611315565b92506020840135915061137160408501611315565b90509250925092565b6000806020838503121561138d57600080fd5b823567ffffffffffffffff808211156113a557600080fd5b818501915085601f8301126113b957600080fd5b8135818111156113c857600080fd5b8660208260051b85010111156113dd57600080fd5b60209290920196919550909350505050565b602080825282518282018190526000919060409081850190868401855b8281101561145d5761144d848351805177ffffffffffffffffffffffffffffffffffffffffffffffff16825260209081015167ffffffffffffffff16910152565b928401929085019060010161140c565b5091979650505050505050565b60006020828403121561147c57600080fd5b61102a82611315565b803567ffffffffffffffff8116811461133957600080fd5b6000602082840312156114af57600080fd5b61102a82611485565b815177ffffffffffffffffffffffffffffffffffffffffffffffff16815260208083015167ffffffffffffffff1690820152604081016104f3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261153357600080fd5b8135602067ffffffffffffffff80831115611550576115506114f3565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611593576115936114f3565b6040529384528581018301938381019250878511156115b157600080fd5b83870191505b848210156115d7576115c882611315565b835291830191908301906115b7565b979650505050505050565b600080604083850312156115f557600080fd5b823567ffffffffffffffff8082111561160d57600080fd5b61161986838701611522565b9350602085013591508082111561162f57600080fd5b5061163c85828601611522565b9150509250929050565b60006020828403121561165857600080fd5b813567ffffffffffffffff81111561166f57600080fd5b82016060818503121561102a57600080fd5b6020808252825182820181905260009190848201906040850190845b818110156116cf57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161169d565b50909695505050505050565b600080604083850312156116ee57600080fd5b6116f783611315565b915061170560208401611485565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176104f3576104f361170e565b60008261178a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036117ef576117ef61170e565b5060010190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261182b57600080fd5b83018035915067ffffffffffffffff82111561184657600080fd5b6020019150600681901b3603821315610b0257600080fd5b803577ffffffffffffffffffffffffffffffffffffffffffffffff8116811461133957600080fd5b60006040828403121561189857600080fd5b6040516040810181811067ffffffffffffffff821117156118bb576118bb6114f3565b6040526118c783611315565b81526118d56020840161185e565b60208201529392505050565b6000602082840312156118f357600080fd5b61102a8261185e565b818103818111156104f3576104f361170e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", +} + +var PriceRegistryABI = PriceRegistryMetaData.ABI + +var PriceRegistryBin = PriceRegistryMetaData.Bin + +func DeployPriceRegistry(auth *bind.TransactOpts, backend bind.ContractBackend, priceUpdaters []common.Address, feeTokens []common.Address, stalenessThreshold uint32) (common.Address, *types.Transaction, *PriceRegistry, error) { + parsed, err := PriceRegistryMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(PriceRegistryBin), backend, priceUpdaters, feeTokens, stalenessThreshold) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &PriceRegistry{PriceRegistryCaller: PriceRegistryCaller{contract: contract}, PriceRegistryTransactor: PriceRegistryTransactor{contract: contract}, PriceRegistryFilterer: PriceRegistryFilterer{contract: contract}}, nil +} + +type PriceRegistry struct { + address common.Address + abi abi.ABI + PriceRegistryCaller + PriceRegistryTransactor + PriceRegistryFilterer +} + +type PriceRegistryCaller struct { + contract *bind.BoundContract +} + +type PriceRegistryTransactor struct { + contract *bind.BoundContract +} + +type PriceRegistryFilterer struct { + contract *bind.BoundContract +} + +type PriceRegistrySession struct { + Contract *PriceRegistry + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type PriceRegistryCallerSession struct { + Contract *PriceRegistryCaller + CallOpts bind.CallOpts +} + +type PriceRegistryTransactorSession struct { + Contract *PriceRegistryTransactor + TransactOpts bind.TransactOpts +} + +type PriceRegistryRaw struct { + Contract *PriceRegistry +} + +type PriceRegistryCallerRaw struct { + Contract *PriceRegistryCaller +} + +type PriceRegistryTransactorRaw struct { + Contract *PriceRegistryTransactor +} + +func NewPriceRegistry(address common.Address, backend bind.ContractBackend) (*PriceRegistry, error) { + abi, err := abi.JSON(strings.NewReader(PriceRegistryABI)) + if err != nil { + return nil, err + } + contract, err := bindPriceRegistry(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &PriceRegistry{address: address, abi: abi, PriceRegistryCaller: PriceRegistryCaller{contract: contract}, PriceRegistryTransactor: PriceRegistryTransactor{contract: contract}, PriceRegistryFilterer: PriceRegistryFilterer{contract: contract}}, nil +} + +func NewPriceRegistryCaller(address common.Address, caller bind.ContractCaller) (*PriceRegistryCaller, error) { + contract, err := bindPriceRegistry(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &PriceRegistryCaller{contract: contract}, nil +} + +func NewPriceRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*PriceRegistryTransactor, error) { + contract, err := bindPriceRegistry(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &PriceRegistryTransactor{contract: contract}, nil +} + +func NewPriceRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*PriceRegistryFilterer, error) { + contract, err := bindPriceRegistry(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &PriceRegistryFilterer{contract: contract}, nil +} + +func bindPriceRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := PriceRegistryMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_PriceRegistry *PriceRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _PriceRegistry.Contract.PriceRegistryCaller.contract.Call(opts, result, method, params...) +} + +func (_PriceRegistry *PriceRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PriceRegistry.Contract.PriceRegistryTransactor.contract.Transfer(opts) +} + +func (_PriceRegistry *PriceRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _PriceRegistry.Contract.PriceRegistryTransactor.contract.Transact(opts, method, params...) +} + +func (_PriceRegistry *PriceRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _PriceRegistry.Contract.contract.Call(opts, result, method, params...) +} + +func (_PriceRegistry *PriceRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PriceRegistry.Contract.contract.Transfer(opts) +} + +func (_PriceRegistry *PriceRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _PriceRegistry.Contract.contract.Transact(opts, method, params...) +} + +func (_PriceRegistry *PriceRegistryCaller) ConvertTokenAmount(opts *bind.CallOpts, fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address) (*big.Int, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "convertTokenAmount", fromToken, fromTokenAmount, toToken) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) ConvertTokenAmount(fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address) (*big.Int, error) { + return _PriceRegistry.Contract.ConvertTokenAmount(&_PriceRegistry.CallOpts, fromToken, fromTokenAmount, toToken) +} + +func (_PriceRegistry *PriceRegistryCallerSession) ConvertTokenAmount(fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address) (*big.Int, error) { + return _PriceRegistry.Contract.ConvertTokenAmount(&_PriceRegistry.CallOpts, fromToken, fromTokenAmount, toToken) +} + +func (_PriceRegistry *PriceRegistryCaller) GetDestinationChainGasPrice(opts *bind.CallOpts, destChainSelector uint64) (InternalTimestampedUint192Value, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getDestinationChainGasPrice", destChainSelector) + + if err != nil { + return *new(InternalTimestampedUint192Value), err + } + + out0 := *abi.ConvertType(out[0], new(InternalTimestampedUint192Value)).(*InternalTimestampedUint192Value) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetDestinationChainGasPrice(destChainSelector uint64) (InternalTimestampedUint192Value, error) { + return _PriceRegistry.Contract.GetDestinationChainGasPrice(&_PriceRegistry.CallOpts, destChainSelector) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetDestinationChainGasPrice(destChainSelector uint64) (InternalTimestampedUint192Value, error) { + return _PriceRegistry.Contract.GetDestinationChainGasPrice(&_PriceRegistry.CallOpts, destChainSelector) +} + +func (_PriceRegistry *PriceRegistryCaller) GetFeeTokens(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getFeeTokens") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetFeeTokens() ([]common.Address, error) { + return _PriceRegistry.Contract.GetFeeTokens(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetFeeTokens() ([]common.Address, error) { + return _PriceRegistry.Contract.GetFeeTokens(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCaller) GetPriceUpdaters(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getPriceUpdaters") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetPriceUpdaters() ([]common.Address, error) { + return _PriceRegistry.Contract.GetPriceUpdaters(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetPriceUpdaters() ([]common.Address, error) { + return _PriceRegistry.Contract.GetPriceUpdaters(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCaller) GetStalenessThreshold(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getStalenessThreshold") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetStalenessThreshold() (*big.Int, error) { + return _PriceRegistry.Contract.GetStalenessThreshold(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetStalenessThreshold() (*big.Int, error) { + return _PriceRegistry.Contract.GetStalenessThreshold(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCaller) GetTokenAndGasPrices(opts *bind.CallOpts, token common.Address, destChainSelector uint64) (GetTokenAndGasPrices, + + error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getTokenAndGasPrices", token, destChainSelector) + + outstruct := new(GetTokenAndGasPrices) + if err != nil { + return *outstruct, err + } + + outstruct.TokenPrice = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.GasPriceValue = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetTokenAndGasPrices(token common.Address, destChainSelector uint64) (GetTokenAndGasPrices, + + error) { + return _PriceRegistry.Contract.GetTokenAndGasPrices(&_PriceRegistry.CallOpts, token, destChainSelector) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetTokenAndGasPrices(token common.Address, destChainSelector uint64) (GetTokenAndGasPrices, + + error) { + return _PriceRegistry.Contract.GetTokenAndGasPrices(&_PriceRegistry.CallOpts, token, destChainSelector) +} + +func (_PriceRegistry *PriceRegistryCaller) GetTokenPrice(opts *bind.CallOpts, token common.Address) (InternalTimestampedUint192Value, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getTokenPrice", token) + + if err != nil { + return *new(InternalTimestampedUint192Value), err + } + + out0 := *abi.ConvertType(out[0], new(InternalTimestampedUint192Value)).(*InternalTimestampedUint192Value) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetTokenPrice(token common.Address) (InternalTimestampedUint192Value, error) { + return _PriceRegistry.Contract.GetTokenPrice(&_PriceRegistry.CallOpts, token) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetTokenPrice(token common.Address) (InternalTimestampedUint192Value, error) { + return _PriceRegistry.Contract.GetTokenPrice(&_PriceRegistry.CallOpts, token) +} + +func (_PriceRegistry *PriceRegistryCaller) GetTokenPrices(opts *bind.CallOpts, tokens []common.Address) ([]InternalTimestampedUint192Value, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getTokenPrices", tokens) + + if err != nil { + return *new([]InternalTimestampedUint192Value), err + } + + out0 := *abi.ConvertType(out[0], new([]InternalTimestampedUint192Value)).(*[]InternalTimestampedUint192Value) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetTokenPrices(tokens []common.Address) ([]InternalTimestampedUint192Value, error) { + return _PriceRegistry.Contract.GetTokenPrices(&_PriceRegistry.CallOpts, tokens) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetTokenPrices(tokens []common.Address) ([]InternalTimestampedUint192Value, error) { + return _PriceRegistry.Contract.GetTokenPrices(&_PriceRegistry.CallOpts, tokens) +} + +func (_PriceRegistry *PriceRegistryCaller) GetValidatedTokenPrice(opts *bind.CallOpts, token common.Address) (*big.Int, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "getValidatedTokenPrice", token) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) GetValidatedTokenPrice(token common.Address) (*big.Int, error) { + return _PriceRegistry.Contract.GetValidatedTokenPrice(&_PriceRegistry.CallOpts, token) +} + +func (_PriceRegistry *PriceRegistryCallerSession) GetValidatedTokenPrice(token common.Address) (*big.Int, error) { + return _PriceRegistry.Contract.GetValidatedTokenPrice(&_PriceRegistry.CallOpts, token) +} + +func (_PriceRegistry *PriceRegistryCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _PriceRegistry.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_PriceRegistry *PriceRegistrySession) Owner() (common.Address, error) { + return _PriceRegistry.Contract.Owner(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryCallerSession) Owner() (common.Address, error) { + return _PriceRegistry.Contract.Owner(&_PriceRegistry.CallOpts) +} + +func (_PriceRegistry *PriceRegistryTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PriceRegistry.contract.Transact(opts, "acceptOwnership") +} + +func (_PriceRegistry *PriceRegistrySession) AcceptOwnership() (*types.Transaction, error) { + return _PriceRegistry.Contract.AcceptOwnership(&_PriceRegistry.TransactOpts) +} + +func (_PriceRegistry *PriceRegistryTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _PriceRegistry.Contract.AcceptOwnership(&_PriceRegistry.TransactOpts) +} + +func (_PriceRegistry *PriceRegistryTransactor) ApplyFeeTokensUpdates(opts *bind.TransactOpts, feeTokensToAdd []common.Address, feeTokensToRemove []common.Address) (*types.Transaction, error) { + return _PriceRegistry.contract.Transact(opts, "applyFeeTokensUpdates", feeTokensToAdd, feeTokensToRemove) +} + +func (_PriceRegistry *PriceRegistrySession) ApplyFeeTokensUpdates(feeTokensToAdd []common.Address, feeTokensToRemove []common.Address) (*types.Transaction, error) { + return _PriceRegistry.Contract.ApplyFeeTokensUpdates(&_PriceRegistry.TransactOpts, feeTokensToAdd, feeTokensToRemove) +} + +func (_PriceRegistry *PriceRegistryTransactorSession) ApplyFeeTokensUpdates(feeTokensToAdd []common.Address, feeTokensToRemove []common.Address) (*types.Transaction, error) { + return _PriceRegistry.Contract.ApplyFeeTokensUpdates(&_PriceRegistry.TransactOpts, feeTokensToAdd, feeTokensToRemove) +} + +func (_PriceRegistry *PriceRegistryTransactor) ApplyPriceUpdatersUpdates(opts *bind.TransactOpts, priceUpdatersToAdd []common.Address, priceUpdatersToRemove []common.Address) (*types.Transaction, error) { + return _PriceRegistry.contract.Transact(opts, "applyPriceUpdatersUpdates", priceUpdatersToAdd, priceUpdatersToRemove) +} + +func (_PriceRegistry *PriceRegistrySession) ApplyPriceUpdatersUpdates(priceUpdatersToAdd []common.Address, priceUpdatersToRemove []common.Address) (*types.Transaction, error) { + return _PriceRegistry.Contract.ApplyPriceUpdatersUpdates(&_PriceRegistry.TransactOpts, priceUpdatersToAdd, priceUpdatersToRemove) +} + +func (_PriceRegistry *PriceRegistryTransactorSession) ApplyPriceUpdatersUpdates(priceUpdatersToAdd []common.Address, priceUpdatersToRemove []common.Address) (*types.Transaction, error) { + return _PriceRegistry.Contract.ApplyPriceUpdatersUpdates(&_PriceRegistry.TransactOpts, priceUpdatersToAdd, priceUpdatersToRemove) +} + +func (_PriceRegistry *PriceRegistryTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _PriceRegistry.contract.Transact(opts, "transferOwnership", to) +} + +func (_PriceRegistry *PriceRegistrySession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _PriceRegistry.Contract.TransferOwnership(&_PriceRegistry.TransactOpts, to) +} + +func (_PriceRegistry *PriceRegistryTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _PriceRegistry.Contract.TransferOwnership(&_PriceRegistry.TransactOpts, to) +} + +func (_PriceRegistry *PriceRegistryTransactor) UpdatePrices(opts *bind.TransactOpts, priceUpdates InternalPriceUpdates) (*types.Transaction, error) { + return _PriceRegistry.contract.Transact(opts, "updatePrices", priceUpdates) +} + +func (_PriceRegistry *PriceRegistrySession) UpdatePrices(priceUpdates InternalPriceUpdates) (*types.Transaction, error) { + return _PriceRegistry.Contract.UpdatePrices(&_PriceRegistry.TransactOpts, priceUpdates) +} + +func (_PriceRegistry *PriceRegistryTransactorSession) UpdatePrices(priceUpdates InternalPriceUpdates) (*types.Transaction, error) { + return _PriceRegistry.Contract.UpdatePrices(&_PriceRegistry.TransactOpts, priceUpdates) +} + +type PriceRegistryFeeTokenAddedIterator struct { + Event *PriceRegistryFeeTokenAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryFeeTokenAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryFeeTokenAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryFeeTokenAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryFeeTokenAddedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryFeeTokenAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryFeeTokenAdded struct { + FeeToken common.Address + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterFeeTokenAdded(opts *bind.FilterOpts, feeToken []common.Address) (*PriceRegistryFeeTokenAddedIterator, error) { + + var feeTokenRule []interface{} + for _, feeTokenItem := range feeToken { + feeTokenRule = append(feeTokenRule, feeTokenItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "FeeTokenAdded", feeTokenRule) + if err != nil { + return nil, err + } + return &PriceRegistryFeeTokenAddedIterator{contract: _PriceRegistry.contract, event: "FeeTokenAdded", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchFeeTokenAdded(opts *bind.WatchOpts, sink chan<- *PriceRegistryFeeTokenAdded, feeToken []common.Address) (event.Subscription, error) { + + var feeTokenRule []interface{} + for _, feeTokenItem := range feeToken { + feeTokenRule = append(feeTokenRule, feeTokenItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "FeeTokenAdded", feeTokenRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryFeeTokenAdded) + if err := _PriceRegistry.contract.UnpackLog(event, "FeeTokenAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseFeeTokenAdded(log types.Log) (*PriceRegistryFeeTokenAdded, error) { + event := new(PriceRegistryFeeTokenAdded) + if err := _PriceRegistry.contract.UnpackLog(event, "FeeTokenAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryFeeTokenRemovedIterator struct { + Event *PriceRegistryFeeTokenRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryFeeTokenRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryFeeTokenRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryFeeTokenRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryFeeTokenRemovedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryFeeTokenRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryFeeTokenRemoved struct { + FeeToken common.Address + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterFeeTokenRemoved(opts *bind.FilterOpts, feeToken []common.Address) (*PriceRegistryFeeTokenRemovedIterator, error) { + + var feeTokenRule []interface{} + for _, feeTokenItem := range feeToken { + feeTokenRule = append(feeTokenRule, feeTokenItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "FeeTokenRemoved", feeTokenRule) + if err != nil { + return nil, err + } + return &PriceRegistryFeeTokenRemovedIterator{contract: _PriceRegistry.contract, event: "FeeTokenRemoved", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchFeeTokenRemoved(opts *bind.WatchOpts, sink chan<- *PriceRegistryFeeTokenRemoved, feeToken []common.Address) (event.Subscription, error) { + + var feeTokenRule []interface{} + for _, feeTokenItem := range feeToken { + feeTokenRule = append(feeTokenRule, feeTokenItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "FeeTokenRemoved", feeTokenRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryFeeTokenRemoved) + if err := _PriceRegistry.contract.UnpackLog(event, "FeeTokenRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseFeeTokenRemoved(log types.Log) (*PriceRegistryFeeTokenRemoved, error) { + event := new(PriceRegistryFeeTokenRemoved) + if err := _PriceRegistry.contract.UnpackLog(event, "FeeTokenRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryOwnershipTransferRequestedIterator struct { + Event *PriceRegistryOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*PriceRegistryOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &PriceRegistryOwnershipTransferRequestedIterator{contract: _PriceRegistry.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *PriceRegistryOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryOwnershipTransferRequested) + if err := _PriceRegistry.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseOwnershipTransferRequested(log types.Log) (*PriceRegistryOwnershipTransferRequested, error) { + event := new(PriceRegistryOwnershipTransferRequested) + if err := _PriceRegistry.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryOwnershipTransferredIterator struct { + Event *PriceRegistryOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*PriceRegistryOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &PriceRegistryOwnershipTransferredIterator{contract: _PriceRegistry.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *PriceRegistryOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryOwnershipTransferred) + if err := _PriceRegistry.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseOwnershipTransferred(log types.Log) (*PriceRegistryOwnershipTransferred, error) { + event := new(PriceRegistryOwnershipTransferred) + if err := _PriceRegistry.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryPriceUpdaterRemovedIterator struct { + Event *PriceRegistryPriceUpdaterRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryPriceUpdaterRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryPriceUpdaterRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryPriceUpdaterRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryPriceUpdaterRemovedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryPriceUpdaterRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryPriceUpdaterRemoved struct { + PriceUpdater common.Address + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterPriceUpdaterRemoved(opts *bind.FilterOpts, priceUpdater []common.Address) (*PriceRegistryPriceUpdaterRemovedIterator, error) { + + var priceUpdaterRule []interface{} + for _, priceUpdaterItem := range priceUpdater { + priceUpdaterRule = append(priceUpdaterRule, priceUpdaterItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "PriceUpdaterRemoved", priceUpdaterRule) + if err != nil { + return nil, err + } + return &PriceRegistryPriceUpdaterRemovedIterator{contract: _PriceRegistry.contract, event: "PriceUpdaterRemoved", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchPriceUpdaterRemoved(opts *bind.WatchOpts, sink chan<- *PriceRegistryPriceUpdaterRemoved, priceUpdater []common.Address) (event.Subscription, error) { + + var priceUpdaterRule []interface{} + for _, priceUpdaterItem := range priceUpdater { + priceUpdaterRule = append(priceUpdaterRule, priceUpdaterItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "PriceUpdaterRemoved", priceUpdaterRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryPriceUpdaterRemoved) + if err := _PriceRegistry.contract.UnpackLog(event, "PriceUpdaterRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParsePriceUpdaterRemoved(log types.Log) (*PriceRegistryPriceUpdaterRemoved, error) { + event := new(PriceRegistryPriceUpdaterRemoved) + if err := _PriceRegistry.contract.UnpackLog(event, "PriceUpdaterRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryPriceUpdaterSetIterator struct { + Event *PriceRegistryPriceUpdaterSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryPriceUpdaterSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryPriceUpdaterSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryPriceUpdaterSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryPriceUpdaterSetIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryPriceUpdaterSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryPriceUpdaterSet struct { + PriceUpdater common.Address + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterPriceUpdaterSet(opts *bind.FilterOpts, priceUpdater []common.Address) (*PriceRegistryPriceUpdaterSetIterator, error) { + + var priceUpdaterRule []interface{} + for _, priceUpdaterItem := range priceUpdater { + priceUpdaterRule = append(priceUpdaterRule, priceUpdaterItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "PriceUpdaterSet", priceUpdaterRule) + if err != nil { + return nil, err + } + return &PriceRegistryPriceUpdaterSetIterator{contract: _PriceRegistry.contract, event: "PriceUpdaterSet", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchPriceUpdaterSet(opts *bind.WatchOpts, sink chan<- *PriceRegistryPriceUpdaterSet, priceUpdater []common.Address) (event.Subscription, error) { + + var priceUpdaterRule []interface{} + for _, priceUpdaterItem := range priceUpdater { + priceUpdaterRule = append(priceUpdaterRule, priceUpdaterItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "PriceUpdaterSet", priceUpdaterRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryPriceUpdaterSet) + if err := _PriceRegistry.contract.UnpackLog(event, "PriceUpdaterSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParsePriceUpdaterSet(log types.Log) (*PriceRegistryPriceUpdaterSet, error) { + event := new(PriceRegistryPriceUpdaterSet) + if err := _PriceRegistry.contract.UnpackLog(event, "PriceUpdaterSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryUsdPerTokenUpdatedIterator struct { + Event *PriceRegistryUsdPerTokenUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryUsdPerTokenUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryUsdPerTokenUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryUsdPerTokenUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryUsdPerTokenUpdatedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryUsdPerTokenUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryUsdPerTokenUpdated struct { + Token common.Address + Value *big.Int + Timestamp *big.Int + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterUsdPerTokenUpdated(opts *bind.FilterOpts, token []common.Address) (*PriceRegistryUsdPerTokenUpdatedIterator, error) { + + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "UsdPerTokenUpdated", tokenRule) + if err != nil { + return nil, err + } + return &PriceRegistryUsdPerTokenUpdatedIterator{contract: _PriceRegistry.contract, event: "UsdPerTokenUpdated", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchUsdPerTokenUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryUsdPerTokenUpdated, token []common.Address) (event.Subscription, error) { + + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "UsdPerTokenUpdated", tokenRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryUsdPerTokenUpdated) + if err := _PriceRegistry.contract.UnpackLog(event, "UsdPerTokenUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseUsdPerTokenUpdated(log types.Log) (*PriceRegistryUsdPerTokenUpdated, error) { + event := new(PriceRegistryUsdPerTokenUpdated) + if err := _PriceRegistry.contract.UnpackLog(event, "UsdPerTokenUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type PriceRegistryUsdPerUnitGasUpdatedIterator struct { + Event *PriceRegistryUsdPerUnitGasUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *PriceRegistryUsdPerUnitGasUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(PriceRegistryUsdPerUnitGasUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(PriceRegistryUsdPerUnitGasUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *PriceRegistryUsdPerUnitGasUpdatedIterator) Error() error { + return it.fail +} + +func (it *PriceRegistryUsdPerUnitGasUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type PriceRegistryUsdPerUnitGasUpdated struct { + DestChain uint64 + Value *big.Int + Timestamp *big.Int + Raw types.Log +} + +func (_PriceRegistry *PriceRegistryFilterer) FilterUsdPerUnitGasUpdated(opts *bind.FilterOpts, destChain []uint64) (*PriceRegistryUsdPerUnitGasUpdatedIterator, error) { + + var destChainRule []interface{} + for _, destChainItem := range destChain { + destChainRule = append(destChainRule, destChainItem) + } + + logs, sub, err := _PriceRegistry.contract.FilterLogs(opts, "UsdPerUnitGasUpdated", destChainRule) + if err != nil { + return nil, err + } + return &PriceRegistryUsdPerUnitGasUpdatedIterator{contract: _PriceRegistry.contract, event: "UsdPerUnitGasUpdated", logs: logs, sub: sub}, nil +} + +func (_PriceRegistry *PriceRegistryFilterer) WatchUsdPerUnitGasUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryUsdPerUnitGasUpdated, destChain []uint64) (event.Subscription, error) { + + var destChainRule []interface{} + for _, destChainItem := range destChain { + destChainRule = append(destChainRule, destChainItem) + } + + logs, sub, err := _PriceRegistry.contract.WatchLogs(opts, "UsdPerUnitGasUpdated", destChainRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(PriceRegistryUsdPerUnitGasUpdated) + if err := _PriceRegistry.contract.UnpackLog(event, "UsdPerUnitGasUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_PriceRegistry *PriceRegistryFilterer) ParseUsdPerUnitGasUpdated(log types.Log) (*PriceRegistryUsdPerUnitGasUpdated, error) { + event := new(PriceRegistryUsdPerUnitGasUpdated) + if err := _PriceRegistry.contract.UnpackLog(event, "UsdPerUnitGasUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type GetTokenAndGasPrices struct { + TokenPrice *big.Int + GasPriceValue *big.Int +} + +func (_PriceRegistry *PriceRegistry) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _PriceRegistry.abi.Events["FeeTokenAdded"].ID: + return _PriceRegistry.ParseFeeTokenAdded(log) + case _PriceRegistry.abi.Events["FeeTokenRemoved"].ID: + return _PriceRegistry.ParseFeeTokenRemoved(log) + case _PriceRegistry.abi.Events["OwnershipTransferRequested"].ID: + return _PriceRegistry.ParseOwnershipTransferRequested(log) + case _PriceRegistry.abi.Events["OwnershipTransferred"].ID: + return _PriceRegistry.ParseOwnershipTransferred(log) + case _PriceRegistry.abi.Events["PriceUpdaterRemoved"].ID: + return _PriceRegistry.ParsePriceUpdaterRemoved(log) + case _PriceRegistry.abi.Events["PriceUpdaterSet"].ID: + return _PriceRegistry.ParsePriceUpdaterSet(log) + case _PriceRegistry.abi.Events["UsdPerTokenUpdated"].ID: + return _PriceRegistry.ParseUsdPerTokenUpdated(log) + case _PriceRegistry.abi.Events["UsdPerUnitGasUpdated"].ID: + return _PriceRegistry.ParseUsdPerUnitGasUpdated(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (PriceRegistryFeeTokenAdded) Topic() common.Hash { + return common.HexToHash("0xdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba23") +} + +func (PriceRegistryFeeTokenRemoved) Topic() common.Hash { + return common.HexToHash("0x1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f91") +} + +func (PriceRegistryOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (PriceRegistryOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (PriceRegistryPriceUpdaterRemoved) Topic() common.Hash { + return common.HexToHash("0xff7dbb85c77ca68ca1f894d6498570e3d5095cd19466f07ee8d222b337e4068c") +} + +func (PriceRegistryPriceUpdaterSet) Topic() common.Hash { + return common.HexToHash("0x34a02290b7920078c19f58e94b78c77eb9cc10195b20676e19bd3b82085893b8") +} + +func (PriceRegistryUsdPerTokenUpdated) Topic() common.Hash { + return common.HexToHash("0x52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a") +} + +func (PriceRegistryUsdPerUnitGasUpdated) Topic() common.Hash { + return common.HexToHash("0xdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e") +} + +func (_PriceRegistry *PriceRegistry) Address() common.Address { + return _PriceRegistry.address +} + +type PriceRegistryInterface interface { + ConvertTokenAmount(opts *bind.CallOpts, fromToken common.Address, fromTokenAmount *big.Int, toToken common.Address) (*big.Int, error) + + GetDestinationChainGasPrice(opts *bind.CallOpts, destChainSelector uint64) (InternalTimestampedUint192Value, error) + + GetFeeTokens(opts *bind.CallOpts) ([]common.Address, error) + + GetPriceUpdaters(opts *bind.CallOpts) ([]common.Address, error) + + GetStalenessThreshold(opts *bind.CallOpts) (*big.Int, error) + + GetTokenAndGasPrices(opts *bind.CallOpts, token common.Address, destChainSelector uint64) (GetTokenAndGasPrices, + + error) + + GetTokenPrice(opts *bind.CallOpts, token common.Address) (InternalTimestampedUint192Value, error) + + GetTokenPrices(opts *bind.CallOpts, tokens []common.Address) ([]InternalTimestampedUint192Value, error) + + GetValidatedTokenPrice(opts *bind.CallOpts, token common.Address) (*big.Int, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + ApplyFeeTokensUpdates(opts *bind.TransactOpts, feeTokensToAdd []common.Address, feeTokensToRemove []common.Address) (*types.Transaction, error) + + ApplyPriceUpdatersUpdates(opts *bind.TransactOpts, priceUpdatersToAdd []common.Address, priceUpdatersToRemove []common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + UpdatePrices(opts *bind.TransactOpts, priceUpdates InternalPriceUpdates) (*types.Transaction, error) + + FilterFeeTokenAdded(opts *bind.FilterOpts, feeToken []common.Address) (*PriceRegistryFeeTokenAddedIterator, error) + + WatchFeeTokenAdded(opts *bind.WatchOpts, sink chan<- *PriceRegistryFeeTokenAdded, feeToken []common.Address) (event.Subscription, error) + + ParseFeeTokenAdded(log types.Log) (*PriceRegistryFeeTokenAdded, error) + + FilterFeeTokenRemoved(opts *bind.FilterOpts, feeToken []common.Address) (*PriceRegistryFeeTokenRemovedIterator, error) + + WatchFeeTokenRemoved(opts *bind.WatchOpts, sink chan<- *PriceRegistryFeeTokenRemoved, feeToken []common.Address) (event.Subscription, error) + + ParseFeeTokenRemoved(log types.Log) (*PriceRegistryFeeTokenRemoved, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*PriceRegistryOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *PriceRegistryOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*PriceRegistryOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*PriceRegistryOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *PriceRegistryOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*PriceRegistryOwnershipTransferred, error) + + FilterPriceUpdaterRemoved(opts *bind.FilterOpts, priceUpdater []common.Address) (*PriceRegistryPriceUpdaterRemovedIterator, error) + + WatchPriceUpdaterRemoved(opts *bind.WatchOpts, sink chan<- *PriceRegistryPriceUpdaterRemoved, priceUpdater []common.Address) (event.Subscription, error) + + ParsePriceUpdaterRemoved(log types.Log) (*PriceRegistryPriceUpdaterRemoved, error) + + FilterPriceUpdaterSet(opts *bind.FilterOpts, priceUpdater []common.Address) (*PriceRegistryPriceUpdaterSetIterator, error) + + WatchPriceUpdaterSet(opts *bind.WatchOpts, sink chan<- *PriceRegistryPriceUpdaterSet, priceUpdater []common.Address) (event.Subscription, error) + + ParsePriceUpdaterSet(log types.Log) (*PriceRegistryPriceUpdaterSet, error) + + FilterUsdPerTokenUpdated(opts *bind.FilterOpts, token []common.Address) (*PriceRegistryUsdPerTokenUpdatedIterator, error) + + WatchUsdPerTokenUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryUsdPerTokenUpdated, token []common.Address) (event.Subscription, error) + + ParseUsdPerTokenUpdated(log types.Log) (*PriceRegistryUsdPerTokenUpdated, error) + + FilterUsdPerUnitGasUpdated(opts *bind.FilterOpts, destChain []uint64) (*PriceRegistryUsdPerUnitGasUpdatedIterator, error) + + WatchUsdPerUnitGasUpdated(opts *bind.WatchOpts, sink chan<- *PriceRegistryUsdPerUnitGasUpdated, destChain []uint64) (event.Subscription, error) + + ParseUsdPerUnitGasUpdated(log types.Log) (*PriceRegistryUsdPerUnitGasUpdated, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go index d1e22d109f..4e6dece481 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go @@ -21,6 +21,7 @@ const ( COMMIT_PRICE_UPDATES = "Commit price updates" FEE_TOKEN_ADDED = "Fee token added" FEE_TOKEN_REMOVED = "Fee token removed" + ExecPluginLabel = "exec" ) var ( @@ -70,8 +71,7 @@ func NewPriceRegistryReader(lggr logger.Logger, priceRegistryAddress common.Addr } switch version.String() { case v1_2_0: - // TODO: ABI is same now but will break shortly with multigas price updates - return NewPriceRegistryV1_0_0(lggr, priceRegistryAddress, lp, cl) + return NewPriceRegistryV1_2_0(lggr, priceRegistryAddress, lp, cl) default: return nil, errors.Errorf("got unexpected version %v", version.String()) } diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_0_0.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_0_0.go index d05f86fbff..9e16330dc1 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_0_0.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_0_0.go @@ -23,8 +23,6 @@ var ( _ PriceRegistryReader = &PriceRegistryV1_0_0{} ) -const ExecPluginLabel = "exec" - type PriceRegistryV1_0_0 struct { priceRegistry *observability.ObservedPriceRegistryV1_0_0 address common.Address diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_2_0.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_2_0.go new file mode 100644 index 0000000000..4fd6210c9d --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_2_0.go @@ -0,0 +1,58 @@ +package ccipdata + +import ( + "context" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/observability" +) + +var ( + _ PriceRegistryReader = &PriceRegistryV1_2_0{} +) + +type PriceRegistryV1_2_0 struct { + *PriceRegistryV1_0_0 + obs *observability.ObservedPriceRegistryV1_2_0 +} + +func NewPriceRegistryV1_2_0(lggr logger.Logger, priceRegistryAddr common.Address, lp logpoller.LogPoller, ec client.Client) (*PriceRegistryV1_2_0, error) { + v100, err := NewPriceRegistryV1_0_0(lggr, priceRegistryAddr, lp, ec) + if err != nil { + return nil, err + } + obs, err := observability.NewObservedPriceRegistryV1_2_0(priceRegistryAddr, ExecPluginLabel, ec) + if err != nil { + return nil, err + } + return &PriceRegistryV1_2_0{ + PriceRegistryV1_0_0: v100, + obs: obs, + }, nil +} + +// GetTokenPrices must be overridden to use the 1.2 ABI (return parameter changed from uint192 to uint224. +func (p *PriceRegistryV1_2_0) GetTokenPrices(ctx context.Context, wantedTokens []common.Address) ([]TokenPriceUpdate, error) { + // Make call using 224 ABI. + tps, err := p.obs.GetTokenPrices(&bind.CallOpts{Context: ctx}, wantedTokens) + if err != nil { + return nil, err + } + var tpu []TokenPriceUpdate + for i, tp := range tps { + tpu = append(tpu, TokenPriceUpdate{ + TokenPrice: TokenPrice{ + Token: wantedTokens[i], + Value: tp.Value, + }, + Timestamp: big.NewInt(int64(tp.Timestamp)), // TODO: valid conversion + }) + } + return tpu, nil +} diff --git a/core/services/ocr2/plugins/ccip/observability/price_registry.go b/core/services/ocr2/plugins/ccip/observability/price_registry_v1_0_0.go similarity index 71% rename from core/services/ocr2/plugins/ccip/observability/price_registry.go rename to core/services/ocr2/plugins/ccip/observability/price_registry_v1_0_0.go index 1087e132ff..618fecca74 100644 --- a/core/services/ocr2/plugins/ccip/observability/price_registry.go +++ b/core/services/ocr2/plugins/ccip/observability/price_registry_v1_0_0.go @@ -6,16 +6,16 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_0_0" ) type ObservedPriceRegistryV1_0_0 struct { - *price_registry.PriceRegistry + *price_registry_1_0_0.PriceRegistry metric metricDetails } func NewObservedPriceRegistryV1_0_0(address common.Address, pluginName string, client client.Client) (*ObservedPriceRegistryV1_0_0, error) { - priceRegistry, err := price_registry.NewPriceRegistry(address, client) + priceRegistry, err := price_registry_1_0_0.NewPriceRegistry(address, client) if err != nil { return nil, err } @@ -36,20 +36,20 @@ func (o *ObservedPriceRegistryV1_0_0) GetFeeTokens(opts *bind.CallOpts) ([]commo }) } -func (o *ObservedPriceRegistryV1_0_0) GetTokenPrices(opts *bind.CallOpts, tokens []common.Address) ([]price_registry.InternalTimestampedPackedUint224, error) { - return withObservedContract(o.metric, "GetTokenPrices", func() ([]price_registry.InternalTimestampedPackedUint224, error) { +func (o *ObservedPriceRegistryV1_0_0) GetTokenPrices(opts *bind.CallOpts, tokens []common.Address) ([]price_registry_1_0_0.InternalTimestampedUint192Value, error) { + return withObservedContract(o.metric, "GetTokenPrices", func() ([]price_registry_1_0_0.InternalTimestampedUint192Value, error) { return o.PriceRegistry.GetTokenPrices(opts, tokens) }) } -func (o *ObservedPriceRegistryV1_0_0) ParseUsdPerUnitGasUpdated(log types.Log) (*price_registry.PriceRegistryUsdPerUnitGasUpdated, error) { - return withObservedContract(o.metric, "ParseUsdPerUnitGasUpdated", func() (*price_registry.PriceRegistryUsdPerUnitGasUpdated, error) { +func (o *ObservedPriceRegistryV1_0_0) ParseUsdPerUnitGasUpdated(log types.Log) (*price_registry_1_0_0.PriceRegistryUsdPerUnitGasUpdated, error) { + return withObservedContract(o.metric, "ParseUsdPerUnitGasUpdated", func() (*price_registry_1_0_0.PriceRegistryUsdPerUnitGasUpdated, error) { return o.PriceRegistry.ParseUsdPerUnitGasUpdated(log) }) } -func (o *ObservedPriceRegistryV1_0_0) ParseUsdPerTokenUpdated(log types.Log) (*price_registry.PriceRegistryUsdPerTokenUpdated, error) { - return withObservedContract(o.metric, "ParseUsdPerTokenUpdated", func() (*price_registry.PriceRegistryUsdPerTokenUpdated, error) { +func (o *ObservedPriceRegistryV1_0_0) ParseUsdPerTokenUpdated(log types.Log) (*price_registry_1_0_0.PriceRegistryUsdPerTokenUpdated, error) { + return withObservedContract(o.metric, "ParseUsdPerTokenUpdated", func() (*price_registry_1_0_0.PriceRegistryUsdPerTokenUpdated, error) { return o.PriceRegistry.ParseUsdPerTokenUpdated(log) }) } diff --git a/core/services/ocr2/plugins/ccip/observability/price_registry_v1_2_0.go b/core/services/ocr2/plugins/ccip/observability/price_registry_v1_2_0.go new file mode 100644 index 0000000000..c42f15882d --- /dev/null +++ b/core/services/ocr2/plugins/ccip/observability/price_registry_v1_2_0.go @@ -0,0 +1,37 @@ +package observability + +import ( + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" +) + +type ObservedPriceRegistryV1_2_0 struct { + *ObservedPriceRegistryV1_0_0 + pr *price_registry.PriceRegistry +} + +func NewObservedPriceRegistryV1_2_0(address common.Address, pluginName string, client client.Client) (*ObservedPriceRegistryV1_2_0, error) { + v100, err := NewObservedPriceRegistryV1_0_0(address, pluginName, client) + if err != nil { + return nil, err + } + priceRegistry, err := price_registry.NewPriceRegistry(address, client) + if err != nil { + return nil, err + } + + return &ObservedPriceRegistryV1_2_0{ + ObservedPriceRegistryV1_0_0: v100, + pr: priceRegistry, + }, nil +} + +// Changed in 1.2.0 +func (o *ObservedPriceRegistryV1_2_0) GetTokenPrices(opts *bind.CallOpts, tokens []common.Address) ([]price_registry.InternalTimestampedPackedUint224, error) { + return withObservedContract(o.metric, "GetTokenPrices", func() ([]price_registry.InternalTimestampedPackedUint224, error) { + return o.pr.GetTokenPrices(opts, tokens) + }) +} From 1bb71d2a1af0f8af279216fc967b0e0b03e95fa4 Mon Sep 17 00:00:00 2001 From: connorwstein Date: Tue, 10 Oct 2023 17:58:07 -0400 Subject: [PATCH 10/24] Black box testing --- .../ccipdata/commit_store_reader_test.go | 33 ++--- .../ccipdata/commit_store_v1_0_0_test.go | 5 + .../internal/ccipdata/offramp_reader_test.go | 40 ++++-- .../ccipdata/offramp_reader_v1_0_0_test.go | 15 --- .../internal/ccipdata/onramp_v1_0_0_test.go | 5 +- .../internal/ccipdata/onramp_v1_2_0_test.go | 5 +- .../ccipdata/price_registry_reader.go | 8 +- .../ccipdata/price_registry_reader_test.go | 121 +++++++++++++++++- .../ccipdata/price_registry_v1_0_0.go | 63 +++++---- .../ccipdata/price_registry_v1_2_0.go | 2 +- .../ccipdata/usdc_reader_internal_test.go | 78 +++++++++++ .../internal/ccipdata/usdc_reader_test.go | 75 +---------- 12 files changed, 291 insertions(+), 159 deletions(-) create mode 100644 core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader_internal_test.go diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go index 9bdbad4076..9961de281f 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go @@ -1,4 +1,4 @@ -package ccipdata +package ccipdata_test import ( "math/big" @@ -16,10 +16,11 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" "github.com/smartcontractkit/chainlink/v2/core/store/models" ) -func assertFilterRegistration(t *testing.T, lp *lpmocks.LogPoller, buildCloser func(lp *lpmocks.LogPoller, addr common.Address) Closer, numFilter int) { +func assertFilterRegistration(t *testing.T, lp *lpmocks.LogPoller, buildCloser func(lp *lpmocks.LogPoller, addr common.Address) ccipdata.Closer, numFilter int) { // Expected filter properties for a closer: // - Should be the same filter set registered that is unregistered // - Should be registered to the address specified @@ -44,13 +45,13 @@ func assertFilterRegistration(t *testing.T, lp *lpmocks.LogPoller, buildCloser f } func TestCommitFilters(t *testing.T) { - assertFilterRegistration(t, new(lpmocks.LogPoller), func(lp *lpmocks.LogPoller, addr common.Address) Closer { - c, err := NewCommitStoreV1_0_0(logger.TestLogger(t), addr, new(mocks.Client), lp, nil) + assertFilterRegistration(t, new(lpmocks.LogPoller), func(lp *lpmocks.LogPoller, addr common.Address) ccipdata.Closer { + c, err := ccipdata.NewCommitStoreV1_0_0(logger.TestLogger(t), addr, new(mocks.Client), lp, nil) require.NoError(t, err) return c }, 1) - assertFilterRegistration(t, new(lpmocks.LogPoller), func(lp *lpmocks.LogPoller, addr common.Address) Closer { - c, err := NewCommitStoreV1_2_0(logger.TestLogger(t), addr, new(mocks.Client), lp, nil) + assertFilterRegistration(t, new(lpmocks.LogPoller), func(lp *lpmocks.LogPoller, addr common.Address) ccipdata.Closer { + c, err := ccipdata.NewCommitStoreV1_2_0(logger.TestLogger(t), addr, new(mocks.Client), lp, nil) require.NoError(t, err) return c }, 1) @@ -58,11 +59,11 @@ func TestCommitFilters(t *testing.T) { func TestCommitOffchainConfig_Encoding(t *testing.T) { tests := map[string]struct { - want CommitOffchainConfigV1_2_0 + want ccipdata.CommitOffchainConfigV1_2_0 expectErr bool }{ "encodes and decodes config with all fields set": { - want: CommitOffchainConfigV1_2_0{ + want: ccipdata.CommitOffchainConfigV1_2_0{ SourceFinalityDepth: 3, DestFinalityDepth: 3, GasPriceHeartBeat: models.MustMakeDuration(1 * time.Hour), @@ -75,7 +76,7 @@ func TestCommitOffchainConfig_Encoding(t *testing.T) { }, }, "fails decoding when all fields present but with 0 values": { - want: CommitOffchainConfigV1_2_0{ + want: ccipdata.CommitOffchainConfigV1_2_0{ SourceFinalityDepth: 0, DestFinalityDepth: 0, GasPriceHeartBeat: models.MustMakeDuration(0), @@ -89,11 +90,11 @@ func TestCommitOffchainConfig_Encoding(t *testing.T) { expectErr: true, }, "fails decoding when all fields are missing": { - want: CommitOffchainConfigV1_2_0{}, + want: ccipdata.CommitOffchainConfigV1_2_0{}, expectErr: true, }, "fails decoding when some fields are missing": { - want: CommitOffchainConfigV1_2_0{ + want: ccipdata.CommitOffchainConfigV1_2_0{ SourceFinalityDepth: 3, GasPriceHeartBeat: models.MustMakeDuration(1 * time.Hour), DAGasPriceDeviationPPB: 5e7, @@ -109,7 +110,7 @@ func TestCommitOffchainConfig_Encoding(t *testing.T) { t.Run(name, func(t *testing.T) { encode, err := ccipconfig.EncodeOffchainConfig(tc.want) require.NoError(t, err) - got, err := ccipconfig.DecodeOffchainConfig[CommitOffchainConfigV1_2_0](encode) + got, err := ccipconfig.DecodeOffchainConfig[ccipdata.CommitOffchainConfigV1_2_0](encode) if tc.expectErr { require.ErrorContains(t, err, "must set") @@ -128,19 +129,19 @@ func randomAddress() common.Address { func TestCommitOnchainConfig(t *testing.T) { tests := []struct { name string - want CommitOnchainConfig + want ccipdata.CommitOnchainConfig expectErr bool }{ { name: "encodes and decodes config with all fields set", - want: CommitOnchainConfig{ + want: ccipdata.CommitOnchainConfig{ PriceRegistry: randomAddress(), }, expectErr: false, }, { name: "encodes and fails decoding config with missing fields", - want: CommitOnchainConfig{}, + want: ccipdata.CommitOnchainConfig{}, expectErr: true, }, } @@ -149,7 +150,7 @@ func TestCommitOnchainConfig(t *testing.T) { encoded, err := abihelpers.EncodeAbiStruct(tt.want) require.NoError(t, err) - decoded, err := abihelpers.DecodeAbiStruct[CommitOnchainConfig](encoded) + decoded, err := abihelpers.DecodeAbiStruct[ccipdata.CommitOnchainConfig](encoded) if tt.expectErr { require.ErrorContains(t, err, "must set") } else { diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_0_0_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_0_0_test.go index 52c88df608..be500b74d4 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_0_0_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_0_0_test.go @@ -5,6 +5,7 @@ import ( "math/rand" "testing" + "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -14,6 +15,10 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/utils" ) +func randomAddress() common.Address { + return common.BigToAddress(big.NewInt(rand.Int63())) +} + func TestCommitReportEncodingV1_0_0(t *testing.T) { report := CommitStoreReport{ TokenPrices: []TokenPrice{ diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go index 8a83e33e2c..fc2a3aff31 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go @@ -1,24 +1,42 @@ -package ccipdata +package ccipdata_test import ( "math/rand" "testing" "time" + "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" + lpmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" "github.com/smartcontractkit/chainlink/v2/core/store/models" ) +func TestOffRampFilters(t *testing.T) { + assertFilterRegistration(t, new(lpmocks.LogPoller), func(lp *lpmocks.LogPoller, addr common.Address) ccipdata.Closer { + c, err := ccipdata.NewOffRampV1_0_0(logger.TestLogger(t), addr, new(mocks.Client), lp, nil) + require.NoError(t, err) + return c + }, 3) + assertFilterRegistration(t, new(lpmocks.LogPoller), func(lp *lpmocks.LogPoller, addr common.Address) ccipdata.Closer { + c, err := ccipdata.NewOffRampV1_2_0(logger.TestLogger(t), addr, new(mocks.Client), lp, nil) + require.NoError(t, err) + return c + }, 3) +} + func TestExecOffchainConfig_Encoding(t *testing.T) { tests := map[string]struct { - want ExecOffchainConfig + want ccipdata.ExecOffchainConfig expectErr bool }{ "encodes and decodes config with all fields set": { - want: ExecOffchainConfig{ + want: ccipdata.ExecOffchainConfig{ SourceFinalityDepth: 3, DestOptimisticConfirmations: 6, DestFinalityDepth: 3, @@ -30,7 +48,7 @@ func TestExecOffchainConfig_Encoding(t *testing.T) { }, }, "fails decoding when all fields present but with 0 values": { - want: ExecOffchainConfig{ + want: ccipdata.ExecOffchainConfig{ SourceFinalityDepth: 0, DestFinalityDepth: 0, DestOptimisticConfirmations: 0, @@ -43,11 +61,11 @@ func TestExecOffchainConfig_Encoding(t *testing.T) { expectErr: true, }, "fails decoding when all fields are missing": { - want: ExecOffchainConfig{}, + want: ccipdata.ExecOffchainConfig{}, expectErr: true, }, "fails decoding when some fields are missing": { - want: ExecOffchainConfig{ + want: ccipdata.ExecOffchainConfig{ SourceFinalityDepth: 99999999, InflightCacheExpiry: models.MustMakeDuration(64 * time.Second), }, @@ -59,7 +77,7 @@ func TestExecOffchainConfig_Encoding(t *testing.T) { exp := tc.want encode, err := ccipconfig.EncodeOffchainConfig(&exp) require.NoError(t, err) - got, err := ccipconfig.DecodeOffchainConfig[ExecOffchainConfig](encode) + got, err := ccipconfig.DecodeOffchainConfig[ccipdata.ExecOffchainConfig](encode) if tc.expectErr { require.ErrorContains(t, err, "must set") @@ -74,12 +92,12 @@ func TestExecOffchainConfig_Encoding(t *testing.T) { func TestExecOnchainConfig(t *testing.T) { tests := []struct { name string - want ExecOnchainConfigV1_0_0 + want ccipdata.ExecOnchainConfigV1_0_0 expectErr bool }{ { name: "encodes and decodes config with all fields set", - want: ExecOnchainConfigV1_0_0{ + want: ccipdata.ExecOnchainConfigV1_0_0{ PermissionLessExecutionThresholdSeconds: rand.Uint32(), Router: randomAddress(), PriceRegistry: randomAddress(), @@ -89,7 +107,7 @@ func TestExecOnchainConfig(t *testing.T) { }, { name: "encodes and fails decoding config with missing fields", - want: ExecOnchainConfigV1_0_0{ + want: ccipdata.ExecOnchainConfigV1_0_0{ PermissionLessExecutionThresholdSeconds: rand.Uint32(), MaxDataSize: rand.Uint32(), }, @@ -101,7 +119,7 @@ func TestExecOnchainConfig(t *testing.T) { encoded, err := abihelpers.EncodeAbiStruct(tt.want) require.NoError(t, err) - decoded, err := abihelpers.DecodeAbiStruct[ExecOnchainConfigV1_0_0](encoded) + decoded, err := abihelpers.DecodeAbiStruct[ccipdata.ExecOnchainConfigV1_0_0](encoded) if tt.expectErr { require.ErrorContains(t, err, "must set") } else { diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_v1_0_0_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_v1_0_0_test.go index 14bbe7fbb0..76a680764d 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_v1_0_0_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_v1_0_0_test.go @@ -4,11 +4,9 @@ import ( "math/big" "testing" - "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" lpmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -38,16 +36,3 @@ func TestExecutionReportEncoding(t *testing.T) { require.Equal(t, report.Proofs, decodeCommitReport.Proofs) // require.Equal(t, report, decodeCommitReport) // TODO: fails because some fields are not supported on v1_0_0 } - -func TestOffRampFilters(t *testing.T) { - assertFilterRegistration(t, new(lpmocks.LogPoller), func(lp *lpmocks.LogPoller, addr common.Address) Closer { - c, err := NewOffRampV1_0_0(logger.TestLogger(t), addr, new(mocks.Client), lp, nil) - require.NoError(t, err) - return c - }, 3) - assertFilterRegistration(t, new(lpmocks.LogPoller), func(lp *lpmocks.LogPoller, addr common.Address) Closer { - c, err := NewOffRampV1_2_0(logger.TestLogger(t), addr, new(mocks.Client), lp, nil) - require.NoError(t, err) - return c - }, 3) -} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_0_0_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_0_0_test.go index 164e9bd617..6d63c08df8 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_0_0_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_0_0_test.go @@ -3,10 +3,8 @@ package ccipdata import ( "encoding/hex" "math/big" - "strings" "testing" - "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/stretchr/testify/require" @@ -19,8 +17,7 @@ import ( func TestHasherV1_0_0(t *testing.T) { sourceChainSelector, destChainSelector := uint64(1), uint64(4) onRampAddress := common.HexToAddress("0x5550000000000000000000000000000000000001") - onRampABI, err := abi.JSON(strings.NewReader(evm_2_evm_onramp_1_0_0.EVM2EVMOnRampABI)) - require.NoError(t, err) + onRampABI := abihelpers.MustParseABI(evm_2_evm_onramp_1_0_0.EVM2EVMOnRampABI) ramp, err := evm_2_evm_onramp_1_0_0.NewEVM2EVMOnRamp(onRampAddress, nil) require.NoError(t, err) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_2_0_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_2_0_test.go index d271b87654..ac7e0bcd03 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_2_0_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_2_0_test.go @@ -4,10 +4,8 @@ import ( "context" "encoding/hex" "math/big" - "strings" "testing" - "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/stretchr/testify/assert" @@ -27,8 +25,7 @@ import ( func TestHasherV1_2_0(t *testing.T) { sourceChainSelector, destChainSelector := uint64(1), uint64(4) onRampAddress := common.HexToAddress("0x5550000000000000000000000000000000000001") - onRampABI, err := abi.JSON(strings.NewReader(evm_2_evm_onramp.EVM2EVMOnRampABI)) - require.NoError(t, err) + onRampABI := abihelpers.MustParseABI(evm_2_evm_onramp.EVM2EVMOnRampABI) hashingCtx := hashlib.NewKeccakCtx() ramp, err := evm_2_evm_onramp.NewEVM2EVMOnRamp(onRampAddress, nil) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go index 4e6dece481..14f5d519a3 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go @@ -10,9 +10,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) @@ -24,10 +22,6 @@ const ( ExecPluginLabel = "exec" ) -var ( - UsdPerUnitGasUpdatedV1_0_0 = abihelpers.MustGetEventID("UsdPerUnitGasUpdated", abihelpers.MustParseABI(price_registry.PriceRegistryABI)) -) - type TokenPrice struct { Token common.Address Value *big.Int @@ -35,6 +29,7 @@ type TokenPrice struct { type TokenPriceUpdate struct { TokenPrice + // Unix time stamp in seconds. Timestamp *big.Int } @@ -45,6 +40,7 @@ type GasPrice struct { type GasPriceUpdate struct { GasPrice + // Unix time stamp in seconds Timestamp *big.Int } diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go index 2e3f73733b..40da116494 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go @@ -1,24 +1,139 @@ -package ccipdata +package ccipdata_test import ( + "context" "math/big" "testing" + "time" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" lpmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" ) func TestPriceRegistryFilters(t *testing.T) { cl := mocks.NewClient(t) cl.On("ConfiguredChainID").Return(big.NewInt(1)) - assertFilterRegistration(t, new(lpmocks.LogPoller), func(lp *lpmocks.LogPoller, addr common.Address) Closer { - c, err := NewPriceRegistryV1_0_0(logger.TestLogger(t), addr, lp, cl) + assertFilterRegistration(t, new(lpmocks.LogPoller), func(lp *lpmocks.LogPoller, addr common.Address) ccipdata.Closer { + c, err := ccipdata.NewPriceRegistryV1_0_0(logger.TestLogger(t), addr, lp, cl) require.NoError(t, err) return c }, 3) + + assertFilterRegistration(t, new(lpmocks.LogPoller), func(lp *lpmocks.LogPoller, addr common.Address) ccipdata.Closer { + c, err := ccipdata.NewPriceRegistryV1_2_0(logger.TestLogger(t), addr, lp, cl) + require.NoError(t, err) + return c + }, 3) +} + +type priceRegReaderTH struct { + lp logpoller.LogPollerTest + ec client.Client + lggr logger.Logger + user *bind.TransactOpts + sim *backends.SimulatedBackend + readers []ccipdata.PriceRegistryReader + + // Expected state + expectedFeeTokens []common.Address + expectedGasUpdates []ccipdata.GasPrice +} + +// setupPriceRegistryReaderTH instatiates all versions of the price registry reader +// with a snapshot of data so reader tests can do multi-version assertions. +func setupPriceRegistryReaderTH(t *testing.T) priceRegReaderTH { + user := testutils.MustNewSimTransactor(t) + sim := backends.NewSimulatedBackend(map[common.Address]core.GenesisAccount{ + user.From: { + Balance: big.NewInt(0).Mul(big.NewInt(10), big.NewInt(1e18)), + }, + }, 10e6) + sim.Commit() + ec := client.NewSimulatedBackendClient(t, sim, testutils.SimulatedChainID) + lggr := logger.TestLogger(t) + // TODO: We should be able to use an in memory log poller ORM here to speed up the tests. + lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.SimulatedChainID, pgtest.NewSqlxDB(t), lggr, pgtest.NewQConfig(true)), ec, lggr, 100*time.Millisecond, 2, 3, 2, 1000) + + feeTokens := []common.Address{randomAddress(), randomAddress()} + gasPriceUpdates := []ccipdata.GasPrice{ + { + DestChainSelector: uint64(10), + Value: big.NewInt(11), + }, + } + addr, _, pr, err := price_registry_1_0_0.DeployPriceRegistry(user, sim, nil, feeTokens, 1000) + require.NoError(t, err) + _, err = pr.UpdatePrices(user, price_registry_1_0_0.InternalPriceUpdates{ + TokenPriceUpdates: []price_registry_1_0_0.InternalTokenPriceUpdate{}, + DestChainSelector: gasPriceUpdates[0].DestChainSelector, + UsdPerUnitGas: gasPriceUpdates[0].Value, + }) + require.NoError(t, err) + sim.Commit() + pr10, err := ccipdata.NewPriceRegistryReader(lggr, addr, lp, ec) + require.NoError(t, err) + + addr, _, pr2, err := price_registry.DeployPriceRegistry(user, sim, nil, feeTokens, 1000) + require.NoError(t, err) + _, err = pr2.UpdatePrices(user, price_registry.InternalPriceUpdates{ + TokenPriceUpdates: []price_registry.InternalTokenPriceUpdate{}, + GasPriceUpdates: []price_registry.InternalGasPriceUpdate{ + { + DestChainSelector: gasPriceUpdates[0].DestChainSelector, + UsdPerUnitGas: gasPriceUpdates[0].Value, + }, + }, + }) + require.NoError(t, err) + sim.Commit() + pr12r, err := ccipdata.NewPriceRegistryReader(lggr, addr, lp, ec) + require.NoError(t, err) + + // Capture all lp data. + lp.PollAndSaveLogs(context.Background(), 1) + + return priceRegReaderTH{ + lp: lp, + ec: ec, + lggr: lggr, + user: user, + sim: sim, + readers: []ccipdata.PriceRegistryReader{pr10, pr12r}, + expectedFeeTokens: feeTokens, + expectedGasUpdates: gasPriceUpdates, + } +} + +func TestPriceRegistryReader(t *testing.T) { + th := setupPriceRegistryReaderTH(t) + for _, pr := range th.readers { + // Assert fee token read. + gotFeeTokens, err := pr.GetFeeTokens(context.Background()) + require.NoError(t, err) + assert.Equal(t, th.expectedFeeTokens, gotFeeTokens) + + // Assert latest gas price read. + updates, err := pr.GetGasPriceUpdatesCreatedAfter(context.Background(), th.expectedGasUpdates[0].DestChainSelector, time.Unix(0, 0), 0) + require.NoError(t, err) + require.Equal(t, len(updates), 1) + assert.Equal(t, updates[0].Data.GasPrice, th.expectedGasUpdates[0]) + + // TODO test other price reader methods. + } } diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_0_0.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_0_0.go index 9e16330dc1..f8eb4eb69f 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_0_0.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_0_0.go @@ -12,6 +12,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_0_0" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/logpollerutil" @@ -21,21 +22,24 @@ import ( var ( _ PriceRegistryReader = &PriceRegistryV1_0_0{} + // Exposed only for backwards compatibility with tests. + UsdPerUnitGasUpdatedV1_0_0 = abihelpers.MustGetEventID("UsdPerUnitGasUpdated", abihelpers.MustParseABI(price_registry.PriceRegistryABI)) ) type PriceRegistryV1_0_0 struct { - priceRegistry *observability.ObservedPriceRegistryV1_0_0 - address common.Address - lp logpoller.LogPoller - lggr logger.Logger - filters []logpoller.Filter - tokenUpdated common.Hash - gasUpdated common.Hash + priceRegistry *observability.ObservedPriceRegistryV1_0_0 + address common.Address + lp logpoller.LogPoller + lggr logger.Logger + filters []logpoller.Filter + tokenUpdated common.Hash + gasUpdated common.Hash + feeTokenAdded common.Hash + feeTokenRemoved common.Hash } func (p *PriceRegistryV1_0_0) FeeTokenEvents() []common.Hash { - priceRegABI := abihelpers.MustParseABI(price_registry.PriceRegistryABI) - return []common.Hash{abihelpers.MustGetEventID("FeeTokenRemoved", priceRegABI), abihelpers.MustGetEventID("FeeTokenAdded", priceRegABI)} + return []common.Hash{p.feeTokenAdded, p.feeTokenRemoved} } func (p *PriceRegistryV1_0_0) GetTokenPrices(ctx context.Context, wantedTokens []common.Address) ([]TokenPriceUpdate, error) { @@ -50,7 +54,7 @@ func (p *PriceRegistryV1_0_0) GetTokenPrices(ctx context.Context, wantedTokens [ Token: wantedTokens[i], Value: tp.Value, }, - Timestamp: big.NewInt(int64(tp.Timestamp)), // TODO: valid conversion + Timestamp: big.NewInt(int64(tp.Timestamp)), }) } return tpu, nil @@ -133,27 +137,28 @@ func (p *PriceRegistryV1_0_0) GetGasPriceUpdatesCreatedAfter(ctx context.Context } func NewPriceRegistryV1_0_0(lggr logger.Logger, priceRegistryAddr common.Address, lp logpoller.LogPoller, ec client.Client) (*PriceRegistryV1_0_0, error) { - // TODO pass label priceRegistry, err := observability.NewObservedPriceRegistryV1_0_0(priceRegistryAddr, ExecPluginLabel, ec) if err != nil { return nil, err } - priceRegistryABI := abihelpers.MustParseABI(price_registry.PriceRegistryABI) - // TODO: clean up strings - tokenUpdated := abihelpers.MustGetEventID("UsdPerTokenUpdated", priceRegistryABI) - var filters = []logpoller.Filter{{ - Name: logpoller.FilterName(COMMIT_PRICE_UPDATES, priceRegistryAddr.String()), - EventSigs: []common.Hash{UsdPerUnitGasUpdatedV1_0_0, tokenUpdated}, - Addresses: []common.Address{priceRegistryAddr}, - }, + priceRegABI := abihelpers.MustParseABI(price_registry_1_0_0.PriceRegistryABI) + usdPerTokenUpdated := abihelpers.MustGetEventID("UsdPerTokenUpdated", priceRegABI) + feeTokenRemoved := abihelpers.MustGetEventID("FeeTokenRemoved", priceRegABI) + feeTokenAdded := abihelpers.MustGetEventID("FeeTokenAdded", priceRegABI) + var filters = []logpoller.Filter{ + { + Name: logpoller.FilterName(COMMIT_PRICE_UPDATES, priceRegistryAddr.String()), + EventSigs: []common.Hash{UsdPerUnitGasUpdatedV1_0_0, usdPerTokenUpdated}, + Addresses: []common.Address{priceRegistryAddr}, + }, { Name: logpoller.FilterName(FEE_TOKEN_ADDED, priceRegistryAddr.String()), - EventSigs: []common.Hash{abihelpers.MustGetEventID("FeeTokenAdded", priceRegistryABI)}, + EventSigs: []common.Hash{feeTokenAdded}, Addresses: []common.Address{priceRegistryAddr}, }, { Name: logpoller.FilterName(FEE_TOKEN_REMOVED, priceRegistryAddr.String()), - EventSigs: []common.Hash{abihelpers.MustGetEventID("FeeTokenAdded", priceRegistryABI)}, + EventSigs: []common.Hash{feeTokenRemoved}, Addresses: []common.Address{priceRegistryAddr}, }} err = logpollerutil.RegisterLpFilters(lp, filters) @@ -161,12 +166,14 @@ func NewPriceRegistryV1_0_0(lggr logger.Logger, priceRegistryAddr common.Address return nil, err } return &PriceRegistryV1_0_0{ - priceRegistry: priceRegistry, - address: priceRegistryAddr, - lp: lp, - lggr: lggr, - gasUpdated: UsdPerUnitGasUpdatedV1_0_0, - tokenUpdated: tokenUpdated, - filters: filters, + priceRegistry: priceRegistry, + address: priceRegistryAddr, + lp: lp, + lggr: lggr, + gasUpdated: UsdPerUnitGasUpdatedV1_0_0, + tokenUpdated: usdPerTokenUpdated, + feeTokenRemoved: feeTokenRemoved, + feeTokenAdded: feeTokenAdded, + filters: filters, }, nil } diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_2_0.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_2_0.go index 4fd6210c9d..c61d390f30 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_2_0.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_2_0.go @@ -51,7 +51,7 @@ func (p *PriceRegistryV1_2_0) GetTokenPrices(ctx context.Context, wantedTokens [ Token: wantedTokens[i], Value: tp.Value, }, - Timestamp: big.NewInt(int64(tp.Timestamp)), // TODO: valid conversion + Timestamp: big.NewInt(int64(tp.Timestamp)), }) } return tpu, nil diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader_internal_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader_internal_test.go new file mode 100644 index 0000000000..d10f9a7af8 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader_internal_test.go @@ -0,0 +1,78 @@ +package ccipdata + +import ( + "context" + "fmt" + "testing" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + lpmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/utils" +) + +func TestLogPollerClient_GetLastUSDCMessagePriorToLogIndexInTx(t *testing.T) { + txHash := utils.RandomAddress().Hash() + ccipLogIndex := int64(100) + + expectedData := "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000f80000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc08610000000000000000" + expectedPostParse := "0x0000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc0861" + lggr := logger.TestLogger(t) + + t.Run("multiple found", func(t *testing.T) { + lp := lpmocks.NewLogPoller(t) + lp.On("RegisterFilter", mock.Anything).Return(nil) + u, err := NewUSDCReader(lggr, utils.RandomAddress(), lp) + require.NoError(t, err) + lp.On("IndexedLogsByTxHash", + u.usdcMessageSent, + txHash, + mock.Anything, + ).Return([]logpoller.Log{ + {LogIndex: ccipLogIndex - 2, Data: []byte("-2")}, + {LogIndex: ccipLogIndex - 1, Data: hexutil.MustDecode(expectedData)}, + {LogIndex: ccipLogIndex, Data: []byte("0")}, + {LogIndex: ccipLogIndex + 1, Data: []byte("1")}, + }, nil) + + usdcMessageData, err := u.GetLastUSDCMessagePriorToLogIndexInTx(context.Background(), ccipLogIndex, txHash) + assert.NoError(t, err) + assert.Equal(t, expectedPostParse, hexutil.Encode(usdcMessageData)) + lp.AssertExpectations(t) + }) + + t.Run("none found", func(t *testing.T) { + lp := lpmocks.NewLogPoller(t) + lp.On("RegisterFilter", mock.Anything).Return(nil) + u, err := NewUSDCReader(lggr, utils.RandomAddress(), lp) + require.NoError(t, err) + lp.On("IndexedLogsByTxHash", + u.usdcMessageSent, + txHash, + mock.Anything, + ).Return([]logpoller.Log{}, nil) + + usdcMessageData, err := u.GetLastUSDCMessagePriorToLogIndexInTx(context.Background(), ccipLogIndex, txHash) + assert.Errorf(t, err, fmt.Sprintf("no USDC message found prior to log index %d in tx %s", ccipLogIndex, txHash.Hex())) + assert.Nil(t, usdcMessageData) + + lp.AssertExpectations(t) + }) +} + +func TestParse(t *testing.T) { + expectedBody, err := hexutil.Decode("0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000f80000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc08610000000000000000") + require.NoError(t, err) + + parsedBody, err := parseUSDCMessageSent(expectedBody) + require.NoError(t, err) + + expectedPostParse := "0x0000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc0861" + + require.Equal(t, expectedPostParse, hexutil.Encode(parsedBody)) +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader_test.go index d8e8db0ef6..e540247eca 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader_test.go @@ -1,86 +1,19 @@ -package ccipdata +package ccipdata_test import ( - "context" - "fmt" "testing" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" lpmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/utils" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" ) -func TestLogPollerClient_GetLastUSDCMessagePriorToLogIndexInTx(t *testing.T) { - txHash := utils.RandomAddress().Hash() - ccipLogIndex := int64(100) - - expectedData := "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000f80000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc08610000000000000000" - expectedPostParse := "0x0000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc0861" - lggr := logger.TestLogger(t) - - t.Run("multiple found", func(t *testing.T) { - lp := lpmocks.NewLogPoller(t) - lp.On("RegisterFilter", mock.Anything).Return(nil) - u, err := NewUSDCReader(lggr, utils.RandomAddress(), lp) - require.NoError(t, err) - lp.On("IndexedLogsByTxHash", - u.usdcMessageSent, - txHash, - mock.Anything, - ).Return([]logpoller.Log{ - {LogIndex: ccipLogIndex - 2, Data: []byte("-2")}, - {LogIndex: ccipLogIndex - 1, Data: hexutil.MustDecode(expectedData)}, - {LogIndex: ccipLogIndex, Data: []byte("0")}, - {LogIndex: ccipLogIndex + 1, Data: []byte("1")}, - }, nil) - - usdcMessageData, err := u.GetLastUSDCMessagePriorToLogIndexInTx(context.Background(), ccipLogIndex, txHash) - assert.NoError(t, err) - assert.Equal(t, expectedPostParse, hexutil.Encode(usdcMessageData)) - lp.AssertExpectations(t) - }) - - t.Run("none found", func(t *testing.T) { - lp := lpmocks.NewLogPoller(t) - lp.On("RegisterFilter", mock.Anything).Return(nil) - u, err := NewUSDCReader(lggr, utils.RandomAddress(), lp) - require.NoError(t, err) - lp.On("IndexedLogsByTxHash", - u.usdcMessageSent, - txHash, - mock.Anything, - ).Return([]logpoller.Log{}, nil) - - usdcMessageData, err := u.GetLastUSDCMessagePriorToLogIndexInTx(context.Background(), ccipLogIndex, txHash) - assert.Errorf(t, err, fmt.Sprintf("no USDC message found prior to log index %d in tx %s", ccipLogIndex, txHash.Hex())) - assert.Nil(t, usdcMessageData) - - lp.AssertExpectations(t) - }) -} - -func TestParse(t *testing.T) { - expectedBody, err := hexutil.Decode("0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000f80000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc08610000000000000000") - require.NoError(t, err) - - parsedBody, err := parseUSDCMessageSent(expectedBody) - require.NoError(t, err) - - expectedPostParse := "0x0000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc0861" - - require.Equal(t, expectedPostParse, hexutil.Encode(parsedBody)) -} - func TestUSDCReaderFilters(t *testing.T) { - assertFilterRegistration(t, new(lpmocks.LogPoller), func(lp *lpmocks.LogPoller, addr common.Address) Closer { - c, err := NewUSDCReader(logger.TestLogger(t), addr, lp) + assertFilterRegistration(t, new(lpmocks.LogPoller), func(lp *lpmocks.LogPoller, addr common.Address) ccipdata.Closer { + c, err := ccipdata.NewUSDCReader(logger.TestLogger(t), addr, lp) require.NoError(t, err) return c }, 1) From 7d5598dd35fd261a19e13374a9b6fcb9b767d9d2 Mon Sep 17 00:00:00 2001 From: connorwstein Date: Wed, 11 Oct 2023 13:05:29 -0400 Subject: [PATCH 11/24] Improve test coverage --- .../ccipdata/price_registry_reader_test.go | 78 ++++++++++++++----- 1 file changed, 59 insertions(+), 19 deletions(-) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go index 40da116494..fb51237ed3 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go @@ -51,11 +51,12 @@ type priceRegReaderTH struct { readers []ccipdata.PriceRegistryReader // Expected state - expectedFeeTokens []common.Address - expectedGasUpdates []ccipdata.GasPrice + expectedFeeTokens []common.Address + expectedGasUpdates []ccipdata.GasPrice + expectedTokenUpdates []ccipdata.TokenPrice } -// setupPriceRegistryReaderTH instatiates all versions of the price registry reader +// setupPriceRegistryReaderTH instantiates all versions of the price registry reader // with a snapshot of data so reader tests can do multi-version assertions. func setupPriceRegistryReaderTH(t *testing.T) priceRegReaderTH { user := testutils.MustNewSimTransactor(t) @@ -77,10 +78,19 @@ func setupPriceRegistryReaderTH(t *testing.T) priceRegReaderTH { Value: big.NewInt(11), }, } + tokenPriceUpdates := []ccipdata.TokenPrice{ + { + Token: randomAddress(), + Value: big.NewInt(12), + }, + } addr, _, pr, err := price_registry_1_0_0.DeployPriceRegistry(user, sim, nil, feeTokens, 1000) require.NoError(t, err) _, err = pr.UpdatePrices(user, price_registry_1_0_0.InternalPriceUpdates{ - TokenPriceUpdates: []price_registry_1_0_0.InternalTokenPriceUpdate{}, + TokenPriceUpdates: []price_registry_1_0_0.InternalTokenPriceUpdate{{ + SourceToken: tokenPriceUpdates[0].Token, + UsdPerToken: tokenPriceUpdates[0].Value, + }}, DestChainSelector: gasPriceUpdates[0].DestChainSelector, UsdPerUnitGas: gasPriceUpdates[0].Value, }) @@ -92,7 +102,12 @@ func setupPriceRegistryReaderTH(t *testing.T) priceRegReaderTH { addr, _, pr2, err := price_registry.DeployPriceRegistry(user, sim, nil, feeTokens, 1000) require.NoError(t, err) _, err = pr2.UpdatePrices(user, price_registry.InternalPriceUpdates{ - TokenPriceUpdates: []price_registry.InternalTokenPriceUpdate{}, + TokenPriceUpdates: []price_registry.InternalTokenPriceUpdate{ + { + SourceToken: tokenPriceUpdates[0].Token, + UsdPerToken: tokenPriceUpdates[0].Value, + }, + }, GasPriceUpdates: []price_registry.InternalGasPriceUpdate{ { DestChainSelector: gasPriceUpdates[0].DestChainSelector, @@ -109,31 +124,56 @@ func setupPriceRegistryReaderTH(t *testing.T) priceRegReaderTH { lp.PollAndSaveLogs(context.Background(), 1) return priceRegReaderTH{ - lp: lp, - ec: ec, - lggr: lggr, - user: user, - sim: sim, - readers: []ccipdata.PriceRegistryReader{pr10, pr12r}, - expectedFeeTokens: feeTokens, - expectedGasUpdates: gasPriceUpdates, + lp: lp, + ec: ec, + lggr: lggr, + user: user, + sim: sim, + readers: []ccipdata.PriceRegistryReader{pr10, pr12r}, + expectedFeeTokens: feeTokens, + expectedGasUpdates: gasPriceUpdates, + expectedTokenUpdates: tokenPriceUpdates, } } func TestPriceRegistryReader(t *testing.T) { th := setupPriceRegistryReaderTH(t) + // Assert all readers produce the same expected results. for _, pr := range th.readers { - // Assert fee token read. + // Assert have expected fee tokens. gotFeeTokens, err := pr.GetFeeTokens(context.Background()) require.NoError(t, err) assert.Equal(t, th.expectedFeeTokens, gotFeeTokens) - // Assert latest gas price read. - updates, err := pr.GetGasPriceUpdatesCreatedAfter(context.Background(), th.expectedGasUpdates[0].DestChainSelector, time.Unix(0, 0), 0) + // Note unsupported chain selector simply returns an empty set not an error + gasUpdates, err := pr.GetGasPriceUpdatesCreatedAfter(context.Background(), th.expectedGasUpdates[0].DestChainSelector+1, time.Unix(0, 0), 0) + require.NoError(t, err) + assert.Len(t, gasUpdates, 0) + + // Assert expected gas updates. + gasUpdates, err = pr.GetGasPriceUpdatesCreatedAfter(context.Background(), th.expectedGasUpdates[0].DestChainSelector, time.Unix(0, 0), 0) + require.NoError(t, err) + require.Len(t, gasUpdates, 1) + assert.Equal(t, gasUpdates[0].Data.GasPrice, th.expectedGasUpdates[0]) + + // Assert expected token updates. + tokenUpdates, err := pr.GetTokenPriceUpdatesCreatedAfter(context.Background(), time.Unix(0, 0), 0) + require.NoError(t, err) + require.Len(t, tokenUpdates, 1) + assert.Equal(t, tokenUpdates[0].Data.TokenPrice, th.expectedTokenUpdates[0]) + + // Empty token set should return empty set no error. + gotEmpty, err := pr.GetTokenPrices(context.Background(), []common.Address{}) + require.NoError(t, err) + assert.Len(t, gotEmpty, 0) + + // Assert expected token prices + tokenPrices, err := pr.GetTokenPrices(context.Background(), []common.Address{th.expectedTokenUpdates[0].Token}) require.NoError(t, err) - require.Equal(t, len(updates), 1) - assert.Equal(t, updates[0].Data.GasPrice, th.expectedGasUpdates[0]) + require.Len(t, tokenPrices, 1) + assert.Equal(t, tokenPrices[0].TokenPrice, th.expectedTokenUpdates[0]) - // TODO test other price reader methods. + // We expect 2 fee token events (added/removed). Exact event sigs may differ. + assert.Len(t, pr.FeeTokenEvents(), 2) } } From dc7c5375e126547b3032f705b6d845e2417a673f Mon Sep 17 00:00:00 2001 From: connorwstein Date: Wed, 11 Oct 2023 16:24:34 -0400 Subject: [PATCH 12/24] Finish price reg test --- core/chains/evm/logpoller/orm.go | 30 ++- .../internal/ccipdata/commit_store_reader.go | 8 +- .../ccip/internal/ccipdata/offramp_reader.go | 6 +- .../ccipdata/offramp_reader_v1_0_0_test.go | 2 +- .../ccip/internal/ccipdata/onramp_reader.go | 6 +- .../ccipdata/price_registry_reader.go | 6 +- .../ccipdata/price_registry_reader_test.go | 212 +++++++++++------- .../ccipdata/price_registry_v1_0_0.go | 27 +++ .../ccipdata/price_registry_v1_2_0.go | 39 ++++ .../plugins/ccip/internal/ccipdata/reader.go | 6 +- 10 files changed, 228 insertions(+), 114 deletions(-) diff --git a/core/chains/evm/logpoller/orm.go b/core/chains/evm/logpoller/orm.go index 8cb80094c0..a4a84e7b84 100644 --- a/core/chains/evm/logpoller/orm.go +++ b/core/chains/evm/logpoller/orm.go @@ -276,21 +276,20 @@ func (o *DbORM) SelectLogs(start, end int64, address common.Address, eventSig co // SelectLogsCreatedAfter finds logs created after some timestamp. func (o *DbORM) SelectLogsCreatedAfter(address common.Address, eventSig common.Hash, after time.Time, confs int, qopts ...pg.QOpt) ([]Log, error) { - minBlock, maxBlock, err := o.blocksRangeAfterTimestamp(after, confs, qopts...) - if err != nil { - return nil, err - } + //minBlock, maxBlock, err := o.blocksRangeAfterTimestamp(after, confs, qopts...) + //if err != nil { + // return nil, err + //} var logs []Log q := o.q.WithOpts(qopts...) - err = q.Select(&logs, ` + err := q.Select(&logs, ` SELECT * FROM evm.logs WHERE evm_chain_id = $1 AND address = $2 AND event_sig = $3 - AND block_number > $4 - AND block_number <= $5 - ORDER BY (block_number, log_index)`, utils.NewBig(o.chainID), address, eventSig, minBlock, maxBlock) + AND block_timestamp > $4 + ORDER BY (block_number, log_index)`, utils.NewBig(o.chainID), address, eventSig, after) if err != nil { return nil, err } @@ -547,23 +546,22 @@ func validateTopicIndex(index int) error { } func (o *DbORM) SelectIndexedLogsCreatedAfter(address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, after time.Time, confs int, qopts ...pg.QOpt) ([]Log, error) { - minBlock, maxBlock, err := o.blocksRangeAfterTimestamp(after, confs, qopts...) - if err != nil { - return nil, err - } + //minBlock, maxBlock, err := o.blocksRangeAfterTimestamp(after, confs, qopts...) + //if err != nil { + // return nil, err + //} var logs []Log q := o.q.WithOpts(qopts...) topicValuesBytes := concatBytes(topicValues) // Add 1 since postgresql arrays are 1-indexed. - err = q.Select(&logs, ` + err := q.Select(&logs, ` SELECT * FROM evm.logs WHERE evm.logs.evm_chain_id = $1 AND address = $2 AND event_sig = $3 AND topics[$4] = ANY($5) - AND block_number > $6 - AND block_number <= $7 - ORDER BY (block_number, log_index)`, utils.NewBig(o.chainID), address, eventSig.Bytes(), topicIndex+1, topicValuesBytes, minBlock, maxBlock) + AND block_timestamp > $6 + ORDER BY (block_number, log_index)`, utils.NewBig(o.chainID), address, eventSig.Bytes(), topicIndex+1, topicValuesBytes, after) if err != nil { return nil, err } diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader.go index a7dd40c3ab..c41097192b 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader.go @@ -89,9 +89,9 @@ func NewCommitStoreReader(lggr logger.Logger, address common.Address, ec client. return nil, errors.Errorf("expected %v got %v", ccipconfig.EVM2EVMOnRamp, contractType) } switch version.String() { - case v1_0_0, v1_1_0: + case V1_0_0, V1_1_0: return NewCommitStoreV1_0_0(lggr, address, ec, lp, estimator) - case v1_2_0: + case V1_2_0: return NewCommitStoreV1_2_0(lggr, address, ec, lp, estimator) default: return nil, errors.Errorf("got unexpected version %v", version.String()) @@ -108,7 +108,7 @@ func CommitReportToEthTxMeta(typ ccipconfig.ContractType, ver semver.Version) (f return nil, errors.Errorf("expected %v got %v", ccipconfig.CommitStore, typ) } switch ver.String() { - case v1_0_0, v1_1_0: + case V1_0_0, V1_1_0: commitStoreABI := abihelpers.MustParseABI(commit_store_1_0_0.CommitStoreABI) return func(report []byte) (*txmgr.TxMeta, error) { commitReport, err := decodeCommitReportV1_0_0(abihelpers.MustGetEventInputs(ReportAccepted, commitStoreABI), report) @@ -117,7 +117,7 @@ func CommitReportToEthTxMeta(typ ccipconfig.ContractType, ver semver.Version) (f } return commitReportToEthTxMeta(commitReport) }, nil - case v1_2_0: + case V1_2_0: commitStoreABI := abihelpers.MustParseABI(commit_store.CommitStoreABI) return func(report []byte) (*txmgr.TxMeta, error) { commitReport, err := decodeCommitReportV1_2_0(abihelpers.MustGetEventInputs(ReportAccepted, commitStoreABI), report) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader.go index 42f6159704..40da5e604c 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader.go @@ -163,9 +163,9 @@ func NewOffRampReader(lggr logger.Logger, addr common.Address, destClient client return nil, err } switch version.String() { - case v1_0_0, v1_1_0: + case V1_0_0, V1_1_0: return NewOffRampV1_0_0(lggr, addr, destClient, lp, estimator) - case v1_2_0: + case V1_2_0: return NewOffRampV1_2_0(lggr, addr, destClient, lp, estimator) default: return nil, errors.Errorf("unsupported offramp version %v", version.String()) @@ -178,7 +178,7 @@ func ExecReportToEthTxMeta(typ ccipconfig.ContractType, ver semver.Version) (fun return nil, errors.Errorf("expected %v got %v", ccipconfig.EVM2EVMOffRamp, typ) } switch ver.String() { - case v1_0_0, v1_1_0, v1_2_0: + case V1_0_0, V1_1_0, V1_2_0: // ABI remains the same across all offramp versions. offRampABI := abihelpers.MustParseABI(evm_2_evm_offramp.EVM2EVMOffRampABI) return func(report []byte) (*txmgr.TxMeta, error) { diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_v1_0_0_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_v1_0_0_test.go index 76a680764d..f6cde7993c 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_v1_0_0_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_v1_0_0_test.go @@ -34,5 +34,5 @@ func TestExecutionReportEncoding(t *testing.T) { decodeCommitReport, err := offRamp.DecodeExecutionReport(encodeExecutionReport) require.NoError(t, err) require.Equal(t, report.Proofs, decodeCommitReport.Proofs) - // require.Equal(t, report, decodeCommitReport) // TODO: fails because some fields are not supported on v1_0_0 + // require.Equal(t, report, decodeCommitReport) // TODO: fails because some fields are not supported on V1_0_0 } diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_reader.go index f09952008c..bd485b5080 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_reader.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_reader.go @@ -45,11 +45,11 @@ func NewOnRampReader(lggr logger.Logger, sourceSelector, destSelector uint64, on return nil, errors.Errorf("expected %v got %v", ccipconfig.EVM2EVMOnRamp, contractType) } switch version.String() { - case v1_0_0: + case V1_0_0: return NewOnRampV1_0_0(lggr, sourceSelector, destSelector, onRampAddress, sourceLP, source, finalityTags) - case v1_1_0: + case V1_1_0: return NewOnRampV1_1_0(lggr, sourceSelector, destSelector, onRampAddress, sourceLP, source, finalityTags) - case v1_2_0: + case V1_2_0: return NewOnRampV1_2_0(lggr, sourceSelector, destSelector, onRampAddress, sourceLP, source, finalityTags) default: return nil, errors.Errorf("got unexpected version %v", version.String()) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go index 14f5d519a3..97fcc4e468 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go @@ -48,8 +48,10 @@ type GasPriceUpdate struct { type PriceRegistryReader interface { Close(qopts ...pg.QOpt) error // GetTokenPriceUpdatesCreatedAfter returns all the token price updates that happened after the provided timestamp. + // The returned updates are sorted by timestamp in ascending order. GetTokenPriceUpdatesCreatedAfter(ctx context.Context, ts time.Time, confs int) ([]Event[TokenPriceUpdate], error) // GetGasPriceUpdatesCreatedAfter returns all the gas price updates that happened after the provided timestamp. + // The returned updates are sorted by timestamp in ascending order. GetGasPriceUpdatesCreatedAfter(ctx context.Context, chainSelector uint64, ts time.Time, confs int) ([]Event[GasPriceUpdate], error) Address() common.Address FeeTokenEvents() []common.Hash @@ -61,12 +63,14 @@ type PriceRegistryReader interface { func NewPriceRegistryReader(lggr logger.Logger, priceRegistryAddress common.Address, lp logpoller.LogPoller, cl client.Client) (PriceRegistryReader, error) { _, version, err := ccipconfig.TypeAndVersion(priceRegistryAddress, cl) if err != nil { + lggr.Infof("Assuming %v is 1.0.0 price registry", priceRegistryAddress.String()) // Unfortunately the v1 price registry doesn't have a method to get the version so assume if it errors // its v1. + // TODO: if there's an RPC error we may actually create a 100 reader for 120 contract? return NewPriceRegistryV1_0_0(lggr, priceRegistryAddress, lp, cl) } switch version.String() { - case v1_2_0: + case V1_2_0: return NewPriceRegistryV1_2_0(lggr, priceRegistryAddress, lp, cl) default: return nil, errors.Errorf("got unexpected version %v", version.String()) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go index fb51237ed3..4e35e213aa 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go @@ -2,6 +2,7 @@ package ccipdata_test import ( "context" + "fmt" "math/big" "testing" "time" @@ -48,12 +49,21 @@ type priceRegReaderTH struct { lggr logger.Logger user *bind.TransactOpts sim *backends.SimulatedBackend - readers []ccipdata.PriceRegistryReader + readers map[string]ccipdata.PriceRegistryReader // Expected state + blockTs []uint64 expectedFeeTokens []common.Address - expectedGasUpdates []ccipdata.GasPrice - expectedTokenUpdates []ccipdata.TokenPrice + expectedGasUpdates map[uint64][]ccipdata.GasPrice + expectedTokenUpdates map[uint64][]ccipdata.TokenPrice + dest uint64 +} + +func commitAndGetBlockTs(ec *client.SimulatedBackendClient) uint64 { + h := ec.Commit() + b, _ := ec.BlockByHash(context.Background(), h) + fmt.Println("bh", b.Number(), b.Hash()) + return b.Time() } // setupPriceRegistryReaderTH instantiates all versions of the price registry reader @@ -72,108 +82,144 @@ func setupPriceRegistryReaderTH(t *testing.T) priceRegReaderTH { lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.SimulatedChainID, pgtest.NewSqlxDB(t), lggr, pgtest.NewQConfig(true)), ec, lggr, 100*time.Millisecond, 2, 3, 2, 1000) feeTokens := []common.Address{randomAddress(), randomAddress()} - gasPriceUpdates := []ccipdata.GasPrice{ + dest := uint64(10) + gasPriceUpdatesBlock1 := []ccipdata.GasPrice{ { - DestChainSelector: uint64(10), + DestChainSelector: dest, Value: big.NewInt(11), }, } - tokenPriceUpdates := []ccipdata.TokenPrice{ + gasPriceUpdatesBlock2 := []ccipdata.GasPrice{ + { + DestChainSelector: dest, // Reset same gas price + Value: big.NewInt(12), + }, + } + token1 := randomAddress() + token2 := randomAddress() + tokenPriceUpdatesBlock1 := []ccipdata.TokenPrice{ { - Token: randomAddress(), + Token: token1, Value: big.NewInt(12), }, } - addr, _, pr, err := price_registry_1_0_0.DeployPriceRegistry(user, sim, nil, feeTokens, 1000) - require.NoError(t, err) - _, err = pr.UpdatePrices(user, price_registry_1_0_0.InternalPriceUpdates{ - TokenPriceUpdates: []price_registry_1_0_0.InternalTokenPriceUpdate{{ - SourceToken: tokenPriceUpdates[0].Token, - UsdPerToken: tokenPriceUpdates[0].Value, - }}, - DestChainSelector: gasPriceUpdates[0].DestChainSelector, - UsdPerUnitGas: gasPriceUpdates[0].Value, - }) - require.NoError(t, err) - sim.Commit() - pr10, err := ccipdata.NewPriceRegistryReader(lggr, addr, lp, ec) - require.NoError(t, err) - - addr, _, pr2, err := price_registry.DeployPriceRegistry(user, sim, nil, feeTokens, 1000) - require.NoError(t, err) - _, err = pr2.UpdatePrices(user, price_registry.InternalPriceUpdates{ - TokenPriceUpdates: []price_registry.InternalTokenPriceUpdate{ - { - SourceToken: tokenPriceUpdates[0].Token, - UsdPerToken: tokenPriceUpdates[0].Value, - }, + tokenPriceUpdatesBlock2 := []ccipdata.TokenPrice{ + { + Token: token1, + Value: big.NewInt(13), }, - GasPriceUpdates: []price_registry.InternalGasPriceUpdate{ - { - DestChainSelector: gasPriceUpdates[0].DestChainSelector, - UsdPerUnitGas: gasPriceUpdates[0].Value, - }, + { + Token: token2, + Value: big.NewInt(12), }, - }) + } + addr, _, _, err := price_registry_1_0_0.DeployPriceRegistry(user, sim, nil, feeTokens, 1000) require.NoError(t, err) - sim.Commit() - pr12r, err := ccipdata.NewPriceRegistryReader(lggr, addr, lp, ec) + addr2, _, _, err := price_registry.DeployPriceRegistry(user, sim, nil, feeTokens, 1000) + require.NoError(t, err) + ec.Commit() // Deploy these + // Apply block1. + ccipdata.ApplyPriceRegistryUpdateV1_0_0(t, user, addr, ec, gasPriceUpdatesBlock1, tokenPriceUpdatesBlock1) + ccipdata.ApplyPriceRegistryUpdateV1_2_0(t, user, addr2, ec, gasPriceUpdatesBlock1, tokenPriceUpdatesBlock1) + b1 := commitAndGetBlockTs(ec) + // Apply block2 + ccipdata.ApplyPriceRegistryUpdateV1_0_0(t, user, addr, ec, gasPriceUpdatesBlock2, tokenPriceUpdatesBlock2) + ccipdata.ApplyPriceRegistryUpdateV1_2_0(t, user, addr2, ec, gasPriceUpdatesBlock2, tokenPriceUpdatesBlock2) + b2 := commitAndGetBlockTs(ec) + + pr10r, err := ccipdata.NewPriceRegistryReader(lggr, addr, lp, ec) + require.NoError(t, err) + pr12r, err := ccipdata.NewPriceRegistryReader(lggr, addr2, lp, ec) require.NoError(t, err) // Capture all lp data. lp.PollAndSaveLogs(context.Background(), 1) return priceRegReaderTH{ - lp: lp, - ec: ec, - lggr: lggr, - user: user, - sim: sim, - readers: []ccipdata.PriceRegistryReader{pr10, pr12r}, - expectedFeeTokens: feeTokens, - expectedGasUpdates: gasPriceUpdates, - expectedTokenUpdates: tokenPriceUpdates, + lp: lp, + ec: ec, + lggr: lggr, + user: user, + sim: sim, + readers: map[string]ccipdata.PriceRegistryReader{ + ccipdata.V1_0_0: pr10r, ccipdata.V1_2_0: pr12r, + }, + expectedFeeTokens: feeTokens, + expectedGasUpdates: map[uint64][]ccipdata.GasPrice{ + b1: gasPriceUpdatesBlock1, + b2: gasPriceUpdatesBlock2, + }, + expectedTokenUpdates: map[uint64][]ccipdata.TokenPrice{ + b1: tokenPriceUpdatesBlock1, + b2: tokenPriceUpdatesBlock2, + }, + blockTs: []uint64{b1, b2}, + dest: dest, } } func TestPriceRegistryReader(t *testing.T) { th := setupPriceRegistryReaderTH(t) // Assert all readers produce the same expected results. - for _, pr := range th.readers { - // Assert have expected fee tokens. - gotFeeTokens, err := pr.GetFeeTokens(context.Background()) - require.NoError(t, err) - assert.Equal(t, th.expectedFeeTokens, gotFeeTokens) - - // Note unsupported chain selector simply returns an empty set not an error - gasUpdates, err := pr.GetGasPriceUpdatesCreatedAfter(context.Background(), th.expectedGasUpdates[0].DestChainSelector+1, time.Unix(0, 0), 0) - require.NoError(t, err) - assert.Len(t, gasUpdates, 0) - - // Assert expected gas updates. - gasUpdates, err = pr.GetGasPriceUpdatesCreatedAfter(context.Background(), th.expectedGasUpdates[0].DestChainSelector, time.Unix(0, 0), 0) - require.NoError(t, err) - require.Len(t, gasUpdates, 1) - assert.Equal(t, gasUpdates[0].Data.GasPrice, th.expectedGasUpdates[0]) - - // Assert expected token updates. - tokenUpdates, err := pr.GetTokenPriceUpdatesCreatedAfter(context.Background(), time.Unix(0, 0), 0) - require.NoError(t, err) - require.Len(t, tokenUpdates, 1) - assert.Equal(t, tokenUpdates[0].Data.TokenPrice, th.expectedTokenUpdates[0]) - - // Empty token set should return empty set no error. - gotEmpty, err := pr.GetTokenPrices(context.Background(), []common.Address{}) - require.NoError(t, err) - assert.Len(t, gotEmpty, 0) - - // Assert expected token prices - tokenPrices, err := pr.GetTokenPrices(context.Background(), []common.Address{th.expectedTokenUpdates[0].Token}) - require.NoError(t, err) - require.Len(t, tokenPrices, 1) - assert.Equal(t, tokenPrices[0].TokenPrice, th.expectedTokenUpdates[0]) - - // We expect 2 fee token events (added/removed). Exact event sigs may differ. - assert.Len(t, pr.FeeTokenEvents(), 2) + for version, pr := range th.readers { + pr := pr + t.Run("PriceRegistryReader"+version, func(t *testing.T) { + // Assert have expected fee tokens. + gotFeeTokens, err := pr.GetFeeTokens(context.Background()) + require.NoError(t, err) + assert.Equal(t, th.expectedFeeTokens, gotFeeTokens) + + // Note unsupported chain selector simply returns an empty set not an error + gasUpdates, err := pr.GetGasPriceUpdatesCreatedAfter(context.Background(), 1e6, time.Unix(0, 0), 0) + require.NoError(t, err) + assert.Len(t, gasUpdates, 0) + + for i, ts := range th.blockTs { + // Should see all updates >= ts. + var expectedGas []ccipdata.GasPrice + var expectedToken []ccipdata.TokenPrice + for j := i; j < len(th.blockTs); j++ { + expectedGas = append(expectedGas, th.expectedGasUpdates[th.blockTs[j]]...) + expectedToken = append(expectedToken, th.expectedTokenUpdates[th.blockTs[j]]...) + } + gasUpdates, err = pr.GetGasPriceUpdatesCreatedAfter(context.Background(), th.dest, time.Unix(int64(ts-1), 0), 0) + require.NoError(t, err) + assert.Len(t, gasUpdates, len(expectedGas)) + + tokenUpdates, err := pr.GetTokenPriceUpdatesCreatedAfter(context.Background(), time.Unix(int64(ts-1), 0), 0) + require.NoError(t, err) + assert.Len(t, tokenUpdates, len(expectedToken)) + } + + // Empty token set should return empty set no error. + gotEmpty, err := pr.GetTokenPrices(context.Background(), []common.Address{}) + require.NoError(t, err) + assert.Len(t, gotEmpty, 0) + + // We expect latest token prices to apply + allTokenUpdates, err := pr.GetTokenPriceUpdatesCreatedAfter(context.Background(), time.Unix(0, 0), 0) + require.NoError(t, err) + // Build latest map + latest := make(map[common.Address]*big.Int) + // Comes back in ascending order (oldest first) + var allTokens []common.Address + for i := len(allTokenUpdates) - 1; i >= 0; i-- { + _, have := latest[allTokenUpdates[i].Data.Token] + if have { + continue + } + latest[allTokenUpdates[i].Data.Token] = allTokenUpdates[i].Data.Value + allTokens = append(allTokens, allTokenUpdates[i].Data.Token) + } + tokenPrices, err := pr.GetTokenPrices(context.Background(), allTokens) + require.NoError(t, err) + require.Len(t, tokenPrices, len(allTokens)) + for _, p := range tokenPrices { + assert.Equal(t, p.Value, latest[p.Token]) + } + + // We expect 2 fee token events (added/removed). Exact event sigs may differ. + assert.Len(t, pr.FeeTokenEvents(), 2) + }) } } diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_0_0.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_0_0.go index f8eb4eb69f..cef60630f6 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_0_0.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_0_0.go @@ -3,11 +3,13 @@ package ccipdata import ( "context" "math/big" + "testing" "time" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" @@ -177,3 +179,28 @@ func NewPriceRegistryV1_0_0(lggr logger.Logger, priceRegistryAddr common.Address filters: filters, }, nil } + +func ApplyPriceRegistryUpdateV1_0_0(t *testing.T, user *bind.TransactOpts, addr common.Address, ec client.Client, gasPrice []GasPrice, tokenPrices []TokenPrice) { + require.True(t, len(gasPrice) <= 1) + pr, err := price_registry_1_0_0.NewPriceRegistry(addr, ec) + require.NoError(t, err) + var tps []price_registry_1_0_0.InternalTokenPriceUpdate + for _, tp := range tokenPrices { + tps = append(tps, price_registry_1_0_0.InternalTokenPriceUpdate{ + SourceToken: tp.Token, + UsdPerToken: tp.Value, + }) + } + dest := uint64(0) + gas := big.NewInt(0) + if len(gasPrice) == 1 { + dest = gasPrice[0].DestChainSelector + gas = gasPrice[0].Value + } + _, err = pr.UpdatePrices(user, price_registry_1_0_0.InternalPriceUpdates{ + TokenPriceUpdates: tps, + DestChainSelector: dest, + UsdPerUnitGas: gas, + }) + require.NoError(t, err) +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_2_0.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_2_0.go index c61d390f30..6a6c88d784 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_2_0.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_2_0.go @@ -3,13 +3,17 @@ package ccipdata import ( "context" "math/big" + "testing" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/observability" ) @@ -17,6 +21,12 @@ var ( _ PriceRegistryReader = &PriceRegistryV1_2_0{} ) +func init() { + if abihelpers.MustGetEventID("UsdPerUnitGasUpdated", abihelpers.MustParseABI(price_registry.PriceRegistryABI)) != UsdPerUnitGasUpdatedV1_0_0 { + panic("UsdPerUnitGasUpdatedV1_0_0 must be the same as UsdPerUnitGasUpdated") + } +} + type PriceRegistryV1_2_0 struct { *PriceRegistryV1_0_0 obs *observability.ObservedPriceRegistryV1_2_0 @@ -56,3 +66,32 @@ func (p *PriceRegistryV1_2_0) GetTokenPrices(ctx context.Context, wantedTokens [ } return tpu, nil } + +func ApplyPriceRegistryUpdateV1_2_0(t *testing.T, user *bind.TransactOpts, addr common.Address, ec client.Client, gasPrices []GasPrice, tokenPrices []TokenPrice) common.Hash { + require.True(t, len(gasPrices) <= 1) + pr, err := price_registry.NewPriceRegistry(addr, ec) + require.NoError(t, err) + o, err := pr.Owner(nil) + require.NoError(t, err) + require.Equal(t, user.From, o) + var tps []price_registry.InternalTokenPriceUpdate + for _, tp := range tokenPrices { + tps = append(tps, price_registry.InternalTokenPriceUpdate{ + SourceToken: tp.Token, + UsdPerToken: tp.Value, + }) + } + var gps []price_registry.InternalGasPriceUpdate + for _, gp := range gasPrices { + gps = append(gps, price_registry.InternalGasPriceUpdate{ + DestChainSelector: gp.DestChainSelector, + UsdPerUnitGas: gp.Value, + }) + } + tx, err := pr.UpdatePrices(user, price_registry.InternalPriceUpdates{ + TokenPriceUpdates: tps, + GasPriceUpdates: gps, + }) + require.NoError(t, err) + return tx.Hash() +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/reader.go index 48f2b2e71b..dd0c6b14cd 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/reader.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/reader.go @@ -22,9 +22,9 @@ type Meta struct { } const ( - v1_0_0 = "1.0.0" - v1_1_0 = "1.1.0" - v1_2_0 = "1.2.0" + V1_0_0 = "1.0.0" + V1_1_0 = "1.1.0" + V1_2_0 = "1.2.0" ) type Closer interface { From 48eaafebf5612e0aeb3e2c1f9f21c2c69131a256 Mon Sep 17 00:00:00 2001 From: connorwstein Date: Wed, 11 Oct 2023 17:06:23 -0400 Subject: [PATCH 13/24] Fix lp test --- core/chains/evm/logpoller/orm.go | 19 ++++------ core/chains/evm/logpoller/orm_test.go | 36 +++++++++++-------- .../ccipdata/price_registry_reader_test.go | 14 +++----- 3 files changed, 32 insertions(+), 37 deletions(-) diff --git a/core/chains/evm/logpoller/orm.go b/core/chains/evm/logpoller/orm.go index a4a84e7b84..63810f733e 100644 --- a/core/chains/evm/logpoller/orm.go +++ b/core/chains/evm/logpoller/orm.go @@ -276,11 +276,6 @@ func (o *DbORM) SelectLogs(start, end int64, address common.Address, eventSig co // SelectLogsCreatedAfter finds logs created after some timestamp. func (o *DbORM) SelectLogsCreatedAfter(address common.Address, eventSig common.Hash, after time.Time, confs int, qopts ...pg.QOpt) ([]Log, error) { - //minBlock, maxBlock, err := o.blocksRangeAfterTimestamp(after, confs, qopts...) - //if err != nil { - // return nil, err - //} - var logs []Log q := o.q.WithOpts(qopts...) err := q.Select(&logs, ` @@ -288,8 +283,9 @@ func (o *DbORM) SelectLogsCreatedAfter(address common.Address, eventSig common.H WHERE evm_chain_id = $1 AND address = $2 AND event_sig = $3 - AND block_timestamp > $4 - ORDER BY (block_number, log_index)`, utils.NewBig(o.chainID), address, eventSig, after) + AND (block_number + $4) <= (SELECT COALESCE(block_number, 0) FROM evm.log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) + AND block_timestamp > $5 + ORDER BY (block_number, log_index)`, utils.NewBig(o.chainID), address, eventSig, confs, after) if err != nil { return nil, err } @@ -546,10 +542,6 @@ func validateTopicIndex(index int) error { } func (o *DbORM) SelectIndexedLogsCreatedAfter(address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, after time.Time, confs int, qopts ...pg.QOpt) ([]Log, error) { - //minBlock, maxBlock, err := o.blocksRangeAfterTimestamp(after, confs, qopts...) - //if err != nil { - // return nil, err - //} var logs []Log q := o.q.WithOpts(qopts...) topicValuesBytes := concatBytes(topicValues) @@ -560,8 +552,9 @@ func (o *DbORM) SelectIndexedLogsCreatedAfter(address common.Address, eventSig c AND address = $2 AND event_sig = $3 AND topics[$4] = ANY($5) - AND block_timestamp > $6 - ORDER BY (block_number, log_index)`, utils.NewBig(o.chainID), address, eventSig.Bytes(), topicIndex+1, topicValuesBytes, after) + AND (block_number + $6) <= (SELECT COALESCE(block_number, 0) FROM evm.log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) + AND block_timestamp > $7 + ORDER BY (block_number, log_index)`, utils.NewBig(o.chainID), address, eventSig.Bytes(), topicIndex+1, topicValuesBytes, confs, after) if err != nil { return nil, err } diff --git a/core/chains/evm/logpoller/orm_test.go b/core/chains/evm/logpoller/orm_test.go index 531aec2ff3..bb676d2acc 100644 --- a/core/chains/evm/logpoller/orm_test.go +++ b/core/chains/evm/logpoller/orm_test.go @@ -40,6 +40,12 @@ func GenLog(chainID *big.Int, logIndex int64, blockNum int64, blockHash string, } } +func GenLogWithTimestamp(chainID *big.Int, logIndex int64, blockNum int64, blockHash string, topic1 []byte, address common.Address, ts time.Time) logpoller.Log { + lg := GenLog(chainID, logIndex, blockNum, blockHash, topic1, address) + lg.BlockTimestamp = ts + return lg +} + func TestLogPoller_Batching(t *testing.T) { t.Parallel() th := SetupTH(t, 2, 3, 2) @@ -1177,19 +1183,19 @@ func TestSelectLogsCreatedAfter(t *testing.T) { event := EmitterABI.Events["Log1"].ID address := utils.RandomAddress() - past := time.Date(2010, 1, 1, 12, 12, 12, 0, time.UTC) - now := time.Date(2020, 1, 1, 12, 12, 12, 0, time.UTC) - future := time.Date(2030, 1, 1, 12, 12, 12, 0, time.UTC) + block1 := time.Date(2010, 1, 1, 12, 12, 12, 0, time.UTC) + block2 := time.Date(2020, 1, 1, 12, 12, 12, 0, time.UTC) + block3 := time.Date(2030, 1, 1, 12, 12, 12, 0, time.UTC) require.NoError(t, th.ORM.InsertLogs([]logpoller.Log{ - GenLog(th.ChainID, 1, 1, utils.RandomAddress().String(), event[:], address), - GenLog(th.ChainID, 1, 2, utils.RandomAddress().String(), event[:], address), - GenLog(th.ChainID, 2, 2, utils.RandomAddress().String(), event[:], address), - GenLog(th.ChainID, 1, 3, utils.RandomAddress().String(), event[:], address), + GenLogWithTimestamp(th.ChainID, 1, 1, utils.RandomAddress().String(), event[:], address, block1), + GenLogWithTimestamp(th.ChainID, 1, 2, utils.RandomAddress().String(), event[:], address, block2), + GenLogWithTimestamp(th.ChainID, 2, 2, utils.RandomAddress().String(), event[:], address, block2), + GenLogWithTimestamp(th.ChainID, 1, 3, utils.RandomAddress().String(), event[:], address, block3), })) - require.NoError(t, th.ORM.InsertBlock(utils.RandomAddress().Hash(), 1, past)) - require.NoError(t, th.ORM.InsertBlock(utils.RandomAddress().Hash(), 2, now)) - require.NoError(t, th.ORM.InsertBlock(utils.RandomAddress().Hash(), 3, future)) + require.NoError(t, th.ORM.InsertBlock(utils.RandomAddress().Hash(), 1, block1)) + require.NoError(t, th.ORM.InsertBlock(utils.RandomAddress().Hash(), 2, block2)) + require.NoError(t, th.ORM.InsertBlock(utils.RandomAddress().Hash(), 3, block3)) type expectedLog struct { block int64 @@ -1205,7 +1211,7 @@ func TestSelectLogsCreatedAfter(t *testing.T) { { name: "picks logs after block 1", confs: 0, - after: past.Add(-time.Hour), + after: block1.Add(time.Hour), expectedLogs: []expectedLog{ {block: 2, log: 1}, {block: 2, log: 2}, @@ -1215,7 +1221,7 @@ func TestSelectLogsCreatedAfter(t *testing.T) { { name: "skips blocks with not enough confirmations", confs: 1, - after: past.Add(-time.Hour), + after: block1.Add(time.Hour), expectedLogs: []expectedLog{ {block: 2, log: 1}, {block: 2, log: 2}, @@ -1224,7 +1230,7 @@ func TestSelectLogsCreatedAfter(t *testing.T) { { name: "limits number of blocks by block_timestamp", confs: 0, - after: now.Add(-time.Hour), + after: block2.Add(time.Hour), expectedLogs: []expectedLog{ {block: 3, log: 1}, }, @@ -1232,13 +1238,13 @@ func TestSelectLogsCreatedAfter(t *testing.T) { { name: "returns empty dataset for future timestamp", confs: 0, - after: future, + after: block3, expectedLogs: []expectedLog{}, }, { name: "returns empty dataset when too many confirmations are required", confs: 3, - after: past.Add(-time.Hour), + after: block1.Add(-time.Hour), expectedLogs: []expectedLog{}, }, } diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go index 4e35e213aa..e6b9c9b89a 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go @@ -2,7 +2,6 @@ package ccipdata_test import ( "context" - "fmt" "math/big" "testing" "time" @@ -62,7 +61,6 @@ type priceRegReaderTH struct { func commitAndGetBlockTs(ec *client.SimulatedBackendClient) uint64 { h := ec.Commit() b, _ := ec.BlockByHash(context.Background(), h) - fmt.Println("bh", b.Number(), b.Hash()) return b.Time() } @@ -75,7 +73,6 @@ func setupPriceRegistryReaderTH(t *testing.T) priceRegReaderTH { Balance: big.NewInt(0).Mul(big.NewInt(10), big.NewInt(1e18)), }, }, 10e6) - sim.Commit() ec := client.NewSimulatedBackendClient(t, sim, testutils.SimulatedChainID) lggr := logger.TestLogger(t) // TODO: We should be able to use an in memory log poller ORM here to speed up the tests. @@ -117,7 +114,11 @@ func setupPriceRegistryReaderTH(t *testing.T) priceRegReaderTH { require.NoError(t, err) addr2, _, _, err := price_registry.DeployPriceRegistry(user, sim, nil, feeTokens, 1000) require.NoError(t, err) - ec.Commit() // Deploy these + pr10r, err := ccipdata.NewPriceRegistryReader(lggr, addr, lp, ec) + require.NoError(t, err) + pr12r, err := ccipdata.NewPriceRegistryReader(lggr, addr2, lp, ec) + require.NoError(t, err) + commitAndGetBlockTs(ec) // Deploy these // Apply block1. ccipdata.ApplyPriceRegistryUpdateV1_0_0(t, user, addr, ec, gasPriceUpdatesBlock1, tokenPriceUpdatesBlock1) ccipdata.ApplyPriceRegistryUpdateV1_2_0(t, user, addr2, ec, gasPriceUpdatesBlock1, tokenPriceUpdatesBlock1) @@ -127,11 +128,6 @@ func setupPriceRegistryReaderTH(t *testing.T) priceRegReaderTH { ccipdata.ApplyPriceRegistryUpdateV1_2_0(t, user, addr2, ec, gasPriceUpdatesBlock2, tokenPriceUpdatesBlock2) b2 := commitAndGetBlockTs(ec) - pr10r, err := ccipdata.NewPriceRegistryReader(lggr, addr, lp, ec) - require.NoError(t, err) - pr12r, err := ccipdata.NewPriceRegistryReader(lggr, addr2, lp, ec) - require.NoError(t, err) - // Capture all lp data. lp.PollAndSaveLogs(context.Background(), 1) From d806fda09a829bcbe785c94d4bebcdfb8951d9a1 Mon Sep 17 00:00:00 2001 From: connorwstein Date: Wed, 11 Oct 2023 17:17:10 -0400 Subject: [PATCH 14/24] Cleanup --- .../ccipdata/price_registry_reader_test.go | 117 +++++++++--------- 1 file changed, 61 insertions(+), 56 deletions(-) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go index e6b9c9b89a..c2a3b33dd3 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go @@ -154,68 +154,73 @@ func setupPriceRegistryReaderTH(t *testing.T) priceRegReaderTH { } } +func testPriceRegistryReader(t *testing.T, th priceRegReaderTH, pr ccipdata.PriceRegistryReader) { + // Assert have expected fee tokens. + gotFeeTokens, err := pr.GetFeeTokens(context.Background()) + require.NoError(t, err) + assert.Equal(t, th.expectedFeeTokens, gotFeeTokens) + + // Note unsupported chain selector simply returns an empty set not an error + gasUpdates, err := pr.GetGasPriceUpdatesCreatedAfter(context.Background(), 1e6, time.Unix(0, 0), 0) + require.NoError(t, err) + assert.Len(t, gasUpdates, 0) + + for i, ts := range th.blockTs { + // Should see all updates >= ts. + var expectedGas []ccipdata.GasPrice + var expectedToken []ccipdata.TokenPrice + for j := i; j < len(th.blockTs); j++ { + expectedGas = append(expectedGas, th.expectedGasUpdates[th.blockTs[j]]...) + expectedToken = append(expectedToken, th.expectedTokenUpdates[th.blockTs[j]]...) + } + gasUpdates, err = pr.GetGasPriceUpdatesCreatedAfter(context.Background(), th.dest, time.Unix(int64(ts-1), 0), 0) + require.NoError(t, err) + assert.Len(t, gasUpdates, len(expectedGas)) + + tokenUpdates, err := pr.GetTokenPriceUpdatesCreatedAfter(context.Background(), time.Unix(int64(ts-1), 0), 0) + require.NoError(t, err) + assert.Len(t, tokenUpdates, len(expectedToken)) + } + + // Empty token set should return empty set no error. + gotEmpty, err := pr.GetTokenPrices(context.Background(), []common.Address{}) + require.NoError(t, err) + assert.Len(t, gotEmpty, 0) + + // We expect latest token prices to apply + allTokenUpdates, err := pr.GetTokenPriceUpdatesCreatedAfter(context.Background(), time.Unix(0, 0), 0) + require.NoError(t, err) + // Build latest map + latest := make(map[common.Address]*big.Int) + // Comes back in ascending order (oldest first) + var allTokens []common.Address + for i := len(allTokenUpdates) - 1; i >= 0; i-- { + _, have := latest[allTokenUpdates[i].Data.Token] + if have { + continue + } + latest[allTokenUpdates[i].Data.Token] = allTokenUpdates[i].Data.Value + allTokens = append(allTokens, allTokenUpdates[i].Data.Token) + } + tokenPrices, err := pr.GetTokenPrices(context.Background(), allTokens) + require.NoError(t, err) + require.Len(t, tokenPrices, len(allTokens)) + for _, p := range tokenPrices { + assert.Equal(t, p.Value, latest[p.Token]) + } + + // We expect 2 fee token events (added/removed). Exact event sigs may differ. + assert.Len(t, pr.FeeTokenEvents(), 2) + +} + func TestPriceRegistryReader(t *testing.T) { th := setupPriceRegistryReaderTH(t) // Assert all readers produce the same expected results. for version, pr := range th.readers { pr := pr t.Run("PriceRegistryReader"+version, func(t *testing.T) { - // Assert have expected fee tokens. - gotFeeTokens, err := pr.GetFeeTokens(context.Background()) - require.NoError(t, err) - assert.Equal(t, th.expectedFeeTokens, gotFeeTokens) - - // Note unsupported chain selector simply returns an empty set not an error - gasUpdates, err := pr.GetGasPriceUpdatesCreatedAfter(context.Background(), 1e6, time.Unix(0, 0), 0) - require.NoError(t, err) - assert.Len(t, gasUpdates, 0) - - for i, ts := range th.blockTs { - // Should see all updates >= ts. - var expectedGas []ccipdata.GasPrice - var expectedToken []ccipdata.TokenPrice - for j := i; j < len(th.blockTs); j++ { - expectedGas = append(expectedGas, th.expectedGasUpdates[th.blockTs[j]]...) - expectedToken = append(expectedToken, th.expectedTokenUpdates[th.blockTs[j]]...) - } - gasUpdates, err = pr.GetGasPriceUpdatesCreatedAfter(context.Background(), th.dest, time.Unix(int64(ts-1), 0), 0) - require.NoError(t, err) - assert.Len(t, gasUpdates, len(expectedGas)) - - tokenUpdates, err := pr.GetTokenPriceUpdatesCreatedAfter(context.Background(), time.Unix(int64(ts-1), 0), 0) - require.NoError(t, err) - assert.Len(t, tokenUpdates, len(expectedToken)) - } - - // Empty token set should return empty set no error. - gotEmpty, err := pr.GetTokenPrices(context.Background(), []common.Address{}) - require.NoError(t, err) - assert.Len(t, gotEmpty, 0) - - // We expect latest token prices to apply - allTokenUpdates, err := pr.GetTokenPriceUpdatesCreatedAfter(context.Background(), time.Unix(0, 0), 0) - require.NoError(t, err) - // Build latest map - latest := make(map[common.Address]*big.Int) - // Comes back in ascending order (oldest first) - var allTokens []common.Address - for i := len(allTokenUpdates) - 1; i >= 0; i-- { - _, have := latest[allTokenUpdates[i].Data.Token] - if have { - continue - } - latest[allTokenUpdates[i].Data.Token] = allTokenUpdates[i].Data.Value - allTokens = append(allTokens, allTokenUpdates[i].Data.Token) - } - tokenPrices, err := pr.GetTokenPrices(context.Background(), allTokens) - require.NoError(t, err) - require.Len(t, tokenPrices, len(allTokens)) - for _, p := range tokenPrices { - assert.Equal(t, p.Value, latest[p.Token]) - } - - // We expect 2 fee token events (added/removed). Exact event sigs may differ. - assert.Len(t, pr.FeeTokenEvents(), 2) + testPriceRegistryReader(t, th, pr) }) } } From 828ff5e74a6452d84ae359f2f892877926405e6b Mon Sep 17 00:00:00 2001 From: connorwstein Date: Wed, 11 Oct 2023 17:23:39 -0400 Subject: [PATCH 15/24] Fix lint --- .../ccip/internal/ccipdata/price_registry_reader_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go index c2a3b33dd3..27eba4e7b9 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go @@ -177,8 +177,8 @@ func testPriceRegistryReader(t *testing.T, th priceRegReaderTH, pr ccipdata.Pric require.NoError(t, err) assert.Len(t, gasUpdates, len(expectedGas)) - tokenUpdates, err := pr.GetTokenPriceUpdatesCreatedAfter(context.Background(), time.Unix(int64(ts-1), 0), 0) - require.NoError(t, err) + tokenUpdates, err2 := pr.GetTokenPriceUpdatesCreatedAfter(context.Background(), time.Unix(int64(ts-1), 0), 0) + require.NoError(t, err2) assert.Len(t, tokenUpdates, len(expectedToken)) } From 9eff47ad0cae94d9572758dac47e0a7e2bdaaa87 Mon Sep 17 00:00:00 2001 From: connorwstein Date: Thu, 12 Oct 2023 12:07:49 -0400 Subject: [PATCH 16/24] Port lp test and 2 easy TODOs --- core/chains/evm/logpoller/log_poller_test.go | 60 +++++++++++++++++++ .../ccip/commit_reporting_plugin_test.go | 2 +- .../ccip/internal/ccipdata/offramp_v1_2_0.go | 1 - .../ccipdata/price_registry_reader.go | 13 ++-- .../ccipdata/price_registry_reader_test.go | 22 ++++--- 5 files changed, 83 insertions(+), 15 deletions(-) diff --git a/core/chains/evm/logpoller/log_poller_test.go b/core/chains/evm/logpoller/log_poller_test.go index e21fc0f383..f6be57aa6e 100644 --- a/core/chains/evm/logpoller/log_poller_test.go +++ b/core/chains/evm/logpoller/log_poller_test.go @@ -1152,3 +1152,63 @@ func TestTooManyLogResults(t *testing.T) { require.Len(t, crit, 1) assert.Contains(t, crit[0].Message, "Too many log results in a single block") } + +func Test_CreatedAfterQueriesWithBackfill(t *testing.T) { + emittedLogs := 60 + finalityDepth := 10 + ctx := testutils.Context(t) + th := SetupTH(t, int64(finalityDepth), 3, 2) + + header, err := th.Client.HeaderByNumber(ctx, nil) + require.NoError(t, err) + + genesisBlockTime := time.UnixMilli(int64(header.Time)) + + // Emit some logs in blocks + for i := 0; i < emittedLogs; i++ { + _, err := th.Emitter1.EmitLog1(th.Owner, []*big.Int{big.NewInt(int64(i))}) + require.NoError(t, err) + th.Client.Commit() + } + + // First PollAndSave, no filters are registered + currentBlock := th.PollAndSaveLogs(ctx, 1) + + err = th.LogPoller.RegisterFilter(logpoller.Filter{ + Name: "Test Emitter", + EventSigs: []common.Hash{EmitterABI.Events["Log1"].ID}, + Addresses: []common.Address{th.EmitterAddress1}, + }) + require.NoError(t, err) + + // Emit blocks to cover finality depth, because backup always backfill up to the one block before last finalized + for i := 0; i < finalityDepth+1; i++ { + th.Client.Commit() + } + + // LogPoller should backfill entire history + th.LogPoller.BackupPollAndSaveLogs(ctx, 100) + require.NoError(t, err) + + // Make sure that all logs are backfilled + logs, err := th.LogPoller.Logs( + 0, + currentBlock, + EmitterABI.Events["Log1"].ID, + th.EmitterAddress1, + pg.WithParentCtx(testutils.Context(t)), + ) + require.NoError(t, err) + require.Len(t, logs, emittedLogs) + + // We should get all the logs by the block_timestamp + logs, err = th.LogPoller.LogsCreatedAfter( + EmitterABI.Events["Log1"].ID, + th.EmitterAddress1, + genesisBlockTime, + 0, + pg.WithParentCtx(testutils.Context(t)), + ) + require.NoError(t, err) + require.Len(t, logs, emittedLogs) +} diff --git a/core/services/ocr2/plugins/ccip/commit_reporting_plugin_test.go b/core/services/ocr2/plugins/ccip/commit_reporting_plugin_test.go index d47d2bd123..7d71b3d7ca 100644 --- a/core/services/ocr2/plugins/ccip/commit_reporting_plugin_test.go +++ b/core/services/ocr2/plugins/ccip/commit_reporting_plugin_test.go @@ -1696,7 +1696,7 @@ func TestCommitReportToEthTxMeta(t *testing.T) { txMeta, err := fn(out) require.NoError(t, err) require.NotNil(t, txMeta) - //require.EqualValues(t, tc.expectedRange, txMeta.SeqNumbers) // TODO: the commit store intervals are not decoded + require.EqualValues(t, tc.expectedRange, txMeta.SeqNumbers) }) } } diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_v1_2_0.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_v1_2_0.go index bf20ab4e48..c0cd3df8bc 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_v1_2_0.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_v1_2_0.go @@ -121,7 +121,6 @@ func (o *OffRampV1_2_0) ChangeConfig(onchainConfig []byte, offchainConfig []byte return onchainConfigParsed.PriceRegistry, destWrappedNative, nil } -// TODO probably a way to reuse 1.0.0 func (o *OffRampV1_2_0) OffchainConfig() ExecOffchainConfig { o.configMu.RLock() defer o.configMu.RUnlock() diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go index 97fcc4e468..a214c55fa4 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go @@ -3,6 +3,7 @@ package ccipdata import ( "context" "math/big" + "strings" "time" "github.com/ethereum/go-ethereum/common" @@ -63,11 +64,13 @@ type PriceRegistryReader interface { func NewPriceRegistryReader(lggr logger.Logger, priceRegistryAddress common.Address, lp logpoller.LogPoller, cl client.Client) (PriceRegistryReader, error) { _, version, err := ccipconfig.TypeAndVersion(priceRegistryAddress, cl) if err != nil { - lggr.Infof("Assuming %v is 1.0.0 price registry", priceRegistryAddress.String()) - // Unfortunately the v1 price registry doesn't have a method to get the version so assume if it errors - // its v1. - // TODO: if there's an RPC error we may actually create a 100 reader for 120 contract? - return NewPriceRegistryV1_0_0(lggr, priceRegistryAddress, lp, cl) + if strings.Contains(err.Error(), "execution reverted") { + lggr.Infof("Assuming %v is 1.0.0 price registry, got %v", priceRegistryAddress.String(), err) + // Unfortunately the v1 price registry doesn't have a method to get the version so assume if it reverts + // its v1. + return NewPriceRegistryV1_0_0(lggr, priceRegistryAddress, lp, cl) + } + return nil, err } switch version.String() { case V1_2_0: diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go index 27eba4e7b9..75634e0bc1 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go @@ -3,6 +3,7 @@ package ccipdata_test import ( "context" "math/big" + "reflect" "testing" "time" @@ -47,7 +48,6 @@ type priceRegReaderTH struct { ec client.Client lggr logger.Logger user *bind.TransactOpts - sim *backends.SimulatedBackend readers map[string]ccipdata.PriceRegistryReader // Expected state @@ -64,9 +64,7 @@ func commitAndGetBlockTs(ec *client.SimulatedBackendClient) uint64 { return b.Time() } -// setupPriceRegistryReaderTH instantiates all versions of the price registry reader -// with a snapshot of data so reader tests can do multi-version assertions. -func setupPriceRegistryReaderTH(t *testing.T) priceRegReaderTH { +func newSim(t *testing.T) (*bind.TransactOpts, *client.SimulatedBackendClient) { user := testutils.MustNewSimTransactor(t) sim := backends.NewSimulatedBackend(map[common.Address]core.GenesisAccount{ user.From: { @@ -74,6 +72,13 @@ func setupPriceRegistryReaderTH(t *testing.T) priceRegReaderTH { }, }, 10e6) ec := client.NewSimulatedBackendClient(t, sim, testutils.SimulatedChainID) + return user, ec +} + +// setupPriceRegistryReaderTH instantiates all versions of the price registry reader +// with a snapshot of data so reader tests can do multi-version assertions. +func setupPriceRegistryReaderTH(t *testing.T) priceRegReaderTH { + user, ec := newSim(t) lggr := logger.TestLogger(t) // TODO: We should be able to use an in memory log poller ORM here to speed up the tests. lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.SimulatedChainID, pgtest.NewSqlxDB(t), lggr, pgtest.NewQConfig(true)), ec, lggr, 100*time.Millisecond, 2, 3, 2, 1000) @@ -110,15 +115,17 @@ func setupPriceRegistryReaderTH(t *testing.T) priceRegReaderTH { Value: big.NewInt(12), }, } - addr, _, _, err := price_registry_1_0_0.DeployPriceRegistry(user, sim, nil, feeTokens, 1000) + addr, _, _, err := price_registry_1_0_0.DeployPriceRegistry(user, ec, nil, feeTokens, 1000) require.NoError(t, err) - addr2, _, _, err := price_registry.DeployPriceRegistry(user, sim, nil, feeTokens, 1000) + addr2, _, _, err := price_registry.DeployPriceRegistry(user, ec, nil, feeTokens, 1000) require.NoError(t, err) + commitAndGetBlockTs(ec) // Deploy these pr10r, err := ccipdata.NewPriceRegistryReader(lggr, addr, lp, ec) require.NoError(t, err) + assert.Equal(t, reflect.TypeOf(pr10r).String(), reflect.TypeOf(&ccipdata.PriceRegistryV1_0_0{}).String()) pr12r, err := ccipdata.NewPriceRegistryReader(lggr, addr2, lp, ec) require.NoError(t, err) - commitAndGetBlockTs(ec) // Deploy these + assert.Equal(t, reflect.TypeOf(pr10r).String(), reflect.TypeOf(&ccipdata.PriceRegistryV1_0_0{}).String()) // Apply block1. ccipdata.ApplyPriceRegistryUpdateV1_0_0(t, user, addr, ec, gasPriceUpdatesBlock1, tokenPriceUpdatesBlock1) ccipdata.ApplyPriceRegistryUpdateV1_2_0(t, user, addr2, ec, gasPriceUpdatesBlock1, tokenPriceUpdatesBlock1) @@ -136,7 +143,6 @@ func setupPriceRegistryReaderTH(t *testing.T) priceRegReaderTH { ec: ec, lggr: lggr, user: user, - sim: sim, readers: map[string]ccipdata.PriceRegistryReader{ ccipdata.V1_0_0: pr10r, ccipdata.V1_2_0: pr12r, }, From 840ba66b09e6189572c6ef7fbeba21a3b94b93ff Mon Sep 17 00:00:00 2001 From: connorwstein Date: Thu, 12 Oct 2023 13:59:40 -0400 Subject: [PATCH 17/24] Improve commit store coverage --- core/chains/evm/logpoller/orm.go | 4 +- .../commit_store_helper_1_0_0.go | 1966 +++++++++++++++++ .../internal/ccipdata/commit_store_reader.go | 1 + .../ccipdata/commit_store_reader_test.go | 119 + 4 files changed, 2088 insertions(+), 2 deletions(-) create mode 100644 core/gethwrappers/ccip/generated/commit_store_helper_1_0_0/commit_store_helper_1_0_0.go diff --git a/core/chains/evm/logpoller/orm.go b/core/chains/evm/logpoller/orm.go index 63810f733e..d51ddaae91 100644 --- a/core/chains/evm/logpoller/orm.go +++ b/core/chains/evm/logpoller/orm.go @@ -283,7 +283,7 @@ func (o *DbORM) SelectLogsCreatedAfter(address common.Address, eventSig common.H WHERE evm_chain_id = $1 AND address = $2 AND event_sig = $3 - AND (block_number + $4) <= (SELECT COALESCE(block_number, 0) FROM evm.log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) + AND block_number <= (SELECT COALESCE(block_number, 0) FROM evm.log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $4 AND block_timestamp > $5 ORDER BY (block_number, log_index)`, utils.NewBig(o.chainID), address, eventSig, confs, after) if err != nil { @@ -552,7 +552,7 @@ func (o *DbORM) SelectIndexedLogsCreatedAfter(address common.Address, eventSig c AND address = $2 AND event_sig = $3 AND topics[$4] = ANY($5) - AND (block_number + $6) <= (SELECT COALESCE(block_number, 0) FROM evm.log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) + AND block_number <= (SELECT COALESCE(block_number, 0) FROM evm.log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $6 AND block_timestamp > $7 ORDER BY (block_number, log_index)`, utils.NewBig(o.chainID), address, eventSig.Bytes(), topicIndex+1, topicValuesBytes, confs, after) if err != nil { diff --git a/core/gethwrappers/ccip/generated/commit_store_helper_1_0_0/commit_store_helper_1_0_0.go b/core/gethwrappers/ccip/generated/commit_store_helper_1_0_0/commit_store_helper_1_0_0.go new file mode 100644 index 0000000000..5a1e15b253 --- /dev/null +++ b/core/gethwrappers/ccip/generated/commit_store_helper_1_0_0/commit_store_helper_1_0_0.go @@ -0,0 +1,1966 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package commit_store_helper_1_0_0 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type CommitStoreCommitReport struct { + PriceUpdates InternalPriceUpdates + Interval CommitStoreInterval + MerkleRoot [32]byte +} + +type CommitStoreDynamicConfig struct { + PriceRegistry common.Address +} + +type CommitStoreInterval struct { + Min uint64 + Max uint64 +} + +type CommitStoreStaticConfig struct { + ChainSelector uint64 + SourceChainSelector uint64 + OnRamp common.Address + ArmProxy common.Address +} + +type InternalPriceUpdates struct { + TokenPriceUpdates []InternalTokenPriceUpdate + DestChainSelector uint64 + UsdPerUnitGas *big.Int +} + +type InternalTokenPriceUpdate struct { + SourceToken common.Address + UsdPerToken *big.Int +} + +var CommitStoreHelperMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCommitStoreConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PausedError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"usdPerToken\",\"type\":\"uint192\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint192\",\"name\":\"usdPerUnitGas\",\"type\":\"uint192\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structCommitStore.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"ReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceEpochAndRound\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUnpausedAndARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"commitReport\",\"type\":\"bytes\"},{\"internalType\":\"uint40\",\"name\":\"epochAndRound\",\"type\":\"uint40\"}],\"name\":\"report\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"rootToReset\",\"type\":\"bytes32[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint40\",\"name\":\"latestPriceEpochAndRound\",\"type\":\"uint40\"}],\"name\":\"setLatestPriceEpochAndRound\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"}],\"name\":\"setMinSeqNr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedLeaves\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x61014060405260098054600165ff000000000160401b03191660011790553480156200002a57600080fd5b5060405162003824380380620038248339810160408190526200004d9162000274565b80600033808281620000a65760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d957620000d98162000194565b50505015156080524660a05260408101516001600160a01b0316158062000108575080516001600160401b0316155b806200011f575060208101516001600160401b0316155b8062000136575060608101516001600160a01b0316155b156200015557604051631fc5f15f60e11b815260040160405180910390fd5b80516001600160401b0390811660c05260208201511660e05260408101516001600160a01b039081166101005260609091015116610120525062000308565b336001600160a01b03821603620001ee5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200009d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160401b03811681146200025757600080fd5b919050565b80516001600160a01b03811681146200025757600080fd5b6000608082840312156200028757600080fd5b604051608081016001600160401b0381118282101715620002b857634e487b7160e01b600052604160045260246000fd5b604052620002c6836200023f565b8152620002d6602084016200023f565b6020820152620002e9604084016200025c565b6040820152620002fc606084016200025c565b60608201529392505050565b60805160a05160c05160e051610100516101205161348d620003976000396000818161027801528181610555015281816111a1015281816119c801528181611a89015261202d01526000818161023c015261200601526000818161020c0152611fdf0152600081816101dc0152611fb001526000818161131c0152611368015260006113e3015261348d6000f3fe608060405234801561001057600080fd5b50600436106101a35760003560e01c80637437ff9f116100ee578063a7206cd611610097578063b1dc65a411610071578063b1dc65a414610505578063f2fde38b14610518578063f47a86901461052b578063ff888fb11461053e57600080fd5b8063a7206cd6146104b2578063ad7a22f8146104d2578063afcb95d7146104e557600080fd5b80638456cb59116100c85780638456cb591461047a5780638da5cb5b146104825780638db94e44146104aa57600080fd5b80637437ff9f1461040357806379ba50971461044257806381ff70481461044a57600080fd5b806329b980e4116101505780634120fccd1161012a5780634120fccd146103c05780635c975abb146103d2578063666cab8d146103ee57600080fd5b806329b980e41461038457806332048875146103975780633f4ba83a146103b857600080fd5b8063181f5a7711610181578063181f5a77146103135780631dc18e561461035c5780631ef381741461037157600080fd5b806306285c69146101a85780630a6cd30d146102cb57806310c374ed146102e3575b600080fd5b6102b560408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b6040516102c29190612688565b60405180910390f35b6102d3610551565b60405190151581526020016102c2565b60095468010000000000000000900464ffffffffff165b60405167ffffffffffffffff90911681526020016102c2565b61034f6040518060400160405280601181526020017f436f6d6d697453746f726520312e302e3000000000000000000000000000000081525081565b6040516102c29190612745565b61036f61036a3660046127bb565b6105e8565b005b61036f61037f366004612a4a565b6105f8565b61036f610392366004612b17565b610e19565b6103aa6103a5366004612b77565b610e65565b6040519081526020016102c2565b61036f610f5b565b60095467ffffffffffffffff166102fa565b6009546d0100000000000000000000000000900460ff166102d3565b6103f6610fc1565b6040516102c29190612c3c565b604080516020808201835260009091528151808201835260085473ffffffffffffffffffffffffffffffffffffffff16908190529151918252016102c2565b61036f611030565b6004546002546040805163ffffffff808516825264010000000090940490931660208401528201526060016102c2565b61036f61112d565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102c2565b6102d361119d565b6103aa6104c0366004612c4f565b6000908152600a602052604090205490565b61036f6104e0366004612c68565b611254565b6040805160018152600060208201819052918101919091526060016102c2565b61036f610513366004612c83565b611297565b61036f610526366004612d3a565b6118b7565b61036f610539366004612d57565b6118cb565b6102d361054c366004612c4f565b611965565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e29190612d99565b15905090565b6105f3838383611a39565b505050565b855185518560ff16601f831115610670576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e6572730000000000000000000000000000000060448201526064015b60405180910390fd5b806000036106da576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610667565b818314610768576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610667565b610773816003612dea565b83116107db576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610667565b6107e3611e4f565b6107ec86611ed2565b60065460005b818110156108e857600560006006838154811061081157610811612e01565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556007805460059291908490811061088157610881612e01565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556108e181612e30565b90506107f2565b50895160005b81811015610cc15760008c828151811061090a5761090a612e01565b602002602001015190506000600281111561092757610927612e68565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff16600281111561096657610966612e68565b146109cd576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610667565b73ffffffffffffffffffffffffffffffffffffffff8116610a1a576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016001905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610aca57610aca612e68565b021790555090505060008c8381518110610ae657610ae6612e01565b6020026020010151905060006002811115610b0357610b03612e68565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff166002811115610b4257610b42612e68565b14610ba9576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610667565b73ffffffffffffffffffffffffffffffffffffffff8116610bf6576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff84168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610ca657610ca6612e68565b0217905550905050505080610cba90612e30565b90506108ee565b508a51610cd59060069060208e01906125ca565b508951610ce99060079060208d01906125ca565b506003805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908c161717905560048054610d6f914691309190600090610d419063ffffffff16612e97565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168e8e8e8e8e8e61208e565b600260000181905550600060048054906101000a900463ffffffff169050436004806101000a81548163ffffffff021916908363ffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600260000154600460009054906101000a900463ffffffff168f8f8f8f8f8f604051610e0399989796959493929190612eba565b60405180910390a1505050505050505050505050565b610e21611e4f565b6009805464ffffffffff90921668010000000000000000027fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff909216919091179055565b6009546000906d0100000000000000000000000000900460ff1615610eb6576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610f2787878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a925089918291850190849080828437600092019190915250889250612139915050565b9050610f3281611965565b610f40576000915050610f52565b6000908152600a602052604090205490505b95945050505050565b610f63611e4f565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b6060600780548060200260200160405190810160405280929190818152602001828054801561102657602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610ffb575b5050505050905090565b60015473ffffffffffffffffffffffffffffffffffffffff1633146110b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610667565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611135611e4f565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff166d01000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610fb7565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561120a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122e9190612d99565b15801561124f57506009546d0100000000000000000000000000900460ff16155b905090565b61125c611e4f565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff92909216919091179055565b6112a6878760208b0135611a39565b6040805160608101825260025480825260035460ff8082166020850152610100909104169282019290925289359182146113195780516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604401610667565b467f00000000000000000000000000000000000000000000000000000000000000001461139a576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610667565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a160007f00000000000000000000000000000000000000000000000000000000000000001561143c5760028260200151836040015161141d9190612f50565b6114279190612f69565b611432906001612f50565b60ff169050611452565b602082015161144c906001612f50565b60ff1690505b86811461148b576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8685146114c4576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526005602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561150757611507612e68565b600281111561151857611518612e68565b905250905060028160200151600281111561153557611535612e68565b14801561157c57506007816000015160ff168154811061155757611557612e01565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b6115b2576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060006115c0866020612dea565b6115cb896020612dea565b6115d78c610144612fb2565b6115e19190612fb2565b6115eb9190612fb2565b905036811461162f576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610667565b5060008a8a604051611642929190612fc5565b604051908190038120611659918e90602001612fd5565b604051602081830303815290604052805190602001209050611679612654565b8860005b818110156118a65760006001858a846020811061169c5761169c612e01565b6116a991901a601b612f50565b8f8f868181106116bb576116bb612e01565b905060200201358e8e878181106116d4576116d4612e01565b9050602002013560405160008152602001604052604051611711949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611733573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152848220848601909552845460ff80821686529397509195509293928401916101009091041660028111156117b6576117b6612e68565b60028111156117c7576117c7612e68565b90525090506001816020015160028111156117e4576117e4612e68565b1461181b576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061183257611832612e01565b60200201511561186e576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061188957611889612e01565b911515602090920201525061189f905081612e30565b905061167d565b505050505050505050505050505050565b6118bf611e4f565b6118c88161245a565b50565b6118d3611e4f565b60005b818110156105f35760008383838181106118f2576118f2612e01565b90506020020135905061190481611965565b611954576000818152600a602052604080822091909155517f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f129061194b9083815260200190565b60405180910390a15b5061195e81612e30565b90506118d6565b6040805180820182523081526020810183815291517f4d616771000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa158015611a0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a339190612d99565b92915050565b6009546d0100000000000000000000000000900460ff1615611a87576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611af2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b169190612d99565b15611b4d576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611b5b8385018561304f565b80515151909150151580611b7d575080516020015167ffffffffffffffff1615155b15611cb55760095464ffffffffff80841668010000000000000000909204161015611c7a57600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff166801000000000000000064ffffffffff85160217905560085481516040517f866548c900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9092169163866548c991611c3491600401613266565b600060405180830381600087803b158015611c4e57600080fd5b505af1158015611c62573d6000803e3d6000fd5b505050506040810151611c755750505050565b611cb5565b6040810151611cb5576040517ff803a2ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101515160095467ffffffffffffffff9081169116141580611cf0575060208082015190810151905167ffffffffffffffff9182169116115b15611d2d5780602001516040517fbb1ae18d0000000000000000000000000000000000000000000000000000000081526004016106679190613279565b6040810151611d68576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040808201516000908152600a602052205415611db1576040517fa0bce24f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808201510151611dc490600161329e565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790556040818101516000908152600a602052819020429055517fe81b49e583122eb290c46fc255c962b9a2dec468816c00fb7a2e6ebc42dc92d490611e419083906132c6565b60405180910390a150505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611ed0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610667565b565b600081806020019051810190611ee89190613322565b805190915073ffffffffffffffffffffffffffffffffffffffff16611f39576040517f3f8be2be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff928316179055600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff169055604080516080810182527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff90811682527f00000000000000000000000000000000000000000000000000000000000000001660208201527f00000000000000000000000000000000000000000000000000000000000000008316818301527f00000000000000000000000000000000000000000000000000000000000000009092166060830152517fc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec39161208291849061336e565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a6040516020016120b2999897969594939291906133eb565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b825182516000919081830361217a576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610101821180159061218e57506101018111155b6121c4576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82820101610100811115612225576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003612252578660008151811061224057612240612e01565b60200260200101519350505050612453565b60008167ffffffffffffffff81111561226d5761226d61280f565b604051908082528060200260200182016040528015612296578160200160208202803683370190505b50905060008080805b858110156123d95760006001821b8b8116036122fa57888510156122e3578c5160018601958e9181106122d4576122d4612e01565b6020026020010151905061231c565b85516001850194879181106122d4576122d4612e01565b8b5160018401938d91811061231157612311612e01565b602002602001015190505b60008986101561234c578d5160018701968f91811061233d5761233d612e01565b6020026020010151905061236e565b865160018601958891811061236357612363612e01565b602002602001015190505b828511156123a8576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6123b2828261254f565b8784815181106123c4576123c4612e01565b6020908102919091010152505060010161229f565b5060018503821480156123eb57508683145b80156123f657508581145b61242c576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83600186038151811061244157612441612e01565b60200260200101519750505050505050505b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036124d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610667565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008183106125915760408051600160208083019190915281830185905260608083018790528351808403909101815260809092019092528051910120612453565b60408051600160208083019190915281830186905260608083018690528351808403909101815260809092019092528051910120612453565b828054828255906000526020600020908101928215612644579160200282015b8281111561264457825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906125ea565b50612650929150612673565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b808211156126505760008155600101612674565b60808101611a33828467ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b6000815180845260005b81811015612707576020818501810151868301820152016126eb565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061245360208301846126e1565b60008083601f84011261276a57600080fd5b50813567ffffffffffffffff81111561278257600080fd5b60208301915083602082850101111561279a57600080fd5b9250929050565b803564ffffffffff811681146127b657600080fd5b919050565b6000806000604084860312156127d057600080fd5b833567ffffffffffffffff8111156127e757600080fd5b6127f386828701612758565b90945092506128069050602085016127a1565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156128615761286161280f565b60405290565b6040516060810167ffffffffffffffff811182821017156128615761286161280f565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156128d1576128d161280f565b604052919050565b600067ffffffffffffffff8211156128f3576128f361280f565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff811681146118c857600080fd5b600082601f83011261293057600080fd5b81356020612945612940836128d9565b61288a565b82815260059290921b8401810191818101908684111561296457600080fd5b8286015b8481101561298857803561297b816128fd565b8352918301918301612968565b509695505050505050565b803560ff811681146127b657600080fd5b600082601f8301126129b557600080fd5b813567ffffffffffffffff8111156129cf576129cf61280f565b612a0060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161288a565b818152846020838601011115612a1557600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff811681146127b657600080fd5b60008060008060008060c08789031215612a6357600080fd5b863567ffffffffffffffff80821115612a7b57600080fd5b612a878a838b0161291f565b97506020890135915080821115612a9d57600080fd5b612aa98a838b0161291f565b9650612ab760408a01612993565b95506060890135915080821115612acd57600080fd5b612ad98a838b016129a4565b9450612ae760808a01612a32565b935060a0890135915080821115612afd57600080fd5b50612b0a89828a016129a4565b9150509295509295509295565b600060208284031215612b2957600080fd5b612453826127a1565b60008083601f840112612b4457600080fd5b50813567ffffffffffffffff811115612b5c57600080fd5b6020830191508360208260051b850101111561279a57600080fd5b600080600080600060608688031215612b8f57600080fd5b853567ffffffffffffffff80821115612ba757600080fd5b612bb389838a01612b32565b90975095506020880135915080821115612bcc57600080fd5b50612bd988828901612b32565b96999598509660400135949350505050565b600081518084526020808501945080840160005b83811015612c3157815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101612bff565b509495945050505050565b6020815260006124536020830184612beb565b600060208284031215612c6157600080fd5b5035919050565b600060208284031215612c7a57600080fd5b61245382612a32565b60008060008060008060008060e0898b031215612c9f57600080fd5b606089018a811115612cb057600080fd5b8998503567ffffffffffffffff80821115612cca57600080fd5b612cd68c838d01612758565b909950975060808b0135915080821115612cef57600080fd5b612cfb8c838d01612b32565b909750955060a08b0135915080821115612d1457600080fd5b50612d218b828c01612b32565b999c989b50969995989497949560c00135949350505050565b600060208284031215612d4c57600080fd5b8135612453816128fd565b60008060208385031215612d6a57600080fd5b823567ffffffffffffffff811115612d8157600080fd5b612d8d85828601612b32565b90969095509350505050565b600060208284031215612dab57600080fd5b8151801515811461245357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417611a3357611a33612dbb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612e6157612e61612dbb565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600063ffffffff808316818103612eb057612eb0612dbb565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152612eea8184018a612beb565b90508281036080840152612efe8189612beb565b905060ff871660a084015282810360c0840152612f1b81876126e1565b905067ffffffffffffffff851660e0840152828103610100840152612f4081856126e1565b9c9b505050505050505050505050565b60ff8181168382160190811115611a3357611a33612dbb565b600060ff831680612fa3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b8060ff84160491505092915050565b80820180821115611a3357611a33612dbb565b8183823760009101908152919050565b828152606082602083013760800192915050565b803577ffffffffffffffffffffffffffffffffffffffffffffffff811681146127b657600080fd5b60006040828403121561302357600080fd5b61302b61283e565b905061303682612a32565b815261304460208301612a32565b602082015292915050565b6000602080838503121561306257600080fd5b823567ffffffffffffffff8082111561307a57600080fd5b908401906080828703121561308e57600080fd5b613096612867565b8235828111156130a557600080fd5b8301606081890312156130b757600080fd5b6130bf612867565b8135848111156130ce57600080fd5b82019350601f840189136130e157600080fd5b83356130ef612940826128d9565b81815260069190911b8501870190878101908b83111561310e57600080fd5b958801955b82871015613162576040878d03121561312c5760008081fd5b61313461283e565b873561313f816128fd565b815261314c888b01612fe9565b818b015282526040969096019590880190613113565b8352506131729050828701612a32565b8682015261318260408301612fe9565b604082015282525061319687848601613011565b93810193909352506060013560408201529392505050565b805160608084528151908401819052600091602091908201906080860190845b81811015613225578351805173ffffffffffffffffffffffffffffffffffffffff16845285015177ffffffffffffffffffffffffffffffffffffffffffffffff1685840152928401926040909201916001016131ce565b505067ffffffffffffffff83860151168387015260408501519250610f52604087018477ffffffffffffffffffffffffffffffffffffffffffffffff169052565b60208152600061245360208301846131ae565b60408101611a338284805167ffffffffffffffff908116835260209182015116910152565b67ffffffffffffffff8181168382160190808211156132bf576132bf612dbb565b5092915050565b6020815260008251608060208401526132e260a08401826131ae565b9050602084015161330d6040850182805167ffffffffffffffff908116835260209182015116910152565b50604084015160808401528091505092915050565b60006020828403121561333457600080fd5b6040516020810181811067ffffffffffffffff821117156133575761335761280f565b6040528251613365816128fd565b81529392505050565b60a081016133c7828567ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b73ffffffffffffffffffffffffffffffffffffffff83511660808301529392505050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526134328285018b612beb565b91508382036080850152613446828a612beb565b915060ff881660a085015283820360c085015261346382886126e1565b90861660e08501528381036101008501529050612f4081856126e156fea164736f6c6343000813000a", +} + +var CommitStoreHelperABI = CommitStoreHelperMetaData.ABI + +var CommitStoreHelperBin = CommitStoreHelperMetaData.Bin + +func DeployCommitStoreHelper(auth *bind.TransactOpts, backend bind.ContractBackend, staticConfig CommitStoreStaticConfig) (common.Address, *types.Transaction, *CommitStoreHelper, error) { + parsed, err := CommitStoreHelperMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(CommitStoreHelperBin), backend, staticConfig) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &CommitStoreHelper{CommitStoreHelperCaller: CommitStoreHelperCaller{contract: contract}, CommitStoreHelperTransactor: CommitStoreHelperTransactor{contract: contract}, CommitStoreHelperFilterer: CommitStoreHelperFilterer{contract: contract}}, nil +} + +type CommitStoreHelper struct { + address common.Address + abi abi.ABI + CommitStoreHelperCaller + CommitStoreHelperTransactor + CommitStoreHelperFilterer +} + +type CommitStoreHelperCaller struct { + contract *bind.BoundContract +} + +type CommitStoreHelperTransactor struct { + contract *bind.BoundContract +} + +type CommitStoreHelperFilterer struct { + contract *bind.BoundContract +} + +type CommitStoreHelperSession struct { + Contract *CommitStoreHelper + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type CommitStoreHelperCallerSession struct { + Contract *CommitStoreHelperCaller + CallOpts bind.CallOpts +} + +type CommitStoreHelperTransactorSession struct { + Contract *CommitStoreHelperTransactor + TransactOpts bind.TransactOpts +} + +type CommitStoreHelperRaw struct { + Contract *CommitStoreHelper +} + +type CommitStoreHelperCallerRaw struct { + Contract *CommitStoreHelperCaller +} + +type CommitStoreHelperTransactorRaw struct { + Contract *CommitStoreHelperTransactor +} + +func NewCommitStoreHelper(address common.Address, backend bind.ContractBackend) (*CommitStoreHelper, error) { + abi, err := abi.JSON(strings.NewReader(CommitStoreHelperABI)) + if err != nil { + return nil, err + } + contract, err := bindCommitStoreHelper(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &CommitStoreHelper{address: address, abi: abi, CommitStoreHelperCaller: CommitStoreHelperCaller{contract: contract}, CommitStoreHelperTransactor: CommitStoreHelperTransactor{contract: contract}, CommitStoreHelperFilterer: CommitStoreHelperFilterer{contract: contract}}, nil +} + +func NewCommitStoreHelperCaller(address common.Address, caller bind.ContractCaller) (*CommitStoreHelperCaller, error) { + contract, err := bindCommitStoreHelper(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &CommitStoreHelperCaller{contract: contract}, nil +} + +func NewCommitStoreHelperTransactor(address common.Address, transactor bind.ContractTransactor) (*CommitStoreHelperTransactor, error) { + contract, err := bindCommitStoreHelper(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &CommitStoreHelperTransactor{contract: contract}, nil +} + +func NewCommitStoreHelperFilterer(address common.Address, filterer bind.ContractFilterer) (*CommitStoreHelperFilterer, error) { + contract, err := bindCommitStoreHelper(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &CommitStoreHelperFilterer{contract: contract}, nil +} + +func bindCommitStoreHelper(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := CommitStoreHelperMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_CommitStoreHelper *CommitStoreHelperRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _CommitStoreHelper.Contract.CommitStoreHelperCaller.contract.Call(opts, result, method, params...) +} + +func (_CommitStoreHelper *CommitStoreHelperRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.CommitStoreHelperTransactor.contract.Transfer(opts) +} + +func (_CommitStoreHelper *CommitStoreHelperRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.CommitStoreHelperTransactor.contract.Transact(opts, method, params...) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _CommitStoreHelper.Contract.contract.Call(opts, result, method, params...) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.contract.Transfer(opts) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.contract.Transact(opts, method, params...) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) GetDynamicConfig(opts *bind.CallOpts) (CommitStoreDynamicConfig, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "getDynamicConfig") + + if err != nil { + return *new(CommitStoreDynamicConfig), err + } + + out0 := *abi.ConvertType(out[0], new(CommitStoreDynamicConfig)).(*CommitStoreDynamicConfig) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) GetDynamicConfig() (CommitStoreDynamicConfig, error) { + return _CommitStoreHelper.Contract.GetDynamicConfig(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) GetDynamicConfig() (CommitStoreDynamicConfig, error) { + return _CommitStoreHelper.Contract.GetDynamicConfig(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) GetExpectedNextSequenceNumber(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "getExpectedNextSequenceNumber") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) GetExpectedNextSequenceNumber() (uint64, error) { + return _CommitStoreHelper.Contract.GetExpectedNextSequenceNumber(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) GetExpectedNextSequenceNumber() (uint64, error) { + return _CommitStoreHelper.Contract.GetExpectedNextSequenceNumber(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) GetLatestPriceEpochAndRound(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "getLatestPriceEpochAndRound") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) GetLatestPriceEpochAndRound() (uint64, error) { + return _CommitStoreHelper.Contract.GetLatestPriceEpochAndRound(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) GetLatestPriceEpochAndRound() (uint64, error) { + return _CommitStoreHelper.Contract.GetLatestPriceEpochAndRound(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) GetMerkleRoot(opts *bind.CallOpts, root [32]byte) (*big.Int, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "getMerkleRoot", root) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) GetMerkleRoot(root [32]byte) (*big.Int, error) { + return _CommitStoreHelper.Contract.GetMerkleRoot(&_CommitStoreHelper.CallOpts, root) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) GetMerkleRoot(root [32]byte) (*big.Int, error) { + return _CommitStoreHelper.Contract.GetMerkleRoot(&_CommitStoreHelper.CallOpts, root) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) GetStaticConfig(opts *bind.CallOpts) (CommitStoreStaticConfig, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "getStaticConfig") + + if err != nil { + return *new(CommitStoreStaticConfig), err + } + + out0 := *abi.ConvertType(out[0], new(CommitStoreStaticConfig)).(*CommitStoreStaticConfig) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) GetStaticConfig() (CommitStoreStaticConfig, error) { + return _CommitStoreHelper.Contract.GetStaticConfig(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) GetStaticConfig() (CommitStoreStaticConfig, error) { + return _CommitStoreHelper.Contract.GetStaticConfig(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "getTransmitters") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) GetTransmitters() ([]common.Address, error) { + return _CommitStoreHelper.Contract.GetTransmitters(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) GetTransmitters() ([]common.Address, error) { + return _CommitStoreHelper.Contract.GetTransmitters(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) IsARMHealthy(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "isARMHealthy") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) IsARMHealthy() (bool, error) { + return _CommitStoreHelper.Contract.IsARMHealthy(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) IsARMHealthy() (bool, error) { + return _CommitStoreHelper.Contract.IsARMHealthy(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) IsBlessed(opts *bind.CallOpts, root [32]byte) (bool, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "isBlessed", root) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) IsBlessed(root [32]byte) (bool, error) { + return _CommitStoreHelper.Contract.IsBlessed(&_CommitStoreHelper.CallOpts, root) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) IsBlessed(root [32]byte) (bool, error) { + return _CommitStoreHelper.Contract.IsBlessed(&_CommitStoreHelper.CallOpts, root) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) IsUnpausedAndARMHealthy(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "isUnpausedAndARMHealthy") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) IsUnpausedAndARMHealthy() (bool, error) { + return _CommitStoreHelper.Contract.IsUnpausedAndARMHealthy(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) IsUnpausedAndARMHealthy() (bool, error) { + return _CommitStoreHelper.Contract.IsUnpausedAndARMHealthy(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "latestConfigDetails") + + outstruct := new(LatestConfigDetails) + if err != nil { + return *outstruct, err + } + + outstruct.ConfigCount = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.BlockNumber = *abi.ConvertType(out[1], new(uint32)).(*uint32) + outstruct.ConfigDigest = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) + + return *outstruct, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _CommitStoreHelper.Contract.LatestConfigDetails(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _CommitStoreHelper.Contract.LatestConfigDetails(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "latestConfigDigestAndEpoch") + + outstruct := new(LatestConfigDigestAndEpoch) + if err != nil { + return *outstruct, err + } + + outstruct.ScanLogs = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.ConfigDigest = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + outstruct.Epoch = *abi.ConvertType(out[2], new(uint32)).(*uint32) + + return *outstruct, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _CommitStoreHelper.Contract.LatestConfigDigestAndEpoch(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _CommitStoreHelper.Contract.LatestConfigDigestAndEpoch(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) Owner() (common.Address, error) { + return _CommitStoreHelper.Contract.Owner(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) Owner() (common.Address, error) { + return _CommitStoreHelper.Contract.Owner(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) Paused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "paused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) Paused() (bool, error) { + return _CommitStoreHelper.Contract.Paused(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) Paused() (bool, error) { + return _CommitStoreHelper.Contract.Paused(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) TypeAndVersion() (string, error) { + return _CommitStoreHelper.Contract.TypeAndVersion(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) TypeAndVersion() (string, error) { + return _CommitStoreHelper.Contract.TypeAndVersion(&_CommitStoreHelper.CallOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperCaller) Verify(opts *bind.CallOpts, hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) { + var out []interface{} + err := _CommitStoreHelper.contract.Call(opts, &out, "verify", hashedLeaves, proofs, proofFlagBits) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_CommitStoreHelper *CommitStoreHelperSession) Verify(hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) { + return _CommitStoreHelper.Contract.Verify(&_CommitStoreHelper.CallOpts, hashedLeaves, proofs, proofFlagBits) +} + +func (_CommitStoreHelper *CommitStoreHelperCallerSession) Verify(hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) { + return _CommitStoreHelper.Contract.Verify(&_CommitStoreHelper.CallOpts, hashedLeaves, proofs, proofFlagBits) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "acceptOwnership") +} + +func (_CommitStoreHelper *CommitStoreHelperSession) AcceptOwnership() (*types.Transaction, error) { + return _CommitStoreHelper.Contract.AcceptOwnership(&_CommitStoreHelper.TransactOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _CommitStoreHelper.Contract.AcceptOwnership(&_CommitStoreHelper.TransactOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) Pause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "pause") +} + +func (_CommitStoreHelper *CommitStoreHelperSession) Pause() (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Pause(&_CommitStoreHelper.TransactOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) Pause() (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Pause(&_CommitStoreHelper.TransactOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) Report(opts *bind.TransactOpts, commitReport []byte, epochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "report", commitReport, epochAndRound) +} + +func (_CommitStoreHelper *CommitStoreHelperSession) Report(commitReport []byte, epochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Report(&_CommitStoreHelper.TransactOpts, commitReport, epochAndRound) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) Report(commitReport []byte, epochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Report(&_CommitStoreHelper.TransactOpts, commitReport, epochAndRound) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) ResetUnblessedRoots(opts *bind.TransactOpts, rootToReset [][32]byte) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "resetUnblessedRoots", rootToReset) +} + +func (_CommitStoreHelper *CommitStoreHelperSession) ResetUnblessedRoots(rootToReset [][32]byte) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.ResetUnblessedRoots(&_CommitStoreHelper.TransactOpts, rootToReset) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) ResetUnblessedRoots(rootToReset [][32]byte) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.ResetUnblessedRoots(&_CommitStoreHelper.TransactOpts, rootToReset) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) SetLatestPriceEpochAndRound(opts *bind.TransactOpts, latestPriceEpochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "setLatestPriceEpochAndRound", latestPriceEpochAndRound) +} + +func (_CommitStoreHelper *CommitStoreHelperSession) SetLatestPriceEpochAndRound(latestPriceEpochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.SetLatestPriceEpochAndRound(&_CommitStoreHelper.TransactOpts, latestPriceEpochAndRound) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) SetLatestPriceEpochAndRound(latestPriceEpochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.SetLatestPriceEpochAndRound(&_CommitStoreHelper.TransactOpts, latestPriceEpochAndRound) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) SetMinSeqNr(opts *bind.TransactOpts, minSeqNr uint64) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "setMinSeqNr", minSeqNr) +} + +func (_CommitStoreHelper *CommitStoreHelperSession) SetMinSeqNr(minSeqNr uint64) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.SetMinSeqNr(&_CommitStoreHelper.TransactOpts, minSeqNr) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) SetMinSeqNr(minSeqNr uint64) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.SetMinSeqNr(&_CommitStoreHelper.TransactOpts, minSeqNr) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) SetOCR2Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "setOCR2Config", signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_CommitStoreHelper *CommitStoreHelperSession) SetOCR2Config(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.SetOCR2Config(&_CommitStoreHelper.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) SetOCR2Config(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.SetOCR2Config(&_CommitStoreHelper.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "transferOwnership", to) +} + +func (_CommitStoreHelper *CommitStoreHelperSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.TransferOwnership(&_CommitStoreHelper.TransactOpts, to) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.TransferOwnership(&_CommitStoreHelper.TransactOpts, to) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "transmit", reportContext, report, rs, ss, rawVs) +} + +func (_CommitStoreHelper *CommitStoreHelperSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Transmit(&_CommitStoreHelper.TransactOpts, reportContext, report, rs, ss, rawVs) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Transmit(&_CommitStoreHelper.TransactOpts, reportContext, report, rs, ss, rawVs) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactor) Unpause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStoreHelper.contract.Transact(opts, "unpause") +} + +func (_CommitStoreHelper *CommitStoreHelperSession) Unpause() (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Unpause(&_CommitStoreHelper.TransactOpts) +} + +func (_CommitStoreHelper *CommitStoreHelperTransactorSession) Unpause() (*types.Transaction, error) { + return _CommitStoreHelper.Contract.Unpause(&_CommitStoreHelper.TransactOpts) +} + +type CommitStoreHelperConfigSetIterator struct { + Event *CommitStoreHelperConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperConfigSetIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperConfigSet struct { + StaticConfig CommitStoreStaticConfig + DynamicConfig CommitStoreDynamicConfig + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterConfigSet(opts *bind.FilterOpts) (*CommitStoreHelperConfigSetIterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &CommitStoreHelperConfigSetIterator{contract: _CommitStoreHelper.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperConfigSet) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperConfigSet) + if err := _CommitStoreHelper.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseConfigSet(log types.Log) (*CommitStoreHelperConfigSet, error) { + event := new(CommitStoreHelperConfigSet) + if err := _CommitStoreHelper.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperConfigSet0Iterator struct { + Event *CommitStoreHelperConfigSet0 + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperConfigSet0Iterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperConfigSet0) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperConfigSet0) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperConfigSet0Iterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperConfigSet0Iterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperConfigSet0 struct { + PreviousConfigBlockNumber uint32 + ConfigDigest [32]byte + ConfigCount uint64 + Signers []common.Address + Transmitters []common.Address + F uint8 + OnchainConfig []byte + OffchainConfigVersion uint64 + OffchainConfig []byte + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterConfigSet0(opts *bind.FilterOpts) (*CommitStoreHelperConfigSet0Iterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "ConfigSet0") + if err != nil { + return nil, err + } + return &CommitStoreHelperConfigSet0Iterator{contract: _CommitStoreHelper.contract, event: "ConfigSet0", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchConfigSet0(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperConfigSet0) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "ConfigSet0") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperConfigSet0) + if err := _CommitStoreHelper.contract.UnpackLog(event, "ConfigSet0", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseConfigSet0(log types.Log) (*CommitStoreHelperConfigSet0, error) { + event := new(CommitStoreHelperConfigSet0) + if err := _CommitStoreHelper.contract.UnpackLog(event, "ConfigSet0", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperOwnershipTransferRequestedIterator struct { + Event *CommitStoreHelperOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreHelperOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &CommitStoreHelperOwnershipTransferRequestedIterator{contract: _CommitStoreHelper.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperOwnershipTransferRequested) + if err := _CommitStoreHelper.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseOwnershipTransferRequested(log types.Log) (*CommitStoreHelperOwnershipTransferRequested, error) { + event := new(CommitStoreHelperOwnershipTransferRequested) + if err := _CommitStoreHelper.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperOwnershipTransferredIterator struct { + Event *CommitStoreHelperOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreHelperOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &CommitStoreHelperOwnershipTransferredIterator{contract: _CommitStoreHelper.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperOwnershipTransferred) + if err := _CommitStoreHelper.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseOwnershipTransferred(log types.Log) (*CommitStoreHelperOwnershipTransferred, error) { + event := new(CommitStoreHelperOwnershipTransferred) + if err := _CommitStoreHelper.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperPausedIterator struct { + Event *CommitStoreHelperPaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperPausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperPausedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperPaused struct { + Account common.Address + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterPaused(opts *bind.FilterOpts) (*CommitStoreHelperPausedIterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "Paused") + if err != nil { + return nil, err + } + return &CommitStoreHelperPausedIterator{contract: _CommitStoreHelper.contract, event: "Paused", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperPaused) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "Paused") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperPaused) + if err := _CommitStoreHelper.contract.UnpackLog(event, "Paused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParsePaused(log types.Log) (*CommitStoreHelperPaused, error) { + event := new(CommitStoreHelperPaused) + if err := _CommitStoreHelper.contract.UnpackLog(event, "Paused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperReportAcceptedIterator struct { + Event *CommitStoreHelperReportAccepted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperReportAcceptedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperReportAccepted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperReportAccepted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperReportAcceptedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperReportAcceptedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperReportAccepted struct { + Report CommitStoreCommitReport + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterReportAccepted(opts *bind.FilterOpts) (*CommitStoreHelperReportAcceptedIterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "ReportAccepted") + if err != nil { + return nil, err + } + return &CommitStoreHelperReportAcceptedIterator{contract: _CommitStoreHelper.contract, event: "ReportAccepted", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchReportAccepted(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperReportAccepted) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "ReportAccepted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperReportAccepted) + if err := _CommitStoreHelper.contract.UnpackLog(event, "ReportAccepted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseReportAccepted(log types.Log) (*CommitStoreHelperReportAccepted, error) { + event := new(CommitStoreHelperReportAccepted) + if err := _CommitStoreHelper.contract.UnpackLog(event, "ReportAccepted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperRootRemovedIterator struct { + Event *CommitStoreHelperRootRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperRootRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperRootRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperRootRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperRootRemovedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperRootRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperRootRemoved struct { + Root [32]byte + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterRootRemoved(opts *bind.FilterOpts) (*CommitStoreHelperRootRemovedIterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "RootRemoved") + if err != nil { + return nil, err + } + return &CommitStoreHelperRootRemovedIterator{contract: _CommitStoreHelper.contract, event: "RootRemoved", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchRootRemoved(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperRootRemoved) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "RootRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperRootRemoved) + if err := _CommitStoreHelper.contract.UnpackLog(event, "RootRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseRootRemoved(log types.Log) (*CommitStoreHelperRootRemoved, error) { + event := new(CommitStoreHelperRootRemoved) + if err := _CommitStoreHelper.contract.UnpackLog(event, "RootRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperTransmittedIterator struct { + Event *CommitStoreHelperTransmitted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperTransmittedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperTransmittedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperTransmittedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperTransmitted struct { + ConfigDigest [32]byte + Epoch uint32 + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterTransmitted(opts *bind.FilterOpts) (*CommitStoreHelperTransmittedIterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return &CommitStoreHelperTransmittedIterator{contract: _CommitStoreHelper.contract, event: "Transmitted", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperTransmitted) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperTransmitted) + if err := _CommitStoreHelper.contract.UnpackLog(event, "Transmitted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseTransmitted(log types.Log) (*CommitStoreHelperTransmitted, error) { + event := new(CommitStoreHelperTransmitted) + if err := _CommitStoreHelper.contract.UnpackLog(event, "Transmitted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreHelperUnpausedIterator struct { + Event *CommitStoreHelperUnpaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreHelperUnpausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreHelperUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreHelperUnpausedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreHelperUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreHelperUnpaused struct { + Account common.Address + Raw types.Log +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) FilterUnpaused(opts *bind.FilterOpts) (*CommitStoreHelperUnpausedIterator, error) { + + logs, sub, err := _CommitStoreHelper.contract.FilterLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return &CommitStoreHelperUnpausedIterator{contract: _CommitStoreHelper.contract, event: "Unpaused", logs: logs, sub: sub}, nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperUnpaused) (event.Subscription, error) { + + logs, sub, err := _CommitStoreHelper.contract.WatchLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreHelperUnpaused) + if err := _CommitStoreHelper.contract.UnpackLog(event, "Unpaused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStoreHelper *CommitStoreHelperFilterer) ParseUnpaused(log types.Log) (*CommitStoreHelperUnpaused, error) { + event := new(CommitStoreHelperUnpaused) + if err := _CommitStoreHelper.contract.UnpackLog(event, "Unpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LatestConfigDetails struct { + ConfigCount uint32 + BlockNumber uint32 + ConfigDigest [32]byte +} +type LatestConfigDigestAndEpoch struct { + ScanLogs bool + ConfigDigest [32]byte + Epoch uint32 +} + +func (_CommitStoreHelper *CommitStoreHelper) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _CommitStoreHelper.abi.Events["ConfigSet"].ID: + return _CommitStoreHelper.ParseConfigSet(log) + case _CommitStoreHelper.abi.Events["ConfigSet0"].ID: + return _CommitStoreHelper.ParseConfigSet0(log) + case _CommitStoreHelper.abi.Events["OwnershipTransferRequested"].ID: + return _CommitStoreHelper.ParseOwnershipTransferRequested(log) + case _CommitStoreHelper.abi.Events["OwnershipTransferred"].ID: + return _CommitStoreHelper.ParseOwnershipTransferred(log) + case _CommitStoreHelper.abi.Events["Paused"].ID: + return _CommitStoreHelper.ParsePaused(log) + case _CommitStoreHelper.abi.Events["ReportAccepted"].ID: + return _CommitStoreHelper.ParseReportAccepted(log) + case _CommitStoreHelper.abi.Events["RootRemoved"].ID: + return _CommitStoreHelper.ParseRootRemoved(log) + case _CommitStoreHelper.abi.Events["Transmitted"].ID: + return _CommitStoreHelper.ParseTransmitted(log) + case _CommitStoreHelper.abi.Events["Unpaused"].ID: + return _CommitStoreHelper.ParseUnpaused(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (CommitStoreHelperConfigSet) Topic() common.Hash { + return common.HexToHash("0xc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec3") +} + +func (CommitStoreHelperConfigSet0) Topic() common.Hash { + return common.HexToHash("0x1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05") +} + +func (CommitStoreHelperOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (CommitStoreHelperOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (CommitStoreHelperPaused) Topic() common.Hash { + return common.HexToHash("0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258") +} + +func (CommitStoreHelperReportAccepted) Topic() common.Hash { + return common.HexToHash("0xe81b49e583122eb290c46fc255c962b9a2dec468816c00fb7a2e6ebc42dc92d4") +} + +func (CommitStoreHelperRootRemoved) Topic() common.Hash { + return common.HexToHash("0x202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12") +} + +func (CommitStoreHelperTransmitted) Topic() common.Hash { + return common.HexToHash("0xb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62") +} + +func (CommitStoreHelperUnpaused) Topic() common.Hash { + return common.HexToHash("0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa") +} + +func (_CommitStoreHelper *CommitStoreHelper) Address() common.Address { + return _CommitStoreHelper.address +} + +type CommitStoreHelperInterface interface { + GetDynamicConfig(opts *bind.CallOpts) (CommitStoreDynamicConfig, error) + + GetExpectedNextSequenceNumber(opts *bind.CallOpts) (uint64, error) + + GetLatestPriceEpochAndRound(opts *bind.CallOpts) (uint64, error) + + GetMerkleRoot(opts *bind.CallOpts, root [32]byte) (*big.Int, error) + + GetStaticConfig(opts *bind.CallOpts) (CommitStoreStaticConfig, error) + + GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) + + IsARMHealthy(opts *bind.CallOpts) (bool, error) + + IsBlessed(opts *bind.CallOpts, root [32]byte) (bool, error) + + IsUnpausedAndARMHealthy(opts *bind.CallOpts) (bool, error) + + LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) + + LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + Paused(opts *bind.CallOpts) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + Verify(opts *bind.CallOpts, hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + Pause(opts *bind.TransactOpts) (*types.Transaction, error) + + Report(opts *bind.TransactOpts, commitReport []byte, epochAndRound *big.Int) (*types.Transaction, error) + + ResetUnblessedRoots(opts *bind.TransactOpts, rootToReset [][32]byte) (*types.Transaction, error) + + SetLatestPriceEpochAndRound(opts *bind.TransactOpts, latestPriceEpochAndRound *big.Int) (*types.Transaction, error) + + SetMinSeqNr(opts *bind.TransactOpts, minSeqNr uint64) (*types.Transaction, error) + + SetOCR2Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) + + Unpause(opts *bind.TransactOpts) (*types.Transaction, error) + + FilterConfigSet(opts *bind.FilterOpts) (*CommitStoreHelperConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*CommitStoreHelperConfigSet, error) + + FilterConfigSet0(opts *bind.FilterOpts) (*CommitStoreHelperConfigSet0Iterator, error) + + WatchConfigSet0(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperConfigSet0) (event.Subscription, error) + + ParseConfigSet0(log types.Log) (*CommitStoreHelperConfigSet0, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreHelperOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*CommitStoreHelperOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreHelperOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*CommitStoreHelperOwnershipTransferred, error) + + FilterPaused(opts *bind.FilterOpts) (*CommitStoreHelperPausedIterator, error) + + WatchPaused(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperPaused) (event.Subscription, error) + + ParsePaused(log types.Log) (*CommitStoreHelperPaused, error) + + FilterReportAccepted(opts *bind.FilterOpts) (*CommitStoreHelperReportAcceptedIterator, error) + + WatchReportAccepted(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperReportAccepted) (event.Subscription, error) + + ParseReportAccepted(log types.Log) (*CommitStoreHelperReportAccepted, error) + + FilterRootRemoved(opts *bind.FilterOpts) (*CommitStoreHelperRootRemovedIterator, error) + + WatchRootRemoved(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperRootRemoved) (event.Subscription, error) + + ParseRootRemoved(log types.Log) (*CommitStoreHelperRootRemoved, error) + + FilterTransmitted(opts *bind.FilterOpts) (*CommitStoreHelperTransmittedIterator, error) + + WatchTransmitted(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperTransmitted) (event.Subscription, error) + + ParseTransmitted(log types.Log) (*CommitStoreHelperTransmitted, error) + + FilterUnpaused(opts *bind.FilterOpts) (*CommitStoreHelperUnpausedIterator, error) + + WatchUnpaused(opts *bind.WatchOpts, sink chan<- *CommitStoreHelperUnpaused) (event.Subscription, error) + + ParseUnpaused(log types.Log) (*CommitStoreHelperUnpaused, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader.go index 49c02ff7b2..30a5a16e57 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader.go @@ -90,6 +90,7 @@ func NewCommitStoreReader(lggr logger.Logger, address common.Address, ec client. } switch version.String() { case V1_0_0, V1_1_0: + // Versions are identical return NewCommitStoreV1_0_0(lggr, address, ec, lp, estimator) case V1_2_0: return NewCommitStoreV1_2_0(lggr, address, ec, lp, estimator) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go index 9961de281f..6323e36591 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go @@ -1,18 +1,29 @@ package ccipdata_test import ( + "context" "math/big" "math/rand" + "reflect" "testing" "time" "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" + gasmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" lpmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_helper" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_helper_1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" @@ -160,3 +171,111 @@ func TestCommitOnchainConfig(t *testing.T) { }) } } + +func TestCommitStoreReaders(t *testing.T) { + user, ec := newSim(t) + lggr := logger.TestLogger(t) + lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.SimulatedChainID, pgtest.NewSqlxDB(t), lggr, pgtest.NewQConfig(true)), ec, lggr, 100*time.Millisecond, 2, 3, 2, 1000) + + // Deploy 2 commit store versions + onramp1 := randomAddress() + onramp2 := randomAddress() + // Report + rep := ccipdata.CommitStoreReport{ + TokenPrices: []ccipdata.TokenPrice{{Token: randomAddress(), Value: big.NewInt(1)}}, + GasPrices: []ccipdata.GasPrice{{DestChainSelector: 1, Value: big.NewInt(1)}}, + Interval: ccipdata.CommitStoreInterval{Min: 1, Max: 10}, + MerkleRoot: common.HexToHash("0x1"), + } + er := big.NewInt(1) + armAddr, _, arm, err := mock_arm_contract.DeployMockARMContract(user, ec) + require.NoError(t, err) + addr, _, ch, err := commit_store_helper_1_0_0.DeployCommitStoreHelper(user, ec, commit_store_helper_1_0_0.CommitStoreStaticConfig{ + ChainSelector: testutils.SimulatedChainID.Uint64(), + SourceChainSelector: testutils.SimulatedChainID.Uint64(), + OnRamp: onramp1, + ArmProxy: armAddr, + }) + require.NoError(t, err) + addr2, _, ch2, err := commit_store_helper.DeployCommitStoreHelper(user, ec, commit_store_helper.CommitStoreStaticConfig{ + ChainSelector: testutils.SimulatedChainID.Uint64(), + SourceChainSelector: testutils.SimulatedChainID.Uint64(), + OnRamp: onramp2, + ArmProxy: armAddr, + }) + require.NoError(t, err) + commitAndGetBlockTs(ec) // Deploy these + pr, _, _, err := price_registry_1_0_0.DeployPriceRegistry(user, ec, []common.Address{addr}, nil, 1e6) + require.NoError(t, err) + pr2, _, _, err := price_registry.DeployPriceRegistry(user, ec, []common.Address{addr2}, nil, 1e6) + require.NoError(t, err) + commitAndGetBlockTs(ec) // Deploy these + ge := new(gasmocks.EvmFeeEstimator) + c10r, err := ccipdata.NewCommitStoreReader(lggr, addr, ec, lp, ge) + require.NoError(t, err) + assert.Equal(t, reflect.TypeOf(c10r).String(), reflect.TypeOf(&ccipdata.CommitStoreV1_0_0{}).String()) + c12r, err := ccipdata.NewCommitStoreReader(lggr, addr2, ec, lp, ge) + require.NoError(t, err) + assert.Equal(t, reflect.TypeOf(c12r).String(), reflect.TypeOf(&ccipdata.CommitStoreV1_2_0{}).String()) + + // Apply config + signers := []common.Address{randomAddress(), randomAddress(), randomAddress(), randomAddress()} + transmitters := []common.Address{randomAddress(), randomAddress(), randomAddress(), randomAddress()} + onchainConfig, err := abihelpers.EncodeAbiStruct[ccipdata.CommitOnchainConfig](ccipdata.CommitOnchainConfig{ + PriceRegistry: pr, + }) + _, err = ch.SetOCR2Config(user, signers, transmitters, 1, onchainConfig, 1, []byte{}) + require.NoError(t, err) + onchainConfig2, err := abihelpers.EncodeAbiStruct[ccipdata.CommitOnchainConfig](ccipdata.CommitOnchainConfig{ + PriceRegistry: pr2, + }) + _, err = ch2.SetOCR2Config(user, signers, transmitters, 1, onchainConfig2, 1, []byte{}) + require.NoError(t, err) + commitAndGetBlockTs(ec) + + // Apply report + b, err := c10r.EncodeCommitReport(rep) + require.NoError(t, err) + _, err = ch.Report(user, b, er) + require.NoError(t, err) + b, err = c12r.EncodeCommitReport(rep) + require.NoError(t, err) + _, err = ch2.Report(user, b, er) + require.NoError(t, err) + commitAndGetBlockTs(ec) + + // Capture all logs. + lp.PollAndSaveLogs(context.Background(), 1) + + for _, cr := range []ccipdata.CommitStoreReader{c10r, c12r} { + // Assert encoding + b, err := cr.EncodeCommitReport(rep) + require.NoError(t, err) + d, err := cr.DecodeCommitReport(b) + require.NoError(t, err) + assert.Equal(t, d.Interval.Max, rep.Interval.Max) + + // Assert reading + latest, err := cr.GetLatestPriceEpochAndRound(context.Background()) + require.NoError(t, err) + assert.Equal(t, er.Uint64(), latest) + + // Assert cursing + down, err := cr.IsDown(context.Background()) + require.NoError(t, err) + assert.False(t, down) + _, err = arm.VoteToCurse(user, [32]byte{}) + require.NoError(t, err) + ec.Commit() + down, err = cr.IsDown(context.Background()) + require.NoError(t, err) + assert.True(t, down) + _, err = arm.OwnerUnvoteToCurse(user, nil) + require.NoError(t, err) + ec.Commit() + + seqNr, err := cr.GetExpectedNextSequenceNumber(context.Background()) + require.NoError(t, err) + assert.Equal(t, rep.Interval.Max+1, seqNr) + } +} From 38430021118c15f306c2012de1ae7d2b7f5b0434 Mon Sep 17 00:00:00 2001 From: connorwstein Date: Thu, 12 Oct 2023 14:37:23 -0400 Subject: [PATCH 18/24] Test ChangeConfig and fix bug --- core/chains/evm/logpoller/log_poller_test.go | 2 +- .../internal/ccipdata/commit_store_reader.go | 2 +- .../ccipdata/commit_store_reader_test.go | 122 ++++++++++++++---- .../internal/ccipdata/commit_store_v1_0_0.go | 2 + .../internal/ccipdata/commit_store_v1_2_0.go | 2 + 5 files changed, 101 insertions(+), 29 deletions(-) diff --git a/core/chains/evm/logpoller/log_poller_test.go b/core/chains/evm/logpoller/log_poller_test.go index f6be57aa6e..a3f11cb6dc 100644 --- a/core/chains/evm/logpoller/log_poller_test.go +++ b/core/chains/evm/logpoller/log_poller_test.go @@ -1166,7 +1166,7 @@ func Test_CreatedAfterQueriesWithBackfill(t *testing.T) { // Emit some logs in blocks for i := 0; i < emittedLogs; i++ { - _, err := th.Emitter1.EmitLog1(th.Owner, []*big.Int{big.NewInt(int64(i))}) + _, err = th.Emitter1.EmitLog1(th.Owner, []*big.Int{big.NewInt(int64(i))}) require.NoError(t, err) th.Client.Commit() } diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader.go index 30a5a16e57..0629f8d926 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader.go @@ -68,7 +68,7 @@ type CommitStoreReader interface { Closer GetExpectedNextSequenceNumber(context context.Context) (uint64, error) GetLatestPriceEpochAndRound(context context.Context) (uint64, error) - // GetAcceptedCommitReportsGteSeqNum returns all the accepted commit reports that have sequence number greater than or equal to the provided. + // GetAcceptedCommitReportsGteSeqNum returns all the accepted commit reports that have max sequence number greater than or equal to the provided. GetAcceptedCommitReportsGteSeqNum(ctx context.Context, seqNum uint64, confs int) ([]Event[CommitStoreReport], error) // GetAcceptedCommitReportsGteTimestamp returns all the commit reports with timestamp greater than or equal to the provided. GetAcceptedCommitReportsGteTimestamp(ctx context.Context, ts time.Time, confs int) ([]Event[CommitStoreReport], error) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go index 6323e36591..f3c825c51a 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go @@ -15,6 +15,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" gasmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/mocks" + rollupMocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" lpmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_helper" @@ -224,11 +225,40 @@ func TestCommitStoreReaders(t *testing.T) { onchainConfig, err := abihelpers.EncodeAbiStruct[ccipdata.CommitOnchainConfig](ccipdata.CommitOnchainConfig{ PriceRegistry: pr, }) + + commonOffchain := ccipdata.CommitOffchainConfig{ + SourceFinalityDepth: 1, + GasPriceDeviationPPB: 1e6, + GasPriceHeartBeat: 1 * time.Hour, + TokenPriceDeviationPPB: 1e6, + TokenPriceHeartBeat: 1 * time.Hour, + InflightCacheExpiry: 3 * time.Hour, + DestFinalityDepth: 2, + } + offchainConfig, err := ccipconfig.EncodeOffchainConfig[ccipdata.CommitOffchainConfigV1_0_0](ccipdata.CommitOffchainConfigV1_0_0{ + SourceFinalityDepth: commonOffchain.SourceFinalityDepth, + DestFinalityDepth: commonOffchain.DestFinalityDepth, + FeeUpdateHeartBeat: models.MustMakeDuration(commonOffchain.GasPriceHeartBeat), + FeeUpdateDeviationPPB: commonOffchain.GasPriceDeviationPPB, + MaxGasPrice: 1e9, + InflightCacheExpiry: models.MustMakeDuration(commonOffchain.InflightCacheExpiry), + }) _, err = ch.SetOCR2Config(user, signers, transmitters, 1, onchainConfig, 1, []byte{}) require.NoError(t, err) onchainConfig2, err := abihelpers.EncodeAbiStruct[ccipdata.CommitOnchainConfig](ccipdata.CommitOnchainConfig{ PriceRegistry: pr2, }) + offchainConfig2, err := ccipconfig.EncodeOffchainConfig[ccipdata.CommitOffchainConfigV1_2_0](ccipdata.CommitOffchainConfigV1_2_0{ + SourceFinalityDepth: commonOffchain.SourceFinalityDepth, + DestFinalityDepth: commonOffchain.DestFinalityDepth, + MaxGasPrice: 1e9, + GasPriceHeartBeat: models.MustMakeDuration(commonOffchain.GasPriceHeartBeat), + DAGasPriceDeviationPPB: 1e7, + ExecGasPriceDeviationPPB: commonOffchain.GasPriceDeviationPPB, + TokenPriceDeviationPPB: commonOffchain.TokenPriceDeviationPPB, + TokenPriceHeartBeat: models.MustMakeDuration(commonOffchain.TokenPriceHeartBeat), + InflightCacheExpiry: models.MustMakeDuration(commonOffchain.InflightCacheExpiry), + }) _, err = ch2.SetOCR2Config(user, signers, transmitters, 1, onchainConfig2, 1, []byte{}) require.NoError(t, err) commitAndGetBlockTs(ec) @@ -247,35 +277,73 @@ func TestCommitStoreReaders(t *testing.T) { // Capture all logs. lp.PollAndSaveLogs(context.Background(), 1) - for _, cr := range []ccipdata.CommitStoreReader{c10r, c12r} { - // Assert encoding - b, err := cr.EncodeCommitReport(rep) - require.NoError(t, err) - d, err := cr.DecodeCommitReport(b) - require.NoError(t, err) - assert.Equal(t, d.Interval.Max, rep.Interval.Max) + configs := map[string][][]byte{ + ccipdata.V1_0_0: {onchainConfig, offchainConfig}, + ccipdata.V1_2_0: {onchainConfig2, offchainConfig2}, + } + crs := map[string]ccipdata.CommitStoreReader{ + ccipdata.V1_0_0: c10r, + ccipdata.V1_2_0: c12r, + } + prs := map[string]common.Address{ + ccipdata.V1_0_0: pr, + ccipdata.V1_2_0: pr2, + } + lm := new(rollupMocks.L1Oracle) + ge.On("L1Oracle").Return(lm) + for v, cr := range crs { + cr := cr + t.Run("CommitStoreReader "+v, func(t *testing.T) { + // Assert encoding + b, err := cr.EncodeCommitReport(rep) + require.NoError(t, err) + d, err := cr.DecodeCommitReport(b) + require.NoError(t, err) + assert.Equal(t, d, rep) - // Assert reading - latest, err := cr.GetLatestPriceEpochAndRound(context.Background()) - require.NoError(t, err) - assert.Equal(t, er.Uint64(), latest) + // Assert reading + latest, err := cr.GetLatestPriceEpochAndRound(context.Background()) + require.NoError(t, err) + assert.Equal(t, er.Uint64(), latest) - // Assert cursing - down, err := cr.IsDown(context.Background()) - require.NoError(t, err) - assert.False(t, down) - _, err = arm.VoteToCurse(user, [32]byte{}) - require.NoError(t, err) - ec.Commit() - down, err = cr.IsDown(context.Background()) - require.NoError(t, err) - assert.True(t, down) - _, err = arm.OwnerUnvoteToCurse(user, nil) - require.NoError(t, err) - ec.Commit() + // Assert cursing + down, err := cr.IsDown(context.Background()) + require.NoError(t, err) + assert.False(t, down) + _, err = arm.VoteToCurse(user, [32]byte{}) + require.NoError(t, err) + ec.Commit() + down, err = cr.IsDown(context.Background()) + require.NoError(t, err) + assert.True(t, down) + _, err = arm.OwnerUnvoteToCurse(user, nil) + require.NoError(t, err) + ec.Commit() - seqNr, err := cr.GetExpectedNextSequenceNumber(context.Background()) - require.NoError(t, err) - assert.Equal(t, rep.Interval.Max+1, seqNr) + seqNr, err := cr.GetExpectedNextSequenceNumber(context.Background()) + require.NoError(t, err) + assert.Equal(t, rep.Interval.Max+1, seqNr) + + reps, err := cr.GetAcceptedCommitReportsGteSeqNum(context.Background(), rep.Interval.Max+1, 0) + require.NoError(t, err) + assert.Len(t, reps, 0) + + reps, err = cr.GetAcceptedCommitReportsGteSeqNum(context.Background(), rep.Interval.Max, 0) + require.NoError(t, err) + require.Len(t, reps, 1) + assert.Equal(t, reps[0].Data, rep) + + reps, err = cr.GetAcceptedCommitReportsGteSeqNum(context.Background(), rep.Interval.Min-1, 0) + require.NoError(t, err) + require.Len(t, reps, 1) + assert.Equal(t, reps[0].Data, rep) + + // Until we detect the config, we'll have empty offchain config + assert.Equal(t, cr.OffchainConfig(), ccipdata.CommitOffchainConfig{}) + newPr, err := cr.ChangeConfig(configs[v][0], configs[v][1]) + require.NoError(t, err) + assert.Equal(t, newPr, prs[v]) + assert.Equal(t, commonOffchain, cr.OffchainConfig()) + }) } } diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_0_0.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_0_0.go index 64b8d063b3..3c250bedf2 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_0_0.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_0_0.go @@ -210,6 +210,8 @@ func (c *CommitStoreV1_0_0) ChangeConfig(onchainConfig []byte, offchainConfig [] c.offchainConfig = CommitOffchainConfig{ SourceFinalityDepth: offchainConfigV1.SourceFinalityDepth, GasPriceDeviationPPB: offchainConfigV1.FeeUpdateDeviationPPB, + GasPriceHeartBeat: offchainConfigV1.FeeUpdateHeartBeat.Duration(), + TokenPriceHeartBeat: offchainConfigV1.FeeUpdateHeartBeat.Duration(), TokenPriceDeviationPPB: offchainConfigV1.FeeUpdateDeviationPPB, InflightCacheExpiry: offchainConfigV1.InflightCacheExpiry.Duration(), DestFinalityDepth: offchainConfigV1.DestFinalityDepth, diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_2_0.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_2_0.go index 915b18b302..f78ebc74d2 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_2_0.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_2_0.go @@ -220,7 +220,9 @@ func (c *CommitStoreV1_2_0) ChangeConfig(onchainConfig []byte, offchainConfig [] c.offchainConfig = CommitOffchainConfig{ SourceFinalityDepth: offchainConfigParsed.SourceFinalityDepth, GasPriceDeviationPPB: offchainConfigParsed.ExecGasPriceDeviationPPB, + GasPriceHeartBeat: offchainConfigParsed.GasPriceHeartBeat.Duration(), TokenPriceDeviationPPB: offchainConfigParsed.TokenPriceDeviationPPB, + TokenPriceHeartBeat: offchainConfigParsed.TokenPriceHeartBeat.Duration(), InflightCacheExpiry: offchainConfigParsed.InflightCacheExpiry.Duration(), DestFinalityDepth: offchainConfigParsed.DestFinalityDepth, } From 926ce5d376ea17fa7b45519908ba95932e60fcb0 Mon Sep 17 00:00:00 2001 From: connorwstein Date: Thu, 12 Oct 2023 14:54:08 -0400 Subject: [PATCH 19/24] Finish commit store sanity --- .../ccipdata/commit_store_reader_test.go | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go index f3c825c51a..1f3eb3903d 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go @@ -2,6 +2,7 @@ package ccipdata_test import ( "context" + "fmt" "math/big" "math/rand" "reflect" @@ -13,7 +14,9 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink/v2/core/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" gasmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/mocks" rollupMocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" @@ -225,6 +228,7 @@ func TestCommitStoreReaders(t *testing.T) { onchainConfig, err := abihelpers.EncodeAbiStruct[ccipdata.CommitOnchainConfig](ccipdata.CommitOnchainConfig{ PriceRegistry: pr, }) + require.NoError(t, err) commonOffchain := ccipdata.CommitOffchainConfig{ SourceFinalityDepth: 1, @@ -235,12 +239,13 @@ func TestCommitStoreReaders(t *testing.T) { InflightCacheExpiry: 3 * time.Hour, DestFinalityDepth: 2, } + maxGas := uint64(1e9) offchainConfig, err := ccipconfig.EncodeOffchainConfig[ccipdata.CommitOffchainConfigV1_0_0](ccipdata.CommitOffchainConfigV1_0_0{ SourceFinalityDepth: commonOffchain.SourceFinalityDepth, DestFinalityDepth: commonOffchain.DestFinalityDepth, FeeUpdateHeartBeat: models.MustMakeDuration(commonOffchain.GasPriceHeartBeat), FeeUpdateDeviationPPB: commonOffchain.GasPriceDeviationPPB, - MaxGasPrice: 1e9, + MaxGasPrice: maxGas, InflightCacheExpiry: models.MustMakeDuration(commonOffchain.InflightCacheExpiry), }) _, err = ch.SetOCR2Config(user, signers, transmitters, 1, onchainConfig, 1, []byte{}) @@ -248,10 +253,11 @@ func TestCommitStoreReaders(t *testing.T) { onchainConfig2, err := abihelpers.EncodeAbiStruct[ccipdata.CommitOnchainConfig](ccipdata.CommitOnchainConfig{ PriceRegistry: pr2, }) + require.NoError(t, err) offchainConfig2, err := ccipconfig.EncodeOffchainConfig[ccipdata.CommitOffchainConfigV1_2_0](ccipdata.CommitOffchainConfigV1_2_0{ SourceFinalityDepth: commonOffchain.SourceFinalityDepth, DestFinalityDepth: commonOffchain.DestFinalityDepth, - MaxGasPrice: 1e9, + MaxGasPrice: maxGas, GasPriceHeartBeat: models.MustMakeDuration(commonOffchain.GasPriceHeartBeat), DAGasPriceDeviationPPB: 1e7, ExecGasPriceDeviationPPB: commonOffchain.GasPriceDeviationPPB, @@ -259,6 +265,7 @@ func TestCommitStoreReaders(t *testing.T) { TokenPriceHeartBeat: models.MustMakeDuration(commonOffchain.TokenPriceHeartBeat), InflightCacheExpiry: models.MustMakeDuration(commonOffchain.InflightCacheExpiry), }) + require.NoError(t, err) _, err = ch2.SetOCR2Config(user, signers, transmitters, 1, onchainConfig2, 1, []byte{}) require.NoError(t, err) commitAndGetBlockTs(ec) @@ -289,8 +296,17 @@ func TestCommitStoreReaders(t *testing.T) { ccipdata.V1_0_0: pr, ccipdata.V1_2_0: pr2, } + gasPrice := big.NewInt(10) + daPrice := big.NewInt(20) + expectedGas := map[string]string{ + ccipdata.V1_0_0: gasPrice.String(), + ccipdata.V1_2_0: fmt.Sprintf("DA Price: %s, Exec Price: %s", daPrice, gasPrice), + } + ge.On("GetFee", mock.Anything, mock.Anything, mock.Anything, assets.NewWei(big.NewInt(int64(maxGas)))).Return(gas.EvmFee{Legacy: assets.NewWei(gasPrice)}, uint32(0), nil) lm := new(rollupMocks.L1Oracle) + lm.On("GasPrice", mock.Anything).Return(assets.NewWei(daPrice), nil) ge.On("L1Oracle").Return(lm) + for v, cr := range crs { cr := cr t.Run("CommitStoreReader "+v, func(t *testing.T) { @@ -344,6 +360,10 @@ func TestCommitStoreReaders(t *testing.T) { require.NoError(t, err) assert.Equal(t, newPr, prs[v]) assert.Equal(t, commonOffchain, cr.OffchainConfig()) + // We should be able to query for gas prices now. + gp, err := cr.GasPriceEstimator().GetGasPrice(context.Background()) + require.NoError(t, err) + assert.Equal(t, expectedGas[v], cr.GasPriceEstimator().String(gp)) }) } } From 6acfd780c3dbd09b865800960fdb3f6add8cb8a9 Mon Sep 17 00:00:00 2001 From: connorwstein Date: Thu, 12 Oct 2023 15:10:21 -0400 Subject: [PATCH 20/24] Few more todos --- .../ccip/internal/ccipdata/commit_store_reader_test.go | 7 +++++++ .../ccip/internal/ccipdata/offramp_reader_v1_0_0_test.go | 4 ++-- .../ccip/internal/ccipdata/offramp_reader_v1_2_0_test.go | 4 ++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go index 1f3eb3903d..93a0c44572 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go @@ -248,6 +248,7 @@ func TestCommitStoreReaders(t *testing.T) { MaxGasPrice: maxGas, InflightCacheExpiry: models.MustMakeDuration(commonOffchain.InflightCacheExpiry), }) + require.NoError(t, err) _, err = ch.SetOCR2Config(user, signers, transmitters, 1, onchainConfig, 1, []byte{}) require.NoError(t, err) onchainConfig2, err := abihelpers.EncodeAbiStruct[ccipdata.CommitOnchainConfig](ccipdata.CommitOnchainConfig{ @@ -354,6 +355,12 @@ func TestCommitStoreReaders(t *testing.T) { require.Len(t, reps, 1) assert.Equal(t, reps[0].Data, rep) + // Sanity + reps, err = cr.GetAcceptedCommitReportsGteTimestamp(context.Background(), time.Unix(0, 0), 0) + require.NoError(t, err) + require.Len(t, reps, 1) + assert.Equal(t, reps[0].Data, rep) + // Until we detect the config, we'll have empty offchain config assert.Equal(t, cr.OffchainConfig(), ccipdata.CommitOffchainConfig{}) newPr, err := cr.ChangeConfig(configs[v][0], configs[v][1]) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_v1_0_0_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_v1_0_0_test.go index 599121f22b..00585a90b3 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_v1_0_0_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_v1_0_0_test.go @@ -21,7 +21,7 @@ func TestExecutionReportEncodingV100(t *testing.T) { // but I think that would essentially be testing geth's abi library // as our encode/decode is a thin wrapper around that. report := ccipdata.ExecReport{ - Messages: []internal.EVM2EVMMessage{}, + Messages: []internal.EVM2EVMMessage(nil), OffchainTokenData: [][][]byte{{}}, Proofs: [][32]byte{testutils.Random32Byte()}, ProofFlagBits: big.NewInt(133), @@ -37,7 +37,7 @@ func TestExecutionReportEncodingV100(t *testing.T) { decodeCommitReport, err := offRamp.DecodeExecutionReport(encodeExecutionReport) require.NoError(t, err) require.Equal(t, report.Proofs, decodeCommitReport.Proofs) - // require.Equal(t, report, decodeCommitReport) // TODO: fails because some fields are not supported on V1_0_0 + require.Equal(t, report, decodeCommitReport) } func TestOffRampFiltersV100(t *testing.T) { diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_v1_2_0_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_v1_2_0_test.go index 4a823fa15a..c3e0b9e03b 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_v1_2_0_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_v1_2_0_test.go @@ -21,7 +21,7 @@ func TestExecutionReportEncodingV120(t *testing.T) { // but I think that would essentially be testing geth's abi library // as our encode/decode is a thin wrapper around that. report := ccipdata.ExecReport{ - Messages: []internal.EVM2EVMMessage{}, + Messages: []internal.EVM2EVMMessage(nil), OffchainTokenData: [][][]byte{{}}, Proofs: [][32]byte{testutils.Random32Byte()}, ProofFlagBits: big.NewInt(133), @@ -37,7 +37,7 @@ func TestExecutionReportEncodingV120(t *testing.T) { decodeCommitReport, err := offRamp.DecodeExecutionReport(encodeExecutionReport) require.NoError(t, err) require.Equal(t, report.Proofs, decodeCommitReport.Proofs) - // require.Equal(t, report, decodeCommitReport) // TODO: fails because some fields are not supported on v1_0_0 + require.Equal(t, report, decodeCommitReport) } func TestOffRampFiltersV120(t *testing.T) { From 5a24c7a3ead9c132370d82b62209a568139bbf41 Mon Sep 17 00:00:00 2001 From: connorwstein Date: Fri, 13 Oct 2023 10:51:33 -0400 Subject: [PATCH 21/24] Comments --- core/chains/evm/logpoller/orm.go | 21 ------------------- .../plugins/ccip/commit_reporting_plugin.go | 4 ++-- .../ccip/commit_reporting_plugin_test.go | 16 +++++++------- .../ccip/execution_reporting_plugin_test.go | 4 ++-- .../internal/ccipdata/commit_store_reader.go | 20 ++++++++++++++++++ .../ccipdata/commit_store_reader_test.go | 18 +++++++--------- .../internal/ccipdata/commit_store_v1_0_0.go | 17 +++++++-------- .../ccipdata/commit_store_v1_0_0_test.go | 7 +------ .../internal/ccipdata/commit_store_v1_2_0.go | 18 ++++++++-------- .../ccipdata/commit_store_v1_2_0_test.go | 2 +- .../internal/ccipdata/offramp_reader_test.go | 9 ++++---- .../ccipdata/offramp_reader_v1_0_0_test.go | 5 +++-- .../ccipdata/offramp_reader_v1_2_0_test.go | 5 +++-- .../ccip/internal/ccipdata/offramp_v1_0_0.go | 2 +- .../ccip/internal/ccipdata/offramp_v1_2_0.go | 2 +- .../ccipdata/price_registry_reader.go | 6 ++---- .../ccipdata/price_registry_reader_test.go | 15 ++++++------- .../ccipdata/price_registry_v1_0_0.go | 6 +++--- .../ccipdata/price_registry_v1_2_0.go | 12 +++-------- 19 files changed, 87 insertions(+), 102 deletions(-) diff --git a/core/chains/evm/logpoller/orm.go b/core/chains/evm/logpoller/orm.go index d51ddaae91..39597ef025 100644 --- a/core/chains/evm/logpoller/orm.go +++ b/core/chains/evm/logpoller/orm.go @@ -616,27 +616,6 @@ func (o *DbORM) SelectIndexedLogsWithSigsExcluding(sigA, sigB common.Hash, topic return logs, nil } -func (o *DbORM) blocksRangeAfterTimestamp(after time.Time, confs int, qopts ...pg.QOpt) (int64, int64, error) { - type blockRange struct { - MinBlockNumber int64 `db:"min_block"` - MaxBlockNumber int64 `db:"max_block"` - } - - var br blockRange - q := o.q.WithOpts(qopts...) - err := q.Get(&br, ` - SELECT - coalesce(min(block_number), 0) as min_block, - coalesce(max(block_number), 0) as max_block - FROM evm.log_poller_blocks - WHERE evm_chain_id = $1 - AND block_timestamp > $2`, utils.NewBig(o.chainID), after) - if err != nil { - return 0, 0, err - } - return br.MinBlockNumber, br.MaxBlockNumber - int64(confs), nil -} - type bytesProducer interface { Bytes() []byte } diff --git a/core/services/ocr2/plugins/ccip/commit_reporting_plugin.go b/core/services/ocr2/plugins/ccip/commit_reporting_plugin.go index bb24464574..3dd5f8748e 100644 --- a/core/services/ocr2/plugins/ccip/commit_reporting_plugin.go +++ b/core/services/ocr2/plugins/ccip/commit_reporting_plugin.go @@ -373,7 +373,7 @@ func (r *CommitReportingPlugin) getLatestTokenPriceUpdates(ctx context.Context, for _, tokenUpdate := range tokenPriceUpdates { priceUpdate := tokenUpdate.Data // Ordered by ascending timestamps - timestamp := time.Unix(priceUpdate.Timestamp.Int64(), 0) + timestamp := time.Unix(priceUpdate.TimestampUnixSec.Int64(), 0) if priceUpdate.Value != nil && !timestamp.Before(latestUpdates[priceUpdate.Token].timestamp) { latestUpdates[priceUpdate.Token] = update{ timestamp: timestamp, @@ -426,7 +426,7 @@ func (r *CommitReportingPlugin) getLatestGasPriceUpdate(ctx context.Context, now for _, priceUpdate := range gasPriceUpdates { // Ordered by ascending timestamps - timestamp := time.Unix(priceUpdate.Data.Timestamp.Int64(), 0) + timestamp := time.Unix(priceUpdate.Data.TimestampUnixSec.Int64(), 0) if !timestamp.Before(gasUpdate.timestamp) { gasUpdate = update{ timestamp: timestamp, diff --git a/core/services/ocr2/plugins/ccip/commit_reporting_plugin_test.go b/core/services/ocr2/plugins/ccip/commit_reporting_plugin_test.go index 7d71b3d7ca..4517d39979 100644 --- a/core/services/ocr2/plugins/ccip/commit_reporting_plugin_test.go +++ b/core/services/ocr2/plugins/ccip/commit_reporting_plugin_test.go @@ -217,7 +217,7 @@ func TestCommitReportingPlugin_Report(t *testing.T) { DestChainSelector: sourceChainSelector, Value: big.NewInt(1), }, - Timestamp: big.NewInt(time.Now().Add(-2 * gasPriceHeartBeat.Duration()).Unix()), + TimestampUnixSec: big.NewInt(time.Now().Add(-2 * gasPriceHeartBeat.Duration()).Unix()), }, }, }, @@ -243,7 +243,7 @@ func TestCommitReportingPlugin_Report(t *testing.T) { DestChainSelector: sourceChainSelector, Value: big.NewInt(1), }, - Timestamp: big.NewInt(time.Now().Add(-gasPriceHeartBeat.Duration() / 2).Unix()), + TimestampUnixSec: big.NewInt(time.Now().Add(-gasPriceHeartBeat.Duration() / 2).Unix()), }, }, }, @@ -1408,8 +1408,8 @@ func TestCommitReportingPlugin_getLatestGasPriceUpdate(t *testing.T) { for _, u := range tc.destGasPriceUpdates { events = append(events, ccipdata.Event[ccipdata.GasPriceUpdate]{ Data: ccipdata.GasPriceUpdate{ - GasPrice: ccipdata.GasPrice{Value: u.value}, - Timestamp: big.NewInt(u.timestamp.Unix()), + GasPrice: ccipdata.GasPrice{Value: u.value}, + TimestampUnixSec: big.NewInt(u.timestamp.Unix()), }, }) } @@ -1452,14 +1452,14 @@ func TestCommitReportingPlugin_getLatestTokenPriceUpdates(t *testing.T) { Token: tk1, Value: big.NewInt(1000), }, - Timestamp: big.NewInt(now.Add(1 * time.Minute).Unix()), + TimestampUnixSec: big.NewInt(now.Add(1 * time.Minute).Unix()), }, { TokenPrice: ccipdata.TokenPrice{ Token: tk2, Value: big.NewInt(2000), }, - Timestamp: big.NewInt(now.Add(2 * time.Minute).Unix()), + TimestampUnixSec: big.NewInt(now.Add(2 * time.Minute).Unix()), }, }, checkInflight: false, @@ -1477,14 +1477,14 @@ func TestCommitReportingPlugin_getLatestTokenPriceUpdates(t *testing.T) { Token: tk1, Value: big.NewInt(1000), }, - Timestamp: big.NewInt(now.Add(1 * time.Minute).Unix()), + TimestampUnixSec: big.NewInt(now.Add(1 * time.Minute).Unix()), }, { TokenPrice: ccipdata.TokenPrice{ Token: tk2, Value: big.NewInt(2000), }, - Timestamp: big.NewInt(now.Add(2 * time.Minute).Unix()), + TimestampUnixSec: big.NewInt(now.Add(2 * time.Minute).Unix()), }, }, checkInflight: true, diff --git a/core/services/ocr2/plugins/ccip/execution_reporting_plugin_test.go b/core/services/ocr2/plugins/ccip/execution_reporting_plugin_test.go index 38c5d9b16c..369e31833b 100644 --- a/core/services/ocr2/plugins/ccip/execution_reporting_plugin_test.go +++ b/core/services/ocr2/plugins/ccip/execution_reporting_plugin_test.go @@ -142,12 +142,12 @@ func TestExecutionReportingPlugin_Observation(t *testing.T) { destPriceRegReader := ccipdata.NewMockPriceRegistryReader(t) destPriceRegReader.On("GetTokenPrices", ctx, mock.Anything).Return( - []ccipdata.TokenPriceUpdate{{TokenPrice: ccipdata.TokenPrice{Token: common.HexToAddress("0x1"), Value: big.NewInt(123)}, Timestamp: big.NewInt(time.Now().Unix())}}, nil).Maybe() + []ccipdata.TokenPriceUpdate{{TokenPrice: ccipdata.TokenPrice{Token: common.HexToAddress("0x1"), Value: big.NewInt(123)}, TimestampUnixSec: big.NewInt(time.Now().Unix())}}, nil).Maybe() destPriceRegReader.On("Address").Return(utils.RandomAddress()).Maybe() sourcePriceRegReader := ccipdata.NewMockPriceRegistryReader(t) sourcePriceRegReader.On("Address").Return(utils.RandomAddress()).Maybe() sourcePriceRegReader.On("GetTokenPrices", ctx, mock.Anything).Return( - []ccipdata.TokenPriceUpdate{{TokenPrice: ccipdata.TokenPrice{Token: common.HexToAddress("0x1"), Value: big.NewInt(123)}, Timestamp: big.NewInt(time.Now().Unix())}}, nil).Maybe() + []ccipdata.TokenPriceUpdate{{TokenPrice: ccipdata.TokenPrice{Token: common.HexToAddress("0x1"), Value: big.NewInt(123)}, TimestampUnixSec: big.NewInt(time.Now().Unix())}}, nil).Maybe() p.destPriceRegistry = destPriceRegReader p.config.sourcePriceRegistry = sourcePriceRegReader diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader.go index 0629f8d926..0c191eba26 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader.go @@ -63,6 +63,26 @@ type CommitOffchainConfig struct { DestFinalityDepth uint32 } +func NewCommitOffchainConfig( + sourceFinalityDepth uint32, + gasPriceDeviationPPB uint32, + gasPriceHeartBeat time.Duration, + tokenPriceDeviationPPB uint32, + tokenPriceHeartBeat time.Duration, + inflightCacheExpiry time.Duration, + destFinalityDepth uint32, +) CommitOffchainConfig { + return CommitOffchainConfig{ + SourceFinalityDepth: sourceFinalityDepth, + GasPriceDeviationPPB: gasPriceDeviationPPB, + GasPriceHeartBeat: gasPriceHeartBeat, + TokenPriceDeviationPPB: tokenPriceDeviationPPB, + TokenPriceHeartBeat: tokenPriceHeartBeat, + InflightCacheExpiry: inflightCacheExpiry, + DestFinalityDepth: destFinalityDepth, + } +} + //go:generate mockery --quiet --name CommitStoreReader --output . --filename commit_store_reader_mock.go --inpackage --case=underscore type CommitStoreReader interface { Closer diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go index 93a0c44572..714602c5c9 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "math/big" - "math/rand" "reflect" "testing" "time" @@ -33,6 +32,7 @@ import ( ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" "github.com/smartcontractkit/chainlink/v2/core/store/models" + "github.com/smartcontractkit/chainlink/v2/core/utils" ) func assertFilterRegistration(t *testing.T, lp *lpmocks.LogPoller, buildCloser func(lp *lpmocks.LogPoller, addr common.Address) ccipdata.Closer, numFilter int) { @@ -137,10 +137,6 @@ func TestCommitOffchainConfig_Encoding(t *testing.T) { } } -func randomAddress() common.Address { - return common.BigToAddress(big.NewInt(rand.Int63())) -} - func TestCommitOnchainConfig(t *testing.T) { tests := []struct { name string @@ -150,7 +146,7 @@ func TestCommitOnchainConfig(t *testing.T) { { name: "encodes and decodes config with all fields set", want: ccipdata.CommitOnchainConfig{ - PriceRegistry: randomAddress(), + PriceRegistry: utils.RandomAddress(), }, expectErr: false, }, @@ -182,11 +178,11 @@ func TestCommitStoreReaders(t *testing.T) { lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.SimulatedChainID, pgtest.NewSqlxDB(t), lggr, pgtest.NewQConfig(true)), ec, lggr, 100*time.Millisecond, 2, 3, 2, 1000) // Deploy 2 commit store versions - onramp1 := randomAddress() - onramp2 := randomAddress() + onramp1 := utils.RandomAddress() + onramp2 := utils.RandomAddress() // Report rep := ccipdata.CommitStoreReport{ - TokenPrices: []ccipdata.TokenPrice{{Token: randomAddress(), Value: big.NewInt(1)}}, + TokenPrices: []ccipdata.TokenPrice{{Token: utils.RandomAddress(), Value: big.NewInt(1)}}, GasPrices: []ccipdata.GasPrice{{DestChainSelector: 1, Value: big.NewInt(1)}}, Interval: ccipdata.CommitStoreInterval{Min: 1, Max: 10}, MerkleRoot: common.HexToHash("0x1"), @@ -223,8 +219,8 @@ func TestCommitStoreReaders(t *testing.T) { assert.Equal(t, reflect.TypeOf(c12r).String(), reflect.TypeOf(&ccipdata.CommitStoreV1_2_0{}).String()) // Apply config - signers := []common.Address{randomAddress(), randomAddress(), randomAddress(), randomAddress()} - transmitters := []common.Address{randomAddress(), randomAddress(), randomAddress(), randomAddress()} + signers := []common.Address{utils.RandomAddress(), utils.RandomAddress(), utils.RandomAddress(), utils.RandomAddress()} + transmitters := []common.Address{utils.RandomAddress(), utils.RandomAddress(), utils.RandomAddress(), utils.RandomAddress()} onchainConfig, err := abihelpers.EncodeAbiStruct[ccipdata.CommitOnchainConfig](ccipdata.CommitOnchainConfig{ PriceRegistry: pr, }) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_0_0.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_0_0.go index 3c250bedf2..4b94ff48f9 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_0_0.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_0_0.go @@ -207,15 +207,14 @@ func (c *CommitStoreV1_0_0) ChangeConfig(onchainConfig []byte, offchainConfig [] c.estimator, big.NewInt(int64(offchainConfigV1.MaxGasPrice)), int64(offchainConfigV1.FeeUpdateDeviationPPB)) - c.offchainConfig = CommitOffchainConfig{ - SourceFinalityDepth: offchainConfigV1.SourceFinalityDepth, - GasPriceDeviationPPB: offchainConfigV1.FeeUpdateDeviationPPB, - GasPriceHeartBeat: offchainConfigV1.FeeUpdateHeartBeat.Duration(), - TokenPriceHeartBeat: offchainConfigV1.FeeUpdateHeartBeat.Duration(), - TokenPriceDeviationPPB: offchainConfigV1.FeeUpdateDeviationPPB, - InflightCacheExpiry: offchainConfigV1.InflightCacheExpiry.Duration(), - DestFinalityDepth: offchainConfigV1.DestFinalityDepth, - } + c.offchainConfig = NewCommitOffchainConfig( + offchainConfigV1.SourceFinalityDepth, + offchainConfigV1.FeeUpdateDeviationPPB, + offchainConfigV1.FeeUpdateHeartBeat.Duration(), + offchainConfigV1.FeeUpdateDeviationPPB, + offchainConfigV1.FeeUpdateHeartBeat.Duration(), + offchainConfigV1.InflightCacheExpiry.Duration(), + offchainConfigV1.DestFinalityDepth) c.configMu.Unlock() c.lggr.Infow("ChangeConfig", "offchainConfig", offchainConfigV1, diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_0_0_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_0_0_test.go index be500b74d4..302f700f43 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_0_0_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_0_0_test.go @@ -5,7 +5,6 @@ import ( "math/rand" "testing" - "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -15,10 +14,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/utils" ) -func randomAddress() common.Address { - return common.BigToAddress(big.NewInt(rand.Int63())) -} - func TestCommitReportEncodingV1_0_0(t *testing.T) { report := CommitStoreReport{ TokenPrices: []TokenPrice{ @@ -40,7 +35,7 @@ func TestCommitReportEncodingV1_0_0(t *testing.T) { lp := mocks.NewLogPoller(t) lp.On("RegisterFilter", mock.Anything).Return(nil) - c, err := NewCommitStoreV1_0_0(logger.TestLogger(t), randomAddress(), nil, lp, nil) + c, err := NewCommitStoreV1_0_0(logger.TestLogger(t), utils.RandomAddress(), nil, lp, nil) assert.NoError(t, err) encodedReport, err := c.EncodeCommitReport(report) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_2_0.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_2_0.go index f78ebc74d2..0db5c00bf7 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_2_0.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_2_0.go @@ -217,15 +217,15 @@ func (c *CommitStoreV1_2_0) ChangeConfig(onchainConfig []byte, offchainConfig [] int64(offchainConfigParsed.ExecGasPriceDeviationPPB), int64(offchainConfigParsed.DAGasPriceDeviationPPB), ) - c.offchainConfig = CommitOffchainConfig{ - SourceFinalityDepth: offchainConfigParsed.SourceFinalityDepth, - GasPriceDeviationPPB: offchainConfigParsed.ExecGasPriceDeviationPPB, - GasPriceHeartBeat: offchainConfigParsed.GasPriceHeartBeat.Duration(), - TokenPriceDeviationPPB: offchainConfigParsed.TokenPriceDeviationPPB, - TokenPriceHeartBeat: offchainConfigParsed.TokenPriceHeartBeat.Duration(), - InflightCacheExpiry: offchainConfigParsed.InflightCacheExpiry.Duration(), - DestFinalityDepth: offchainConfigParsed.DestFinalityDepth, - } + c.offchainConfig = NewCommitOffchainConfig( + offchainConfigParsed.SourceFinalityDepth, + offchainConfigParsed.ExecGasPriceDeviationPPB, + offchainConfigParsed.GasPriceHeartBeat.Duration(), + offchainConfigParsed.TokenPriceDeviationPPB, + offchainConfigParsed.TokenPriceHeartBeat.Duration(), + offchainConfigParsed.InflightCacheExpiry.Duration(), + offchainConfigParsed.DestFinalityDepth, + ) c.configMu.Unlock() c.lggr.Infow("ChangeConfig", diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_2_0_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_2_0_test.go index ff1ecff9fb..2ed606c989 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_2_0_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_2_0_test.go @@ -43,7 +43,7 @@ func TestCommitReportEncodingV_1_2_0(t *testing.T) { lp := mocks.NewLogPoller(t) lp.On("RegisterFilter", mock.Anything).Return(nil) - c, err := NewCommitStoreV1_2_0(logger.TestLogger(t), randomAddress(), nil, lp, nil) + c, err := NewCommitStoreV1_2_0(logger.TestLogger(t), utils.RandomAddress(), nil, lp, nil) assert.NoError(t, err) encodedReport, err := c.EncodeCommitReport(report) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go index 2082531a07..0b8dbaa16d 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go @@ -15,6 +15,7 @@ import ( ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" "github.com/smartcontractkit/chainlink/v2/core/store/models" + "github.com/smartcontractkit/chainlink/v2/core/utils" ) func TestOffRampFilters(t *testing.T) { @@ -99,8 +100,8 @@ func TestExecOnchainConfig100(t *testing.T) { name: "encodes and decodes config with all fields set", want: ccipdata.ExecOnchainConfigV1_0_0{ PermissionLessExecutionThresholdSeconds: rand.Uint32(), - Router: randomAddress(), - PriceRegistry: randomAddress(), + Router: utils.RandomAddress(), + PriceRegistry: utils.RandomAddress(), MaxTokensLength: uint16(rand.Uint32()), MaxDataSize: rand.Uint32(), }, @@ -140,8 +141,8 @@ func TestExecOnchainConfig120(t *testing.T) { name: "encodes and decodes config with all fields set", want: ccipdata.ExecOnchainConfigV1_2_0{ PermissionLessExecutionThresholdSeconds: rand.Uint32(), - Router: randomAddress(), - PriceRegistry: randomAddress(), + Router: utils.RandomAddress(), + PriceRegistry: utils.RandomAddress(), MaxTokensLength: uint16(rand.Uint32()), MaxDataSize: rand.Uint32(), MaxPoolGas: rand.Uint32(), diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_v1_0_0_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_v1_0_0_test.go index 00585a90b3..34f48b5b97 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_v1_0_0_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_v1_0_0_test.go @@ -14,6 +14,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/utils" ) func TestExecutionReportEncodingV100(t *testing.T) { @@ -21,7 +22,7 @@ func TestExecutionReportEncodingV100(t *testing.T) { // but I think that would essentially be testing geth's abi library // as our encode/decode is a thin wrapper around that. report := ccipdata.ExecReport{ - Messages: []internal.EVM2EVMMessage(nil), + Messages: []internal.EVM2EVMMessage{}, OffchainTokenData: [][][]byte{{}}, Proofs: [][32]byte{testutils.Random32Byte()}, ProofFlagBits: big.NewInt(133), @@ -29,7 +30,7 @@ func TestExecutionReportEncodingV100(t *testing.T) { lp := lpmocks.NewLogPoller(t) lp.On("RegisterFilter", mock.Anything).Return(nil) - offRamp, err := ccipdata.NewOffRampV1_0_0(logger.TestLogger(t), randomAddress(), nil, lp, nil) + offRamp, err := ccipdata.NewOffRampV1_0_0(logger.TestLogger(t), utils.RandomAddress(), nil, lp, nil) require.NoError(t, err) encodeExecutionReport, err := offRamp.EncodeExecutionReport(report) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_v1_2_0_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_v1_2_0_test.go index c3e0b9e03b..b0c45ec562 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_v1_2_0_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_v1_2_0_test.go @@ -14,6 +14,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/utils" ) func TestExecutionReportEncodingV120(t *testing.T) { @@ -21,7 +22,7 @@ func TestExecutionReportEncodingV120(t *testing.T) { // but I think that would essentially be testing geth's abi library // as our encode/decode is a thin wrapper around that. report := ccipdata.ExecReport{ - Messages: []internal.EVM2EVMMessage(nil), + Messages: []internal.EVM2EVMMessage{}, OffchainTokenData: [][][]byte{{}}, Proofs: [][32]byte{testutils.Random32Byte()}, ProofFlagBits: big.NewInt(133), @@ -29,7 +30,7 @@ func TestExecutionReportEncodingV120(t *testing.T) { lp := lpmocks.NewLogPoller(t) lp.On("RegisterFilter", mock.Anything).Return(nil) - offRamp, err := ccipdata.NewOffRampV1_2_0(logger.TestLogger(t), randomAddress(), nil, lp, nil) + offRamp, err := ccipdata.NewOffRampV1_2_0(logger.TestLogger(t), utils.RandomAddress(), nil, lp, nil) require.NoError(t, err) encodeExecutionReport, err := offRamp.EncodeExecutionReport(report) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_v1_0_0.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_v1_0_0.go index 194bfb5c56..71a7f9283f 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_v1_0_0.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_v1_0_0.go @@ -281,7 +281,7 @@ func decodeExecReportV1_0_0(args abi.Arguments, report []byte) (ExecReport, erro if !ok { return ExecReport{}, fmt.Errorf("got %T", unpacked[0]) } - var messages []internal.EVM2EVMMessage + messages := []internal.EVM2EVMMessage{} for _, msg := range erStruct.Messages { var tokensAndAmounts []internal.TokenAmount for _, tokenAndAmount := range msg.TokenAmounts { diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_v1_2_0.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_v1_2_0.go index c0cd3df8bc..4fc65d712b 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_v1_2_0.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_v1_2_0.go @@ -214,7 +214,7 @@ func decodeExecReportV1_2_0(args abi.Arguments, report []byte) (ExecReport, erro if !ok { return ExecReport{}, fmt.Errorf("got %T", unpacked[0]) } - var messages []internal.EVM2EVMMessage + messages := []internal.EVM2EVMMessage{} for _, msg := range erStruct.Messages { var tokensAndAmounts []internal.TokenAmount for _, tokenAndAmount := range msg.TokenAmounts { diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go index a214c55fa4..4b67772d6f 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go @@ -30,8 +30,7 @@ type TokenPrice struct { type TokenPriceUpdate struct { TokenPrice - // Unix time stamp in seconds. - Timestamp *big.Int + TimestampUnixSec *big.Int } type GasPrice struct { @@ -41,8 +40,7 @@ type GasPrice struct { type GasPriceUpdate struct { GasPrice - // Unix time stamp in seconds - Timestamp *big.Int + TimestampUnixSec *big.Int } //go:generate mockery --quiet --name PriceRegistryReader --output . --filename price_registry_reader_mock.go --inpackage --case=underscore diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go index 75634e0bc1..6a75d2c24d 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go @@ -24,6 +24,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/utils" ) func TestPriceRegistryFilters(t *testing.T) { @@ -83,7 +84,7 @@ func setupPriceRegistryReaderTH(t *testing.T) priceRegReaderTH { // TODO: We should be able to use an in memory log poller ORM here to speed up the tests. lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.SimulatedChainID, pgtest.NewSqlxDB(t), lggr, pgtest.NewQConfig(true)), ec, lggr, 100*time.Millisecond, 2, 3, 2, 1000) - feeTokens := []common.Address{randomAddress(), randomAddress()} + feeTokens := []common.Address{utils.RandomAddress(), utils.RandomAddress()} dest := uint64(10) gasPriceUpdatesBlock1 := []ccipdata.GasPrice{ { @@ -93,12 +94,12 @@ func setupPriceRegistryReaderTH(t *testing.T) priceRegReaderTH { } gasPriceUpdatesBlock2 := []ccipdata.GasPrice{ { - DestChainSelector: dest, // Reset same gas price - Value: big.NewInt(12), + DestChainSelector: dest, // Reset same gas price + Value: big.NewInt(12), // Intentionally different from block1 }, } - token1 := randomAddress() - token2 := randomAddress() + token1 := utils.RandomAddress() + token2 := utils.RandomAddress() tokenPriceUpdatesBlock1 := []ccipdata.TokenPrice{ { Token: token1, @@ -108,11 +109,11 @@ func setupPriceRegistryReaderTH(t *testing.T) priceRegReaderTH { tokenPriceUpdatesBlock2 := []ccipdata.TokenPrice{ { Token: token1, - Value: big.NewInt(13), + Value: big.NewInt(13), // Intentionally change token1 value }, { Token: token2, - Value: big.NewInt(12), + Value: big.NewInt(12), // Intentionally set a same value different token }, } addr, _, _, err := price_registry_1_0_0.DeployPriceRegistry(user, ec, nil, feeTokens, 1000) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_0_0.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_0_0.go index cef60630f6..083a307c00 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_0_0.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_0_0.go @@ -56,7 +56,7 @@ func (p *PriceRegistryV1_0_0) GetTokenPrices(ctx context.Context, wantedTokens [ Token: wantedTokens[i], Value: tp.Value, }, - Timestamp: big.NewInt(int64(tp.Timestamp)), + TimestampUnixSec: big.NewInt(int64(tp.Timestamp)), }) } return tpu, nil @@ -99,7 +99,7 @@ func (p *PriceRegistryV1_0_0) GetTokenPriceUpdatesCreatedAfter(ctx context.Conte Token: tp.Token, Value: tp.Value, }, - Timestamp: tp.Timestamp, + TimestampUnixSec: tp.Timestamp, }, nil }, ) @@ -132,7 +132,7 @@ func (p *PriceRegistryV1_0_0) GetGasPriceUpdatesCreatedAfter(ctx context.Context DestChainSelector: p.DestChain, Value: p.Value, }, - Timestamp: p.Timestamp, + TimestampUnixSec: p.Timestamp, }, nil }, ) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_2_0.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_2_0.go index 6a6c88d784..a5f334f091 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_2_0.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_2_0.go @@ -13,7 +13,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/observability" ) @@ -21,12 +20,6 @@ var ( _ PriceRegistryReader = &PriceRegistryV1_2_0{} ) -func init() { - if abihelpers.MustGetEventID("UsdPerUnitGasUpdated", abihelpers.MustParseABI(price_registry.PriceRegistryABI)) != UsdPerUnitGasUpdatedV1_0_0 { - panic("UsdPerUnitGasUpdatedV1_0_0 must be the same as UsdPerUnitGasUpdated") - } -} - type PriceRegistryV1_2_0 struct { *PriceRegistryV1_0_0 obs *observability.ObservedPriceRegistryV1_2_0 @@ -47,7 +40,8 @@ func NewPriceRegistryV1_2_0(lggr logger.Logger, priceRegistryAddr common.Address }, nil } -// GetTokenPrices must be overridden to use the 1.2 ABI (return parameter changed from uint192 to uint224. +// GetTokenPrices must be overridden to use the 1.2 ABI (return parameter changed from uint192 to uint224) +// See https://github.com/smartcontractkit/ccip/blob/ccip-develop/contracts/src/v0.8/ccip/PriceRegistry.sol#L141 func (p *PriceRegistryV1_2_0) GetTokenPrices(ctx context.Context, wantedTokens []common.Address) ([]TokenPriceUpdate, error) { // Make call using 224 ABI. tps, err := p.obs.GetTokenPrices(&bind.CallOpts{Context: ctx}, wantedTokens) @@ -61,7 +55,7 @@ func (p *PriceRegistryV1_2_0) GetTokenPrices(ctx context.Context, wantedTokens [ Token: wantedTokens[i], Value: tp.Value, }, - Timestamp: big.NewInt(int64(tp.Timestamp)), + TimestampUnixSec: big.NewInt(int64(tp.Timestamp)), }) } return tpu, nil From 0548c014ab7c0137ff560381f2c8405f00a97782 Mon Sep 17 00:00:00 2001 From: connorwstein Date: Fri, 13 Oct 2023 11:13:42 -0400 Subject: [PATCH 22/24] Fmt --- .../plugins/ccip/internal/ccipdata/offramp_reader_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go index b9ca16349d..c8ad6759f9 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go @@ -143,9 +143,9 @@ func TestExecOnchainConfig120(t *testing.T) { PermissionLessExecutionThresholdSeconds: rand.Uint32(), Router: utils.RandomAddress(), PriceRegistry: utils.RandomAddress(), - MaxNumberOfTokensPerMsg: uint16(rand.Uint32()), - MaxDataBytes: rand.Uint32(), - MaxPoolReleaseOrMintGas: rand.Uint32(), + MaxNumberOfTokensPerMsg: uint16(rand.Uint32()), + MaxDataBytes: rand.Uint32(), + MaxPoolReleaseOrMintGas: rand.Uint32(), }, }, { From 8fce78575a1ae1b0ebbf30bdd888f933ab159361 Mon Sep 17 00:00:00 2001 From: connorwstein Date: Fri, 13 Oct 2023 12:59:26 -0400 Subject: [PATCH 23/24] Fix merge conflicts --- .../ccipdata/price_registry_v1_2_0.go | 9 ++- .../observability/price_registry_v1_0_0.go | 55 ------------------- .../observability/price_registry_v1_2_0.go | 37 ------------- 3 files changed, 4 insertions(+), 97 deletions(-) delete mode 100644 core/services/ocr2/plugins/ccip/internal/observability/price_registry_v1_0_0.go delete mode 100644 core/services/ocr2/plugins/ccip/internal/observability/price_registry_v1_2_0.go diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_2_0.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_2_0.go index a5f334f091..341dfccfcb 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_2_0.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_2_0.go @@ -13,7 +13,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/observability" ) var ( @@ -22,7 +21,7 @@ var ( type PriceRegistryV1_2_0 struct { *PriceRegistryV1_0_0 - obs *observability.ObservedPriceRegistryV1_2_0 + pr *price_registry.PriceRegistry } func NewPriceRegistryV1_2_0(lggr logger.Logger, priceRegistryAddr common.Address, lp logpoller.LogPoller, ec client.Client) (*PriceRegistryV1_2_0, error) { @@ -30,13 +29,13 @@ func NewPriceRegistryV1_2_0(lggr logger.Logger, priceRegistryAddr common.Address if err != nil { return nil, err } - obs, err := observability.NewObservedPriceRegistryV1_2_0(priceRegistryAddr, ExecPluginLabel, ec) + priceRegistry, err := price_registry.NewPriceRegistry(priceRegistryAddr, ec) if err != nil { return nil, err } return &PriceRegistryV1_2_0{ PriceRegistryV1_0_0: v100, - obs: obs, + pr: priceRegistry, }, nil } @@ -44,7 +43,7 @@ func NewPriceRegistryV1_2_0(lggr logger.Logger, priceRegistryAddr common.Address // See https://github.com/smartcontractkit/ccip/blob/ccip-develop/contracts/src/v0.8/ccip/PriceRegistry.sol#L141 func (p *PriceRegistryV1_2_0) GetTokenPrices(ctx context.Context, wantedTokens []common.Address) ([]TokenPriceUpdate, error) { // Make call using 224 ABI. - tps, err := p.obs.GetTokenPrices(&bind.CallOpts{Context: ctx}, wantedTokens) + tps, err := p.pr.GetTokenPrices(&bind.CallOpts{Context: ctx}, wantedTokens) if err != nil { return nil, err } diff --git a/core/services/ocr2/plugins/ccip/internal/observability/price_registry_v1_0_0.go b/core/services/ocr2/plugins/ccip/internal/observability/price_registry_v1_0_0.go deleted file mode 100644 index 618fecca74..0000000000 --- a/core/services/ocr2/plugins/ccip/internal/observability/price_registry_v1_0_0.go +++ /dev/null @@ -1,55 +0,0 @@ -package observability - -import ( - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_0_0" -) - -type ObservedPriceRegistryV1_0_0 struct { - *price_registry_1_0_0.PriceRegistry - metric metricDetails -} - -func NewObservedPriceRegistryV1_0_0(address common.Address, pluginName string, client client.Client) (*ObservedPriceRegistryV1_0_0, error) { - priceRegistry, err := price_registry_1_0_0.NewPriceRegistry(address, client) - if err != nil { - return nil, err - } - - return &ObservedPriceRegistryV1_0_0{ - PriceRegistry: priceRegistry, - metric: metricDetails{ - histogram: priceRegistryHistogram, - pluginName: pluginName, - chainId: client.ConfiguredChainID(), - }, - }, nil -} - -func (o *ObservedPriceRegistryV1_0_0) GetFeeTokens(opts *bind.CallOpts) ([]common.Address, error) { - return withObservedContract(o.metric, "GetFeeTokens", func() ([]common.Address, error) { - return o.PriceRegistry.GetFeeTokens(opts) - }) -} - -func (o *ObservedPriceRegistryV1_0_0) GetTokenPrices(opts *bind.CallOpts, tokens []common.Address) ([]price_registry_1_0_0.InternalTimestampedUint192Value, error) { - return withObservedContract(o.metric, "GetTokenPrices", func() ([]price_registry_1_0_0.InternalTimestampedUint192Value, error) { - return o.PriceRegistry.GetTokenPrices(opts, tokens) - }) -} - -func (o *ObservedPriceRegistryV1_0_0) ParseUsdPerUnitGasUpdated(log types.Log) (*price_registry_1_0_0.PriceRegistryUsdPerUnitGasUpdated, error) { - return withObservedContract(o.metric, "ParseUsdPerUnitGasUpdated", func() (*price_registry_1_0_0.PriceRegistryUsdPerUnitGasUpdated, error) { - return o.PriceRegistry.ParseUsdPerUnitGasUpdated(log) - }) -} - -func (o *ObservedPriceRegistryV1_0_0) ParseUsdPerTokenUpdated(log types.Log) (*price_registry_1_0_0.PriceRegistryUsdPerTokenUpdated, error) { - return withObservedContract(o.metric, "ParseUsdPerTokenUpdated", func() (*price_registry_1_0_0.PriceRegistryUsdPerTokenUpdated, error) { - return o.PriceRegistry.ParseUsdPerTokenUpdated(log) - }) -} diff --git a/core/services/ocr2/plugins/ccip/internal/observability/price_registry_v1_2_0.go b/core/services/ocr2/plugins/ccip/internal/observability/price_registry_v1_2_0.go deleted file mode 100644 index c42f15882d..0000000000 --- a/core/services/ocr2/plugins/ccip/internal/observability/price_registry_v1_2_0.go +++ /dev/null @@ -1,37 +0,0 @@ -package observability - -import ( - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" -) - -type ObservedPriceRegistryV1_2_0 struct { - *ObservedPriceRegistryV1_0_0 - pr *price_registry.PriceRegistry -} - -func NewObservedPriceRegistryV1_2_0(address common.Address, pluginName string, client client.Client) (*ObservedPriceRegistryV1_2_0, error) { - v100, err := NewObservedPriceRegistryV1_0_0(address, pluginName, client) - if err != nil { - return nil, err - } - priceRegistry, err := price_registry.NewPriceRegistry(address, client) - if err != nil { - return nil, err - } - - return &ObservedPriceRegistryV1_2_0{ - ObservedPriceRegistryV1_0_0: v100, - pr: priceRegistry, - }, nil -} - -// Changed in 1.2.0 -func (o *ObservedPriceRegistryV1_2_0) GetTokenPrices(opts *bind.CallOpts, tokens []common.Address) ([]price_registry.InternalTimestampedPackedUint224, error) { - return withObservedContract(o.metric, "GetTokenPrices", func() ([]price_registry.InternalTimestampedPackedUint224, error) { - return o.pr.GetTokenPrices(opts, tokens) - }) -} From 24ee1f770f022f5af0100a9e0bbdbec7f73fce1d Mon Sep 17 00:00:00 2001 From: connorwstein Date: Fri, 13 Oct 2023 13:04:34 -0400 Subject: [PATCH 24/24] Fix 100 --- .../ccip/internal/ccipdata/price_registry_v1_0_0.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_0_0.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_0_0.go index 6bbf78062e..0e7869075f 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_0_0.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_0_0.go @@ -13,7 +13,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_0_0" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" @@ -24,11 +23,11 @@ import ( var ( _ PriceRegistryReader = &PriceRegistryV1_0_0{} // Exposed only for backwards compatibility with tests. - UsdPerUnitGasUpdatedV1_0_0 = abihelpers.MustGetEventID("UsdPerUnitGasUpdated", abihelpers.MustParseABI(price_registry.PriceRegistryABI)) + UsdPerUnitGasUpdatedV1_0_0 = abihelpers.MustGetEventID("UsdPerUnitGasUpdated", abihelpers.MustParseABI(price_registry_1_0_0.PriceRegistryABI)) ) type PriceRegistryV1_0_0 struct { - priceRegistry price_registry.PriceRegistryInterface + priceRegistry price_registry_1_0_0.PriceRegistryInterface address common.Address lp logpoller.LogPoller lggr logger.Logger @@ -138,7 +137,7 @@ func (p *PriceRegistryV1_0_0) GetGasPriceUpdatesCreatedAfter(ctx context.Context } func NewPriceRegistryV1_0_0(lggr logger.Logger, priceRegistryAddr common.Address, lp logpoller.LogPoller, ec client.Client) (*PriceRegistryV1_0_0, error) { - priceRegistry, err := price_registry.NewPriceRegistry(priceRegistryAddr, ec) + priceRegistry, err := price_registry_1_0_0.NewPriceRegistry(priceRegistryAddr, ec) if err != nil { return nil, err }