99
1010#include < nlohmann/json.hpp>
1111
12+ #include < algorithm>
13+ #include < unordered_set>
14+
1215namespace Hiero
1316{
1417// -----
15- TransactionResponse::TransactionResponse (AccountId nodeId, TransactionId transactionId, std::vector<std::byte> hash)
18+ TransactionResponse::TransactionResponse (AccountId nodeId,
19+ TransactionId transactionId,
20+ std::vector<std::byte> hash,
21+ std::vector<AccountId> transactionNodeAccountIds)
1622 : mNodeId (std::move(nodeId))
1723 , mTransactionHash (std::move(hash))
1824 , mTransactionId (std::move(transactionId))
25+ , mTransactionNodeAccountIds (std::move(transactionNodeAccountIds))
1926{
2027}
2128
@@ -29,7 +36,7 @@ TransactionReceipt TransactionResponse::getReceipt(const Client& client) const
2936TransactionReceipt TransactionResponse::getReceipt (const Client& client,
3037 const std::chrono::system_clock::duration& timeout) const
3138{
32- TransactionReceipt txReceipt = getReceiptQuery ().execute (client, timeout);
39+ TransactionReceipt txReceipt = getReceiptQuery (&client ).execute (client, timeout);
3340
3441 if (mValidateStatus )
3542 {
@@ -40,9 +47,20 @@ TransactionReceipt TransactionResponse::getReceipt(const Client& client,
4047}
4148
4249// -----
43- TransactionReceiptQuery TransactionResponse::getReceiptQuery () const
50+ TransactionReceiptQuery TransactionResponse::getReceiptQuery (const Client* client ) const
4451{
45- return TransactionReceiptQuery ().setTransactionId (mTransactionId ).setNodeAccountIds ({ mNodeId });
52+ auto query = TransactionReceiptQuery ().setTransactionId (mTransactionId );
53+
54+ if (client && client->getAllowReceiptNodeFailover ())
55+ {
56+ query.setNodeAccountIds (buildFailoverNodeList (*client));
57+ }
58+ else
59+ {
60+ query.setNodeAccountIds ({ mNodeId });
61+ }
62+
63+ return query;
4664}
4765
4866// -----
@@ -123,13 +141,77 @@ TransactionRecord TransactionResponse::getRecord(const Client& client) const
123141TransactionRecord TransactionResponse::getRecord (const Client& client,
124142 const std::chrono::system_clock::duration& timeout) const
125143{
126- return TransactionRecordQuery (). setTransactionId ( mTransactionId ).execute (client, timeout);
144+ return getRecordQuery (&client ).execute (client, timeout);
127145}
128146
129147// -----
130- TransactionRecordQuery TransactionResponse::getRecordQuery () const
148+ TransactionRecordQuery TransactionResponse::getRecordQuery (const Client* client ) const
131149{
132- return TransactionRecordQuery ().setTransactionId (mTransactionId ).setNodeAccountIds ({ mNodeId });
150+ auto query = TransactionRecordQuery ().setTransactionId (mTransactionId );
151+
152+ if (client && client->getAllowReceiptNodeFailover ())
153+ {
154+ query.setNodeAccountIds (buildFailoverNodeList (*client));
155+ }
156+ else
157+ {
158+ query.setNodeAccountIds ({ mNodeId });
159+ }
160+
161+ return query;
162+ }
163+
164+ // -----
165+ std::vector<AccountId> TransactionResponse::buildFailoverNodeList (const Client& client) const
166+ {
167+ std::vector<AccountId> candidates;
168+ if (!mTransactionNodeAccountIds .empty ())
169+ {
170+ candidates = mTransactionNodeAccountIds ;
171+ }
172+ else
173+ {
174+ std::unordered_set<std::string> seen;
175+ for (const auto & [url, accountId] : client.getNetwork ())
176+ {
177+ const std::string key = accountId.toString ();
178+ if (seen.find (key) == seen.end ())
179+ {
180+ seen.insert (key);
181+ candidates.push_back (accountId);
182+ }
183+ }
184+ }
185+
186+ std::unordered_set<std::string> seen;
187+ std::vector<AccountId> nodeIds;
188+ nodeIds.push_back (mNodeId );
189+ seen.insert (mNodeId .toString ());
190+
191+ std::vector<AccountId> others;
192+ for (const auto & node : candidates)
193+ {
194+ const std::string key = node.toString ();
195+ if (seen.find (key) == seen.end ())
196+ {
197+ seen.insert (key);
198+ others.push_back (node);
199+ }
200+ }
201+
202+ std::sort (others.begin (),
203+ others.end (),
204+ [](const AccountId& a, const AccountId& b)
205+ {
206+ if (a.mShardNum != b.mShardNum )
207+ return a.mShardNum < b.mShardNum ;
208+ if (a.mRealmNum != b.mRealmNum )
209+ return a.mRealmNum < b.mRealmNum ;
210+ return a.mAccountNum .value_or (0ULL ) < b.mAccountNum .value_or (0ULL );
211+ });
212+
213+ nodeIds.insert (nodeIds.end (), others.begin (), others.end ());
214+ return nodeIds;
133215}
134216
135217// -----
0 commit comments