Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Implement CCIPHome based on RMNHome #1459

Closed
wants to merge 36 commits into from
Closed

Conversation

RensR
Copy link
Collaborator

@RensR RensR commented Sep 23, 2024

No description provided.

Copy link
Contributor

github-actions bot commented Sep 23, 2024

LCOV of commit 0b64028 during Solidity Foundry #8333

Summary coverage rate:
  lines......: 93.6% (2205 of 2356 lines)
  functions..: 90.9% (418 of 460 functions)
  branches...: 88.5% (515 of 582 branches)

Files changed coverage rate: n/a

⛔ The code coverage is too low: 93.59. Expected at least 97.6.

Copy link
Contributor

@RyanRHall RyanRHall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At a high level, I feel like HomeBase might be trying to do too much. I think allowing a little bit of duplication b/t CCIPHome and RMNHome might bring down the overall complexity.

Ex could we allow both CCIPHome and RMNHome to define their own config storage and validation? That would allow us to remove the _validate...Config() callbacks. Doing that would also allow the setConfig functions to be strongly typed (instead of doing abi-decode on chain) which, which tends to be simpler for off chain to deal with.

We could still use HomeBase for revoking & promoting. Maybe versioning too?

contracts/src/v0.8/ccip/capability/RMNHome.sol Outdated Show resolved Hide resolved
contracts/src/v0.8/ccip/capability/HomeBase.sol Outdated Show resolved Hide resolved
contracts/src/v0.8/ccip/capability/HomeBase.sol Outdated Show resolved Hide resolved
contracts/src/v0.8/ccip/capability/CCIPHome.sol Outdated Show resolved Hide resolved

/// @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(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: natspec

Comment on lines 155 to 174
function getConfig(
bytes32 pluginKey,
bytes32 configDigest
) external view returns (VersionedConfig memory versionedConfig, bool ok) {
(StoredConfig memory storedConfig, bool configOK) = _getStoredConfig(pluginKey, configDigest);
if (configOK) {
return (
VersionedConfig({
version: storedConfig.version,
configDigest: storedConfig.configDigest,
staticConfig: abi.decode(storedConfig.staticConfig, (OCR3Config))
}),
true
);
}

return (versionedConfig, false);
}

function getAllConfigs(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: I find it a touch incongruent that getConfig() returns a valid/invalid boolean, while getAllConfigs() just returns empty structs if the configs are unset. I understand why _getStoredConfig() returns the bool so that the parent contract can decide how to handle such cases. In getConfig() I think it might be more consistent to just return empty.

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

function _validateStaticAndDynamicConfig(bytes memory encodedStaticConfig, bytes memory) internal view override {
Copy link
Contributor

@RyanRHall RyanRHall Sep 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there no dynamic config?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CCIP does not use config that is not part of the config digest (dynamic config) at this time

Comment on lines 119 to 120
bytes calldata encodedStaticConfig,
bytes calldata encodedDynamicConfig,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I usually try to avoid defining external function where data has to be pre-encoded in order to call the func. I know we're trying to make things generic here, but I would opt for making this an internal function and then allowing CCIPHome and RMNHome to call this function after abi.encoding their respective config structs.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would significantly add to the cost right? Is that worth it?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm I think you'd avoid the abi.decode in the validation hook that way, because you could validate before calling setSecondary. So I think similar gas wise but definitely more readable without the validation hook?

@RensR RensR changed the base branch from rmn-home- to ccip-develop September 23, 2024 21:24
@cl-sonarqube-production
Copy link

Quality Gate passed Quality Gate passed

Issues
0 New issues
0 Fixed issues
0 Accepted issues

Measures
0 Security Hotspots
No data about Coverage
No data about Duplication

See analysis details on SonarQube

// 1. promoteSecondaryAndRevokePrimary requires
// - blue digest to be the current secondary digest
// - green digest to be the zero digest
if (currentGreenDigest == newBlueDigest && newGreenDigest == ZERO_DIGEST) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm won't newBlueDigest never be equal to currentGreenDigest because the versions are different? E.g.

  1. Say count=1 and blue=nil, green=C (initial set). Digest of green is hash(.., C, 1)
  2. Now set blue=C, green=nil.
  3. newConfigVersion=2, hash(..,C,2) != hash(..,C,1)?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah maybe the fix is straightforward just need newBlueDigest to be newBlueDigestWithCurrentVersion

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the current design the versions don't change when you promote a config, I thought that was the desired effect?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants