Skip to content

Conversation

lawRathod
Copy link
Member

@lawRathod lawRathod commented Sep 18, 2025

🔗 zboto Link

gemini-code-assist[bot]

This comment was marked as outdated.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for Lotus v2 APIs to leverage F3 finality, which is a significant and valuable feature. The changes are extensive, touching the main application logic and all Rosetta services to handle v1 and v2 API clients, and to process finality tags from requests. New helper functions and tests for the v2 API logic have been added, which is great.

My review has identified a few key areas for improvement. There are a couple of places where the new v2 API logic is not fully utilized, with calls still being made to the v1 API, which could defeat the purpose of the finality feature. I've also noted some opportunities to improve testing, particularly by adding coverage for the new finality-aware code paths in the service-level tests and by refactoring a test that duplicates implementation logic. Additionally, there are some minor cleanup opportunities in the Makefile and error handling.

Overall, the changes are well-structured. Addressing the feedback will help ensure the new features are robust, correct, and well-tested.

Copy link
Member

@emmanuelm41 emmanuelm41 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, the PR looks great! I left some comments to address/review/discuss. So far tests are just covering the same features we had on v1. No new test cases added for v2 features. I would be amazing to add v2 test cases on each file

README.md Outdated
}
```

**Key Behavior**: With finality tags, the proxy returns `max(requested_height, finality_height)`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This behavior depends on this flag right?
FORCE_SAFE_F3_FINALITY

If it is not enable, it is max what we return. When enabled, if the client as for height 1000 and tag is provided, but height returned by the provided tag is 998, we reject and give an error?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic is reworked in latest design document. The FORCE_SAFE_F3_FINALITY is removed in favor of anchor mode. With anchor mode enabled, the requested height is always returned with disabled the max(requested, finality) is returned

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No default finality can be forced only specified in request

main.go Outdated
Comment on lines 58 to 77
if strings.HasSuffix(addr, "/rpc") {
// New format: base URL ends with /rpc
// Append /v1 and /v2 to create specific endpoints
v1Addr = addr + "/v1"
v2Addr = addr + "/v2"
srv.Logger.Infof("Using base /rpc endpoint - V1: %s, V2: %s", v1Addr, v2Addr)
} else if strings.Contains(addr, "/rpc/v1") {
// Legacy format: already has /rpc/v1
v1Addr = addr
v2Addr = strings.Replace(addr, "/rpc/v1", "/rpc/v2", 1)
srv.Logger.Infof("Using legacy /rpc/v1 endpoint - V1: %s, V2: %s", v1Addr, v2Addr)
} else if strings.Contains(addr, "/rpc/v2") {
// If someone provides v2 endpoint directly, derive v1 from it
v1Addr = strings.Replace(addr, "/rpc/v2", "/rpc/v1", 1)
v2Addr = addr
srv.Logger.Infof("Using /rpc/v2 endpoint - V1: %s, V2: %s", v1Addr, v2Addr)
} else {
// Unrecognized format - return error
return nil, nil, nil, fmt.Errorf("unrecognized RPC endpoint format: %s. Expected format ending with /rpc, /rpc/v1, or /rpc/v2", addr)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we extract this into a utils function?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done! it's now in helper.go

main.go Outdated
Comment on lines 89 to 93
v2Client, v2Closer, err := client.NewFullNodeRPCV2(context.Background(), v2Addr, headers)
if err != nil {
srv.Logger.Warnf("V2 APIs enabled but failed to create V2 client: %v. Will use V1 only", err)
return v1Client, nil, v1Closer, nil
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If v2 is required, but fail to connect, I think we are hiding the error, as we are not returning it

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

main.go Outdated
rosettaLib *rosettaFilecoinLib.RosettaConstructionFilecoin,
) http.Handler {
accountAPIService := srv.NewAccountAPIService(network, &api, rosettaLib)
accountAPIService := srv.NewAccountAPIService(network, &v1API, v2API, rosettaLib)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason why one is a reference (v1), while the other is not (v2)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed the stuct def, not i's similar

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mempool endpoint is meant to retrieve pending mempool txs, which indicates they are not really on any tipset yet. Asking for mempool txs with a tipset key different to latest may be inconsistent. We should check what that value is meant for on lotus node. Maybe we don't really need v2 features on it (just v1, or v2 with latest)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, we don't need v2 on mempool.

Comment on lines 99 to 136
if finalityTag != "" {
// Get the finality-based tipset
finalityTipSet, err := ChainGetTipSetWithFallback(ctx, s.v1Node, s.v2Node, finalityTag)
if err != nil {
return nil, BuildError(ErrUnableToGetTipset, err, true)
}
finalityHeight := int64(finalityTipSet.Height())

// Return the maximum between requested and finality-based height
if requestedHeight >= finalityHeight {
// Requested block is already at or beyond finality height, return it
impl := func() {
tipSet, err = s.v1Node.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(requestedHeight), filTypes.EmptyTSK)
}
errTimeOut := tools.WrapWithTimeout(impl, LotusCallTimeOut)
if errTimeOut != nil {
return nil, ErrLotusCallTimedOut
}
if err != nil {
return nil, BuildError(ErrUnableToGetTipset, err, true)
}
} else {
// Requested block is before finality, return the finality-based block
tipSet = finalityTipSet
requestedHeight = finalityHeight
}
} else {
// No finality tag - return the requested block
impl := func() {
tipSet, err = s.v1Node.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(requestedHeight), filTypes.EmptyTSK)
}
errTimeOut := tools.WrapWithTimeout(impl, LotusCallTimeOut)
if errTimeOut != nil {
return nil, ErrLotusCallTimedOut
}
if err != nil {
return nil, BuildError(ErrUnableToGetTipset, err, true)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if we move this into a different utils function, so that it is easier to review?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's now part of single height resolution function in v2Helper.go

@lawRathod lawRathod marked this pull request as draft October 6, 2025 14:14
@lawRathod lawRathod requested a review from emmanuelm41 October 13, 2025 09:33
@lawRathod lawRathod marked this pull request as ready for review October 13, 2025 09:39
@lawRathod
Copy link
Member Author

/gemini review

@lawRathod
Copy link
Member Author

/gemini summary

@lawRathod lawRathod changed the base branch from master to dev October 13, 2025 09:47
Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces significant new functionality by adding support for the Lotus v2 API and F3 finality. The changes are extensive, touching the main application entrypoint, all Rosetta services, and adding new helper files for the finality logic. While the overall implementation is solid and includes some nice improvements like better error handling in main.go, I've identified a few issues. These include a critical bug that could lead to a panic, a high-severity issue causing data inconsistency in the account balance endpoint, and some medium-severity concerns regarding code robustness and maintainability. My detailed comments below provide explanations and suggestions for addressing these points.

Copy link

Summary of Changes

This pull request significantly upgrades the Rosetta Filecoin Proxy by integrating the Lotus V2 API, which introduces crucial finality features (F3). The changes involve extensive refactoring of core services to support dual API versions, enabling more precise and configurable data retrieval for blocks and accounts. Additionally, it includes important dependency updates and enhancements to the development and testing infrastructure.

Highlights

  • Lotus V2 API Integration: Introduced support for the Lotus V2 API, enabling advanced finality features (F3) for block and account data retrieval. This includes new logic for resolving tipsets based on finality tags and an 'anchor mode'.
  • Dependency Upgrades: Updated Go version to 1.23.10 and upgraded several key dependencies, including rosetta-sdk-go, go-address, go-jsonrpc, go-state-types, and lotus to their latest versions.
  • Refactored API Service Calls: Modified main.go, account.go, and block.go to handle both V1 and V2 Lotus API clients, dynamically selecting the appropriate API based on configuration and request parameters. This includes a new ResolveRPCEndpoints helper for robust RPC URL parsing.
  • Enhanced Finality Handling: Implemented ResolveTipSetForFinality to manage tipset resolution, supporting different finality tags ('latest', 'safe', 'finalized') and an 'anchor mode' for precise block height queries. Network options now expose these finality capabilities.
  • Improved Development Workflow: Added Dependabot configuration for automated dependency updates, introduced .mockery.yaml for mock generation, and updated the Makefile with new targets for mock generation and improved LOTUS_RPC_URL handling.
  • Robust Error Handling and Logging: Addressed several review comments by implementing explicit error handling for environment variable parsing (strconv.Atoi, strconv.ParseBool) and improving logging for V2 API and finality anchor mode status.
Changelog
  • .github/dependabot.yml
    • Added Dependabot configuration for gomod and github-actions.
  • .gitignore
    • Added .DS_Store and main to the ignore list.
  • .mockery.yaml
    • Added configuration for generating mocks for the FullNode interface.
  • Makefile
    • Updated ROSETTASDKVER grep pattern for more precise dependency version extraction.
    • Introduced LOTUS_DIR and LOTUS_VERSION variables for mock generation.
    • Modified the run target to include ENABLE_FINALITY_ANCHOR=1.
    • Updated the test_calibration_macos RPC URL to zondax.ch.
    • Added a new generate_mocks target to automate mock creation using mockery.
  • README.md
    • Minor formatting adjustments (added blank lines) for improved readability.
  • extern/filecoin-ffi
    • Updated the filecoin-ffi subproject commit to 2e0c1aff7003f3ca8df46396ad87d275e9517e45.
  • go.mod
    • Updated Go version to 1.23.10 and specified toolchain go1.24.4.
    • Upgraded github.com/coinbase/rosetta-sdk-go from v0.7.2 to v0.8.5.
    • Upgraded github.com/filecoin-project/go-address from v1.1.0 to v1.2.0.
    • Added github.com/filecoin-project/go-f3 v0.8.10.
    • Upgraded github.com/filecoin-project/go-jsonrpc from v0.2.1 to v0.8.0.
    • Upgraded github.com/filecoin-project/go-state-types from v0.11.1 to v0.17.0.
    • Upgraded github.com/filecoin-project/lotus from v1.22.1 to v1.34.1.
    • Upgraded github.com/google/uuid from v1.3.0 to v1.6.0.
    • Upgraded github.com/ipfs/go-block-format from v0.1.1 to v0.2.2.
    • Upgraded github.com/ipfs/go-cid from v0.3.2 to v0.5.0.
    • Upgraded github.com/libp2p/go-libp2p-core to github.com/libp2p/go-libp2p v0.42.0.
    • Upgraded github.com/multiformats/go-multihash from v0.2.1 to v0.2.3.
    • Upgraded github.com/orcaman/concurrent-map to v1.0.0.
    • Upgraded github.com/stretchr/testify from v1.8.1 to v1.10.0.
    • Upgraded github.com/zondax/rosetta-filecoin-lib from v1.2201.0 to v1.3401.0.
    • Updated numerous indirect dependencies.
  • main.go
    • Imported v2api from lotus to support V2 API calls.
    • Refactored getFullNodeAPI to return both V1 and V2 API clients, handling endpoint resolution and client creation based on ENABLE_LOTUS_V2_APIS.
    • Updated newBlockchainRouter to accept both v1API and v2API for service initialization.
    • Modified startRosettaRPC to create NetworkIdentifiers for F3 sub-networks, enabling finality support.
    • Updated connectAPI to return both V1 and V2 API clients.
    • Added logic to read ENABLE_LOTUS_V2_APIS and ENABLE_FINALITY_ANCHOR environment variables.
    • Improved error handling for strconv.Atoi and strconv.ParseBool.
  • rosetta/services/account.go
    • Updated AccountAPIService struct to include v1Node and v2Node.
    • Modified NewAccountAPIService constructor to accept both V1 and V2 API interfaces.
    • Refactored AccountBalance logic to use ResolveTipSetForFinality for finality-aware tipset resolution and v1Node for actor state and balance queries.
  • rosetta/services/account_test.go
    • Updated AccountAPIService fields and NewAccountAPIService calls in tests to align with the new V1/V2 API structure.
  • rosetta/services/block.go
    • Updated BlockAPIService struct to include v1Node and v2Node.
    • Modified NewBlockAPIService constructor to accept both V1 and V2 API interfaces.
    • Refactored the Block method to utilize ResolveTipSetForFinality for finality-aware tipset resolution.
    • Added handling for IsNullTipSet in anchor mode or when no finality tag is specified.
    • Updated processTrace, parseExecParams, and parseMsigParams to use *filTypes.MessageTrace for message parsing.
  • rosetta/services/block_test.go
    • Updated BlockAPIService fields and NewBlockAPIService calls in tests to align with the new V1/V2 API structure.
  • rosetta/services/constants.go
    • Added time import.
    • Introduced EnableLotusV2APIs and EnableFinalityAnchor variables for V2 API configuration.
    • Defined SubNetworkF3, FinalityTagLatest, FinalityTagSafe, FinalityTagFinalized, and MetadataFinalityTag constants for finality features.
    • Moved LotusCallTimeOut constant to this file.
    • Added EVM_CALL to SupportedOperations.
  • rosetta/services/helpers.go
    • Added fmt, strings, and abi imports.
    • Introduced constants like ACCOUNT_ACTOR_NAME, ETHACCOUNT_ACTOR_NAME, METHOD_SEND, METHOD_FALLBACK, and FIRST_EXPORTED_METHOD_NUMBER.
    • Updated ValidateNetworkId to validate SubNetworkIdentifier and its metadata for finality tags.
    • Refactored GetMethodName to use *filTypes.MessageTrace and include new logic for fallback methods and searching across all actor types.
    • Added isAccountActorFallback, FindMethodInType, FindMethodNameInAllActors, and GetMethodByActorName helper functions.
    • Introduced RPCEndpoints struct and ResolveRPCEndpoints function for robust V1/V2 RPC endpoint resolution.
  • rosetta/services/mempool.go
    • Updated MempoolTransaction to use filTypes.MessageTrace when calling GetMethodName.
  • rosetta/services/mempool_test.go
    • Minor import reordering.
  • rosetta/services/mocks/fullnode_mock.go
    • Removed this file, as mock generation is now handled by .mockery.yaml.
  • rosetta/services/network.go
    • Updated NetworkList to include F3 sub-network identifier if V2 APIs are enabled.
    • Modified NetworkStatus to include the Synced field in SyncStatus.
    • Updated NetworkOptions to include V2 API finality metadata if V2 APIs are enabled.
  • rosetta/services/network_test.go
    • Minor import reordering.
  • rosetta/services/sync_status.go
    • Minor import reordering.
  • rosetta/services/sync_status_test.go
    • Updated mock type from mocks.FullNodeMock to mocks.FullNode.
  • rosetta/services/v2_helpers.go
    • New file introduced containing V2 API specific helper functions, including FinalityTag type and constants, IsV2EnabledForService, IsFinalityAnchorEnabled, shouldUseV2API, GetFinalityTagFromMetadata, GetFinalityTagFromNetworkIdentifier, CreateTagSelector, ChainGetTipSetWithFallback, TipSetResolution struct, and ResolveTipSetForFinality.
  • rosetta/tests/helper_test.go
    • New file added with tests for FindMethodNameInAllActors and FindMethodInType.
  • rosetta/tests/rosetta-config-PR-calibration.json
    • Updated start_index from 320000 to 3027817 and end_conditions.index from 321000 to 3028817.
  • rosetta/tests/rosetta-config-PR-mainnet.json
    • Updated start_index from 2121000 to 3763750 and end_conditions.index from 2121400 to 3768750.
Ignored Files
  • Ignored by pattern: .github/workflows/** (1)
    • .github/workflows/main.yml
Activity
  • lawRathod requested a Gemini review.
  • lawRathod requested a Gemini summary.
  • gemini-code-assist[bot] identified a high-priority issue where TestEndpointParsing duplicated getFullNodeAPI logic, recommending extraction into a separate function.
  • gemini-code-assist[bot] raised a high-priority concern that StateGetActor bypassed V2 API finality logic, suggesting the use of StateGetActorWithFallback. emmanuelm41 and lawRathod questioned the applicability of finality in this specific context.
  • gemini-code-assist[bot] noted a high-priority issue where getLotusStateCompute was hardcoded to the v1 node, recommending V2-awareness. emmanuelm41 and lawRathod questioned this, stating explicit tipset usage.
  • gemini-code-assist[bot] pointed out a medium-priority issue with the misleading test_calibration_macos target name, suggesting a rename. emmanuelm41 advocated for keeping 'calibration', and lawRathod subsequently fixed the issue.
  • gemini-code-assist[bot] highlighted a medium-priority issue regarding the ignored error from strconv.ParseBool. lawRathod fixed this.
  • gemini-code-assist[bot] identified a medium-priority issue where the error from strconv.Atoi was ignored. emmanuelm41 agreed, and lawRathod fixed it.
  • gemini-code-assist[bot] suggested a medium-priority simplification by removing a redundant request.BlockIdentifier != nil check. lawRathod fixed this.
  • emmanuelm41 inquired about the behavior of the finality flag, specifically FORCE_SAFE_F3_FINALITY. lawRathod clarified that the logic was reworked for anchor mode, replacing the previous flag.
  • emmanuelm41 suggested extracting a utility function for certain logic. lawRathod confirmed this was done and moved to helper.go.
  • emmanuelm41 raised a concern about potential error hiding if the V2 API failed to connect. lawRathod fixed this.
  • emmanuelm41 questioned the inconsistency of using a reference for V1 API and not for V2 API. lawRathod fixed the struct definition for consistency.
  • emmanuelm41 questioned the need for V2 features on the mempool endpoint, suggesting it might be inconsistent. lawRathod agreed that V2 is not needed for mempool.
  • emmanuelm41 suggested moving a block of logic into a separate utility function for easier review. lawRathod confirmed it was moved to a single height resolution function in v2Helper.go.
  • gemini-code-assist[bot] issued a critical comment about a potential nil v2Node causing a panic in Anchor Mode, recommending a nil check.
  • gemini-code-assist[bot] identified a high-priority issue in AccountBalance logic, pointing out unreachable code and potential data inconsistencies due to incorrect error handling.
  • gemini-code-assist[bot] suggested a medium-priority improvement for logging the finality anchor mode, recommending the use of srv.IsFinalityAnchorEnabled() for robustness.
  • gemini-code-assist[bot] noted a medium-priority redundancy in finality tag constants, suggesting they be defined only once as typed constants in v2_helpers.go.
  • gemini-code-assist[bot] recommended a medium-priority fix for RPC endpoint resolution, suggesting strings.HasSuffix instead of strings.Contains for more robust path matching.

@ziscky
Copy link
Contributor

ziscky commented Oct 13, 2025

@lawRathod for CI to work please start the calibration-next node on dev

@lawRathod
Copy link
Member Author

/gemini review

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for Lotus v2 APIs and F3 finality, which is a significant and valuable feature. The implementation is well-structured, with the new finality logic correctly centralized in rosetta/services/v2_helpers.go. The changes also include several good refactorings, such as handling previously ignored errors and cleaning up API client creation.

My review focuses on ensuring the correctness and consistency of the new API extensions. I've identified a few areas for improvement:

  • There's an issue with how sub-network identifiers are exposed in the /network/list endpoint, which could affect client compatibility.
  • A potential correctness bug in the account balance calculation due to an incorrect fallback logic.
  • A minor opportunity to reduce code duplication in the main function.

Overall, this is a solid contribution. Addressing these points will further improve the robustness and clarity of the implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants