Skip to content

feat: transaction record query include duplicates#1671

Open
gangulysiddhartha22-cmyk wants to merge 19 commits intohiero-ledger:mainfrom
gangulysiddhartha22-cmyk:feature/1635-transaction-record-query-include-duplicates-1
Open

feat: transaction record query include duplicates#1671
gangulysiddhartha22-cmyk wants to merge 19 commits intohiero-ledger:mainfrom
gangulysiddhartha22-cmyk:feature/1635-transaction-record-query-include-duplicates-1

Conversation

@gangulysiddhartha22-cmyk
Copy link
Contributor

Description:

Add support for the includeDuplicates flag

Related issue(s):

Fixes #1635

Notes for reviewer:

-No breaking changes
-Unit/Integration tests added

Checklist

  • Documented (Code comments, README, etc.)
  • Tested (unit, integration, etc.)

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 1, 2026

Warning

Rate limit exceeded

@gangulysiddhartha22-cmyk has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 12 minutes and 58 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Walkthrough

Adds include_duplicates support to TransactionRecordQuery (requesting and mapping duplicate records) and a public duplicates list to TransactionRecord; updates mapping/execution logic, tests, an example, and CHANGELOG entries. (22 words)

Changes

Cohort / File(s) Summary
Query implementation
src/hiero_sdk_python/query/transaction_record_query.py
Add include_duplicates: bool ctor arg and public attribute; set_include_duplicates(bool) with validation and chaining; allow Optional[TransactionId] in set_transaction_id; add _map_record_list() to convert protobuf records; set includeDuplicates on the TransactionGetRecordQuery proto in _make_request; update execute() to map and attach duplicates; minor signature change for _map_status_error.
Transaction record model
src/hiero_sdk_python/transaction/transaction_record.py
Add public duplicates: list['TransactionRecord'] (default empty list); change _from_proto(..., *, duplicates=None) to accept duplicates; add static helpers for transaction_id resolution and parsing (token/HBAR transfers, pending airdrops, contract call result); ensure _to_proto does not serialize duplicates; include duplicates_count in __repr__.
Unit tests
tests/unit/transaction_record_query_test.py, tests/unit/transaction_record_test.py
Add/expand tests validating include_duplicates chaining/validation, _make_request proto construction (includeDuplicates flag and missing transaction_id), _map_record_list behavior, and TransactionRecord duplicates storage/representation/round-trip behavior and error paths.
Integration tests
tests/integration/transaction_record_query_e2e_test.py
Add flaky-gated test_query_with_include_duplicates() that submits the same AccountCreateTransaction multiple times and queries with include_duplicates=True to assert duplicates are returned.
Examples
examples/query/transaction_record_query_with_duplicates.py
New example demonstrating submitting duplicate transactions, querying with include_duplicates=True, and printing primary record + duplicates; includes helper functions and a main wrapper.
Changelog
CHANGELOG.md
Document addition of includeDuplicates flag to TransactionRecordQuery and duplicates field on TransactionRecord.

Sequence Diagram

sequenceDiagram
    participant Client as Client
    participant Query as TransactionRecordQuery
    participant Service as TransactionGetRecordService
    participant Mapper as _map_record_list
    participant Record as TransactionRecord

    Client->>Query: set_transaction_id(tx_id)
    Client->>Query: set_include_duplicates(true)
    Client->>Query: execute(client)
    Query->>Service: send TransactionGetRecord (includeDuplicates=true)
    Service-->>Query: response (transactionRecord + duplicateTransactionRecords)
    Query->>Mapper: _map_record_list(proto_duplicate_records)
    Mapper->>Record: TransactionRecord._from_proto(proto_dup, tx_id)
    Record-->>Mapper: duplicate TransactionRecord
    Mapper-->>Query: list of duplicates
    Query->>Record: TransactionRecord._from_proto(primary_proto, tx_id, duplicates=list)
    Record-->>Query: primary TransactionRecord (with duplicates)
    Query-->>Client: return TransactionRecord
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: transaction record query include duplicates' directly and clearly summarizes the main change: adding support for the include_duplicates feature to TransactionRecordQuery.
Description check ✅ Passed The PR description is related to the changeset, mentioning support for includeDuplicates flag, referencing issue #1635, and confirming tests and documentation are included.
Linked Issues check ✅ Passed The PR successfully implements all core requirements from issue #1635: include_duplicates field in TransactionRecordQuery with setter, duplicates list in TransactionRecord, _map_record_list helper, _make_request protobuf update, execute flow with duplicate mapping, and comprehensive unit/integration tests.
Out of Scope Changes check ✅ Passed All changes are in-scope and aligned with issue #1635: query class enhancements, record class updates, helper methods, test additions, example file, and CHANGELOG entry are all directly required or supportive of the include_duplicates feature.
Docstring Coverage ✅ Passed Docstring coverage is 87.93% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

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

