Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(rpc): filter unconfirmed txs by tx hash #1053

Merged
merged 9 commits into from
Mar 3, 2025
Merged

Conversation

lklimek
Copy link
Collaborator

@lklimek lklimek commented Feb 13, 2025

Issue being fixed or feature implemented

We need a way to check if a transaction exists in the mempool.

What was done?

Added unconfirmed_tx?hash=0x....... endpoint

How Has This Been Tested?

  1. Started rotate e2e devnet.
  2. Stopped all validators but one, to ensure transactions are not removed from the mempool.
  3. Broadcasted transaction:
curl 0:5708/broadcast_tx?tx=0xbabadada
{"code":0,"data":"","codespace":"","hash":"4E200DB5AC1DCA60DDC5F3386A6F2DA333AF4A77A12A74C7D00E78FE16F1CD77","info":""}
  1. Fetched transaction by hash:
curl 0:5708/unconfirmed_tx?hash=0x4E200DB5AC1DCA60DDC5F3386A6F2DA333AF4A77A12A74C7D00E78FE16F1CD77
{"tx":"urra2g=="}
  1. Double-checked that retrieved tx matches submitted one:
base64 -d <<< 'urra2g==' | xxd -ps
babadada

Breaking Changes

None

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have made corresponding changes to the documentation

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

Summary by CodeRabbit

  • New Features

    • Introduced functionality to directly look up a transaction in the mempool using its hash.
    • Added an RPC endpoint for retrieving an individual unconfirmed transaction by its hash.
    • Enhanced the mock capabilities for testing unconfirmed transaction retrieval.
  • Documentation

    • Updated the API specification and documentation, reflecting service rebranding and new endpoints.
  • Refactor

    • Enhanced the transaction key generation process for improved consistency.

Copy link
Contributor

coderabbitai bot commented Feb 13, 2025

Walkthrough

This pull request introduces functionality for retrieving transactions based on a transaction hash. New methods named GetTxByHash have been added to several mempool-related structures and their mocks. Alongside this, a new RPC endpoint (/unconfirmed_tx) and corresponding client methods are introduced to fetch single unconfirmed transactions. The OpenAPI specification is updated to reflect these changes, and minor modifications were made to transaction key generation in the types package.

Changes

File(s) Change Summary
internal/consensus/replay_stubs.go, internal/mempool/mempool.go, internal/mempool/mocks/mempool.go, internal/mempool/types.go Added GetTxByHash method to emptyMempool, TxMempool, its mock type, and the Mempool interface.
internal/rpc/core/doc.go, internal/rpc/core/mempool.go, internal/rpc/core/routes.go Introduced new /unconfirmed_tx RPC endpoint and added the UnconfirmedTx method in the Environment and RPCService interface.
light/proxy/routes.go, light/rpc/client.go Added UnconfirmedTx method for handling unconfirmed transactions in proxyService and the Light RPC Client.
rpc/client/http/http.go, rpc/client/interface.go, rpc/client/local/local.go, rpc/client/mocks/client.go, rpc/client/mocks/remoteclient.go, rpc/client/rpc_test.go Extended RPC client support by adding UnconfirmedTx methods, updating HexBytes usage to tmbytes.HexBytes, introducing mocks, and adding a new test case.
rpc/coretypes/requests.go, rpc/coretypes/responses.go Introduced new types RequestUnconfirmedTx and ResultUnconfirmedTx for handling unconfirmed transaction requests and responses.
rpc/openapi/openapi.yaml Updated OpenAPI spec with rebranding to "Tenderdash RPC", added /unconfirmed_tx endpoint with response schema, and removed /dump_consensus_state.
types/tx.go Modified the Key method to generate keys using TxKey(tx.Hash()) instead of a direct SHA-256 hash.

Sequence Diagram(s)

sequenceDiagram
    participant C as Client
    participant S as RPC Server
    participant E as Environment
    participant M as Mempool

    C->>S: Send /unconfirmed_tx request with txHash
    S->>E: Invoke UnconfirmedTx(ctx, req)
    E->>M: Call GetTxByHash(txHash)
    M-->>E: Return transaction (or nil)
    E->>S: Respond with ResultUnconfirmedTx or error
    S-->>C: Return response to client
Loading

Suggested labels

S:wip

Suggested reviewers

  • QuantumExplorer
  • shumkov

Poem

I’m a rabbit with code so bright,
Hopping through changes in the night.
New endpoints sprout like springtime blooms,
While transactions dance in digital rooms.
I nibble at keys and hop on the track,
Celebrating each tweak with a joyful clack!


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@lklimek lklimek linked an issue Feb 13, 2025 that may be closed by this pull request
@lklimek lklimek marked this pull request as ready for review February 24, 2025 07:50
@lklimek
Copy link
Collaborator Author

lklimek commented Feb 24, 2025

