Skip to content

Commit

Permalink
chore: mcm::set_config sync changes
Browse files Browse the repository at this point in the history
  • Loading branch information
jadepark-dev committed Dec 19, 2024
1 parent 6badcdb commit 72eea70
Show file tree
Hide file tree
Showing 14 changed files with 467 additions and 360 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::constant::*;
use crate::error::*;
use crate::eth_utils::*;
use crate::event::*;
use crate::state::root::*;

/// Set the configuration for the multisig instance after validating the input
pub fn set_config(
Expand Down Expand Up @@ -110,6 +111,27 @@ pub fn set_config(
config.group_quorums = group_quorums;
config.group_parents = group_parents;

// clear_root is equivalent to overriding with a completely empty root
if clear_root {
let expiring_root = &mut ctx.accounts.expiring_root_and_op_count;
let root_metadata = &mut ctx.accounts.root_metadata;

// preserve the current op_count
let current_op_count = expiring_root.op_count;

// clear the expiring root while preserving op_count
expiring_root.root = [0u8; 32]; // clear root (equivalent to bytes32(0) in Solidity)
expiring_root.valid_until = 0; // clear timestamp
expiring_root.op_count = current_op_count;

// set root metadata to a cleared state
root_metadata.chain_id = ctx.accounts.multisig_config.chain_id;
root_metadata.multisig = ctx.accounts.multisig_config.key();
root_metadata.pre_op_count = current_op_count;
root_metadata.post_op_count = current_op_count;
root_metadata.override_previous_root = true;
}

emit!(ConfigSet {
group_parents,
group_quorums,
Expand Down Expand Up @@ -218,6 +240,12 @@ pub struct SetConfig<'info> {
)]
pub config_signers: Account<'info, ConfigSigners>, // preloaded signers account

#[account(mut, seeds = [ROOT_METADATA_SEED, multisig_name.as_ref()], bump)]
pub root_metadata: Account<'info, RootMetadata>,

#[account(mut, seeds = [EXPIRING_ROOT_AND_OP_COUNT_SEED, multisig_name.as_ref()], bump)]
pub expiring_root_and_op_count: Account<'info, ExpiringRootAndOpCount>,

#[account(mut, address = multisig_config.owner @ AuthError::Unauthorized)]
pub authority: Signer<'info>,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ pub fn set_root(
);

let current_op_count = ctx.accounts.expiring_root_and_op_count.op_count;
// don't allow a new root to be set if there are still outstanding ops that have not been
// executed, unless override_previous_root is set
require!(
current_op_count == ctx.accounts.root_metadata.post_op_count
|| metadata.override_previous_root,
Expand Down
10 changes: 10 additions & 0 deletions chains/solana/contracts/target/idl/mcm.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,16 @@
"isMut": true,
"isSigner": false
},
{
"name": "rootMetadata",
"isMut": true,
"isSigner": false
},
{
"name": "expiringRootAndOpCount",
"isMut": true,
"isSigner": false
},
{
"name": "authority",
"isMut": true,
Expand Down
3 changes: 3 additions & 0 deletions chains/solana/contracts/tests/config/mcm_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ var (
MaxNumSigners = 200
MaxAppendSignerBatchSize = 45
MaxAppendSignatureBatchSize = 13

McmEmptyRoot = [32]byte{}
McmEmptyTimestamp = uint32(0)
// root related configs
// the following diagram shows the structure of the signers and groups:
// ref: https://github.com/smartcontractkit/ccip-owner-contracts/blob/56f1a8d2cd4ba5ef2b99d2185ffded53957dd410/src/ManyChainMultiSig.sol#L65
Expand Down
86 changes: 86 additions & 0 deletions chains/solana/contracts/tests/mcms/mcm.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,47 @@ func NewMcmMultisig(name [32]byte) mcmsUtils.Multisig {
}
}

// instructions builder for preloading signers
func McmPreloadSignersIxs(signerAddresses [][20]uint8, msigName [32]byte, multisigCfgPDA solana.PublicKey, cfgSignersPDA solana.PublicKey, authority solana.PublicKey, appendChunkSize int) ([]solana.Instruction, error) {
ixs := make([]solana.Instruction, 0)

parsedTotalSigners, pErr := mcmsUtils.SafeToUint8(len(signerAddresses))
if pErr != nil {
return nil, pErr
}
initSignersIx, isErr := mcm.NewInitSignersInstruction(
msigName,
parsedTotalSigners,
multisigCfgPDA,
cfgSignersPDA,
authority,
solana.SystemProgramID,
).ValidateAndBuild()
if isErr != nil {
return nil, isErr
}
ixs = append(ixs, initSignersIx)

appendSignersIxs, asErr := AppendSignersIxs(signerAddresses, msigName, multisigCfgPDA, cfgSignersPDA, authority, appendChunkSize)
if asErr != nil {
return nil, asErr
}
ixs = append(ixs, appendSignersIxs...)

finalizeSignersIx, fsErr := mcm.NewFinalizeSignersInstruction(
msigName,
multisigCfgPDA,
cfgSignersPDA,
authority,
).ValidateAndBuild()
if fsErr != nil {
return nil, fsErr
}
ixs = append(ixs, finalizeSignersIx)

return ixs, nil
}

// get chunked append instructions to preload signers to pda, required before set_config
func AppendSignersIxs(signerAddresses [][20]uint8, msigName [32]byte, multisigCfgPDA solana.PublicKey, cfgSignersPDA solana.PublicKey, authority solana.PublicKey, chunkSize int) ([]solana.Instruction, error) {
if chunkSize > config.MaxAppendSignerBatchSize {
Expand All @@ -124,6 +165,51 @@ func AppendSignersIxs(signerAddresses [][20]uint8, msigName [32]byte, multisigCf
return ixs, nil
}

// instructions builder for preloading signatures
func McmPreloadSignaturesIxs(signatures []mcm.Signature, msigName [32]byte, root [32]uint8, validUntil uint32, signaturesPDA solana.PublicKey, authority solana.PublicKey, appendChunkSize int) ([]solana.Instruction, error) {
ixs := make([]solana.Instruction, 0)

parsedTotalSigs, pErr := mcmsUtils.SafeToUint8(len(signatures))
if pErr != nil {
return nil, pErr
}

initSigsIx, isErr := mcm.NewInitSignaturesInstruction(
msigName,
root,
validUntil,
parsedTotalSigs,
signaturesPDA,
authority,
solana.SystemProgramID,
).ValidateAndBuild()
if isErr != nil {
return nil, isErr
}
ixs = append(ixs, initSigsIx)

appendSigsIxs, asErr := AppendSignaturesIxs(signatures, msigName, root, validUntil, signaturesPDA, authority, appendChunkSize)
if asErr != nil {
return nil, asErr
}

ixs = append(ixs, appendSigsIxs...)

finalizeSigsIx, fsErr := mcm.NewFinalizeSignaturesInstruction(
msigName,
root,
validUntil,
signaturesPDA,
authority,
).ValidateAndBuild()
if fsErr != nil {
return nil, fsErr
}
ixs = append(ixs, finalizeSigsIx)

return ixs, nil
}

// get chunked append instructions to preload signatures to pda, required before set_root
func AppendSignaturesIxs(signatures []mcm.Signature, msigName [32]byte, root [32]uint8, validUntil uint32, signaturesPDA solana.PublicKey, authority solana.PublicKey, chunkSize int) ([]solana.Instruction, error) {
if chunkSize > config.MaxAppendSignatureBatchSize {
Expand Down
72 changes: 12 additions & 60 deletions chains/solana/contracts/tests/mcms/mcm_multiple_multisigs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,37 +114,10 @@ func TestMcmMultipleMultisigs(t *testing.T) {
signerAddresses := mcmConfig.SignerAddresses

t.Run("mcm:set_config: preload signers on PDA", func(t *testing.T) {
ixs := make([]solana.Instruction, 0)
preloadIxs, pierr := McmPreloadSignersIxs(signerAddresses, testMsigName1, multisigConfigPDA1, configSignersPDA1, admin.PublicKey(), config.MaxAppendSignerBatchSize)
require.NoError(t, pierr)

parsedTotalSigners, err := mcmsUtils.SafeToUint8(len(signerAddresses))
require.NoError(t, err)

initSignersIx, err := mcm.NewInitSignersInstruction(
testMsigName1,
parsedTotalSigners,
multisigConfigPDA1,
configSignersPDA1,
admin.PublicKey(),
solana.SystemProgramID,
).ValidateAndBuild()

require.NoError(t, err)
ixs = append(ixs, initSignersIx)

appendSignersIxs, err := AppendSignersIxs(signerAddresses, testMsigName1, multisigConfigPDA1, configSignersPDA1, admin.PublicKey(), config.MaxAppendSignerBatchSize)
require.NoError(t, err)
ixs = append(ixs, appendSignersIxs...)

finalizeSignersIx, err := mcm.NewFinalizeSignersInstruction(
testMsigName1,
multisigConfigPDA1,
configSignersPDA1,
admin.PublicKey(),
).ValidateAndBuild()
require.NoError(t, err)
ixs = append(ixs, finalizeSignersIx)

for _, ix := range ixs {
for _, ix := range preloadIxs {
utils.SendAndConfirm(ctx, t, solanaGoClient, []solana.Instruction{ix}, admin, config.DefaultCommitment)
}

Expand All @@ -169,6 +142,8 @@ func TestMcmMultipleMultisigs(t *testing.T) {
mcmConfig.ClearRoot,
multisigConfigPDA1,
configSignersPDA1,
rootMetadataPDA1,
expiringRootAndOpCountPDA1,
admin.PublicKey(),
solana.SystemProgramID,
).ValidateAndBuild()
Expand Down Expand Up @@ -262,37 +237,10 @@ func TestMcmMultipleMultisigs(t *testing.T) {
signerAddresses := mcmConfig.SignerAddresses

t.Run("mcm:set_config: preload signers on PDA", func(t *testing.T) {
ixs := make([]solana.Instruction, 0)

parsedTotalSigners, err := mcmsUtils.SafeToUint8(len(signerAddresses))
require.NoError(t, err)

initSignersIx, err := mcm.NewInitSignersInstruction(
testMsigName2,
parsedTotalSigners,
multisigConfigPDA2,
configSignersPDA2,
admin.PublicKey(),
solana.SystemProgramID,
).ValidateAndBuild()

require.NoError(t, err)
ixs = append(ixs, initSignersIx)

appendSignersIxs, err := AppendSignersIxs(signerAddresses, testMsigName2, multisigConfigPDA2, configSignersPDA2, admin.PublicKey(), config.MaxAppendSignerBatchSize)
require.NoError(t, err)
ixs = append(ixs, appendSignersIxs...)

finalizeSignersIx, err := mcm.NewFinalizeSignersInstruction(
testMsigName2,
multisigConfigPDA2,
configSignersPDA2,
admin.PublicKey(),
).ValidateAndBuild()
require.NoError(t, err)
ixs = append(ixs, finalizeSignersIx)
preloadIxs, pierr := McmPreloadSignersIxs(signerAddresses, testMsigName2, multisigConfigPDA2, configSignersPDA2, admin.PublicKey(), config.MaxAppendSignerBatchSize)
require.NoError(t, pierr)

for _, ix := range ixs {
for _, ix := range preloadIxs {
utils.SendAndConfirm(ctx, t, solanaGoClient, []solana.Instruction{ix}, admin, config.DefaultCommitment)
}

Expand All @@ -317,6 +265,8 @@ func TestMcmMultipleMultisigs(t *testing.T) {
mcmConfig.ClearRoot,
multisigConfigPDA2,
configSignersPDA2,
rootMetadataPDA2,
expiringRootAndOpCountPDA2,
admin.PublicKey(),
solana.SystemProgramID,
).ValidateAndBuild()
Expand All @@ -336,6 +286,8 @@ func TestMcmMultipleMultisigs(t *testing.T) {
mcmConfig.ClearRoot,
multisigConfigPDA2,
configSignersPDA2,
rootMetadataPDA2,
expiringRootAndOpCountPDA2,
admin.PublicKey(),
solana.SystemProgramID,
).ValidateAndBuild()
Expand Down
Loading

0 comments on commit 72eea70

Please sign in to comment.