Signed-off-by: Siddhartha Ganguly <gangulysiddhartha22@gmail.com>
@gangulysiddhartha22-cmyk gangulysiddhartha22-cmyk force-pushed the feature/1635-transaction-record-query-include-duplicates-1 branch from 792dbc0 to e9a1bdb Compare February 1, 2026 08:32
@manishdait
Copy link
Contributor

Hi @gangulysiddhartha22-cmyk, Thanks for PR, add an entry in CHANGELOG.md

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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/unit/transaction_record_query_test.py (1)

89-124: 🧹 Nitpick | 🔵 Trivial

Consider adding unit test for execute with include_duplicates=True.

The existing test_transaction_record_query_execute tests the basic flow, but there's no unit-level test verifying:

  1. The duplicates attribute exists on the returned TransactionRecord
  2. The behavior when include_duplicates=True and duplicate records are returned

Per PRIORITY 1 guidelines, tests should assert public attributes exist to protect against breaking changes.

♻️ Suggested test addition
def test_transaction_record_query_execute_with_duplicates(transaction_id):
    """Test TransactionRecordQuery with include_duplicates=True returns duplicates."""
    receipt = transaction_receipt_pb2.TransactionReceipt(status=ResponseCode.SUCCESS)
    
    main_record = transaction_record_pb2.TransactionRecord(
        receipt=receipt,
        transactionID=transaction_id._to_proto(),
        memo="Main record",
    )
    
    duplicate_record = transaction_record_pb2.TransactionRecord(
        receipt=receipt,
        transactionID=transaction_id._to_proto(),
        memo="Duplicate record",
    )
    
    response_sequences = [[
        # Cost query response
        response_pb2.Response(
            transactionGetRecord=transaction_get_record_pb2.TransactionGetRecordResponse(
                header=response_header_pb2.ResponseHeader(
                    nodeTransactionPrecheckCode=ResponseCode.OK,
                    responseType=ResponseType.COST_ANSWER,
                    cost=2
                )
            )
        ),
        # Actual query response with duplicates
        response_pb2.Response(
            transactionGetRecord=transaction_get_record_pb2.TransactionGetRecordResponse(
                header=response_header_pb2.ResponseHeader(
                    nodeTransactionPrecheckCode=ResponseCode.OK,
                    responseType=ResponseType.ANSWER_ONLY,
                ),
                transactionRecord=main_record,
                duplicateTransactionRecords=[duplicate_record],
            )
        )
    ]]
    
    with mock_hedera_servers(response_sequences) as client:
        query = TransactionRecordQuery(transaction_id).set_include_duplicates(True)
        result = query.execute(client)
        
        # Assert duplicates attribute exists (PRIORITY 1)
        assert hasattr(result, 'duplicates'), "TransactionRecord should have 'duplicates' attribute"
        assert isinstance(result.duplicates, list)

Based on learnings: "Assert public attributes exist (e.g., assert hasattr(obj, 'account_id'))."

