Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 34 additions & 37 deletions relayer/chainreader/reader/chainreader.go
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,7 @@ func (s *suiChainReader) callFunction(ctx context.Context, parsed *readIdentifie
}

// Extract generic type tags from function params
typeArgs, err := s.extractGenericTypeTags(ctx, parsed, functionConfig)
typeArgs, err := s.extractGenericTypeTags(ctx, parsed, functionConfig, args)
if err != nil {
return nil, fmt.Errorf("failed to extract generic type tags: %w", err)
}
Expand All @@ -657,7 +657,7 @@ func (s *suiChainReader) callFunction(ctx context.Context, parsed *readIdentifie
}

// Helper function to extract generic type tags
func (s *suiChainReader) extractGenericTypeTags(ctx context.Context, parsed *readIdentifier, functionConfig *config.ChainReaderFunction) ([]string, error) {
func (s *suiChainReader) extractGenericTypeTags(ctx context.Context, parsed *readIdentifier, functionConfig *config.ChainReaderFunction, args []any) ([]string, error) {
if functionConfig.Params == nil {
return []string{}, nil
}
Expand All @@ -666,16 +666,16 @@ func (s *suiChainReader) extractGenericTypeTags(ctx context.Context, parsed *rea
uniqueTags := make(map[string]struct{})
keyOrder := make([]string, 0)

for _, param := range functionConfig.Params {
for paramIndex, param := range functionConfig.Params {
if param.GenericType != nil && *param.GenericType != "" {
genericType := *param.GenericType
// Only add if not already present
if _, exists := uniqueTags[genericType]; !exists {
keyOrder = append(keyOrder, genericType)
uniqueTags[genericType] = struct{}{}
}
} else if param.GenericDependency != nil && *param.GenericDependency != "" {
genericType, err := s.fetchGenericDependency(ctx, functionConfig.SignerAddress, parsed, &param)
} else if param.GenericDependency != nil && *param.GenericDependency != "" && paramIndex < len(args) {
genericType, err := s.fetchGenericDependency(ctx, &param, args[paramIndex])
if err != nil {
return nil, fmt.Errorf("failed to fetch generic dependency: %w", err)
}
Expand All @@ -689,50 +689,35 @@ func (s *suiChainReader) extractGenericTypeTags(ctx context.Context, parsed *rea
return keyOrder, nil
}

func (s *suiChainReader) fetchGenericDependency(ctx context.Context, signerAddress string, parsed *readIdentifier, param *codec.SuiFunctionParam) (string, error) {
func (s *suiChainReader) fetchGenericDependency(
ctx context.Context,
param *codec.SuiFunctionParam,
paramValue any,
) (string, error) {
if param == nil || param.GenericDependency == nil || *param.GenericDependency == "" {
return "", fmt.Errorf("generic dependency is not set")
}

switch *param.GenericDependency {
case "get_token_pool_state_type":
// Try to get the CCIP / TokenAdminRegistry package address from the package resolver (requires that it has been bound to CR)
ccipPackageAddress, err := s.packageResolver.ResolvePackageAddress("token_admin_registry")
if err != nil {
// Attempt getting the ccip package address via the offramp binding as a fallback
offrampPackageAddress, err := s.packageResolver.ResolvePackageAddress("offramp")
if err != nil {
return "", fmt.Errorf("get_token_pool_state_type requires that the OffRamp package has been bound to ChainReader: %w", err)
}

s.logger.Debugw("get_token_pool_state_type falling back to OffRamp package", "offrampPackageAddress", offrampPackageAddress)

ccipPackageAddress, err = s.client.GetCCIPPackageID(ctx, offrampPackageAddress, signerAddress)
if err != nil {
return "", fmt.Errorf("failed to get CCIP package ID from offramp package address in fetchGenericDependency: %w", err)
}

latestCcipPackageAddress, err := s.client.GetLatestPackageId(ctx, ccipPackageAddress, "state_object")
if err != nil {
return "", fmt.Errorf("failed to get latest CCIP package address from offramp package address in fetchGenericDependency: %w", err)
}

s.logger.Debugw("get_token_pool_state_type using latest CCIP package address", "latestCcipPackageAddress", latestCcipPackageAddress)

ccipPackageAddress = latestCcipPackageAddress
if paramValue == nil || paramValue.(string) == "" {
return "", fmt.Errorf("param value is nil or empty string")
}

if ccipPackageAddress == "" {
return "", fmt.Errorf("get_token_pool_state_type requires that the CCIP / TokenAdminRegistry package has been bound to ChainReader: %w", err)
}
// Use the state object ID to deduce the type
stateObject, err := s.client.ReadObjectId(ctx, paramValue.(string))
if err != nil {
return "", fmt.Errorf("failed to read state object: %w", err)
}

s.logger.Warnw("get_token_pool_state_type using CCIP package address", "ccipPackageAddress", ccipPackageAddress)
s.logger.Debugw("stateObjectType", "stateObjectType", stateObject.Type)

tokenConfig, err := s.client.GetTokenPoolConfigByPackageAddress(ctx, signerAddress, parsed.address, ccipPackageAddress)
genericType, err := parseGenericTypeFromObjectType(stateObject.Type)
if err != nil {
return "", fmt.Errorf("failed to get token pool state type: %w", err)
return "", err
}
return tokenConfig.TokenType, nil

return genericType, nil
default:
return "", fmt.Errorf("unknown generic dependency: %s", *param.GenericDependency)
}
Expand Down Expand Up @@ -1183,3 +1168,15 @@ func (s *suiChainReader) transformEventsToSequences(eventRecords []database.Even

return sequences, nil
}

func parseGenericTypeFromObjectType(objectType string) (string, error) {
startIdx := strings.Index(objectType, "<")
endIdx := strings.LastIndex(objectType, ">")

if startIdx == -1 || endIdx == -1 || startIdx >= endIdx {
return "", fmt.Errorf("invalid object type format, expected generic type parameter: %s", objectType)
}

genericType := objectType[startIdx+1 : endIdx]
return genericType, nil
}
65 changes: 1 addition & 64 deletions relayer/chainreader/reader/chainreader_testnet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/smartcontractkit/chainlink-common/pkg/logger"
Expand All @@ -33,12 +32,6 @@ func TestChainReaderTestnet(t *testing.T) {
log := logger.Test(t)
rpcUrl := testutils.TestnetUrl

offrampContractName := "OffRamp"
offrampPackageId := "0x01a0a22b2abacbd48e9a026c1661189a8ec5ce4942cba07017b63eaad0a205a4"

tokenAdminRegistryContractName := "TokenAdminRegistry"
tokenAdminRegistryPackageId := "0x9de8a33d158e26f0b51f199da8be1a22e9755510b705cfb88230b257187da733"

burnMintTokenPoolContractName := "BurnMintTokenPool"
burnMintTokenPoolPackageId := "0xfeff675b624e55da49f80fda3b676fe1ef5a957a8334cb675ca35de8918f612d"
burnMintTokenPoolIdentifier := strings.Join([]string{burnMintTokenPoolPackageId, burnMintTokenPoolContractName, "get_token"}, "-")
Expand Down Expand Up @@ -74,30 +67,8 @@ func TestChainReaderTestnet(t *testing.T) {
SyncTimeout: 60 * time.Second,
},
Modules: map[string]*config.ChainReaderModule{
tokenAdminRegistryContractName: {
Name: "token_admin_registry",
Functions: map[string]*config.ChainReaderFunction{},
},
offrampContractName: {
Name: "offramp",
Functions: map[string]*config.ChainReaderFunction{},
Events: map[string]*config.ChainReaderEvent{
"execution_state_changed": {
Name: "execution_state_changed",
EventType: "ExecutionStateChanged",
EventSelector: client.EventFilterByMoveEventModule{
Module: "offramp",
Event: "ExecutionStateChanged",
},
EventSelectorDefaultOffset: &client.EventId{
TxDigest: "7KyXWWmJnX4u5aKr1ofvdh5Af5Vix6rnHnonk33CiDtV",
EventSeq: "0",
},
},
},
},
burnMintTokenPoolContractName: {
Name: "token_pool",
Name: "burn_mint_token_pool",
Functions: map[string]*config.ChainReaderFunction{
"get_token": {
Name: "get_token",
Expand Down Expand Up @@ -255,14 +226,8 @@ func TestChainReaderTestnet(t *testing.T) {
require.NoError(t, err)

err = chainReader.Bind(context.Background(), []types.BoundContract{{
Name: offrampContractName,
Address: offrampPackageId,
}, {
Name: burnMintTokenPoolContractName,
Address: burnMintTokenPoolPackageId,
}, {
Name: tokenAdminRegistryContractName,
Address: tokenAdminRegistryPackageId,
}})
require.NoError(t, err)

Expand Down Expand Up @@ -407,34 +372,6 @@ func TestChainReaderTestnet(t *testing.T) {
log.Infof("Completed %d requests, %d errors", processedCount, errorCount)
})

t.Run("TransactionIndexer_ExecutionStateChanged_event", func(t *testing.T) {
t.Skip("Skipping TransactionIndexer_ExecutionStateChanged_event test")
indexerInstance.Start(ctx)
defer indexerInstance.Close()

assert.Eventually(t, func() bool {
println("\n\n------------------------------------------------------------------------------\n\n")

eventHandle := offrampPackageId + "::offramp::ExecutionStateChanged"
events, err := dbStore.QueryEvents(ctx, offrampPackageId, eventHandle, nil, query.LimitAndSort{
Limit: query.Limit{
Count: 100,
},
})
require.NoError(t, err)

foundExecutionStateChangedDummyReceiver := false
for _, event := range events {
if event.Data["state"] == 3 {
foundExecutionStateChangedDummyReceiver = true
break
}
}

return foundExecutionStateChangedDummyReceiver
}, 45*60*time.Second, 60*time.Second)
})

t.Run("token pool events", func(t *testing.T) {
var retReleasedOrMinted map[string]any

Expand Down
Loading