Skip to content

Commit

Permalink
extended catch error flow
Browse files Browse the repository at this point in the history
  • Loading branch information
vadiminc committed Dec 27, 2023
1 parent 0272ae8 commit 3415d9d
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 34 deletions.
2 changes: 1 addition & 1 deletion dist/tsc/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ssv-keys",
"version": "1.0.6",
"version": "1.0.7",
"description": "Tool for splitting a validator key into a predefined threshold of shares via Shamir-Secret-Sharing (SSS), and encrypt them with a set of operator keys.",
"author": "SSV.Network",
"repository": "https://github.com/bloxapp/ssv-keys",
Expand Down
17 changes: 14 additions & 3 deletions examples/console/example-complex.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const path = require('path');
const fsp = require('fs').promises;
const { SSVKeys, KeyShares, KeySharesItem } = require('ssv-keys');
const { SSVKeys, KeyShares, KeySharesItem, SSVKeysException } = require('ssv-keys');

const operatorKeys = require('./operators.json');
const keystore = require('./test.keystore.json');
Expand Down Expand Up @@ -66,8 +66,19 @@ async function main() {
const jsonKeyShares = await fsp.readFile(getKeySharesFilePath(4), { encoding: 'utf-8' });

const keyShares2 = await KeyShares.fromJson(jsonKeyShares);

console.log('KeyShares list', keyShares2.list().map(item => item.toJson()));
for (const keySharesItem of keyShares2.list()) {
if (keySharesItem.error) {
if (keySharesItem.error instanceof SSVKeysException) {
console.log('SSVKeys Error name:', keySharesItem.error.name);
console.log('SSVKeys Error message:', keySharesItem.error.message);
console.log('SSVKeys Error trace:', keySharesItem.error.trace);
} else {
// Handle other types of errors
console.log('Other Error caught:', keySharesItem.error);
}
}
console.log(keySharesItem.toJson());
}
}

void main();
29 changes: 15 additions & 14 deletions examples/console/example-ts.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SSVKeys, KeyShares, KeySharesItem, SSVKeysException } from 'ssv-keys';
import { SSVKeys, KeyShares, KeySharesItem, SSVKeysException } from '../../src/main';

