Skip to content

Commit 1a29c82

Browse files
committed
polishing new classes added new interfaces and aliases to make clarify what they do
Signed-off-by: instamenta <[email protected]>
1 parent 3e3cdd9 commit 1a29c82

File tree

7 files changed

+166
-93
lines changed

7 files changed

+166
-93
lines changed

src/commands/network.ts

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -132,21 +132,19 @@ export class NetworkCommand extends BaseCommand {
132132
];
133133
}
134134

135-
async prepareValuesArg(
136-
config: {
137-
chartDirectory?: string;
138-
app?: string;
139-
nodeAliases: string[];
140-
debugNodeAlias?: NodeAlias;
141-
enablePrometheusSvcMonitor?: boolean;
142-
releaseTag?: string;
143-
persistentVolumeClaims?: string;
144-
valuesFile?: string;
145-
haproxyIpsParsed?: Record<NodeAlias, IP>;
146-
envoyIpsParsed?: Record<NodeAlias, IP>;
147-
genesisNetworkData: GenesisNetworkDataConstructor;
148-
}
149-
) {
135+
async prepareValuesArg(config: {
136+
chartDirectory?: string;
137+
app?: string;
138+
nodeAliases: string[];
139+
debugNodeAlias?: NodeAlias;
140+
enablePrometheusSvcMonitor?: boolean;
141+
releaseTag?: string;
142+
persistentVolumeClaims?: string;
143+
valuesFile?: string;
144+
haproxyIpsParsed?: Record<NodeAlias, IP>;
145+
envoyIpsParsed?: Record<NodeAlias, IP>;
146+
genesisNetworkData: GenesisNetworkDataConstructor;
147+
}) {
150148
let valuesArg = config.chartDirectory
151149
? `-f ${path.join(config.chartDirectory, 'solo-deployment', 'values.yaml')}`
152150
: '';
@@ -163,7 +161,10 @@ export class NetworkCommand extends BaseCommand {
163161
}
164162

165163
const profileName = this.configManager.getFlag<string>(flags.profileName) as string;
166-
this.profileValuesFile = await this.profileManager.prepareValuesForSoloChart(profileName, config.genesisNetworkData);
164+
this.profileValuesFile = await this.profileManager.prepareValuesForSoloChart(
165+
profileName,
166+
config.genesisNetworkData,
167+
);
167168
if (this.profileValuesFile) {
168169
valuesArg += this.prepareValuesFiles(this.profileValuesFile);
169170
}
@@ -200,7 +201,7 @@ export class NetworkCommand extends BaseCommand {
200201
valuesArg += this.prepareValuesFiles(config.valuesFile);
201202
}
202203

203-
valuesArg += `--set "hedera.configMaps.genesisNetworkJson=${config.genesisNetworkData.toJSON()}"`
204+
valuesArg += `--set "hedera.configMaps.genesisNetworkJson=${config.genesisNetworkData.toJSON()}"`;
204205

205206
this.logger.debug('Prepared helm chart values', {valuesArg});
206207
return valuesArg;
@@ -262,7 +263,7 @@ export class NetworkCommand extends BaseCommand {
262263
constants.SOLO_DEPLOYMENT_CHART,
263264
);
264265

265-
config.genesisNetworkData = new GenesisNetworkDataConstructor(config.nodeAliases);
266+
config.genesisNetworkData = new GenesisNetworkDataConstructor(config.nodeAliases, this.keyManager, config.keysDir);
266267

267268
config.valuesArg = await this.prepareValuesArg(config);
268269

@@ -683,7 +684,7 @@ export class NetworkCommand extends BaseCommand {
683684
}
684685

685686
prepareGenesisNetworkJson(config: NetworkDeployConfigClass): string {
686-
const data = {network: {nodes: []}}
687+
const data = {network: {nodes: []}};
687688

688689
// TODO
689690

src/core/helpers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import {type NodeAlias, type NodeAliases} from '../types/aliases.js';
2828
import {type CommandFlag} from '../types/flag_types.js';
2929
import {type SoloLogger} from './logging.js';
3030
import {type Duration} from './time/duration.js';
31-
import {NodeAddConfigClass} from '../commands/node/configs.js';
31+
import {type NodeAddConfigClass} from '../commands/node/configs.js';
3232

3333
export function sleep(duration: Duration) {
3434
return new Promise<void>(resolve => {

src/core/models/genesisNetworkDataConstructor.ts

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,50 +14,61 @@
1414
* limitations under the License.
1515
*
1616
*/
17-
import type {NodeAlias, NodeAliases} from '../../types/aliases.js';
18-
import {GenesisNetworkNodeDataWrapper} from './genesisNetworkNodeDataWrapper.js';
19-
import {Templates} from '../templates.js';
20-
import {KeyManager} from '../key_manager.js';
21-
2217
import crypto from 'node:crypto';
2318
import {PrivateKey} from '@hashgraph/sdk';
24-
import * as constants from '../constants.js';
19+
import {Templates} from '../templates.js';
20+
import {GenesisNetworkNodeDataWrapper} from './genesisNetworkNodeDataWrapper.js';
2521
import * as x509 from '@peculiar/x509';
22+
import * as constants from '../constants.js';
23+
24+
import type {KeyManager} from '../key_manager.js';
25+
import type {ToJSON} from '../../types/index.js';
26+
import type {NodeAlias, NodeAliases} from '../../types/aliases.js';
2627

27-
export class GenesisNetworkDataConstructor {
28+
/**
29+
* Used to construct the nodes data and convert them to JSON
30+
*/
31+
export class GenesisNetworkDataConstructor implements ToJSON {
2832
public readonly nodes: Record<NodeAlias, GenesisNetworkNodeDataWrapper>;
2933

30-
public constructor (public readonly nodeAliases: NodeAliases) {
34+
public constructor(
35+
private readonly nodeAliases: NodeAliases,
36+
private readonly keyManager: KeyManager,
37+
private readonly keysDir: string,
38+
) {
3139
this.nodeAliases.forEach(nodeAlias => {
32-
this.nodes[nodeAlias] = new GenesisNetworkNodeDataWrapper(Templates.nodeIdFromNodeAlias(nodeAlias))
40+
const nodeId = Templates.nodeIdFromNodeAlias(nodeAlias);
41+
42+
const adminKey = PrivateKey.fromStringED25519(constants.GENESIS_KEY);
3343

34-
const adminKey = PrivateKey.fromStringED25519(constants.GENESIS_KEY)
35-
this.nodes[nodeAlias].adminKey = adminKey.publicKey
36-
})
44+
this.nodes[nodeAlias] = new GenesisNetworkNodeDataWrapper(nodeId, adminKey.publicKey.toStringRaw(), nodeAlias);
45+
});
3746
}
3847

3948
/**
40-
* @param keyManager
41-
* @param keysDir - !!! config.keysDir !!!
49+
* Loads the gossipCaCertificate and grpcCertificateHash
4250
*/
43-
public async load (keyManager: KeyManager, keysDir: string) {
44-
await Promise.all(this.nodeAliases.map(async nodeAlias => {
45-
const nodeKeys = await keyManager.loadSigningKey(nodeAlias, keysDir);
46-
51+
public async load() {
52+
await Promise.all(
53+
this.nodeAliases.map(async nodeAlias => {
54+
const nodeKeys = await this.keyManager.loadSigningKey(nodeAlias, this.keysDir);
4755

48-
const certPem = nodeKeys.certificate.toString()
56+
const certPem = nodeKeys.certificate.toString();
4957

50-
this.nodes[nodeAlias].gossipCaCertificate = certPem
58+
this.nodes[nodeAlias].gossipCaCertificate = certPem;
5159

52-
const tlsCertDer = new Uint8Array(x509.PemConverter.decode(certPem)[0]);
60+
const tlsCertDer = new Uint8Array(x509.PemConverter.decode(certPem)[0]);
5361

54-
const grpcCertificateHash = crypto.createHash('sha384').update(tlsCertDer).digest();
62+
const grpcCertificateHash = crypto.createHash('sha384').update(tlsCertDer).digest();
5563

56-
this.nodes[nodeAlias].grpcCertificateHash = grpcCertificateHash.toString();
57-
}))
64+
this.nodes[nodeAlias].grpcCertificateHash = grpcCertificateHash.toString();
65+
}),
66+
);
5867
}
5968

60-
public toJSON (): string {
61-
return JSON.stringify(this.nodes);
69+
public toJSON() {
70+
return JSON.stringify({
71+
nodeMetadata: Object.values(this.nodes).map(node => node.toObject()),
72+
});
6273
}
63-
}
74+
}

src/core/models/genesisNetworkNodeDataWrapper.ts

Lines changed: 52 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -14,45 +14,65 @@
1414
* limitations under the License.
1515
*
1616
*/
17-
import type {Nullable} from '../../types/aliases.js';
18-
import type {AccountId, Key} from '@hashgraph/sdk';
19-
import type {ServiceEndpoint} from '../../types/index.js';
17+
import {parseIpAddressToUint8Array} from '../helpers.js';
18+
import type {AccountId} from '@hashgraph/sdk';
19+
import {type GenesisNetworkNodeStructure, type ServiceEndpoint, type ToObject} from '../../types/index.js';
2020

21-
interface Node {
22-
nodeId: number;
23-
accountId: AccountId | string;
24-
description: string;
25-
gossipEndpoint: Nullable<ServiceEndpoint>;
26-
serviceEndpoint: Nullable<ServiceEndpoint>;
27-
gossipCaCertificate: string; // Bytes
28-
grpcCertificateHash: string; // Bytes
29-
weight: number;
30-
deleted: boolean;
31-
adminKey: Nullable<Key>;
32-
}
33-
34-
export class GenesisNetworkNodeDataWrapper implements Node{
35-
public readonly nodeId: number;
21+
export class GenesisNetworkNodeDataWrapper
22+
implements GenesisNetworkNodeStructure, ToObject<{node: GenesisNetworkNodeStructure}>
23+
{
3624
public accountId: AccountId | string;
37-
public readonly description: string;
38-
public gossipEndpoint: ServiceEndpoint;
39-
public serviceEndpoint: ServiceEndpoint;
25+
public gossipEndpoint: ServiceEndpoint[] = [];
26+
public serviceEndpoint: ServiceEndpoint[] = [];
4027
public gossipCaCertificate: string;
4128
public grpcCertificateHash: string;
42-
public readonly weight: number;
43-
public readonly deleted: boolean;
44-
public adminKey: Nullable<Key>;
29+
public weight: number;
30+
public readonly deleted = false;
4531

46-
constructor (nodeId: number) {
47-
this.nodeId = nodeId;
48-
this.deleted = false;
32+
constructor(
33+
public readonly nodeId: number,
34+
public readonly adminKey: string,
35+
public readonly description: string,
36+
) {}
37+
38+
/**
39+
* @param domainName - a fully qualified domain name
40+
* @param port
41+
*/
42+
public addServiceEndpoint(domainName: string, port: number): void {
43+
this.serviceEndpoint.push({
44+
ipAddressV4: parseIpAddressToUint8Array(domainName),
45+
domainName,
46+
port,
47+
});
4948
}
5049

51-
addGossipEndpoint (ipAddressV4: string, port: number, domainName: string): void {
52-
this.gossipEndpoint = {ipAddressV4, port, domainName};
50+
/**
51+
* @param domainName - a fully qualified domain name
52+
* @param port
53+
*/
54+
public addGossipEndpoint(domainName: string, port: number): void {
55+
this.gossipEndpoint.push({
56+
ipAddressV4: parseIpAddressToUint8Array(domainName),
57+
domainName,
58+
port,
59+
});
5360
}
5461

55-
addServiceEndpoint (ipAddressV4: string, port: number, domainName: string): void {
56-
this.serviceEndpoint = {ipAddressV4, port, domainName};
62+
public toObject() {
63+
return {
64+
node: {
65+
nodeId: this.nodeId,
66+
accountId: this.accountId,
67+
description: this.description,
68+
gossipEndpoint: this.gossipEndpoint,
69+
serviceEndpoint: this.serviceEndpoint,
70+
gossipCaCertificate: this.gossipCaCertificate,
71+
grpcCertificateHash: this.grpcCertificateHash,
72+
weight: this.weight,
73+
deleted: this.deleted,
74+
adminKey: this.adminKey,
75+
},
76+
};
5777
}
58-
}
78+
}

src/core/profile_manager.ts

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ import {Templates} from './templates.js';
2828
import * as constants from './constants.js';
2929
import {type ConfigManager} from './config_manager.js';
3030
import * as helpers from './helpers.js';
31-
import {getNodeAccountMap} from './helpers.js';
31+
import {getNodeAccountMap, parseIpAddressToUint8Array} from './helpers.js';
3232
import type {SoloLogger} from './logging.js';
3333
import type {NodeAlias, NodeAliases} from '../types/aliases.js';
34-
import {GenesisNetworkDataConstructor} from './models/genesisNetworkDataConstructor.js';
34+
import {type GenesisNetworkDataConstructor} from './models/genesisNetworkDataConstructor.js';
3535

3636
const consensusSidecars = [
3737
'recordStreamUploader',
@@ -171,7 +171,12 @@ export class ProfileManager {
171171
}
172172
}
173173

174-
resourcesForConsensusPod(profile: any, nodeAliases: NodeAliases, yamlRoot: object, genesisNetworkData: GenesisNetworkDataConstructor): object {
174+
resourcesForConsensusPod(
175+
profile: any,
176+
nodeAliases: NodeAliases,
177+
yamlRoot: object,
178+
genesisNetworkData: GenesisNetworkDataConstructor,
179+
): object {
175180
if (!profile) throw new MissingArgumentError('profile is required');
176181

177182
const accountMap = getNodeAccountMap(nodeAliases);
@@ -198,7 +203,7 @@ export class ProfileManager {
198203
this.configManager.getFlag(flags.releaseTag),
199204
this.configManager.getFlag(flags.app),
200205
this.configManager.getFlag(flags.chainId),
201-
genesisNetworkData
206+
genesisNetworkData,
202207
);
203208

204209
for (const flag of flags.nodeConfigFileFlags.values()) {
@@ -480,7 +485,7 @@ export class ProfileManager {
480485
releaseTag: string,
481486
appName = constants.HEDERA_APP_NAME,
482487
chainId = constants.HEDERA_CHAIN_ID,
483-
genesisNetworkData: GenesisNetworkDataConstructor
488+
genesisNetworkData: GenesisNetworkDataConstructor,
484489
) {
485490
if (!nodeAccountMap || nodeAccountMap.size === 0)
486491
throw new MissingArgumentError('nodeAccountMap the map of node IDs to account IDs is required');
@@ -490,8 +495,8 @@ export class ProfileManager {
490495
throw new IllegalArgumentError(`config destPath does not exist: ${destPath}`, destPath);
491496

492497
// init variables
493-
const internalPort = constants.HEDERA_NODE_INTERNAL_GOSSIP_PORT;
494-
const externalPort = constants.HEDERA_NODE_EXTERNAL_GOSSIP_PORT;
498+
const internalPort = +constants.HEDERA_NODE_INTERNAL_GOSSIP_PORT;
499+
const externalPort = +constants.HEDERA_NODE_EXTERNAL_GOSSIP_PORT;
495500
const nodeStakeAmount = constants.HEDERA_NODE_DEFAULT_STAKE_AMOUNT;
496501

497502
// @ts-ignore
@@ -508,12 +513,19 @@ export class ProfileManager {
508513
const externalIP = Templates.renderFullyQualifiedNetworkSvcName(namespace, nodeAlias);
509514

510515
const nodeDataWrapper = genesisNetworkData.nodes[nodeAlias];
511-
nodeDataWrapper.addGossipEndpoint(externalIP, +externalPort, '');
512-
nodeDataWrapper.addServiceEndpoint(internalIP, +internalPort, '');
516+
517+
nodeDataWrapper.weight = nodeStakeAmount;
518+
519+
// Add gossip endpoints
520+
nodeDataWrapper.addGossipEndpoint(externalIP, externalPort);
521+
nodeDataWrapper.addGossipEndpoint(internalIP, internalPort);
522+
523+
// Add service endpoints
524+
nodeDataWrapper.addServiceEndpoint(internalIP, internalPort);
513525

514526
const account = nodeAccountMap.get(nodeAlias);
515527

516-
nodeDataWrapper.accountId = account
528+
nodeDataWrapper.accountId = account;
517529

518530
if (releaseVersion.minor >= 40) {
519531
configLines.push(

src/types/aliases.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,5 @@ export type ConfigBuilder = (argv, ctx, task) => Promise<any>;
4242
export type Nullable<T> = T | null;
4343

4444
export type IP = string;
45+
46+
export type JsonString = string;

0 commit comments

Comments
 (0)