-
Notifications
You must be signed in to change notification settings - Fork 209
Description
🧩 Intermediate Contributors
This issue is intended for contributors who already have some familiarity with the
Hiero Python SDK codebase and contribution workflow.
You should feel comfortable:
- navigating existing source code and examples
- understanding SDK concepts without step-by-step guidance
- following the standard PR workflow without additional onboarding
If this is your very first contribution to the project, we recommend starting with a few
Good First Issues before working on this one.
🐞 Problem Description
The Python SDK's TransactionResponse.get_receipt() method does not pin the receipt query to the submitting node. Instead, it uses the default client node selection, which may query any node in the network.
This behavior differs from other Hiero SDKs (JavaScript, Java, Swift, C++, Go), which all explicitly pin receipt queries to the submitting node via set_node_account_ids([submitting_node]).
Why this matters:
When a transaction is rejected pre-consensus (non-billable — e.g., invalid payer, bad signature, insufficient balance), only the submitting node has visibility into that failure. The transaction is never propagated to other nodes. If the receipt query goes to a different node, it won't find the transaction and may return misleading results or errors.
Pinning receipt queries to the submitting node ensures consistent behavior for these edge cases.
Current implementation:
# src/hiero_sdk_python/transaction/transaction_response.py (lines 27-47)
def get_receipt(self, client):
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)
.execute(client) # ← Does NOT pin to self.node_id
)
return receiptNote: There's already a TODO comment acknowledging this gap.
Relevant files:
src/hiero_sdk_python/transaction/transaction_response.pysrc/hiero_sdk_python/query/transaction_get_receipt_query.pysrc/hiero_sdk_python/executable.py(containsset_node_account_ids())
💡 Expected Solution
Update TransactionResponse.get_receipt() to pin the receipt query to the submitting node by calling set_node_account_ids([self.node_id]).
The change should:
- Pin receipt queries to the submitting node (
self.node_id) - Preserve existing API behavior (no breaking changes)
- Follow the same pattern used by other SDKs
- Remove or update the existing TODO comment
Expected usage (unchanged):
response = transaction.execute(client)
receipt = response.get_receipt(client)
# Receipt query now explicitly targets the submitting nodeReference implementation (from JavaScript SDK):
// src/transaction/TransactionResponse.js
getReceiptQuery() {
return new TransactionReceiptQuery()
.setTransactionId(this.transactionId)
.setNodeAccountIds([this.nodeId]); // ← Pinned to submitting node
}🧠 Implementation Notes
Likely steps:
- In
TransactionResponse.get_receipt(), add.set_node_account_ids([self.node_id])to the query chain - Consider adding a
get_receipt_query()method that returns the configured query object (for consistency with other SDKs) - If
get_record()exists, apply the same pinning logic there - Remove or update the TODO comment on line 40
- Add or update tests to verify the node pinning behavior
The infrastructure already exists:
Executable.set_node_account_ids()is implemented inexecutable.py(line 83)TransactionResponsealready storesself.node_id(the submitting node)TransactionGetReceiptQueryinherits fromQuery, which inherits fromExecutable
Similar patterns:
- JavaScript SDK:
TransactionResponse.getReceiptQuery()pins tothis.nodeId - Java SDK:
TransactionResponse.getReceiptQuery()usesCollections.singletonList(nodeId) - Swift SDK:
TransactionResponse.getReceiptQuery()uses.nodeAccountIds([nodeAccountId])
Things to verify:
- Ensure
self.node_idis always populated whenget_receipt()is called - Check if there's a
get_record()method that needs the same treatment
✅ Acceptance Criteria
To merge this issue, the pull request must:
- Pin receipt queries to the submitting node via
set_node_account_ids([self.node_id]) - Apply the same pinning to record queries if applicable (
get_record()) - Remove or update the existing TODO comment
- Follow existing project conventions and patterns
- Include tests verifying the node pinning behavior
- Pass all CI checks
- Include a valid changelog entry
- Be DCO and GPG key signed as
git commit -S -s -m "chore: my change"with a GPG key set up
📚 Additional Context or Resources
- SDK Collaboration Hub Proposal: Opt-In Receipt/Record Query Failover
- This issue is a prerequisite for the opt-in failover feature
- The proposal requires all SDKs to have consistent baseline behavior (pinning) before implementing failover
- SDK Developer Docs
- SDK Developer Training
Related SDKs for reference: