Skip to content

Commit

Permalink
unit tests for lookups
Browse files Browse the repository at this point in the history
  • Loading branch information
silaslenihan committed Nov 21, 2024
1 parent a7b8b8b commit 93cba43
Show file tree
Hide file tree
Showing 6 changed files with 466 additions and 43 deletions.
5 changes: 4 additions & 1 deletion .mockery.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,7 @@ packages:
SimpleKeystore:
config:
filename: simple_keystore.go
case: underscore
case: underscore
Txm:
config:
filename: txm.go
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ require (
github.com/smartcontractkit/chainlink-common v0.3.1-0.20241112140826-0e2daed34ef6
github.com/smartcontractkit/libocr v0.0.0-20241007185508-adbe57025f12
github.com/stretchr/testify v1.9.0
github.com/test-go/testify v1.1.4
go.uber.org/zap v1.27.0
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0
golang.org/x/sync v0.8.0
Expand Down
72 changes: 72 additions & 0 deletions gotest.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
📦 github.com/smartcontractkit/chainlink-solana/pkg/solana/chainwriter
exit status 1
❌ TestLookupTables (30.07s)
ports.go:37: found open port: 54520
ports.go:37: found open port: 8536
test_helpers.go:50: API server not ready yet (attempt 1)
test_helpers.go:50: API server not ready yet (attempt 2)
test_helpers.go:50: API server not ready yet (attempt 3)
test_helpers.go:50: API server not ready yet (attempt 4)
test_helpers.go:50: API server not ready yet (attempt 5)
test_helpers.go:50: API server not ready yet (attempt 6)
test_helpers.go:50: API server not ready yet (attempt 7)
test_helpers.go:50: API server not ready yet (attempt 8)
test_helpers.go:50: API server not ready yet (attempt 9)
test_helpers.go:50: API server not ready yet (attempt 10)
test_helpers.go:50: API server not ready yet (attempt 11)
test_helpers.go:50: API server not ready yet (attempt 12)
test_helpers.go:50: API server not ready yet (attempt 13)
test_helpers.go:50: API server not ready yet (attempt 14)
test_helpers.go:50: API server not ready yet (attempt 15)
test_helpers.go:50: API server not ready yet (attempt 16)
test_helpers.go:50: API server not ready yet (attempt 17)
test_helpers.go:50: API server not ready yet (attempt 18)
test_helpers.go:50: API server not ready yet (attempt 19)
test_helpers.go:50: API server not ready yet (attempt 20)
test_helpers.go:50: API server not ready yet (attempt 21)
test_helpers.go:50: API server not ready yet (attempt 22)
test_helpers.go:50: API server not ready yet (attempt 23)
test_helpers.go:50: API server not ready yet (attempt 24)
test_helpers.go:50: API server not ready yet (attempt 25)
test_helpers.go:50: API server not ready yet (attempt 26)
test_helpers.go:50: API server not ready yet (attempt 27)
test_helpers.go:50: API server not ready yet (attempt 28)
test_helpers.go:50: API server not ready yet (attempt 29)
test_helpers.go:50: API server not ready yet (attempt 30)
test_helpers.go:57: Cmd output:
Notice! No wallet available. `solana airdrop` localnet SOL after creating one

Ledger location: /var/folders/p4/jlx3pf896blgl6tcj0xbkhvm0000gn/T/TestLookupTables940285115/001
Log: /var/folders/p4/jlx3pf896blgl6tcj0xbkhvm0000gn/T/TestLookupTables940285115/001/validator.log
Initializing...
Error: failed to start validator: Failed to create ledger at /var/folders/p4/jlx3pf896blgl6tcj0xbkhvm0000gn/T/TestLookupTables940285115/001: blockstore error

Cmd error:
test_helpers.go:59:
Error Trace: /Users/silaslenihan/Desktop/repos/chainlink-solana/pkg/solana/client/test_helpers.go:59
/Users/silaslenihan/Desktop/repos/chainlink-solana/pkg/solana/chainwriter/lookups_test.go:148
Error: Should be true
Test: TestLookupTables
test_helpers.go:37:
Error Trace: /Users/silaslenihan/Desktop/repos/chainlink-solana/pkg/solana/client/test_helpers.go:37
/Users/silaslenihan/go/pkg/mod/golang.org/[email protected]/src/testing/testing.go:1176
/Users/silaslenihan/go/pkg/mod/golang.org/[email protected]/src/testing/testing.go:1354
/Users/silaslenihan/go/pkg/mod/golang.org/[email protected]/src/testing/testing.go:1684
/Users/silaslenihan/go/pkg/mod/golang.org/[email protected]/src/runtime/panic.go:629
/Users/silaslenihan/go/pkg/mod/golang.org/[email protected]/src/testing/testing.go:1006
/Users/silaslenihan/Desktop/repos/chainlink-solana/pkg/solana/client/test_helpers.go:59
/Users/silaslenihan/Desktop/repos/chainlink-solana/pkg/solana/chainwriter/lookups_test.go:148
Error: "exit status 1" does not contain "signal: killed"
Test: TestLookupTables
Messages: exit status 1
test_helpers.go:38: solana-test-validator
stdout:
Notice! No wallet available. `solana airdrop` localnet SOL after creating one

Ledger location: /var/folders/p4/jlx3pf896blgl6tcj0xbkhvm0000gn/T/TestLookupTables940285115/001
Log: /var/folders/p4/jlx3pf896blgl6tcj0xbkhvm0000gn/T/TestLookupTables940285115/001/validator.log
Initializing...
Error: failed to start validator: Failed to create ledger at /var/folders/p4/jlx3pf896blgl6tcj0xbkhvm0000gn/T/TestLookupTables940285115/001: blockstore error

stderr:

2 changes: 1 addition & 1 deletion pkg/solana/chainwriter/chain_writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ func (s *SolanaChainWriterService) SubmitTransaction(ctx context.Context, contra
}

// Fetch derived and static table maps
derivedTableMap, staticTableMap, err := s.getDerivedTableMap(ctx, methodConfig.LookupTables, debugID)
derivedTableMap, staticTableMap, err := s.ResolveLookupTables(ctx, methodConfig.LookupTables, debugID)
if err != nil {
return errorWithDebugID(fmt.Errorf("error getting lookup tables: %w", err), debugID)
}
Expand Down
60 changes: 19 additions & 41 deletions pkg/solana/chainwriter/lookups.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"

"github.com/gagliardetto/solana-go"
addresslookuptable "github.com/gagliardetto/solana-go/programs/address-lookup-table"
"github.com/gagliardetto/solana-go/rpc"
"github.com/smartcontractkit/chainlink-solana/pkg/solana/client"
)
Expand Down Expand Up @@ -181,7 +182,7 @@ func generatePDAs(publicKeys []*solana.AccountMeta, seeds [][]byte, lookup PDALo
return addresses, nil
}

