UNPKG

@hashgraph/solo

Version:

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

97 lines 7.04 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 * as constants from '../../../src/core/constants.js'; import { accountCreationShouldSucceed, balanceQueryShouldSucceed, getNodeAliasesPrivateKeysHash, getTemporaryDirectory, } from '../../test-utility.js'; import { Duration } from '../../../src/core/time/duration.js'; import { NodeUpdateTest } from './tests/node-update-test.js'; import { main } from '../../../src/index.js'; import { PrivateKey, AccountCreateTransaction, Hbar, HbarUnit, AccountId } from '@hiero-ledger/sdk'; export function testSeparateNodeUpdate(argv, bootstrapResp, namespace, timeout) { const updateNodeId = 'node2'; let newAccountId = ''; argv.setArg(flags.nodeAliasesUnparsed, 'node1,node2,node3'); argv.setArg(flags.nodeAlias, updateNodeId); argv.setArg(flags.newAccountNumber, newAccountId); argv.setArg(flags.newAdminKey, '302e020100300506032b6570042204200cde8d512569610f184b8b399e91e46899805c6171f7c2b8666d2a417bcc66c2'); const { opts: { k8Factory, logger, remoteConfig, accountManager, keyManager }, } = bootstrapResp; describe('Node update via separated commands', async () => { let existingServiceMap; let existingNodeIdsPrivateKeysHash; it('should create a new account for the updated node', async () => { await accountManager.loadNodeClient(namespace, remoteConfig.getClusterRefs(), argv.getArg(flags.deployment), argv.getArg(flags.forcePortForward)); const privateKey = PrivateKey.generateED25519(); const amount = 100; const newAccount = await new AccountCreateTransaction() .setKeyWithoutAlias(privateKey) .setInitialBalance(Hbar.from(amount, HbarUnit.Hbar)) .execute(accountManager._nodeClient); const getReceipt = await newAccount.getReceipt(accountManager._nodeClient); const accountId = getReceipt.accountId.toString(); logger.info(`New account created for updated node: ${accountId}`); argv.setArg(flags.newAccountNumber, accountId); newAccountId = accountId; // save to k8 secret for later use await accountManager.createOrReplaceAccountKeySecret(privateKey, AccountId.fromString(accountId), false, namespace); }).timeout(Duration.ofMinutes(2).toMillis()); 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(Duration.ofMinutes(8).toMillis()); it('should update a new node property successfully', async () => { // generate gossip and tls keys for the updated node const temporaryDirectory = getTemporaryDirectory(); const signingKey = await keyManager.generateSigningKey(updateNodeId); const signingKeyFiles = await keyManager.storeSigningKey(updateNodeId, signingKey, temporaryDirectory); logger.debug(`generated test gossip signing keys for node ${updateNodeId} : ${signingKeyFiles.certificateFile}`); argv.setArg(flags.gossipPublicKey, signingKeyFiles.certificateFile); argv.setArg(flags.gossipPrivateKey, signingKeyFiles.privateKeyFile); const tlsKey = await keyManager.generateGrpcTlsKey(updateNodeId); const tlsKeyFiles = await keyManager.storeTLSKey(updateNodeId, tlsKey, temporaryDirectory); logger.debug(`generated test TLS keys for node ${updateNodeId} : ${tlsKeyFiles.certificateFile}`); argv.setArg(flags.tlsPublicKey, tlsKeyFiles.certificateFile); argv.setArg(flags.tlsPrivateKey, tlsKeyFiles.privateKeyFile); const temporaryDirectory2 = 'contextDir'; await main(NodeUpdateTest.soloNodeUpdatePrepareArgv(argv.getArg(flags.deployment), temporaryDirectory2, argv.getArg(flags.cacheDir), { nodeAlias: updateNodeId, newAdminKey: argv.getArg(flags.newAdminKey), newAccountNumber: argv.getArg(flags.newAccountNumber), tlsPublicKey: argv.getArg(flags.tlsPublicKey), tlsPrivateKey: argv.getArg(flags.tlsPrivateKey), gossipPublicKey: argv.getArg(flags.gossipPublicKey), gossipPrivateKey: argv.getArg(flags.gossipPrivateKey), })); await main(NodeUpdateTest.soloNodeUpdateSubmitArgv(argv.getArg(flags.deployment), temporaryDirectory2, argv.getArg(flags.cacheDir))); await main(NodeUpdateTest.soloNodeUpdateExecuteArgv(argv.getArg(flags.deployment), temporaryDirectory2, argv.getArg(flags.cacheDir))); await accountManager.close(); }).timeout(Duration.ofMinutes(30).toMillis()); balanceQueryShouldSucceed(accountManager, namespace, remoteConfig, logger, updateNodeId); accountCreationShouldSucceed(accountManager, namespace, remoteConfig, logger, updateNodeId); it('signing key and tls key should not match previous one', 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()) { if (nodeAlias === updateNodeId && (keyFileName.startsWith(constants.SIGNING_KEY_PREFIX) || keyFileName.startsWith('hedera'))) { expect(`${nodeAlias}:${keyFileName}:${currentNodeKeyHashMap.get(keyFileName)}`).not.to.equal(`${nodeAlias}:${keyFileName}:${existingKeyHash}`); } else { expect(`${nodeAlias}:${keyFileName}:${currentNodeKeyHashMap.get(keyFileName)}`).to.equal(`${nodeAlias}:${keyFileName}:${existingKeyHash}`); } } } }).timeout(timeout); it('the consensus nodes accountId should be the newAccountId', async () => { // read config.txt file from first node, read config.txt line by line, it should not contain value of newAccountId const pods = await k8Factory .default() .pods() .list(namespace, [`solo.hedera.com/node-name=${updateNodeId}`]); const accountId = pods[0].labels['solo.hedera.com/account-id']; expect(accountId).to.equal(newAccountId); }).timeout(Duration.ofMinutes(10).toMillis()); }); } //# sourceMappingURL=separate-node-update.test.js.map