Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 29 additions & 54 deletions tee-worker/ts-tests/identity.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { describeLitentry, encryptWithTeeShieldingKey, generateVerificationMessage, listenEvent, sendTxUntilInBlock } from './utils';
import { describeLitentry, encryptWithTeeShieldingKey, generateVerificationMessage, listenEvent, sendTxUntilInBlock, checkFailReason } from './utils';
import { hexToU8a, u8aConcat, u8aToHex, u8aToU8a, stringToU8a } from '@polkadot/util';
import {
setUserShieldingKey,
Expand Down Expand Up @@ -213,7 +213,6 @@ describeLitentry('Test Identity', (context) => {
assert.isNotEmpty(resp_extension_substrate.challengeCode, 'challengeCode empty');
}
});

step('verify identities', async function () {
//Alice verify all identities
const [twitter_identity_verified, ethereum_identity_verified, substrate_identity_verified] =
Expand Down Expand Up @@ -252,15 +251,7 @@ describeLitentry('Test Identity', (context) => {
[twitterIdentity, ethereumIdentity, substrateIdentity],
[twitterValidationData, ethereumValidationData, substrateValidationData]
)) as string[];

for (let k = 0; k < resp_same_verify.length; k++) {
const data = resp_same_verify[k];
assert.equal(
data,
'code not found',
'verify same identities to one account should fail with reason `code not found`'
);
}
await checkFailReason(resp_same_verify, 'code not found', false);

//verify an identity to an account but it isn't created before
const resp_not_exist_verify = (await verifyErrorIdentities(
Expand All @@ -270,15 +261,7 @@ describeLitentry('Test Identity', (context) => {
[twitterIdentity, ethereumIdentity, substrateIdentity],
[twitterValidationData, ethereumValidationData, substrateValidationData]
)) as string[];

for (let l = 0; l < resp_not_exist_verify.length; l++) {
const data = resp_not_exist_verify[l];
assert.equal(
data,
'code not found',
'verify nonexistent identity should fail with reason `code not found`'
);
}
await checkFailReason(resp_not_exist_verify, 'code not found', false);
});

step('remove identities', async function () {
Expand Down Expand Up @@ -358,54 +341,46 @@ describeLitentry('Test Identity', (context) => {
});

step('remove error identities', async function () {
//remove a nonexistent identity from an account
const resp_not_exist_identities = (await removeErrorIdentities(context, context.defaultSigner[0], true, [
twitterIdentity,
ethereumIdentity,
substrateIdentity,
])) as string[];
const identities = [twitterIdentity, ethereumIdentity, substrateIdentity];

resp_not_exist_identities.map((item: any) => {
const result = item.toHuman().data.reason;
assert(
result.search('IdentityNotExist') !== -1,
'remove twitter should fail with reason `IdentityNotExist`'
);
});
//remove a nonexistent identity
//context.defaultSigner[0] has aleady removed all identities in step('remove identities')
const resp_not_exist_identities = (await removeErrorIdentities(
context,
context.defaultSigner[0],
true,
identities
)) as string[];

await checkFailReason(resp_not_exist_identities, 'IdentityNotExist', true);

//remove a challenge code before the code is set
const resp_not_created_identities = (await removeErrorIdentities(context, context.defaultSigner[2], true, [
twitterIdentity,
ethereumIdentity,
substrateIdentity,
])) as string[];
//context.defaultSigner[2] doesn't have a challenge code
const resp_not_created_identities = (await removeErrorIdentities(
context,
context.defaultSigner[2],
true,
identities
)) as string[];

resp_not_created_identities.map((item: any) => {
const result = item.toHuman().data.reason;
assert(
result.search('IdentityNotExist') !== -1,
'remove twitter should fail with reason `IdentityNotExist`'
);
});
await checkFailReason(resp_not_created_identities, 'IdentityNotExist', true);
});

step('set error user shielding key', async function () {
const result = await setErrorUserShieldingKey(context, context.defaultSigner[0], errorAseKey, true);
assert.equal(
result,
'SetUserShieldingKeyHandlingFailed',
'result is not equal to SetUserShieldingKeyHandlingFailed'
const resp_error_shielding_key = await setErrorUserShieldingKey(
context,
context.defaultSigner[0],
errorAseKey,
true
);
await checkFailReason([resp_error_shielding_key] as string[], 'SetUserShieldingKeyHandlingFailed', false);
});

step('create error identities', async function () {
//The simulation generates the wrong Ciphertext
const resp_error_identities = (await createErrorIdentities(context, context.defaultSigner[0], true, [
errorCiphertext,
])) as string[];
for (let i = 0; i < resp_error_identities.length; i++) {
const result = resp_error_identities[i];
assert.equal(result, 'CreateIdentityHandlingFailed', 'result is not equal to CreateIdentityHandlingFailed');
}
await checkFailReason(resp_error_identities, 'CreateIdentityHandlingFailed', false);
});
});
80 changes: 77 additions & 3 deletions tee-worker/ts-tests/indirect_error_calls.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { encryptWithTeeShieldingKey, listenEvent, sendTxUntilInBlock, sendTxUntilInBlockList } from './utils';
import { KeyringPair } from '@polkadot/keyring/types';
import { HexString } from '@polkadot/util/types';
import { Event } from '@polkadot/types/interfaces';

import {
Assertion,
IntegrationTestContext,
LitentryIdentity,
LitentryValidationData,
Expand Down Expand Up @@ -37,6 +40,8 @@ export async function createErrorIdentities(
errorCiphertexts: string[]
): Promise<string[] | undefined> {
let txs: TransactionSubmit[] = [];
const nonce = await context.substrate.rpc.system.accountNextIndex(signer.address);

for (let k = 0; k < errorCiphertexts.length; k++) {
const errorCiphertext = errorCiphertexts[k];
const tx = context.substrate.tx.identityManagement.createIdentity(
Expand All @@ -46,7 +51,6 @@ export async function createErrorIdentities(
null
);

const nonce = await context.substrate.rpc.system.accountNextIndex(signer.address);
let newNonce = nonce.toNumber() + k;
txs.push({
tx,
Expand Down Expand Up @@ -78,6 +82,8 @@ export async function verifyErrorIdentities(
datas: LitentryValidationData[]
): Promise<string[] | undefined> {
let txs: TransactionSubmit[] = [];
const nonce = await context.substrate.rpc.system.accountNextIndex(signer.address);

for (let k = 0; k < identities.length; k++) {
let identity = identities[k];
let data = datas[k];
Expand All @@ -96,7 +102,6 @@ export async function verifyErrorIdentities(
`0x${validation_ciphertext}`
);

const nonce = await context.substrate.rpc.system.accountNextIndex(signer.address);
let newNonce = nonce.toNumber() + k;
txs.push({
tx,
Expand Down Expand Up @@ -126,12 +131,13 @@ export async function removeErrorIdentities(
identities: any[]
): Promise<any[] | undefined> {
let txs: TransactionSubmit[] = [];
const nonce = await context.substrate.rpc.system.accountNextIndex(signer.address);

for (let index = 0; index < identities.length; index++) {
const identity = identities[index];
const encode = context.substrate.createType('LitentryIdentity', identity).toHex();
const ciphertext = encryptWithTeeShieldingKey(context.teeShieldingKey, encode).toString('hex');
const tx = context.substrate.tx.identityManagement.removeIdentity(context.mrEnclave, `0x${ciphertext}`);
const nonce = await context.substrate.rpc.system.accountNextIndex(signer.address);
let newNonce = nonce.toNumber() + index;

txs.push({
Expand All @@ -149,3 +155,71 @@ export async function removeErrorIdentities(
}
return undefined;
}
export async function requestErrorVCs(
context: IntegrationTestContext,
signer: KeyringPair,
aesKey: HexString,
listening: boolean,
mrEnclave: HexString,
assertion: Assertion,
keys: string[]
): Promise<Event[] | undefined> {
let txs: TransactionSubmit[] = [];
const nonce = await context.substrate.rpc.system.accountNextIndex(signer.address);

for (let index = 0; index < keys.length; index++) {
const key = keys[index];
const tx = context.substrate.tx.vcManagement.requestVc(mrEnclave, {
[key]: assertion[key as keyof Assertion],
});
let newNonce = nonce.toNumber() + index;
txs.push({ tx, nonce: newNonce });
}

await sendTxUntilInBlockList(context.substrate, txs, signer);

if (listening) {
const events = (await listenEvent(context.substrate, 'vcManagement', ['StfError'])) as Event[];
expect(events.length).to.be.equal(keys.length);
return events;
}
return undefined;
}
export async function disableErrorVCs(
context: IntegrationTestContext,
signer: KeyringPair,
listening: boolean,
indexList: HexString[]
): Promise<string[] | undefined> {
let txs: TransactionSubmit[] = [];
const nonce = await context.substrate.rpc.system.accountNextIndex(signer.address);

for (let k = 0; k < indexList.length; k++) {
const tx = context.substrate.tx.vcManagement.disableVc(indexList[k]);
let newNonce = nonce.toNumber() + k;
txs.push({ tx, nonce: newNonce });
}

const res = (await sendTxUntilInBlockList(context.substrate, txs, signer)) as string[];

return res.length ? res : undefined;
}
export async function revokeErrorVCs(
context: IntegrationTestContext,
signer: KeyringPair,
listening: boolean,
indexList: HexString[]
): Promise<string[] | undefined> {
let txs: TransactionSubmit[] = [];
const nonce = await context.substrate.rpc.system.accountNextIndex(signer.address);

for (let k = 0; k < indexList.length; k++) {
const tx = context.substrate.tx.vcManagement.revokeVc(indexList[k]);
let newNonce = nonce.toNumber() + k;
txs.push({ tx, nonce: newNonce });
}

const res = (await sendTxUntilInBlockList(context.substrate, txs, signer)) as string[];

return res.length ? res : undefined;
}
63 changes: 47 additions & 16 deletions tee-worker/ts-tests/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
teeTypes,
WorkerRpcReturnValue,
TransactionSubmit,
JsonSchema,
JsonSchema
} from './type-definitions';
import { blake2AsHex, cryptoWaitReady } from '@polkadot/util-crypto';
import { ApiTypes, SubmittableExtrinsic } from '@polkadot/api/types';
Expand All @@ -25,7 +25,7 @@ import { after, before, describe } from 'mocha';
import { generateChallengeCode, getSigner } from './web3/setup';
import { ethers } from 'ethers';
import { generateTestKeys } from './web3/functions';
import { expect } from 'chai';
import { assert, expect } from 'chai';
import { Base64 } from 'js-base64';
import Ajv from 'ajv';
import * as ed from '@noble/ed25519';
Expand Down Expand Up @@ -121,25 +121,37 @@ export async function sendTxUntilInBlock(api: ApiPromise, tx: SubmittableExtrins
}

export async function sendTxUntilInBlockList(api: ApiPromise, txs: TransactionSubmit[], signer: KeyringPair) {
return new Promise<{
block: string;
}>(async (resolve, reject) => {
await Promise.all(
txs.map(async ({ tx, nonce }) => {
// await tx.paymentInfo(signer);
return Promise.all(
txs.map(async ({ tx, nonce }) => {
const result = await new Promise((resolve, reject) => {
tx.signAndSend(signer, { nonce }, (result) => {
if (result.status.isInBlock) {
console.log(`Transaction included at blockHash ${result.status.asInBlock}`);
resolve({
block: result.status.asInBlock.toString(),
});
//catch error
if (result.dispatchError) {
if (result.dispatchError.isModule) {
const decoded = api.registry.findMetaError(result.dispatchError.asModule);
const { docs, name, section } = decoded;

console.log(`${section}.${name}: ${docs.join(' ')}`);
resolve(`${section}.${name}`);
} else {
console.log(result.dispatchError.toString());
resolve(result.dispatchError.toString());
}
} else {
console.log(`Transaction included at blockHash ${result.status.asInBlock}`);
resolve({
block: result.status.asInBlock.toString(),
});
}
} else if (result.status.isInvalid) {
reject(`Transaction is ${result.status}`);
}
});
})
);
});
});
return result;
})
);
}

// Subscribe to the chain until we get the first specified event with given `section` and `methods`.
Expand Down Expand Up @@ -367,11 +379,30 @@ export async function checkJSON(vc: any, proofJson: any): Promise<boolean> {
const validate = ajv.compile(JsonSchema);
const isValid = validate(vc);
expect(isValid).to.be.true;

expect(
vc.type[0] === 'VerifiableCredential' &&
vc.issuer.id === proofJson.verificationMethod &&
proofJson.type === 'Ed25519Signature2020'
).to.be.true;
return true;
}

export async function checkFailReason(
response: string[] | Event[],
expectedReason: string,
isModule: boolean
): Promise<boolean> {

let failReason = '';

response.map((item: any) => {
isModule ? (failReason = item.toHuman().data.reason) : (failReason = item);

assert.notEqual(
failReason.search(expectedReason),
-1,
`check fail reason failed, expected reason is ${expectedReason}, but got ${failReason}`
);
});
return true;
}
Loading