PHP WebShell

Текущая директория: /opt/BitGoJS/node_modules/@hashgraph/sdk/src/client

Просмотр файла: Network.js

/*-
 * ‌
 * Hedera JavaScript SDK
 * ​
 * Copyright (C) 2020 - 2022 Hedera Hashgraph, LLC
 * ​
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ‍
 */

import AccountId from "../account/AccountId.js";
import Node from "../Node.js";
import {
    PREVIEWNET_ADDRESS_BOOK,
    TESTNET_ADDRESS_BOOK,
    MAINNET_ADDRESS_BOOK,
} from "../address_book/AddressBooks.js";
import ManagedNetwork from "./ManagedNetwork.js";

/**
 * @typedef {import("../channel/Channel.js").default} Channel
 * @typedef {import("../address_book/NodeAddressBook.js").default} NodeAddressBook
 */

/**
 * @augments {ManagedNetwork<Channel, Node, AccountId>}
 */
export default class Network extends ManagedNetwork {
    /**
     * @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.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 = MAINNET_ADDRESS_BOOK;
                break;
            case "testnet":
                this._addressBook = TESTNET_ADDRESS_BOOK;
                break;
            case "previewnet":
                this._addressBook = 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.fromString(entry[1])
                : entry[1];

        return new Node({
            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);
    }
}

Выполнить команду


Для локальной разработки. Не используйте в интернете!