@gangulysiddhartha22-cmyk gangulysiddhartha22-cmyk force-pushed the feature/1635-transaction-record-query-include-duplicates-1 branch from 22dd578 to 2b22818 Compare February 1, 2026 10:45
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/unit/transaction_record_query_test.py (1)

89-155: 🛠️ Refactor suggestion | 🟠 Major

Consider adding a test for execute() with duplicate records.

The existing test_transaction_record_query_execute tests the basic flow but doesn't cover the new include_duplicates functionality. Per PRIORITY 3 (comprehensive coverage), consider adding a test that:

  1. Sets include_duplicates=True
  2. Provides a response with duplicateTransactionRecords
  3. Verifies the returned TransactionRecord.duplicates list is populated
♻️ Suggested test addition
def test_transaction_record_query_execute_with_duplicates(transaction_id):
    """Test TransactionRecordQuery returns duplicates when include_duplicates=True."""
    receipt = transaction_receipt_pb2.TransactionReceipt(status=ResponseCode.SUCCESS)
    
    primary_record = transaction_record_pb2.TransactionRecord(
        receipt=receipt,
        memo="primary",
        transactionFee=100000
    )
    
    duplicate_record = transaction_record_pb2.TransactionRecord(
        receipt=receipt,
        memo="duplicate",
        transactionFee=100000
    )

    response_sequences = [[
        # Cost query responses...
        response_pb2.Response(
            transactionGetRecord=transaction_get_record_pb2.TransactionGetRecordResponse(
                header=response_header_pb2.ResponseHeader(
                    nodeTransactionPrecheckCode=ResponseCode.OK,
                    responseType=ResponseType.COST_ANSWER,
                    cost=2
                )
            )
        ),
        response_pb2.Response(
            transactionGetRecord=transaction_get_record_pb2.TransactionGetRecordResponse(
                header=response_header_pb2.ResponseHeader(
                    nodeTransactionPrecheckCode=ResponseCode.OK,
                    responseType=ResponseType.COST_ANSWER,
                    cost=2
                )
            )
        ),
        response_pb2.Response(
            transactionGetRecord=transaction_get_record_pb2.TransactionGetRecordResponse(
                header=response_header_pb2.ResponseHeader(
                    nodeTransactionPrecheckCode=ResponseCode.OK,
                    responseType=ResponseType.ANSWER_ONLY,
                ),
                transactionRecord=primary_record,
                duplicateTransactionRecords=[duplicate_record]
            )
        )
    ]]
    
    with mock_hedera_servers(response_sequences) as client:
        query = TransactionRecordQuery(transaction_id, include_duplicates=True)
        result = query.execute(client)
        
        assert result.transaction_memo == "primary"
        assert hasattr(result, 'duplicates'), "duplicates attribute must exist"
        assert len(result.duplicates) == 1
        assert result.duplicates[0].transaction_memo == "duplicate"

Signed-off-by: Siddhartha Ganguly <gangulysiddhartha22@gmail.com>
@gangulysiddhartha22-cmyk gangulysiddhartha22-cmyk force-pushed the feature/1635-transaction-record-query-include-duplicates-1 branch from 2b22818 to fb9e91f Compare February 1, 2026 11:09
@gangulysiddhartha22-cmyk
Copy link
Contributor Author

@AntonioCeppellini ⚠️ Should I run Black on all the Python files touched in a PR to apply formatting?

@AntonioCeppellini
Copy link
Member

@AntonioCeppellini ⚠️ Should I run Black on all the Python files touched in a PR to apply formatting?

Hi @gangulysiddhartha22-cmyk this could be out of scope right now but i recommend to follow black formatting in the code you write :D.
@manishdait @aceppaluni what do you think?

@manishdait
Copy link
Contributor

Makes sense to me applying Black formatting only to the files changed in the PR sounds like a good approach

Copy link
Contributor

@exploreriii exploreriii left a comment

Choose a reason for hiding this comment

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

Hi @gangulysiddhartha22-cmyk
This is excellent!
Can you add an example please?

@exploreriii exploreriii marked this pull request as draft February 1, 2026 20:32
Copy link
Contributor