@coderabbitai review all

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
rpc/coretypes/responses.go (1)

315-318: Consider enriching the response type with additional metadata.

While the current implementation is functional, consider adding useful metadata fields such as:

  • Transaction timestamp
  • Transaction priority
  • Time spent in mempool
  • Transaction size
 type ResultUnconfirmedTx struct {
     Tx types.Tx `json:"tx"`
+    Timestamp time.Time `json:"timestamp"`
+    Priority int64 `json:"priority"`
+    TimeInMempool time.Duration `json:"time_in_mempool"`
+    Size int64 `json:"size"`
 }
internal/rpc/core/mempool.go (1)

200-207: Consider improving error handling.

The error handling could be enhanced for better user experience:

  1. Split validation errors into separate checks for clearer error messages
  2. Use structured errors for better error handling by clients

Consider this refactoring:

-	if req == nil || req.TxHash.IsZero() || len(req.TxHash) != crypto.HashSize {
-		return nil, fmt.Errorf("you must provide a valid %d-byte transaction hash in hash= argument", crypto.HashSize)
+	if req == nil {
+		return nil, errors.New("request cannot be nil")
+	}
+	if req.TxHash.IsZero() {
+		return nil, errors.New("transaction hash cannot be zero")
+	}
+	if len(req.TxHash) != crypto.HashSize {
+		return nil, fmt.Errorf("invalid hash size: got %d bytes, expected %d bytes", len(req.TxHash), crypto.HashSize)
+	}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 414d46d and 3e1326c.

📒 Files selected for processing (19)
  • internal/consensus/replay_stubs.go (1 hunks)
  • internal/mempool/mempool.go (1 hunks)
  • internal/mempool/mocks/mempool.go (1 hunks)
  • internal/mempool/types.go (1 hunks)
  • internal/rpc/core/doc.go (1 hunks)
  • internal/rpc/core/mempool.go (3 hunks)
  • internal/rpc/core/routes.go (2 hunks)
  • light/proxy/routes.go (1 hunks)
  • light/rpc/client.go (1 hunks)
  • rpc/client/http/http.go (6 hunks)
  • rpc/client/interface.go (1 hunks)
  • rpc/client/local/local.go (1 hunks)
  • rpc/client/mocks/client.go (1 hunks)
  • rpc/client/mocks/remoteclient.go (1 hunks)
  • rpc/client/rpc_test.go (1 hunks)
  • rpc/coretypes/requests.go (1 hunks)
  • rpc/coretypes/responses.go (1 hunks)
  • rpc/openapi/openapi.yaml (4 hunks)
  • types/tx.go (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • internal/rpc/core/doc.go
🔇 Additional comments (21)
internal/consensus/replay_stubs.go (1)

42-42: LGTM!

The implementation of GetTxByHash is consistent with the stub nature of the emptyMempool struct, returning nil as expected.

rpc/coretypes/requests.go (1)

83-86: LGTM!

The RequestUnconfirmedTx type is well-defined with appropriate documentation and field type. The JSON tag omitempty is correctly used for optional fields.

rpc/client/interface.go (1)

167-167: LGTM!

The UnconfirmedTx method is well-defined with appropriate parameters and return types, maintaining consistency with other methods in the interface.

rpc/client/local/local.go (1)

108-110: LGTM!

The implementation follows the established pattern of delegating to the environment's corresponding method, with proper parameter passing and error handling.

internal/mempool/mempool.go (1)

263-272: LGTM! Clean and efficient implementation.

The implementation is thread-safe and provides O(1) lookup performance using the existing txByKey map.

light/proxy/routes.go (1)

143-145: LGTM! Consistent with proxy pattern.

The implementation follows the established pattern of delegating calls to the underlying client.

internal/mempool/types.go (1)

43-44: LGTM! Well-documented interface addition.

The interface method is clearly documented and follows the established pattern of the codebase.

light/rpc/client.go (1)

243-245: LGTM!

The implementation follows the established pattern of delegating to the next client, maintaining consistency with other similar methods in the file.

types/tx.go (1)

27-31: LGTM! Good optimization.

The change to use the transaction's hash as the key is a good optimization as it:

  1. Reuses the existing hash computation
  2. Ensures consistent transaction identification across the system
  3. Makes it easier to lookup transactions in the mempool
internal/rpc/core/routes.go (1)

59-59: LGTM!

The new RPC route and interface method are added consistently with the existing patterns in the codebase.

Also applies to: 117-117

internal/rpc/core/mempool.go (1)

198-210: LGTM! Implementation looks solid.

The implementation correctly:

  1. Validates the input request and transaction hash
  2. Uses the mempool's GetTxByHash to retrieve the transaction
  3. Returns appropriate responses for both success and failure cases
rpc/client/rpc_test.go (1)

667-700: LGTM! Well-structured test case.

The test case thoroughly validates the new UnconfirmedTx functionality:

  • Proper test setup with multiple transactions
  • Robust synchronization using channels
  • Timeout handling for transaction processing
  • Verification of transaction retrieval by hash
  • Proper cleanup
rpc/openapi/openapi.yaml (1)

2739-2761: LGTM! Well-defined response schema.

The schema follows JSONRPC standards and properly defines the response structure with base64-encoded transaction data.

internal/mempool/mocks/mempool.go (2)

189-207: LGTM! The mock implementation for GetTxByHash is well-structured.

The implementation follows the standard mockery pattern, with proper error handling and type assertions. The method signature matches the interface requirements.


209-235: LGTM! The mock helper types and methods are properly implemented.

The implementation includes all necessary helper types and methods for setting up test expectations, following the standard mockery pattern consistently.

rpc/client/mocks/client.go (2)

1914-1942: LGTM! The mock implementation for UnconfirmedTx is well-structured.

The implementation follows the standard mockery pattern, with proper error handling and type assertions. The method signature matches the interface requirements.


1944-1971: LGTM! The mock helper types and methods are properly implemented.

The implementation includes all necessary helper types and methods for setting up test expectations, following the standard mockery pattern consistently.

rpc/client/mocks/remoteclient.go (1)

1959-2016: LGTM! The mock implementation follows best practices.

The new UnconfirmedTx mock method and its helper types are well-implemented:

  • Consistent with the established pattern in the file
  • Proper error handling and return value management
  • Helper methods for test expectations
rpc/client/http/http.go (3)

10-10: LGTM! Import change aligns with the codebase.

The change from bytes to tmbytes package is consistent with the PR objectives and maintains uniformity across the codebase.


211-213: LGTM! Type changes maintain consistency.

The change from bytes.HexBytes to tmbytes.HexBytes in method signatures:

  • Maintains consistency across the codebase
  • Properly handles transaction-related byte data

Also applies to: 215-226, 393-399, 421-429, 447-453


270-279: LGTM! UnconfirmedTx implementation follows best practices.

The new UnconfirmedTx method:

  • Follows the established pattern of other RPC methods
  • Properly handles errors
  • Correctly converts txHash to HexBytes

Copy link
Contributor

coderabbitai bot commented Feb 24, 2025

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Fetch the PR diff
gh pr diff 1053

# Search for relevant test files
fd -e go test

Length of output: 34752


@lklimek The changes look well-implemented! I particularly like:

  • Efficient transaction lookup using the existing txByKey map
  • Proper error handling for invalid transaction hashes
  • Comprehensive test coverage including both unit tests and manual testing
  • Clear API documentation updates

A few minor suggestions to consider:

  1. Add a comment explaining why TxKey is now using Hash() instead of sha256.Sum256() in types/tx.go
  2. Consider adding an example in the OpenAPI spec showing the error response when transaction is not found
  3. Consider adding a test case for invalid hash format in rpc/client/rpc_test.go

Let me know if you'd like me to elaborate on any of these points.

✅ Actions performed

Comments resolved.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
rpc/openapi/openapi.yaml (2)

1222-1251: New Endpoint for Retrieving an Unconfirmed Transaction

The new /unconfirmed_tx endpoint is integrated correctly. The query parameter hash is correctly marked as required with a clear example, and the response references the proper schema.

Suggestions:

  • Consider expanding the description to explain that this endpoint returns an unconfirmed transaction from the mempool if it exists, and clarify the expected behavior when no matching transaction is found (e.g. using a 404 status or a more specific error message).

2739-2761: Addition of the UnconfirmedTransactionResponse Schema

The schema for UnconfirmedTransactionResponse is well defined—it extends the standard JSON-RPC structure and specifies a required tx field described as a Base-64 encoded transaction. This clear structure is consistent with the overall design of the API responses.

Suggestions:

  • If in the future the endpoint is expected to provide additional metadata (such as a status flag or timestamp), consider evolving this schema accordingly. For now, its simplicity aligns with the feature’s needs.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3e1326c and 0287b53.

📒 Files selected for processing (1)
  • rpc/openapi/openapi.yaml (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: test_apps
  • GitHub Check: test_abci_cli
  • GitHub Check: tests (02)
  • GitHub Check: tests (01)
  • GitHub Check: e2e-test (rotate)
  • GitHub Check: golangci-lint
  • GitHub Check: e2e-test (dashcore)
  • GitHub Check: Super linter

Copy link
Member

@shumkov shumkov left a comment

Choose a reason for hiding this comment

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

👍

@lklimek lklimek merged commit 8bacade into v1.5-dev Mar 3, 2025
19 checks passed
@lklimek lklimek deleted the feat/filter-tx-hash branch March 3, 2025 08:58
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.

feat(rpc): filter unconfirmed txs by tx hash
2 participants