lisk-framework
Version:
Lisk blockchain application platform
169 lines • 11.3 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseInteroperabilityModule = void 0;
const lisk_utils_1 = require("@liskhq/lisk-utils");
const lisk_validator_1 = require("@liskhq/lisk-validator");
const lisk_codec_1 = require("@liskhq/lisk-codec");
const base_interoperable_module_1 = require("./base_interoperable_module");
const constants_1 = require("./constants");
const chain_account_1 = require("./stores/chain_account");
const chain_validators_1 = require("./stores/chain_validators");
const channel_data_1 = require("./stores/channel_data");
const outbox_root_1 = require("./stores/outbox_root");
const own_chain_account_1 = require("./stores/own_chain_account");
const registered_names_1 = require("./stores/registered_names");
const terminated_outbox_1 = require("./stores/terminated_outbox");
const terminated_state_1 = require("./stores/terminated_state");
const utils_1 = require("./utils");
const schemas_1 = require("./schemas");
const ccm_processed_1 = require("./events/ccm_processed");
const ccm_send_fail_1 = require("./events/ccm_send_fail");
const ccm_send_success_1 = require("./events/ccm_send_success");
const chain_account_updated_1 = require("./events/chain_account_updated");
const invalid_certificate_signature_1 = require("./events/invalid_certificate_signature");
const invalid_registration_signature_1 = require("./events/invalid_registration_signature");
const terminated_outbox_created_1 = require("./events/terminated_outbox_created");
const terminated_state_created_1 = require("./events/terminated_state_created");
const invalid_smt_verification_1 = require("./events/invalid_smt_verification");
const invalid_rmt_verification_1 = require("./events/invalid_rmt_verification");
const invalid_outbox_root_verification_1 = require("./events/invalid_outbox_root_verification");
class BaseInteroperabilityModule extends base_interoperable_module_1.BaseInteroperableModule {
constructor() {
super();
this.interoperableCCCommands = new Map();
this.interoperableCCMethods = new Map();
this.stores.register(outbox_root_1.OutboxRootStore, new outbox_root_1.OutboxRootStore(this.name, 0));
this.stores.register(chain_account_1.ChainAccountStore, new chain_account_1.ChainAccountStore(this.name, 1));
this.stores.register(own_chain_account_1.OwnChainAccountStore, new own_chain_account_1.OwnChainAccountStore(this.name, 13));
this.stores.register(channel_data_1.ChannelDataStore, new channel_data_1.ChannelDataStore(this.name, 5));
this.stores.register(chain_validators_1.ChainValidatorsStore, new chain_validators_1.ChainValidatorsStore(this.name, 9));
this.stores.register(terminated_state_1.TerminatedStateStore, new terminated_state_1.TerminatedStateStore(this.name, 3));
this.stores.register(terminated_outbox_1.TerminatedOutboxStore, new terminated_outbox_1.TerminatedOutboxStore(this.name, 11));
this.stores.register(registered_names_1.RegisteredNamesStore, new registered_names_1.RegisteredNamesStore(this.name, 7));
this.events.register(chain_account_updated_1.ChainAccountUpdatedEvent, new chain_account_updated_1.ChainAccountUpdatedEvent(this.name));
this.events.register(ccm_processed_1.CcmProcessedEvent, new ccm_processed_1.CcmProcessedEvent(this.name));
this.events.register(ccm_send_success_1.CcmSendSuccessEvent, new ccm_send_success_1.CcmSendSuccessEvent(this.name));
this.events.register(ccm_send_fail_1.CcmSentFailedEvent, new ccm_send_fail_1.CcmSentFailedEvent(this.name));
this.events.register(invalid_registration_signature_1.InvalidRegistrationSignatureEvent, new invalid_registration_signature_1.InvalidRegistrationSignatureEvent(this.name));
this.events.register(terminated_state_created_1.TerminatedStateCreatedEvent, new terminated_state_created_1.TerminatedStateCreatedEvent(this.name));
this.events.register(terminated_outbox_created_1.TerminatedOutboxCreatedEvent, new terminated_outbox_created_1.TerminatedOutboxCreatedEvent(this.name));
this.events.register(invalid_smt_verification_1.InvalidSMTVerificationEvent, new invalid_smt_verification_1.InvalidSMTVerificationEvent(this.name));
this.events.register(invalid_rmt_verification_1.InvalidRMTVerificationEvent, new invalid_rmt_verification_1.InvalidRMTVerificationEvent(this.name));
this.events.register(invalid_certificate_signature_1.InvalidCertificateSignatureEvent, new invalid_certificate_signature_1.InvalidCertificateSignatureEvent(this.name));
this.events.register(invalid_outbox_root_verification_1.InvalidOutboxRootVerificationEvent, new invalid_outbox_root_verification_1.InvalidOutboxRootVerificationEvent(this.name));
}
get name() {
return constants_1.MODULE_NAME_INTEROPERABILITY;
}
registerInteroperableModule(module) {
this.interoperableCCCommands.set(this.name, this.crossChainCommand);
this.interoperableCCMethods.set(module.name, module.crossChainMethod);
this.interoperableCCCommands.set(module.name, module.crossChainCommand);
}
_verifyChannelData(ctx, chainInfo) {
const mainchainTokenID = (0, utils_1.getTokenIDLSK)(ctx.chainID);
const { channelData } = chainInfo;
if (!channelData.messageFeeTokenID.equals(mainchainTokenID)) {
throw new Error('channelData.messageFeeTokenID is not equal to Token.getTokenIDLSK().');
}
if (channelData.minReturnFeePerByte !== constants_1.MIN_RETURN_FEE_PER_BYTE_BEDDOWS) {
throw new Error(`channelData.minReturnFeePerByte is not equal to ${constants_1.MIN_RETURN_FEE_PER_BYTE_BEDDOWS}.`);
}
}
_verifyChainValidators(chainInfo) {
const { chainValidators, chainData } = chainInfo;
const { activeValidators, certificateThreshold } = chainValidators;
if (activeValidators.length === 0 || activeValidators.length > constants_1.MAX_NUM_VALIDATORS) {
throw new Error(`activeValidators must have at least 1 element and at most ${constants_1.MAX_NUM_VALIDATORS} elements.`);
}
const blsKeys = activeValidators.map(v => v.blsKey);
if (!lisk_utils_1.objects.isBufferArrayOrdered(blsKeys)) {
throw new Error('activeValidators must be ordered lexicographically by blsKey property.');
}
if (!lisk_utils_1.objects.bufferArrayUniqueItems(blsKeys)) {
throw new Error(`All blsKey properties must be pairwise distinct.`);
}
if (activeValidators.filter(v => v.bftWeight <= BigInt(0)).length > 0) {
throw new Error(`validator.bftWeight must be > 0.`);
}
const totalWeight = activeValidators.reduce((accumulator, v) => accumulator + v.bftWeight, BigInt(0));
if (totalWeight > lisk_validator_1.MAX_UINT64) {
throw new Error(`totalWeight has to be less than or equal to ${lisk_validator_1.MAX_UINT64}.`);
}
if (totalWeight / BigInt(3) + BigInt(1) > certificateThreshold ||
certificateThreshold > totalWeight) {
throw new Error('Invalid certificateThreshold input.');
}
const { validatorsHash } = chainData.lastCertificate;
if (!validatorsHash.equals((0, utils_1.computeValidatorsHash)(activeValidators, certificateThreshold))) {
throw new Error('Invalid validatorsHash from chainData.lastCertificate.');
}
}
_verifyChainID(chainID, mainchainID, prefix) {
if (chainID.equals(mainchainID)) {
throw new Error(`${prefix}chainID must not be equal to ${mainchainID.toString('hex')}.`);
}
if (chainID[0] !== mainchainID[0]) {
throw new Error(`${prefix}chainID[0] must be equal to ${mainchainID[0]}.`);
}
}
_verifyTerminatedStateAccountsIDs(chainIDs) {
if (!lisk_utils_1.objects.bufferArrayUniqueItems(chainIDs)) {
throw new Error(`terminatedStateAccounts don't hold unique chainID.`);
}
if (!lisk_utils_1.objects.isBufferArrayOrdered(chainIDs)) {
throw new Error('terminatedStateAccounts must be ordered lexicographically by chainID.');
}
}
async processGenesisState(ctx, genesisInteroperability) {
const { ownChainName, ownChainNonce, chainInfos, terminatedStateAccounts, terminatedOutboxAccounts, } = genesisInteroperability;
const ownChainAccountSubStore = this.stores.get(own_chain_account_1.OwnChainAccountStore);
const chainAccountStore = this.stores.get(chain_account_1.ChainAccountStore);
const channelDataSubStore = this.stores.get(channel_data_1.ChannelDataStore);
const chainValidatorsSubStore = this.stores.get(chain_validators_1.ChainValidatorsStore);
const outboxRootSubStore = this.stores.get(outbox_root_1.OutboxRootStore);
const terminatedStateSubStore = this.stores.get(terminated_state_1.TerminatedStateStore);
const terminatedOutboxStore = this.stores.get(terminated_outbox_1.TerminatedOutboxStore);
if (ownChainName !== '') {
const ownChainAccount = {
name: ownChainName,
chainID: ctx.chainID,
nonce: ownChainNonce,
};
await ownChainAccountSubStore.set(ctx, constants_1.EMPTY_BYTES, ownChainAccount);
}
for (const chainInfo of chainInfos) {
await chainAccountStore.set(ctx, chainInfo.chainID, chainInfo.chainData);
await channelDataSubStore.set(ctx, chainInfo.chainID, chainInfo.channelData);
await chainValidatorsSubStore.set(ctx, chainInfo.chainID, chainInfo.chainValidators);
if (chainInfo.chainData.status !== 2) {
const outboxRoot = {
root: chainInfo.channelData.outbox.root,
};
await outboxRootSubStore.set(ctx, chainInfo.chainID, outboxRoot);
}
}
for (const stateAccount of terminatedStateAccounts) {
await terminatedStateSubStore.set(ctx, stateAccount.chainID, stateAccount.terminatedStateAccount);
}
for (const outboxAccount of terminatedOutboxAccounts) {
await terminatedOutboxStore.set(ctx, outboxAccount.chainID, outboxAccount.terminatedOutboxAccount);
}
}
async finalizeGenesisState(ctx) {
var _a, _b;
const genesisBlockAssetBytes = ctx.assets.getAsset(constants_1.MODULE_NAME_INTEROPERABILITY);
const genesisInteroperability = lisk_codec_1.codec.decode(schemas_1.genesisInteroperabilitySchema, genesisBlockAssetBytes);
const { chainInfos } = genesisInteroperability;
for (const chainInfo of chainInfos) {
const { messageFeeTokenID } = chainInfo.channelData;
if ((_a = this.tokenMethod) === null || _a === void 0 ? void 0 : _a.isNativeToken(messageFeeTokenID)) {
if (!(await ((_b = this.tokenMethod) === null || _b === void 0 ? void 0 : _b.escrowSubstoreExists(ctx.getMethodContext(), chainInfo.chainID, messageFeeTokenID)))) {
throw new Error("Corresponding escrow account doesn't exist.");
}
}
}
}
}
exports.BaseInteroperabilityModule = BaseInteroperabilityModule;
//# sourceMappingURL=base_interoperability_module.js.map
;