Skip to content

Commit a7bfdec

Browse files
committed
updated comments and slight tweaks
1 parent d656123 commit a7bfdec

File tree

6 files changed

+45
-45
lines changed

6 files changed

+45
-45
lines changed

integration-tests/relayinterface/lookups_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ func TestAccountLookups(t *testing.T) {
126126
}
127127

128128
func TestPDALookups(t *testing.T) {
129-
programID := solana.SystemProgramID
129+
programID := chainwriter.GetRandomPubKey(t)
130130

131131
t.Run("PDALookup resolves valid PDA with constant address seeds", func(t *testing.T) {
132132
seed := chainwriter.GetRandomPubKey(t)
@@ -281,7 +281,7 @@ func TestLookupTables(t *testing.T) {
281281
table := chainwriter.CreateTestLookupTable(ctx, t, rpcClient, sender, pubKeys)
282282
lookupConfig := chainwriter.LookupTables{
283283
DerivedLookupTables: nil,
284-
StaticLookupTables: []string{table.String()},
284+
StaticLookupTables: []solana.PublicKey{table},
285285
}
286286
_, staticTableMap, resolveErr := cw.ResolveLookupTables(ctx, nil, lookupConfig)
287287
require.NoError(t, resolveErr)
@@ -342,7 +342,7 @@ func TestLookupTables(t *testing.T) {
342342

343343
lookupConfig := chainwriter.LookupTables{
344344
DerivedLookupTables: nil,
345-
StaticLookupTables: []string{invalidTable.String()},
345+
StaticLookupTables: []solana.PublicKey{invalidTable},
346346
}
347347

348348
_, _, err = cw.ResolveLookupTables(ctx, nil, lookupConfig)

pkg/solana/chainwriter/ccip_example_config.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package chainwriter
22

33
import (
4-
"fmt"
4+
"github.com/gagliardetto/solana-go"
55
)
66

77
func TestConfig() {
@@ -13,8 +13,8 @@ func TestConfig() {
1313
systemProgramAddress := "4Nn9dsYBcSTzRbK9hg9kzCUdrCSkMZq1UR6Vw1Tkaf6E"
1414
computeBudgetProgramAddress := "4Nn9dsYBcSTzRbK9hg9kzCUdrCSkMZq1UR6Vw1Tkaf6F"
1515
sysvarProgramAddress := "4Nn9dsYBcSTzRbK9hg9kzCUdrCSkMZq1UR6Vw1Tkaf6G"
16-
commonAddressesLookupTable := "4Nn9dsYBcSTzRbK9hg9kzCUdrCSkMZq1UR6Vw1Tkaf6H"
17-
routerLookupTable := "4Nn9dsYBcSTzRbK9hg9kzCUdrCSkMZq1UR6Vw1Tkaf6I"
16+
commonAddressesLookupTable := solana.MustPublicKeyFromBase58("4Nn9dsYBcSTzRbK9hg9kzCUdrCSkMZq1UR6Vw1Tkaf6H")
17+
routerLookupTable := solana.MustPublicKeyFromBase58("4Nn9dsYBcSTzRbK9hg9kzCUdrCSkMZq1UR6Vw1Tkaf6I")
1818
userAddress := "4Nn9dsYBcSTzRbK9hg9kzCUdrCSkMZq1UR6Vw1Tkaf6J"
1919

2020
executionReportSingleChainIDL := `{"name":"ExecutionReportSingleChain","type":{"kind":"struct","fields":[{"name":"source_chain_selector","type":"u64"},{"name":"message","type":{"defined":"Any2SolanaRampMessage"}},{"name":"root","type":{"array":["u8",32]}},{"name":"proofs","type":{"vec":{"array":["u8",32]}}}]}},{"name":"Any2SolanaRampMessage","type":{"kind":"struct","fields":[{"name":"header","type":{"defined":"RampMessageHeader"}},{"name":"sender","type":{"vec":"u8"}},{"name":"data","type":{"vec":"u8"}},{"name":"receiver","type":{"array":["u8",32]}},{"name":"extra_args","type":{"defined":"SolanaExtraArgs"}}]}},{"name":"RampMessageHeader","type":{"kind":"struct","fields":[{"name":"message_id","type":{"array":["u8",32]}},{"name":"source_chain_selector","type":"u64"},{"name":"dest_chain_selector","type":"u64"},{"name":"sequence_number","type":"u64"},{"name":"nonce","type":"u64"}]}},{"name":"SolanaExtraArgs","type":{"kind":"struct","fields":[{"name":"compute_units","type":"u32"},{"name":"allow_out_of_order_execution","type":"bool"}]}}`
@@ -58,7 +58,7 @@ func TestConfig() {
5858
// Static lookup tables are the traditional use case (point 2 above) of Lookup tables. These are lookup
5959
// tables which contain commonly used addresses in all CCIP execute transactions. The ChainWriter reads
6060
// these lookup tables and appends them to the transaction to reduce the size of the transaction.
61-
StaticLookupTables: []string{
61+
StaticLookupTables: []solana.PublicKey{
6262
commonAddressesLookupTable,
6363
routerLookupTable,
6464
},
@@ -255,7 +255,7 @@ func TestConfig() {
255255
InputModifications: nil,
256256
ChainSpecificName: "commit",
257257
LookupTables: LookupTables{
258-
StaticLookupTables: []string{
258+
StaticLookupTables: []solana.PublicKey{
259259
commonAddressesLookupTable,
260260
routerLookupTable,
261261
},
@@ -329,5 +329,5 @@ func TestConfig() {
329329
},
330330
},
331331
}
332-
fmt.Println(chainWriterConfig)
332+
_ = chainWriterConfig
333333
}

pkg/solana/chainwriter/chain_writer.go

+9-6
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ func (s *SolanaChainWriterService) FilterLookupTableAddresses(
203203
return filteredLookupTables
204204
}
205205

206-
func (s *SolanaChainWriterService) SubmitTransaction(ctx context.Context, contractName, method string, args any, transactionID string, toAddress string, meta *types.TxMeta, value *big.Int) error {
206+
func (s *SolanaChainWriterService) SubmitTransaction(ctx context.Context, contractName, method string, args any, transactionID string, toAddress string, _ *types.TxMeta, _ *big.Int) error {
207207
programConfig, exists := s.config.Programs[contractName]
208208
if !exists {
209209
return fmt.Errorf("failed to find program config for contract name: %s", contractName)
@@ -241,6 +241,14 @@ func (s *SolanaChainWriterService) SubmitTransaction(ctx context.Context, contra
241241
return errorWithDebugID(fmt.Errorf("error resolving account addresses: %w", err), debugID)
242242
}
243243

244+
feePayer, err := solana.PublicKeyFromBase58(methodConfig.FromAddress)
245+
if err != nil {
246+
return errorWithDebugID(fmt.Errorf("error parsing fee payer address: %w", err), debugID)
247+
}
248+
249+
accounts = append([]*solana.AccountMeta{solana.Meta(feePayer).SIGNER().WRITE()}, accounts...)
250+
accounts = append(accounts, solana.Meta(solana.SystemProgramID))
251+
244252
// Filter the lookup table addresses based on which accounts are actually used
245253
filteredLookupTableMap := s.FilterLookupTableAddresses(accounts, derivedTableMap, staticTableMap)
246254

@@ -256,11 +264,6 @@ func (s *SolanaChainWriterService) SubmitTransaction(ctx context.Context, contra
256264
return errorWithDebugID(fmt.Errorf("error parsing program ID: %w", err), debugID)
257265
}
258266

259-
feePayer, err := solana.PublicKeyFromBase58(methodConfig.FromAddress)
260-
if err != nil {
261-
return errorWithDebugID(fmt.Errorf("error parsing fee payer address: %w", err), debugID)
262-
}
263-
264267
tx, err := solana.NewTransaction(
265268
[]solana.Instruction{
266269
solana.NewInstruction(programID, accounts, encodedPayload),

pkg/solana/chainwriter/chain_writer_test.go

+12-10
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ func TestChainWriter_FilterLookupTableAddresses(t *testing.T) {
273273
Name: "DataAccountPDA",
274274
PublicKey: chainwriter.AccountConstant{Name: "WriteTest", Address: programID.String()},
275275
Seeds: []chainwriter.Lookup{
276-
// extract seed2 for PDA lookup
276+
// extract seed1 for PDA lookup
277277
chainwriter.AccountLookup{Name: "seed1", Location: "seed1"},
278278
},
279279
IsSigner: true,
@@ -302,7 +302,7 @@ func TestChainWriter_FilterLookupTableAddresses(t *testing.T) {
302302
},
303303
},
304304
},
305-
StaticLookupTables: []string{staticLookupTablePubkey1.String(), staticLookupTablePubkey2.String()},
305+
StaticLookupTables: []solana.PublicKey{staticLookupTablePubkey1, staticLookupTablePubkey2},
306306
}
307307

308308
args := map[string]interface{}{
@@ -441,7 +441,7 @@ func TestChainWriter_SubmitTransaction(t *testing.T) {
441441
},
442442
},
443443
},
444-
StaticLookupTables: []string{staticLookupTablePubkey.String()},
444+
StaticLookupTables: []solana.PublicKey{staticLookupTablePubkey},
445445
},
446446
Accounts: []chainwriter.Lookup{
447447
chainwriter.AccountConstant{
@@ -528,16 +528,18 @@ func TestChainWriter_SubmitTransaction(t *testing.T) {
528528
rw.On("LatestBlockhash", mock.Anything).Return(&rpc.GetLatestBlockhashResult{Value: &rpc.LatestBlockhashResult{Blockhash: recentBlockHash, LastValidBlockHeight: uint64(100)}}, nil).Once()
529529
txID := uuid.NewString()
530530

531-
txm.On("Enqueue", mock.Anything, account1.String(), mock.MatchedBy(func(tx *solana.Transaction) bool {
531+
txm.On("Enqueue", mock.Anything, admin.String(), mock.MatchedBy(func(tx *solana.Transaction) bool {
532532
// match transaction fields to ensure it was built as expected
533533
require.Equal(t, recentBlockHash, tx.Message.RecentBlockhash)
534534
require.Len(t, tx.Message.Instructions, 1)
535-
require.Len(t, tx.Message.AccountKeys, 5) // fee payer + derived accounts
536-
require.Equal(t, admin, tx.Message.AccountKeys[0]) // fee payer
537-
require.Equal(t, account1, tx.Message.AccountKeys[1]) // account constant
538-
require.Equal(t, account2, tx.Message.AccountKeys[2]) // account lookup
539-
require.Equal(t, account3, tx.Message.AccountKeys[3]) // pda lookup
540-
require.Equal(t, programID, tx.Message.AccountKeys[4]) // instruction program ID
535+
require.Len(t, tx.Message.AccountKeys, 6) // fee payer + derived accounts
536+
require.Equal(t, admin, tx.Message.AccountKeys[0]) // fee payer
537+
require.Equal(t, account1, tx.Message.AccountKeys[1]) // account constant
538+
require.Equal(t, account2, tx.Message.AccountKeys[2]) // account lookup
539+
require.Equal(t, account3, tx.Message.AccountKeys[3]) // pda lookup
540+
require.Equal(t, solana.SystemProgramID, tx.Message.AccountKeys[4]) // system program ID
541+
require.Equal(t, programID, tx.Message.AccountKeys[5]) // instruction program ID
542+
// instruction program ID
541543
require.Len(t, tx.Message.AddressTableLookups, 1) // address table look contains entry
542544
require.Equal(t, derivedLookupTablePubkey, tx.Message.AddressTableLookups[0].AccountKey) // address table
543545
return true

pkg/solana/chainwriter/helpers.go

+3
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ func GetDebugIDAtLocation(args any, location string) (string, error) {
6161
return "", err
6262
}
6363

64+
if len(debugIDList) == 0 {
65+
return "", errors.New("no debug ID found at location: " + location)
66+
}
6467
// there should only be one debug ID, others will be ignored.
6568
debugID := string(debugIDList[0])
6669

pkg/solana/chainwriter/lookups.go

+12-20
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,10 @@ type InternalField struct {
5252
Location string
5353
}
5454

55-
type ValueLookup struct {
56-
Location string
57-
}
58-
5955
// LookupTables represents a list of lookup tables that are used to derive addresses for a program.
6056
type LookupTables struct {
6157
DerivedLookupTables []DerivedLookupTable
62-
StaticLookupTables []string
58+
StaticLookupTables []solana.PublicKey
6359
}
6460

6561
// DerivedLookupTable represents a lookup table that is used to derive addresses for a program.
@@ -212,19 +208,18 @@ func decodeBorshIntoType(data []byte, typ reflect.Type) (interface{}, error) {
212208
// It handles both AddressSeeds (which are public keys) and ValueSeeds (which are byte arrays from input args).
213209
func getSeedBytes(ctx context.Context, lookup PDALookups, args any, derivedTableMap map[string]map[string][]*solana.AccountMeta, reader client.Reader) ([][]byte, error) {
214210
var seedBytes [][]byte
215-
maxSeedLength := 32
216211

217212
for _, seed := range lookup.Seeds {
218213
if lookupSeed, ok := seed.(AccountLookup); ok {
219-
// Get value from a location (This doens't have to be an address, it can be any value)
214+
// Get value from a location (This doesn't have to be an address, it can be any value)
220215
bytes, err := GetValuesAtLocation(args, lookupSeed.Location)
221216
if err != nil {
222217
return nil, fmt.Errorf("error getting address seed: %w", err)
223218
}
224219
// validate seed length
225220
for _, b := range bytes {
226-
if len(b) > maxSeedLength {
227-
return nil, fmt.Errorf("seed byte array exceeds maximum length of %d: got %d bytes", maxSeedLength, len(b))
221+
if len(b) > solana.MaxSeedLength {
222+
return nil, fmt.Errorf("seed byte array exceeds maximum length of %d: got %d bytes", solana.MaxSeedLength, len(b))
228223
}
229224
seedBytes = append(seedBytes, b)
230225
}
@@ -247,7 +242,7 @@ func getSeedBytes(ctx context.Context, lookup PDALookups, args any, derivedTable
247242

248243
// generatePDAs generates program-derived addresses (PDAs) from public keys and seeds.
249244
func generatePDAs(publicKeys []*solana.AccountMeta, seeds [][]byte, lookup PDALookups) ([]*solana.AccountMeta, error) {
250-
if len(seeds) > 16 {
245+
if len(seeds) > solana.MaxSeeds {
251246
return nil, fmt.Errorf("seed maximum exceeded: %d", len(seeds))
252247
}
253248
var addresses []*solana.AccountMeta
@@ -271,6 +266,8 @@ func (s *SolanaChainWriterService) ResolveLookupTables(ctx context.Context, args
271266

272267
// Read derived lookup tables
273268
for _, derivedLookup := range lookupTables.DerivedLookupTables {
269+
// Load the lookup table - note: This could be multiple tables if the lookup is a PDALookups that resovles to more
270+
// than one address
274271
lookupTableMap, _, err := s.LoadTable(ctx, args, derivedLookup, s.reader, derivedTableMap)
275272
if err != nil {
276273
return nil, nil, fmt.Errorf("error loading derived lookup table: %w", err)
@@ -289,17 +286,11 @@ func (s *SolanaChainWriterService) ResolveLookupTables(ctx context.Context, args
289286

290287
// Read static lookup tables
291288
for _, staticTable := range lookupTables.StaticLookupTables {
292-
// Parse the static table address
293-
tableAddress, err := solana.PublicKeyFromBase58(staticTable)
294-
if err != nil {
295-
return nil, nil, fmt.Errorf("invalid static lookup table address: %s, error: %w", staticTable, err)
296-
}
297-
298-
addressses, err := getLookupTableAddresses(ctx, s.reader, tableAddress)
289+
addressses, err := getLookupTableAddresses(ctx, s.reader, staticTable)
299290
if err != nil {
300291
return nil, nil, fmt.Errorf("error fetching static lookup table address: %w", err)
301292
}
302-
staticTableMap[tableAddress] = addressses
293+
staticTableMap[staticTable] = addressses
303294
}
304295

305296
return derivedTableMap, staticTableMap, nil
@@ -312,15 +303,16 @@ func (s *SolanaChainWriterService) LoadTable(ctx context.Context, args any, rlt
312303
return nil, nil, fmt.Errorf("error resolving addresses for lookup table: %w", err)
313304
}
314305

306+
// Nested map in case the lookup table resolves to multiple addresses
315307
resultMap := make(map[string]map[string][]*solana.AccountMeta)
316308
var lookupTableMetas []*solana.AccountMeta
317309

318310
// Iterate over each address of the lookup table
319311
for _, addressMeta := range lookupTableAddresses {
320-
// Fetch account info
312+
// Read the full list of addresses from the lookup table
321313
addresses, err := getLookupTableAddresses(ctx, reader, addressMeta.PublicKey)
322314
if err != nil {
323-
return nil, nil, fmt.Errorf("error fetching lookup table address: %w", err)
315+
return nil, nil, fmt.Errorf("error fetching lookup table address: %s, error: %w", addressMeta.PublicKey, err)
324316
}
325317

326318
// Create the inner map for this lookup table

0 commit comments

Comments
 (0)