UNPKG

lisk-framework

Version:

Lisk blockchain application platform

151 lines 8.06 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AuthModule = void 0; const lisk_utils_1 = require("@liskhq/lisk-utils"); const lisk_codec_1 = require("@liskhq/lisk-codec"); const lisk_validator_1 = require("@liskhq/lisk-validator"); const base_module_1 = require("../base_module"); const state_machine_1 = require("../../state_machine"); const method_1 = require("./method"); const constants_1 = require("./constants"); const endpoint_1 = require("./endpoint"); const schemas_1 = require("./schemas"); const utils_1 = require("./utils"); const auth_account_1 = require("./stores/auth_account"); const multisignature_registration_1 = require("./events/multisignature_registration"); const register_multisignature_1 = require("./commands/register_multisignature"); const invalid_signature_1 = require("./events/invalid_signature"); const errors_1 = require("./errors"); class AuthModule extends base_module_1.BaseModule { constructor() { super(); this.method = new method_1.AuthMethod(this.stores, this.events); this.endpoint = new endpoint_1.AuthEndpoint(this.stores, this.offchainStores); this.configSchema = schemas_1.configSchema; this._registerMultisignatureCommand = new register_multisignature_1.RegisterMultisignatureCommand(this.stores, this.events); this.commands = [this._registerMultisignatureCommand]; this.stores.register(auth_account_1.AuthAccountStore, new auth_account_1.AuthAccountStore(this.name, 0)); this.events.register(multisignature_registration_1.MultisignatureRegistrationEvent, new multisignature_registration_1.MultisignatureRegistrationEvent(this.name)); this.events.register(invalid_signature_1.InvalidSignatureEvent, new invalid_signature_1.InvalidSignatureEvent(this.name)); } metadata() { return { ...this.baseMetadata(), endpoints: [ { name: this.endpoint.getAuthAccount.name, request: schemas_1.addressRequestSchema, response: auth_account_1.authAccountSchema, }, { name: this.endpoint.isValidNonce.name, request: schemas_1.transactionRequestSchema, response: schemas_1.verifyResultSchema, }, { name: this.endpoint.isValidSignature.name, request: schemas_1.transactionRequestSchema, response: schemas_1.verifyResultSchema, }, { name: this.endpoint.getMultiSigRegMsgSchema.name, response: schemas_1.multisigRegMsgSchema, }, { name: this.endpoint.sortMultisignatureGroup.name, request: schemas_1.sortMultisignatureGroupRequestSchema, response: schemas_1.sortMultisignatureGroupResponseSchema, }, { name: this.endpoint.getMultiSigRegMsgTag.name, response: schemas_1.multiSigRegMsgTagSchema, }, ], assets: [ { version: 0, data: schemas_1.genesisAuthStoreSchema, }, ], }; } async init(args) { const { moduleConfig } = args; const config = lisk_utils_1.objects.mergeDeep({}, constants_1.defaultConfig, moduleConfig); lisk_validator_1.validator.validate(schemas_1.configSchema, config); this._moduleConfig = { maxNumberOfSignatures: config.maxNumberOfSignatures }; this._registerMultisignatureCommand.init({ maxNumberOfSignatures: config.maxNumberOfSignatures, }); } async initGenesisState(context) { const assetBytes = context.assets.getAsset(this.name); if (!assetBytes) { return; } const genesisStore = lisk_codec_1.codec.decode(schemas_1.genesisAuthStoreSchema, assetBytes); const store = this.stores.get(auth_account_1.AuthAccountStore); const keys = []; for (const { address, authAccount } of genesisStore.authDataSubstore) { if (address.length !== constants_1.ADDRESS_LENGTH) { throw new Error('Invalid store key length for auth module.'); } keys.push(address); lisk_validator_1.validator.validate(auth_account_1.authAccountSchema, authAccount); const { mandatoryKeys, optionalKeys, numberOfSignatures } = authAccount; if (!lisk_utils_1.objects.isBufferArrayOrdered(mandatoryKeys)) { throw new Error('Invalid store value for auth module. MandatoryKeys are not sorted lexicographically.'); } if (!lisk_utils_1.objects.bufferArrayUniqueItems(mandatoryKeys)) { throw new Error('Invalid store value for auth module. MandatoryKeys are not unique.'); } if (!lisk_utils_1.objects.isBufferArrayOrdered(optionalKeys)) { throw new Error('Invalid store value for auth module. OptionalKeys are not sorted lexicographically.'); } if (!lisk_utils_1.objects.bufferArrayUniqueItems(optionalKeys)) { throw new Error('Invalid store value for auth module. OptionalKeys are not unique.'); } if (mandatoryKeys.length + optionalKeys.length > this._moduleConfig.maxNumberOfSignatures) { throw new Error(`The count of Mandatory and Optional keys should be maximum ${this._moduleConfig.maxNumberOfSignatures}.`); } const repeatedKeys = mandatoryKeys.filter(value => optionalKeys.find(optional => optional.equals(value)) !== undefined); if (repeatedKeys.length > 0) { throw new Error('Invalid combination of Mandatory and Optional keys. Repeated keys across Mandatory and Optional were found.'); } if (mandatoryKeys.length + optionalKeys.length < numberOfSignatures) { throw new Error('The numberOfSignatures is bigger than the count of Mandatory and Optional keys.'); } if (mandatoryKeys.length > numberOfSignatures) { throw new Error('The numberOfSignatures is smaller than the count of Mandatory keys.'); } await store.set(context, address, authAccount); } if (!lisk_utils_1.objects.bufferArrayUniqueItems(keys)) { throw new Error('Duplicate address in the for auth module.'); } } async verifyTransaction(context) { const { transaction, chainID } = context; const authAccountStore = this.stores.get(auth_account_1.AuthAccountStore); const senderAccount = await authAccountStore.getOrDefault(context, transaction.senderAddress); const nonceStatus = (0, utils_1.verifyNonce)(transaction, senderAccount); if (nonceStatus.status === state_machine_1.VerifyStatus.FAIL) { throw new errors_1.InvalidNonceError(`Transaction with id:${transaction.id.toString('hex')} nonce is lower than account nonce.`, transaction.nonce, senderAccount.nonce); } (0, utils_1.verifySignatures)(transaction, chainID, senderAccount); return nonceStatus; } async beforeCommandExecute(context) { const { transaction } = context; const authAccountStore = this.stores.get(auth_account_1.AuthAccountStore); const senderAccount = await authAccountStore.getOrDefault(context, transaction.senderAddress); await authAccountStore.set(context, transaction.senderAddress, { nonce: senderAccount.nonce + BigInt(1), numberOfSignatures: senderAccount.numberOfSignatures, mandatoryKeys: senderAccount.mandatoryKeys, optionalKeys: senderAccount.optionalKeys, }); } } exports.AuthModule = AuthModule; //# sourceMappingURL=module.js.map