Skip to content

Commit

Permalink
Use RMN changeset in e2e tests and refactor RMN remote changeset (#15664
Browse files Browse the repository at this point in the history
)

* Use RMN changeset in e2e tests and refactor RMN remote changeset

RMN remote changeset was changed to allow more flexibility when
configuring remote configs. Allowing a subset of chains to be updated in
a single changeset

* Address PR comments
  • Loading branch information
carte7000 authored Dec 13, 2024
1 parent 235d98d commit 000df4f
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 67 deletions.
38 changes: 25 additions & 13 deletions deployment/ccip/changeset/cs_update_rmn_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,10 +339,14 @@ func buildRMNRemotePerChain(e deployment.Environment, state CCIPOnChainState) ma
return timelocksPerChain
}

type RMNRemoteConfig struct {
Signers []rmn_remote.RMNRemoteSigner
F uint64
}

type SetRMNRemoteConfig struct {
HomeChainSelector uint64
Signers []rmn_remote.RMNRemoteSigner
F uint64
RMNRemoteConfigs map[uint64]RMNRemoteConfig
MCMSConfig *MCMSConfig
}

Expand All @@ -352,14 +356,21 @@ func (c SetRMNRemoteConfig) Validate() error {
return err
}

for i := 0; i < len(c.Signers)-1; i++ {
if c.Signers[i].NodeIndex >= c.Signers[i+1].NodeIndex {
return fmt.Errorf("signers must be in ascending order of nodeIndex")
for chain, config := range c.RMNRemoteConfigs {
err := deployment.IsValidChainSelector(chain)
if err != nil {
return err
}
}

if len(c.Signers) < 2*int(c.F)+1 {
return fmt.Errorf("signers count must greater than or equal to %d", 2*c.F+1)
for i := 0; i < len(config.Signers)-1; i++ {
if config.Signers[i].NodeIndex >= config.Signers[i+1].NodeIndex {
return fmt.Errorf("signers must be in ascending order of nodeIndex, but found %d >= %d", config.Signers[i].NodeIndex, config.Signers[i+1].NodeIndex)
}
}

if len(config.Signers) < 2*int(config.F)+1 {
return fmt.Errorf("signers count (%d) must be greater than or equal to %d", len(config.Signers), 2*config.F+1)
}
}

return nil
Expand Down Expand Up @@ -396,9 +407,10 @@ func NewSetRMNRemoteConfigChangeset(e deployment.Environment, config SetRMNRemot

rmnRemotePerChain := buildRMNRemotePerChain(e, state)
batches := make([]timelock.BatchChainOperation, 0)
for chain, remote := range rmnRemotePerChain {
if remote == nil {
continue
for chain, remoteConfig := range config.RMNRemoteConfigs {
remote, ok := rmnRemotePerChain[chain]
if !ok {
return deployment.ChangesetOutput{}, fmt.Errorf("RMNRemote contract not found for chain %d", chain)
}

currentVersionConfig, err := remote.GetVersionedConfig(nil)
Expand All @@ -408,8 +420,8 @@ func NewSetRMNRemoteConfigChangeset(e deployment.Environment, config SetRMNRemot

newConfig := rmn_remote.RMNRemoteConfig{
RmnHomeContractConfigDigest: activeConfig,
Signers: config.Signers,
F: config.F,
Signers: remoteConfig.Signers,
F: remoteConfig.F,
}

if reflect.DeepEqual(currentVersionConfig.Config, newConfig) {
Expand Down
13 changes: 11 additions & 2 deletions deployment/ccip/changeset/cs_update_rmn_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,19 @@ func updateRMNConfig(t *testing.T, tc updateRMNConfigTestCase) {
signers = append(signers, nop.ToRMNRemoteSigner())
}

remoteConfigs := make(map[uint64]RMNRemoteConfig, len(e.Env.Chains))
for _, chain := range e.Env.Chains {
remoteConfig := RMNRemoteConfig{
Signers: signers,
F: 0,
}

remoteConfigs[chain.Selector] = remoteConfig
}

setRemoteConfig := SetRMNRemoteConfig{
HomeChainSelector: e.HomeChainSel,
Signers: signers,
F: 0,
RMNRemoteConfigs: remoteConfigs,
MCMSConfig: mcmsConfig,
}

Expand Down
82 changes: 30 additions & 52 deletions integration-tests/smoke/ccip/ccip_rmn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,9 +258,6 @@ func runRmnTestCase(t *testing.T, tc rmnTestCase) {
require.NoError(t, err)
t.Logf("onChainState: %#v", onChainState)

homeChain, ok := envWithRMN.Env.Chains[envWithRMN.HomeChainSel]
require.True(t, ok)

homeChainState, ok := onChainState.Chains[envWithRMN.HomeChainSel]
require.True(t, ok)

Expand All @@ -274,23 +271,28 @@ func runRmnTestCase(t *testing.T, tc rmnTestCase) {
dynamicConfig := rmn_home.RMNHomeDynamicConfig{SourceChains: tc.pf.rmnHomeSourceChains, OffchainConfig: []byte{}}
t.Logf("Setting RMNHome candidate with staticConfig: %+v, dynamicConfig: %+v, current candidateDigest: %x",
staticConfig, dynamicConfig, allDigests.CandidateConfigDigest[:])
tx, err := homeChainState.RMNHome.SetCandidate(homeChain.DeployerKey, staticConfig, dynamicConfig, allDigests.CandidateConfigDigest)

candidateDigest, err := homeChainState.RMNHome.GetCandidateDigest(&bind.CallOpts{Context: ctx})
require.NoError(t, err)

_, err = deployment.ConfirmIfNoError(homeChain, tx, err)
_, err = changeset.NewSetRMNHomeCandidateConfigChangeset(envWithRMN.Env, changeset.SetRMNHomeCandidateConfig{
HomeChainSelector: envWithRMN.HomeChainSel,
RMNStaticConfig: staticConfig,
RMNDynamicConfig: dynamicConfig,
DigestToOverride: candidateDigest,
})
require.NoError(t, err)

candidateDigest, err := homeChainState.RMNHome.GetCandidateDigest(&bind.CallOpts{Context: ctx})
candidateDigest, err = homeChainState.RMNHome.GetCandidateDigest(&bind.CallOpts{Context: ctx})
require.NoError(t, err)

t.Logf("RMNHome candidateDigest after setting new candidate: %x", candidateDigest[:])
t.Logf("Promoting RMNHome candidate with candidateDigest: %x", candidateDigest[:])

tx, err = homeChainState.RMNHome.PromoteCandidateAndRevokeActive(
homeChain.DeployerKey, candidateDigest, allDigests.ActiveConfigDigest)
require.NoError(t, err)

_, err = deployment.ConfirmIfNoError(homeChain, tx, err)
_, err = changeset.NewPromoteCandidateConfigChangeset(envWithRMN.Env, changeset.PromoteRMNHomeCandidateConfig{
HomeChainSelector: envWithRMN.HomeChainSel,
DigestToPromote: candidateDigest,
})
require.NoError(t, err)

// check the active digest is the same as the candidate digest
Expand All @@ -300,7 +302,23 @@ func runRmnTestCase(t *testing.T, tc rmnTestCase) {
"active digest should be the same as the previously candidate digest after promotion, previous candidate: %x, active: %x",
candidateDigest[:], activeDigest[:])

tc.setRmnRemoteConfig(ctx, t, onChainState, activeDigest, envWithRMN)
rmnRemoteConfig := make(map[uint64]changeset.RMNRemoteConfig)
for _, remoteCfg := range tc.remoteChainsConfig {
selector := tc.pf.chainSelectors[remoteCfg.chainIdx]
if remoteCfg.f < 0 {
t.Fatalf("remoteCfg.f is negative: %d", remoteCfg.f)
}
rmnRemoteConfig[selector] = changeset.RMNRemoteConfig{
F: uint64(remoteCfg.f),
Signers: tc.pf.rmnRemoteSigners,
}
}

_, err = changeset.NewSetRMNRemoteConfigChangeset(envWithRMN.Env, changeset.SetRMNRemoteConfig{
HomeChainSelector: envWithRMN.HomeChainSel,
RMNRemoteConfigs: rmnRemoteConfig,
})
require.NoError(t, err)

tc.killMarkedRmnNodes(t, rmnCluster)

Expand Down Expand Up @@ -524,46 +542,6 @@ func (tc rmnTestCase) validate() error {
return nil
}

func (tc rmnTestCase) setRmnRemoteConfig(
ctx context.Context,
t *testing.T,
onChainState changeset.CCIPOnChainState,
activeDigest [32]byte,
envWithRMN changeset.DeployedEnv) {
for _, remoteCfg := range tc.remoteChainsConfig {
remoteSel := tc.pf.chainSelectors[remoteCfg.chainIdx]
chState, ok := onChainState.Chains[remoteSel]
require.True(t, ok)
if remoteCfg.f < 0 {
t.Fatalf("negative F: %d", remoteCfg.f)
}
rmnRemoteConfig := rmn_remote.RMNRemoteConfig{
RmnHomeContractConfigDigest: activeDigest,
Signers: tc.pf.rmnRemoteSigners,
F: uint64(remoteCfg.f),
}

chain := envWithRMN.Env.Chains[tc.pf.chainSelectors[remoteCfg.chainIdx]]

t.Logf("Setting RMNRemote config with RMNHome active digest: %x, cfg: %+v", activeDigest[:], rmnRemoteConfig)
tx2, err2 := chState.RMNRemote.SetConfig(chain.DeployerKey, rmnRemoteConfig)
require.NoError(t, err2)
_, err2 = deployment.ConfirmIfNoError(chain, tx2, err2)
require.NoError(t, err2)

// confirm the config is set correctly
config, err2 := chState.RMNRemote.GetVersionedConfig(&bind.CallOpts{Context: ctx})
require.NoError(t, err2)
require.Equalf(t,
activeDigest,
config.Config.RmnHomeContractConfigDigest,
"RMNRemote config digest should be the same as the active digest of RMNHome after setting, RMNHome active: %x, RMNRemote config: %x",
activeDigest[:], config.Config.RmnHomeContractConfigDigest[:])

t.Logf("RMNRemote config digest after setting: %x", config.Config.RmnHomeContractConfigDigest[:])
}
}

func (tc rmnTestCase) killMarkedRmnNodes(t *testing.T, rmnCluster devenv.RMNCluster) {
for _, n := range tc.rmnNodes {
if n.forceExit {
Expand Down

0 comments on commit 000df4f

Please sign in to comment.