Skip to content

Commit

Permalink
move CR to CCIPHome
Browse files Browse the repository at this point in the history
  • Loading branch information
RensR committed Sep 23, 2024
1 parent 488c5e6 commit 5309aa2
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 118 deletions.
44 changes: 21 additions & 23 deletions contracts/gas-snapshots/ccip.gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -809,34 +809,32 @@ PingPong_plumbing:test_OutOfOrderExecution_Success() (gas: 20310)
PingPong_plumbing:test_Pausing_Success() (gas: 17810)
PingPong_startPingPong:test_StartPingPong_With_OOO_Success() (gas: 162091)
PingPong_startPingPong:test_StartPingPong_With_Sequenced_Ordered_Success() (gas: 181509)
RMNHome_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_OnlyCapabilitiesRegistryCanCall_reverts() (gas: 9872)
RMNHome_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_success() (gas: 275003)
RMNHome_promoteSecondaryAndRevokePrimary:test_promoteSecondaryAndRevokePrimary_OnlyOwner_reverts() (gas: 10907)
RMNHome_promoteSecondaryAndRevokePrimary:test_promoteSecondaryAndRevokePrimary_OnlyOwner_reverts() (gas: 10953)
RMNHome_promoteSecondaryAndRevokePrimary:test_promoteSecondaryAndRevokePrimary_OnlyOwner_reverts() (gas: 10885)
RMNHome_promoteSecondaryAndRevokePrimary:test_promoteSecondaryAndRevokePrimary_OnlyOwner_reverts() (gas: 10997)
RMNHome_promoteSecondaryAndRevokePrimary:test_promoteSecondaryAndRevokePrimary_success() (gas: 209)
RMNHome_promoteSecondaryAndRevokePrimary:test_promoteSecondaryAndRevokePrimary_success() (gas: 209)
RMNHome_revokeSecondary:test_revokeSecondary_ConfigDigestMismatch_reverts() (gas: 19344)
RMNHome_revokeSecondary:test_revokeSecondary_ConfigDigestMismatch_reverts() (gas: 19366)
RMNHome_revokeSecondary:test_revokeSecondary_ConfigDigestMismatch_reverts() (gas: 19344)
RMNHome_revokeSecondary:test_revokeSecondary_OnlyOwner_reverts() (gas: 10890)
RMNHome_revokeSecondary:test_revokeSecondary_OnlyOwner_reverts() (gas: 10912)
RMNHome_revokeSecondary:test_revokeSecondary_OnlyOwner_reverts() (gas: 10956)
RMNHome_revokeSecondary:test_revokeSecondary_success() (gas: 27066)
RMNHome_revokeSecondary:test_revokeSecondary_success() (gas: 28966)
RMNHome_setDynamicConfig:test_setDynamicConfig_DigestNotFound_reverts() (gas: 33266)
RMNHome_setDynamicConfig:test_setDynamicConfig_MinObserversTooHigh_reverts() (gas: 20422)
RMNHome_setDynamicConfig:test_setDynamicConfig_OnlyOwner_reverts() (gas: 11834)
RMNHome_setDynamicConfig:test_setDynamicConfig_OnlyOwner_reverts() (gas: 15457)
RMNHome_setDynamicConfig:test_setDynamicConfig_success() (gas: 133123)
RMNHome_setDynamicConfig:test_setDynamicConfig_success() (gas: 63135)
RMNHome_setSecondary:test_setSecondary_DuplicateOffchainPublicKey_reverts() (gas: 20894)
RMNHome_setSecondary:test_setSecondary_DuplicatePeerId_reverts() (gas: 20688)
RMNHome_setSecondary:test_setSecondary_DuplicateSourceChain_reverts() (gas: 24455)
RMNHome_setSecondary:test_setSecondary_MinObserversTooHigh_reverts() (gas: 24894)
RMNHome_revokeSecondary:test_revokeSecondary_success() (gas: 27088)
RMNHome_revokeSecondary:test_revokeSecondary_success() (gas: 28943)
RMNHome_setDynamicConfig:test_setDynamicConfig_DigestNotFound_reverts() (gas: 33356)
RMNHome_setDynamicConfig:test_setDynamicConfig_MinObserversTooHigh_reverts() (gas: 20467)
RMNHome_setDynamicConfig:test_setDynamicConfig_OnlyOwner_reverts() (gas: 11812)
RMNHome_setDynamicConfig:test_setDynamicConfig_OnlyOwner_reverts() (gas: 15502)
RMNHome_setDynamicConfig:test_setDynamicConfig_success() (gas: 133259)
RMNHome_setDynamicConfig:test_setDynamicConfig_success() (gas: 63157)
RMNHome_setSecondary:test_setSecondary_DuplicateOffchainPublicKey_reverts() (gas: 20872)
RMNHome_setSecondary:test_setSecondary_DuplicatePeerId_reverts() (gas: 20666)
RMNHome_setSecondary:test_setSecondary_DuplicateSourceChain_reverts() (gas: 24457)
RMNHome_setSecondary:test_setSecondary_MinObserversTooHigh_reverts() (gas: 24896)
RMNHome_setSecondary:test_setSecondary_OnlyOwner_reverts() (gas: 12661)
RMNHome_setSecondary:test_setSecondary_OnlyOwner_reverts() (gas: 18070)
RMNHome_setSecondary:test_setSecondary_OutOfBoundsNodesLength_reverts() (gas: 186826)
RMNHome_setSecondary:test_setSecondary_OutOfBoundsObserverNodeIndex_reverts() (gas: 24599)
RMNHome_setSecondary:test_setSecondary_success() (gas: 282478)
RMNHome_setSecondary:test_setSecondary_success() (gas: 820692)
RMNHome_setSecondary:test_setSecondary_OnlyOwner_reverts() (gas: 18048)
RMNHome_setSecondary:test_setSecondary_OutOfBoundsNodesLength_reverts() (gas: 186804)
RMNHome_setSecondary:test_setSecondary_OutOfBoundsObserverNodeIndex_reverts() (gas: 24601)
RMNHome_setSecondary:test_setSecondary_success() (gas: 282455)
RMNHome_setSecondary:test_setSecondary_success() (gas: 820695)
RMNRemote_constructor:test_constructor_success() (gas: 8334)
RMNRemote_constructor:test_constructor_zeroChainSelector_reverts() (gas: 59165)
RMNRemote_curse:test_curse_AlreadyCursed_duplicateSubject_reverts() (gas: 154457)
Expand Down
69 changes: 63 additions & 6 deletions contracts/src/v0.8/ccip/capability/CCIPHome.sol
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.24;

import {ICapabilityConfiguration} from "../../keystone/interfaces/ICapabilityConfiguration.sol";
import {ICapabilitiesRegistry} from "./interfaces/ICapabilitiesRegistry.sol";

import {Internal} from "../libraries/Internal.sol";
import {HomeBase} from "./HomeBase.sol";

import {IERC165} from "../../vendor/openzeppelin-solidity/v5.0.2/contracts/interfaces/IERC165.sol";
import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableSet.sol";

/// @notice CCIPHome stores the configuration for the CCIP capability.
/// We have two classes of configuration: chain configuration and DON (in the CapabilitiesRegistry sense) configuration.
/// Each chain will have a single configuration which includes information like the router address.
/// Each CR DON will have up to four configurations: for each of (commit, exec), one blue and one green configuration.
/// This is done in order to achieve "blue-green" deployments.
contract CCIPHome is HomeBase {
contract CCIPHome is HomeBase, ICapabilityConfiguration, IERC165 {
using EnumerableSet for EnumerableSet.UintSet;

event ChainConfigRemoved(uint64 chainSelector);
Expand Down Expand Up @@ -86,20 +88,65 @@ contract CCIPHome is HomeBase {
/// @dev 256 is the hard limit due to the bit encoding of their indexes into a uint256.
uint256 internal constant MAX_NUM_ORACLES = 256;

/// @dev The canonical capabilities registry address.
address internal immutable i_capabilitiesRegistry;

/// @dev chain configuration for each chain that CCIP is deployed on.
mapping(uint64 chainSelector => ChainConfig chainConfig) private s_chainConfigurations;

/// @dev All chains that are configured.
EnumerableSet.UintSet private s_remoteChainSelectors;

constructor(address capabilitiesRegistry) HomeBase(capabilitiesRegistry) {}
constructor(address capabilitiesRegistry) {
if (capabilitiesRegistry == address(0)) {
revert ZeroAddressNotAllowed();
}
i_capabilitiesRegistry = capabilitiesRegistry;
}

/// @notice Returns the total number of chains configured.
/// @return The total number of chains configured.
function getNumChainConfigurations() external view returns (uint256) {
return s_remoteChainSelectors.length();
// ================================================================
// │ Capability Registry │
// ================================================================

/// @notice Returns the capabilities registry address.
/// @return The capabilities registry address.
function getCapabilityRegistry() external view returns (address) {
return i_capabilitiesRegistry;
}

/// @inheritdoc IERC165
function supportsInterface(bytes4 interfaceId) external pure override returns (bool) {
return interfaceId == type(ICapabilityConfiguration).interfaceId || interfaceId == type(IERC165).interfaceId;
}

/// @notice Called by the registry prior to the config being set for a particular DON.
/// @dev precondition Requires destination chain config to be set
function beforeCapabilityConfigSet(
bytes32[] calldata, // nodes
bytes calldata update,
uint64, // configCount
uint32 // donId
) external override {
if (msg.sender != i_capabilitiesRegistry) {
revert OnlyCapabilitiesRegistryCanCall();
}
(bool success, bytes memory errorData) = address(this).call(update);
if (!success) {
revert(string(errorData));
}
}

/// @inheritdoc ICapabilityConfiguration
/// @dev The CCIP capability will fetch the configuration needed directly from this contract.
/// The offchain syncer will call this function, so its important that it doesn't revert.
function getCapabilityConfiguration(uint32 /* donId */ ) external pure override returns (bytes memory configuration) {
return bytes("");
}

// ================================================================
// │ Getters │
// ================================================================

/// @notice The offchain code can use this to fetch an old config which might still be in use by some remotes. Use
/// in case one of the configs is too large to be returnable by one of the other getters.
/// @param configDigest The digest of the config to fetch.
Expand Down Expand Up @@ -150,6 +197,10 @@ contract CCIPHome is HomeBase {
return (primaryConfig, secondaryConfig);
}

// ================================================================
// │ Validation │
// ================================================================

function _validateStaticAndDynamicConfig(bytes memory encodedStaticConfig, bytes memory) internal view override {
OCR3Config memory cfg = abi.decode(encodedStaticConfig, (OCR3Config));

Expand Down Expand Up @@ -222,6 +273,12 @@ contract CCIPHome is HomeBase {
// │ Chain Configuration │
// ================================================================

/// @notice Returns the total number of chains configured.
/// @return The total number of chains configured.
function getNumChainConfigurations() external view returns (uint256) {
return s_remoteChainSelectors.length();
}

/// @notice Returns all the chain configurations.
/// @param pageIndex The page index.
/// @param pageSize The page size.
Expand Down
55 changes: 1 addition & 54 deletions contracts/src/v0.8/ccip/capability/HomeBase.sol
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.24;

import {ICapabilityConfiguration} from "../../keystone/interfaces/ICapabilityConfiguration.sol";
import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol";

import {OwnerIsCreator} from "../../shared/access/OwnerIsCreator.sol";

import {IERC165} from "../../vendor/openzeppelin-solidity/v5.0.2/contracts/interfaces/IERC165.sol";

abstract contract HomeBase is OwnerIsCreator, ITypeAndVersion, ICapabilityConfiguration, IERC165 {
abstract contract HomeBase is OwnerIsCreator, ITypeAndVersion {
event ConfigSet(StoredConfig versionedConfig);
event ConfigRevoked(bytes32 indexed configDigest);
event DynamicConfigSet(bytes32 indexed configDigest, bytes dynamicConfig);
Expand All @@ -27,9 +24,6 @@ abstract contract HomeBase is OwnerIsCreator, ITypeAndVersion, ICapabilityConfig
/// @notice Helper to identify the zero config digest with less casting.
bytes32 private constant ZERO_DIGEST = bytes32(uint256(0));

/// @dev The canonical capabilities registry address.
address internal immutable i_capabilitiesRegistry;

/// @notice This array holds the configs.
/// @dev Value i in this array is valid iff s_configs[i].configDigest != 0.
mapping(bytes32 pluginKey => StoredConfig[MAX_CONCURRENT_CONFIGS]) private s_configs;
Expand All @@ -46,59 +40,12 @@ abstract contract HomeBase is OwnerIsCreator, ITypeAndVersion, ICapabilityConfig
bytes dynamicConfig;
}

/// @param capabilitiesRegistry the canonical capabilities registry address.
constructor(address capabilitiesRegistry) {
if (capabilitiesRegistry == address(0)) {
revert ZeroAddressNotAllowed();
}
i_capabilitiesRegistry = capabilitiesRegistry;
}

function _validateStaticAndDynamicConfig(bytes memory staticConfig, bytes memory dynamicConfig) internal view virtual;

function _validateDynamicConfig(bytes memory staticConfig, bytes memory dynamicConfig) internal view virtual;

function _getConfigDigestPrefix() internal pure virtual returns (uint256);

// ================================================================
// │ Capability Registry │
// ================================================================

/// @notice Returns the capabilities registry address.
/// @return The capabilities registry address.
function getCapabilityRegistry() external view returns (address) {
return i_capabilitiesRegistry;
}

/// @inheritdoc IERC165
function supportsInterface(bytes4 interfaceId) external pure override returns (bool) {
return interfaceId == type(ICapabilityConfiguration).interfaceId || interfaceId == type(IERC165).interfaceId;
}

/// @notice Called by the registry prior to the config being set for a particular DON.
/// @dev precondition Requires destination chain config to be set
function beforeCapabilityConfigSet(
bytes32[] calldata, // nodes
bytes calldata update,
uint64, // configCount
uint32 // donId
) external override {
if (msg.sender != i_capabilitiesRegistry) {
revert OnlyCapabilitiesRegistryCanCall();
}
(bool success, bytes memory errorData) = address(this).call(update);
if (!success) {
revert(string(errorData));
}
}

/// @inheritdoc ICapabilityConfiguration
/// @dev The CCIP capability will fetch the configuration needed directly from this contract.
/// The offchain syncer will call this function, so its important that it doesn't revert.
function getCapabilityConfiguration(uint32 /* donId */ ) external pure override returns (bytes memory configuration) {
return bytes("");
}

// ================================================================
// │ Getters │
// ================================================================
Expand Down
2 changes: 0 additions & 2 deletions contracts/src/v0.8/ccip/capability/RMNHome.sol
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ contract RMNHome is HomeBase {

uint256 private constant PREFIX = 0x000b << (256 - 16); // 0x000b00..00

constructor() HomeBase(address(1)) {}

/// @notice The offchain code can use this to fetch an old config which might still be in use by some remotes. Use
/// in case one of the configs is too large to be returnable by one of the other getters.
/// @param configDigest The digest of the config to fetch.
Expand Down
61 changes: 30 additions & 31 deletions contracts/src/v0.8/ccip/test/capability/HomeBaseTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@ contract HomeBaseTest is Test {
bytes32 internal constant ZERO_DIGEST = bytes32(uint256(0));

HomeBaseHelper internal s_homeBase;
address internal constant CAPABILITIES_REGISTRY = address(1);

function setUp() public virtual {
s_homeBase = new HomeBaseHelper(CAPABILITIES_REGISTRY);
s_homeBase = new HomeBaseHelper();
}

uint256 private constant PREFIX_MASK = type(uint256).max << (256 - 16); // 0xFFFF00..00
Expand Down Expand Up @@ -169,32 +168,32 @@ contract RMNHome_promoteSecondaryAndRevokePrimary is HomeBaseTest {
}
}

contract RMNHome_beforeCapabilityConfigSet is HomeBaseTest {
function test_beforeCapabilityConfigSet_success() public {
vm.startPrank(CAPABILITIES_REGISTRY);

HomeBase.StoredConfig memory encodedConfig = HomeBase.StoredConfig({
configDigest: ZERO_DIGEST,
version: 1,
staticConfig: _getStaticConfig(),
dynamicConfig: _getDynamicConfig()
});
encodedConfig.configDigest = _getConfigDigest(encodedConfig.staticConfig, encodedConfig.version);

bytes memory callPayload = abi.encodeCall(
HomeBase.setSecondary, (DON_ID, encodedConfig.staticConfig, encodedConfig.dynamicConfig, ZERO_DIGEST)
);

vm.expectEmit();
emit HomeBase.ConfigSet(encodedConfig);

s_homeBase.beforeCapabilityConfigSet(new bytes32[](0), callPayload, 0, 0);
}

function test_beforeCapabilityConfigSet_OnlyCapabilitiesRegistryCanCall_reverts() public {
vm.startPrank(address(0));

vm.expectRevert(HomeBase.OnlyCapabilitiesRegistryCanCall.selector);
s_homeBase.beforeCapabilityConfigSet(new bytes32[](0), new bytes(0), 0, 0);
}
}
//contract RMNHome_beforeCapabilityConfigSet is HomeBaseTest {
// function test_beforeCapabilityConfigSet_success() public {
// vm.startPrank(CAPABILITIES_REGISTRY);
//
// HomeBase.StoredConfig memory encodedConfig = HomeBase.StoredConfig({
// configDigest: ZERO_DIGEST,
// version: 1,
// staticConfig: _getStaticConfig(),
// dynamicConfig: _getDynamicConfig()
// });
// encodedConfig.configDigest = _getConfigDigest(encodedConfig.staticConfig, encodedConfig.version);
//
// bytes memory callPayload = abi.encodeCall(
// HomeBase.setSecondary, (DON_ID, encodedConfig.staticConfig, encodedConfig.dynamicConfig, ZERO_DIGEST)
// );
//
// vm.expectEmit();
// emit HomeBase.ConfigSet(encodedConfig);
//
// s_homeBase.beforeCapabilityConfigSet(new bytes32[](0), callPayload, 0, 0);
// }
//
// function test_beforeCapabilityConfigSet_OnlyCapabilitiesRegistryCanCall_reverts() public {
// vm.startPrank(address(0));
//
// vm.expectRevert(HomeBase.OnlyCapabilitiesRegistryCanCall.selector);
// s_homeBase.beforeCapabilityConfigSet(new bytes32[](0), new bytes(0), 0, 0);
// }
//}
2 changes: 0 additions & 2 deletions contracts/src/v0.8/ccip/test/helpers/HomeBaseHelper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ contract HomeBaseHelper is HomeBase {

uint256 public constant PREFIX = 0x0c0c << (256 - 16);

constructor(address capabilitiesRegistry) HomeBase(capabilitiesRegistry) {}

function _validateStaticAndDynamicConfig(bytes memory, bytes memory) internal view override {}

function _validateDynamicConfig(bytes memory, bytes memory) internal view override {}
Expand Down

0 comments on commit 5309aa2

Please sign in to comment.