Skip to content

Fix: child receipt account#2013

Open
Mounil2005 wants to merge 13 commits intohiero-ledger:mainfrom
Mounil2005:fix/child-receipt-account-id
Open

Fix: child receipt account#2013
Mounil2005 wants to merge 13 commits intohiero-ledger:mainfrom
Mounil2005:fix/child-receipt-account-id

Conversation

@Mounil2005
Copy link
Copy Markdown
Contributor

Description:
Fix child transaction receipts not exposing account_id field.

Child receipts were incorrectly initialized with the parent's transaction_id instead of None, preventing proper access to protobuf fields like accountID.

  • Pass None for child/duplicate receipts in _map_receipt_list()
  • Update TransactionReceipt._from_proto() type hint to Optional[TransactionId]
  • Add unit test verifying child receipt account_id accessibility

Related issue(s):
Fixes #1849

Notes for reviewer:

Root cause: Child receipts created with parent transaction_id instead of None

Fix: TransactionReceipt._from_proto(receipt_proto, None)

Testing:
14/14 unit tests pass, including new verification test for child receipt account_id

Checklist

[] Documented (Type hints updated)
[] Tested (14/14 unit tests pass)

@github-actions
Copy link
Copy Markdown

Hi, this is WorkflowBot.
Your pull request cannot be merged as it is not passing all our workflow checks.
Please click on each check to review the logs and resolve issues so all checks pass.
To help you:

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes an issue where child transaction receipts returned by TransactionGetReceiptQuery do not expose expected receipt protobuf fields (e.g., accountID / account_id) when include_children is enabled.

Changes:

  • Map child/duplicate receipt protos via _map_receipt_list() using TransactionReceipt._from_proto(..., None) rather than passing the parent transaction_id.
  • Update TransactionReceipt._from_proto() type hint to accept Optional[TransactionId].
  • Add a unit test asserting child receipt account_id access and transaction_id behavior; add a changelog entry.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
src/hiero_sdk_python/query/transaction_get_receipt_query.py Changes receipt mapping for children/duplicates to pass None as transaction_id.
src/hiero_sdk_python/transaction/transaction_receipt.py Updates _from_proto() signature/docstring to allow transaction_id=None.
tests/unit/get_receipt_query_test.py Adds a unit test for child receipt account_id accessibility.
CHANGELOG.md Documents the intended fix under [Unreleased].

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 22, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Child and duplicate transaction receipt mapping was changed so child receipts are converted from protobuf with a None parent transaction_id, allowing child accountID fields to be populated; TransactionReceipt._from_proto now accepts an optional transaction_id. Unit and E2E tests plus CHANGELOG updated.

Changes

