Skip to content

Commit 40cc742

Browse files
tests: replace legacy changeset usage with new
Replace legacy changeset usage in the new changeset tests , spefiically the deploy mcms legacy changeset, now they use the new deploy changeset for mcms
1 parent 06e4c39 commit 40cc742

12 files changed

Lines changed: 288 additions & 154 deletions

File tree

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Package solanatest provides test utilities for Solana MCMS integration tests.
2+
package solanatest
3+
4+
import (
5+
"testing"
6+
7+
"github.com/smartcontractkit/chainlink-deployments-framework/datastore"
8+
mcmscontracts "github.com/smartcontractkit/chainlink-deployments-framework/engine/cld/contracts/mcms"
9+
"github.com/stretchr/testify/require"
10+
11+
"github.com/smartcontractkit/cld-changesets/internal/semvers"
12+
"github.com/smartcontractkit/cld-changesets/legacy/pkg/family/solana/solutils"
13+
)
14+
15+
// PreloadDatastoreWithMCMSPrograms seeds a datastore with canonical MCMS program IDs
16+
// for the given chain selector. Use with the mcms/changesets/deploy changeset.
17+
func PreloadDatastoreWithMCMSPrograms(t *testing.T, selector uint64) datastore.DataStore {
18+
t.Helper()
19+
20+
v := semvers.V1_0_0
21+
ds := datastore.NewMemoryDataStore()
22+
for _, entry := range []struct {
23+
addr string
24+
ct datastore.ContractType
25+
}{
26+
{solutils.GetProgramID(solutils.ProgAccessController), datastore.ContractType(mcmscontracts.AccessControllerProgram)},
27+
{solutils.GetProgramID(solutils.ProgMCM), datastore.ContractType(mcmscontracts.ManyChainMultisigProgram)},
28+
{solutils.GetProgramID(solutils.ProgTimelock), datastore.ContractType(mcmscontracts.RBACTimelockProgram)},
29+
} {
30+
require.NoError(t, ds.Addresses().Add(datastore.AddressRef{
31+
ChainSelector: selector,
32+
Address: entry.addr,
33+
Type: entry.ct,
34+
Version: &v,
35+
}))
36+
}
37+
38+
return ds.Seal()
39+
}

legacy/pkg/family/solana/testutils/preload.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,13 @@ func PreloadMCMS(t *testing.T, selector uint64) (string, map[string]string, *cld
8686

8787
return programsPath, programIDs, ab
8888
}
89+
90+
// LoadMCMSPrograms downloads MCMS Solana program artifacts once per test process
91+
// and returns the shared cache directory plus program IDs.
92+
func LoadMCMSPrograms(t *testing.T) (string, map[string]string) {
93+
t.Helper()
94+
95+
acquireSolanaTestIsolation(t)
96+
97+
return sharedMCMSPrograms(t)
98+
}

mcms/changesets/set-config/changeset_test.go

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414

1515
chain_selectors "github.com/smartcontractkit/chain-selectors"
1616
cldf_evm "github.com/smartcontractkit/chainlink-deployments-framework/chain/evm"
17+
"github.com/smartcontractkit/chainlink-deployments-framework/datastore"
1718
cldf "github.com/smartcontractkit/chainlink-deployments-framework/deployment"
1819
mcmscontracts "github.com/smartcontractkit/chainlink-deployments-framework/engine/cld/contracts/mcms"
1920
cldfproposalutils "github.com/smartcontractkit/chainlink-deployments-framework/engine/cld/mcms/proposalutils"
@@ -25,15 +26,14 @@ import (
2526

2627
"github.com/smartcontractkit/cld-changesets/datastore/refkey"
2728
"github.com/smartcontractkit/cld-changesets/internal/semvers"
28-
29-
// TODO: remove legacymcms import once remaining MCMS changesets are migrated out of legacy/mcms/changesets.
30-
legacymcms "github.com/smartcontractkit/cld-changesets/legacy/mcms/changesets"
31-
evmstate "github.com/smartcontractkit/cld-changesets/legacy/pkg/family/evm"
3229
solstate "github.com/smartcontractkit/cld-changesets/legacy/pkg/family/solana"
3330
solchangesets "github.com/smartcontractkit/cld-changesets/legacy/pkg/family/solana/changesets"
3431
soltestutils "github.com/smartcontractkit/cld-changesets/legacy/pkg/family/solana/testutils"
32+
"github.com/smartcontractkit/cld-changesets/mcms/changesets/deploy"
3533
setconfig "github.com/smartcontractkit/cld-changesets/mcms/changesets/set-config"
3634
_ "github.com/smartcontractkit/cld-changesets/mcms/changesets/set-config/all"
35+
_ "github.com/smartcontractkit/cld-changesets/mcms/evm/deploy"
36+
evmreaders "github.com/smartcontractkit/cld-changesets/mcms/evm/readers"
3737
)
3838

3939
//nolint:paralleltest // global mcm.SetProgramID state and shared Solana CTF container setup
@@ -241,14 +241,14 @@ func TestChangeset_EVM(t *testing.T) {
241241
},
242242
} {
243243
t.Run(tt.name, func(t *testing.T) {
244-
mcmsState, _ := evmMCMSChainState(t, rt, tt.selector)
244+
mcmsRefs, _ := loadEVMMCMSRefs(t, rt, tt.selector)
245245
originalCfg := cldftesthelpers.SingleGroupMCMS(t)
246246

247247
var targets []setconfig.ContractSetConfig
248248
var mcmsInput *cldf.MCMSTimelockProposalInput
249249
if tt.useMCMS {
250250
cfgCanceller := cldftesthelpers.SingleGroupMCMS(t)
251-
cfgCanceller.Signers = append(cfgCanceller.Signers, mcmsState.BypasserMcm.Address())
251+
cfgCanceller.Signers = append(cfgCanceller.Signers, mcmsRefs.Bypasser)
252252
cfgCanceller.Quorum = 2
253253
targets = []setconfig.ContractSetConfig{
254254
{
@@ -258,15 +258,15 @@ func TestChangeset_EVM(t *testing.T) {
258258
}
259259
mcmsInput = newMCMSInput(mcmstypes.TimelockActionBypass, "Set config proposal", "")
260260
} else {
261-
timelockAddress := mcmsState.Timelock.Address()
261+
timelockAddress := mcmsRefs.Timelock
262262

263263
cfgProposer := cldftesthelpers.SingleGroupMCMS(t)
264264
cfgProposer.Signers = append(cfgProposer.Signers, timelockAddress)
265265
cfgProposer.Quorum = 2
266266
cfgCanceller := cldftesthelpers.SingleGroupMCMS(t)
267267
cfgBypasser := cldftesthelpers.SingleGroupMCMS(t)
268268
cfgBypasser.Signers = append(cfgBypasser.Signers, timelockAddress)
269-
cfgBypasser.Signers = append(cfgBypasser.Signers, mcmsState.ProposerMcm.Address())
269+
cfgBypasser.Signers = append(cfgBypasser.Signers, mcmsRefs.Proposer)
270270
cfgBypasser.Quorum = 3
271271

272272
targets = mcmsTargets(tt.selector, cfgProposer, cfgCanceller, cfgBypasser)
@@ -286,17 +286,17 @@ func TestChangeset_EVM(t *testing.T) {
286286

287287
if tt.useMCMS {
288288
cfgCanceller := targets[0].Config
289-
newConf, err := inspector.GetConfig(t.Context(), mcmsState.CancellerMcm.Address().Hex())
289+
newConf, err := inspector.GetConfig(t.Context(), mcmsRefs.Canceller.Hex())
290290
require.NoError(t, err)
291291
require.ElementsMatch(t, cfgCanceller.Signers, newConf.Signers)
292292
require.Equal(t, cfgCanceller.Quorum, newConf.Quorum)
293293

294-
proposerConf, err := inspector.GetConfig(t.Context(), mcmsState.ProposerMcm.Address().Hex())
294+
proposerConf, err := inspector.GetConfig(t.Context(), mcmsRefs.Proposer.Hex())
295295
require.NoError(t, err)
296296
require.ElementsMatch(t, originalCfg.Signers, proposerConf.Signers)
297297
require.Equal(t, originalCfg.Quorum, proposerConf.Quorum)
298298

299-
bypasserConf, err := inspector.GetConfig(t.Context(), mcmsState.BypasserMcm.Address().Hex())
299+
bypasserConf, err := inspector.GetConfig(t.Context(), mcmsRefs.Bypasser.Hex())
300300
require.NoError(t, err)
301301
require.ElementsMatch(t, originalCfg.Signers, bypasserConf.Signers)
302302
require.Equal(t, originalCfg.Quorum, bypasserConf.Quorum)
@@ -308,17 +308,17 @@ func TestChangeset_EVM(t *testing.T) {
308308
cfgCanceller := targets[1].Config
309309
cfgBypasser := targets[2].Config
310310

311-
newConf, err := inspector.GetConfig(t.Context(), mcmsState.ProposerMcm.Address().Hex())
311+
newConf, err := inspector.GetConfig(t.Context(), mcmsRefs.Proposer.Hex())
312312
require.NoError(t, err)
313313
require.ElementsMatch(t, cfgProposer.Signers, newConf.Signers)
314314
require.Equal(t, cfgProposer.Quorum, newConf.Quorum)
315315

316-
newConf, err = inspector.GetConfig(t.Context(), mcmsState.BypasserMcm.Address().Hex())
316+
newConf, err = inspector.GetConfig(t.Context(), mcmsRefs.Bypasser.Hex())
317317
require.NoError(t, err)
318318
require.ElementsMatch(t, cfgBypasser.Signers, newConf.Signers)
319319
require.Equal(t, cfgBypasser.Quorum, newConf.Quorum)
320320

321-
newConf, err = inspector.GetConfig(t.Context(), mcmsState.CancellerMcm.Address().Hex())
321+
newConf, err = inspector.GetConfig(t.Context(), mcmsRefs.Canceller.Hex())
322322
require.NoError(t, err)
323323
require.ElementsMatch(t, cfgCanceller.Signers, newConf.Signers)
324324
require.Equal(t, cfgCanceller.Quorum, newConf.Quorum)
@@ -332,10 +332,10 @@ func TestChangeset_EVM_PartialTargets(t *testing.T) {
332332
selector := chain_selectors.TEST_90000001.Selector
333333

334334
rt := newEVMRuntimeWithDeploy(t, selector)
335-
mcmsState, chain := evmMCMSChainState(t, rt, selector)
335+
mcmsRefs, chain := loadEVMMCMSRefs(t, rt, selector)
336336

337337
cfgProposer := cldftesthelpers.SingleGroupMCMS(t)
338-
cfgProposer.Signers = append(cfgProposer.Signers, mcmsState.Timelock.Address())
338+
cfgProposer.Signers = append(cfgProposer.Signers, mcmsRefs.Timelock)
339339
cfgProposer.Quorum = 2
340340

341341
err := rt.Exec(
@@ -354,17 +354,17 @@ func TestChangeset_EVM_PartialTargets(t *testing.T) {
354354
inspector := evm.NewInspector(chain.Client)
355355
originalCfg := cldftesthelpers.SingleGroupMCMS(t)
356356

357-
proposerConf, err := inspector.GetConfig(t.Context(), mcmsState.ProposerMcm.Address().Hex())
357+
proposerConf, err := inspector.GetConfig(t.Context(), mcmsRefs.Proposer.Hex())
358358
require.NoError(t, err)
359359
require.ElementsMatch(t, cfgProposer.Signers, proposerConf.Signers)
360360
require.Equal(t, cfgProposer.Quorum, proposerConf.Quorum)
361361

362-
cancellerConf, err := inspector.GetConfig(t.Context(), mcmsState.CancellerMcm.Address().Hex())
362+
cancellerConf, err := inspector.GetConfig(t.Context(), mcmsRefs.Canceller.Hex())
363363
require.NoError(t, err)
364364
require.ElementsMatch(t, originalCfg.Signers, cancellerConf.Signers)
365365
require.Equal(t, originalCfg.Quorum, cancellerConf.Quorum)
366366

367-
bypasserConf, err := inspector.GetConfig(t.Context(), mcmsState.BypasserMcm.Address().Hex())
367+
bypasserConf, err := inspector.GetConfig(t.Context(), mcmsRefs.Bypasser.Hex())
368368
require.NoError(t, err)
369369
require.ElementsMatch(t, originalCfg.Signers, bypasserConf.Signers)
370370
require.Equal(t, originalCfg.Quorum, bypasserConf.Quorum)
@@ -386,21 +386,26 @@ func TestChangeset_EVM_Qualifier(t *testing.T) {
386386
rmnmcmsConfig.Qualifier = &rmnmcmsQualifier
387387

388388
err := rt.Exec(
389-
runtime.ChangesetTask(cldf.CreateLegacyChangeSet(legacymcms.DeployMCMSWithTimelockV2), map[uint64]cldfproposalutils.MCMSWithTimelockConfig{
390-
selector: cllccipConfig,
389+
runtime.ChangesetTask(deploy.Changeset{}, deploy.Input{
390+
ConfigByChain: map[uint64]cldfproposalutils.MCMSWithTimelockConfig{
391+
selector: cllccipConfig,
392+
},
391393
}),
392-
runtime.ChangesetTask(cldf.CreateLegacyChangeSet(legacymcms.DeployMCMSWithTimelockV2), map[uint64]cldfproposalutils.MCMSWithTimelockConfig{
393-
selector: rmnmcmsConfig,
394+
runtime.ChangesetTask(deploy.Changeset{}, deploy.Input{
395+
ConfigByChain: map[uint64]cldfproposalutils.MCMSWithTimelockConfig{
396+
selector: rmnmcmsConfig,
397+
},
394398
}),
395399
)
396400
require.NoError(t, err)
397401

398-
cllccipState, err := evmstate.MaybeLoadMCMSWithTimelockStateWithQualifier(rt.Environment(), []uint64{selector}, cllccipQualifier)
402+
cllccipTimelock, err := evmreaders.Reader{}.GetTimelockRef(rt.Environment(), selector, cldf.MCMSTimelockProposalInput{
403+
Qualifier: cllccipQualifier,
404+
})
399405
require.NoError(t, err)
400-
require.NotNil(t, cllccipState[selector])
401406

402407
cfgProposer := cldftesthelpers.SingleGroupMCMS(t)
403-
cfgProposer.Signers = append(cfgProposer.Signers, cllccipState[selector].Timelock.Address())
408+
cfgProposer.Signers = append(cfgProposer.Signers, common.HexToAddress(cllccipTimelock.Address))
404409
cfgProposer.Quorum = 2
405410

406411
for _, tt := range []struct {
@@ -479,9 +484,8 @@ func TestChangeset_Solana(t *testing.T) {
479484
rt := newSolanaRuntimeWithDeploy(t, selector)
480485
chain := rt.Environment().BlockChains.SolanaChains()[selector]
481486

482-
addrs, err := rt.State().AddressBook.AddressesForChain(selector)
483-
require.NoError(t, err)
484-
mcmsState, err := solstate.MaybeLoadMCMSWithTimelockChainState(chain, addrs)
487+
refs := rt.State().DataStore.Addresses().Filter(datastore.AddressRefByChainSelector(selector))
488+
mcmsState, err := solstate.MaybeLoadMCMSWithTimelockChainStateV2(refs)
485489
require.NoError(t, err)
486490
soltestutils.FundSignerPDAs(t, chain, mcmsState)
487491

mcms/changesets/set-config/helpers_test.go

Lines changed: 62 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,18 @@ import (
2525

2626
"github.com/smartcontractkit/cld-changesets/datastore/refkey"
2727
"github.com/smartcontractkit/cld-changesets/internal/semvers"
28+
"github.com/smartcontractkit/cld-changesets/internal/testutil/solanatest"
2829

29-
// TODO: remove legacymcms import once remaining MCMS changesets are migrated out of legacy/mcms/changesets.
30-
legacymcms "github.com/smartcontractkit/cld-changesets/legacy/mcms/changesets"
31-
evmstate "github.com/smartcontractkit/cld-changesets/legacy/pkg/family/evm"
3230
soltestutils "github.com/smartcontractkit/cld-changesets/legacy/pkg/family/solana/testutils"
31+
"github.com/smartcontractkit/cld-changesets/mcms/changesets/deploy"
3332
setconfig "github.com/smartcontractkit/cld-changesets/mcms/changesets/set-config"
3433
_ "github.com/smartcontractkit/cld-changesets/mcms/changesets/set-config/all"
34+
transfertotimelock "github.com/smartcontractkit/cld-changesets/mcms/changesets/transfer-to-timelock"
35+
_ "github.com/smartcontractkit/cld-changesets/mcms/evm/deploy"
36+
_ "github.com/smartcontractkit/cld-changesets/mcms/evm/readers"
37+
evmreaders "github.com/smartcontractkit/cld-changesets/mcms/evm/readers"
38+
_ "github.com/smartcontractkit/cld-changesets/mcms/evm/transfer-to-timelock"
39+
_ "github.com/smartcontractkit/cld-changesets/mcms/solana/deploy"
3540
)
3641

3742
func contractRef(chainSelector uint64, contractType cldf.ContractType, qualifier string) refkey.RefKey {
@@ -92,10 +97,9 @@ func deployEVMMCMSWithTimelock(t *testing.T, rt *runtime.Runtime, selectors ...u
9297
configByChain[selector] = cfg
9398
}
9499

95-
err := rt.Exec(
96-
// TODO: replace with new deploy changeset when available
97-
runtime.ChangesetTask(cldf.CreateLegacyChangeSet(legacymcms.DeployMCMSWithTimelockV2), configByChain),
98-
)
100+
err := rt.Exec(runtime.ChangesetTask(deploy.Changeset{}, deploy.Input{
101+
ConfigByChain: configByChain,
102+
}))
99103
require.NoError(t, err)
100104
}
101105

@@ -111,17 +115,25 @@ func newEVMRuntimeWithDeploy(t *testing.T, selectors ...uint64) *runtime.Runtime
111115
func transferEVMMCMSToTimelock(t *testing.T, rt *runtime.Runtime, selector uint64) {
112116
t.Helper()
113117

114-
mcmsState, _ := evmMCMSChainState(t, rt, selector)
118+
mcmsRefs, _ := loadEVMMCMSRefs(t, rt, selector)
115119

116120
err := rt.Exec(
117-
runtime.ChangesetTask(cldf.CreateLegacyChangeSet(legacymcms.TransferToMCMSWithTimelockV2), legacymcms.TransferToMCMSWithTimelockConfig{
118-
ContractsByChain: map[uint64][]common.Address{
119-
selector: {
120-
mcmsState.ProposerMcm.Address(),
121-
mcmsState.BypasserMcm.Address(),
122-
mcmsState.CancellerMcm.Address(),
121+
runtime.ChangesetTask(transfertotimelock.Changeset{}, transfertotimelock.Input{
122+
Cfg: transfertotimelock.Config{
123+
ContractsByChain: map[uint64][]common.Address{
124+
selector: {
125+
mcmsRefs.Proposer,
126+
mcmsRefs.Bypasser,
127+
mcmsRefs.Canceller,
128+
},
123129
},
124130
},
131+
MCMS: &cldf.MCMSTimelockProposalInput{
132+
TimelockAction: mcmstypes.TimelockActionBypass,
133+
ValidUntil: uint32(time.Now().Add(2 * time.Hour).UTC().Unix()), //nolint:gosec // test timestamp
134+
TimelockDelay: mcmstypes.NewDuration(0),
135+
Description: "transfer MCM to timelock",
136+
},
125137
}),
126138
runtime.SignAndExecuteProposalsTask([]*ecdsa.PrivateKey{cldftesthelpers.TestXXXMCMSSigner}),
127139
)
@@ -137,17 +149,41 @@ func newEVMRuntimeWithDeployAndTransfer(t *testing.T, selector uint64) *runtime.
137149
return rt
138150
}
139151

140-
func evmMCMSChainState(t *testing.T, rt *runtime.Runtime, selector uint64) (*evmstate.MCMSWithTimelockState, cldf_evm.Chain) {
152+
type evmMCMSRefs struct {
153+
Timelock common.Address
154+
Proposer common.Address
155+
Canceller common.Address
156+
Bypasser common.Address
157+
}
158+
159+
func loadEVMMCMSRefs(t *testing.T, rt *runtime.Runtime, selector uint64) (evmMCMSRefs, cldf_evm.Chain) {
141160
t.Helper()
142161

143-
chain := rt.Environment().BlockChains.EVMChains()[selector]
144-
addrs, err := rt.State().AddressBook.AddressesForChain(selector)
145-
require.NoError(t, err)
162+
env := rt.Environment()
163+
chain := env.BlockChains.EVMChains()[selector]
146164

147-
mcmsState, err := evmstate.MaybeLoadMCMSWithTimelockChainState(chain, addrs)
165+
reader := evmreaders.Reader{}
166+
timelock, err := reader.GetTimelockRef(env, selector, cldf.MCMSTimelockProposalInput{})
167+
require.NoError(t, err)
168+
proposer, err := reader.GetMCMSRef(env, selector, cldf.MCMSTimelockProposalInput{
169+
TimelockAction: mcmstypes.TimelockActionSchedule,
170+
})
171+
require.NoError(t, err)
172+
canceller, err := reader.GetMCMSRef(env, selector, cldf.MCMSTimelockProposalInput{
173+
TimelockAction: mcmstypes.TimelockActionCancel,
174+
})
175+
require.NoError(t, err)
176+
bypasser, err := reader.GetMCMSRef(env, selector, cldf.MCMSTimelockProposalInput{
177+
TimelockAction: mcmstypes.TimelockActionBypass,
178+
})
148179
require.NoError(t, err)
149180

150-
return mcmsState, chain
181+
return evmMCMSRefs{
182+
Timelock: common.HexToAddress(timelock.Address),
183+
Proposer: common.HexToAddress(proposer.Address),
184+
Canceller: common.HexToAddress(canceller.Address),
185+
Bypasser: common.HexToAddress(bypasser.Address),
186+
}, chain
151187
}
152188

153189
// newSolanaVerifyPreconditionsEnv builds a mock Solana environment for VerifyPreconditions
@@ -189,18 +225,20 @@ func newSolanaVerifyPreconditionsEnv(t *testing.T, selector uint64) cldf.Environ
189225
func newSolanaRuntimeWithDeploy(t *testing.T, selector uint64) *runtime.Runtime {
190226
t.Helper()
191227

192-
programsPath, programIDs, ab := soltestutils.PreloadMCMS(t, selector)
228+
programsPath, programIDs := soltestutils.LoadMCMSPrograms(t)
193229
rt, err := runtime.New(t.Context(), runtime.WithEnvOpts(
194230
environment.WithSolanaContainer(t, []uint64{selector}, programsPath, programIDs),
195-
environment.WithAddressBook(ab),
231+
environment.WithDatastore(solanatest.PreloadDatastoreWithMCMSPrograms(t, selector)),
196232
environment.WithLogger(logger.Test(t)),
197233
))
198234
require.NoError(t, err)
199235
require.Contains(t, rt.Environment().BlockChains.SolanaChains(), selector)
200236

201237
err = rt.Exec(
202-
runtime.ChangesetTask(cldf.CreateLegacyChangeSet(legacymcms.DeployMCMSWithTimelockV2), map[uint64]cldfproposalutils.MCMSWithTimelockConfig{
203-
selector: cldftesthelpers.SingleGroupTimelockConfig(t),
238+
runtime.ChangesetTask(deploy.Changeset{}, deploy.Input{
239+
ConfigByChain: map[uint64]cldfproposalutils.MCMSWithTimelockConfig{
240+
selector: cldftesthelpers.SingleGroupTimelockConfig(t),
241+
},
204242
}),
205243
)
206244
require.NoError(t, err)

0 commit comments

Comments
 (0)