diff --git a/executable.go b/executable.go index c4774eba..f7cdd60c 100644 --- a/executable.go +++ b/executable.go @@ -67,7 +67,7 @@ func (e *Executable) SetRoot(ctx context.Context, chainSelector types.ChainSelec return types.TransactionResult{}, err } - hash, err := e.proposal.SigningHash() //nolint:contextcheck //OPT-400 + hash, err := e.proposal.SigningHash() //nolint:contextcheck,nolintlint //OPT-400 if err != nil { return types.TransactionResult{}, err } diff --git a/factory.go b/factory.go index f50fbfb5..57799a12 100644 --- a/factory.go +++ b/factory.go @@ -81,7 +81,7 @@ func newTimelockConverter(csel types.ChainSelector, metadata types.ChainMetadata } func operationIDFn(_ context.Context, csel types.ChainSelector) (sdk.OperationID, error) { - family, err := types.GetChainSelectorFamily(csel) //nolint:contextcheck //OPT-400 + family, err := types.GetChainSelectorFamily(csel) //nolint:contextcheck,nolintlint //OPT-400 if err != nil { return nil, err } diff --git a/go.mod b/go.mod index 8e31bde3..13c1762f 100644 --- a/go.mod +++ b/go.mod @@ -26,7 +26,7 @@ require ( github.com/samber/lo v1.53.0 github.com/smartcontractkit/chain-selectors v1.0.101 github.com/smartcontractkit/chainlink-aptos v0.0.0-20260428085939-5c70de12dbfc - github.com/smartcontractkit/chainlink-canton v0.0.0-20260609155219-dcbe77d4a320 + github.com/smartcontractkit/chainlink-canton v0.0.0-20260610231852-15f1d20f2728 github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260129103204-4c8453dd8139 github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20260129103204-4c8453dd8139 github.com/smartcontractkit/chainlink-common v0.11.2-0.20260506120607-7f10be016c89 @@ -34,7 +34,7 @@ require ( github.com/smartcontractkit/chainlink-testing-framework/framework v0.16.5 github.com/smartcontractkit/chainlink-ton v1.0.5-0.20260514223130-48bc90aca745 github.com/smartcontractkit/freeport v0.1.3-0.20250828155247-add56fa28aad - github.com/smartcontractkit/go-daml v0.0.0-20260604143752-c6f6567940ba + github.com/smartcontractkit/go-daml v0.0.0-20260610225315-f38fea9a45b0 github.com/spf13/cast v1.10.0 github.com/stellar/go-stellar-sdk v0.5.0 github.com/stretchr/testify v1.11.1 diff --git a/go.sum b/go.sum index b85b4ebc..ca009629 100644 --- a/go.sum +++ b/go.sum @@ -686,8 +686,8 @@ github.com/smartcontractkit/chain-selectors v1.0.101 h1:TF4ma9h3QeyIZ8XoEmgI5lrU github.com/smartcontractkit/chain-selectors v1.0.101/go.mod h1:qy7whtgG5g+7z0jt0nRyii9bLND9m15NZTzuQPkMZ5w= github.com/smartcontractkit/chainlink-aptos v0.0.0-20260428085939-5c70de12dbfc h1:Um9FBcf0JNSFuGbxgccDG1vM3cNrMGy0SdJ7r6VbX0o= github.com/smartcontractkit/chainlink-aptos v0.0.0-20260428085939-5c70de12dbfc/go.mod h1:zfE2R7887kiwXkGTHKPe5NBgwhFwIC3pnA2uAxrbvig= -github.com/smartcontractkit/chainlink-canton v0.0.0-20260609155219-dcbe77d4a320 h1:ix4tCtSTB7S2XGll+uqnhrqAQ+2iW/Zk/vnPjBMYRB0= -github.com/smartcontractkit/chainlink-canton v0.0.0-20260609155219-dcbe77d4a320/go.mod h1:WKmNUX4oy8IvB66ukudrE99uaXjlZ7WghCDwHOTyB1c= +github.com/smartcontractkit/chainlink-canton v0.0.0-20260610231852-15f1d20f2728 h1:Tnf/CFNE0Rr27s4j7GucxurjidpI3qSkoDUzHPYVPJ8= +github.com/smartcontractkit/chainlink-canton v0.0.0-20260610231852-15f1d20f2728/go.mod h1:8GZ82TYTEMP8KolUWbYMVJcIK+rwGQHA3K4opBeQY60= github.com/smartcontractkit/chainlink-ccip v0.1.1-solana.0.20260428205619-2db1389501a1 h1:p0nFrTYrOQzDhWYm6suaM5CoWiXV5NV7llHnp6/Kn/8= github.com/smartcontractkit/chainlink-ccip v0.1.1-solana.0.20260428205619-2db1389501a1/go.mod h1:1XxxpkgCmG/z6y30yRuVrcxre6zixIVX3xzi706Db/8= github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260129103204-4c8453dd8139 h1:jkChf04hhdiMBApbb+lLDxHMY62Md6UeM7v++GSw3K8= @@ -724,8 +724,8 @@ github.com/smartcontractkit/chainlink-tron/relayer/gotron-sdk v0.0.4 h1:J4qtAo0Z github.com/smartcontractkit/chainlink-tron/relayer/gotron-sdk v0.0.4/go.mod h1:4WhGgCA0smBbBud5mK+jnDb2wwndMvoqaWBJ3OV/7Bw= github.com/smartcontractkit/freeport v0.1.3-0.20250828155247-add56fa28aad h1:lgHxTHuzJIF3Vj6LSMOnjhqKgRqYW+0MV2SExtCYL1Q= github.com/smartcontractkit/freeport v0.1.3-0.20250828155247-add56fa28aad/go.mod h1:T4zH9R8R8lVWKfU7tUvYz2o2jMv1OpGCdpY2j2QZXzU= -github.com/smartcontractkit/go-daml v0.0.0-20260604143752-c6f6567940ba h1:peYJwUWOv54aigdk1VFzkmXdZmZK4xixfxv0Af1l6/I= -github.com/smartcontractkit/go-daml v0.0.0-20260604143752-c6f6567940ba/go.mod h1:SqWfl3Bp9NleC9jhzFUaOGzOZeKfldpY4QOW6A6NSNM= +github.com/smartcontractkit/go-daml v0.0.0-20260610225315-f38fea9a45b0 h1:7BFrFhmw4R8vPBQRvQ8eQ87Zs9M5Ij+6WBHMFb8Obmo= +github.com/smartcontractkit/go-daml v0.0.0-20260610225315-f38fea9a45b0/go.mod h1:SqWfl3Bp9NleC9jhzFUaOGzOZeKfldpY4QOW6A6NSNM= github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 h1:12ijqMM9tvYVEm+nR826WsrNi6zCKpwBhuApq127wHs= github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7/go.mod h1:FX7/bVdoep147QQhsOPkYsPEXhGZjeYx6lBSaSXtZOA= github.com/smartcontractkit/libocr v0.0.0-20260304194147-a03701e2c02e h1:poXTj5cFVM6XfC4HICIDYkDVc/A6OYB0eeID0wU2JQE= diff --git a/sdk/canton/constants.go b/sdk/canton/constants.go index b4a8d26d..8fdc2e87 100644 --- a/sdk/canton/constants.go +++ b/sdk/canton/constants.go @@ -19,4 +19,6 @@ const ( mcmsInstanceIDCCIP = "mcms-ccip" mcmsInstanceIDCCV = "mcms-ccv" mcmsInstanceIDDefault = "mcms" + + instanceIDFieldLabel = "instanceId" ) diff --git a/sdk/canton/decoder_test.go b/sdk/canton/decoder_test.go index 3bee347a..de42d249 100644 --- a/sdk/canton/decoder_test.go +++ b/sdk/canton/decoder_test.go @@ -88,7 +88,7 @@ func TestDecoder_Deploy(t *testing.T) { dec, err := NewDecoder().Decode(tx, "") require.NoError(t, err) require.Equal(t, "CCIPFactory::DeployRMNRemote", dec.MethodName()) - require.Equal(t, []string{"instanceId", "rmnOwner", "ccipOwner", "customObservers", "cursedSubjects"}, dec.Keys()) + require.Equal(t, []string{instanceIDFieldLabel, "rmnOwner", "ccipOwner", "customObservers", "cursedSubjects"}, dec.Keys()) // toDisplayArg strips Daml type aliases to plain Go primitives for the renderer. require.Equal(t, "rmn-remote-1", dec.Args()[0]) require.Equal(t, "alice::abc123", dec.Args()[1]) @@ -255,3 +255,50 @@ func candidateTypeNames(candidateTypes []reflect.Type) []string { return names } + +// TestDecoder_DeployExecutor_FinalityVariant decodes DeployExecutorParams +// which has a core.FinalityConfig Daml variant (uint8 tag + payload) +func TestDecoder_DeployExecutor_FinalityVariant(t *testing.T) { + t.Parallel() + + const proposalHex = "0e6578656375746f722d77776268714f636369704f776e65723a3a3132323065333832663465353762303831356536626537333730303665333831653662376465343438653036626430333365636536646634393830313738373966353531000000000000000a0000" + raw, err := hex.DecodeString(proposalHex) + require.NoError(t, err) + + tx := types.Transaction{ + To: "0x2e318f4339676a2fb01d8761982ba5dbe9b6b7578e83f34fdddf20f8c5a17509", + Data: raw, + AdditionalFields: additionalFields(t, AdditionalFields{ + TargetInstanceAddress: "factory@ccipOwner::1220e382f4e57b0815e6be737006e381e6b7de448e06bd033ece6df498017879f551", + FunctionName: "DeployExecutor", + TargetTemplateID: "#pkg:CCIP.Factory:CCIPFactory", + }), + } + + dec, err := NewDecoder().Decode(tx, "") + require.NoError(t, err) + require.Equal(t, "CCIPFactory::DeployExecutor", dec.MethodName()) + require.Equal(t, []string{instanceIDFieldLabel, "owner", "maxCCVsPerMsg", "allowedFinalityConfig", "ccvAllowlistEnabled"}, dec.Keys()) + require.Equal(t, "executor-wwbhq", dec.Args()[0]) + require.Equal(t, "ccipOwner::1220e382f4e57b0815e6be737006e381e6b7de448e06bd033ece6df498017879f551", dec.Args()[1]) + require.Equal(t, int64(10), dec.Args()[2]) + + finality, ok := dec.Args()[3].(map[string]any) + require.True(t, ok, "allowedFinalityConfig should render as a map, got %T", dec.Args()[3]) + + // Proposal has `allowedFinalityConfig: { BlockDepth: null, WaitForFinality: {}, WaitForSafe: null }` + require.NotNil(t, finality["WaitForFinality"]) + require.Nil(t, finality["WaitForSafe"]) + require.Nil(t, finality["BlockDepth"]) + require.Equal(t, false, dec.Args()[4]) + + // The variant must round-trip (decode → re-encode reproduces the proposal bytes), so the + // decoder selects DeployExecutorParams via the strict path rather than the single-decode fallback. + decoded, err := decodeOperationData("CCIPFactory", "DeployExecutor", raw) + require.NoError(t, err) + params, ok := decoded.(*factory.DeployExecutorParams) + require.True(t, ok, "expected *factory.DeployExecutorParams, got %T", decoded) + reEncoded, err := params.MarshalHex() + require.NoError(t, err) + require.Equal(t, string(raw), reEncoded) +} diff --git a/sdk/canton/resolver.go b/sdk/canton/resolver.go index aee24d4e..a0d9bfa5 100644 --- a/sdk/canton/resolver.go +++ b/sdk/canton/resolver.go @@ -105,7 +105,7 @@ func findActiveContractByInstanceAddress(ctx context.Context, stateService apiv2 var contractInstanceID string for _, field := range createArguments.GetFields() { - if field.GetLabel() == "instanceId" { + if field.GetLabel() == instanceIDFieldLabel { contractInstanceID = field.GetValue().GetText() break } diff --git a/signable.go b/signable.go index 82cc445a..9c793664 100644 --- a/signable.go +++ b/signable.go @@ -159,7 +159,7 @@ func (s *Signable) CheckQuorum(ctx context.Context, chain types.ChainSelector) ( return false, errors.New("inspector not found for chain " + strconv.FormatUint(uint64(chain), 10)) } - recoveredSigners, err := s.proposal.RecoverSigningAddressesStrict() //nolint:contextcheck //OPT-400 + recoveredSigners, err := s.proposal.RecoverSigningAddressesStrict() //nolint:contextcheck,nolintlint //OPT-400 if err != nil { return false, err }