Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
- Added `/working` command to reset the inactivity timer on issues and PRs. ([#1552](https://github.com/hiero-ledger/hiero-sdk-python/issues/1552))
- Added `grpc_deadline` support for transaction and query execution.
- Type hints to exception classes (`PrecheckError`, `MaxAttemptsError`, `ReceiptStatusError`) constructors and string methods.
- Added `__eq__` and `__hash__` functions for Keys.
- Added `__eq__` and `__hash__` functions for Key

### Documentation
- Fix relative links in `testing.md`, clean up `CONTRIBUTING.md` TOC, and normalize test file naming and paths (`#1706`)
Expand Down Expand Up @@ -259,10 +259,10 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
- chore: update maintainer guidelines link in MAINTAINERS.md (#1605)
- chore: update merge conflict bot message with web editor tips (#1592)
- chore: update MAINTAINERS.md to include new maintainer Manish Dait and sort maintainers by GitHub ID. (#1691)
- 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))
- chore: clarify wording in the bot-assignment-check.sh (#1748)
- Refactored SDK dependencies to use version ranges, moved build-only deps out of runtime, removed unused core deps and added optional extras.


### Fixed
- Corrected broken documentation links in SDK developer training files.(#1707)
- 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)
Expand Down
2 changes: 1 addition & 1 deletion src/hiero_sdk_python/transaction/transaction_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ def get_receipt(self, client):
"""
# TODO: Decide how to avoid circular imports
from hiero_sdk_python.query.transaction_get_receipt_query import TransactionGetReceiptQuery
# TODO: Implement set_node_account_ids() to get failure reason for preHandle failures
receipt = (
TransactionGetReceiptQuery()
.set_transaction_id(self.transaction_id)
.set_node_account_ids([self.node_id])
.execute(client)
)

Expand Down
89 changes: 89 additions & 0 deletions tests/unit/test_transaction_response.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
"""
Tests for TransactionResponse behavior.
"""

import pytest

from hiero_sdk_python.account.account_id import AccountId
from hiero_sdk_python.response_code import ResponseCode
from hiero_sdk_python.transaction.transaction_response import TransactionResponse
from hiero_sdk_python.hapi.services import (
response_header_pb2,
response_pb2,
transaction_get_receipt_pb2,
transaction_receipt_pb2,
)

from tests.unit.mock_server import mock_hedera_servers

pytestmark = pytest.mark.unit


def test_transaction_response_fields(transaction_id):
"""asserting response is correctly populated"""
resp = TransactionResponse()

# Assert public attributes exist (PRIORITY 1: protect against breaking changes)
assert hasattr(resp, 'transaction_id'), "Missing public attribute: transaction_id"
assert hasattr(resp, 'node_id'), "Missing public attribute: node_id"
assert hasattr(resp, 'hash'), "Missing public attribute: hash"
assert hasattr(resp, 'validate_status'), "Missing public attribute: validate_status"
assert hasattr(resp, 'transaction'), "Missing public attribute: transaction"

# Assert default values
assert resp.hash == bytes(), "Default hash should be empty bytes"
assert resp.validate_status is False, "Default validate_status should be False"
assert resp.transaction is None, "Default transaction should be None"

resp.transaction_id = transaction_id
resp.node_id = AccountId(0, 0, 3)

assert resp.transaction_id == transaction_id
assert resp.node_id == AccountId(0, 0, 3)


def test_transaction_response_get_receipt_is_pinned_to_submitting_node(transaction_id):
"""
mock_hedera_servers assigns:
- server[0] -> node 0.0.3
- server[1] -> node 0.0.4

We make node 0.0.3 return a NON-retryable precheck error, and node 0.0.4 return SUCCESS.
If TransactionResponse.get_receipt() does not pin, it will likely hit 0.0.3 and fail.
If it pins to self.node_id (0.0.4), it will succeed.
"""
bad_node_response = response_pb2.Response(
transactionGetReceipt=transaction_get_receipt_pb2.TransactionGetReceiptResponse(
header=response_header_pb2.ResponseHeader(
nodeTransactionPrecheckCode=ResponseCode.INVALID_TRANSACTION
),
receipt=transaction_receipt_pb2.TransactionReceipt(
status=ResponseCode.UNKNOWN
),
)
)

good_node_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
),
)
)

response_sequences = [
[bad_node_response], # node 0.0.3
[good_node_response], # node 0.0.4
]

with mock_hedera_servers(response_sequences) as client:
resp = TransactionResponse()
resp.transaction_id = transaction_id
resp.node_id = AccountId(0, 0, 4) # submitting node (server[1])

receipt = resp.get_receipt(client)

assert receipt.status == ResponseCode.SUCCESS