Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions deployment/changesets/cs_block_function.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type BlockFunctionConfig struct {
ModuleName string `yaml:"moduleName"`
FunctionName string `yaml:"functionName"`
Version uint8 `yaml:"version"`
LatestPackageId string `yaml:"latestPackageId,omitempty"`
TimelockConfig *utils.TimelockConfig `yaml:"timelockConfig,omitempty"`
}

Expand Down Expand Up @@ -62,6 +63,7 @@ func (d BlockFunction) Apply(e cldf.Environment, config BlockFunctionConfig) (cl
ModuleName: config.ModuleName,
FunctionName: config.FunctionName,
Version: config.Version,
LatestPackageId: config.LatestPackageId,
})
if err != nil {
return cldf.ChangesetOutput{}, fmt.Errorf("failed to block function for Sui chain %d: %w", config.SuiChainSelector, err)
Expand Down
2 changes: 2 additions & 0 deletions deployment/changesets/cs_block_version.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type BlockVersionConfig struct {
CCIPPackageId string `yaml:"ccipPackageId"`
ModuleName string `yaml:"moduleName"`
Version uint8 `yaml:"version"`
LatestPackageId string `yaml:"latestPackageId,omitempty"`
TimelockConfig *utils.TimelockConfig `yaml:"timelockConfig,omitempty"`
}

Expand Down Expand Up @@ -60,6 +61,7 @@ func (d BlockVersion) Apply(e cldf.Environment, config BlockVersionConfig) (cldf
OwnerCapObjectId: chainState.CCIPOwnerCapObjectId,
ModuleName: config.ModuleName,
Version: config.Version,
LatestPackageId: config.LatestPackageId,
})
if err != nil {
return cldf.ChangesetOutput{}, fmt.Errorf("failed to block version for Sui chain %d: %w", config.SuiChainSelector, err)
Expand Down
4 changes: 2 additions & 2 deletions deployment/ops/ccip/op_state_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type AddPackageIdStateObjectObjects struct {
}

var addPackageIdStateObjectHandler = func(b cld_ops.Bundle, deps sui_ops.OpTxDeps, input AddPackageIdStateObjectInput) (output sui_ops.OpTxResult[AddPackageIdStateObjectObjects], err error) {
contract, err := module_state_object.NewStateObject(input.CCIPPackageId, deps.Client)
contract, err := module_state_object.NewStateObject(input.PackageId, deps.Client)
if err != nil {
return sui_ops.OpTxResult[AddPackageIdStateObjectObjects]{}, fmt.Errorf("failed to create StateObject contract: %w", err)
}
Expand Down Expand Up @@ -91,7 +91,7 @@ type RemovePackageIdStateObjectObjects struct {
}

var removePackageIdStateObjectHandler = func(b cld_ops.Bundle, deps sui_ops.OpTxDeps, input RemovePackageIdStateObjectInput) (output sui_ops.OpTxResult[RemovePackageIdStateObjectObjects], err error) {
contract, err := module_state_object.NewStateObject(input.CCIPPackageId, deps.Client)
contract, err := module_state_object.NewStateObject(input.PackageId, deps.Client)
if err != nil {
return sui_ops.OpTxResult[RemovePackageIdStateObjectObjects]{}, fmt.Errorf("failed to create StateObject contract: %w", err)
}
Expand Down
11 changes: 5 additions & 6 deletions deployment/ops/ccip/op_state_object_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,32 +86,31 @@ func TestStateObjectOperations(t *testing.T) {
})

t.Run("Test Add Package ID", func(t *testing.T) {
newPackageId := "0x123456789abcdef" // Example package ID
addReport, err := cld_ops.ExecuteOperation(bundle, AddPackageIdStateObjectOp, deps, AddPackageIdStateObjectInput{
CCIPPackageId: ccipReport.Output.PackageId,
CCIPObjectRefObjectId: ccipReport.Output.Objects.CCIPObjectRefObjectId,
OwnerCapObjectId: ccipReport.Output.Objects.OwnerCapObjectId,
PackageId: newPackageId,
PackageId: ccipReport.Output.PackageId,
})
require.NoError(t, err, "failed to add package ID")
require.NotEmpty(t, addReport.Output.Digest, "add package ID transaction should have a digest")
})

t.Run("Test Remove Package ID", func(t *testing.T) {
// First add a package ID to remove
newPackageId := "0xabcdef1234567890abcdef1234567890abcdef12"
// First add the package ID so we can remove it
_, err := cld_ops.ExecuteOperation(bundle, AddPackageIdStateObjectOp, deps, AddPackageIdStateObjectInput{
CCIPPackageId: ccipReport.Output.PackageId,
CCIPObjectRefObjectId: ccipReport.Output.Objects.CCIPObjectRefObjectId,
OwnerCapObjectId: ccipReport.Output.Objects.OwnerCapObjectId,
PackageId: newPackageId,
PackageId: ccipReport.Output.PackageId,
})
require.NoError(t, err, "failed to add package ID for removal test")
// Now remove the package ID
removeReport, err := cld_ops.ExecuteOperation(bundle, RemovePackageIdStateObjectOp, deps, RemovePackageIdStateObjectInput{
CCIPPackageId: ccipReport.Output.PackageId,
CCIPObjectRefObjectId: ccipReport.Output.Objects.CCIPObjectRefObjectId,
OwnerCapObjectId: ccipReport.Output.Objects.OwnerCapObjectId,
PackageId: newPackageId,
PackageId: ccipReport.Output.PackageId,
})
require.NoError(t, err, "failed to remove package ID")
require.NotEmpty(t, removeReport.Output.Digest, "remove package ID transaction should have a digest")
Expand Down
12 changes: 12 additions & 0 deletions deployment/ops/ccip/op_upgrade_registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ type BlockVersionInput struct {
OwnerCapObjectId string
ModuleName string
Version uint8
// LatestPackageId is emitted on Call for MCMS proposals as additionalFields.latest_package_id.
LatestPackageId string `json:"latestPackageId,omitempty"`
}

type BlockVersionObjects struct {
Expand All @@ -109,6 +111,7 @@ var blockVersionHandler = func(b cld_ops.Bundle, deps sui_ops.OpTxDeps, input Bl
if err != nil {
return sui_ops.OpTxResult[BlockVersionObjects]{}, fmt.Errorf("failed to convert encoded call to TransactionCall: %w", err)
}
call.LatestPackageId = input.LatestPackageId
if deps.Signer == nil {
b.Logger.Infow("Skipping execution of BlockVersion on UpgradeRegistry as per no Signer provided",
"moduleName", input.ModuleName, "version", input.Version)
Expand Down Expand Up @@ -155,6 +158,8 @@ type UnblockVersionInput struct {
OwnerCapObjectId string
ModuleName string
Version uint8
// LatestPackageId is emitted on Call for MCMS proposals as additionalFields.latest_package_id.
LatestPackageId string `json:"latestPackageId,omitempty"`
}

type UnblockVersionObjects struct {
Expand All @@ -180,6 +185,7 @@ var unblockVersionHandler = func(b cld_ops.Bundle, deps sui_ops.OpTxDeps, input
if err != nil {
return sui_ops.OpTxResult[UnblockVersionObjects]{}, fmt.Errorf("failed to convert encoded call to TransactionCall: %w", err)
}
call.LatestPackageId = input.LatestPackageId
if deps.Signer == nil {
b.Logger.Infow("Skipping execution of UnblockVersion on UpgradeRegistry as per no Signer provided",
"moduleName", input.ModuleName, "version", input.Version)
Expand Down Expand Up @@ -227,6 +233,8 @@ type BlockFunctionInput struct {
ModuleName string
FunctionName string
Version uint8
// LatestPackageId is emitted on Call for MCMS proposals as additionalFields.latest_package_id.
LatestPackageId string `json:"latestPackageId,omitempty"`
}

type BlockFunctionObjects struct {
Expand All @@ -252,6 +260,7 @@ var blockFunctionHandler = func(b cld_ops.Bundle, deps sui_ops.OpTxDeps, input B
if err != nil {
return sui_ops.OpTxResult[BlockFunctionObjects]{}, fmt.Errorf("failed to convert encoded call to TransactionCall: %w", err)
}
call.LatestPackageId = input.LatestPackageId
if deps.Signer == nil {
b.Logger.Infow("Skipping execution of BlockFunction on UpgradeRegistry as per no Signer provided",
"moduleName", input.ModuleName, "functionName", input.FunctionName, "version", input.Version)
Expand Down Expand Up @@ -300,6 +309,8 @@ type UnblockFunctionInput struct {
ModuleName string
FunctionName string
Version uint8
// LatestPackageId is emitted on Call for MCMS proposals as additionalFields.latest_package_id.
LatestPackageId string `json:"latestPackageId,omitempty"`
}

type UnblockFunctionObjects struct {
Expand All @@ -325,6 +336,7 @@ var unblockFunctionHandler = func(b cld_ops.Bundle, deps sui_ops.OpTxDeps, input
if err != nil {
return sui_ops.OpTxResult[UnblockFunctionObjects]{}, fmt.Errorf("failed to convert encoded call to TransactionCall: %w", err)
}
call.LatestPackageId = input.LatestPackageId
if deps.Signer == nil {
b.Logger.Infow("Skipping execution of UnblockFunction on UpgradeRegistry as per no Signer provided",
"moduleName", input.ModuleName, "functionName", input.FunctionName, "version", input.Version)
Expand Down
4 changes: 4 additions & 0 deletions deployment/ops/mcms/op_proposal_generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ var generateProposalHandler = func(b cld_ops.Bundle, deps sui_ops.OpTxDeps, inpu
if err != nil {
return mcms.TimelockProposal{}, fmt.Errorf("failed to create transaction for operation %s: %w", def.ID, err)
}
tx, err = utils.MergeLatestPackageIDIntoMCMSTransaction(tx, call.LatestPackageId)
if err != nil {
return mcms.TimelockProposal{}, fmt.Errorf("set latest_package_id for operation %s: %w", def.ID, err)
}
mcmsTxs[i] = tx
}

Expand Down
3 changes: 3 additions & 0 deletions deployment/ops/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ type TransactionCall struct {
Data []byte
StateObjID string
TypeArgs []string
// LatestPackageId is copied into MCMS transaction additionalFields as latest_package_id when
// building timelock proposals; PackageID remains the on-chain target (original package).
LatestPackageId string `json:"latestPackageId,omitempty"`
}

type OpTxDeps struct {
Expand Down
24 changes: 24 additions & 0 deletions deployment/utils/mcms.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,30 @@ func ExtractTransactionCall(output interface{}, operationID string) (sui_ops.Tra
return call, nil
}

// MergeLatestPackageIDIntoMCMSTransaction sets sdk/sui.AdditionalFields.latest_package_id on a built
// MCMS transaction. Pass empty latestPackageID for a no-op. Preserves existing JSON object keys
// (e.g. compiled_modules) by merging at RawMessage granularity.
func MergeLatestPackageIDIntoMCMSTransaction(tx types.Transaction, latestPackageID string) (types.Transaction, error) {
if latestPackageID == "" {
return tx, nil
}
var fields map[string]json.RawMessage
if err := json.Unmarshal(tx.AdditionalFields, &fields); err != nil {
return types.Transaction{}, fmt.Errorf("unmarshal additionalFields: %w", err)
}
quoted, err := json.Marshal(latestPackageID)
if err != nil {
return types.Transaction{}, err
}
fields["latest_package_id"] = quoted
merged, err := json.Marshal(fields)
if err != nil {
return types.Transaction{}, err
}
tx.AdditionalFields = merged
return tx, nil
}

func getRoleFromAction(action types.TimelockAction) (suisdk.TimelockRole, error) {
switch action {
case types.TimelockActionSchedule:
Expand Down
Loading