Skip to content

Commit

Permalink
Updated PDALookup internal field to use codec
Browse files Browse the repository at this point in the history
  • Loading branch information
silaslenihan committed Jan 30, 2025
1 parent cb6a64f commit aa71d84
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 66 deletions.
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
Expand All @@ -617,6 +618,9 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
Expand Down
2 changes: 0 additions & 2 deletions pkg/solana/chainwriter/ccip_example_config.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package chainwriter

import (
"reflect"

"github.com/gagliardetto/solana-go"
"github.com/smartcontractkit/chainlink-common/pkg/codec"
)
Expand Down
176 changes: 112 additions & 64 deletions pkg/solana/chainwriter/chain_writer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -587,14 +587,6 @@ func TestChainWriter_SubmitTransaction(t *testing.T) {
func TestChainWriter_CCIPRouter(t *testing.T) {
t.Parallel()

ctx := tests.Context(t)
// mock client
rw := clientmocks.NewReaderWriter(t)
// mock estimator
ge := feemocks.NewEstimator(t)
// mock txm
txm := txmMocks.NewTxManager(t)

// setup admin key
adminPk, err := solana.NewRandomPrivateKey()
require.NoError(t, err)
Expand All @@ -603,16 +595,9 @@ func TestChainWriter_CCIPRouter(t *testing.T) {
routerAddr := chainwriter.GetRandomPubKey(t)
destTokenAddr := chainwriter.GetRandomPubKey(t)

pda, _, err := solana.FindProgramAddress([][]byte{[]byte("token_admin_registry"), destTokenAddr.Bytes()}, routerAddr)
require.NoError(t, err)

lookupTable := mockTokenAdminRegistryLookupTable(t, rw, pda)

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

mockFetchLookupTableAddresses(t, rw, lookupTable, poolKeys)

// simplified CCIP Config - does not contain full account list
ccipCWConfig := chainwriter.ChainWriterConfig{
Programs: map[string]chainwriter.ProgramConfig{
Expand All @@ -625,7 +610,7 @@ func TestChainWriter_CCIPRouter(t *testing.T) {
Fields: map[string]string{"ReportContextByteWords": "ReportContext"},
},
&codec.RenameModifierConfig{
Fields: map[string]string{"ExecutionReport": "AbstractReport"},
Fields: map[string]string{"RawExecutionReport": "Report"},
},
},
ChainSpecificName: "execute",
Expand Down Expand Up @@ -662,27 +647,70 @@ func TestChainWriter_CCIPRouter(t *testing.T) {
},
},
},
"commit": {
FromAddress: admin.String(),
InputModifications: []codec.ModifierConfig{
&codec.RenameModifierConfig{
Fields: map[string]string{"ReportContextByteWords": "ReportContext"},
},
&codec.RenameModifierConfig{
Fields: map[string]string{"RawReport": "Report"},
},
},
ChainSpecificName: "commit",
ArgsTransform: "",
LookupTables: chainwriter.LookupTables{},
Accounts: []chainwriter.Lookup{
chainwriter.AccountConstant{
Name: "testAcc1",
Address: chainwriter.GetRandomPubKey(t).String(),
},
chainwriter.AccountConstant{
Name: "testAcc2",
Address: chainwriter.GetRandomPubKey(t).String(),
},
chainwriter.AccountConstant{
Name: "testAcc3",
Address: chainwriter.GetRandomPubKey(t).String(),
},
},
},
},
IDL: ccipRouterIDL,
},
},
}

// initialize chain writer
cw, err := chainwriter.NewSolanaChainWriterService(testutils.NewNullLogger(), rw, txm, ge, ccipCWConfig)
require.NoError(t, err)
ctx := tests.Context(t)
// mock client
rw := clientmocks.NewReaderWriter(t)
// mock estimator
ge := feemocks.NewEstimator(t)

