diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index 5abff8ca4c..97609ff3aa 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -252,6 +252,7 @@ EVM2EVMOnRamp_forwardFromRouter_upgrade:test_V2_Success() (gas: 95349) EVM2EVMOnRamp_getDataAvailabilityCost:test_EmptyMessageCalculatesDataAvailabilityCost_Success() (gas: 20544) EVM2EVMOnRamp_getDataAvailabilityCost:test_SimpleMessageCalculatesDataAvailabilityCost_Success() (gas: 20912) EVM2EVMOnRamp_getFee:test_EmptyMessage_Success() (gas: 78230) +EVM2EVMOnRamp_getFee:test_GetFeeOfZeroForTokenMessage_Success() (gas: 81762) EVM2EVMOnRamp_getFee:test_HighGasMessage_Success() (gas: 234078) EVM2EVMOnRamp_getFee:test_MessageGasLimitTooHigh_Revert() (gas: 16715) EVM2EVMOnRamp_getFee:test_MessageTooLarge_Revert() (gas: 95271) @@ -343,10 +344,10 @@ FeeQuoter_applyTokenTransferFeeConfigUpdates:test_ApplyTokenTransferFeeConfig_Su FeeQuoter_applyTokenTransferFeeConfigUpdates:test_ApplyTokenTransferFeeZeroInput() (gas: 13089) FeeQuoter_applyTokenTransferFeeConfigUpdates:test_InvalidDestBytesOverhead_Revert() (gas: 17071) FeeQuoter_applyTokenTransferFeeConfigUpdates:test_OnlyCallableByOwnerOrAdmin_Revert() (gas: 12240) -FeeQuoter_constructor:test_InvalidLinkTokenEqZeroAddress_Revert() (gas: 107016) -FeeQuoter_constructor:test_InvalidMaxFeeJuelsPerMsg_Revert() (gas: 111366) -FeeQuoter_constructor:test_InvalidStalenessThreshold_Revert() (gas: 111419) -FeeQuoter_constructor:test_Setup_Success() (gas: 5336824) +FeeQuoter_constructor:test_InvalidLinkTokenEqZeroAddress_Revert() (gas: 107046) +FeeQuoter_constructor:test_InvalidMaxFeeJuelsPerMsg_Revert() (gas: 111396) +FeeQuoter_constructor:test_InvalidStalenessThreshold_Revert() (gas: 111449) +FeeQuoter_constructor:test_Setup_Success() (gas: 5358690) FeeQuoter_convertTokenAmount:test_ConvertTokenAmount_Success() (gas: 72739) FeeQuoter_convertTokenAmount:test_LinkTokenNotSupported_Revert() (gas: 30963) FeeQuoter_getDataAvailabilityCost:test_EmptyMessageCalculatesDataAvailabilityCost_Success() (gas: 94303) @@ -368,17 +369,17 @@ FeeQuoter_getTokenTransferCost:test_ZeroAmountTokenTransferChargesMinFeeAndGas_S FeeQuoter_getTokenTransferCost:test_ZeroFeeConfigChargesMinFee_Success() (gas: 40013) FeeQuoter_getTokenTransferCost:test_getTokenTransferCost_selfServeUsesDefaults_Success() (gas: 29299) FeeQuoter_getValidatedFee:test_DestinationChainNotEnabled_Revert() (gas: 18180) -FeeQuoter_getValidatedFee:test_EmptyMessage_Success() (gas: 81054) -FeeQuoter_getValidatedFee:test_EnforceOutOfOrder_Revert() (gas: 54294) -FeeQuoter_getValidatedFee:test_HighGasMessage_Success() (gas: 237472) -FeeQuoter_getValidatedFee:test_InvalidEVMAddress_Revert() (gas: 19949) -FeeQuoter_getValidatedFee:test_MessageGasLimitTooHigh_Revert() (gas: 31746) -FeeQuoter_getValidatedFee:test_MessageTooLarge_Revert() (gas: 97692) -FeeQuoter_getValidatedFee:test_MessageWithDataAndTokenTransfer_Success() (gas: 142833) -FeeQuoter_getValidatedFee:test_NotAFeeToken_Revert() (gas: 29407) -FeeQuoter_getValidatedFee:test_SingleTokenMessage_Success() (gas: 111861) -FeeQuoter_getValidatedFee:test_TooManyTokens_Revert() (gas: 20085) -FeeQuoter_getValidatedFee:test_ZeroDataAvailabilityMultiplier_Success() (gas: 61933) +FeeQuoter_getValidatedFee:test_EmptyMessage_Success() (gas: 85936) +FeeQuoter_getValidatedFee:test_EnforceOutOfOrder_Revert() (gas: 56735) +FeeQuoter_getValidatedFee:test_HighGasMessage_Success() (gas: 242354) +FeeQuoter_getValidatedFee:test_InvalidEVMAddress_Revert() (gas: 22390) +FeeQuoter_getValidatedFee:test_MessageGasLimitTooHigh_Revert() (gas: 34187) +FeeQuoter_getValidatedFee:test_MessageTooLarge_Revert() (gas: 100133) +FeeQuoter_getValidatedFee:test_MessageWithDataAndTokenTransfer_Success() (gas: 147715) +FeeQuoter_getValidatedFee:test_NotAFeeToken_Revert() (gas: 21043) +FeeQuoter_getValidatedFee:test_SingleTokenMessage_Success() (gas: 116743) +FeeQuoter_getValidatedFee:test_TooManyTokens_Revert() (gas: 22526) +FeeQuoter_getValidatedFee:test_ZeroDataAvailabilityMultiplier_Success() (gas: 64374) FeeQuoter_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedErc20Above18Decimals_Success() (gas: 2094539) FeeQuoter_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedErc20Below18Decimals_Success() (gas: 2094497) FeeQuoter_getValidatedTokenPrice:test_GetValidatedTokenPriceFromFeedFeedAt0Decimals_Success() (gas: 2074616) @@ -564,8 +565,8 @@ MultiOCR3Base_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 24191) MultiOCR3Base_transmit:test_UnauthorizedSigner_Revert() (gas: 61409) MultiOCR3Base_transmit:test_UnconfiguredPlugin_Revert() (gas: 39890) MultiOCR3Base_transmit:test_ZeroSignatures_Revert() (gas: 32973) -MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 410714) -MultiRampsE2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1504468) +MultiOnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 414301) +MultiRampsE2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1506106) NonceManager_NonceIncrementation:test_getIncrementedOutboundNonce_Success() (gas: 37907) NonceManager_NonceIncrementation:test_incrementInboundNonce_Skip() (gas: 23694) NonceManager_NonceIncrementation:test_incrementInboundNonce_Success() (gas: 38763) @@ -577,10 +578,10 @@ NonceManager_OffRampUpgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success( NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRampTransitive_Success() (gas: 244814) NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRamp_Success() (gas: 233069) NonceManager_OffRampUpgrade:test_Upgraded_Success() (gas: 153186) -NonceManager_OnRampUpgrade:test_UpgradeNonceNewSenderStartsAtZero_Success() (gas: 168502) -NonceManager_OnRampUpgrade:test_UpgradeNonceStartsAtV1Nonce_Success() (gas: 220478) +NonceManager_OnRampUpgrade:test_UpgradeNonceNewSenderStartsAtZero_Success() (gas: 168681) +NonceManager_OnRampUpgrade:test_UpgradeNonceStartsAtV1Nonce_Success() (gas: 220836) NonceManager_OnRampUpgrade:test_UpgradeSenderNoncesReadsPreviousRamp_Success() (gas: 125070) -NonceManager_OnRampUpgrade:test_Upgrade_Success() (gas: 107731) +NonceManager_OnRampUpgrade:test_Upgrade_Success() (gas: 107910) NonceManager_applyPreviousRampsUpdates:test_MultipleRampsUpdates() (gas: 122943) NonceManager_applyPreviousRampsUpdates:test_PreviousRampAlreadySetOffRamp_Revert() (gas: 42959) NonceManager_applyPreviousRampsUpdates:test_PreviousRampAlreadySetOnRampAndOffRamp_Revert() (gas: 64282) @@ -747,47 +748,52 @@ OffRamp_verify:test_NotBlessedWrongChainSelector_Success() (gas: 178754) OffRamp_verify:test_NotBlessed_Success() (gas: 141593) OffRamp_verify:test_TooManyLeaves_Revert() (gas: 51510) OnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 390336) -OnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_Success() (gas: 63649) -OnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_WithInalidChainSelector_Revert() (gas: 13308) -OnRamp_constructor:test_Constructor_InvalidConfigChainSelectorEqZero_Revert() (gas: 94260) -OnRamp_constructor:test_Constructor_InvalidConfigNonceManagerEqAddressZero_Revert() (gas: 92177) -OnRamp_constructor:test_Constructor_InvalidConfigRMNProxyEqAddressZero_Revert() (gas: 97198) -OnRamp_constructor:test_Constructor_InvalidConfigTokenAdminRegistryEqAddressZero_Revert() (gas: 92235) -OnRamp_constructor:test_Constructor_Success() (gas: 2455004) -OnRamp_forwardFromRouter:test_CannotSendZeroTokens_Revert() (gas: 72010) -OnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2AllowOutOfOrderTrue_Success() (gas: 112791) -OnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2_Success() (gas: 143561) -OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessCustomExtraArgs() (gas: 143137) -OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessEmptyExtraArgs() (gas: 141314) -OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessLegacyExtraArgs() (gas: 143367) -OnRamp_forwardFromRouter:test_ForwardFromRouter_Success() (gas: 142736) -OnRamp_forwardFromRouter:test_ForwardFromRouter_Success_ConfigurableSourceRouter() (gas: 135246) -OnRamp_forwardFromRouter:test_InvalidExtraArgsTag_Revert() (gas: 26349) -OnRamp_forwardFromRouter:test_MessageValidationError_Revert() (gas: 133253) -OnRamp_forwardFromRouter:test_MesssageFeeTooHigh_Revert() (gas: 24426) -OnRamp_forwardFromRouter:test_OriginalSender_Revert() (gas: 12872) -OnRamp_forwardFromRouter:test_Paused_Revert() (gas: 32033) -OnRamp_forwardFromRouter:test_Permissions_Revert() (gas: 15762) -OnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: 182032) -OnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 208301) -OnRamp_forwardFromRouter:test_ShouldStoreLinkFees() (gas: 122714) -OnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 144094) -OnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3887491) -OnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 108659) -OnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 74066) -OnRamp_forwardFromRouter:test_forwardFromRouter_WithValidation_Success() (gas: 273416) -OnRamp_getFee:test_EmptyMessage_Success() (gas: 104351) -OnRamp_getFee:test_EnforceOutOfOrder_Revert() (gas: 73173) -OnRamp_getFee:test_SingleTokenMessage_Success() (gas: 119675) -OnRamp_getFee:test_Unhealthy_Revert() (gas: 43679) +OnRamp_allowListConfigUpdates:test_applyAllowList_Revert() (gas: 66509) +OnRamp_allowListConfigUpdates:test_applyAllowList_Success() (gas: 323566) +OnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_Success() (gas: 64501) +OnRamp_applyDestChainConfigUpdates:test_ApplyDestChainConfigUpdates_WithInvalidChainSelector_Revert() (gas: 13242) +OnRamp_constructor:test_Constructor_InvalidConfigChainSelectorEqZero_Revert() (gas: 94878) +OnRamp_constructor:test_Constructor_InvalidConfigNonceManagerEqAddressZero_Revert() (gas: 92812) +OnRamp_constructor:test_Constructor_InvalidConfigRMNProxyEqAddressZero_Revert() (gas: 97827) +OnRamp_constructor:test_Constructor_InvalidConfigTokenAdminRegistryEqAddressZero_Revert() (gas: 92870) +OnRamp_constructor:test_Constructor_Success() (gas: 2866937) +OnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2AllowOutOfOrderTrue_Success() (gas: 115250) +OnRamp_forwardFromRouter:test_ForwardFromRouterExtraArgsV2_Success() (gas: 146019) +OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessCustomExtraArgs() (gas: 145615) +OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessEmptyExtraArgs() (gas: 143816) +OnRamp_forwardFromRouter:test_ForwardFromRouterSuccessLegacyExtraArgs() (gas: 145847) +OnRamp_forwardFromRouter:test_ForwardFromRouter_Success() (gas: 145216) +OnRamp_forwardFromRouter:test_ForwardFromRouter_Success_ConfigurableSourceRouter() (gas: 140359) +OnRamp_forwardFromRouter:test_InvalidExtraArgsTag_Revert() (gas: 28810) +OnRamp_forwardFromRouter:test_MessageValidationError_Revert() (gas: 138683) +OnRamp_forwardFromRouter:test_MesssageFeeTooHigh_Revert() (gas: 26910) +OnRamp_forwardFromRouter:test_MultiCannotSendZeroTokens_Revert() (gas: 74456) +OnRamp_forwardFromRouter:test_OriginalSender_Revert() (gas: 12918) +OnRamp_forwardFromRouter:test_Paused_Revert() (gas: 37224) +OnRamp_forwardFromRouter:test_Permissions_Revert() (gas: 18179) +OnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: 185252) +OnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 211543) +OnRamp_forwardFromRouter:test_ShouldStoreLinkFees() (gas: 125128) +OnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 146530) +OnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3891732) +OnRamp_forwardFromRouter:test_UnAllowedOriginalSender_Revert() (gas: 18609) +OnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 111118) +OnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 76545) +OnRamp_forwardFromRouter:test_forwardFromRouter_WithValidation_Success() (gas: 278740) +OnRamp_getFee:test_EmptyMessage_Success() (gas: 110107) +OnRamp_getFee:test_EnforceOutOfOrder_Revert() (gas: 75610) +OnRamp_getFee:test_GetFeeOfZeroForTokenMessage_Success() (gas: 95456) +OnRamp_getFee:test_NotAFeeTokenButPricedToken_Revert() (gas: 41814) +OnRamp_getFee:test_SingleTokenMessage_Success() (gas: 125476) +OnRamp_getFee:test_Unhealthy_Revert() (gas: 43669) OnRamp_getSupportedTokens:test_GetSupportedTokens_Revert() (gas: 10438) -OnRamp_getTokenPool:test_GetTokenPool_Success() (gas: 35270) -OnRamp_setDynamicConfig:test_SetConfigInvalidConfigFeeAggregatorEqAddressZero_Revert() (gas: 11155) -OnRamp_setDynamicConfig:test_SetConfigInvalidConfigFeeQuoterEqAddressZero_Revert() (gas: 12763) -OnRamp_setDynamicConfig:test_SetConfigInvalidConfig_Revert() (gas: 11112) -OnRamp_setDynamicConfig:test_SetConfigOnlyOwner_Revert() (gas: 15939) -OnRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 52018) -OnRamp_withdrawFeeTokens:test_WithdrawFeeTokens_Success() (gas: 97192) +OnRamp_getTokenPool:test_GetTokenPool_Success() (gas: 35204) +OnRamp_setDynamicConfig:test_SetConfigInvalidConfigFeeAggregatorEqAddressZero_Revert() (gas: 11402) +OnRamp_setDynamicConfig:test_SetConfigInvalidConfigFeeQuoterEqAddressZero_Revert() (gas: 13001) +OnRamp_setDynamicConfig:test_SetConfigInvalidConfig_Revert() (gas: 11359) +OnRamp_setDynamicConfig:test_SetConfigOnlyOwner_Revert() (gas: 16385) +OnRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 55321) +OnRamp_withdrawFeeTokens:test_WithdrawFeeTokens_Success() (gas: 97107) PingPong_ccipReceive:test_CcipReceive_Success() (gas: 150169) PingPong_plumbing:test_OutOfOrderExecution_Success() (gas: 20277) PingPong_plumbing:test_Pausing_Success() (gas: 17777) diff --git a/contracts/src/v0.8/ccip/FeeQuoter.sol b/contracts/src/v0.8/ccip/FeeQuoter.sol index c2a7231d96..aea632fc4e 100644 --- a/contracts/src/v0.8/ccip/FeeQuoter.sol +++ b/contracts/src/v0.8/ccip/FeeQuoter.sol @@ -28,6 +28,7 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver, using KeystoneFeedDefaultMetadataLib for bytes; error TokenNotSupported(address token); + error FeeTokenNotSupported(address token); error ChainNotSupported(uint64 chain); error StaleGasPrice(uint64 destChainSelector, uint256 threshold, uint256 timePassed); error StaleKeystoneUpdate(address token, uint256 feedTimestamp, uint256 storedTimeStamp); @@ -147,7 +148,7 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver, /// applyPremiumMultiplierWeiPerEthUpdates to set the mapping struct PremiumMultiplierWeiPerEthArgs { address token; // // ───────────────────╮ Token address - uint64 premiumMultiplierWeiPerEth; // ──╯ Multiplier for destination chain specific premiums. Should never be 0 so can be used as an isEnabled flag + uint64 premiumMultiplierWeiPerEth; // ──╯ Multiplier for destination chain specific premiums. } string public constant override typeAndVersion = "FeeQuoter 1.6.0-dev"; @@ -174,7 +175,6 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver, mapping(address token => IFeeQuoter.TokenPriceFeedConfig dataFeedAddress) private s_usdPriceFeedsPerToken; /// @dev The multiplier for destination chain specific premiums that can be set by the owner or fee admin - /// This should never be 0 once set, so it can be used as an isEnabled flag mapping(address token => uint64 premiumMultiplierWeiPerEth) internal s_premiumMultiplierWeiPerEth; /// @dev The destination chain specific fee configs @@ -473,6 +473,7 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver, ) external view returns (uint256 feeTokenAmount) { DestChainConfig memory destChainConfig = s_destChainConfigs[destChainSelector]; if (!destChainConfig.isEnabled) revert DestinationChainNotEnabled(destChainSelector); + if (!s_feeTokens.contains(message.feeToken)) revert FeeTokenNotSupported(message.feeToken); uint256 numberOfTokens = message.tokenAmounts.length; _validateMessage(destChainConfig, message.data.length, numberOfTokens, message.receiver); diff --git a/contracts/src/v0.8/ccip/onRamp/OnRamp.sol b/contracts/src/v0.8/ccip/onRamp/OnRamp.sol index aa4edba3ac..947859eb01 100644 --- a/contracts/src/v0.8/ccip/onRamp/OnRamp.sol +++ b/contracts/src/v0.8/ccip/onRamp/OnRamp.sol @@ -19,12 +19,14 @@ import {USDPriceWith18Decimals} from "../libraries/USDPriceWith18Decimals.sol"; import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; +import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableSet.sol"; /// @notice The OnRamp is a contract that handles lane-specific fee logic /// @dev The OnRamp and OffRamp form an xchain upgradeable unit. Any change to one of them /// results in an onchain upgrade of all 3. contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { using SafeERC20 for IERC20; + using EnumerableSet for EnumerableSet.AddressSet; using USDPriceWith18Decimals for uint224; error CannotSendZeroTokens(); @@ -35,13 +37,21 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { error CursedByRMN(uint64 sourceChainSelector); error GetSupportedTokensFunctionalityRemovedCheckAdminRegistry(); error InvalidDestChainConfig(uint64 sourceChainSelector); + error OnlyCallableByOwnerOrAllowlistAdmin(); + error SenderNotAllowed(address sender); + error InvalidAllowListRequest(uint64 destChainSelector); event ConfigSet(StaticConfig staticConfig, DynamicConfig dynamicConfig); - event DestChainConfigSet(uint64 indexed destChainSelector, DestChainConfig destChainConfig); + event DestChainConfigSet( + uint64 indexed destChainSelector, uint64 sequenceNumber, IRouter router, bool allowListEnabled + ); event FeePaid(address indexed feeToken, uint256 feeValueJuels); event FeeTokenWithdrawn(address indexed feeAggregator, address indexed feeToken, uint256 amount); /// RMN depends on this event, if changing, please notify the RMN maintainers. event CCIPSendRequested(uint64 indexed destChainSelector, Internal.EVM2AnyRampMessage message); + event AllowListAdminSet(address indexed allowListAdmin); + event AllowListSendersAdded(uint64 indexed destChainSelector, address[] senders); + event AllowListSendersRemoved(uint64 indexed destChainSelector, address[] senders); /// @dev Struct that contains the static configuration /// RMN depends on this struct, if changing, please notify the RMN maintainers. @@ -59,16 +69,19 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { address feeQuoter; // FeeQuoter address address messageValidator; // Optional message validator to validate outbound messages (zero address = no validator) address feeAggregator; // Fee aggregator address + address allowListAdmin; // authorized admin to add or remove allowed senders } /// @dev Struct to hold the configs for a destination chain + /// @dev sequenceNumber, allowListEnabled, router will all be packed in 1 slot struct DestChainConfig { // The last used sequence number. This is zero in the case where no messages have yet been sent. // 0 is not a valid sequence number for any real transaction. - uint64 sequenceNumber; - // This is the local router address that is allowed to send messages to the destination chain. - // This is NOT the receiving router address on the destination chain. - IRouter router; + uint64 sequenceNumber; // ──────╮ The last used sequence number + bool allowListEnabled; // │ boolean indicator to specify if allowList check is enabled + IRouter router; // ─────────────╯ Local router address that is allowed to send messages to the destination chain. + // This is the list of addresses allowed to send messages from onRamp + EnumerableSet.AddressSet allowedSendersList; } /// @dev Same as DestChainConfig but with the destChainSelector so that an array of these @@ -79,6 +92,19 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { IRouter router; // Source router address } + /// @dev Struct used to apply AllowList Senders for multiple destChainSelectors + /// @dev the senders in the AllowlistedSenders here is the user that sends the message + /// @dev the config restricts the chain to allow only allowedList of senders to send message from this chain to a destChainSelector + /// @dev destChainSelector, allowListEnabled will be packed in 1 slot + //solhint-disable gas-struct-packing + struct AllowListConfigArgs { + uint64 destChainSelector; // ─────────────╮ Destination chain selector + // │ destChainSelector and allowListEnabled are packed in the same slot + bool allowListEnabled; // ────────────────╯ boolean indicator to specify if allowList check is enabled. + address[] addedAllowlistedSenders; // list of senders to be added to the allowedSendersList + address[] removedAllowlistedSenders; // list of senders to be removed from the allowedSendersList + } + // STATIC CONFIG string public constant override typeAndVersion = "OnRamp 1.6.0-dev"; /// @dev The chain ID of the source chain that this contract is deployed to @@ -141,6 +167,13 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { // NOTE: assumes the message has already been validated through the getFee call // Validate message sender is set and allowed. Not validated in `getFee` since it is not user-driven. if (originalSender == address(0)) revert RouterMustSetOriginalSender(); + + if (destChainConfig.allowListEnabled) { + if (!destChainConfig.allowedSendersList.contains(originalSender)) { + revert SenderNotAllowed(originalSender); + } + } + // Router address may be zero intentionally to pause. if (msg.sender != address(destChainConfig.router)) revert MustBeCalledByRouter(); @@ -327,13 +360,82 @@ contract OnRamp is IEVM2AnyOnRampClient, ITypeAndVersion, OwnerIsCreator { revert InvalidDestChainConfig(destChainSelector); } - DestChainConfig memory newDestChainConfig = DestChainConfig({ - sequenceNumber: s_destChainConfigs[destChainSelector].sequenceNumber, - router: destChainConfigArg.router - }); - s_destChainConfigs[destChainSelector] = newDestChainConfig; + DestChainConfig storage destChainConfig = s_destChainConfigs[destChainSelector]; + destChainConfig.router = destChainConfigArg.router; + + emit DestChainConfigSet( + destChainSelector, destChainConfig.sequenceNumber, destChainConfigArg.router, destChainConfig.allowListEnabled + ); + } + } + + /// @notice get ChainConfig configured for the DestinationChainSelector + /// @param destChainSelector The destination chain selector + /// @return sequenceNumber The last used sequence number + /// @return allowListEnabled boolean indicator to specify if allowList check is enabled + /// @return router address of the router + function getDestChainConfig(uint64 destChainSelector) + public + view + returns (uint64 sequenceNumber, bool allowListEnabled, address router) + { + DestChainConfig storage config = s_destChainConfigs[destChainSelector]; + sequenceNumber = config.sequenceNumber; + allowListEnabled = config.allowListEnabled; + router = address(config.router); + return (sequenceNumber, allowListEnabled, router); + } + + /// @notice get allowedSenders List configured for the DestinationChainSelector + /// @param destChainSelector The destination chain selector + /// @return array of allowedList of Senders + function getAllowedSendersList(uint64 destChainSelector) public view returns (address[] memory) { + return s_destChainConfigs[destChainSelector].allowedSendersList.values(); + } + + // ================================================================ + // │ Allowlist │ + // ================================================================ + + /// @notice Updates allowListConfig for Senders + /// @dev configuration used to set the list of senders who are authorized to send messages + /// @param allowListConfigArgsItems Array of AllowListConfigArguments where each item is for a destChainSelector + function applyAllowListUpdates(AllowListConfigArgs[] calldata allowListConfigArgsItems) external { + if (msg.sender != owner()) { + if (msg.sender != s_dynamicConfig.allowListAdmin) { + revert OnlyCallableByOwnerOrAllowlistAdmin(); + } + } + + for (uint256 i = 0; i < allowListConfigArgsItems.length; ++i) { + AllowListConfigArgs memory allowListConfigArgs = allowListConfigArgsItems[i]; - emit DestChainConfigSet(destChainSelector, newDestChainConfig); + DestChainConfig storage destChainConfig = s_destChainConfigs[allowListConfigArgs.destChainSelector]; + destChainConfig.allowListEnabled = allowListConfigArgs.allowListEnabled; + + if (allowListConfigArgs.allowListEnabled) { + for (uint256 j = 0; j < allowListConfigArgs.addedAllowlistedSenders.length; ++j) { + address toAdd = allowListConfigArgs.addedAllowlistedSenders[j]; + if (toAdd == address(0)) { + revert InvalidAllowListRequest(allowListConfigArgs.destChainSelector); + } + destChainConfig.allowedSendersList.add(toAdd); + } + + if (allowListConfigArgs.addedAllowlistedSenders.length > 0) { + emit AllowListSendersAdded(allowListConfigArgs.destChainSelector, allowListConfigArgs.addedAllowlistedSenders); + } + } + + for (uint256 k = 0; k < allowListConfigArgs.removedAllowlistedSenders.length; ++k) { + destChainConfig.allowedSendersList.remove(allowListConfigArgs.removedAllowlistedSenders[k]); + } + + if (allowListConfigArgs.removedAllowlistedSenders.length > 0) { + emit AllowListSendersRemoved( + allowListConfigArgs.destChainSelector, allowListConfigArgs.removedAllowlistedSenders + ); + } } } diff --git a/contracts/src/v0.8/ccip/test/feeQuoter/FeeQuoter.t.sol b/contracts/src/v0.8/ccip/test/feeQuoter/FeeQuoter.t.sol index 11836b3d7b..cdbf1cef7a 100644 --- a/contracts/src/v0.8/ccip/test/feeQuoter/FeeQuoter.t.sol +++ b/contracts/src/v0.8/ccip/test/feeQuoter/FeeQuoter.t.sol @@ -1706,7 +1706,7 @@ contract FeeQuoter_getValidatedFee is FeeQuoterFeeSetup { Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(notAFeeToken, 1); message.feeToken = notAFeeToken; - vm.expectRevert(abi.encodeWithSelector(FeeQuoter.TokenNotSupported.selector, notAFeeToken)); + vm.expectRevert(abi.encodeWithSelector(FeeQuoter.FeeTokenNotSupported.selector, notAFeeToken)); s_feeQuoter.getValidatedFee(DEST_CHAIN_SELECTOR, message); } 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 7b400c0df6..f0cd0f80ed 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol @@ -1407,6 +1407,32 @@ contract EVM2EVMOnRamp_getFee is EVM2EVMOnRamp_getFeeSetup { } } + function test_GetFeeOfZeroForTokenMessage_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + uint256 feeAmount = s_onRamp.getFee(DEST_CHAIN_SELECTOR, message); + assertTrue(feeAmount > 0); + + EVM2EVMOnRamp.FeeTokenConfigArgs[] memory feeTokenConfigArgs = new EVM2EVMOnRamp.FeeTokenConfigArgs[](1); + feeTokenConfigArgs[0] = EVM2EVMOnRamp.FeeTokenConfigArgs({ + token: message.feeToken, + networkFeeUSDCents: 0, + gasMultiplierWeiPerEth: 0, + premiumMultiplierWeiPerEth: 0, + enabled: true + }); + + s_onRamp.setFeeTokenConfig(feeTokenConfigArgs); + EVM2EVMOnRamp.DynamicConfig memory config = + generateDynamicOnRampConfig(address(s_sourceRouter), address(s_feeQuoter)); + config.destDataAvailabilityMultiplierBps = 0; + + s_onRamp.setDynamicConfig(config); + + feeAmount = s_onRamp.getFee(DEST_CHAIN_SELECTOR, message); + assertEq(0, feeAmount); + } + function test_ZeroDataAvailabilityMultiplier_Success() public { EVM2EVMOnRamp.DynamicConfig memory dynamicConfig = s_onRamp.getDynamicConfig(); dynamicConfig.destDataAvailabilityMultiplierBps = 0; diff --git a/contracts/src/v0.8/ccip/test/onRamp/OnRamp.t.sol b/contracts/src/v0.8/ccip/test/onRamp/OnRamp.t.sol index 43d57b4624..a6f4205ee1 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/OnRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/OnRamp.t.sol @@ -30,7 +30,7 @@ contract OnRamp_constructor is OnRampSetup { vm.expectEmit(); emit OnRamp.ConfigSet(staticConfig, dynamicConfig); vm.expectEmit(); - emit OnRamp.DestChainConfigSet(DEST_CHAIN_SELECTOR, OnRamp.DestChainConfig(0, s_sourceRouter)); + emit OnRamp.DestChainConfigSet(DEST_CHAIN_SELECTOR, 0, s_sourceRouter, false); _deployOnRamp(SOURCE_CHAIN_SELECTOR, s_sourceRouter, address(s_outboundNonceManager), address(s_tokenAdminRegistry)); @@ -117,6 +117,20 @@ contract OnRamp_forwardFromRouter is OnRampSetup { feeTokens[0] = s_sourceTokens[1]; s_feeQuoter.applyFeeTokensUpdates(feeTokens, new address[](0)); + uint64[] memory destinationChainSelectors = new uint64[](1); + destinationChainSelectors[0] = DEST_CHAIN_SELECTOR; + address[] memory addAllowedList = new address[](1); + addAllowedList[0] = OWNER; + OnRamp.AllowListConfigArgs memory allowListConfigArgs = OnRamp.AllowListConfigArgs({ + allowListEnabled: true, + destChainSelector: DEST_CHAIN_SELECTOR, + addedAllowlistedSenders: addAllowedList, + removedAllowlistedSenders: new address[](0) + }); + OnRamp.AllowListConfigArgs[] memory applyAllowListConfigArgsItems = new OnRamp.AllowListConfigArgs[](1); + applyAllowListConfigArgsItems[0] = allowListConfigArgs; + s_onRamp.applyAllowListUpdates(applyAllowListConfigArgsItems); + // Since we'll mostly be testing for valid calls from the router we'll // mock all calls to be originating from the router and re-mock in // tests that require failure. @@ -308,6 +322,25 @@ contract OnRamp_forwardFromRouter is OnRampSetup { vm.assume(originalSender != address(0)); vm.assume(uint160(receiver) >= Internal.PRECOMPILE_SPACE); feeTokenAmount = uint96(bound(feeTokenAmount, 0, MAX_MSG_FEES_JUELS)); + vm.stopPrank(); + + vm.startPrank(OWNER); + uint64[] memory destinationChainSelectors = new uint64[](1); + destinationChainSelectors[0] = uint64(DEST_CHAIN_SELECTOR); + address[] memory addAllowedList = new address[](1); + addAllowedList[0] = originalSender; + OnRamp.AllowListConfigArgs memory allowListConfigArgs = OnRamp.AllowListConfigArgs({ + allowListEnabled: true, + destChainSelector: DEST_CHAIN_SELECTOR, + addedAllowlistedSenders: addAllowedList, + removedAllowlistedSenders: new address[](0) + }); + OnRamp.AllowListConfigArgs[] memory applyAllowListConfigArgsItems = new OnRamp.AllowListConfigArgs[](1); + applyAllowListConfigArgsItems[0] = allowListConfigArgs; + s_onRamp.applyAllowListUpdates(applyAllowListConfigArgsItems); + vm.stopPrank(); + + vm.startPrank(address(s_sourceRouter)); Client.EVM2AnyMessage memory message = _generateEmptyMessage(); message.receiver = abi.encode(receiver); @@ -379,6 +412,13 @@ contract OnRamp_forwardFromRouter is OnRampSetup { s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, _generateEmptyMessage(), 0, address(0)); } + function test_UnAllowedOriginalSender_Revert() public { + vm.stopPrank(); + vm.startPrank(STRANGER); + vm.expectRevert(abi.encodeWithSelector(OnRamp.SenderNotAllowed.selector, STRANGER)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, _generateEmptyMessage(), 0, STRANGER); + } + function test_MessageValidationError_Revert() public { _enableOutboundMessageValidator(); @@ -398,13 +438,13 @@ contract OnRamp_forwardFromRouter is OnRampSetup { s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, feeAmount, OWNER); } - function test_CannotSendZeroTokens_Revert() public { + function test_MultiCannotSendZeroTokens_Revert() public { Client.EVM2AnyMessage memory message = _generateEmptyMessage(); message.tokenAmounts = new Client.EVMTokenAmount[](1); message.tokenAmounts[0].amount = 0; message.tokenAmounts[0].token = s_sourceTokens[0]; vm.expectRevert(OnRamp.CannotSendZeroTokens.selector); - s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, STRANGER); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); } function test_UnsupportedToken_Revert() public { @@ -569,6 +609,26 @@ contract OnRamp_getFee is OnRampSetup { } } + function test_GetFeeOfZeroForTokenMessage_Success() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + uint256 feeAmount = s_onRamp.getFee(DEST_CHAIN_SELECTOR, message); + assertTrue(feeAmount > 0); + + FeeQuoter.PremiumMultiplierWeiPerEthArgs[] memory tokenMults = new FeeQuoter.PremiumMultiplierWeiPerEthArgs[](1); + tokenMults[0] = FeeQuoter.PremiumMultiplierWeiPerEthArgs({token: message.feeToken, premiumMultiplierWeiPerEth: 0}); + s_feeQuoter.applyPremiumMultiplierWeiPerEthUpdates(tokenMults); + + FeeQuoter.DestChainConfigArgs[] memory destChainConfigArgs = _generateFeeQuoterDestChainConfigArgs(); + destChainConfigArgs[0].destChainConfig.destDataAvailabilityMultiplierBps = 0; + destChainConfigArgs[0].destChainConfig.gasMultiplierWeiPerEth = 0; + s_feeQuoter.applyDestChainConfigUpdates(destChainConfigArgs); + + feeAmount = s_onRamp.getFee(DEST_CHAIN_SELECTOR, message); + + assertEq(0, feeAmount); + } + // Reverts function test_Unhealthy_Revert() public { @@ -594,6 +654,15 @@ contract OnRamp_getFee is OnRampSetup { vm.expectRevert(FeeQuoter.ExtraArgOutOfOrderExecutionMustBeTrue.selector); s_onRamp.getFee(DEST_CHAIN_SELECTOR, message); } + + function test_NotAFeeTokenButPricedToken_Revert() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + message.feeToken = s_sourceTokens[1]; + + vm.expectRevert(abi.encodeWithSelector(FeeQuoter.FeeTokenNotSupported.selector, message.feeToken)); + + s_onRamp.getFee(DEST_CHAIN_SELECTOR, message); + } } contract OnRamp_setDynamicConfig is OnRampSetup { @@ -602,7 +671,8 @@ contract OnRamp_setDynamicConfig is OnRampSetup { OnRamp.DynamicConfig memory newConfig = OnRamp.DynamicConfig({ feeQuoter: address(23423), messageValidator: makeAddr("messageValidator"), - feeAggregator: FEE_AGGREGATOR + feeAggregator: FEE_AGGREGATOR, + allowListAdmin: address(0) }); vm.expectEmit(); @@ -620,7 +690,8 @@ contract OnRamp_setDynamicConfig is OnRampSetup { OnRamp.DynamicConfig memory newConfig = OnRamp.DynamicConfig({ feeQuoter: address(0), feeAggregator: FEE_AGGREGATOR, - messageValidator: makeAddr("messageValidator") + messageValidator: makeAddr("messageValidator"), + allowListAdmin: address(0) }); vm.expectRevert(OnRamp.InvalidConfig.selector); @@ -628,8 +699,12 @@ contract OnRamp_setDynamicConfig is OnRampSetup { } function test_SetConfigInvalidConfig_Revert() public { - OnRamp.DynamicConfig memory newConfig = - OnRamp.DynamicConfig({feeQuoter: address(23423), messageValidator: address(0), feeAggregator: FEE_AGGREGATOR}); + OnRamp.DynamicConfig memory newConfig = OnRamp.DynamicConfig({ + feeQuoter: address(23423), + messageValidator: address(0), + feeAggregator: FEE_AGGREGATOR, + allowListAdmin: address(0) + }); // Invalid price reg reverts. newConfig.feeQuoter = address(0); @@ -638,8 +713,13 @@ contract OnRamp_setDynamicConfig is OnRampSetup { } function test_SetConfigInvalidConfigFeeAggregatorEqAddressZero_Revert() public { - OnRamp.DynamicConfig memory newConfig = - OnRamp.DynamicConfig({feeQuoter: address(23423), messageValidator: address(0), feeAggregator: address(0)}); + OnRamp.DynamicConfig memory newConfig = OnRamp.DynamicConfig({ + feeQuoter: address(23423), + messageValidator: address(0), + feeAggregator: address(0), + allowListAdmin: address(0) + }); + vm.expectRevert(OnRamp.InvalidConfig.selector); s_onRamp.setDynamicConfig(newConfig); } @@ -740,7 +820,7 @@ contract OnRamp_applyDestChainConfigUpdates is OnRampSetup { // supports disabling a lane by setting a router to zero vm.expectEmit(); - emit OnRamp.DestChainConfigSet(DEST_CHAIN_SELECTOR, OnRamp.DestChainConfig(0, IRouter(address(0)))); + emit OnRamp.DestChainConfigSet(DEST_CHAIN_SELECTOR, 0, IRouter(address(0)), false); s_onRamp.applyDestChainConfigUpdates(configArgs); assertEq(address(0), address(s_onRamp.getRouter(DEST_CHAIN_SELECTOR))); @@ -749,9 +829,9 @@ contract OnRamp_applyDestChainConfigUpdates is OnRampSetup { configArgs[0] = OnRamp.DestChainConfigArgs({destChainSelector: DEST_CHAIN_SELECTOR, router: s_sourceRouter}); configArgs[1] = OnRamp.DestChainConfigArgs({destChainSelector: 9999, router: IRouter(address(9999))}); vm.expectEmit(); - emit OnRamp.DestChainConfigSet(DEST_CHAIN_SELECTOR, OnRamp.DestChainConfig(0, s_sourceRouter)); + emit OnRamp.DestChainConfigSet(DEST_CHAIN_SELECTOR, 0, s_sourceRouter, false); vm.expectEmit(); - emit OnRamp.DestChainConfigSet(9999, OnRamp.DestChainConfig(0, IRouter(address(9999)))); + emit OnRamp.DestChainConfigSet(9999, 0, IRouter(address(9999)), false); s_onRamp.applyDestChainConfigUpdates(configArgs); assertEq(address(s_sourceRouter), address(s_onRamp.getRouter(DEST_CHAIN_SELECTOR))); assertEq(address(9999), address(s_onRamp.getRouter(9999))); @@ -763,7 +843,7 @@ contract OnRamp_applyDestChainConfigUpdates is OnRampSetup { assertEq(numLogs, vm.getRecordedLogs().length); // indicates no changes made } - function test_ApplyDestChainConfigUpdates_WithInalidChainSelector_Revert() external { + function test_ApplyDestChainConfigUpdates_WithInvalidChainSelector_Revert() external { vm.stopPrank(); vm.startPrank(OWNER); OnRamp.DestChainConfigArgs[] memory configArgs = new OnRamp.DestChainConfigArgs[](1); @@ -772,3 +852,141 @@ contract OnRamp_applyDestChainConfigUpdates is OnRampSetup { s_onRamp.applyDestChainConfigUpdates(configArgs); } } + +contract OnRamp_allowListConfigUpdates is OnRampSetup { + function test_applyAllowList_Success() public { + vm.stopPrank(); + vm.startPrank(OWNER); + + OnRamp.DestChainConfigArgs[] memory configArgs = new OnRamp.DestChainConfigArgs[](2); + configArgs[0] = OnRamp.DestChainConfigArgs({destChainSelector: DEST_CHAIN_SELECTOR, router: s_sourceRouter}); + configArgs[1] = OnRamp.DestChainConfigArgs({destChainSelector: 9999, router: IRouter(address(9999))}); + vm.expectEmit(); + emit OnRamp.DestChainConfigSet(DEST_CHAIN_SELECTOR, 0, s_sourceRouter, false); + vm.expectEmit(); + emit OnRamp.DestChainConfigSet(9999, 0, IRouter(address(9999)), false); + s_onRamp.applyDestChainConfigUpdates(configArgs); + + (uint64 sequenceNumber, bool allowListEnabled, address router) = s_onRamp.getDestChainConfig(9999); + assertEq(sequenceNumber, 0); + assertEq(allowListEnabled, false); + assertEq(router, address(9999)); + + uint64[] memory destinationChainSelectors = new uint64[](2); + destinationChainSelectors[0] = DEST_CHAIN_SELECTOR; + destinationChainSelectors[1] = uint64(99999); + + address[] memory addedAllowlistedSenders = new address[](4); + addedAllowlistedSenders[0] = vm.addr(1); + addedAllowlistedSenders[1] = vm.addr(2); + addedAllowlistedSenders[2] = vm.addr(3); + addedAllowlistedSenders[3] = vm.addr(4); + + vm.expectEmit(); + emit OnRamp.AllowListSendersAdded(DEST_CHAIN_SELECTOR, addedAllowlistedSenders); + + OnRamp.AllowListConfigArgs memory allowListConfigArgs = OnRamp.AllowListConfigArgs({ + allowListEnabled: true, + destChainSelector: DEST_CHAIN_SELECTOR, + addedAllowlistedSenders: addedAllowlistedSenders, + removedAllowlistedSenders: new address[](0) + }); + + OnRamp.AllowListConfigArgs[] memory applyAllowListConfigArgsItems = new OnRamp.AllowListConfigArgs[](1); + applyAllowListConfigArgsItems[0] = allowListConfigArgs; + + s_onRamp.applyAllowListUpdates(applyAllowListConfigArgsItems); + assertEq(4, s_onRamp.getAllowedSendersList(DEST_CHAIN_SELECTOR).length); + + assertEq(addedAllowlistedSenders, s_onRamp.getAllowedSendersList(DEST_CHAIN_SELECTOR)); + + address[] memory removedAllowlistedSenders = new address[](1); + removedAllowlistedSenders[0] = vm.addr(2); + + vm.expectEmit(); + emit OnRamp.AllowListSendersRemoved(DEST_CHAIN_SELECTOR, removedAllowlistedSenders); + + allowListConfigArgs = OnRamp.AllowListConfigArgs({ + allowListEnabled: true, + destChainSelector: DEST_CHAIN_SELECTOR, + addedAllowlistedSenders: new address[](0), + removedAllowlistedSenders: removedAllowlistedSenders + }); + + OnRamp.AllowListConfigArgs[] memory allowListConfigArgsItems_2 = new OnRamp.AllowListConfigArgs[](1); + allowListConfigArgsItems_2[0] = allowListConfigArgs; + + s_onRamp.applyAllowListUpdates(allowListConfigArgsItems_2); + assertEq(3, s_onRamp.getAllowedSendersList(DEST_CHAIN_SELECTOR).length); + + addedAllowlistedSenders = new address[](2); + addedAllowlistedSenders[0] = vm.addr(5); + addedAllowlistedSenders[1] = vm.addr(6); + + removedAllowlistedSenders = new address[](2); + removedAllowlistedSenders[0] = vm.addr(1); + removedAllowlistedSenders[1] = vm.addr(3); + + vm.expectEmit(); + emit OnRamp.AllowListSendersAdded(DEST_CHAIN_SELECTOR, addedAllowlistedSenders); + emit OnRamp.AllowListSendersRemoved(DEST_CHAIN_SELECTOR, removedAllowlistedSenders); + + allowListConfigArgs = OnRamp.AllowListConfigArgs({ + allowListEnabled: true, + destChainSelector: DEST_CHAIN_SELECTOR, + addedAllowlistedSenders: addedAllowlistedSenders, + removedAllowlistedSenders: removedAllowlistedSenders + }); + + OnRamp.AllowListConfigArgs[] memory allowListConfigArgsItems_3 = new OnRamp.AllowListConfigArgs[](1); + allowListConfigArgsItems_3[0] = allowListConfigArgs; + + s_onRamp.applyAllowListUpdates(allowListConfigArgsItems_3); + assertEq(3, s_onRamp.getAllowedSendersList(DEST_CHAIN_SELECTOR).length); + } + + function test_applyAllowList_Revert() public { + vm.stopPrank(); + vm.startPrank(OWNER); + + OnRamp.DestChainConfigArgs[] memory configArgs = new OnRamp.DestChainConfigArgs[](2); + configArgs[0] = OnRamp.DestChainConfigArgs({destChainSelector: DEST_CHAIN_SELECTOR, router: s_sourceRouter}); + configArgs[1] = OnRamp.DestChainConfigArgs({destChainSelector: 9999, router: IRouter(address(9999))}); + vm.expectEmit(); + emit OnRamp.DestChainConfigSet(DEST_CHAIN_SELECTOR, 0, s_sourceRouter, false); + vm.expectEmit(); + emit OnRamp.DestChainConfigSet(9999, 0, IRouter(address(9999)), false); + s_onRamp.applyDestChainConfigUpdates(configArgs); + + uint64[] memory destinationChainSelectors = new uint64[](2); + destinationChainSelectors[0] = DEST_CHAIN_SELECTOR; + destinationChainSelectors[1] = uint64(99999); + + address[] memory addedAllowlistedSenders = new address[](4); + addedAllowlistedSenders[0] = vm.addr(1); + addedAllowlistedSenders[1] = vm.addr(2); + addedAllowlistedSenders[2] = vm.addr(3); + addedAllowlistedSenders[3] = vm.addr(4); + + OnRamp.AllowListConfigArgs memory allowListConfigArgs = OnRamp.AllowListConfigArgs({ + allowListEnabled: true, + destChainSelector: DEST_CHAIN_SELECTOR, + addedAllowlistedSenders: addedAllowlistedSenders, + removedAllowlistedSenders: new address[](0) + }); + + OnRamp.AllowListConfigArgs[] memory applyAllowListConfigArgsItems = new OnRamp.AllowListConfigArgs[](1); + applyAllowListConfigArgsItems[0] = allowListConfigArgs; + + vm.startPrank(STRANGER); + vm.expectRevert(OnRamp.OnlyCallableByOwnerOrAllowlistAdmin.selector); + s_onRamp.applyAllowListUpdates(applyAllowListConfigArgsItems); + vm.stopPrank(); + + applyAllowListConfigArgsItems[0].addedAllowlistedSenders[0] = address(0); + vm.expectRevert(abi.encodeWithSelector(OnRamp.InvalidAllowListRequest.selector, DEST_CHAIN_SELECTOR)); + vm.startPrank(OWNER); + s_onRamp.applyAllowListUpdates(applyAllowListConfigArgsItems); + vm.stopPrank(); + } +} diff --git a/contracts/src/v0.8/ccip/test/onRamp/OnRampSetup.t.sol b/contracts/src/v0.8/ccip/test/onRamp/OnRampSetup.t.sol index 635a75c843..f43bce6a99 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/OnRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/OnRampSetup.t.sol @@ -85,7 +85,12 @@ contract OnRampSetup is FeeQuoterFeeSetup { } function _generateDynamicOnRampConfig(address feeQuoter) internal pure returns (OnRamp.DynamicConfig memory) { - return OnRamp.DynamicConfig({feeQuoter: feeQuoter, messageValidator: address(0), feeAggregator: FEE_AGGREGATOR}); + return OnRamp.DynamicConfig({ + feeQuoter: feeQuoter, + messageValidator: address(0), + feeAggregator: FEE_AGGREGATOR, + allowListAdmin: address(0) + }); } // Slicing is only available for calldata. So we have to build a new bytes array. diff --git a/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go b/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go index ed5fe1aedb..05a91eb289 100644 --- a/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go +++ b/core/capabilities/ccip/ccip_integration_tests/ccipreader/ccipreader_test.go @@ -19,6 +19,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/types" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" @@ -115,7 +116,7 @@ func TestCCIPReader_CommitReportsGTETimestamp(t *testing.T) { ) require.NoError(t, err) return len(reports) == numReports-1 - }, 10*time.Second, 50*time.Millisecond) + }, tests.WaitTimeout(t), 50*time.Millisecond) assert.Len(t, reports[0].Report.MerkleRoots, 1) assert.Equal(t, chainS1, reports[0].Report.MerkleRoots[0].ChainSel) @@ -268,7 +269,7 @@ func TestCCIPReader_MsgsBetweenSeqNums(t *testing.T) { ) require.NoError(t, err) return len(msgs) == 2 - }, 10*time.Second, 100*time.Millisecond) + }, tests.WaitTimeout(t), 100*time.Millisecond) require.Len(t, msgs, 2) // sort to ensure ascending order of sequence numbers. diff --git a/core/capabilities/ccip/delegate.go b/core/capabilities/ccip/delegate.go index ef3822c4de..2a39334549 100644 --- a/core/capabilities/ccip/delegate.go +++ b/core/capabilities/ccip/delegate.go @@ -18,6 +18,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" + cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/config" kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" @@ -134,21 +135,36 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, spec job.Job) (services ccipConfigBinding, ) - oracleCreator := oraclecreator.New( - ocrKeys, - transmitterKeys, - d.chains, - d.peerWrapper, - spec.ExternalJobID, - spec.ID, - d.isNewlyCreatedJob, - spec.CCIPSpec.PluginConfig, - ocrDB, - d.lggr, - d.monitoringEndpointGen, - bootstrapperLocators, - hcr, - ) + // if bootstrappers are provided we assume that the node is a plugin oracle. + // the reason for this is that bootstrap oracles do not need to be aware + // of other bootstrap oracles. however, plugin oracles, at least initially, + // must be aware of available bootstrappers. + var oracleCreator cctypes.OracleCreator + if len(spec.CCIPSpec.P2PV2Bootstrappers) > 0 { + oracleCreator = oraclecreator.NewPluginOracleCreator( + ocrKeys, + transmitterKeys, + d.chains, + d.peerWrapper, + spec.ExternalJobID, + spec.ID, + d.isNewlyCreatedJob, + spec.CCIPSpec.PluginConfig, + ocrDB, + d.lggr, + d.monitoringEndpointGen, + bootstrapperLocators, + hcr, + ) + } else { + oracleCreator = oraclecreator.NewBootstrapOracleCreator( + d.peerWrapper, + bootstrapperLocators, + ocrDB, + d.monitoringEndpointGen, + d.lggr, + ) + } capLauncher := launcher.New( spec.CCIPSpec.CapabilityVersion, @@ -156,8 +172,8 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, spec job.Job) (services ragep2ptypes.PeerID(p2pID.PeerID()), d.lggr, hcr, - oracleCreator, 12*time.Second, + oracleCreator, ) // register the capability launcher with the registry syncer diff --git a/core/capabilities/ccip/launcher/bluegreen.go b/core/capabilities/ccip/launcher/bluegreen.go index 6245846629..c15f8c038f 100644 --- a/core/capabilities/ccip/launcher/bluegreen.go +++ b/core/capabilities/ccip/launcher/bluegreen.go @@ -16,21 +16,11 @@ type blueGreenDeployment struct { // blue must always be present. blue cctypes.CCIPOracle - // bootstrapBlue is the bootstrap node of the blue OCR instance. - // Only a subset of the DON will be running bootstrap instances, - // so this may be nil. - bootstrapBlue cctypes.CCIPOracle - // green is the green OCR instance. // green may or may not be present. // green must never be present if blue is not present. // TODO: should we enforce this invariant somehow? green cctypes.CCIPOracle - - // bootstrapGreen is the bootstrap node of the green OCR instance. - // Only a subset of the DON will be running bootstrap instances, - // so this may be nil, even when green is not nil. - bootstrapGreen cctypes.CCIPOracle } // ccipDeployment represents blue-green deployments of both commit and exec @@ -44,33 +34,21 @@ type ccipDeployment struct { func (c *ccipDeployment) Close() error { var err error - // shutdown blue commit instances. + // shutdown blue commit instance. err = multierr.Append(err, c.commit.blue.Close()) - if c.commit.bootstrapBlue != nil { - err = multierr.Append(err, c.commit.bootstrapBlue.Close()) - } - // shutdown green commit instances. + // shutdown green commit instance. if c.commit.green != nil { err = multierr.Append(err, c.commit.green.Close()) } - if c.commit.bootstrapGreen != nil { - err = multierr.Append(err, c.commit.bootstrapGreen.Close()) - } - // shutdown blue exec instances. + // shutdown blue exec instance. err = multierr.Append(err, c.exec.blue.Close()) - if c.exec.bootstrapBlue != nil { - err = multierr.Append(err, c.exec.bootstrapBlue.Close()) - } - // shutdown green exec instances. + // shutdown green exec instance. if c.exec.green != nil { err = multierr.Append(err, c.exec.green.Close()) } - if c.exec.bootstrapGreen != nil { - err = multierr.Append(err, c.exec.bootstrapGreen.Close()) - } return err } @@ -80,13 +58,7 @@ func (c *ccipDeployment) StartBlue() error { var err error err = multierr.Append(err, c.commit.blue.Start()) - if c.commit.bootstrapBlue != nil { - err = multierr.Append(err, c.commit.bootstrapBlue.Start()) - } err = multierr.Append(err, c.exec.blue.Start()) - if c.exec.bootstrapBlue != nil { - err = multierr.Append(err, c.exec.bootstrapBlue.Start()) - } return err } @@ -96,13 +68,7 @@ func (c *ccipDeployment) CloseBlue() error { var err error err = multierr.Append(err, c.commit.blue.Close()) - if c.commit.bootstrapBlue != nil { - err = multierr.Append(err, c.commit.bootstrapBlue.Close()) - } err = multierr.Append(err, c.exec.blue.Close()) - if c.exec.bootstrapBlue != nil { - err = multierr.Append(err, c.exec.bootstrapBlue.Close()) - } return err } @@ -127,28 +93,16 @@ func (c *ccipDeployment) HandleBlueGreen(prevDeployment *ccipDeployment) error { var err error if prevDeployment.commit.green != nil && c.commit.green == nil { err = multierr.Append(err, prevDeployment.commit.blue.Close()) - if prevDeployment.commit.bootstrapBlue != nil { - err = multierr.Append(err, prevDeployment.commit.bootstrapBlue.Close()) - } } else if prevDeployment.commit.green == nil && c.commit.green != nil { err = multierr.Append(err, c.commit.green.Start()) - if c.commit.bootstrapGreen != nil { - err = multierr.Append(err, c.commit.bootstrapGreen.Start()) - } } else { return fmt.Errorf("invalid blue-green deployment transition") } if prevDeployment.exec.green != nil && c.exec.green == nil { err = multierr.Append(err, prevDeployment.exec.blue.Close()) - if prevDeployment.exec.bootstrapBlue != nil { - err = multierr.Append(err, prevDeployment.exec.bootstrapBlue.Close()) - } } else if prevDeployment.exec.green == nil && c.exec.green != nil { err = multierr.Append(err, c.exec.green.Start()) - if c.exec.bootstrapGreen != nil { - err = multierr.Append(err, c.exec.bootstrapGreen.Start()) - } } else { return fmt.Errorf("invalid blue-green deployment transition") } diff --git a/core/capabilities/ccip/launcher/bluegreen_test.go b/core/capabilities/ccip/launcher/bluegreen_test.go index 9fd71a0cb4..965491180e 100644 --- a/core/capabilities/ccip/launcher/bluegreen_test.go +++ b/core/capabilities/ccip/launcher/bluegreen_test.go @@ -14,14 +14,10 @@ import ( func Test_ccipDeployment_Close(t *testing.T) { type args struct { - commitBlue *mocktypes.CCIPOracle - commitBlueBootstrap *mocktypes.CCIPOracle - commitGreen *mocktypes.CCIPOracle - commitGreenBootstrap *mocktypes.CCIPOracle - execBlue *mocktypes.CCIPOracle - execBlueBootstrap *mocktypes.CCIPOracle - execGreen *mocktypes.CCIPOracle - execGreenBootstrap *mocktypes.CCIPOracle + commitBlue *mocktypes.CCIPOracle + commitGreen *mocktypes.CCIPOracle + execBlue *mocktypes.CCIPOracle + execGreen *mocktypes.CCIPOracle } tests := []struct { name string @@ -33,12 +29,10 @@ func Test_ccipDeployment_Close(t *testing.T) { { name: "no errors, blue only", args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - commitGreen: nil, - commitGreenBootstrap: nil, - execBlue: mocktypes.NewCCIPOracle(t), - execGreen: nil, - execGreenBootstrap: nil, + commitBlue: mocktypes.NewCCIPOracle(t), + commitGreen: nil, + execBlue: mocktypes.NewCCIPOracle(t), + execGreen: nil, }, expect: func(t *testing.T, args args) { args.commitBlue.On("Close").Return(nil).Once() @@ -90,62 +84,6 @@ func Test_ccipDeployment_Close(t *testing.T) { }, wantErr: true, }, - { - name: "bootstrap blue also closed", - args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - execBlueBootstrap: mocktypes.NewCCIPOracle(t), - }, - expect: func(t *testing.T, args args) { - args.commitBlue.On("Close").Return(nil).Once() - args.commitBlueBootstrap.On("Close").Return(nil).Once() - args.execBlue.On("Close").Return(nil).Once() - args.execBlueBootstrap.On("Close").Return(nil).Once() - }, - asserts: func(t *testing.T, args args) { - args.commitBlue.AssertExpectations(t) - args.commitBlueBootstrap.AssertExpectations(t) - args.execBlue.AssertExpectations(t) - args.execBlueBootstrap.AssertExpectations(t) - }, - wantErr: false, - }, - { - name: "bootstrap green also closed", - args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: mocktypes.NewCCIPOracle(t), - commitGreen: mocktypes.NewCCIPOracle(t), - commitGreenBootstrap: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - execBlueBootstrap: mocktypes.NewCCIPOracle(t), - execGreen: mocktypes.NewCCIPOracle(t), - execGreenBootstrap: mocktypes.NewCCIPOracle(t), - }, - expect: func(t *testing.T, args args) { - args.commitBlue.On("Close").Return(nil).Once() - args.commitBlueBootstrap.On("Close").Return(nil).Once() - args.commitGreen.On("Close").Return(nil).Once() - args.commitGreenBootstrap.On("Close").Return(nil).Once() - args.execBlue.On("Close").Return(nil).Once() - args.execBlueBootstrap.On("Close").Return(nil).Once() - args.execGreen.On("Close").Return(nil).Once() - args.execGreenBootstrap.On("Close").Return(nil).Once() - }, - asserts: func(t *testing.T, args args) { - args.commitBlue.AssertExpectations(t) - args.commitBlueBootstrap.AssertExpectations(t) - args.commitGreen.AssertExpectations(t) - args.commitGreenBootstrap.AssertExpectations(t) - args.execBlue.AssertExpectations(t) - args.execBlueBootstrap.AssertExpectations(t) - args.execGreen.AssertExpectations(t) - args.execGreenBootstrap.AssertExpectations(t) - }, - wantErr: false, - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -160,22 +98,10 @@ func Test_ccipDeployment_Close(t *testing.T) { if tt.args.commitGreen != nil { c.commit.green = tt.args.commitGreen } - if tt.args.commitBlueBootstrap != nil { - c.commit.bootstrapBlue = tt.args.commitBlueBootstrap - } - if tt.args.commitGreenBootstrap != nil { - c.commit.bootstrapGreen = tt.args.commitGreenBootstrap - } if tt.args.execGreen != nil { c.exec.green = tt.args.execGreen } - if tt.args.execBlueBootstrap != nil { - c.exec.bootstrapBlue = tt.args.execBlueBootstrap - } - if tt.args.execGreenBootstrap != nil { - c.exec.bootstrapGreen = tt.args.execGreenBootstrap - } tt.expect(t, tt.args) defer tt.asserts(t, tt.args) @@ -191,10 +117,8 @@ func Test_ccipDeployment_Close(t *testing.T) { func Test_ccipDeployment_StartBlue(t *testing.T) { type args struct { - commitBlue *mocktypes.CCIPOracle - commitBlueBootstrap *mocktypes.CCIPOracle - execBlue *mocktypes.CCIPOracle - execBlueBootstrap *mocktypes.CCIPOracle + commitBlue *mocktypes.CCIPOracle + execBlue *mocktypes.CCIPOracle } tests := []struct { name string @@ -204,12 +128,10 @@ func Test_ccipDeployment_StartBlue(t *testing.T) { wantErr bool }{ { - name: "no errors, no bootstrap", + name: "no errors", args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: nil, - execBlueBootstrap: nil, + commitBlue: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), }, expect: func(t *testing.T, args args) { args.commitBlue.On("Start").Return(nil).Once() @@ -221,35 +143,11 @@ func Test_ccipDeployment_StartBlue(t *testing.T) { }, wantErr: false, }, - { - name: "no errors, with bootstrap", - args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: mocktypes.NewCCIPOracle(t), - execBlueBootstrap: mocktypes.NewCCIPOracle(t), - }, - expect: func(t *testing.T, args args) { - args.commitBlue.On("Start").Return(nil).Once() - args.commitBlueBootstrap.On("Start").Return(nil).Once() - args.execBlue.On("Start").Return(nil).Once() - args.execBlueBootstrap.On("Start").Return(nil).Once() - }, - asserts: func(t *testing.T, args args) { - args.commitBlue.AssertExpectations(t) - args.commitBlueBootstrap.AssertExpectations(t) - args.execBlue.AssertExpectations(t) - args.execBlueBootstrap.AssertExpectations(t) - }, - wantErr: false, - }, { name: "error on commit blue", args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: nil, - execBlueBootstrap: nil, + commitBlue: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), }, expect: func(t *testing.T, args args) { args.commitBlue.On("Start").Return(errors.New("failed")).Once() @@ -264,10 +162,8 @@ func Test_ccipDeployment_StartBlue(t *testing.T) { { name: "error on exec blue", args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: nil, - execBlueBootstrap: nil, + commitBlue: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), }, expect: func(t *testing.T, args args) { args.commitBlue.On("Start").Return(nil).Once() @@ -279,46 +175,6 @@ func Test_ccipDeployment_StartBlue(t *testing.T) { }, wantErr: true, }, - { - name: "error on commit blue bootstrap", - args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: mocktypes.NewCCIPOracle(t), - execBlueBootstrap: nil, - }, - expect: func(t *testing.T, args args) { - args.commitBlue.On("Start").Return(nil).Once() - args.commitBlueBootstrap.On("Start").Return(errors.New("failed")).Once() - args.execBlue.On("Start").Return(nil).Once() - }, - asserts: func(t *testing.T, args args) { - args.commitBlue.AssertExpectations(t) - args.commitBlueBootstrap.AssertExpectations(t) - args.execBlue.AssertExpectations(t) - }, - wantErr: true, - }, - { - name: "error on exec blue bootstrap", - args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: nil, - execBlueBootstrap: mocktypes.NewCCIPOracle(t), - }, - expect: func(t *testing.T, args args) { - args.commitBlue.On("Start").Return(nil).Once() - args.execBlue.On("Start").Return(nil).Once() - args.execBlueBootstrap.On("Start").Return(errors.New("failed")).Once() - }, - asserts: func(t *testing.T, args args) { - args.commitBlue.AssertExpectations(t) - args.execBlue.AssertExpectations(t) - args.execBlueBootstrap.AssertExpectations(t) - }, - wantErr: true, - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -330,12 +186,6 @@ func Test_ccipDeployment_StartBlue(t *testing.T) { blue: tt.args.execBlue, }, } - if tt.args.commitBlueBootstrap != nil { - c.commit.bootstrapBlue = tt.args.commitBlueBootstrap - } - if tt.args.execBlueBootstrap != nil { - c.exec.bootstrapBlue = tt.args.execBlueBootstrap - } tt.expect(t, tt.args) defer tt.asserts(t, tt.args) @@ -351,10 +201,8 @@ func Test_ccipDeployment_StartBlue(t *testing.T) { func Test_ccipDeployment_CloseBlue(t *testing.T) { type args struct { - commitBlue *mocktypes.CCIPOracle - commitBlueBootstrap *mocktypes.CCIPOracle - execBlue *mocktypes.CCIPOracle - execBlueBootstrap *mocktypes.CCIPOracle + commitBlue *mocktypes.CCIPOracle + execBlue *mocktypes.CCIPOracle } tests := []struct { name string @@ -364,12 +212,10 @@ func Test_ccipDeployment_CloseBlue(t *testing.T) { wantErr bool }{ { - name: "no errors, no bootstrap", + name: "no errors", args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: nil, - execBlueBootstrap: nil, + commitBlue: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), }, expect: func(t *testing.T, args args) { args.commitBlue.On("Close").Return(nil).Once() @@ -381,35 +227,11 @@ func Test_ccipDeployment_CloseBlue(t *testing.T) { }, wantErr: false, }, - { - name: "no errors, with bootstrap", - args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: mocktypes.NewCCIPOracle(t), - execBlueBootstrap: mocktypes.NewCCIPOracle(t), - }, - expect: func(t *testing.T, args args) { - args.commitBlue.On("Close").Return(nil).Once() - args.commitBlueBootstrap.On("Close").Return(nil).Once() - args.execBlue.On("Close").Return(nil).Once() - args.execBlueBootstrap.On("Close").Return(nil).Once() - }, - asserts: func(t *testing.T, args args) { - args.commitBlue.AssertExpectations(t) - args.commitBlueBootstrap.AssertExpectations(t) - args.execBlue.AssertExpectations(t) - args.execBlueBootstrap.AssertExpectations(t) - }, - wantErr: false, - }, { name: "error on commit blue", args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: nil, - execBlueBootstrap: nil, + commitBlue: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), }, expect: func(t *testing.T, args args) { args.commitBlue.On("Close").Return(errors.New("failed")).Once() @@ -424,10 +246,8 @@ func Test_ccipDeployment_CloseBlue(t *testing.T) { { name: "error on exec blue", args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: nil, - execBlueBootstrap: nil, + commitBlue: mocktypes.NewCCIPOracle(t), + execBlue: mocktypes.NewCCIPOracle(t), }, expect: func(t *testing.T, args args) { args.commitBlue.On("Close").Return(nil).Once() @@ -439,46 +259,6 @@ func Test_ccipDeployment_CloseBlue(t *testing.T) { }, wantErr: true, }, - { - name: "error on commit blue bootstrap", - args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: mocktypes.NewCCIPOracle(t), - execBlueBootstrap: nil, - }, - expect: func(t *testing.T, args args) { - args.commitBlue.On("Close").Return(nil).Once() - args.commitBlueBootstrap.On("Close").Return(errors.New("failed")).Once() - args.execBlue.On("Close").Return(nil).Once() - }, - asserts: func(t *testing.T, args args) { - args.commitBlue.AssertExpectations(t) - args.commitBlueBootstrap.AssertExpectations(t) - args.execBlue.AssertExpectations(t) - }, - wantErr: true, - }, - { - name: "error on exec blue bootstrap", - args: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: nil, - execBlueBootstrap: mocktypes.NewCCIPOracle(t), - }, - expect: func(t *testing.T, args args) { - args.commitBlue.On("Close").Return(nil).Once() - args.execBlue.On("Close").Return(nil).Once() - args.execBlueBootstrap.On("Close").Return(errors.New("failed")).Once() - }, - asserts: func(t *testing.T, args args) { - args.commitBlue.AssertExpectations(t) - args.execBlue.AssertExpectations(t) - args.execBlueBootstrap.AssertExpectations(t) - }, - wantErr: true, - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -490,12 +270,6 @@ func Test_ccipDeployment_CloseBlue(t *testing.T) { blue: tt.args.execBlue, }, } - if tt.args.commitBlueBootstrap != nil { - c.commit.bootstrapBlue = tt.args.commitBlueBootstrap - } - if tt.args.execBlueBootstrap != nil { - c.exec.bootstrapBlue = tt.args.execBlueBootstrap - } tt.expect(t, tt.args) defer tt.asserts(t, tt.args) @@ -515,14 +289,10 @@ func Test_ccipDeployment_HandleBlueGreen_PrevDeploymentNil(t *testing.T) { func Test_ccipDeployment_HandleBlueGreen(t *testing.T) { type args struct { - commitBlue *mocktypes.CCIPOracle - commitBlueBootstrap *mocktypes.CCIPOracle - commitGreen *mocktypes.CCIPOracle - commitGreenBootstrap *mocktypes.CCIPOracle - execBlue *mocktypes.CCIPOracle - execBlueBootstrap *mocktypes.CCIPOracle - execGreen *mocktypes.CCIPOracle - execGreenBootstrap *mocktypes.CCIPOracle + commitBlue *mocktypes.CCIPOracle + commitGreen *mocktypes.CCIPOracle + execBlue *mocktypes.CCIPOracle + execGreen *mocktypes.CCIPOracle } tests := []struct { name string @@ -533,7 +303,7 @@ func Test_ccipDeployment_HandleBlueGreen(t *testing.T) { wantErr bool }{ { - name: "promotion blue to green, no bootstrap", + name: "promotion blue to green", argsPrevDeployment: args{ commitBlue: mocktypes.NewCCIPOracle(t), commitGreen: mocktypes.NewCCIPOracle(t), @@ -557,43 +327,7 @@ func Test_ccipDeployment_HandleBlueGreen(t *testing.T) { wantErr: false, }, { - name: "promotion blue to green, with bootstrap", - argsPrevDeployment: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: mocktypes.NewCCIPOracle(t), - commitGreen: mocktypes.NewCCIPOracle(t), - commitGreenBootstrap: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - execBlueBootstrap: mocktypes.NewCCIPOracle(t), - execGreen: mocktypes.NewCCIPOracle(t), - execGreenBootstrap: mocktypes.NewCCIPOracle(t), - }, - argsFutureDeployment: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: mocktypes.NewCCIPOracle(t), - commitGreen: nil, - commitGreenBootstrap: nil, - execBlue: mocktypes.NewCCIPOracle(t), - execBlueBootstrap: mocktypes.NewCCIPOracle(t), - execGreen: nil, - execGreenBootstrap: nil, - }, - expect: func(t *testing.T, args args, argsPrevDeployment args) { - argsPrevDeployment.commitBlue.On("Close").Return(nil).Once() - argsPrevDeployment.commitBlueBootstrap.On("Close").Return(nil).Once() - argsPrevDeployment.execBlue.On("Close").Return(nil).Once() - argsPrevDeployment.execBlueBootstrap.On("Close").Return(nil).Once() - }, - asserts: func(t *testing.T, args args, argsPrevDeployment args) { - argsPrevDeployment.commitBlue.AssertExpectations(t) - argsPrevDeployment.commitBlueBootstrap.AssertExpectations(t) - argsPrevDeployment.execBlue.AssertExpectations(t) - argsPrevDeployment.execBlueBootstrap.AssertExpectations(t) - }, - wantErr: false, - }, - { - name: "new green deployment, no bootstrap", + name: "new green deployment", argsPrevDeployment: args{ commitBlue: mocktypes.NewCCIPOracle(t), commitGreen: nil, @@ -616,42 +350,6 @@ func Test_ccipDeployment_HandleBlueGreen(t *testing.T) { }, wantErr: false, }, - { - name: "new green deployment, with bootstrap", - argsPrevDeployment: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: mocktypes.NewCCIPOracle(t), - commitGreen: nil, - commitGreenBootstrap: nil, - execBlue: mocktypes.NewCCIPOracle(t), - execBlueBootstrap: mocktypes.NewCCIPOracle(t), - execGreen: nil, - execGreenBootstrap: nil, - }, - argsFutureDeployment: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: mocktypes.NewCCIPOracle(t), - commitGreen: mocktypes.NewCCIPOracle(t), - commitGreenBootstrap: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - execBlueBootstrap: mocktypes.NewCCIPOracle(t), - execGreen: mocktypes.NewCCIPOracle(t), - execGreenBootstrap: mocktypes.NewCCIPOracle(t), - }, - expect: func(t *testing.T, args args, argsPrevDeployment args) { - args.commitGreen.On("Start").Return(nil).Once() - args.commitGreenBootstrap.On("Start").Return(nil).Once() - args.execGreen.On("Start").Return(nil).Once() - args.execGreenBootstrap.On("Start").Return(nil).Once() - }, - asserts: func(t *testing.T, args args, argsPrevDeployment args) { - args.commitGreen.AssertExpectations(t) - args.commitGreenBootstrap.AssertExpectations(t) - args.execGreen.AssertExpectations(t) - args.execGreenBootstrap.AssertExpectations(t) - }, - wantErr: false, - }, { name: "error on commit green start", argsPrevDeployment: args{ @@ -700,42 +398,6 @@ func Test_ccipDeployment_HandleBlueGreen(t *testing.T) { }, wantErr: true, }, - { - name: "error on commit green bootstrap start", - argsPrevDeployment: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: mocktypes.NewCCIPOracle(t), - commitGreen: nil, - commitGreenBootstrap: nil, - execBlue: mocktypes.NewCCIPOracle(t), - execBlueBootstrap: mocktypes.NewCCIPOracle(t), - execGreen: nil, - execGreenBootstrap: nil, - }, - argsFutureDeployment: args{ - commitBlue: mocktypes.NewCCIPOracle(t), - commitBlueBootstrap: mocktypes.NewCCIPOracle(t), - commitGreen: mocktypes.NewCCIPOracle(t), - commitGreenBootstrap: mocktypes.NewCCIPOracle(t), - execBlue: mocktypes.NewCCIPOracle(t), - execBlueBootstrap: mocktypes.NewCCIPOracle(t), - execGreen: mocktypes.NewCCIPOracle(t), - execGreenBootstrap: mocktypes.NewCCIPOracle(t), - }, - expect: func(t *testing.T, args args, argsPrevDeployment args) { - args.commitGreen.On("Start").Return(nil).Once() - args.commitGreenBootstrap.On("Start").Return(errors.New("failed")).Once() - args.execGreen.On("Start").Return(nil).Once() - args.execGreenBootstrap.On("Start").Return(nil).Once() - }, - asserts: func(t *testing.T, args args, argsPrevDeployment args) { - args.commitGreen.AssertExpectations(t) - args.commitGreenBootstrap.AssertExpectations(t) - args.execGreen.AssertExpectations(t) - args.execGreenBootstrap.AssertExpectations(t) - }, - wantErr: true, - }, { name: "invalid blue-green deployment transition commit: both prev and future deployment have green", argsPrevDeployment: args{ @@ -755,7 +417,7 @@ func Test_ccipDeployment_HandleBlueGreen(t *testing.T) { wantErr: true, }, { - name: "invalid blue-green deployment transition exec: both prev and future deployment have green", + name: "invalid blue-green deployment transition exec: both prev and future exec deployment have green", argsPrevDeployment: args{ commitBlue: mocktypes.NewCCIPOracle(t), commitGreen: nil, @@ -790,21 +452,9 @@ func Test_ccipDeployment_HandleBlueGreen(t *testing.T) { if tt.argsFutureDeployment.commitGreen != nil { futDeployment.commit.green = tt.argsFutureDeployment.commitGreen } - if tt.argsFutureDeployment.commitBlueBootstrap != nil { - futDeployment.commit.bootstrapBlue = tt.argsFutureDeployment.commitBlueBootstrap - } - if tt.argsFutureDeployment.commitGreenBootstrap != nil { - futDeployment.commit.bootstrapGreen = tt.argsFutureDeployment.commitGreenBootstrap - } if tt.argsFutureDeployment.execGreen != nil { futDeployment.exec.green = tt.argsFutureDeployment.execGreen } - if tt.argsFutureDeployment.execBlueBootstrap != nil { - futDeployment.exec.bootstrapBlue = tt.argsFutureDeployment.execBlueBootstrap - } - if tt.argsFutureDeployment.execGreenBootstrap != nil { - futDeployment.exec.bootstrapGreen = tt.argsFutureDeployment.execGreenBootstrap - } prevDeployment := &ccipDeployment{ commit: blueGreenDeployment{ @@ -817,21 +467,9 @@ func Test_ccipDeployment_HandleBlueGreen(t *testing.T) { if tt.argsPrevDeployment.commitGreen != nil { prevDeployment.commit.green = tt.argsPrevDeployment.commitGreen } - if tt.argsPrevDeployment.commitBlueBootstrap != nil { - prevDeployment.commit.bootstrapBlue = tt.argsPrevDeployment.commitBlueBootstrap - } - if tt.argsPrevDeployment.commitGreenBootstrap != nil { - prevDeployment.commit.bootstrapGreen = tt.argsPrevDeployment.commitGreenBootstrap - } if tt.argsPrevDeployment.execGreen != nil { prevDeployment.exec.green = tt.argsPrevDeployment.execGreen } - if tt.argsPrevDeployment.execBlueBootstrap != nil { - prevDeployment.exec.bootstrapBlue = tt.argsPrevDeployment.execBlueBootstrap - } - if tt.argsPrevDeployment.execGreenBootstrap != nil { - prevDeployment.exec.bootstrapGreen = tt.argsPrevDeployment.execGreenBootstrap - } tt.expect(t, tt.argsFutureDeployment, tt.argsPrevDeployment) defer tt.asserts(t, tt.argsFutureDeployment, tt.argsPrevDeployment) diff --git a/core/capabilities/ccip/launcher/diff.go b/core/capabilities/ccip/launcher/diff.go index e44b5478ed..787e33dadc 100644 --- a/core/capabilities/ccip/launcher/diff.go +++ b/core/capabilities/ccip/launcher/diff.go @@ -141,16 +141,3 @@ func isMemberOfDON(don kcr.CapabilitiesRegistryDONInfo, p2pID ragep2ptypes.PeerI } return false } - -// isMemberOfBootstrapSubcommittee returns true if and only if the given p2pID is a member of the given bootstrap subcommittee. -func isMemberOfBootstrapSubcommittee( - bootstrapP2PIDs [][32]byte, - p2pID ragep2ptypes.PeerID, -) bool { - for _, bootstrapID := range bootstrapP2PIDs { - if bootstrapID == p2pID { - return true - } - } - return false -} diff --git a/core/capabilities/ccip/launcher/diff_test.go b/core/capabilities/ccip/launcher/diff_test.go index 37371945ab..b1914e1770 100644 --- a/core/capabilities/ccip/launcher/diff_test.go +++ b/core/capabilities/ccip/launcher/diff_test.go @@ -467,15 +467,6 @@ func Test_isMemberOfDON(t *testing.T) { require.False(t, isMemberOfDON(don, ragep2ptypes.PeerID(p2pkey.MustNewV2XXXTestingOnly(big.NewInt(5)).PeerID()))) } -func Test_isMemberOfBootstrapSubcommittee(t *testing.T) { - var bootstrapKeys [][32]byte - for i := range [4]struct{}{} { - bootstrapKeys = append(bootstrapKeys, p2pkey.MustNewV2XXXTestingOnly(big.NewInt(int64(i+1))).PeerID()) - } - require.True(t, isMemberOfBootstrapSubcommittee(bootstrapKeys, ragep2ptypes.PeerID(p2pkey.MustNewV2XXXTestingOnly(big.NewInt(1)).PeerID()))) - require.False(t, isMemberOfBootstrapSubcommittee(bootstrapKeys, ragep2ptypes.PeerID(p2pkey.MustNewV2XXXTestingOnly(big.NewInt(5)).PeerID()))) -} - func mustHashedCapabilityID(capabilityLabelledName, capabilityVersion string) [32]byte { r, err := capcommon.HashedCapabilityID(capabilityLabelledName, capabilityVersion) if err != nil { diff --git a/core/capabilities/ccip/launcher/integration_test.go b/core/capabilities/ccip/launcher/integration_test.go index 58b6a5d6a2..da1ac36465 100644 --- a/core/capabilities/ccip/launcher/integration_test.go +++ b/core/capabilities/ccip/launcher/integration_test.go @@ -32,17 +32,17 @@ func TestIntegration_Launcher(t *testing.T) { regSyncer, err := registrysyncer.New(lggr, uni, uni.CapReg.Address().String()) require.NoError(t, err) - hcr := uni.HomeChainReader + oracleCreator := &oracleCreatorPrints{ + t: t, + } launcher := New( it.CcipCapabilityVersion, it.CcipCapabilityLabelledName, p2pIDs[0], logger.TestLogger(t), - hcr, - &oracleCreatorPrints{ - t: t, - }, + uni.HomeChainReader, 1*time.Second, + oracleCreator, ) regSyncer.AddLauncher(launcher) @@ -99,14 +99,14 @@ type oracleCreatorPrints struct { t *testing.T } -func (o *oracleCreatorPrints) CreatePluginOracle(pluginType cctypes.PluginType, config cctypes.OCR3ConfigWithMeta) (cctypes.CCIPOracle, error) { +func (o *oracleCreatorPrints) Create(config cctypes.OCR3ConfigWithMeta) (cctypes.CCIPOracle, error) { + pluginType := cctypes.PluginType(config.Config.PluginType) o.t.Logf("Creating plugin oracle (pluginType: %s) with config %+v\n", pluginType, config) return &oraclePrints{pluginType: pluginType, config: config, t: o.t}, nil } -func (o *oracleCreatorPrints) CreateBootstrapOracle(config cctypes.OCR3ConfigWithMeta) (cctypes.CCIPOracle, error) { - o.t.Logf("Creating bootstrap oracle with config %+v\n", config) - return &oraclePrints{pluginType: cctypes.PluginTypeCCIPCommit, config: config, isBootstrap: true, t: o.t}, nil +func (o *oracleCreatorPrints) Type() cctypes.OracleType { + return cctypes.OracleTypePlugin } var _ cctypes.OracleCreator = &oracleCreatorPrints{} diff --git a/core/capabilities/ccip/launcher/launcher.go b/core/capabilities/ccip/launcher/launcher.go index 9acfebfa9a..4d60bfcdc9 100644 --- a/core/capabilities/ccip/launcher/launcher.go +++ b/core/capabilities/ccip/launcher/launcher.go @@ -6,16 +6,14 @@ import ( "sync" "time" - cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" - "go.uber.org/multierr" ragep2ptypes "github.com/smartcontractkit/libocr/ragep2p/types" - ccipreaderpkg "github.com/smartcontractkit/chainlink-ccip/pkg/reader" "github.com/smartcontractkit/chainlink-common/pkg/services" ccipreader "github.com/smartcontractkit/chainlink-ccip/pkg/reader" + cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" @@ -34,8 +32,8 @@ func New( p2pID ragep2ptypes.PeerID, lggr logger.Logger, homeChainReader ccipreader.HomeChain, - oracleCreator cctypes.OracleCreator, tickInterval time.Duration, + oracleCreator cctypes.OracleCreator, ) *launcher { return &launcher{ capabilityVersion: capabilityVersion, @@ -48,9 +46,9 @@ func New( IDsToNodes: make(map[p2ptypes.PeerID]kcr.CapabilitiesRegistryNodeInfo), IDsToCapabilities: make(map[registrysyncer.HashedCapabilityID]kcr.CapabilitiesRegistryCapabilityInfo), }, - oracleCreator: oracleCreator, dons: make(map[registrysyncer.DonID]*ccipDeployment), tickInterval: tickInterval, + oracleCreator: oracleCreator, } } @@ -68,10 +66,10 @@ type launcher struct { latestState registrysyncer.State // regState is the latest capability registry state that we have successfully processed. regState registrysyncer.State - oracleCreator cctypes.OracleCreator lock sync.RWMutex wg sync.WaitGroup tickInterval time.Duration + oracleCreator cctypes.OracleCreator // dons is a map of CCIP DON IDs to the OCR instances that are running on them. // we can have up to two OCR instances per CCIP plugin, since we are running two plugins, @@ -197,9 +195,9 @@ func (l *launcher) processUpdate(updated map[registrysyncer.DonID]kcr.Capabiliti l.lggr, l.p2pID, l.homeChainReader, - l.oracleCreator, *prevDeployment, don, + l.oracleCreator, ) if err != nil { return err @@ -228,8 +226,8 @@ func (l *launcher) processAdded(added map[registrysyncer.DonID]kcr.CapabilitiesR l.lggr, l.p2pID, l.homeChainReader, - l.oracleCreator, don, + l.oracleCreator, ) if err != nil { return err @@ -287,9 +285,9 @@ func updateDON( lggr logger.Logger, p2pID ragep2ptypes.PeerID, homeChainReader ccipreader.HomeChain, - oracleCreator cctypes.OracleCreator, prevDeployment ccipDeployment, don kcr.CapabilitiesRegistryDONInfo, + oracleCreator cctypes.OracleCreator, ) (futDeployment *ccipDeployment, err error) { if !isMemberOfDON(don, p2pID) { lggr.Infow("Not a member of this DON, skipping", "donId", don.Id, "p2pId", p2pID.String()) @@ -331,14 +329,14 @@ func updateDON( // All other cases are invalid. This is enforced in the ccip config contract. func createFutureBlueGreenDeployment( prevDeployment ccipDeployment, - ocrConfigs []ccipreaderpkg.OCR3ConfigWithMeta, + ocrConfigs []ccipreader.OCR3ConfigWithMeta, oracleCreator cctypes.OracleCreator, pluginType cctypes.PluginType, ) (blueGreenDeployment, error) { var deployment blueGreenDeployment if isNewGreenInstance(pluginType, ocrConfigs, prevDeployment) { // this is a new green instance. - greenOracle, err := oracleCreator.CreatePluginOracle(pluginType, cctypes.OCR3ConfigWithMeta(ocrConfigs[1])) + greenOracle, err := oracleCreator.Create(cctypes.OCR3ConfigWithMeta(ocrConfigs[1])) if err != nil { return blueGreenDeployment{}, fmt.Errorf("failed to create CCIP commit oracle: %w", err) } @@ -361,14 +359,9 @@ func createDON( lggr logger.Logger, p2pID ragep2ptypes.PeerID, homeChainReader ccipreader.HomeChain, - oracleCreator cctypes.OracleCreator, don kcr.CapabilitiesRegistryDONInfo, + oracleCreator cctypes.OracleCreator, ) (*ccipDeployment, error) { - if !isMemberOfDON(don, p2pID) { - lggr.Infow("Not a member of this DON, skipping", "donId", don.Id, "p2pId", p2pID.String()) - return nil, nil - } - // this should be a retryable error. commitOCRConfigs, err := homeChainReader.GetOCRConfigs(context.Background(), don.Id, uint8(cctypes.PluginTypeCCIPCommit)) if err != nil { @@ -391,45 +384,29 @@ func createDON( return nil, fmt.Errorf("expected exactly one OCR config for CCIP exec plugin (don id: %d), got %d", don.Id, len(execOCRConfigs)) } - commitOracle, commitBootstrap, err := createOracle(p2pID, oracleCreator, cctypes.PluginTypeCCIPCommit, commitOCRConfigs) + if !isMemberOfDON(don, p2pID) && oracleCreator.Type() == cctypes.OracleTypePlugin { + lggr.Infow("Not a member of this DON and not a bootstrap node either, skipping", "donId", don.Id, "p2pId", p2pID.String()) + return nil, nil + } + + // at this point we know we are either a member of the DON or a bootstrap node. + // the injected oracleCreator will create the appropriate oracle. + commitOracle, err := oracleCreator.Create(cctypes.OCR3ConfigWithMeta(commitOCRConfigs[0])) if err != nil { return nil, fmt.Errorf("failed to create CCIP commit oracle: %w", err) } - execOracle, execBootstrap, err := createOracle(p2pID, oracleCreator, cctypes.PluginTypeCCIPExec, execOCRConfigs) + execOracle, err := oracleCreator.Create(cctypes.OCR3ConfigWithMeta(execOCRConfigs[0])) if err != nil { return nil, fmt.Errorf("failed to create CCIP exec oracle: %w", err) } return &ccipDeployment{ commit: blueGreenDeployment{ - blue: commitOracle, - bootstrapBlue: commitBootstrap, + blue: commitOracle, }, exec: blueGreenDeployment{ - blue: execOracle, - bootstrapBlue: execBootstrap, + blue: execOracle, }, }, nil } - -func createOracle( - p2pID ragep2ptypes.PeerID, - oracleCreator cctypes.OracleCreator, - pluginType cctypes.PluginType, - ocrConfigs []ccipreaderpkg.OCR3ConfigWithMeta, -) (pluginOracle, bootstrapOracle cctypes.CCIPOracle, err error) { - pluginOracle, err = oracleCreator.CreatePluginOracle(pluginType, cctypes.OCR3ConfigWithMeta(ocrConfigs[0])) - if err != nil { - return nil, nil, fmt.Errorf("failed to create CCIP plugin oracle (plugintype: %d): %w", pluginType, err) - } - - if isMemberOfBootstrapSubcommittee(ocrConfigs[0].Config.BootstrapP2PIds, p2pID) { - bootstrapOracle, err = oracleCreator.CreateBootstrapOracle(cctypes.OCR3ConfigWithMeta(ocrConfigs[0])) - if err != nil { - return nil, nil, fmt.Errorf("failed to create CCIP bootstrap oracle (plugintype: %d): %w", pluginType, err) - } - } - - return pluginOracle, bootstrapOracle, nil -} diff --git a/core/capabilities/ccip/launcher/launcher_test.go b/core/capabilities/ccip/launcher/launcher_test.go index 493f962c2c..bb24464c62 100644 --- a/core/capabilities/ccip/launcher/launcher_test.go +++ b/core/capabilities/ccip/launcher/launcher_test.go @@ -1,7 +1,6 @@ package launcher import ( - "errors" "math/big" "reflect" "testing" @@ -16,154 +15,69 @@ import ( ccipreaderpkg "github.com/smartcontractkit/chainlink-ccip/pkg/reader" kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" "github.com/smartcontractkit/chainlink/v2/core/services/registrysyncer" ) -func Test_createOracle(t *testing.T) { - var p2pKeys []ragep2ptypes.PeerID - for i := 0; i < 3; i++ { - p2pKeys = append(p2pKeys, ragep2ptypes.PeerID(p2pkey.MustNewV2XXXTestingOnly(big.NewInt(int64(i+1))).PeerID())) - } - myP2PKey := p2pKeys[0] +func Test_createDON(t *testing.T) { type args struct { - p2pID ragep2ptypes.PeerID - oracleCreator *mocks.OracleCreator - pluginType cctypes.PluginType - ocrConfigs []ccipreaderpkg.OCR3ConfigWithMeta + lggr logger.Logger + p2pID ragep2ptypes.PeerID + homeChainReader *mocks.HomeChainReader + oracleCreator *mocks.OracleCreator + don kcr.CapabilitiesRegistryDONInfo } tests := []struct { name string args args - expect func(t *testing.T, args args, oracleCreator *mocks.OracleCreator) + expect func(t *testing.T, args args, oracleCreator *mocks.OracleCreator, homeChainReader *mocks.HomeChainReader) wantErr bool }{ { - "success, no bootstrap", + "not a member of the DON and not a bootstrap node", args{ - myP2PKey, + logger.TestLogger(t), + ragep2ptypes.PeerID(p2pkey.MustNewV2XXXTestingOnly(big.NewInt(1)).PeerID()), + mocks.NewHomeChainReader(t), mocks.NewOracleCreator(t), - cctypes.PluginTypeCCIPCommit, - []ccipreaderpkg.OCR3ConfigWithMeta{ - { - Config: ccipreaderpkg.OCR3Config{}, - ConfigCount: 1, - ConfigDigest: testutils.Random32Byte(), + kcr.CapabilitiesRegistryDONInfo{ + NodeP2PIds: [][32]byte{ + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(3)).PeerID(), + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(4)).PeerID(), }, + Id: 2, }, }, - func(t *testing.T, args args, oracleCreator *mocks.OracleCreator) { - oracleCreator. - On("CreatePluginOracle", cctypes.PluginTypeCCIPCommit, cctypes.OCR3ConfigWithMeta(args.ocrConfigs[0])). - Return(mocks.NewCCIPOracle(t), nil) - }, - false, - }, - { - "success, with bootstrap", - args{ - myP2PKey, - mocks.NewOracleCreator(t), - cctypes.PluginTypeCCIPCommit, - []ccipreaderpkg.OCR3ConfigWithMeta{ - { + func(t *testing.T, args args, oracleCreator *mocks.OracleCreator, homeChainReader *mocks.HomeChainReader) { + homeChainReader. + On("GetOCRConfigs", mock.Anything, uint32(2), uint8(cctypes.PluginTypeCCIPCommit)). + Return([]ccipreaderpkg.OCR3ConfigWithMeta{{ Config: ccipreaderpkg.OCR3Config{ - BootstrapP2PIds: [][32]byte{myP2PKey}, + PluginType: uint8(cctypes.PluginTypeCCIPCommit), + P2PIds: [][32]byte{ + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(3)).PeerID(), + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(4)).PeerID(), + }, }, - ConfigCount: 1, - ConfigDigest: testutils.Random32Byte(), - }, - }, - }, - func(t *testing.T, args args, oracleCreator *mocks.OracleCreator) { - oracleCreator. - On("CreatePluginOracle", cctypes.PluginTypeCCIPCommit, cctypes.OCR3ConfigWithMeta(args.ocrConfigs[0])). - Return(mocks.NewCCIPOracle(t), nil) - oracleCreator. - On("CreateBootstrapOracle", cctypes.OCR3ConfigWithMeta(args.ocrConfigs[0])). - Return(mocks.NewCCIPOracle(t), nil) - }, - false, - }, - { - "error creating plugin oracle", - args{ - myP2PKey, - mocks.NewOracleCreator(t), - cctypes.PluginTypeCCIPCommit, - []ccipreaderpkg.OCR3ConfigWithMeta{ - { - Config: ccipreaderpkg.OCR3Config{}, - ConfigCount: 1, - ConfigDigest: testutils.Random32Byte(), - }, - }, - }, - func(t *testing.T, args args, oracleCreator *mocks.OracleCreator) { - oracleCreator. - On("CreatePluginOracle", cctypes.PluginTypeCCIPCommit, cctypes.OCR3ConfigWithMeta(args.ocrConfigs[0])). - Return(nil, errors.New("error creating oracle")) - }, - true, - }, - { - "error creating bootstrap oracle", - args{ - myP2PKey, - mocks.NewOracleCreator(t), - cctypes.PluginTypeCCIPCommit, - []ccipreaderpkg.OCR3ConfigWithMeta{ - { + }}, nil) + homeChainReader. + On("GetOCRConfigs", mock.Anything, uint32(2), uint8(cctypes.PluginTypeCCIPExec)). + Return([]ccipreaderpkg.OCR3ConfigWithMeta{{ Config: ccipreaderpkg.OCR3Config{ - BootstrapP2PIds: [][32]byte{myP2PKey}, + PluginType: uint8(cctypes.PluginTypeCCIPExec), + P2PIds: [][32]byte{ + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(3)).PeerID(), + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(4)).PeerID(), + }, }, - ConfigCount: 1, - ConfigDigest: testutils.Random32Byte(), - }, - }, + }}, nil) + oracleCreator.EXPECT().Type().Return(cctypes.OracleTypePlugin).Once() }, - func(t *testing.T, args args, oracleCreator *mocks.OracleCreator) { - oracleCreator. - On("CreatePluginOracle", cctypes.PluginTypeCCIPCommit, cctypes.OCR3ConfigWithMeta(args.ocrConfigs[0])). - Return(mocks.NewCCIPOracle(t), nil) - oracleCreator. - On("CreateBootstrapOracle", cctypes.OCR3ConfigWithMeta(args.ocrConfigs[0])). - Return(nil, errors.New("error creating oracle")) - }, - true, + false, }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - tt.expect(t, tt.args, tt.args.oracleCreator) - _, _, err := createOracle(tt.args.p2pID, tt.args.oracleCreator, tt.args.pluginType, tt.args.ocrConfigs) - if tt.wantErr { - require.Error(t, err) - } else { - require.NoError(t, err) - } - }) - } -} - -func Test_createDON(t *testing.T) { - type args struct { - lggr logger.Logger - p2pID ragep2ptypes.PeerID - homeChainReader *mocks.HomeChainReader - oracleCreator *mocks.OracleCreator - don kcr.CapabilitiesRegistryDONInfo - } - tests := []struct { - name string - args args - expect func(t *testing.T, args args, oracleCreator *mocks.OracleCreator, homeChainReader *mocks.HomeChainReader) - wantErr bool - }{ { - "not a member of the DON", + "not a member of the DON but a running a bootstrap oracle creator", args{ logger.TestLogger(t), ragep2ptypes.PeerID(p2pkey.MustNewV2XXXTestingOnly(big.NewInt(1)).PeerID()), @@ -171,17 +85,44 @@ func Test_createDON(t *testing.T) { mocks.NewOracleCreator(t), kcr.CapabilitiesRegistryDONInfo{ NodeP2PIds: [][32]byte{ - p2pkey.MustNewV2XXXTestingOnly(big.NewInt(2)).PeerID(), + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(3)).PeerID(), + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(4)).PeerID(), }, Id: 2, }, }, func(t *testing.T, args args, oracleCreator *mocks.OracleCreator, homeChainReader *mocks.HomeChainReader) { + homeChainReader. + On("GetOCRConfigs", mock.Anything, uint32(2), uint8(cctypes.PluginTypeCCIPCommit)). + Return([]ccipreaderpkg.OCR3ConfigWithMeta{{ + Config: ccipreaderpkg.OCR3Config{ + PluginType: uint8(cctypes.PluginTypeCCIPCommit), + P2PIds: [][32]byte{ + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(3)).PeerID(), + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(4)).PeerID(), + }, + }, + }}, nil) + homeChainReader. + On("GetOCRConfigs", mock.Anything, uint32(2), uint8(cctypes.PluginTypeCCIPExec)). + Return([]ccipreaderpkg.OCR3ConfigWithMeta{{ + Config: ccipreaderpkg.OCR3Config{ + PluginType: uint8(cctypes.PluginTypeCCIPExec), + P2PIds: [][32]byte{ + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(3)).PeerID(), + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(4)).PeerID(), + }, + }, + }}, nil) + oracleCreator.EXPECT().Type().Return(cctypes.OracleTypeBootstrap).Once() + oracleCreator. + On("Create", mock.Anything). + Return(mocks.NewCCIPOracle(t), nil).Twice() }, false, }, { - "success, no bootstrap", + "success", args{ logger.TestLogger(t), ragep2ptypes.PeerID(p2pkey.MustNewV2XXXTestingOnly(big.NewInt(1)).PeerID()), @@ -190,6 +131,7 @@ func Test_createDON(t *testing.T) { kcr.CapabilitiesRegistryDONInfo{ NodeP2PIds: [][32]byte{ p2pkey.MustNewV2XXXTestingOnly(big.NewInt(1)).PeerID(), + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(2)).PeerID(), }, Id: 1, }, @@ -197,15 +139,34 @@ func Test_createDON(t *testing.T) { func(t *testing.T, args args, oracleCreator *mocks.OracleCreator, homeChainReader *mocks.HomeChainReader) { homeChainReader. On("GetOCRConfigs", mock.Anything, uint32(1), uint8(cctypes.PluginTypeCCIPCommit)). - Return([]ccipreaderpkg.OCR3ConfigWithMeta{{}}, nil) + Return([]ccipreaderpkg.OCR3ConfigWithMeta{{ + Config: ccipreaderpkg.OCR3Config{ + PluginType: uint8(cctypes.PluginTypeCCIPCommit), + P2PIds: [][32]byte{ + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(1)).PeerID(), + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(2)).PeerID(), + }, + }, + }}, nil) homeChainReader. On("GetOCRConfigs", mock.Anything, uint32(1), uint8(cctypes.PluginTypeCCIPExec)). - Return([]ccipreaderpkg.OCR3ConfigWithMeta{{}}, nil) - oracleCreator. - On("CreatePluginOracle", cctypes.PluginTypeCCIPCommit, mock.Anything). + Return([]ccipreaderpkg.OCR3ConfigWithMeta{{ + Config: ccipreaderpkg.OCR3Config{ + PluginType: uint8(cctypes.PluginTypeCCIPExec), + P2PIds: [][32]byte{ + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(1)).PeerID(), + p2pkey.MustNewV2XXXTestingOnly(big.NewInt(2)).PeerID(), + }, + }, + }}, nil) + + oracleCreator.EXPECT().Create(mock.MatchedBy(func(cfg cctypes.OCR3ConfigWithMeta) bool { + return cfg.Config.PluginType == uint8(cctypes.PluginTypeCCIPCommit) + })). Return(mocks.NewCCIPOracle(t), nil) - oracleCreator. - On("CreatePluginOracle", cctypes.PluginTypeCCIPExec, mock.Anything). + oracleCreator.EXPECT().Create(mock.MatchedBy(func(cfg cctypes.OCR3ConfigWithMeta) bool { + return cfg.Config.PluginType == uint8(cctypes.PluginTypeCCIPExec) + })). Return(mocks.NewCCIPOracle(t), nil) }, false, @@ -216,7 +177,8 @@ func Test_createDON(t *testing.T) { if tt.expect != nil { tt.expect(t, tt.args, tt.args.oracleCreator, tt.args.homeChainReader) } - _, err := createDON(tt.args.lggr, tt.args.p2pID, tt.args.homeChainReader, tt.args.oracleCreator, tt.args.don) + + _, err := createDON(tt.args.lggr, tt.args.p2pID, tt.args.homeChainReader, tt.args.don, tt.args.oracleCreator) if tt.wantErr { require.Error(t, err) } else { @@ -274,7 +236,7 @@ func Test_updateDON(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - gotFutDeployment, err := updateDON(tt.args.lggr, tt.args.p2pID, tt.args.homeChainReader, tt.args.oracleCreator, tt.args.prevDeployment, tt.args.don) + gotFutDeployment, err := updateDON(tt.args.lggr, tt.args.p2pID, tt.args.homeChainReader, tt.args.prevDeployment, tt.args.don, tt.args.oracleCreator) if (err != nil) != tt.wantErr { t.Errorf("updateDON() error = %v, wantErr %v", err, tt.wantErr) return @@ -358,9 +320,17 @@ func Test_launcher_processDiff(t *testing.T) { return mocks.NewHomeChainReader(t) }, func(m *mocks.HomeChainReader) { m.On("GetOCRConfigs", mock.Anything, uint32(1), uint8(cctypes.PluginTypeCCIPCommit)). - Return([]ccipreaderpkg.OCR3ConfigWithMeta{{}}, nil) + Return([]ccipreaderpkg.OCR3ConfigWithMeta{{ + Config: ccipreaderpkg.OCR3Config{ + PluginType: uint8(cctypes.PluginTypeCCIPCommit), + }, + }}, nil) m.On("GetOCRConfigs", mock.Anything, uint32(1), uint8(cctypes.PluginTypeCCIPExec)). - Return([]ccipreaderpkg.OCR3ConfigWithMeta{{}}, nil) + Return([]ccipreaderpkg.OCR3ConfigWithMeta{{ + Config: ccipreaderpkg.OCR3Config{ + PluginType: uint8(cctypes.PluginTypeCCIPExec), + }, + }}, nil) }), oracleCreator: newMock(t, func(t *testing.T) *mocks.OracleCreator { return mocks.NewOracleCreator(t) @@ -369,9 +339,13 @@ func Test_launcher_processDiff(t *testing.T) { commitOracle.On("Start").Return(nil) execOracle := mocks.NewCCIPOracle(t) execOracle.On("Start").Return(nil) - m.On("CreatePluginOracle", cctypes.PluginTypeCCIPCommit, mock.Anything). + m.EXPECT().Create(mock.MatchedBy(func(cfg cctypes.OCR3ConfigWithMeta) bool { + return cfg.Config.PluginType == uint8(cctypes.PluginTypeCCIPCommit) + })). Return(commitOracle, nil) - m.On("CreatePluginOracle", cctypes.PluginTypeCCIPExec, mock.Anything). + m.EXPECT().Create(mock.MatchedBy(func(cfg cctypes.OCR3ConfigWithMeta) bool { + return cfg.Config.PluginType == uint8(cctypes.PluginTypeCCIPExec) + })). Return(execOracle, nil) }), dons: map[registrysyncer.DonID]*ccipDeployment{}, @@ -406,9 +380,25 @@ func Test_launcher_processDiff(t *testing.T) { return mocks.NewHomeChainReader(t) }, func(m *mocks.HomeChainReader) { m.On("GetOCRConfigs", mock.Anything, uint32(1), uint8(cctypes.PluginTypeCCIPCommit)). - Return([]ccipreaderpkg.OCR3ConfigWithMeta{{}, {}}, nil) + Return([]ccipreaderpkg.OCR3ConfigWithMeta{{ + Config: ccipreaderpkg.OCR3Config{ + PluginType: uint8(cctypes.PluginTypeCCIPCommit), + }, + }, { + Config: ccipreaderpkg.OCR3Config{ + PluginType: uint8(cctypes.PluginTypeCCIPCommit), + }, + }}, nil) m.On("GetOCRConfigs", mock.Anything, uint32(1), uint8(cctypes.PluginTypeCCIPExec)). - Return([]ccipreaderpkg.OCR3ConfigWithMeta{{}, {}}, nil) + Return([]ccipreaderpkg.OCR3ConfigWithMeta{{ + Config: ccipreaderpkg.OCR3Config{ + PluginType: uint8(cctypes.PluginTypeCCIPExec), + }, + }, { + Config: ccipreaderpkg.OCR3Config{ + PluginType: uint8(cctypes.PluginTypeCCIPExec), + }, + }}, nil) }), oracleCreator: newMock(t, func(t *testing.T) *mocks.OracleCreator { return mocks.NewOracleCreator(t) @@ -417,9 +407,13 @@ func Test_launcher_processDiff(t *testing.T) { commitOracle.On("Start").Return(nil) execOracle := mocks.NewCCIPOracle(t) execOracle.On("Start").Return(nil) - m.On("CreatePluginOracle", cctypes.PluginTypeCCIPCommit, mock.Anything). + m.EXPECT().Create(mock.MatchedBy(func(cfg cctypes.OCR3ConfigWithMeta) bool { + return cfg.Config.PluginType == uint8(cctypes.PluginTypeCCIPCommit) + })). Return(commitOracle, nil) - m.On("CreatePluginOracle", cctypes.PluginTypeCCIPExec, mock.Anything). + m.EXPECT().Create(mock.MatchedBy(func(cfg cctypes.OCR3ConfigWithMeta) bool { + return cfg.Config.PluginType == uint8(cctypes.PluginTypeCCIPExec) + })). Return(execOracle, nil) }), dons: map[registrysyncer.DonID]*ccipDeployment{ diff --git a/core/capabilities/ccip/oraclecreator/bootstrap.go b/core/capabilities/ccip/oraclecreator/bootstrap.go new file mode 100644 index 0000000000..a4bf03a4de --- /dev/null +++ b/core/capabilities/ccip/oraclecreator/bootstrap.go @@ -0,0 +1,97 @@ +package oraclecreator + +import ( + "context" + "fmt" + + "github.com/ethereum/go-ethereum/common/hexutil" + + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/libocr/commontypes" + libocr3 "github.com/smartcontractkit/libocr/offchainreporting2plus" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + + "github.com/smartcontractkit/chainlink-common/pkg/types" + + "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ocrimpls" + cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" + "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" + "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" + "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" +) + +var _ cctypes.OracleCreator = &bootstrapOracleCreator{} + +type bootstrapOracleCreator struct { + peerWrapper *ocrcommon.SingletonPeerWrapper + bootstrapperLocators []commontypes.BootstrapperLocator + db ocr3types.Database + monitoringEndpointGen telemetry.MonitoringEndpointGenerator + lggr logger.Logger +} + +func NewBootstrapOracleCreator( + peerWrapper *ocrcommon.SingletonPeerWrapper, + bootstrapperLocators []commontypes.BootstrapperLocator, + db ocr3types.Database, + monitoringEndpointGen telemetry.MonitoringEndpointGenerator, + lggr logger.Logger, +) cctypes.OracleCreator { + return &bootstrapOracleCreator{ + peerWrapper: peerWrapper, + bootstrapperLocators: bootstrapperLocators, + db: db, + monitoringEndpointGen: monitoringEndpointGen, + lggr: lggr, + } +} + +// Type implements types.OracleCreator. +func (i *bootstrapOracleCreator) Type() cctypes.OracleType { + return cctypes.OracleTypeBootstrap +} + +// Create implements types.OracleCreator. +func (i *bootstrapOracleCreator) Create(config cctypes.OCR3ConfigWithMeta) (cctypes.CCIPOracle, error) { + // Assuming that the chain selector is referring to an evm chain for now. + // TODO: add an api that returns chain family. + // NOTE: this doesn't really matter for the bootstrap node, it doesn't do anything on-chain. + // Its for the monitoring endpoint generation below. + chainID, err := chainsel.ChainIdFromSelector(uint64(config.Config.ChainSelector)) + if err != nil { + return nil, fmt.Errorf("failed to get chain ID from selector: %w", err) + } + + destChainFamily := chaintype.EVM + destRelayID := types.NewRelayID(string(destChainFamily), fmt.Sprintf("%d", chainID)) + + bootstrapperArgs := libocr3.BootstrapperArgs{ + BootstrapperFactory: i.peerWrapper.Peer2, + V2Bootstrappers: i.bootstrapperLocators, + ContractConfigTracker: ocrimpls.NewConfigTracker(config), + Database: i.db, + LocalConfig: defaultLocalConfig(), + Logger: ocrcommon.NewOCRWrapper( + i.lggr. + Named("CCIPBootstrap"). + Named(destRelayID.String()). + Named(config.Config.ChainSelector.String()). + Named(hexutil.Encode(config.Config.OfframpAddress)), + false, /* traceLogging */ + func(ctx context.Context, msg string) {}), + MonitoringEndpoint: i.monitoringEndpointGen.GenMonitoringEndpoint( + string(destChainFamily), + destRelayID.ChainID, + hexutil.Encode(config.Config.OfframpAddress), + synchronization.OCR3CCIPBootstrap, + ), + OffchainConfigDigester: ocrimpls.NewConfigDigester(config.ConfigDigest), + } + bootstrapper, err := libocr3.NewBootstrapper(bootstrapperArgs) + if err != nil { + return nil, err + } + return bootstrapper, nil +} diff --git a/core/capabilities/ccip/oraclecreator/inprocess_test.go b/core/capabilities/ccip/oraclecreator/inprocess_test.go deleted file mode 100644 index 639f01e62e..0000000000 --- a/core/capabilities/ccip/oraclecreator/inprocess_test.go +++ /dev/null @@ -1,239 +0,0 @@ -package oraclecreator_test - -import ( - "fmt" - "testing" - "time" - - "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/oraclecreator" - cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" - - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/google/uuid" - "github.com/hashicorp/consul/sdk/freeport" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "gopkg.in/guregu/null.v4" - - chainsel "github.com/smartcontractkit/chain-selectors" - "github.com/smartcontractkit/libocr/offchainreporting2/types" - confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" - "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" - - "github.com/smartcontractkit/chainlink-ccip/pkg/reader" - "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" - "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" - - "github.com/smartcontractkit/libocr/commontypes" - - "github.com/smartcontractkit/chainlink/v2/core/bridges" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" - "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - "github.com/smartcontractkit/chainlink/v2/core/services/job" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2" - ocr2validate "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" - "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" - "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" - "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" - "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" - "github.com/smartcontractkit/chainlink/v2/core/testdata/testspecs" - "github.com/smartcontractkit/chainlink/v2/core/utils" -) - -func TestOracleCreator_CreateBootstrap(t *testing.T) { - db := pgtest.NewSqlxDB(t) - - keyStore := keystore.New(db, utils.DefaultScryptParams, logger.NullLogger) - require.NoError(t, keyStore.Unlock(testutils.Context(t), cltest.Password), "unable to unlock keystore") - p2pKey, err := keyStore.P2P().Create(testutils.Context(t)) - require.NoError(t, err) - peerID := p2pKey.PeerID() - listenPort := freeport.GetOne(t) - generalConfig := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.P2P.PeerID = ptr(peerID) - c.P2P.TraceLogging = ptr(false) - c.P2P.V2.Enabled = ptr(true) - c.P2P.V2.ListenAddresses = ptr([]string{fmt.Sprintf("127.0.0.1:%d", listenPort)}) - - c.OCR2.Enabled = ptr(true) - }) - peerWrapper := ocrcommon.NewSingletonPeerWrapper(keyStore, generalConfig.P2P(), generalConfig.OCR(), db, logger.NullLogger) - require.NoError(t, peerWrapper.Start(testutils.Context(t))) - t.Cleanup(func() { assert.NoError(t, peerWrapper.Close()) }) - - // NOTE: this is a bit of a hack to get the OCR2 job created in order to use the ocr db - // the ocr2_contract_configs table has a foreign key constraint on ocr2_oracle_spec_id - // which is passed into ocr2.NewDB. - pipelineORM := pipeline.NewORM(db, - logger.NullLogger, generalConfig.JobPipeline().MaxSuccessfulRuns()) - bridgesORM := bridges.NewORM(db) - - jobORM := job.NewORM(db, pipelineORM, bridgesORM, keyStore, logger.TestLogger(t)) - t.Cleanup(func() { assert.NoError(t, jobORM.Close()) }) - - jb, err := ocr2validate.ValidatedOracleSpecToml(testutils.Context(t), generalConfig.OCR2(), generalConfig.Insecure(), testspecs.GetOCR2EVMSpecMinimal(), nil) - require.NoError(t, err) - const juelsPerFeeCoinSource = ` - ds [type=http method=GET url="https://chain.link/ETH-USD"]; - ds_parse [type=jsonparse path="data.price" separator="."]; - ds_multiply [type=multiply times=100]; - ds -> ds_parse -> ds_multiply;` - - _, address := cltest.MustInsertRandomKey(t, keyStore.Eth()) - jb.Name = null.StringFrom("Job 1") - jb.OCR2OracleSpec.TransmitterID = null.StringFrom(address.String()) - jb.OCR2OracleSpec.PluginConfig["juelsPerFeeCoinSource"] = juelsPerFeeCoinSource - - err = jobORM.CreateJob(testutils.Context(t), &jb) - require.NoError(t, err) - - cltest.AssertCount(t, db, "ocr2_oracle_specs", 1) - cltest.AssertCount(t, db, "jobs", 1) - - var oracleSpecID int32 - err = db.Get(&oracleSpecID, "SELECT id FROM ocr2_oracle_specs LIMIT 1") - require.NoError(t, err) - - ocrdb := ocr2.NewDB(db, oracleSpecID, 0, logger.NullLogger) - - oc := oraclecreator.New( - nil, - nil, - nil, - peerWrapper, - uuid.Max, - 0, - false, - nil, - ocrdb, - logger.TestLogger(t), - &mockEndpointGen{}, - []commontypes.BootstrapperLocator{}, - nil, - ) - - chainSelector := chainsel.GETH_TESTNET.Selector - oracles, offchainConfig := ocrOffchainConfig(t, keyStore) - bootstrapP2PID, err := p2pkey.MakePeerID(oracles[0].PeerID) - require.NoError(t, err) - transmitters := func() [][]byte { - var transmitters [][]byte - for _, o := range oracles { - transmitters = append(transmitters, hexutil.MustDecode(string(o.TransmitAccount))) - } - return transmitters - }() - configDigest := ccipConfigDigest() - bootstrap, err := oc.CreateBootstrapOracle(cctypes.OCR3ConfigWithMeta{ - ConfigDigest: configDigest, - ConfigCount: 1, - Config: reader.OCR3Config{ - ChainSelector: ccipocr3.ChainSelector(chainSelector), - OfframpAddress: testutils.NewAddress().Bytes(), - PluginType: uint8(cctypes.PluginTypeCCIPCommit), - F: 1, - OffchainConfigVersion: 30, - BootstrapP2PIds: [][32]byte{bootstrapP2PID}, - P2PIds: func() [][32]byte { - var ids [][32]byte - for _, o := range oracles { - id, err2 := p2pkey.MakePeerID(o.PeerID) - require.NoError(t, err2) - ids = append(ids, id) - } - return ids - }(), - Signers: func() [][]byte { - var signers [][]byte - for _, o := range oracles { - signers = append(signers, o.OnchainPublicKey) - } - return signers - }(), - Transmitters: transmitters, - OffchainConfig: offchainConfig, - }, - }) - require.NoError(t, err) - require.NoError(t, bootstrap.Start()) - t.Cleanup(func() { assert.NoError(t, bootstrap.Close()) }) - - tests.AssertEventually(t, func() bool { - c, err := ocrdb.ReadConfig(testutils.Context(t)) - require.NoError(t, err) - return c.ConfigDigest == configDigest - }) -} - -func ccipConfigDigest() [32]byte { - rand32Bytes := testutils.Random32Byte() - // overwrite first four bytes to be 0x000a, to match the prefix in libocr. - rand32Bytes[0] = 0x00 - rand32Bytes[1] = 0x0a - return rand32Bytes -} - -type mockEndpointGen struct{} - -func (m *mockEndpointGen) GenMonitoringEndpoint(network string, chainID string, contractID string, telemType synchronization.TelemetryType) commontypes.MonitoringEndpoint { - return &telemetry.NoopAgent{} -} - -func ptr[T any](b T) *T { - return &b -} - -func ocrOffchainConfig(t *testing.T, ks keystore.Master) (oracles []confighelper2.OracleIdentityExtra, offchainConfig []byte) { - for i := 0; i < 4; i++ { - kb, err := ks.OCR2().Create(testutils.Context(t), chaintype.EVM) - require.NoError(t, err) - p2pKey, err := ks.P2P().Create(testutils.Context(t)) - require.NoError(t, err) - ethKey, err := ks.Eth().Create(testutils.Context(t)) - require.NoError(t, err) - oracles = append(oracles, confighelper2.OracleIdentityExtra{ - OracleIdentity: confighelper2.OracleIdentity{ - OffchainPublicKey: kb.OffchainPublicKey(), - OnchainPublicKey: types.OnchainPublicKey(kb.OnChainPublicKey()), - PeerID: p2pKey.ID(), - TransmitAccount: types.Account(ethKey.Address.Hex()), - }, - ConfigEncryptionPublicKey: kb.ConfigEncryptionPublicKey(), - }) - } - var schedule []int - for range oracles { - schedule = append(schedule, 1) - } - offchainConfig, onchainConfig := []byte{}, []byte{} - f := uint8(1) - - _, _, _, _, _, offchainConfig, err := ocr3confighelper.ContractSetConfigArgsForTests( - 30*time.Second, // deltaProgress - 10*time.Second, // deltaResend - 20*time.Second, // deltaInitial - 2*time.Second, // deltaRound - 20*time.Second, // deltaGrace - 10*time.Second, // deltaCertifiedCommitRequest - 10*time.Second, // deltaStage - 3, // rmax - schedule, - oracles, - offchainConfig, - 50*time.Millisecond, // maxDurationQuery - 5*time.Second, // maxDurationObservation - 10*time.Second, // maxDurationShouldAcceptAttestedReport - 10*time.Second, // maxDurationShouldTransmitAcceptedReport - int(f), - onchainConfig) - require.NoError(t, err, "failed to create contract config") - - return oracles, offchainConfig -} diff --git a/core/capabilities/ccip/oraclecreator/inprocess.go b/core/capabilities/ccip/oraclecreator/plugin.go similarity index 79% rename from core/capabilities/ccip/oraclecreator/inprocess.go rename to core/capabilities/ccip/oraclecreator/plugin.go index 21e9bcec6d..c87c4e97c1 100644 --- a/core/capabilities/ccip/oraclecreator/inprocess.go +++ b/core/capabilities/ccip/oraclecreator/plugin.go @@ -36,7 +36,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" "github.com/smartcontractkit/chainlink/v2/core/services/relay" @@ -46,15 +45,15 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" ) -var _ cctypes.OracleCreator = &inprocessOracleCreator{} +var _ cctypes.OracleCreator = &pluginOracleCreator{} const ( defaultCommitGasLimit = 500_000 ) -// inprocessOracleCreator creates oracles that reference plugins running +// pluginOracleCreator creates oracles that reference plugins running // in the same process as the chainlink node, i.e not LOOPPs. -type inprocessOracleCreator struct { +type pluginOracleCreator struct { ocrKeyBundles map[string]ocr2key.KeyBundle transmitters map[types.RelayID][]string chains legacyevm.LegacyChainContainer @@ -70,7 +69,7 @@ type inprocessOracleCreator struct { homeChainReader ccipreaderpkg.HomeChain } -func New( +func NewPluginOracleCreator( ocrKeyBundles map[string]ocr2key.KeyBundle, transmitters map[types.RelayID][]string, chains legacyevm.LegacyChainContainer, @@ -85,7 +84,7 @@ func New( bootstrapperLocators []commontypes.BootstrapperLocator, homeChainReader ccipreaderpkg.HomeChain, ) cctypes.OracleCreator { - return &inprocessOracleCreator{ + return &pluginOracleCreator{ ocrKeyBundles: ocrKeyBundles, transmitters: transmitters, chains: chains, @@ -102,49 +101,15 @@ func New( } } -// CreateBootstrapOracle implements types.OracleCreator. -func (i *inprocessOracleCreator) CreateBootstrapOracle(config cctypes.OCR3ConfigWithMeta) (cctypes.CCIPOracle, error) { - // Assuming that the chain selector is referring to an evm chain for now. - // TODO: add an api that returns chain family. - chainID, err := chainsel.ChainIdFromSelector(uint64(config.Config.ChainSelector)) - if err != nil { - return nil, fmt.Errorf("failed to get chain ID from selector: %w", err) - } - - destChainFamily := chaintype.EVM - destRelayID := types.NewRelayID(string(destChainFamily), fmt.Sprintf("%d", chainID)) - - bootstrapperArgs := libocr3.BootstrapperArgs{ - BootstrapperFactory: i.peerWrapper.Peer2, - V2Bootstrappers: i.bootstrapperLocators, - ContractConfigTracker: ocrimpls.NewConfigTracker(config), - Database: i.db, - LocalConfig: defaultLocalConfig(), - Logger: ocrcommon.NewOCRWrapper( - i.lggr. - Named("CCIPBootstrap"). - Named(destRelayID.String()). - Named(config.Config.ChainSelector.String()). - Named(hexutil.Encode(config.Config.OfframpAddress)), - false, /* traceLogging */ - func(ctx context.Context, msg string) {}), - MonitoringEndpoint: i.monitoringEndpointGen.GenMonitoringEndpoint( - string(destChainFamily), - destRelayID.ChainID, - hexutil.Encode(config.Config.OfframpAddress), - synchronization.OCR3CCIPBootstrap, - ), - OffchainConfigDigester: ocrimpls.NewConfigDigester(config.ConfigDigest), - } - bootstrapper, err := libocr3.NewBootstrapper(bootstrapperArgs) - if err != nil { - return nil, err - } - return bootstrapper, nil +// Type implements types.OracleCreator. +func (i *pluginOracleCreator) Type() cctypes.OracleType { + return cctypes.OracleTypePlugin } -// CreatePluginOracle implements types.OracleCreator. -func (i *inprocessOracleCreator) CreatePluginOracle(pluginType cctypes.PluginType, config cctypes.OCR3ConfigWithMeta) (cctypes.CCIPOracle, error) { +// Create implements types.OracleCreator. +func (i *pluginOracleCreator) Create(config cctypes.OCR3ConfigWithMeta) (cctypes.CCIPOracle, error) { + pluginType := cctypes.PluginType(config.Config.PluginType) + // Assuming that the chain selector is referring to an evm chain for now. // TODO: add an api that returns chain family. destChainID, err := chainsel.ChainIdFromSelector(uint64(config.Config.ChainSelector)) @@ -172,7 +137,141 @@ func (i *inprocessOracleCreator) CreatePluginOracle(pluginType cctypes.PluginTyp execBatchGasLimit = execOffchainConfig.BatchGasLimit } - // this is so that we can use the msg hasher and report encoder from that dest chain relayer's provider. + contractReaders, chainWriters, err := i.createReadersAndWriters( + destChainID, + pluginType, + config, + execBatchGasLimit, + ) + if err != nil { + return nil, fmt.Errorf("failed to create readers and writers: %w", err) + } + + // build the onchain keyring. it will be the signing key for the destination chain family. + keybundle, ok := i.ocrKeyBundles[destChainFamily] + if !ok { + return nil, fmt.Errorf("no OCR key bundle found for chain family %s, forgot to create one?", destChainFamily) + } + onchainKeyring := ocrimpls.NewOnchainKeyring[[]byte](keybundle, i.lggr) + + // build the contract transmitter + // assume that we are using the first account in the keybundle as the from account + // and that we are able to transmit to the dest chain. + // TODO: revisit this in the future, since not all oracles will be able to transmit to the dest chain. + destChainWriter, ok := chainWriters[config.Config.ChainSelector] + if !ok { + return nil, fmt.Errorf("no chain writer found for dest chain selector %d, can't create contract transmitter", + config.Config.ChainSelector) + } + destFromAccounts, ok := i.transmitters[destRelayID] + if !ok { + return nil, fmt.Errorf("no transmitter found for dest relay ID %s, can't create contract transmitter", destRelayID) + } + + // TODO: Extract the correct transmitter address from the destsFromAccount + factory, transmitter, err := i.createFactoryAndTransmitter(config, destRelayID, contractReaders, chainWriters, destChainWriter, destFromAccounts) + if err != nil { + return nil, fmt.Errorf("failed to create factory and transmitter: %w", err) + } + + oracleArgs := libocr3.OCR3OracleArgs[[]byte]{ + BinaryNetworkEndpointFactory: i.peerWrapper.Peer2, + Database: i.db, + // NOTE: when specifying V2Bootstrappers here we actually do NOT need to run a full bootstrap node! + // Thus it is vital that the bootstrapper locators are correctly set in the job spec. + V2Bootstrappers: i.bootstrapperLocators, + ContractConfigTracker: configTracker, + ContractTransmitter: transmitter, + LocalConfig: defaultLocalConfig(), + Logger: ocrcommon.NewOCRWrapper( + i.lggr. + Named(fmt.Sprintf("CCIP%sOCR3", pluginType.String())). + Named(destRelayID.String()). + Named(hexutil.Encode(config.Config.OfframpAddress)), + false, + func(ctx context.Context, msg string) {}), + MetricsRegisterer: prometheus.WrapRegistererWith(map[string]string{"name": fmt.Sprintf("commit-%d", config.Config.ChainSelector)}, prometheus.DefaultRegisterer), + MonitoringEndpoint: i.monitoringEndpointGen.GenMonitoringEndpoint( + destChainFamily, + destRelayID.ChainID, + string(config.Config.OfframpAddress), + synchronization.OCR3CCIPCommit, + ), + OffchainConfigDigester: ocrimpls.NewConfigDigester(config.ConfigDigest), + OffchainKeyring: keybundle, + OnchainKeyring: onchainKeyring, + ReportingPluginFactory: factory, + } + oracle, err := libocr3.NewOracle(oracleArgs) + if err != nil { + return nil, err + } + return oracle, nil +} + +func (i *pluginOracleCreator) createFactoryAndTransmitter( + config cctypes.OCR3ConfigWithMeta, + destRelayID types.RelayID, + contractReaders map[cciptypes.ChainSelector]types.ContractReader, + chainWriters map[cciptypes.ChainSelector]types.ChainWriter, + destChainWriter types.ChainWriter, + destFromAccounts []string, +) (ocr3types.ReportingPluginFactory[[]byte], ocr3types.ContractTransmitter[[]byte], error) { + var factory ocr3types.ReportingPluginFactory[[]byte] + var transmitter ocr3types.ContractTransmitter[[]byte] + if config.Config.PluginType == uint8(cctypes.PluginTypeCCIPCommit) { + factory = commitocr3.NewPluginFactory( + i.lggr. + Named("CCIPCommitPlugin"). + Named(destRelayID.String()). + Named(fmt.Sprintf("%d", config.Config.ChainSelector)). + Named(hexutil.Encode(config.Config.OfframpAddress)), + ccipreaderpkg.OCR3ConfigWithMeta(config), + ccipevm.NewCommitPluginCodecV1(), + ccipevm.NewMessageHasherV1(), + i.homeChainReader, + contractReaders, + chainWriters, + ) + transmitter = ocrimpls.NewCommitContractTransmitter[[]byte](destChainWriter, + ocrtypes.Account(destFromAccounts[0]), + hexutil.Encode(config.Config.OfframpAddress), // TODO: this works for evm only, how about non-evm? + ) + } else if config.Config.PluginType == uint8(cctypes.PluginTypeCCIPExec) { + factory = execocr3.NewPluginFactory( + i.lggr. + Named("CCIPExecPlugin"). + Named(destRelayID.String()). + Named(hexutil.Encode(config.Config.OfframpAddress)), + ccipreaderpkg.OCR3ConfigWithMeta(config), + ccipevm.NewExecutePluginCodecV1(), + ccipevm.NewMessageHasherV1(), + i.homeChainReader, + superfakes.NewNilTokenDataReader(), + ccipevm.NewGasEstimateProvider(), + contractReaders, + chainWriters, + ) + transmitter = ocrimpls.NewExecContractTransmitter[[]byte](destChainWriter, + ocrtypes.Account(destFromAccounts[0]), + hexutil.Encode(config.Config.OfframpAddress), // TODO: this works for evm only, how about non-evm? + ) + } else { + return nil, nil, fmt.Errorf("unsupported plugin type %d", config.Config.PluginType) + } + return factory, transmitter, nil +} + +func (i *pluginOracleCreator) createReadersAndWriters( + destChainID uint64, + pluginType cctypes.PluginType, + config cctypes.OCR3ConfigWithMeta, + execBatchGasLimit uint64, +) ( + map[cciptypes.ChainSelector]types.ContractReader, + map[cciptypes.ChainSelector]types.ChainWriter, + error, +) { contractReaders := make(map[cciptypes.ChainSelector]types.ContractReader) chainWriters := make(map[cciptypes.ChainSelector]types.ChainWriter) for _, chain := range i.chains.Slice() { @@ -194,7 +293,7 @@ func (i *inprocessOracleCreator) CreatePluginOracle(pluginType cctypes.PluginTyp chainReaderConfig, ) if err2 != nil { - return nil, fmt.Errorf("failed to create contract reader for chain %s: %w", chain.ID(), err2) + return nil, nil, fmt.Errorf("failed to create contract reader for chain %s: %w", chain.ID(), err2) } if chain.ID().Uint64() == destChainID { @@ -207,7 +306,7 @@ func (i *inprocessOracleCreator) CreatePluginOracle(pluginType cctypes.PluginTyp }, }) if err3 != nil { - return nil, fmt.Errorf("failed to bind chain reader for dest chain %s's offramp at %s: %w", chain.ID(), offrampAddressHex, err3) + return nil, nil, fmt.Errorf("failed to bind chain reader for dest chain %s's offramp at %s: %w", chain.ID(), offrampAddressHex, err3) } } @@ -215,7 +314,7 @@ func (i *inprocessOracleCreator) CreatePluginOracle(pluginType cctypes.PluginTyp // maybe from the plugin directly? err2 = cr.Start(context.Background()) if err2 != nil { - return nil, fmt.Errorf("failed to start contract reader for chain %s: %w", chain.ID(), err2) + return nil, nil, fmt.Errorf("failed to start contract reader for chain %s: %w", chain.ID(), err2) } // Even though we only write to the dest chain, we need to create chain writers for all chains @@ -240,121 +339,25 @@ func (i *inprocessOracleCreator) CreatePluginOracle(pluginType cctypes.PluginTyp ), ) if err2 != nil { - return nil, fmt.Errorf("failed to create chain writer for chain %s: %w", chain.ID(), err2) + return nil, nil, fmt.Errorf("failed to create chain writer for chain %s: %w", chain.ID(), err2) } // TODO: figure out shutdown. // maybe from the plugin directly? err2 = cw.Start(context.Background()) if err2 != nil { - return nil, fmt.Errorf("failed to start chain writer for chain %s: %w", chain.ID(), err2) + return nil, nil, fmt.Errorf("failed to start chain writer for chain %s: %w", chain.ID(), err2) } chainSelector, ok := chainsel.EvmChainIdToChainSelector()[chain.ID().Uint64()] if !ok { - return nil, fmt.Errorf("failed to get chain selector from chain ID %s", chain.ID()) + return nil, nil, fmt.Errorf("failed to get chain selector from chain ID %s", chain.ID()) } contractReaders[cciptypes.ChainSelector(chainSelector)] = cr chainWriters[cciptypes.ChainSelector(chainSelector)] = cw } - - // build the onchain keyring. it will be the signing key for the destination chain family. - keybundle, ok := i.ocrKeyBundles[destChainFamily] - if !ok { - return nil, fmt.Errorf("no OCR key bundle found for chain family %s, forgot to create one?", destChainFamily) - } - onchainKeyring := ocrimpls.NewOnchainKeyring[[]byte](keybundle, i.lggr) - - // build the contract transmitter - // assume that we are using the first account in the keybundle as the from account - // and that we are able to transmit to the dest chain. - // TODO: revisit this in the future, since not all oracles will be able to transmit to the dest chain. - destChainWriter, ok := chainWriters[config.Config.ChainSelector] - if !ok { - return nil, fmt.Errorf("no chain writer found for dest chain selector %d, can't create contract transmitter", - config.Config.ChainSelector) - } - destFromAccounts, ok := i.transmitters[destRelayID] - if !ok { - return nil, fmt.Errorf("no transmitter found for dest relay ID %s, can't create contract transmitter", destRelayID) - } - - // TODO: Extract the correct transmitter address from the destsFromAccount - var factory ocr3types.ReportingPluginFactory[[]byte] - var transmitter ocr3types.ContractTransmitter[[]byte] - if config.Config.PluginType == uint8(cctypes.PluginTypeCCIPCommit) { - factory = commitocr3.NewPluginFactory( - i.lggr. - Named("CCIPCommitPlugin"). - Named(destRelayID.String()). - Named(fmt.Sprintf("%d", config.Config.ChainSelector)). - Named(hexutil.Encode(config.Config.OfframpAddress)), - ccipreaderpkg.OCR3ConfigWithMeta(config), - ccipevm.NewCommitPluginCodecV1(), - ccipevm.NewMessageHasherV1(), - i.homeChainReader, - contractReaders, - chainWriters, - ) - transmitter = ocrimpls.NewCommitContractTransmitter[[]byte](destChainWriter, - ocrtypes.Account(destFromAccounts[0]), - hexutil.Encode(config.Config.OfframpAddress), // TODO: this works for evm only, how about non-evm? - ) - } else if config.Config.PluginType == uint8(cctypes.PluginTypeCCIPExec) { - factory = execocr3.NewPluginFactory( - i.lggr. - Named("CCIPExecPlugin"). - Named(destRelayID.String()). - Named(hexutil.Encode(config.Config.OfframpAddress)), - ccipreaderpkg.OCR3ConfigWithMeta(config), - ccipevm.NewExecutePluginCodecV1(), - ccipevm.NewMessageHasherV1(), - i.homeChainReader, - superfakes.NewNilTokenDataReader(), - ccipevm.NewGasEstimateProvider(), // TODO: this works for evm only, how about non-evm? - contractReaders, - chainWriters, - ) - transmitter = ocrimpls.NewExecContractTransmitter[[]byte](destChainWriter, - ocrtypes.Account(destFromAccounts[0]), - hexutil.Encode(config.Config.OfframpAddress), // TODO: this works for evm only, how about non-evm? - ) - } else { - return nil, fmt.Errorf("unsupported plugin type %d", config.Config.PluginType) - } - - oracleArgs := libocr3.OCR3OracleArgs[[]byte]{ - BinaryNetworkEndpointFactory: i.peerWrapper.Peer2, - Database: i.db, - V2Bootstrappers: i.bootstrapperLocators, - ContractConfigTracker: configTracker, - ContractTransmitter: transmitter, - LocalConfig: defaultLocalConfig(), - Logger: ocrcommon.NewOCRWrapper( - i.lggr. - Named(fmt.Sprintf("CCIP%sOCR3", pluginType.String())). - Named(destRelayID.String()). - Named(hexutil.Encode(config.Config.OfframpAddress)), - false, - func(ctx context.Context, msg string) {}), - MetricsRegisterer: prometheus.WrapRegistererWith(map[string]string{"name": fmt.Sprintf("commit-%d", config.Config.ChainSelector)}, prometheus.DefaultRegisterer), - MonitoringEndpoint: i.monitoringEndpointGen.GenMonitoringEndpoint( - destChainFamily, - destRelayID.ChainID, - string(config.Config.OfframpAddress), - synchronization.OCR3CCIPCommit, - ), - OffchainConfigDigester: ocrimpls.NewConfigDigester(config.ConfigDigest), - OffchainKeyring: keybundle, - OnchainKeyring: onchainKeyring, - ReportingPluginFactory: factory, - } - oracle, err := libocr3.NewOracle(oracleArgs) - if err != nil { - return nil, err - } - return oracle, nil + return contractReaders, chainWriters, nil } func defaultLocalConfig() ocrtypes.LocalConfig { diff --git a/core/capabilities/ccip/types/mocks/oracle_creator.go b/core/capabilities/ccip/types/mocks/oracle_creator.go index d83ad042bf..1d327e9652 100644 --- a/core/capabilities/ccip/types/mocks/oracle_creator.go +++ b/core/capabilities/ccip/types/mocks/oracle_creator.go @@ -20,12 +20,12 @@ func (_m *OracleCreator) EXPECT() *OracleCreator_Expecter { return &OracleCreator_Expecter{mock: &_m.Mock} } -// CreateBootstrapOracle provides a mock function with given fields: config -func (_m *OracleCreator) CreateBootstrapOracle(config types.OCR3ConfigWithMeta) (types.CCIPOracle, error) { +// Create provides a mock function with given fields: config +func (_m *OracleCreator) Create(config types.OCR3ConfigWithMeta) (types.CCIPOracle, error) { ret := _m.Called(config) if len(ret) == 0 { - panic("no return value specified for CreateBootstrapOracle") + panic("no return value specified for Create") } var r0 types.CCIPOracle @@ -50,89 +50,75 @@ func (_m *OracleCreator) CreateBootstrapOracle(config types.OCR3ConfigWithMeta) return r0, r1 } -// OracleCreator_CreateBootstrapOracle_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateBootstrapOracle' -type OracleCreator_CreateBootstrapOracle_Call struct { +// OracleCreator_Create_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Create' +type OracleCreator_Create_Call struct { *mock.Call } -// CreateBootstrapOracle is a helper method to define mock.On call +// Create is a helper method to define mock.On call // - config types.OCR3ConfigWithMeta -func (_e *OracleCreator_Expecter) CreateBootstrapOracle(config interface{}) *OracleCreator_CreateBootstrapOracle_Call { - return &OracleCreator_CreateBootstrapOracle_Call{Call: _e.mock.On("CreateBootstrapOracle", config)} +func (_e *OracleCreator_Expecter) Create(config interface{}) *OracleCreator_Create_Call { + return &OracleCreator_Create_Call{Call: _e.mock.On("Create", config)} } -func (_c *OracleCreator_CreateBootstrapOracle_Call) Run(run func(config types.OCR3ConfigWithMeta)) *OracleCreator_CreateBootstrapOracle_Call { +func (_c *OracleCreator_Create_Call) Run(run func(config types.OCR3ConfigWithMeta)) *OracleCreator_Create_Call { _c.Call.Run(func(args mock.Arguments) { run(args[0].(types.OCR3ConfigWithMeta)) }) return _c } -func (_c *OracleCreator_CreateBootstrapOracle_Call) Return(_a0 types.CCIPOracle, _a1 error) *OracleCreator_CreateBootstrapOracle_Call { +func (_c *OracleCreator_Create_Call) Return(_a0 types.CCIPOracle, _a1 error) *OracleCreator_Create_Call { _c.Call.Return(_a0, _a1) return _c } -func (_c *OracleCreator_CreateBootstrapOracle_Call) RunAndReturn(run func(types.OCR3ConfigWithMeta) (types.CCIPOracle, error)) *OracleCreator_CreateBootstrapOracle_Call { +func (_c *OracleCreator_Create_Call) RunAndReturn(run func(types.OCR3ConfigWithMeta) (types.CCIPOracle, error)) *OracleCreator_Create_Call { _c.Call.Return(run) return _c } -// CreatePluginOracle provides a mock function with given fields: pluginType, config -func (_m *OracleCreator) CreatePluginOracle(pluginType types.PluginType, config types.OCR3ConfigWithMeta) (types.CCIPOracle, error) { - ret := _m.Called(pluginType, config) +// Type provides a mock function with given fields: +func (_m *OracleCreator) Type() types.OracleType { + ret := _m.Called() if len(ret) == 0 { - panic("no return value specified for CreatePluginOracle") + panic("no return value specified for Type") } - var r0 types.CCIPOracle - var r1 error - if rf, ok := ret.Get(0).(func(types.PluginType, types.OCR3ConfigWithMeta) (types.CCIPOracle, error)); ok { - return rf(pluginType, config) - } - if rf, ok := ret.Get(0).(func(types.PluginType, types.OCR3ConfigWithMeta) types.CCIPOracle); ok { - r0 = rf(pluginType, config) + var r0 types.OracleType + if rf, ok := ret.Get(0).(func() types.OracleType); ok { + r0 = rf() } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(types.CCIPOracle) - } + r0 = ret.Get(0).(types.OracleType) } - if rf, ok := ret.Get(1).(func(types.PluginType, types.OCR3ConfigWithMeta) error); ok { - r1 = rf(pluginType, config) - } else { - r1 = ret.Error(1) - } - - return r0, r1 + return r0 } -// OracleCreator_CreatePluginOracle_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreatePluginOracle' -type OracleCreator_CreatePluginOracle_Call struct { +// OracleCreator_Type_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Type' +type OracleCreator_Type_Call struct { *mock.Call } -// CreatePluginOracle is a helper method to define mock.On call -// - pluginType types.PluginType -// - config types.OCR3ConfigWithMeta -func (_e *OracleCreator_Expecter) CreatePluginOracle(pluginType interface{}, config interface{}) *OracleCreator_CreatePluginOracle_Call { - return &OracleCreator_CreatePluginOracle_Call{Call: _e.mock.On("CreatePluginOracle", pluginType, config)} +// Type is a helper method to define mock.On call +func (_e *OracleCreator_Expecter) Type() *OracleCreator_Type_Call { + return &OracleCreator_Type_Call{Call: _e.mock.On("Type")} } -func (_c *OracleCreator_CreatePluginOracle_Call) Run(run func(pluginType types.PluginType, config types.OCR3ConfigWithMeta)) *OracleCreator_CreatePluginOracle_Call { +func (_c *OracleCreator_Type_Call) Run(run func()) *OracleCreator_Type_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.PluginType), args[1].(types.OCR3ConfigWithMeta)) + run() }) return _c } -func (_c *OracleCreator_CreatePluginOracle_Call) Return(_a0 types.CCIPOracle, _a1 error) *OracleCreator_CreatePluginOracle_Call { - _c.Call.Return(_a0, _a1) +func (_c *OracleCreator_Type_Call) Return(_a0 types.OracleType) *OracleCreator_Type_Call { + _c.Call.Return(_a0) return _c } -func (_c *OracleCreator_CreatePluginOracle_Call) RunAndReturn(run func(types.PluginType, types.OCR3ConfigWithMeta) (types.CCIPOracle, error)) *OracleCreator_CreatePluginOracle_Call { +func (_c *OracleCreator_Type_Call) RunAndReturn(run func() types.OracleType) *OracleCreator_Type_Call { _c.Call.Return(run) return _c } diff --git a/core/capabilities/ccip/types/types.go b/core/capabilities/ccip/types/types.go index 952b8fe446..e42990f4c4 100644 --- a/core/capabilities/ccip/types/types.go +++ b/core/capabilities/ccip/types/types.go @@ -27,6 +27,13 @@ func (pt PluginType) String() string { } } +type OracleType uint8 + +const ( + OracleTypePlugin OracleType = 0 + OracleTypeBootstrap OracleType = 1 +) + // CCIPOracle represents either a CCIP commit or exec oracle or a bootstrap node. type CCIPOracle interface { Close() error @@ -36,11 +43,12 @@ type CCIPOracle interface { // OracleCreator is an interface for creating CCIP oracles. // Whether the oracle uses a LOOPP or not is an implementation detail. type OracleCreator interface { - // CreatePlugin creates a new oracle that will run either the commit or exec ccip plugin. + // Create creates a new oracle that will run either the commit or exec ccip plugin, + // if its a plugin oracle, or a bootstrap oracle if its a bootstrap oracle. // The oracle must be returned unstarted. - CreatePluginOracle(pluginType PluginType, config OCR3ConfigWithMeta) (CCIPOracle, error) + Create(config OCR3ConfigWithMeta) (CCIPOracle, error) - // CreateBootstrapOracle creates a new bootstrap node with the given OCR config. - // The oracle must be returned unstarted. - CreateBootstrapOracle(config OCR3ConfigWithMeta) (CCIPOracle, error) + // Type returns the type of oracle that this creator creates. + // The only valid values are OracleTypePlugin and OracleTypeBootstrap. + Type() OracleType } diff --git a/core/capabilities/ccip/validate/validate.go b/core/capabilities/ccip/validate/validate.go index 04f4f4a495..02e1cb5c8e 100644 --- a/core/capabilities/ccip/validate/validate.go +++ b/core/capabilities/ccip/validate/validate.go @@ -40,9 +40,6 @@ func ValidatedCCIPSpec(tomlString string) (jb job.Job, err error) { if jb.CCIPSpec.P2PKeyID == "" { return job.Job{}, fmt.Errorf("p2pKeyID must be set") } - if len(jb.CCIPSpec.P2PV2Bootstrappers) == 0 { - return job.Job{}, fmt.Errorf("p2pV2Bootstrappers must be set") - } // ensure that the P2PV2Bootstrappers is in the right format. for _, bootstrapperLocator := range jb.CCIPSpec.P2PV2Bootstrappers { diff --git a/core/gethwrappers/ccip/generated/fee_quoter/fee_quoter.go b/core/gethwrappers/ccip/generated/fee_quoter/fee_quoter.go index 74ed33b73a..807a932da6 100644 --- a/core/gethwrappers/ccip/generated/fee_quoter/fee_quoter.go +++ b/core/gethwrappers/ccip/generated/fee_quoter/fee_quoter.go @@ -154,8 +154,8 @@ type KeystoneFeedsPermissionHandlerPermission struct { } var FeeQuoterMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structFeeQuoter.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"priceUpdaters\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokens\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIFeeQuoter.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeeds\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structFeeQuoter.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chain\",\"type\":\"uint64\"}],\"name\":\"ChainNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DataFeedValueOutOfUint224Range\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"DestinationChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExtraArgOutOfOrderExecutionMustBeTrue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"name\":\"InvalidDestBytesOverhead\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint256\"}],\"name\":\"MessageFeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"}],\"name\":\"ReportForwarderUnauthorized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SourceTokenDataTooLarge\",\"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\":\"feedTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"storedTimeStamp\",\"type\":\"uint256\"}],\"name\":\"StaleKeystoneUpdate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenNotSupported\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainConfigUpdated\",\"type\":\"event\"},{\"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\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"name\":\"PremiumMultiplierWeiPerEthUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"indexed\":false,\"internalType\":\"structIFeeQuoter.TokenPriceFeedConfig\",\"name\":\"priceFeedConfig\",\"type\":\"tuple\"}],\"name\":\"PriceFeedPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"reportId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isAllowed\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structKeystoneFeedsPermissionHandler.Permission\",\"name\":\"permission\",\"type\":\"tuple\"}],\"name\":\"ReportPermissionSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenTransferFeeConfigDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structFeeQuoter.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"name\":\"TokenTransferFeeConfigUpdated\",\"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\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"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\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structFeeQuoter.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyPremiumMultiplierWeiPerEthUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigRemoveArgs[]\",\"name\":\"tokensToUseDefaultFeeConfigs\",\"type\":\"tuple[]\"}],\"name\":\"applyTokenTransferFeeConfigUpdates\",\"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\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"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\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getPremiumMultiplierWeiPerEth\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structFeeQuoter.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"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\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPriceFeedConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIFeeQuoter.TokenPriceFeedConfig\",\"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\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getValidatedFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getValidatedTokenPrice\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"metadata\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"onReport\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"name\":\"processMessageArgs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isOutOfOrderExecution\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"convertedExtraArgs\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"rampTokenAmounts\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"sourceTokenAmounts\",\"type\":\"tuple[]\"}],\"name\":\"processPoolReturnData\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"destExecDataPerToken\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isAllowed\",\"type\":\"bool\"}],\"internalType\":\"structKeystoneFeedsPermissionHandler.Permission[]\",\"name\":\"permissions\",\"type\":\"tuple[]\"}],\"name\":\"setReportPermissions\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"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\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIFeeQuoter.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeedUpdates\",\"type\":\"tuple[]\"}],\"name\":\"updateTokenPriceFeeds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b50604051620076d8380380620076d8833981016040819052620000349162001834565b8533806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000207565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620002b2565b5060208701516001600160a01b0316158062000112575086516001600160601b0316155b80620001265750604087015163ffffffff16155b15620001455760405163d794ef9560e01b815260040160405180910390fd5b6020878101516001600160a01b031660a05287516001600160601b031660805260408089015163ffffffff1660c05280516000815291820190526200018c90869062000401565b620001978462000549565b620001a2816200061a565b620001ad8262000a5a565b60408051600080825260208201909252620001fa91859190620001f3565b6040805180820190915260008082526020820152815260200190600190039081620001cb5790505b5062000b26565b5050505050505062001ae5565b336001600160a01b03821603620002615760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b815181101562000342576000828281518110620002db57620002db62001953565b60209081029190910101519050620002f560028262000e5f565b1562000338576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620002ba565b50815160005b8151811015620003fb57600082828151811062000369576200036962001953565b6020026020010151905060006001600160a01b0316816001600160a01b031603620003a7576040516342bcdf7f60e11b815260040160405180910390fd5b620003b460028262000e7f565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000348565b50505050565b60005b8251811015620004a2576200044083828151811062000427576200042762001953565b6020026020010151600b62000e7f60201b90919060201c565b1562000499578281815181106200045b576200045b62001953565b60200260200101516001600160a01b03167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b60010162000404565b5060005b81518110156200054457620004e2828281518110620004c957620004c962001953565b6020026020010151600b62000e9660201b90919060201c565b156200053b57818181518110620004fd57620004fd62001953565b60200260200101516001600160a01b03167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b600101620004a6565b505050565b60005b8151811015620006165760008282815181106200056d576200056d62001953565b6020908102919091018101518051818301516001600160a01b0380831660008181526007875260409081902084518154868a018051929096166001600160a81b03199091168117600160a01b60ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a25050508060010190506200054c565b5050565b60005b8151811015620006165760008282815181106200063e576200063e62001953565b6020026020010151905060008383815181106200065f576200065f62001953565b6020026020010151600001519050600082602001519050816001600160401b03166000148062000698575061016081015163ffffffff16155b80620006ba57506101e08101516001600160e01b031916630a04b54b60e21b14155b80620006da5750806060015163ffffffff1681610160015163ffffffff16115b15620007055760405163c35aa79d60e01b81526001600160401b038316600482015260240162000083565b6001600160401b038216600090815260096020526040812060010154600160881b900460e01b6001600160e01b03191690036200078557816001600160401b03167fd31c671936387b2f84ed402b553bd50c0e9c20408ea4e91a836d77b8180fb7248260405162000777919062001969565b60405180910390a2620007c9565b816001600160401b03167f1edd6f3553cfa16f10b95b195abae3a1cfca4783de4843f95d674b1e1df5ab2082604051620007c0919062001969565b60405180910390a25b8060096000846001600160401b03166001600160401b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a8154816001600160401b0302191690836001600160401b031602179055506101a082015181600101600c6101000a81548163ffffffff021916908363ffffffff1602179055506101c08201518160010160106101000a81548160ff0219169083151502179055506101e08201518160010160116101000a81548163ffffffff021916908360e01c02179055509050505050508060010190506200061d565b60005b81518110156200061657600082828151811062000a7e5762000a7e62001953565b6020026020010151600001519050600083838151811062000aa35762000aa362001953565b6020908102919091018101518101516001600160a01b03841660008181526008845260409081902080546001600160401b0319166001600160401b0385169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a2505060010162000a5d565b60005b825181101562000d9957600083828151811062000b4a5762000b4a62001953565b6020026020010151905060008160000151905060005b82602001515181101562000d8a5760008360200151828151811062000b895762000b8962001953565b602002602001015160200151905060008460200151838151811062000bb25762000bb262001953565b6020026020010151600001519050602063ffffffff16826080015163ffffffff16101562000c115760808201516040516312766e0160e11b81526001600160a01b038316600482015263ffffffff909116602482015260440162000083565b6001600160401b0384166000818152600a602090815260408083206001600160a01b0386168085529083529281902086518154938801518389015160608a015160808b015160a08c01511515600160901b0260ff60901b1963ffffffff928316600160701b021664ffffffffff60701b199383166a01000000000000000000000263ffffffff60501b1961ffff90961668010000000000000000029590951665ffffffffffff60401b19968416640100000000026001600160401b0319909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b59062000d77908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a3505060010162000b60565b50505080600101905062000b29565b5060005b81518110156200054457600082828151811062000dbe5762000dbe62001953565b6020026020010151600001519050600083838151811062000de35762000de362001953565b6020908102919091018101518101516001600160401b0384166000818152600a845260408082206001600160a01b038516808452955280822080546001600160981b03191690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a3505060010162000d9d565b600062000e76836001600160a01b03841662000ead565b90505b92915050565b600062000e76836001600160a01b03841662000fb1565b600062000e76836001600160a01b03841662001003565b6000818152600183016020526040812054801562000fa657600062000ed460018362001aad565b855490915060009062000eea9060019062001aad565b905081811462000f5657600086600001828154811062000f0e5762000f0e62001953565b906000526020600020015490508087600001848154811062000f345762000f3462001953565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000f6a5762000f6a62001acf565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000e79565b600091505062000e79565b600081815260018301602052604081205462000ffa5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000e79565b50600062000e79565b6000818152600183016020526040812054801562000fa65760006200102a60018362001aad565b8554909150600090620010409060019062001aad565b905080821462000f5657600086600001828154811062000f0e5762000f0e62001953565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b03811182821017156200109f576200109f62001064565b60405290565b60405160c081016001600160401b03811182821017156200109f576200109f62001064565b60405161020081016001600160401b03811182821017156200109f576200109f62001064565b604051601f8201601f191681016001600160401b03811182821017156200111b576200111b62001064565b604052919050565b80516001600160a01b03811681146200113b57600080fd5b919050565b805163ffffffff811681146200113b57600080fd5b6000606082840312156200116857600080fd5b604051606081016001600160401b03811182821017156200118d576200118d62001064565b604052825190915081906001600160601b0381168114620011ad57600080fd5b8152620011bd6020840162001123565b6020820152620011d06040840162001140565b60408201525092915050565b60006001600160401b03821115620011f857620011f862001064565b5060051b60200190565b600082601f8301126200121457600080fd5b815160206200122d6200122783620011dc565b620010f0565b8083825260208201915060208460051b8701019350868411156200125057600080fd5b602086015b848110156200127757620012698162001123565b835291830191830162001255565b509695505050505050565b600082601f8301126200129457600080fd5b81516020620012a76200122783620011dc565b82815260609283028501820192828201919087851115620012c757600080fd5b8387015b858110156200135a5780890382811215620012e65760008081fd5b620012f06200107a565b620012fb8362001123565b8152604080601f1984011215620013125760008081fd5b6200131c6200107a565b92506200132b88850162001123565b835283015160ff81168114620013415760008081fd5b82880152808701919091528452928401928101620012cb565b5090979650505050505050565b80516001600160401b03811681146200113b57600080fd5b805161ffff811681146200113b57600080fd5b805180151581146200113b57600080fd5b600082601f830112620013b557600080fd5b81516020620013c86200122783620011dc565b82815260059290921b84018101918181019086841115620013e857600080fd5b8286015b84811015620012775780516001600160401b03808211156200140d57600080fd5b908801906040601f19838c0381018213156200142857600080fd5b620014326200107a565b6200143f89860162001367565b815282850151848111156200145357600080fd5b8086019550508c603f8601126200146957600080fd5b8885015193506200147e6200122785620011dc565b84815260e09094028501830193898101908e8611156200149d57600080fd5b958401955b858710156200157657868f0360e0811215620014bd57600080fd5b620014c76200107a565b620014d28962001123565b815260c08683011215620014e557600080fd5b620014ef620010a5565b9150620014fe8d8a0162001140565b82526200150d878a0162001140565b8d8301526200151f60608a016200137f565b878301526200153160808a0162001140565b60608301526200154460a08a0162001140565b60808301526200155760c08a0162001392565b60a0830152808d0191909152825260e09690960195908a0190620014a2565b828b015250875250505092840192508301620013ec565b600082601f8301126200159f57600080fd5b81516020620015b26200122783620011dc565b82815260069290921b84018101918181019086841115620015d257600080fd5b8286015b84811015620012775760408189031215620015f15760008081fd5b620015fb6200107a565b620016068262001123565b81526200161585830162001367565b81860152835291830191604001620015d6565b80516001600160e01b0319811681146200113b57600080fd5b600082601f8301126200165357600080fd5b81516020620016666200122783620011dc565b82815261022092830285018201928282019190878511156200168757600080fd5b8387015b858110156200135a5780890382811215620016a65760008081fd5b620016b06200107a565b620016bb8362001367565b815261020080601f1984011215620016d35760008081fd5b620016dd620010ca565b9250620016ec88850162001392565b83526040620016fd8186016200137f565b8985015260606200171081870162001140565b82860152608091506200172582870162001140565b9085015260a06200173886820162001140565b8286015260c091506200174d8287016200137f565b9085015260e06200176086820162001140565b828601526101009150620017768287016200137f565b908501526101206200178a8682016200137f565b828601526101409150620017a08287016200137f565b90850152610160620017b486820162001140565b828601526101809150620017ca82870162001140565b908501526101a0620017de86820162001367565b828601526101c09150620017f482870162001140565b908501526101e06200180886820162001392565b828601526200181983870162001628565b9085015250508087019190915284529284019281016200168b565b6000806000806000806000610120888a0312156200185157600080fd5b6200185d898962001155565b60608901519097506001600160401b03808211156200187b57600080fd5b620018898b838c0162001202565b975060808a0151915080821115620018a057600080fd5b620018ae8b838c0162001202565b965060a08a0151915080821115620018c557600080fd5b620018d38b838c0162001282565b955060c08a0151915080821115620018ea57600080fd5b620018f88b838c01620013a3565b945060e08a01519150808211156200190f57600080fd5b6200191d8b838c016200158d565b93506101008a01519150808211156200193557600080fd5b50620019448a828b0162001641565b91505092959891949750929550565b634e487b7160e01b600052603260045260246000fd5b815115158152610200810160208301516200198a602084018261ffff169052565b506040830151620019a3604084018263ffffffff169052565b506060830151620019bc606084018263ffffffff169052565b506080830151620019d5608084018263ffffffff169052565b5060a0830151620019ec60a084018261ffff169052565b5060c083015162001a0560c084018263ffffffff169052565b5060e083015162001a1c60e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501516001600160401b0316908401526101a080850151909116908301526101c0808401511515908301526101e0928301516001600160e01b031916929091019190915290565b8181038181111562000e7957634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c051615b9962001b3f600039600081816102ef0152818161219101526121fa0152600081816102b301528181611917015261197701526000818161027f015281816119a00152611a100152615b996000f3fe608060405234801561001057600080fd5b50600436106101ce5760003560e01c806379ba509711610104578063a69c64c0116100a2578063d02641a011610071578063d02641a014610a81578063d8694ccd14610a94578063f2fde38b14610aa7578063ffdb4b3714610aba57600080fd5b8063a69c64c014610997578063bf78e03f146109aa578063c4276bfc14610a57578063cdc73d5114610a7957600080fd5b806382b49eb0116100de57806382b49eb0146107d95780638da5cb5b1461094957806391a2749a146109715780639ea600261461098457600080fd5b806379ba5097146107ab5780637afac322146107b3578063805f2132146107c657600080fd5b8063407e1086116101715780634ab35b0b1161014b5780634ab35b0b14610441578063514e8cff146104815780636def4ce714610524578063770e2dc41461079857600080fd5b8063407e1086146103fb57806341ed29e71461040e57806345ac924d1461042157600080fd5b8063085318f8116101ad578063085318f814610368578063181f5a77146103885780632451a627146103d15780633937306f146103e657600080fd5b806241e5be146101d3578063061877e3146101f957806306285c6914610252575b600080fd5b6101e66101e1366004614250565b610b02565b6040519081526020015b60405180910390f35b61023961020736600461428c565b73ffffffffffffffffffffffffffffffffffffffff1660009081526008602052604090205467ffffffffffffffff1690565b60405167ffffffffffffffff90911681526020016101f0565b61031c604080516060810182526000808252602082018190529181019190915260405180606001604052807f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000063ffffffff16815250905090565b6040805182516bffffffffffffffffffffffff16815260208084015173ffffffffffffffffffffffffffffffffffffffff16908201529181015163ffffffff16908201526060016101f0565b61037b610376366004614304565b610b70565b6040516101f09190614416565b6103c46040518060400160405280601381526020017f46656551756f74657220312e362e302d6465760000000000000000000000000081525081565b6040516101f09190614498565b6103d9610ee2565b6040516101f091906144ab565b6103f96103f4366004614505565b610ef3565b005b6103f96104093660046146a7565b6111a8565b6103f961041c3660046147d9565b6111bc565b61043461042f366004614914565b6111fe565b6040516101f09190614956565b61045461044f36600461428c565b6112c9565b6040517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b61051761048f3660046149d1565b60408051808201909152600080825260208201525067ffffffffffffffff166000908152600560209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b6040516101f091906149ec565b61078b6105323660046149d1565b6040805161020081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e08101919091525067ffffffffffffffff908116600090815260096020908152604091829020825161020081018452815460ff8082161515835261ffff61010080840482169685019690965263ffffffff630100000084048116978501979097526701000000000000008304871660608501526b0100000000000000000000008304871660808501526f010000000000000000000000000000008304811660a085015271010000000000000000000000000000000000808404881660c086015275010000000000000000000000000000000000000000008404821660e08087019190915277010000000000000000000000000000000000000000000000850483169786019790975279010000000000000000000000000000000000000000000000000084049091166101208501527b01000000000000000000000000000000000000000000000000000000909204861661014084015260019093015480861661016084015264010000000081049096166101808301526c0100000000000000000000000086049094166101a0820152700100000000000000000000000000000000850490911615156101c08201527fffffffff0000000000000000000000000000000000000000000000000000000092909304901b166101e082015290565b6040516101f09190614a27565b6103f96107a6366004614c3e565b6112d4565b6103f96112e6565b6103f96107c1366004614f58565b6113e3565b6103f96107d4366004614ffe565b6113f5565b6108e96107e736600461506a565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091525067ffffffffffffffff919091166000908152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff94909416835292815290829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a082015290565b6040516101f09190600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b6103f961097f366004615094565b6118dd565b6103f9610992366004615155565b6118ee565b6103f96109a5366004615362565b6118ff565b610a236109b836600461428c565b6040805180820182526000808252602091820181905273ffffffffffffffffffffffffffffffffffffffff93841681526007825282902082518084019093525492831682527401000000000000000000000000000000000000000090920460ff169181019190915290565b60408051825173ffffffffffffffffffffffffffffffffffffffff16815260209283015160ff1692810192909252016101f0565b610a6a610a65366004615427565b611910565b6040516101f093929190615496565b6103d9611b06565b610517610a8f36600461428c565b611b12565b6101e6610aa23660046154b7565b611c0e565b6103f9610ab536600461428c565b6120ac565b610acd610ac836600461550c565b6120bd565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9384168152929091166020830152016101f0565b6000610b0d82612248565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16610b3485612248565b610b5c907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1685615565565b610b66919061557c565b90505b9392505050565b67ffffffffffffffff8086166000908152600960205260409020600101546060917101000000000000000000000000000000000090910460e01b908590811115610bbc57610bbc614540565b604051908082528060200260200182016040528015610bef57816020015b6060815260200190600190039081610bda5790505b50915060005b85811015610ed7576000858583818110610c1157610c116155b7565b610c27926020604090920201908101915061428c565b90506000888884818110610c3d57610c3d6155b7565b9050602002810190610c4f91906155e6565b610c5d906040810190615624565b9150506020811115610d125767ffffffffffffffff8a166000908152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020546e010000000000000000000000000000900463ffffffff16811115610d12576040517f36f536ca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024015b60405180910390fd5b610d82848a8a86818110610d2857610d286155b7565b9050602002810190610d3a91906155e6565b610d48906020810190615624565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506122e292505050565b67ffffffffffffffff8a166000818152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684528252808320815160c081018352905463ffffffff8082168352640100000000820481168386015268010000000000000000820461ffff16838501526a01000000000000000000008204811660608401526e010000000000000000000000000000820481166080840152720100000000000000000000000000000000000090910460ff16151560a08301908152958552600990935290832054935190937b0100000000000000000000000000000000000000000000000000000090049091169190610e815781610e87565b82606001515b6040805163ffffffff8316602082015291925001604051602081830303815290604052888781518110610ebc57610ebc6155b7565b60200260200101819052505050505050806001019050610bf5565b505095945050505050565b6060610eee6002612339565b905090565b610efb612346565b6000610f078280615689565b9050905060005b81811015611051576000610f228480615689565b83818110610f3257610f326155b7565b905060400201803603810190610f48919061571d565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885173ffffffffffffffffffffffffffffffffffffffff9081166000908152600690975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a926110409290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610f0e565b5060006110616020840184615689565b9050905060005b818110156111a257600061107f6020860186615689565b8381811061108f5761108f6155b7565b9050604002018036038101906110a5919061575a565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885167ffffffffffffffff9081166000908152600590975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927fdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e926111919290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101611068565b50505050565b6111b061238b565b6111b98161240c565b50565b6111c461238b565b60005b81518110156111fa576111f28282815181106111e5576111e56155b7565b602002602001015161250a565b6001016111c7565b5050565b60608160008167ffffffffffffffff81111561121c5761121c614540565b60405190808252806020026020018201604052801561126157816020015b604080518082019091526000808252602082015281526020019060019003908161123a5790505b50905060005b828110156112be57611299868683818110611284576112846155b7565b9050602002016020810190610a8f919061428c565b8282815181106112ab576112ab6155b7565b6020908102919091010152600101611267565b509150505b92915050565b60006112c382612248565b6112dc61238b565b6111fa82826126dc565b60015473ffffffffffffffffffffffffffffffffffffffff163314611367576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610d09565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6113eb61238b565b6111fa8282612ae9565b600080600061143987878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612c3092505050565b92509250925061144b33838584612c4b565b60006114598587018761577d565b905060005b81518110156118d25760006007600084848151811061147f5761147f6155b7565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160009081205474010000000000000000000000000000000000000000900460ff169150819003611540578282815181106114e9576114e96155b7565b6020908102919091010151516040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610d09565b600061158960128386868151811061155a5761155a6155b7565b6020026020010151602001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16612da3565b9050600660008585815181106115a1576115a16155b7565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001601c9054906101000a900463ffffffff1663ffffffff16848481518110611613576116136155b7565b60200260200101516040015163ffffffff16101561171d5783838151811061163d5761163d6155b7565b60200260200101516000015184848151811061165b5761165b6155b7565b6020026020010151604001516006600087878151811061167d5761167d6155b7565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff90811683529082019290925260409081016000205490517f191ec70600000000000000000000000000000000000000000000000000000000815293909116600484015263ffffffff91821660248401527c01000000000000000000000000000000000000000000000000000000009004166044820152606401610d09565b6040518060400160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260200185858151811061175e5761175e6155b7565b60200260200101516040015163ffffffff1681525060066000868681518110611789576117896155b7565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251929091015163ffffffff167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092169190911790558351849084908110611821576118216155b7565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff167f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a82868681518110611877576118776155b7565b6020026020010151604001516040516118c09291907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff92909216825263ffffffff16602082015260400190565b60405180910390a2505060010161145e565b505050505050505050565b6118e561238b565b6111b981612e69565b6118f661238b565b6111b981612ff5565b61190761238b565b6111b98161349b565b60008060607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16036119705785925061199e565b61199b87877f0000000000000000000000000000000000000000000000000000000000000000610b02565b92505b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff16831115611a3d576040517f6a92a483000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610d09565b67ffffffffffffffff881660009081526009602052604081206001015463ffffffff1690611a6c878784613585565b9050806020015193508484611af3836040805182516024820152602092830151151560448083019190915282518083039091018152606490910190915290810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f181dcf100000000000000000000000000000000000000000000000000000000017905290565b9450945094505050955095509592505050565b6060610eee600b612339565b604080518082019091526000808252602082015273ffffffffffffffffffffffffffffffffffffffff8281166000908152600760209081526040918290208251808401909352549283168083527401000000000000000000000000000000000000000090930460ff169082015290611c0557505073ffffffffffffffffffffffffffffffffffffffff166000908152600660209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b610b698161372e565b67ffffffffffffffff8083166000908152600960209081526040808320815161020081018352815460ff808216151580845261ffff61010080850482169886019890985263ffffffff630100000085048116978601979097526701000000000000008404871660608601526b0100000000000000000000008404871660808601526f010000000000000000000000000000008404811660a086015271010000000000000000000000000000000000808504881660c087015275010000000000000000000000000000000000000000008504821660e08088019190915277010000000000000000000000000000000000000000000000860483169987019990995279010000000000000000000000000000000000000000000000000085049091166101208601527b01000000000000000000000000000000000000000000000000000000909304861661014085015260019094015480861661016085015264010000000081049098166101808401526c0100000000000000000000000088049094166101a0830152700100000000000000000000000000000000870490931615156101c08201527fffffffff000000000000000000000000000000000000000000000000000000009290950490921b166101e0840152909190611e28576040517f99ac52f200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610d09565b6000611e376040850185615689565b9150611e93905082611e4c6020870187615624565b905083611e598880615624565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506138bd92505050565b6000600881611ea8608088016060890161428c565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160009081205467ffffffffffffffff16915080611ef7611ef16080890160608a0161428c565b896120bd565b9092509050600080808615611f3d57611f31888c611f1b60808e0160608f0161428c565b888e8060400190611f2c9190615689565b613967565b91945092509050611f5d565b6101a0880151611f5a9063ffffffff16662386f26fc10000615565565b92505b61010088015160009061ffff1615611fa157611f9e896dffffffffffffffffffffffffffff607088901c16611f9560208f018f615624565b90508b86613c3f565b90505b61018089015160009067ffffffffffffffff16611fca611fc460808f018f615624565b8d613cef565b600001518563ffffffff168c60a0015161ffff168f8060200190611fee9190615624565b611ff9929150615565565b8d6080015163ffffffff1661200e9190615844565b6120189190615844565b6120229190615844565b61203c906dffffffffffffffffffffffffffff8916615565565b6120469190615565565b90507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8716828261207d67ffffffffffffffff8c1689615565565b6120879190615844565b6120919190615844565b61209b919061557c565b9d9c50505050505050505050505050565b6120b461238b565b6111b981613db0565b67ffffffffffffffff811660009081526005602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff1691810182905282918203612175576040517f2e59db3a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610d09565b6000816020015163ffffffff164261218d9190615857565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff1681111561222e576040517ff08bcb3e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401610d09565b61223786612248565b9151919350909150505b9250929050565b60008061225483611b12565b9050806020015163ffffffff166000148061228c575080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16155b156122db576040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610d09565b5192915050565b7fd7ed2ad4000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316016111fa5761233481613ea5565b505050565b60606000610b6983613f58565b612351600233613fb4565b612389576040517fd86ad9cf000000000000000000000000000000000000000000000000000000008152336004820152602401610d09565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314612389576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610d09565b60005b81518110156111fa57600082828151811061242c5761242c6155b7565b60209081029190910181015180518183015173ffffffffffffffffffffffffffffffffffffffff80831660008181526007875260409081902084518154868a018051929096167fffffffffffffffffffffff00000000000000000000000000000000000000000090911681177401000000000000000000000000000000000000000060ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a250505080600101905061240f565b60006125c382600001518360600151846020015185604001516040805173ffffffffffffffffffffffffffffffffffffffff80871660208301528516918101919091527fffffffffffffffffffff00000000000000000000000000000000000000000000831660608201527fffff0000000000000000000000000000000000000000000000000000000000008216608082015260009060a001604051602081830303815290604052805190602001209050949350505050565b60808301516000828152600460205260409081902080549215157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909316929092179091555190915081907f32a4ba3fa3351b11ad555d4c8ec70a744e8705607077a946807030d64b6ab1a3906126d0908590600060a08201905073ffffffffffffffffffffffffffffffffffffffff8084511683527fffffffffffffffffffff0000000000000000000000000000000000000000000060208501511660208401527fffff00000000000000000000000000000000000000000000000000000000000060408501511660408401528060608501511660608401525060808301511515608083015292915050565b60405180910390a25050565b60005b8251811015612a055760008382815181106126fc576126fc6155b7565b6020026020010151905060008160000151905060005b8260200151518110156129f757600083602001518281518110612737576127376155b7565b602002602001015160200151905060008460200151838151811061275d5761275d6155b7565b6020026020010151600001519050602063ffffffff16826080015163ffffffff1610156127e05760808201516040517f24ecdc0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015263ffffffff9091166024820152604401610d09565b67ffffffffffffffff84166000818152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff86168085529083529281902086518154938801518389015160608a015160808b015160a08c015115157201000000000000000000000000000000000000027fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff63ffffffff9283166e01000000000000000000000000000002167fffffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffff9383166a0100000000000000000000027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff61ffff9096166801000000000000000002959095167fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff968416640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b5906129e5908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a35050600101612712565b5050508060010190506126df565b5060005b8151811015612334576000828281518110612a2657612a266155b7565b60200260200101516000015190506000838381518110612a4857612a486155b7565b60209081029190910181015181015167ffffffffffffffff84166000818152600a8452604080822073ffffffffffffffffffffffffffffffffffffffff8516808452955280822080547fffffffffffffffffffffffffff000000000000000000000000000000000000001690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a35050600101612a09565b60005b8251811015612b8c57612b22838281518110612b0a57612b0a6155b7565b6020026020010151600b613fe390919063ffffffff16565b15612b8457828181518110612b3957612b396155b7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b600101612aec565b5060005b815181101561233457612bc6828281518110612bae57612bae6155b7565b6020026020010151600b61400590919063ffffffff16565b15612c2857818181518110612bdd57612bdd6155b7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b600101612b90565b6040810151604a820151605e90920151909260609290921c91565b6040805173ffffffffffffffffffffffffffffffffffffffff868116602080840191909152908616828401527fffffffffffffffffffff00000000000000000000000000000000000000000000851660608301527fffff00000000000000000000000000000000000000000000000000000000000084166080808401919091528351808403909101815260a09092018352815191810191909120600081815260049092529190205460ff16612d9c576040517f097e17ff00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8087166004830152851660248201527fffffffffffffffffffff00000000000000000000000000000000000000000000841660448201527fffff00000000000000000000000000000000000000000000000000000000000083166064820152608401610d09565b5050505050565b600080612db0848661586a565b9050600060248260ff161115612de757612dcb602483615883565b612dd690600a6159bc565b612de0908561557c565b9050612e0a565b612df2826024615883565b612dfd90600a6159bc565b612e079085615565565b90505b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811115612e60576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b95945050505050565b602081015160005b8151811015612f04576000828281518110612e8e57612e8e6155b7565b60200260200101519050612eac81600261402790919063ffffffff16565b15612efb5760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101612e71565b50815160005b81518110156111a2576000828281518110612f2757612f276155b7565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612f97576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612fa2600282613fe3565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a150600101612f0a565b60005b81518110156111fa576000828281518110613015576130156155b7565b602002602001015190506000838381518110613033576130336155b7565b60200260200101516000015190506000826020015190508167ffffffffffffffff166000148061306c575061016081015163ffffffff16155b806130be57506101e08101517fffffffff00000000000000000000000000000000000000000000000000000000167f2812d52c0000000000000000000000000000000000000000000000000000000014155b806130dd5750806060015163ffffffff1681610160015163ffffffff16115b15613120576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff83166004820152602401610d09565b67ffffffffffffffff821660009081526009602052604081206001015471010000000000000000000000000000000000900460e01b7fffffffff000000000000000000000000000000000000000000000000000000001690036131c4578167ffffffffffffffff167fd31c671936387b2f84ed402b553bd50c0e9c20408ea4e91a836d77b8180fb724826040516131b79190614a27565b60405180910390a2613207565b8167ffffffffffffffff167f1edd6f3553cfa16f10b95b195abae3a1cfca4783de4843f95d674b1e1df5ab20826040516131fe9190614a27565b60405180910390a25b80600960008467ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506101a082015181600101600c6101000a81548163ffffffff021916908363ffffffff1602179055506101c08201518160010160106101000a81548160ff0219169083151502179055506101e08201518160010160116101000a81548163ffffffff021916908360e01c0217905550905050505050806001019050612ff8565b60005b81518110156111fa5760008282815181106134bb576134bb6155b7565b602002602001015160000151905060008383815181106134dd576134dd6155b7565b60209081029190910181015181015173ffffffffffffffffffffffffffffffffffffffff841660008181526008845260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a2505060010161349e565b604080518082019091526000808252602082015260008390036135c657506040805180820190915267ffffffffffffffff8216815260006020820152610b69565b60006135d284866159cb565b905060006135e38560048189615a11565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050507fffffffff0000000000000000000000000000000000000000000000000000000082167fe7e230f0000000000000000000000000000000000000000000000000000000000161368057808060200190518101906136779190615a3b565b92505050610b69565b7f6859a837000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316016136fc576040518060400160405280828060200190518101906136e89190615a67565b815260006020909101529250610b69915050565b6040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091526000808252602082015260008260000151905060008173ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613798573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137bc9190615a9a565b50505091505060008112156137fd576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061387c8373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561384d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138719190615aea565b866020015184612da3565b604080518082019091527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909116815263ffffffff4216602082015295945050505050565b836040015163ffffffff168311156139165760408085015190517f8693378900000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101849052604401610d09565b836020015161ffff16821115613958576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111a2846101e00151826122e2565b6000808083815b81811015613c3157600087878381811061398a5761398a6155b7565b9050604002018036038101906139a09190615b07565b67ffffffffffffffff8c166000908152600a60209081526040808320845173ffffffffffffffffffffffffffffffffffffffff168452825291829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a0820181905291925090613ac0576101208d0151613a8d9061ffff16662386f26fc10000615565565b613a979088615844565b96508c610140015186613aaa9190615b40565b9550613ab7602086615b40565b94505050613c29565b604081015160009061ffff1615613b795760008c73ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff1614613b1c578351613b1590612248565b9050613b1f565b508a5b620186a0836040015161ffff16613b618660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661404990919063ffffffff16565b613b6b9190615565565b613b75919061557c565b9150505b6060820151613b889088615b40565b9650816080015186613b9a9190615b40565b8251909650600090613bb99063ffffffff16662386f26fc10000615565565b905080821015613bd857613bcd818a615844565b985050505050613c29565b6000836020015163ffffffff16662386f26fc10000613bf79190615565565b905080831115613c1757613c0b818b615844565b99505050505050613c29565b613c21838b615844565b995050505050505b60010161396e565b505096509650969350505050565b60008063ffffffff8316613c5561016086615565565b613c61876101c0615844565b613c6b9190615844565b613c759190615844565b905060008760c0015163ffffffff168860e0015161ffff1683613c989190615565565b613ca29190615844565b61010089015190915061ffff16613cc96dffffffffffffffffffffffffffff891683615565565b613cd39190615565565b613ce390655af3107a4000615565565b98975050505050505050565b60408051808201909152600080825260208201526000613d1b858585610160015163ffffffff16613585565b9050826060015163ffffffff1681600001511115613d65576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826101c001518015613d7957508060200151155b15610b66576040517fee433e9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821603613e2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610d09565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008151602014613ee457816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610d099190614498565b600082806020019051810190613efa9190615a67565b905073ffffffffffffffffffffffffffffffffffffffff811180613f1f575061040081105b156112c357826040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610d099190614498565b606081600001805480602002602001604051908101604052809291908181526020018280548015613fa857602002820191906000526020600020905b815481526020019060010190808311613f94575b50505050509050919050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610b69565b6000610b698373ffffffffffffffffffffffffffffffffffffffff8416614086565b6000610b698373ffffffffffffffffffffffffffffffffffffffff84166140d5565b6000610b698373ffffffffffffffffffffffffffffffffffffffff84166141cf565b6000670de0b6b3a764000061407c837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8616615565565b610b69919061557c565b60008181526001830160205260408120546140cd575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556112c3565b5060006112c3565b600081815260018301602052604081205480156141be5760006140f9600183615857565b855490915060009061410d90600190615857565b905080821461417257600086600001828154811061412d5761412d6155b7565b9060005260206000200154905080876000018481548110614150576141506155b7565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061418357614183615b5d565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506112c3565b60009150506112c3565b5092915050565b600081815260018301602052604081205480156141be5760006141f3600183615857565b855490915060009061420790600190615857565b905081811461417257600086600001828154811061412d5761412d6155b7565b803573ffffffffffffffffffffffffffffffffffffffff8116811461424b57600080fd5b919050565b60008060006060848603121561426557600080fd5b61426e84614227565b92506020840135915061428360408501614227565b90509250925092565b60006020828403121561429e57600080fd5b610b6982614227565b803567ffffffffffffffff8116811461424b57600080fd5b60008083601f8401126142d157600080fd5b50813567ffffffffffffffff8111156142e957600080fd5b6020830191508360208260051b850101111561224157600080fd5b60008060008060006060868803121561431c57600080fd5b614325866142a7565b9450602086013567ffffffffffffffff8082111561434257600080fd5b61434e89838a016142bf565b9096509450604088013591508082111561436757600080fd5b818801915088601f83011261437b57600080fd5b81358181111561438a57600080fd5b8960208260061b850101111561439f57600080fd5b9699959850939650602001949392505050565b6000815180845260005b818110156143d8576020818501810151868301820152016143bc565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b8281101561448b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526144798583516143b2565b9450928501929085019060010161443f565b5092979650505050505050565b602081526000610b6960208301846143b2565b6020808252825182820181905260009190848201906040850190845b818110156144f957835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016144c7565b50909695505050505050565b60006020828403121561451757600080fd5b813567ffffffffffffffff81111561452e57600080fd5b820160408185031215610b6957600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561459257614592614540565b60405290565b60405160a0810167ffffffffffffffff8111828210171561459257614592614540565b60405160c0810167ffffffffffffffff8111828210171561459257614592614540565b604051610200810167ffffffffffffffff8111828210171561459257614592614540565b6040516060810167ffffffffffffffff8111828210171561459257614592614540565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561466c5761466c614540565b604052919050565b600067ffffffffffffffff82111561468e5761468e614540565b5060051b60200190565b60ff811681146111b957600080fd5b600060208083850312156146ba57600080fd5b823567ffffffffffffffff8111156146d157600080fd5b8301601f810185136146e257600080fd5b80356146f56146f082614674565b614625565b8181526060918202830184019184820191908884111561471457600080fd5b938501935b838510156147b457848903818112156147325760008081fd5b61473a61456f565b61474387614227565b81526040807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156147775760008081fd5b61477f61456f565b925061478c898901614227565b835287013561479a81614698565b828901528088019190915283529384019391850191614719565b50979650505050505050565b80151581146111b957600080fd5b803561424b816147c0565b600060208083850312156147ec57600080fd5b823567ffffffffffffffff81111561480357600080fd5b8301601f8101851361481457600080fd5b80356148226146f082614674565b81815260a0918202830184019184820191908884111561484157600080fd5b938501935b838510156147b45780858a03121561485e5760008081fd5b614866614598565b61486f86614227565b8152868601357fffffffffffffffffffff00000000000000000000000000000000000000000000811681146148a45760008081fd5b818801526040868101357fffff000000000000000000000000000000000000000000000000000000000000811681146148dd5760008081fd5b9082015260606148ee878201614227565b90820152608086810135614901816147c0565b9082015283529384019391850191614846565b6000806020838503121561492757600080fd5b823567ffffffffffffffff81111561493e57600080fd5b61494a858286016142bf565b90969095509350505050565b602080825282518282018190526000919060409081850190868401855b828110156149c4576149b484835180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16825260209081015163ffffffff16910152565b9284019290850190600101614973565b5091979650505050505050565b6000602082840312156149e357600080fd5b610b69826142a7565b81517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260208083015163ffffffff1690820152604081016112c3565b81511515815261020081016020830151614a47602084018261ffff169052565b506040830151614a5f604084018263ffffffff169052565b506060830151614a77606084018263ffffffff169052565b506080830151614a8f608084018263ffffffff169052565b5060a0830151614aa560a084018261ffff169052565b5060c0830151614abd60c084018263ffffffff169052565b5060e0830151614ad360e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff90811691840191909152610160808501518216908401526101808085015167ffffffffffffffff16908401526101a080850151909116908301526101c0808401511515908301526101e0808401517fffffffff000000000000000000000000000000000000000000000000000000008116828501525b505092915050565b803563ffffffff8116811461424b57600080fd5b803561ffff8116811461424b57600080fd5b600082601f830112614bb757600080fd5b81356020614bc76146f083614674565b82815260069290921b84018101918181019086841115614be657600080fd5b8286015b84811015614c335760408189031215614c035760008081fd5b614c0b61456f565b614c14826142a7565b8152614c21858301614227565b81860152835291830191604001614bea565b509695505050505050565b60008060408385031215614c5157600080fd5b67ffffffffffffffff83351115614c6757600080fd5b83601f843585010112614c7957600080fd5b614c896146f08435850135614674565b8335840180358083526020808401939260059290921b90910101861015614caf57600080fd5b602085358601015b85358601803560051b01602001811015614ebc5767ffffffffffffffff81351115614ce157600080fd5b8035863587010160407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828a03011215614d1a57600080fd5b614d2261456f565b614d2e602083016142a7565b815267ffffffffffffffff60408301351115614d4957600080fd5b88603f604084013584010112614d5e57600080fd5b614d746146f06020604085013585010135614674565b6020604084810135850182810135808552928401939260e00201018b1015614d9b57600080fd5b6040808501358501015b6040858101358601602081013560e0020101811015614e9d5760e0818d031215614dce57600080fd5b614dd661456f565b614ddf82614227565b815260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838f03011215614e1357600080fd5b614e1b6145bb565b614e2760208401614b80565b8152614e3560408401614b80565b6020820152614e4660608401614b94565b6040820152614e5760808401614b80565b6060820152614e6860a08401614b80565b6080820152614e7a60c08401356147c0565b60c083013560a0820152602082810191909152908452929092019160e001614da5565b5080602084015250508085525050602083019250602081019050614cb7565b5092505067ffffffffffffffff60208401351115614ed957600080fd5b614ee98460208501358501614ba6565b90509250929050565b600082601f830112614f0357600080fd5b81356020614f136146f083614674565b8083825260208201915060208460051b870101935086841115614f3557600080fd5b602086015b84811015614c3357614f4b81614227565b8352918301918301614f3a565b60008060408385031215614f6b57600080fd5b823567ffffffffffffffff80821115614f8357600080fd5b614f8f86838701614ef2565b93506020850135915080821115614fa557600080fd5b50614fb285828601614ef2565b9150509250929050565b60008083601f840112614fce57600080fd5b50813567ffffffffffffffff811115614fe657600080fd5b60208301915083602082850101111561224157600080fd5b6000806000806040858703121561501457600080fd5b843567ffffffffffffffff8082111561502c57600080fd5b61503888838901614fbc565b9096509450602087013591508082111561505157600080fd5b5061505e87828801614fbc565b95989497509550505050565b6000806040838503121561507d57600080fd5b615086836142a7565b9150614ee960208401614227565b6000602082840312156150a657600080fd5b813567ffffffffffffffff808211156150be57600080fd5b90830190604082860312156150d257600080fd5b6150da61456f565b8235828111156150e957600080fd5b6150f587828601614ef2565b82525060208301358281111561510a57600080fd5b61511687828601614ef2565b60208301525095945050505050565b80357fffffffff000000000000000000000000000000000000000000000000000000008116811461424b57600080fd5b6000602080838503121561516857600080fd5b823567ffffffffffffffff81111561517f57600080fd5b8301601f8101851361519057600080fd5b803561519e6146f082614674565b81815261022091820283018401918482019190888411156151be57600080fd5b938501935b838510156147b457848903818112156151dc5760008081fd5b6151e461456f565b6151ed876142a7565b8152610200807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156152225760008081fd5b61522a6145de565b92506152378989016147ce565b83526040615246818a01614b94565b8a8501526060615257818b01614b80565b828601526080915061526a828b01614b80565b9085015260a061527b8a8201614b80565b8286015260c0915061528e828b01614b94565b9085015260e061529f8a8201614b80565b8286015261010091506152b3828b01614b94565b908501526101206152c58a8201614b94565b8286015261014091506152d9828b01614b94565b908501526101606152eb8a8201614b80565b8286015261018091506152ff828b01614b80565b908501526101a06153118a82016142a7565b828601526101c09150615325828b01614b80565b908501526101e06153378a82016147ce565b82860152615346838b01615125565b90850152505080880191909152835293840193918501916151c3565b6000602080838503121561537557600080fd5b823567ffffffffffffffff81111561538c57600080fd5b8301601f8101851361539d57600080fd5b80356153ab6146f082614674565b81815260069190911b820183019083810190878311156153ca57600080fd5b928401925b8284101561541c57604084890312156153e85760008081fd5b6153f061456f565b6153f985614227565b81526154068686016142a7565b81870152825260409390930192908401906153cf565b979650505050505050565b60008060008060006080868803121561543f57600080fd5b615448866142a7565b945061545660208701614227565b935060408601359250606086013567ffffffffffffffff81111561547957600080fd5b61548588828901614fbc565b969995985093965092949392505050565b8381528215156020820152606060408201526000612e6060608301846143b2565b600080604083850312156154ca57600080fd5b6154d3836142a7565b9150602083013567ffffffffffffffff8111156154ef57600080fd5b830160a0818603121561550157600080fd5b809150509250929050565b6000806040838503121561551f57600080fd5b61552883614227565b9150614ee9602084016142a7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176112c3576112c3615536565b6000826155b2577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6183360301811261561a57600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261565957600080fd5b83018035915067ffffffffffffffff82111561567457600080fd5b60200191503681900382131561224157600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126156be57600080fd5b83018035915067ffffffffffffffff8211156156d957600080fd5b6020019150600681901b360382131561224157600080fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461424b57600080fd5b60006040828403121561572f57600080fd5b61573761456f565b61574083614227565b815261574e602084016156f1565b60208201529392505050565b60006040828403121561576c57600080fd5b61577461456f565b615740836142a7565b6000602080838503121561579057600080fd5b823567ffffffffffffffff8111156157a757600080fd5b8301601f810185136157b857600080fd5b80356157c66146f082614674565b818152606091820283018401918482019190888411156157e557600080fd5b938501935b838510156147b45780858a0312156158025760008081fd5b61580a614602565b61581386614227565b81526158208787016156f1565b878201526040615831818801614b80565b90820152835293840193918501916157ea565b808201808211156112c3576112c3615536565b818103818111156112c3576112c3615536565b60ff81811683821601908111156112c3576112c3615536565b60ff82811682821603908111156112c3576112c3615536565b600181815b808511156158f557817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156158db576158db615536565b808516156158e857918102915b93841c93908002906158a1565b509250929050565b60008261590c575060016112c3565b81615919575060006112c3565b816001811461592f576002811461593957615955565b60019150506112c3565b60ff84111561594a5761594a615536565b50506001821b6112c3565b5060208310610133831016604e8410600b8410161715615978575081810a6112c3565b615982838361589c565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156159b4576159b4615536565b029392505050565b6000610b6960ff8416836158fd565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015614b785760049490940360031b84901b1690921692915050565b60008085851115615a2157600080fd5b83861115615a2e57600080fd5b5050820193919092039150565b600060408284031215615a4d57600080fd5b615a5561456f565b82518152602083015161574e816147c0565b600060208284031215615a7957600080fd5b5051919050565b805169ffffffffffffffffffff8116811461424b57600080fd5b600080600080600060a08688031215615ab257600080fd5b615abb86615a80565b9450602086015193506040860151925060608601519150615ade60808701615a80565b90509295509295909350565b600060208284031215615afc57600080fd5b8151610b6981614698565b600060408284031215615b1957600080fd5b615b2161456f565b615b2a83614227565b8152602083013560208201528091505092915050565b63ffffffff8181168382160190808211156141c8576141c8615536565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structFeeQuoter.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"priceUpdaters\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokens\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIFeeQuoter.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeeds\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structFeeQuoter.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chain\",\"type\":\"uint64\"}],\"name\":\"ChainNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DataFeedValueOutOfUint224Range\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"DestinationChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExtraArgOutOfOrderExecutionMustBeTrue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"FeeTokenNotSupported\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"name\":\"InvalidDestBytesOverhead\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidEVMAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidStaticConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint256\"}],\"name\":\"MessageFeeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"}],\"name\":\"ReportForwarderUnauthorized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SourceTokenDataTooLarge\",\"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\":\"feedTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"storedTimeStamp\",\"type\":\"uint256\"}],\"name\":\"StaleKeystoneUpdate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenNotSupported\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"indexed\":false,\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainConfigUpdated\",\"type\":\"event\"},{\"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\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"name\":\"PremiumMultiplierWeiPerEthUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"indexed\":false,\"internalType\":\"structIFeeQuoter.TokenPriceFeedConfig\",\"name\":\"priceFeedConfig\",\"type\":\"tuple\"}],\"name\":\"PriceFeedPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"reportId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isAllowed\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structKeystoneFeedsPermissionHandler.Permission\",\"name\":\"permission\",\"type\":\"tuple\"}],\"name\":\"ReportPermissionSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenTransferFeeConfigDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structFeeQuoter.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"name\":\"TokenTransferFeeConfigUpdated\",\"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\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"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\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"internalType\":\"structFeeQuoter.PremiumMultiplierWeiPerEthArgs[]\",\"name\":\"premiumMultiplierWeiPerEthArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyPremiumMultiplierWeiPerEthUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigSingleTokenArgs[]\",\"name\":\"tokenTransferFeeConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfigRemoveArgs[]\",\"name\":\"tokensToUseDefaultFeeConfigs\",\"type\":\"tuple[]\"}],\"name\":\"applyTokenTransferFeeConfigUpdates\",\"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\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint16\",\"name\":\"maxNumberOfTokensPerMsg\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataBytes\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerMsgGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplierBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"defaultTokenFeeUSDCents\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"defaultTokenDestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplierWeiPerEth\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enforceOutOfOrder\",\"type\":\"bool\"},{\"internalType\":\"bytes4\",\"name\":\"chainFamilySelector\",\"type\":\"bytes4\"}],\"internalType\":\"structFeeQuoter.DestChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"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\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getPremiumMultiplierWeiPerEth\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"premiumMultiplierWeiPerEth\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"maxFeeJuelsPerMsg\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"internalType\":\"structFeeQuoter.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"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\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPriceFeedConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIFeeQuoter.TokenPriceFeedConfig\",\"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\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSDCents\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"deciBps\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"}],\"internalType\":\"structFeeQuoter.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getValidatedFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getValidatedTokenPrice\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"metadata\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"onReport\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"name\":\"processMessageArgs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"msgFeeJuels\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isOutOfOrderExecution\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"convertedExtraArgs\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"rampTokenAmounts\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"sourceTokenAmounts\",\"type\":\"tuple[]\"}],\"name\":\"processPoolReturnData\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"destExecDataPerToken\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"bytes10\",\"name\":\"workflowName\",\"type\":\"bytes10\"},{\"internalType\":\"bytes2\",\"name\":\"reportName\",\"type\":\"bytes2\"},{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isAllowed\",\"type\":\"bool\"}],\"internalType\":\"structKeystoneFeedsPermissionHandler.Permission[]\",\"name\":\"permissions\",\"type\":\"tuple[]\"}],\"name\":\"setReportPermissions\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"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\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"dataFeedAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structIFeeQuoter.TokenPriceFeedConfig\",\"name\":\"feedConfig\",\"type\":\"tuple\"}],\"internalType\":\"structFeeQuoter.TokenPriceFeedUpdate[]\",\"name\":\"tokenPriceFeedUpdates\",\"type\":\"tuple[]\"}],\"name\":\"updateTokenPriceFeeds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60e06040523480156200001157600080fd5b506040516200775238038062007752833981016040819052620000349162001834565b8533806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000207565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620002b2565b5060208701516001600160a01b0316158062000112575086516001600160601b0316155b80620001265750604087015163ffffffff16155b15620001455760405163d794ef9560e01b815260040160405180910390fd5b6020878101516001600160a01b031660a05287516001600160601b031660805260408089015163ffffffff1660c05280516000815291820190526200018c90869062000401565b620001978462000549565b620001a2816200061a565b620001ad8262000a5a565b60408051600080825260208201909252620001fa91859190620001f3565b6040805180820190915260008082526020820152815260200190600190039081620001cb5790505b5062000b26565b5050505050505062001ae5565b336001600160a01b03821603620002615760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b815181101562000342576000828281518110620002db57620002db62001953565b60209081029190910101519050620002f560028262000e5f565b1562000338576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620002ba565b50815160005b8151811015620003fb57600082828151811062000369576200036962001953565b6020026020010151905060006001600160a01b0316816001600160a01b031603620003a7576040516342bcdf7f60e11b815260040160405180910390fd5b620003b460028262000e7f565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000348565b50505050565b60005b8251811015620004a2576200044083828151811062000427576200042762001953565b6020026020010151600b62000e7f60201b90919060201c565b1562000499578281815181106200045b576200045b62001953565b60200260200101516001600160a01b03167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b60010162000404565b5060005b81518110156200054457620004e2828281518110620004c957620004c962001953565b6020026020010151600b62000e9660201b90919060201c565b156200053b57818181518110620004fd57620004fd62001953565b60200260200101516001600160a01b03167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b600101620004a6565b505050565b60005b8151811015620006165760008282815181106200056d576200056d62001953565b6020908102919091018101518051818301516001600160a01b0380831660008181526007875260409081902084518154868a018051929096166001600160a81b03199091168117600160a01b60ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a25050508060010190506200054c565b5050565b60005b8151811015620006165760008282815181106200063e576200063e62001953565b6020026020010151905060008383815181106200065f576200065f62001953565b6020026020010151600001519050600082602001519050816001600160401b03166000148062000698575061016081015163ffffffff16155b80620006ba57506101e08101516001600160e01b031916630a04b54b60e21b14155b80620006da5750806060015163ffffffff1681610160015163ffffffff16115b15620007055760405163c35aa79d60e01b81526001600160401b038316600482015260240162000083565b6001600160401b038216600090815260096020526040812060010154600160881b900460e01b6001600160e01b03191690036200078557816001600160401b03167fd31c671936387b2f84ed402b553bd50c0e9c20408ea4e91a836d77b8180fb7248260405162000777919062001969565b60405180910390a2620007c9565b816001600160401b03167f1edd6f3553cfa16f10b95b195abae3a1cfca4783de4843f95d674b1e1df5ab2082604051620007c0919062001969565b60405180910390a25b8060096000846001600160401b03166001600160401b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a8154816001600160401b0302191690836001600160401b031602179055506101a082015181600101600c6101000a81548163ffffffff021916908363ffffffff1602179055506101c08201518160010160106101000a81548160ff0219169083151502179055506101e08201518160010160116101000a81548163ffffffff021916908360e01c02179055509050505050508060010190506200061d565b60005b81518110156200061657600082828151811062000a7e5762000a7e62001953565b6020026020010151600001519050600083838151811062000aa35762000aa362001953565b6020908102919091018101518101516001600160a01b03841660008181526008845260409081902080546001600160401b0319166001600160401b0385169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a2505060010162000a5d565b60005b825181101562000d9957600083828151811062000b4a5762000b4a62001953565b6020026020010151905060008160000151905060005b82602001515181101562000d8a5760008360200151828151811062000b895762000b8962001953565b602002602001015160200151905060008460200151838151811062000bb25762000bb262001953565b6020026020010151600001519050602063ffffffff16826080015163ffffffff16101562000c115760808201516040516312766e0160e11b81526001600160a01b038316600482015263ffffffff909116602482015260440162000083565b6001600160401b0384166000818152600a602090815260408083206001600160a01b0386168085529083529281902086518154938801518389015160608a015160808b015160a08c01511515600160901b0260ff60901b1963ffffffff928316600160701b021664ffffffffff60701b199383166a01000000000000000000000263ffffffff60501b1961ffff90961668010000000000000000029590951665ffffffffffff60401b19968416640100000000026001600160401b0319909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b59062000d77908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a3505060010162000b60565b50505080600101905062000b29565b5060005b81518110156200054457600082828151811062000dbe5762000dbe62001953565b6020026020010151600001519050600083838151811062000de35762000de362001953565b6020908102919091018101518101516001600160401b0384166000818152600a845260408082206001600160a01b038516808452955280822080546001600160981b03191690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a3505060010162000d9d565b600062000e76836001600160a01b03841662000ead565b90505b92915050565b600062000e76836001600160a01b03841662000fb1565b600062000e76836001600160a01b03841662001003565b6000818152600183016020526040812054801562000fa657600062000ed460018362001aad565b855490915060009062000eea9060019062001aad565b905081811462000f5657600086600001828154811062000f0e5762000f0e62001953565b906000526020600020015490508087600001848154811062000f345762000f3462001953565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000f6a5762000f6a62001acf565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000e79565b600091505062000e79565b600081815260018301602052604081205462000ffa5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000e79565b50600062000e79565b6000818152600183016020526040812054801562000fa65760006200102a60018362001aad565b8554909150600090620010409060019062001aad565b905080821462000f5657600086600001828154811062000f0e5762000f0e62001953565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b03811182821017156200109f576200109f62001064565b60405290565b60405160c081016001600160401b03811182821017156200109f576200109f62001064565b60405161020081016001600160401b03811182821017156200109f576200109f62001064565b604051601f8201601f191681016001600160401b03811182821017156200111b576200111b62001064565b604052919050565b80516001600160a01b03811681146200113b57600080fd5b919050565b805163ffffffff811681146200113b57600080fd5b6000606082840312156200116857600080fd5b604051606081016001600160401b03811182821017156200118d576200118d62001064565b604052825190915081906001600160601b0381168114620011ad57600080fd5b8152620011bd6020840162001123565b6020820152620011d06040840162001140565b60408201525092915050565b60006001600160401b03821115620011f857620011f862001064565b5060051b60200190565b600082601f8301126200121457600080fd5b815160206200122d6200122783620011dc565b620010f0565b8083825260208201915060208460051b8701019350868411156200125057600080fd5b602086015b848110156200127757620012698162001123565b835291830191830162001255565b509695505050505050565b600082601f8301126200129457600080fd5b81516020620012a76200122783620011dc565b82815260609283028501820192828201919087851115620012c757600080fd5b8387015b858110156200135a5780890382811215620012e65760008081fd5b620012f06200107a565b620012fb8362001123565b8152604080601f1984011215620013125760008081fd5b6200131c6200107a565b92506200132b88850162001123565b835283015160ff81168114620013415760008081fd5b82880152808701919091528452928401928101620012cb565b5090979650505050505050565b80516001600160401b03811681146200113b57600080fd5b805161ffff811681146200113b57600080fd5b805180151581146200113b57600080fd5b600082601f830112620013b557600080fd5b81516020620013c86200122783620011dc565b82815260059290921b84018101918181019086841115620013e857600080fd5b8286015b84811015620012775780516001600160401b03808211156200140d57600080fd5b908801906040601f19838c0381018213156200142857600080fd5b620014326200107a565b6200143f89860162001367565b815282850151848111156200145357600080fd5b8086019550508c603f8601126200146957600080fd5b8885015193506200147e6200122785620011dc565b84815260e09094028501830193898101908e8611156200149d57600080fd5b958401955b858710156200157657868f0360e0811215620014bd57600080fd5b620014c76200107a565b620014d28962001123565b815260c08683011215620014e557600080fd5b620014ef620010a5565b9150620014fe8d8a0162001140565b82526200150d878a0162001140565b8d8301526200151f60608a016200137f565b878301526200153160808a0162001140565b60608301526200154460a08a0162001140565b60808301526200155760c08a0162001392565b60a0830152808d0191909152825260e09690960195908a0190620014a2565b828b015250875250505092840192508301620013ec565b600082601f8301126200159f57600080fd5b81516020620015b26200122783620011dc565b82815260069290921b84018101918181019086841115620015d257600080fd5b8286015b84811015620012775760408189031215620015f15760008081fd5b620015fb6200107a565b620016068262001123565b81526200161585830162001367565b81860152835291830191604001620015d6565b80516001600160e01b0319811681146200113b57600080fd5b600082601f8301126200165357600080fd5b81516020620016666200122783620011dc565b82815261022092830285018201928282019190878511156200168757600080fd5b8387015b858110156200135a5780890382811215620016a65760008081fd5b620016b06200107a565b620016bb8362001367565b815261020080601f1984011215620016d35760008081fd5b620016dd620010ca565b9250620016ec88850162001392565b83526040620016fd8186016200137f565b8985015260606200171081870162001140565b82860152608091506200172582870162001140565b9085015260a06200173886820162001140565b8286015260c091506200174d8287016200137f565b9085015260e06200176086820162001140565b828601526101009150620017768287016200137f565b908501526101206200178a8682016200137f565b828601526101409150620017a08287016200137f565b90850152610160620017b486820162001140565b828601526101809150620017ca82870162001140565b908501526101a0620017de86820162001367565b828601526101c09150620017f482870162001140565b908501526101e06200180886820162001392565b828601526200181983870162001628565b9085015250508087019190915284529284019281016200168b565b6000806000806000806000610120888a0312156200185157600080fd5b6200185d898962001155565b60608901519097506001600160401b03808211156200187b57600080fd5b620018898b838c0162001202565b975060808a0151915080821115620018a057600080fd5b620018ae8b838c0162001202565b965060a08a0151915080821115620018c557600080fd5b620018d38b838c0162001282565b955060c08a0151915080821115620018ea57600080fd5b620018f88b838c01620013a3565b945060e08a01519150808211156200190f57600080fd5b6200191d8b838c016200158d565b93506101008a01519150808211156200193557600080fd5b50620019448a828b0162001641565b91505092959891949750929550565b634e487b7160e01b600052603260045260246000fd5b815115158152610200810160208301516200198a602084018261ffff169052565b506040830151620019a3604084018263ffffffff169052565b506060830151620019bc606084018263ffffffff169052565b506080830151620019d5608084018263ffffffff169052565b5060a0830151620019ec60a084018261ffff169052565b5060c083015162001a0560c084018263ffffffff169052565b5060e083015162001a1c60e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff9081169184019190915261016080850151821690840152610180808501516001600160401b0316908401526101a080850151909116908301526101c0808401511515908301526101e0928301516001600160e01b031916929091019190915290565b8181038181111562000e7957634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c051615c1362001b3f600039600081816102ef0152818161220b01526122740152600081816102b301528181611917015261197701526000818161027f015281816119a00152611a100152615c136000f3fe608060405234801561001057600080fd5b50600436106101ce5760003560e01c806379ba509711610104578063a69c64c0116100a2578063d02641a011610071578063d02641a014610a81578063d8694ccd14610a94578063f2fde38b14610aa7578063ffdb4b3714610aba57600080fd5b8063a69c64c014610997578063bf78e03f146109aa578063c4276bfc14610a57578063cdc73d5114610a7957600080fd5b806382b49eb0116100de57806382b49eb0146107d95780638da5cb5b1461094957806391a2749a146109715780639ea600261461098457600080fd5b806379ba5097146107ab5780637afac322146107b3578063805f2132146107c657600080fd5b8063407e1086116101715780634ab35b0b1161014b5780634ab35b0b14610441578063514e8cff146104815780636def4ce714610524578063770e2dc41461079857600080fd5b8063407e1086146103fb57806341ed29e71461040e57806345ac924d1461042157600080fd5b8063085318f8116101ad578063085318f814610368578063181f5a77146103885780632451a627146103d15780633937306f146103e657600080fd5b806241e5be146101d3578063061877e3146101f957806306285c6914610252575b600080fd5b6101e66101e13660046142ca565b610b02565b6040519081526020015b60405180910390f35b610239610207366004614306565b73ffffffffffffffffffffffffffffffffffffffff1660009081526008602052604090205467ffffffffffffffff1690565b60405167ffffffffffffffff90911681526020016101f0565b61031c604080516060810182526000808252602082018190529181019190915260405180606001604052807f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000063ffffffff16815250905090565b6040805182516bffffffffffffffffffffffff16815260208084015173ffffffffffffffffffffffffffffffffffffffff16908201529181015163ffffffff16908201526060016101f0565b61037b61037636600461437e565b610b70565b6040516101f09190614490565b6103c46040518060400160405280601381526020017f46656551756f74657220312e362e302d6465760000000000000000000000000081525081565b6040516101f09190614512565b6103d9610ee2565b6040516101f09190614525565b6103f96103f436600461457f565b610ef3565b005b6103f9610409366004614721565b6111a8565b6103f961041c366004614853565b6111bc565b61043461042f36600461498e565b6111fe565b6040516101f091906149d0565b61045461044f366004614306565b6112c9565b6040517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b61051761048f366004614a4b565b60408051808201909152600080825260208201525067ffffffffffffffff166000908152600560209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b6040516101f09190614a66565b61078b610532366004614a4b565b6040805161020081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e08101919091525067ffffffffffffffff908116600090815260096020908152604091829020825161020081018452815460ff8082161515835261ffff61010080840482169685019690965263ffffffff630100000084048116978501979097526701000000000000008304871660608501526b0100000000000000000000008304871660808501526f010000000000000000000000000000008304811660a085015271010000000000000000000000000000000000808404881660c086015275010000000000000000000000000000000000000000008404821660e08087019190915277010000000000000000000000000000000000000000000000850483169786019790975279010000000000000000000000000000000000000000000000000084049091166101208501527b01000000000000000000000000000000000000000000000000000000909204861661014084015260019093015480861661016084015264010000000081049096166101808301526c0100000000000000000000000086049094166101a0820152700100000000000000000000000000000000850490911615156101c08201527fffffffff0000000000000000000000000000000000000000000000000000000092909304901b166101e082015290565b6040516101f09190614aa1565b6103f96107a6366004614cb8565b6112d4565b6103f96112e6565b6103f96107c1366004614fd2565b6113e3565b6103f96107d4366004615078565b6113f5565b6108e96107e73660046150e4565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091525067ffffffffffffffff919091166000908152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff94909416835292815290829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a082015290565b6040516101f09190600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b6103f961097f36600461510e565b6118dd565b6103f96109923660046151cf565b6118ee565b6103f96109a53660046153dc565b6118ff565b610a236109b8366004614306565b6040805180820182526000808252602091820181905273ffffffffffffffffffffffffffffffffffffffff93841681526007825282902082518084019093525492831682527401000000000000000000000000000000000000000090920460ff169181019190915290565b60408051825173ffffffffffffffffffffffffffffffffffffffff16815260209283015160ff1692810192909252016101f0565b610a6a610a653660046154a1565b611910565b6040516101f093929190615510565b6103d9611b06565b610517610a8f366004614306565b611b12565b6101e6610aa2366004615531565b611c0e565b6103f9610ab5366004614306565b612126565b610acd610ac8366004615586565b612137565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9384168152929091166020830152016101f0565b6000610b0d826122c2565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16610b34856122c2565b610b5c907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16856155df565b610b6691906155f6565b90505b9392505050565b67ffffffffffffffff8086166000908152600960205260409020600101546060917101000000000000000000000000000000000090910460e01b908590811115610bbc57610bbc6145ba565b604051908082528060200260200182016040528015610bef57816020015b6060815260200190600190039081610bda5790505b50915060005b85811015610ed7576000858583818110610c1157610c11615631565b610c279260206040909202019081019150614306565b90506000888884818110610c3d57610c3d615631565b9050602002810190610c4f9190615660565b610c5d90604081019061569e565b9150506020811115610d125767ffffffffffffffff8a166000908152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020546e010000000000000000000000000000900463ffffffff16811115610d12576040517f36f536ca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024015b60405180910390fd5b610d82848a8a86818110610d2857610d28615631565b9050602002810190610d3a9190615660565b610d4890602081019061569e565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061235c92505050565b67ffffffffffffffff8a166000818152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684528252808320815160c081018352905463ffffffff8082168352640100000000820481168386015268010000000000000000820461ffff16838501526a01000000000000000000008204811660608401526e010000000000000000000000000000820481166080840152720100000000000000000000000000000000000090910460ff16151560a08301908152958552600990935290832054935190937b0100000000000000000000000000000000000000000000000000000090049091169190610e815781610e87565b82606001515b6040805163ffffffff8316602082015291925001604051602081830303815290604052888781518110610ebc57610ebc615631565b60200260200101819052505050505050806001019050610bf5565b505095945050505050565b6060610eee60026123b3565b905090565b610efb6123c0565b6000610f078280615703565b9050905060005b81811015611051576000610f228480615703565b83818110610f3257610f32615631565b905060400201803603810190610f489190615797565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885173ffffffffffffffffffffffffffffffffffffffff9081166000908152600690975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a926110409290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101610f0e565b5060006110616020840184615703565b9050905060005b818110156111a257600061107f6020860186615703565b8381811061108f5761108f615631565b9050604002018036038101906110a591906157d4565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885167ffffffffffffffff9081166000908152600590975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927fdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e926111919290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250600101611068565b50505050565b6111b0612405565b6111b981612486565b50565b6111c4612405565b60005b81518110156111fa576111f28282815181106111e5576111e5615631565b6020026020010151612584565b6001016111c7565b5050565b60608160008167ffffffffffffffff81111561121c5761121c6145ba565b60405190808252806020026020018201604052801561126157816020015b604080518082019091526000808252602082015281526020019060019003908161123a5790505b50905060005b828110156112be5761129986868381811061128457611284615631565b9050602002016020810190610a8f9190614306565b8282815181106112ab576112ab615631565b6020908102919091010152600101611267565b509150505b92915050565b60006112c3826122c2565b6112dc612405565b6111fa8282612756565b60015473ffffffffffffffffffffffffffffffffffffffff163314611367576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610d09565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6113eb612405565b6111fa8282612b63565b600080600061143987878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612caa92505050565b92509250925061144b33838584612cc5565b6000611459858701876157f7565b905060005b81518110156118d25760006007600084848151811061147f5761147f615631565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160009081205474010000000000000000000000000000000000000000900460ff169150819003611540578282815181106114e9576114e9615631565b6020908102919091010151516040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610d09565b600061158960128386868151811061155a5761155a615631565b6020026020010151602001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16612e1d565b9050600660008585815181106115a1576115a1615631565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001601c9054906101000a900463ffffffff1663ffffffff1684848151811061161357611613615631565b60200260200101516040015163ffffffff16101561171d5783838151811061163d5761163d615631565b60200260200101516000015184848151811061165b5761165b615631565b6020026020010151604001516006600087878151811061167d5761167d615631565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff90811683529082019290925260409081016000205490517f191ec70600000000000000000000000000000000000000000000000000000000815293909116600484015263ffffffff91821660248401527c01000000000000000000000000000000000000000000000000000000009004166044820152606401610d09565b6040518060400160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260200185858151811061175e5761175e615631565b60200260200101516040015163ffffffff168152506006600086868151811061178957611789615631565b6020908102919091018101515173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251929091015163ffffffff167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909216919091179055835184908490811061182157611821615631565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff167f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a8286868151811061187757611877615631565b6020026020010151604001516040516118c09291907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff92909216825263ffffffff16602082015260400190565b60405180910390a2505060010161145e565b505050505050505050565b6118e5612405565b6111b981612ee3565b6118f6612405565b6111b98161306f565b611907612405565b6111b981613515565b60008060607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16036119705785925061199e565b61199b87877f0000000000000000000000000000000000000000000000000000000000000000610b02565b92505b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff16831115611a3d576040517f6a92a483000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610d09565b67ffffffffffffffff881660009081526009602052604081206001015463ffffffff1690611a6c8787846135ff565b9050806020015193508484611af3836040805182516024820152602092830151151560448083019190915282518083039091018152606490910190915290810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f181dcf100000000000000000000000000000000000000000000000000000000017905290565b9450945094505050955095509592505050565b6060610eee600b6123b3565b604080518082019091526000808252602082015273ffffffffffffffffffffffffffffffffffffffff8281166000908152600760209081526040918290208251808401909352549283168083527401000000000000000000000000000000000000000090930460ff169082015290611c0557505073ffffffffffffffffffffffffffffffffffffffff166000908152600660209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b610b69816137a8565b67ffffffffffffffff8083166000908152600960209081526040808320815161020081018352815460ff808216151580845261ffff61010080850482169886019890985263ffffffff630100000085048116978601979097526701000000000000008404871660608601526b0100000000000000000000008404871660808601526f010000000000000000000000000000008404811660a086015271010000000000000000000000000000000000808504881660c087015275010000000000000000000000000000000000000000008504821660e08088019190915277010000000000000000000000000000000000000000000000860483169987019990995279010000000000000000000000000000000000000000000000000085049091166101208601527b01000000000000000000000000000000000000000000000000000000909304861661014085015260019094015480861661016085015264010000000081049098166101808401526c0100000000000000000000000088049094166101a0830152700100000000000000000000000000000000870490931615156101c08201527fffffffff000000000000000000000000000000000000000000000000000000009290950490921b166101e0840152909190611e28576040517f99ac52f200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610d09565b611e43611e3b6080850160608601614306565b600b90613937565b611ea257611e576080840160608501614306565b6040517f2502348c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610d09565b6000611eb16040850185615703565b9150611f0d905082611ec6602087018761569e565b905083611ed3888061569e565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061396692505050565b6000600881611f226080880160608901614306565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160009081205467ffffffffffffffff16915080611f71611f6b6080890160608a01614306565b89612137565b9092509050600080808615611fb757611fab888c611f9560808e0160608f01614306565b888e8060400190611fa69190615703565b613a10565b91945092509050611fd7565b6101a0880151611fd49063ffffffff16662386f26fc100006155df565b92505b61010088015160009061ffff161561201b57612018896dffffffffffffffffffffffffffff607088901c1661200f60208f018f61569e565b90508b86613ce8565b90505b61018089015160009067ffffffffffffffff1661204461203e60808f018f61569e565b8d613d98565b600001518563ffffffff168c60a0015161ffff168f8060200190612068919061569e565b6120739291506155df565b8d6080015163ffffffff1661208891906158be565b61209291906158be565b61209c91906158be565b6120b6906dffffffffffffffffffffffffffff89166155df565b6120c091906155df565b90507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff871682826120f767ffffffffffffffff8c16896155df565b61210191906158be565b61210b91906158be565b61211591906155f6565b9d9c50505050505050505050505050565b61212e612405565b6111b981613e59565b67ffffffffffffffff811660009081526005602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff16918101829052829182036121ef576040517f2e59db3a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610d09565b6000816020015163ffffffff164261220791906158d1565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168111156122a8576040517ff08bcb3e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401610d09565b6122b1866122c2565b9151919350909150505b9250929050565b6000806122ce83611b12565b9050806020015163ffffffff1660001480612306575080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16155b15612355576040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610d09565b5192915050565b7fd7ed2ad4000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316016111fa576123ae81613f4e565b505050565b60606000610b6983614001565b6123cb600233613937565b612403576040517fd86ad9cf000000000000000000000000000000000000000000000000000000008152336004820152602401610d09565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314612403576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610d09565b60005b81518110156111fa5760008282815181106124a6576124a6615631565b60209081029190910181015180518183015173ffffffffffffffffffffffffffffffffffffffff80831660008181526007875260409081902084518154868a018051929096167fffffffffffffffffffffff00000000000000000000000000000000000000000090911681177401000000000000000000000000000000000000000060ff9384160217909255825191825293519093169683019690965293955091939092917f08a5f7f5bb38a81d8e43aca13ecd76431dbf8816ae4699affff7b00b2fc1c464910160405180910390a2505050806001019050612489565b600061263d82600001518360600151846020015185604001516040805173ffffffffffffffffffffffffffffffffffffffff80871660208301528516918101919091527fffffffffffffffffffff00000000000000000000000000000000000000000000831660608201527fffff0000000000000000000000000000000000000000000000000000000000008216608082015260009060a001604051602081830303815290604052805190602001209050949350505050565b60808301516000828152600460205260409081902080549215157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909316929092179091555190915081907f32a4ba3fa3351b11ad555d4c8ec70a744e8705607077a946807030d64b6ab1a39061274a908590600060a08201905073ffffffffffffffffffffffffffffffffffffffff8084511683527fffffffffffffffffffff0000000000000000000000000000000000000000000060208501511660208401527fffff00000000000000000000000000000000000000000000000000000000000060408501511660408401528060608501511660608401525060808301511515608083015292915050565b60405180910390a25050565b60005b8251811015612a7f57600083828151811061277657612776615631565b6020026020010151905060008160000151905060005b826020015151811015612a71576000836020015182815181106127b1576127b1615631565b60200260200101516020015190506000846020015183815181106127d7576127d7615631565b6020026020010151600001519050602063ffffffff16826080015163ffffffff16101561285a5760808201516040517f24ecdc0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015263ffffffff9091166024820152604401610d09565b67ffffffffffffffff84166000818152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff86168085529083529281902086518154938801518389015160608a015160808b015160a08c015115157201000000000000000000000000000000000000027fffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff63ffffffff9283166e01000000000000000000000000000002167fffffffffffffffffffffffffff0000000000ffffffffffffffffffffffffffff9383166a0100000000000000000000027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff61ffff9096166801000000000000000002959095167fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff968416640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b16939097169290921798909817939093169390931717919091161792909217909155519091907f94967ae9ea7729ad4f54021c1981765d2b1d954f7c92fbec340aa0a54f46b8b590612a5f908690600060c08201905063ffffffff80845116835280602085015116602084015261ffff60408501511660408401528060608501511660608401528060808501511660808401525060a0830151151560a083015292915050565b60405180910390a3505060010161278c565b505050806001019050612759565b5060005b81518110156123ae576000828281518110612aa057612aa0615631565b60200260200101516000015190506000838381518110612ac257612ac2615631565b60209081029190910181015181015167ffffffffffffffff84166000818152600a8452604080822073ffffffffffffffffffffffffffffffffffffffff8516808452955280822080547fffffffffffffffffffffffffff000000000000000000000000000000000000001690555192945090917f4de5b1bcbca6018c11303a2c3f4a4b4f22a1c741d8c4ba430d246ac06c5ddf8b9190a35050600101612a83565b60005b8251811015612c0657612b9c838281518110612b8457612b84615631565b6020026020010151600b61405d90919063ffffffff16565b15612bfe57828181518110612bb357612bb3615631565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b600101612b66565b5060005b81518110156123ae57612c40828281518110612c2857612c28615631565b6020026020010151600b61407f90919063ffffffff16565b15612ca257818181518110612c5757612c57615631565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b600101612c0a565b6040810151604a820151605e90920151909260609290921c91565b6040805173ffffffffffffffffffffffffffffffffffffffff868116602080840191909152908616828401527fffffffffffffffffffff00000000000000000000000000000000000000000000851660608301527fffff00000000000000000000000000000000000000000000000000000000000084166080808401919091528351808403909101815260a09092018352815191810191909120600081815260049092529190205460ff16612e16576040517f097e17ff00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8087166004830152851660248201527fffffffffffffffffffff00000000000000000000000000000000000000000000841660448201527fffff00000000000000000000000000000000000000000000000000000000000083166064820152608401610d09565b5050505050565b600080612e2a84866158e4565b9050600060248260ff161115612e6157612e456024836158fd565b612e5090600a615a36565b612e5a90856155f6565b9050612e84565b612e6c8260246158fd565b612e7790600a615a36565b612e8190856155df565b90505b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811115612eda576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b95945050505050565b602081015160005b8151811015612f7e576000828281518110612f0857612f08615631565b60200260200101519050612f268160026140a190919063ffffffff16565b15612f755760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101612eeb565b50815160005b81518110156111a2576000828281518110612fa157612fa1615631565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613011576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61301c60028261405d565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a150600101612f84565b60005b81518110156111fa57600082828151811061308f5761308f615631565b6020026020010151905060008383815181106130ad576130ad615631565b60200260200101516000015190506000826020015190508167ffffffffffffffff16600014806130e6575061016081015163ffffffff16155b8061313857506101e08101517fffffffff00000000000000000000000000000000000000000000000000000000167f2812d52c0000000000000000000000000000000000000000000000000000000014155b806131575750806060015163ffffffff1681610160015163ffffffff16115b1561319a576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff83166004820152602401610d09565b67ffffffffffffffff821660009081526009602052604081206001015471010000000000000000000000000000000000900460e01b7fffffffff0000000000000000000000000000000000000000000000000000000016900361323e578167ffffffffffffffff167fd31c671936387b2f84ed402b553bd50c0e9c20408ea4e91a836d77b8180fb724826040516132319190614aa1565b60405180910390a2613281565b8167ffffffffffffffff167f1edd6f3553cfa16f10b95b195abae3a1cfca4783de4843f95d674b1e1df5ab20826040516132789190614aa1565b60405180910390a25b80600960008467ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600b6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600f6101000a81548161ffff021916908361ffff16021790555060c08201518160000160116101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160156101000a81548161ffff021916908361ffff1602179055506101008201518160000160176101000a81548161ffff021916908361ffff1602179055506101208201518160000160196101000a81548161ffff021916908361ffff16021790555061014082015181600001601b6101000a81548163ffffffff021916908363ffffffff1602179055506101608201518160010160006101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160010160046101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506101a082015181600101600c6101000a81548163ffffffff021916908363ffffffff1602179055506101c08201518160010160106101000a81548160ff0219169083151502179055506101e08201518160010160116101000a81548163ffffffff021916908360e01c0217905550905050505050806001019050613072565b60005b81518110156111fa57600082828151811061353557613535615631565b6020026020010151600001519050600083838151811061355757613557615631565b60209081029190910181015181015173ffffffffffffffffffffffffffffffffffffffff841660008181526008845260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff85169081179091559051908152919350917fbb77da6f7210cdd16904228a9360133d1d7dfff99b1bc75f128da5b53e28f97d910160405180910390a25050600101613518565b6040805180820190915260008082526020820152600083900361364057506040805180820190915267ffffffffffffffff8216815260006020820152610b69565b600061364c8486615a45565b9050600061365d8560048189615a8b565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050507fffffffff0000000000000000000000000000000000000000000000000000000082167fe7e230f000000000000000000000000000000000000000000000000000000000016136fa57808060200190518101906136f19190615ab5565b92505050610b69565b7f6859a837000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601613776576040518060400160405280828060200190518101906137629190615ae1565b815260006020909101529250610b69915050565b6040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518082019091526000808252602082015260008260000151905060008173ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613812573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138369190615b14565b5050509150506000811215613877576040517f10cb51d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006138f68373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156138c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138eb9190615b64565b866020015184612e1d565b604080518082019091527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909116815263ffffffff4216602082015295945050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610b69565b836040015163ffffffff168311156139bf5760408085015190517f8693378900000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015260248101849052604401610d09565b836020015161ffff16821115613a01576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111a2846101e001518261235c565b6000808083815b81811015613cda576000878783818110613a3357613a33615631565b905060400201803603810190613a499190615b81565b67ffffffffffffffff8c166000908152600a60209081526040808320845173ffffffffffffffffffffffffffffffffffffffff168452825291829020825160c081018452905463ffffffff8082168352640100000000820481169383019390935268010000000000000000810461ffff16938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000083049091166080820152720100000000000000000000000000000000000090910460ff16151560a0820181905291925090613b69576101208d0151613b369061ffff16662386f26fc100006155df565b613b4090886158be565b96508c610140015186613b539190615bba565b9550613b60602086615bba565b94505050613cd2565b604081015160009061ffff1615613c225760008c73ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff1614613bc5578351613bbe906122c2565b9050613bc8565b508a5b620186a0836040015161ffff16613c0a8660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166140c390919063ffffffff16565b613c1491906155df565b613c1e91906155f6565b9150505b6060820151613c319088615bba565b9650816080015186613c439190615bba565b8251909650600090613c629063ffffffff16662386f26fc100006155df565b905080821015613c8157613c76818a6158be565b985050505050613cd2565b6000836020015163ffffffff16662386f26fc10000613ca091906155df565b905080831115613cc057613cb4818b6158be565b99505050505050613cd2565b613cca838b6158be565b995050505050505b600101613a17565b505096509650969350505050565b60008063ffffffff8316613cfe610160866155df565b613d0a876101c06158be565b613d1491906158be565b613d1e91906158be565b905060008760c0015163ffffffff168860e0015161ffff1683613d4191906155df565b613d4b91906158be565b61010089015190915061ffff16613d726dffffffffffffffffffffffffffff8916836155df565b613d7c91906155df565b613d8c90655af3107a40006155df565b98975050505050505050565b60408051808201909152600080825260208201526000613dc4858585610160015163ffffffff166135ff565b9050826060015163ffffffff1681600001511115613e0e576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826101c001518015613e2257508060200151155b15610b66576040517fee433e9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821603613ed8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610d09565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008151602014613f8d57816040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610d099190614512565b600082806020019051810190613fa39190615ae1565b905073ffffffffffffffffffffffffffffffffffffffff811180613fc8575061040081105b156112c357826040517f8d666f60000000000000000000000000000000000000000000000000000000008152600401610d099190614512565b60608160000180548060200260200160405190810160405280929190818152602001828054801561405157602002820191906000526020600020905b81548152602001906001019080831161403d575b50505050509050919050565b6000610b698373ffffffffffffffffffffffffffffffffffffffff8416614100565b6000610b698373ffffffffffffffffffffffffffffffffffffffff841661414f565b6000610b698373ffffffffffffffffffffffffffffffffffffffff8416614249565b6000670de0b6b3a76400006140f6837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff86166155df565b610b6991906155f6565b6000818152600183016020526040812054614147575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556112c3565b5060006112c3565b600081815260018301602052604081205480156142385760006141736001836158d1565b8554909150600090614187906001906158d1565b90508082146141ec5760008660000182815481106141a7576141a7615631565b90600052602060002001549050808760000184815481106141ca576141ca615631565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806141fd576141fd615bd7565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506112c3565b60009150506112c3565b5092915050565b6000818152600183016020526040812054801561423857600061426d6001836158d1565b8554909150600090614281906001906158d1565b90508181146141ec5760008660000182815481106141a7576141a7615631565b803573ffffffffffffffffffffffffffffffffffffffff811681146142c557600080fd5b919050565b6000806000606084860312156142df57600080fd5b6142e8846142a1565b9250602084013591506142fd604085016142a1565b90509250925092565b60006020828403121561431857600080fd5b610b69826142a1565b803567ffffffffffffffff811681146142c557600080fd5b60008083601f84011261434b57600080fd5b50813567ffffffffffffffff81111561436357600080fd5b6020830191508360208260051b85010111156122bb57600080fd5b60008060008060006060868803121561439657600080fd5b61439f86614321565b9450602086013567ffffffffffffffff808211156143bc57600080fd5b6143c889838a01614339565b909650945060408801359150808211156143e157600080fd5b818801915088601f8301126143f557600080fd5b81358181111561440457600080fd5b8960208260061b850101111561441957600080fd5b9699959850939650602001949392505050565b6000815180845260005b8181101561445257602081850181015186830182015201614436565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015614505577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526144f385835161442c565b945092850192908501906001016144b9565b5092979650505050505050565b602081526000610b69602083018461442c565b6020808252825182820181905260009190848201906040850190845b8181101561457357835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614541565b50909695505050505050565b60006020828403121561459157600080fd5b813567ffffffffffffffff8111156145a857600080fd5b820160408185031215610b6957600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561460c5761460c6145ba565b60405290565b60405160a0810167ffffffffffffffff8111828210171561460c5761460c6145ba565b60405160c0810167ffffffffffffffff8111828210171561460c5761460c6145ba565b604051610200810167ffffffffffffffff8111828210171561460c5761460c6145ba565b6040516060810167ffffffffffffffff8111828210171561460c5761460c6145ba565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156146e6576146e66145ba565b604052919050565b600067ffffffffffffffff821115614708576147086145ba565b5060051b60200190565b60ff811681146111b957600080fd5b6000602080838503121561473457600080fd5b823567ffffffffffffffff81111561474b57600080fd5b8301601f8101851361475c57600080fd5b803561476f61476a826146ee565b61469f565b8181526060918202830184019184820191908884111561478e57600080fd5b938501935b8385101561482e57848903818112156147ac5760008081fd5b6147b46145e9565b6147bd876142a1565b81526040807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0840112156147f15760008081fd5b6147f96145e9565b92506148068989016142a1565b835287013561481481614712565b828901528088019190915283529384019391850191614793565b50979650505050505050565b80151581146111b957600080fd5b80356142c58161483a565b6000602080838503121561486657600080fd5b823567ffffffffffffffff81111561487d57600080fd5b8301601f8101851361488e57600080fd5b803561489c61476a826146ee565b81815260a091820283018401918482019190888411156148bb57600080fd5b938501935b8385101561482e5780858a0312156148d85760008081fd5b6148e0614612565b6148e9866142a1565b8152868601357fffffffffffffffffffff000000000000000000000000000000000000000000008116811461491e5760008081fd5b818801526040868101357fffff000000000000000000000000000000000000000000000000000000000000811681146149575760008081fd5b9082015260606149688782016142a1565b9082015260808681013561497b8161483a565b90820152835293840193918501916148c0565b600080602083850312156149a157600080fd5b823567ffffffffffffffff8111156149b857600080fd5b6149c485828601614339565b90969095509350505050565b602080825282518282018190526000919060409081850190868401855b82811015614a3e57614a2e84835180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16825260209081015163ffffffff16910152565b92840192908501906001016149ed565b5091979650505050505050565b600060208284031215614a5d57600080fd5b610b6982614321565b81517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260208083015163ffffffff1690820152604081016112c3565b81511515815261020081016020830151614ac1602084018261ffff169052565b506040830151614ad9604084018263ffffffff169052565b506060830151614af1606084018263ffffffff169052565b506080830151614b09608084018263ffffffff169052565b5060a0830151614b1f60a084018261ffff169052565b5060c0830151614b3760c084018263ffffffff169052565b5060e0830151614b4d60e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015163ffffffff90811691840191909152610160808501518216908401526101808085015167ffffffffffffffff16908401526101a080850151909116908301526101c0808401511515908301526101e0808401517fffffffff000000000000000000000000000000000000000000000000000000008116828501525b505092915050565b803563ffffffff811681146142c557600080fd5b803561ffff811681146142c557600080fd5b600082601f830112614c3157600080fd5b81356020614c4161476a836146ee565b82815260069290921b84018101918181019086841115614c6057600080fd5b8286015b84811015614cad5760408189031215614c7d5760008081fd5b614c856145e9565b614c8e82614321565b8152614c9b8583016142a1565b81860152835291830191604001614c64565b509695505050505050565b60008060408385031215614ccb57600080fd5b67ffffffffffffffff83351115614ce157600080fd5b83601f843585010112614cf357600080fd5b614d0361476a84358501356146ee565b8335840180358083526020808401939260059290921b90910101861015614d2957600080fd5b602085358601015b85358601803560051b01602001811015614f365767ffffffffffffffff81351115614d5b57600080fd5b8035863587010160407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828a03011215614d9457600080fd5b614d9c6145e9565b614da860208301614321565b815267ffffffffffffffff60408301351115614dc357600080fd5b88603f604084013584010112614dd857600080fd5b614dee61476a60206040850135850101356146ee565b6020604084810135850182810135808552928401939260e00201018b1015614e1557600080fd5b6040808501358501015b6040858101358601602081013560e0020101811015614f175760e0818d031215614e4857600080fd5b614e506145e9565b614e59826142a1565b815260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838f03011215614e8d57600080fd5b614e95614635565b614ea160208401614bfa565b8152614eaf60408401614bfa565b6020820152614ec060608401614c0e565b6040820152614ed160808401614bfa565b6060820152614ee260a08401614bfa565b6080820152614ef460c084013561483a565b60c083013560a0820152602082810191909152908452929092019160e001614e1f565b5080602084015250508085525050602083019250602081019050614d31565b5092505067ffffffffffffffff60208401351115614f5357600080fd5b614f638460208501358501614c20565b90509250929050565b600082601f830112614f7d57600080fd5b81356020614f8d61476a836146ee565b8083825260208201915060208460051b870101935086841115614faf57600080fd5b602086015b84811015614cad57614fc5816142a1565b8352918301918301614fb4565b60008060408385031215614fe557600080fd5b823567ffffffffffffffff80821115614ffd57600080fd5b61500986838701614f6c565b9350602085013591508082111561501f57600080fd5b5061502c85828601614f6c565b9150509250929050565b60008083601f84011261504857600080fd5b50813567ffffffffffffffff81111561506057600080fd5b6020830191508360208285010111156122bb57600080fd5b6000806000806040858703121561508e57600080fd5b843567ffffffffffffffff808211156150a657600080fd5b6150b288838901615036565b909650945060208701359150808211156150cb57600080fd5b506150d887828801615036565b95989497509550505050565b600080604083850312156150f757600080fd5b61510083614321565b9150614f63602084016142a1565b60006020828403121561512057600080fd5b813567ffffffffffffffff8082111561513857600080fd5b908301906040828603121561514c57600080fd5b6151546145e9565b82358281111561516357600080fd5b61516f87828601614f6c565b82525060208301358281111561518457600080fd5b61519087828601614f6c565b60208301525095945050505050565b80357fffffffff00000000000000000000000000000000000000000000000000000000811681146142c557600080fd5b600060208083850312156151e257600080fd5b823567ffffffffffffffff8111156151f957600080fd5b8301601f8101851361520a57600080fd5b803561521861476a826146ee565b818152610220918202830184019184820191908884111561523857600080fd5b938501935b8385101561482e57848903818112156152565760008081fd5b61525e6145e9565b61526787614321565b8152610200807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08401121561529c5760008081fd5b6152a4614658565b92506152b1898901614848565b835260406152c0818a01614c0e565b8a85015260606152d1818b01614bfa565b82860152608091506152e4828b01614bfa565b9085015260a06152f58a8201614bfa565b8286015260c09150615308828b01614c0e565b9085015260e06153198a8201614bfa565b82860152610100915061532d828b01614c0e565b9085015261012061533f8a8201614c0e565b828601526101409150615353828b01614c0e565b908501526101606153658a8201614bfa565b828601526101809150615379828b01614bfa565b908501526101a061538b8a8201614321565b828601526101c0915061539f828b01614bfa565b908501526101e06153b18a8201614848565b828601526153c0838b0161519f565b908501525050808801919091528352938401939185019161523d565b600060208083850312156153ef57600080fd5b823567ffffffffffffffff81111561540657600080fd5b8301601f8101851361541757600080fd5b803561542561476a826146ee565b81815260069190911b8201830190838101908783111561544457600080fd5b928401925b8284101561549657604084890312156154625760008081fd5b61546a6145e9565b615473856142a1565b8152615480868601614321565b8187015282526040939093019290840190615449565b979650505050505050565b6000806000806000608086880312156154b957600080fd5b6154c286614321565b94506154d0602087016142a1565b935060408601359250606086013567ffffffffffffffff8111156154f357600080fd5b6154ff88828901615036565b969995985093965092949392505050565b8381528215156020820152606060408201526000612eda606083018461442c565b6000806040838503121561554457600080fd5b61554d83614321565b9150602083013567ffffffffffffffff81111561556957600080fd5b830160a0818603121561557b57600080fd5b809150509250929050565b6000806040838503121561559957600080fd5b6155a2836142a1565b9150614f6360208401614321565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176112c3576112c36155b0565b60008261562c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6183360301811261569457600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126156d357600080fd5b83018035915067ffffffffffffffff8211156156ee57600080fd5b6020019150368190038213156122bb57600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261573857600080fd5b83018035915067ffffffffffffffff82111561575357600080fd5b6020019150600681901b36038213156122bb57600080fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146142c557600080fd5b6000604082840312156157a957600080fd5b6157b16145e9565b6157ba836142a1565b81526157c86020840161576b565b60208201529392505050565b6000604082840312156157e657600080fd5b6157ee6145e9565b6157ba83614321565b6000602080838503121561580a57600080fd5b823567ffffffffffffffff81111561582157600080fd5b8301601f8101851361583257600080fd5b803561584061476a826146ee565b8181526060918202830184019184820191908884111561585f57600080fd5b938501935b8385101561482e5780858a03121561587c5760008081fd5b61588461467c565b61588d866142a1565b815261589a87870161576b565b8782015260406158ab818801614bfa565b9082015283529384019391850191615864565b808201808211156112c3576112c36155b0565b818103818111156112c3576112c36155b0565b60ff81811683821601908111156112c3576112c36155b0565b60ff82811682821603908111156112c3576112c36155b0565b600181815b8085111561596f57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115615955576159556155b0565b8085161561596257918102915b93841c939080029061591b565b509250929050565b600082615986575060016112c3565b81615993575060006112c3565b81600181146159a957600281146159b3576159cf565b60019150506112c3565b60ff8411156159c4576159c46155b0565b50506001821b6112c3565b5060208310610133831016604e8410600b84101617156159f2575081810a6112c3565b6159fc8383615916565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115615a2e57615a2e6155b0565b029392505050565b6000610b6960ff841683615977565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015614bf25760049490940360031b84901b1690921692915050565b60008085851115615a9b57600080fd5b83861115615aa857600080fd5b5050820193919092039150565b600060408284031215615ac757600080fd5b615acf6145e9565b8251815260208301516157c88161483a565b600060208284031215615af357600080fd5b5051919050565b805169ffffffffffffffffffff811681146142c557600080fd5b600080600080600060a08688031215615b2c57600080fd5b615b3586615afa565b9450602086015193506040860151925060608601519150615b5860808701615afa565b90509295509295909350565b600060208284031215615b7657600080fd5b8151610b6981614712565b600060408284031215615b9357600080fd5b615b9b6145e9565b615ba4836142a1565b8152602083013560208201528091505092915050565b63ffffffff818116838216019080821115614242576142426155b0565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", } var FeeQuoterABI = FeeQuoterMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/onramp/onramp.go b/core/gethwrappers/ccip/generated/onramp/onramp.go index db21305dc8..dd2428a143 100644 --- a/core/gethwrappers/ccip/generated/onramp/onramp.go +++ b/core/gethwrappers/ccip/generated/onramp/onramp.go @@ -70,9 +70,11 @@ type InternalRampTokenAmount struct { DestExecData []byte } -type OnRampDestChainConfig struct { - SequenceNumber uint64 - Router common.Address +type OnRampAllowListConfigArgs struct { + DestChainSelector uint64 + AllowListEnabled bool + AddedAllowlistedSenders []common.Address + RemovedAllowlistedSenders []common.Address } type OnRampDestChainConfigArgs struct { @@ -84,6 +86,7 @@ type OnRampDynamicConfig struct { FeeQuoter common.Address MessageValidator common.Address FeeAggregator common.Address + AllowListAdmin common.Address } type OnRampStaticConfig struct { @@ -94,8 +97,8 @@ type OnRampStaticConfig struct { } var OnRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GetSupportedTokensFunctionalityRemovedCheckAdminRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.DestChainConfig\",\"name\":\"destChainConfig\",\"type\":\"tuple\"}],\"name\":\"DestChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeValueJuels\",\"type\":\"uint256\"}],\"name\":\"FeePaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeeTokenWithdrawn\",\"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\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPoolV1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"contractIRouter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"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\":[],\"name\":\"withdrawFeeTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101006040523480156200001257600080fd5b506040516200382d3803806200382d83398101604081905262000035916200069c565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000186565b505083516001600160401b031615905080620000e6575060208301516001600160a01b0316155b80620000fd575060408301516001600160a01b0316155b8062000114575060608301516001600160a01b0316155b1562000133576040516306b7c75960e31b815260040160405180910390fd5b82516001600160401b031660805260208301516001600160a01b0390811660a0526040840151811660c05260608401511660e052620001728262000231565b6200017d816200036d565b5050506200079c565b336001600160a01b03821603620001e05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316158062000254575060408101516001600160a01b0316155b1562000273576040516306b7c75960e31b815260040160405180910390fd5b8051600280546001600160a01b03199081166001600160a01b03938416179091556020808401805160038054851691861691909117905560408086018051600480549096169087161790945580516080808201835280516001600160401b031680835260a08051891684880190815260c080518b1686880190815260e080518d166060988901908152895196875293518d169a86019a909a52518b169684019690965251891693820193909352885188169181019190915292518616908301529251909316918301919091527f2d8f19dc1cd01460c3367a09d2d424f2b1940ba7c886047edd078c7b77ea4558910160405180910390a150565b60005b8151811015620004aa57600082828151811062000391576200039162000786565b602002602001015190506000838381518110620003b257620003b262000786565b6020026020010151600001519050806001600160401b0316600003620003f75760405163c35aa79d60e01b81526001600160401b038216600482015260240162000083565b6040805180820182526001600160401b03838116600081815260056020818152868320805480871688528a8301516001600160a01b03908116848a019081529587905293835287518551851668010000000000000000026001600160e01b0319909216971696871717905586519485529151169083015291927f324d4a7950b57da00ce533ad6697039be6281726a73da959d0ab3ff795181ec6910160405180910390a250505080600101905062000370565b5050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715620004e957620004e9620004ae565b60405290565b604051601f8201601f191681016001600160401b03811182821017156200051a576200051a620004ae565b604052919050565b80516001600160401b03811681146200053a57600080fd5b919050565b6001600160a01b03811681146200055557600080fd5b50565b6000606082840312156200056b57600080fd5b604051606081016001600160401b0381118282101715620005905762000590620004ae565b80604052508091508251620005a5816200053f565b81526020830151620005b7816200053f565b60208201526040830151620005cc816200053f565b6040919091015292915050565b600082601f830112620005eb57600080fd5b815160206001600160401b03821115620006095762000609620004ae565b62000619818360051b01620004ef565b82815260069290921b840181019181810190868411156200063957600080fd5b8286015b84811015620006915760408189031215620006585760008081fd5b62000662620004c4565b6200066d8262000522565b8152848201516200067e816200053f565b818601528352918301916040016200063d565b509695505050505050565b6000806000838503610100811215620006b457600080fd5b6080811215620006c357600080fd5b50604051608081016001600160401b038082118383101715620006ea57620006ea620004ae565b81604052620006f98762000522565b8352602087015191506200070d826200053f565b8160208401526040870151915062000725826200053f565b816040840152606087015191506200073d826200053f565b81606084015282955062000755886080890162000558565b945060e08701519250808311156200076c57600080fd5b50506200077c86828701620005d9565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b60805160a05160c05160e05161301862000815600039600081816101eb015281816108a201526116700152600081816101af01528181610dc60152611649015260008181610173015281816104c4015261161f01526000818161014301528181610cec0152818161121101526115f201526130186000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80637437ff9f11610097578063d77d5ed011610066578063d77d5ed0146103ba578063df0aa9e914610406578063f2fde38b14610419578063fbca3b741461042c57600080fd5b80637437ff9f146102fb57806379ba5097146103685780638da5cb5b146103705780639041be3d1461038e57600080fd5b806320487ded116100d357806320487ded1461028757806334d560e4146102a85780633a019940146102bb57806348a98aa4146102c357600080fd5b80630242cf60146100fa57806306285c691461010f578063181f5a771461023e575b600080fd5b61010d610108366004612098565b61044c565b005b61022860408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b604051610235919061215b565b60405180910390f35b61027a6040518060400160405280601081526020017f4f6e52616d7020312e362e302d6465760000000000000000000000000000000081525081565b6040516102359190612220565b61029a61029536600461224b565b610460565b604051908152602001610235565b61010d6102b63660046122ab565b610619565b61010d61062a565b6102d66102d136600461231d565b61085a565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610235565b61035b6040805160608101825260008082526020820181905291810191909152506040805160608101825260025473ffffffffffffffffffffffffffffffffffffffff908116825260035481166020830152600454169181019190915290565b6040516102359190612356565b61010d61090f565b60005473ffffffffffffffffffffffffffffffffffffffff166102d6565b6103a161039c366004612393565b610a0c565b60405167ffffffffffffffff9091168152602001610235565b6102d66103c8366004612393565b67ffffffffffffffff1660009081526005602052604090205468010000000000000000900473ffffffffffffffffffffffffffffffffffffffff1690565b61029a6104143660046123b0565b610a35565b61010d61042736600461241c565b6112c6565b61043f61043a366004612393565b6112d7565b6040516102359190612439565b61045461130b565b61045d8161138e565b50565b6040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815277ffffffffffffffff00000000000000000000000000000000608084901b16600482015260009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa15801561050b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052f91906124a3565b15610577576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6002546040517fd8694ccd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063d8694ccd906105cf90869086906004016125d2565b602060405180830381865afa1580156105ec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610610919061271b565b90505b92915050565b61062161130b565b61045d81611506565b600254604080517fcdc73d51000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163cdc73d5191600480830192869291908290030181865afa158015610699573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526106df9190810190612734565b60045490915073ffffffffffffffffffffffffffffffffffffffff1660005b825181101561085557600083828151811061071b5761071b6127c3565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610796573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ba919061271b565b9050801561084b576107e373ffffffffffffffffffffffffffffffffffffffff831685836116d0565b8173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f508d7d183612c18fc339b42618912b9fa3239f631dd7ec0671f950200a0fa66e8360405161084291815260200190565b60405180910390a35b50506001016106fe565b505050565b6040517fbbe4f6db00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bbe4f6db90602401602060405180830381865afa1580156108eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061091906127f2565b60015473ffffffffffffffffffffffffffffffffffffffff163314610990576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161056e565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b67ffffffffffffffff80821660009081526005602052604081205490916106139116600161283e565b67ffffffffffffffff8416600090815260056020526040812073ffffffffffffffffffffffffffffffffffffffff8316610a9b576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805468010000000000000000900473ffffffffffffffffffffffffffffffffffffffff163314610af7576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60035473ffffffffffffffffffffffffffffffffffffffff168015610b9d576040517fe0a0e50600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e0a0e50690610b6a908a908a906004016125d2565b600060405180830381600087803b158015610b8457600080fd5b505af1158015610b98573d6000803e3d6000fd5b505050505b506002546000908190819073ffffffffffffffffffffffffffffffffffffffff1663c4276bfc8a610bd460808c0160608d0161241c565b8a610be260808e018e612866565b6040518663ffffffff1660e01b8152600401610c029594939291906128cb565b600060405180830381865afa158015610c1f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610c659190810190612993565b91945092509050610c7c6080890160608a0161241c565b73ffffffffffffffffffffffffffffffffffffffff167f075a2720282fdf622141dae0b048ef90a21a7e57c134c76912d19d006b3b3f6f84604051610cc391815260200190565b60405180910390a2604080516101a081019091526000610100820181815267ffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166101208501528c811661014085015287549293928392916101608401918a918791610d3891166129ea565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905567ffffffffffffffff16815260200186610e38576040517fea458c0c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8f16600482015273ffffffffffffffffffffffffffffffffffffffff8c811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063ea458c0c906044016020604051808303816000875af1158015610e0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e339190612a11565b610e3b565b60005b67ffffffffffffffff1681525081526020018873ffffffffffffffffffffffffffffffffffffffff1681526020018a8060200190610e799190612866565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610ebd8b80612866565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610f0460808c018c612866565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001610f4e60808c0160608d0161241c565b73ffffffffffffffffffffffffffffffffffffffff1681526020018981526020018a8060400190610f7f9190612a2e565b905067ffffffffffffffff811115610f9957610f99611f95565b604051908082528060200260200182016040528015610ffc57816020015b610fe96040518060a0016040528060608152602001606081526020016060815260200160008152602001606081525090565b815260200190600190039081610fb75790505b509052905060005b61101160408b018b612a2e565b90508110156110c05761109761102a60408c018c612a2e565b8381811061103a5761103a6127c3565b9050604002018036038101906110509190612a96565b8c61105b8d80612866565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e925061175d915050565b8260e0015182815181106110ad576110ad6127c3565b6020908102919091010152600101611004565b5060025460e082015160009173ffffffffffffffffffffffffffffffffffffffff169063085318f8908d906110f860408f018f612a2e565b6040518563ffffffff1660e01b81526004016111179493929190612bad565b600060405180830381865afa158015611134573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261117a9190810190612be3565b905060005b8260e00151518110156111d35781818151811061119e5761119e6127c3565b60200260200101518360e0015182815181106111bc576111bc6127c3565b60209081029190910101516080015260010161117f565b506080808301849052604080517f130ac867e79e2789f923760a88743d292acdf7002139a588206e2260f73f7321602082015267ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692820192909252908d166060820152309181019190915261126d90839060a00160405160208183030381529060405280519060200120611a83565b82515260405167ffffffffffffffff8c16907fcae3d9f68a9ed33d0a770e9bcc6fc25d4041dd6391e6cd8015546547a3c93140906112ac908590612c94565b60405180910390a25051519450505050505b949350505050565b6112ce61130b565b61045d81611b83565b60606040517f9e7177c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005473ffffffffffffffffffffffffffffffffffffffff16331461138c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161056e565b565b60005b81518110156115025760008282815181106113ae576113ae6127c3565b6020026020010151905060008383815181106113cc576113cc6127c3565b60200260200101516000015190508067ffffffffffffffff1660000361142a576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161056e565b60408051808201825267ffffffffffffffff838116600081815260056020818152868320805480871688528a83015173ffffffffffffffffffffffffffffffffffffffff908116848a019081529587905293835287518551851668010000000000000000027fffffffff00000000000000000000000000000000000000000000000000000000909216971696871717905586519485529151169083015291927f324d4a7950b57da00ce533ad6697039be6281726a73da959d0ab3ff795181ec6910160405180910390a2505050806001019050611391565b5050565b805173ffffffffffffffffffffffffffffffffffffffff1615806115425750604081015173ffffffffffffffffffffffffffffffffffffffff16155b15611579576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600280547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff93841617909155602080840151600380548416918516919091179055604080850151600480549094169085161790925581516080810183527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681527f00000000000000000000000000000000000000000000000000000000000000008416918101919091527f00000000000000000000000000000000000000000000000000000000000000008316818301527f00000000000000000000000000000000000000000000000000000000000000009092166060830152517f2d8f19dc1cd01460c3367a09d2d424f2b1940ba7c886047edd078c7b77ea4558916116c5918490612de2565b60405180910390a150565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052610855908490611c78565b61178f6040518060a0016040528060608152602001606081526020016060815260200160008152602001606081525090565b84602001516000036117cd576040517f5cf0444900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006117dd85876000015161085a565b905073ffffffffffffffffffffffffffffffffffffffff811615806118ad57506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527faff2afbf00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015611887573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ab91906124a3565b155b156118ff5785516040517fbf16aab600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161056e565b60008173ffffffffffffffffffffffffffffffffffffffff16639a4575b96040518060a001604052808881526020018967ffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018a6020015181526020018a6000015173ffffffffffffffffffffffffffffffffffffffff168152506040518263ffffffff1660e01b815260040161199e9190612e74565b6000604051808303816000875af11580156119bd573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611a039190810190612eea565b6040805160a0810190915273ffffffffffffffffffffffffffffffffffffffff841660c08201529091508060e0810160405160208183030381529060405281526020018260000151815260200182602001518152602001886020015181526020016040518060200160405280600081525081525092505050949350505050565b60008060001b82846020015185606001518660000151606001518760000151608001518860a001518960c00151604051602001611ac596959493929190612f7b565b604051602081830303815290604052805190602001208560400151805190602001208660e00151604051602001611afc9190612fdc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206080808c0151805190840120928501989098529183019590955260608201939093529384015260a083015260c082015260e00160405160208183030381529060405280519060200120905092915050565b3373ffffffffffffffffffffffffffffffffffffffff821603611c02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161056e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611cda826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611d849092919063ffffffff16565b8051909150156108555780806020019051810190611cf891906124a3565b610855576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161056e565b6060611d938484600085611d9d565b90505b9392505050565b606082471015611e2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161056e565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611e589190612fef565b60006040518083038185875af1925050503d8060008114611e95576040519150601f19603f3d011682016040523d82523d6000602084013e611e9a565b606091505b5091509150611eab87838387611eb6565b979650505050505050565b60608315611f4c578251600003611f455773ffffffffffffffffffffffffffffffffffffffff85163b611f45576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161056e565b50816112be565b6112be8383815115611f615781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161056e9190612220565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611fe757611fe7611f95565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561203457612034611f95565b604052919050565b600067ffffffffffffffff82111561205657612056611f95565b5060051b60200190565b67ffffffffffffffff8116811461045d57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461045d57600080fd5b600060208083850312156120ab57600080fd5b823567ffffffffffffffff8111156120c257600080fd5b8301601f810185136120d357600080fd5b80356120e66120e18261203c565b611fed565b81815260069190911b8201830190838101908783111561210557600080fd5b928401925b82841015611eab57604084890312156121235760008081fd5b61212b611fc4565b843561213681612060565b81528486013561214581612076565b818701528252604093909301929084019061210a565b60808101610613828467ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b60005b838110156121cd5781810151838201526020016121b5565b50506000910152565b600081518084526121ee8160208601602086016121b2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061061060208301846121d6565b600060a0828403121561224557600080fd5b50919050565b6000806040838503121561225e57600080fd5b823561226981612060565b9150602083013567ffffffffffffffff81111561228557600080fd5b61229185828601612233565b9150509250929050565b80356122a681612076565b919050565b6000606082840312156122bd57600080fd5b6040516060810181811067ffffffffffffffff821117156122e0576122e0611f95565b60405282356122ee81612076565b815260208301356122fe81612076565b6020820152604083013561231181612076565b60408201529392505050565b6000806040838503121561233057600080fd5b823561233b81612060565b9150602083013561234b81612076565b809150509250929050565b606081016106138284805173ffffffffffffffffffffffffffffffffffffffff908116835260208083015182169084015260409182015116910152565b6000602082840312156123a557600080fd5b8135611d9681612060565b600080600080608085870312156123c657600080fd5b84356123d181612060565b9350602085013567ffffffffffffffff8111156123ed57600080fd5b6123f987828801612233565b93505060408501359150606085013561241181612076565b939692955090935050565b60006020828403121561242e57600080fd5b8135611d9681612076565b6020808252825182820181905260009190848201906040850190845b8181101561248757835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612455565b50909695505050505050565b805180151581146122a657600080fd5b6000602082840312156124b557600080fd5b61061082612493565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126124f357600080fd5b830160208101925035905067ffffffffffffffff81111561251357600080fd5b80360382131561252257600080fd5b9250929050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b8183526000602080850194508260005b858110156125c757813561259581612076565b73ffffffffffffffffffffffffffffffffffffffff168752818301358388015260409687019690910190600101612582565b509495945050505050565b600067ffffffffffffffff8085168352604060208401526125f384856124be565b60a0604086015261260860e086018284612529565b91505061261860208601866124be565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08087850301606088015261264e848385612529565b9350604088013592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe188360301831261268757600080fd5b602092880192830192359150848211156126a057600080fd5b8160061b36038313156126b257600080fd5b808785030160808801526126c7848385612572565b94506126d56060890161229b565b73ffffffffffffffffffffffffffffffffffffffff811660a0890152935061270060808901896124be565b94509250808786030160c08801525050611eab838383612529565b60006020828403121561272d57600080fd5b5051919050565b6000602080838503121561274757600080fd5b825167ffffffffffffffff81111561275e57600080fd5b8301601f8101851361276f57600080fd5b805161277d6120e18261203c565b81815260059190911b8201830190838101908783111561279c57600080fd5b928401925b82841015611eab5783516127b481612076565b825292840192908401906127a1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561280457600080fd5b8151611d9681612076565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff81811683821601908082111561285f5761285f61280f565b5092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261289b57600080fd5b83018035915067ffffffffffffffff8211156128b657600080fd5b60200191503681900382131561252257600080fd5b67ffffffffffffffff8616815273ffffffffffffffffffffffffffffffffffffffff85166020820152836040820152608060608201526000611eab608083018486612529565b600082601f83011261292257600080fd5b815167ffffffffffffffff81111561293c5761293c611f95565b61296d60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611fed565b81815284602083860101111561298257600080fd5b6112be8260208301602087016121b2565b6000806000606084860312156129a857600080fd5b835192506129b860208501612493565b9150604084015167ffffffffffffffff8111156129d457600080fd5b6129e086828701612911565b9150509250925092565b600067ffffffffffffffff808316818103612a0757612a0761280f565b6001019392505050565b600060208284031215612a2357600080fd5b8151611d9681612060565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612a6357600080fd5b83018035915067ffffffffffffffff821115612a7e57600080fd5b6020019150600681901b360382131561252257600080fd5b600060408284031215612aa857600080fd5b612ab0611fc4565b8235612abb81612076565b81526020928301359281019290925250919050565b600082825180855260208086019550808260051b84010181860160005b84811015612ba0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0868403018952815160a08151818652612b31828701826121d6565b9150508582015185820387870152612b4982826121d6565b91505060408083015186830382880152612b6383826121d6565b92505050606080830151818701525060808083015192508582038187015250612b8c81836121d6565b9a86019a9450505090830190600101612aed565b5090979650505050505050565b67ffffffffffffffff85168152606060208201526000612bd06060830186612ad0565b8281036040840152611eab818587612572565b60006020808385031215612bf657600080fd5b825167ffffffffffffffff80821115612c0e57600080fd5b818501915085601f830112612c2257600080fd5b8151612c306120e18261203c565b81815260059190911b83018401908481019088831115612c4f57600080fd5b8585015b83811015612c8757805185811115612c6b5760008081fd5b612c798b89838a0101612911565b845250918601918601612c53565b5098975050505050505050565b60208152612ce560208201835180518252602081015167ffffffffffffffff808216602085015280604084015116604085015280606084015116606085015280608084015116608085015250505050565b60006020830151612d0e60c084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060408301516101808060e0850152612d2b6101a08501836121d6565b915060608501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08086850301610100870152612d6884836121d6565b9350608087015191508086850301610120870152612d8684836121d6565b935060a08701519150612db261014087018373ffffffffffffffffffffffffffffffffffffffff169052565b60c087015161016087015260e0870151915080868503018387015250612dd88382612ad0565b9695505050505050565b60e08101612e39828567ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b825173ffffffffffffffffffffffffffffffffffffffff90811660808401526020840151811660a084015260408401511660c0830152611d96565b602081526000825160a06020840152612e9060c08401826121d6565b905067ffffffffffffffff6020850151166040840152604084015173ffffffffffffffffffffffffffffffffffffffff8082166060860152606086015160808601528060808701511660a086015250508091505092915050565b600060208284031215612efc57600080fd5b815167ffffffffffffffff80821115612f1457600080fd5b9083019060408286031215612f2857600080fd5b612f30611fc4565b825182811115612f3f57600080fd5b612f4b87828601612911565b825250602083015182811115612f6057600080fd5b612f6c87828601612911565b60208301525095945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808916835260c06020840152612fab60c08401896121d6565b67ffffffffffffffff97881660408501529590961660608301525091909316608082015260a0019190915292915050565b6020815260006106106020830184612ad0565b600082516130018184602087016121b2565b919091019291505056fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"allowListAdmin\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GetSupportedTokensFunctionalityRemovedCheckAdminRegistry\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidAllowListRequest\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidDestChainConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAllowlistAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"allowListAdmin\",\"type\":\"address\"}],\"name\":\"AllowListAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"senders\",\"type\":\"address[]\"}],\"name\":\"AllowListSendersAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"senders\",\"type\":\"address[]\"}],\"name\":\"AllowListSendersRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"destExecData\",\"type\":\"bytes\"}],\"internalType\":\"structInternal.RampTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2AnyRampMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"allowListAdmin\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"allowListEnabled\",\"type\":\"bool\"}],\"name\":\"DestChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeValueJuels\",\"type\":\"uint256\"}],\"name\":\"FeePaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeeTokenWithdrawn\",\"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\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowListEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"addedAllowlistedSenders\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedAllowlistedSenders\",\"type\":\"address[]\"}],\"internalType\":\"structOnRamp.AllowListConfigArgs[]\",\"name\":\"allowListConfigArgsItems\",\"type\":\"tuple[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DestChainConfigArgs[]\",\"name\":\"destChainConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyDestChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getAllowedSendersList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestChainConfig\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowListEnabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"allowListAdmin\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPoolV1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"contractIRouter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAggregator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"allowListAdmin\",\"type\":\"address\"}],\"internalType\":\"structOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"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\":[],\"name\":\"withdrawFeeTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b506040516200407338038062004073833981016040819052620000359162000665565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000186565b505083516001600160401b031615905080620000e6575060208301516001600160a01b0316155b80620000fd575060408301516001600160a01b0316155b8062000114575060608301516001600160a01b0316155b1562000133576040516306b7c75960e31b815260040160405180910390fd5b82516001600160401b031660805260208301516001600160a01b0390811660a0526040840151811660c05260608401511660e052620001728262000231565b6200017d8162000390565b5050506200079f565b336001600160a01b03821603620001e05760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0316158062000254575060408101516001600160a01b0316155b1562000273576040516306b7c75960e31b815260040160405180910390fd5b8051600280546001600160a01b03199081166001600160a01b0393841617909155602080840180516003805485169186169190911790556040808601805160048054871691881691909117905560608088018051600580549098169089161790965582516080808201855280516001600160401b031680835260a080518b16848a0190815260c080518d16868a0190815260e080518f169789019788528a5195865292518e169b85019b909b5299518c169783019790975292518a169381019390935289518916908301529351871693810193909352518516928201929092529151909216918101919091527f23a1adf8ad7fad6091a4803227af2cee848c01a7c812404cade7c25636925e32906101000160405180910390a150565b60005b8151811015620004cf576000828281518110620003b457620003b462000789565b602002602001015190506000838381518110620003d557620003d562000789565b6020026020010151600001519050806001600160401b03166000036200041a5760405163c35aa79d60e01b81526001600160401b038216600482015260240162000083565b6001600160401b03818116600081815260066020908152604091829020868201518154600160481b600160e81b0319811669010000000000000000006001600160a01b03909316928302908117808555865192891691909816178152928301526801000000000000000090940460ff161515918101919091527fd5ad72bc37dc7a80a8b9b9df20500046fd7341adb1be2258a540466fdd7dcef59060600160405180910390a250505080600101905062000393565b5050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b03811182821017156200050e576200050e620004d3565b60405290565b604080519081016001600160401b03811182821017156200050e576200050e620004d3565b604051601f8201601f191681016001600160401b0381118282101715620005645762000564620004d3565b604052919050565b80516001600160401b03811681146200058457600080fd5b919050565b6001600160a01b03811681146200059f57600080fd5b50565b600082601f830112620005b457600080fd5b815160206001600160401b03821115620005d257620005d2620004d3565b620005e2818360051b0162000539565b82815260069290921b840181019181810190868411156200060257600080fd5b8286015b848110156200065a5760408189031215620006215760008081fd5b6200062b62000514565b62000636826200056c565b815284820151620006478162000589565b8186015283529183019160400162000606565b509695505050505050565b60008060008385036101208112156200067d57600080fd5b60808112156200068c57600080fd5b62000696620004e9565b620006a1866200056c565b81526020860151620006b38162000589565b60208201526040860151620006c88162000589565b60408201526060860151620006dd8162000589565b606082015293506080607f1982011215620006f757600080fd5b5062000702620004e9565b6080850151620007128162000589565b815260a0850151620007248162000589565b602082015260c0850151620007398162000589565b604082015260e08501516200074e8162000589565b60608201526101008501519092506001600160401b038111156200077157600080fd5b6200077f86828701620005a2565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b60805160a05160c05160e05161385b620008186000396000818161022c01528181610c790152611beb0152600081816101f0015281816112480152611bc40152600081816101b4015281816105de0152611b9a0152600081816101840152818161116e015281816116930152611b6d015261385b6000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c806379ba5097116100b2578063a6f3ab6c11610081578063df0aa9e911610066578063df0aa9e91461052d578063f2fde38b14610540578063fbca3b741461055357600080fd5b8063a6f3ab6c146104cd578063d77d5ed0146104e057600080fd5b806379ba50971461045b5780638da5cb5b146104635780639041be3d14610481578063972b4612146104ad57600080fd5b806334adf4941161010957806348a98aa4116100ee57806348a98aa4146103045780636def4ce71461033c5780637437ff9f146103db57600080fd5b806334adf494146102e95780633a019940146102fc57600080fd5b80630242cf601461013b57806306285c6914610150578063181f5a771461027f57806320487ded146102c8575b600080fd5b61014e6101493660046126e0565b610566565b005b61026960408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b60405161027691906127a3565b60405180910390f35b6102bb6040518060400160405280601081526020017f4f6e52616d7020312e362e302d6465760000000000000000000000000000000081525081565b6040516102769190612868565b6102db6102d6366004612893565b61057a565b604051908152602001610276565b61014e6102f73660046128e3565b610733565b61014e610a06565b610317610312366004612958565b610c31565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610276565b61039f61034a366004612991565b67ffffffffffffffff9081166000908152600660205260409020549081169168010000000000000000820460ff16916901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1690565b6040805167ffffffffffffffff9094168452911515602084015273ffffffffffffffffffffffffffffffffffffffff1690820152606001610276565b61044e604080516080810182526000808252602082018190529181018290526060810191909152506040805160808101825260025473ffffffffffffffffffffffffffffffffffffffff908116825260035481166020830152600454811692820192909252600554909116606082015290565b60405161027691906129ae565b61014e610ce6565b60005473ffffffffffffffffffffffffffffffffffffffff16610317565b61049461048f366004612991565b610de3565b60405167ffffffffffffffff9091168152602001610276565b6104c06104bb366004612991565b610e0c565b60405161027691906129f7565b61014e6104db366004612a61565b610e34565b6103176104ee366004612991565b67ffffffffffffffff166000908152600660205260409020546901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1690565b6102db61053b366004612ac8565b610e45565b61014e61054e366004612b34565b611748565b6104c0610561366004612991565b611759565b61056e61178d565b61057781611810565b50565b6040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815277ffffffffffffffff00000000000000000000000000000000608084901b16600482015260009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa158015610625573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106499190612b5f565b15610691576040517ffdbd6a7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6002546040517fd8694ccd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063d8694ccd906106e99086908690600401612c90565b602060405180830381865afa158015610706573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072a9190612dd9565b90505b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146107a35760055473ffffffffffffffffffffffffffffffffffffffff1633146107a3576040517f905d7d9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610a015760008383838181106107c2576107c2612df2565b90506020028101906107d49190612e21565b6107dd90612ed2565b805167ffffffffffffffff1660009081526006602090815260409091209082015181547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000009115801592909202178255919250906109545760005b8260400151518110156108fd5760008360400151828151811061086757610867612df2565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036108e65783516040517f463258ff00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610688565b6108f36001840182611987565b5050600101610842565b506040820151511561095457816000015167ffffffffffffffff167f330939f6eafe8bb516716892fe962ff19770570838686e6579dbc1cc51fc3281836040015160405161094b91906129f7565b60405180910390a25b60005b8260600151518110156109a0576109978360600151828151811061097d5761097d612df2565b6020026020010151836001016119a990919063ffffffff16565b50600101610957565b50606082015151156109f757816000015167ffffffffffffffff167fc237ec1921f855ccd5e9a5af9733f2d58943a5a8501ec5988e305d7a4d42158683606001516040516109ee91906129f7565b60405180910390a25b50506001016107a6565b505050565b600254604080517fcdc73d51000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163cdc73d5191600480830192869291908290030181865afa158015610a75573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610abb9190810190612f65565b60045490915073ffffffffffffffffffffffffffffffffffffffff1660005b8251811015610a01576000838281518110610af757610af7612df2565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610b72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b969190612dd9565b90508015610c2757610bbf73ffffffffffffffffffffffffffffffffffffffff831685836119cb565b8173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f508d7d183612c18fc339b42618912b9fa3239f631dd7ec0671f950200a0fa66e83604051610c1e91815260200190565b60405180910390a35b5050600101610ada565b6040517fbbe4f6db00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bbe4f6db90602401602060405180830381865afa158015610cc2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072a9190612ff4565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d67576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610688565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b67ffffffffffffffff808216600090815260066020526040812054909161072d91166001613040565b67ffffffffffffffff8116600090815260066020526040902060609061072d90600101611a58565b610e3c61178d565b61057781611a6c565b67ffffffffffffffff8416600090815260066020526040812073ffffffffffffffffffffffffffffffffffffffff8316610eab576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805468010000000000000000900460ff1615610f1c57610ece6001820184611c4e565b610f1c576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610688565b80546901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff163314610f79576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60035473ffffffffffffffffffffffffffffffffffffffff16801561101f576040517fe0a0e50600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063e0a0e50690610fec908a908a90600401612c90565b600060405180830381600087803b15801561100657600080fd5b505af115801561101a573d6000803e3d6000fd5b505050505b506002546000908190819073ffffffffffffffffffffffffffffffffffffffff1663c4276bfc8a61105660808c0160608d01612b34565b8a61106460808e018e613061565b6040518663ffffffff1660e01b81526004016110849594939291906130c6565b600060405180830381865afa1580156110a1573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526110e7919081019061318e565b919450925090506110fe6080890160608a01612b34565b73ffffffffffffffffffffffffffffffffffffffff167f075a2720282fdf622141dae0b048ef90a21a7e57c134c76912d19d006b3b3f6f8460405161114591815260200190565b60405180910390a2604080516101a081019091526000610100820181815267ffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166101208501528c811661014085015287549293928392916101608401918a9187916111ba91166131e8565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905567ffffffffffffffff168152602001866112ba576040517fea458c0c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8f16600482015273ffffffffffffffffffffffffffffffffffffffff8c811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063ea458c0c906044016020604051808303816000875af1158015611291573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112b5919061320f565b6112bd565b60005b67ffffffffffffffff1681525081526020018873ffffffffffffffffffffffffffffffffffffffff1681526020018a80602001906112fb9190613061565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060200161133f8b80613061565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060200161138660808c018c613061565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050908252506020016113d060808c0160608d01612b34565b73ffffffffffffffffffffffffffffffffffffffff1681526020018981526020018a8060400190611401919061322c565b905067ffffffffffffffff81111561141b5761141b6125ba565b60405190808252806020026020018201604052801561147e57816020015b61146b6040518060a0016040528060608152602001606081526020016060815260200160008152602001606081525090565b8152602001906001900390816114395790505b509052905060005b61149360408b018b61322c565b9050811015611542576115196114ac60408c018c61322c565b838181106114bc576114bc612df2565b9050604002018036038101906114d29190613294565b8c6114dd8d80613061565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e9250611c7d915050565b8260e00151828151811061152f5761152f612df2565b6020908102919091010152600101611486565b5060025460e082015160009173ffffffffffffffffffffffffffffffffffffffff169063085318f8908d9061157a60408f018f61322c565b6040518563ffffffff1660e01b815260040161159994939291906133ab565b600060405180830381865afa1580156115b6573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526115fc91908101906133e1565b905060005b8260e00151518110156116555781818151811061162057611620612df2565b60200260200101518360e00151828151811061163e5761163e612df2565b602090810291909101015160800152600101611601565b506080808301849052604080517f130ac867e79e2789f923760a88743d292acdf7002139a588206e2260f73f7321602082015267ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811692820192909252908d16606082015230918101919091526116ef90839060a00160405160208183030381529060405280519060200120611fa3565b82515260405167ffffffffffffffff8c16907fcae3d9f68a9ed33d0a770e9bcc6fc25d4041dd6391e6cd8015546547a3c931409061172e908590613492565b60405180910390a25051519450505050505b949350505050565b61175061178d565b610577816120a3565b60606040517f9e7177c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005473ffffffffffffffffffffffffffffffffffffffff16331461180e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610688565b565b60005b815181101561198357600082828151811061183057611830612df2565b60200260200101519050600083838151811061184e5761184e612df2565b60200260200101516000015190508067ffffffffffffffff166000036118ac576040517fc35aa79d00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610688565b67ffffffffffffffff8181166000818152600660209081526040918290208682015181547fffffff0000000000000000000000000000000000000000ffffffffffffffffff8116690100000000000000000073ffffffffffffffffffffffffffffffffffffffff909316928302908117808555865192891691909816178152928301526801000000000000000090940460ff161515918101919091527fd5ad72bc37dc7a80a8b9b9df20500046fd7341adb1be2258a540466fdd7dcef59060600160405180910390a2505050806001019050611813565b5050565b600061072a8373ffffffffffffffffffffffffffffffffffffffff8416612198565b600061072a8373ffffffffffffffffffffffffffffffffffffffff84166121e7565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052610a019084906122e1565b60606000611a65836123ed565b9392505050565b805173ffffffffffffffffffffffffffffffffffffffff161580611aa85750604081015173ffffffffffffffffffffffffffffffffffffffff16155b15611adf576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600280547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff93841617909155602080840151600380548416918516919091179055604080850151600480548516918616919091179055606080860151600580549095169086161790935580516080810182527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681527f00000000000000000000000000000000000000000000000000000000000000008516928101929092527f00000000000000000000000000000000000000000000000000000000000000008416828201527f00000000000000000000000000000000000000000000000000000000000000009093169181019190915290517f23a1adf8ad7fad6091a4803227af2cee848c01a7c812404cade7c25636925e3291611c439184906135e0565b60405180910390a150565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561072a565b611caf6040518060a0016040528060608152602001606081526020016060815260200160008152602001606081525090565b8460200151600003611ced576040517f5cf0444900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611cfd858760000151610c31565b905073ffffffffffffffffffffffffffffffffffffffff81161580611dcd57506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527faff2afbf00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015611da7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dcb9190612b5f565b155b15611e1f5785516040517fbf16aab600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610688565b60008173ffffffffffffffffffffffffffffffffffffffff16639a4575b96040518060a001604052808881526020018967ffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018a6020015181526020018a6000015173ffffffffffffffffffffffffffffffffffffffff168152506040518263ffffffff1660e01b8152600401611ebe919061367f565b6000604051808303816000875af1158015611edd573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611f2391908101906136f5565b6040805160a0810190915273ffffffffffffffffffffffffffffffffffffffff841660c08201529091508060e0810160405160208183030381529060405281526020018260000151815260200182602001518152602001886020015181526020016040518060200160405280600081525081525092505050949350505050565b60008060001b82846020015185606001518660000151606001518760000151608001518860a001518960c00151604051602001611fe596959493929190613786565b604051602081830303815290604052805190602001208560400151805190602001208660e0015160405160200161201c91906137e7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206080808c0151805190840120928501989098529183019590955260608201939093529384015260a083015260c082015260e00160405160208183030381529060405280519060200120905092915050565b3373ffffffffffffffffffffffffffffffffffffffff821603612122576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610688565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008181526001830160205260408120546121df5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561072d565b50600061072d565b600081815260018301602052604081205480156122d057600061220b6001836137fa565b855490915060009061221f906001906137fa565b905080821461228457600086600001828154811061223f5761223f612df2565b906000526020600020015490508087600001848154811061226257612262612df2565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806122955761229561380d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061072d565b600091505061072d565b5092915050565b6000612343826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166124499092919063ffffffff16565b805190915015610a0157808060200190518101906123619190612b5f565b610a01576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610688565b60608160000180548060200260200160405190810160405280929190818152602001828054801561243d57602002820191906000526020600020905b815481526020019060010190808311612429575b50505050509050919050565b60606117408484600085856000808673ffffffffffffffffffffffffffffffffffffffff16858760405161247d919061383c565b60006040518083038185875af1925050503d80600081146124ba576040519150601f19603f3d011682016040523d82523d6000602084013e6124bf565b606091505b50915091506124d0878383876124db565b979650505050505050565b6060831561257157825160000361256a5773ffffffffffffffffffffffffffffffffffffffff85163b61256a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610688565b5081611740565b61174083838151156125865781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106889190612868565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561260c5761260c6125ba565b60405290565b6040516080810167ffffffffffffffff8111828210171561260c5761260c6125ba565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561267c5761267c6125ba565b604052919050565b600067ffffffffffffffff82111561269e5761269e6125ba565b5060051b60200190565b67ffffffffffffffff8116811461057757600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461057757600080fd5b600060208083850312156126f357600080fd5b823567ffffffffffffffff81111561270a57600080fd5b8301601f8101851361271b57600080fd5b803561272e61272982612684565b612635565b81815260069190911b8201830190838101908783111561274d57600080fd5b928401925b828410156124d0576040848903121561276b5760008081fd5b6127736125e9565b843561277e816126a8565b81528486013561278d816126be565b8187015282526040939093019290840190612752565b6080810161072d828467ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b60005b838110156128155781810151838201526020016127fd565b50506000910152565b600081518084526128368160208601602086016127fa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061072a602083018461281e565b600060a0828403121561288d57600080fd5b50919050565b600080604083850312156128a657600080fd5b82356128b1816126a8565b9150602083013567ffffffffffffffff8111156128cd57600080fd5b6128d98582860161287b565b9150509250929050565b600080602083850312156128f657600080fd5b823567ffffffffffffffff8082111561290e57600080fd5b818501915085601f83011261292257600080fd5b81358181111561293157600080fd5b8660208260051b850101111561294657600080fd5b60209290920196919550909350505050565b6000806040838503121561296b57600080fd5b8235612976816126a8565b91506020830135612986816126be565b809150509250929050565b6000602082840312156129a357600080fd5b8135611a65816126a8565b6080810161072d8284805173ffffffffffffffffffffffffffffffffffffffff908116835260208083015182169084015260408083015182169084015260609182015116910152565b6020808252825182820181905260009190848201906040850190845b81811015612a4557835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612a13565b50909695505050505050565b8035612a5c816126be565b919050565b600060808284031215612a7357600080fd5b612a7b612612565b8235612a86816126be565b81526020830135612a96816126be565b60208201526040830135612aa9816126be565b60408201526060830135612abc816126be565b60608201529392505050565b60008060008060808587031215612ade57600080fd5b8435612ae9816126a8565b9350602085013567ffffffffffffffff811115612b0557600080fd5b612b118782880161287b565b935050604085013591506060850135612b29816126be565b939692955090935050565b600060208284031215612b4657600080fd5b8135611a65816126be565b801515811461057757600080fd5b600060208284031215612b7157600080fd5b8151611a6581612b51565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612bb157600080fd5b830160208101925035905067ffffffffffffffff811115612bd157600080fd5b803603821315612be057600080fd5b9250929050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b8183526000602080850194508260005b85811015612c85578135612c53816126be565b73ffffffffffffffffffffffffffffffffffffffff168752818301358388015260409687019690910190600101612c40565b509495945050505050565b600067ffffffffffffffff808516835260406020840152612cb18485612b7c565b60a06040860152612cc660e086018284612be7565b915050612cd66020860186612b7c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc080878503016060880152612d0c848385612be7565b9350604088013592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1883603018312612d4557600080fd5b60209288019283019235915084821115612d5e57600080fd5b8160061b3603831315612d7057600080fd5b80878503016080880152612d85848385612c30565b9450612d9360608901612a51565b73ffffffffffffffffffffffffffffffffffffffff811660a08901529350612dbe6080890189612b7c565b94509250808786030160c088015250506124d0838383612be7565b600060208284031215612deb57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112612e5557600080fd5b9190910192915050565b600082601f830112612e7057600080fd5b81356020612e8061272983612684565b8083825260208201915060208460051b870101935086841115612ea257600080fd5b602086015b84811015612ec7578035612eba816126be565b8352918301918301612ea7565b509695505050505050565b600060808236031215612ee457600080fd5b612eec612612565b8235612ef7816126a8565b81526020830135612f0781612b51565b6020820152604083013567ffffffffffffffff80821115612f2757600080fd5b612f3336838701612e5f565b60408401526060850135915080821115612f4c57600080fd5b50612f5936828601612e5f565b60608301525092915050565b60006020808385031215612f7857600080fd5b825167ffffffffffffffff811115612f8f57600080fd5b8301601f81018513612fa057600080fd5b8051612fae61272982612684565b81815260059190911b82018301908381019087831115612fcd57600080fd5b928401925b828410156124d0578351612fe5816126be565b82529284019290840190612fd2565b60006020828403121561300657600080fd5b8151611a65816126be565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff8181168382160190808211156122da576122da613011565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261309657600080fd5b83018035915067ffffffffffffffff8211156130b157600080fd5b602001915036819003821315612be057600080fd5b67ffffffffffffffff8616815273ffffffffffffffffffffffffffffffffffffffff851660208201528360408201526080606082015260006124d0608083018486612be7565b600082601f83011261311d57600080fd5b815167ffffffffffffffff811115613137576131376125ba565b61316860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601612635565b81815284602083860101111561317d57600080fd5b6117408260208301602087016127fa565b6000806000606084860312156131a357600080fd5b8351925060208401516131b581612b51565b604085015190925067ffffffffffffffff8111156131d257600080fd5b6131de8682870161310c565b9150509250925092565b600067ffffffffffffffff80831681810361320557613205613011565b6001019392505050565b60006020828403121561322157600080fd5b8151611a65816126a8565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261326157600080fd5b83018035915067ffffffffffffffff82111561327c57600080fd5b6020019150600681901b3603821315612be057600080fd5b6000604082840312156132a657600080fd5b6132ae6125e9565b82356132b9816126be565b81526020928301359281019290925250919050565b600082825180855260208086019550808260051b84010181860160005b8481101561339e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0868403018952815160a0815181865261332f8287018261281e565b9150508582015185820387870152613347828261281e565b91505060408083015186830382880152613361838261281e565b9250505060608083015181870152506080808301519250858203818701525061338a818361281e565b9a86019a94505050908301906001016132eb565b5090979650505050505050565b67ffffffffffffffff851681526060602082015260006133ce60608301866132ce565b82810360408401526124d0818587612c30565b600060208083850312156133f457600080fd5b825167ffffffffffffffff8082111561340c57600080fd5b818501915085601f83011261342057600080fd5b815161342e61272982612684565b81815260059190911b8301840190848101908883111561344d57600080fd5b8585015b83811015613485578051858111156134695760008081fd5b6134778b89838a010161310c565b845250918601918601613451565b5098975050505050505050565b602081526134e360208201835180518252602081015167ffffffffffffffff808216602085015280604084015116604085015280606084015116606085015280608084015116608085015250505050565b6000602083015161350c60c084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060408301516101808060e08501526135296101a085018361281e565b915060608501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08086850301610100870152613566848361281e565b9350608087015191508086850301610120870152613584848361281e565b935060a087015191506135b061014087018373ffffffffffffffffffffffffffffffffffffffff169052565b60c087015161016087015260e08701519150808685030183870152506135d683826132ce565b9695505050505050565b6101008101613638828567ffffffffffffffff8151168252602081015173ffffffffffffffffffffffffffffffffffffffff808216602085015280604084015116604085015280606084015116606085015250505050565b825173ffffffffffffffffffffffffffffffffffffffff90811660808401526020840151811660a08401526040840151811660c084015260608401511660e0830152611a65565b602081526000825160a0602084015261369b60c084018261281e565b905067ffffffffffffffff6020850151166040840152604084015173ffffffffffffffffffffffffffffffffffffffff8082166060860152606086015160808601528060808701511660a086015250508091505092915050565b60006020828403121561370757600080fd5b815167ffffffffffffffff8082111561371f57600080fd5b908301906040828603121561373357600080fd5b61373b6125e9565b82518281111561374a57600080fd5b6137568782860161310c565b82525060208301518281111561376b57600080fd5b6137778782860161310c565b60208301525095945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808916835260c060208401526137b660c084018961281e565b67ffffffffffffffff97881660408501529590961660608301525091909316608082015260a0019190915292915050565b60208152600061072a60208301846132ce565b8181038181111561072d5761072d613011565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008251612e558184602087016127fa56fea164736f6c6343000818000a", } var OnRampABI = OnRampMetaData.ABI @@ -234,6 +237,59 @@ func (_OnRamp *OnRampTransactorRaw) Transact(opts *bind.TransactOpts, method str return _OnRamp.Contract.contract.Transact(opts, method, params...) } +func (_OnRamp *OnRampCaller) GetAllowedSendersList(opts *bind.CallOpts, destChainSelector uint64) ([]common.Address, error) { + var out []interface{} + err := _OnRamp.contract.Call(opts, &out, "getAllowedSendersList", destChainSelector) + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_OnRamp *OnRampSession) GetAllowedSendersList(destChainSelector uint64) ([]common.Address, error) { + return _OnRamp.Contract.GetAllowedSendersList(&_OnRamp.CallOpts, destChainSelector) +} + +func (_OnRamp *OnRampCallerSession) GetAllowedSendersList(destChainSelector uint64) ([]common.Address, error) { + return _OnRamp.Contract.GetAllowedSendersList(&_OnRamp.CallOpts, destChainSelector) +} + +func (_OnRamp *OnRampCaller) GetDestChainConfig(opts *bind.CallOpts, destChainSelector uint64) (GetDestChainConfig, + + error) { + var out []interface{} + err := _OnRamp.contract.Call(opts, &out, "getDestChainConfig", destChainSelector) + + outstruct := new(GetDestChainConfig) + if err != nil { + return *outstruct, err + } + + outstruct.SequenceNumber = *abi.ConvertType(out[0], new(uint64)).(*uint64) + outstruct.AllowListEnabled = *abi.ConvertType(out[1], new(bool)).(*bool) + outstruct.Router = *abi.ConvertType(out[2], new(common.Address)).(*common.Address) + + return *outstruct, err + +} + +func (_OnRamp *OnRampSession) GetDestChainConfig(destChainSelector uint64) (GetDestChainConfig, + + error) { + return _OnRamp.Contract.GetDestChainConfig(&_OnRamp.CallOpts, destChainSelector) +} + +func (_OnRamp *OnRampCallerSession) GetDestChainConfig(destChainSelector uint64) (GetDestChainConfig, + + error) { + return _OnRamp.Contract.GetDestChainConfig(&_OnRamp.CallOpts, destChainSelector) +} + func (_OnRamp *OnRampCaller) GetDynamicConfig(opts *bind.CallOpts) (OnRampDynamicConfig, error) { var out []interface{} err := _OnRamp.contract.Call(opts, &out, "getDynamicConfig") @@ -444,6 +500,18 @@ func (_OnRamp *OnRampTransactorSession) AcceptOwnership() (*types.Transaction, e return _OnRamp.Contract.AcceptOwnership(&_OnRamp.TransactOpts) } +func (_OnRamp *OnRampTransactor) ApplyAllowListUpdates(opts *bind.TransactOpts, allowListConfigArgsItems []OnRampAllowListConfigArgs) (*types.Transaction, error) { + return _OnRamp.contract.Transact(opts, "applyAllowListUpdates", allowListConfigArgsItems) +} + +func (_OnRamp *OnRampSession) ApplyAllowListUpdates(allowListConfigArgsItems []OnRampAllowListConfigArgs) (*types.Transaction, error) { + return _OnRamp.Contract.ApplyAllowListUpdates(&_OnRamp.TransactOpts, allowListConfigArgsItems) +} + +func (_OnRamp *OnRampTransactorSession) ApplyAllowListUpdates(allowListConfigArgsItems []OnRampAllowListConfigArgs) (*types.Transaction, error) { + return _OnRamp.Contract.ApplyAllowListUpdates(&_OnRamp.TransactOpts, allowListConfigArgsItems) +} + func (_OnRamp *OnRampTransactor) ApplyDestChainConfigUpdates(opts *bind.TransactOpts, destChainConfigArgs []OnRampDestChainConfigArgs) (*types.Transaction, error) { return _OnRamp.contract.Transact(opts, "applyDestChainConfigUpdates", destChainConfigArgs) } @@ -504,6 +572,389 @@ func (_OnRamp *OnRampTransactorSession) WithdrawFeeTokens() (*types.Transaction, return _OnRamp.Contract.WithdrawFeeTokens(&_OnRamp.TransactOpts) } +type OnRampAllowListAdminSetIterator struct { + Event *OnRampAllowListAdminSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *OnRampAllowListAdminSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(OnRampAllowListAdminSet) + 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(OnRampAllowListAdminSet) + 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 *OnRampAllowListAdminSetIterator) Error() error { + return it.fail +} + +func (it *OnRampAllowListAdminSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type OnRampAllowListAdminSet struct { + AllowListAdmin common.Address + Raw types.Log +} + +func (_OnRamp *OnRampFilterer) FilterAllowListAdminSet(opts *bind.FilterOpts, allowListAdmin []common.Address) (*OnRampAllowListAdminSetIterator, error) { + + var allowListAdminRule []interface{} + for _, allowListAdminItem := range allowListAdmin { + allowListAdminRule = append(allowListAdminRule, allowListAdminItem) + } + + logs, sub, err := _OnRamp.contract.FilterLogs(opts, "AllowListAdminSet", allowListAdminRule) + if err != nil { + return nil, err + } + return &OnRampAllowListAdminSetIterator{contract: _OnRamp.contract, event: "AllowListAdminSet", logs: logs, sub: sub}, nil +} + +func (_OnRamp *OnRampFilterer) WatchAllowListAdminSet(opts *bind.WatchOpts, sink chan<- *OnRampAllowListAdminSet, allowListAdmin []common.Address) (event.Subscription, error) { + + var allowListAdminRule []interface{} + for _, allowListAdminItem := range allowListAdmin { + allowListAdminRule = append(allowListAdminRule, allowListAdminItem) + } + + logs, sub, err := _OnRamp.contract.WatchLogs(opts, "AllowListAdminSet", allowListAdminRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(OnRampAllowListAdminSet) + if err := _OnRamp.contract.UnpackLog(event, "AllowListAdminSet", 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 (_OnRamp *OnRampFilterer) ParseAllowListAdminSet(log types.Log) (*OnRampAllowListAdminSet, error) { + event := new(OnRampAllowListAdminSet) + if err := _OnRamp.contract.UnpackLog(event, "AllowListAdminSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type OnRampAllowListSendersAddedIterator struct { + Event *OnRampAllowListSendersAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *OnRampAllowListSendersAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(OnRampAllowListSendersAdded) + 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(OnRampAllowListSendersAdded) + 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 *OnRampAllowListSendersAddedIterator) Error() error { + return it.fail +} + +func (it *OnRampAllowListSendersAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type OnRampAllowListSendersAdded struct { + DestChainSelector uint64 + Senders []common.Address + Raw types.Log +} + +func (_OnRamp *OnRampFilterer) FilterAllowListSendersAdded(opts *bind.FilterOpts, destChainSelector []uint64) (*OnRampAllowListSendersAddedIterator, error) { + + var destChainSelectorRule []interface{} + for _, destChainSelectorItem := range destChainSelector { + destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) + } + + logs, sub, err := _OnRamp.contract.FilterLogs(opts, "AllowListSendersAdded", destChainSelectorRule) + if err != nil { + return nil, err + } + return &OnRampAllowListSendersAddedIterator{contract: _OnRamp.contract, event: "AllowListSendersAdded", logs: logs, sub: sub}, nil +} + +func (_OnRamp *OnRampFilterer) WatchAllowListSendersAdded(opts *bind.WatchOpts, sink chan<- *OnRampAllowListSendersAdded, destChainSelector []uint64) (event.Subscription, error) { + + var destChainSelectorRule []interface{} + for _, destChainSelectorItem := range destChainSelector { + destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) + } + + logs, sub, err := _OnRamp.contract.WatchLogs(opts, "AllowListSendersAdded", destChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(OnRampAllowListSendersAdded) + if err := _OnRamp.contract.UnpackLog(event, "AllowListSendersAdded", 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 (_OnRamp *OnRampFilterer) ParseAllowListSendersAdded(log types.Log) (*OnRampAllowListSendersAdded, error) { + event := new(OnRampAllowListSendersAdded) + if err := _OnRamp.contract.UnpackLog(event, "AllowListSendersAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type OnRampAllowListSendersRemovedIterator struct { + Event *OnRampAllowListSendersRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *OnRampAllowListSendersRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(OnRampAllowListSendersRemoved) + 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(OnRampAllowListSendersRemoved) + 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 *OnRampAllowListSendersRemovedIterator) Error() error { + return it.fail +} + +func (it *OnRampAllowListSendersRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type OnRampAllowListSendersRemoved struct { + DestChainSelector uint64 + Senders []common.Address + Raw types.Log +} + +func (_OnRamp *OnRampFilterer) FilterAllowListSendersRemoved(opts *bind.FilterOpts, destChainSelector []uint64) (*OnRampAllowListSendersRemovedIterator, error) { + + var destChainSelectorRule []interface{} + for _, destChainSelectorItem := range destChainSelector { + destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) + } + + logs, sub, err := _OnRamp.contract.FilterLogs(opts, "AllowListSendersRemoved", destChainSelectorRule) + if err != nil { + return nil, err + } + return &OnRampAllowListSendersRemovedIterator{contract: _OnRamp.contract, event: "AllowListSendersRemoved", logs: logs, sub: sub}, nil +} + +func (_OnRamp *OnRampFilterer) WatchAllowListSendersRemoved(opts *bind.WatchOpts, sink chan<- *OnRampAllowListSendersRemoved, destChainSelector []uint64) (event.Subscription, error) { + + var destChainSelectorRule []interface{} + for _, destChainSelectorItem := range destChainSelector { + destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) + } + + logs, sub, err := _OnRamp.contract.WatchLogs(opts, "AllowListSendersRemoved", destChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(OnRampAllowListSendersRemoved) + if err := _OnRamp.contract.UnpackLog(event, "AllowListSendersRemoved", 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 (_OnRamp *OnRampFilterer) ParseAllowListSendersRemoved(log types.Log) (*OnRampAllowListSendersRemoved, error) { + event := new(OnRampAllowListSendersRemoved) + if err := _OnRamp.contract.UnpackLog(event, "AllowListSendersRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + type OnRampCCIPSendRequestedIterator struct { Event *OnRampCCIPSendRequested @@ -812,7 +1263,9 @@ func (it *OnRampDestChainConfigSetIterator) Close() error { type OnRampDestChainConfigSet struct { DestChainSelector uint64 - DestChainConfig OnRampDestChainConfig + SequenceNumber uint64 + Router common.Address + AllowListEnabled bool Raw types.Log } @@ -1415,8 +1868,20 @@ func (_OnRamp *OnRampFilterer) ParseOwnershipTransferred(log types.Log) (*OnRamp return event, nil } +type GetDestChainConfig struct { + SequenceNumber uint64 + AllowListEnabled bool + Router common.Address +} + func (_OnRamp *OnRamp) ParseLog(log types.Log) (generated.AbigenLog, error) { switch log.Topics[0] { + case _OnRamp.abi.Events["AllowListAdminSet"].ID: + return _OnRamp.ParseAllowListAdminSet(log) + case _OnRamp.abi.Events["AllowListSendersAdded"].ID: + return _OnRamp.ParseAllowListSendersAdded(log) + case _OnRamp.abi.Events["AllowListSendersRemoved"].ID: + return _OnRamp.ParseAllowListSendersRemoved(log) case _OnRamp.abi.Events["CCIPSendRequested"].ID: return _OnRamp.ParseCCIPSendRequested(log) case _OnRamp.abi.Events["ConfigSet"].ID: @@ -1437,16 +1902,28 @@ func (_OnRamp *OnRamp) ParseLog(log types.Log) (generated.AbigenLog, error) { } } +func (OnRampAllowListAdminSet) Topic() common.Hash { + return common.HexToHash("0xb8c9b44ae5b5e3afb195f67391d9ff50cb904f9c0fa5fd520e497a97c1aa5a1e") +} + +func (OnRampAllowListSendersAdded) Topic() common.Hash { + return common.HexToHash("0x330939f6eafe8bb516716892fe962ff19770570838686e6579dbc1cc51fc3281") +} + +func (OnRampAllowListSendersRemoved) Topic() common.Hash { + return common.HexToHash("0xc237ec1921f855ccd5e9a5af9733f2d58943a5a8501ec5988e305d7a4d421586") +} + func (OnRampCCIPSendRequested) Topic() common.Hash { return common.HexToHash("0xcae3d9f68a9ed33d0a770e9bcc6fc25d4041dd6391e6cd8015546547a3c93140") } func (OnRampConfigSet) Topic() common.Hash { - return common.HexToHash("0x2d8f19dc1cd01460c3367a09d2d424f2b1940ba7c886047edd078c7b77ea4558") + return common.HexToHash("0x23a1adf8ad7fad6091a4803227af2cee848c01a7c812404cade7c25636925e32") } func (OnRampDestChainConfigSet) Topic() common.Hash { - return common.HexToHash("0x324d4a7950b57da00ce533ad6697039be6281726a73da959d0ab3ff795181ec6") + return common.HexToHash("0xd5ad72bc37dc7a80a8b9b9df20500046fd7341adb1be2258a540466fdd7dcef5") } func (OnRampFeePaid) Topic() common.Hash { @@ -1470,6 +1947,12 @@ func (_OnRamp *OnRamp) Address() common.Address { } type OnRampInterface interface { + GetAllowedSendersList(opts *bind.CallOpts, destChainSelector uint64) ([]common.Address, error) + + GetDestChainConfig(opts *bind.CallOpts, destChainSelector uint64) (GetDestChainConfig, + + error) + GetDynamicConfig(opts *bind.CallOpts) (OnRampDynamicConfig, error) GetExpectedNextSequenceNumber(opts *bind.CallOpts, destChainSelector uint64) (uint64, error) @@ -1490,6 +1973,8 @@ type OnRampInterface interface { AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + ApplyAllowListUpdates(opts *bind.TransactOpts, allowListConfigArgsItems []OnRampAllowListConfigArgs) (*types.Transaction, error) + ApplyDestChainConfigUpdates(opts *bind.TransactOpts, destChainConfigArgs []OnRampDestChainConfigArgs) (*types.Transaction, error) ForwardFromRouter(opts *bind.TransactOpts, destChainSelector uint64, message ClientEVM2AnyMessage, feeTokenAmount *big.Int, originalSender common.Address) (*types.Transaction, error) @@ -1500,6 +1985,24 @@ type OnRampInterface interface { WithdrawFeeTokens(opts *bind.TransactOpts) (*types.Transaction, error) + FilterAllowListAdminSet(opts *bind.FilterOpts, allowListAdmin []common.Address) (*OnRampAllowListAdminSetIterator, error) + + WatchAllowListAdminSet(opts *bind.WatchOpts, sink chan<- *OnRampAllowListAdminSet, allowListAdmin []common.Address) (event.Subscription, error) + + ParseAllowListAdminSet(log types.Log) (*OnRampAllowListAdminSet, error) + + FilterAllowListSendersAdded(opts *bind.FilterOpts, destChainSelector []uint64) (*OnRampAllowListSendersAddedIterator, error) + + WatchAllowListSendersAdded(opts *bind.WatchOpts, sink chan<- *OnRampAllowListSendersAdded, destChainSelector []uint64) (event.Subscription, error) + + ParseAllowListSendersAdded(log types.Log) (*OnRampAllowListSendersAdded, error) + + FilterAllowListSendersRemoved(opts *bind.FilterOpts, destChainSelector []uint64) (*OnRampAllowListSendersRemovedIterator, error) + + WatchAllowListSendersRemoved(opts *bind.WatchOpts, sink chan<- *OnRampAllowListSendersRemoved, destChainSelector []uint64) (event.Subscription, error) + + ParseAllowListSendersRemoved(log types.Log) (*OnRampAllowListSendersRemoved, error) + FilterCCIPSendRequested(opts *bind.FilterOpts, destChainSelector []uint64) (*OnRampCCIPSendRequestedIterator, error) WatchCCIPSendRequested(opts *bind.WatchOpts, sink chan<- *OnRampCCIPSendRequested, destChainSelector []uint64) (event.Subscription, error) 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 688818f694..afbdd51c79 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 @@ -11,7 +11,7 @@ commit_store_helper: ../../../contracts/solc/v0.8.24/CommitStoreHelper/CommitSto ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin 09510a3f773f108a3c231e8d202835c845ded862d071ec54c4f89c12d868b8de evm_2_evm_offramp: ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOffRamp/EVM2EVMOffRamp.bin b0d77babbe635cd6ba04c2af049badc9e9d28a4b6ed6bb75f830ad902a618beb evm_2_evm_onramp: ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.24/EVM2EVMOnRamp/EVM2EVMOnRamp.bin 5c02c2b167946b3467636ff2bb58594cb4652fc63d8bdfee2488ed562e2a3e50 -fee_quoter: ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.abi ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.bin 95cdd54835272004bbe4a469b8529aa6f92ece2f903d914615010f1bf80a16c8 +fee_quoter: ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.abi ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.bin 920b7a293165fe8306fbed0cafd866bafc5943e8759486f7803bfbbd40309b6b lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin e6a8ec9e8faccb1da7d90e0f702ed72975964f97dc3222b54cfcca0a0ba3fea2 lock_release_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.bin e632b08be0fbd1d013e8b3a9d75293d0d532b83071c531ff2be1deec1fa48ec1 maybe_revert_message_receiver: ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.abi ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.bin d73956c26232ebcc4a5444429fa99cbefed960e323be9b5a24925885c2e477d5 @@ -24,7 +24,7 @@ multi_ocr3_helper: ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Help nonce_manager: ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.abi ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.bin 6f64e1083b356c06ee66b9138e398b9c97a4cd3e8c9ec38cf3010cebc79af536 ocr3_config_encoder: ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.abi ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.bin e21180898e1ad54a045ee20add85a2793c681425ea06f66d1a9e5cab128b6487 offramp: ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.abi ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.bin a3b8a9644f0d450dbf53d3371555dcc4084fb2eaf138a3797ef5cf73ed665bae -onramp: ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.abi ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.bin 13927b48bd09b9ab2c62143973c747f8c2e1ebc9f95f17a61ace67a68c71ec75 +onramp: ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.abi ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.bin 1ae9e3ebefc56d0382308c67c4ec066cdf3fa3eed2d31af8015d5d8db67f9c90 ping_pong_demo: ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.abi ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.bin c1c2f8a65c7ffd971899cae7fe62f2da57d09e936151e2b92163c4bebe699d6b price_registry: ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin e7781d600c1bb7aa4620106af7f6e146a109b97f4cb6a7d06c9e15773340ecb2 registry_module_owner_custom: ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.abi ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.bin 75be86323c227917a9bbc3f799d7ed02f92db546653a36db30ed0ebe64461353 diff --git a/integration-tests/ccip-tests/README.md b/integration-tests/ccip-tests/README.md index f7182338f7..39b8360428 100644 --- a/integration-tests/ccip-tests/README.md +++ b/integration-tests/ccip-tests/README.md @@ -35,21 +35,11 @@ For example, if you want to override the `Network` input in test and want to run ``` 3. Secrets - You also need to set some secrets. This is a mandatory step needed to run the tests. Please refer to [.testsecrets.example](./examples/.testsecrets.example) for the list of secrets and instruction how to set them up. - - The chainlink image and tag are required secrets for all the tests. + - The chainlink image is a required secret for all tests - If you are running tests in live networks like testnet and mainnet, you need to set the secrets (rpc urls and private keys) for the respective networks. - - If you are running tests in simulated networks no network specific secrets are required. - here is a sample secrets.toml file, for running the tests in simulated networks, with the chainlink image and tag set as secrets: **Please note that the secrets should NOT be checked in to the repo and should be kept locally.** -We recommend against changing the content of [secrets.toml.example](./testconfig/examples/secrets.toml.example). Please create a new file and set it as the secrets file. - -You can run this command to ignore any changes to the file. - -```bash -git update-index --skip-worktree -``` - ## Running the Tests There are two ways to run the tests: diff --git a/integration-tests/ccip-tests/load/helper.go b/integration-tests/ccip-tests/load/helper.go index 54d9fb2c11..dbb5ffc3e9 100644 --- a/integration-tests/ccip-tests/load/helper.go +++ b/integration-tests/ccip-tests/load/helper.go @@ -111,8 +111,15 @@ func (l *LoadArgs) scheduleForDest(destNetworkName string) []*wasp.Segment { // if found, use that frequency for the destination network // otherwise, use the default frequency if l.TestCfg.TestGroupInput.LoadProfile.FrequencyByDestination != nil { + l.lggr.Debug(). + Interface("FrequencyByDestination", l.TestCfg.TestGroupInput.LoadProfile.FrequencyByDestination). + Msg("LoadProfile provided") for networkName, freq := range l.TestCfg.TestGroupInput.LoadProfile.FrequencyByDestination { - if strings.Contains(destNetworkName, strings.ToLower(networkName)) { + l.lggr.Debug().Str("Destination", destNetworkName).Str("NetworkName", networkName).Msg("Checking frequency for destination") + if strings.EqualFold(destNetworkName, networkName) { + l.lggr.Info().Str("Destination", destNetworkName). + Ints64("RequestPerUnitTime", freq.RequestPerUnitTime). + Msg("Using frequency for destination") return WaspSchedule( freq.RequestPerUnitTime, l.TestCfg.TestGroupInput.LoadProfile.TestDuration, diff --git a/integration-tests/ccip-tests/testconfig/tomls/ccip-default.toml b/integration-tests/ccip-tests/testconfig/tomls/ccip-default.toml index 77dc97f77f..076c334e07 100644 --- a/integration-tests/ccip-tests/testconfig/tomls/ccip-default.toml +++ b/integration-tests/ccip-tests/testconfig/tomls/ccip-default.toml @@ -229,6 +229,10 @@ BlockHistorySize = 200 EIP1559FeeCapBufferBlocks = 0 """ +# Run by default using latest version from `ccip-develop` branch, override this value to use a specific version +[CCIP.Env.NewCLCluster.Common.ChainlinkImage] +version = "ccip-develop" + # the following configs are specific to each test type, smoke, load , chaos, etc... [CCIP.Groups] [CCIP.Groups.smoke] diff --git a/integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/baseline.toml b/integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/baseline.toml index 02ca2f4d9f..c404d3a0c0 100644 --- a/integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/baseline.toml +++ b/integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/baseline.toml @@ -7,8 +7,15 @@ ## ## make test_load_ccip testimage=.dkr.ecr..amazonaws.com/chainlink-ccip-tests:ccip-develop \ ## testname=TestLoadCCIPStableRequestTriggeringWithNetworkChaos \ -## override_toml=./testconfig/tomls/ccip-1.4-stress/baseline.toml \ -## secret_toml=./testconfig/tomls/secrets.toml +## override_toml=./testconfig/tomls/ccip-1.4-stress/baseline.toml + +## Adjust this value depending on what you want to test. +# Using releases and git tag requires changing the image name to the correct one in `~/.testsecrets`, e.g. +# E2E_TEST_CHAINLINK_IMAGE="public.ecr.aws/w0i8p0z9/chainlink-ccip" +# If you want to use a specific commit or a branch you need to switch to the internal ECR in `~/.testsecrets` +# E2E_TEST_CHAINLINK_IMAGE=".dkr.ecr..amazonaws.com/chainlink-ccip" +[CCIP.Env.NewCLCluster.Common.ChainlinkImage] +version = "2.14.0-ccip1.5.0" [CCIP] [CCIP.ContractVersions] @@ -22,7 +29,7 @@ CommitStore = '1.2.0' TTL = '10h' [CCIP.Env.Network] -selected_networks= ['PRIVATE-CHAIN-1', 'PRIVATE-CHAIN-2'] +selected_networks = ['PRIVATE-CHAIN-1', 'PRIVATE-CHAIN-2'] [CCIP.Env.Network.EVMNetworks.PRIVATE-CHAIN-1] evm_name = 'private-chain-1' @@ -152,7 +159,7 @@ BatchGasLimit = 11000000 TimeoutForPriceUpdate = '15m' NoOfTokensPerChain = 10 NoOfTokensWithDynamicPrice = 10 -DynamicPriceUpdateInterval ='15s' +DynamicPriceUpdateInterval = '15s' CCIPOwnerTokens = true [CCIP.Groups.load.LoadProfile] @@ -164,7 +171,7 @@ NetworkChaosDelay = '100ms' # to represent 20%, 60%, 15%, 5% of the total messages [CCIP.Groups.load.LoadProfile.MsgProfile] -Frequencies = [4,12,3,1] +Frequencies = [4, 12, 3, 1] [[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] MsgType = 'Token' diff --git a/integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/prod-testnet.toml b/integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/prod-testnet.toml index f8321584c8..917a739b18 100644 --- a/integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/prod-testnet.toml +++ b/integration-tests/ccip-tests/testconfig/tomls/ccip1.4-stress/prod-testnet.toml @@ -901,26 +901,20 @@ Data = """ """ [CCIP.Env] -TTL = '8h' +TTL = '2h' [CCIP.Env.Network] selected_networks = [ - 'ARBITRUM_SEPOLIA', - 'AVALANCHE_FUJI', - 'OPTIMISM_SEPOLIA', - 'BASE_SEPOLIA', - 'BSC_TESTNET', - 'WEMIX_TESTNET', - 'SEPOLIA', - 'POLYGON_AMOY', - 'KROMA_SEPOLIA', - 'BLAST_SEPOLIA' + 'AVALANCHE_FUJI', + 'OPTIMISM_SEPOLIA', + 'BASE_SEPOLIA', + 'SEPOLIA', ] [CCIP.Groups.load] NetworkPairs = [ - 'AVALANCHE_FUJI,SEPOLIA', - 'OPTIMISM_SEPOLIA,BASE_SEPOLIA' + 'AVALANCHE_FUJI,SEPOLIA', + 'OPTIMISM_SEPOLIA,BASE_SEPOLIA' ] BiDirectionalLane = true @@ -929,15 +923,21 @@ ExistingDeployment = true NoOfTokensPerChain = 1 +# 1msg/5sec = 12msg/min [CCIP.Groups.load.LoadProfile] -RequestPerUnitTime = [1] -TimeUnit = '5s' +RequestPerUnitTime = [12] +TimeUnit = '1m' TestDuration = '1h' TestRunName = 'v2.12.0-ccip1.4.16-load' +# There is slower exec rounds in Sepolia/Ethereum, therefore reducing the frequency +# 1msg/12sec = 5msg/min +[CCIP.Groups.load.LoadProfile.FrequencyByDestination.sepolia-testnet] +RequestPerUnitTime = [5] + # to represent 20%, 60%, 15%, 5% of the total messages [CCIP.Groups.load.LoadProfile.MsgProfile] -Frequencies = [4,12,3,1] +Frequencies = [4, 12, 3, 1] [[CCIP.Groups.load.LoadProfile.MsgProfile.MsgDetails]] MsgType = 'Token' diff --git a/integration-tests/ccip-tests/testsetups/test_env.go b/integration-tests/ccip-tests/testsetups/test_env.go index 85a5a10511..1eb7ebd452 100644 --- a/integration-tests/ccip-tests/testsetups/test_env.go +++ b/integration-tests/ccip-tests/testsetups/test_env.go @@ -490,8 +490,7 @@ func DeployEnvironments( "fullnameOverride": actions.NetworkName(network.Name), "image": map[string]interface{}{ "repository": "ghcr.io/foundry-rs/foundry", - "tag": "nightly-5ac78a9cd4b94dc53d1fe5e0f42372b28b5a7559", - // "tag": "nightly-ea2eff95b5c17edd3ffbdfc6daab5ce5cc80afc0", + "tag": "nightly-2442e7a5fc165d7d0b022aa8b9f09dcdf675157b", }, "anvil": map[string]interface{}{ "chainId": fmt.Sprintf("%d", network.ChainID), diff --git a/integration-tests/deployment/ccip/jobs.go b/integration-tests/deployment/ccip/jobs.go index f45fe4c553..923bda45f6 100644 --- a/integration-tests/deployment/ccip/jobs.go +++ b/integration-tests/deployment/ccip/jobs.go @@ -48,8 +48,17 @@ func NewCCIPJobSpecs(nodeIds []string, oc deployment.OffchainClient) (map[string if err != nil { return nil, err } + + // only set P2PV2Bootstrappers in the job spec if the node is a plugin node. + var p2pV2Bootstrappers []string + for _, chainConfig := range nodeChainConfigs.ChainConfigs { + if !chainConfig.Ocr2Config.IsBootstrap { + p2pV2Bootstrappers = bootstraps + break + } + } spec, err := validate.NewCCIPSpecToml(validate.SpecArgs{ - P2PV2Bootstrappers: bootstraps, + P2PV2Bootstrappers: p2pV2Bootstrappers, CapabilityVersion: CapabilityVersion, CapabilityLabelledName: CapabilityLabelledName, OCRKeyBundleIDs: map[string]string{ diff --git a/integration-tests/deployment/memory/environment.go b/integration-tests/deployment/memory/environment.go index d496d173c0..a6fa690135 100644 --- a/integration-tests/deployment/memory/environment.go +++ b/integration-tests/deployment/memory/environment.go @@ -71,15 +71,18 @@ func NewNodes(t *testing.T, logLevel zapcore.Level, chains map[uint64]deployment } } nodesByPeerID := make(map[string]Node) - ports := freeport.GetN(t, numNodes) - var existingNumBootstraps int + ports := freeport.GetN(t, numBootstraps+numNodes) + // bootstrap nodes must be separate nodes from plugin nodes, + // since we won't run a bootstrapper and a plugin oracle on the same + // chainlink node in production. + for i := 0; i < numBootstraps; i++ { + node := NewNode(t, ports[i], mchains, logLevel, true /* bootstrap */, registryConfig) + nodesByPeerID[node.Keys.PeerID.String()] = *node + // Note in real env, this ID is allocated by JD. + } for i := 0; i < numNodes; i++ { - bootstrap := false - if existingNumBootstraps < numBootstraps { - bootstrap = true - existingNumBootstraps++ - } - node := NewNode(t, ports[i], mchains, logLevel, bootstrap, registryConfig) + // grab port offset by numBootstraps, since above loop also takes some ports. + node := NewNode(t, ports[numBootstraps+i], mchains, logLevel, false /* bootstrap */, registryConfig) nodesByPeerID[node.Keys.PeerID.String()] = *node // Note in real env, this ID is allocated by JD. } diff --git a/integration-tests/go.mod b/integration-tests/go.mod index e20e98bcf9..f63a30fa31 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -258,7 +258,7 @@ require ( github.com/grafana/loki v1.6.2-0.20231215164305-b51b7d7b5503 // indirect github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4 // indirect github.com/grafana/pyroscope-go v1.1.1 // indirect - github.com/grafana/pyroscope-go/godeltaprof v0.1.6 // indirect + github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect @@ -314,7 +314,7 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/julienschmidt/httprouter v1.3.0 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect - github.com/klauspost/compress v1.17.7 // indirect + github.com/klauspost/compress v1.17.8 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 5789a6ccc2..a573b2c41f 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -806,8 +806,8 @@ github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4 h1:wQ0FnSeeb github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4/go.mod h1:f3JSoxBTPXX5ec4FxxeC19nTBSxoTz+cBgS3cYLMcr0= github.com/grafana/pyroscope-go v1.1.1 h1:PQoUU9oWtO3ve/fgIiklYuGilvsm8qaGhlY4Vw6MAcQ= github.com/grafana/pyroscope-go v1.1.1/go.mod h1:Mw26jU7jsL/KStNSGGuuVYdUq7Qghem5P8aXYXSXG88= -github.com/grafana/pyroscope-go/godeltaprof v0.1.6 h1:nEdZ8louGAplSvIJi1HVp7kWvFvdiiYg3COLlTwJiFo= -github.com/grafana/pyroscope-go/godeltaprof v0.1.6/go.mod h1:Tk376Nbldo4Cha9RgiU7ik8WKFkNpfds98aUzS8omLE= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd h1:PpuIBO5P3e9hpqBD0O/HjhShYuM6XE0i/lbE6J94kww= github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A= github.com/graph-gophers/dataloader v5.0.0+incompatible h1:R+yjsbrNq1Mo3aPG+Z/EKYrXrXXUNJHOgbRt+U6jOug= @@ -1034,9 +1034,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= -github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= -github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= +github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index ef077ba768..95d92451e0 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -234,7 +234,7 @@ require ( github.com/grafana/loki v1.6.2-0.20231215164305-b51b7d7b5503 // indirect github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4 // indirect github.com/grafana/pyroscope-go v1.1.1 // indirect - github.com/grafana/pyroscope-go/godeltaprof v0.1.6 // indirect + github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect @@ -291,7 +291,7 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/julienschmidt/httprouter v1.3.0 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect - github.com/klauspost/compress v1.17.7 // indirect + github.com/klauspost/compress v1.17.8 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 3e5d20d303..7ec40db665 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -780,8 +780,8 @@ github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4 h1:wQ0FnSeeb github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4/go.mod h1:f3JSoxBTPXX5ec4FxxeC19nTBSxoTz+cBgS3cYLMcr0= github.com/grafana/pyroscope-go v1.1.1 h1:PQoUU9oWtO3ve/fgIiklYuGilvsm8qaGhlY4Vw6MAcQ= github.com/grafana/pyroscope-go v1.1.1/go.mod h1:Mw26jU7jsL/KStNSGGuuVYdUq7Qghem5P8aXYXSXG88= -github.com/grafana/pyroscope-go/godeltaprof v0.1.6 h1:nEdZ8louGAplSvIJi1HVp7kWvFvdiiYg3COLlTwJiFo= -github.com/grafana/pyroscope-go/godeltaprof v0.1.6/go.mod h1:Tk376Nbldo4Cha9RgiU7ik8WKFkNpfds98aUzS8omLE= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd h1:PpuIBO5P3e9hpqBD0O/HjhShYuM6XE0i/lbE6J94kww= github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A= github.com/graph-gophers/dataloader v5.0.0+incompatible h1:R+yjsbrNq1Mo3aPG+Z/EKYrXrXXUNJHOgbRt+U6jOug= @@ -1006,9 +1006,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= -github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= -github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= +github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= diff --git a/integration-tests/web/sdk/client/client.go b/integration-tests/web/sdk/client/client.go index bf0bf49f1b..e13a02aa5a 100644 --- a/integration-tests/web/sdk/client/client.go +++ b/integration-tests/web/sdk/client/client.go @@ -48,12 +48,12 @@ type Credentials struct { } func New(baseURI string, creds Credentials) (Client, error) { - e := endpoints{ + ep := endpoints{ Sessions: baseURI + "/sessions", Query: baseURI + "/query", } c := &client{ - endpoints: e, + endpoints: ep, credentials: creds, }