Skip to content
This repository has been archived by the owner on Jun 11, 2024. It is now read-only.

Merge release/6.0.0 into release/6.1.0 #9123

Merged
merged 53 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
dc47a3f
:truck: module/dynamic_rewards -> module/dynamic_reward (#8947)
has5aan Sep 11, 2023
034e2fd
defaultCommission to pos_getConstants (#8952)
has5aan Sep 14, 2023
c315013
Consumes iterations when encrypting with passphrase (#8949)
has5aan Sep 15, 2023
5e6cf7c
DynamicRewardEndpoint.getExpectedValidatorRewards request & response …
has5aan Sep 20, 2023
ce2ecb6
Fix absolute path issue and add export-json flag (#9020)
ishantiw Sep 20, 2023
2bdcc73
Update lisk-db version (#9023)
shuse2 Sep 21, 2023
1c1c9ab
Remove unnecessary initGenesisState check (#9027)
mosmartin Sep 21, 2023
cfd46fd
Update PoS constants (#9021)
ishantiw Sep 21, 2023
26b2850
Fix reward distribution to use # of validators instead of constant (#…
shuse2 Sep 21, 2023
aa95c24
⬆️ Bump version 6.0.0-rc.1
ishantiw Sep 21, 2023
3bf3b35
Add --add-legacy flag to keys create (#9032)
shuse2 Sep 24, 2023
923d839
:arrow_up: lisk-commander version
shuse2 Sep 24, 2023
758ec0b
TokenInteroperableMethod.recover validates storeValue (#9029)
has5aan Sep 25, 2023
ef9e6be
Fix `verifyValidatorsUpdate` and `mainchain registration` logic (#9042)
mitsuaki-u Sep 29, 2023
321a376
Fix genesis block aggregate commit (#9048)
shuse2 Sep 29, 2023
1067f5a
Add missing chainID to offline transaction signing (#9038)
bobanm Sep 29, 2023
ab8aa88
Update IPC timeout (#9052)
shuse2 Sep 29, 2023
196c9ec
Update getMaxRemovalHeight to start from minCerifyHeight - 1 (#9060)
shuse2 Oct 4, 2023
da598fb
Fix outdated getMaxRemovalHeight (#9065)
shuse2 Oct 6, 2023
c589442
Legacy endpoints issue (#9058)
ishantiw Oct 6, 2023
a420fcd
Add keys info to generator:status and create singleCommits when enabl…
shuse2 Oct 6, 2023
cc369ee
⬆️ Bump version 6.0.0-rc.2
ishantiw Oct 6, 2023
0d984bd
Revert #9048 to fix the testnet genesis block issue (#9071)
shuse2 Oct 7, 2023
c9c1ecc
⬆️ Bump version 6.0.0-rc.3
ishantiw Oct 7, 2023
25e4ce7
Fix validator unshuffling (#9088)
bobanm Oct 13, 2023
03fec4d
Fix unintended removal of element (#9089)
shuse2 Oct 13, 2023
6fc44ea
Fix Monitor Plugin `getTransactionStats` (#9091)
bobanm Oct 13, 2023
da03f11
_verifyTerminatedStateAccountsCommon doesn't need to be inside loop (…
sitetester Oct 18, 2023
4968383
Offline transaction signing gives a misleading error message (#9093)
bobanm Oct 18, 2023
7c6f3a6
Remove unnecessary exceptions (#9108)
shuse2 Oct 20, 2023
21f0182
Enhance interop example scripts (#9109)
Tschakki Oct 20, 2023
bf141fb
Update getChildQueue to replace default topic (#9110)
ishantiw Oct 22, 2023
b2c85d3
Revert "Revert #9048" (#9107)
shuse2 Oct 23, 2023
5745085
⬆️ Bump version 6.0.0-rc.4
ishantiw Oct 23, 2023
ce8329b
Align init message recovery command with LIP0054 (#9117)
ishantiw Oct 23, 2023
a943cd0
⬆️ Bump @babel/traverse from 7.8.6 to 7.23.2 (#9103)
dependabot[bot] Oct 23, 2023
4994353
Improve logging and handling of syncing node in chain connector plugi…
ishantiw Oct 23, 2023
905e6af
⬆️ Bump version 6.0.0-rc.5
ishantiw Oct 23, 2023
12c5d4c
Merge release/6.0.0 into release/6.1.0
shuse2 Oct 24, 2023
30d120f
Merge branch 'release/6.0.0' of https://github.com/LiskHQ/lisk-sdk in…
shuse2 Oct 24, 2023
63b3238
:white_check_mark: Fix genesis block
shuse2 Oct 25, 2023
0056f19
Fix missing multisig signatures (#9095)
bobanm Oct 25, 2023
8862332
:recycle: Fix merge conflicts
shuse2 Oct 30, 2023
9a6063f
:recycle: Remove duplicate test
shuse2 Oct 30, 2023
0e50017
Revert and remove another duplicate test
shuse2 Oct 30, 2023
098b822
:fire: Remove duplicate test
shuse2 Oct 30, 2023
0c2b1b0
:recycle: Fix the test structure
shuse2 Oct 31, 2023
8688ff3
:recycle: Remove duplicate
shuse2 Oct 31, 2023
f814022
:recycle: Remove duplicate
shuse2 Oct 31, 2023
380a1de
Update & clean up interop example (#9114)
Tschakki Nov 1, 2023
0146205
Merge branch 'release/6.0.0' of https://github.com/LiskHQ/lisk-sdk in…
shuse2 Nov 1, 2023
64f162a
Merge branch 'release/6.1.0' of https://github.com/LiskHQ/lisk-sdk in…
shuse2 Nov 1, 2023
dcb7d10
:recycle: Revert removed test
shuse2 Nov 1, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
683 changes: 683 additions & 0 deletions commander/oclif.manifest.json

Large diffs are not rendered by default.

24 changes: 22 additions & 2 deletions commander/src/bootstrapping/commands/genesis-block/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ import { Application, PartialApplicationConfig } from 'lisk-framework';
import { objects } from '@liskhq/lisk-utils';
import { Command, Flags as flagParser } from '@oclif/core';
import * as fs from 'fs-extra';
import { join, resolve } from 'path';
import { isAbsolute, join, resolve } from 'path';
import { validator } from '@liskhq/lisk-validator';
import { codec } from '@liskhq/lisk-codec';
import { homedir } from 'os';
import { GenesisAssetsInput, genesisAssetsSchema } from '../../../utils/genesis_creation';
import { flagsWithParser } from '../../../utils/flags';
import { getNetworkConfigFilesPath } from '../../../utils/path';
Expand All @@ -47,6 +48,10 @@ export abstract class BaseGenesisBlockCommand extends Command {
description: 'Path to file which contains genesis block asset in JSON format',
required: true,
}),
'export-json': flagParser.boolean({
description: 'Export genesis block as JSON format along with blob',
default: false,
}),
height: flagParser.integer({
char: 'h',
description: 'Genesis block height',
Expand Down Expand Up @@ -74,6 +79,7 @@ export abstract class BaseGenesisBlockCommand extends Command {
height,
timestamp,
'previous-block-id': previousBlockIDString,
'export-json': exportJSON,
},
} = await this.parse(BaseGenesisBlockCommand);
// validate folder name to not include camelcase or whitespace
Expand All @@ -95,7 +101,12 @@ export abstract class BaseGenesisBlockCommand extends Command {
config = objects.mergeDeep(config, customConfig);
}
// determine proper path
const configPath = join(process.cwd(), output);
let configPath = output;
if (output.includes('~')) {
configPath = configPath.replace('~', homedir());
} else if (!isAbsolute(output)) {
configPath = join(process.cwd(), output);
}
const app = this.getApplication(config);
// If assetsFile exist, create from assetsFile and default config/accounts are not needed
const assetsJSON = (await fs.readJSON(resolve(assetsFile))) as GenesisAssetsInput;
Expand All @@ -118,6 +129,15 @@ export abstract class BaseGenesisBlockCommand extends Command {
fs.writeFileSync(resolve(configPath, 'genesis_block.blob'), genesisBlock.getBytes(), {
mode: OWNER_READ_WRITE,
});
if (exportJSON) {
fs.writeFileSync(
resolve(configPath, 'genesis_block.json'),
JSON.stringify(genesisBlock.toJSON(), undefined, ' '),
{
mode: OWNER_READ_WRITE,
},
);
}
this.log(`Genesis block files saved at: ${configPath}`);
}

Expand Down
126 changes: 97 additions & 29 deletions commander/src/bootstrapping/commands/keys/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
*/

import { codec } from '@liskhq/lisk-codec';
import { bls, address as addressUtil, ed, encrypt } from '@liskhq/lisk-cryptography';
import { bls, address as addressUtil, ed, encrypt, legacy } from '@liskhq/lisk-cryptography';
import { Command, Flags as flagParser } from '@oclif/core';
import * as fs from 'fs-extra';
import * as path from 'path';
Expand Down Expand Up @@ -60,6 +60,9 @@ export class CreateCommand extends Command {
description: 'Chain id',
default: 0,
}),
'add-legacy': flagParser.boolean({
description: 'Add legacy key derivation path to the result',
}),
};

async run(): Promise<void> {
Expand All @@ -72,6 +75,7 @@ export class CreateCommand extends Command {
count,
offset,
chainid,
'add-legacy': addLegacy,
},
} = await this.parse(CreateCommand);

Expand All @@ -86,7 +90,37 @@ export class CreateCommand extends Command {
}

const keys = [];
for (let i = 0; i < count; i += 1) {
let i = 0;
if (addLegacy) {
const legacyKeyPath = 'legacy';
shuse2 marked this conversation as resolved.
Show resolved Hide resolved
const { privateKey: accountPrivateKey, publicKey: accountPublicKey } =
legacy.getPrivateAndPublicKeyFromPassphrase(passphrase);
const address = addressUtil.getAddressFromPublicKey(accountPublicKey);
const generatorPrivateKey = accountPrivateKey;
const generatorPublicKey = ed.getPublicKeyFromPrivateKey(generatorPrivateKey);
const blsKeyPath = `m/12381/134/${chainid}/99999`;
const blsPrivateKey = await bls.getPrivateKeyFromPhraseAndPath(passphrase, blsKeyPath);
const blsPublicKey = bls.getPublicKeyFromPrivateKey(blsPrivateKey);
const result = await this._createEncryptedObject(
{
address,
keyPath: legacyKeyPath,
accountPrivateKey,
accountPublicKey,
generatorKeyPath: legacyKeyPath,
generatorPrivateKey,
generatorPublicKey,
blsKeyPath,
blsPrivateKey,
blsPublicKey,
password,
},
noEncrypt,
);
keys.push(result);
i += 1;
}
for (; i < count; i += 1) {
const accountKeyPath = `m/44'/134'/${offset + i}'`;
const generatorKeyPath = `m/25519'/134'/${chainid}'/${offset + i}'`;
const blsKeyPath = `m/12381/134/${chainid}/${offset + i}`;
Expand All @@ -102,37 +136,23 @@ export class CreateCommand extends Command {
const blsPrivateKey = await bls.getPrivateKeyFromPhraseAndPath(passphrase, blsKeyPath);
const blsPublicKey = bls.getPublicKeyFromPrivateKey(blsPrivateKey);

let encryptedMessageObject = {};
if (!noEncrypt) {
const plainGeneratorKeyData = {
generatorKey: generatorPublicKey,
const result = await this._createEncryptedObject(
{
address,
keyPath: accountKeyPath,
accountPrivateKey,
accountPublicKey,
generatorKeyPath,
generatorPrivateKey,
blsKey: blsPublicKey,
generatorPublicKey,
blsKeyPath,
blsPrivateKey,
};
const encodedGeneratorKeys = codec.encode(plainGeneratorKeysSchema, plainGeneratorKeyData);
encryptedMessageObject = await encrypt.encryptMessageWithPassword(
encodedGeneratorKeys,
blsPublicKey,
password,
);
}

keys.push({
address: addressUtil.getLisk32AddressFromAddress(address),
keyPath: accountKeyPath,
publicKey: accountPublicKey.toString('hex'),
privateKey: accountPrivateKey.toString('hex'),
plain: {
generatorKeyPath,
generatorKey: generatorPublicKey.toString('hex'),
generatorPrivateKey: generatorPrivateKey.toString('hex'),
blsKeyPath,
blsKey: blsPublicKey.toString('hex'),
blsProofOfPossession: bls.popProve(blsPrivateKey).toString('hex'),
blsPrivateKey: blsPrivateKey.toString('hex'),
},
encrypted: encryptedMessageObject,
});
noEncrypt,
);
keys.push(result);
}

if (output) {
Expand All @@ -141,4 +161,52 @@ export class CreateCommand extends Command {
this.log(JSON.stringify({ keys }, undefined, ' '));
}
}
private async _createEncryptedObject(
input: {
address: Buffer;
keyPath: string;
accountPublicKey: Buffer;
accountPrivateKey: Buffer;
generatorKeyPath: string;
generatorPublicKey: Buffer;
generatorPrivateKey: Buffer;
blsKeyPath: string;
blsPublicKey: Buffer;
blsPrivateKey: Buffer;
password: string;
},
shuse2 marked this conversation as resolved.
Show resolved Hide resolved
noEncrypt: boolean,
) {
let encryptedMessageObject = {};
if (!noEncrypt) {
const plainGeneratorKeyData = {
generatorKey: input.generatorPublicKey,
generatorPrivateKey: input.generatorPrivateKey,
blsKey: input.blsPublicKey,
blsPrivateKey: input.blsPrivateKey,
};
const encodedGeneratorKeys = codec.encode(plainGeneratorKeysSchema, plainGeneratorKeyData);
encryptedMessageObject = await encrypt.encryptMessageWithPassword(
encodedGeneratorKeys,
input.password,
);
}

return {
address: addressUtil.getLisk32AddressFromAddress(input.address),
keyPath: input.keyPath,
shuse2 marked this conversation as resolved.
Show resolved Hide resolved
publicKey: input.accountPublicKey.toString('hex'),
privateKey: input.accountPrivateKey.toString('hex'),
plain: {
generatorKeyPath: input.generatorKeyPath,
generatorKey: input.generatorPublicKey.toString('hex'),
generatorPrivateKey: input.generatorPrivateKey.toString('hex'),
blsKeyPath: input.blsKeyPath,
blsKey: input.blsPublicKey.toString('hex'),
blsProofOfPossession: bls.popProve(input.blsPrivateKey).toString('hex'),
blsPrivateKey: input.blsPrivateKey.toString('hex'),
},
encrypted: encryptedMessageObject,
};
}
}
14 changes: 3 additions & 11 deletions commander/src/bootstrapping/commands/transaction/sign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
*/
import { Command, Flags as flagParser } from '@oclif/core';
import * as apiClient from '@liskhq/lisk-api-client';
import * as cryptography from '@liskhq/lisk-cryptography';
import {
Application,
blockHeaderSchema,
Expand All @@ -37,7 +36,6 @@ import {
getParamsSchema,
} from '../../../utils/transaction';
import { getDefaultPath } from '../../../utils/path';
import { isApplicationRunning } from '../../../utils/application';
import { PromiseResolvedType } from '../../../types';
import { DEFAULT_KEY_DERIVATION_PATH } from '../../../utils/config';
import { deriveKeypair } from '../../../utils/commons';
Expand Down Expand Up @@ -78,7 +76,7 @@ const signTransaction = async (

const chainIDBuffer = Buffer.from(chainID as string, 'hex');
const passphrase = flags.passphrase ?? (await getPassphraseFromPrompt('passphrase'));
const edKeys = cryptography.legacy.getPrivateAndPublicKeyFromPassphrase(passphrase);
const edKeys = await deriveKeypair(passphrase, flags['key-derivation-path']);

let signedTransaction: Record<string, unknown>;
if (flags['mandatory-keys'] || flags['optional-keys']) {
Expand Down Expand Up @@ -203,7 +201,7 @@ export abstract class SignCommand extends Command {
let signedTransaction: Record<string, unknown>;

if (flags.offline) {
const app = this.getApplication({}, {});
const app = this.getApplication({ genesis: { chainID: flags['chain-id'] } });
this._metadata = app.getMetadata();
this._schema = {
header: blockHeaderSchema,
Expand Down Expand Up @@ -256,18 +254,12 @@ export abstract class SignCommand extends Command {

async finally(error?: Error | string): Promise<void> {
if (error) {
if (this._dataPath && !isApplicationRunning(this._dataPath)) {
throw new Error(`Application at data path ${this._dataPath} is not running.`);
}
this.error(error instanceof Error ? error.message : error);
}
if (this._client) {
await this._client.disconnect();
}
}

abstract getApplication(
genesisBlock: Record<string, unknown>,
config: PartialApplicationConfig,
): Application;
abstract getApplication(config: PartialApplicationConfig): Application;
}
66 changes: 66 additions & 0 deletions commander/test/bootstrapping/commands/keys/create.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ describe('keys:create command', () => {
jest.spyOn(process.stdout, 'write').mockImplementation(val => stdout.push(val as string) > -1);
jest.spyOn(process.stderr, 'write').mockImplementation(val => stderr.push(val as string) > -1);
jest.spyOn(cryptography.ed, 'getPrivateKeyFromPhraseAndPath');
jest.spyOn(cryptography.legacy, 'getPrivateAndPublicKeyFromPassphrase');
jest.spyOn(cryptography.ed, 'getPublicKeyFromPrivateKey');
jest.spyOn(cryptography.address, 'getAddressFromPublicKey');
jest.spyOn(cryptography.bls, 'getPrivateKeyFromPhraseAndPath');
Expand Down Expand Up @@ -176,6 +177,71 @@ describe('keys:create command', () => {
});
});

describe('keys:create --add-legacy --passphrase', () => {
it('should create valid keys', async () => {
const legacyKeys =
cryptography.legacy.getPrivateAndPublicKeyFromPassphrase(defaultPassphrase);
const legacyBLSKeyPath = 'm/12381/134/0/99999';
const legacyBLSPrivateKey = await cryptography.bls.getPrivateKeyFromPhraseAndPath(
defaultPassphrase,
legacyBLSKeyPath,
);
await CreateCommand.run(['--add-legacy', '--passphrase', defaultPassphrase], config);
const loggedData = JSON.parse(stdout[0]);

expect(cryptography.legacy.getPrivateAndPublicKeyFromPassphrase).toHaveBeenCalledWith(
defaultPassphrase,
);
expect(cryptography.address.getAddressFromPublicKey).toHaveBeenCalledWith(
legacyKeys.publicKey,
);
expect(cryptography.ed.getPublicKeyFromPrivateKey).not.toHaveBeenCalledWith(
defaultAccountPrivateKey,
);
expect(cryptography.ed.getPrivateKeyFromPhraseAndPath).not.toHaveBeenCalledWith(
defaultPassphrase,
defaultGeneratorKeyPath,
);
expect(cryptography.ed.getPublicKeyFromPrivateKey).not.toHaveBeenCalledWith(
defaultGeneratorPrivateKey,
);
expect(cryptography.bls.getPrivateKeyFromPhraseAndPath).toHaveBeenCalledWith(
defaultPassphrase,
legacyBLSKeyPath,
);
expect(cryptography.bls.getPublicKeyFromPrivateKey).toHaveBeenCalledWith(legacyBLSPrivateKey);
expect(readerUtils.getPassphraseFromPrompt).not.toHaveBeenCalledWith('passphrase', true);
expect(readerUtils.getPasswordFromPrompt).toHaveBeenCalledWith('password', true);

expect(loggedData).toMatchObject({
keys: [
{
address: cryptography.address.getLisk32AddressFromPublicKey(legacyKeys.publicKey),
keyPath: 'legacy',
publicKey: legacyKeys.publicKey.toString('hex'),
privateKey: legacyKeys.privateKey.toString('hex'),
plain: {
generatorKeyPath: 'legacy',
generatorKey: legacyKeys.publicKey.toString('hex'),
generatorPrivateKey: legacyKeys.privateKey.toString('hex'),
blsKeyPath: legacyBLSKeyPath,
blsPrivateKey: legacyBLSPrivateKey.toString('hex'),
},
},
],
});
expect(loggedData.keys[0].encrypted).toBeDefined();
expect(loggedData.keys[0].encrypted).toHaveProperty('ciphertext');
expect(loggedData.keys[0].encrypted).toHaveProperty('mac');
expect(loggedData.keys[0].encrypted).toHaveProperty('cipherparams');
expect(loggedData.keys[0].encrypted).toHaveProperty('kdfparams');
expect(loggedData.keys[0].encrypted.cipher).toBe('aes-128-gcm');
expect(loggedData.keys[0].encrypted.kdf).toBe('argon2id');
expect(loggedData.keys[0].encrypted.version).toBe('1');
expect(consoleWarnSpy).toHaveBeenCalledTimes(0);
});
});

describe('keys:create --no-encrypt true', () => {
it('should create valid keys', async () => {
await CreateCommand.run(['--no-encrypt'], config);
Expand Down
Loading