t.Run("ArgsTransform works", func(t *testing.T) {
txID := uuid.NewString()
recentBlockHash := solana.Hash{}
t.Run("CCIP execute is encoded successfully and ArgsTransform is applied correctly.", func(t *testing.T) {
// mock txm
txm := txmMocks.NewTxManager(t)
// initialize chain writer
cw, err := chainwriter.NewSolanaChainWriterService(testutils.NewNullLogger(), rw, txm, ge, ccipCWConfig)
require.NoError(t, err)

recentBlockHash := solana.Hash{}
rw.On("LatestBlockhash", mock.Anything).Return(&rpc.GetLatestBlockhashResult{Value: &rpc.LatestBlockhashResult{Blockhash: recentBlockHash, LastValidBlockHeight: uint64(100)}}, nil).Once()

pda, _, err := solana.FindProgramAddress([][]byte{[]byte("token_admin_registry"), destTokenAddr.Bytes()}, routerAddr)
require.NoError(t, err)

lookupTable := mockTokenAdminRegistryLookupTable(t, rw, pda)

mockFetchLookupTableAddresses(t, rw, lookupTable, poolKeys)

txID := uuid.NewString()
txm.On("Enqueue", mock.Anything, admin.String(), mock.MatchedBy(func(tx *solana.Transaction) bool {
txData := tx.Message.Instructions[0].Data
payload := txData[8:]
var decoded ccip_router.Execute
dec := ag_binary.NewBorshDecoder(payload)
err := dec.Decode(&decoded)
err = dec.Decode(&decoded)
require.NoError(t, err)

tokenIndexes := *decoded.TokenIndexes
Expand All @@ -692,63 +720,83 @@ func TestChainWriter_CCIPRouter(t *testing.T) {
return true
}), &txID, mock.Anything).Return(nil).Once()

abstractReport := ccip_router.ExecutionReportSingleChain{
SourceChainSelector: 1,
Message: ccip_router.Any2SVMRampMessage{
Header: ccip_router.RampMessageHeader{
MessageId: ccipocr3.Bytes32{0x1},
SourceChainSelector: 1,
DestChainSelector: 2,
SequenceNumber: 1,
Nonce: 0,
},
Sender: admin.Bytes(),
Data: ccipocr3.Bytes{0x1},
LogicReceiver: chainwriter.GetRandomPubKey(t),
TokenReceiver: admin,
TokenAmounts: []ccip_router.Any2SVMTokenTransfer{
{
SourcePoolAddress: chainwriter.GetRandomPubKey(t).Bytes(),
DestTokenAddress: destTokenAddr,
ExtraData: ccipocr3.Bytes{0x1},
Amount: ccip_router.CrossChainAmount{LeBytes: [32]uint8{0x1}},
DestGasAmount: 2,
},
},
ExtraArgs: ccip_router.SVMExtraArgs{
ComputeUnits: 1,
IsWritableBitmap: 6,
Accounts: []solana.PublicKey{
chainwriter.GetRandomPubKey(t),
// stripped back report just for purposes of example
abstractReport := ccipocr3.ExecutePluginReportSingleChain{
Messages: []ccipocr3.Message{
{
TokenAmounts: []ccipocr3.RampTokenAmount{
{
DestTokenAddress: destTokenAddr.Bytes(),
},
},
},
OnRampAddress: []byte{0x1},
},
OffchainTokenData: [][]byte{{0x1}},
Proofs: [][32]byte{{0x1}},
}

// Marshal the abstract report to json just for testing purposes.
encodededReport, err := json.Marshal(abstractReport)
encodedReport, err := json.Marshal(abstractReport)
require.NoError(t, err)

args := chainwriter.ReportPreTransform{
ReportContext: [3][32]uint8{{0x01, 0x02, 0x03}},
Report: encodededReport,
ReportContext: [2][32]byte{{0x01}, {0x02}},
Report: encodedReport,
Info: ccipocr3.ExecuteReportInfo{
{
ChainSel: 1,
OnRampAddress: chainwriter.GetRandomPubKey(t).Bytes(),
SeqNumsRange: ccipocr3.NewSeqNumRange(1, 2),
MerkleRoot: [32]byte{0x01, 0x02, 0x03},
},
MerkleRoots: []ccipocr3.MerkleRootChain{},
AbstractReports: []ccipocr3.ExecutePluginReportSingleChain{abstractReport},
},
AbstractReport: abstractReport,
}

submitErr := cw.SubmitTransaction(ctx, "ccip_router", "execute", args, txID, routerAddr.String(), nil, nil)
require.NoError(t, submitErr)
})

t.Run("CCIP commit is encoded successfully", func(t *testing.T) {
// mock txm
txm := txmMocks.NewTxManager(t)
// initialize chain writer
cw, err := chainwriter.NewSolanaChainWriterService(testutils.NewNullLogger(), rw, txm, ge, ccipCWConfig)
require.NoError(t, err)

recentBlockHash := solana.Hash{}
rw.On("LatestBlockhash", mock.Anything).Return(&rpc.GetLatestBlockhashResult{Value: &rpc.LatestBlockhashResult{Blockhash: recentBlockHash, LastValidBlockHeight: uint64(100)}}, nil).Once()

type CommitArgs struct {
ReportContext [2][32]byte
Report []byte
Rs [][32]byte
Ss [][32]byte
RawVs [32]byte
Info ccipocr3.CommitReportInfo
}

txID := uuid.NewString()

// TODO: Replace with actual type from ccipocr3
args := CommitArgs{
ReportContext: [2][32]byte{{0x01}, {0x02}},
Report: []byte{0x01, 0x02},
Rs: [][32]byte{{0x01, 0x02}},
Ss: [][32]byte{{0x01, 0x02}},
RawVs: [32]byte{0x01, 0x02},
Info: ccipocr3.CommitReportInfo{
RemoteF: 1,
MerkleRoots: []ccipocr3.MerkleRootChain{},
},
}

txm.On("Enqueue", mock.Anything, admin.String(), mock.MatchedBy(func(tx *solana.Transaction) bool {
txData := tx.Message.Instructions[0].Data
payload := txData[8:]
var decoded ccip_router.Commit
dec := ag_binary.NewBorshDecoder(payload)
err := dec.Decode(&decoded)
require.NoError(t, err)
return true
}), &txID, mock.Anything).Return(nil).Once()

submitErr := cw.SubmitTransaction(ctx, "ccip_router", "commit", args, txID, routerAddr.String(), nil, nil)
require.NoError(t, submitErr)
})
}

func TestChainWriter_CCIPRouter(t *testing.T) {
Expand Down

0 comments on commit aa71d84

Please sign in to comment.