Skip to content
This repository has been archived by the owner on Jun 11, 2024. It is now read-only.

Implement applyRecovery for message recovery command #7764

Closed
Tracked by #7211
ishantiw opened this issue Nov 10, 2022 · 0 comments
Closed
Tracked by #7211

Implement applyRecovery for message recovery command #7764

ishantiw opened this issue Nov 10, 2022 · 0 comments
Assignees
Labels
framework/module/interoperability Interoperability module
Milestone

Comments

@ishantiw
Copy link
Contributor

ishantiw commented Nov 10, 2022

Description

Implement applyRecovery function used in execution based on LIP0054

def applyRecovery(trs: Transaction, ccm: CCM) -> None:
    # Calculate CCM ID, used later in events.
    ccmID = sha256(encode(crossChainMessageSchema, ccm))
    ccm.status = CCM_STATUS_CODE_RECOVERED
    ccm.sendingChainID, ccm.receivingChainID = ccm.receivingChainID, ccm.sendingChainID

    try:
        # Modules can verify the CCM.
        # The Token module verifies the escrowed balance in the CCM sending chain for the message fee.
        for each module mdl for which verifyCrossChainMessage exists:
            mdl.verifyCrossChainMessage(trs, ccm)
    except:
        emitEvent(
            module = MODULE_NAME_INTEROPERABILITY,
            name = EVENT_NAME_CCM_PROCESSED,
            data = {"ccmID": ccmID, "result": CCM_PROCESSED_RESULT_DISCARDED, "code": CCM_PROCESSED_CODE_INVALID_CCM_VERIFY_CCM_EXCEPTION},
            topics = [ccm.sendingChainID, ccm.receivingChainID]
        )
        return

    if ccm.module is not supported:
        emitEvent(
            module = MODULE_NAME_INTEROPERABILITY,
            name = EVENT_NAME_CCM_PROCESSED,
            data = {"ccmID": ccmID, "result": CCM_PROCESSED_RESULT_DISCARDED, "code": CCM_PROCESSED_CODE_MODULE_NOT_SUPPORTED},
            topics = [ccm.sendingChainID, ccm.receivingChainID]
        )
        return
    elif crossChainCommand is not supported:
        emitEvent(
            module = MODULE_NAME_INTEROPERABILITY,
            name = EVENT_NAME_CCM_PROCESSED,
            data = {"ccmID": ccmID, "result": CCM_PROCESSED_RESULT_DISCARDED, "code": CCM_PROCESSED_CODE_CROSS_CHAIN_COMMAND_NOT_SUPPORTED},
            topics = [ccm.sendingChainID, ccm.receivingChainID]
        )
        return

    crossChainCommand = cross-chain command associated with (ccm.module, ccm.crossChainCommand)
    try:
        crossChainCommand.verify(trs, ccm)
    except:
        emitEvent(
            module = MODULE_NAME_INTEROPERABILITY,
            name = EVENT_NAME_CCM_PROCESSED,
            data = {"ccmID": ccmID, "result": CCM_PROCESSED_RESULT_DISCARDED, "code": CCM_PROCESSED_CODE_INVALID_CCM_VERIFY_EXCEPTION},
            topics = [ccm.sendingChainID, ccm.receivingChainID]
        )
        return

    # Create a state snapshot.
    baseSnapshot = snapshot of the current state
    try:
        # Call the beforeCrossChainCommandExecution functions from other modules.
        # For example, the Token module assigns the message fee to the transaction sender.
        for each module mdl for which beforeCrossChainCommandExecution exists:
            mdl.beforeCrossChainCommandExecution(trs, ccm)
    except:
        revert state to baseSnapshot
        emitEvent(
            module = MODULE_NAME_INTEROPERABILITY,
            name = EVENT_NAME_CCM_PROCESSED,
            data = {"ccmID": ccmID, "result": CCM_PROCESSED_RESULT_DISCARDED, "code": CCM_PROCESSED_CODE_INVALID_CCM_BEFORE_CCC_EXECUTION_EXCEPTION},
            topics = [ccm.sendingChainID, ccm.receivingChainID]
        )
        return
    # Create a state snapshot.
    executionSnapshot = snapshot of the current state
    try:
        # Execute the cross-chain command.
        crossChainCommand.execute(trs, ccm)
        emitEvent(
            module = MODULE_NAME_INTEROPERABILITY,
            name = EVENT_NAME_CCM_PROCESSED,
            data = {"ccmID": ccmID, "result": CCM_PROCESSED_RESULT_APPLIED, "code": CCM_PROCESSED_CODE_SUCCESS},
            topics = [ccm.sendingChainID, ccm.receivingChainID]
        )
    except:
        revert state to executionSnapshot
        emitEvent(
            module = MODULE_NAME_INTEROPERABILITY,
            name = EVENT_NAME_CCM_PROCESSED,
            data = {"ccmID": ccmID, "result": CCM_PROCESSED_RESULT_DISCARDED, "code": CCM_PROCESSED_CODE_FAILED_CCM},
            topics = [ccm.sendingChainID, ccm.receivingChainID]
        )

    try:
        # Call the afterCrossChainCommandExecution functions from other modules.
        for each module mdl for which afterCrossChainCommandExecution exists:
            mdl.afterCrossChainCommandExecution(trs, ccm)
    except:
        revert state to baseSnapshot
        emitEvent(
            module = MODULE_NAME_INTEROPERABILITY,
            name = EVENT_NAME_CCM_PROCESSED,
            data = {"ccmID": ccmID, "result": CCM_PROCESSED_RESULT_DISCARDED, "code": CCM_PROCESSED_CODE_INVALID_CCM_AFTER_CCC_EXECUTION_EXCEPTION},
            topics = [ccm.sendingChainID, ccm.receivingChainID]
        )

Acceptance Criteria

  • Should have all the related unit tests

Additional Information

@ishantiw ishantiw added the framework/module/interoperability Interoperability module label Nov 10, 2022
@shuse2 shuse2 self-assigned this Nov 16, 2022
@shuse2 shuse2 added this to the Sprint 82 milestone Nov 16, 2022
ishantiw added a commit that referenced this issue Nov 18, 2022
### What was the problem?

This PR resolves #7764 

### How was it solved?

- Add applyRecovery for mainchain message recovery

### How was it tested?

- Add unit tests
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
framework/module/interoperability Interoperability module
Projects
None yet
Development

No branches or pull requests

2 participants