@aceppaluni aceppaluni left a comment

Choose a reason for hiding this comment

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

@gangulysiddhartha22-cmyk This is great work, thank you for your contribution!!

Please only run Black on files changed in this PR, thank you.

Once suggested changes are implemented happy to re-review.

Thank you and happy contributing!!

@gangulysiddhartha22-cmyk
Copy link
Contributor Author

@manishdait @exploreriii @AntonioCeppellini @aceppaluni
Quick ping on the failing test test_transaction_record_query_execute_with_duplicates — even after adding transactionID + transactionHash to the mock records, the primary memo still comes back empty in result.
Suspect the issue might be inside mock_hedera_servers — possibly losing partial protobuf fields during serialization/deserialization or response handling when include_duplicates=True.
Would like to know how mock_hedera_servers handles TransactionGetRecordResponse objects? Should we try forcing a SerializeToString → ParseFromString round-trip on the mock protos before injecting them into response_sequences?
Thanks!

…e-duplicates-1

Signed-off-by: Siddhartha Ganguly <gangulysiddhartha22@gmail.com>
@gangulysiddhartha22-cmyk gangulysiddhartha22-cmyk force-pushed the feature/1635-transaction-record-query-include-duplicates-1 branch from 2f8c6c1 to 3e7ce3a Compare February 2, 2026 12:52
@gangulysiddhartha22-cmyk gangulysiddhartha22-cmyk force-pushed the feature/1635-transaction-record-query-include-duplicates-1 branch from 8c5d8a4 to 0db3f82 Compare February 2, 2026 13:09
@gangulysiddhartha22-cmyk gangulysiddhartha22-cmyk marked this pull request as ready for review February 2, 2026 13:10
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

@gangulysiddhartha22-cmyk gangulysiddhartha22-cmyk force-pushed the feature/1635-transaction-record-query-include-duplicates-1 branch from 0db3f82 to 4646c4d Compare February 2, 2026 14:41
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

@gangulysiddhartha22-cmyk gangulysiddhartha22-cmyk force-pushed the feature/1635-transaction-record-query-include-duplicates-1 branch from 4646c4d to 45c9ed5 Compare February 2, 2026 14:51
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: 2

@gangulysiddhartha22-cmyk gangulysiddhartha22-cmyk force-pushed the feature/1635-transaction-record-query-include-duplicates-1 branch from 45c9ed5 to 2363b5d Compare February 2, 2026 15:08
…e-duplicates-1

Signed-off-by: Siddhartha Ganguly <gangulysiddhartha22@gmail.com>
… example

Signed-off-by: Siddhartha Ganguly <gangulysiddhartha22@gmail.com>
@gangulysiddhartha22-cmyk gangulysiddhartha22-cmyk force-pushed the feature/1635-transaction-record-query-include-duplicates-1 branch from 7900857 to bc8fe96 Compare February 7, 2026 07:28
@exploreriii exploreriii added status: needs committer review PR needs a review from the committer team and removed status: needs developer revision PR has requested changes that the developer needs to implement labels Feb 7, 2026
@exploreriii
Copy link
Contributor

Hi @gangulysiddhartha22-cmyk please click to resolve the conversations if you are able 👍

@gangulysiddhartha22-cmyk
Copy link
Contributor Author

@exploreriii I've resolved all the conversations on my end. Let me know if there's anything left. Thanks!

Copy link
Contributor

@exploreriii exploreriii left a comment

Choose a reason for hiding this comment

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

While we wait for @hiero-ledger/hiero-sdk-python-committers or @hiero-ledger/hiero-sdk-python-maintainers, could you please double check your code coverage meets our threshold requirement 👍

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: 4

@gangulysiddhartha22-cmyk gangulysiddhartha22-cmyk force-pushed the feature/1635-transaction-record-query-include-duplicates-1 branch 2 times, most recently from 977cc97 to 7e00d6f Compare February 7, 2026 17:51
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/unit/transaction_record_query_test.py (1)

