UNPKG

@hashgraph/solo

Version:

An opinionated CLI tool to deploy and manage private Hedera Networks.

90 lines 6.51 kB
// SPDX-License-Identifier: Apache-2.0 import { it, describe } from 'mocha'; import { expect } from 'chai'; import { Flags as flags } from '../../../src/commands/flags.js'; import { accountCreationShouldSucceed, balanceQueryShouldSucceed, getNodeAliasesPrivateKeysHash, getTemporaryDirectory, } from '../../test-utility.js'; import { Duration } from '../../../src/core/time/duration.js'; import { AccountBalanceQuery, AccountCreateTransaction, Hbar, HbarUnit, PrivateKey, } from '@hiero-ledger/sdk'; import { sleep } from '../../../src/core/helpers.js'; import { PathEx } from '../../../src/business/utils/path-ex.js'; import { SOLO_LOGS_DIR } from '../../../src/core/constants.js'; import { ConsensusNodeTest } from './tests/consensus-node-test.js'; import { LedgerTest } from './tests/ledger-test.js'; import { ConsensusNodeAddTest } from './tests/consensus-node-add-test.js'; import { main } from '../../../src/index.js'; export function testSeparateNodeAdd(argv, bootstrapResp, namespace, timeout) { const temporaryDirectory = 'contextDir'; const argvPrepare = argv.clone(); argvPrepare.setArg(flags.outputDir, temporaryDirectory); const argvExecute = argv.clone(); argvExecute.setArg(flags.inputDir, temporaryDirectory); const { opts: { k8Factory, accountManager, remoteConfig, logger }, } = bootstrapResp; describe('Node add via separated commands should success', async () => { let existingServiceMap; let existingNodeIdsPrivateKeysHash; it('cache current version of private keys', async () => { existingServiceMap = await accountManager.getNodeServiceMap(namespace, remoteConfig.getClusterRefs(), argv.getArg(flags.deployment)); existingNodeIdsPrivateKeysHash = await getNodeAliasesPrivateKeysHash(existingServiceMap, k8Factory, getTemporaryDirectory()); }).timeout(timeout); it('should succeed with init command', async () => { await main(LedgerTest.soloLedgerSystemInitArgv(argv.getArg(flags.deployment), argv.getArg(flags.nodeAliasesUnparsed), argv.getArg(flags.clusterRef))); }).timeout(Duration.ofMinutes(8).toMillis()); it('should add a new node to the network successfully', async () => { await main(ConsensusNodeAddTest.soloConsensusNodeAddPrepareArgv(argv.getArg(flags.deployment), temporaryDirectory, argv.getArg(flags.cacheDir), { persistentVolumeClaims: true, generateGossipKeys: true, generateTlsKeys: true, })); await main(ConsensusNodeAddTest.soloConsensusNodeAddSubmitArgv(argv.getArg(flags.deployment), temporaryDirectory)); await main(ConsensusNodeAddTest.soloConsensusNodeAddExecuteArgv(argv.getArg(flags.deployment), temporaryDirectory, argv.getArg(flags.cacheDir))); await accountManager.close(); argv.setArg(flags.nodeAliasesUnparsed, 'node1,node2,node3'); }).timeout(Duration.ofMinutes(12).toMillis()); it('should be able to create account after a separated consensus node add commands', async () => { await main(LedgerTest.soloLedgerAccountCreateArgv(argv.getArg(flags.deployment))); }); balanceQueryShouldSucceed(accountManager, namespace, remoteConfig, logger); accountCreationShouldSucceed(accountManager, namespace, remoteConfig, logger); it('existing nodes private keys should not have changed', async () => { const currentNodeIdsPrivateKeysHash = await getNodeAliasesPrivateKeysHash(existingServiceMap, k8Factory, getTemporaryDirectory()); for (const [nodeAlias, existingKeyHashMap] of existingNodeIdsPrivateKeysHash.entries()) { const currentNodeKeyHashMap = currentNodeIdsPrivateKeysHash.get(nodeAlias); for (const [keyFileName, existingKeyHash] of existingKeyHashMap.entries()) { expect(`${nodeAlias}:${keyFileName}:${currentNodeKeyHashMap.get(keyFileName)}`).to.equal(`${nodeAlias}:${keyFileName}:${existingKeyHash}`); } } }).timeout(timeout); it('should save the state, restart node, and preserve account balances', async () => { // create account before stopping await accountManager.loadNodeClient(namespace, remoteConfig.getClusterRefs(), argv.getArg(flags.deployment), argv.getArg(flags.forcePortForward)); const privateKey = PrivateKey.generate(); // get random integer between 100 and 1000 const amount = Math.floor(Math.random() * (1000 - 100) + 100); const newAccount = await new AccountCreateTransaction() .setKeyWithoutAlias(privateKey.publicKey) .setInitialBalance(Hbar.from(amount, HbarUnit.Hbar)) .execute(accountManager._nodeClient); // Get the new account ID const getReceipt = await newAccount.getReceipt(accountManager._nodeClient); const accountInfo = { accountId: getReceipt.accountId.toString(), balance: amount, }; // create more transactions to save more round of states await main(LedgerTest.soloLedgerAccountCreateArgv(argv.getArg(flags.deployment))); await sleep(Duration.ofSeconds(1)); await main(LedgerTest.soloLedgerAccountCreateArgv(argv.getArg(flags.deployment))); await main(ConsensusNodeTest.soloConsensusNetworkFreezeArgv(argv.getArg(flags.deployment))); await main(ConsensusNodeTest.soloConsensusStateDownloadArgv(argv.getArg(flags.deployment), argv.getArg(flags.nodeAliasesUnparsed))); await main(ConsensusNodeTest.soloConsensusNodeRestartArgv(argv.getArg(flags.deployment))); argv.setArg(flags.stateFile, PathEx.joinWithRealPath(SOLO_LOGS_DIR, namespace.name, 'network-node1-0-state.zip')); // check balance of accountInfo.accountId await accountManager.loadNodeClient(namespace, remoteConfig.getClusterRefs(), argv.getArg(flags.deployment), argv.getArg(flags.forcePortForward)); const balance = await new AccountBalanceQuery() .setAccountId(accountInfo.accountId) .execute(accountManager._nodeClient); expect(balance.hbars).to.be.eql(Hbar.from(accountInfo.balance, HbarUnit.Hbar)); }).timeout(Duration.ofMinutes(10).toMillis()); }).timeout(Duration.ofMinutes(3).toMillis()); } //# sourceMappingURL=separate-node-add.test.js.map