Cohort / File(s) Summary
Receipt query mapping
src/hiero_sdk_python/query/transaction_get_receipt_query.py
Added include_parent_tx_id: bool = False to _map_receipt_list(...). Child receipts are mapped with transaction_id=None; duplicate receipts mapped with the parent transaction_id. Parent receipt mapping unchanged.
Receipt model
src/hiero_sdk_python/transaction/transaction_receipt.py
Updated TransactionReceipt._from_proto signature to accept `transaction_id: TransactionId
Tests (unit & integration)
tests/unit/get_receipt_query_test.py, tests/integration/transaction_get_receipt_query_e2e_test.py
Added unit tests covering child and duplicate receipt accountID mapping and transaction_id behavior; added E2E tests validating child/duplicate receipt transaction_id and account_id population. Restored missing trailing newlines.
Changelog
CHANGELOG.md
Documented fix describing exposure of protobuf receipt fields for child transaction receipts by passing None instead of the parent transaction_id.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Fix: child receipt account' is partially related to the changeset, referring to a key aspect of the change (fixing child receipt account_id) but is vague and incomplete, omitting important context about the root cause and solution approach. Consider a more descriptive title like 'Fix: child transaction receipts not exposing account_id by passing None instead of parent transaction_id' to clearly convey the main change.
✅ Passed checks (4 passed)
Check name Status Explanation
Description check ✅ Passed The description clearly explains the problem (child receipts initialized with parent's transaction_id instead of None), the solution (pass None for child/duplicate receipts, update type hint), and includes testing information. It is well-related to the changeset.
Linked Issues check ✅ Passed The PR successfully addresses the linked issue #1849 by making child receipts properly expose the account_id field through None transaction_id initialization and updated type hints, with comprehensive unit and integration tests validating the fix.
Out of Scope Changes check ✅ Passed All changes directly support the objective of fixing child/duplicate receipt account_id exposure: modified query mapping logic, updated type hints, added unit and integration tests, and updated changelog. No unrelated changes were detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% 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

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
Copy Markdown
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


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 89bf9397-57f5-405e-a6c3-9250dde31e41

📥 Commits

Reviewing files that changed from the base of the PR and between 2898bf9 and 547bbfc.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • src/hiero_sdk_python/query/transaction_get_receipt_query.py
  • src/hiero_sdk_python/transaction/transaction_receipt.py
  • tests/unit/get_receipt_query_test.py

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 22, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #2013      +/-   ##
==========================================
+ Coverage   93.68%   93.71%   +0.02%     
==========================================
  Files         144      144              
  Lines        9350     9351       +1     
==========================================
+ Hits         8760     8763       +3     
+ Misses        590      588       -2     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Mounil2005 Mounil2005 marked this pull request as ready for review March 22, 2026 10:56
Copy link
Copy Markdown
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

♻️ Duplicate comments (1)
tests/unit/get_receipt_query_test.py (1)

517-517: 🧹 Nitpick | 🔵 Trivial

Add a matching duplicate-receipt regression test for the same mapping path.

_map_receipt_list() is used for both children and duplicates, but the new tests only harden children. Add the same account_id assertion for include_duplicates=True to prevent branch-specific regressions and ensure duplicate receipts retain the parent's transaction_id.

✅ Suggested additional test
+
+
+def test_duplicate_receipts_with_account_id(transaction_id):
+    """Test that duplicate receipts have accountID populated and retain parent transaction_id."""
+    duplicate_account_id = basic_types_pb2.AccountID(shardNum=0, realmNum=0, accountNum=888)
+
+    response = response_pb2.Response(
+        transactionGetReceipt=transaction_get_receipt_pb2.TransactionGetReceiptResponse(
+            header=response_header_pb2.ResponseHeader(
+                nodeTransactionPrecheckCode=ResponseCode.OK
+            ),
+            receipt=transaction_receipt_pb2.TransactionReceipt(status=ResponseCode.SUCCESS),
+            duplicateTransactionReceipts=[
+                transaction_receipt_pb2.TransactionReceipt(
+                    status=ResponseCode.SUCCESS,
+                    accountID=duplicate_account_id,
+                ),
+            ],
+        )
+    )
+
+    response_sequences = [[response]]
+
+    with mock_hedera_servers(response_sequences) as client:
+        result = (
+            TransactionGetReceiptQuery()
+            .set_transaction_id(transaction_id)
+            .set_include_duplicates(True)
+            .execute(client)
+        )
+
+        assert len(result.duplicates) == 1
+        duplicate_receipt = result.duplicates[0]
+        assert duplicate_receipt.account_id is not None
+        assert duplicate_receipt.account_id.num == 888
+        # Duplicates retain parent transaction_id (different from child receipts)
+        assert duplicate_receipt.transaction_id == transaction_id

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: c1e3c61d-2c88-4d4b-bad7-c79998414ef6

📥 Commits

Reviewing files that changed from the base of the PR and between 547bbfc and a4f0b98.

📒 Files selected for processing (3)
  • src/hiero_sdk_python/query/transaction_get_receipt_query.py
  • src/hiero_sdk_python/transaction/transaction_receipt.py
  • tests/unit/get_receipt_query_test.py

Copy link
Copy Markdown
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

♻️ Duplicate comments (1)
tests/unit/get_receipt_query_test.py (1)

466-471: ⚠️ Potential issue | 🟡 Minor

Strengthen child-receipt regression by asserting transaction_id is None.

Both child-receipt tests validate account_id, but neither verifies the mapping behavior that prevents parent ID inheritance. Add an explicit transaction_id is None assertion (and optionally hasattr) in both tests.

Suggested test hardening
         assert len(result.children) == 1
         child_receipt = result.children[0]
         
         # Verify: child receipt has account_id accessible
+        assert hasattr(child_receipt, "account_id")
         assert child_receipt.account_id is not None
         assert child_receipt.account_id.num == 999
+        assert child_receipt.transaction_id is None
@@
         assert len(result.children) == 1
         child_receipt = result.children[0]
         
         # Verify: account_id is accessible even with accountNum=0
+        assert hasattr(child_receipt, "account_id")
         assert child_receipt.account_id is not None
         assert child_receipt.account_id.num == 0
         assert child_receipt.account_id.shard == 0
         assert child_receipt.account_id.realm == 0
+        assert child_receipt.transaction_id is None

As per coding guidelines "Assert public attributes exist (e.g., assert hasattr(obj, 'account_id'))." and "Unit tests should be extensive - test even if we don't expect users to use it currently."

Also applies to: 510-517


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: c03cbac2-49b3-49a4-b723-d62b2e85dcac

📥 Commits

Reviewing files that changed from the base of the PR and between a4f0b98 and 6c0f800.

📒 Files selected for processing (1)
  • tests/unit/get_receipt_query_test.py

@Mounil2005 Mounil2005 changed the title Fix/child receipt account Fix: child receipt account Mar 22, 2026
@Mounil2005 Mounil2005 force-pushed the fix/child-receipt-account-id branch from 132b7f5 to 87703e2 Compare March 22, 2026 11:31
@exploreriii exploreriii added status: needs triage review PR needs a review from the triage team status: needs committer review PR needs a review from the committer team labels Mar 22, 2026
Copy link
Copy Markdown
Member

@AntonioCeppellini AntonioCeppellini left a comment

Choose a reason for hiding this comment

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

Hi @Mounil2005 great work so far!
Do you think we should update also integration tests about it?

@Mounil2005 Mounil2005 force-pushed the fix/child-receipt-account-id branch from 01649c3 to cbcb40a Compare March 24, 2026 04:18
Copy link
Copy Markdown
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: 5


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4b1788cd-9ca2-46ee-9743-3bff614b0954

📥 Commits

Reviewing files that changed from the base of the PR and between 87703e2 and 01649c3.

📒 Files selected for processing (2)
  • test_collection.txt
  • tests/integration/transaction_get_receipt_query_e2e_test.py

@Mounil2005 Mounil2005 marked this pull request as draft March 24, 2026 04:19
@Mounil2005 Mounil2005 force-pushed the fix/child-receipt-account-id branch from c300294 to 7fff39c Compare March 24, 2026 04:30
@exploreriii exploreriii marked this pull request as ready for review March 24, 2026 11:47
@Mounil2005 Mounil2005 force-pushed the fix/child-receipt-account-id branch from cabf5d7 to 32135db Compare March 24, 2026 14:20
Copy link
Copy Markdown
Member

@cheese-cakee cheese-cakee left a comment

Choose a reason for hiding this comment

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

The fix looks good , child receipts getting None instead of the parent's transaction_id makes sense, and the tests cover it well.

One thing that stood out: the account_id property behavior changed. It now returns an AccountId(shard=0, realm=0, num=0) instead of None when accountNum == 0. The other ID properties in the same file still check for != 0, so this feels inconsistent. Is that intentional for the EVM use case?

Also, might be worth adding a quick test for the case where accountID isn't set in the protobuf at all, just to document that it returns None.
Otherwise LGTM.

cheese-cakee

This comment was marked as duplicate.

@github-actions
Copy link
Copy Markdown

Hello, this is the OfficeHourBot.

This is a reminder that the Hiero Python SDK Office Hours are scheduled in approximately 4 hours (14:00 UTC).

This session provides an opportunity to ask questions regarding this Pull Request.

Details:

Disclaimer: This is an automated reminder. Please verify the schedule here for any changes.

From,
The Python SDK Team

manishdait
manishdait previously approved these changes Mar 25, 2026
@manishdait manishdait self-requested a review March 26, 2026 14:28
@manishdait manishdait dismissed their stale review March 26, 2026 16:08

dismiss

@Mounil2005 Mounil2005 force-pushed the fix/child-receipt-account-id branch from 32135db to 5eda8b0 Compare March 27, 2026 07:48
@Mounil2005 Mounil2005 force-pushed the fix/child-receipt-account-id branch from f2df543 to cbf5d3e Compare March 30, 2026 04:17
@Mounil2005
Copy link
Copy Markdown
Contributor Author

Mounil2005 commented Mar 30, 2026

Great catch on the inconsistency @cheese-cakee ! You're absolutely right that account_id differs from token_id, file_id, contract_id, etc. by returning even when num=0.
This is intentional for EVM auto-account creation scenarios. When a user transfers to an EVM address, the network returns a child receipt with AccountID(shard=0, realm=0, accountNum=0). In Hedera's EVM model, this (0,0,0) + the EVM address represents the pending auto-created account before full initialization on-chain.

The semantic difference matters:

  • Other IDs: num=0 means "no resource" → return None makes sense
  • AccountID: num=0 with protobuf field set means "auto-account pending" → return AccountId(0,0,0) is meaningful
    I've updated the docstring to make this distinction explicit and added test_account_id_returns_none_when_not_set() to document the edge case: when accountID isn't set in the protobuf at all (vs. explicitly set with num=0, it correctly returns None.

Signed-off-by: Mounil Kanakhara <mounilkankhara@gmail.com>
Signed-off-by: Mounil Kanakhara <mounilkankhara@gmail.com>
Signed-off-by: Mounil Kanakhara <mounilkankhara@gmail.com>
Signed-off-by: Mounil Kanakhara <mounilkankhara@gmail.com>
Signed-off-by: Mounil Kanakhara <mounilkankhara@gmail.com>
Signed-off-by: Mounil Kanakhara <mounilkankhara@gmail.com>
Signed-off-by: Mounil Kanakhara <mounilkankhara@gmail.com>
… fixes

Signed-off-by: Mounil Kanakhara <mounilkankhara@gmail.com>
Signed-off-by: Mounil Kanakhara <mounilkankhara@gmail.com>
Signed-off-by: Mounil Kanakhara <mounilkankhara@gmail.com>
Signed-off-by: Mounil Kanakhara <mounilkankhara@gmail.com>
Signed-off-by: Mounil Kanakhara <mounilkankhara@gmail.com>
Signed-off-by: Mounil Kanakhara <mounilkankhara@gmail.com>
@Mounil2005 Mounil2005 force-pushed the fix/child-receipt-account-id branch from 812d9c7 to aeb33d4 Compare March 30, 2026 04:46
@exploreriii exploreriii requested a review from Adityarya11 April 1, 2026 21:02
Copy link
Copy Markdown
Contributor

@Adityarya11 Adityarya11 left a comment

Choose a reason for hiding this comment

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

A minor suggestion, i have provided though they are completely fine.
This LGTM @exploreriii

Approved!!


@classmethod
def _from_proto(cls, proto: transaction_receipt_pb2.TransactionReceipt, transaction_id: TransactionId) -> "TransactionReceipt":
def _from_proto(cls, proto: transaction_receipt_pb2.TransactionReceipt, transaction_id: TransactionId | None) -> "TransactionReceipt":
Copy link
Copy Markdown
Contributor

@Adityarya11 Adityarya11 Apr 2, 2026

Choose a reason for hiding this comment

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

**non-blocking Issue:** a minor note, the PR description mentions using Optional[TransactionId] but the code uses TransactionId | None. Since we run on Python 3.10+ this is perfectly valid and safe, just pointing it out as a small stylistic difference compared to older files.

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

Labels

status: needs committer review PR needs a review from the committer team status: needs triage review PR needs a review from the triage team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: AccountId not found in child transaction

7 participants