UNPKG

@hashgraph/sdk

Version:
257 lines (234 loc) 7.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _AccountId = _interopRequireDefault(require("../account/AccountId.cjs")); var _Node = _interopRequireDefault(require("../Node.cjs")); var _AddressBooks = require("../address_book/AddressBooks.cjs"); var _ManagedNetwork = _interopRequireDefault(require("./ManagedNetwork.cjs")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } // SPDX-License-Identifier: Apache-2.0 /** * @typedef {import("../channel/Channel.js").default} Channel * @typedef {import("../address_book/NodeAddressBook.js").default} NodeAddressBook */ /** * @augments {ManagedNetwork<Channel, Node, AccountId>} */ class Network extends _ManagedNetwork.default { /** * @param {(address: string) => Channel} createNetworkChannel */ constructor(createNetworkChannel) { super(createNetworkChannel); this._maxNodesPerTransaction = -1; /** @type {NodeAddressBook | null} */ this._addressBook = null; /** @type {boolean} */ this._transportSecurity = false; } /** * @param {{[key: string]: (string | AccountId)}} network */ setNetwork(network) { this._setNetwork( // eslint-disable-next-line ie11/no-collection-args new Map( // eslint-disable-next-line ie11/no-collection-args Object.entries(network).map(([key, value]) => { return [key, typeof value === "string" ? _AccountId.default.fromString(value) : value]; }))); } /** * @param {NodeAddressBook} addressBook * @returns {this} */ setNetworkFromAddressBook(addressBook) { /** @type {Record<string, AccountId>} */ const network = {}; const port = this.isTransportSecurity() ? 50212 : 50211; for (const nodeAddress of addressBook.nodeAddresses) { for (const endpoint of nodeAddress.addresses) { // TODO: We hard code ports too much, should fix if (endpoint.port === port && nodeAddress.accountId != null) { network[endpoint.toString()] = nodeAddress.accountId; } } } this.setNetwork(network); return this; } /** * @returns {{[key: string]: (string | AccountId)}} */ get network() { /** * @type {{[key: string]: (string | AccountId)}} */ var n = {}; // eslint-disable-next-line @typescript-eslint/no-unused-vars for (const node of this._nodes) { n[node.address.toString()] = node.accountId; } return n; } /** * @param {string} networkName * @returns {this} */ // eslint-disable-next-line @typescript-eslint/no-unused-vars setNetworkName(networkName) { super.setLedgerId(networkName); switch (networkName) { case "mainnet": this._addressBook = _AddressBooks.MAINNET_ADDRESS_BOOK; break; case "testnet": this._addressBook = _AddressBooks.TESTNET_ADDRESS_BOOK; break; case "previewnet": this._addressBook = _AddressBooks.PREVIEWNET_ADDRESS_BOOK; break; } if (this._addressBook != null) { for (const node of this._nodes) { for (const address of this._addressBook.nodeAddresses) { if (address.accountId != null && address.accountId.toString() === node.accountId.toString()) { node.setNodeAddress(address); } } } } return this; } /** * @returns {string | null} */ get networkName() { return this._ledgerId != null ? this._ledgerId.toString() : null; } /** * @abstract * @param {[string, (string | AccountId)]} entry * @returns {Node} */ _createNodeFromNetworkEntry(entry) { const accountId = typeof entry[1] === "string" ? _AccountId.default.fromString(entry[1]) : entry[1]; return new _Node.default({ newNode: { address: entry[0], accountId, channelInitFunction: this._createNetworkChannel } }).setMinBackoff(this._minBackoff); } /** * @abstract * @param {Map<string, AccountId>} network * @returns {number[]} */ _getNodesToRemove(network) { const indexes = []; for (let i = this._nodes.length - 1; i >= 0; i--) { const node = this._nodes[i]; const accountId = network.get(node.address.toString()); if (accountId == null || accountId.toString() !== node.accountId.toString()) { indexes.push(i); } } return indexes; } /** * @abstract * @param {[string, (string | AccountId)]} entry * @returns {boolean} */ _checkNetworkContainsEntry(entry) { for (const node of this._nodes) { if (node.address.toString() === entry[0]) { return true; } } return false; } /** * @returns {number} */ get maxNodesPerTransaction() { return this._maxNodesPerTransaction; } /** * @param {number} maxNodesPerTransaction * @returns {this} */ setMaxNodesPerTransaction(maxNodesPerTransaction) { this._maxNodesPerTransaction = maxNodesPerTransaction; return this; } /** * @returns {number} */ get maxNodeAttempts() { return this._maxNodeAttempts; } /** * @param {number} maxNodeAttempts * @returns {this} */ setMaxNodeAttempts(maxNodeAttempts) { this._maxNodeAttempts = maxNodeAttempts; return this; } /** * @returns {boolean} */ isTransportSecurity() { return this._transportSecurity; } /** * @param {boolean} transportSecurity * @returns {this} */ setTransportSecurity(transportSecurity) { if (this._transportSecurity == transportSecurity) { return this; } this._network.clear(); for (let i = 0; i < this._nodes.length; i++) { let node = this._nodes[i]; node.close(); node = /** @type {Node} */ transportSecurity ? node.toSecure().setCert(this._ledgerId != null ? this._ledgerId.toString() : "") : node.toInsecure(); this._nodes[i] = node; const nodes = this._network.get(node.getKey()) != null ? (/** @type {Node[]} */this._network.get(node.getKey())) : []; nodes.push(node); this._network.set(node.getKey(), nodes); } // Overwrite healthy node list since new ports might make the node work again this._healthyNodes = [...this._nodes]; this._transportSecurity = transportSecurity; return this; } /** * @internal * @returns {number} */ getNumberOfNodesForTransaction() { if (this._maxNodesPerTransaction > 0) { return this._maxNodesPerTransaction; } // ultimately it does not matter if we round up or down // if we round up, we will eventually take one more healthy node for execution // and we would hit the 'nodes.length == count' check in _getNumberOfMostHealthyNodes() less often return this._nodes.length <= 9 ? this._nodes.length : Math.floor((this._nodes.length + 3 - 1) / 3); } /** * @internal * @returns {AccountId[]} */ getNodeAccountIdsForExecute() { return this._getNumberOfMostHealthyNodes(this.getNumberOfNodesForTransaction()).map(node => node.accountId); } } exports.default = Network;