diff --git a/chains/solana/contracts/tests/config/mcm_config.go b/chains/solana/contracts/tests/config/mcm_config.go index c7e0efcc..a155b127 100644 --- a/chains/solana/contracts/tests/config/mcm_config.go +++ b/chains/solana/contracts/tests/config/mcm_config.go @@ -24,7 +24,7 @@ var ( } // [0,0,0,...'t','e','s','t','-','m','c','m',] - TestMsigNamePaddedBuffer = [32]byte{ + TestMsigName = [32]byte{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x6d, 0x63, 0x6d, } MaxNumSigners = 180 diff --git a/chains/solana/contracts/tests/config/timelock_config.go b/chains/solana/contracts/tests/config/timelock_config.go index 2e0e78e3..a49a46d2 100644 --- a/chains/solana/contracts/tests/config/timelock_config.go +++ b/chains/solana/contracts/tests/config/timelock_config.go @@ -8,7 +8,7 @@ var ( TimelockProgram = solana.MustPublicKeyFromBase58("LoCoNsJFuhTkSQjfdDfn3yuwqhSYoPujmviRHVCzsqn") // [0,0,0,...'t','e','s','t','-','t','i','m','e','l','o','c','k'] - TestTimelockIDPaddedBuffer = [32]byte{ + TestTimelockID = [32]byte{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x6f, 0x63, 0x6b, } NumAccountsPerRole = 63 // max 64 accounts per role(access list) * 4 - 1(to keep test accounts fits single funding) diff --git a/chains/solana/contracts/tests/mcms/mcm_set_config_test.go b/chains/solana/contracts/tests/mcms/mcm_set_config_test.go index 9a2440bb..73e2d0ee 100644 --- a/chains/solana/contracts/tests/mcms/mcm_set_config_test.go +++ b/chains/solana/contracts/tests/mcms/mcm_set_config_test.go @@ -39,7 +39,7 @@ func TestMcmSetConfig(t *testing.T) { solanaGoClient := testutils.DeployAllPrograms(t, testutils.PathToAnchorConfig, admin) // mcm name - testMsigName := config.TestMsigNamePaddedBuffer + testMsigName := config.TestMsigName // test mcm pdas multisigConfigPDA := mcms.GetConfigPDA(testMsigName) diff --git a/chains/solana/contracts/tests/mcms/mcm_set_root_execute_test.go b/chains/solana/contracts/tests/mcms/mcm_set_root_execute_test.go index 4b2f6862..46e66954 100644 --- a/chains/solana/contracts/tests/mcms/mcm_set_root_execute_test.go +++ b/chains/solana/contracts/tests/mcms/mcm_set_root_execute_test.go @@ -57,7 +57,7 @@ func TestMcmSetRootAndExecute(t *testing.T) { t.Run("mcm:general test cases", func(t *testing.T) { // mcm name - testMsigName := config.TestMsigNamePaddedBuffer + testMsigName := config.TestMsigName // test mcm pdas multisigConfigPDA := mcms.GetConfigPDA(testMsigName) @@ -95,7 +95,7 @@ func TestMcmSetRootAndExecute(t *testing.T) { IsWritable: true, }, { - PublicKey: mcms.GetSignerPDA(config.TestMsigNamePaddedBuffer), + PublicKey: mcms.GetSignerPDA(config.TestMsigName), IsSigner: false, IsWritable: true, }, @@ -149,7 +149,7 @@ func TestMcmSetRootAndExecute(t *testing.T) { IsWritable: true, }, { - PublicKey: mcms.GetSignerPDA(config.TestMsigNamePaddedBuffer), + PublicKey: mcms.GetSignerPDA(config.TestMsigName), IsSigner: false, IsWritable: true, }, diff --git a/chains/solana/contracts/tests/mcms/mcm_timelock_test.go b/chains/solana/contracts/tests/mcms/mcm_timelock_test.go index 44ec4d15..e90e4c82 100644 --- a/chains/solana/contracts/tests/mcms/mcm_timelock_test.go +++ b/chains/solana/contracts/tests/mcms/mcm_timelock_test.go @@ -67,7 +67,7 @@ func TestMcmWithTimelock(t *testing.T) { admin, config.DefaultCommitment) } // fund timelock signer - fundPDAIx := system.NewTransferInstruction(1*solana.LAMPORTS_PER_SOL, admin.PublicKey(), timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer)).Build() + fundPDAIx := system.NewTransferInstruction(1*solana.LAMPORTS_PER_SOL, admin.PublicKey(), timelockutil.GetSignerPDA(config.TestTimelockID)).Build() testutils.SendAndConfirm(ctx, t, solanaGoClient, []solana.Instruction{fundPDAIx}, admin, config.DefaultCommitment) @@ -260,9 +260,9 @@ func TestMcmWithTimelock(t *testing.T) { require.NoError(t, bin.UnmarshalBorsh(&programData, data.Bytes())) initTimelockIx, initTimelockErr := timelock.NewInitializeInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, config.MinDelay, - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), admin.PublicKey(), solana.SystemProgramID, config.TimelockProgram, @@ -278,7 +278,7 @@ func TestMcmWithTimelock(t *testing.T) { testutils.SendAndConfirm(ctx, t, solanaGoClient, []solana.Instruction{initTimelockIx}, admin, config.DefaultCommitment) var configAccount timelock.Config - err = common.GetAccountDataBorshInto(ctx, solanaGoClient, timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), config.DefaultCommitment, &configAccount) + err = common.GetAccountDataBorshInto(ctx, solanaGoClient, timelockutil.GetConfigPDA(config.TestTimelockID), config.DefaultCommitment, &configAccount) if err != nil { require.NoError(t, err, "failed to get account info") } @@ -299,7 +299,7 @@ func TestMcmWithTimelock(t *testing.T) { for _, msig := range roleMsigs.Multisigs { addresses = append(addresses, msig.SignerPDA) } - batchAddAccessIxs, batchAddAccessErr := timelockutil.GetBatchAddAccessIxs(ctx, config.TestTimelockIDPaddedBuffer, roleMsigs.AccessController.PublicKey(), role, addresses, admin, config.BatchAddAccessChunkSize, solanaGoClient) + batchAddAccessIxs, batchAddAccessErr := timelockutil.GetBatchAddAccessIxs(ctx, config.TestTimelockID, roleMsigs.AccessController.PublicKey(), role, addresses, admin, config.BatchAddAccessChunkSize, solanaGoClient) require.NoError(t, batchAddAccessErr) for _, ix := range batchAddAccessIxs { @@ -324,7 +324,7 @@ func TestMcmWithTimelock(t *testing.T) { t.Run(fmt.Sprintf(role.String(), mcms.UnpadString32(msig.PaddedName)), func(t *testing.T) { ix, transferOwnershipErr := mcm.NewTransferOwnershipInstruction( msig.PaddedName, - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), // new proposed owner + timelockutil.GetSignerPDA(config.TestTimelockID), // new proposed owner msig.ConfigPDA, admin.PublicKey(), ).ValidateAndBuild() @@ -338,18 +338,19 @@ func TestMcmWithTimelock(t *testing.T) { require.NoError(t, err, "failed to get account info") } require.Equal(t, admin.PublicKey(), configAccount.Owner) - require.Equal(t, timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), configAccount.ProposedOwner) + require.Equal(t, timelockutil.GetSignerPDA(config.TestTimelockID), configAccount.ProposedOwner) acceptOwnershipIx, acceptOwnershipixErr := mcm.NewAcceptOwnershipInstruction( msig.PaddedName, msig.ConfigPDA, - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetSignerPDA(config.TestTimelockID), ).ValidateAndBuild() require.NoError(t, acceptOwnershipixErr) salt, sErr := mcms.SimpleSalt() require.NoError(t, sErr) acceptOwnershipOp := timelockutil.Operation{ + TimelockID: config.TestTimelockID, Predecessor: config.TimelockEmptyOpID, Salt: salt, Delay: uint64(1), @@ -360,18 +361,18 @@ func TestMcmWithTimelock(t *testing.T) { id := acceptOwnershipOp.OperationID() operationPDA := acceptOwnershipOp.OperationPDA() - ixs, ierr := timelockutil.GetPreloadOperationIxs(config.TestTimelockIDPaddedBuffer, acceptOwnershipOp, admin.PublicKey()) + ixs, ierr := timelockutil.GetPreloadOperationIxs(config.TestTimelockID, acceptOwnershipOp, admin.PublicKey()) require.NoError(t, ierr) for _, ix := range ixs { testutils.SendAndConfirm(ctx, t, solanaGoClient, []solana.Instruction{ix}, admin, config.DefaultCommitment) } scheduleBatchIx, scErr := timelock.NewScheduleBatchInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, acceptOwnershipOp.OperationID(), acceptOwnershipOp.Delay, operationPDA, - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), roleMsigs.AccessController.PublicKey(), admin.PublicKey(), ).ValidateAndBuild() @@ -410,11 +411,11 @@ func TestMcmWithTimelock(t *testing.T) { ) bypassExeIx := timelock.NewBypasserExecuteBatchInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, acceptOwnershipOp.OperationID(), acceptOwnershipOp.OperationPDA(), - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), + timelockutil.GetSignerPDA(config.TestTimelockID), roleMsigs.AccessController.PublicKey(), admin.PublicKey(), // bypass execute with admin previledges ) @@ -442,7 +443,7 @@ func TestMcmWithTimelock(t *testing.T) { if err != nil { require.NoError(t, err, "failed to get account info") } - require.Equal(t, timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), configAccount.Owner) + require.Equal(t, timelockutil.GetSignerPDA(config.TestTimelockID), configAccount.Owner) require.Equal(t, solana.PublicKey{}, configAccount.ProposedOwner) }) } @@ -507,7 +508,7 @@ func TestMcmWithTimelock(t *testing.T) { require.Equal(t, 0, rInitBal) // mint authority to timelock - authIx, aErr := tokens.SetTokenMintAuthority(v.tokenProgram, timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), mint, admin.PublicKey()) + authIx, aErr := tokens.SetTokenMintAuthority(v.tokenProgram, timelockutil.GetSignerPDA(config.TestTimelockID), mint, admin.PublicKey()) require.NoError(t, aErr) testutils.SendAndConfirm(ctx, t, solanaGoClient, []solana.Instruction{authIx}, admin, config.DefaultCommitment) @@ -517,6 +518,7 @@ func TestMcmWithTimelock(t *testing.T) { salt, sErr := mcms.SimpleSalt() require.NoError(t, sErr) opToSchedule := timelockutil.Operation{ + TimelockID: config.TestTimelockID, Predecessor: config.TimelockEmptyOpID, // no predecessor Salt: salt, Delay: uint64(1), @@ -524,14 +526,14 @@ func TestMcmWithTimelock(t *testing.T) { for i := 0; i < numMintIxs; i++ { // timelock signer can mint token (transferred authority) - ix, mIxErr := tokens.MintTo(1*solana.LAMPORTS_PER_SOL, v.tokenProgram, mint, rAta, timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer)) + ix, mIxErr := tokens.MintTo(1*solana.LAMPORTS_PER_SOL, v.tokenProgram, mint, rAta, timelockutil.GetSignerPDA(config.TestTimelockID)) require.NoError(t, mIxErr) // add instruction to timelock operation opToSchedule.AddInstruction(ix, []solana.PublicKey{v.tokenProgram}) } - ixs, ierr := timelockutil.GetPreloadOperationIxs(config.TestTimelockIDPaddedBuffer, opToSchedule, admin.PublicKey()) + ixs, ierr := timelockutil.GetPreloadOperationIxs(config.TestTimelockID, opToSchedule, admin.PublicKey()) require.NoError(t, ierr) for _, ix := range ixs { testutils.SendAndConfirm(ctx, t, solanaGoClient, []solana.Instruction{ix}, admin, config.DefaultCommitment) @@ -539,11 +541,11 @@ func TestMcmWithTimelock(t *testing.T) { // Schedule the operation scheduleIx, scErr := timelock.NewScheduleBatchInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, opToSchedule.OperationID(), opToSchedule.Delay, opToSchedule.OperationPDA(), - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), msigs[timelock.Proposer_Role].AccessController.PublicKey(), proposerMsig.SignerPDA, // msig signer since we're going to run this ix with mcm::execute ).ValidateAndBuild() @@ -648,7 +650,7 @@ func TestMcmWithTimelock(t *testing.T) { t.Run("mcm:execute -> timelock::schedule_batch", func(t *testing.T) { t.Run("check if timelock config is correct", func(t *testing.T) { - info, infoErr := solanaGoClient.GetAccountInfoWithOpts(ctx, timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), &rpc.GetAccountInfoOpts{ + info, infoErr := solanaGoClient.GetAccountInfoWithOpts(ctx, timelockutil.GetConfigPDA(config.TestTimelockID), &rpc.GetAccountInfoOpts{ Commitment: config.DefaultCommitment, }) require.NoError(t, infoErr) @@ -738,12 +740,12 @@ func TestMcmWithTimelock(t *testing.T) { t.Run("timelock worker -> timelock::execute_batch", func(t *testing.T) { ix := timelock.NewExecuteBatchInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, opToSchedule.OperationID(), opToSchedule.OperationPDA(), config.TimelockEmptyOpID, - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), + timelockutil.GetSignerPDA(config.TestTimelockID), msigs[timelock.Executor_Role].AccessController.PublicKey(), admin.PublicKey(), // timelock worker authority ) @@ -821,7 +823,7 @@ func TestMcmWithTimelock(t *testing.T) { ) require.NoError(t, cterr) - authIx, aterr := tokens.SetTokenMintAuthority(tokenProgram, timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), mint, admin.PublicKey()) + authIx, aterr := tokens.SetTokenMintAuthority(tokenProgram, timelockutil.GetSignerPDA(config.TestTimelockID), mint, admin.PublicKey()) require.NoError(t, aterr) setupIxs := append(createTokenIxs, authIx) @@ -834,15 +836,16 @@ func TestMcmWithTimelock(t *testing.T) { treasury, kerr := solana.NewRandomPrivateKey() require.NoError(t, kerr) - ix1, treasuryATA, taerr := tokens.CreateAssociatedTokenAccount(tokenProgram, mint, treasury.PublicKey(), timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer)) + ix1, treasuryATA, taerr := tokens.CreateAssociatedTokenAccount(tokenProgram, mint, treasury.PublicKey(), timelockutil.GetSignerPDA(config.TestTimelockID)) require.NoError(t, taerr) - ix2, tmerr := tokens.MintTo(1000*solana.LAMPORTS_PER_SOL, tokenProgram, mint, treasuryATA, timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer)) + ix2, tmerr := tokens.MintTo(1000*solana.LAMPORTS_PER_SOL, tokenProgram, mint, treasuryATA, timelockutil.GetSignerPDA(config.TestTimelockID)) require.NoError(t, tmerr) salt1, serr := mcms.SimpleSalt() require.NoError(t, serr) op1 := timelockutil.Operation{ + TimelockID: config.TestTimelockID, Predecessor: config.TimelockEmptyOpID, // no predecessor Salt: salt1, Delay: uint64(1), @@ -862,25 +865,26 @@ func TestMcmWithTimelock(t *testing.T) { ix3, team1ATA, t1cerr := tokens.CreateAssociatedTokenAccount( tokenProgram, mint, team1.PublicKey(), - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetSignerPDA(config.TestTimelockID), ) require.NoError(t, t1cerr) ix4, team2ATA, t2cerr := tokens.CreateAssociatedTokenAccount( tokenProgram, mint, team2.PublicKey(), - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetSignerPDA(config.TestTimelockID), ) require.NoError(t, t2cerr) ix5, team3ATA, t3cerr := tokens.CreateAssociatedTokenAccount( tokenProgram, mint, team3.PublicKey(), - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetSignerPDA(config.TestTimelockID), ) require.NoError(t, t3cerr) salt2, s2err := mcms.SimpleSalt() require.NoError(t, s2err) op2 := timelockutil.Operation{ + TimelockID: config.TestTimelockID, Predecessor: op1.OperationID(), // must happen after initial mint Salt: salt2, Delay: uint64(1), @@ -892,17 +896,18 @@ func TestMcmWithTimelock(t *testing.T) { ////////////////////////////////////////////////////////////// // Timelock Operation 3 - Schedule team token distribution // ////////////////////////////////////////////////////////////// - ix6, i6err := tokens.TokenTransferChecked(100*solana.LAMPORTS_PER_SOL, 9, tokenProgram, treasuryATA, mint, team1ATA, timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), []solana.PublicKey{}) + ix6, i6err := tokens.TokenTransferChecked(100*solana.LAMPORTS_PER_SOL, 9, tokenProgram, treasuryATA, mint, team1ATA, timelockutil.GetSignerPDA(config.TestTimelockID), []solana.PublicKey{}) require.NoError(t, i6err) - ix7, i7err := tokens.TokenTransferChecked(200*solana.LAMPORTS_PER_SOL, 9, tokenProgram, treasuryATA, mint, team2ATA, timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), []solana.PublicKey{}) + ix7, i7err := tokens.TokenTransferChecked(200*solana.LAMPORTS_PER_SOL, 9, tokenProgram, treasuryATA, mint, team2ATA, timelockutil.GetSignerPDA(config.TestTimelockID), []solana.PublicKey{}) require.NoError(t, i7err) - ix8, i8err := tokens.TokenTransferChecked(300*solana.LAMPORTS_PER_SOL, 9, tokenProgram, treasuryATA, mint, team3ATA, timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), []solana.PublicKey{}) + ix8, i8err := tokens.TokenTransferChecked(300*solana.LAMPORTS_PER_SOL, 9, tokenProgram, treasuryATA, mint, team3ATA, timelockutil.GetSignerPDA(config.TestTimelockID), []solana.PublicKey{}) require.NoError(t, i8err) // add all team distribution instructions salt3, s3err := mcms.SimpleSalt() require.NoError(t, s3err) op3 := timelockutil.Operation{ + TimelockID: config.TestTimelockID, Predecessor: op2.OperationID(), // must happen after ata creation Salt: salt3, Delay: uint64(1), @@ -923,18 +928,18 @@ func TestMcmWithTimelock(t *testing.T) { for i, op := range timelockOps { t.Run(fmt.Sprintf("prepare mcm op node %d with timelock::schedule_batch ix", i), func(t *testing.T) { - ixs, ierr := timelockutil.GetPreloadOperationIxs(config.TestTimelockIDPaddedBuffer, op, admin.PublicKey()) + ixs, ierr := timelockutil.GetPreloadOperationIxs(config.TestTimelockID, op, admin.PublicKey()) require.NoError(t, ierr) for _, ix := range ixs { testutils.SendAndConfirm(ctx, t, solanaGoClient, []solana.Instruction{ix}, admin, config.DefaultCommitment) } scheduleOpIx, scErr := timelock.NewScheduleBatchInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, op.OperationID(), op.Delay, op.OperationPDA(), - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), msigs[timelock.Proposer_Role].AccessController.PublicKey(), proposerMsig.SignerPDA, ).ValidateAndBuild() @@ -1114,10 +1119,10 @@ func TestMcmWithTimelock(t *testing.T) { canceller := msigs[timelock.Canceller_Role].GetAnyMultisig() cancelIx, cerr := timelock.NewCancelInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, op3.OperationID(), op3.OperationPDA(), - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), msigs[timelock.Canceller_Role].AccessController.PublicKey(), canceller.SignerPDA, ).ValidateAndBuild() @@ -1235,17 +1240,18 @@ func TestMcmWithTimelock(t *testing.T) { t.Run("create new operation with corrected amounts", func(t *testing.T) { // Create corrected transfer instructions with new amounts - ix1, i1err := tokens.TokenTransferChecked(150*solana.LAMPORTS_PER_SOL, 9, tokenProgram, treasuryATA, mint, team1ATA, timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), []solana.PublicKey{}) + ix1, i1err := tokens.TokenTransferChecked(150*solana.LAMPORTS_PER_SOL, 9, tokenProgram, treasuryATA, mint, team1ATA, timelockutil.GetSignerPDA(config.TestTimelockID), []solana.PublicKey{}) require.NoError(t, i1err) - ix2, i2err := tokens.TokenTransferChecked(150*solana.LAMPORTS_PER_SOL, 9, tokenProgram, treasuryATA, mint, team2ATA, timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), []solana.PublicKey{}) + ix2, i2err := tokens.TokenTransferChecked(150*solana.LAMPORTS_PER_SOL, 9, tokenProgram, treasuryATA, mint, team2ATA, timelockutil.GetSignerPDA(config.TestTimelockID), []solana.PublicKey{}) require.NoError(t, i2err) - ix3, i3err := tokens.TokenTransferChecked(100*solana.LAMPORTS_PER_SOL, 9, tokenProgram, treasuryATA, mint, team3ATA, timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), []solana.PublicKey{}) + ix3, i3err := tokens.TokenTransferChecked(100*solana.LAMPORTS_PER_SOL, 9, tokenProgram, treasuryATA, mint, team3ATA, timelockutil.GetSignerPDA(config.TestTimelockID), []solana.PublicKey{}) require.NoError(t, i3err) // Create new operation salt, serr := mcms.SimpleSalt() require.NoError(t, serr) newOp3 = timelockutil.Operation{ + TimelockID: config.TestTimelockID, Predecessor: op2.OperationID(), Salt: salt, Delay: uint64(1), @@ -1255,7 +1261,7 @@ func TestMcmWithTimelock(t *testing.T) { newOp3.AddInstruction(ix2, []solana.PublicKey{tokenProgram}) newOp3.AddInstruction(ix3, []solana.PublicKey{tokenProgram}) - ixs, perr := timelockutil.GetPreloadOperationIxs(config.TestTimelockIDPaddedBuffer, newOp3, admin.PublicKey()) + ixs, perr := timelockutil.GetPreloadOperationIxs(config.TestTimelockID, newOp3, admin.PublicKey()) require.NoError(t, perr) for _, ix := range ixs { testutils.SendAndConfirm(ctx, t, solanaGoClient, []solana.Instruction{ix}, admin, config.DefaultCommitment) @@ -1263,11 +1269,11 @@ func TestMcmWithTimelock(t *testing.T) { // Create mcm operation node for scheduling scheduleIx, scerr := timelock.NewScheduleBatchInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, newOp3.OperationID(), newOp3.Delay, newOp3.OperationPDA(), - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), msigs[timelock.Proposer_Role].AccessController.PublicKey(), proposerMsig.SignerPDA, ).ValidateAndBuild() @@ -1403,12 +1409,12 @@ func TestMcmWithTimelock(t *testing.T) { t.Run("op2: cannot be executed before op1", func(t *testing.T) { ix := timelock.NewExecuteBatchInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, op2.OperationID(), op2.OperationPDA(), op1.OperationPDA(), // provide op1 PDA as predecessor - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), + timelockutil.GetSignerPDA(config.TestTimelockID), msigs[timelock.Executor_Role].AccessController.PublicKey(), admin.PublicKey(), ) @@ -1427,12 +1433,12 @@ func TestMcmWithTimelock(t *testing.T) { t.Run("op1: initial mint to treasury", func(t *testing.T) { ix := timelock.NewExecuteBatchInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, op1.OperationID(), op1.OperationPDA(), config.TimelockEmptyOpID, - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), + timelockutil.GetSignerPDA(config.TestTimelockID), msigs[timelock.Executor_Role].AccessController.PublicKey(), admin.PublicKey(), ) @@ -1493,7 +1499,7 @@ func TestMcmWithTimelock(t *testing.T) { tokenProgram, treasuryATA, mint, - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetSignerPDA(config.TestTimelockID), treasury.PublicKey(), nil, ) @@ -1503,12 +1509,12 @@ func TestMcmWithTimelock(t *testing.T) { t.Run("op2: should provide the correct predecessor pda address", func(t *testing.T) { ix := timelock.NewExecuteBatchInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, op2.OperationID(), op2.OperationPDA(), op1.OperationID(), // provide op1 ID as predecessor - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), + timelockutil.GetSignerPDA(config.TestTimelockID), msigs[timelock.Executor_Role].AccessController.PublicKey(), admin.PublicKey(), ) @@ -1527,12 +1533,12 @@ func TestMcmWithTimelock(t *testing.T) { t.Run("op2: team ata creation", func(t *testing.T) { ix := timelock.NewExecuteBatchInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, op2.OperationID(), op2.OperationPDA(), op1.OperationPDA(), // provide op1 PDA as predecessor - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), + timelockutil.GetSignerPDA(config.TestTimelockID), msigs[timelock.Executor_Role].AccessController.PublicKey(), admin.PublicKey(), ) @@ -1576,12 +1582,12 @@ func TestMcmWithTimelock(t *testing.T) { require.NoError(t, werr) executeTimelockIx := timelock.NewExecuteBatchInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, newOp3.OperationID(), newOp3.OperationPDA(), op2.OperationPDA(), - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), + timelockutil.GetSignerPDA(config.TestTimelockID), msigs[timelock.Executor_Role].AccessController.PublicKey(), admin.PublicKey(), ) @@ -1907,7 +1913,7 @@ func TestMcmWithTimelock(t *testing.T) { testutils.SendAndConfirm(ctx, t, solanaGoClient, setupIxs, admin, config.DefaultCommitment, common.AddSigners(mintKeypair)) // setup mint authority to Timelock signer - authIx, err := tokens.SetTokenMintAuthority(tokenProgram, timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), mint, admin.PublicKey()) + authIx, err := tokens.SetTokenMintAuthority(tokenProgram, timelockutil.GetSignerPDA(config.TestTimelockID), mint, admin.PublicKey()) require.NoError(t, err) testutils.SendAndConfirm(ctx, t, solanaGoClient, []solana.Instruction{authIx}, admin, config.DefaultCommitment) @@ -1946,7 +1952,7 @@ func TestMcmWithTimelock(t *testing.T) { tokenProgram, treasuryATA, mint, - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetSignerPDA(config.TestTimelockID), treasury.PublicKey(), nil, ) @@ -2002,7 +2008,7 @@ func TestMcmWithTimelock(t *testing.T) { treasuryATA, mint, ata, - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetSignerPDA(config.TestTimelockID), []solana.PublicKey{}, ) require.NoError(t, err) @@ -2031,6 +2037,7 @@ func TestMcmWithTimelock(t *testing.T) { require.NoError(t, err) op := timelockutil.Operation{ + TimelockID: config.TestTimelockID, Predecessor: config.TimelockEmptyOpID, Salt: salt, Delay: uint64(1), @@ -2042,7 +2049,7 @@ func TestMcmWithTimelock(t *testing.T) { } // create and initialize operation accounts - ixs, err := timelockutil.GetPreloadOperationIxs(config.TestTimelockIDPaddedBuffer, op, admin.PublicKey()) + ixs, err := timelockutil.GetPreloadOperationIxs(config.TestTimelockID, op, admin.PublicKey()) require.NoError(t, err) for _, ix := range ixs { cu := testutils.GetRequiredCU(ctx, t, solanaGoClient, []solana.Instruction{ix}, admin, config.DefaultCommitment) @@ -2057,11 +2064,11 @@ func TestMcmWithTimelock(t *testing.T) { // schedule the operation scheduleIx, err := timelock.NewScheduleBatchInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, op.OperationID(), op.Delay, op.OperationPDA(), - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), msigs[timelock.Proposer_Role].AccessController.PublicKey(), proposerMsig.SignerPDA, ).ValidateAndBuild() @@ -2167,12 +2174,12 @@ func TestMcmWithTimelock(t *testing.T) { require.NoError(t, err) tlExeIx := timelock.NewExecuteBatchInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, op.OperationID(), op.OperationPDA(), config.TimelockEmptyOpID, - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), + timelockutil.GetSignerPDA(config.TestTimelockID), msigs[timelock.Executor_Role].AccessController.PublicKey(), admin.PublicKey(), ) diff --git a/chains/solana/contracts/tests/mcms/timelock_bypasser_execute_test.go b/chains/solana/contracts/tests/mcms/timelock_bypasser_execute_test.go index 99a12bc7..9470862d 100644 --- a/chains/solana/contracts/tests/mcms/timelock_bypasser_execute_test.go +++ b/chains/solana/contracts/tests/mcms/timelock_bypasser_execute_test.go @@ -97,9 +97,9 @@ func TestTimelockBypasserExecute(t *testing.T) { require.NoError(t, bin.UnmarshalBorsh(&programData, data.Bytes())) initTimelockIx, initErr := timelock.NewInitializeInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, config.MinDelay, - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), admin.PublicKey(), solana.SystemProgramID, config.TimelockProgram, @@ -115,7 +115,7 @@ func TestTimelockBypasserExecute(t *testing.T) { testutils.SendAndConfirm(ctx, t, solanaGoClient, []solana.Instruction{initTimelockIx}, admin, config.DefaultCommitment) var configAccount timelock.Config - cfgErr := common.GetAccountDataBorshInto(ctx, solanaGoClient, timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), config.DefaultCommitment, &configAccount) + cfgErr := common.GetAccountDataBorshInto(ctx, solanaGoClient, timelockutil.GetConfigPDA(config.TestTimelockID), config.DefaultCommitment, &configAccount) if cfgErr != nil { require.NoError(t, cfgErr, "failed to get account info") } @@ -134,7 +134,7 @@ func TestTimelockBypasserExecute(t *testing.T) { for _, account := range data.Accounts { addresses = append(addresses, account.PublicKey()) } - batchAddAccessIxs, batchAddAccessIxsErr := timelockutil.GetBatchAddAccessIxs(ctx, config.TestTimelockIDPaddedBuffer, data.AccessController.PublicKey(), role, addresses, admin, config.BatchAddAccessChunkSize, solanaGoClient) + batchAddAccessIxs, batchAddAccessIxsErr := timelockutil.GetBatchAddAccessIxs(ctx, config.TestTimelockID, data.AccessController.PublicKey(), role, addresses, admin, config.BatchAddAccessChunkSize, solanaGoClient) require.NoError(t, batchAddAccessIxsErr) for _, ix := range batchAddAccessIxs { @@ -153,7 +153,7 @@ func TestTimelockBypasserExecute(t *testing.T) { t.Run("setup: wsol transfer operation", func(t *testing.T) { requiredAmount := allowance.recipient - fundPDAIx := system.NewTransferInstruction(allowance.timelockAuthority, admin.PublicKey(), timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer)).Build() + fundPDAIx := system.NewTransferInstruction(allowance.timelockAuthority, admin.PublicKey(), timelockutil.GetSignerPDA(config.TestTimelockID)).Build() createAdminATAIx, _, caErr := tokens.CreateAssociatedTokenAccount(tokenProgram, wsol, admin.PublicKey(), admin.PublicKey()) require.NoError(t, caErr) @@ -178,7 +178,7 @@ func TestTimelockBypasserExecute(t *testing.T) { tokenProgram, adminATA, wsol, - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetSignerPDA(config.TestTimelockID), admin.PublicKey(), nil, ) @@ -192,7 +192,7 @@ func TestTimelockBypasserExecute(t *testing.T) { // check results timelockAuthorityBalance, tlBalanceErr := solanaGoClient.GetBalance( ctx, - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetSignerPDA(config.TestTimelockID), config.DefaultCommitment, ) require.NoError(t, tlBalanceErr) @@ -211,6 +211,7 @@ func TestTimelockBypasserExecute(t *testing.T) { salt, err := mcms.SimpleSalt() require.NoError(t, err) op := timelockutil.Operation{ + TimelockID: config.TestTimelockID, Predecessor: config.TimelockEmptyOpID, Salt: salt, Delay: uint64(1000), @@ -220,7 +221,7 @@ func TestTimelockBypasserExecute(t *testing.T) { tokenProgram, wsol, recipient.PublicKey(), - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetSignerPDA(config.TestTimelockID), ) require.NoError(t, ciErr) op.AddInstruction( @@ -235,7 +236,7 @@ func TestTimelockBypasserExecute(t *testing.T) { adminATA, wsol, recipientATA, - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetSignerPDA(config.TestTimelockID), nil, ) require.NoError(t, tiErr) @@ -245,7 +246,7 @@ func TestTimelockBypasserExecute(t *testing.T) { operationPDA := op.OperationPDA() signer := roleMap[timelock.Proposer_Role].RandomPick() - ixs, err := timelockutil.GetPreloadOperationIxs(config.TestTimelockIDPaddedBuffer, op, signer.PublicKey()) + ixs, err := timelockutil.GetPreloadOperationIxs(config.TestTimelockID, op, signer.PublicKey()) require.NoError(t, err) for _, ix := range ixs { testutils.SendAndConfirm(ctx, t, solanaGoClient, []solana.Instruction{ix}, signer, config.DefaultCommitment) @@ -268,11 +269,11 @@ func TestTimelockBypasserExecute(t *testing.T) { ac := roleMap[timelock.Bypasser_Role].AccessController ix := timelock.NewBypasserExecuteBatchInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, id, operationPDA, - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), + timelockutil.GetSignerPDA(config.TestTimelockID), ac.PublicKey(), signer.PublicKey(), ) diff --git a/chains/solana/contracts/tests/mcms/timelock_multiple_instances_test.go b/chains/solana/contracts/tests/mcms/timelock_multiple_instances_test.go index e66353a0..422ee0fe 100644 --- a/chains/solana/contracts/tests/mcms/timelock_multiple_instances_test.go +++ b/chains/solana/contracts/tests/mcms/timelock_multiple_instances_test.go @@ -210,4 +210,150 @@ func TestTimelockMultipleInstances(t *testing.T) { } } }) + // todo: config / signer seeds constraints + t.Run("instance isolation tests", func(t *testing.T) { + t.Run("config isolation", func(t *testing.T) { + t.Run("cannot access other instance config using own roles", func(t *testing.T) { + // try to use instance1's proposer to schedule on instance2 + proposer := timelockInstances[0].RoleMap[timelock.Proposer_Role].RandomPick() + salt, err := mcms.SimpleSalt() + require.NoError(t, err) + + // create test operation for instance2 but using instance1's proposer + op := timelockutil.Operation{ + TimelockID: timelockInstances[1].ID, + Predecessor: config.TimelockEmptyOpID, + Salt: salt, + Delay: uint64(1), + } + + // preload operation instructions + preloadIxs, prierr := timelockutil.GetPreloadOperationIxs( + timelockInstances[1].ID, + op, + proposer.PublicKey(), + ) + require.NoError(t, prierr) + + for _, ix := range preloadIxs { + testutils.SendAndConfirm( + ctx, + t, + solanaGoClient, + []solana.Instruction{ix}, + proposer, + config.DefaultCommitment, + ) + } + + // Try to schedule operation on instance2 using instance1's proposer + ix, ierr := timelock.NewScheduleBatchInstruction( + timelockInstances[1].ID, // instance2's ID + op.OperationID(), + op.Delay, + op.OperationPDA(), + timelockInstances[1].ConfigPDA, // instance2's config + timelockInstances[0].RoleMap[timelock.Proposer_Role].AccessController.PublicKey(), // instance1's proposer AC + proposer.PublicKey(), + ).ValidateAndBuild() + require.NoError(t, ierr) + + result := testutils.SendAndFailWith( + ctx, + t, + solanaGoClient, + []solana.Instruction{ix}, + proposer, // signing with instance1's proposer + config.DefaultCommitment, + []string{"Error Code: " + timelock.InvalidAccessController_TimelockError.String()}, + ) + require.NotNil(t, result) + }) + + t.Run("cannot update delay using other instance's admin", func(t *testing.T) { + // try to update instance2's delay using instance1's admin + newMinDelay := uint64(14000) + + ix, ierr := timelock.NewUpdateDelayInstruction( + timelockInstances[1].ID, // instance2's ID + newMinDelay, + timelockInstances[1].ConfigPDA, + timelockInstances[0].Admin.PublicKey(), // instance1's admin trying to update + ).ValidateAndBuild() + require.NoError(t, ierr) + + result := testutils.SendAndFailWith( + ctx, + t, + solanaGoClient, + []solana.Instruction{ix}, + timelockInstances[0].Admin, // signing with instance1's admin + config.DefaultCommitment, + []string{"Error Code: " + timelockutil.UnauthorizedError.String()}, + ) + require.NotNil(t, result) + }) + + t.Run("cannot modify access controllers of another instance", func(t *testing.T) { + // try to use instance1's admin to modify instance2's access controller + randomKey, err := solana.NewRandomPrivateKey() + require.NoError(t, err) + + // try to add access to instance2's proposer role using instance1's admin + ix, ierr := access_controller.NewAddAccessInstruction( + timelockInstances[1].RoleMap[timelock.Proposer_Role].AccessController.PublicKey(), // instance2's proposer AC + timelockInstances[0].Admin.PublicKey(), // instance1's admin trying to modify + randomKey.PublicKey(), // random key to add + ).ValidateAndBuild() + require.NoError(t, ierr) + + result := testutils.SendAndFailWith( + ctx, + t, + solanaGoClient, + []solana.Instruction{ix}, + timelockInstances[0].Admin, // signing with instance1's admin + config.DefaultCommitment, + []string{"Error Code: ConstraintHasOne"}, + ) + require.NotNil(t, result) + }) + + t.Run("cannot transfer ownership of another instance", func(t *testing.T) { + // try to transfer instance2's ownership using instance1's admin + ix, ierr := timelock.NewTransferOwnershipInstruction( + timelockInstances[1].ID, // instance2's ID + timelockInstances[0].Admin.PublicKey(), // trying to transfer to instance1's admin + timelockInstances[1].ConfigPDA, + timelockInstances[0].Admin.PublicKey(), // instance1's admin trying to transfer + ).ValidateAndBuild() + require.NoError(t, ierr) + + result := testutils.SendAndFailWith( + ctx, + t, + solanaGoClient, + []solana.Instruction{ix}, + timelockInstances[0].Admin, // signing with instance1's admin + config.DefaultCommitment, + []string{"Error Code: " + timelockutil.UnauthorizedError.String()}, + ) + require.NotNil(t, result) + }) + }) + + t.Run("operation isolation", func(t *testing.T) { + t.Run("cannot schedule operation using other instance's signer PDA", func(t *testing.T) {}) + t.Run("cannot execute operation scheduled on another instance", func(t *testing.T) {}) + t.Run("cannot cancel operation from another instance", func(t *testing.T) {}) + t.Run("cannot reuse operation ID between instances", func(t *testing.T) {}) + }) + + t.Run("role isolation", func(t *testing.T) { + t.Run("proposer cannot schedule on other instance", func(t *testing.T) {}) + t.Run("executor cannot execute on other instance", func(t *testing.T) {}) + t.Run("canceller cannot cancel on other instance", func(t *testing.T) {}) + t.Run("bypasser cannot bypass on other instance", func(t *testing.T) {}) + }) + }) } diff --git a/chains/solana/contracts/tests/mcms/timelock_rbac_test.go b/chains/solana/contracts/tests/mcms/timelock_rbac_test.go index 53aa1b6c..04dbabcd 100644 --- a/chains/solana/contracts/tests/mcms/timelock_rbac_test.go +++ b/chains/solana/contracts/tests/mcms/timelock_rbac_test.go @@ -80,9 +80,9 @@ func TestTimelockRBAC(t *testing.T) { require.NoError(t, bin.UnmarshalBorsh(&programData, data.Bytes())) initTimelockIx, ierr := timelock.NewInitializeInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, config.MinDelay, - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), anotherAdmin.PublicKey(), solana.SystemProgramID, config.TimelockProgram, @@ -114,9 +114,9 @@ func TestTimelockRBAC(t *testing.T) { require.NoError(t, bin.UnmarshalBorsh(&programData, data.Bytes())) initTimelockIx, ierr := timelock.NewInitializeInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, config.MinDelay, - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), admin.PublicKey(), solana.SystemProgramID, config.TimelockProgram, @@ -132,7 +132,7 @@ func TestTimelockRBAC(t *testing.T) { testutils.SendAndConfirm(ctx, t, solanaGoClient, []solana.Instruction{initTimelockIx}, admin, config.DefaultCommitment) var configAccount timelock.Config - err = common.GetAccountDataBorshInto(ctx, solanaGoClient, timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), config.DefaultCommitment, &configAccount) + err = common.GetAccountDataBorshInto(ctx, solanaGoClient, timelockutil.GetConfigPDA(config.TestTimelockID), config.DefaultCommitment, &configAccount) if err != nil { require.NoError(t, err, "failed to get account info") } @@ -148,9 +148,9 @@ func TestTimelockRBAC(t *testing.T) { t.Run("timelock:ownership", func(t *testing.T) { t.Run("fail to transfer ownership when not owner", func(t *testing.T) { instruction, ierr := timelock.NewTransferOwnershipInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, anotherAdmin.PublicKey(), - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), user.PublicKey(), ).ValidateAndBuild() require.NoError(t, ierr) @@ -160,9 +160,9 @@ func TestTimelockRBAC(t *testing.T) { t.Run("Current owner cannot propose self", func(t *testing.T) { instruction, ierr := timelock.NewTransferOwnershipInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, admin.PublicKey(), - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), admin.PublicKey(), ).ValidateAndBuild() require.NoError(t, ierr) @@ -172,9 +172,9 @@ func TestTimelockRBAC(t *testing.T) { t.Run("successfully transfer ownership", func(t *testing.T) { instruction, ierr := timelock.NewTransferOwnershipInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, anotherAdmin.PublicKey(), - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), admin.PublicKey(), ).ValidateAndBuild() require.NoError(t, ierr) @@ -184,8 +184,8 @@ func TestTimelockRBAC(t *testing.T) { t.Run("Fail to accept ownership when not proposed_owner", func(t *testing.T) { instruction, ierr := timelock.NewAcceptOwnershipInstruction( - config.TestTimelockIDPaddedBuffer, - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + config.TestTimelockID, + timelockutil.GetConfigPDA(config.TestTimelockID), user.PublicKey(), ).ValidateAndBuild() require.NoError(t, ierr) @@ -195,8 +195,8 @@ func TestTimelockRBAC(t *testing.T) { t.Run("anotherAdmin becomes owner", func(t *testing.T) { instruction, ierr := timelock.NewAcceptOwnershipInstruction( - config.TestTimelockIDPaddedBuffer, - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + config.TestTimelockID, + timelockutil.GetConfigPDA(config.TestTimelockID), anotherAdmin.PublicKey(), ).ValidateAndBuild() require.NoError(t, ierr) @@ -205,7 +205,7 @@ func TestTimelockRBAC(t *testing.T) { // Validate proposed set to 0-address after accepting ownership var configAccount timelock.Config - err = common.GetAccountDataBorshInto(ctx, solanaGoClient, timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), config.DefaultCommitment, &configAccount) + err = common.GetAccountDataBorshInto(ctx, solanaGoClient, timelockutil.GetConfigPDA(config.TestTimelockID), config.DefaultCommitment, &configAccount) if err != nil { require.NoError(t, err, "failed to get account info") } @@ -216,9 +216,9 @@ func TestTimelockRBAC(t *testing.T) { // get it back t.Run("retrieve back ownership to admin", func(t *testing.T) { tix, ierr := timelock.NewTransferOwnershipInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, admin.PublicKey(), - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), anotherAdmin.PublicKey(), ).ValidateAndBuild() require.NoError(t, ierr) @@ -226,8 +226,8 @@ func TestTimelockRBAC(t *testing.T) { require.NotNil(t, result) aix, aerr := timelock.NewAcceptOwnershipInstruction( - config.TestTimelockIDPaddedBuffer, - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + config.TestTimelockID, + timelockutil.GetConfigPDA(config.TestTimelockID), admin.PublicKey(), ).ValidateAndBuild() require.NoError(t, aerr) @@ -235,7 +235,7 @@ func TestTimelockRBAC(t *testing.T) { require.NotNil(t, result) var configAccount timelock.Config - err = common.GetAccountDataBorshInto(ctx, solanaGoClient, timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), config.DefaultCommitment, &configAccount) + err = common.GetAccountDataBorshInto(ctx, solanaGoClient, timelockutil.GetConfigPDA(config.TestTimelockID), config.DefaultCommitment, &configAccount) if err != nil { require.NoError(t, err, "failed to get account info") } @@ -251,7 +251,7 @@ func TestTimelockRBAC(t *testing.T) { for _, account := range data.Accounts { addresses = append(addresses, account.PublicKey()) } - batchAddAccessIxs, baerr := timelockutil.GetBatchAddAccessIxs(ctx, config.TestTimelockIDPaddedBuffer, data.AccessController.PublicKey(), role, addresses, admin, config.BatchAddAccessChunkSize, solanaGoClient) + batchAddAccessIxs, baerr := timelockutil.GetBatchAddAccessIxs(ctx, config.TestTimelockID, data.AccessController.PublicKey(), role, addresses, admin, config.BatchAddAccessChunkSize, solanaGoClient) require.NoError(t, baerr) for _, ix := range batchAddAccessIxs { @@ -270,30 +270,31 @@ func TestTimelockRBAC(t *testing.T) { salt, serr := mcms.SimpleSalt() require.NoError(t, serr) nonExecutableOp := timelockutil.Operation{ + TimelockID: config.TestTimelockID, Predecessor: config.TimelockEmptyOpID, Salt: salt, Delay: uint64(1), } - ix := system.NewTransferInstruction(1*solana.LAMPORTS_PER_SOL, admin.PublicKey(), timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer)).Build() + ix := system.NewTransferInstruction(1*solana.LAMPORTS_PER_SOL, admin.PublicKey(), timelockutil.GetSignerPDA(config.TestTimelockID)).Build() nonExecutableOp.AddInstruction(ix, []solana.PublicKey{}) t.Run("rbac: when try to schedule from non proposer role, it fails", func(t *testing.T) { nonProposer := roleMap[timelock.Executor_Role].RandomPick() ac := roleMap[timelock.Proposer_Role].AccessController - ixs, prierr := timelockutil.GetPreloadOperationIxs(config.TestTimelockIDPaddedBuffer, nonExecutableOp, nonProposer.PublicKey()) + ixs, prierr := timelockutil.GetPreloadOperationIxs(config.TestTimelockID, nonExecutableOp, nonProposer.PublicKey()) require.NoError(t, prierr) for _, ix := range ixs { testutils.SendAndConfirm(ctx, t, solanaGoClient, []solana.Instruction{ix}, nonProposer, config.DefaultCommitment) } ix, scerr := timelock.NewScheduleBatchInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, nonExecutableOp.OperationID(), nonExecutableOp.Delay, nonExecutableOp.OperationPDA(), - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), ac.PublicKey(), nonProposer.PublicKey(), ).ValidateAndBuild() @@ -319,11 +320,11 @@ func TestTimelockRBAC(t *testing.T) { require.False(t, found, "Account %s should not be in the AccessList", proposer.PublicKey()) ix, scerr := timelock.NewScheduleBatchInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, nonExecutableOp.OperationID(), nonExecutableOp.Delay, nonExecutableOp.OperationPDA(), - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), ac.PublicKey(), proposer.PublicKey(), ).ValidateAndBuild() @@ -346,25 +347,26 @@ func TestTimelockRBAC(t *testing.T) { salt, serr := mcms.SimpleSalt() require.NoError(t, serr) nonExecutableOp2 := timelockutil.Operation{ + TimelockID: config.TestTimelockID, Predecessor: config.TimelockEmptyOpID, Salt: salt, Delay: uint64(1), } - ix := system.NewTransferInstruction(1*solana.LAMPORTS_PER_SOL, admin.PublicKey(), timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer)).Build() + ix := system.NewTransferInstruction(1*solana.LAMPORTS_PER_SOL, admin.PublicKey(), timelockutil.GetSignerPDA(config.TestTimelockID)).Build() nonExecutableOp2.AddInstruction(ix, []solana.PublicKey{}) - ixs, prerr := timelockutil.GetPreloadOperationIxs(config.TestTimelockIDPaddedBuffer, nonExecutableOp2, proposer.PublicKey()) + ixs, prerr := timelockutil.GetPreloadOperationIxs(config.TestTimelockID, nonExecutableOp2, proposer.PublicKey()) require.NoError(t, prerr) for _, ix := range ixs { testutils.SendAndConfirm(ctx, t, solanaGoClient, []solana.Instruction{ix}, proposer, config.DefaultCommitment) } sbix, sberr := timelock.NewScheduleBatchInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, nonExecutableOp2.OperationID(), nonExecutableOp2.Delay, nonExecutableOp2.OperationPDA(), // formerly uploaded - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), ac.PublicKey(), proposer.PublicKey(), ).ValidateAndBuild() @@ -413,10 +415,10 @@ func TestTimelockRBAC(t *testing.T) { ac := roleMap[timelock.Proposer_Role].AccessController ix, cerr := timelock.NewCancelInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, nonExecutableOp2.OperationID(), nonExecutableOp2.OperationPDA(), - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), ac.PublicKey(), signer.PublicKey(), ).ValidateAndBuild() @@ -432,10 +434,10 @@ func TestTimelockRBAC(t *testing.T) { ac := roleMap[timelock.Canceller_Role].AccessController ix, cerr := timelock.NewCancelInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, nonExecutableOp2.OperationID(), nonExecutableOp2.OperationPDA(), - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), ac.PublicKey(), signer.PublicKey(), ).ValidateAndBuild() @@ -450,10 +452,10 @@ func TestTimelockRBAC(t *testing.T) { ac := roleMap[timelock.Canceller_Role].AccessController ix, cerr := timelock.NewCancelInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, nonExecutableOp2.OperationID(), nonExecutableOp2.OperationPDA(), - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), ac.PublicKey(), signer.PublicKey(), ).ValidateAndBuild() @@ -486,9 +488,9 @@ func TestTimelockRBAC(t *testing.T) { signer := roleMap[timelock.Proposer_Role].RandomPick() ix, ierr := timelock.NewUpdateDelayInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, newMinDelay, - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), signer.PublicKey(), ).ValidateAndBuild() require.NoError(t, ierr) @@ -501,15 +503,15 @@ func TestTimelockRBAC(t *testing.T) { signer := admin var oldConfigAccount timelock.Config - err = common.GetAccountDataBorshInto(ctx, solanaGoClient, timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), config.DefaultCommitment, &oldConfigAccount) + err = common.GetAccountDataBorshInto(ctx, solanaGoClient, timelockutil.GetConfigPDA(config.TestTimelockID), config.DefaultCommitment, &oldConfigAccount) if err != nil { require.NoError(t, err, "failed to get account info") } ix, err := timelock.NewUpdateDelayInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, newMinDelay, - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), signer.PublicKey(), ).ValidateAndBuild() require.NoError(t, err) @@ -528,7 +530,7 @@ func TestTimelockRBAC(t *testing.T) { require.Equal(t, newMinDelay, event.NewDuration) var newConfigAccount timelock.Config - err = common.GetAccountDataBorshInto(ctx, solanaGoClient, timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), config.DefaultCommitment, &newConfigAccount) + err = common.GetAccountDataBorshInto(ctx, solanaGoClient, timelockutil.GetConfigPDA(config.TestTimelockID), config.DefaultCommitment, &newConfigAccount) if err != nil { require.NoError(t, err, "failed to get account info") } diff --git a/chains/solana/contracts/tests/mcms/timelock_schedule_execute_test.go b/chains/solana/contracts/tests/mcms/timelock_schedule_execute_test.go index ec6a1b7f..43c62f3b 100644 --- a/chains/solana/contracts/tests/mcms/timelock_schedule_execute_test.go +++ b/chains/solana/contracts/tests/mcms/timelock_schedule_execute_test.go @@ -97,9 +97,9 @@ func TestTimelockScheduleAndExecute(t *testing.T) { require.NoError(t, bin.UnmarshalBorsh(&programData, data.Bytes())) initTimelockIx, initErr := timelock.NewInitializeInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, config.MinDelay, - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), admin.PublicKey(), solana.SystemProgramID, config.TimelockProgram, @@ -115,7 +115,7 @@ func TestTimelockScheduleAndExecute(t *testing.T) { testutils.SendAndConfirm(ctx, t, solanaGoClient, []solana.Instruction{initTimelockIx}, admin, config.DefaultCommitment) var configAccount timelock.Config - cfgErr := common.GetAccountDataBorshInto(ctx, solanaGoClient, timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), config.DefaultCommitment, &configAccount) + cfgErr := common.GetAccountDataBorshInto(ctx, solanaGoClient, timelockutil.GetConfigPDA(config.TestTimelockID), config.DefaultCommitment, &configAccount) if cfgErr != nil { require.NoError(t, cfgErr, "failed to get account info") } @@ -134,7 +134,7 @@ func TestTimelockScheduleAndExecute(t *testing.T) { for _, account := range data.Accounts { addresses = append(addresses, account.PublicKey()) } - batchAddAccessIxs, batchAddAccessIxsErr := timelockutil.GetBatchAddAccessIxs(ctx, config.TestTimelockIDPaddedBuffer, data.AccessController.PublicKey(), role, addresses, admin, config.BatchAddAccessChunkSize, solanaGoClient) + batchAddAccessIxs, batchAddAccessIxsErr := timelockutil.GetBatchAddAccessIxs(ctx, config.TestTimelockID, data.AccessController.PublicKey(), role, addresses, admin, config.BatchAddAccessChunkSize, solanaGoClient) require.NoError(t, batchAddAccessIxsErr) for _, ix := range batchAddAccessIxs { @@ -154,9 +154,9 @@ func TestTimelockScheduleAndExecute(t *testing.T) { newMinDelay := uint64(1) ix, updateDelayIxErr := timelock.NewUpdateDelayInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, newMinDelay, - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), admin.PublicKey(), ).ValidateAndBuild() require.NoError(t, updateDelayIxErr) @@ -165,7 +165,7 @@ func TestTimelockScheduleAndExecute(t *testing.T) { require.NotNil(t, result) var configAccount timelock.Config - getConfigAccountErr := common.GetAccountDataBorshInto(ctx, solanaGoClient, timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), config.DefaultCommitment, &configAccount) + getConfigAccountErr := common.GetAccountDataBorshInto(ctx, solanaGoClient, timelockutil.GetConfigPDA(config.TestTimelockID), config.DefaultCommitment, &configAccount) require.NoError(t, getConfigAccountErr, "failed to get account info") require.Equal(t, newMinDelay, configAccount.MinDelay, "MinDelay is not updated") @@ -174,7 +174,7 @@ func TestTimelockScheduleAndExecute(t *testing.T) { t.Run("setup: wsol transfer operation", func(t *testing.T) { requiredAmount := allowance.recipient - fundPDAIx := system.NewTransferInstruction(allowance.timelockAuthority, admin.PublicKey(), timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer)).Build() + fundPDAIx := system.NewTransferInstruction(allowance.timelockAuthority, admin.PublicKey(), timelockutil.GetSignerPDA(config.TestTimelockID)).Build() createAdminATAIx, _, caErr := tokens.CreateAssociatedTokenAccount(tokenProgram, wsol, admin.PublicKey(), admin.PublicKey()) require.NoError(t, caErr) @@ -198,7 +198,7 @@ func TestTimelockScheduleAndExecute(t *testing.T) { tokenProgram, adminATA, wsol, - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetSignerPDA(config.TestTimelockID), admin.PublicKey(), nil, ) @@ -211,7 +211,7 @@ func TestTimelockScheduleAndExecute(t *testing.T) { timelockAuthorityBalance, tlBalanceErr := solanaGoClient.GetBalance( ctx, - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetSignerPDA(config.TestTimelockID), config.DefaultCommitment, ) require.NoError(t, tlBalanceErr) @@ -230,6 +230,7 @@ func TestTimelockScheduleAndExecute(t *testing.T) { salt1, err := mcms.SimpleSalt() require.NoError(t, err) op1 := timelockutil.Operation{ + TimelockID: config.TestTimelockID, Predecessor: config.TimelockEmptyOpID, Salt: salt1, Delay: 2, @@ -238,7 +239,7 @@ func TestTimelockScheduleAndExecute(t *testing.T) { tokenProgram, wsol, recipient.PublicKey(), - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetSignerPDA(config.TestTimelockID), ) require.NoError(t, ciErr) op1.AddInstruction(cIx, []solana.PublicKey{solana.TokenProgramID, solana.SPLAssociatedTokenAccountProgramID}) @@ -246,6 +247,7 @@ func TestTimelockScheduleAndExecute(t *testing.T) { salt2, err := mcms.SimpleSalt() require.NoError(t, err) op2 := timelockutil.Operation{ + TimelockID: config.TestTimelockID, Predecessor: op1.OperationID(), Salt: salt2, Delay: 2, @@ -258,7 +260,7 @@ func TestTimelockScheduleAndExecute(t *testing.T) { adminATA, wsol, recipientATA, - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetSignerPDA(config.TestTimelockID), nil, ) require.NoError(t, tiErr) @@ -267,6 +269,7 @@ func TestTimelockScheduleAndExecute(t *testing.T) { salt3, err := mcms.SimpleSalt() require.NoError(t, err) op3 := timelockutil.Operation{ + TimelockID: config.TestTimelockID, Predecessor: op1.OperationID(), Salt: salt3, Delay: 300, // enough delay to assert OperationNotReady error @@ -279,7 +282,7 @@ func TestTimelockScheduleAndExecute(t *testing.T) { adminATA, wsol, recipientATA, - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetSignerPDA(config.TestTimelockID), nil, ) require.NoError(t, atErr) @@ -294,7 +297,7 @@ func TestTimelockScheduleAndExecute(t *testing.T) { t.Run("success: schedule all operations", func(t *testing.T) { for _, op := range []timelockutil.Operation{op1, op2, op3} { - invalidIxs, ierr := timelockutil.GetPreloadOperationIxs(config.TestTimelockIDPaddedBuffer, op, proposer.PublicKey()) + invalidIxs, ierr := timelockutil.GetPreloadOperationIxs(config.TestTimelockID, op, proposer.PublicKey()) require.NoError(t, ierr) for _, ix := range invalidIxs { testutils.SendAndConfirm(ctx, t, solanaGoClient, []solana.Instruction{ix}, proposer, config.DefaultCommitment) @@ -303,10 +306,10 @@ func TestTimelockScheduleAndExecute(t *testing.T) { t.Run("clear operation", func(t *testing.T) { // clear instructions so that we can reinitialize the operation clearIx, ciErr := timelock.NewClearOperationInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, op.OperationID(), op.OperationPDA(), - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), proposer.PublicKey(), ).ValidateAndBuild() require.NoError(t, ciErr) @@ -317,18 +320,18 @@ func TestTimelockScheduleAndExecute(t *testing.T) { }) // re-preload instructions - ixs, err := timelockutil.GetPreloadOperationIxs(config.TestTimelockIDPaddedBuffer, op, proposer.PublicKey()) + ixs, err := timelockutil.GetPreloadOperationIxs(config.TestTimelockID, op, proposer.PublicKey()) require.NoError(t, err) for _, ix := range ixs { testutils.SendAndConfirm(ctx, t, solanaGoClient, []solana.Instruction{ix}, proposer, config.DefaultCommitment) } ix, ixVErr := timelock.NewScheduleBatchInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, op.OperationID(), op.Delay, op.OperationPDA(), - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), proposerAccessController, proposer.PublicKey(), ).ValidateAndBuild() @@ -363,11 +366,11 @@ func TestTimelockScheduleAndExecute(t *testing.T) { t.Run("fail: OperationAlreadyExists", func(t *testing.T) { ix := timelock.NewScheduleBatchInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, op1.OperationID(), op1.Delay, op1.OperationPDA(), - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), proposerAccessController, proposer.PublicKey(), ).Build() @@ -383,12 +386,12 @@ func TestTimelockScheduleAndExecute(t *testing.T) { t.Run("fail: should provide the right dependency pda", func(t *testing.T) { ix := timelock.NewExecuteBatchInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, op2.OperationID(), op2.OperationPDA(), op2.OperationPDA(), // wrong dependency - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), + timelockutil.GetSignerPDA(config.TestTimelockID), executorAccessController, executor.PublicKey(), ) @@ -402,12 +405,12 @@ func TestTimelockScheduleAndExecute(t *testing.T) { t.Run("fail: not able to execute op2 before dependency(op1) execution", func(t *testing.T) { ix := timelock.NewExecuteBatchInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, op2.OperationID(), op2.OperationPDA(), op1.OperationPDA(), // not executed yet - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), + timelockutil.GetSignerPDA(config.TestTimelockID), executorAccessController, executor.PublicKey(), ) @@ -422,12 +425,12 @@ func TestTimelockScheduleAndExecute(t *testing.T) { t.Run("success: op1 executed", func(t *testing.T) { ix := timelock.NewExecuteBatchInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, op1.OperationID(), op1.OperationPDA(), config.TimelockEmptyOpID, - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), + timelockutil.GetSignerPDA(config.TestTimelockID), executorAccessController, executor.PublicKey(), ) @@ -469,12 +472,12 @@ func TestTimelockScheduleAndExecute(t *testing.T) { t.Run("success: op2 executed", func(t *testing.T) { ix := timelock.NewExecuteBatchInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, op2.OperationID(), op2.OperationPDA(), op1.OperationPDA(), - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), + timelockutil.GetSignerPDA(config.TestTimelockID), executorAccessController, executor.PublicKey(), ) @@ -528,12 +531,12 @@ func TestTimelockScheduleAndExecute(t *testing.T) { t.Run("failure on execution try: op3 is not ready", func(t *testing.T) { ix := timelock.NewExecuteBatchInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, op3.OperationID(), op3.OperationPDA(), config.TimelockEmptyOpID, - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), - timelockutil.GetSignerPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), + timelockutil.GetSignerPDA(config.TestTimelockID), executorAccessController, executor.PublicKey(), ) @@ -556,6 +559,7 @@ func TestTimelockScheduleAndExecute(t *testing.T) { require.NoError(t, err) op := timelockutil.Operation{ + TimelockID: config.TestTimelockID, Predecessor: config.TimelockEmptyOpID, Salt: salt, Delay: 1, @@ -572,24 +576,24 @@ func TestTimelockScheduleAndExecute(t *testing.T) { t.Run("blocks initialize function", func(t *testing.T) { bIx, bIxErr := timelock.NewBlockFunctionSelectorInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, [8]uint8(external_program_cpi_stub.Instruction_Initialize.Bytes()), - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), admin.PublicKey(), ).ValidateAndBuild() require.NoError(t, bIxErr) testutils.SendAndConfirm(ctx, t, solanaGoClient, []solana.Instruction{bIx}, admin, config.DefaultCommitment) - blockedSelectors, bserr := timelockutil.GetBlockedFunctionSelectors(ctx, solanaGoClient, timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), config.DefaultCommitment) + blockedSelectors, bserr := timelockutil.GetBlockedFunctionSelectors(ctx, solanaGoClient, timelockutil.GetConfigPDA(config.TestTimelockID), config.DefaultCommitment) require.NoError(t, bserr) require.Contains(t, blockedSelectors, external_program_cpi_stub.Instruction_Initialize.Bytes()) }) t.Run("not able to block function that is already blocked", func(t *testing.T) { bbIx, bbIxErr := timelock.NewBlockFunctionSelectorInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, [8]uint8(external_program_cpi_stub.Instruction_Initialize.Bytes()), - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), admin.PublicKey(), ).ValidateAndBuild() require.NoError(t, bbIxErr) @@ -599,18 +603,18 @@ func TestTimelockScheduleAndExecute(t *testing.T) { id := op.OperationID() operationPDA := op.OperationPDA() - ixs, err := timelockutil.GetPreloadOperationIxs(config.TestTimelockIDPaddedBuffer, op, proposer.PublicKey()) + ixs, err := timelockutil.GetPreloadOperationIxs(config.TestTimelockID, op, proposer.PublicKey()) require.NoError(t, err) for _, ix := range ixs { testutils.SendAndConfirm(ctx, t, solanaGoClient, []solana.Instruction{ix}, proposer, config.DefaultCommitment) } scIx, scIxVErr := timelock.NewScheduleBatchInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, id, op.Delay, operationPDA, - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), proposerAccessController, proposer.PublicKey(), ).ValidateAndBuild() @@ -620,24 +624,24 @@ func TestTimelockScheduleAndExecute(t *testing.T) { t.Run("unblocks initialize function", func(t *testing.T) { bIx, bIxErr := timelock.NewUnblockFunctionSelectorInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, [8]uint8(external_program_cpi_stub.Instruction_Initialize.Bytes()), - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), admin.PublicKey(), ).ValidateAndBuild() require.NoError(t, bIxErr) testutils.SendAndConfirm(ctx, t, solanaGoClient, []solana.Instruction{bIx}, admin, config.DefaultCommitment) - blockedSelectors, bserr := timelockutil.GetBlockedFunctionSelectors(ctx, solanaGoClient, timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), config.DefaultCommitment) + blockedSelectors, bserr := timelockutil.GetBlockedFunctionSelectors(ctx, solanaGoClient, timelockutil.GetConfigPDA(config.TestTimelockID), config.DefaultCommitment) require.NoError(t, bserr) require.NotContains(t, blockedSelectors, external_program_cpi_stub.Instruction_Initialize.Bytes()) }) t.Run("not able to unblock function that is not blocked", func(t *testing.T) { bbIx, bbIxErr := timelock.NewUnblockFunctionSelectorInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, [8]uint8(external_program_cpi_stub.Instruction_Initialize.Bytes()), - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), admin.PublicKey(), ).ValidateAndBuild() require.NoError(t, bbIxErr) @@ -662,16 +666,16 @@ func TestTimelockScheduleAndExecute(t *testing.T) { t.Run("can't register more than MAX_SELECTOR", func(t *testing.T) { // check if it's empty - oldBlockedSelectors, gberr := timelockutil.GetBlockedFunctionSelectors(ctx, solanaGoClient, timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), config.DefaultCommitment) + oldBlockedSelectors, gberr := timelockutil.GetBlockedFunctionSelectors(ctx, solanaGoClient, timelockutil.GetConfigPDA(config.TestTimelockID), config.DefaultCommitment) require.NoError(t, gberr) require.Empty(t, oldBlockedSelectors) ixs := []solana.Instruction{} for i := 0; i < config.MaxFunctionSelectorLen; i++ { ix, nberr := timelock.NewBlockFunctionSelectorInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, [8]uint8{byte(i)}, - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), admin.PublicKey(), ).ValidateAndBuild() require.NoError(t, nberr) @@ -691,15 +695,15 @@ func TestTimelockScheduleAndExecute(t *testing.T) { } // check if it's full - blockedSelectors, bserr := timelockutil.GetBlockedFunctionSelectors(ctx, solanaGoClient, timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), config.DefaultCommitment) + blockedSelectors, bserr := timelockutil.GetBlockedFunctionSelectors(ctx, solanaGoClient, timelockutil.GetConfigPDA(config.TestTimelockID), config.DefaultCommitment) require.NoError(t, bserr) require.Equal(t, config.MaxFunctionSelectorLen, len(blockedSelectors)) // try one more ix, nberr := timelock.NewBlockFunctionSelectorInstruction( - config.TestTimelockIDPaddedBuffer, + config.TestTimelockID, [8]uint8{255}, - timelockutil.GetConfigPDA(config.TestTimelockIDPaddedBuffer), + timelockutil.GetConfigPDA(config.TestTimelockID), admin.PublicKey(), ).ValidateAndBuild() require.NoError(t, nberr) diff --git a/chains/solana/utils/timelock/timelock_operations.go b/chains/solana/utils/timelock/timelock_operations.go index e7c63792..48924690 100644 --- a/chains/solana/utils/timelock/timelock_operations.go +++ b/chains/solana/utils/timelock/timelock_operations.go @@ -7,7 +7,6 @@ import ( "github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings/timelock" - "github.com/smartcontractkit/chainlink-ccip/chains/solana/contracts/tests/config" "github.com/smartcontractkit/chainlink-ccip/chains/solana/utils/eth" ) @@ -19,6 +18,7 @@ type Instruction struct { // represents a batch of instructions that having atomicy to be scheduled and executed via timelock type Operation struct { + TimelockID [32]byte // timelock instance identifier Predecessor [32]byte // hashed id of the previous operation Salt [32]byte // random salt for the operation Delay uint64 // delay in seconds @@ -96,7 +96,7 @@ func (op *Operation) OperationID() [32]byte { func (op *Operation) OperationPDA() solana.PublicKey { id := op.OperationID() - return GetOperationPDA(config.TestTimelockIDPaddedBuffer, id) + return GetOperationPDA(op.TimelockID, id) } // type conversion from solana instruction to timelock instruction data