You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Recently there were increased complaints for INVALID_NODE_ACCOUNT error. After debugging with the team it turns out if a transaction is built to be a submitted to a specific node, but that node is not listed in the Clinet's list instead of throwing an error the SDK will send the transaction to a random node and it will reach the consensus node where it will fail at PRECHECK. This is possible because of a this logic in the JS SDK code.
Fix
We must introduce a new error to the user indicating that they are trying to submit a transaction to a node id which is not available in the Client's list and the user will have to adjust its setup. This way the user experience when using the JS SDK and interacting with the Hedera network will be improved.
Example of the new error:
Attempting to execute a transaction against node id 0.0.X, which is not present in Client's node list. Please review and adjust your setup.
By introducing the new error we will prevent sending it to the consensus node and failing at PRECHECK
How to Reproduce
Steps
Create a client that uses a default address book like Client.forTestne
Create a transaction and sign but not submit it.
Create a second Client and modify the list of nodes for that network by creating a custom network.
Remove two of the nodes from the network being used in the first client.
Take the transaction from the first client and submit it using the next client
Run the following example. The whole setup can be found in this repository and example - Four.js
import {
AccountId,
PrivateKey,
Client,
Hbar,
TransferTransaction,
} from "@hashgraph/sdk";
import { sortNodes } from '../utils/SortNodeList.js';
import { trimmedNodes } from "../utils/ListOfTrimmedNodes.js";
import { findMissingNodes } from "../utils/FindMissingNodes.js";
import dotenv from "dotenv";
dotenv.config();
/**
* Case 4: Create a client that uses a default address book like Client.forTestnet and use it to create a transaction and sign but not submit it.
* Create a second Client and modify the list of nodes for that network by creating a custom network.
* Remove two of the nodes from the network being used in the first client. Take the transaction from the first client and submit it using the next client.
*/
async function main() {
if (
process.env.OPERATOR_ID == null ||
process.env.OPERATOR_KEY == null ||
process.env.HEDERA_NETWORK == null
) {
throw new Error(
"Environment variables OPERATOR_ID, HEDERA_NETWORK, and OPERATOR_KEY are required."
);
}
// 1. Configure account
const operatorId = AccountId.fromString(process.env.OPERATOR_ID);
const operatorKey = PrivateKey.fromStringECDSA(process.env.OPERATOR_KEY);
// 2. Setup the first client
const clientOne = Client.forMainnet();
clientOne.setOperator(operatorId, operatorKey);
// 3. Get nodes fro, clientOne
const nodesClient = clientOne._network._network.keys();
const sortedNodes = sortNodes([...nodesClient]);
// 4. Defines the account which will receive the hbars after a TransferTransaction.
const recipientAccountId = new AccountId(3941207);
// 5. Setup the second client with trimmed nodes, Nodes 16 and Node 21 are removed
// trimmedNodes are in utils/ListOfTrimmedNodes.js
const clientTwo = Client.forNetwork(trimmedNodes);
clientTwo.setOperator(operatorId, operatorKey);
// 6. We run a loop in order to randomly hit some of the missing nodes
// Each 5 seconds a transaction is submitted to one of the nodes.
// If the transaction is submitted to one of the missing nodes INVALID_NODE_ACCOUNT error will be thrown
setInterval(async () => {
try {
// 7. Only sign the transaction with ClientOne, but don't submit it.
const signTransferTransaction = await new TransferTransaction()
.addHbarTransfer(operatorId, Hbar.fromTinybars(-1)) //Sending account
.addHbarTransfer(recipientAccountId, Hbar.fromTinybars(1)) //Receiving account
.freezeWith(clientOne)
.sign(operatorKey);
// 8. Log the missing nodes
const nodesTrimmedClient = sortNodes([...clientTwo._network._network.keys()]);
console.log("Missing nodes", findMissingNodes(sortedNodes, nodesTrimmedClient));
// 9. Execute the transaction with ClientTwo.
const transferTransaction = await signTransferTransaction.execute(clientTwo);
// 10. Gets the record and logs it.
const transactionRecord = await transferTransaction.getRecord(clientTwo);
console.log(
"The transfer transaction from account " +
operatorId +
" to account " +
recipientAccountId +
" was: " +
transactionRecord.transactionId
+
" executed against node id "
+ transferTransaction.nodeId.toString()
);
} catch (e) {
console.log(e);
}
}, 5000)
}
void main();
The text was updated successfully, but these errors were encountered:
Description
Recently there were increased complaints for INVALID_NODE_ACCOUNT error. After debugging with the team it turns out if a transaction is built to be a submitted to a specific node, but that node is not listed in the Clinet's list instead of throwing an error the SDK will send the transaction to a random node and it will reach the consensus node where it will fail at PRECHECK. This is possible because of a this logic in the JS SDK code.
Fix
We must introduce a new error to the user indicating that they are trying to submit a transaction to a node id which is not available in the Client's list and the user will have to adjust its setup. This way the user experience when using the JS SDK and interacting with the Hedera network will be improved.
Example of the new error:
By introducing the new error we will prevent sending it to the consensus node and failing at PRECHECK
How to Reproduce
Steps
Run the following example. The whole setup can be found in this repository and example - Four.js
The text was updated successfully, but these errors were encountered: