From 5c70bd28fbddfdfbfc5b4f58ddcf838369c2d0f2 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Fri, 29 Mar 2024 15:26:54 -0700 Subject: [PATCH 01/41] [worker] test simple websocket connection --- packages/worker-api/src/worker.spec.ts | 32 ++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/packages/worker-api/src/worker.spec.ts b/packages/worker-api/src/worker.spec.ts index 73aec95b..a27f2dfa 100644 --- a/packages/worker-api/src/worker.spec.ts +++ b/packages/worker-api/src/worker.spec.ts @@ -56,7 +56,7 @@ describe('worker', () => { // skip it, as this requires a worker (and hence a node) to be running // To my knowledge jest does not have an option to run skipped tests specifically, does it? // Todo: add proper CI to test this too. - describe.skip('needs worker and node running', () => { + describe('needs worker and node running', () => { describe('getWorkerPubKey', () => { it('should return value', async () => { const result = await worker.getShieldingKey(); @@ -65,8 +65,36 @@ describe('worker', () => { }); }); + describe('openAndCloseWorks', () => { + it('should return value', async () => { + + let unresolvedPromise = new Promise((resolve, _) => { + const ws = new WebSocket("wss://127.0.0.1:2000", 'tls'); + + ws.onopen = () => { + console.log('WebSocket opened'); + ws.send("hello"); + ws.close(); + resolve(""); + }; + + ws.onmessage = (message) => { + console.log('Received message:', message.data); + }; + + ws.onclose = () => { + console.log('WebSocket closed'); + }; + }); + + await unresolvedPromise; + console.log("Test finished") + }); + }); + + describe('getTotalIssuance', () => { - it('should return value', async () => { + it('should return value', async () => { const result = await worker.getTotalIssuance(network.chosenCid); // console.log('getTotalIssuance', result); expect(result).toBeDefined(); From e7ba030ad6bd9ae52d7fdffcc684d10d304e15c8 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Fri, 29 Mar 2024 15:27:10 -0700 Subject: [PATCH 02/41] [jest] allow any kind of certificate --- jest.config.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/jest.config.js b/jest.config.js index 7a94c87d..d15feaca 100644 --- a/jest.config.js +++ b/jest.config.js @@ -6,6 +6,11 @@ const fs = require("fs"); const { defaults } = require("jest-config"); +const https = require('https'); + +// Override certificate validation to accept all certificates (including self-signed ones) +https.globalAgent.options.rejectUnauthorized = false; + module.exports = { moduleFileExtensions: [...defaults.moduleFileExtensions, "ts", "tsx"], modulePathIgnorePatterns: [ From 8d32315d318251c7838bebb75f38e70a8da47297 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Fri, 29 Mar 2024 15:27:54 -0700 Subject: [PATCH 03/41] [worker] update get balance to just get regular balance of incognito accounts --- packages/worker-api/src/worker.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/worker-api/src/worker.ts b/packages/worker-api/src/worker.ts index 24118c04..29c3ac40 100644 --- a/packages/worker-api/src/worker.ts +++ b/packages/worker-api/src/worker.ts @@ -16,7 +16,7 @@ import type { KeyringPair } from '@polkadot/keyring/types'; import type { Vec, u32, u64 } from '@polkadot/types'; import type { AccountId, Balance, Moment } from '@polkadot/types/interfaces/runtime'; import type { - Attestation, BalanceEntry, BalanceTransferArgs, CommunityIdentifier, GrantReputationArgs, + Attestation, BalanceTransferArgs, CommunityIdentifier, GrantReputationArgs, MeetupIndexType, ParticipantIndexType, RegisterAttestationsArgs, RegisterParticipantArgs, SchedulerState, TrustedCallSigned @@ -153,8 +153,8 @@ export class EncointerWorker extends WebSocketAsPromised implements IEncointerWo return await callGetter(this, [Request.PublicGetter, 'scheduler_state', 'SchedulerState'], {cid}, options) } - public async getBalance(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: CallOptions = {} as CallOptions): Promise { - return await callGetter(this, [Request.TrustedGetter, 'balance', 'BalanceEntry'], { + public async getBalance(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: CallOptions = {} as CallOptions): Promise { + return await callGetter(this, [Request.TrustedGetter, 'free_balance', 'Balance'], { cid, account: toAccount(accountOrPubKey, this.#keyring) }, options) From e49ed8a6f603d87c1c045e2b6e04cd09876cef17 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Fri, 29 Mar 2024 15:28:13 -0700 Subject: [PATCH 04/41] [network] update localDockerNetwork to be correct --- packages/worker-api/src/testUtils/networks.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/worker-api/src/testUtils/networks.ts b/packages/worker-api/src/testUtils/networks.ts index f89dd907..e7ea96c6 100644 --- a/packages/worker-api/src/testUtils/networks.ts +++ b/packages/worker-api/src/testUtils/networks.ts @@ -36,13 +36,13 @@ export const chainbrickNetwork = () => { // Note: `mrenclave` is not deterministic, this needs to be edited for every worker build. export const localDockerNetwork = () => { return { - chain: 'ws://127.0.0.1:9979', - worker: 'ws://127.0.0.1:2079', + chain: 'ws://127.0.0.1:9944', + worker: 'wss://127.0.0.1:2000', genesisHash: '0x388c446a804e24e77ae89f5bb099edb60cacc2ac7c898ce175bdaa08629c1439', - mrenclave: '4SkU25tusVChcrUprW8X22QoEgamCgj3HKQeje7j8Z4E', + mrenclave: 'HjkQuPjBn531Hkji2Dsj4CEYCGpqCc3aXqETMCM7x7z4', chosenCid: '4Xgnkpg4RwXjFegLzYKgY6Y3jCSPmxyPmNvfs42Uvsuh', - customTypes: TypeOverrides_V3_8, - palletOverrides: PalletOverrides_V3_8 + customTypes: {}, + palletOverrides: {} }; }; From 376899694f0f6481723cb5eecf3917ebbc98440c Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Tue, 2 Apr 2024 15:52:19 -0700 Subject: [PATCH 05/41] [worker.spec] successfully connect to the worker. --- packages/worker-api/src/worker.spec.ts | 46 ++++++++++++-------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/packages/worker-api/src/worker.spec.ts b/packages/worker-api/src/worker.spec.ts index a27f2dfa..1779ad41 100644 --- a/packages/worker-api/src/worker.spec.ts +++ b/packages/worker-api/src/worker.spec.ts @@ -2,10 +2,9 @@ import { Keyring } from '@polkadot/api'; import { cryptoWaitReady } from '@polkadot/util-crypto'; import { localDockerNetwork } from './testUtils/networks.js'; import { EncointerWorker } from './worker.js'; -import WS from 'websocket'; +import WebSocket from 'ws'; import type { CommunityIdentifier } from "@encointer/types"; -const {w3cwebsocket: WebSocket} = WS; describe('worker', () => { const network = localDockerNetwork(); @@ -66,29 +65,26 @@ describe('worker', () => { }); describe('openAndCloseWorks', () => { - it('should return value', async () => { - - let unresolvedPromise = new Promise((resolve, _) => { - const ws = new WebSocket("wss://127.0.0.1:2000", 'tls'); - - ws.onopen = () => { - console.log('WebSocket opened'); - ws.send("hello"); - ws.close(); - resolve(""); - }; - - ws.onmessage = (message) => { - console.log('Received message:', message.data); - }; - - ws.onclose = () => { - console.log('WebSocket closed'); - }; - }); - - await unresolvedPromise; - console.log("Test finished") + it('should return value', function (done) { + // Create WebSocket client + const ws = new WebSocket(network.worker, { + rejectUnauthorized: false, + }); + + ws.on('open', () => { + // Send a message to the server + ws.send('Hello, server!'); + }); + + ws.on('message', (message) => { + console.log(`Received message from server: ${message}`); + // Assert that the server echoes the message back + expect(message).toBe('Hello, server!'); + + // Close the WebSocket client and server + ws.close(); + done() + }); }); }); From 9b7585449c5a49cc734f9a4cfca62cd3499a1611 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Tue, 2 Apr 2024 15:56:04 -0700 Subject: [PATCH 06/41] Revert "[worker.spec] successfully connect to the worker." This reverts commit 376899694f0f6481723cb5eecf3917ebbc98440c. --- packages/worker-api/src/worker.spec.ts | 46 ++++++++++++++------------ 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/packages/worker-api/src/worker.spec.ts b/packages/worker-api/src/worker.spec.ts index 1779ad41..a27f2dfa 100644 --- a/packages/worker-api/src/worker.spec.ts +++ b/packages/worker-api/src/worker.spec.ts @@ -2,9 +2,10 @@ import { Keyring } from '@polkadot/api'; import { cryptoWaitReady } from '@polkadot/util-crypto'; import { localDockerNetwork } from './testUtils/networks.js'; import { EncointerWorker } from './worker.js'; -import WebSocket from 'ws'; +import WS from 'websocket'; import type { CommunityIdentifier } from "@encointer/types"; +const {w3cwebsocket: WebSocket} = WS; describe('worker', () => { const network = localDockerNetwork(); @@ -65,26 +66,29 @@ describe('worker', () => { }); describe('openAndCloseWorks', () => { - it('should return value', function (done) { - // Create WebSocket client - const ws = new WebSocket(network.worker, { - rejectUnauthorized: false, - }); - - ws.on('open', () => { - // Send a message to the server - ws.send('Hello, server!'); - }); - - ws.on('message', (message) => { - console.log(`Received message from server: ${message}`); - // Assert that the server echoes the message back - expect(message).toBe('Hello, server!'); - - // Close the WebSocket client and server - ws.close(); - done() - }); + it('should return value', async () => { + + let unresolvedPromise = new Promise((resolve, _) => { + const ws = new WebSocket("wss://127.0.0.1:2000", 'tls'); + + ws.onopen = () => { + console.log('WebSocket opened'); + ws.send("hello"); + ws.close(); + resolve(""); + }; + + ws.onmessage = (message) => { + console.log('Received message:', message.data); + }; + + ws.onclose = () => { + console.log('WebSocket closed'); + }; + }); + + await unresolvedPromise; + console.log("Test finished") }); }); From 641858a786fb17f4b0e13aa6feaa984cddffe9a3 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Fri, 5 Apr 2024 11:42:51 +0800 Subject: [PATCH 07/41] [worker.spec] connect to worker with original implementation; protocol changes needed. --- packages/worker-api/src/worker.spec.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/worker-api/src/worker.spec.ts b/packages/worker-api/src/worker.spec.ts index a27f2dfa..6ff2815b 100644 --- a/packages/worker-api/src/worker.spec.ts +++ b/packages/worker-api/src/worker.spec.ts @@ -24,7 +24,13 @@ describe('worker', () => { keyring: keyring, types: network.customTypes, // @ts-ignore - createWebSocket: (url) => new WebSocket(url), + createWebSocket: (url) => new WebSocket( + url, + undefined, + undefined, + undefined, + { rejectUnauthorized: false } + ), api: null, }); }); From a5a2222c088ab9e3dff01576e1bacf3d030ef1e6 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Fri, 5 Apr 2024 12:41:18 +0800 Subject: [PATCH 08/41] [worker] implement new trusted rpc protocol and successfully fetch the shielding key --- .../types/src/interfaces/augment-types.ts | 6 ++- .../src/interfaces/worker/definitions.ts | 28 +++++++++++-- packages/types/src/interfaces/worker/types.ts | 40 +++++++++++++++---- packages/worker-api/src/getterApi.ts | 18 +++++---- packages/worker-api/src/interface.ts | 16 ++++++++ packages/worker-api/src/worker.ts | 18 +++++++-- 6 files changed, 101 insertions(+), 25 deletions(-) diff --git a/packages/types/src/interfaces/augment-types.ts b/packages/types/src/interfaces/augment-types.ts index 090019e3..bcc1218b 100644 --- a/packages/types/src/interfaces/augment-types.ts +++ b/packages/types/src/interfaces/augment-types.ts @@ -11,7 +11,7 @@ import type { Assignment, AssignmentCount, AssignmentParams, Attestation, Attest import type { FixedI64F64, IpfsCid, PalletString } from '@encointer/types/interfaces/common'; import type { AnnouncementSigner, Bip340, CidDigest, CidName, CommunityCeremony, CommunityIdentifier, CommunityMetadataType, CommunityRules, DegreeFixed, DegreeRpc, GeoHash, Location, LocationRpc, NominalIncomeType } from '@encointer/types/interfaces/community'; import type { SchedulerState, SystemNumber } from '@encointer/types/interfaces/scheduler'; -import type { BalanceTransferArgs, ClientRequest, Enclave, Getter, GetterArgs, GrantReputationArgs, PublicGetter, RegisterAttestationsArgs, RegisterParticipantArgs, Request, ShardIdentifier, TrustedCall, TrustedCallSigned, TrustedGetter, TrustedGetterSigned, WorkerEncoded } from '@encointer/types/interfaces/worker'; +import type { BalanceTransferArgs, DirectRequestStatus, Enclave, Getter, GetterArgs, GrantReputationArgs, PublicGetter, RegisterAttestationsArgs, RegisterParticipantArgs, Request, RpcReturnValue, ShardIdentifier, TrustedCall, TrustedCallSigned, TrustedGetter, TrustedGetterSigned, TrustedOperationStatus, WorkerEncoded } from '@encointer/types/interfaces/worker'; import type { Data, StorageKey } from '@polkadot/types'; import type { BitVec, Bool, Bytes, F32, F64, I128, I16, I256, I32, I64, I8, ISize, Json, Null, OptionBool, Raw, Text, Type, U128, U16, U256, U32, U64, U8, USize, bool, f32, f64, i128, i16, i256, i32, i64, i8, isize, u128, u16, u256, u32, u64, u8, usize } from '@polkadot/types-codec'; import type { AssetApproval, AssetApprovalKey, AssetBalance, AssetDestroyWitness, AssetDetails, AssetMetadata, TAssetBalance, TAssetDepositBalance } from '@polkadot/types/interfaces/assets'; @@ -242,7 +242,6 @@ declare module '@polkadot/types/types/registry' { ClassDetails: ClassDetails; ClassId: ClassId; ClassMetadata: ClassMetadata; - ClientRequest: ClientRequest; CodecHash: CodecHash; CodeHash: CodeHash; CodeSource: CodeSource; @@ -367,6 +366,7 @@ declare module '@polkadot/types/types/registry' { Digest: Digest; DigestItem: DigestItem; DigestOf: DigestOf; + DirectRequestStatus: DirectRequestStatus; DispatchClass: DispatchClass; DispatchError: DispatchError; DispatchErrorModule: DispatchErrorModule; @@ -947,6 +947,7 @@ declare module '@polkadot/types/types/registry' { RoundSnapshot: RoundSnapshot; RoundState: RoundState; RpcMethods: RpcMethods; + RpcReturnValue: RpcReturnValue; RuntimeApiMetadataLatest: RuntimeApiMetadataLatest; RuntimeApiMetadataV15: RuntimeApiMetadataV15; RuntimeApiMethodMetadataV15: RuntimeApiMethodMetadataV15; @@ -1156,6 +1157,7 @@ declare module '@polkadot/types/types/registry' { TrustedCallSigned: TrustedCallSigned; TrustedGetter: TrustedGetter; TrustedGetterSigned: TrustedGetterSigned; + TrustedOperationStatus: TrustedOperationStatus; Type: Type; u128: u128; U128: U128; diff --git a/packages/types/src/interfaces/worker/definitions.ts b/packages/types/src/interfaces/worker/definitions.ts index cc3c5e79..3609b686 100644 --- a/packages/types/src/interfaces/worker/definitions.ts +++ b/packages/types/src/interfaces/worker/definitions.ts @@ -39,11 +39,31 @@ export default { trusted: 'TrustedGetterSigned' } }, - ClientRequest: { + RpcReturnValue: { + value: 'Vec', + do_watch: 'bool', + status: 'DirectRequestStatus' + }, + DirectRequestStatus: { + _enum: { + Ok: null, + TrustedOperationStatus: 'TrustedOperationStatus', + Error: null + } + }, + TrustedOperationStatus: { _enum: { - PubKeyWorker: null, - MuRaPortWorker: null, - StfState: '(Getter, ShardIdentifier)' + Submitted: null, + Future: null, + Ready: null, + BroadCast: null, + InSidechainBlock: 'Hash', + Retracted: null, + FinalityTimeout: null, + Finalized: null, + Usurped: null, + Dropped: null, + Invalid: null } }, WorkerEncoded: 'Vec', diff --git a/packages/types/src/interfaces/worker/types.ts b/packages/types/src/interfaces/worker/types.ts index 532a6884..633851f9 100644 --- a/packages/types/src/interfaces/worker/types.ts +++ b/packages/types/src/interfaces/worker/types.ts @@ -4,7 +4,7 @@ import type { BalanceType } from '@encointer/types/interfaces/balances'; import type { Attestation, ProofOfAttendance } from '@encointer/types/interfaces/ceremony'; import type { CommunityIdentifier } from '@encointer/types/interfaces/community'; -import type { Bytes, Enum, Option, Struct, Text, Vec, u32, u64 } from '@polkadot/types-codec'; +import type { Bytes, Enum, Option, Struct, Text, Vec, bool, u32, u64 } from '@polkadot/types-codec'; import type { ITuple } from '@polkadot/types-codec/types'; import type { Signature } from '@polkadot/types/interfaces/extrinsics'; import type { AccountId, Hash } from '@polkadot/types/interfaces/runtime'; @@ -12,13 +12,13 @@ import type { AccountId, Hash } from '@polkadot/types/interfaces/runtime'; /** @name BalanceTransferArgs */ export interface BalanceTransferArgs extends ITuple<[AccountId, AccountId, CommunityIdentifier, BalanceType]> {} -/** @name ClientRequest */ -export interface ClientRequest extends Enum { - readonly isPubKeyWorker: boolean; - readonly isMuRaPortWorker: boolean; - readonly isStfState: boolean; - readonly asStfState: ITuple<[Getter, ShardIdentifier]>; - readonly type: 'PubKeyWorker' | 'MuRaPortWorker' | 'StfState'; +/** @name DirectRequestStatus */ +export interface DirectRequestStatus extends Enum { + readonly isOk: boolean; + readonly isTrustedOperationStatus: boolean; + readonly asTrustedOperationStatus: TrustedOperationStatus; + readonly isError: boolean; + readonly type: 'Ok' | 'TrustedOperationStatus' | 'Error'; } /** @name Enclave */ @@ -75,6 +75,13 @@ export interface Request extends Struct { readonly cyphertext: WorkerEncoded; } +/** @name RpcReturnValue */ +export interface RpcReturnValue extends Struct { + readonly value: Bytes; + readonly do_watch: bool; + readonly status: DirectRequestStatus; +} + /** @name ShardIdentifier */ export interface ShardIdentifier extends Hash {} @@ -119,6 +126,23 @@ export interface TrustedGetterSigned extends Struct { readonly signature: Signature; } +/** @name TrustedOperationStatus */ +export interface TrustedOperationStatus extends Enum { + readonly isSubmitted: boolean; + readonly isFuture: boolean; + readonly isReady: boolean; + readonly isBroadCast: boolean; + readonly isInSidechainBlock: boolean; + readonly asInSidechainBlock: Hash; + readonly isRetracted: boolean; + readonly isFinalityTimeout: boolean; + readonly isFinalized: boolean; + readonly isUsurped: boolean; + readonly isDropped: boolean; + readonly isInvalid: boolean; + readonly type: 'Submitted' | 'Future' | 'Ready' | 'BroadCast' | 'InSidechainBlock' | 'Retracted' | 'FinalityTimeout' | 'Finalized' | 'Usurped' | 'Dropped' | 'Invalid'; +} + /** @name WorkerEncoded */ export interface WorkerEncoded extends Bytes {} diff --git a/packages/worker-api/src/getterApi.ts b/packages/worker-api/src/getterApi.ts index 0ef66cd4..a7c00706 100644 --- a/packages/worker-api/src/getterApi.ts +++ b/packages/worker-api/src/getterApi.ts @@ -1,4 +1,12 @@ -import type { IEncointerWorker, TrustedGetterArgs, PublicGetterArgs, RequestArgs, CallOptions, WorkerMethod } from './interface.js'; +import { + type IEncointerWorker, + type TrustedGetterArgs, + type PublicGetterArgs, + type RequestArgs, + type CallOptions, + type WorkerMethod, + createJsonRpcRequest +} from './interface.js'; import { Request } from './interface.js'; const sendWorkerRequest = (self: IEncointerWorker, clientRequest: any, parserType: string, options: CallOptions): Promise =>{ @@ -11,12 +19,6 @@ const sendWorkerRequest = (self: IEncointerWorker, clientRequest: any, parserTyp ) } -const clientRequest = (self: IEncointerWorker, request: string) => { - return self.createType( 'ClientRequest', { - [request]: null - }); -} - const clientRequestGetter = (self: IEncointerWorker, request: string, args: PublicGetterArgs) => { const { cid } = args; const getter = self.createType('PublicGetter', { @@ -70,7 +72,7 @@ export const callGetter = async (self: IEncointerWorker, workerMethod: Worker result = sendPublicRequest(self, method, parserType, args as PublicGetterArgs, options) break; case Request.Worker: - result = sendWorkerRequest(self, clientRequest(self, method), parserType, options) + result = sendWorkerRequest(self, createJsonRpcRequest(method, [], 1), parserType, options) break; default: result = sendPublicRequest(self, method, parserType, args as PublicGetterArgs, options) diff --git a/packages/worker-api/src/interface.ts b/packages/worker-api/src/interface.ts index 03d1338b..9b42648c 100644 --- a/packages/worker-api/src/interface.ts +++ b/packages/worker-api/src/interface.ts @@ -10,6 +10,22 @@ export interface IEncointerWorker extends WebSocketAsPromised { open: () => Promise; } +export interface JsonRpcRequest { + jsonrpc: string; + method: string; + params?: any; + id: number | string; +} + +export function createJsonRpcRequest(method: string, params: any, id: number | string): JsonRpcRequest { + return { + jsonrpc: '2.0', + method: method, + params: params, + id: id + }; +} + export interface WorkerOptions { keyring?: Keyring; api: any; diff --git a/packages/worker-api/src/worker.ts b/packages/worker-api/src/worker.ts index 29c3ac40..54d3dd66 100644 --- a/packages/worker-api/src/worker.ts +++ b/packages/worker-api/src/worker.ts @@ -45,6 +45,14 @@ const parseGetterResponse = (self: IEncointerWorker, responseType: string, data: if (data === 'Could not decode request') { throw new Error(`Worker error: ${data}`); } + + console.log(`Getter response: ${data}`); + const json = JSON.parse(data); + + const value = hexToU8a(json["result"]); + const returnValue = self.createType('RpcReturnValue', value); + console.log(`RpcReturnValue ${JSON.stringify(returnValue)}`); + let parsedData: any; try { switch (responseType) { @@ -60,7 +68,11 @@ const parseGetterResponse = (self: IEncointerWorker, responseType: string, data: parsedData = parseI64F64(self.createType('i128', parsedData)); break; case 'NodeRSA': - parsedData = parseNodeRSA(data); + const jsonStr = self.createType('String', returnValue.value); + // Todo: For some reason there are 2 non-utf characters, where I don't know where + // they come from currently. + // console.log(`jsonStr.sub(2): ${jsonStr.toJSON().substring(2)}`); + parsedData = parseNodeRSA(jsonStr.toJSON().substring(2)); break default: parsedData = unwrapWorkerResponse(self, data); @@ -86,7 +98,7 @@ export class EncointerWorker extends WebSocketAsPromised implements IEncointerWo constructor(url: string, options: WorkerOptions = {} as WorkerOptions) { super(url, { createWebSocket: (options.createWebSocket || undefined), - packMessage: (data: any) => this.createType('ClientRequest', data).toU8a(), + packMessage: (data: any) => JSON.stringify(data), unpackMessage: (data: any) => parseGetterResponse(this, this.rqStack.shift() || '', data), attachRequestId: (data: any): any => data, extractRequestId: () => this.rsCount = ++this.rsCount @@ -122,7 +134,7 @@ export class EncointerWorker extends WebSocketAsPromised implements IEncointerWo } public async getShieldingKey(options: CallOptions = {} as CallOptions): Promise { - return await callGetter(this, [Request.Worker, 'PubKeyWorker', 'NodeRSA'], {}, options) + return await callGetter(this, [Request.Worker, 'author_getShieldingKey', 'NodeRSA'], {}, options) } public async getTotalIssuance(cid: string, options: CallOptions = {} as CallOptions): Promise { From 4125540bc8a2bcd18d6ffd1ad62b1a5d04aacb82 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Fri, 5 Apr 2024 12:43:40 +0800 Subject: [PATCH 09/41] [worker.spec] remove primitive websocket test --- packages/worker-api/src/worker.spec.ts | 28 -------------------------- 1 file changed, 28 deletions(-) diff --git a/packages/worker-api/src/worker.spec.ts b/packages/worker-api/src/worker.spec.ts index 6ff2815b..5551203f 100644 --- a/packages/worker-api/src/worker.spec.ts +++ b/packages/worker-api/src/worker.spec.ts @@ -71,34 +71,6 @@ describe('worker', () => { }); }); - describe('openAndCloseWorks', () => { - it('should return value', async () => { - - let unresolvedPromise = new Promise((resolve, _) => { - const ws = new WebSocket("wss://127.0.0.1:2000", 'tls'); - - ws.onopen = () => { - console.log('WebSocket opened'); - ws.send("hello"); - ws.close(); - resolve(""); - }; - - ws.onmessage = (message) => { - console.log('Received message:', message.data); - }; - - ws.onclose = () => { - console.log('WebSocket closed'); - }; - }); - - await unresolvedPromise; - console.log("Test finished") - }); - }); - - describe('getTotalIssuance', () => { it('should return value', async () => { const result = await worker.getTotalIssuance(network.chosenCid); From f0409f13775b25e5c5e63093f0e4fb354efba631 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Fri, 5 Apr 2024 12:45:04 +0800 Subject: [PATCH 10/41] [worker.spec] separate tests for encointer-specific protocol --- packages/worker-api/src/worker.spec.ts | 149 +++++++++++++------------ 1 file changed, 76 insertions(+), 73 deletions(-) diff --git a/packages/worker-api/src/worker.spec.ts b/packages/worker-api/src/worker.spec.ts index 5551203f..60f20b3d 100644 --- a/packages/worker-api/src/worker.spec.ts +++ b/packages/worker-api/src/worker.spec.ts @@ -71,101 +71,104 @@ describe('worker', () => { }); }); - describe('getTotalIssuance', () => { - it('should return value', async () => { - const result = await worker.getTotalIssuance(network.chosenCid); - // console.log('getTotalIssuance', result); - expect(result).toBeDefined(); + // Tests specific for the encointer protocol + describe('encointer-worker', () => { + describe('getTotalIssuance', () => { + it('should return value', async () => { + const result = await worker.getTotalIssuance(network.chosenCid); + // console.log('getTotalIssuance', result); + expect(result).toBeDefined(); + }); }); - }); - describe('getParticipantCount', () => { - it('should return default value', async () => { - const result = await worker.getParticipantCount(network.chosenCid); - expect(result).toBe(0); + describe('getParticipantCount', () => { + it('should return default value', async () => { + const result = await worker.getParticipantCount(network.chosenCid); + expect(result).toBe(0); + }); }); - }); - describe('getMeetupCount', () => { - it('should return default value', async () => { - const result = await worker.getMeetupCount(network.chosenCid); - expect(result).toBe(0); + describe('getMeetupCount', () => { + it('should return default value', async () => { + const result = await worker.getMeetupCount(network.chosenCid); + expect(result).toBe(0); + }); }); - }); - describe('getCeremonyReward', () => { - it('should return default value', async () => { - const result = await worker.getCeremonyReward(network.chosenCid); - expect(result).toBe(1); + describe('getCeremonyReward', () => { + it('should return default value', async () => { + const result = await worker.getCeremonyReward(network.chosenCid); + expect(result).toBe(1); + }); }); - }); - describe('getLocationTolerance', () => { - it('should return default value', async () => { - const result = await worker.getLocationTolerance(network.chosenCid); - expect(result).toBe(1000); + describe('getLocationTolerance', () => { + it('should return default value', async () => { + const result = await worker.getLocationTolerance(network.chosenCid); + expect(result).toBe(1000); + }); }); - }); - describe('getTimeTolerance', () => { - it('should return default value', async () => { - const result = await worker.getTimeTolerance(network.chosenCid); - expect(result.toNumber()).toBe(600000); + describe('getTimeTolerance', () => { + it('should return default value', async () => { + const result = await worker.getTimeTolerance(network.chosenCid); + expect(result.toNumber()).toBe(600000); + }); }); - }); - describe('getSchedulerState', () => { - it('should return value', async () => { - const result = await worker.getSchedulerState(network.chosenCid); - // console.log('schedulerStateResult', result); - expect(result).toBeDefined(); + describe('getSchedulerState', () => { + it('should return value', async () => { + const result = await worker.getSchedulerState(network.chosenCid); + // console.log('schedulerStateResult', result); + expect(result).toBeDefined(); + }); }); - }); - describe('getBalance', () => { - it('should return value', async () => { - const result = await worker.getBalance({ - pubKey: '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty', - pin: '1234' - }, network.chosenCid); - // console.log('getBalance', result); - expect(result).toBeDefined(); + describe('getBalance', () => { + it('should return value', async () => { + const result = await worker.getBalance({ + pubKey: '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty', + pin: '1234' + }, network.chosenCid); + // console.log('getBalance', result); + expect(result).toBeDefined(); + }); }); - }); - describe('getRegistration', () => { - it('should return default value', async () => { - await cryptoWaitReady(); - const bob = keyring.addFromUri('//Bob', {name: 'Bob default'}); - const result = await worker.getParticipantIndex(bob, network.chosenCid); - expect(result.toNumber()).toBe(0); + describe('getRegistration', () => { + it('should return default value', async () => { + await cryptoWaitReady(); + const bob = keyring.addFromUri('//Bob', {name: 'Bob default'}); + const result = await worker.getParticipantIndex(bob, network.chosenCid); + expect(result.toNumber()).toBe(0); + }); }); - }); - describe('getMeetupIndex', () => { - it('should return default value', async () => { - await cryptoWaitReady(); - const bob = keyring.addFromUri('//Bob', {name: 'Bob default'}); - const result = await worker.getMeetupIndex(bob, network.chosenCid); - expect(result.toNumber()).toBe(0); + describe('getMeetupIndex', () => { + it('should return default value', async () => { + await cryptoWaitReady(); + const bob = keyring.addFromUri('//Bob', {name: 'Bob default'}); + const result = await worker.getMeetupIndex(bob, network.chosenCid); + expect(result.toNumber()).toBe(0); + }); }); - }); - describe('getAttestations', () => { - it('should be empty', async () => { - await cryptoWaitReady(); - const bob = keyring.addFromUri('//Bob', {name: 'Bob default'}); - const result = await worker.getAttestations(bob, network.chosenCid); - expect(result.toJSON()).toStrictEqual([]); + describe('getAttestations', () => { + it('should be empty', async () => { + await cryptoWaitReady(); + const bob = keyring.addFromUri('//Bob', {name: 'Bob default'}); + const result = await worker.getAttestations(bob, network.chosenCid); + expect(result.toJSON()).toStrictEqual([]); + }); }); - }); - describe('getMeetupRegistry method', () => { - it('should be empty', async () => { - await cryptoWaitReady(); - const bob = keyring.addFromUri('//Bob', {name: 'Bob default'}); - const result = await worker.getMeetupRegistry(bob, network.chosenCid); - expect(result.toJSON()).toStrictEqual([]); + describe('getMeetupRegistry method', () => { + it('should be empty', async () => { + await cryptoWaitReady(); + const bob = keyring.addFromUri('//Bob', {name: 'Bob default'}); + const result = await worker.getMeetupRegistry(bob, network.chosenCid); + expect(result.toJSON()).toStrictEqual([]); + }); }); }); }); From 32dba386f6187515049be1796548361aa491336d Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Sat, 6 Apr 2024 10:06:08 +0800 Subject: [PATCH 11/41] [worker] successfully get free balance of an account --- packages/worker-api/src/getterApi.ts | 30 +++++++++++++------------- packages/worker-api/src/interface.ts | 9 ++++++-- packages/worker-api/src/worker.spec.ts | 23 ++++++++++---------- 3 files changed, 34 insertions(+), 28 deletions(-) diff --git a/packages/worker-api/src/getterApi.ts b/packages/worker-api/src/getterApi.ts index a7c00706..477cf292 100644 --- a/packages/worker-api/src/getterApi.ts +++ b/packages/worker-api/src/getterApi.ts @@ -28,27 +28,27 @@ const clientRequestGetter = (self: IEncointerWorker, request: string, args: Publ StfState: [{ public: getter }, cid] } } -const requestParams = (self: IEncointerWorker, address: string, shard: string) => - self.createType('(AccountId, CommunityIdentifier)', [address, shard]); const clientRequestTrustedGetter = (self: IEncointerWorker, request: string, args: TrustedGetterArgs) => { - const {cid, account} = args; + const {shard, account} = args; const address = account.address; const getter = self.createType('TrustedGetter', { - [request]: requestParams(self, address, cid) + [request]: address }); + const signature = account.sign(getter.toU8a()); - return { - StfState: [ - { - trusted: { - getter, - signature - } - }, - cid - ] - } + const g = self.createType( 'Getter',{ + trusted: { + getter, + signature, + } + }); + + const r = self.createType( + 'Request', { shard: shard, cyphertext: g.toU8a() } + ); + + return createJsonRpcRequest('state_executeGetter', [r.toHex()],1) } const sendTrustedRequest = (self: IEncointerWorker, method: string, parser: string, args: TrustedGetterArgs, options: CallOptions) => diff --git a/packages/worker-api/src/interface.ts b/packages/worker-api/src/interface.ts index 9b42648c..9d6ddb2a 100644 --- a/packages/worker-api/src/interface.ts +++ b/packages/worker-api/src/interface.ts @@ -33,16 +33,21 @@ export interface WorkerOptions { createWebSocket?: (url: string) => WebSocket; } -export interface TrustedGetterArgs { +export interface TrustedGetterArgsDeprecated { cid: string; account: KeyringPair; } +export interface TrustedGetterArgs { + shard: string; + account: KeyringPair; +} + export interface PublicGetterArgs { cid: string; } -export type RequestArgs = PublicGetterArgs | TrustedGetterArgs | { } +export type RequestArgs = PublicGetterArgs | TrustedGetterArgs | TrustedGetterArgsDeprecated | { } export interface CallOptions { timeout: number; diff --git a/packages/worker-api/src/worker.spec.ts b/packages/worker-api/src/worker.spec.ts index 60f20b3d..e39e6312 100644 --- a/packages/worker-api/src/worker.spec.ts +++ b/packages/worker-api/src/worker.spec.ts @@ -71,6 +71,18 @@ describe('worker', () => { }); }); + describe('getBalance', () => { + it('should return value', async () => { + const result = await worker.getBalance({ + pubKey: '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty', + pin: '1234' + }, network.chosenCid); + // console.log('getBalance', result); + expect(result).toBeDefined(); + }); + }); + + // Tests specific for the encointer protocol describe('encointer-worker', () => { describe('getTotalIssuance', () => { @@ -124,17 +136,6 @@ describe('worker', () => { }); }); - describe('getBalance', () => { - it('should return value', async () => { - const result = await worker.getBalance({ - pubKey: '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty', - pin: '1234' - }, network.chosenCid); - // console.log('getBalance', result); - expect(result).toBeDefined(); - }); - }); - describe('getRegistration', () => { it('should return default value', async () => { await cryptoWaitReady(); From 3d4e3524877865ac5b5e8c3d9d7fe99eca0ac787 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Sat, 6 Apr 2024 10:32:57 +0800 Subject: [PATCH 12/41] [worker] implement getting shard vault --- .../types/src/interfaces/augment-types.ts | 4 ++- .../src/interfaces/worker/definitions.ts | 16 ++++++---- packages/types/src/interfaces/worker/types.ts | 29 ++++++++++++------- packages/worker-api/src/worker.spec.ts | 8 +++++ packages/worker-api/src/worker.ts | 9 +++++- 5 files changed, 48 insertions(+), 18 deletions(-) diff --git a/packages/types/src/interfaces/augment-types.ts b/packages/types/src/interfaces/augment-types.ts index bcc1218b..2b63dca1 100644 --- a/packages/types/src/interfaces/augment-types.ts +++ b/packages/types/src/interfaces/augment-types.ts @@ -11,7 +11,7 @@ import type { Assignment, AssignmentCount, AssignmentParams, Attestation, Attest import type { FixedI64F64, IpfsCid, PalletString } from '@encointer/types/interfaces/common'; import type { AnnouncementSigner, Bip340, CidDigest, CidName, CommunityCeremony, CommunityIdentifier, CommunityMetadataType, CommunityRules, DegreeFixed, DegreeRpc, GeoHash, Location, LocationRpc, NominalIncomeType } from '@encointer/types/interfaces/community'; import type { SchedulerState, SystemNumber } from '@encointer/types/interfaces/scheduler'; -import type { BalanceTransferArgs, DirectRequestStatus, Enclave, Getter, GetterArgs, GrantReputationArgs, PublicGetter, RegisterAttestationsArgs, RegisterParticipantArgs, Request, RpcReturnValue, ShardIdentifier, TrustedCall, TrustedCallSigned, TrustedGetter, TrustedGetterSigned, TrustedOperationStatus, WorkerEncoded } from '@encointer/types/interfaces/worker'; +import type { BalanceTransferArgs, DirectRequestStatus, Enclave, Getter, GetterArgs, GrantReputationArgs, ParentchainId, PublicGetter, RegisterAttestationsArgs, RegisterParticipantArgs, Request, RpcReturnValue, ShardIdentifier, TrustedCall, TrustedCallSigned, TrustedGetter, TrustedGetterSigned, TrustedOperationStatus, Vault, WorkerEncoded } from '@encointer/types/interfaces/worker'; import type { Data, StorageKey } from '@polkadot/types'; import type { BitVec, Bool, Bytes, F32, F64, I128, I16, I256, I32, I64, I8, ISize, Json, Null, OptionBool, Raw, Text, Type, U128, U16, U256, U32, U64, U8, USize, bool, f32, f64, i128, i16, i256, i32, i64, i8, isize, u128, u16, u256, u32, u64, u8, usize } from '@polkadot/types-codec'; import type { AssetApproval, AssetApprovalKey, AssetBalance, AssetDestroyWitness, AssetDetails, AssetMetadata, TAssetBalance, TAssetDepositBalance } from '@polkadot/types/interfaces/assets'; @@ -830,6 +830,7 @@ declare module '@polkadot/types/types/registry' { ParathreadClaimQueue: ParathreadClaimQueue; ParathreadEntry: ParathreadEntry; ParaValidatorIndex: ParaValidatorIndex; + ParentchainId: ParentchainId; ParticipantIndexType: ParticipantIndexType; ParticipantRegistration: ParticipantRegistration; Pays: Pays; @@ -1205,6 +1206,7 @@ declare module '@polkadot/types/types/registry' { ValidDisputeStatementKind: ValidDisputeStatementKind; ValidityAttestation: ValidityAttestation; ValidTransaction: ValidTransaction; + Vault: Vault; VecInboundHrmpMessage: VecInboundHrmpMessage; VersionedMultiAsset: VersionedMultiAsset; VersionedMultiAssets: VersionedMultiAssets; diff --git a/packages/types/src/interfaces/worker/definitions.ts b/packages/types/src/interfaces/worker/definitions.ts index 3609b686..81f978f0 100644 --- a/packages/types/src/interfaces/worker/definitions.ts +++ b/packages/types/src/interfaces/worker/definitions.ts @@ -22,11 +22,9 @@ export default { }, TrustedGetter: { _enum: { - balance: '(AccountId, CommunityIdentifier)', - participant_index: '(AccountId, CommunityIdentifier)', - meetup_index: '(AccountId, CommunityIdentifier)', - attestations: '(AccountId, CommunityIdentifier)', - meetup_registry: '(AccountId, CommunityIdentifier)' + free_balance: 'AccountId', + reserved_balance: 'AccountId', + nonce: 'AccountId', } }, TrustedGetterSigned: { @@ -84,6 +82,14 @@ export default { ceremonies_grant_reputation: 'GrantReputationArgs' } }, + Vault: '(AccountId, ParentchainId)', + ParentchainId: { + _enum: { + Integritee: null, + TargetA: null, + TargetB: null, + } + }, BalanceTransferArgs: '(AccountId, AccountId, CommunityIdentifier, BalanceType)', RegisterParticipantArgs: '(AccountId, CommunityIdentifier, Option>)', RegisterAttestationsArgs: '(AccountId, Vec>)', diff --git a/packages/types/src/interfaces/worker/types.ts b/packages/types/src/interfaces/worker/types.ts index 633851f9..fda084d5 100644 --- a/packages/types/src/interfaces/worker/types.ts +++ b/packages/types/src/interfaces/worker/types.ts @@ -44,6 +44,14 @@ export interface GetterArgs extends ITuple<[AccountId, CommunityIdentifier]> {} /** @name GrantReputationArgs */ export interface GrantReputationArgs extends ITuple<[AccountId, CommunityIdentifier, AccountId]> {} +/** @name ParentchainId */ +export interface ParentchainId extends Enum { + readonly isIntegritee: boolean; + readonly isTargetA: boolean; + readonly isTargetB: boolean; + readonly type: 'Integritee' | 'TargetA' | 'TargetB'; +} + /** @name PublicGetter */ export interface PublicGetter extends Enum { readonly isTotalIssuance: boolean; @@ -107,17 +115,13 @@ export interface TrustedCallSigned extends Struct { /** @name TrustedGetter */ export interface TrustedGetter extends Enum { - readonly isBalance: boolean; - readonly asBalance: ITuple<[AccountId, CommunityIdentifier]>; - readonly isParticipantIndex: boolean; - readonly asParticipantIndex: ITuple<[AccountId, CommunityIdentifier]>; - readonly isMeetupIndex: boolean; - readonly asMeetupIndex: ITuple<[AccountId, CommunityIdentifier]>; - readonly isAttestations: boolean; - readonly asAttestations: ITuple<[AccountId, CommunityIdentifier]>; - readonly isMeetupRegistry: boolean; - readonly asMeetupRegistry: ITuple<[AccountId, CommunityIdentifier]>; - readonly type: 'Balance' | 'ParticipantIndex' | 'MeetupIndex' | 'Attestations' | 'MeetupRegistry'; + readonly isFreeBalance: boolean; + readonly asFreeBalance: AccountId; + readonly isReservedBalance: boolean; + readonly asReservedBalance: AccountId; + readonly isNonce: boolean; + readonly asNonce: AccountId; + readonly type: 'FreeBalance' | 'ReservedBalance' | 'Nonce'; } /** @name TrustedGetterSigned */ @@ -143,6 +147,9 @@ export interface TrustedOperationStatus extends Enum { readonly type: 'Submitted' | 'Future' | 'Ready' | 'BroadCast' | 'InSidechainBlock' | 'Retracted' | 'FinalityTimeout' | 'Finalized' | 'Usurped' | 'Dropped' | 'Invalid'; } +/** @name Vault */ +export interface Vault extends ITuple<[AccountId, ParentchainId]> {} + /** @name WorkerEncoded */ export interface WorkerEncoded extends Bytes {} diff --git a/packages/worker-api/src/worker.spec.ts b/packages/worker-api/src/worker.spec.ts index e39e6312..1b0ee111 100644 --- a/packages/worker-api/src/worker.spec.ts +++ b/packages/worker-api/src/worker.spec.ts @@ -71,6 +71,14 @@ describe('worker', () => { }); }); + describe('getShardVault', () => { + it('should return value', async () => { + const result = await worker.getShardVault(); + console.log('ShardVault', result.toHuman()); + expect(result).toBeDefined(); + }); + }); + describe('getBalance', () => { it('should return value', async () => { const result = await worker.getBalance({ diff --git a/packages/worker-api/src/worker.ts b/packages/worker-api/src/worker.ts index 54d3dd66..a71db170 100644 --- a/packages/worker-api/src/worker.ts +++ b/packages/worker-api/src/worker.ts @@ -19,7 +19,7 @@ import type { Attestation, BalanceTransferArgs, CommunityIdentifier, GrantReputationArgs, MeetupIndexType, ParticipantIndexType, RegisterAttestationsArgs, RegisterParticipantArgs, - SchedulerState, TrustedCallSigned + SchedulerState, TrustedCallSigned, Vault } from '@encointer/types'; import type { IEncointerWorker, WorkerOptions, CallOptions } from './interface.js'; @@ -74,6 +74,9 @@ const parseGetterResponse = (self: IEncointerWorker, responseType: string, data: // console.log(`jsonStr.sub(2): ${jsonStr.toJSON().substring(2)}`); parsedData = parseNodeRSA(jsonStr.toJSON().substring(2)); break + case 'Vault': + parsedData = self.createType(responseType, returnValue.value); + break default: parsedData = unwrapWorkerResponse(self, data); parsedData = self.createType(responseType, parsedData); @@ -137,6 +140,10 @@ export class EncointerWorker extends WebSocketAsPromised implements IEncointerWo return await callGetter(this, [Request.Worker, 'author_getShieldingKey', 'NodeRSA'], {}, options) } + public async getShardVault(options: CallOptions = {} as CallOptions): Promise { + return await callGetter(this, [Request.Worker, 'author_getShardVault', 'Vault'], {}, options) + } + public async getTotalIssuance(cid: string, options: CallOptions = {} as CallOptions): Promise { return await callGetter(this, [Request.PublicGetter, 'total_issuance', 'Balance'], {cid}, options) } From b7f3b26c6de020dd310737931132fa240dccdbc7 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Sat, 6 Apr 2024 10:45:20 +0800 Subject: [PATCH 13/41] [worker] fix return value parsing in generic cases --- packages/worker-api/src/worker.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/worker-api/src/worker.ts b/packages/worker-api/src/worker.ts index a71db170..cdb469bf 100644 --- a/packages/worker-api/src/worker.ts +++ b/packages/worker-api/src/worker.ts @@ -57,14 +57,14 @@ const parseGetterResponse = (self: IEncointerWorker, responseType: string, data: try { switch (responseType) { case 'raw': - parsedData = unwrapWorkerResponse(self, data); + parsedData = unwrapWorkerResponse(self, returnValue.value); break; case 'BalanceEntry': - parsedData = unwrapWorkerResponse(self, data); + parsedData = unwrapWorkerResponse(self, returnValue.value); parsedData = parseBalance(self, parsedData); break; case 'I64F64': - parsedData = unwrapWorkerResponse(self, data); + parsedData = unwrapWorkerResponse(self, returnValue.value); parsedData = parseI64F64(self.createType('i128', parsedData)); break; case 'NodeRSA': @@ -78,7 +78,7 @@ const parseGetterResponse = (self: IEncointerWorker, responseType: string, data: parsedData = self.createType(responseType, returnValue.value); break default: - parsedData = unwrapWorkerResponse(self, data); + parsedData = unwrapWorkerResponse(self, returnValue.value); parsedData = self.createType(responseType, parsedData); break; } From 767b5d857633ab93fc35ece0e6b012b11c13ddc8 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Sat, 6 Apr 2024 11:37:31 +0800 Subject: [PATCH 14/41] [worker] refactor request creation into its own file --- packages/worker-api/src/getterApi.ts | 33 +--------- packages/worker-api/src/requests.ts | 74 +++++++++++++++++++++++ packages/worker-api/src/trustedCallApi.ts | 42 ------------- 3 files changed, 75 insertions(+), 74 deletions(-) create mode 100644 packages/worker-api/src/requests.ts delete mode 100644 packages/worker-api/src/trustedCallApi.ts diff --git a/packages/worker-api/src/getterApi.ts b/packages/worker-api/src/getterApi.ts index 477cf292..bb9a6c37 100644 --- a/packages/worker-api/src/getterApi.ts +++ b/packages/worker-api/src/getterApi.ts @@ -8,6 +8,7 @@ import { createJsonRpcRequest } from './interface.js'; import { Request } from './interface.js'; +import {clientRequestGetter, clientRequestTrustedGetter} from "@encointer/worker-api/requests.js"; const sendWorkerRequest = (self: IEncointerWorker, clientRequest: any, parserType: string, options: CallOptions): Promise =>{ const requestId = self.rqStack.push(parserType) + self.rsCount; @@ -19,38 +20,6 @@ const sendWorkerRequest = (self: IEncointerWorker, clientRequest: any, parserTyp ) } -const clientRequestGetter = (self: IEncointerWorker, request: string, args: PublicGetterArgs) => { - const { cid } = args; - const getter = self.createType('PublicGetter', { - [request]: cid - }); - return { - StfState: [{ public: getter }, cid] - } -} - -const clientRequestTrustedGetter = (self: IEncointerWorker, request: string, args: TrustedGetterArgs) => { - const {shard, account} = args; - const address = account.address; - const getter = self.createType('TrustedGetter', { - [request]: address - }); - - const signature = account.sign(getter.toU8a()); - const g = self.createType( 'Getter',{ - trusted: { - getter, - signature, - } - }); - - const r = self.createType( - 'Request', { shard: shard, cyphertext: g.toU8a() } - ); - - return createJsonRpcRequest('state_executeGetter', [r.toHex()],1) -} - const sendTrustedRequest = (self: IEncointerWorker, method: string, parser: string, args: TrustedGetterArgs, options: CallOptions) => sendWorkerRequest(self, clientRequestTrustedGetter(self, method, args), parser, options) diff --git a/packages/worker-api/src/requests.ts b/packages/worker-api/src/requests.ts new file mode 100644 index 00000000..bbee666d --- /dev/null +++ b/packages/worker-api/src/requests.ts @@ -0,0 +1,74 @@ +import { + createJsonRpcRequest, + type IEncointerWorker, + type PublicGetterArgs, + type TrustedGetterArgs +} from "@encointer/worker-api/interface.js"; +import type {BalanceTransferArgs, BalanceUnshieldArgs, ShardIdentifier, TrustedCallSigned} from "@encointer/types"; +import type {KeyringPair} from "@polkadot/keyring/types"; +import {PubKeyPinPair, toAccount} from "@encointer/util/common.js"; +import type {u32} from "@polkadot/types"; +import bs58 from "bs58"; + +// Todo: this one is deprecated and needs to be rewritten like the trusted getter below/ +export const clientRequestGetter = (self: IEncointerWorker, request: string, args: PublicGetterArgs) => { + const { cid } = args; + const getter = self.createType('PublicGetter', { + [request]: cid + }); + return { + StfState: [{ public: getter }, cid] + } +} + +export const clientRequestTrustedGetter = (self: IEncointerWorker, request: string, args: TrustedGetterArgs) => { + const {shard, account} = args; + const address = account.address; + const getter = self.createType('TrustedGetter', { + [request]: address + }); + + const signature = account.sign(getter.toU8a()); + const g = self.createType( 'Getter',{ + trusted: { + getter, + signature, + } + }); + + const r = self.createType( + 'Request', { shard: shard, cyphertext: g.toU8a() } + ); + + return createJsonRpcRequest('state_executeGetter', [r.toHex()],1) +} + +export type TrustedCallArgs = (BalanceTransferArgs | BalanceUnshieldArgs); + +export type TrustedCallVariant = [string, string] + +export const createTrustedCall = ( + self: IEncointerWorker, + trustedCall: TrustedCallVariant, + accountOrPubKey: (KeyringPair | PubKeyPinPair), + shard: ShardIdentifier, + mrenclave: string, + nonce: u32, + params: TrustedCallArgs +): TrustedCallSigned => { + + const [variant, argType] = trustedCall; + const hash = self.createType('Hash', bs58.decode(mrenclave)); + + const call = self.createType('TrustedCall', { + [variant]: self.createType(argType, params) + }); + + const payload = Uint8Array.from([...call.toU8a(), ...nonce.toU8a(), ...hash.toU8a(), ...shard.toU8a()]); + + return self.createType('TrustedCallSigned', { + call: call, + nonce: nonce, + signature: toAccount(accountOrPubKey, self.keyring()).sign(payload) + }); +} diff --git a/packages/worker-api/src/trustedCallApi.ts b/packages/worker-api/src/trustedCallApi.ts deleted file mode 100644 index 7bf1d2e8..00000000 --- a/packages/worker-api/src/trustedCallApi.ts +++ /dev/null @@ -1,42 +0,0 @@ -import type { IEncointerWorker } from "./interface.js" -import type { - BalanceTransferArgs, CommunityIdentifier, - GrantReputationArgs, - RegisterAttestationsArgs, - RegisterParticipantArgs, - TrustedCallSigned -} from "@encointer/types"; -import type { KeyringPair } from "@polkadot/keyring/types"; -import type { u32 } from "@polkadot/types"; -import bs58 from "bs58"; -import { toAccount, PubKeyPinPair } from "@encointer/util/common"; - -export type TrustedCallArgs = (BalanceTransferArgs | RegisterParticipantArgs | RegisterAttestationsArgs | GrantReputationArgs); - -export type TrustedCallVariant = [string, string] - -export const createTrustedCall = ( - self: IEncointerWorker, - trustedCall: TrustedCallVariant, - accountOrPubKey: (KeyringPair | PubKeyPinPair), - cid: CommunityIdentifier, - mrenclave: string, - nonce: u32, - params: TrustedCallArgs -): TrustedCallSigned => { - - const [variant, argType] = trustedCall; - const hash = self.createType('Hash', bs58.decode(mrenclave)); - - const call = self.createType('TrustedCall', { - [variant]: self.createType(argType, params) - }); - - const payload = Uint8Array.from([...call.toU8a(), ...nonce.toU8a(), ...hash.toU8a(), ...cid.toU8a()]); - - return self.createType('TrustedCallSigned', { - call: call, - nonce: nonce, - signature: toAccount(accountOrPubKey, self.keyring()).sign(payload) - }); -} From de9c30764bdd8670ad9c472f36eb4aad9ceca239 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Sat, 6 Apr 2024 11:46:23 +0800 Subject: [PATCH 15/41] [worker] rename getter api to sendRequest --- packages/worker-api/src/{getterApi.ts => sendRequest.ts} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename packages/worker-api/src/{getterApi.ts => sendRequest.ts} (91%) diff --git a/packages/worker-api/src/getterApi.ts b/packages/worker-api/src/sendRequest.ts similarity index 91% rename from packages/worker-api/src/getterApi.ts rename to packages/worker-api/src/sendRequest.ts index bb9a6c37..88509a78 100644 --- a/packages/worker-api/src/getterApi.ts +++ b/packages/worker-api/src/sendRequest.ts @@ -26,7 +26,7 @@ const sendTrustedRequest = (self: IEncointerWorker, method: string, parser: stri const sendPublicRequest = (self: IEncointerWorker, method: string, parser: string, args: PublicGetterArgs, options: CallOptions) => sendWorkerRequest(self, clientRequestGetter(self, method, args), parser, options) -export const callGetter = async (self: IEncointerWorker, workerMethod: WorkerMethod, args: RequestArgs, options: CallOptions = {} as CallOptions): Promise => { +export const sendRequest = async (self: IEncointerWorker, workerMethod: WorkerMethod, args: RequestArgs, options: CallOptions = {} as CallOptions): Promise => { if( !self.isOpened ) { await self.open(); } From 1461d73d4c5d0a943acee3941a76e5c65f86b36d Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Sat, 6 Apr 2024 12:11:07 +0800 Subject: [PATCH 16/41] [worker] update public getter --- packages/worker-api/src/requests.ts | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/packages/worker-api/src/requests.ts b/packages/worker-api/src/requests.ts index bbee666d..46046cdc 100644 --- a/packages/worker-api/src/requests.ts +++ b/packages/worker-api/src/requests.ts @@ -1,7 +1,6 @@ import { createJsonRpcRequest, - type IEncointerWorker, - type PublicGetterArgs, + type IEncointerWorker, type PublicGetterArgs, type TrustedGetterArgs } from "@encointer/worker-api/interface.js"; import type {BalanceTransferArgs, BalanceUnshieldArgs, ShardIdentifier, TrustedCallSigned} from "@encointer/types"; @@ -10,15 +9,24 @@ import {PubKeyPinPair, toAccount} from "@encointer/util/common.js"; import type {u32} from "@polkadot/types"; import bs58 from "bs58"; -// Todo: this one is deprecated and needs to be rewritten like the trusted getter below/ +// Todo: Properly resolve cid vs shard export const clientRequestGetter = (self: IEncointerWorker, request: string, args: PublicGetterArgs) => { const { cid } = args; const getter = self.createType('PublicGetter', { [request]: cid }); - return { - StfState: [{ public: getter }, cid] - } + + const g = self.createType( 'Getter',{ + public: { + getter, + } + }); + + const r = self.createType( + 'Request', { shard: cid, cyphertext: g.toU8a() } + ); + + return createJsonRpcRequest('state_executeGetter', [r.toHex()],1); } export const clientRequestTrustedGetter = (self: IEncointerWorker, request: string, args: TrustedGetterArgs) => { @@ -40,7 +48,7 @@ export const clientRequestTrustedGetter = (self: IEncointerWorker, request: stri 'Request', { shard: shard, cyphertext: g.toU8a() } ); - return createJsonRpcRequest('state_executeGetter', [r.toHex()],1) + return createJsonRpcRequest('state_executeGetter', [r.toHex()],1); } export type TrustedCallArgs = (BalanceTransferArgs | BalanceUnshieldArgs); From 992cfea94b9c4a32cacefebcf05fdae5901e4a4c Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Sat, 6 Apr 2024 12:12:44 +0800 Subject: [PATCH 17/41] [worker] rename callGetter to sendRequest --- packages/worker-api/src/sendRequest.ts | 2 +- packages/worker-api/src/worker.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/worker-api/src/sendRequest.ts b/packages/worker-api/src/sendRequest.ts index 88509a78..bb9a6c37 100644 --- a/packages/worker-api/src/sendRequest.ts +++ b/packages/worker-api/src/sendRequest.ts @@ -26,7 +26,7 @@ const sendTrustedRequest = (self: IEncointerWorker, method: string, parser: stri const sendPublicRequest = (self: IEncointerWorker, method: string, parser: string, args: PublicGetterArgs, options: CallOptions) => sendWorkerRequest(self, clientRequestGetter(self, method, args), parser, options) -export const sendRequest = async (self: IEncointerWorker, workerMethod: WorkerMethod, args: RequestArgs, options: CallOptions = {} as CallOptions): Promise => { +export const callGetter = async (self: IEncointerWorker, workerMethod: WorkerMethod, args: RequestArgs, options: CallOptions = {} as CallOptions): Promise => { if( !self.isOpened ) { await self.open(); } diff --git a/packages/worker-api/src/worker.ts b/packages/worker-api/src/worker.ts index cdb469bf..93159a2a 100644 --- a/packages/worker-api/src/worker.ts +++ b/packages/worker-api/src/worker.ts @@ -25,7 +25,7 @@ import type { import type { IEncointerWorker, WorkerOptions, CallOptions } from './interface.js'; import { Request } from './interface.js'; import { parseBalance, parseNodeRSA } from './parsers.js'; -import { callGetter } from './getterApi.js'; +import { callGetter } from './sendRequest.js'; import { createTrustedCall } from "@encointer/worker-api/trustedCallApi"; import { toAccount, PubKeyPinPair } from "@encointer/util/common"; From 86a9af505250aab44df6abccfff3683f6aa506a7 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Sat, 6 Apr 2024 12:13:49 +0800 Subject: [PATCH 18/41] [worker] more explicit naming --- packages/worker-api/src/sendRequest.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/worker-api/src/sendRequest.ts b/packages/worker-api/src/sendRequest.ts index bb9a6c37..90faaaf0 100644 --- a/packages/worker-api/src/sendRequest.ts +++ b/packages/worker-api/src/sendRequest.ts @@ -20,10 +20,10 @@ const sendWorkerRequest = (self: IEncointerWorker, clientRequest: any, parserTyp ) } -const sendTrustedRequest = (self: IEncointerWorker, method: string, parser: string, args: TrustedGetterArgs, options: CallOptions) => +const sendTrustedGetterRequest = (self: IEncointerWorker, method: string, parser: string, args: TrustedGetterArgs, options: CallOptions) => sendWorkerRequest(self, clientRequestTrustedGetter(self, method, args), parser, options) -const sendPublicRequest = (self: IEncointerWorker, method: string, parser: string, args: PublicGetterArgs, options: CallOptions) => +const sendPublicGetterRequest = (self: IEncointerWorker, method: string, parser: string, args: PublicGetterArgs, options: CallOptions) => sendWorkerRequest(self, clientRequestGetter(self, method, args), parser, options) export const callGetter = async (self: IEncointerWorker, workerMethod: WorkerMethod, args: RequestArgs, options: CallOptions = {} as CallOptions): Promise => { @@ -35,16 +35,19 @@ export const callGetter = async (self: IEncointerWorker, workerMethod: Worker let parserType: string = options.debug ? 'raw': parser; switch (getterType) { case Request.TrustedGetter: - result = sendTrustedRequest(self, method, parserType, args as TrustedGetterArgs, options) + result = sendTrustedGetterRequest(self, method, parserType, args as TrustedGetterArgs, options) break; case Request.PublicGetter: - result = sendPublicRequest(self, method, parserType, args as PublicGetterArgs, options) + result = sendPublicGetterRequest(self, method, parserType, args as PublicGetterArgs, options) break; case Request.Worker: result = sendWorkerRequest(self, createJsonRpcRequest(method, [], 1), parserType, options) break; + case Request.TrustedCall: + result = sendWorkerRequest(self, createJsonRpcRequest(method, [], 1), parserType, options) + break; default: - result = sendPublicRequest(self, method, parserType, args as PublicGetterArgs, options) + result = sendPublicGetterRequest(self, method, parserType, args as PublicGetterArgs, options) break; } return result as Promise From 1966fe946e7e1803c311c862b1c6154d48302b0a Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Sat, 6 Apr 2024 13:37:50 +0800 Subject: [PATCH 19/41] [worker] implement draft of trusted call balance transfer, (getting nonce fails currently) --- .../types/src/interfaces/augment-types.ts | 6 +- .../src/interfaces/worker/definitions.ts | 10 +-- packages/types/src/interfaces/worker/types.ts | 27 +++----- packages/worker-api/src/requests.ts | 5 +- packages/worker-api/src/sendRequest.ts | 26 ++++++-- packages/worker-api/src/worker.spec.ts | 59 ++++++++--------- packages/worker-api/src/worker.ts | 63 +++++++++---------- 7 files changed, 95 insertions(+), 101 deletions(-) diff --git a/packages/types/src/interfaces/augment-types.ts b/packages/types/src/interfaces/augment-types.ts index 2b63dca1..803cdab3 100644 --- a/packages/types/src/interfaces/augment-types.ts +++ b/packages/types/src/interfaces/augment-types.ts @@ -11,7 +11,7 @@ import type { Assignment, AssignmentCount, AssignmentParams, Attestation, Attest import type { FixedI64F64, IpfsCid, PalletString } from '@encointer/types/interfaces/common'; import type { AnnouncementSigner, Bip340, CidDigest, CidName, CommunityCeremony, CommunityIdentifier, CommunityMetadataType, CommunityRules, DegreeFixed, DegreeRpc, GeoHash, Location, LocationRpc, NominalIncomeType } from '@encointer/types/interfaces/community'; import type { SchedulerState, SystemNumber } from '@encointer/types/interfaces/scheduler'; -import type { BalanceTransferArgs, DirectRequestStatus, Enclave, Getter, GetterArgs, GrantReputationArgs, ParentchainId, PublicGetter, RegisterAttestationsArgs, RegisterParticipantArgs, Request, RpcReturnValue, ShardIdentifier, TrustedCall, TrustedCallSigned, TrustedGetter, TrustedGetterSigned, TrustedOperationStatus, Vault, WorkerEncoded } from '@encointer/types/interfaces/worker'; +import type { BalanceTransferArgs, BalanceUnshieldArgs, DirectRequestStatus, Enclave, Getter, GetterArgs, ParentchainId, PublicGetter, Request, RpcReturnValue, ShardIdentifier, TrustedCall, TrustedCallSigned, TrustedGetter, TrustedGetterSigned, TrustedOperationStatus, Vault, WorkerEncoded } from '@encointer/types/interfaces/worker'; import type { Data, StorageKey } from '@polkadot/types'; import type { BitVec, Bool, Bytes, F32, F64, I128, I16, I256, I32, I64, I8, ISize, Json, Null, OptionBool, Raw, Text, Type, U128, U16, U256, U32, U64, U8, USize, bool, f32, f64, i128, i16, i256, i32, i64, i8, isize, u128, u16, u256, u32, u64, u8, usize } from '@polkadot/types-codec'; import type { AssetApproval, AssetApprovalKey, AssetBalance, AssetDestroyWitness, AssetDetails, AssetMetadata, TAssetBalance, TAssetDepositBalance } from '@polkadot/types/interfaces/assets'; @@ -160,6 +160,7 @@ declare module '@polkadot/types/types/registry' { BalanceOf: BalanceOf; BalanceTransferArgs: BalanceTransferArgs; BalanceType: BalanceType; + BalanceUnshieldArgs: BalanceUnshieldArgs; BeefyAuthoritySet: BeefyAuthoritySet; BeefyCommitment: BeefyCommitment; BeefyEquivocationProof: BeefyEquivocationProof; @@ -555,7 +556,6 @@ declare module '@polkadot/types/types/registry' { GrandpaPrecommit: GrandpaPrecommit; GrandpaPrevote: GrandpaPrevote; GrandpaSignedPrecommit: GrandpaSignedPrecommit; - GrantReputationArgs: GrantReputationArgs; GroupIndex: GroupIndex; GroupRotationInfo: GroupRotationInfo; H1024: H1024; @@ -912,9 +912,7 @@ declare module '@polkadot/types/types/registry' { ReferendumInfoFinished: ReferendumInfoFinished; ReferendumInfoTo239: ReferendumInfoTo239; ReferendumStatus: ReferendumStatus; - RegisterAttestationsArgs: RegisterAttestationsArgs; RegisteredParachainInfo: RegisteredParachainInfo; - RegisterParticipantArgs: RegisterParticipantArgs; RegistrarIndex: RegistrarIndex; RegistrarInfo: RegistrarInfo; Registration: Registration; diff --git a/packages/types/src/interfaces/worker/definitions.ts b/packages/types/src/interfaces/worker/definitions.ts index 81f978f0..bdee4456 100644 --- a/packages/types/src/interfaces/worker/definitions.ts +++ b/packages/types/src/interfaces/worker/definitions.ts @@ -77,9 +77,7 @@ export default { TrustedCall: { _enum: { balance_transfer: 'BalanceTransferArgs', - ceremonies_register_participant: 'RegisterParticipantArgs', - ceremonies_register_attestations: 'RegisterAttestationsArgs', - ceremonies_grant_reputation: 'GrantReputationArgs' + balance_unshield: 'BalanceUnshieldArgs', } }, Vault: '(AccountId, ParentchainId)', @@ -90,9 +88,7 @@ export default { TargetB: null, } }, - BalanceTransferArgs: '(AccountId, AccountId, CommunityIdentifier, BalanceType)', - RegisterParticipantArgs: '(AccountId, CommunityIdentifier, Option>)', - RegisterAttestationsArgs: '(AccountId, Vec>)', - GrantReputationArgs: '(AccountId, CommunityIdentifier, AccountId)' + BalanceTransferArgs: '(AccountId, AccountId, BalanceType)', + BalanceUnshieldArgs: '(AccountId, AccountId, BalanceType, ShardIdentifier)', } } diff --git a/packages/types/src/interfaces/worker/types.ts b/packages/types/src/interfaces/worker/types.ts index fda084d5..3dff5321 100644 --- a/packages/types/src/interfaces/worker/types.ts +++ b/packages/types/src/interfaces/worker/types.ts @@ -2,15 +2,17 @@ /* eslint-disable */ import type { BalanceType } from '@encointer/types/interfaces/balances'; -import type { Attestation, ProofOfAttendance } from '@encointer/types/interfaces/ceremony'; import type { CommunityIdentifier } from '@encointer/types/interfaces/community'; -import type { Bytes, Enum, Option, Struct, Text, Vec, bool, u32, u64 } from '@polkadot/types-codec'; +import type { Bytes, Enum, Struct, Text, bool, u32, u64 } from '@polkadot/types-codec'; import type { ITuple } from '@polkadot/types-codec/types'; import type { Signature } from '@polkadot/types/interfaces/extrinsics'; import type { AccountId, Hash } from '@polkadot/types/interfaces/runtime'; /** @name BalanceTransferArgs */ -export interface BalanceTransferArgs extends ITuple<[AccountId, AccountId, CommunityIdentifier, BalanceType]> {} +export interface BalanceTransferArgs extends ITuple<[AccountId, AccountId, BalanceType]> {} + +/** @name BalanceUnshieldArgs */ +export interface BalanceUnshieldArgs extends ITuple<[AccountId, AccountId, BalanceType, ShardIdentifier]> {} /** @name DirectRequestStatus */ export interface DirectRequestStatus extends Enum { @@ -41,9 +43,6 @@ export interface Getter extends Enum { /** @name GetterArgs */ export interface GetterArgs extends ITuple<[AccountId, CommunityIdentifier]> {} -/** @name GrantReputationArgs */ -export interface GrantReputationArgs extends ITuple<[AccountId, CommunityIdentifier, AccountId]> {} - /** @name ParentchainId */ export interface ParentchainId extends Enum { readonly isIntegritee: boolean; @@ -71,12 +70,6 @@ export interface PublicGetter extends Enum { readonly type: 'TotalIssuance' | 'ParticipantCount' | 'MeetupCount' | 'CeremonyReward' | 'LocationTolerance' | 'TimeTolerance' | 'SchedulerState'; } -/** @name RegisterAttestationsArgs */ -export interface RegisterAttestationsArgs extends ITuple<[AccountId, Vec]> {} - -/** @name RegisterParticipantArgs */ -export interface RegisterParticipantArgs extends ITuple<[AccountId, CommunityIdentifier, Option]> {} - /** @name Request */ export interface Request extends Struct { readonly shard: ShardIdentifier; @@ -97,13 +90,9 @@ export interface ShardIdentifier extends Hash {} export interface TrustedCall extends Enum { readonly isBalanceTransfer: boolean; readonly asBalanceTransfer: BalanceTransferArgs; - readonly isCeremoniesRegisterParticipant: boolean; - readonly asCeremoniesRegisterParticipant: RegisterParticipantArgs; - readonly isCeremoniesRegisterAttestations: boolean; - readonly asCeremoniesRegisterAttestations: RegisterAttestationsArgs; - readonly isCeremoniesGrantReputation: boolean; - readonly asCeremoniesGrantReputation: GrantReputationArgs; - readonly type: 'BalanceTransfer' | 'CeremoniesRegisterParticipant' | 'CeremoniesRegisterAttestations' | 'CeremoniesGrantReputation'; + readonly isBalanceUnshield: boolean; + readonly asBalanceUnshield: BalanceUnshieldArgs; + readonly type: 'BalanceTransfer' | 'BalanceUnshield'; } /** @name TrustedCallSigned */ diff --git a/packages/worker-api/src/requests.ts b/packages/worker-api/src/requests.ts index 46046cdc..baeda705 100644 --- a/packages/worker-api/src/requests.ts +++ b/packages/worker-api/src/requests.ts @@ -44,8 +44,11 @@ export const clientRequestTrustedGetter = (self: IEncointerWorker, request: stri } }); + console.log(`TrustedGetter: ${JSON.stringify(g)}`); + + const s = self.createType('ShardIdentifier', bs58.decode(shard)); const r = self.createType( - 'Request', { shard: shard, cyphertext: g.toU8a() } + 'Request', { shard: s, cyphertext: g.toU8a() } ); return createJsonRpcRequest('state_executeGetter', [r.toHex()],1); diff --git a/packages/worker-api/src/sendRequest.ts b/packages/worker-api/src/sendRequest.ts index 90faaaf0..446cdc60 100644 --- a/packages/worker-api/src/sendRequest.ts +++ b/packages/worker-api/src/sendRequest.ts @@ -8,7 +8,11 @@ import { createJsonRpcRequest } from './interface.js'; import { Request } from './interface.js'; -import {clientRequestGetter, clientRequestTrustedGetter} from "@encointer/worker-api/requests.js"; +import { + clientRequestGetter, + clientRequestTrustedGetter, +} from "@encointer/worker-api/requests.js"; +import type {ShardIdentifier, TrustedCallSigned} from "@encointer/types"; const sendWorkerRequest = (self: IEncointerWorker, clientRequest: any, parserType: string, options: CallOptions): Promise =>{ const requestId = self.rqStack.push(parserType) + self.rsCount; @@ -43,12 +47,26 @@ export const callGetter = async (self: IEncointerWorker, workerMethod: Worker case Request.Worker: result = sendWorkerRequest(self, createJsonRpcRequest(method, [], 1), parserType, options) break; - case Request.TrustedCall: - result = sendWorkerRequest(self, createJsonRpcRequest(method, [], 1), parserType, options) - break; default: result = sendPublicGetterRequest(self, method, parserType, args as PublicGetterArgs, options) break; } return result as Promise } + +export const sendTrustedCall = async (self: IEncointerWorker, call: TrustedCallSigned, shard: ShardIdentifier, parser: string, options: CallOptions = {} as CallOptions): Promise => { + if( !self.isOpened ) { + await self.open(); + } + + let result: Promise; + let parserType: string = options.debug ? 'raw': parser; + + const r = self.createType( + 'Request', { shard, cyphertext: call.toU8a() } + ); + + result = sendWorkerRequest(self, createJsonRpcRequest('author_submitExtrinsic', [r.toHex()], 1), parserType, options) + return result as Promise +} + diff --git a/packages/worker-api/src/worker.spec.ts b/packages/worker-api/src/worker.spec.ts index 1b0ee111..6c682219 100644 --- a/packages/worker-api/src/worker.spec.ts +++ b/packages/worker-api/src/worker.spec.ts @@ -3,7 +3,8 @@ import { cryptoWaitReady } from '@polkadot/util-crypto'; import { localDockerNetwork } from './testUtils/networks.js'; import { EncointerWorker } from './worker.js'; import WS from 'websocket'; -import type { CommunityIdentifier } from "@encointer/types"; +import {KeyringPair} from "@polkadot/keyring/types"; +import bs58 from "bs58"; const {w3cwebsocket: WebSocket} = WS; @@ -11,14 +12,14 @@ describe('worker', () => { const network = localDockerNetwork(); let keyring: Keyring; let worker: EncointerWorker; + let alice: KeyringPair; + let bob: KeyringPair; beforeAll(async () => { jest.setTimeout(90000); await cryptoWaitReady(); keyring = new Keyring({type: 'sr25519'}); - const keypair = keyring.addFromUri('//Bob'); - const json = keypair.toJson('1234'); - keypair.lock(); - keyring.addFromJson(json); + alice = keyring.addFromUri('//Alice', {name: 'Alice default'}); + bob = keyring.addFromUri('//Bob', {name: 'Bob default'}); worker = new EncointerWorker(network.worker, { keyring: keyring, @@ -35,30 +36,6 @@ describe('worker', () => { }); }); - describe('trusted call', () => { - it('ceremonies_register_participant is valid', () => { - const alice = keyring.addFromUri('//Alice'); - const proof = worker.createType('Option>'); - const cid: CommunityIdentifier = worker.cidFromStr('gbsuv7YXq9G'); - const nonce = worker.createType('u32', 0) - const args = worker.createType('RegisterParticipantArgs', [alice.publicKey, cid, proof]) - - // trustedCall from the previous js-implementation that is known to work. - const tCallHex = '0x01d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d6762737576ffffffff0000000000940cf3e675d8bd25066ad8a15af580ca9a41d3b13f840f43647f51869875fb62232086204dffc8ee67d959e2e3135eae214dd6296e76706459f6c9c8f2b3be86' - - const call = worker.trustedCallRegisterParticipant( - alice, - cid, - network.mrenclave, - nonce, - args - ); - - // the last 64 bytes are from the non-deterministic signature - expect(call.toHex().slice(0, -128)).toEqual(tCallHex.slice(0, -128)); - }) - }) - // skip it, as this requires a worker (and hence a node) to be running // To my knowledge jest does not have an option to run skipped tests specifically, does it? // Todo: add proper CI to test this too. @@ -81,15 +58,29 @@ describe('worker', () => { describe('getBalance', () => { it('should return value', async () => { - const result = await worker.getBalance({ - pubKey: '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty', - pin: '1234' - }, network.chosenCid); - // console.log('getBalance', result); + const result = await worker.getBalance(alice, network.mrenclave); + console.log('getBalance', result); + expect(result).toBeDefined(); + }); + }); + + describe('getNonce', () => { + it('should return value', async () => { + const result = await worker.getNonce(alice, network.mrenclave); + console.log('getBalance', result); expect(result).toBeDefined(); }); }); + describe('balance transfer should workd', () => { + it('should return value', async () => { + const shard = worker.createType('ShardIdentifier', bs58.decode(network.mrenclave)); + const params = worker.createType('BalanceTransferArgs', [alice.address, bob.address, 1100000000000]) + const result = await worker.trustedBalanceTransfer(alice, shard, network.mrenclave, params); + console.log('balance transfer result', result); + expect(result).toBeDefined(); + }); + }); // Tests specific for the encointer protocol describe('encointer-worker', () => { diff --git a/packages/worker-api/src/worker.ts b/packages/worker-api/src/worker.ts index 93159a2a..9fc049b5 100644 --- a/packages/worker-api/src/worker.ts +++ b/packages/worker-api/src/worker.ts @@ -1,33 +1,35 @@ -import { TypeRegistry } from '@polkadot/types'; -import type { RegistryTypes } from '@polkadot/types/types'; -import { Keyring } from '@polkadot/keyring' -import { hexToU8a, u8aToHex } from '@polkadot/util'; +import type {u32, u64, Vec} from '@polkadot/types'; +import {TypeRegistry} from '@polkadot/types'; +import type {RegistryTypes} from '@polkadot/types/types'; +import {Keyring} from '@polkadot/keyring' +import {hexToU8a, u8aToHex} from '@polkadot/util'; import WebSocketAsPromised from 'websocket-as-promised'; -import { options as encointerOptions } from '@encointer/node-api'; +import {options as encointerOptions} from '@encointer/node-api'; import {communityIdentifierFromString, parseI64F64} from '@encointer/util'; // @ts-ignore import NodeRSA from 'node-rsa'; -import type { KeyringPair } from '@polkadot/keyring/types'; -import type { Vec, u32, u64 } from '@polkadot/types'; -import type { AccountId, Balance, Moment } from '@polkadot/types/interfaces/runtime'; +import type {KeyringPair} from '@polkadot/keyring/types'; +import type {AccountId, Balance, Moment} from '@polkadot/types/interfaces/runtime'; import type { - Attestation, BalanceTransferArgs, CommunityIdentifier, GrantReputationArgs, + Attestation, + BalanceTransferArgs, + CommunityIdentifier, MeetupIndexType, - ParticipantIndexType, RegisterAttestationsArgs, RegisterParticipantArgs, - SchedulerState, TrustedCallSigned, Vault + ParticipantIndexType, + SchedulerState, ShardIdentifier, + Vault } from '@encointer/types'; -import type { IEncointerWorker, WorkerOptions, CallOptions } from './interface.js'; -import { Request } from './interface.js'; -import { parseBalance, parseNodeRSA } from './parsers.js'; -import { callGetter } from './sendRequest.js'; -import { createTrustedCall } from "@encointer/worker-api/trustedCallApi"; -import { toAccount, PubKeyPinPair } from "@encointer/util/common"; +import {type CallOptions, type IEncointerWorker, Request, type WorkerOptions} from './interface.js'; +import {parseBalance, parseNodeRSA} from './parsers.js'; +import {callGetter, sendTrustedCall} from './sendRequest.js'; +import {createTrustedCall} from "@encointer/worker-api/requests.js"; +import {PubKeyPinPair, toAccount} from "@encointer/util/common"; const unwrapWorkerResponse = (self: IEncointerWorker, data: string) => { /// Unwraps the value that is wrapped in all the Options and encoding from the worker. @@ -144,6 +146,13 @@ export class EncointerWorker extends WebSocketAsPromised implements IEncointerWo return await callGetter(this, [Request.Worker, 'author_getShardVault', 'Vault'], {}, options) } + public async getNonce(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: CallOptions = {} as CallOptions): Promise { + return await callGetter(this, [Request.TrustedGetter, 'nonce', 'u32'], { + shard: cid, + account: toAccount(accountOrPubKey, this.#keyring) + }, options) + } + public async getTotalIssuance(cid: string, options: CallOptions = {} as CallOptions): Promise { return await callGetter(this, [Request.PublicGetter, 'total_issuance', 'Balance'], {cid}, options) } @@ -174,7 +183,7 @@ export class EncointerWorker extends WebSocketAsPromised implements IEncointerWo public async getBalance(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: CallOptions = {} as CallOptions): Promise { return await callGetter(this, [Request.TrustedGetter, 'free_balance', 'Balance'], { - cid, + shard: cid, account: toAccount(accountOrPubKey, this.#keyring) }, options) } @@ -207,19 +216,9 @@ export class EncointerWorker extends WebSocketAsPromised implements IEncointerWo }, options) } - public trustedCallBalanceTransfer(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: CommunityIdentifier, mrenclave: string, nonce: u32, params: BalanceTransferArgs): TrustedCallSigned { - return createTrustedCall(this, ['balance_transfer', 'BalanceTransferArgs'], accountOrPubKey, cid, mrenclave, nonce, params) - } - - public trustedCallRegisterParticipant(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: CommunityIdentifier, mrenclave: string, nonce: u32, params: RegisterParticipantArgs): TrustedCallSigned { - return createTrustedCall(this, ['ceremonies_register_participant', 'RegisterParticipantArgs'], accountOrPubKey, cid, mrenclave, nonce, params) - } - - public trustedCallRegisterAttestations(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: CommunityIdentifier, mrenclave: string, nonce: u32, params: RegisterAttestationsArgs): TrustedCallSigned { - return createTrustedCall(this, ['ceremonies_register_attestations', 'RegisterAttestationsArgs'], accountOrPubKey, cid, mrenclave, nonce, params) - } - - public trustedCallGrantReputation(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: CommunityIdentifier, mrenclave: string, nonce: u32, params: GrantReputationArgs): TrustedCallSigned { - return createTrustedCall(this, ['ceremonies_grant_reputation', 'GrantReputationArgs'], accountOrPubKey, cid, mrenclave, nonce, params) + public async trustedBalanceTransfer(accountOrPubKey: KeyringPair | PubKeyPinPair, shard: ShardIdentifier, mrenclave: string, params: BalanceTransferArgs, options: CallOptions = {} as CallOptions): Promise { + const nonce = await this.getNonce(accountOrPubKey, mrenclave, options); + const call = createTrustedCall(this, ['balance_transfer', 'BalanceTransferArgs'], accountOrPubKey, shard, mrenclave, nonce, params); + return sendTrustedCall(this, call, shard, 'u32', options); } } From efb5ff86e5ba8305b6b1ee65a9244449d572d436 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Sat, 6 Apr 2024 13:45:05 +0800 Subject: [PATCH 20/41] [worker] fix getting nonce by using toHex instead of to u8a --- packages/worker-api/src/requests.ts | 5 ++++- packages/worker-api/src/worker.spec.ts | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/worker-api/src/requests.ts b/packages/worker-api/src/requests.ts index baeda705..6ba23e69 100644 --- a/packages/worker-api/src/requests.ts +++ b/packages/worker-api/src/requests.ts @@ -48,7 +48,10 @@ export const clientRequestTrustedGetter = (self: IEncointerWorker, request: stri const s = self.createType('ShardIdentifier', bs58.decode(shard)); const r = self.createType( - 'Request', { shard: s, cyphertext: g.toU8a() } + 'Request', { + shard: s, + cyphertext: g.toHex() + } ); return createJsonRpcRequest('state_executeGetter', [r.toHex()],1); diff --git a/packages/worker-api/src/worker.spec.ts b/packages/worker-api/src/worker.spec.ts index 6c682219..725d788f 100644 --- a/packages/worker-api/src/worker.spec.ts +++ b/packages/worker-api/src/worker.spec.ts @@ -67,7 +67,7 @@ describe('worker', () => { describe('getNonce', () => { it('should return value', async () => { const result = await worker.getNonce(alice, network.mrenclave); - console.log('getBalance', result); + console.log('getNonce', result); expect(result).toBeDefined(); }); }); From b1b5c6e8903818cdae93d0494b2ff700ab244aa0 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Sat, 6 Apr 2024 17:00:29 +0800 Subject: [PATCH 21/41] [worker] fix signature type in trusted calls/getters --- packages/types/src/interfaces/worker/definitions.ts | 4 ++-- packages/types/src/interfaces/worker/types.ts | 6 +++--- packages/worker-api/src/requests.ts | 2 +- packages/worker-api/src/sendRequest.ts | 4 +++- packages/worker-api/src/worker.spec.ts | 2 +- packages/worker-api/src/worker.ts | 5 +++++ 6 files changed, 15 insertions(+), 8 deletions(-) diff --git a/packages/types/src/interfaces/worker/definitions.ts b/packages/types/src/interfaces/worker/definitions.ts index bdee4456..7d9ef955 100644 --- a/packages/types/src/interfaces/worker/definitions.ts +++ b/packages/types/src/interfaces/worker/definitions.ts @@ -29,7 +29,7 @@ export default { }, TrustedGetterSigned: { getter: 'TrustedGetter', - signature: 'Signature' + signature: 'MultiSignature' }, Getter: { _enum: { @@ -72,7 +72,7 @@ export default { TrustedCallSigned: { call: 'TrustedCall', nonce: 'u32', - signature: 'Signature' + signature: 'MultiSignature' }, TrustedCall: { _enum: { diff --git a/packages/types/src/interfaces/worker/types.ts b/packages/types/src/interfaces/worker/types.ts index 3dff5321..9b82c1fe 100644 --- a/packages/types/src/interfaces/worker/types.ts +++ b/packages/types/src/interfaces/worker/types.ts @@ -5,7 +5,7 @@ import type { BalanceType } from '@encointer/types/interfaces/balances'; import type { CommunityIdentifier } from '@encointer/types/interfaces/community'; import type { Bytes, Enum, Struct, Text, bool, u32, u64 } from '@polkadot/types-codec'; import type { ITuple } from '@polkadot/types-codec/types'; -import type { Signature } from '@polkadot/types/interfaces/extrinsics'; +import type { MultiSignature } from '@polkadot/types/interfaces/extrinsics'; import type { AccountId, Hash } from '@polkadot/types/interfaces/runtime'; /** @name BalanceTransferArgs */ @@ -99,7 +99,7 @@ export interface TrustedCall extends Enum { export interface TrustedCallSigned extends Struct { readonly call: TrustedCall; readonly nonce: u32; - readonly signature: Signature; + readonly signature: MultiSignature; } /** @name TrustedGetter */ @@ -116,7 +116,7 @@ export interface TrustedGetter extends Enum { /** @name TrustedGetterSigned */ export interface TrustedGetterSigned extends Struct { readonly getter: TrustedGetter; - readonly signature: Signature; + readonly signature: MultiSignature; } /** @name TrustedOperationStatus */ diff --git a/packages/worker-api/src/requests.ts b/packages/worker-api/src/requests.ts index 6ba23e69..c515cb44 100644 --- a/packages/worker-api/src/requests.ts +++ b/packages/worker-api/src/requests.ts @@ -40,7 +40,7 @@ export const clientRequestTrustedGetter = (self: IEncointerWorker, request: stri const g = self.createType( 'Getter',{ trusted: { getter, - signature, + signature: { Sr25519: signature }, } }); diff --git a/packages/worker-api/src/sendRequest.ts b/packages/worker-api/src/sendRequest.ts index 446cdc60..c2fadf7d 100644 --- a/packages/worker-api/src/sendRequest.ts +++ b/packages/worker-api/src/sendRequest.ts @@ -62,8 +62,10 @@ export const sendTrustedCall = async (self: IEncointerWorker, call: TrustedCa let result: Promise; let parserType: string = options.debug ? 'raw': parser; + console.log(`TrustedCall: ${JSON.stringify(call)}`); + const r = self.createType( - 'Request', { shard, cyphertext: call.toU8a() } + 'Request', { shard, cyphertext: call.toHex() } ); result = sendWorkerRequest(self, createJsonRpcRequest('author_submitExtrinsic', [r.toHex()], 1), parserType, options) diff --git a/packages/worker-api/src/worker.spec.ts b/packages/worker-api/src/worker.spec.ts index 725d788f..499c015c 100644 --- a/packages/worker-api/src/worker.spec.ts +++ b/packages/worker-api/src/worker.spec.ts @@ -72,7 +72,7 @@ describe('worker', () => { }); }); - describe('balance transfer should workd', () => { + describe('balance transfer should work', () => { it('should return value', async () => { const shard = worker.createType('ShardIdentifier', bs58.decode(network.mrenclave)); const params = worker.createType('BalanceTransferArgs', [alice.address, bob.address, 1100000000000]) diff --git a/packages/worker-api/src/worker.ts b/packages/worker-api/src/worker.ts index 9fc049b5..83da594a 100644 --- a/packages/worker-api/src/worker.ts +++ b/packages/worker-api/src/worker.ts @@ -55,6 +55,11 @@ const parseGetterResponse = (self: IEncointerWorker, responseType: string, data: const returnValue = self.createType('RpcReturnValue', value); console.log(`RpcReturnValue ${JSON.stringify(returnValue)}`); + if (returnValue.status.isError) { + const errorMsg = self.createType('String', returnValue.value); + throw new Error(`RPC Error: ${errorMsg}`); + } + let parsedData: any; try { switch (responseType) { From 7773a51209930559783e0911a478c902a335c967 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Sat, 6 Apr 2024 17:19:07 +0800 Subject: [PATCH 22/41] [worker] fix interpreting the result of getters --- packages/worker-api/src/worker.spec.ts | 2 +- packages/worker-api/src/worker.ts | 12 ++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/packages/worker-api/src/worker.spec.ts b/packages/worker-api/src/worker.spec.ts index 499c015c..1d363ab4 100644 --- a/packages/worker-api/src/worker.spec.ts +++ b/packages/worker-api/src/worker.spec.ts @@ -59,7 +59,7 @@ describe('worker', () => { describe('getBalance', () => { it('should return value', async () => { const result = await worker.getBalance(alice, network.mrenclave); - console.log('getBalance', result); + console.log('getBalance toNumber:', result.toString(10)); expect(result).toBeDefined(); }); }); diff --git a/packages/worker-api/src/worker.ts b/packages/worker-api/src/worker.ts index 83da594a..952168d6 100644 --- a/packages/worker-api/src/worker.ts +++ b/packages/worker-api/src/worker.ts @@ -2,7 +2,7 @@ import type {u32, u64, Vec} from '@polkadot/types'; import {TypeRegistry} from '@polkadot/types'; import type {RegistryTypes} from '@polkadot/types/types'; import {Keyring} from '@polkadot/keyring' -import {hexToU8a, u8aToHex} from '@polkadot/util'; +import {hexToU8a} from '@polkadot/util'; import WebSocketAsPromised from 'websocket-as-promised'; @@ -32,15 +32,10 @@ import {createTrustedCall} from "@encointer/worker-api/requests.js"; import {PubKeyPinPair, toAccount} from "@encointer/util/common"; const unwrapWorkerResponse = (self: IEncointerWorker, data: string) => { - /// Unwraps the value that is wrapped in all the Options and encoding from the worker. /// Defaults to return `[]`, which is fine as `createType(api.registry, , [])` /// instantiates the with its default value. - const dataTyped = self.createType('Option', hexToU8a('0x'.concat(data))) - .unwrapOrDefault(); // (Option.enc+whitespacePad) - const trimmed = u8aToHex(dataTyped).replace(/(20)+$/, ''); - const unwrappedData = self.createType('Option', hexToU8a(trimmed)) - .unwrapOrDefault(); - return unwrappedData + const dataTyped = self.createType('Option', data) + return dataTyped.unwrapOrDefault(); } const parseGetterResponse = (self: IEncointerWorker, responseType: string, data: string) => { @@ -86,6 +81,7 @@ const parseGetterResponse = (self: IEncointerWorker, responseType: string, data: break default: parsedData = unwrapWorkerResponse(self, returnValue.value); + console.log(`unwrapped data ${parsedData}`); parsedData = self.createType(responseType, parsedData); break; } From 187075ec31927ca1cce95a4b8ffbfd529d433e70 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Sat, 6 Apr 2024 18:46:50 +0800 Subject: [PATCH 23/41] [worker] fix signature of trusted call --- packages/worker-api/src/requests.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/worker-api/src/requests.ts b/packages/worker-api/src/requests.ts index c515cb44..009ad01f 100644 --- a/packages/worker-api/src/requests.ts +++ b/packages/worker-api/src/requests.ts @@ -83,6 +83,6 @@ export const createTrustedCall = ( return self.createType('TrustedCallSigned', { call: call, nonce: nonce, - signature: toAccount(accountOrPubKey, self.keyring()).sign(payload) + signature: { Sr25519: toAccount(accountOrPubKey, self.keyring()).sign(payload) }, }); } From e13865a7b3a3d38c4802a5926de70ad2b4a4eb62 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Sat, 6 Apr 2024 18:48:56 +0800 Subject: [PATCH 24/41] [worker] try to encrypt the trusted call upon sending --- packages/worker-api/src/interface.ts | 3 +++ packages/worker-api/src/sendRequest.ts | 4 +++- packages/worker-api/src/worker.ts | 33 +++++++++++++++++++++++--- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/packages/worker-api/src/interface.ts b/packages/worker-api/src/interface.ts index 9d6ddb2a..71ec531d 100644 --- a/packages/worker-api/src/interface.ts +++ b/packages/worker-api/src/interface.ts @@ -1,6 +1,8 @@ import type { KeyringPair } from '@polkadot/keyring/types'; import WebSocketAsPromised from 'websocket-as-promised'; import {Keyring} from "@polkadot/keyring"; +import type {u8} from "@polkadot/types-codec"; +import type {Vec} from "@polkadot/types"; export interface IEncointerWorker extends WebSocketAsPromised { rsCount: number; @@ -8,6 +10,7 @@ export interface IEncointerWorker extends WebSocketAsPromised { keyring: () => Keyring | undefined; createType: (apiType: string, obj?: any) => any; open: () => Promise; + encrypt: (data: Uint8Array) => Vec } export interface JsonRpcRequest { diff --git a/packages/worker-api/src/sendRequest.ts b/packages/worker-api/src/sendRequest.ts index c2fadf7d..f7264c6f 100644 --- a/packages/worker-api/src/sendRequest.ts +++ b/packages/worker-api/src/sendRequest.ts @@ -64,8 +64,10 @@ export const sendTrustedCall = async (self: IEncointerWorker, call: TrustedCa console.log(`TrustedCall: ${JSON.stringify(call)}`); + const cyphertext = self.encrypt(call.toU8a()); + const r = self.createType( - 'Request', { shard, cyphertext: call.toHex() } + 'Request', { shard, cyphertext: cyphertext } ); result = sendWorkerRequest(self, createJsonRpcRequest('author_submitExtrinsic', [r.toHex()], 1), parserType, options) diff --git a/packages/worker-api/src/worker.ts b/packages/worker-api/src/worker.ts index 952168d6..08cf810c 100644 --- a/packages/worker-api/src/worker.ts +++ b/packages/worker-api/src/worker.ts @@ -2,7 +2,7 @@ import type {u32, u64, Vec} from '@polkadot/types'; import {TypeRegistry} from '@polkadot/types'; import type {RegistryTypes} from '@polkadot/types/types'; import {Keyring} from '@polkadot/keyring' -import {hexToU8a} from '@polkadot/util'; +import {bufferToU8a, compactAddLength, hexToU8a, u8aToBuffer} from '@polkadot/util'; import WebSocketAsPromised from 'websocket-as-promised'; @@ -21,7 +21,7 @@ import type { CommunityIdentifier, MeetupIndexType, ParticipantIndexType, - SchedulerState, ShardIdentifier, + SchedulerState, ShardIdentifier, TrustedCallSigned, Vault } from '@encointer/types'; @@ -30,6 +30,7 @@ import {parseBalance, parseNodeRSA} from './parsers.js'; import {callGetter, sendTrustedCall} from './sendRequest.js'; import {createTrustedCall} from "@encointer/worker-api/requests.js"; import {PubKeyPinPair, toAccount} from "@encointer/util/common"; +import type {u8} from "@polkadot/types-codec"; const unwrapWorkerResponse = (self: IEncointerWorker, data: string) => { /// Defaults to return `[]`, which is fine as `createType(api.registry, , [])` @@ -97,6 +98,8 @@ export class EncointerWorker extends WebSocketAsPromised implements IEncointerWo #keyring?: Keyring; + #shieldingKey?: NodeRSA + rsCount: number; rqStack: string[]; @@ -123,6 +126,13 @@ export class EncointerWorker extends WebSocketAsPromised implements IEncointerWo } } + public encrypt(data: Uint8Array): Vec { + const buffer = u8aToBuffer(data); + const cypherTextBuffer = this.shieldingKey().encrypt(buffer); + const cypherArray = bufferToU8a(cypherTextBuffer); + return this.createType('Vec', compactAddLength(cypherArray)) + } + public createType(apiType: string, obj?: any): any { return this.#registry.createType(apiType as never, obj) } @@ -135,6 +145,14 @@ export class EncointerWorker extends WebSocketAsPromised implements IEncointerWo this.#keyring = keyring; } + public shieldingKey(): NodeRSA | undefined { + return this.#shieldingKey; + } + + public setShieldingKey(shieldingKey: NodeRSA): void { + this.#shieldingKey = shieldingKey; + } + public cidFromStr(cidStr: String): CommunityIdentifier { return communityIdentifierFromString(this.#registry, cidStr); } @@ -220,6 +238,15 @@ export class EncointerWorker extends WebSocketAsPromised implements IEncointerWo public async trustedBalanceTransfer(accountOrPubKey: KeyringPair | PubKeyPinPair, shard: ShardIdentifier, mrenclave: string, params: BalanceTransferArgs, options: CallOptions = {} as CallOptions): Promise { const nonce = await this.getNonce(accountOrPubKey, mrenclave, options); const call = createTrustedCall(this, ['balance_transfer', 'BalanceTransferArgs'], accountOrPubKey, shard, mrenclave, nonce, params); - return sendTrustedCall(this, call, shard, 'u32', options); + return this.sendTrustedCall(call, shard, 'u32', options); + } + + async sendTrustedCall(call: TrustedCallSigned, shard: ShardIdentifier, parser: string, options: CallOptions = {} as CallOptions): Promise { + if (this.shieldingKey() == undefined) { + const key = await this.getShieldingKey(options); + this.setShieldingKey(key); + } + + return sendTrustedCall(this, call, shard, parser, options); } } From 7efd96ae4aa69448a1dd749c34671374cc3467f9 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Mon, 8 Apr 2024 09:25:59 +0800 Subject: [PATCH 25/41] [worker] introduce trusted operation --- packages/types/src/interfaces/augment-types.ts | 3 ++- .../types/src/interfaces/worker/definitions.ts | 7 +++++++ packages/types/src/interfaces/worker/types.ts | 11 +++++++++++ packages/worker-api/src/sendRequest.ts | 15 +++++++++++++-- packages/worker-api/src/worker.ts | 2 +- 5 files changed, 34 insertions(+), 4 deletions(-) diff --git a/packages/types/src/interfaces/augment-types.ts b/packages/types/src/interfaces/augment-types.ts index 803cdab3..6fcdb0d1 100644 --- a/packages/types/src/interfaces/augment-types.ts +++ b/packages/types/src/interfaces/augment-types.ts @@ -11,7 +11,7 @@ import type { Assignment, AssignmentCount, AssignmentParams, Attestation, Attest import type { FixedI64F64, IpfsCid, PalletString } from '@encointer/types/interfaces/common'; import type { AnnouncementSigner, Bip340, CidDigest, CidName, CommunityCeremony, CommunityIdentifier, CommunityMetadataType, CommunityRules, DegreeFixed, DegreeRpc, GeoHash, Location, LocationRpc, NominalIncomeType } from '@encointer/types/interfaces/community'; import type { SchedulerState, SystemNumber } from '@encointer/types/interfaces/scheduler'; -import type { BalanceTransferArgs, BalanceUnshieldArgs, DirectRequestStatus, Enclave, Getter, GetterArgs, ParentchainId, PublicGetter, Request, RpcReturnValue, ShardIdentifier, TrustedCall, TrustedCallSigned, TrustedGetter, TrustedGetterSigned, TrustedOperationStatus, Vault, WorkerEncoded } from '@encointer/types/interfaces/worker'; +import type { BalanceTransferArgs, BalanceUnshieldArgs, DirectRequestStatus, Enclave, Getter, GetterArgs, ParentchainId, PublicGetter, Request, RpcReturnValue, ShardIdentifier, TrustedCall, TrustedCallSigned, TrustedGetter, TrustedGetterSigned, TrustedOperation, TrustedOperationStatus, Vault, WorkerEncoded } from '@encointer/types/interfaces/worker'; import type { Data, StorageKey } from '@polkadot/types'; import type { BitVec, Bool, Bytes, F32, F64, I128, I16, I256, I32, I64, I8, ISize, Json, Null, OptionBool, Raw, Text, Type, U128, U16, U256, U32, U64, U8, USize, bool, f32, f64, i128, i16, i256, i32, i64, i8, isize, u128, u16, u256, u32, u64, u8, usize } from '@polkadot/types-codec'; import type { AssetApproval, AssetApprovalKey, AssetBalance, AssetDestroyWitness, AssetDetails, AssetMetadata, TAssetBalance, TAssetDepositBalance } from '@polkadot/types/interfaces/assets'; @@ -1156,6 +1156,7 @@ declare module '@polkadot/types/types/registry' { TrustedCallSigned: TrustedCallSigned; TrustedGetter: TrustedGetter; TrustedGetterSigned: TrustedGetterSigned; + TrustedOperation: TrustedOperation; TrustedOperationStatus: TrustedOperationStatus; Type: Type; u128: u128; diff --git a/packages/types/src/interfaces/worker/definitions.ts b/packages/types/src/interfaces/worker/definitions.ts index 7d9ef955..85fb8afc 100644 --- a/packages/types/src/interfaces/worker/definitions.ts +++ b/packages/types/src/interfaces/worker/definitions.ts @@ -69,6 +69,13 @@ export default { shard: 'ShardIdentifier', cyphertext: 'WorkerEncoded' }, + TrustedOperation: { + _enum: { + indirect_call: 'TrustedCallSigned', + direct_call: 'TrustedCallSigned', + get: 'Getter' + } + }, TrustedCallSigned: { call: 'TrustedCall', nonce: 'u32', diff --git a/packages/types/src/interfaces/worker/types.ts b/packages/types/src/interfaces/worker/types.ts index 9b82c1fe..ee7bd5d1 100644 --- a/packages/types/src/interfaces/worker/types.ts +++ b/packages/types/src/interfaces/worker/types.ts @@ -119,6 +119,17 @@ export interface TrustedGetterSigned extends Struct { readonly signature: MultiSignature; } +/** @name TrustedOperation */ +export interface TrustedOperation extends Enum { + readonly isIndirectCall: boolean; + readonly asIndirectCall: TrustedCallSigned; + readonly isDirectCall: boolean; + readonly asDirectCall: TrustedCallSigned; + readonly isGet: boolean; + readonly asGet: Getter; + readonly type: 'IndirectCall' | 'DirectCall' | 'Get'; +} + /** @name TrustedOperationStatus */ export interface TrustedOperationStatus extends Enum { readonly isSubmitted: boolean; diff --git a/packages/worker-api/src/sendRequest.ts b/packages/worker-api/src/sendRequest.ts index f7264c6f..5d67059c 100644 --- a/packages/worker-api/src/sendRequest.ts +++ b/packages/worker-api/src/sendRequest.ts @@ -54,7 +54,7 @@ export const callGetter = async (self: IEncointerWorker, workerMethod: Worker return result as Promise } -export const sendTrustedCall = async (self: IEncointerWorker, call: TrustedCallSigned, shard: ShardIdentifier, parser: string, options: CallOptions = {} as CallOptions): Promise => { +export const sendTrustedCall = async (self: IEncointerWorker, call: TrustedCallSigned, shard: ShardIdentifier, direct: boolean, parser: string, options: CallOptions = {} as CallOptions): Promise => { if( !self.isOpened ) { await self.open(); } @@ -64,7 +64,18 @@ export const sendTrustedCall = async (self: IEncointerWorker, call: TrustedCa console.log(`TrustedCall: ${JSON.stringify(call)}`); - const cyphertext = self.encrypt(call.toU8a()); + let top; + if (direct) { + top = self.createType('TrustedOperation', { + direct_call: call + }) + } else { + top = self.createType('TrustedOperation', { + indirect_call: call + }) + } + + const cyphertext = self.encrypt(top.toU8a()); const r = self.createType( 'Request', { shard, cyphertext: cyphertext } diff --git a/packages/worker-api/src/worker.ts b/packages/worker-api/src/worker.ts index 08cf810c..23f479f0 100644 --- a/packages/worker-api/src/worker.ts +++ b/packages/worker-api/src/worker.ts @@ -247,6 +247,6 @@ export class EncointerWorker extends WebSocketAsPromised implements IEncointerWo this.setShieldingKey(key); } - return sendTrustedCall(this, call, shard, parser, options); + return sendTrustedCall(this, call, shard, true, parser, options); } } From f1e879057c432750ec2b46c36603a0f6edd78f49 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Mon, 8 Apr 2024 11:38:51 +0800 Subject: [PATCH 26/41] [worker] fix encryption --- packages/worker-api/src/parsers.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/worker-api/src/parsers.ts b/packages/worker-api/src/parsers.ts index 1f50ab22..1923bb3b 100644 --- a/packages/worker-api/src/parsers.ts +++ b/packages/worker-api/src/parsers.ts @@ -38,6 +38,7 @@ export function parseNodeRSA(data: any): NodeRSA { function setKeyOpts(key: NodeRSA) { key.setOptions( { + environment: 'browser', encryptionScheme: { scheme: 'pkcs1_oaep', hash: 'sha256', From 90e2c4fe594f9e67e3f3a2493c322ee9b5b23af9 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Mon, 8 Apr 2024 11:45:22 +0800 Subject: [PATCH 27/41] [worker] add comment for node-rsa setting --- packages/worker-api/src/parsers.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/worker-api/src/parsers.ts b/packages/worker-api/src/parsers.ts index 1923bb3b..72ec3c3b 100644 --- a/packages/worker-api/src/parsers.ts +++ b/packages/worker-api/src/parsers.ts @@ -38,6 +38,9 @@ export function parseNodeRSA(data: any): NodeRSA { function setKeyOpts(key: NodeRSA) { key.setOptions( { + // Enforce using the pure javascript implementations, as + // compatibility with node's crypto is broken and leads + // to bad outputs. environment: 'browser', encryptionScheme: { scheme: 'pkcs1_oaep', From 13066b571fe8a0b60747c9f62d73d0b2efdd8a54 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Mon, 8 Apr 2024 13:36:42 +0800 Subject: [PATCH 28/41] [worker] successfully send a top to the worker. --- .../types/src/interfaces/augment-types.ts | 5 ++++- .../src/interfaces/worker/definitions.ts | 7 +++++++ packages/types/src/interfaces/worker/types.ts | 21 +++++++++++++++++-- packages/worker-api/src/sendRequest.ts | 2 ++ 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/packages/types/src/interfaces/augment-types.ts b/packages/types/src/interfaces/augment-types.ts index 6fcdb0d1..adc5dcae 100644 --- a/packages/types/src/interfaces/augment-types.ts +++ b/packages/types/src/interfaces/augment-types.ts @@ -11,7 +11,7 @@ import type { Assignment, AssignmentCount, AssignmentParams, Attestation, Attest import type { FixedI64F64, IpfsCid, PalletString } from '@encointer/types/interfaces/common'; import type { AnnouncementSigner, Bip340, CidDigest, CidName, CommunityCeremony, CommunityIdentifier, CommunityMetadataType, CommunityRules, DegreeFixed, DegreeRpc, GeoHash, Location, LocationRpc, NominalIncomeType } from '@encointer/types/interfaces/community'; import type { SchedulerState, SystemNumber } from '@encointer/types/interfaces/scheduler'; -import type { BalanceTransferArgs, BalanceUnshieldArgs, DirectRequestStatus, Enclave, Getter, GetterArgs, ParentchainId, PublicGetter, Request, RpcReturnValue, ShardIdentifier, TrustedCall, TrustedCallSigned, TrustedGetter, TrustedGetterSigned, TrustedOperation, TrustedOperationStatus, Vault, WorkerEncoded } from '@encointer/types/interfaces/worker'; +import type { BalanceSetBalanceArgs, BalanceShieldArgs, BalanceTransferArgs, BalanceUnshieldArgs, DirectRequestStatus, Enclave, Getter, GetterArgs, ParentchainId, PublicGetter, Request, RpcReturnValue, ShardIdentifier, TimestampSetArgs, TrustedCall, TrustedCallSigned, TrustedGetter, TrustedGetterSigned, TrustedOperation, TrustedOperationStatus, Vault, WorkerEncoded } from '@encointer/types/interfaces/worker'; import type { Data, StorageKey } from '@polkadot/types'; import type { BitVec, Bool, Bytes, F32, F64, I128, I16, I256, I32, I64, I8, ISize, Json, Null, OptionBool, Raw, Text, Type, U128, U16, U256, U32, U64, U8, USize, bool, f32, f64, i128, i16, i256, i32, i64, i8, isize, u128, u16, u256, u32, u64, u8, usize } from '@polkadot/types-codec'; import type { AssetApproval, AssetApprovalKey, AssetBalance, AssetDestroyWitness, AssetDetails, AssetMetadata, TAssetBalance, TAssetDepositBalance } from '@polkadot/types/interfaces/assets'; @@ -158,6 +158,8 @@ declare module '@polkadot/types/types/registry' { Balance: Balance; BalanceEntry: BalanceEntry; BalanceOf: BalanceOf; + BalanceSetBalanceArgs: BalanceSetBalanceArgs; + BalanceShieldArgs: BalanceShieldArgs; BalanceTransferArgs: BalanceTransferArgs; BalanceType: BalanceType; BalanceUnshieldArgs: BalanceUnshieldArgs; @@ -1132,6 +1134,7 @@ declare module '@polkadot/types/types/registry' { TAssetDepositBalance: TAssetDepositBalance; Text: Text; Timepoint: Timepoint; + TimestampSetArgs: TimestampSetArgs; TokenError: TokenError; TombstoneContractInfo: TombstoneContractInfo; TraceBlockResponse: TraceBlockResponse; diff --git a/packages/types/src/interfaces/worker/definitions.ts b/packages/types/src/interfaces/worker/definitions.ts index 85fb8afc..514fef64 100644 --- a/packages/types/src/interfaces/worker/definitions.ts +++ b/packages/types/src/interfaces/worker/definitions.ts @@ -83,8 +83,12 @@ export default { }, TrustedCall: { _enum: { + noop: 'AccountId', + balance_set_balance: 'BalanceSetBalanceArgs', balance_transfer: 'BalanceTransferArgs', balance_unshield: 'BalanceUnshieldArgs', + balance_shield: 'BalanceShieldArgs', + timestamp_set: 'TimestampSetArgs', } }, Vault: '(AccountId, ParentchainId)', @@ -95,7 +99,10 @@ export default { TargetB: null, } }, + BalanceSetBalanceArgs: '(AccountId, AccountId, BalanceType, BalanceType)', BalanceTransferArgs: '(AccountId, AccountId, BalanceType)', BalanceUnshieldArgs: '(AccountId, AccountId, BalanceType, ShardIdentifier)', + BalanceShieldArgs: '(AccountId, AccountId, BalanceType, ParentchainId)', + TimestampSetArgs: '(AccountId, H160, BalanceType)', } } diff --git a/packages/types/src/interfaces/worker/types.ts b/packages/types/src/interfaces/worker/types.ts index ee7bd5d1..72001ccd 100644 --- a/packages/types/src/interfaces/worker/types.ts +++ b/packages/types/src/interfaces/worker/types.ts @@ -6,7 +6,13 @@ import type { CommunityIdentifier } from '@encointer/types/interfaces/community' import type { Bytes, Enum, Struct, Text, bool, u32, u64 } from '@polkadot/types-codec'; import type { ITuple } from '@polkadot/types-codec/types'; import type { MultiSignature } from '@polkadot/types/interfaces/extrinsics'; -import type { AccountId, Hash } from '@polkadot/types/interfaces/runtime'; +import type { AccountId, H160, Hash } from '@polkadot/types/interfaces/runtime'; + +/** @name BalanceSetBalanceArgs */ +export interface BalanceSetBalanceArgs extends ITuple<[AccountId, AccountId, BalanceType, BalanceType]> {} + +/** @name BalanceShieldArgs */ +export interface BalanceShieldArgs extends ITuple<[AccountId, AccountId, BalanceType, ParentchainId]> {} /** @name BalanceTransferArgs */ export interface BalanceTransferArgs extends ITuple<[AccountId, AccountId, BalanceType]> {} @@ -86,13 +92,24 @@ export interface RpcReturnValue extends Struct { /** @name ShardIdentifier */ export interface ShardIdentifier extends Hash {} +/** @name TimestampSetArgs */ +export interface TimestampSetArgs extends ITuple<[AccountId, H160, BalanceType]> {} + /** @name TrustedCall */ export interface TrustedCall extends Enum { + readonly isNoop: boolean; + readonly asNoop: AccountId; + readonly isBalanceSetBalance: boolean; + readonly asBalanceSetBalance: BalanceSetBalanceArgs; readonly isBalanceTransfer: boolean; readonly asBalanceTransfer: BalanceTransferArgs; readonly isBalanceUnshield: boolean; readonly asBalanceUnshield: BalanceUnshieldArgs; - readonly type: 'BalanceTransfer' | 'BalanceUnshield'; + readonly isBalanceShield: boolean; + readonly asBalanceShield: BalanceShieldArgs; + readonly isTimestampSet: boolean; + readonly asTimestampSet: TimestampSetArgs; + readonly type: 'Noop' | 'BalanceSetBalance' | 'BalanceTransfer' | 'BalanceUnshield' | 'BalanceShield' | 'TimestampSet'; } /** @name TrustedCallSigned */ diff --git a/packages/worker-api/src/sendRequest.ts b/packages/worker-api/src/sendRequest.ts index 5d67059c..cc0330d4 100644 --- a/packages/worker-api/src/sendRequest.ts +++ b/packages/worker-api/src/sendRequest.ts @@ -75,6 +75,8 @@ export const sendTrustedCall = async (self: IEncointerWorker, call: TrustedCa }) } + console.log(`TrustedOperation: ${JSON.stringify(top)}`); + const cyphertext = self.encrypt(top.toU8a()); const r = self.createType( From 823659dedb56499baf99ff4faf272610ccc66c78 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Mon, 8 Apr 2024 13:38:53 +0800 Subject: [PATCH 29/41] [worker] better doc --- packages/worker-api/src/parsers.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/worker-api/src/parsers.ts b/packages/worker-api/src/parsers.ts index 72ec3c3b..4f59abe5 100644 --- a/packages/worker-api/src/parsers.ts +++ b/packages/worker-api/src/parsers.ts @@ -38,9 +38,9 @@ export function parseNodeRSA(data: any): NodeRSA { function setKeyOpts(key: NodeRSA) { key.setOptions( { - // Enforce using the pure javascript implementations, as - // compatibility with node's crypto is broken and leads - // to bad outputs. + // Enforce using the pure javascript implementations by + // setting the `browser` environment, as compatibility + // with node's crypto is broken and leads to bad outputs. environment: 'browser', encryptionScheme: { scheme: 'pkcs1_oaep', From 46f550d4fec633cda4775c8cbb79bfd2229cd886 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Mon, 8 Apr 2024 14:00:02 +0800 Subject: [PATCH 30/41] [worker] fix sending trusted calls with `author_submitExtrinsic` --- packages/worker-api/src/worker.spec.ts | 2 +- packages/worker-api/src/worker.ts | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/worker-api/src/worker.spec.ts b/packages/worker-api/src/worker.spec.ts index 1d363ab4..4195b9ef 100644 --- a/packages/worker-api/src/worker.spec.ts +++ b/packages/worker-api/src/worker.spec.ts @@ -77,7 +77,7 @@ describe('worker', () => { const shard = worker.createType('ShardIdentifier', bs58.decode(network.mrenclave)); const params = worker.createType('BalanceTransferArgs', [alice.address, bob.address, 1100000000000]) const result = await worker.trustedBalanceTransfer(alice, shard, network.mrenclave, params); - console.log('balance transfer result', result); + console.log('balance transfer result', result.toHuman()); expect(result).toBeDefined(); }); }); diff --git a/packages/worker-api/src/worker.ts b/packages/worker-api/src/worker.ts index 23f479f0..9af9d0b2 100644 --- a/packages/worker-api/src/worker.ts +++ b/packages/worker-api/src/worker.ts @@ -14,7 +14,7 @@ import NodeRSA from 'node-rsa'; import type {KeyringPair} from '@polkadot/keyring/types'; -import type {AccountId, Balance, Moment} from '@polkadot/types/interfaces/runtime'; +import type {AccountId, Balance, Hash, Moment} from '@polkadot/types/interfaces/runtime'; import type { Attestation, BalanceTransferArgs, @@ -74,12 +74,15 @@ const parseGetterResponse = (self: IEncointerWorker, responseType: string, data: const jsonStr = self.createType('String', returnValue.value); // Todo: For some reason there are 2 non-utf characters, where I don't know where // they come from currently. - // console.log(`jsonStr.sub(2): ${jsonStr.toJSON().substring(2)}`); + console.log(`Got shielding key: ${jsonStr.toJSON().substring(2)}`); parsedData = parseNodeRSA(jsonStr.toJSON().substring(2)); break case 'Vault': parsedData = self.createType(responseType, returnValue.value); break + case 'TrustedOperationResult': + parsedData = self.createType('Hash', returnValue.value); + break default: parsedData = unwrapWorkerResponse(self, returnValue.value); console.log(`unwrapped data ${parsedData}`); @@ -235,18 +238,19 @@ export class EncointerWorker extends WebSocketAsPromised implements IEncointerWo }, options) } - public async trustedBalanceTransfer(accountOrPubKey: KeyringPair | PubKeyPinPair, shard: ShardIdentifier, mrenclave: string, params: BalanceTransferArgs, options: CallOptions = {} as CallOptions): Promise { + public async trustedBalanceTransfer(accountOrPubKey: KeyringPair | PubKeyPinPair, shard: ShardIdentifier, mrenclave: string, params: BalanceTransferArgs, options: CallOptions = {} as CallOptions): Promise { const nonce = await this.getNonce(accountOrPubKey, mrenclave, options); const call = createTrustedCall(this, ['balance_transfer', 'BalanceTransferArgs'], accountOrPubKey, shard, mrenclave, nonce, params); - return this.sendTrustedCall(call, shard, 'u32', options); + return this.sendTrustedCall(call, shard, options); } - async sendTrustedCall(call: TrustedCallSigned, shard: ShardIdentifier, parser: string, options: CallOptions = {} as CallOptions): Promise { + async sendTrustedCall(call: TrustedCallSigned, shard: ShardIdentifier, options: CallOptions = {} as CallOptions): Promise { if (this.shieldingKey() == undefined) { const key = await this.getShieldingKey(options); + console.log(`Setting the shielding pubKey of the worker.`) this.setShieldingKey(key); } - return sendTrustedCall(this, call, shard, true, parser, options); + return sendTrustedCall(this, call, shard, true, 'TrustedOperationResult', options); } } From e22849b02681be9c19e0f1490c6b0815bb9d6917 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Mon, 8 Apr 2024 14:13:08 +0800 Subject: [PATCH 31/41] [jest] remove tls certificate config that didn't work --- jest.config.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/jest.config.js b/jest.config.js index d15feaca..7a94c87d 100644 --- a/jest.config.js +++ b/jest.config.js @@ -6,11 +6,6 @@ const fs = require("fs"); const { defaults } = require("jest-config"); -const https = require('https'); - -// Override certificate validation to accept all certificates (including self-signed ones) -https.globalAgent.options.rejectUnauthorized = false; - module.exports = { moduleFileExtensions: [...defaults.moduleFileExtensions, "ts", "tsx"], modulePathIgnorePatterns: [ From 911ca61ddeff5794d6359f24092d79f6f2620105 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Mon, 8 Apr 2024 14:16:32 +0800 Subject: [PATCH 32/41] [jest] remove tls certificate config that didn't work --- packages/worker-api/src/worker.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/worker-api/src/worker.spec.ts b/packages/worker-api/src/worker.spec.ts index 4195b9ef..8799a21e 100644 --- a/packages/worker-api/src/worker.spec.ts +++ b/packages/worker-api/src/worker.spec.ts @@ -30,6 +30,7 @@ describe('worker', () => { undefined, undefined, undefined, + // Allow the worker's self-signed certificate { rejectUnauthorized: false } ), api: null, From 29473cc25ac5a62a29d805494f6b077e7106c552 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Mon, 8 Apr 2024 15:08:48 +0800 Subject: [PATCH 33/41] [worker] implement balance_unshield trusted call --- packages/worker-api/src/worker.spec.ts | 10 ++++++++++ packages/worker-api/src/worker.ts | 8 +++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/packages/worker-api/src/worker.spec.ts b/packages/worker-api/src/worker.spec.ts index 8799a21e..3f833c75 100644 --- a/packages/worker-api/src/worker.spec.ts +++ b/packages/worker-api/src/worker.spec.ts @@ -83,6 +83,16 @@ describe('worker', () => { }); }); + describe('balance unshield should work', () => { + it('should return value', async () => { + const shard = worker.createType('ShardIdentifier', bs58.decode(network.mrenclave)); + const params = worker.createType('BalanceUnshieldArgs', [alice.address, bob.address, 1100000000000, shard]) + const result = await worker.balanceUnshieldFunds(alice, shard, network.mrenclave, params); + console.log('balance unshield result', result.toHuman()); + expect(result).toBeDefined(); + }); + }); + // Tests specific for the encointer protocol describe('encointer-worker', () => { describe('getTotalIssuance', () => { diff --git a/packages/worker-api/src/worker.ts b/packages/worker-api/src/worker.ts index 9af9d0b2..77ce1437 100644 --- a/packages/worker-api/src/worker.ts +++ b/packages/worker-api/src/worker.ts @@ -17,7 +17,7 @@ import type {KeyringPair} from '@polkadot/keyring/types'; import type {AccountId, Balance, Hash, Moment} from '@polkadot/types/interfaces/runtime'; import type { Attestation, - BalanceTransferArgs, + BalanceTransferArgs, BalanceUnshieldArgs, CommunityIdentifier, MeetupIndexType, ParticipantIndexType, @@ -244,6 +244,12 @@ export class EncointerWorker extends WebSocketAsPromised implements IEncointerWo return this.sendTrustedCall(call, shard, options); } + public async balanceUnshieldFunds(accountOrPubKey: KeyringPair | PubKeyPinPair, shard: ShardIdentifier, mrenclave: string, params: BalanceUnshieldArgs, options: CallOptions = {} as CallOptions): Promise { + const nonce = await this.getNonce(accountOrPubKey, mrenclave, options); + const call = createTrustedCall(this, ['balance_unshield', 'BalanceUnshieldArgs'], accountOrPubKey, shard, mrenclave, nonce, params); + return this.sendTrustedCall(call, shard, options); + } + async sendTrustedCall(call: TrustedCallSigned, shard: ShardIdentifier, options: CallOptions = {} as CallOptions): Promise { if (this.shieldingKey() == undefined) { const key = await this.getShieldingKey(options); From a9fa8a056408653baf6ead3ab3408c2b6fa1fa83 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Wed, 10 Apr 2024 08:59:53 +0800 Subject: [PATCH 34/41] [worker] use charlie in tests --- packages/worker-api/src/worker.spec.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/worker-api/src/worker.spec.ts b/packages/worker-api/src/worker.spec.ts index 3f833c75..2c35d344 100644 --- a/packages/worker-api/src/worker.spec.ts +++ b/packages/worker-api/src/worker.spec.ts @@ -13,13 +13,13 @@ describe('worker', () => { let keyring: Keyring; let worker: EncointerWorker; let alice: KeyringPair; - let bob: KeyringPair; + let charlie: KeyringPair; beforeAll(async () => { jest.setTimeout(90000); await cryptoWaitReady(); keyring = new Keyring({type: 'sr25519'}); alice = keyring.addFromUri('//Alice', {name: 'Alice default'}); - bob = keyring.addFromUri('//Bob', {name: 'Bob default'}); + charlie = keyring.addFromUri('//Charlie', {name: 'Bob default'}); worker = new EncointerWorker(network.worker, { keyring: keyring, @@ -59,7 +59,7 @@ describe('worker', () => { describe('getBalance', () => { it('should return value', async () => { - const result = await worker.getBalance(alice, network.mrenclave); + const result = await worker.getBalance(charlie, network.mrenclave); console.log('getBalance toNumber:', result.toString(10)); expect(result).toBeDefined(); }); @@ -76,7 +76,7 @@ describe('worker', () => { describe('balance transfer should work', () => { it('should return value', async () => { const shard = worker.createType('ShardIdentifier', bs58.decode(network.mrenclave)); - const params = worker.createType('BalanceTransferArgs', [alice.address, bob.address, 1100000000000]) + const params = worker.createType('BalanceTransferArgs', [alice.address, charlie.address, 1100000000000]) const result = await worker.trustedBalanceTransfer(alice, shard, network.mrenclave, params); console.log('balance transfer result', result.toHuman()); expect(result).toBeDefined(); @@ -86,7 +86,7 @@ describe('worker', () => { describe('balance unshield should work', () => { it('should return value', async () => { const shard = worker.createType('ShardIdentifier', bs58.decode(network.mrenclave)); - const params = worker.createType('BalanceUnshieldArgs', [alice.address, bob.address, 1100000000000, shard]) + const params = worker.createType('BalanceUnshieldArgs', [alice.address, charlie.address, 1100000000000, shard]) const result = await worker.balanceUnshieldFunds(alice, shard, network.mrenclave, params); console.log('balance unshield result', result.toHuman()); expect(result).toBeDefined(); From c1068afc11c38e41e893fd690609ecdd79255114 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Wed, 10 Apr 2024 09:03:12 +0800 Subject: [PATCH 35/41] [worker] rename interface IEncointerWorker to IIntegriteeWorker --- packages/worker-api/src/interface.ts | 9 ++------- packages/worker-api/src/parsers.ts | 4 ++-- packages/worker-api/src/requests.ts | 8 ++++---- packages/worker-api/src/sendRequest.ts | 12 ++++++------ packages/worker-api/src/worker.ts | 8 ++++---- 5 files changed, 18 insertions(+), 23 deletions(-) diff --git a/packages/worker-api/src/interface.ts b/packages/worker-api/src/interface.ts index 71ec531d..e6ab22ae 100644 --- a/packages/worker-api/src/interface.ts +++ b/packages/worker-api/src/interface.ts @@ -4,7 +4,7 @@ import {Keyring} from "@polkadot/keyring"; import type {u8} from "@polkadot/types-codec"; import type {Vec} from "@polkadot/types"; -export interface IEncointerWorker extends WebSocketAsPromised { +export interface IIntegriteeWorker extends WebSocketAsPromised { rsCount: number; rqStack: string[]; keyring: () => Keyring | undefined; @@ -36,11 +36,6 @@ export interface WorkerOptions { createWebSocket?: (url: string) => WebSocket; } -export interface TrustedGetterArgsDeprecated { - cid: string; - account: KeyringPair; -} - export interface TrustedGetterArgs { shard: string; account: KeyringPair; @@ -50,7 +45,7 @@ export interface PublicGetterArgs { cid: string; } -export type RequestArgs = PublicGetterArgs | TrustedGetterArgs | TrustedGetterArgsDeprecated | { } +export type RequestArgs = PublicGetterArgs | TrustedGetterArgs | { } export interface CallOptions { timeout: number; diff --git a/packages/worker-api/src/parsers.ts b/packages/worker-api/src/parsers.ts index 4f59abe5..a4e0419f 100644 --- a/packages/worker-api/src/parsers.ts +++ b/packages/worker-api/src/parsers.ts @@ -4,10 +4,10 @@ import { u8aToBn, u8aToBuffer } from '@polkadot/util'; // @ts-ignore import NodeRSA from 'node-rsa'; -import type { IEncointerWorker } from './interface.js'; +import type { IIntegriteeWorker } from './interface.js'; import type { BalanceEntry } from "@encointer/types"; -export function parseBalance(self: IEncointerWorker, data: any): BalanceEntry { +export function parseBalance(self: IIntegriteeWorker, data: any): BalanceEntry { const balanceEntry = self.createType('BalanceEntry', data); // Todo: apply demurrage return self.createType('BalanceEntry', diff --git a/packages/worker-api/src/requests.ts b/packages/worker-api/src/requests.ts index 009ad01f..8673fff0 100644 --- a/packages/worker-api/src/requests.ts +++ b/packages/worker-api/src/requests.ts @@ -1,6 +1,6 @@ import { createJsonRpcRequest, - type IEncointerWorker, type PublicGetterArgs, + type IIntegriteeWorker, type PublicGetterArgs, type TrustedGetterArgs } from "@encointer/worker-api/interface.js"; import type {BalanceTransferArgs, BalanceUnshieldArgs, ShardIdentifier, TrustedCallSigned} from "@encointer/types"; @@ -10,7 +10,7 @@ import type {u32} from "@polkadot/types"; import bs58 from "bs58"; // Todo: Properly resolve cid vs shard -export const clientRequestGetter = (self: IEncointerWorker, request: string, args: PublicGetterArgs) => { +export const clientRequestGetter = (self: IIntegriteeWorker, request: string, args: PublicGetterArgs) => { const { cid } = args; const getter = self.createType('PublicGetter', { [request]: cid @@ -29,7 +29,7 @@ export const clientRequestGetter = (self: IEncointerWorker, request: string, arg return createJsonRpcRequest('state_executeGetter', [r.toHex()],1); } -export const clientRequestTrustedGetter = (self: IEncointerWorker, request: string, args: TrustedGetterArgs) => { +export const clientRequestTrustedGetter = (self: IIntegriteeWorker, request: string, args: TrustedGetterArgs) => { const {shard, account} = args; const address = account.address; const getter = self.createType('TrustedGetter', { @@ -62,7 +62,7 @@ export type TrustedCallArgs = (BalanceTransferArgs | BalanceUnshieldArgs); export type TrustedCallVariant = [string, string] export const createTrustedCall = ( - self: IEncointerWorker, + self: IIntegriteeWorker, trustedCall: TrustedCallVariant, accountOrPubKey: (KeyringPair | PubKeyPinPair), shard: ShardIdentifier, diff --git a/packages/worker-api/src/sendRequest.ts b/packages/worker-api/src/sendRequest.ts index cc0330d4..1b1d9b63 100644 --- a/packages/worker-api/src/sendRequest.ts +++ b/packages/worker-api/src/sendRequest.ts @@ -1,5 +1,5 @@ import { - type IEncointerWorker, + type IIntegriteeWorker, type TrustedGetterArgs, type PublicGetterArgs, type RequestArgs, @@ -14,7 +14,7 @@ import { } from "@encointer/worker-api/requests.js"; import type {ShardIdentifier, TrustedCallSigned} from "@encointer/types"; -const sendWorkerRequest = (self: IEncointerWorker, clientRequest: any, parserType: string, options: CallOptions): Promise =>{ +const sendWorkerRequest = (self: IIntegriteeWorker, clientRequest: any, parserType: string, options: CallOptions): Promise =>{ const requestId = self.rqStack.push(parserType) + self.rsCount; return self.sendRequest( clientRequest, { @@ -24,13 +24,13 @@ const sendWorkerRequest = (self: IEncointerWorker, clientRequest: any, parserTyp ) } -const sendTrustedGetterRequest = (self: IEncointerWorker, method: string, parser: string, args: TrustedGetterArgs, options: CallOptions) => +const sendTrustedGetterRequest = (self: IIntegriteeWorker, method: string, parser: string, args: TrustedGetterArgs, options: CallOptions) => sendWorkerRequest(self, clientRequestTrustedGetter(self, method, args), parser, options) -const sendPublicGetterRequest = (self: IEncointerWorker, method: string, parser: string, args: PublicGetterArgs, options: CallOptions) => +const sendPublicGetterRequest = (self: IIntegriteeWorker, method: string, parser: string, args: PublicGetterArgs, options: CallOptions) => sendWorkerRequest(self, clientRequestGetter(self, method, args), parser, options) -export const callGetter = async (self: IEncointerWorker, workerMethod: WorkerMethod, args: RequestArgs, options: CallOptions = {} as CallOptions): Promise => { +export const callGetter = async (self: IIntegriteeWorker, workerMethod: WorkerMethod, args: RequestArgs, options: CallOptions = {} as CallOptions): Promise => { if( !self.isOpened ) { await self.open(); } @@ -54,7 +54,7 @@ export const callGetter = async (self: IEncointerWorker, workerMethod: Worker return result as Promise } -export const sendTrustedCall = async (self: IEncointerWorker, call: TrustedCallSigned, shard: ShardIdentifier, direct: boolean, parser: string, options: CallOptions = {} as CallOptions): Promise => { +export const sendTrustedCall = async (self: IIntegriteeWorker, call: TrustedCallSigned, shard: ShardIdentifier, direct: boolean, parser: string, options: CallOptions = {} as CallOptions): Promise => { if( !self.isOpened ) { await self.open(); } diff --git a/packages/worker-api/src/worker.ts b/packages/worker-api/src/worker.ts index 77ce1437..fc56630a 100644 --- a/packages/worker-api/src/worker.ts +++ b/packages/worker-api/src/worker.ts @@ -25,21 +25,21 @@ import type { Vault } from '@encointer/types'; -import {type CallOptions, type IEncointerWorker, Request, type WorkerOptions} from './interface.js'; +import {type CallOptions, type IIntegriteeWorker, Request, type WorkerOptions} from './interface.js'; import {parseBalance, parseNodeRSA} from './parsers.js'; import {callGetter, sendTrustedCall} from './sendRequest.js'; import {createTrustedCall} from "@encointer/worker-api/requests.js"; import {PubKeyPinPair, toAccount} from "@encointer/util/common"; import type {u8} from "@polkadot/types-codec"; -const unwrapWorkerResponse = (self: IEncointerWorker, data: string) => { +const unwrapWorkerResponse = (self: IIntegriteeWorker, data: string) => { /// Defaults to return `[]`, which is fine as `createType(api.registry, , [])` /// instantiates the with its default value. const dataTyped = self.createType('Option', data) return dataTyped.unwrapOrDefault(); } -const parseGetterResponse = (self: IEncointerWorker, responseType: string, data: string) => { +const parseGetterResponse = (self: IIntegriteeWorker, responseType: string, data: string) => { if (data === 'Could not decode request') { throw new Error(`Worker error: ${data}`); } @@ -95,7 +95,7 @@ const parseGetterResponse = (self: IEncointerWorker, responseType: string, data: return parsedData; } -export class EncointerWorker extends WebSocketAsPromised implements IEncointerWorker { +export class EncointerWorker extends WebSocketAsPromised implements IIntegriteeWorker { readonly #registry: TypeRegistry; From aa147871157b121b12e796a1c6b72ea9169621d8 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Wed, 10 Apr 2024 09:23:22 +0800 Subject: [PATCH 36/41] [worker] separate encointer from integritee worker --- .../worker-api/src/encointerWorker.spec.ts | 133 ++++++++++++++++++ packages/worker-api/src/encointerWorker.ts | 116 +++++++++++++++ packages/worker-api/src/index.ts | 4 +- .../worker-api/src/integriteeWorker.spec.ts | 96 +++++++++++++ packages/worker-api/src/integriteeWorker.ts | 57 ++++++++ packages/worker-api/src/interface.ts | 2 +- packages/worker-api/src/parsers.ts | 4 +- packages/worker-api/src/requests.ts | 8 +- packages/worker-api/src/sendRequest.ts | 12 +- packages/worker-api/src/worker.ts | 121 +--------------- 10 files changed, 425 insertions(+), 128 deletions(-) create mode 100644 packages/worker-api/src/encointerWorker.spec.ts create mode 100644 packages/worker-api/src/encointerWorker.ts create mode 100644 packages/worker-api/src/integriteeWorker.spec.ts create mode 100644 packages/worker-api/src/integriteeWorker.ts diff --git a/packages/worker-api/src/encointerWorker.spec.ts b/packages/worker-api/src/encointerWorker.spec.ts new file mode 100644 index 00000000..c72290b7 --- /dev/null +++ b/packages/worker-api/src/encointerWorker.spec.ts @@ -0,0 +1,133 @@ +import { Keyring } from '@polkadot/api'; +import { cryptoWaitReady } from '@polkadot/util-crypto'; +import { localDockerNetwork } from './testUtils/networks.js'; +import { EncointerWorker } from './encointerWorker.js'; +import WS from 'websocket'; +import {KeyringPair} from "@polkadot/keyring/types"; + +const {w3cwebsocket: WebSocket} = WS; + +describe('worker', () => { + const network = localDockerNetwork(); + let keyring: Keyring; + let worker: EncointerWorker; + let alice: KeyringPair; + let charlie: KeyringPair; + beforeAll(async () => { + jest.setTimeout(90000); + await cryptoWaitReady(); + keyring = new Keyring({type: 'sr25519'}); + alice = keyring.addFromUri('//Alice', {name: 'Alice default'}); + charlie = keyring.addFromUri('//Charlie', {name: 'Bob default'}); + + worker = new EncointerWorker(network.worker, { + keyring: keyring, + types: network.customTypes, + // @ts-ignore + createWebSocket: (url) => new WebSocket( + url, + undefined, + undefined, + undefined, + // Allow the worker's self-signed certificate + { rejectUnauthorized: false } + ), + api: null, + }); + }); + + // skip it, as this requires a worker (and hence a node) to be running + // To my knowledge jest does not have an option to run skipped tests specifically, does it? + // Todo: add proper CI to test this too. + describe('needs worker and node running', () => { + // Tests specific for the encointer protocol + describe('encointer-worker', () => { + describe('getTotalIssuance', () => { + it('should return value', async () => { + const result = await worker.getTotalIssuance(network.chosenCid); + // console.log('getTotalIssuance', result); + expect(result).toBeDefined(); + }); + }); + + describe('getParticipantCount', () => { + it('should return default value', async () => { + const result = await worker.getParticipantCount(network.chosenCid); + expect(result).toBe(0); + }); + }); + + describe('getMeetupCount', () => { + it('should return default value', async () => { + const result = await worker.getMeetupCount(network.chosenCid); + expect(result).toBe(0); + }); + }); + + describe('getCeremonyReward', () => { + it('should return default value', async () => { + const result = await worker.getCeremonyReward(network.chosenCid); + expect(result).toBe(1); + }); + }); + + describe('getLocationTolerance', () => { + it('should return default value', async () => { + const result = await worker.getLocationTolerance(network.chosenCid); + expect(result).toBe(1000); + }); + }); + + describe('getTimeTolerance', () => { + it('should return default value', async () => { + const result = await worker.getTimeTolerance(network.chosenCid); + expect(result.toNumber()).toBe(600000); + }); + }); + + describe('getSchedulerState', () => { + it('should return value', async () => { + const result = await worker.getSchedulerState(network.chosenCid); + // console.log('schedulerStateResult', result); + expect(result).toBeDefined(); + }); + }); + + describe('getRegistration', () => { + it('should return default value', async () => { + await cryptoWaitReady(); + const bob = keyring.addFromUri('//Bob', {name: 'Bob default'}); + const result = await worker.getParticipantIndex(bob, network.chosenCid); + expect(result.toNumber()).toBe(0); + }); + }); + + describe('getMeetupIndex', () => { + it('should return default value', async () => { + await cryptoWaitReady(); + const bob = keyring.addFromUri('//Bob', {name: 'Bob default'}); + const result = await worker.getMeetupIndex(bob, network.chosenCid); + expect(result.toNumber()).toBe(0); + }); + }); + + describe('getAttestations', () => { + it('should be empty', async () => { + await cryptoWaitReady(); + const bob = keyring.addFromUri('//Bob', {name: 'Bob default'}); + const result = await worker.getAttestations(bob, network.chosenCid); + expect(result.toJSON()).toStrictEqual([]); + }); + }); + + describe('getMeetupRegistry method', () => { + it('should be empty', async () => { + await cryptoWaitReady(); + const bob = keyring.addFromUri('//Bob', {name: 'Bob default'}); + const result = await worker.getMeetupRegistry(bob, network.chosenCid); + expect(result.toJSON()).toStrictEqual([]); + }); + }); + }); + }); +}); diff --git a/packages/worker-api/src/encointerWorker.ts b/packages/worker-api/src/encointerWorker.ts new file mode 100644 index 00000000..8fcbb468 --- /dev/null +++ b/packages/worker-api/src/encointerWorker.ts @@ -0,0 +1,116 @@ +import type {u32, u64, Vec} from '@polkadot/types'; +import {communityIdentifierFromString} from '@encointer/util'; + +// @ts-ignore +import NodeRSA from 'node-rsa'; + +import type { + CommunityIdentifier, ShardIdentifier, +} from '@encointer/types'; + +import {type CallOptions} from './interface.js'; +import {callGetter, sendTrustedCall} from './sendRequest.js'; +import {createTrustedCall} from "@encointer/worker-api/requests.js"; +import {PubKeyPinPair, toAccount} from "@encointer/util/common"; +import type {KeyringPair} from "@polkadot/keyring/types"; +import {Worker} from "@encointer/worker-api/worker.js"; +import type {AccountId, Balance, Hash} from "@polkadot/types/interfaces/runtime"; + +export class EncointerWorker extends Worker { + + public cidFromStr(cidStr: String): CommunityIdentifier { + return communityIdentifierFromString(this.registry(), cidStr); + } + + public async getNonce(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: CallOptions = {} as CallOptions): Promise { + return await callGetter(this, [Request.TrustedGetter, 'nonce', 'u32'], { + shard: cid, + account: toAccount(accountOrPubKey, this.keyring()) + }, options) + } + + public async getTotalIssuance(cid: string, options: CallOptions = {} as CallOptions): Promise { + return await callGetter(this, [Request.PublicGetter, 'total_issuance', 'Balance'], {cid}, options) + } + + public async getParticipantCount(cid: string, options: CallOptions = {} as CallOptions): Promise { + return (await callGetter(this, [Request.PublicGetter, 'participant_count', 'u64'], {cid}, options)).toNumber() + } + + public async getMeetupCount(cid: string, options: CallOptions = {} as CallOptions): Promise { + return (await callGetter(this, [Request.PublicGetter, 'meetup_count', 'u64'], {cid}, options)).toNumber() + } + + public async getCeremonyReward(cid: string, options: CallOptions = {} as CallOptions): Promise { + return await callGetter(this, [Request.PublicGetter, 'ceremony_reward', 'I64F64'], {cid}, options) + } + + public async getLocationTolerance(cid: string, options: CallOptions = {} as CallOptions): Promise { + return (await callGetter(this, [Request.PublicGetter, 'location_tolerance', 'u32'], {cid}, options)).toNumber() + } + + public async getTimeTolerance(cid: string, options: CallOptions = {} as CallOptions): Promise { + return await callGetter(this, [Request.PublicGetter, 'time_tolerance', 'Moment'], {cid}, options) + } + + public async getSchedulerState(cid: string, options: CallOptions = {} as CallOptions): Promise { + return await callGetter(this, [Request.PublicGetter, 'scheduler_state', 'SchedulerState'], {cid}, options) + } + + public async getBalance(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: CallOptions = {} as CallOptions): Promise { + return await callGetter(this, [Request.TrustedGetter, 'free_balance', 'Balance'], { + shard: cid, + account: toAccount(accountOrPubKey, this.#keyring) + }, options) + } + + public async getParticipantIndex(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: CallOptions = {} as CallOptions): Promise { + return await callGetter(this, [Request.TrustedGetter, 'participant_index', 'ParticipantIndexType'], { + cid, + account: toAccount(accountOrPubKey, this.#keyring) + }, options) + } + + public async getMeetupIndex(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: CallOptions = {} as CallOptions): Promise { + return await callGetter(this, [Request.TrustedGetter, 'meetup_index', 'MeetupIndexType'], { + cid, + account: toAccount(accountOrPubKey, this.#keyring) + }, options) + } + + public async getAttestations(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: CallOptions = {} as CallOptions): Promise> { + return await callGetter>(this, [Request.TrustedGetter, 'attestations', 'Vec'], { + cid, + account: toAccount(accountOrPubKey, this.#keyring) + }, options) + } + + public async getMeetupRegistry(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: CallOptions = {} as CallOptions): Promise> { + return await callGetter>(this, [Request.TrustedGetter, 'meetup_registry', 'Vec'], { + cid, + account: toAccount(accountOrPubKey, this.keyring()) + }, options) + } + + public async trustedBalanceTransfer(accountOrPubKey: KeyringPair | PubKeyPinPair, shard: ShardIdentifier, mrenclave: string, params: BalanceTransferArgs, options: CallOptions = {} as CallOptions): Promise { + const nonce = await this.getNonce(accountOrPubKey, mrenclave, options); + const call = createTrustedCall(this, ['balance_transfer', 'BalanceTransferArgs'], accountOrPubKey, shard, mrenclave, nonce, params); + return this.sendTrustedCall(call, shard, options); + } + + public async balanceUnshieldFunds(accountOrPubKey: KeyringPair | PubKeyPinPair, shard: ShardIdentifier, mrenclave: string, params: BalanceUnshieldArgs, options: CallOptions = {} as CallOptions): Promise { + const nonce = await this.getNonce(accountOrPubKey, mrenclave, options); + const call = createTrustedCall(this, ['balance_unshield', 'BalanceUnshieldArgs'], accountOrPubKey, shard, mrenclave, nonce, params); + return this.sendTrustedCall(call, shard, options); + } + + async sendTrustedCall(call: TrustedCallSigned, shard: ShardIdentifier, options: CallOptions = {} as CallOptions): Promise { + if (this.shieldingKey() == undefined) { + const key = await this.getShieldingKey(options); + console.log(`Setting the shielding pubKey of the worker.`) + this.setShieldingKey(key); + } + + return sendTrustedCall(this, call, shard, true, 'TrustedOperationResult', options); + } +} diff --git a/packages/worker-api/src/index.ts b/packages/worker-api/src/index.ts index 78d32b95..90f94eda 100644 --- a/packages/worker-api/src/index.ts +++ b/packages/worker-api/src/index.ts @@ -1,3 +1,5 @@ -export { EncointerWorker } from './worker.js'; +export { Worker } from './worker.js'; +export { EncointerWorker } from './encointerWorker.js'; +export { IntegriteeWorker } from './integriteeWorker.js'; export * from './interface.js'; diff --git a/packages/worker-api/src/integriteeWorker.spec.ts b/packages/worker-api/src/integriteeWorker.spec.ts new file mode 100644 index 00000000..eb403816 --- /dev/null +++ b/packages/worker-api/src/integriteeWorker.spec.ts @@ -0,0 +1,96 @@ +import { Keyring } from '@polkadot/api'; +import { cryptoWaitReady } from '@polkadot/util-crypto'; +import { localDockerNetwork } from './testUtils/networks.js'; +import { IntegriteeWorker } from './integriteeWorker.js'; +import WS from 'websocket'; +import {KeyringPair} from "@polkadot/keyring/types"; +import bs58 from "bs58"; + +const {w3cwebsocket: WebSocket} = WS; + +describe('worker', () => { + const network = localDockerNetwork(); + let keyring: Keyring; + let worker: IntegriteeWorker; + let alice: KeyringPair; + let charlie: KeyringPair; + beforeAll(async () => { + jest.setTimeout(90000); + await cryptoWaitReady(); + keyring = new Keyring({type: 'sr25519'}); + alice = keyring.addFromUri('//Alice', {name: 'Alice default'}); + charlie = keyring.addFromUri('//Charlie', {name: 'Bob default'}); + + worker = new IntegriteeWorker(network.worker, { + keyring: keyring, + types: network.customTypes, + // @ts-ignore + createWebSocket: (url) => new WebSocket( + url, + undefined, + undefined, + undefined, + // Allow the worker's self-signed certificate + { rejectUnauthorized: false } + ), + api: null, + }); + }); + + // skip it, as this requires a worker (and hence a node) to be running + // To my knowledge jest does not have an option to run skipped tests specifically, does it? + // Todo: add proper CI to test this too. + describe('needs worker and node running', () => { + describe('getWorkerPubKey', () => { + it('should return value', async () => { + const result = await worker.getShieldingKey(); + // console.log('Shielding Key', result); + expect(result).toBeDefined(); + }); + }); + + describe('getShardVault', () => { + it('should return value', async () => { + const result = await worker.getShardVault(); + console.log('ShardVault', result.toHuman()); + expect(result).toBeDefined(); + }); + }); + + describe('getBalance', () => { + it('should return value', async () => { + const result = await worker.getBalance(charlie, network.mrenclave); + console.log('getBalance toNumber:', result.toString(10)); + expect(result).toBeDefined(); + }); + }); + + describe('getNonce', () => { + it('should return value', async () => { + const result = await worker.getNonce(alice, network.mrenclave); + console.log('getNonce', result); + expect(result).toBeDefined(); + }); + }); + + describe('balance transfer should work', () => { + it('should return value', async () => { + const shard = worker.createType('ShardIdentifier', bs58.decode(network.mrenclave)); + const params = worker.createType('BalanceTransferArgs', [alice.address, charlie.address, 1100000000000]) + const result = await worker.trustedBalanceTransfer(alice, shard, network.mrenclave, params); + console.log('balance transfer result', result.toHuman()); + expect(result).toBeDefined(); + }); + }); + + describe('balance unshield should work', () => { + it('should return value', async () => { + const shard = worker.createType('ShardIdentifier', bs58.decode(network.mrenclave)); + const params = worker.createType('BalanceUnshieldArgs', [alice.address, charlie.address, 1100000000000, shard]) + const result = await worker.balanceUnshieldFunds(alice, shard, network.mrenclave, params); + console.log('balance unshield result', result.toHuman()); + expect(result).toBeDefined(); + }); + }); + }); +}); diff --git a/packages/worker-api/src/integriteeWorker.ts b/packages/worker-api/src/integriteeWorker.ts new file mode 100644 index 00000000..0d32d22d --- /dev/null +++ b/packages/worker-api/src/integriteeWorker.ts @@ -0,0 +1,57 @@ +import type {u32} from '@polkadot/types'; + +// @ts-ignore +import NodeRSA from 'node-rsa'; + + +import type {KeyringPair} from '@polkadot/keyring/types'; +import type {Balance, Hash} from '@polkadot/types/interfaces/runtime'; +import type { + BalanceTransferArgs, BalanceUnshieldArgs, + ShardIdentifier, TrustedCallSigned, +} from '@encointer/types'; + +import {type CallOptions, Request} from './interface.js'; +import {callGetter, sendTrustedCall} from './sendRequest.js'; +import {createTrustedCall} from "@encointer/worker-api/requests.js"; +import {PubKeyPinPair, toAccount} from "@encointer/util/common"; +import {Worker} from "@encointer/worker-api/worker.js"; + +export class IntegriteeWorker extends Worker { + + public async getNonce(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: CallOptions = {} as CallOptions): Promise { + return await callGetter(this, [Request.TrustedGetter, 'nonce', 'u32'], { + shard: cid, + account: toAccount(accountOrPubKey, this.keyring()) + }, options) + } + + public async getBalance(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: CallOptions = {} as CallOptions): Promise { + return await callGetter(this, [Request.TrustedGetter, 'free_balance', 'Balance'], { + shard: cid, + account: toAccount(accountOrPubKey, this.keyring()) + }, options) + } + + public async trustedBalanceTransfer(accountOrPubKey: KeyringPair | PubKeyPinPair, shard: ShardIdentifier, mrenclave: string, params: BalanceTransferArgs, options: CallOptions = {} as CallOptions): Promise { + const nonce = await this.getNonce(accountOrPubKey, mrenclave, options); + const call = createTrustedCall(this, ['balance_transfer', 'BalanceTransferArgs'], accountOrPubKey, shard, mrenclave, nonce, params); + return this.sendTrustedCall(call, shard, options); + } + + public async balanceUnshieldFunds(accountOrPubKey: KeyringPair | PubKeyPinPair, shard: ShardIdentifier, mrenclave: string, params: BalanceUnshieldArgs, options: CallOptions = {} as CallOptions): Promise { + const nonce = await this.getNonce(accountOrPubKey, mrenclave, options); + const call = createTrustedCall(this, ['balance_unshield', 'BalanceUnshieldArgs'], accountOrPubKey, shard, mrenclave, nonce, params); + return this.sendTrustedCall(call, shard, options); + } + + async sendTrustedCall(call: TrustedCallSigned, shard: ShardIdentifier, options: CallOptions = {} as CallOptions): Promise { + if (this.shieldingKey() == undefined) { + const key = await this.getShieldingKey(options); + console.log(`Setting the shielding pubKey of the worker.`) + this.setShieldingKey(key); + } + + return sendTrustedCall(this, call, shard, true, 'TrustedOperationResult', options); + } +} diff --git a/packages/worker-api/src/interface.ts b/packages/worker-api/src/interface.ts index e6ab22ae..2afb1427 100644 --- a/packages/worker-api/src/interface.ts +++ b/packages/worker-api/src/interface.ts @@ -4,7 +4,7 @@ import {Keyring} from "@polkadot/keyring"; import type {u8} from "@polkadot/types-codec"; import type {Vec} from "@polkadot/types"; -export interface IIntegriteeWorker extends WebSocketAsPromised { +export interface IWorker extends WebSocketAsPromised { rsCount: number; rqStack: string[]; keyring: () => Keyring | undefined; diff --git a/packages/worker-api/src/parsers.ts b/packages/worker-api/src/parsers.ts index a4e0419f..b6b90ca5 100644 --- a/packages/worker-api/src/parsers.ts +++ b/packages/worker-api/src/parsers.ts @@ -4,10 +4,10 @@ import { u8aToBn, u8aToBuffer } from '@polkadot/util'; // @ts-ignore import NodeRSA from 'node-rsa'; -import type { IIntegriteeWorker } from './interface.js'; +import type { IWorker } from './interface.js'; import type { BalanceEntry } from "@encointer/types"; -export function parseBalance(self: IIntegriteeWorker, data: any): BalanceEntry { +export function parseBalance(self: IWorker, data: any): BalanceEntry { const balanceEntry = self.createType('BalanceEntry', data); // Todo: apply demurrage return self.createType('BalanceEntry', diff --git a/packages/worker-api/src/requests.ts b/packages/worker-api/src/requests.ts index 8673fff0..95fb4e01 100644 --- a/packages/worker-api/src/requests.ts +++ b/packages/worker-api/src/requests.ts @@ -1,6 +1,6 @@ import { createJsonRpcRequest, - type IIntegriteeWorker, type PublicGetterArgs, + type IWorker, type PublicGetterArgs, type TrustedGetterArgs } from "@encointer/worker-api/interface.js"; import type {BalanceTransferArgs, BalanceUnshieldArgs, ShardIdentifier, TrustedCallSigned} from "@encointer/types"; @@ -10,7 +10,7 @@ import type {u32} from "@polkadot/types"; import bs58 from "bs58"; // Todo: Properly resolve cid vs shard -export const clientRequestGetter = (self: IIntegriteeWorker, request: string, args: PublicGetterArgs) => { +export const clientRequestGetter = (self: IWorker, request: string, args: PublicGetterArgs) => { const { cid } = args; const getter = self.createType('PublicGetter', { [request]: cid @@ -29,7 +29,7 @@ export const clientRequestGetter = (self: IIntegriteeWorker, request: string, ar return createJsonRpcRequest('state_executeGetter', [r.toHex()],1); } -export const clientRequestTrustedGetter = (self: IIntegriteeWorker, request: string, args: TrustedGetterArgs) => { +export const clientRequestTrustedGetter = (self: IWorker, request: string, args: TrustedGetterArgs) => { const {shard, account} = args; const address = account.address; const getter = self.createType('TrustedGetter', { @@ -62,7 +62,7 @@ export type TrustedCallArgs = (BalanceTransferArgs | BalanceUnshieldArgs); export type TrustedCallVariant = [string, string] export const createTrustedCall = ( - self: IIntegriteeWorker, + self: IWorker, trustedCall: TrustedCallVariant, accountOrPubKey: (KeyringPair | PubKeyPinPair), shard: ShardIdentifier, diff --git a/packages/worker-api/src/sendRequest.ts b/packages/worker-api/src/sendRequest.ts index 1b1d9b63..7c27413a 100644 --- a/packages/worker-api/src/sendRequest.ts +++ b/packages/worker-api/src/sendRequest.ts @@ -1,5 +1,5 @@ import { - type IIntegriteeWorker, + type IWorker, type TrustedGetterArgs, type PublicGetterArgs, type RequestArgs, @@ -14,7 +14,7 @@ import { } from "@encointer/worker-api/requests.js"; import type {ShardIdentifier, TrustedCallSigned} from "@encointer/types"; -const sendWorkerRequest = (self: IIntegriteeWorker, clientRequest: any, parserType: string, options: CallOptions): Promise =>{ +const sendWorkerRequest = (self: IWorker, clientRequest: any, parserType: string, options: CallOptions): Promise =>{ const requestId = self.rqStack.push(parserType) + self.rsCount; return self.sendRequest( clientRequest, { @@ -24,13 +24,13 @@ const sendWorkerRequest = (self: IIntegriteeWorker, clientRequest: any, parserTy ) } -const sendTrustedGetterRequest = (self: IIntegriteeWorker, method: string, parser: string, args: TrustedGetterArgs, options: CallOptions) => +const sendTrustedGetterRequest = (self: IWorker, method: string, parser: string, args: TrustedGetterArgs, options: CallOptions) => sendWorkerRequest(self, clientRequestTrustedGetter(self, method, args), parser, options) -const sendPublicGetterRequest = (self: IIntegriteeWorker, method: string, parser: string, args: PublicGetterArgs, options: CallOptions) => +const sendPublicGetterRequest = (self: IWorker, method: string, parser: string, args: PublicGetterArgs, options: CallOptions) => sendWorkerRequest(self, clientRequestGetter(self, method, args), parser, options) -export const callGetter = async (self: IIntegriteeWorker, workerMethod: WorkerMethod, args: RequestArgs, options: CallOptions = {} as CallOptions): Promise => { +export const callGetter = async (self: IWorker, workerMethod: WorkerMethod, args: RequestArgs, options: CallOptions = {} as CallOptions): Promise => { if( !self.isOpened ) { await self.open(); } @@ -54,7 +54,7 @@ export const callGetter = async (self: IIntegriteeWorker, workerMethod: Worke return result as Promise } -export const sendTrustedCall = async (self: IIntegriteeWorker, call: TrustedCallSigned, shard: ShardIdentifier, direct: boolean, parser: string, options: CallOptions = {} as CallOptions): Promise => { +export const sendTrustedCall = async (self: IWorker, call: TrustedCallSigned, shard: ShardIdentifier, direct: boolean, parser: string, options: CallOptions = {} as CallOptions): Promise => { if( !self.isOpened ) { await self.open(); } diff --git a/packages/worker-api/src/worker.ts b/packages/worker-api/src/worker.ts index fc56630a..16009ca5 100644 --- a/packages/worker-api/src/worker.ts +++ b/packages/worker-api/src/worker.ts @@ -1,4 +1,4 @@ -import type {u32, u64, Vec} from '@polkadot/types'; +import type {Vec} from '@polkadot/types'; import {TypeRegistry} from '@polkadot/types'; import type {RegistryTypes} from '@polkadot/types/types'; import {Keyring} from '@polkadot/keyring' @@ -7,39 +7,28 @@ import {bufferToU8a, compactAddLength, hexToU8a, u8aToBuffer} from '@polkadot/ut import WebSocketAsPromised from 'websocket-as-promised'; import {options as encointerOptions} from '@encointer/node-api'; -import {communityIdentifierFromString, parseI64F64} from '@encointer/util'; +import {parseI64F64} from '@encointer/util'; // @ts-ignore import NodeRSA from 'node-rsa'; - -import type {KeyringPair} from '@polkadot/keyring/types'; -import type {AccountId, Balance, Hash, Moment} from '@polkadot/types/interfaces/runtime'; import type { - Attestation, - BalanceTransferArgs, BalanceUnshieldArgs, - CommunityIdentifier, - MeetupIndexType, - ParticipantIndexType, - SchedulerState, ShardIdentifier, TrustedCallSigned, Vault } from '@encointer/types'; -import {type CallOptions, type IIntegriteeWorker, Request, type WorkerOptions} from './interface.js'; +import {type CallOptions, type IWorker, Request, type WorkerOptions} from './interface.js'; import {parseBalance, parseNodeRSA} from './parsers.js'; -import {callGetter, sendTrustedCall} from './sendRequest.js'; -import {createTrustedCall} from "@encointer/worker-api/requests.js"; -import {PubKeyPinPair, toAccount} from "@encointer/util/common"; +import {callGetter} from './sendRequest.js'; import type {u8} from "@polkadot/types-codec"; -const unwrapWorkerResponse = (self: IIntegriteeWorker, data: string) => { +const unwrapWorkerResponse = (self: IWorker, data: string) => { /// Defaults to return `[]`, which is fine as `createType(api.registry, , [])` /// instantiates the with its default value. const dataTyped = self.createType('Option', data) return dataTyped.unwrapOrDefault(); } -const parseGetterResponse = (self: IIntegriteeWorker, responseType: string, data: string) => { +const parseGetterResponse = (self: IWorker, responseType: string, data: string) => { if (data === 'Could not decode request') { throw new Error(`Worker error: ${data}`); } @@ -95,7 +84,7 @@ const parseGetterResponse = (self: IIntegriteeWorker, responseType: string, data return parsedData; } -export class EncointerWorker extends WebSocketAsPromised implements IIntegriteeWorker { +export class Worker extends WebSocketAsPromised implements IWorker { readonly #registry: TypeRegistry; @@ -156,10 +145,6 @@ export class EncointerWorker extends WebSocketAsPromised implements IIntegriteeW this.#shieldingKey = shieldingKey; } - public cidFromStr(cidStr: String): CommunityIdentifier { - return communityIdentifierFromString(this.#registry, cidStr); - } - public async getShieldingKey(options: CallOptions = {} as CallOptions): Promise { return await callGetter(this, [Request.Worker, 'author_getShieldingKey', 'NodeRSA'], {}, options) } @@ -167,96 +152,4 @@ export class EncointerWorker extends WebSocketAsPromised implements IIntegriteeW public async getShardVault(options: CallOptions = {} as CallOptions): Promise { return await callGetter(this, [Request.Worker, 'author_getShardVault', 'Vault'], {}, options) } - - public async getNonce(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: CallOptions = {} as CallOptions): Promise { - return await callGetter(this, [Request.TrustedGetter, 'nonce', 'u32'], { - shard: cid, - account: toAccount(accountOrPubKey, this.#keyring) - }, options) - } - - public async getTotalIssuance(cid: string, options: CallOptions = {} as CallOptions): Promise { - return await callGetter(this, [Request.PublicGetter, 'total_issuance', 'Balance'], {cid}, options) - } - - public async getParticipantCount(cid: string, options: CallOptions = {} as CallOptions): Promise { - return (await callGetter(this, [Request.PublicGetter, 'participant_count', 'u64'], {cid}, options)).toNumber() - } - - public async getMeetupCount(cid: string, options: CallOptions = {} as CallOptions): Promise { - return (await callGetter(this, [Request.PublicGetter, 'meetup_count', 'u64'], {cid}, options)).toNumber() - } - - public async getCeremonyReward(cid: string, options: CallOptions = {} as CallOptions): Promise { - return await callGetter(this, [Request.PublicGetter, 'ceremony_reward', 'I64F64'], {cid}, options) - } - - public async getLocationTolerance(cid: string, options: CallOptions = {} as CallOptions): Promise { - return (await callGetter(this, [Request.PublicGetter, 'location_tolerance', 'u32'], {cid}, options)).toNumber() - } - - public async getTimeTolerance(cid: string, options: CallOptions = {} as CallOptions): Promise { - return await callGetter(this, [Request.PublicGetter, 'time_tolerance', 'Moment'], {cid}, options) - } - - public async getSchedulerState(cid: string, options: CallOptions = {} as CallOptions): Promise { - return await callGetter(this, [Request.PublicGetter, 'scheduler_state', 'SchedulerState'], {cid}, options) - } - - public async getBalance(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: CallOptions = {} as CallOptions): Promise { - return await callGetter(this, [Request.TrustedGetter, 'free_balance', 'Balance'], { - shard: cid, - account: toAccount(accountOrPubKey, this.#keyring) - }, options) - } - - public async getParticipantIndex(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: CallOptions = {} as CallOptions): Promise { - return await callGetter(this, [Request.TrustedGetter, 'participant_index', 'ParticipantIndexType'], { - cid, - account: toAccount(accountOrPubKey, this.#keyring) - }, options) - } - - public async getMeetupIndex(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: CallOptions = {} as CallOptions): Promise { - return await callGetter(this, [Request.TrustedGetter, 'meetup_index', 'MeetupIndexType'], { - cid, - account: toAccount(accountOrPubKey, this.#keyring) - }, options) - } - - public async getAttestations(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: CallOptions = {} as CallOptions): Promise> { - return await callGetter>(this, [Request.TrustedGetter, 'attestations', 'Vec'], { - cid, - account: toAccount(accountOrPubKey, this.#keyring) - }, options) - } - - public async getMeetupRegistry(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: CallOptions = {} as CallOptions): Promise> { - return await callGetter>(this, [Request.TrustedGetter, 'meetup_registry', 'Vec'], { - cid, - account: toAccount(accountOrPubKey, this.#keyring) - }, options) - } - - public async trustedBalanceTransfer(accountOrPubKey: KeyringPair | PubKeyPinPair, shard: ShardIdentifier, mrenclave: string, params: BalanceTransferArgs, options: CallOptions = {} as CallOptions): Promise { - const nonce = await this.getNonce(accountOrPubKey, mrenclave, options); - const call = createTrustedCall(this, ['balance_transfer', 'BalanceTransferArgs'], accountOrPubKey, shard, mrenclave, nonce, params); - return this.sendTrustedCall(call, shard, options); - } - - public async balanceUnshieldFunds(accountOrPubKey: KeyringPair | PubKeyPinPair, shard: ShardIdentifier, mrenclave: string, params: BalanceUnshieldArgs, options: CallOptions = {} as CallOptions): Promise { - const nonce = await this.getNonce(accountOrPubKey, mrenclave, options); - const call = createTrustedCall(this, ['balance_unshield', 'BalanceUnshieldArgs'], accountOrPubKey, shard, mrenclave, nonce, params); - return this.sendTrustedCall(call, shard, options); - } - - async sendTrustedCall(call: TrustedCallSigned, shard: ShardIdentifier, options: CallOptions = {} as CallOptions): Promise { - if (this.shieldingKey() == undefined) { - const key = await this.getShieldingKey(options); - console.log(`Setting the shielding pubKey of the worker.`) - this.setShieldingKey(key); - } - - return sendTrustedCall(this, call, shard, true, 'TrustedOperationResult', options); - } } From 6a846f3bde2167f8fca9c05e935e76beaf437786 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Wed, 10 Apr 2024 09:28:59 +0800 Subject: [PATCH 37/41] [worker] finalize separation of workers --- .../worker-api/src/encointerWorker.spec.ts | 9 +- packages/worker-api/src/encointerWorker.ts | 14 +- .../worker-api/src/integriteeWorker.spec.ts | 2 +- packages/worker-api/src/interface.ts | 3 +- packages/worker-api/src/worker.spec.ts | 133 +----------------- packages/worker-api/src/worker.ts | 4 + 6 files changed, 21 insertions(+), 144 deletions(-) diff --git a/packages/worker-api/src/encointerWorker.spec.ts b/packages/worker-api/src/encointerWorker.spec.ts index c72290b7..0b60c462 100644 --- a/packages/worker-api/src/encointerWorker.spec.ts +++ b/packages/worker-api/src/encointerWorker.spec.ts @@ -3,7 +3,6 @@ import { cryptoWaitReady } from '@polkadot/util-crypto'; import { localDockerNetwork } from './testUtils/networks.js'; import { EncointerWorker } from './encointerWorker.js'; import WS from 'websocket'; -import {KeyringPair} from "@polkadot/keyring/types"; const {w3cwebsocket: WebSocket} = WS; @@ -11,14 +10,14 @@ describe('worker', () => { const network = localDockerNetwork(); let keyring: Keyring; let worker: EncointerWorker; - let alice: KeyringPair; - let charlie: KeyringPair; + // let alice: KeyringPair; + // let charlie: KeyringPair; beforeAll(async () => { jest.setTimeout(90000); await cryptoWaitReady(); keyring = new Keyring({type: 'sr25519'}); - alice = keyring.addFromUri('//Alice', {name: 'Alice default'}); - charlie = keyring.addFromUri('//Charlie', {name: 'Bob default'}); + // alice = keyring.addFromUri('//Alice', {name: 'Alice default'}); + // charlie = keyring.addFromUri('//Charlie', {name: 'Bob default'}); worker = new EncointerWorker(network.worker, { keyring: keyring, diff --git a/packages/worker-api/src/encointerWorker.ts b/packages/worker-api/src/encointerWorker.ts index 8fcbb468..49d14030 100644 --- a/packages/worker-api/src/encointerWorker.ts +++ b/packages/worker-api/src/encointerWorker.ts @@ -5,16 +5,16 @@ import {communityIdentifierFromString} from '@encointer/util'; import NodeRSA from 'node-rsa'; import type { - CommunityIdentifier, ShardIdentifier, + CommunityIdentifier, MeetupIndexType, ParticipantIndexType, SchedulerState, ShardIdentifier, TrustedCallSigned, } from '@encointer/types'; -import {type CallOptions} from './interface.js'; +import {type CallOptions, Request} from './interface.js'; import {callGetter, sendTrustedCall} from './sendRequest.js'; import {createTrustedCall} from "@encointer/worker-api/requests.js"; import {PubKeyPinPair, toAccount} from "@encointer/util/common"; import type {KeyringPair} from "@polkadot/keyring/types"; import {Worker} from "@encointer/worker-api/worker.js"; -import type {AccountId, Balance, Hash} from "@polkadot/types/interfaces/runtime"; +import type {AccountId, Balance, Hash, Moment} from "@polkadot/types/interfaces/runtime"; export class EncointerWorker extends Worker { @@ -60,28 +60,28 @@ export class EncointerWorker extends Worker { public async getBalance(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: CallOptions = {} as CallOptions): Promise { return await callGetter(this, [Request.TrustedGetter, 'free_balance', 'Balance'], { shard: cid, - account: toAccount(accountOrPubKey, this.#keyring) + account: toAccount(accountOrPubKey,this.keyring()) }, options) } public async getParticipantIndex(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: CallOptions = {} as CallOptions): Promise { return await callGetter(this, [Request.TrustedGetter, 'participant_index', 'ParticipantIndexType'], { cid, - account: toAccount(accountOrPubKey, this.#keyring) + account: toAccount(accountOrPubKey,this.keyring()) }, options) } public async getMeetupIndex(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: CallOptions = {} as CallOptions): Promise { return await callGetter(this, [Request.TrustedGetter, 'meetup_index', 'MeetupIndexType'], { cid, - account: toAccount(accountOrPubKey, this.#keyring) + account: toAccount(accountOrPubKey,this.keyring()) }, options) } public async getAttestations(accountOrPubKey: KeyringPair | PubKeyPinPair, cid: string, options: CallOptions = {} as CallOptions): Promise> { return await callGetter>(this, [Request.TrustedGetter, 'attestations', 'Vec'], { cid, - account: toAccount(accountOrPubKey, this.#keyring) + account: toAccount(accountOrPubKey,this.keyring()) }, options) } diff --git a/packages/worker-api/src/integriteeWorker.spec.ts b/packages/worker-api/src/integriteeWorker.spec.ts index eb403816..83db8869 100644 --- a/packages/worker-api/src/integriteeWorker.spec.ts +++ b/packages/worker-api/src/integriteeWorker.spec.ts @@ -3,7 +3,7 @@ import { cryptoWaitReady } from '@polkadot/util-crypto'; import { localDockerNetwork } from './testUtils/networks.js'; import { IntegriteeWorker } from './integriteeWorker.js'; import WS from 'websocket'; -import {KeyringPair} from "@polkadot/keyring/types"; +import {type KeyringPair} from "@polkadot/keyring/types"; import bs58 from "bs58"; const {w3cwebsocket: WebSocket} = WS; diff --git a/packages/worker-api/src/interface.ts b/packages/worker-api/src/interface.ts index 2afb1427..b335fb24 100644 --- a/packages/worker-api/src/interface.ts +++ b/packages/worker-api/src/interface.ts @@ -2,7 +2,7 @@ import type { KeyringPair } from '@polkadot/keyring/types'; import WebSocketAsPromised from 'websocket-as-promised'; import {Keyring} from "@polkadot/keyring"; import type {u8} from "@polkadot/types-codec"; -import type {Vec} from "@polkadot/types"; +import type {TypeRegistry, Vec} from "@polkadot/types"; export interface IWorker extends WebSocketAsPromised { rsCount: number; @@ -11,6 +11,7 @@ export interface IWorker extends WebSocketAsPromised { createType: (apiType: string, obj?: any) => any; open: () => Promise; encrypt: (data: Uint8Array) => Vec + registry: () => TypeRegistry } export interface JsonRpcRequest { diff --git a/packages/worker-api/src/worker.spec.ts b/packages/worker-api/src/worker.spec.ts index 2c35d344..2c38d746 100644 --- a/packages/worker-api/src/worker.spec.ts +++ b/packages/worker-api/src/worker.spec.ts @@ -1,17 +1,16 @@ import { Keyring } from '@polkadot/api'; import { cryptoWaitReady } from '@polkadot/util-crypto'; import { localDockerNetwork } from './testUtils/networks.js'; -import { EncointerWorker } from './worker.js'; +import { Worker } from './worker.js'; import WS from 'websocket'; import {KeyringPair} from "@polkadot/keyring/types"; -import bs58 from "bs58"; const {w3cwebsocket: WebSocket} = WS; describe('worker', () => { const network = localDockerNetwork(); let keyring: Keyring; - let worker: EncointerWorker; + let worker: Worker; let alice: KeyringPair; let charlie: KeyringPair; beforeAll(async () => { @@ -21,7 +20,7 @@ describe('worker', () => { alice = keyring.addFromUri('//Alice', {name: 'Alice default'}); charlie = keyring.addFromUri('//Charlie', {name: 'Bob default'}); - worker = new EncointerWorker(network.worker, { + worker = new Worker(network.worker, { keyring: keyring, types: network.customTypes, // @ts-ignore @@ -56,131 +55,5 @@ describe('worker', () => { expect(result).toBeDefined(); }); }); - - describe('getBalance', () => { - it('should return value', async () => { - const result = await worker.getBalance(charlie, network.mrenclave); - console.log('getBalance toNumber:', result.toString(10)); - expect(result).toBeDefined(); - }); - }); - - describe('getNonce', () => { - it('should return value', async () => { - const result = await worker.getNonce(alice, network.mrenclave); - console.log('getNonce', result); - expect(result).toBeDefined(); - }); - }); - - describe('balance transfer should work', () => { - it('should return value', async () => { - const shard = worker.createType('ShardIdentifier', bs58.decode(network.mrenclave)); - const params = worker.createType('BalanceTransferArgs', [alice.address, charlie.address, 1100000000000]) - const result = await worker.trustedBalanceTransfer(alice, shard, network.mrenclave, params); - console.log('balance transfer result', result.toHuman()); - expect(result).toBeDefined(); - }); - }); - - describe('balance unshield should work', () => { - it('should return value', async () => { - const shard = worker.createType('ShardIdentifier', bs58.decode(network.mrenclave)); - const params = worker.createType('BalanceUnshieldArgs', [alice.address, charlie.address, 1100000000000, shard]) - const result = await worker.balanceUnshieldFunds(alice, shard, network.mrenclave, params); - console.log('balance unshield result', result.toHuman()); - expect(result).toBeDefined(); - }); - }); - - // Tests specific for the encointer protocol - describe('encointer-worker', () => { - describe('getTotalIssuance', () => { - it('should return value', async () => { - const result = await worker.getTotalIssuance(network.chosenCid); - // console.log('getTotalIssuance', result); - expect(result).toBeDefined(); - }); - }); - - describe('getParticipantCount', () => { - it('should return default value', async () => { - const result = await worker.getParticipantCount(network.chosenCid); - expect(result).toBe(0); - }); - }); - - describe('getMeetupCount', () => { - it('should return default value', async () => { - const result = await worker.getMeetupCount(network.chosenCid); - expect(result).toBe(0); - }); - }); - - describe('getCeremonyReward', () => { - it('should return default value', async () => { - const result = await worker.getCeremonyReward(network.chosenCid); - expect(result).toBe(1); - }); - }); - - describe('getLocationTolerance', () => { - it('should return default value', async () => { - const result = await worker.getLocationTolerance(network.chosenCid); - expect(result).toBe(1000); - }); - }); - - describe('getTimeTolerance', () => { - it('should return default value', async () => { - const result = await worker.getTimeTolerance(network.chosenCid); - expect(result.toNumber()).toBe(600000); - }); - }); - - describe('getSchedulerState', () => { - it('should return value', async () => { - const result = await worker.getSchedulerState(network.chosenCid); - // console.log('schedulerStateResult', result); - expect(result).toBeDefined(); - }); - }); - - describe('getRegistration', () => { - it('should return default value', async () => { - await cryptoWaitReady(); - const bob = keyring.addFromUri('//Bob', {name: 'Bob default'}); - const result = await worker.getParticipantIndex(bob, network.chosenCid); - expect(result.toNumber()).toBe(0); - }); - }); - - describe('getMeetupIndex', () => { - it('should return default value', async () => { - await cryptoWaitReady(); - const bob = keyring.addFromUri('//Bob', {name: 'Bob default'}); - const result = await worker.getMeetupIndex(bob, network.chosenCid); - expect(result.toNumber()).toBe(0); - }); - }); - - describe('getAttestations', () => { - it('should be empty', async () => { - await cryptoWaitReady(); - const bob = keyring.addFromUri('//Bob', {name: 'Bob default'}); - const result = await worker.getAttestations(bob, network.chosenCid); - expect(result.toJSON()).toStrictEqual([]); - }); - }); - - describe('getMeetupRegistry method', () => { - it('should be empty', async () => { - await cryptoWaitReady(); - const bob = keyring.addFromUri('//Bob', {name: 'Bob default'}); - const result = await worker.getMeetupRegistry(bob, network.chosenCid); - expect(result.toJSON()).toStrictEqual([]); - }); - }); - }); }); }); diff --git a/packages/worker-api/src/worker.ts b/packages/worker-api/src/worker.ts index 16009ca5..ac8c08a0 100644 --- a/packages/worker-api/src/worker.ts +++ b/packages/worker-api/src/worker.ts @@ -125,6 +125,10 @@ export class Worker extends WebSocketAsPromised implements IWorker { return this.createType('Vec', compactAddLength(cypherArray)) } + public registry(): TypeRegistry { + return this.#registry + } + public createType(apiType: string, obj?: any): any { return this.#registry.createType(apiType as never, obj) } From 57ab509ad971df4bbfb23080fd2c4c8308faac43 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Wed, 10 Apr 2024 09:54:29 +0800 Subject: [PATCH 38/41] [worker] separate types of integritee and encointer --- .../types/src/interfaces/augment-types.ts | 29 +++-- packages/types/src/interfaces/definitions.ts | 2 + .../interfaces/encointerWorker/definitions.ts | 53 +++++++++ .../src/interfaces/encointerWorker/index.ts | 4 + .../src/interfaces/encointerWorker/types.ts | 96 ++++++++++++++++ .../integriteeWorker/definitions.ts | 60 ++++++++++ .../src/interfaces/integriteeWorker/index.ts | 4 + .../src/interfaces/integriteeWorker/types.ts | 107 ++++++++++++++++++ packages/types/src/interfaces/types.ts | 2 + .../src/interfaces/worker/definitions.ts | 55 --------- packages/types/src/interfaces/worker/types.ts | 101 +---------------- packages/worker-api/src/encointerWorker.ts | 40 +++---- packages/worker-api/src/integriteeWorker.ts | 4 +- packages/worker-api/src/requests.ts | 18 +-- packages/worker-api/src/sendRequest.ts | 8 +- 15 files changed, 383 insertions(+), 200 deletions(-) create mode 100644 packages/types/src/interfaces/encointerWorker/definitions.ts create mode 100644 packages/types/src/interfaces/encointerWorker/index.ts create mode 100644 packages/types/src/interfaces/encointerWorker/types.ts create mode 100644 packages/types/src/interfaces/integriteeWorker/definitions.ts create mode 100644 packages/types/src/interfaces/integriteeWorker/index.ts create mode 100644 packages/types/src/interfaces/integriteeWorker/types.ts diff --git a/packages/types/src/interfaces/augment-types.ts b/packages/types/src/interfaces/augment-types.ts index adc5dcae..03f2d308 100644 --- a/packages/types/src/interfaces/augment-types.ts +++ b/packages/types/src/interfaces/augment-types.ts @@ -10,8 +10,10 @@ import type { BusinessData, BusinessIdentifier, OfferingData, OfferingIdentifier import type { Assignment, AssignmentCount, AssignmentParams, Attestation, AttestationIndexType, CeremonyIndexType, CeremonyPhaseType, ClaimOfAttendance, ClaimOfAttendanceSigningPayload, CommunityCeremonyStats, CommunityReputation, Meetup, MeetupAssignment, MeetupIndexType, MeetupResult, MeetupTimeOffsetType, ParticipantIndexType, ParticipantRegistration, ProofOfAttendance, RegistrationType, Reputation } from '@encointer/types/interfaces/ceremony'; import type { FixedI64F64, IpfsCid, PalletString } from '@encointer/types/interfaces/common'; import type { AnnouncementSigner, Bip340, CidDigest, CidName, CommunityCeremony, CommunityIdentifier, CommunityMetadataType, CommunityRules, DegreeFixed, DegreeRpc, GeoHash, Location, LocationRpc, NominalIncomeType } from '@encointer/types/interfaces/community'; +import type { EncointerBalanceTransferArgs, EncointerGetter, EncointerGetterArgs, EncointerPublicGetter, EncointerTrustedCall, EncointerTrustedCallSigned, EncointerTrustedGetter, EncointerTrustedGetterSigned, GrantReputationArgs, RegisterAttestationsArgs, RegisterParticipantArgs } from '@encointer/types/interfaces/encointerWorker'; +import type { BalanceSetBalanceArgs, BalanceShieldArgs, BalanceTransferArgs, BalanceUnshieldArgs, IntegriteeGetter, IntegriteePublicGetter, IntegriteeTrustedCall, IntegriteeTrustedCallSigned, IntegriteeTrustedGetter, IntegriteeTrustedGetterSigned, IntegriteeTrustedOperation, TimestampSetArgs } from '@encointer/types/interfaces/integriteeWorker'; import type { SchedulerState, SystemNumber } from '@encointer/types/interfaces/scheduler'; -import type { BalanceSetBalanceArgs, BalanceShieldArgs, BalanceTransferArgs, BalanceUnshieldArgs, DirectRequestStatus, Enclave, Getter, GetterArgs, ParentchainId, PublicGetter, Request, RpcReturnValue, ShardIdentifier, TimestampSetArgs, TrustedCall, TrustedCallSigned, TrustedGetter, TrustedGetterSigned, TrustedOperation, TrustedOperationStatus, Vault, WorkerEncoded } from '@encointer/types/interfaces/worker'; +import type { DirectRequestStatus, Enclave, GetterArgs, ParentchainId, Request, RpcReturnValue, ShardIdentifier, TrustedOperationStatus, Vault, WorkerEncoded } from '@encointer/types/interfaces/worker'; import type { Data, StorageKey } from '@polkadot/types'; import type { BitVec, Bool, Bytes, F32, F64, I128, I16, I256, I32, I64, I8, ISize, Json, Null, OptionBool, Raw, Text, Type, U128, U16, U256, U32, U64, U8, USize, bool, f32, f64, i128, i16, i256, i32, i64, i8, isize, u128, u16, u256, u32, u64, u8, usize } from '@polkadot/types-codec'; import type { AssetApproval, AssetApprovalKey, AssetBalance, AssetDestroyWitness, AssetDetails, AssetMetadata, TAssetBalance, TAssetDepositBalance } from '@polkadot/types/interfaces/assets'; @@ -409,6 +411,14 @@ declare module '@polkadot/types/types/registry' { Enclave: Enclave; EncodedFinalityProofs: EncodedFinalityProofs; EncodedJustification: EncodedJustification; + EncointerBalanceTransferArgs: EncointerBalanceTransferArgs; + EncointerGetter: EncointerGetter; + EncointerGetterArgs: EncointerGetterArgs; + EncointerPublicGetter: EncointerPublicGetter; + EncointerTrustedCall: EncointerTrustedCall; + EncointerTrustedCallSigned: EncointerTrustedCallSigned; + EncointerTrustedGetter: EncointerTrustedGetter; + EncointerTrustedGetterSigned: EncointerTrustedGetterSigned; Epoch: Epoch; EpochAuthorship: EpochAuthorship; Era: Era; @@ -545,7 +555,6 @@ declare module '@polkadot/types/types/registry' { FungiblesAccessError: FungiblesAccessError; Gas: Gas; GeoHash: GeoHash; - Getter: Getter; GetterArgs: GetterArgs; GiltBid: GiltBid; GlobalValidationData: GlobalValidationData; @@ -558,6 +567,7 @@ declare module '@polkadot/types/types/registry' { GrandpaPrecommit: GrandpaPrecommit; GrandpaPrevote: GrandpaPrevote; GrandpaSignedPrecommit: GrandpaSignedPrecommit; + GrantReputationArgs: GrantReputationArgs; GroupIndex: GroupIndex; GroupRotationInfo: GroupRotationInfo; H1024: H1024; @@ -630,6 +640,13 @@ declare module '@polkadot/types/types/registry' { InstantiateReturnValueTo267: InstantiateReturnValueTo267; InstructionV2: InstructionV2; InstructionWeights: InstructionWeights; + IntegriteeGetter: IntegriteeGetter; + IntegriteePublicGetter: IntegriteePublicGetter; + IntegriteeTrustedCall: IntegriteeTrustedCall; + IntegriteeTrustedCallSigned: IntegriteeTrustedCallSigned; + IntegriteeTrustedGetter: IntegriteeTrustedGetter; + IntegriteeTrustedGetterSigned: IntegriteeTrustedGetterSigned; + IntegriteeTrustedOperation: IntegriteeTrustedOperation; InteriorMultiLocation: InteriorMultiLocation; InvalidDisputeStatementKind: InvalidDisputeStatementKind; InvalidTransaction: InvalidTransaction; @@ -879,7 +896,6 @@ declare module '@polkadot/types/types/registry' { ProxyDefinition: ProxyDefinition; ProxyState: ProxyState; ProxyType: ProxyType; - PublicGetter: PublicGetter; PvfCheckStatement: PvfCheckStatement; PvfExecTimeoutKind: PvfExecTimeoutKind; PvfPrepTimeoutKind: PvfPrepTimeoutKind; @@ -914,7 +930,9 @@ declare module '@polkadot/types/types/registry' { ReferendumInfoFinished: ReferendumInfoFinished; ReferendumInfoTo239: ReferendumInfoTo239; ReferendumStatus: ReferendumStatus; + RegisterAttestationsArgs: RegisterAttestationsArgs; RegisteredParachainInfo: RegisteredParachainInfo; + RegisterParticipantArgs: RegisterParticipantArgs; RegistrarIndex: RegistrarIndex; RegistrarInfo: RegistrarInfo; Registration: Registration; @@ -1155,11 +1173,6 @@ declare module '@polkadot/types/types/registry' { TreasuryProposal: TreasuryProposal; TrieId: TrieId; TrieIndex: TrieIndex; - TrustedCall: TrustedCall; - TrustedCallSigned: TrustedCallSigned; - TrustedGetter: TrustedGetter; - TrustedGetterSigned: TrustedGetterSigned; - TrustedOperation: TrustedOperation; TrustedOperationStatus: TrustedOperationStatus; Type: Type; u128: u128; diff --git a/packages/types/src/interfaces/definitions.ts b/packages/types/src/interfaces/definitions.ts index 36e0e16a..c4f166d2 100644 --- a/packages/types/src/interfaces/definitions.ts +++ b/packages/types/src/interfaces/definitions.ts @@ -5,3 +5,5 @@ export { default as ceremony } from './ceremony/definitions.js'; export { default as community } from './community/definitions.js'; export { default as scheduler } from './scheduler/definitions.js'; export { default as worker } from './worker/definitions.js'; +export { default as encointerWorker } from './encointerWorker/definitions.js' +export { default as integriteeWorker } from './integriteeWorker/definitions.js' diff --git a/packages/types/src/interfaces/encointerWorker/definitions.ts b/packages/types/src/interfaces/encointerWorker/definitions.ts new file mode 100644 index 00000000..091d18b2 --- /dev/null +++ b/packages/types/src/interfaces/encointerWorker/definitions.ts @@ -0,0 +1,53 @@ +export default { + rpc: {}, + types: { + EncointerGetterArgs: '(AccountId, CommunityIdentifier)', + EncointerPublicGetter: { + _enum: { + total_issuance: 'CommunityIdentifier', + participant_count: 'CommunityIdentifier', + meetup_count: 'CommunityIdentifier', + ceremony_reward: 'CommunityIdentifier', + location_tolerance: 'CommunityIdentifier', + time_tolerance: 'CommunityIdentifier', + scheduler_state: 'CommunityIdentifier' + } + }, + EncointerTrustedGetter: { + _enum: { + balance: '(AccountId, CommunityIdentifier)', + participant_index: '(AccountId, CommunityIdentifier)', + meetup_index: '(AccountId, CommunityIdentifier)', + attestations: '(AccountId, CommunityIdentifier)', + meetup_registry: '(AccountId, CommunityIdentifier)' + } + }, + EncointerTrustedGetterSigned: { + getter: 'EncointerTrustedGetter', + signature: 'Signature' + }, + EncointerGetter: { + _enum: { + public: 'EncointerPublicGetter', + trusted: 'EncointerTrustedGetterSigned' + } + }, + EncointerTrustedCallSigned: { + call: 'EncointerTrustedCall', + nonce: 'u32', + signature: 'Signature' + }, + EncointerTrustedCall: { + _enum: { + balance_transfer: 'EncointerBalanceTransferArgs', + ceremonies_register_participant: 'RegisterParticipantArgs', + ceremonies_register_attestations: 'RegisterAttestationsArgs', + ceremonies_grant_reputation: 'GrantReputationArgs' + } + }, + EncointerBalanceTransferArgs: '(AccountId, AccountId, CommunityIdentifier, BalanceType)', + RegisterParticipantArgs: '(AccountId, CommunityIdentifier, Option>)', + RegisterAttestationsArgs: '(AccountId, Vec>)', + GrantReputationArgs: '(AccountId, CommunityIdentifier, AccountId)' + } +} diff --git a/packages/types/src/interfaces/encointerWorker/index.ts b/packages/types/src/interfaces/encointerWorker/index.ts new file mode 100644 index 00000000..7f1de782 --- /dev/null +++ b/packages/types/src/interfaces/encointerWorker/index.ts @@ -0,0 +1,4 @@ +// Auto-generated via `yarn polkadot-types-from-defs`, do not edit +/* eslint-disable */ + +export * from './types.js'; diff --git a/packages/types/src/interfaces/encointerWorker/types.ts b/packages/types/src/interfaces/encointerWorker/types.ts new file mode 100644 index 00000000..2436ee89 --- /dev/null +++ b/packages/types/src/interfaces/encointerWorker/types.ts @@ -0,0 +1,96 @@ +// Auto-generated via `yarn polkadot-types-from-defs`, do not edit +/* eslint-disable */ + +import type { BalanceType } from '@encointer/types/interfaces/balances'; +import type { Attestation, ProofOfAttendance } from '@encointer/types/interfaces/ceremony'; +import type { CommunityIdentifier } from '@encointer/types/interfaces/community'; +import type { Enum, Option, Struct, Vec, u32 } from '@polkadot/types-codec'; +import type { ITuple } from '@polkadot/types-codec/types'; +import type { Signature } from '@polkadot/types/interfaces/extrinsics'; +import type { AccountId } from '@polkadot/types/interfaces/runtime'; + +/** @name EncointerBalanceTransferArgs */ +export interface EncointerBalanceTransferArgs extends ITuple<[AccountId, AccountId, CommunityIdentifier, BalanceType]> {} + +/** @name EncointerGetter */ +export interface EncointerGetter extends Enum { + readonly isPublic: boolean; + readonly asPublic: EncointerPublicGetter; + readonly isTrusted: boolean; + readonly asTrusted: EncointerTrustedGetterSigned; + readonly type: 'Public' | 'Trusted'; +} + +/** @name EncointerGetterArgs */ +export interface EncointerGetterArgs extends ITuple<[AccountId, CommunityIdentifier]> {} + +/** @name EncointerPublicGetter */ +export interface EncointerPublicGetter extends Enum { + readonly isTotalIssuance: boolean; + readonly asTotalIssuance: CommunityIdentifier; + readonly isParticipantCount: boolean; + readonly asParticipantCount: CommunityIdentifier; + readonly isMeetupCount: boolean; + readonly asMeetupCount: CommunityIdentifier; + readonly isCeremonyReward: boolean; + readonly asCeremonyReward: CommunityIdentifier; + readonly isLocationTolerance: boolean; + readonly asLocationTolerance: CommunityIdentifier; + readonly isTimeTolerance: boolean; + readonly asTimeTolerance: CommunityIdentifier; + readonly isSchedulerState: boolean; + readonly asSchedulerState: CommunityIdentifier; + readonly type: 'TotalIssuance' | 'ParticipantCount' | 'MeetupCount' | 'CeremonyReward' | 'LocationTolerance' | 'TimeTolerance' | 'SchedulerState'; +} + +/** @name EncointerTrustedCall */ +export interface EncointerTrustedCall extends Enum { + readonly isBalanceTransfer: boolean; + readonly asBalanceTransfer: EncointerBalanceTransferArgs; + readonly isCeremoniesRegisterParticipant: boolean; + readonly asCeremoniesRegisterParticipant: RegisterParticipantArgs; + readonly isCeremoniesRegisterAttestations: boolean; + readonly asCeremoniesRegisterAttestations: RegisterAttestationsArgs; + readonly isCeremoniesGrantReputation: boolean; + readonly asCeremoniesGrantReputation: GrantReputationArgs; + readonly type: 'BalanceTransfer' | 'CeremoniesRegisterParticipant' | 'CeremoniesRegisterAttestations' | 'CeremoniesGrantReputation'; +} + +/** @name EncointerTrustedCallSigned */ +export interface EncointerTrustedCallSigned extends Struct { + readonly call: EncointerTrustedCall; + readonly nonce: u32; + readonly signature: Signature; +} + +/** @name EncointerTrustedGetter */ +export interface EncointerTrustedGetter extends Enum { + readonly isBalance: boolean; + readonly asBalance: ITuple<[AccountId, CommunityIdentifier]>; + readonly isParticipantIndex: boolean; + readonly asParticipantIndex: ITuple<[AccountId, CommunityIdentifier]>; + readonly isMeetupIndex: boolean; + readonly asMeetupIndex: ITuple<[AccountId, CommunityIdentifier]>; + readonly isAttestations: boolean; + readonly asAttestations: ITuple<[AccountId, CommunityIdentifier]>; + readonly isMeetupRegistry: boolean; + readonly asMeetupRegistry: ITuple<[AccountId, CommunityIdentifier]>; + readonly type: 'Balance' | 'ParticipantIndex' | 'MeetupIndex' | 'Attestations' | 'MeetupRegistry'; +} + +/** @name EncointerTrustedGetterSigned */ +export interface EncointerTrustedGetterSigned extends Struct { + readonly getter: EncointerTrustedGetter; + readonly signature: Signature; +} + +/** @name GrantReputationArgs */ +export interface GrantReputationArgs extends ITuple<[AccountId, CommunityIdentifier, AccountId]> {} + +/** @name RegisterAttestationsArgs */ +export interface RegisterAttestationsArgs extends ITuple<[AccountId, Vec]> {} + +/** @name RegisterParticipantArgs */ +export interface RegisterParticipantArgs extends ITuple<[AccountId, CommunityIdentifier, Option]> {} + +export type PHANTOM_ENCOINTERWORKER = 'encointerWorker'; diff --git a/packages/types/src/interfaces/integriteeWorker/definitions.ts b/packages/types/src/interfaces/integriteeWorker/definitions.ts new file mode 100644 index 00000000..bd324299 --- /dev/null +++ b/packages/types/src/interfaces/integriteeWorker/definitions.ts @@ -0,0 +1,60 @@ +export default { + rpc: {}, + types: { + IntegriteePublicGetter: { + _enum: { + total_issuance: 'CommunityIdentifier', + participant_count: 'CommunityIdentifier', + meetup_count: 'CommunityIdentifier', + ceremony_reward: 'CommunityIdentifier', + location_tolerance: 'CommunityIdentifier', + time_tolerance: 'CommunityIdentifier', + scheduler_state: 'CommunityIdentifier' + } + }, + IntegriteeTrustedGetter: { + _enum: { + free_balance: 'AccountId', + reserved_balance: 'AccountId', + nonce: 'AccountId', + } + }, + IntegriteeTrustedGetterSigned: { + getter: 'IntegriteeTrustedGetter', + signature: 'MultiSignature' + }, + IntegriteeGetter: { + _enum: { + public: 'IntegriteePublicGetter', + trusted: 'IntegriteeTrustedGetterSigned' + } + }, + IntegriteeTrustedOperation: { + _enum: { + indirect_call: 'IntegriteeTrustedCallSigned', + direct_call: 'IntegriteeTrustedCallSigned', + get: 'IntegriteeGetter' + } + }, + IntegriteeTrustedCallSigned: { + call: 'IntegriteeTrustedCall', + nonce: 'u32', + signature: 'MultiSignature' + }, + IntegriteeTrustedCall: { + _enum: { + noop: 'AccountId', + balance_set_balance: 'BalanceSetBalanceArgs', + balance_transfer: 'BalanceTransferArgs', + balance_unshield: 'BalanceUnshieldArgs', + balance_shield: 'BalanceShieldArgs', + timestamp_set: 'TimestampSetArgs', + } + }, + BalanceSetBalanceArgs: '(AccountId, AccountId, BalanceType, BalanceType)', + BalanceTransferArgs: '(AccountId, AccountId, BalanceType)', + BalanceUnshieldArgs: '(AccountId, AccountId, BalanceType, ShardIdentifier)', + BalanceShieldArgs: '(AccountId, AccountId, BalanceType, ParentchainId)', + TimestampSetArgs: '(AccountId, H160, BalanceType)', + } +} diff --git a/packages/types/src/interfaces/integriteeWorker/index.ts b/packages/types/src/interfaces/integriteeWorker/index.ts new file mode 100644 index 00000000..7f1de782 --- /dev/null +++ b/packages/types/src/interfaces/integriteeWorker/index.ts @@ -0,0 +1,4 @@ +// Auto-generated via `yarn polkadot-types-from-defs`, do not edit +/* eslint-disable */ + +export * from './types.js'; diff --git a/packages/types/src/interfaces/integriteeWorker/types.ts b/packages/types/src/interfaces/integriteeWorker/types.ts new file mode 100644 index 00000000..aa239de8 --- /dev/null +++ b/packages/types/src/interfaces/integriteeWorker/types.ts @@ -0,0 +1,107 @@ +// Auto-generated via `yarn polkadot-types-from-defs`, do not edit +/* eslint-disable */ + +import type { BalanceType } from '@encointer/types/interfaces/balances'; +import type { CommunityIdentifier } from '@encointer/types/interfaces/community'; +import type { ParentchainId, ShardIdentifier } from '@encointer/types/interfaces/worker'; +import type { Enum, Struct, u32 } from '@polkadot/types-codec'; +import type { ITuple } from '@polkadot/types-codec/types'; +import type { MultiSignature } from '@polkadot/types/interfaces/extrinsics'; +import type { AccountId, H160 } from '@polkadot/types/interfaces/runtime'; + +/** @name BalanceSetBalanceArgs */ +export interface BalanceSetBalanceArgs extends ITuple<[AccountId, AccountId, BalanceType, BalanceType]> {} + +/** @name BalanceShieldArgs */ +export interface BalanceShieldArgs extends ITuple<[AccountId, AccountId, BalanceType, ParentchainId]> {} + +/** @name BalanceTransferArgs */ +export interface BalanceTransferArgs extends ITuple<[AccountId, AccountId, BalanceType]> {} + +/** @name BalanceUnshieldArgs */ +export interface BalanceUnshieldArgs extends ITuple<[AccountId, AccountId, BalanceType, ShardIdentifier]> {} + +/** @name IntegriteeGetter */ +export interface IntegriteeGetter extends Enum { + readonly isPublic: boolean; + readonly asPublic: IntegriteePublicGetter; + readonly isTrusted: boolean; + readonly asTrusted: IntegriteeTrustedGetterSigned; + readonly type: 'Public' | 'Trusted'; +} + +/** @name IntegriteePublicGetter */ +export interface IntegriteePublicGetter extends Enum { + readonly isTotalIssuance: boolean; + readonly asTotalIssuance: CommunityIdentifier; + readonly isParticipantCount: boolean; + readonly asParticipantCount: CommunityIdentifier; + readonly isMeetupCount: boolean; + readonly asMeetupCount: CommunityIdentifier; + readonly isCeremonyReward: boolean; + readonly asCeremonyReward: CommunityIdentifier; + readonly isLocationTolerance: boolean; + readonly asLocationTolerance: CommunityIdentifier; + readonly isTimeTolerance: boolean; + readonly asTimeTolerance: CommunityIdentifier; + readonly isSchedulerState: boolean; + readonly asSchedulerState: CommunityIdentifier; + readonly type: 'TotalIssuance' | 'ParticipantCount' | 'MeetupCount' | 'CeremonyReward' | 'LocationTolerance' | 'TimeTolerance' | 'SchedulerState'; +} + +/** @name IntegriteeTrustedCall */ +export interface IntegriteeTrustedCall extends Enum { + readonly isNoop: boolean; + readonly asNoop: AccountId; + readonly isBalanceSetBalance: boolean; + readonly asBalanceSetBalance: BalanceSetBalanceArgs; + readonly isBalanceTransfer: boolean; + readonly asBalanceTransfer: BalanceTransferArgs; + readonly isBalanceUnshield: boolean; + readonly asBalanceUnshield: BalanceUnshieldArgs; + readonly isBalanceShield: boolean; + readonly asBalanceShield: BalanceShieldArgs; + readonly isTimestampSet: boolean; + readonly asTimestampSet: TimestampSetArgs; + readonly type: 'Noop' | 'BalanceSetBalance' | 'BalanceTransfer' | 'BalanceUnshield' | 'BalanceShield' | 'TimestampSet'; +} + +/** @name IntegriteeTrustedCallSigned */ +export interface IntegriteeTrustedCallSigned extends Struct { + readonly call: IntegriteeTrustedCall; + readonly nonce: u32; + readonly signature: MultiSignature; +} + +/** @name IntegriteeTrustedGetter */ +export interface IntegriteeTrustedGetter extends Enum { + readonly isFreeBalance: boolean; + readonly asFreeBalance: AccountId; + readonly isReservedBalance: boolean; + readonly asReservedBalance: AccountId; + readonly isNonce: boolean; + readonly asNonce: AccountId; + readonly type: 'FreeBalance' | 'ReservedBalance' | 'Nonce'; +} + +/** @name IntegriteeTrustedGetterSigned */ +export interface IntegriteeTrustedGetterSigned extends Struct { + readonly getter: IntegriteeTrustedGetter; + readonly signature: MultiSignature; +} + +/** @name IntegriteeTrustedOperation */ +export interface IntegriteeTrustedOperation extends Enum { + readonly isIndirectCall: boolean; + readonly asIndirectCall: IntegriteeTrustedCallSigned; + readonly isDirectCall: boolean; + readonly asDirectCall: IntegriteeTrustedCallSigned; + readonly isGet: boolean; + readonly asGet: IntegriteeGetter; + readonly type: 'IndirectCall' | 'DirectCall' | 'Get'; +} + +/** @name TimestampSetArgs */ +export interface TimestampSetArgs extends ITuple<[AccountId, H160, BalanceType]> {} + +export type PHANTOM_INTEGRITEEWORKER = 'integriteeWorker'; diff --git a/packages/types/src/interfaces/types.ts b/packages/types/src/interfaces/types.ts index d7f4cdf3..b8fe7d58 100644 --- a/packages/types/src/interfaces/types.ts +++ b/packages/types/src/interfaces/types.ts @@ -6,5 +6,7 @@ export * from './bazaar/types.js'; export * from './ceremony/types.js'; export * from './common/types.js'; export * from './community/types.js'; +export * from './encointerWorker/types.js'; +export * from './integriteeWorker/types.js'; export * from './scheduler/types.js'; export * from './worker/types.js'; diff --git a/packages/types/src/interfaces/worker/definitions.ts b/packages/types/src/interfaces/worker/definitions.ts index 514fef64..4be7303b 100644 --- a/packages/types/src/interfaces/worker/definitions.ts +++ b/packages/types/src/interfaces/worker/definitions.ts @@ -9,34 +9,6 @@ export default { timestamp: 'u64', url: 'Text' }, - PublicGetter: { - _enum: { - total_issuance: 'CommunityIdentifier', - participant_count: 'CommunityIdentifier', - meetup_count: 'CommunityIdentifier', - ceremony_reward: 'CommunityIdentifier', - location_tolerance: 'CommunityIdentifier', - time_tolerance: 'CommunityIdentifier', - scheduler_state: 'CommunityIdentifier' - } - }, - TrustedGetter: { - _enum: { - free_balance: 'AccountId', - reserved_balance: 'AccountId', - nonce: 'AccountId', - } - }, - TrustedGetterSigned: { - getter: 'TrustedGetter', - signature: 'MultiSignature' - }, - Getter: { - _enum: { - public: 'PublicGetter', - trusted: 'TrustedGetterSigned' - } - }, RpcReturnValue: { value: 'Vec', do_watch: 'bool', @@ -69,28 +41,6 @@ export default { shard: 'ShardIdentifier', cyphertext: 'WorkerEncoded' }, - TrustedOperation: { - _enum: { - indirect_call: 'TrustedCallSigned', - direct_call: 'TrustedCallSigned', - get: 'Getter' - } - }, - TrustedCallSigned: { - call: 'TrustedCall', - nonce: 'u32', - signature: 'MultiSignature' - }, - TrustedCall: { - _enum: { - noop: 'AccountId', - balance_set_balance: 'BalanceSetBalanceArgs', - balance_transfer: 'BalanceTransferArgs', - balance_unshield: 'BalanceUnshieldArgs', - balance_shield: 'BalanceShieldArgs', - timestamp_set: 'TimestampSetArgs', - } - }, Vault: '(AccountId, ParentchainId)', ParentchainId: { _enum: { @@ -99,10 +49,5 @@ export default { TargetB: null, } }, - BalanceSetBalanceArgs: '(AccountId, AccountId, BalanceType, BalanceType)', - BalanceTransferArgs: '(AccountId, AccountId, BalanceType)', - BalanceUnshieldArgs: '(AccountId, AccountId, BalanceType, ShardIdentifier)', - BalanceShieldArgs: '(AccountId, AccountId, BalanceType, ParentchainId)', - TimestampSetArgs: '(AccountId, H160, BalanceType)', } } diff --git a/packages/types/src/interfaces/worker/types.ts b/packages/types/src/interfaces/worker/types.ts index 72001ccd..194f3aca 100644 --- a/packages/types/src/interfaces/worker/types.ts +++ b/packages/types/src/interfaces/worker/types.ts @@ -1,24 +1,10 @@ // Auto-generated via `yarn polkadot-types-from-defs`, do not edit /* eslint-disable */ -import type { BalanceType } from '@encointer/types/interfaces/balances'; import type { CommunityIdentifier } from '@encointer/types/interfaces/community'; -import type { Bytes, Enum, Struct, Text, bool, u32, u64 } from '@polkadot/types-codec'; +import type { Bytes, Enum, Struct, Text, bool, u64 } from '@polkadot/types-codec'; import type { ITuple } from '@polkadot/types-codec/types'; -import type { MultiSignature } from '@polkadot/types/interfaces/extrinsics'; -import type { AccountId, H160, Hash } from '@polkadot/types/interfaces/runtime'; - -/** @name BalanceSetBalanceArgs */ -export interface BalanceSetBalanceArgs extends ITuple<[AccountId, AccountId, BalanceType, BalanceType]> {} - -/** @name BalanceShieldArgs */ -export interface BalanceShieldArgs extends ITuple<[AccountId, AccountId, BalanceType, ParentchainId]> {} - -/** @name BalanceTransferArgs */ -export interface BalanceTransferArgs extends ITuple<[AccountId, AccountId, BalanceType]> {} - -/** @name BalanceUnshieldArgs */ -export interface BalanceUnshieldArgs extends ITuple<[AccountId, AccountId, BalanceType, ShardIdentifier]> {} +import type { AccountId, Hash } from '@polkadot/types/interfaces/runtime'; /** @name DirectRequestStatus */ export interface DirectRequestStatus extends Enum { @@ -37,15 +23,6 @@ export interface Enclave extends Struct { readonly url: Text; } -/** @name Getter */ -export interface Getter extends Enum { - readonly isPublic: boolean; - readonly asPublic: PublicGetter; - readonly isTrusted: boolean; - readonly asTrusted: TrustedGetterSigned; - readonly type: 'Public' | 'Trusted'; -} - /** @name GetterArgs */ export interface GetterArgs extends ITuple<[AccountId, CommunityIdentifier]> {} @@ -57,25 +34,6 @@ export interface ParentchainId extends Enum { readonly type: 'Integritee' | 'TargetA' | 'TargetB'; } -/** @name PublicGetter */ -export interface PublicGetter extends Enum { - readonly isTotalIssuance: boolean; - readonly asTotalIssuance: CommunityIdentifier; - readonly isParticipantCount: boolean; - readonly asParticipantCount: CommunityIdentifier; - readonly isMeetupCount: boolean; - readonly asMeetupCount: CommunityIdentifier; - readonly isCeremonyReward: boolean; - readonly asCeremonyReward: CommunityIdentifier; - readonly isLocationTolerance: boolean; - readonly asLocationTolerance: CommunityIdentifier; - readonly isTimeTolerance: boolean; - readonly asTimeTolerance: CommunityIdentifier; - readonly isSchedulerState: boolean; - readonly asSchedulerState: CommunityIdentifier; - readonly type: 'TotalIssuance' | 'ParticipantCount' | 'MeetupCount' | 'CeremonyReward' | 'LocationTolerance' | 'TimeTolerance' | 'SchedulerState'; -} - /** @name Request */ export interface Request extends Struct { readonly shard: ShardIdentifier; @@ -92,61 +50,6 @@ export interface RpcReturnValue extends Struct { /** @name ShardIdentifier */ export interface ShardIdentifier extends Hash {} -/** @name TimestampSetArgs */ -export interface TimestampSetArgs extends ITuple<[AccountId, H160, BalanceType]> {} - -/** @name TrustedCall */ -export interface TrustedCall extends Enum { - readonly isNoop: boolean; - readonly asNoop: AccountId; - readonly isBalanceSetBalance: boolean; - readonly asBalanceSetBalance: BalanceSetBalanceArgs; - readonly isBalanceTransfer: boolean; - readonly asBalanceTransfer: BalanceTransferArgs; - readonly isBalanceUnshield: boolean; - readonly asBalanceUnshield: BalanceUnshieldArgs; - readonly isBalanceShield: boolean; - readonly asBalanceShield: BalanceShieldArgs; - readonly isTimestampSet: boolean; - readonly asTimestampSet: TimestampSetArgs; - readonly type: 'Noop' | 'BalanceSetBalance' | 'BalanceTransfer' | 'BalanceUnshield' | 'BalanceShield' | 'TimestampSet'; -} - -/** @name TrustedCallSigned */ -export interface TrustedCallSigned extends Struct { - readonly call: TrustedCall; - readonly nonce: u32; - readonly signature: MultiSignature; -} - -/** @name TrustedGetter */ -export interface TrustedGetter extends Enum { - readonly isFreeBalance: boolean; - readonly asFreeBalance: AccountId; - readonly isReservedBalance: boolean; - readonly asReservedBalance: AccountId; - readonly isNonce: boolean; - readonly asNonce: AccountId; - readonly type: 'FreeBalance' | 'ReservedBalance' | 'Nonce'; -} - -/** @name TrustedGetterSigned */ -export interface TrustedGetterSigned extends Struct { - readonly getter: TrustedGetter; - readonly signature: MultiSignature; -} - -/** @name TrustedOperation */ -export interface TrustedOperation extends Enum { - readonly isIndirectCall: boolean; - readonly asIndirectCall: TrustedCallSigned; - readonly isDirectCall: boolean; - readonly asDirectCall: TrustedCallSigned; - readonly isGet: boolean; - readonly asGet: Getter; - readonly type: 'IndirectCall' | 'DirectCall' | 'Get'; -} - /** @name TrustedOperationStatus */ export interface TrustedOperationStatus extends Enum { readonly isSubmitted: boolean; diff --git a/packages/worker-api/src/encointerWorker.ts b/packages/worker-api/src/encointerWorker.ts index 49d14030..516eafc4 100644 --- a/packages/worker-api/src/encointerWorker.ts +++ b/packages/worker-api/src/encointerWorker.ts @@ -5,12 +5,17 @@ import {communityIdentifierFromString} from '@encointer/util'; import NodeRSA from 'node-rsa'; import type { - CommunityIdentifier, MeetupIndexType, ParticipantIndexType, SchedulerState, ShardIdentifier, TrustedCallSigned, + CommunityIdentifier, + MeetupIndexType, + ParticipantIndexType, + SchedulerState, + ShardIdentifier, + EncointerTrustedCallSigned, + Attestation, } from '@encointer/types'; import {type CallOptions, Request} from './interface.js'; import {callGetter, sendTrustedCall} from './sendRequest.js'; -import {createTrustedCall} from "@encointer/worker-api/requests.js"; import {PubKeyPinPair, toAccount} from "@encointer/util/common"; import type {KeyringPair} from "@polkadot/keyring/types"; import {Worker} from "@encointer/worker-api/worker.js"; @@ -92,25 +97,14 @@ export class EncointerWorker extends Worker { }, options) } - public async trustedBalanceTransfer(accountOrPubKey: KeyringPair | PubKeyPinPair, shard: ShardIdentifier, mrenclave: string, params: BalanceTransferArgs, options: CallOptions = {} as CallOptions): Promise { - const nonce = await this.getNonce(accountOrPubKey, mrenclave, options); - const call = createTrustedCall(this, ['balance_transfer', 'BalanceTransferArgs'], accountOrPubKey, shard, mrenclave, nonce, params); - return this.sendTrustedCall(call, shard, options); - } - - public async balanceUnshieldFunds(accountOrPubKey: KeyringPair | PubKeyPinPair, shard: ShardIdentifier, mrenclave: string, params: BalanceUnshieldArgs, options: CallOptions = {} as CallOptions): Promise { - const nonce = await this.getNonce(accountOrPubKey, mrenclave, options); - const call = createTrustedCall(this, ['balance_unshield', 'BalanceUnshieldArgs'], accountOrPubKey, shard, mrenclave, nonce, params); - return this.sendTrustedCall(call, shard, options); - } - - async sendTrustedCall(call: TrustedCallSigned, shard: ShardIdentifier, options: CallOptions = {} as CallOptions): Promise { - if (this.shieldingKey() == undefined) { - const key = await this.getShieldingKey(options); - console.log(`Setting the shielding pubKey of the worker.`) - this.setShieldingKey(key); - } - - return sendTrustedCall(this, call, shard, true, 'TrustedOperationResult', options); - } + // Todo: `sendTrustedCall` must be generic over the trusted call or we have to duplicate code for encointer. + // async sendTrustedCall(call: EncointerTrustedCallSigned, shard: ShardIdentifier, options: CallOptions = {} as CallOptions): Promise { + // if (this.shieldingKey() == undefined) { + // const key = await this.getShieldingKey(options); + // console.log(`Setting the shielding pubKey of the worker.`) + // this.setShieldingKey(key); + // } + // + // return sendTrustedCall(this, call, shard, true, 'TrustedOperationResult', options); + // } } diff --git a/packages/worker-api/src/integriteeWorker.ts b/packages/worker-api/src/integriteeWorker.ts index 0d32d22d..ce955413 100644 --- a/packages/worker-api/src/integriteeWorker.ts +++ b/packages/worker-api/src/integriteeWorker.ts @@ -8,7 +8,7 @@ import type {KeyringPair} from '@polkadot/keyring/types'; import type {Balance, Hash} from '@polkadot/types/interfaces/runtime'; import type { BalanceTransferArgs, BalanceUnshieldArgs, - ShardIdentifier, TrustedCallSigned, + ShardIdentifier, IntegriteeTrustedCallSigned, } from '@encointer/types'; import {type CallOptions, Request} from './interface.js'; @@ -45,7 +45,7 @@ export class IntegriteeWorker extends Worker { return this.sendTrustedCall(call, shard, options); } - async sendTrustedCall(call: TrustedCallSigned, shard: ShardIdentifier, options: CallOptions = {} as CallOptions): Promise { + async sendTrustedCall(call: IntegriteeTrustedCallSigned, shard: ShardIdentifier, options: CallOptions = {} as CallOptions): Promise { if (this.shieldingKey() == undefined) { const key = await this.getShieldingKey(options); console.log(`Setting the shielding pubKey of the worker.`) diff --git a/packages/worker-api/src/requests.ts b/packages/worker-api/src/requests.ts index 95fb4e01..511affdb 100644 --- a/packages/worker-api/src/requests.ts +++ b/packages/worker-api/src/requests.ts @@ -3,20 +3,20 @@ import { type IWorker, type PublicGetterArgs, type TrustedGetterArgs } from "@encointer/worker-api/interface.js"; -import type {BalanceTransferArgs, BalanceUnshieldArgs, ShardIdentifier, TrustedCallSigned} from "@encointer/types"; +import type {BalanceTransferArgs, BalanceUnshieldArgs, ShardIdentifier, IntegriteeTrustedCallSigned} from "@encointer/types"; import type {KeyringPair} from "@polkadot/keyring/types"; -import {PubKeyPinPair, toAccount} from "@encointer/util/common.js"; +import {type PubKeyPinPair, toAccount} from "@encointer/util/common.js"; import type {u32} from "@polkadot/types"; import bs58 from "bs58"; // Todo: Properly resolve cid vs shard export const clientRequestGetter = (self: IWorker, request: string, args: PublicGetterArgs) => { const { cid } = args; - const getter = self.createType('PublicGetter', { + const getter = self.createType('IntegriteePublicGetter', { [request]: cid }); - const g = self.createType( 'Getter',{ + const g = self.createType( 'IntegriteeGetter',{ public: { getter, } @@ -32,12 +32,12 @@ export const clientRequestGetter = (self: IWorker, request: string, args: Public export const clientRequestTrustedGetter = (self: IWorker, request: string, args: TrustedGetterArgs) => { const {shard, account} = args; const address = account.address; - const getter = self.createType('TrustedGetter', { + const getter = self.createType('IntegriteeTrustedGetter', { [request]: address }); const signature = account.sign(getter.toU8a()); - const g = self.createType( 'Getter',{ + const g = self.createType( 'IntegriteeGetter',{ trusted: { getter, signature: { Sr25519: signature }, @@ -69,18 +69,18 @@ export const createTrustedCall = ( mrenclave: string, nonce: u32, params: TrustedCallArgs -): TrustedCallSigned => { +): IntegriteeTrustedCallSigned => { const [variant, argType] = trustedCall; const hash = self.createType('Hash', bs58.decode(mrenclave)); - const call = self.createType('TrustedCall', { + const call = self.createType('IntegriteeTrustedCall', { [variant]: self.createType(argType, params) }); const payload = Uint8Array.from([...call.toU8a(), ...nonce.toU8a(), ...hash.toU8a(), ...shard.toU8a()]); - return self.createType('TrustedCallSigned', { + return self.createType('IntegriteeIntegriteeTrustedCallSigned', { call: call, nonce: nonce, signature: { Sr25519: toAccount(accountOrPubKey, self.keyring()).sign(payload) }, diff --git a/packages/worker-api/src/sendRequest.ts b/packages/worker-api/src/sendRequest.ts index 7c27413a..b4a5dd5c 100644 --- a/packages/worker-api/src/sendRequest.ts +++ b/packages/worker-api/src/sendRequest.ts @@ -12,7 +12,7 @@ import { clientRequestGetter, clientRequestTrustedGetter, } from "@encointer/worker-api/requests.js"; -import type {ShardIdentifier, TrustedCallSigned} from "@encointer/types"; +import type {ShardIdentifier, IntegriteeTrustedCallSigned} from "@encointer/types"; const sendWorkerRequest = (self: IWorker, clientRequest: any, parserType: string, options: CallOptions): Promise =>{ const requestId = self.rqStack.push(parserType) + self.rsCount; @@ -54,7 +54,7 @@ export const callGetter = async (self: IWorker, workerMethod: WorkerMethod, a return result as Promise } -export const sendTrustedCall = async (self: IWorker, call: TrustedCallSigned, shard: ShardIdentifier, direct: boolean, parser: string, options: CallOptions = {} as CallOptions): Promise => { +export const sendTrustedCall = async (self: IWorker, call: IntegriteeTrustedCallSigned, shard: ShardIdentifier, direct: boolean, parser: string, options: CallOptions = {} as CallOptions): Promise => { if( !self.isOpened ) { await self.open(); } @@ -66,11 +66,11 @@ export const sendTrustedCall = async (self: IWorker, call: TrustedCallSigned, let top; if (direct) { - top = self.createType('TrustedOperation', { + top = self.createType('IntegriteeTrustedOperation', { direct_call: call }) } else { - top = self.createType('TrustedOperation', { + top = self.createType('IntegriteeTrustedOperation', { indirect_call: call }) } From 2c11c030c0037756fc9310573010aead73111757 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Wed, 10 Apr 2024 10:19:07 +0800 Subject: [PATCH 39/41] [worker] fix unused imports in encointer worker --- packages/worker-api/src/encointerWorker.spec.ts | 2 +- packages/worker-api/src/encointerWorker.ts | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/worker-api/src/encointerWorker.spec.ts b/packages/worker-api/src/encointerWorker.spec.ts index 0b60c462..c8c230ad 100644 --- a/packages/worker-api/src/encointerWorker.spec.ts +++ b/packages/worker-api/src/encointerWorker.spec.ts @@ -38,7 +38,7 @@ describe('worker', () => { // skip it, as this requires a worker (and hence a node) to be running // To my knowledge jest does not have an option to run skipped tests specifically, does it? // Todo: add proper CI to test this too. - describe('needs worker and node running', () => { + describe.skip('needs worker and node running', () => { // Tests specific for the encointer protocol describe('encointer-worker', () => { describe('getTotalIssuance', () => { diff --git a/packages/worker-api/src/encointerWorker.ts b/packages/worker-api/src/encointerWorker.ts index 516eafc4..61581276 100644 --- a/packages/worker-api/src/encointerWorker.ts +++ b/packages/worker-api/src/encointerWorker.ts @@ -9,17 +9,15 @@ import type { MeetupIndexType, ParticipantIndexType, SchedulerState, - ShardIdentifier, - EncointerTrustedCallSigned, Attestation, } from '@encointer/types'; import {type CallOptions, Request} from './interface.js'; -import {callGetter, sendTrustedCall} from './sendRequest.js'; +import {callGetter} from './sendRequest.js'; import {PubKeyPinPair, toAccount} from "@encointer/util/common"; import type {KeyringPair} from "@polkadot/keyring/types"; import {Worker} from "@encointer/worker-api/worker.js"; -import type {AccountId, Balance, Hash, Moment} from "@polkadot/types/interfaces/runtime"; +import type {AccountId, Balance, Moment} from "@polkadot/types/interfaces/runtime"; export class EncointerWorker extends Worker { From f21fad8d0896ac0a750269e5ce30425741f01360 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Wed, 10 Apr 2024 10:42:01 +0800 Subject: [PATCH 40/41] [worker] skip CI that needs a worker --- packages/worker-api/src/integriteeWorker.spec.ts | 2 +- packages/worker-api/src/worker.spec.ts | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/worker-api/src/integriteeWorker.spec.ts b/packages/worker-api/src/integriteeWorker.spec.ts index 83db8869..a01435ff 100644 --- a/packages/worker-api/src/integriteeWorker.spec.ts +++ b/packages/worker-api/src/integriteeWorker.spec.ts @@ -40,7 +40,7 @@ describe('worker', () => { // skip it, as this requires a worker (and hence a node) to be running // To my knowledge jest does not have an option to run skipped tests specifically, does it? // Todo: add proper CI to test this too. - describe('needs worker and node running', () => { + describe.skip('needs worker and node running', () => { describe('getWorkerPubKey', () => { it('should return value', async () => { const result = await worker.getShieldingKey(); diff --git a/packages/worker-api/src/worker.spec.ts b/packages/worker-api/src/worker.spec.ts index 2c38d746..07972d29 100644 --- a/packages/worker-api/src/worker.spec.ts +++ b/packages/worker-api/src/worker.spec.ts @@ -3,7 +3,6 @@ import { cryptoWaitReady } from '@polkadot/util-crypto'; import { localDockerNetwork } from './testUtils/networks.js'; import { Worker } from './worker.js'; import WS from 'websocket'; -import {KeyringPair} from "@polkadot/keyring/types"; const {w3cwebsocket: WebSocket} = WS; @@ -11,14 +10,10 @@ describe('worker', () => { const network = localDockerNetwork(); let keyring: Keyring; let worker: Worker; - let alice: KeyringPair; - let charlie: KeyringPair; beforeAll(async () => { jest.setTimeout(90000); await cryptoWaitReady(); keyring = new Keyring({type: 'sr25519'}); - alice = keyring.addFromUri('//Alice', {name: 'Alice default'}); - charlie = keyring.addFromUri('//Charlie', {name: 'Bob default'}); worker = new Worker(network.worker, { keyring: keyring, @@ -39,7 +34,7 @@ describe('worker', () => { // skip it, as this requires a worker (and hence a node) to be running // To my knowledge jest does not have an option to run skipped tests specifically, does it? // Todo: add proper CI to test this too. - describe('needs worker and node running', () => { + describe.skip('needs worker and node running', () => { describe('getWorkerPubKey', () => { it('should return value', async () => { const result = await worker.getShieldingKey(); From ab2e0d88a01ae90b447ef9e241891dcae7263f8e Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Wed, 10 Apr 2024 10:55:08 +0800 Subject: [PATCH 41/41] [worker] add todo for encointer worker --- packages/worker-api/src/encointerWorker.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/worker-api/src/encointerWorker.ts b/packages/worker-api/src/encointerWorker.ts index 61581276..efbfe4e1 100644 --- a/packages/worker-api/src/encointerWorker.ts +++ b/packages/worker-api/src/encointerWorker.ts @@ -19,6 +19,8 @@ import type {KeyringPair} from "@polkadot/keyring/types"; import {Worker} from "@encointer/worker-api/worker.js"; import type {AccountId, Balance, Moment} from "@polkadot/types/interfaces/runtime"; +// Todo: This code is a WIP and will not work as is: https://github.com/encointer/encointer-js/issues/91 + export class EncointerWorker extends Worker { public cidFromStr(cidStr: String): CommunityIdentifier {