From 14e9ab563e5cca2f86a16519381183e282cc3025 Mon Sep 17 00:00:00 2001 From: Silas Lenihan Date: Mon, 9 Mar 2026 09:18:37 -0400 Subject: [PATCH 1/8] Added emit_cpi support --- .../generated/log_read_test/constants.go | 2 +- .../generated/log_read_test/discriminators.go | 3 +- contracts/generated/log_read_test/doc.go | 7 + contracts/generated/log_read_test/errors.go | 2 +- contracts/generated/log_read_test/events.go | 2 +- contracts/generated/log_read_test/fetchers.go | 2 +- .../generated/log_read_test/instructions.go | 331 +++--------------- .../{program_id.go => program-id.go} | 2 +- .../generated/log_read_test/tests_test.go | 2 +- contracts/generated/log_read_test/types.go | 8 +- contracts/go.mod | 3 +- contracts/go.sum | 6 +- contracts/programs/log-read-test/Cargo.toml | 2 +- contracts/programs/log-read-test/src/lib.rs | 15 + go.mod | 4 +- go.sum | 8 +- integration-tests/go.mod | 10 +- integration-tests/go.sum | 24 +- pkg/solana/logpoller/cpi_event_extractor.go | 101 +++--- .../logpoller/cpi_event_extractor_test.go | 296 ++++++++++++++++ pkg/solana/logpoller/types/types.go | 18 + pkg/solana/logpoller/types/types_test.go | 23 ++ pkg/solana/solana_service.go | 24 +- 23 files changed, 518 insertions(+), 377 deletions(-) create mode 100644 contracts/generated/log_read_test/doc.go rename contracts/generated/log_read_test/{program_id.go => program-id.go} (73%) create mode 100644 pkg/solana/logpoller/types/types_test.go diff --git a/contracts/generated/log_read_test/constants.go b/contracts/generated/log_read_test/constants.go index 82bd54cc9..7cb9ea0ff 100644 --- a/contracts/generated/log_read_test/constants.go +++ b/contracts/generated/log_read_test/constants.go @@ -1,4 +1,4 @@ -// Code generated by https://github.com/Unheilbar/anchor-go. DO NOT EDIT. +// Code generated by https://github.com/gagliardetto/anchor-go. DO NOT EDIT. // This file contains constants. package log_read_test diff --git a/contracts/generated/log_read_test/discriminators.go b/contracts/generated/log_read_test/discriminators.go index eec9b5d3b..0c2275138 100644 --- a/contracts/generated/log_read_test/discriminators.go +++ b/contracts/generated/log_read_test/discriminators.go @@ -1,4 +1,4 @@ -// Code generated by https://github.com/Unheilbar/anchor-go. DO NOT EDIT. +// Code generated by https://github.com/gagliardetto/anchor-go. DO NOT EDIT. // This file contains the discriminators for accounts and events defined in the IDL. package log_read_test @@ -14,5 +14,6 @@ var ( // Instruction discriminators var ( Instruction_CreateLog = [8]byte{215, 95, 248, 114, 153, 204, 208, 48} + Instruction_CreateLogCpi = [8]byte{101, 207, 236, 250, 214, 98, 173, 146} Instruction_CreateTruncatedLog = [8]byte{133, 74, 116, 132, 80, 11, 241, 64} ) diff --git a/contracts/generated/log_read_test/doc.go b/contracts/generated/log_read_test/doc.go new file mode 100644 index 000000000..71dc0c602 --- /dev/null +++ b/contracts/generated/log_read_test/doc.go @@ -0,0 +1,7 @@ +// Code generated by https://github.com/gagliardetto/anchor-go. DO NOT EDIT. +// This file contains documentation and example usage for the generated code. + +package log_read_test + +// No documentation available from the IDL. +// Please refer to the IDL source or the program documentation for more information. diff --git a/contracts/generated/log_read_test/errors.go b/contracts/generated/log_read_test/errors.go index 022f87126..de8e428d5 100644 --- a/contracts/generated/log_read_test/errors.go +++ b/contracts/generated/log_read_test/errors.go @@ -1,4 +1,4 @@ -// Code generated by https://github.com/Unheilbar/anchor-go. DO NOT EDIT. +// Code generated by https://github.com/gagliardetto/anchor-go. DO NOT EDIT. // This file contains errors. package log_read_test diff --git a/contracts/generated/log_read_test/events.go b/contracts/generated/log_read_test/events.go index 09499c0cb..c76cbb969 100644 --- a/contracts/generated/log_read_test/events.go +++ b/contracts/generated/log_read_test/events.go @@ -1,4 +1,4 @@ -// Code generated by https://github.com/Unheilbar/anchor-go. DO NOT EDIT. +// Code generated by https://github.com/gagliardetto/anchor-go. DO NOT EDIT. // This file contains parsers for the events defined in the IDL. package log_read_test diff --git a/contracts/generated/log_read_test/fetchers.go b/contracts/generated/log_read_test/fetchers.go index 918a36e1b..5c2afff0d 100644 --- a/contracts/generated/log_read_test/fetchers.go +++ b/contracts/generated/log_read_test/fetchers.go @@ -1,4 +1,4 @@ -// Code generated by https://github.com/Unheilbar/anchor-go. DO NOT EDIT. +// Code generated by https://github.com/gagliardetto/anchor-go. DO NOT EDIT. // This file contains fetcher functions. package log_read_test diff --git a/contracts/generated/log_read_test/instructions.go b/contracts/generated/log_read_test/instructions.go index df2540556..8239f6a58 100644 --- a/contracts/generated/log_read_test/instructions.go +++ b/contracts/generated/log_read_test/instructions.go @@ -1,12 +1,12 @@ -// Code generated by https://github.com/Unheilbar/anchor-go. DO NOT EDIT. -// This file contains instructions and instruction parsers. +// Code generated by https://github.com/gagliardetto/anchor-go. DO NOT EDIT. +// This file contains instructions. package log_read_test import ( "bytes" "fmt" - errors "github.com/Unheilbar/anchor-go/errors" + errors "github.com/gagliardetto/anchor-go/errors" binary "github.com/gagliardetto/binary" solanago "github.com/gagliardetto/solana-go" ) @@ -53,20 +53,22 @@ func NewCreateLogInstruction( ), nil } -// Builds a "create_truncated_log" instruction. -func NewCreateTruncatedLogInstruction( +// Builds a "create_log_cpi" instruction. +func NewCreateLogCpiInstruction( // Params: valueParam uint64, // Accounts: authorityAccount solanago.PublicKey, systemProgramAccount solanago.PublicKey, + eventAuthorityAccount solanago.PublicKey, + programAccount solanago.PublicKey, ) (solanago.Instruction, error) { buf__ := new(bytes.Buffer) enc__ := binary.NewBorshEncoder(buf__) // Encode the instruction discriminator. - err := enc__.WriteBytes(Instruction_CreateTruncatedLog[:], false) + err := enc__.WriteBytes(Instruction_CreateLogCpi[:], false) if err != nil { return nil, fmt.Errorf("failed to write instruction discriminator: %w", err) } @@ -85,6 +87,10 @@ func NewCreateTruncatedLogInstruction( accounts__.Append(solanago.NewAccountMeta(authorityAccount, false, true)) // Account 1 "system_program": Read-only, Non-signer, Required accounts__.Append(solanago.NewAccountMeta(systemProgramAccount, false, false)) + // Account 2 "event_authority": Read-only, Non-signer, Required + accounts__.Append(solanago.NewAccountMeta(eventAuthorityAccount, false, false)) + // Account 3 "program": Read-only, Non-signer, Required + accounts__.Append(solanago.NewAccountMeta(programAccount, false, false)) } // Create the instruction. @@ -95,299 +101,44 @@ func NewCreateTruncatedLogInstruction( ), nil } -type CreateLogInstruction struct { - Value uint64 `json:"value"` - - // Accounts: - Authority solanago.PublicKey `json:"authority"` - AuthoritySigner bool `json:"authority_signer"` - SystemProgram solanago.PublicKey `json:"system_program"` -} - -func (obj *CreateLogInstruction) GetDiscriminator() []byte { - return Instruction_CreateLog[:] -} - -// UnmarshalWithDecoder unmarshals the CreateLogInstruction from Borsh-encoded bytes prefixed with its discriminator. -func (obj *CreateLogInstruction) UnmarshalWithDecoder(decoder *binary.Decoder) error { - var err error - // Read the discriminator and check it against the expected value: - discriminator, err := decoder.ReadDiscriminator() - if err != nil { - return fmt.Errorf("failed to read instruction discriminator for %s: %w", "CreateLogInstruction", err) - } - if discriminator != Instruction_CreateLog { - return fmt.Errorf("instruction discriminator mismatch for %s: expected %s, got %s", "CreateLogInstruction", Instruction_CreateLog, discriminator) - } - // Deserialize `Value`: - err = decoder.Decode(&obj.Value) - if err != nil { - return err - } - return nil -} - -func (obj *CreateLogInstruction) UnmarshalAccountIndices(buf []byte) ([]uint8, error) { - // UnmarshalAccountIndices decodes account indices from Borsh-encoded bytes - decoder := binary.NewBorshDecoder(buf) - indices := make([]uint8, 0) - index := uint8(0) - var err error - // Decode from authority account index - index = uint8(0) - err = decoder.Decode(&index) - if err != nil { - return nil, fmt.Errorf("failed to decode %s account index: %w", "authority", err) - } - indices = append(indices, index) - // Decode from system_program account index - index = uint8(0) - err = decoder.Decode(&index) - if err != nil { - return nil, fmt.Errorf("failed to decode %s account index: %w", "system_program", err) - } - indices = append(indices, index) - return indices, nil -} - -func (obj *CreateLogInstruction) PopulateFromAccountIndices(indices []uint8, accountKeys []solanago.PublicKey) error { - // PopulateFromAccountIndices sets account public keys from indices and account keys array - if len(indices) != 2 { - return fmt.Errorf("mismatch between expected accounts (%d) and provided indices (%d)", 2, len(indices)) - } - indexOffset := 0 - // Set authority account from index - if indices[indexOffset] >= uint8(len(accountKeys)) { - return fmt.Errorf("account index %d for %s is out of bounds (max: %d)", indices[indexOffset], "authority", len(accountKeys)-1) - } - obj.Authority = accountKeys[indices[indexOffset]] - indexOffset++ - // Set system_program account from index - if indices[indexOffset] >= uint8(len(accountKeys)) { - return fmt.Errorf("account index %d for %s is out of bounds (max: %d)", indices[indexOffset], "system_program", len(accountKeys)-1) - } - obj.SystemProgram = accountKeys[indices[indexOffset]] - indexOffset++ - return nil -} - -func (obj *CreateLogInstruction) GetAccountKeys() []solanago.PublicKey { - keys := make([]solanago.PublicKey, 0) - keys = append(keys, obj.Authority) - keys = append(keys, obj.SystemProgram) - return keys -} - -// Unmarshal unmarshals the CreateLogInstruction from Borsh-encoded bytes prefixed with the discriminator. -func (obj *CreateLogInstruction) Unmarshal(buf []byte) error { - var err error - err = obj.UnmarshalWithDecoder(binary.NewBorshDecoder(buf)) - if err != nil { - return fmt.Errorf("error while unmarshaling CreateLogInstruction: %w", err) - } - return nil -} - -// UnmarshalCreateLogInstruction unmarshals the instruction from Borsh-encoded bytes prefixed with the discriminator. -func UnmarshalCreateLogInstruction(buf []byte) (*CreateLogInstruction, error) { - obj := new(CreateLogInstruction) - var err error - err = obj.Unmarshal(buf) - if err != nil { - return nil, err - } - return obj, nil -} - -type CreateTruncatedLogInstruction struct { - Value uint64 `json:"value"` +// Builds a "create_truncated_log" instruction. +func NewCreateTruncatedLogInstruction( + // Params: + valueParam uint64, // Accounts: - Authority solanago.PublicKey `json:"authority"` - AuthoritySigner bool `json:"authority_signer"` - SystemProgram solanago.PublicKey `json:"system_program"` -} - -func (obj *CreateTruncatedLogInstruction) GetDiscriminator() []byte { - return Instruction_CreateTruncatedLog[:] -} - -// UnmarshalWithDecoder unmarshals the CreateTruncatedLogInstruction from Borsh-encoded bytes prefixed with its discriminator. -func (obj *CreateTruncatedLogInstruction) UnmarshalWithDecoder(decoder *binary.Decoder) error { - var err error - // Read the discriminator and check it against the expected value: - discriminator, err := decoder.ReadDiscriminator() - if err != nil { - return fmt.Errorf("failed to read instruction discriminator for %s: %w", "CreateTruncatedLogInstruction", err) - } - if discriminator != Instruction_CreateTruncatedLog { - return fmt.Errorf("instruction discriminator mismatch for %s: expected %s, got %s", "CreateTruncatedLogInstruction", Instruction_CreateTruncatedLog, discriminator) - } - // Deserialize `Value`: - err = decoder.Decode(&obj.Value) - if err != nil { - return err - } - return nil -} - -func (obj *CreateTruncatedLogInstruction) UnmarshalAccountIndices(buf []byte) ([]uint8, error) { - // UnmarshalAccountIndices decodes account indices from Borsh-encoded bytes - decoder := binary.NewBorshDecoder(buf) - indices := make([]uint8, 0) - index := uint8(0) - var err error - // Decode from authority account index - index = uint8(0) - err = decoder.Decode(&index) - if err != nil { - return nil, fmt.Errorf("failed to decode %s account index: %w", "authority", err) - } - indices = append(indices, index) - // Decode from system_program account index - index = uint8(0) - err = decoder.Decode(&index) - if err != nil { - return nil, fmt.Errorf("failed to decode %s account index: %w", "system_program", err) - } - indices = append(indices, index) - return indices, nil -} - -func (obj *CreateTruncatedLogInstruction) PopulateFromAccountIndices(indices []uint8, accountKeys []solanago.PublicKey) error { - // PopulateFromAccountIndices sets account public keys from indices and account keys array - if len(indices) != 2 { - return fmt.Errorf("mismatch between expected accounts (%d) and provided indices (%d)", 2, len(indices)) - } - indexOffset := 0 - // Set authority account from index - if indices[indexOffset] >= uint8(len(accountKeys)) { - return fmt.Errorf("account index %d for %s is out of bounds (max: %d)", indices[indexOffset], "authority", len(accountKeys)-1) - } - obj.Authority = accountKeys[indices[indexOffset]] - indexOffset++ - // Set system_program account from index - if indices[indexOffset] >= uint8(len(accountKeys)) { - return fmt.Errorf("account index %d for %s is out of bounds (max: %d)", indices[indexOffset], "system_program", len(accountKeys)-1) - } - obj.SystemProgram = accountKeys[indices[indexOffset]] - indexOffset++ - return nil -} - -func (obj *CreateTruncatedLogInstruction) GetAccountKeys() []solanago.PublicKey { - keys := make([]solanago.PublicKey, 0) - keys = append(keys, obj.Authority) - keys = append(keys, obj.SystemProgram) - return keys -} - -// Unmarshal unmarshals the CreateTruncatedLogInstruction from Borsh-encoded bytes prefixed with the discriminator. -func (obj *CreateTruncatedLogInstruction) Unmarshal(buf []byte) error { - var err error - err = obj.UnmarshalWithDecoder(binary.NewBorshDecoder(buf)) - if err != nil { - return fmt.Errorf("error while unmarshaling CreateTruncatedLogInstruction: %w", err) - } - return nil -} + authorityAccount solanago.PublicKey, + systemProgramAccount solanago.PublicKey, +) (solanago.Instruction, error) { + buf__ := new(bytes.Buffer) + enc__ := binary.NewBorshEncoder(buf__) -// UnmarshalCreateTruncatedLogInstruction unmarshals the instruction from Borsh-encoded bytes prefixed with the discriminator. -func UnmarshalCreateTruncatedLogInstruction(buf []byte) (*CreateTruncatedLogInstruction, error) { - obj := new(CreateTruncatedLogInstruction) - var err error - err = obj.Unmarshal(buf) + // Encode the instruction discriminator. + err := enc__.WriteBytes(Instruction_CreateTruncatedLog[:], false) if err != nil { - return nil, err - } - return obj, nil -} - -// Instruction interface defines common methods for all instruction types -type Instruction interface { - GetDiscriminator() []byte - - UnmarshalWithDecoder(decoder *binary.Decoder) error - - UnmarshalAccountIndices(buf []byte) ([]uint8, error) - - PopulateFromAccountIndices(indices []uint8, accountKeys []solanago.PublicKey) error - - GetAccountKeys() []solanago.PublicKey -} - -// ParseInstruction parses instruction data and optionally populates accounts -// If accountIndicesData is nil or empty, accounts will not be populated -func ParseInstruction(instructionData []byte, accountIndicesData []byte, accountKeys []solanago.PublicKey) (Instruction, error) { - // Validate inputs - if len(instructionData) < 8 { - return nil, fmt.Errorf("instruction data too short: expected at least 8 bytes, got %d", len(instructionData)) + return nil, fmt.Errorf("failed to write instruction discriminator: %w", err) } - // Extract discriminator - discriminator := [8]byte{} - copy(discriminator[:], instructionData[0:8]) - // Parse based on discriminator - switch discriminator { - case Instruction_CreateLog: - instruction := new(CreateLogInstruction) - decoder := binary.NewBorshDecoder(instructionData) - err := instruction.UnmarshalWithDecoder(decoder) - if err != nil { - return nil, fmt.Errorf("failed to unmarshal instruction as CreateLogInstruction: %w", err) - } - if accountIndicesData != nil && len(accountIndicesData) > 0 { - indices, err := instruction.UnmarshalAccountIndices(accountIndicesData) - if err != nil { - return nil, fmt.Errorf("failed to unmarshal account indices: %w", err) - } - err = instruction.PopulateFromAccountIndices(indices, accountKeys) - if err != nil { - return nil, fmt.Errorf("failed to populate accounts: %w", err) - } - } - return instruction, nil - case Instruction_CreateTruncatedLog: - instruction := new(CreateTruncatedLogInstruction) - decoder := binary.NewBorshDecoder(instructionData) - err := instruction.UnmarshalWithDecoder(decoder) + { + // Serialize `valueParam`: + err = enc__.Encode(valueParam) if err != nil { - return nil, fmt.Errorf("failed to unmarshal instruction as CreateTruncatedLogInstruction: %w", err) - } - if accountIndicesData != nil && len(accountIndicesData) > 0 { - indices, err := instruction.UnmarshalAccountIndices(accountIndicesData) - if err != nil { - return nil, fmt.Errorf("failed to unmarshal account indices: %w", err) - } - err = instruction.PopulateFromAccountIndices(indices, accountKeys) - if err != nil { - return nil, fmt.Errorf("failed to populate accounts: %w", err) - } + return nil, errors.NewField("valueParam", err) } - return instruction, nil - default: - return nil, fmt.Errorf("unknown instruction discriminator: %s", binary.FormatDiscriminator(discriminator)) } -} + accounts__ := solanago.AccountMetaSlice{} -// ParseInstructionTyped parses instruction data and returns a specific instruction type // T must implement the Instruction interface -func ParseInstructionTyped[T Instruction](instructionData []byte, accountIndicesData []byte, accountKeys []solanago.PublicKey) (T, error) { - instruction, err := ParseInstruction(instructionData, accountIndicesData, accountKeys) - if err != nil { - return *new(T), err - } - typed, ok := instruction.(T) - if !ok { - return *new(T), fmt.Errorf("instruction is not of expected type") + // Add the accounts to the instruction. + { + // Account 0 "authority": Read-only, Signer, Required + accounts__.Append(solanago.NewAccountMeta(authorityAccount, false, true)) + // Account 1 "system_program": Read-only, Non-signer, Required + accounts__.Append(solanago.NewAccountMeta(systemProgramAccount, false, false)) } - return typed, nil -} - -// ParseInstructionWithoutAccounts parses instruction data without account information -func ParseInstructionWithoutAccounts(instructionData []byte) (Instruction, error) { - return ParseInstruction(instructionData, nil, []solanago.PublicKey{}) -} -// ParseInstructionWithAccounts parses instruction data with account information -func ParseInstructionWithAccounts(instructionData []byte, accountIndicesData []byte, accountKeys []solanago.PublicKey) (Instruction, error) { - return ParseInstruction(instructionData, accountIndicesData, accountKeys) + // Create the instruction. + return solanago.NewInstruction( + ProgramID, + accounts__, + buf__.Bytes(), + ), nil } diff --git a/contracts/generated/log_read_test/program_id.go b/contracts/generated/log_read_test/program-id.go similarity index 73% rename from contracts/generated/log_read_test/program_id.go rename to contracts/generated/log_read_test/program-id.go index fd4b6b67d..62beffb5e 100644 --- a/contracts/generated/log_read_test/program_id.go +++ b/contracts/generated/log_read_test/program-id.go @@ -1,4 +1,4 @@ -// Code generated by https://github.com/Unheilbar/anchor-go. DO NOT EDIT. +// Code generated by https://github.com/gagliardetto/anchor-go. DO NOT EDIT. // This file contains the program ID. package log_read_test diff --git a/contracts/generated/log_read_test/tests_test.go b/contracts/generated/log_read_test/tests_test.go index 15cd1cea0..115811e52 100644 --- a/contracts/generated/log_read_test/tests_test.go +++ b/contracts/generated/log_read_test/tests_test.go @@ -1,4 +1,4 @@ -// Code generated by https://github.com/Unheilbar/anchor-go. DO NOT EDIT. +// Code generated by https://github.com/gagliardetto/anchor-go. DO NOT EDIT. // This file contains tests. package log_read_test diff --git a/contracts/generated/log_read_test/types.go b/contracts/generated/log_read_test/types.go index 0cc5a8a47..c161a13e6 100644 --- a/contracts/generated/log_read_test/types.go +++ b/contracts/generated/log_read_test/types.go @@ -1,4 +1,4 @@ -// Code generated by https://github.com/Unheilbar/anchor-go. DO NOT EDIT. +// Code generated by https://github.com/gagliardetto/anchor-go. DO NOT EDIT. // This file contains parsers for the types defined in the IDL. package log_read_test @@ -6,13 +6,13 @@ package log_read_test import ( "bytes" "fmt" - errors "github.com/Unheilbar/anchor-go/errors" + errors "github.com/gagliardetto/anchor-go/errors" binary "github.com/gagliardetto/binary" ) type TestEvent struct { - StrVal string `json:"str_val"` - U64Value uint64 `json:"u64_value"` + StrVal string `json:"strVal"` + U64Value uint64 `json:"u64Value"` } func (obj TestEvent) MarshalWithEncoder(encoder *binary.Encoder) (err error) { diff --git a/contracts/go.mod b/contracts/go.mod index e791c5152..f037e7e99 100644 --- a/contracts/go.mod +++ b/contracts/go.mod @@ -6,6 +6,7 @@ require ( github.com/Unheilbar/anchor-go v1.0.3 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc github.com/ethereum/go-ethereum v1.17.0 + github.com/gagliardetto/anchor-go v1.0.0 github.com/gagliardetto/binary v0.8.0 github.com/gagliardetto/gofuzz v1.2.2 github.com/gagliardetto/solana-go v1.13.0 @@ -123,7 +124,7 @@ require ( github.com/sirupsen/logrus v1.9.4 // indirect github.com/smartcontractkit/chain-selectors v1.0.97 // indirect github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 // indirect - github.com/smartcontractkit/chainlink-common v0.10.1-0.20260225165959-ca7f453e0dcc // indirect + github.com/smartcontractkit/chainlink-common v0.10.1-0.20260304224420-7456e47e1226 // indirect github.com/smartcontractkit/chainlink-testing-framework/framework v0.14.3 // indirect github.com/smartcontractkit/chainlink-ton v0.0.0-20260219201907-054376f21418 // indirect github.com/smartcontractkit/chainlink-tron/relayer v0.0.11-0.20251014143056-a0c6328c91e9 // indirect diff --git a/contracts/go.sum b/contracts/go.sum index 0f72e02c7..b0ee2ef63 100644 --- a/contracts/go.sum +++ b/contracts/go.sum @@ -182,6 +182,8 @@ github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/gabriel-vasile/mimetype v1.4.13 h1:46nXokslUBsAJE/wMsp5gtO500a4F3Nkz9Ufpk2AcUM= github.com/gabriel-vasile/mimetype v1.4.13/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s= +github.com/gagliardetto/anchor-go v1.0.0 h1:YNt9I/9NOrNzz5uuzfzByAcbp39Ft07w63iPqC/wi34= +github.com/gagliardetto/anchor-go v1.0.0/go.mod h1:X6c9bx9JnmwNiyy8hmV5pAsq1c/zzPvkdzeq9/qmlCg= github.com/gagliardetto/binary v0.8.0 h1:U9ahc45v9HW0d15LoN++vIXSJyqR/pWw8DDlhd7zvxg= github.com/gagliardetto/binary v0.8.0/go.mod h1:2tfj51g5o9dnvsc+fL3Jxr22MuWzYXwx9wEoN0XQ7/c= github.com/gagliardetto/gofuzz v1.2.2 h1:XL/8qDMzcgvR4+CyRQW9UGdwPRPMHVJfqQ/uMvSUuQw= @@ -501,8 +503,8 @@ github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260220192608-a github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260220192608-af6bd538e0ca/go.mod h1:k1aNQP8nPFkSqWJZ4kFQaa1JGlWVIg6Y+XA2++qs6Cg= github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 h1:Z4t2ZY+ZyGWxtcXvPr11y4o3CGqhg3frJB5jXkCSvWA= github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5/go.mod h1:xtZNi6pOKdC3sLvokDvXOhgHzT+cyBqH/gWwvxTxqrg= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260225165959-ca7f453e0dcc h1:LQBkqJbsduX1O8ijoSmr4DLMvUeAH41UZkV0AThhFyQ= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260225165959-ca7f453e0dcc/go.mod h1:HXgSKzmZ/bhSx8nHU7hHW6dR+BHSXkdcpFv2T8qJcS8= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260304224420-7456e47e1226 h1:XZ4yNFF8yspofSeVVwegXxZjmpngdXVsaowLNI7o9+A= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260304224420-7456e47e1226/go.mod h1:2+zTrPZBRMJdrDqCKfFhk3WokQ+jfP5UEFaEtOEruk0= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 h1:FJAFgXS9oqASnkS03RE1HQwYQQxrO4l46O5JSzxqLgg= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10/go.mod h1:oiDa54M0FwxevWwyAX773lwdWvFYYlYHHQV1LQ5HpWY= github.com/smartcontractkit/chainlink-deployments-framework v0.81.2 h1:rEPEywuLv6YPIN6YhXJpReapVM+bPOOLXlpJwItlTu0= diff --git a/contracts/programs/log-read-test/Cargo.toml b/contracts/programs/log-read-test/Cargo.toml index 13f2106f3..6be59f58a 100644 --- a/contracts/programs/log-read-test/Cargo.toml +++ b/contracts/programs/log-read-test/Cargo.toml @@ -17,4 +17,4 @@ default = [] idl-build = ["anchor-lang/idl-build"] [dependencies] -anchor-lang = "0.31.0" +anchor-lang = { version = "0.31.0", features = ["event-cpi"] } diff --git a/contracts/programs/log-read-test/src/lib.rs b/contracts/programs/log-read-test/src/lib.rs index ba9814492..045f9d0b1 100644 --- a/contracts/programs/log-read-test/src/lib.rs +++ b/contracts/programs/log-read-test/src/lib.rs @@ -29,6 +29,14 @@ pub mod log_read_test { Ok(()) } + + pub fn create_log_cpi(ctx: Context, value: u64) -> Result<()> { + emit_cpi!(event::TestEvent { + str_val: "Hello, CPI!".to_string(), + u64_value: value, + }); + Ok(()) + } } #[derive(Accounts)] @@ -36,3 +44,10 @@ pub struct Initialization<'info> { pub authority: Signer<'info>, pub system_program: Program<'info, System>, } + +#[event_cpi] +#[derive(Accounts)] +pub struct CreateLogCpi<'info> { + pub authority: Signer<'info>, + pub system_program: Program<'info, System>, +} diff --git a/go.mod b/go.mod index 944c3a218..a517197cb 100644 --- a/go.mod +++ b/go.mod @@ -22,12 +22,12 @@ require ( github.com/smartcontractkit/chainlink-ccip v0.1.1-solana.0.20260203202624-5101f4d33736 github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260121163256-85accaf3d28d github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 - github.com/smartcontractkit/chainlink-common v0.10.1-0.20260225165959-ca7f453e0dcc + github.com/smartcontractkit/chainlink-common v0.10.1-0.20260304224420-7456e47e1226 github.com/smartcontractkit/chainlink-common/keystore v1.0.0 github.com/smartcontractkit/chainlink-common/pkg/monitoring v0.0.0-20251215152504-b1e41f508340 github.com/smartcontractkit/chainlink-framework/metrics v0.0.0-20251210101658-1c5c8e4c4f15 github.com/smartcontractkit/chainlink-framework/multinode v0.0.0-20251021173435-e86785845942 - github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260217043601-5cc966896c4f + github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260304224222-c5c5976d3417 github.com/smartcontractkit/freeport v0.1.3-0.20250716200817-cb5dfd0e369e github.com/smartcontractkit/libocr v0.0.0-20251212213002-0a5e2f907dda github.com/stretchr/testify v1.11.1 diff --git a/go.sum b/go.sum index fed8beed2..2e867afb0 100644 --- a/go.sum +++ b/go.sum @@ -565,8 +565,8 @@ github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260121163256-8 github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260121163256-85accaf3d28d/go.mod h1:bgmqE7x9xwmIVr8PqLbC0M5iPm4AV2DBl596lO6S5Sw= github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 h1:Z4t2ZY+ZyGWxtcXvPr11y4o3CGqhg3frJB5jXkCSvWA= github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5/go.mod h1:xtZNi6pOKdC3sLvokDvXOhgHzT+cyBqH/gWwvxTxqrg= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260225165959-ca7f453e0dcc h1:LQBkqJbsduX1O8ijoSmr4DLMvUeAH41UZkV0AThhFyQ= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260225165959-ca7f453e0dcc/go.mod h1:HXgSKzmZ/bhSx8nHU7hHW6dR+BHSXkdcpFv2T8qJcS8= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260304224420-7456e47e1226 h1:XZ4yNFF8yspofSeVVwegXxZjmpngdXVsaowLNI7o9+A= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260304224420-7456e47e1226/go.mod h1:2+zTrPZBRMJdrDqCKfFhk3WokQ+jfP5UEFaEtOEruk0= github.com/smartcontractkit/chainlink-common/keystore v1.0.0 h1:sVa3j2FWK/5OxXpnlfDkF1deDAkuXEfaLKzYqBTA880= github.com/smartcontractkit/chainlink-common/keystore v1.0.0/go.mod h1:wGRJJlCFUOKIfBlBGEdBFiTf7R787B8HKyobjiymw3Q= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 h1:FJAFgXS9oqASnkS03RE1HQwYQQxrO4l46O5JSzxqLgg= @@ -577,8 +577,8 @@ github.com/smartcontractkit/chainlink-framework/metrics v0.0.0-20251210101658-1c github.com/smartcontractkit/chainlink-framework/metrics v0.0.0-20251210101658-1c5c8e4c4f15/go.mod h1:HG/aei0MgBOpsyRLexdKGtOUO8yjSJO3iUu0Uu8KBm4= github.com/smartcontractkit/chainlink-framework/multinode v0.0.0-20251021173435-e86785845942 h1:T/eCDsUI8EJT4n5zSP4w1mz4RHH+ap8qieA17QYfBhk= github.com/smartcontractkit/chainlink-framework/multinode v0.0.0-20251021173435-e86785845942/go.mod h1:2JTBNp3FlRdO/nHc4dsc9bfxxMClMO1Qt8sLJgtreBY= -github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260217043601-5cc966896c4f h1:MHlgzqiDPyDV397bZkzS9TtWXb3FR9Pb8FR9cP9h0As= -github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260217043601-5cc966896c4f/go.mod h1:Jqt53s27Tr0jDl8mdBXg1xhu6F8Fci8JOuq43tgHOM8= +github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260304224222-c5c5976d3417 h1:WEmNgQGjbYJH50EtaII8iX5Vx3VcOX10AMuhmK8VTaA= +github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260304224222-c5c5976d3417/go.mod h1:Jqt53s27Tr0jDl8mdBXg1xhu6F8Fci8JOuq43tgHOM8= github.com/smartcontractkit/chainlink-protos/linking-service/go v0.0.0-20251002192024-d2ad9222409b h1:QuI6SmQFK/zyUlVWEf0GMkiUYBPY4lssn26nKSd/bOM= github.com/smartcontractkit/chainlink-protos/linking-service/go v0.0.0-20251002192024-d2ad9222409b/go.mod h1:qSTSwX3cBP3FKQwQacdjArqv0g6QnukjV4XuzO6UyoY= github.com/smartcontractkit/chainlink-protos/node-platform v0.0.0-20260205130626-db2a2aab956b h1:36knUpKHHAZ86K4FGWXtx8i/EQftGdk2bqCoEu/Cha8= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 32bb4f04b..96998042b 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -19,9 +19,9 @@ require ( github.com/rs/zerolog v1.34.0 github.com/smartcontractkit/chain-selectors v1.0.97 github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260220192608-af6bd538e0ca - github.com/smartcontractkit/chainlink-common v0.10.1-0.20260225165959-ca7f453e0dcc - github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260217043601-5cc966896c4f - github.com/smartcontractkit/chainlink-solana v1.1.2-0.20260223222711-2fa6b0e07db0 + github.com/smartcontractkit/chainlink-common v0.10.1-0.20260304224420-7456e47e1226 + github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260304224222-c5c5976d3417 + github.com/smartcontractkit/chainlink-solana v1.1.2-0.20260223132514-df62be174f36 github.com/smartcontractkit/chainlink-solana/contracts v0.0.0-20260217175957-8f1af02c5075 github.com/smartcontractkit/chainlink-testing-framework/lib v1.54.7 github.com/smartcontractkit/chainlink-testing-framework/parrot v0.6.2 @@ -385,9 +385,9 @@ require ( github.com/smartcontractkit/chainlink-ccv v0.0.0-20260224105024-807568ff394d // indirect github.com/smartcontractkit/chainlink-common/keystore v1.0.2 // indirect github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 // indirect - github.com/smartcontractkit/chainlink-data-streams v0.1.12-0.20260224150904-47eef37d9005 // indirect + github.com/smartcontractkit/chainlink-data-streams v0.1.11 // indirect github.com/smartcontractkit/chainlink-deployments-framework v0.81.2 // indirect - github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260223142528-fe0bf6474c99 // indirect + github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260217171105-755485c4e00f // indirect github.com/smartcontractkit/chainlink-evm/contracts/cre/gobindings v0.0.0-20260107191744-4b93f62cffe3 // indirect github.com/smartcontractkit/chainlink-evm/gethwrappers v0.0.0-20251222115927-36a18321243c // indirect github.com/smartcontractkit/chainlink-feeds v0.1.2-0.20250227211209-7cd000095135 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 0b285592f..8aba08fce 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1349,22 +1349,22 @@ github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260220192608-a github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260220192608-af6bd538e0ca/go.mod h1:k1aNQP8nPFkSqWJZ4kFQaa1JGlWVIg6Y+XA2++qs6Cg= github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 h1:Z4t2ZY+ZyGWxtcXvPr11y4o3CGqhg3frJB5jXkCSvWA= github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5/go.mod h1:xtZNi6pOKdC3sLvokDvXOhgHzT+cyBqH/gWwvxTxqrg= -github.com/smartcontractkit/chainlink-ccv v0.0.0-20260224105024-807568ff394d h1:eTMWOP3Q91Qp7b+D2nuh9k2WHct57tBxhn+524YFJq0= -github.com/smartcontractkit/chainlink-ccv v0.0.0-20260224105024-807568ff394d/go.mod h1:RnuNcn7DZmjmzEkeEWX0uL5y1oslB3c9URPLOjFU+jE= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260225165959-ca7f453e0dcc h1:LQBkqJbsduX1O8ijoSmr4DLMvUeAH41UZkV0AThhFyQ= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260225165959-ca7f453e0dcc/go.mod h1:HXgSKzmZ/bhSx8nHU7hHW6dR+BHSXkdcpFv2T8qJcS8= +github.com/smartcontractkit/chainlink-ccv v0.0.0-20260219123955-11b2ac2cfa68 h1:Jy6LtNVM11MCDBYFAKMPeWUnT3Q2U1n4gVlwx1IKvlw= +github.com/smartcontractkit/chainlink-ccv v0.0.0-20260219123955-11b2ac2cfa68/go.mod h1:RnuNcn7DZmjmzEkeEWX0uL5y1oslB3c9URPLOjFU+jE= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260304224420-7456e47e1226 h1:XZ4yNFF8yspofSeVVwegXxZjmpngdXVsaowLNI7o9+A= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260304224420-7456e47e1226/go.mod h1:2+zTrPZBRMJdrDqCKfFhk3WokQ+jfP5UEFaEtOEruk0= github.com/smartcontractkit/chainlink-common/keystore v1.0.2 h1:AWisx4JT3QV8tcgh6J5NCrex+wAgTYpWyHsyNPSXzsQ= github.com/smartcontractkit/chainlink-common/keystore v1.0.2/go.mod h1:rSkIHdomyak3YnUtXLenl6poIq8q0V3UZPiiyYqPdGA= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 h1:FJAFgXS9oqASnkS03RE1HQwYQQxrO4l46O5JSzxqLgg= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10/go.mod h1:oiDa54M0FwxevWwyAX773lwdWvFYYlYHHQV1LQ5HpWY= github.com/smartcontractkit/chainlink-common/pkg/monitoring v0.0.0-20251215152504-b1e41f508340 h1:PsjEI+5jZIz9AS4eOsLS5VpSWJINf38clXV3wryPyMk= github.com/smartcontractkit/chainlink-common/pkg/monitoring v0.0.0-20251215152504-b1e41f508340/go.mod h1:P/0OSXUlFaxxD4B/P6HWbxYtIRmmWGDJAvanq19879c= -github.com/smartcontractkit/chainlink-data-streams v0.1.12-0.20260224150904-47eef37d9005 h1:TKodVxZwcHis7eWh8sRWq348p73gBSKaIVIrCO19PE0= -github.com/smartcontractkit/chainlink-data-streams v0.1.12-0.20260224150904-47eef37d9005/go.mod h1:8rUcGhjeXBoTFx2MynWgXiBWzVSB+LXd9JR6m8y2FfQ= +github.com/smartcontractkit/chainlink-data-streams v0.1.11 h1:yBzjU0Cu8AcfuM858G4xcQIulfNQkPfpUs5FDxX9UaY= +github.com/smartcontractkit/chainlink-data-streams v0.1.11/go.mod h1:8rUcGhjeXBoTFx2MynWgXiBWzVSB+LXd9JR6m8y2FfQ= github.com/smartcontractkit/chainlink-deployments-framework v0.81.2 h1:rEPEywuLv6YPIN6YhXJpReapVM+bPOOLXlpJwItlTu0= github.com/smartcontractkit/chainlink-deployments-framework v0.81.2/go.mod h1:2gCxFZMOFqlXIM2UHYtlSaYokcczx65Z7h/3KD761ao= -github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260223142528-fe0bf6474c99 h1:hZTafPs2L9PXC+dhQZcIDKZTU6bND4Lr2esu7yhUl0c= -github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260223142528-fe0bf6474c99/go.mod h1:vyCNAFYkDz+GAG/dcHXxfk3U9C1P2NLGLEBCmk9OzgY= +github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260217171105-755485c4e00f h1:29dXt+8hnpSK42N/O+u9Wn3rH8ZTeLYAj7jhbdZvpnI= +github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260217171105-755485c4e00f/go.mod h1:vf3/QOdXKTaNzrD2h2wzklHk+MvDC+J0kKmqdIz4www= github.com/smartcontractkit/chainlink-evm/contracts/cre/gobindings v0.0.0-20260107191744-4b93f62cffe3 h1:V22ITnWmgBAyxH+VVVo1jxm/LeJ3jcVMCVYB+zLN5mU= github.com/smartcontractkit/chainlink-evm/contracts/cre/gobindings v0.0.0-20260107191744-4b93f62cffe3/go.mod h1:u5vhpPHVUdGUni9o00MBu2aKPE0Q2DRoipAGPYD01e0= github.com/smartcontractkit/chainlink-evm/gethwrappers v0.0.0-20251222115927-36a18321243c h1:eX7SCn5AGUGduv5OrjbVJkUSOnyeal0BtVem6zBSB2Y= @@ -1389,8 +1389,8 @@ github.com/smartcontractkit/chainlink-protos/chainlink-ccv/message-discovery v0. github.com/smartcontractkit/chainlink-protos/chainlink-ccv/message-discovery v0.0.0-20251211142334-5c3421fe2c8d/go.mod h1:ATjAPIVJibHRcIfiG47rEQkUIOoYa6KDvWj3zwCAw6g= github.com/smartcontractkit/chainlink-protos/chainlink-ccv/verifier v0.0.0-20251211142334-5c3421fe2c8d h1:AJy55QJ/pBhXkZjc7N+ATnWfxrcjq9BI9DmdtdjwDUQ= github.com/smartcontractkit/chainlink-protos/chainlink-ccv/verifier v0.0.0-20251211142334-5c3421fe2c8d/go.mod h1:5JdppgngCOUS76p61zCinSCgOhPeYQ+OcDUuome5THQ= -github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260217043601-5cc966896c4f h1:MHlgzqiDPyDV397bZkzS9TtWXb3FR9Pb8FR9cP9h0As= -github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260217043601-5cc966896c4f/go.mod h1:Jqt53s27Tr0jDl8mdBXg1xhu6F8Fci8JOuq43tgHOM8= +github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260304224222-c5c5976d3417 h1:WEmNgQGjbYJH50EtaII8iX5Vx3VcOX10AMuhmK8VTaA= +github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260304224222-c5c5976d3417/go.mod h1:Jqt53s27Tr0jDl8mdBXg1xhu6F8Fci8JOuq43tgHOM8= github.com/smartcontractkit/chainlink-protos/job-distributor v0.17.0 h1:xHPmFDhff7QpeFxKsZfk+24j4AlnQiFjjRh5O87Peu4= github.com/smartcontractkit/chainlink-protos/job-distributor v0.17.0/go.mod h1:/dVVLXrsp+V0AbcYGJo3XMzKg3CkELsweA/TTopCsKE= github.com/smartcontractkit/chainlink-protos/linking-service/go v0.0.0-20251002192024-d2ad9222409b h1:QuI6SmQFK/zyUlVWEf0GMkiUYBPY4lssn26nKSd/bOM= @@ -1411,8 +1411,8 @@ github.com/smartcontractkit/chainlink-protos/svr v1.1.1-0.20260203131522-bb8bc5c github.com/smartcontractkit/chainlink-protos/svr v1.1.1-0.20260203131522-bb8bc5c423b3/go.mod h1:TcOliTQU6r59DwG4lo3U+mFM9WWyBHGuFkkxQpvSujo= github.com/smartcontractkit/chainlink-protos/workflows/go v0.0.0-20260217043601-5cc966896c4f h1:3+vQMwuWL6+OqNutFqo/+gkczJwcr+MBPqeSxcjfI1Y= github.com/smartcontractkit/chainlink-protos/workflows/go v0.0.0-20260217043601-5cc966896c4f/go.mod h1:GTpDgyK0OObf7jpch6p8N281KxN92wbB8serZhU9yRc= -github.com/smartcontractkit/chainlink-sui v0.0.0-20260223231841-af91ea434e03 h1:41xWbUIsD4DvLh3HdX0A1E5X3QZOiYatFvplaxu6lxA= -github.com/smartcontractkit/chainlink-sui v0.0.0-20260223231841-af91ea434e03/go.mod h1:U3XStbEnbx/+L22n1/8aOIdgcGVxtsZB7p59xJGngAs= +github.com/smartcontractkit/chainlink-sui v0.0.0-20260217210647-11c42009ec1f h1:itSU9nCBtbtmJEDlgVjk53AH6cJaZZzg3gMeEPQrbPU= +github.com/smartcontractkit/chainlink-sui v0.0.0-20260217210647-11c42009ec1f/go.mod h1:U3XStbEnbx/+L22n1/8aOIdgcGVxtsZB7p59xJGngAs= github.com/smartcontractkit/chainlink-testing-framework/framework v0.14.3 h1:4PR0ZD6KF8P8YHilDx7a0RtUgnhYLKWWL1j3Y35H2O8= github.com/smartcontractkit/chainlink-testing-framework/framework v0.14.3/go.mod h1:43xdIQuqw/gzfazsqJkBrGdF25TIJDiY/Ak/YrWFTmU= github.com/smartcontractkit/chainlink-testing-framework/lib v1.54.7 h1:6dmdg2tppPKEFuEwBcT1kSEHj5Uj1xrWnKqX0wZg7zo= diff --git a/pkg/solana/logpoller/cpi_event_extractor.go b/pkg/solana/logpoller/cpi_event_extractor.go index c71b96aec..c42d7593a 100644 --- a/pkg/solana/logpoller/cpi_event_extractor.go +++ b/pkg/solana/logpoller/cpi_event_extractor.go @@ -15,9 +15,10 @@ import ( ) const ( - MethodDiscriminatorLen = 8 - VecLengthPrefixLen = 4 - CPIEventDataOffset = MethodDiscriminatorLen + VecLengthPrefixLen + MethodDiscriminatorLen = 8 + VecLengthPrefixLen = 4 + CPIEventDataOffsetLegacy = MethodDiscriminatorLen + VecLengthPrefixLen + CPIEventDataOffsetCurrent = MethodDiscriminatorLen ) type cpiFilterKey struct { @@ -112,8 +113,9 @@ func (e *CPIEventExtractor) ExtractCPIEvents( continue } + outerProgram := types.PublicKey(allAccountKeys[outerInstruction.ProgramIDIndex]) programAtStackHeight := map[uint16]types.PublicKey{ - 1: types.PublicKey(allAccountKeys[outerInstruction.ProgramIDIndex]), + 1: outerProgram, } for _, ix := range inner.Instructions { @@ -123,56 +125,39 @@ func (e *CPIEventExtractor) ExtractCPIEvents( } destProgram := types.PublicKey(allAccountKeys[ix.ProgramIDIndex]) - programAtStackHeight[ix.StackHeight] = destProgram - if len(ix.Data) < CPIEventDataOffset { - e.lggr.Warnw("data shorter than cpiEventDataOffset", "dataLen", len(ix.Data), "required", CPIEventDataOffset) - continue - } - - declaredLen := bin.LittleEndian.Uint32(ix.Data[MethodDiscriminatorLen:CPIEventDataOffset]) - if declaredLen == 0 { - e.lggr.Warnw("cpi event vec length is zero", - "sourceProgram", programAtStackHeight[ix.StackHeight-1].ToSolana().String(), - "destProgram", allAccountKeys[ix.ProgramIDIndex].String(), - ) - continue + if ix.StackHeight > 0 { + programAtStackHeight[ix.StackHeight] = destProgram } - remaining := len(ix.Data) - CPIEventDataOffset - if int(declaredLen) > remaining { - e.lggr.Warnw("cpi event vec length exceeds remaining bytes", - "declaredLen", declaredLen, "remaining", remaining, - "sourceProgram", programAtStackHeight[ix.StackHeight-1].ToSolana().String(), - "destProgram", allAccountKeys[ix.ProgramIDIndex].String(), - ) - continue - } - - if int(declaredLen) != remaining { - e.lggr.Warnw("cpi event vec length does not match remaining bytes", - "declaredLen", declaredLen, "remaining", remaining, - "sourceProgram", programAtStackHeight[ix.StackHeight-1].ToSolana().String(), - "destProgram", allAccountKeys[ix.ProgramIDIndex].String(), - ) + if len(ix.Data) <= MethodDiscriminatorLen { continue } methodSig := types.EventSignature(ix.Data[:MethodDiscriminatorLen]) - if ix.StackHeight <= 1 { - e.lggr.Warnw("unexpected stack height for inner instruction", - "ix", ix, - "destProgram", destProgram.ToSolana(), - "methodSig", methodSig, - "innerIndex", inner.Index, - ) + var eventData []byte + var ok bool + if methodSig == types.AnchorCPIEventDiscriminator() { + eventData, ok = extractAnchorCPIEventData(ix.Data) + } else { + eventData, ok = extractVecCPIEventData(ix.Data) + } + if !ok || len(eventData) == 0 { continue } - sourceProgram, ok := programAtStackHeight[ix.StackHeight-1] - if !ok { - e.lggr.Warnw("could not find caller for instruction", "stackHeight", ix.StackHeight) - continue + // Determine the source program: use StackHeight tracking when available, + // fall back to the outer instruction's program when StackHeight is missing (0). + var sourceProgram types.PublicKey + if ix.StackHeight > 1 { + sp, ok := programAtStackHeight[ix.StackHeight-1] + if !ok { + e.lggr.Warnw("could not find caller for instruction", "stackHeight", ix.StackHeight) + continue + } + sourceProgram = sp + } else { + sourceProgram = outerProgram } key := cpiFilterKey{ @@ -185,14 +170,11 @@ func (e *CPIEventExtractor) ExtractCPIEvents( continue } - eventData := ix.Data[CPIEventDataOffset : CPIEventDataOffset+int(declaredLen)] encodedData := base64.StdEncoding.EncodeToString(eventData) e.lggr.Infow("Found CPI event", "sourceProgram", sourceProgram.ToSolana().String(), "destProgram", allAccountKeys[ix.ProgramIDIndex].String(), - "loadedWritableAddresses", meta.LoadedAddresses.Writable, - "loadedReadOnlyAddresses", meta.LoadedAddresses.ReadOnly, ) event := types.ProgramEvent{ @@ -219,6 +201,31 @@ func (e *CPIEventExtractor) ExtractCPIEvents( return events } +// extractAnchorCPIEventData handles Anchor 0.31+ emit_cpi! format: [method_disc(8)][event_data(N)]. +// Event data directly follows the 8-byte method discriminator with no vec prefix. +func extractAnchorCPIEventData(data []byte) ([]byte, bool) { + if len(data) <= CPIEventDataOffsetCurrent { + return nil, false + } + return data[CPIEventDataOffsetCurrent:], true +} + +// extractVecCPIEventData handles the Borsh Vec format used by CCIP's cpi_event and +// Anchor <=0.29: [method_disc(8)][vec_len(4)][event_data(N)]. +// Validation is strict: declaredLen must be >0 and must exactly equal the remaining bytes. +// Returns (nil, false) on any mismatch -- no fallback. +func extractVecCPIEventData(data []byte) ([]byte, bool) { + if len(data) < CPIEventDataOffsetLegacy { + return nil, false + } + declaredLen := bin.LittleEndian.Uint32(data[MethodDiscriminatorLen:CPIEventDataOffsetLegacy]) + remaining := len(data) - CPIEventDataOffsetLegacy + if declaredLen == 0 || int(declaredLen) != remaining { + return nil, false + } + return data[CPIEventDataOffsetLegacy:], true +} + func getAllAccountKeys(tx *solana.Transaction, meta *rpc.TransactionMeta) []solana.PublicKey { if tx == nil { return nil diff --git a/pkg/solana/logpoller/cpi_event_extractor_test.go b/pkg/solana/logpoller/cpi_event_extractor_test.go index 062bb0e15..f65e6da13 100644 --- a/pkg/solana/logpoller/cpi_event_extractor_test.go +++ b/pkg/solana/logpoller/cpi_event_extractor_test.go @@ -493,4 +493,300 @@ func TestCPIEventExtractor_ExtractCPIEvents(t *testing.T) { require.Len(t, events, 1) require.Equal(t, sourceProgram.ToSolana().String(), events[0].Program) }) + + t.Run("extracts Anchor emit_cpi event using direct format", func(t *testing.T) { + extractor := NewCPIEventExtractor(logger.Sugared(logger.Test(t))) + + sourceProgram := newRandomPublicKey(t) + destProgram := newRandomPublicKey(t) + anchorMethodSig := types.AnchorCPIEventDiscriminator() + eventSig := newRandomEventSignature(t) + + filter := types.Filter{ + ID: 1, + Name: "anchor-cpi-filter", + Address: sourceProgram, + EventSig: eventSig, + ExtraFilterConfig: types.ExtraFilterConfig{ + DestProgram: destProgram, + MethodSignature: anchorMethodSig, + }, + } + extractor.AddFilter(filter) + + eventPayload := []byte{0xDE, 0xAD, 0xBE, 0xEF} + eventData := append(eventSig[:], eventPayload...) + innerInstData := append(anchorMethodSig[:], eventData...) + + tx := &solana.Transaction{ + Message: solana.Message{ + AccountKeys: []solana.PublicKey{ + solana.PublicKey(sourceProgram), + solana.PublicKey(destProgram), + }, + Instructions: []solana.CompiledInstruction{ + {ProgramIDIndex: 0}, + }, + }, + } + + meta := &rpc.TransactionMeta{ + InnerInstructions: []rpc.InnerInstruction{ + { + Index: 0, + Instructions: []rpc.CompiledInstruction{ + { + ProgramIDIndex: 1, + Data: innerInstData, + StackHeight: 2, + }, + }, + }, + }, + } + + detail := eventDetail{slotNumber: 200} + events := extractor.ExtractCPIEvents(tx, meta, detail, 0) + + require.Len(t, events, 1) + require.True(t, events[0].IsCPI) + require.Equal(t, sourceProgram.ToSolana().String(), events[0].Program) + + decodedData, err := base64.StdEncoding.DecodeString(events[0].Data) + require.NoError(t, err) + require.Equal(t, eventData, decodedData) + }) + + t.Run("rejects vec-format CPI event with mismatched declared length", func(t *testing.T) { + extractor := NewCPIEventExtractor(logger.Sugared(logger.Test(t))) + + sourceProgram := newRandomPublicKey(t) + destProgram := newRandomPublicKey(t) + methodSig := newRandomEventSignature(t) + + filter := types.Filter{ + ID: 1, + Name: "ccip-cpi-filter", + Address: sourceProgram, + EventSig: newRandomEventSignature(t), + ExtraFilterConfig: types.ExtraFilterConfig{ + DestProgram: destProgram, + MethodSignature: methodSig, + }, + } + extractor.AddFilter(filter) + + eventData := []byte{0xAA, 0xBB, 0xCC, 0xDD} + wrongLen := make([]byte, 4) + binary.LittleEndian.PutUint32(wrongLen, uint32(len(eventData)+99)) //nolint:gosec + innerInstData := append(methodSig[:], append(wrongLen, eventData...)...) + + tx := &solana.Transaction{ + Message: solana.Message{ + AccountKeys: []solana.PublicKey{ + solana.PublicKey(sourceProgram), + solana.PublicKey(destProgram), + }, + Instructions: []solana.CompiledInstruction{ + {ProgramIDIndex: 0}, + }, + }, + } + + meta := &rpc.TransactionMeta{ + InnerInstructions: []rpc.InnerInstruction{ + { + Index: 0, + Instructions: []rpc.CompiledInstruction{ + { + ProgramIDIndex: 1, + Data: innerInstData, + StackHeight: 2, + }, + }, + }, + }, + } + + detail := eventDetail{slotNumber: 100} + events := extractor.ExtractCPIEvents(tx, meta, detail, 0) + require.Empty(t, events) + }) + + t.Run("rejects vec-format CPI event with zero declared length", func(t *testing.T) { + extractor := NewCPIEventExtractor(logger.Sugared(logger.Test(t))) + + sourceProgram := newRandomPublicKey(t) + destProgram := newRandomPublicKey(t) + methodSig := newRandomEventSignature(t) + + filter := types.Filter{ + ID: 1, + Name: "ccip-cpi-filter", + Address: sourceProgram, + EventSig: newRandomEventSignature(t), + ExtraFilterConfig: types.ExtraFilterConfig{ + DestProgram: destProgram, + MethodSignature: methodSig, + }, + } + extractor.AddFilter(filter) + + eventData := []byte{0xAA, 0xBB, 0xCC, 0xDD} + zeroLen := []byte{0x00, 0x00, 0x00, 0x00} + innerInstData := append(methodSig[:], append(zeroLen, eventData...)...) + + tx := &solana.Transaction{ + Message: solana.Message{ + AccountKeys: []solana.PublicKey{ + solana.PublicKey(sourceProgram), + solana.PublicKey(destProgram), + }, + Instructions: []solana.CompiledInstruction{ + {ProgramIDIndex: 0}, + }, + }, + } + + meta := &rpc.TransactionMeta{ + InnerInstructions: []rpc.InnerInstruction{ + { + Index: 0, + Instructions: []rpc.CompiledInstruction{ + { + ProgramIDIndex: 1, + Data: innerInstData, + StackHeight: 2, + }, + }, + }, + }, + } + + detail := eventDetail{slotNumber: 100} + events := extractor.ExtractCPIEvents(tx, meta, detail, 0) + require.Empty(t, events) + }) + + t.Run("falls back to outer program when StackHeight is zero", func(t *testing.T) { + extractor := NewCPIEventExtractor(logger.Sugared(logger.Test(t))) + + outerProgram := newRandomPublicKey(t) + destProgram := newRandomPublicKey(t) + methodSig := newRandomEventSignature(t) + + filter := types.Filter{ + ID: 1, + Name: "cpi-filter-stackheight-zero", + Address: outerProgram, + EventSig: newRandomEventSignature(t), + ExtraFilterConfig: types.ExtraFilterConfig{ + DestProgram: destProgram, + MethodSignature: methodSig, + }, + } + extractor.AddFilter(filter) + + eventData := []byte{0xCA, 0xFE, 0xBA, 0xBE} + vecLengthPrefix := make([]byte, 4) + binary.LittleEndian.PutUint32(vecLengthPrefix, uint32(len(eventData))) //nolint:gosec + innerInstData := append(methodSig[:], append(vecLengthPrefix, eventData...)...) + + tx := &solana.Transaction{ + Message: solana.Message{ + AccountKeys: []solana.PublicKey{ + solana.PublicKey(outerProgram), + solana.PublicKey(destProgram), + }, + Instructions: []solana.CompiledInstruction{ + {ProgramIDIndex: 0}, + }, + }, + } + + meta := &rpc.TransactionMeta{ + InnerInstructions: []rpc.InnerInstruction{ + { + Index: 0, + Instructions: []rpc.CompiledInstruction{ + { + ProgramIDIndex: 1, + Data: innerInstData, + StackHeight: 0, + }, + }, + }, + }, + } + + detail := eventDetail{slotNumber: 100} + events := extractor.ExtractCPIEvents(tx, meta, detail, 0) + + require.Len(t, events, 1) + require.True(t, events[0].IsCPI) + require.Equal(t, outerProgram.ToSolana().String(), events[0].Program) + }) +} + +func TestExtractAnchorCPIEventData(t *testing.T) { + t.Run("returns event data after discriminator", func(t *testing.T) { + disc := types.AnchorCPIEventDiscriminator() + payload := []byte{0x01, 0x02, 0x03, 0x04} + data := append(disc[:], payload...) + + result, ok := extractAnchorCPIEventData(data) + require.True(t, ok) + require.Equal(t, payload, result) + }) + + t.Run("rejects data too short", func(t *testing.T) { + data := make([]byte, MethodDiscriminatorLen) + result, ok := extractAnchorCPIEventData(data) + require.False(t, ok) + require.Nil(t, result) + }) +} + +func TestExtractVecCPIEventData(t *testing.T) { + t.Run("returns event data with valid vec prefix", func(t *testing.T) { + disc := make([]byte, MethodDiscriminatorLen) + payload := []byte{0xAA, 0xBB, 0xCC, 0xDD} + vecLen := make([]byte, 4) + binary.LittleEndian.PutUint32(vecLen, uint32(len(payload))) //nolint:gosec + data := append(disc, append(vecLen, payload...)...) + + result, ok := extractVecCPIEventData(data) + require.True(t, ok) + require.Equal(t, payload, result) + }) + + t.Run("rejects mismatched declared length", func(t *testing.T) { + disc := make([]byte, MethodDiscriminatorLen) + payload := []byte{0xAA, 0xBB, 0xCC, 0xDD} + vecLen := make([]byte, 4) + binary.LittleEndian.PutUint32(vecLen, uint32(len(payload)+10)) //nolint:gosec + data := append(disc, append(vecLen, payload...)...) + + result, ok := extractVecCPIEventData(data) + require.False(t, ok) + require.Nil(t, result) + }) + + t.Run("rejects zero declared length", func(t *testing.T) { + disc := make([]byte, MethodDiscriminatorLen) + payload := []byte{0xAA, 0xBB, 0xCC, 0xDD} + vecLen := []byte{0x00, 0x00, 0x00, 0x00} + data := append(disc, append(vecLen, payload...)...) + + result, ok := extractVecCPIEventData(data) + require.False(t, ok) + require.Nil(t, result) + }) + + t.Run("rejects data shorter than legacy offset", func(t *testing.T) { + data := make([]byte, CPIEventDataOffsetLegacy-1) + result, ok := extractVecCPIEventData(data) + require.False(t, ok) + require.Nil(t, result) + }) } diff --git a/pkg/solana/logpoller/types/types.go b/pkg/solana/logpoller/types/types.go index 7e3ab6edf..848675421 100644 --- a/pkg/solana/logpoller/types/types.go +++ b/pkg/solana/logpoller/types/types.go @@ -2,6 +2,7 @@ package types import ( "context" + "crypto/sha256" "database/sql/driver" "encoding/binary" "encoding/json" @@ -18,6 +19,10 @@ import ( codecv1 "github.com/smartcontractkit/chainlink-solana/pkg/solana/codec/v1" ) +// AnchorCPIMethodName is the method name used by Anchor's emit_cpi! macro. +// The discriminator is the first 8 bytes of SHA256("anchor:event"). +const AnchorCPIMethodName = "anchor:event" + type PublicKey solana.PublicKey // Scan implements Scanner for database/sql. @@ -129,6 +134,19 @@ func NewMethodSignatureFromName(methodName string) EventSignature { return EventSignature(solcommoncodec.NewMethodDiscriminatorHashPrefix(methodName)) } +// AnchorCPIEventDiscriminator returns the 8-byte instruction discriminator used by +// Anchor's emit_cpi! macro. Anchor computes SHA256("anchor:event"), interprets the +// first 8 bytes as a big-endian u64, and writes it on-chain as little-endian. +// This matches Anchor's EVENT_IX_TAG_LE constant. +func AnchorCPIEventDiscriminator() EventSignature { + sum := sha256.Sum256([]byte(AnchorCPIMethodName)) + var sig EventSignature + for i := range EventSignatureLength { + sig[i] = sum[EventSignatureLength-1-i] + } + return sig +} + // Scan implements Scanner for database/sql. func (s *EventSignature) Scan(src interface{}) error { return scanFixedLengthArray("EventSignature", EventSignatureLength, src, s[:]) diff --git a/pkg/solana/logpoller/types/types_test.go b/pkg/solana/logpoller/types/types_test.go new file mode 100644 index 000000000..d02658bab --- /dev/null +++ b/pkg/solana/logpoller/types/types_test.go @@ -0,0 +1,23 @@ +package types + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestDiscriminatorStability(t *testing.T) { + t.Run("AnchorCPIEventDiscriminator matches Anchor EVENT_IX_TAG_LE", func(t *testing.T) { + expected := EventSignature{0xe4, 0x45, 0xa5, 0x2e, 0x51, 0xcb, 0x9a, 0x1d} + require.Equal(t, expected, AnchorCPIEventDiscriminator()) + }) + + t.Run("cpiEvent method signature matches CCIP RMN Remote Instruction_CpiEvent", func(t *testing.T) { + expected := EventSignature{0xbc, 0xd8, 0xa6, 0x6c, 0x1a, 0xa6, 0x8e, 0xb6} + require.Equal(t, expected, NewMethodSignatureFromName("cpiEvent")) + }) + + t.Run("AnchorCPIEventDiscriminator differs from cpiEvent method signature", func(t *testing.T) { + require.NotEqual(t, AnchorCPIEventDiscriminator(), NewMethodSignatureFromName("cpiEvent")) + }) +} diff --git a/pkg/solana/solana_service.go b/pkg/solana/solana_service.go index a0e1347ab..a59abcb4f 100644 --- a/pkg/solana/solana_service.go +++ b/pkg/solana/solana_service.go @@ -648,7 +648,7 @@ func convertSolPubKeysToCommon(keys []solana.PublicKey) []commonsol.PublicKey { } func convertFilter(f commonsol.LPFilterQuery) (logpollertypes.Filter, error) { - return logpollertypes.Filter{ + filter := logpollertypes.Filter{ Name: f.Name, Address: logpollertypes.PublicKey(f.Address), EventName: f.EventName, @@ -659,7 +659,27 @@ func convertFilter(f commonsol.LPFilterQuery) (logpollertypes.Filter, error) { Retention: f.Retention, MaxLogsKept: f.MaxLogsKept, IncludeReverted: f.IncludeReverted, - }, nil + } + + if f.CPIFilterConfig != nil { + if len(f.CPIFilterConfig.DestAddress) != solana.PublicKeyLength { + return logpollertypes.Filter{}, fmt.Errorf("invalid CPI filter dest address length: expected %d, got %d", solana.PublicKeyLength, len(f.CPIFilterConfig.DestAddress)) + } + var destProgram logpollertypes.PublicKey + copy(destProgram[:], f.CPIFilterConfig.DestAddress[:]) + methodSig := logpollertypes.EventSignature{} + if f.CPIFilterConfig.MethodName == logpollertypes.AnchorCPIMethodName { + methodSig = logpollertypes.AnchorCPIEventDiscriminator() + } else { + methodSig = logpollertypes.NewMethodSignatureFromName(f.CPIFilterConfig.MethodName) + } + filter.ExtraFilterConfig = logpollertypes.ExtraFilterConfig{ + DestProgram: destProgram, + MethodSignature: methodSig, + } + } + + return filter, nil } func convertAccounts(accs []*rpc.Account) ([]*commonsol.Account, error) { From 14d8c5096e3f86dfbb4d178597e589e55831e0cf Mon Sep 17 00:00:00 2001 From: Silas Lenihan Date: Tue, 10 Mar 2026 17:30:12 -0400 Subject: [PATCH 2/8] temp / add debug logging --- pkg/solana/logpoller/cpi_event_extractor.go | 72 ++++++++++++++++++++- pkg/solana/logpoller/filters.go | 22 +++++++ pkg/solana/logpoller/job_get_block.go | 24 ++++++- 3 files changed, 114 insertions(+), 4 deletions(-) diff --git a/pkg/solana/logpoller/cpi_event_extractor.go b/pkg/solana/logpoller/cpi_event_extractor.go index c42d7593a..c32e3e0e0 100644 --- a/pkg/solana/logpoller/cpi_event_extractor.go +++ b/pkg/solana/logpoller/cpi_event_extractor.go @@ -2,9 +2,9 @@ package logpoller import ( "encoding/base64" - "sync" - bin "encoding/binary" + "fmt" + "sync" "github.com/gagliardetto/solana-go" "github.com/gagliardetto/solana-go/rpc" @@ -55,6 +55,13 @@ func (e *CPIEventExtractor) AddFilter(filter types.Filter) { defer e.mu.Unlock() e.registered[key] = struct{}{} + e.lggr.Infow("[DEBUG] CPI filter added", + "filterName", filter.Name, + "sourceProgram", filter.Address.ToSolana().String(), + "destProgram", filter.ExtraFilterConfig.DestProgram.ToSolana().String(), + "methodSig", fmt.Sprintf("%x", filter.ExtraFilterConfig.MethodSignature), + "totalRegistered", len(e.registered), + ) } func (e *CPIEventExtractor) RemoveFilter(filter types.Filter) { @@ -87,17 +94,28 @@ func (e *CPIEventExtractor) ExtractCPIEvents( logIdxOffset uint, ) []types.ProgramEvent { if meta == nil || len(meta.InnerInstructions) == 0 { + e.lggr.Debugw("[DEBUG] ExtractCPIEvents: no inner instructions", + "slot", detail.slotNumber, "metaNil", meta == nil) return nil } allAccountKeys := getAllAccountKeys(tx, meta) if len(allAccountKeys) == 0 { + e.lggr.Debugw("[DEBUG] ExtractCPIEvents: no account keys", "slot", detail.slotNumber) return nil } e.mu.RLock() defer e.mu.RUnlock() + e.lggr.Infow("[DEBUG] ExtractCPIEvents: processing transaction", + "slot", detail.slotNumber, + "txSig", detail.trxSig.String(), + "innerInstructionSets", len(meta.InnerInstructions), + "registeredFilters", len(e.registered), + "accountKeys", len(allAccountKeys), + ) + var events []types.ProgramEvent logIdx := logIdxOffset @@ -118,7 +136,14 @@ func (e *CPIEventExtractor) ExtractCPIEvents( 1: outerProgram, } - for _, ix := range inner.Instructions { + e.lggr.Infow("[DEBUG] ExtractCPIEvents: processing inner instruction set", + "slot", detail.slotNumber, + "outerIndex", inner.Index, + "outerProgram", outerProgram.ToSolana().String(), + "innerIxCount", len(inner.Instructions), + ) + + for ixIdx, ix := range inner.Instructions { if int(ix.ProgramIDIndex) >= len(allAccountKeys) { e.lggr.Warnf("program ID index out of range: %d, len(allAccountKeys): %d", ix.ProgramIDIndex, len(allAccountKeys)) continue @@ -129,11 +154,29 @@ func (e *CPIEventExtractor) ExtractCPIEvents( programAtStackHeight[ix.StackHeight] = destProgram } + e.lggr.Infow("[DEBUG] ExtractCPIEvents: inner ix", + "slot", detail.slotNumber, + "ixIdx", ixIdx, + "destProgram", destProgram.ToSolana().String(), + "stackHeight", ix.StackHeight, + "dataLen", len(ix.Data), + ) + if len(ix.Data) <= MethodDiscriminatorLen { + e.lggr.Debugw("[DEBUG] ExtractCPIEvents: data too short for method disc", + "slot", detail.slotNumber, "dataLen", len(ix.Data)) continue } methodSig := types.EventSignature(ix.Data[:MethodDiscriminatorLen]) + anchorDisc := types.AnchorCPIEventDiscriminator() + + e.lggr.Infow("[DEBUG] ExtractCPIEvents: method discriminator check", + "slot", detail.slotNumber, + "methodSigHex", fmt.Sprintf("%x", methodSig), + "anchorDiscHex", fmt.Sprintf("%x", anchorDisc), + "isAnchor", methodSig == anchorDisc, + ) var eventData []byte var ok bool @@ -143,6 +186,8 @@ func (e *CPIEventExtractor) ExtractCPIEvents( eventData, ok = extractVecCPIEventData(ix.Data) } if !ok || len(eventData) == 0 { + e.lggr.Debugw("[DEBUG] ExtractCPIEvents: event data extraction failed or empty", + "slot", detail.slotNumber, "ok", ok, "eventDataLen", len(eventData)) continue } @@ -166,7 +211,28 @@ func (e *CPIEventExtractor) ExtractCPIEvents( methodSig: methodSig, } + e.lggr.Infow("[DEBUG] ExtractCPIEvents: filter key lookup", + "slot", detail.slotNumber, + "sourceProgram", sourceProgram.ToSolana().String(), + "destProgram", destProgram.ToSolana().String(), + "methodSigHex", fmt.Sprintf("%x", methodSig), + "eventDataLen", len(eventData), + ) + if _, ok := e.registered[key]; !ok { + e.lggr.Warnw("[DEBUG] ExtractCPIEvents: NO matching registered filter", + "slot", detail.slotNumber, + "sourceProgram", sourceProgram.ToSolana().String(), + "destProgram", destProgram.ToSolana().String(), + "methodSigHex", fmt.Sprintf("%x", methodSig), + ) + for rk := range e.registered { + e.lggr.Infow("[DEBUG] ExtractCPIEvents: registered key dump", + "regSource", rk.sourceProgram.ToSolana().String(), + "regDest", rk.destProgram.ToSolana().String(), + "regMethodHex", fmt.Sprintf("%x", rk.methodSig), + ) + } continue } diff --git a/pkg/solana/logpoller/filters.go b/pkg/solana/logpoller/filters.go index 13e07f3e4..0fc372ffa 100644 --- a/pkg/solana/logpoller/filters.go +++ b/pkg/solana/logpoller/filters.go @@ -163,10 +163,26 @@ func (fl *filters) RegisterFilter(ctx context.Context, filter types.Filter) erro fl.filtersMutex.Lock() defer fl.filtersMutex.Unlock() + fl.lggr.Infow("[DEBUG] RegisterFilter called", + "filterName", filter.Name, + "isCPI", filter.IsCPIFilter(), + "address", filter.Address.ToSolana().String(), + "eventName", filter.EventName, + ) + filter.IsBackfilled = false if existingFilterID, ok := fl.filtersByName[filter.Name]; ok { existingFilter := fl.filtersByID[existingFilterID] if !existingFilter.MatchSameLogs(filter) { + fl.lggr.Errorw("[DEBUG] RegisterFilter: ErrFilterNameConflict", + "filterName", filter.Name, + "existingIdlLen", len(existingFilter.ContractIdl), + "newIdlLen", len(filter.ContractIdl), + "idlMatch", existingFilter.ContractIdl == filter.ContractIdl, + "addressMatch", existingFilter.Address == filter.Address, + "eventSigMatch", existingFilter.EventSig == filter.EventSig, + "eventNameMatch", existingFilter.EventName == filter.EventName, + ) return ErrFilterNameConflict } if existingFilter.IsBackfilled { @@ -207,6 +223,12 @@ func (fl *filters) RegisterFilter(ctx context.Context, filter types.Filter) erro filter.ID = filterID fl.addToIndices(filter, decoder) + fl.lggr.Infow("[DEBUG] RegisterFilter succeeded", + "filterName", filter.Name, + "filterID", filterID, + "isCPI", filter.IsCPIFilter(), + ) + return nil } diff --git a/pkg/solana/logpoller/job_get_block.go b/pkg/solana/logpoller/job_get_block.go index 7420dfca5..fb6e8a8c0 100644 --- a/pkg/solana/logpoller/job_get_block.go +++ b/pkg/solana/logpoller/job_get_block.go @@ -154,8 +154,30 @@ func (j *getBlockJob) Run(ctx context.Context) error { events = append(events, txEvents...) // Look for events corresponding to CPI filters - if j.cpiEventExtractor != nil && j.cpiEventExtractor.HasCPIFilters() { + hasCPIExtractor := j.cpiEventExtractor != nil + hasCPIFilters := hasCPIExtractor && j.cpiEventExtractor.HasCPIFilters() + innerIxCount := 0 + if txWithMeta.Meta != nil { + innerIxCount = len(txWithMeta.Meta.InnerInstructions) + } + + j.lggr.Infow("[DEBUG] getBlock: CPI extraction check", + "slot", j.slotNumber, + "txIdx", idx, + "txSig", tx.Signatures[0].String(), + "hasCPIExtractor", hasCPIExtractor, + "hasCPIFilters", hasCPIFilters, + "innerInstructionSets", innerIxCount, + "logEvents", len(txEvents), + ) + + if hasCPIFilters { cpiEvents := j.cpiEventExtractor.ExtractCPIEvents(tx, txWithMeta.Meta, detail, uint(len(txEvents))) + j.lggr.Infow("[DEBUG] getBlock: CPI extraction result", + "slot", j.slotNumber, + "txIdx", idx, + "cpiEventsFound", len(cpiEvents), + ) events = append(events, cpiEvents...) } } From a6fc4289170a377c1e92dc1e0a49cfb90c8f22b4 Mon Sep 17 00:00:00 2001 From: Silas Lenihan Date: Tue, 10 Mar 2026 17:45:27 -0400 Subject: [PATCH 3/8] bump go.mod --- contracts/go.mod | 2 +- contracts/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/contracts/go.mod b/contracts/go.mod index f037e7e99..b88b82457 100644 --- a/contracts/go.mod +++ b/contracts/go.mod @@ -124,7 +124,7 @@ require ( github.com/sirupsen/logrus v1.9.4 // indirect github.com/smartcontractkit/chain-selectors v1.0.97 // indirect github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 // indirect - github.com/smartcontractkit/chainlink-common v0.10.1-0.20260304224420-7456e47e1226 // indirect + github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310214427-ba2a83e55fbf // indirect github.com/smartcontractkit/chainlink-testing-framework/framework v0.14.3 // indirect github.com/smartcontractkit/chainlink-ton v0.0.0-20260219201907-054376f21418 // indirect github.com/smartcontractkit/chainlink-tron/relayer v0.0.11-0.20251014143056-a0c6328c91e9 // indirect diff --git a/contracts/go.sum b/contracts/go.sum index b0ee2ef63..21bb35341 100644 --- a/contracts/go.sum +++ b/contracts/go.sum @@ -503,8 +503,8 @@ github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260220192608-a github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260220192608-af6bd538e0ca/go.mod h1:k1aNQP8nPFkSqWJZ4kFQaa1JGlWVIg6Y+XA2++qs6Cg= github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 h1:Z4t2ZY+ZyGWxtcXvPr11y4o3CGqhg3frJB5jXkCSvWA= github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5/go.mod h1:xtZNi6pOKdC3sLvokDvXOhgHzT+cyBqH/gWwvxTxqrg= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260304224420-7456e47e1226 h1:XZ4yNFF8yspofSeVVwegXxZjmpngdXVsaowLNI7o9+A= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260304224420-7456e47e1226/go.mod h1:2+zTrPZBRMJdrDqCKfFhk3WokQ+jfP5UEFaEtOEruk0= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310214427-ba2a83e55fbf h1:f3g1hZ2jXCdQegjIgAmgNhiLRSewFoBY00ZXGfwB78A= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310214427-ba2a83e55fbf/go.mod h1:2+zTrPZBRMJdrDqCKfFhk3WokQ+jfP5UEFaEtOEruk0= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 h1:FJAFgXS9oqASnkS03RE1HQwYQQxrO4l46O5JSzxqLgg= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10/go.mod h1:oiDa54M0FwxevWwyAX773lwdWvFYYlYHHQV1LQ5HpWY= github.com/smartcontractkit/chainlink-deployments-framework v0.81.2 h1:rEPEywuLv6YPIN6YhXJpReapVM+bPOOLXlpJwItlTu0= diff --git a/go.mod b/go.mod index a517197cb..4845a0926 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/smartcontractkit/chainlink-ccip v0.1.1-solana.0.20260203202624-5101f4d33736 github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260121163256-85accaf3d28d github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 - github.com/smartcontractkit/chainlink-common v0.10.1-0.20260304224420-7456e47e1226 + github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310214427-ba2a83e55fbf github.com/smartcontractkit/chainlink-common/keystore v1.0.0 github.com/smartcontractkit/chainlink-common/pkg/monitoring v0.0.0-20251215152504-b1e41f508340 github.com/smartcontractkit/chainlink-framework/metrics v0.0.0-20251210101658-1c5c8e4c4f15 diff --git a/go.sum b/go.sum index 2e867afb0..173409e57 100644 --- a/go.sum +++ b/go.sum @@ -565,8 +565,8 @@ github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260121163256-8 github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260121163256-85accaf3d28d/go.mod h1:bgmqE7x9xwmIVr8PqLbC0M5iPm4AV2DBl596lO6S5Sw= github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 h1:Z4t2ZY+ZyGWxtcXvPr11y4o3CGqhg3frJB5jXkCSvWA= github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5/go.mod h1:xtZNi6pOKdC3sLvokDvXOhgHzT+cyBqH/gWwvxTxqrg= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260304224420-7456e47e1226 h1:XZ4yNFF8yspofSeVVwegXxZjmpngdXVsaowLNI7o9+A= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260304224420-7456e47e1226/go.mod h1:2+zTrPZBRMJdrDqCKfFhk3WokQ+jfP5UEFaEtOEruk0= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310214427-ba2a83e55fbf h1:f3g1hZ2jXCdQegjIgAmgNhiLRSewFoBY00ZXGfwB78A= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310214427-ba2a83e55fbf/go.mod h1:2+zTrPZBRMJdrDqCKfFhk3WokQ+jfP5UEFaEtOEruk0= github.com/smartcontractkit/chainlink-common/keystore v1.0.0 h1:sVa3j2FWK/5OxXpnlfDkF1deDAkuXEfaLKzYqBTA880= github.com/smartcontractkit/chainlink-common/keystore v1.0.0/go.mod h1:wGRJJlCFUOKIfBlBGEdBFiTf7R787B8HKyobjiymw3Q= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 h1:FJAFgXS9oqASnkS03RE1HQwYQQxrO4l46O5JSzxqLgg= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 96998042b..9b118425a 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -19,7 +19,7 @@ require ( github.com/rs/zerolog v1.34.0 github.com/smartcontractkit/chain-selectors v1.0.97 github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260220192608-af6bd538e0ca - github.com/smartcontractkit/chainlink-common v0.10.1-0.20260304224420-7456e47e1226 + github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310214427-ba2a83e55fbf github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260304224222-c5c5976d3417 github.com/smartcontractkit/chainlink-solana v1.1.2-0.20260223132514-df62be174f36 github.com/smartcontractkit/chainlink-solana/contracts v0.0.0-20260217175957-8f1af02c5075 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 8aba08fce..1ea4454d7 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1351,8 +1351,8 @@ github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250 github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5/go.mod h1:xtZNi6pOKdC3sLvokDvXOhgHzT+cyBqH/gWwvxTxqrg= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260219123955-11b2ac2cfa68 h1:Jy6LtNVM11MCDBYFAKMPeWUnT3Q2U1n4gVlwx1IKvlw= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260219123955-11b2ac2cfa68/go.mod h1:RnuNcn7DZmjmzEkeEWX0uL5y1oslB3c9URPLOjFU+jE= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260304224420-7456e47e1226 h1:XZ4yNFF8yspofSeVVwegXxZjmpngdXVsaowLNI7o9+A= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260304224420-7456e47e1226/go.mod h1:2+zTrPZBRMJdrDqCKfFhk3WokQ+jfP5UEFaEtOEruk0= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310214427-ba2a83e55fbf h1:f3g1hZ2jXCdQegjIgAmgNhiLRSewFoBY00ZXGfwB78A= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310214427-ba2a83e55fbf/go.mod h1:2+zTrPZBRMJdrDqCKfFhk3WokQ+jfP5UEFaEtOEruk0= github.com/smartcontractkit/chainlink-common/keystore v1.0.2 h1:AWisx4JT3QV8tcgh6J5NCrex+wAgTYpWyHsyNPSXzsQ= github.com/smartcontractkit/chainlink-common/keystore v1.0.2/go.mod h1:rSkIHdomyak3YnUtXLenl6poIq8q0V3UZPiiyYqPdGA= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 h1:FJAFgXS9oqASnkS03RE1HQwYQQxrO4l46O5JSzxqLgg= From ffc28669a9bb5e9e66e4334eef1aebf0a720ff05 Mon Sep 17 00:00:00 2001 From: Silas Lenihan Date: Tue, 10 Mar 2026 18:04:41 -0400 Subject: [PATCH 4/8] temp / add debug logging 2 --- pkg/solana/solana_service.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pkg/solana/solana_service.go b/pkg/solana/solana_service.go index a59abcb4f..9d3c8d62d 100644 --- a/pkg/solana/solana_service.go +++ b/pkg/solana/solana_service.go @@ -125,6 +125,20 @@ func (ss *solanaService) SimulateTX(ctx context.Context, req commonsol.SimulateT } func (ss *solanaService) RegisterLogTracking(ctx context.Context, req commonsol.LPFilterQuery) error { + // Diagnostic: log what we received over the wire (after gRPC + FromProto) + hasCPI := req.CPIFilterConfig != nil + ss.logger.Infow("[DEBUG] RegisterLogTracking received", + "filterName", req.Name, + "hasCPIFilterConfig", hasCPI, + ) + if hasCPI { + ss.logger.Infow("[DEBUG] RegisterLogTracking CPI config", + "filterName", req.Name, + "destAddressLen", len(req.CPIFilterConfig.DestAddress), + "methodName", req.CPIFilterConfig.MethodName, + ) + } + lp := ss.chain.LogPoller() if lp.HasFilter(ctx, req.Name) { return nil From ccd91a10def3670aa639a0e9909d069ffeaefaff Mon Sep 17 00:00:00 2001 From: Silas Lenihan Date: Wed, 11 Mar 2026 14:15:08 -0400 Subject: [PATCH 5/8] bump go.mod --- contracts/go.mod | 2 +- contracts/go.sum | 4 ++-- go.mod | 4 ++-- go.sum | 8 ++++---- integration-tests/go.mod | 4 ++-- integration-tests/go.sum | 8 ++++---- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/contracts/go.mod b/contracts/go.mod index b88b82457..9e7a6b2ca 100644 --- a/contracts/go.mod +++ b/contracts/go.mod @@ -124,7 +124,7 @@ require ( github.com/sirupsen/logrus v1.9.4 // indirect github.com/smartcontractkit/chain-selectors v1.0.97 // indirect github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 // indirect - github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310214427-ba2a83e55fbf // indirect + github.com/smartcontractkit/chainlink-common v0.10.1-0.20260311181236-0a45615ebb7f // indirect github.com/smartcontractkit/chainlink-testing-framework/framework v0.14.3 // indirect github.com/smartcontractkit/chainlink-ton v0.0.0-20260219201907-054376f21418 // indirect github.com/smartcontractkit/chainlink-tron/relayer v0.0.11-0.20251014143056-a0c6328c91e9 // indirect diff --git a/contracts/go.sum b/contracts/go.sum index 21bb35341..07dfa1684 100644 --- a/contracts/go.sum +++ b/contracts/go.sum @@ -503,8 +503,8 @@ github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260220192608-a github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260220192608-af6bd538e0ca/go.mod h1:k1aNQP8nPFkSqWJZ4kFQaa1JGlWVIg6Y+XA2++qs6Cg= github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 h1:Z4t2ZY+ZyGWxtcXvPr11y4o3CGqhg3frJB5jXkCSvWA= github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5/go.mod h1:xtZNi6pOKdC3sLvokDvXOhgHzT+cyBqH/gWwvxTxqrg= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310214427-ba2a83e55fbf h1:f3g1hZ2jXCdQegjIgAmgNhiLRSewFoBY00ZXGfwB78A= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310214427-ba2a83e55fbf/go.mod h1:2+zTrPZBRMJdrDqCKfFhk3WokQ+jfP5UEFaEtOEruk0= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260311181236-0a45615ebb7f h1:H/w8KWN1tNgkYa+4PjwX2IMPJ4IVFAkCGBbhGRs4cR0= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260311181236-0a45615ebb7f/go.mod h1:AvurM0bnW/WJdxKD1kYF14aNX/+Pf2xZWp7wKeMl+Bo= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 h1:FJAFgXS9oqASnkS03RE1HQwYQQxrO4l46O5JSzxqLgg= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10/go.mod h1:oiDa54M0FwxevWwyAX773lwdWvFYYlYHHQV1LQ5HpWY= github.com/smartcontractkit/chainlink-deployments-framework v0.81.2 h1:rEPEywuLv6YPIN6YhXJpReapVM+bPOOLXlpJwItlTu0= diff --git a/go.mod b/go.mod index 4845a0926..991794a67 100644 --- a/go.mod +++ b/go.mod @@ -22,12 +22,12 @@ require ( github.com/smartcontractkit/chainlink-ccip v0.1.1-solana.0.20260203202624-5101f4d33736 github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260121163256-85accaf3d28d github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 - github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310214427-ba2a83e55fbf + github.com/smartcontractkit/chainlink-common v0.10.1-0.20260311181236-0a45615ebb7f github.com/smartcontractkit/chainlink-common/keystore v1.0.0 github.com/smartcontractkit/chainlink-common/pkg/monitoring v0.0.0-20251215152504-b1e41f508340 github.com/smartcontractkit/chainlink-framework/metrics v0.0.0-20251210101658-1c5c8e4c4f15 github.com/smartcontractkit/chainlink-framework/multinode v0.0.0-20251021173435-e86785845942 - github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260304224222-c5c5976d3417 + github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260311180747-73ee31ef1766 github.com/smartcontractkit/freeport v0.1.3-0.20250716200817-cb5dfd0e369e github.com/smartcontractkit/libocr v0.0.0-20251212213002-0a5e2f907dda github.com/stretchr/testify v1.11.1 diff --git a/go.sum b/go.sum index 173409e57..6785030df 100644 --- a/go.sum +++ b/go.sum @@ -565,8 +565,8 @@ github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260121163256-8 github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260121163256-85accaf3d28d/go.mod h1:bgmqE7x9xwmIVr8PqLbC0M5iPm4AV2DBl596lO6S5Sw= github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 h1:Z4t2ZY+ZyGWxtcXvPr11y4o3CGqhg3frJB5jXkCSvWA= github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5/go.mod h1:xtZNi6pOKdC3sLvokDvXOhgHzT+cyBqH/gWwvxTxqrg= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310214427-ba2a83e55fbf h1:f3g1hZ2jXCdQegjIgAmgNhiLRSewFoBY00ZXGfwB78A= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310214427-ba2a83e55fbf/go.mod h1:2+zTrPZBRMJdrDqCKfFhk3WokQ+jfP5UEFaEtOEruk0= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260311181236-0a45615ebb7f h1:H/w8KWN1tNgkYa+4PjwX2IMPJ4IVFAkCGBbhGRs4cR0= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260311181236-0a45615ebb7f/go.mod h1:AvurM0bnW/WJdxKD1kYF14aNX/+Pf2xZWp7wKeMl+Bo= github.com/smartcontractkit/chainlink-common/keystore v1.0.0 h1:sVa3j2FWK/5OxXpnlfDkF1deDAkuXEfaLKzYqBTA880= github.com/smartcontractkit/chainlink-common/keystore v1.0.0/go.mod h1:wGRJJlCFUOKIfBlBGEdBFiTf7R787B8HKyobjiymw3Q= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 h1:FJAFgXS9oqASnkS03RE1HQwYQQxrO4l46O5JSzxqLgg= @@ -577,8 +577,8 @@ github.com/smartcontractkit/chainlink-framework/metrics v0.0.0-20251210101658-1c github.com/smartcontractkit/chainlink-framework/metrics v0.0.0-20251210101658-1c5c8e4c4f15/go.mod h1:HG/aei0MgBOpsyRLexdKGtOUO8yjSJO3iUu0Uu8KBm4= github.com/smartcontractkit/chainlink-framework/multinode v0.0.0-20251021173435-e86785845942 h1:T/eCDsUI8EJT4n5zSP4w1mz4RHH+ap8qieA17QYfBhk= github.com/smartcontractkit/chainlink-framework/multinode v0.0.0-20251021173435-e86785845942/go.mod h1:2JTBNp3FlRdO/nHc4dsc9bfxxMClMO1Qt8sLJgtreBY= -github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260304224222-c5c5976d3417 h1:WEmNgQGjbYJH50EtaII8iX5Vx3VcOX10AMuhmK8VTaA= -github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260304224222-c5c5976d3417/go.mod h1:Jqt53s27Tr0jDl8mdBXg1xhu6F8Fci8JOuq43tgHOM8= +github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260311180747-73ee31ef1766 h1:6dCPm7XRRhYmYtoHzxbsSBrbgE5c/lk2RZMK88m/o+c= +github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260311180747-73ee31ef1766/go.mod h1:Jqt53s27Tr0jDl8mdBXg1xhu6F8Fci8JOuq43tgHOM8= github.com/smartcontractkit/chainlink-protos/linking-service/go v0.0.0-20251002192024-d2ad9222409b h1:QuI6SmQFK/zyUlVWEf0GMkiUYBPY4lssn26nKSd/bOM= github.com/smartcontractkit/chainlink-protos/linking-service/go v0.0.0-20251002192024-d2ad9222409b/go.mod h1:qSTSwX3cBP3FKQwQacdjArqv0g6QnukjV4XuzO6UyoY= github.com/smartcontractkit/chainlink-protos/node-platform v0.0.0-20260205130626-db2a2aab956b h1:36knUpKHHAZ86K4FGWXtx8i/EQftGdk2bqCoEu/Cha8= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 9b118425a..b6eea1b1b 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -19,8 +19,8 @@ require ( github.com/rs/zerolog v1.34.0 github.com/smartcontractkit/chain-selectors v1.0.97 github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260220192608-af6bd538e0ca - github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310214427-ba2a83e55fbf - github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260304224222-c5c5976d3417 + github.com/smartcontractkit/chainlink-common v0.10.1-0.20260311181236-0a45615ebb7f + github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260311180747-73ee31ef1766 github.com/smartcontractkit/chainlink-solana v1.1.2-0.20260223132514-df62be174f36 github.com/smartcontractkit/chainlink-solana/contracts v0.0.0-20260217175957-8f1af02c5075 github.com/smartcontractkit/chainlink-testing-framework/lib v1.54.7 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 1ea4454d7..51bf5c3ae 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1351,8 +1351,8 @@ github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250 github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5/go.mod h1:xtZNi6pOKdC3sLvokDvXOhgHzT+cyBqH/gWwvxTxqrg= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260219123955-11b2ac2cfa68 h1:Jy6LtNVM11MCDBYFAKMPeWUnT3Q2U1n4gVlwx1IKvlw= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260219123955-11b2ac2cfa68/go.mod h1:RnuNcn7DZmjmzEkeEWX0uL5y1oslB3c9URPLOjFU+jE= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310214427-ba2a83e55fbf h1:f3g1hZ2jXCdQegjIgAmgNhiLRSewFoBY00ZXGfwB78A= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310214427-ba2a83e55fbf/go.mod h1:2+zTrPZBRMJdrDqCKfFhk3WokQ+jfP5UEFaEtOEruk0= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260311181236-0a45615ebb7f h1:H/w8KWN1tNgkYa+4PjwX2IMPJ4IVFAkCGBbhGRs4cR0= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260311181236-0a45615ebb7f/go.mod h1:AvurM0bnW/WJdxKD1kYF14aNX/+Pf2xZWp7wKeMl+Bo= github.com/smartcontractkit/chainlink-common/keystore v1.0.2 h1:AWisx4JT3QV8tcgh6J5NCrex+wAgTYpWyHsyNPSXzsQ= github.com/smartcontractkit/chainlink-common/keystore v1.0.2/go.mod h1:rSkIHdomyak3YnUtXLenl6poIq8q0V3UZPiiyYqPdGA= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 h1:FJAFgXS9oqASnkS03RE1HQwYQQxrO4l46O5JSzxqLgg= @@ -1389,8 +1389,8 @@ github.com/smartcontractkit/chainlink-protos/chainlink-ccv/message-discovery v0. github.com/smartcontractkit/chainlink-protos/chainlink-ccv/message-discovery v0.0.0-20251211142334-5c3421fe2c8d/go.mod h1:ATjAPIVJibHRcIfiG47rEQkUIOoYa6KDvWj3zwCAw6g= github.com/smartcontractkit/chainlink-protos/chainlink-ccv/verifier v0.0.0-20251211142334-5c3421fe2c8d h1:AJy55QJ/pBhXkZjc7N+ATnWfxrcjq9BI9DmdtdjwDUQ= github.com/smartcontractkit/chainlink-protos/chainlink-ccv/verifier v0.0.0-20251211142334-5c3421fe2c8d/go.mod h1:5JdppgngCOUS76p61zCinSCgOhPeYQ+OcDUuome5THQ= -github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260304224222-c5c5976d3417 h1:WEmNgQGjbYJH50EtaII8iX5Vx3VcOX10AMuhmK8VTaA= -github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260304224222-c5c5976d3417/go.mod h1:Jqt53s27Tr0jDl8mdBXg1xhu6F8Fci8JOuq43tgHOM8= +github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260311180747-73ee31ef1766 h1:6dCPm7XRRhYmYtoHzxbsSBrbgE5c/lk2RZMK88m/o+c= +github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260311180747-73ee31ef1766/go.mod h1:Jqt53s27Tr0jDl8mdBXg1xhu6F8Fci8JOuq43tgHOM8= github.com/smartcontractkit/chainlink-protos/job-distributor v0.17.0 h1:xHPmFDhff7QpeFxKsZfk+24j4AlnQiFjjRh5O87Peu4= github.com/smartcontractkit/chainlink-protos/job-distributor v0.17.0/go.mod h1:/dVVLXrsp+V0AbcYGJo3XMzKg3CkELsweA/TTopCsKE= github.com/smartcontractkit/chainlink-protos/linking-service/go v0.0.0-20251002192024-d2ad9222409b h1:QuI6SmQFK/zyUlVWEf0GMkiUYBPY4lssn26nKSd/bOM= From 2875dfec5b3350c279256a58e6a3b2968278efbb Mon Sep 17 00:00:00 2001 From: Silas Lenihan Date: Wed, 11 Mar 2026 14:15:29 -0400 Subject: [PATCH 6/8] Revert "temp / add debug logging" This reverts commit a9fbc426d56b953a19b680369fa9bac26b52e365. --- pkg/solana/logpoller/cpi_event_extractor.go | 72 +-------------------- pkg/solana/logpoller/filters.go | 22 ------- pkg/solana/logpoller/job_get_block.go | 24 +------ 3 files changed, 4 insertions(+), 114 deletions(-) diff --git a/pkg/solana/logpoller/cpi_event_extractor.go b/pkg/solana/logpoller/cpi_event_extractor.go index c32e3e0e0..c42d7593a 100644 --- a/pkg/solana/logpoller/cpi_event_extractor.go +++ b/pkg/solana/logpoller/cpi_event_extractor.go @@ -2,10 +2,10 @@ package logpoller import ( "encoding/base64" - bin "encoding/binary" - "fmt" "sync" + bin "encoding/binary" + "github.com/gagliardetto/solana-go" "github.com/gagliardetto/solana-go/rpc" @@ -55,13 +55,6 @@ func (e *CPIEventExtractor) AddFilter(filter types.Filter) { defer e.mu.Unlock() e.registered[key] = struct{}{} - e.lggr.Infow("[DEBUG] CPI filter added", - "filterName", filter.Name, - "sourceProgram", filter.Address.ToSolana().String(), - "destProgram", filter.ExtraFilterConfig.DestProgram.ToSolana().String(), - "methodSig", fmt.Sprintf("%x", filter.ExtraFilterConfig.MethodSignature), - "totalRegistered", len(e.registered), - ) } func (e *CPIEventExtractor) RemoveFilter(filter types.Filter) { @@ -94,28 +87,17 @@ func (e *CPIEventExtractor) ExtractCPIEvents( logIdxOffset uint, ) []types.ProgramEvent { if meta == nil || len(meta.InnerInstructions) == 0 { - e.lggr.Debugw("[DEBUG] ExtractCPIEvents: no inner instructions", - "slot", detail.slotNumber, "metaNil", meta == nil) return nil } allAccountKeys := getAllAccountKeys(tx, meta) if len(allAccountKeys) == 0 { - e.lggr.Debugw("[DEBUG] ExtractCPIEvents: no account keys", "slot", detail.slotNumber) return nil } e.mu.RLock() defer e.mu.RUnlock() - e.lggr.Infow("[DEBUG] ExtractCPIEvents: processing transaction", - "slot", detail.slotNumber, - "txSig", detail.trxSig.String(), - "innerInstructionSets", len(meta.InnerInstructions), - "registeredFilters", len(e.registered), - "accountKeys", len(allAccountKeys), - ) - var events []types.ProgramEvent logIdx := logIdxOffset @@ -136,14 +118,7 @@ func (e *CPIEventExtractor) ExtractCPIEvents( 1: outerProgram, } - e.lggr.Infow("[DEBUG] ExtractCPIEvents: processing inner instruction set", - "slot", detail.slotNumber, - "outerIndex", inner.Index, - "outerProgram", outerProgram.ToSolana().String(), - "innerIxCount", len(inner.Instructions), - ) - - for ixIdx, ix := range inner.Instructions { + for _, ix := range inner.Instructions { if int(ix.ProgramIDIndex) >= len(allAccountKeys) { e.lggr.Warnf("program ID index out of range: %d, len(allAccountKeys): %d", ix.ProgramIDIndex, len(allAccountKeys)) continue @@ -154,29 +129,11 @@ func (e *CPIEventExtractor) ExtractCPIEvents( programAtStackHeight[ix.StackHeight] = destProgram } - e.lggr.Infow("[DEBUG] ExtractCPIEvents: inner ix", - "slot", detail.slotNumber, - "ixIdx", ixIdx, - "destProgram", destProgram.ToSolana().String(), - "stackHeight", ix.StackHeight, - "dataLen", len(ix.Data), - ) - if len(ix.Data) <= MethodDiscriminatorLen { - e.lggr.Debugw("[DEBUG] ExtractCPIEvents: data too short for method disc", - "slot", detail.slotNumber, "dataLen", len(ix.Data)) continue } methodSig := types.EventSignature(ix.Data[:MethodDiscriminatorLen]) - anchorDisc := types.AnchorCPIEventDiscriminator() - - e.lggr.Infow("[DEBUG] ExtractCPIEvents: method discriminator check", - "slot", detail.slotNumber, - "methodSigHex", fmt.Sprintf("%x", methodSig), - "anchorDiscHex", fmt.Sprintf("%x", anchorDisc), - "isAnchor", methodSig == anchorDisc, - ) var eventData []byte var ok bool @@ -186,8 +143,6 @@ func (e *CPIEventExtractor) ExtractCPIEvents( eventData, ok = extractVecCPIEventData(ix.Data) } if !ok || len(eventData) == 0 { - e.lggr.Debugw("[DEBUG] ExtractCPIEvents: event data extraction failed or empty", - "slot", detail.slotNumber, "ok", ok, "eventDataLen", len(eventData)) continue } @@ -211,28 +166,7 @@ func (e *CPIEventExtractor) ExtractCPIEvents( methodSig: methodSig, } - e.lggr.Infow("[DEBUG] ExtractCPIEvents: filter key lookup", - "slot", detail.slotNumber, - "sourceProgram", sourceProgram.ToSolana().String(), - "destProgram", destProgram.ToSolana().String(), - "methodSigHex", fmt.Sprintf("%x", methodSig), - "eventDataLen", len(eventData), - ) - if _, ok := e.registered[key]; !ok { - e.lggr.Warnw("[DEBUG] ExtractCPIEvents: NO matching registered filter", - "slot", detail.slotNumber, - "sourceProgram", sourceProgram.ToSolana().String(), - "destProgram", destProgram.ToSolana().String(), - "methodSigHex", fmt.Sprintf("%x", methodSig), - ) - for rk := range e.registered { - e.lggr.Infow("[DEBUG] ExtractCPIEvents: registered key dump", - "regSource", rk.sourceProgram.ToSolana().String(), - "regDest", rk.destProgram.ToSolana().String(), - "regMethodHex", fmt.Sprintf("%x", rk.methodSig), - ) - } continue } diff --git a/pkg/solana/logpoller/filters.go b/pkg/solana/logpoller/filters.go index 0fc372ffa..13e07f3e4 100644 --- a/pkg/solana/logpoller/filters.go +++ b/pkg/solana/logpoller/filters.go @@ -163,26 +163,10 @@ func (fl *filters) RegisterFilter(ctx context.Context, filter types.Filter) erro fl.filtersMutex.Lock() defer fl.filtersMutex.Unlock() - fl.lggr.Infow("[DEBUG] RegisterFilter called", - "filterName", filter.Name, - "isCPI", filter.IsCPIFilter(), - "address", filter.Address.ToSolana().String(), - "eventName", filter.EventName, - ) - filter.IsBackfilled = false if existingFilterID, ok := fl.filtersByName[filter.Name]; ok { existingFilter := fl.filtersByID[existingFilterID] if !existingFilter.MatchSameLogs(filter) { - fl.lggr.Errorw("[DEBUG] RegisterFilter: ErrFilterNameConflict", - "filterName", filter.Name, - "existingIdlLen", len(existingFilter.ContractIdl), - "newIdlLen", len(filter.ContractIdl), - "idlMatch", existingFilter.ContractIdl == filter.ContractIdl, - "addressMatch", existingFilter.Address == filter.Address, - "eventSigMatch", existingFilter.EventSig == filter.EventSig, - "eventNameMatch", existingFilter.EventName == filter.EventName, - ) return ErrFilterNameConflict } if existingFilter.IsBackfilled { @@ -223,12 +207,6 @@ func (fl *filters) RegisterFilter(ctx context.Context, filter types.Filter) erro filter.ID = filterID fl.addToIndices(filter, decoder) - fl.lggr.Infow("[DEBUG] RegisterFilter succeeded", - "filterName", filter.Name, - "filterID", filterID, - "isCPI", filter.IsCPIFilter(), - ) - return nil } diff --git a/pkg/solana/logpoller/job_get_block.go b/pkg/solana/logpoller/job_get_block.go index fb6e8a8c0..7420dfca5 100644 --- a/pkg/solana/logpoller/job_get_block.go +++ b/pkg/solana/logpoller/job_get_block.go @@ -154,30 +154,8 @@ func (j *getBlockJob) Run(ctx context.Context) error { events = append(events, txEvents...) // Look for events corresponding to CPI filters - hasCPIExtractor := j.cpiEventExtractor != nil - hasCPIFilters := hasCPIExtractor && j.cpiEventExtractor.HasCPIFilters() - innerIxCount := 0 - if txWithMeta.Meta != nil { - innerIxCount = len(txWithMeta.Meta.InnerInstructions) - } - - j.lggr.Infow("[DEBUG] getBlock: CPI extraction check", - "slot", j.slotNumber, - "txIdx", idx, - "txSig", tx.Signatures[0].String(), - "hasCPIExtractor", hasCPIExtractor, - "hasCPIFilters", hasCPIFilters, - "innerInstructionSets", innerIxCount, - "logEvents", len(txEvents), - ) - - if hasCPIFilters { + if j.cpiEventExtractor != nil && j.cpiEventExtractor.HasCPIFilters() { cpiEvents := j.cpiEventExtractor.ExtractCPIEvents(tx, txWithMeta.Meta, detail, uint(len(txEvents))) - j.lggr.Infow("[DEBUG] getBlock: CPI extraction result", - "slot", j.slotNumber, - "txIdx", idx, - "cpiEventsFound", len(cpiEvents), - ) events = append(events, cpiEvents...) } } From 074d8dd7e567b5b3c877fa08700381d5cf5a07f6 Mon Sep 17 00:00:00 2001 From: Silas Lenihan Date: Wed, 11 Mar 2026 14:15:36 -0400 Subject: [PATCH 7/8] Revert "temp / add debug logging 2" This reverts commit e6b1a3e0933da0aba763137eeac22a95a5acdcad. --- pkg/solana/solana_service.go | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/pkg/solana/solana_service.go b/pkg/solana/solana_service.go index 9d3c8d62d..a59abcb4f 100644 --- a/pkg/solana/solana_service.go +++ b/pkg/solana/solana_service.go @@ -125,20 +125,6 @@ func (ss *solanaService) SimulateTX(ctx context.Context, req commonsol.SimulateT } func (ss *solanaService) RegisterLogTracking(ctx context.Context, req commonsol.LPFilterQuery) error { - // Diagnostic: log what we received over the wire (after gRPC + FromProto) - hasCPI := req.CPIFilterConfig != nil - ss.logger.Infow("[DEBUG] RegisterLogTracking received", - "filterName", req.Name, - "hasCPIFilterConfig", hasCPI, - ) - if hasCPI { - ss.logger.Infow("[DEBUG] RegisterLogTracking CPI config", - "filterName", req.Name, - "destAddressLen", len(req.CPIFilterConfig.DestAddress), - "methodName", req.CPIFilterConfig.MethodName, - ) - } - lp := ss.chain.LogPoller() if lp.HasFilter(ctx, req.Name) { return nil From eda886a4863800a5c3bc2785efb9b548390e0a40 Mon Sep 17 00:00:00 2001 From: Silas Lenihan Date: Wed, 11 Mar 2026 14:52:19 -0400 Subject: [PATCH 8/8] restored warning logs --- contracts/go.mod | 2 +- contracts/go.sum | 4 +- go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 8 +-- integration-tests/go.sum | 20 +++---- pkg/solana/logpoller/cpi_event_extractor.go | 52 +++++++++++++++++-- .../logpoller/cpi_event_extractor_test.go | 30 ++++++++--- 8 files changed, 91 insertions(+), 31 deletions(-) diff --git a/contracts/go.mod b/contracts/go.mod index 9e7a6b2ca..cc8c617f2 100644 --- a/contracts/go.mod +++ b/contracts/go.mod @@ -124,7 +124,7 @@ require ( github.com/sirupsen/logrus v1.9.4 // indirect github.com/smartcontractkit/chain-selectors v1.0.97 // indirect github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 // indirect - github.com/smartcontractkit/chainlink-common v0.10.1-0.20260311181236-0a45615ebb7f // indirect + github.com/smartcontractkit/chainlink-common v0.10.1-0.20260317155144-2b367262ff09 // indirect github.com/smartcontractkit/chainlink-testing-framework/framework v0.14.3 // indirect github.com/smartcontractkit/chainlink-ton v0.0.0-20260219201907-054376f21418 // indirect github.com/smartcontractkit/chainlink-tron/relayer v0.0.11-0.20251014143056-a0c6328c91e9 // indirect diff --git a/contracts/go.sum b/contracts/go.sum index 07dfa1684..aadf095c6 100644 --- a/contracts/go.sum +++ b/contracts/go.sum @@ -503,8 +503,8 @@ github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260220192608-a github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260220192608-af6bd538e0ca/go.mod h1:k1aNQP8nPFkSqWJZ4kFQaa1JGlWVIg6Y+XA2++qs6Cg= github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 h1:Z4t2ZY+ZyGWxtcXvPr11y4o3CGqhg3frJB5jXkCSvWA= github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5/go.mod h1:xtZNi6pOKdC3sLvokDvXOhgHzT+cyBqH/gWwvxTxqrg= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260311181236-0a45615ebb7f h1:H/w8KWN1tNgkYa+4PjwX2IMPJ4IVFAkCGBbhGRs4cR0= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260311181236-0a45615ebb7f/go.mod h1:AvurM0bnW/WJdxKD1kYF14aNX/+Pf2xZWp7wKeMl+Bo= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260317155144-2b367262ff09 h1:arMdoV8OMwJ/xN8Zn7mxs19hMK547iXK1Ln4JUFH3g4= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260317155144-2b367262ff09/go.mod h1:AvurM0bnW/WJdxKD1kYF14aNX/+Pf2xZWp7wKeMl+Bo= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 h1:FJAFgXS9oqASnkS03RE1HQwYQQxrO4l46O5JSzxqLgg= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10/go.mod h1:oiDa54M0FwxevWwyAX773lwdWvFYYlYHHQV1LQ5HpWY= github.com/smartcontractkit/chainlink-deployments-framework v0.81.2 h1:rEPEywuLv6YPIN6YhXJpReapVM+bPOOLXlpJwItlTu0= diff --git a/go.mod b/go.mod index 991794a67..f803af1bc 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/smartcontractkit/chainlink-ccip v0.1.1-solana.0.20260203202624-5101f4d33736 github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260121163256-85accaf3d28d github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 - github.com/smartcontractkit/chainlink-common v0.10.1-0.20260311181236-0a45615ebb7f + github.com/smartcontractkit/chainlink-common v0.10.1-0.20260317155144-2b367262ff09 github.com/smartcontractkit/chainlink-common/keystore v1.0.0 github.com/smartcontractkit/chainlink-common/pkg/monitoring v0.0.0-20251215152504-b1e41f508340 github.com/smartcontractkit/chainlink-framework/metrics v0.0.0-20251210101658-1c5c8e4c4f15 diff --git a/go.sum b/go.sum index 6785030df..9cd808535 100644 --- a/go.sum +++ b/go.sum @@ -565,8 +565,8 @@ github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260121163256-8 github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260121163256-85accaf3d28d/go.mod h1:bgmqE7x9xwmIVr8PqLbC0M5iPm4AV2DBl596lO6S5Sw= github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 h1:Z4t2ZY+ZyGWxtcXvPr11y4o3CGqhg3frJB5jXkCSvWA= github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5/go.mod h1:xtZNi6pOKdC3sLvokDvXOhgHzT+cyBqH/gWwvxTxqrg= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260311181236-0a45615ebb7f h1:H/w8KWN1tNgkYa+4PjwX2IMPJ4IVFAkCGBbhGRs4cR0= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260311181236-0a45615ebb7f/go.mod h1:AvurM0bnW/WJdxKD1kYF14aNX/+Pf2xZWp7wKeMl+Bo= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260317155144-2b367262ff09 h1:arMdoV8OMwJ/xN8Zn7mxs19hMK547iXK1Ln4JUFH3g4= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260317155144-2b367262ff09/go.mod h1:AvurM0bnW/WJdxKD1kYF14aNX/+Pf2xZWp7wKeMl+Bo= github.com/smartcontractkit/chainlink-common/keystore v1.0.0 h1:sVa3j2FWK/5OxXpnlfDkF1deDAkuXEfaLKzYqBTA880= github.com/smartcontractkit/chainlink-common/keystore v1.0.0/go.mod h1:wGRJJlCFUOKIfBlBGEdBFiTf7R787B8HKyobjiymw3Q= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 h1:FJAFgXS9oqASnkS03RE1HQwYQQxrO4l46O5JSzxqLgg= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index b6eea1b1b..f856ab9d7 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -19,9 +19,9 @@ require ( github.com/rs/zerolog v1.34.0 github.com/smartcontractkit/chain-selectors v1.0.97 github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260220192608-af6bd538e0ca - github.com/smartcontractkit/chainlink-common v0.10.1-0.20260311181236-0a45615ebb7f + github.com/smartcontractkit/chainlink-common v0.10.1-0.20260317155144-2b367262ff09 github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260311180747-73ee31ef1766 - github.com/smartcontractkit/chainlink-solana v1.1.2-0.20260223132514-df62be174f36 + github.com/smartcontractkit/chainlink-solana v1.1.2-0.20260223222711-2fa6b0e07db0 github.com/smartcontractkit/chainlink-solana/contracts v0.0.0-20260217175957-8f1af02c5075 github.com/smartcontractkit/chainlink-testing-framework/lib v1.54.7 github.com/smartcontractkit/chainlink-testing-framework/parrot v0.6.2 @@ -385,9 +385,9 @@ require ( github.com/smartcontractkit/chainlink-ccv v0.0.0-20260224105024-807568ff394d // indirect github.com/smartcontractkit/chainlink-common/keystore v1.0.2 // indirect github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 // indirect - github.com/smartcontractkit/chainlink-data-streams v0.1.11 // indirect + github.com/smartcontractkit/chainlink-data-streams v0.1.12-0.20260224150904-47eef37d9005 // indirect github.com/smartcontractkit/chainlink-deployments-framework v0.81.2 // indirect - github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260217171105-755485c4e00f // indirect + github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260223142528-fe0bf6474c99 // indirect github.com/smartcontractkit/chainlink-evm/contracts/cre/gobindings v0.0.0-20260107191744-4b93f62cffe3 // indirect github.com/smartcontractkit/chainlink-evm/gethwrappers v0.0.0-20251222115927-36a18321243c // indirect github.com/smartcontractkit/chainlink-feeds v0.1.2-0.20250227211209-7cd000095135 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 51bf5c3ae..de1f63a6c 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1349,22 +1349,22 @@ github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260220192608-a github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260220192608-af6bd538e0ca/go.mod h1:k1aNQP8nPFkSqWJZ4kFQaa1JGlWVIg6Y+XA2++qs6Cg= github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 h1:Z4t2ZY+ZyGWxtcXvPr11y4o3CGqhg3frJB5jXkCSvWA= github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5/go.mod h1:xtZNi6pOKdC3sLvokDvXOhgHzT+cyBqH/gWwvxTxqrg= -github.com/smartcontractkit/chainlink-ccv v0.0.0-20260219123955-11b2ac2cfa68 h1:Jy6LtNVM11MCDBYFAKMPeWUnT3Q2U1n4gVlwx1IKvlw= -github.com/smartcontractkit/chainlink-ccv v0.0.0-20260219123955-11b2ac2cfa68/go.mod h1:RnuNcn7DZmjmzEkeEWX0uL5y1oslB3c9URPLOjFU+jE= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260311181236-0a45615ebb7f h1:H/w8KWN1tNgkYa+4PjwX2IMPJ4IVFAkCGBbhGRs4cR0= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260311181236-0a45615ebb7f/go.mod h1:AvurM0bnW/WJdxKD1kYF14aNX/+Pf2xZWp7wKeMl+Bo= +github.com/smartcontractkit/chainlink-ccv v0.0.0-20260224105024-807568ff394d h1:eTMWOP3Q91Qp7b+D2nuh9k2WHct57tBxhn+524YFJq0= +github.com/smartcontractkit/chainlink-ccv v0.0.0-20260224105024-807568ff394d/go.mod h1:RnuNcn7DZmjmzEkeEWX0uL5y1oslB3c9URPLOjFU+jE= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260317155144-2b367262ff09 h1:arMdoV8OMwJ/xN8Zn7mxs19hMK547iXK1Ln4JUFH3g4= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260317155144-2b367262ff09/go.mod h1:AvurM0bnW/WJdxKD1kYF14aNX/+Pf2xZWp7wKeMl+Bo= github.com/smartcontractkit/chainlink-common/keystore v1.0.2 h1:AWisx4JT3QV8tcgh6J5NCrex+wAgTYpWyHsyNPSXzsQ= github.com/smartcontractkit/chainlink-common/keystore v1.0.2/go.mod h1:rSkIHdomyak3YnUtXLenl6poIq8q0V3UZPiiyYqPdGA= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 h1:FJAFgXS9oqASnkS03RE1HQwYQQxrO4l46O5JSzxqLgg= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10/go.mod h1:oiDa54M0FwxevWwyAX773lwdWvFYYlYHHQV1LQ5HpWY= github.com/smartcontractkit/chainlink-common/pkg/monitoring v0.0.0-20251215152504-b1e41f508340 h1:PsjEI+5jZIz9AS4eOsLS5VpSWJINf38clXV3wryPyMk= github.com/smartcontractkit/chainlink-common/pkg/monitoring v0.0.0-20251215152504-b1e41f508340/go.mod h1:P/0OSXUlFaxxD4B/P6HWbxYtIRmmWGDJAvanq19879c= -github.com/smartcontractkit/chainlink-data-streams v0.1.11 h1:yBzjU0Cu8AcfuM858G4xcQIulfNQkPfpUs5FDxX9UaY= -github.com/smartcontractkit/chainlink-data-streams v0.1.11/go.mod h1:8rUcGhjeXBoTFx2MynWgXiBWzVSB+LXd9JR6m8y2FfQ= +github.com/smartcontractkit/chainlink-data-streams v0.1.12-0.20260224150904-47eef37d9005 h1:TKodVxZwcHis7eWh8sRWq348p73gBSKaIVIrCO19PE0= +github.com/smartcontractkit/chainlink-data-streams v0.1.12-0.20260224150904-47eef37d9005/go.mod h1:8rUcGhjeXBoTFx2MynWgXiBWzVSB+LXd9JR6m8y2FfQ= github.com/smartcontractkit/chainlink-deployments-framework v0.81.2 h1:rEPEywuLv6YPIN6YhXJpReapVM+bPOOLXlpJwItlTu0= github.com/smartcontractkit/chainlink-deployments-framework v0.81.2/go.mod h1:2gCxFZMOFqlXIM2UHYtlSaYokcczx65Z7h/3KD761ao= -github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260217171105-755485c4e00f h1:29dXt+8hnpSK42N/O+u9Wn3rH8ZTeLYAj7jhbdZvpnI= -github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260217171105-755485c4e00f/go.mod h1:vf3/QOdXKTaNzrD2h2wzklHk+MvDC+J0kKmqdIz4www= +github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260223142528-fe0bf6474c99 h1:hZTafPs2L9PXC+dhQZcIDKZTU6bND4Lr2esu7yhUl0c= +github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260223142528-fe0bf6474c99/go.mod h1:vyCNAFYkDz+GAG/dcHXxfk3U9C1P2NLGLEBCmk9OzgY= github.com/smartcontractkit/chainlink-evm/contracts/cre/gobindings v0.0.0-20260107191744-4b93f62cffe3 h1:V22ITnWmgBAyxH+VVVo1jxm/LeJ3jcVMCVYB+zLN5mU= github.com/smartcontractkit/chainlink-evm/contracts/cre/gobindings v0.0.0-20260107191744-4b93f62cffe3/go.mod h1:u5vhpPHVUdGUni9o00MBu2aKPE0Q2DRoipAGPYD01e0= github.com/smartcontractkit/chainlink-evm/gethwrappers v0.0.0-20251222115927-36a18321243c h1:eX7SCn5AGUGduv5OrjbVJkUSOnyeal0BtVem6zBSB2Y= @@ -1411,8 +1411,8 @@ github.com/smartcontractkit/chainlink-protos/svr v1.1.1-0.20260203131522-bb8bc5c github.com/smartcontractkit/chainlink-protos/svr v1.1.1-0.20260203131522-bb8bc5c423b3/go.mod h1:TcOliTQU6r59DwG4lo3U+mFM9WWyBHGuFkkxQpvSujo= github.com/smartcontractkit/chainlink-protos/workflows/go v0.0.0-20260217043601-5cc966896c4f h1:3+vQMwuWL6+OqNutFqo/+gkczJwcr+MBPqeSxcjfI1Y= github.com/smartcontractkit/chainlink-protos/workflows/go v0.0.0-20260217043601-5cc966896c4f/go.mod h1:GTpDgyK0OObf7jpch6p8N281KxN92wbB8serZhU9yRc= -github.com/smartcontractkit/chainlink-sui v0.0.0-20260217210647-11c42009ec1f h1:itSU9nCBtbtmJEDlgVjk53AH6cJaZZzg3gMeEPQrbPU= -github.com/smartcontractkit/chainlink-sui v0.0.0-20260217210647-11c42009ec1f/go.mod h1:U3XStbEnbx/+L22n1/8aOIdgcGVxtsZB7p59xJGngAs= +github.com/smartcontractkit/chainlink-sui v0.0.0-20260223231841-af91ea434e03 h1:41xWbUIsD4DvLh3HdX0A1E5X3QZOiYatFvplaxu6lxA= +github.com/smartcontractkit/chainlink-sui v0.0.0-20260223231841-af91ea434e03/go.mod h1:U3XStbEnbx/+L22n1/8aOIdgcGVxtsZB7p59xJGngAs= github.com/smartcontractkit/chainlink-testing-framework/framework v0.14.3 h1:4PR0ZD6KF8P8YHilDx7a0RtUgnhYLKWWL1j3Y35H2O8= github.com/smartcontractkit/chainlink-testing-framework/framework v0.14.3/go.mod h1:43xdIQuqw/gzfazsqJkBrGdF25TIJDiY/Ak/YrWFTmU= github.com/smartcontractkit/chainlink-testing-framework/lib v1.54.7 h1:6dmdg2tppPKEFuEwBcT1kSEHj5Uj1xrWnKqX0wZg7zo= diff --git a/pkg/solana/logpoller/cpi_event_extractor.go b/pkg/solana/logpoller/cpi_event_extractor.go index c42d7593a..56ce454b7 100644 --- a/pkg/solana/logpoller/cpi_event_extractor.go +++ b/pkg/solana/logpoller/cpi_event_extractor.go @@ -138,9 +138,9 @@ func (e *CPIEventExtractor) ExtractCPIEvents( var eventData []byte var ok bool if methodSig == types.AnchorCPIEventDiscriminator() { - eventData, ok = extractAnchorCPIEventData(ix.Data) + eventData, ok = extractAnchorCPIEventData(e.lggr, ix.Data) } else { - eventData, ok = extractVecCPIEventData(ix.Data) + eventData, ok = extractVecCPIEventData(e.lggr, ix.Data, allAccountKeys, ix, programAtStackHeight) } if !ok || len(eventData) == 0 { continue @@ -156,6 +156,14 @@ func (e *CPIEventExtractor) ExtractCPIEvents( continue } sourceProgram = sp + } else if ix.StackHeight == 1 { + e.lggr.Warnw("unexpected stack height for inner instruction", + "ix", ix, + "destProgram", destProgram.ToSolana(), + "methodSig", methodSig, + "innerIndex", inner.Index, + ) + continue } else { sourceProgram = outerProgram } @@ -175,6 +183,8 @@ func (e *CPIEventExtractor) ExtractCPIEvents( e.lggr.Infow("Found CPI event", "sourceProgram", sourceProgram.ToSolana().String(), "destProgram", allAccountKeys[ix.ProgramIDIndex].String(), + "loadedWritableAddresses", meta.LoadedAddresses.Writable, + "loadedReadOnlyAddresses", meta.LoadedAddresses.ReadOnly, ) event := types.ProgramEvent{ @@ -203,8 +213,9 @@ func (e *CPIEventExtractor) ExtractCPIEvents( // extractAnchorCPIEventData handles Anchor 0.31+ emit_cpi! format: [method_disc(8)][event_data(N)]. // Event data directly follows the 8-byte method discriminator with no vec prefix. -func extractAnchorCPIEventData(data []byte) ([]byte, bool) { +func extractAnchorCPIEventData(lggr logger.SugaredLogger, data []byte) ([]byte, bool) { if len(data) <= CPIEventDataOffsetCurrent { + lggr.Warnw("anchor CPI event data shorter than method discriminator", "dataLen", len(data), "required", CPIEventDataOffsetCurrent+1) return nil, false } return data[CPIEventDataOffsetCurrent:], true @@ -214,15 +225,46 @@ func extractAnchorCPIEventData(data []byte) ([]byte, bool) { // Anchor <=0.29: [method_disc(8)][vec_len(4)][event_data(N)]. // Validation is strict: declaredLen must be >0 and must exactly equal the remaining bytes. // Returns (nil, false) on any mismatch -- no fallback. -func extractVecCPIEventData(data []byte) ([]byte, bool) { +func extractVecCPIEventData( + lggr logger.SugaredLogger, + data []byte, + allAccountKeys []solana.PublicKey, + ix rpc.CompiledInstruction, + programAtStackHeight map[uint16]types.PublicKey, +) ([]byte, bool) { if len(data) < CPIEventDataOffsetLegacy { + lggr.Warnw("data shorter than cpiEventDataOffset", "dataLen", len(data), "required", CPIEventDataOffsetLegacy) return nil, false } + declaredLen := bin.LittleEndian.Uint32(data[MethodDiscriminatorLen:CPIEventDataOffsetLegacy]) + if declaredLen == 0 { + lggr.Warnw("cpi event vec length is zero", + "sourceProgram", programAtStackHeight[ix.StackHeight-1].ToSolana().String(), + "destProgram", allAccountKeys[ix.ProgramIDIndex].String(), + ) + return nil, false + } + remaining := len(data) - CPIEventDataOffsetLegacy - if declaredLen == 0 || int(declaredLen) != remaining { + if int(declaredLen) > remaining { + lggr.Warnw("cpi event vec length exceeds remaining bytes", + "declaredLen", declaredLen, "remaining", remaining, + "sourceProgram", programAtStackHeight[ix.StackHeight-1].ToSolana().String(), + "destProgram", allAccountKeys[ix.ProgramIDIndex].String(), + ) return nil, false } + + if int(declaredLen) != remaining { + lggr.Warnw("cpi event vec length does not match remaining bytes", + "declaredLen", declaredLen, "remaining", remaining, + "sourceProgram", programAtStackHeight[ix.StackHeight-1].ToSolana().String(), + "destProgram", allAccountKeys[ix.ProgramIDIndex].String(), + ) + return nil, false + } + return data[CPIEventDataOffsetLegacy:], true } diff --git a/pkg/solana/logpoller/cpi_event_extractor_test.go b/pkg/solana/logpoller/cpi_event_extractor_test.go index f65e6da13..5af5cbc29 100644 --- a/pkg/solana/logpoller/cpi_event_extractor_test.go +++ b/pkg/solana/logpoller/cpi_event_extractor_test.go @@ -729,25 +729,43 @@ func TestCPIEventExtractor_ExtractCPIEvents(t *testing.T) { } func TestExtractAnchorCPIEventData(t *testing.T) { + lggr := logger.Sugared(logger.Test(t)) + t.Run("returns event data after discriminator", func(t *testing.T) { disc := types.AnchorCPIEventDiscriminator() payload := []byte{0x01, 0x02, 0x03, 0x04} data := append(disc[:], payload...) - result, ok := extractAnchorCPIEventData(data) + result, ok := extractAnchorCPIEventData(lggr, data) require.True(t, ok) require.Equal(t, payload, result) }) t.Run("rejects data too short", func(t *testing.T) { data := make([]byte, MethodDiscriminatorLen) - result, ok := extractAnchorCPIEventData(data) + result, ok := extractAnchorCPIEventData(lggr, data) require.False(t, ok) require.Nil(t, result) }) } func TestExtractVecCPIEventData(t *testing.T) { + lggr := logger.Sugared(logger.Test(t)) + + sourceProgram := newRandomPublicKey(t) + destProgram := newRandomPublicKey(t) + allAccountKeys := []solana.PublicKey{ + solana.PublicKey(sourceProgram), + solana.PublicKey(destProgram), + } + programAtStackHeight := map[uint16]types.PublicKey{ + 1: sourceProgram, + } + ix := rpc.CompiledInstruction{ + ProgramIDIndex: 1, + StackHeight: 2, + } + t.Run("returns event data with valid vec prefix", func(t *testing.T) { disc := make([]byte, MethodDiscriminatorLen) payload := []byte{0xAA, 0xBB, 0xCC, 0xDD} @@ -755,7 +773,7 @@ func TestExtractVecCPIEventData(t *testing.T) { binary.LittleEndian.PutUint32(vecLen, uint32(len(payload))) //nolint:gosec data := append(disc, append(vecLen, payload...)...) - result, ok := extractVecCPIEventData(data) + result, ok := extractVecCPIEventData(lggr, data, allAccountKeys, ix, programAtStackHeight) require.True(t, ok) require.Equal(t, payload, result) }) @@ -767,7 +785,7 @@ func TestExtractVecCPIEventData(t *testing.T) { binary.LittleEndian.PutUint32(vecLen, uint32(len(payload)+10)) //nolint:gosec data := append(disc, append(vecLen, payload...)...) - result, ok := extractVecCPIEventData(data) + result, ok := extractVecCPIEventData(lggr, data, allAccountKeys, ix, programAtStackHeight) require.False(t, ok) require.Nil(t, result) }) @@ -778,14 +796,14 @@ func TestExtractVecCPIEventData(t *testing.T) { vecLen := []byte{0x00, 0x00, 0x00, 0x00} data := append(disc, append(vecLen, payload...)...) - result, ok := extractVecCPIEventData(data) + result, ok := extractVecCPIEventData(lggr, data, allAccountKeys, ix, programAtStackHeight) require.False(t, ok) require.Nil(t, result) }) t.Run("rejects data shorter than legacy offset", func(t *testing.T) { data := make([]byte, CPIEventDataOffsetLegacy-1) - result, ok := extractVecCPIEventData(data) + result, ok := extractVecCPIEventData(lggr, data, allAccountKeys, ix, programAtStackHeight) require.False(t, ok) require.Nil(t, result) })