UNPKG

lisk-framework

Version:

Lisk blockchain application platform

134 lines 6.62 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SubmitMainchainCrossChainUpdateCommand = void 0; const lisk_codec_1 = require("@liskhq/lisk-codec"); const state_machine_1 = require("../../../../state_machine"); const base_cross_chain_update_command_1 = require("../../base_cross_chain_update_command"); const constants_1 = require("../../constants"); const ccm_processed_1 = require("../../events/ccm_processed"); const schemas_1 = require("../../schemas"); const chain_account_1 = require("../../stores/chain_account"); const utils_1 = require("../../utils"); const panic_1 = require("../../../../utils/panic"); class SubmitMainchainCrossChainUpdateCommand extends base_cross_chain_update_command_1.BaseCrossChainUpdateCommand { async verify(context) { const { params } = context; await this.verifyCommon(context, true); const sendingChainAccount = (await this.stores .get(chain_account_1.ChainAccountStore) .getOrUndefined(context, params.sendingChainID)); if (sendingChainAccount.status === 0 && !(0, utils_1.isInboxUpdateEmpty)(params.inboxUpdate)) { (0, utils_1.verifyLivenessConditionForRegisteredChains)(context.header.timestamp, context.params.certificate); } return { status: state_machine_1.VerifyStatus.OK, }; } async execute(context) { const { params } = context; await this.verifyCertificateSignatureAndPartnerChainOutboxRoot(context); const [decodedCCMs, ok] = await this.beforeCrossChainMessagesExecution(context, true); if (!ok) { return; } try { context.contextStore.set(constants_1.CONTEXT_STORE_KEY_CCM_PROCESSING, true); for (let i = 0; i < decodedCCMs.length; i += 1) { const ccm = decodedCCMs[i]; const ccmBytes = params.inboxUpdate.crossChainMessages[i]; const ccmID = (0, utils_1.getIDFromCCMBytes)(ccmBytes); const ccmContext = { ...context, ccm, eventQueue: context.eventQueue.getChildQueue(Buffer.concat([constants_1.EVENT_TOPIC_CCM_EXECUTION, ccmID])), }; if (ccm.receivingChainID.equals((0, utils_1.getMainchainID)(context.chainID))) { await this.apply(ccmContext); } else { await this._forward(ccmContext); } await this.internalMethod.appendToInboxTree(context, params.sendingChainID, ccmBytes); } } catch (error) { (0, panic_1.panic)(context.logger, error); } finally { context.contextStore.delete(constants_1.CONTEXT_STORE_KEY_CCM_PROCESSING); } await this.afterCrossChainMessagesExecute(context); } async _beforeCrossChainMessageForwarding(context, eventSnapshotID, stateSnapshotID) { const { ccm, logger } = context; const { ccmID } = (0, utils_1.getEncodedCCMAndID)(ccm); try { for (const [module, method] of this.interoperableCCMethods.entries()) { if (method.beforeCrossChainMessageForwarding) { logger.debug({ moduleName: module, commandName: ccm.crossChainCommand, ccmID: ccmID.toString('hex'), }, 'Execute beforeCrossChainMessageForwarding'); await method.beforeCrossChainMessageForwarding(context); } } } catch (error) { context.eventQueue.restoreSnapshot(eventSnapshotID); context.stateStore.restoreSnapshot(stateSnapshotID); logger.info({ err: error, moduleName: ccm.module, commandName: ccm.crossChainCommand }, 'Fail to execute beforeCrossChainMessageForwarding.'); await this.internalMethod.terminateChainInternal(context, ccm.sendingChainID); this.events.get(ccm_processed_1.CcmProcessedEvent).log(context, ccm.sendingChainID, ccm.receivingChainID, { code: 12, result: 3, ccm, }); return false; } return true; } async _forward(context) { const { ccm } = context; const { ccmID, encodedCCM } = (0, utils_1.getEncodedCCMAndID)(ccm); if (!(await this.verifyCCM(context, ccmID))) { return; } let ccmFailed = false; const chainAccountStore = this.stores.get(chain_account_1.ChainAccountStore); const receivingChainAccount = await chainAccountStore.getOrUndefined(context, ccm.receivingChainID); if (!receivingChainAccount || receivingChainAccount.status === 0) { ccmFailed = true; } else { const live = await this.internalMethod.isLive(context, ccm.receivingChainID, context.header.timestamp); if (!live) { ccmFailed = true; await this.internalMethod.terminateChainInternal(context, ccm.receivingChainID); await this.internalMethod.sendInternal(context, constants_1.EMPTY_FEE_ADDRESS, constants_1.MODULE_NAME_INTEROPERABILITY, constants_1.CROSS_CHAIN_COMMAND_SIDECHAIN_TERMINATED, ccm.sendingChainID, BigInt(0), 0, lisk_codec_1.codec.encode(schemas_1.sidechainTerminatedCCMParamsSchema, { chainID: ccm.receivingChainID, stateRoot: receivingChainAccount === null || receivingChainAccount === void 0 ? void 0 : receivingChainAccount.lastCertificate.stateRoot, })); } } const stateSnapshotID = context.stateStore.createSnapshot(); const eventSnapshotID = context.eventQueue.createSnapshot(); if (!(await this._beforeCrossChainMessageForwarding({ ...context, ccmFailed }, eventSnapshotID, stateSnapshotID))) { return; } if (ccmFailed) { await this.bounce(context, encodedCCM.length, 1, 1); } else { await this.internalMethod.addToOutbox(context, ccm.receivingChainID, ccm); this.events.get(ccm_processed_1.CcmProcessedEvent).log(context, ccm.sendingChainID, ccm.receivingChainID, { code: 0, result: 1, ccm, }); } } } exports.SubmitMainchainCrossChainUpdateCommand = SubmitMainchainCrossChainUpdateCommand; //# sourceMappingURL=submit_mainchain_cross_chain_update.js.map