Skip to content

Commit

Permalink
Added tests for CCIP types and commit method args transform
Browse files Browse the repository at this point in the history
  • Loading branch information
amit-momin committed Feb 20, 2025
1 parent debb8d7 commit 1762775
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 39 deletions.
23 changes: 15 additions & 8 deletions integration-tests/relayinterface/lookups_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,8 +318,9 @@ func TestPDALookups(t *testing.T) {
seed3 := ccipocr3.ChainSelector(4)
bufSeed3 := make([]byte, 8)
binary.LittleEndian.PutUint64(bufSeed3, uint64(seed3))
seed4 := ccipocr3.Bytes32(chainwriter.GetRandomPubKey(t).Bytes())

pda, _, err := solana.FindProgramAddress([][]byte{seed1, bufSeed2, bufSeed3}, programID)
pda, _, err := solana.FindProgramAddress([][]byte{seed1, bufSeed2, bufSeed3, seed4[:]}, programID)
require.NoError(t, err)

expectedMeta := []*solana.AccountMeta{
Expand All @@ -336,16 +337,18 @@ func TestPDALookups(t *testing.T) {
Seeds: []chainwriter.Seed{
{Dynamic: chainwriter.Lookup{AccountLookup: &chainwriter.AccountLookup{Name: "seed1", Location: "test_seed"}}},
{Dynamic: chainwriter.Lookup{AccountLookup: &chainwriter.AccountLookup{Name: "seed2", Location: "another_seed"}}},
{Dynamic: chainwriter.Lookup{AccountLookup: &chainwriter.AccountLookup{Name: "seed3", Location: "3rd_seed"}}},
{Dynamic: chainwriter.Lookup{AccountLookup: &chainwriter.AccountLookup{Name: "seed3", Location: "ccip_chain_selector"}}},
{Dynamic: chainwriter.Lookup{AccountLookup: &chainwriter.AccountLookup{Name: "seed4", Location: "ccip_bytes"}}},
},
IsSigner: false,
IsWritable: true,
}}

args := map[string]interface{}{
"test_seed": seed1,
"another_seed": seed2,
"3rd_seed": seed3,
"test_seed": seed1,
"another_seed": seed2,
"ccip_chain_selector": seed3,
"ccip_bytes": seed4,
}

result, err := pdaLookup.Resolve(ctx, args, nil, client.MultiClient{})
Expand Down Expand Up @@ -376,8 +379,10 @@ func TestPDALookups(t *testing.T) {
t.Run("PDALookup resolves valid PDA with address lookup seeds", func(t *testing.T) {
seed1 := chainwriter.GetRandomPubKey(t)
seed2 := chainwriter.GetRandomPubKey(t)
addr3 := chainwriter.GetRandomPubKey(t)
seed3 := ccipocr3.UnknownEncodedAddress(addr3.String())

pda, _, err := solana.FindProgramAddress([][]byte{seed1.Bytes(), seed2.Bytes()}, programID)
pda, _, err := solana.FindProgramAddress([][]byte{seed1.Bytes(), seed2.Bytes(), addr3.Bytes()}, programID)
require.NoError(t, err)

expectedMeta := []*solana.AccountMeta{
Expand All @@ -394,14 +399,16 @@ func TestPDALookups(t *testing.T) {
Seeds: []chainwriter.Seed{
{Dynamic: chainwriter.Lookup{AccountLookup: &chainwriter.AccountLookup{Name: "seed1", Location: "test_seed"}}},
{Dynamic: chainwriter.Lookup{AccountLookup: &chainwriter.AccountLookup{Name: "seed2", Location: "another_seed"}}},
{Dynamic: chainwriter.Lookup{AccountLookup: &chainwriter.AccountLookup{Name: "seed3", Location: "unknown_encoded_address"}}},
},
IsSigner: false,
IsWritable: true,
}}

args := map[string]interface{}{
"test_seed": seed1,
"another_seed": seed2,
"test_seed": seed1,
"another_seed": seed2,
"unknown_encoded_address": seed3,
}

result, err := pdaLookup.Resolve(ctx, args, nil, client.MultiClient{})
Expand Down
6 changes: 4 additions & 2 deletions pkg/solana/chainwriter/chain_writer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -822,7 +822,7 @@ func TestChainWriter_CCIPOfframp(t *testing.T) {
},
},
ChainSpecificName: "commit",
ArgsTransform: "",
ArgsTransform: "CCIPCommit",
LookupTables: chainwriter.LookupTables{},
Accounts: []chainwriter.Lookup{
{AccountConstant: &chainwriter.AccountConstant{
Expand Down Expand Up @@ -922,7 +922,7 @@ func TestChainWriter_CCIPOfframp(t *testing.T) {
require.NoError(t, submitErr)
})

t.Run("CCIP commit is encoded successfully", func(t *testing.T) {
t.Run("CCIP commit is encoded successfully and ArgsTransform is applied correctly.", func(t *testing.T) {
// mock txm
txm := txmMocks.NewTxManager(t)
// initialize chain writer
Expand Down Expand Up @@ -963,6 +963,8 @@ func TestChainWriter_CCIPOfframp(t *testing.T) {
dec := ag_binary.NewBorshDecoder(payload)
err := dec.Decode(&decoded)
require.NoError(t, err)
// The CCIPCommit ArgsTransform should remove the last account since no price updates were provided in the report
require.Len(t, tx.Message.Instructions[0].Accounts, 2)
return true
}), &txID, mock.Anything).Return(nil).Once()

Expand Down
4 changes: 2 additions & 2 deletions pkg/solana/chainwriter/transform_registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type ReportPostTransform struct {
func FindTransform(id string) (func(context.Context, *SolanaChainWriterService, any, solana.AccountMetaSlice, string) (any, solana.AccountMetaSlice, error), error) {
switch id {
case "CCIPExecute":
return CCIPArgsTransform, nil
return CCIPExecuteArgsTransform, nil
case "CCIPCommit":
return CCIPCommitAccountTransform, nil
default:
Expand All @@ -40,7 +40,7 @@ func FindTransform(id string) (func(context.Context, *SolanaChainWriterService,

// This Transform function looks up the token pool addresses in the accounts slice and augments the args
// with the indexes of the token pool addresses in the accounts slice.
func CCIPArgsTransform(ctx context.Context, cw *SolanaChainWriterService, args any, accounts solana.AccountMetaSlice, toAddress string) (any, solana.AccountMetaSlice, error) {
func CCIPExecuteArgsTransform(ctx context.Context, cw *SolanaChainWriterService, args any, accounts solana.AccountMetaSlice, toAddress string) (any, solana.AccountMetaSlice, error) {
// Fetch offramp config to use to fetch the router address
offrampProgramConfig, ok := cw.config.Programs[ccipconsts.ContractNameOffRamp]
if !ok {
Expand Down
104 changes: 77 additions & 27 deletions pkg/solana/chainwriter/transform_registry_test.go
Original file line number Diff line number Diff line change
@@ -1,59 +1,109 @@
package chainwriter_test

import (
"context"
"testing"

"github.com/gagliardetto/solana-go"
ccipconsts "github.com/smartcontractkit/chainlink-ccip/pkg/consts"
"github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3"
"github.com/smartcontractkit/chainlink-common/pkg/utils/tests"
"github.com/stretchr/testify/require"

"github.com/smartcontractkit/chainlink-solana/pkg/monitoring/testutils"
"github.com/smartcontractkit/chainlink-solana/pkg/solana/chainwriter"
"github.com/smartcontractkit/chainlink-solana/pkg/solana/client"
clientmocks "github.com/smartcontractkit/chainlink-solana/pkg/solana/client/mocks"
)

func Test_CCIPCommitTransform(t *testing.T) {
func Test_CCIPExecuteTransform(t *testing.T) {
ctx := tests.Context(t)
offrampAddress, err := solana.NewRandomPrivateKey()
require.NoError(t, err)
key1, err := solana.NewRandomPrivateKey()
require.NoError(t, err)
key2, err := solana.NewRandomPrivateKey()
offrampAddress := chainwriter.GetRandomPubKey(t)
routerAddress := chainwriter.GetRandomPubKey(t)

// simplified CCIP Config - only IDLs are required for CCIPExecute ArgsTransform
ccipCWConfig := chainwriter.ChainWriterConfig{
Programs: map[string]chainwriter.ProgramConfig{
ccipconsts.ContractNameOffRamp: {
IDL: ccipOfframpIDL,
},
// Requires only the IDL for the CCIPArgsTransform to fetch the TokenAdminRegistry
ccipconsts.ContractNameRouter: {
IDL: ccipRouterIDL,
},
},
}
// mock client
rw := clientmocks.NewReaderWriter(t)
mc := *client.NewMultiClient(func(context.Context) (client.ReaderWriter, error) {
return rw, nil
})
// initialize chain writer
cw, err := chainwriter.NewSolanaChainWriterService(testutils.NewNullLogger(), mc, nil, nil, ccipCWConfig)
require.NoError(t, err)
t.Run("ArgsTransform does not affect accounts if token prices exist", func(t *testing.T) {

destTokenAddr := chainwriter.GetRandomPubKey(t)
poolKeys := []solana.PublicKey{destTokenAddr}
poolKeys = append(poolKeys, chainwriter.CreateTestPubKeys(t, 1)...)

args := chainwriter.ReportPreTransform{
Info: ccipocr3.ExecuteReportInfo{
AbstractReports: []ccipocr3.ExecutePluginReportSingleChain{{
Messages: []ccipocr3.Message{{
TokenAmounts: []ccipocr3.RampTokenAmount{{
DestTokenAddress: ccipocr3.UnknownAddress(destTokenAddr.Bytes()),
}},
}},
}},
},
}

accounts := []*solana.AccountMeta{{PublicKey: poolKeys[0]}, {PublicKey: poolKeys[1]}}

t.Run("CCIPExecute ArgsTransform includes token indexes", func(t *testing.T) {
pda, _, err := solana.FindProgramAddress([][]byte{[]byte("token_admin_registry"), destTokenAddr.Bytes()}, routerAddress)
require.NoError(t, err)

lookupTable := mockTokenAdminRegistryLookupTable(t, rw, pda)
mockFetchRouterAddress(t, rw, routerAddress, offrampAddress)
mockFetchLookupTableAddresses(t, rw, lookupTable, poolKeys)
transformedArgs, newAccounts, err := chainwriter.CCIPExecuteArgsTransform(ctx, cw, args, accounts, offrampAddress.String())
require.NoError(t, err)
// Accounts should be unchanged
require.Len(t, newAccounts, 2)
typedArgs, ok := transformedArgs.(chainwriter.ReportPostTransform)
require.True(t, ok)
require.NotNil(t, typedArgs.TokenIndexes)
require.Len(t, typedArgs.TokenIndexes, 1)
})
}

func Test_CCIPCommitTransform(t *testing.T) {
ctx := tests.Context(t)
offrampAddress := chainwriter.GetRandomPubKey(t)
key1 := chainwriter.GetRandomPubKey(t)
key2 := chainwriter.GetRandomPubKey(t)
t.Run("CCIPCommit ArgsTransform does not affect accounts if token prices exist", func(t *testing.T) {
args := struct {
Info ccipocr3.CommitReportInfo
}{
Info: ccipocr3.CommitReportInfo{
TokenPrices: []ccipocr3.TokenPrice{{TokenID: ccipocr3.UnknownEncodedAddress(key1.PublicKey().String())}},
TokenPrices: []ccipocr3.TokenPrice{{TokenID: ccipocr3.UnknownEncodedAddress(key1.String())}},
},
}
accounts := []*solana.AccountMeta{
{
PublicKey: key1.PublicKey(),
},
{
PublicKey: key2.PublicKey(),
},
}
_, newAccounts, err := chainwriter.CCIPCommitAccountTransform(ctx, nil, args, accounts, offrampAddress.PublicKey().String())
accounts := []*solana.AccountMeta{{PublicKey: key1},{PublicKey: key2}}
_, newAccounts, err := chainwriter.CCIPCommitAccountTransform(ctx, nil, args, accounts, offrampAddress.String())
require.NoError(t, err)
require.Len(t, newAccounts, 2)
})
t.Run("ArgsTransform removes last account if token and gas prices do not exist", func(t *testing.T) {
t.Run("CCIPCommit ArgsTransform removes last account if token and gas prices do not exist", func(t *testing.T) {
args := struct {
Info ccipocr3.CommitReportInfo
}{
Info: ccipocr3.CommitReportInfo{},
}
accounts := []*solana.AccountMeta{
{
PublicKey: key1.PublicKey(),
},
{
PublicKey: key2.PublicKey(),
},
}
_, newAccounts, err := chainwriter.CCIPCommitAccountTransform(ctx, nil, args, accounts, offrampAddress.PublicKey().String())
accounts := []*solana.AccountMeta{{PublicKey: key1},{PublicKey: key2}}
_, newAccounts, err := chainwriter.CCIPCommitAccountTransform(ctx, nil, args, accounts, offrampAddress.String())
require.NoError(t, err)
require.Len(t, newAccounts, 1)
})
Expand Down

0 comments on commit 1762775

Please sign in to comment.