lisk-framework
Version:
Lisk blockchain application platform
204 lines • 9.89 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.Endpoint = void 0;
const lisk_cryptography_1 = require("@liskhq/lisk-cryptography");
const lisk_db_1 = require("@liskhq/lisk-db");
const lisk_validator_1 = require("@liskhq/lisk-validator");
const lisk_codec_1 = require("@liskhq/lisk-codec");
const generator_store_1 = require("./generator_store");
const generated_info_1 = require("./generated_info");
const schemas_1 = require("./schemas");
const errors_1 = require("./errors");
class Endpoint {
constructor(args) {
this._keypairs = args.keypair;
this._consensus = args.consensus;
this._abi = args.abi;
this._chain = args.chain;
this._blockTime = args.blockTime;
}
init(args) {
this._generatorDB = args.generatorDB;
this._genesisHeight = args.genesisHeight;
this._singleCommitHandler = args.singleCommitHandler;
}
async getStatus(_ctx) {
var _a, _b;
const generatorStore = new generator_store_1.GeneratorStore(this._generatorDB);
const list = await (0, generated_info_1.getGeneratedInfo)(generatorStore);
const status = [];
for (const info of list) {
const keys = this._keypairs.get(info.address);
status.push({
...info,
generatorKey: (_a = keys === null || keys === void 0 ? void 0 : keys.publicKey.toString('hex')) !== null && _a !== void 0 ? _a : '',
blsKey: (_b = keys === null || keys === void 0 ? void 0 : keys.blsPublicKey.toString('hex')) !== null && _b !== void 0 ? _b : '',
address: lisk_cryptography_1.address.getLisk32AddressFromAddress(info.address),
enabled: this._keypairs.has(info.address),
});
}
return { status };
}
async setStatus(ctx) {
lisk_validator_1.validator.validate(schemas_1.setStatusRequestSchema, ctx.params);
const req = ctx.params;
const address = lisk_cryptography_1.address.getAddressFromLisk32Address(req.address);
const generatorStore = new generator_store_1.GeneratorStore(this._generatorDB);
const keysExist = await (0, generated_info_1.generatorKeysExist)(generatorStore, address);
if (!keysExist) {
throw new Error(`Keys for ${req.address} is not registered.`);
}
const batch = new lisk_db_1.Batch();
await (0, generated_info_1.setLastGeneratedInfo)(generatorStore, address, req);
generatorStore.finalize(batch);
await this._generatorDB.write(batch);
}
async updateStatus(ctx) {
lisk_validator_1.validator.validate(schemas_1.updateStatusRequestSchema, ctx.params);
const req = ctx.params;
const address = lisk_cryptography_1.address.getAddressFromLisk32Address(req.address);
const generatorStore = new generator_store_1.GeneratorStore(this._generatorDB);
let generatorKeys;
try {
generatorKeys = await (0, generated_info_1.getGeneratorKeys)(generatorStore, address);
}
catch (error) {
if (error instanceof errors_1.NotFoundError) {
throw new Error(`Generator with address: ${req.address} does not have keys registered.`);
}
throw error;
}
let decryptedKeys;
if (generatorKeys.type === 'plain') {
decryptedKeys = generatorKeys.data;
}
else {
const decryptedBytes = await lisk_cryptography_1.encrypt.decryptAES128GCMWithPassword(generatorKeys.data, req.password);
decryptedKeys = lisk_codec_1.codec.decode(schemas_1.plainGeneratorKeysSchema, decryptedBytes);
}
if (!req.enable) {
this._keypairs.delete(lisk_cryptography_1.address.getAddressFromLisk32Address(ctx.params.address));
ctx.logger.info(`Forging disabled on account: ${req.address}`);
return {
address: req.address,
enabled: false,
};
}
const synced = this._consensus.isSynced(req.height, req.maxHeightPrevoted);
if (!synced) {
throw new Error('Failed to enable forging as the node is not synced to the network.');
}
let lastGeneratedInfo;
try {
lastGeneratedInfo = await (0, generated_info_1.getLastGeneratedInfo)(generatorStore, lisk_cryptography_1.address.getAddressFromLisk32Address(req.address));
}
catch (error) {
ctx.logger.debug(`Last generated information does not exist for address: ${req.address}`);
}
if (lastGeneratedInfo && !(0, generated_info_1.isEqualGeneratedInfo)(req, lastGeneratedInfo)) {
throw new Error('Request does not match last generated information.');
}
if (!lastGeneratedInfo && !(0, generated_info_1.isZeroValueGeneratedInfo)(req)) {
throw new Error('Last generated information does not exist.');
}
this._keypairs.set(address, {
blsPublicKey: decryptedKeys.blsKey,
blsSecretKey: decryptedKeys.blsPrivateKey,
privateKey: decryptedKeys.generatorPrivateKey,
publicKey: decryptedKeys.generatorKey,
});
if (!lastGeneratedInfo) {
await (0, generated_info_1.setLastGeneratedInfo)(generatorStore, lisk_cryptography_1.address.getAddressFromLisk32Address(req.address), req);
}
await this._singleCommitHandler.initSingleCommits(address);
ctx.logger.info(`Block generation enabled on address: ${req.address}`);
return {
address: req.address,
enabled: true,
};
}
async estimateSafeStatus(ctx) {
lisk_validator_1.validator.validate(schemas_1.estimateSafeStatusRequestSchema, ctx.params);
const req = ctx.params;
const finalizedHeight = this._consensus.finalizedHeight();
if (finalizedHeight === this._genesisHeight) {
throw new Error('At least one block after the genesis block must be finalized.');
}
const finalizedBlock = await this._chain.dataAccess.getBlockHeaderByHeight(finalizedHeight);
if (req.timeShutdown > finalizedBlock.timestamp) {
throw new Error(`A block at the time shutdown ${req.timeShutdown} must be finalized.`);
}
const numberOfBlocksPerMonth = Math.ceil((60 * 60 * 24 * 30) / this._blockTime);
const heightOneMonthAgo = Math.max(finalizedHeight - numberOfBlocksPerMonth, this._genesisHeight + 1);
const blockHeaderLastMonth = await this._chain.dataAccess.getBlockHeaderByHeight(heightOneMonthAgo);
const expectedBlocksCount = Math.ceil((finalizedBlock.timestamp - blockHeaderLastMonth.timestamp) / this._blockTime);
const generatedBlocksCount = finalizedBlock.height - blockHeaderLastMonth.height;
const missedBlocksCount = expectedBlocksCount - generatedBlocksCount;
const safeGeneratedHeight = finalizedHeight + missedBlocksCount;
return {
height: safeGeneratedHeight,
maxHeightGenerated: safeGeneratedHeight,
maxHeightPrevoted: safeGeneratedHeight,
};
}
async setKeys(ctx) {
lisk_validator_1.validator.validate(schemas_1.setKeysRequestSchema, ctx.params);
let generatorKeys;
const address = lisk_cryptography_1.address.getAddressFromLisk32Address(ctx.params.address);
if (ctx.params.type === 'plain') {
generatorKeys = {
address,
type: ctx.params.type,
data: lisk_codec_1.codec.fromJSON(schemas_1.plainGeneratorKeysSchema, ctx.params.data),
};
}
else {
generatorKeys = {
address,
type: ctx.params.type,
data: lisk_codec_1.codec.fromJSON(schemas_1.encryptedMessageSchema, ctx.params.data),
};
}
const generatorStore = new generator_store_1.GeneratorStore(this._generatorDB);
const batch = new lisk_db_1.Batch();
await (0, generated_info_1.setGeneratorKey)(generatorStore, lisk_cryptography_1.address.getAddressFromLisk32Address(ctx.params.address), generatorKeys);
generatorStore.finalize(batch);
await this._generatorDB.write(batch);
ctx.logger.info(`Setting key for ${ctx.params.address}`);
this._keypairs.delete(address);
}
async getAllKeys(_ctx) {
const generatorStore = new generator_store_1.GeneratorStore(this._generatorDB);
const keys = await (0, generated_info_1.getAllGeneratorKeys)(generatorStore);
const jsonKeys = [];
for (const key of keys) {
if (key.type === 'plain') {
jsonKeys.push({
address: lisk_cryptography_1.address.getLisk32AddressFromAddress(key.address),
type: key.type,
data: lisk_codec_1.codec.toJSON(schemas_1.plainGeneratorKeysSchema, key.data),
});
}
else {
jsonKeys.push({
address: lisk_cryptography_1.address.getLisk32AddressFromAddress(key.address),
type: key.type,
data: key.data,
});
}
}
return {
keys: jsonKeys,
};
}
async hasKeys(ctx) {
lisk_validator_1.validator.validate(schemas_1.hasKeysRequestSchema, ctx.params);
const generatorStore = new generator_store_1.GeneratorStore(this._generatorDB);
const keysExist = await (0, generated_info_1.generatorKeysExist)(generatorStore, lisk_cryptography_1.address.getAddressFromLisk32Address(ctx.params.address));
return {
hasKey: keysExist,
};
}
}
exports.Endpoint = Endpoint;
//# sourceMappingURL=endpoint.js.map
;