Skip to content

Commit c78f359

Browse files
committed
hip 1299 - use new method Client.updateNetworkFromAddressBook()
Signed-off-by: emiliyank <e.kadiyski@gmail.com>
1 parent 9bcfbd3 commit c78f359

File tree

3 files changed

+82
-14
lines changed

3 files changed

+82
-14
lines changed

sdk/src/main/java/com/hedera/hashgraph/sdk/Client.java

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,40 @@ public synchronized Client setMirrorNetwork(List<String> network) throws Interru
473473
return this;
474474
}
475475

476+
/**
477+
* Trigger an immediate address book update.
478+
* This will fetch the address book even if periodic updates are disabled.
479+
*/
480+
public synchronized Client updateNetworkFromAddressBook() {
481+
try {
482+
var fileId = FileId.getAddressBookFileIdFor(this.shard, this.realm);
483+
484+
logger.debug("Fetching address book from file {}", fileId);
485+
System.out.println("Fetching address book from file " + fileId);
486+
487+
// Execute synchronously - no async complexity
488+
var addressBook = new AddressBookQuery()
489+
.setFileId(fileId)
490+
.execute(this); // ← Synchronous!
491+
492+
logger.debug("Received address book with {} nodes", addressBook.nodeAddresses.size());
493+
System.out.println("address book size: " + addressBook.nodeAddresses.size());
494+
495+
// Update the network
496+
this.setNetworkFromAddressBook(addressBook);
497+
498+
logger.info("Address book update completed successfully");
499+
System.out.println("Address book update completed successfully");
500+
501+
} catch (TimeoutException e) {
502+
logger.warn("Failed to fetch address book: {}", e.getMessage());
503+
} catch (Exception e) {
504+
logger.warn("Failed to update address book", e);
505+
}
506+
507+
return this;
508+
}
509+
476510
private synchronized void scheduleNetworkUpdate(@Nullable Duration delay) {
477511
if (delay == null) {
478512
networkUpdateFuture = null;
@@ -1411,10 +1445,26 @@ public synchronized Client setNetworkUpdatePeriod(Duration networkUpdatePeriod)
14111445
*
14121446
* @return {@code this}
14131447
*/
1414-
public synchronized Client updateNetworkFromAddressBook() {
1415-
scheduleNetworkUpdate(Duration.ZERO);
1416-
return this;
1417-
}
1448+
// public synchronized Client updateNetworkFromAddressBook() {
1449+
//// scheduleNetworkUpdate(Duration.ZERO);
1450+
// updateNetworkFromAddressBook2();
1451+
//
1452+
// if (networkUpdateFuture != null) {
1453+
// try {
1454+
// networkUpdateFuture.get(30, TimeUnit.SECONDS);
1455+
// logger.debug("Address book update completed successfully");
1456+
// } catch (TimeoutException e) {
1457+
// logger.warn("Address book update timed out after 30 seconds", e);
1458+
// } catch (InterruptedException e) {
1459+
// Thread.currentThread().interrupt();
1460+
// logger.warn("Address book update was interrupted", e);
1461+
// } catch (ExecutionException e) {
1462+
// logger.warn("Address book update failed", e);
1463+
// }
1464+
// }
1465+
//
1466+
// return this;
1467+
// }
14181468

14191469
public Logger getLogger() {
14201470
return this.logger;

sdk/src/main/java/com/hedera/hashgraph/sdk/Executable.java

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -442,13 +442,13 @@ public O execute(Client client, Duration timeout) throws TimeoutException, Prech
442442
lastException = grpcRequest.mapStatusException();
443443
advanceRequest(); // Advance to next node before retrying
444444

445-
// Handle INVALID_NODE_ACCOUNT after advancing (matches Go SDK's executionStateRetryWithAnotherNode)
445+
// Handle INVALID_NODE_ACCOUNT after advancing
446446
if (status == Status.INVALID_NODE_ACCOUNT) {
447447
logger.trace(
448448
"Received INVALID_NODE_ACCOUNT; updating address book and marking node {} as unhealthy, attempt #{}",
449449
node.getAccountId(),
450450
attempt);
451-
// Schedule async address book update (matches Go's defer client._UpdateAddressBook())
451+
// Schedule async address book update
452452
client.updateNetworkFromAddressBook();
453453
// Mark this node as unhealthy
454454
client.network.increaseBackoff(node);
@@ -613,7 +613,19 @@ void setNodesFromNodeAccountIds(Client client) {
613613
if (nodeAccountIds.size() == 1) {
614614
var nodeProxies = client.network.getNodeProxies(nodeAccountIds.get(0));
615615
if (nodeProxies == null || nodeProxies.isEmpty()) {
616-
throw new IllegalStateException("Account ID did not map to valid node in the client's network");
616+
logger.warn("Node {} not found in network, fetching latest address book",
617+
nodeAccountIds.get(0));
618+
619+
try {
620+
client.updateNetworkFromAddressBook(); // Synchronous update
621+
nodeProxies = client.network.getNodeProxies(nodeAccountIds.get(0));
622+
} catch (Exception e) {
623+
logger.error("Failed to update address book", e);
624+
}
625+
626+
if (nodeProxies == null || nodeProxies.isEmpty()) {
627+
throw new IllegalStateException("nodeProxies is null or empty");
628+
}
617629
}
618630

619631
nodes.addAll(nodeProxies).shuffle();
@@ -696,7 +708,7 @@ private ProtoRequestT getRequestForExecute() {
696708
var request = makeRequest();
697709

698710
// NOTE: advanceRequest() is now called explicitly in the retry logic
699-
// after we determine that a retry is needed, to match Go SDK behavior
711+
// after we determine that a retry is needed
700712
// where node advancement happens AFTER error detection, not before
701713

702714
return request;
@@ -903,12 +915,14 @@ ExecutionState getExecutionState(Status status, ResponseT response) {
903915
return ExecutionState.SERVER_ERROR;
904916
case BUSY:
905917
return ExecutionState.RETRY;
906-
case INVALID_NODE_ACCOUNT:
907-
// Matches Go SDK's executionStateRetryWithAnotherNode behavior:
908-
// immediately retry with next node without delay
909-
// This occurs when a node's account ID has changed
910-
return ExecutionState.SERVER_ERROR;
911-
case OK:
918+
//TODO - use ExecutionState.SUCCESS otherwise there is issue with transaction receipt - raised status INVALID_NODE_ACCOUNT
919+
// case INVALID_NODE_ACCOUNT:
920+
// // Matches Go SDK's executionStateRetryWithAnotherNode behavior:
921+
// // immediately retry with next node without delay
922+
// // This occurs when a node's account ID has changed
923+
// return ExecutionState.SERVER_ERROR;
924+
case INVALID_NODE_ACCOUNT:
925+
case OK:
912926
return ExecutionState.SUCCESS;
913927
default:
914928
return ExecutionState.REQUEST_ERROR; // user error

sdk/src/testIntegration/java/com/hedera/hashgraph/sdk/test/integration/NodeUpdateAccountIdIntegrationTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ void testNodeUpdateTransactionCanChangeNodeAccountUpdateAddressbookAndRetry() th
116116
.setAccountId(newNodeAccountID)
117117
.execute(client);
118118

119+
// Add before line 119 in your test
120+
System.out.println("Transaction node: " + resp.nodeId);
121+
System.out.println("Receipt query nodes: " + resp.getReceiptQuery().getNodeAccountIds());
122+
System.out.println("Client network: " + client.getNetwork());
119123
receipt = resp.setValidateStatus(true).getReceipt(client);
120124
assertThat(receipt.status).isEqualTo(Status.SUCCESS);
121125

0 commit comments

Comments
 (0)