Skip to content

fix(jsonrpc): enforce maxBlockRange on eth_getFilterLogs#15

Open
0xbigapple wants to merge 2 commits into
release_v4.8.2from
fix/getfilterlogs-block-range-bypass
Open

fix(jsonrpc): enforce maxBlockRange on eth_getFilterLogs#15
0xbigapple wants to merge 2 commits into
release_v4.8.2from
fix/getfilterlogs-block-range-bypass

Conversation

@0xbigapple

@0xbigapple 0xbigapple commented Jun 15, 2026

Copy link
Copy Markdown
Owner

What does this PR do?

Applies the jsonRpcMaxBlockRange cap to eth_getFilterLogs, closing a gap where
the block-range limit could be bypassed via the filter path.

eth_getLogs builds its LogFilterWrapper with checkBlockRange=true, so the cap
is enforced. But eth_newFilter builds the wrapper with checkBlockRange=false, and
eth_getFilterLogs reuses that stored wrapper without re-checking — so the cap was
never applied when querying logs through a filter. A client could create a filter
with a wide range (e.g. fromBlock=0x0, toBlock far ahead) and call
eth_getFilterLogs to trigger an unbounded historical scan (CPU/IO pressure,
potential OOM).

Changes:

  • Extract the range check from the LogFilterWrapper constructor into a reusable
    validateBlockRange(currentMaxBlockNum) method (logic and error message unchanged).
  • eth_getFilterLogs now calls validateBlockRange against the current head
    before scanning, mirroring eth_getLogs.
  • Declare JsonRpcInvalidParamsException on the getFilterLogs impl (the interface
    and its @JsonRpcError(code=-32602) mapping already declared it).

Creation-time behavior is intentionally left unchanged: eth_newFilter still accepts
wide ranges (no creation-time gate), matching geth's "creation accepts, query
enforces" model and preserving forward polling via eth_getFilterChanges (which does
not scan a range).

Why are these changes required?

Without this, jsonRpcMaxBlockRange only protects eth_getLogs; the eth_newFilter

  • eth_getFilterLogs path silently bypasses it, leaving a DoS vector on full nodes
    with JSON-RPC enabled.

This PR has been tested by:

  • Unit Tests
  • Manual Testing

Follow up

Extra details

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR introduces two related safeguards for JSON-RPC queries on forked or orphaned chains: (1) block range validation at query time in eth_getFilterLogs, and (2) orphaned-block detection in receipts and block queries by comparing by-hash block IDs against by-height canonical block IDs. LogFilterWrapper extracts its inline validation into a reusable public method, and TronJsonRpcImpl, BlockResult, and Wallet are updated to check whether a by-hash block is on the main chain before serving receipts or computed results.

Changes

Block range re-validation on eth_getFilterLogs

Layer / File(s) Summary
validateBlockRange extraction and getFilterLogs wiring
framework/src/main/java/org/tron/core/services/jsonrpc/filters/LogFilterWrapper.java, framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java
LogFilterWrapper constructor now assigns fromBlock/toBlock before the optional check and delegates to the new public validateBlockRange(long currentMaxBlockNum) method, which reads Args.getInstance().getJsonRpcMaxBlockRange() and throws JsonRpcInvalidParamsException when the effective range exceeds the limit. getFilterLogs adds JsonRpcInvalidParamsException to its throws clause and calls validateBlockRange(currentMaxBlockNum) before log matching to enforce the cap against the current chain head.
Test: getFilterLogs block range enforcement
framework/src/test/java/org/tron/core/jsonrpc/JsonrpcServiceTest.java
testGetFilterLogsEnforcesBlockRange sets jsonRpcMaxBlockRange to 5000, creates a wide-span filter, asserts getFilterLogs throws JsonRpcInvalidParamsException with message exceed max block range: 5000, then confirms a head-to-head in-range filter returns the expected LogFilterElement count; restores the original cap in finally.

Orphaned block detection in receipts and block queries

Layer / File(s) Summary
Wallet helper for by-height block ID lookup
framework/src/main/java/org/tron/core/Wallet.java
New public getBlockIdByNum(long blockNum) delegates to chainBaseManager and returns null when ItemNotFoundException is thrown, enabling null-safe block ID comparison by height.
getBlockReceipts main-chain block ID verification
framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java
getBlockReceipts now compares the resolved-by-hash block ID against wallet.getBlockIdByNum(blockNum) and returns null if they differ, preventing orphaned-by-height blocks from serving receipts by their stale hash.
BlockResult conditional receipt loading for canonical blocks
framework/src/main/java/org/tron/core/services/jsonrpc/types/BlockResult.java
BlockResult constructor initializes transactionInfoList as empty and populates it only when blockCapsule.getBlockId() matches wallet.getBlockIdByNum(blockCapsule.getNum()), preventing orphaned-by-height receipts from being used when fullTx or gasUsedInBlock is computed.
Tests: fork and orphaned block handling
framework/src/test/java/org/tron/core/jsonrpc/JsonrpcServiceTest.java
testGetBlockReceiptsByForkedHash constructs canonical and stale blocks at the same height, asserts getBlockReceipts returns null for the stale hash and receipts with matching hashes for the canonical hash. testEthGetBlockByForkedHashGasUsed verifies ethGetBlockByHash reports gasUsed as 0x0 for the orphaned hash instead of the canonical branch value.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 The chain diverges, blocks fork wide,
But now we know which fork's the guide!
By height we check, by hash we test,
Orphaned blocks fail the canonical quest.
Filter caps enforced at query's door,
This bunny's hop is secure once more! 🌿

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title focuses on one aspect (enforcing maxBlockRange on eth_getFilterLogs) but the PR addresses two independent fixes: enforcing block range limits and fixing orphaned block receipt handling.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/getfilterlogs-block-range-bypass

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No issues found across 3 files

Re-trigger cubic

@0xbigapple

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@0xbigapple 0xbigapple changed the title fix(jsonrpc): enforce maxBlockRange on eth_getFilterLogs fix(jsonrpc): enforce maxBlockRange on eth_getFilterLogs and fix reorg receipt consistency Jun 15, 2026
@0xbigapple

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@0xbigapple 0xbigapple changed the title fix(jsonrpc): enforce maxBlockRange on eth_getFilterLogs and fix reorg receipt consistency fix(jsonrpc): enforce maxBlockRange and fix reorg receipt consistency Jun 16, 2026
@0xbigapple 0xbigapple force-pushed the fix/getfilterlogs-block-range-bypass branch from 7091ccd to 8b92075 Compare June 17, 2026 05:36
@0xbigapple 0xbigapple changed the title fix(jsonrpc): enforce maxBlockRange and fix reorg receipt consistency fix(jsonrpc): enforce maxBlockRange on eth_getFilterLogs Jun 17, 2026
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.

1 participant