From 11a7562a711180a2f2ddc35eb04ab1c36724d75d Mon Sep 17 00:00:00 2001 From: faisal-link Date: Thu, 8 Jan 2026 00:34:56 +0400 Subject: [PATCH 1/2] use the state object of type to extract generic --- relayer/chainreader/reader/chainreader.go | 73 +++++++++---------- .../reader/chainreader_testnet_test.go | 65 +---------------- 2 files changed, 37 insertions(+), 101 deletions(-) diff --git a/relayer/chainreader/reader/chainreader.go b/relayer/chainreader/reader/chainreader.go index 62953bc3..66c58894 100644 --- a/relayer/chainreader/reader/chainreader.go +++ b/relayer/chainreader/reader/chainreader.go @@ -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) } @@ -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 } @@ -666,7 +666,7 @@ 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 @@ -674,8 +674,8 @@ func (s *suiChainReader) extractGenericTypeTags(ctx context.Context, parsed *rea keyOrder = append(keyOrder, genericType) uniqueTags[genericType] = struct{}{} } - } else if param.GenericDependency != nil && *param.GenericDependency != "" { - genericType, err := s.fetchGenericDependency(ctx, functionConfig.SignerAddress, parsed, ¶m) + } else if param.GenericDependency != nil && *param.GenericDependency != "" && paramIndex < len(args) { + genericType, err := s.fetchGenericDependency(ctx, functionConfig.SignerAddress, parsed, ¶m, args[paramIndex]) if err != nil { return nil, fmt.Errorf("failed to fetch generic dependency: %w", err) } @@ -689,50 +689,37 @@ 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, + signerAddress string, + parsed *readIdentifier, + 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) } @@ -1183,3 +1170,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 +} diff --git a/relayer/chainreader/reader/chainreader_testnet_test.go b/relayer/chainreader/reader/chainreader_testnet_test.go index cdba6e31..844b2bd0 100644 --- a/relayer/chainreader/reader/chainreader_testnet_test.go +++ b/relayer/chainreader/reader/chainreader_testnet_test.go @@ -12,7 +12,6 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-common/pkg/logger" @@ -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"}, "-") @@ -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", @@ -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) @@ -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 From 1fb307293175b35211f12e7fe93882a89260a74a Mon Sep 17 00:00:00 2001 From: faisal-link Date: Thu, 8 Jan 2026 00:42:04 +0400 Subject: [PATCH 2/2] remove unnecessary args --- relayer/chainreader/reader/chainreader.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/relayer/chainreader/reader/chainreader.go b/relayer/chainreader/reader/chainreader.go index 66c58894..eefc77c9 100644 --- a/relayer/chainreader/reader/chainreader.go +++ b/relayer/chainreader/reader/chainreader.go @@ -675,7 +675,7 @@ func (s *suiChainReader) extractGenericTypeTags(ctx context.Context, parsed *rea uniqueTags[genericType] = struct{}{} } } else if param.GenericDependency != nil && *param.GenericDependency != "" && paramIndex < len(args) { - genericType, err := s.fetchGenericDependency(ctx, functionConfig.SignerAddress, parsed, ¶m, args[paramIndex]) + genericType, err := s.fetchGenericDependency(ctx, ¶m, args[paramIndex]) if err != nil { return nil, fmt.Errorf("failed to fetch generic dependency: %w", err) } @@ -691,8 +691,6 @@ func (s *suiChainReader) extractGenericTypeTags(ctx context.Context, parsed *rea func (s *suiChainReader) fetchGenericDependency( ctx context.Context, - signerAddress string, - parsed *readIdentifier, param *codec.SuiFunctionParam, paramValue any, ) (string, error) {