Skip to content

Commit

Permalink
feat: Add adminKey flag to node setup command (#1193)
Browse files Browse the repository at this point in the history
Signed-off-by: Ivo Yankov <[email protected]>
Signed-off-by: Jeromy Cannon <[email protected]>
Co-authored-by: Jeromy Cannon <[email protected]>
  • Loading branch information
Ivo-Yankov and jeromy-cannon authored Jan 29, 2025
1 parent 0c4fec2 commit b044fcc
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 5 deletions.
13 changes: 13 additions & 0 deletions src/commands/flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1338,6 +1338,17 @@ export class Flags {
prompt: undefined,
};

static readonly adminPublicKeys: CommandFlag = {
constName: 'adminPublicKeys',
name: 'admin-public-keys',
definition: {
describe: 'Comma separated list of DER encoded ED25519 public keys and must match the order of the node aliases',
defaultValue: constants.GENESIS_KEY,
type: 'string',
},
prompt: undefined,
};

static readonly quiet: CommandFlag = {
constName: 'quiet',
name: 'quiet-mode',
Expand Down Expand Up @@ -1718,6 +1729,8 @@ export class Flags {

static readonly allFlags: CommandFlag[] = [
Flags.accountId,
Flags.adminKey,
Flags.adminPublicKeys,
Flags.amount,
Flags.apiPermissionProperties,
Flags.app,
Expand Down
1 change: 1 addition & 0 deletions src/commands/node/configs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,7 @@ export interface NodeDeleteConfigClass {
export interface NodeSetupConfigClass {
app: string;
appConfig: string;
adminKey: string;
cacheDir: string;
devMode: boolean;
localBuildPath: string;
Expand Down
2 changes: 1 addition & 1 deletion src/commands/node/flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,5 +254,5 @@ export const START_FLAGS = {
export const SETUP_FLAGS = {
requiredFlags: [flags.cacheDir, flags.namespace, flags.releaseTag],
requiredFlagsWithDisabledPrompt: [flags.app, flags.appConfig, flags.nodeAliasesUnparsed],
optionalFlags: [flags.quiet, flags.devMode, flags.localBuildPath],
optionalFlags: [flags.quiet, flags.devMode, flags.localBuildPath, flags.adminPublicKeys],
};
2 changes: 2 additions & 0 deletions src/commands/node/tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -958,11 +958,13 @@ export class NodeCommandTasks {
) {
const networkNodeServiceMap = await this.accountManager.getNodeServiceMap(namespace);

const adminPublicKeys = splitFlagInput(this.configManager.getFlag(flags.adminPublicKeys));
const genesisNetworkData = await GenesisNetworkDataConstructor.initialize(
nodeAliases,
this.keyManager,
keysDir,
networkNodeServiceMap,
adminPublicKeys,
);

const genesisNetworkJson = path.join(stagingDir, 'genesis-network.json');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*
*/
import {AccountId, PrivateKey} from '@hashgraph/sdk';
import {AccountId, PrivateKey, PublicKey} from '@hashgraph/sdk';
import {GenesisNetworkNodeDataWrapper} from './genesis_network_node_data_wrapper.js';
import * as constants from '../constants.js';

Expand All @@ -25,6 +25,8 @@ import {GenesisNetworkRosterEntryDataWrapper} from './genesis_network_roster_ent
import {Templates} from '../templates.js';
import path from 'path';
import type {NetworkNodeServices} from '../network_node_services.js';
import {SoloError} from '../errors.js';
import {Flags as flags} from '../../commands/flags.js';

/**
* Used to construct the nodes data and convert them to JSON
Expand All @@ -38,10 +40,13 @@ export class GenesisNetworkDataConstructor implements ToJSON {
private readonly keyManager: KeyManager,
private readonly keysDir: string,
private readonly networkNodeServiceMap: Map<string, NetworkNodeServices>,
adminPublicKeyMap: Map<NodeAlias, string>,
) {
nodeAliases.forEach(nodeAlias => {
const adminPrivateKey = PrivateKey.fromStringED25519(constants.GENESIS_KEY);
const adminPubKey = adminPrivateKey.publicKey;
const genesisPrivateKey = PrivateKey.fromStringED25519(constants.GENESIS_KEY);
const adminPubKey = PublicKey.fromStringED25519(adminPublicKeyMap[nodeAlias])
? adminPublicKeyMap[nodeAlias]
: genesisPrivateKey.publicKey;

const nodeDataWrapper = new GenesisNetworkNodeDataWrapper(
+networkNodeServiceMap.get(nodeAlias).nodeId,
Expand Down Expand Up @@ -74,8 +79,30 @@ export class GenesisNetworkDataConstructor implements ToJSON {
keyManager: KeyManager,
keysDir: string,
networkNodeServiceMap: Map<string, NetworkNodeServices>,
adminPublicKeys: string[],
): Promise<GenesisNetworkDataConstructor> {
const instance = new GenesisNetworkDataConstructor(nodeAliases, keyManager, keysDir, networkNodeServiceMap);
const adminPublicKeyMap: Map<NodeAlias, string> = new Map();

const adminPublicKeyIsDefaultValue =
adminPublicKeys.length === 1 && adminPublicKeys[0] === flags.adminPublicKeys.definition.defaultValue;
// If admin keys are passed and if it is not the default value from flags then validate and build the adminPublicKeyMap
if (adminPublicKeys.length > 0 && !adminPublicKeyIsDefaultValue) {
if (adminPublicKeys.length !== nodeAliases.length) {
throw new SoloError('Provide a comma separated list of DER encoded ED25519 public keys for each node');
}

adminPublicKeys.forEach((key, i) => {
adminPublicKeyMap[nodeAliases[i]] = key;
});
}

const instance = new GenesisNetworkDataConstructor(
nodeAliases,
keyManager,
keysDir,
networkNodeServiceMap,
adminPublicKeyMap,
);

await instance.load();

Expand Down
1 change: 1 addition & 0 deletions test/test_util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ export function e2eTestSuite(
expect(nodeCmd.getUnusedConfigs(NodeCommandConfigs.SETUP_CONFIGS_NAME)).to.deep.equal([
flags.quiet.constName,
flags.devMode.constName,
flags.adminPublicKeys.constName,
]);
} catch (e) {
nodeCmd.logger.showUserError(e);
Expand Down

0 comments on commit b044fcc

Please sign in to comment.