29-35: 🛠️ Refactor suggestion | 🟠 Major

Use identity check (is) for fluent setter assertion.

Line 35 uses == to verify chaining, but fluent setter tests should use is to confirm the exact same instance is returned, consistent with the pattern used at Line 47 for set_include_duplicates.

Proposed fix
-    assert result == query  # Should return self for chaining
+    assert result is query  # Should return self for chaining

As per coding guidelines, "Assert fluent setters return self (e.g., assert tx.set_memo("test") is tx)."

@gangulysiddhartha22-cmyk gangulysiddhartha22-cmyk force-pushed the feature/1635-transaction-record-query-include-duplicates-1 branch from 7e00d6f to b8ed7b0 Compare February 7, 2026 18:08
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: 2

@gangulysiddhartha22-cmyk gangulysiddhartha22-cmyk force-pushed the feature/1635-transaction-record-query-include-duplicates-1 branch from b8ed7b0 to 17af695 Compare February 7, 2026 18:32
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

Signed-off-by: Siddhartha Ganguly <gangulysiddhartha22@gmail.com>
@gangulysiddhartha22-cmyk gangulysiddhartha22-cmyk force-pushed the feature/1635-transaction-record-query-include-duplicates-1 branch from 17af695 to 6af8f83 Compare February 7, 2026 18:37
@gangulysiddhartha22-cmyk
Copy link
Contributor Author

@exploreriii I've added those extra unit tests for all type checks (invalid bool/transaction_id cases).
Coverage should now be addressed.

Ready for review

Copy link
Contributor

@exploreriii exploreriii left a comment

Choose a reason for hiding this comment

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

Hi @gangulysiddhartha22-cmyk
Note your unit tests are not passing, there is a bug somewhere in this PR will let you know if I find it

@exploreriii exploreriii added status: needs developer revision PR has requested changes that the developer needs to implement and removed status: needs committer review PR needs a review from the committer team labels Feb 7, 2026
@exploreriii exploreriii marked this pull request as draft February 7, 2026 20:45
@gangulysiddhartha22-cmyk gangulysiddhartha22-cmyk force-pushed the feature/1635-transaction-record-query-include-duplicates-1 branch from 6977cf3 to 98bb924 Compare February 8, 2026 07:51
@gangulysiddhartha22-cmyk gangulysiddhartha22-cmyk marked this pull request as ready for review February 8, 2026 08:11
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

@gangulysiddhartha22-cmyk gangulysiddhartha22-cmyk force-pushed the feature/1635-transaction-record-query-include-duplicates-1 branch from 98bb924 to b2f3c7f Compare February 8, 2026 08:18
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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/hiero_sdk_python/query/transaction_record_query.py (1)

145-160: ⚠️ Potential issue | 🟡 Minor

Docstring refers to "transaction receipt query" — should say "transaction record query".

Lines 147 and 150 describe this as "the transaction receipt query" and "getting transaction receipts", but this is TransactionRecordQuery, which retrieves transaction records (not receipts). This mismatch is misleading and could confuse maintainers.

📝 Proposed fix
     def _get_method(self, channel: _Channel) -> _Method:
         """
-        Returns the appropriate gRPC method for the transaction receipt query.
+        Returns the appropriate gRPC method for the transaction record query.
 
         Implements the abstract method from Query to provide the specific
-        gRPC method for getting transaction receipts.
+        gRPC method for getting transaction records.
 
         Args:
             channel (_Channel): The channel containing service stubs

…e-duplicates-1

Signed-off-by: Siddhartha Ganguly <gangulysiddhartha22@gmail.com>
@gangulysiddhartha22-cmyk gangulysiddhartha22-cmyk force-pushed the feature/1635-transaction-record-query-include-duplicates-1 branch from b2f3c7f to 51d94e0 Compare February 8, 2026 08:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: needs developer revision PR has requested changes that the developer needs to implement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for include_duplicates to the TransactionRecordQuery class

6 participants