const path = require('path');
const fsp = require('fs').promises;
Expand Down Expand Up @@ -63,20 +63,21 @@ async function main() {
await fsp.writeFile(getKeySharesFilePath(4), keyShares.toJson(), { encoding: 'utf-8' });

// example to work with keyshares from file
const jsonKeyShares = await fsp.readFile(getKeySharesFilePath(4), { encoding: 'utf-8' });

try {
const keyShares2 = await KeyShares.fromJson(jsonKeyShares);
console.log('Created keyShares list from json', keyShares2.list().map(item => item.toJson()));
} catch (e: any) {
if (e instanceof SSVKeysException) {
console.log('SSVKeys Error name:', e.name);
console.log('SSVKeys Error message:', e.message);
console.log('SSVKeys Error trace:', e.trace);
} else {
// Handle other types of errors
console.log('Other Error caught:', e.message);
const jsonKeyShares = await fsp.readFile('./data/test-error.json', { encoding: 'utf-8' });

const keyShares2 = await KeyShares.fromJson(jsonKeyShares);
for (const keySharesItem of keyShares2.list()) {
if (keySharesItem.error) {
if (keySharesItem.error instanceof SSVKeysException) {
console.log('SSVKeys Error name:', keySharesItem.error.name);
console.log('SSVKeys Error message:', keySharesItem.error.message);
console.log('SSVKeys Error trace:', keySharesItem.error.trace);
} else {
// Handle other types of errors
console.log('Other Error caught:', keySharesItem.error);
}
}
console.log(keySharesItem.toJson());
}
}

Expand Down
1 change: 0 additions & 1 deletion src/lib/KeyShares/KeyShares.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ export class KeyShares {
// Handle old format (single item)
instance.shares.push(await KeySharesItem.fromJson(body));
}

return instance;
}
}
32 changes: 22 additions & 10 deletions src/lib/KeyShares/KeySharesItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ export class KeySharesItem {
@ValidateNested()
public payload: KeySharesPayload;

@IsOptional()
public error: SSVKeysException | null = null;

constructor() {
this.data = new KeySharesData();
this.payload = new KeySharesPayload();
Expand Down Expand Up @@ -170,6 +173,7 @@ export class KeySharesItem {
return JSON.stringify({
data: this.data || null,
payload: this.payload || null,
error: this.error || null,
}, null, 2);
}

Expand All @@ -190,16 +194,24 @@ export class KeySharesItem {
static async fromJson(content: string | any): Promise<KeySharesItem> {
const body = typeof content === 'string' ? JSON.parse(content) : content;
const instance = new KeySharesItem();
instance.data.update(body.data);
instance.payload.update(body.payload);
instance.validate();
// Custom validation: verify signature
await instance.validateSingleShares(instance.payload.sharesData, {
ownerAddress: instance.data.ownerAddress as string,
ownerNonce: instance.data.ownerNonce as number,
publicKey: instance.data.publicKey as string,
});

try {
instance.data.update(body.data);
instance.payload.update(body.payload);
instance.validate();
// Custom validation: verify signature
await instance.validateSingleShares(instance.payload.sharesData, {
ownerAddress: instance.data.ownerAddress as string,
ownerNonce: instance.data.ownerNonce as number,
publicKey: instance.data.publicKey as string,
});
} catch (e: any) {
// Assuming SSVKeysException is a class or interface you've defined
if (e instanceof SSVKeysException) {
instance.error = e;
} else {
instance.error = e;
}
}
return instance;
}
}
12 changes: 7 additions & 5 deletions src/lib/KeyShares/__test__/KeyShares.json.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ describe('KeyShares.fromJson/toJson', () => {
});

it('Should throw an error for invalid operator data', async () => {
expect(async() => await KeySharesItem.fromJson(mockKeySharesItemWithMissedOperatorKey)).rejects.toThrow(OperatorsCountsMismatchError);
expect(async() => await KeySharesItem.fromJson(mockKeySharesItemWithWrongOperatorId)).rejects.toThrow(OperatorsCountsMismatchError);
expect(async() => await KeySharesItem.fromJson(mockKeySharesItemWithDuplicatedOperatorKey)).rejects.toThrow(DuplicatedOperatorPublicKeyError);
expect((await KeySharesItem.fromJson(mockKeySharesItemWithMissedOperatorKey)).error).toBeInstanceOf(OperatorsCountsMismatchError);
expect((await KeySharesItem.fromJson(mockKeySharesItemWithWrongOperatorId)).error).toBeInstanceOf(OperatorsCountsMismatchError);
expect((await KeySharesItem.fromJson(mockKeySharesItemWithDuplicatedOperatorKey)).error).toBeInstanceOf(DuplicatedOperatorPublicKeyError);
});

it('Should create KeyShares Item', async () => {
Expand Down Expand Up @@ -79,7 +79,8 @@ describe('KeyShares.fromJson/toJson', () => {
});

it('should throw error on invalid JSON format', async () => {
await expect(KeyShares.fromJson(mockKeySharesInvalidStruct)).rejects.toThrow();
const keyShares = await KeyShares.fromJson(mockKeySharesInvalidStruct);
expect(keyShares.list()[0].error).not.toBeNull();
});

it('should throw error on version incompatibility', async () => {
Expand All @@ -95,6 +96,7 @@ describe('KeyShares.fromJson/toJson', () => {
...mockKeyShares,
shares: [{ "invalid": "data" }],
};
await expect(KeyShares.fromJson(invalidSharesJson)).rejects.toThrow();
const keyShares = await KeyShares.fromJson(invalidSharesJson);
expect(keyShares.list()[0].error).not.toBeNull();
});
});

0 comments on commit 3415d9d

Please sign in to comment.