func (s *SolanaChainWriterService) getDerivedTableMap(ctx context.Context, lookupTables LookupTables, debugID string) (map[string]map[string][]*solana.AccountMeta, map[solana.PublicKey]solana.PublicKeySlice, error) {
func (s *SolanaChainWriterService) ResolveLookupTables(ctx context.Context, lookupTables LookupTables, debugID string) (map[string]map[string][]*solana.AccountMeta, map[solana.PublicKey]solana.PublicKeySlice, error) {
derivedTableMap := make(map[string]map[string][]*solana.AccountMeta)
staticTableMap := make(map[solana.PublicKey]solana.PublicKeySlice)

Expand Down Expand Up @@ -211,23 +212,8 @@ func (s *SolanaChainWriterService) getDerivedTableMap(ctx context.Context, looku
return nil, nil, errorWithDebugID(fmt.Errorf("invalid static lookup table address: %s, error: %w", staticTable, err), debugID)
}

// Fetch the account info for the static table
accountInfo, err := s.reader.GetAccountInfoWithOpts(ctx, tableAddress, &rpc.GetAccountInfoOpts{
Encoding: "base64",
Commitment: rpc.CommitmentConfirmed,
})
if err != nil || accountInfo == nil || accountInfo.Value == nil {
return nil, nil, errorWithDebugID(fmt.Errorf("error fetching account info for static table: %s, error: %w", staticTable, err), debugID)
}

// Decode the account data into an array of public keys
addresses, err := decodeLookupTable(accountInfo.Value.Data.GetBinary())
if err != nil {
return nil, nil, errorWithDebugID(fmt.Errorf("error decoding static lookup table data for %s: %w", staticTable, err), debugID)
}

// Add the static lookup table to the map
staticTableMap[tableAddress] = addresses
addressses, err := getLookupTableAddress(ctx, s.reader, tableAddress, debugID)
staticTableMap[tableAddress] = addressses
}

return derivedTableMap, staticTableMap, nil
Expand All @@ -246,18 +232,9 @@ func (s *SolanaChainWriterService) LoadTable(rlt DerivedLookupTable, ctx context
// Iterate over each address of the lookup table
for _, addressMeta := range lookupTableAddresses {
// Fetch account info
accountInfo, err := reader.GetAccountInfoWithOpts(ctx, addressMeta.PublicKey, &rpc.GetAccountInfoOpts{
Encoding: "base64",
Commitment: rpc.CommitmentConfirmed,
})
if err != nil || accountInfo == nil || accountInfo.Value == nil {
return nil, nil, errorWithDebugID(fmt.Errorf("error fetching account info for address %s: %w", addressMeta.PublicKey.String(), err), debugID)
}

// Decode the account data into an array of public keys
addresses, err := decodeLookupTable(accountInfo.Value.Data.GetBinary())
addresses, err := getLookupTableAddress(ctx, reader, addressMeta.PublicKey, debugID)
if err != nil {
return nil, nil, errorWithDebugID(fmt.Errorf("error decoding lookup table data for address %s: %w", addressMeta.PublicKey.String(), err), debugID)
return nil, nil, errorWithDebugID(fmt.Errorf("error fetching lookup table address: %w", err), debugID)
}

// Create the inner map for this lookup table
Expand All @@ -281,18 +258,19 @@ func (s *SolanaChainWriterService) LoadTable(rlt DerivedLookupTable, ctx context
return resultMap, lookupTableMetas, nil
}

func decodeLookupTable(data []byte) (solana.PublicKeySlice, error) {
// Example logic to decode lookup table data; you may need to adjust based on the actual format of the data.
var addresses solana.PublicKeySlice
func getLookupTableAddress(ctx context.Context, reader client.Reader, tableAddress solana.PublicKey, debugID string) (solana.PublicKeySlice, error) {
// Fetch the account info for the static table
accountInfo, err := reader.GetAccountInfoWithOpts(ctx, tableAddress, &rpc.GetAccountInfoOpts{
Encoding: "base64",
Commitment: rpc.CommitmentConfirmed,
})

// Assuming the data is a list of 32-byte public keys in binary format:
for i := 0; i < len(data); i += solana.PublicKeyLength {
if i+solana.PublicKeyLength > len(data) {
return nil, fmt.Errorf("invalid lookup table data length")
}
address := solana.PublicKeyFromBytes(data[i : i+solana.PublicKeyLength])
addresses = append(addresses, address)
if err != nil || accountInfo == nil || accountInfo.Value == nil {
return nil, errorWithDebugID(fmt.Errorf("error fetching account info for table: %s, error: %w", tableAddress.String(), err), debugID)
}

return addresses, nil
alt, err := addresslookuptable.DecodeAddressLookupTableState(accountInfo.GetBinary())
if err != nil {
return nil, errorWithDebugID(fmt.Errorf("error decoding address lookup table state: %w", err), debugID)
}
return alt.Addresses, nil
}
Loading

0 comments on commit 93cba43

Please sign in to comment.