Skip to content

Commit

Permalink
add uncurse test case
Browse files Browse the repository at this point in the history
  • Loading branch information
dimkouv committed Dec 13, 2024
1 parent 20d6049 commit 50ceda8
Showing 1 changed file with 69 additions and 11 deletions.
80 changes: 69 additions & 11 deletions integration-tests/smoke/ccip/ccip_rmn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,11 +179,14 @@ func TestRMN_DifferentRmnNodesForDifferentChains(t *testing.T) {

func TestRMN_TwoMessagesOneSourceChainCursed(t *testing.T) {
runRmnTestCase(t, rmnTestCase{
name: "two messages, one source chain is cursed",
name: "two messages, one source chain is cursed the other chain was cursed but curse is revoked",
passIfNoCommitAfter: 15 * time.Second,
cursedSubjectsPerChain: map[int][]int{
chain1: {chain0},
},
revokedCursedSubjectsPerChain: map[int]map[int]time.Duration{
chain0: {globalCurse: 5 * time.Second}, // chain0 will be globally cursed and curse will be revoked later
},
homeChainConfig: homeChainConfig{
f: map[int]int{chain0: 1, chain1: 1},
},
Expand Down Expand Up @@ -309,6 +312,7 @@ func runRmnTestCase(t *testing.T, tc rmnTestCase) {
t.Logf("Sent all messages, seqNumCommit: %v seqNumExec: %v", seqNumCommit, seqNumExec)

tc.callContractsToCurseChains(ctx, t, onChainState, envWithRMN)
tc.callContractsToCurseAndRevokeCurse(ctx, t, onChainState, envWithRMN)

tc.enableOracles(ctx, t, envWithRMN, disabledNodes)

Expand Down Expand Up @@ -421,22 +425,25 @@ type rmnTestCase struct {
// If set to a positive value, the test will wait for that duration and will assert that commit report was not delivered.
passIfNoCommitAfter time.Duration
cursedSubjectsPerChain map[int][]int
waitForExec bool
homeChainConfig homeChainConfig
remoteChainsConfig []remoteChainConfig
rmnNodes []rmnNode
messagesToSend []messageToSend
// revokedCursedSubjectsPerChain is used to revoke this specific curses after a timer expires
revokedCursedSubjectsPerChain map[int]map[int]time.Duration // chainIdx -> subjectIdx -> timer to revoke
waitForExec bool
homeChainConfig homeChainConfig
remoteChainsConfig []remoteChainConfig
rmnNodes []rmnNode
messagesToSend []messageToSend

// populated fields after environment setup
pf testCasePopulatedFields
}

type testCasePopulatedFields struct {
chainSelectors []uint64
rmnHomeNodes []rmn_home.RMNHomeNode
rmnRemoteSigners []rmn_remote.RMNRemoteSigner
rmnHomeSourceChains []rmn_home.RMNHomeSourceChain
cursedSubjectsPerChainSel map[uint64][]uint64
chainSelectors []uint64
rmnHomeNodes []rmn_home.RMNHomeNode
rmnRemoteSigners []rmn_remote.RMNRemoteSigner
rmnHomeSourceChains []rmn_home.RMNHomeSourceChain
cursedSubjectsPerChainSel map[uint64][]uint64
revokedCursedSubjectsPerChainSel map[uint64]map[uint64]time.Duration
}

func (tc *rmnTestCase) populateFields(t *testing.T, envWithRMN changeset.DeployedEnv, rmnCluster devenv.RMNCluster) {
Expand Down Expand Up @@ -491,6 +498,19 @@ func (tc *rmnTestCase) populateFields(t *testing.T, envWithRMN changeset.Deploye
tc.pf.cursedSubjectsPerChainSel[chainSel] = append(tc.pf.cursedSubjectsPerChainSel[chainSel], subjSel)
}
}

// populate revoked cursed subjects with actual chain selectors
tc.pf.revokedCursedSubjectsPerChainSel = make(map[uint64]map[uint64]time.Duration)
for chainIdx, subjects := range tc.revokedCursedSubjectsPerChain {
chainSel := tc.pf.chainSelectors[chainIdx]
for subject, revokeAfter := range subjects {
subjSel := uint64(globalCurse)
if subject != globalCurse {
subjSel = tc.pf.chainSelectors[subject]
}
tc.pf.revokedCursedSubjectsPerChainSel[chainSel][subjSel] = revokeAfter
}
}
}

func (tc rmnTestCase) validate() error {
Expand Down Expand Up @@ -638,6 +658,44 @@ func (tc rmnTestCase) callContractsToCurseChains(ctx context.Context, t *testing
}
}

func (tc rmnTestCase) callContractsToCurseAndRevokeCurse(ctx context.Context, t *testing.T, onChainState changeset.CCIPOnChainState, envWithRMN changeset.DeployedEnv) {
for _, remoteCfg := range tc.remoteChainsConfig {
remoteSel := tc.pf.chainSelectors[remoteCfg.chainIdx]
chState, ok := onChainState.Chains[remoteSel]
require.True(t, ok)
chain, ok := envWithRMN.Env.Chains[remoteSel]
require.True(t, ok)

cursedSubjects, ok := tc.revokedCursedSubjectsPerChain[remoteCfg.chainIdx]
if !ok {
continue // nothing to curse on this chain
}

for subjectDescription, revokeAfter := range cursedSubjects {
subj := reader.GlobalCurseSubject
if subjectDescription != globalCurse {
subj = chainSelectorToBytes16(tc.pf.chainSelectors[subjectDescription])
}
t.Logf("cursing subject %d (%d)", subj, subjectDescription)
txCurse, errCurse := chState.RMNRemote.Curse(chain.DeployerKey, subj)
_, errConfirm := deployment.ConfirmIfNoError(chain, txCurse, errCurse)
require.NoError(t, errConfirm)

go func() {
<-time.NewTimer(revokeAfter).C
t.Logf("revoking curse on subject %d (%d)", subj, subjectDescription)
txUncurse, errUncurse := chState.RMNRemote.Uncurse(chain.DeployerKey, subj)
_, errConfirm = deployment.ConfirmIfNoError(chain, txUncurse, errUncurse)
require.NoError(t, errConfirm)
}()
}

cs, err := chState.RMNRemote.GetCursedSubjects(&bind.CallOpts{Context: ctx})
require.NoError(t, err)
t.Logf("Cursed subjects: %v", cs)
}
}

func (tc rmnTestCase) enableOracles(ctx context.Context, t *testing.T, envWithRMN changeset.DeployedEnv, nodeIDs []string) {
for _, n := range nodeIDs {
_, err := envWithRMN.Env.Offchain.EnableNode(ctx, &node.EnableNodeRequest{Id: n})
Expand Down

0 comments on commit 50ceda8

Please sign in to comment.