Skip to content
Merged
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
3 changes: 3 additions & 0 deletions bindings/bind/bcs_decoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,9 @@ func TestDeserializer(t *testing.T) {
}

func TestDeserializer_ShouldFail(t *testing.T) {
// TODO: this test will fail when https://github.com/block-vision/sui-go-sdk/pull/78
// is released and will have to be removed

// mystenbcs encoder has an issue where fixed-size byte arrays ([n]byte) are treated as regular slices.
// so encoding a u128 via their encoder will result in failure to decode it back.
// We're using this behavior to test our DeserializeBCS error handling.
Expand Down
56 changes: 49 additions & 7 deletions bindings/bind/type_converter.go
Original file line number Diff line number Diff line change
Expand Up @@ -585,20 +585,62 @@ func convertVectorToBCS(innerType string, value any) (any, error) {
type SuiAddressBytes [32]byte

func bcsEncode(value any) ([]byte, error) {
if addrs, ok := value.([][32]byte); ok {
suiAddrs := make([]SuiAddressBytes, len(addrs))
for i, addr := range addrs {
suiAddrs[i] = SuiAddressBytes(addr)
}
value = suiAddrs
// Normalize value before encoding
normalized, err := normalizeValue(value)
if err != nil {
return nil, err
}

bcsEncodedMsg := bytes.Buffer{}
bcsEncoder := mystenbcs.NewEncoder(&bcsEncodedMsg)
err := bcsEncoder.Encode(value)
err = bcsEncoder.Encode(normalized)
if err != nil {
return nil, err
}

return bcsEncodedMsg.Bytes(), nil
}

// normalizeValue converts special Go types into the correct BCS-friendly form.
// TODO: This is a temporary solution until sui-go-sdk addresses [n]bytes bug
// https://github.com/block-vision/sui-go-sdk/issues/75 won't be necessary after release
// fixes vector<address> and vector<vector<address>> encoding.
func normalizeValue(value any) (any, error) {
switch v := value.(type) {
case [][32]byte:
// Single-level vector<address>
return convertToSliceSuiAddressBytes(v), nil
case []interface{}:
// Possible nested address vectors: [][][32]byte (wrapped as []interface{}) (vector<vector<address>>)
if len(v) == 0 {
return v, nil
}
// Check if the first element matches the pattern
if _, ok := v[0].([][32]byte); !ok {
return value, nil
}
result := make([][]SuiAddressBytes, len(v))
for i, item := range v {
// Make sure all the items are of the expected type
addrs, ok := item.([][32]byte)
if !ok {
return nil, fmt.Errorf("expected [][32]byte at index %d, got %T", i, item)
}
result[i] = convertToSliceSuiAddressBytes(addrs)
}

return result, nil
}

return value, nil
}

// convertToSuiAddressBytes converts a slice of [32]byte into []SuiAddressBytes.
func convertToSliceSuiAddressBytes(addresses [][32]byte) []SuiAddressBytes {
out := make([]SuiAddressBytes, len(addresses))
for i, addr := range addresses {
out[i] = SuiAddressBytes(addr)
}

return out
}
92 changes: 69 additions & 23 deletions deployment/ops/ccip_offramp/op_deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,7 @@ var setOCR3ConfigHandler = func(b cld_ops.Bundle, deps sui_ops.OpTxDeps, input S
return sui_ops.OpTxResult[DeployCCIPOffRampObjects]{}, err
}

opts := deps.GetCallOpts()
opts.Signer = deps.Signer
tx, err := offRampPackage.SetOcr3Config(
b.GetContext(),
opts,
encodedCall, err := offRampPackage.Encoder().SetOcr3Config(
bind.Object{Id: input.CCIPObjectRefId},
bind.Object{Id: input.OffRampStateId},
bind.Object{Id: input.OwnerCapObjectId},
Expand All @@ -142,25 +138,52 @@ var setOCR3ConfigHandler = func(b cld_ops.Bundle, deps sui_ops.OpTxDeps, input S
input.Transmitters,
)
if err != nil {
return sui_ops.OpTxResult[DeployCCIPOffRampObjects]{}, fmt.Errorf("failed to execute set ocr3 config in offramp: %w", err)
return sui_ops.OpTxResult[DeployCCIPOffRampObjects]{}, fmt.Errorf("failed to encode SetOcr3Config call: %w", err)
}
call, err := sui_ops.ToTransactionCall(encodedCall, input.OffRampStateId)
if err != nil {
return sui_ops.OpTxResult[DeployCCIPOffRampObjects]{}, fmt.Errorf("failed to convert encoded call to TransactionCall: %w", err)
}
if deps.Signer == nil {
b.Logger.Infow("Skipping execution of SetOcr3Config on OffRamp as per no Signer provided")
return sui_ops.OpTxResult[DeployCCIPOffRampObjects]{
Digest: "",
PackageId: input.OffRampPackageId,
Objects: DeployCCIPOffRampObjects{},
Call: call,
}, nil
}

opts := deps.GetCallOpts()
opts.Signer = deps.Signer
tx, err := offRampPackage.Bound().ExecuteTransaction(
b.GetContext(),
opts,
encodedCall,
)
if err != nil {
return sui_ops.OpTxResult[DeployCCIPOffRampObjects]{}, fmt.Errorf("failed to execute SetOcr3Config on OffRamp: %w", err)
}

b.Logger.Infow("OCR3 config set on OffRamp")

return sui_ops.OpTxResult[DeployCCIPOffRampObjects]{
Digest: tx.Digest,
PackageId: input.OffRampPackageId,
Objects: DeployCCIPOffRampObjects{},
}, err
Call: call,
}, nil
}

type ApplySourceChainConfigUpdateInput struct {
CCIPObjectRef string
OffRampPackageId string
OffRampStateId string
OwnerCapObjectId string
SourceChainsSelectors []uint64
SourceChainsIsEnabled []bool
SouceChainsIsRMNVerificationDisabled []bool
SourceChainsOnRamp [][]byte
CCIPObjectRef string
OffRampPackageId string
OffRampStateId string
OwnerCapObjectId string
SourceChainsSelectors []uint64
SourceChainsIsEnabled []bool
SourceChainsIsRMNVerificationDisabled []bool
SourceChainsOnRamp [][]byte
}

var applySourceChainConfigUpdateHandler = func(b cld_ops.Bundle, deps sui_ops.OpTxDeps, input ApplySourceChainConfigUpdateInput) (output sui_ops.OpTxResult[DeployCCIPOffRampObjects], err error) {
Expand All @@ -169,28 +192,51 @@ var applySourceChainConfigUpdateHandler = func(b cld_ops.Bundle, deps sui_ops.Op
return sui_ops.OpTxResult[DeployCCIPOffRampObjects]{}, err
}

opts := deps.GetCallOpts()
opts.Signer = deps.Signer
tx, err := offRampPackage.ApplySourceChainConfigUpdates(
b.GetContext(),
opts,
encodedCall, err := offRampPackage.Encoder().ApplySourceChainConfigUpdates(
bind.Object{Id: input.CCIPObjectRef},
bind.Object{Id: input.OffRampStateId},
bind.Object{Id: input.OwnerCapObjectId},
input.SourceChainsSelectors,
input.SourceChainsIsEnabled,
input.SouceChainsIsRMNVerificationDisabled,
input.SourceChainsIsRMNVerificationDisabled,
input.SourceChainsOnRamp,
)
if err != nil {
return sui_ops.OpTxResult[DeployCCIPOffRampObjects]{}, fmt.Errorf("failed to execute applySourceChainConfigUpdate in offramp: %w", err)
return sui_ops.OpTxResult[DeployCCIPOffRampObjects]{}, fmt.Errorf("failed to encode ApplySourceChainConfigUpdates call: %w", err)
}
call, err := sui_ops.ToTransactionCall(encodedCall, input.OffRampStateId)
if err != nil {
return sui_ops.OpTxResult[DeployCCIPOffRampObjects]{}, fmt.Errorf("failed to convert encoded call to TransactionCall: %w", err)
}
if deps.Signer == nil {
b.Logger.Infow("Skipping execution of ApplySourceChainConfigUpdates on OffRamp as per no Signer provided")
return sui_ops.OpTxResult[DeployCCIPOffRampObjects]{
Digest: "",
PackageId: input.OffRampPackageId,
Objects: DeployCCIPOffRampObjects{},
Call: call,
}, nil
}

opts := deps.GetCallOpts()
opts.Signer = deps.Signer
tx, err := offRampPackage.Bound().ExecuteTransaction(
b.GetContext(),
opts,
encodedCall,
)
if err != nil {
return sui_ops.OpTxResult[DeployCCIPOffRampObjects]{}, fmt.Errorf("failed to execute ApplySourceChainConfigUpdates on OffRamp: %w", err)
}

b.Logger.Infow("Source chain config updates applied on OffRamp")

return sui_ops.OpTxResult[DeployCCIPOffRampObjects]{
Digest: tx.Digest,
PackageId: input.OffRampPackageId,
Objects: DeployCCIPOffRampObjects{},
}, err
Call: call,
}, nil
}

type AddPackageIdOffRampInput struct {
Expand Down
2 changes: 2 additions & 0 deletions deployment/ops/ccip_offramp/op_registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ var AllOperationsOfframp = []cld_ops.Operation[any, any, any]{
*TransferOwnershipOffRampOp.AsUntyped(),
*AcceptOwnershipOffRampOp.AsUntyped(),
*ExecuteOwnershipTransferToMcmsOffRampOp.AsUntyped(),
*ApplySourceChainConfigUpdatesOp.AsUntyped(),
*SetOCR3ConfigOp.AsUntyped(),
}
Loading
Loading