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

Commit

Permalink
Update State recovery commands (#9119)
Browse files Browse the repository at this point in the history
Update tests for State recovery commands
  • Loading branch information
sitetester authored Nov 3, 2023
1 parent 698a9fd commit abb27d3
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 47 deletions.
6 changes: 3 additions & 3 deletions framework/src/modules/interoperability/base_state_recovery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export class BaseStateRecoveryCommand<
if (!moduleMethod.recover) {
return {
status: VerifyStatus.FAIL,
error: new Error('Module is not recoverable.'),
error: new Error("Module is not recoverable, as it doesn't have a recover method."),
};
}

Expand All @@ -93,7 +93,7 @@ export class BaseStateRecoveryCommand<
if (!objectUtils.bufferArrayUniqueItems(queryKeys)) {
return {
status: VerifyStatus.FAIL,
error: new Error('Recovered store keys are not pairwise distinct.'),
error: new Error('Recoverable store keys are not pairwise distinct.'),
};
}

Expand Down Expand Up @@ -160,7 +160,7 @@ export class BaseStateRecoveryCommand<
});
storeQueriesUpdate.push({
key: Buffer.concat([storePrefix, entry.substorePrefix, utils.hash(entry.storeKey)]),
value: RECOVERED_STORE_VALUE,
value: RECOVERED_STORE_VALUE, // The value is set to a constant without known pre-image.
bitmap: entry.bitmap,
});
} catch (err) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { getMainchainID } from '../../utils';
import { SidechainInteroperabilityInternalMethod } from '../internal_method';
import { InvalidSMTVerificationEvent } from '../../events/invalid_smt_verification';

// https://github.com/LiskHQ/lips/blob/main/proposals/lip-0054.md#state-recovery-initialization-command
export class InitializeStateRecoveryCommand extends BaseInteroperabilityCommand<SidechainInteroperabilityInternalMethod> {
public schema = stateRecoveryInitParamsSchema;

Expand Down Expand Up @@ -106,19 +107,23 @@ export class InitializeStateRecoveryCommand extends BaseInteroperabilityCommand<

const smt = new SparseMerkleTree();
let stateRoot: Buffer;
// it will help whether error is for input chainID or mainchainID
let msg;
if (terminatedStateAccountExists) {
const terminatedStateAccount = await terminatedStateSubstore.get(context, chainID);
stateRoot = terminatedStateAccount.mainchainStateRoot;
msg = `given chainID: ${chainID.toString('hex')}.`;
} else {
const mainchainID = getMainchainID(context.chainID);
const mainchainAccount = await this.stores.get(ChainAccountStore).get(context, mainchainID);
stateRoot = mainchainAccount.lastCertificate.stateRoot;
msg = `mainchainID: ${mainchainID.toString('hex')}`;
}

const verified = await smt.verifyInclusionProof(stateRoot, [queryKey], proofOfInclusion);
if (!verified) {
this.events.get(InvalidSMTVerificationEvent).error(context);
throw new Error('State recovery initialization proof of inclusion is not valid.');
throw new Error(`State recovery initialization proof of inclusion is not valid for ${msg}.`);
}

const deserializedSidechainAccount = codec.decode<ChainAccount>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,9 @@ describe('RecoverStateCommand', () => {
const result = await stateRecoveryCommand.verify(commandVerifyContext);

expect(result.status).toBe(VerifyStatus.FAIL);
expect(result.error?.message).toInclude('Module is not recoverable.');
expect(result.error?.message).toInclude(
"Module is not recoverable, as it doesn't have a recover method.",
);
});

it('should return error if recovered store keys are not pairwise distinct', async () => {
Expand All @@ -180,7 +182,7 @@ describe('RecoverStateCommand', () => {
const result = await stateRecoveryCommand.verify(commandVerifyContext);

expect(result.status).toBe(VerifyStatus.FAIL);
expect(result.error?.message).toInclude('Recovered store keys are not pairwise distinct.');
expect(result.error?.message).toInclude('Recoverable store keys are not pairwise distinct.');
});
});

Expand All @@ -200,6 +202,12 @@ describe('RecoverStateCommand', () => {
expect(invalidSMTVerificationEvent.error).toHaveBeenCalled();
});

it(`should not throw error if recovery is available for "${moduleName}"`, async () => {
await expect(stateRecoveryCommand.execute(commandExecuteContext)).resolves.not.toThrow(
`Recovery failed for module: ${moduleName}`,
);
});

it(`should throw error if recovery not available for "${moduleName}"`, async () => {
interoperableCCMethods.delete(moduleName);

Expand Down
Loading

0 comments on commit abb27d3

Please sign in to comment.