lisk-framework
Version:
Lisk blockchain application platform
124 lines • 6.11 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.RegisterMultisignatureCommand = void 0;
const lisk_codec_1 = require("@liskhq/lisk-codec");
const lisk_utils_1 = require("@liskhq/lisk-utils");
const cryptography = require("@liskhq/lisk-cryptography");
const __1 = require("../..");
const state_machine_1 = require("../../../state_machine");
const auth_account_1 = require("../stores/auth_account");
const constants_1 = require("../constants");
const schemas_1 = require("../schemas");
const invalid_signature_1 = require("../events/invalid_signature");
const multisignature_registration_1 = require("../events/multisignature_registration");
class RegisterMultisignatureCommand extends __1.BaseCommand {
constructor() {
super(...arguments);
this.schema = schemas_1.registerMultisignatureParamsSchema;
}
init(args) {
this._maxNumberOfSignatures = args.maxNumberOfSignatures;
}
async verify(context) {
const { mandatoryKeys, optionalKeys, numberOfSignatures, signatures } = context.params;
if (!lisk_utils_1.objects.bufferArrayUniqueItems(mandatoryKeys)) {
return {
status: state_machine_1.VerifyStatus.FAIL,
error: new Error('MandatoryKeys contains duplicate public keys.'),
};
}
if (!lisk_utils_1.objects.bufferArrayUniqueItems(optionalKeys)) {
return {
status: state_machine_1.VerifyStatus.FAIL,
error: new Error('OptionalKeys contains duplicate public keys.'),
};
}
if (mandatoryKeys.length + optionalKeys.length < numberOfSignatures) {
return {
status: state_machine_1.VerifyStatus.FAIL,
error: new Error('The numberOfSignatures is bigger than the count of Mandatory and Optional keys.'),
};
}
if (mandatoryKeys.length + optionalKeys.length > this._maxNumberOfSignatures ||
mandatoryKeys.length + optionalKeys.length < 1) {
return {
status: state_machine_1.VerifyStatus.FAIL,
error: new Error(`The count of Mandatory and Optional keys should be between 1 and ${this._maxNumberOfSignatures}.`),
};
}
if (mandatoryKeys.length > numberOfSignatures) {
return {
status: state_machine_1.VerifyStatus.FAIL,
error: new Error('The numberOfSignatures needs to be equal or bigger than the number of Mandatory keys.'),
};
}
const repeatedKeys = mandatoryKeys.filter(value => optionalKeys.find(optional => optional.equals(value)) !== undefined);
if (repeatedKeys.length > 0) {
return {
status: state_machine_1.VerifyStatus.FAIL,
error: new Error('Invalid combination of Mandatory and Optional keys. Repeated keys across Mandatory and Optional were found.'),
};
}
if (mandatoryKeys.length + optionalKeys.length !== signatures.length) {
return {
status: state_machine_1.VerifyStatus.FAIL,
error: new Error('The number of mandatory and optional keys should match the number of signatures'),
};
}
if (!lisk_utils_1.objects.isBufferArrayOrdered(mandatoryKeys)) {
return {
status: state_machine_1.VerifyStatus.FAIL,
error: new Error('Mandatory keys should be sorted lexicographically.'),
};
}
if (!lisk_utils_1.objects.isBufferArrayOrdered(optionalKeys)) {
return {
status: state_machine_1.VerifyStatus.FAIL,
error: new Error('Optional keys should be sorted lexicographically.'),
};
}
return {
status: state_machine_1.VerifyStatus.OK,
};
}
async execute(context) {
const { transaction, params } = context;
const message = lisk_codec_1.codec.encode(schemas_1.multisigRegMsgSchema, {
address: transaction.senderAddress,
nonce: transaction.nonce,
numberOfSignatures: params.numberOfSignatures,
mandatoryKeys: params.mandatoryKeys,
optionalKeys: params.optionalKeys,
});
const allKeys = [...params.mandatoryKeys, ...params.optionalKeys].map((key, index) => ({
key,
signature: params.signatures[index],
}));
for (const { key, signature } of allKeys) {
const isValid = cryptography.ed.verifyData(constants_1.MESSAGE_TAG_MULTISIG_REG, context.chainID, message, signature, key);
if (!isValid) {
this.events.get(invalid_signature_1.InvalidSignatureEvent).error(context, transaction.senderAddress, {
numberOfSignatures: params.numberOfSignatures,
mandatoryKeys: params.mandatoryKeys,
optionalKeys: params.optionalKeys,
failingPublicKey: key,
failingSignature: signature,
});
throw new Error(`Invalid signature for public key ${key.toString('hex')}.`);
}
}
const authSubstore = this.stores.get(auth_account_1.AuthAccountStore);
const senderAccount = await authSubstore.get(context, transaction.senderAddress);
senderAccount.mandatoryKeys = params.mandatoryKeys;
senderAccount.optionalKeys = params.optionalKeys;
senderAccount.numberOfSignatures = params.numberOfSignatures;
await authSubstore.set(context, transaction.senderAddress, senderAccount);
this.events.get(multisignature_registration_1.MultisignatureRegistrationEvent).log(context, transaction.senderAddress, {
numberOfSignatures: params.numberOfSignatures,
mandatoryKeys: params.mandatoryKeys,
optionalKeys: params.optionalKeys,
});
}
}
exports.RegisterMultisignatureCommand = RegisterMultisignatureCommand;
//# sourceMappingURL=register_multisignature.js.map