Skip to content

Commit f154a13

Browse files
feat: add set_node_account_ids to the query chain (hiero-ledger#1727)
Signed-off-by: Antonio Ceppellini <antonio.ceppellini@gmail.com> Signed-off-by: AntonioCeppellini <128388022+AntonioCeppellini@users.noreply.github.com>
1 parent d953734 commit f154a13

3 files changed

Lines changed: 92 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
152152
- Added `/working` command to reset the inactivity timer on issues and PRs. ([#1552](https://github.com/hiero-ledger/hiero-sdk-python/issues/1552))
153153
- Added `grpc_deadline` support for transaction and query execution.
154154
- Type hints to exception classes (`PrecheckError`, `MaxAttemptsError`, `ReceiptStatusError`) constructors and string methods.
155-
- Added `__eq__` and `__hash__` functions for Keys.
155+
- Added `__eq__` and `__hash__` functions for Key
156156

157157
### Documentation
158158
- Fix relative links in `testing.md`, clean up `CONTRIBUTING.md` TOC, and normalize test file naming and paths (`#1706`)
@@ -259,10 +259,10 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
259259
- chore: update maintainer guidelines link in MAINTAINERS.md (#1605)
260260
- chore: update merge conflict bot message with web editor tips (#1592)
261261
- chore: update MAINTAINERS.md to include new maintainer Manish Dait and sort maintainers by GitHub ID. (#1691)
262+
- Changed `TransactionResponse.get_receipt()` so now pins receipt queries to the submitting node via `set_node_account_ids()` ([#1686](https://github.com/hiero-ledger/hiero-sdk-python/issues/1686))
262263
- chore: clarify wording in the bot-assignment-check.sh (#1748)
263264
- Refactored SDK dependencies to use version ranges, moved build-only deps out of runtime, removed unused core deps and added optional extras.
264265

265-
266266
### Fixed
267267
- Corrected broken documentation links in SDK developer training files.(#1707)
268268
- Fixed assignment limit check to only count issues (not PRs) towards the maximum 2 concurrent assignments, allowing users to be assigned to PRs without affecting their issue assignment capacity. (#1717)

src/hiero_sdk_python/transaction/transaction_response.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ def get_receipt(self, client):
3737
"""
3838
# TODO: Decide how to avoid circular imports
3939
from hiero_sdk_python.query.transaction_get_receipt_query import TransactionGetReceiptQuery
40-
# TODO: Implement set_node_account_ids() to get failure reason for preHandle failures
4140
receipt = (
4241
TransactionGetReceiptQuery()
4342
.set_transaction_id(self.transaction_id)
43+
.set_node_account_ids([self.node_id])
4444
.execute(client)
4545
)
4646

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
"""
2+
Tests for TransactionResponse behavior.
3+
"""
4+
5+
import pytest
6+
7+
from hiero_sdk_python.account.account_id import AccountId
8+
from hiero_sdk_python.response_code import ResponseCode
9+
from hiero_sdk_python.transaction.transaction_response import TransactionResponse
10+
from hiero_sdk_python.hapi.services import (
11+
response_header_pb2,
12+
response_pb2,
13+
transaction_get_receipt_pb2,
14+
transaction_receipt_pb2,
15+
)
16+
17+
from tests.unit.mock_server import mock_hedera_servers
18+
19+
pytestmark = pytest.mark.unit
20+
21+
22+
def test_transaction_response_fields(transaction_id):
23+
"""asserting response is correctly populated"""
24+
resp = TransactionResponse()
25+
26+
# Assert public attributes exist (PRIORITY 1: protect against breaking changes)
27+
assert hasattr(resp, 'transaction_id'), "Missing public attribute: transaction_id"
28+
assert hasattr(resp, 'node_id'), "Missing public attribute: node_id"
29+
assert hasattr(resp, 'hash'), "Missing public attribute: hash"
30+
assert hasattr(resp, 'validate_status'), "Missing public attribute: validate_status"
31+
assert hasattr(resp, 'transaction'), "Missing public attribute: transaction"
32+
33+
# Assert default values
34+
assert resp.hash == bytes(), "Default hash should be empty bytes"
35+
assert resp.validate_status is False, "Default validate_status should be False"
36+
assert resp.transaction is None, "Default transaction should be None"
37+
38+
resp.transaction_id = transaction_id
39+
resp.node_id = AccountId(0, 0, 3)
40+
41+
assert resp.transaction_id == transaction_id
42+
assert resp.node_id == AccountId(0, 0, 3)
43+
44+
45+
def test_transaction_response_get_receipt_is_pinned_to_submitting_node(transaction_id):
46+
"""
47+
mock_hedera_servers assigns:
48+
- server[0] -> node 0.0.3
49+
- server[1] -> node 0.0.4
50+
51+
We make node 0.0.3 return a NON-retryable precheck error, and node 0.0.4 return SUCCESS.
52+
If TransactionResponse.get_receipt() does not pin, it will likely hit 0.0.3 and fail.
53+
If it pins to self.node_id (0.0.4), it will succeed.
54+
"""
55+
bad_node_response = response_pb2.Response(
56+
transactionGetReceipt=transaction_get_receipt_pb2.TransactionGetReceiptResponse(
57+
header=response_header_pb2.ResponseHeader(
58+
nodeTransactionPrecheckCode=ResponseCode.INVALID_TRANSACTION
59+
),
60+
receipt=transaction_receipt_pb2.TransactionReceipt(
61+
status=ResponseCode.UNKNOWN
62+
),
63+
)
64+
)
65+
66+
good_node_response = response_pb2.Response(
67+
transactionGetReceipt=transaction_get_receipt_pb2.TransactionGetReceiptResponse(
68+
header=response_header_pb2.ResponseHeader(
69+
nodeTransactionPrecheckCode=ResponseCode.OK
70+
),
71+
receipt=transaction_receipt_pb2.TransactionReceipt(
72+
status=ResponseCode.SUCCESS
73+
),
74+
)
75+
)
76+
77+
response_sequences = [
78+
[bad_node_response], # node 0.0.3
79+
[good_node_response], # node 0.0.4
80+
]
81+
82+
with mock_hedera_servers(response_sequences) as client:
83+
resp = TransactionResponse()
84+
resp.transaction_id = transaction_id
85+
resp.node_id = AccountId(0, 0, 4) # submitting node (server[1])
86+
87+
receipt = resp.get_receipt(client)
88+
89+
assert receipt.status == ResponseCode.SUCCESS

0 commit comments

Comments
 (0)