@proto-kit/module 0.1.1-develop.190 → 0.1.1-develop.2024
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/factories/MethodIdFactory.d.ts +6 -6
- package/dist/factories/MethodIdFactory.d.ts.map +1 -1
- package/dist/factories/MethodIdFactory.js +10 -34
- package/dist/factories/MethodIdFactory.js.map +1 -0
- package/dist/index.d.ts +4 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -7
- package/dist/index.js.map +1 -0
- package/dist/messages/OutgoingMessage.d.ts +96 -0
- package/dist/messages/OutgoingMessage.d.ts.map +1 -0
- package/dist/messages/OutgoingMessage.js +68 -0
- package/dist/messages/OutgoingMessage.js.map +1 -0
- package/dist/messages/OutgoingMessages.d.ts +231 -0
- package/dist/messages/OutgoingMessages.d.ts.map +1 -0
- package/dist/messages/OutgoingMessages.js +66 -0
- package/dist/messages/OutgoingMessages.js.map +1 -0
- package/dist/method/MethodParameterEncoder.d.ts +26 -0
- package/dist/method/MethodParameterEncoder.d.ts.map +1 -0
- package/dist/method/MethodParameterEncoder.js +169 -0
- package/dist/method/MethodParameterEncoder.js.map +1 -0
- package/dist/method/runtimeMethod.d.ts +21 -5
- package/dist/method/runtimeMethod.d.ts.map +1 -1
- package/dist/method/runtimeMethod.js +69 -25
- package/dist/method/runtimeMethod.js.map +1 -0
- package/dist/module/decorator.js +1 -0
- package/dist/module/decorator.js.map +1 -0
- package/dist/runtime/MethodIdResolver.d.ts +10 -8
- package/dist/runtime/MethodIdResolver.d.ts.map +1 -1
- package/dist/runtime/MethodIdResolver.js +74 -33
- package/dist/runtime/MethodIdResolver.js.map +1 -0
- package/dist/runtime/Runtime.d.ts +20 -26
- package/dist/runtime/Runtime.d.ts.map +1 -1
- package/dist/runtime/Runtime.js +117 -62
- package/dist/runtime/Runtime.js.map +1 -0
- package/dist/runtime/RuntimeEnvironment.d.ts +10 -0
- package/dist/runtime/RuntimeEnvironment.d.ts.map +1 -0
- package/dist/runtime/RuntimeEnvironment.js +2 -0
- package/dist/runtime/RuntimeEnvironment.js.map +1 -0
- package/dist/runtime/RuntimeModule.d.ts +18 -15
- package/dist/runtime/RuntimeModule.d.ts.map +1 -1
- package/dist/runtime/RuntimeModule.js +33 -8
- package/dist/runtime/RuntimeModule.js.map +1 -0
- package/dist/state/InMemoryStateService.d.ts +11 -10
- package/dist/state/InMemoryStateService.d.ts.map +1 -1
- package/dist/state/InMemoryStateService.js +11 -8
- package/dist/state/InMemoryStateService.js.map +1 -0
- package/dist/state/decorator.d.ts.map +1 -1
- package/dist/state/decorator.js +2 -4
- package/dist/state/decorator.js.map +1 -0
- package/dist/testing/TestingRuntime.d.ts +8 -0
- package/dist/testing/TestingRuntime.d.ts.map +1 -0
- package/dist/testing/TestingRuntime.js +31 -0
- package/dist/testing/TestingRuntime.js.map +1 -0
- package/jest.config.cjs +12 -1
- package/package.json +10 -11
- package/src/factories/MethodIdFactory.ts +10 -17
- package/src/index.ts +4 -7
- package/src/messages/OutgoingMessages.ts +122 -0
- package/src/method/MethodParameterEncoder.ts +262 -0
- package/src/method/runtimeMethod.ts +130 -33
- package/src/runtime/MethodIdResolver.ts +83 -46
- package/src/runtime/Runtime.ts +193 -100
- package/src/runtime/RuntimeEnvironment.ts +16 -0
- package/src/runtime/RuntimeModule.ts +62 -30
- package/src/state/InMemoryStateService.ts +14 -18
- package/test/Runtime.test.ts +68 -42
- package/test/TestingRuntime.ts +43 -0
- package/test/messages/message.test.ts +42 -0
- package/test/method/MethodParameterEncoder.test.ts +124 -0
- package/test/method/runtimeMethod-fail.test.ts +53 -0
- package/{src/method/decorator.test.ts → test/method/runtimeMethod.test.ts} +3 -3
- package/test/modules/Admin.ts +4 -4
- package/test/modules/Balances.test.ts +92 -78
- package/test/modules/Balances.ts +15 -17
- package/test/modules/{methodId.test.ts → MethodIdResolver.test.ts} +24 -36
- package/test/modules/State.test.ts +81 -0
- package/test/runtimeMethod.test.ts +192 -20
- package/test/tsconfig.json +7 -0
- package/tsconfig.json +2 -2
- package/LICENSE.md +0 -201
- package/dist/method/MethodParameterDecoder.d.ts +0 -22
- package/dist/method/MethodParameterDecoder.d.ts.map +0 -1
- package/dist/method/MethodParameterDecoder.js +0 -33
- package/dist/method/RuntimeMethodExecutionContext.d.ts +0 -57
- package/dist/method/RuntimeMethodExecutionContext.d.ts.map +0 -1
- package/dist/method/RuntimeMethodExecutionContext.js +0 -92
- package/dist/method/assert.d.ts +0 -12
- package/dist/method/assert.d.ts.map +0 -1
- package/dist/method/assert.js +0 -23
- package/dist/state/State.d.ts +0 -65
- package/dist/state/State.d.ts.map +0 -1
- package/dist/state/State.js +0 -114
- package/dist/state/StateMap.d.ts +0 -37
- package/dist/state/StateMap.d.ts.map +0 -1
- package/dist/state/StateMap.js +0 -56
- package/dist/state/StateServiceProvider.d.ts +0 -10
- package/dist/state/StateServiceProvider.d.ts.map +0 -1
- package/dist/state/StateServiceProvider.js +0 -34
- package/src/method/MethodParameterDecoder.ts +0 -68
- package/src/method/RuntimeMethodExecutionContext.ts +0 -111
- package/src/method/assert.test.ts +0 -49
- package/src/method/assert.ts +0 -27
- package/src/state/State.ts +0 -154
- package/src/state/StateMap.ts +0 -69
- package/src/state/StateServiceProvider.ts +0 -24
- package/src/state/decorator.ts +0 -65
- package/test/state/MerkleTree.test.ts +0 -95
- package/test/state/MockAsyncMerkleStore.ts +0 -28
- package/test/transaction.test.ts +0 -82
- package/tsconfig.test.json +0 -9
package/src/runtime/Runtime.ts
CHANGED
|
@@ -1,32 +1,54 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
import { DependencyContainer, injectable } from "tsyringe";
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-argument */
|
|
2
|
+
import { ZkProgram } from "o1js";
|
|
3
|
+
import { container, DependencyContainer, injectable } from "tsyringe";
|
|
5
4
|
import {
|
|
6
5
|
StringKeyOf,
|
|
7
6
|
ModuleContainer,
|
|
8
|
-
ModulesConfig,
|
|
9
7
|
ModulesRecord,
|
|
10
8
|
TypedClass,
|
|
11
9
|
ZkProgrammable,
|
|
12
10
|
PlainZkProgram,
|
|
13
|
-
WithZkProgrammable,
|
|
14
11
|
AreProofsEnabled,
|
|
12
|
+
ChildContainerProvider,
|
|
13
|
+
CompilableModule,
|
|
14
|
+
CompileRegistry,
|
|
15
15
|
} from "@proto-kit/common";
|
|
16
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
MethodPublicOutput,
|
|
18
|
+
StateServiceProvider,
|
|
19
|
+
SimpleAsyncStateService,
|
|
20
|
+
RuntimeMethodExecutionContext,
|
|
21
|
+
RuntimeTransaction,
|
|
22
|
+
NetworkState,
|
|
23
|
+
} from "@proto-kit/protocol";
|
|
17
24
|
|
|
18
25
|
import {
|
|
19
26
|
combineMethodName,
|
|
20
27
|
isRuntimeMethod,
|
|
28
|
+
runtimeMethodTypeMetadataKey,
|
|
21
29
|
toWrappedMethod,
|
|
22
|
-
|
|
23
|
-
} from "../method/runtimeMethod
|
|
24
|
-
import { StateService } from "../state/InMemoryStateService.js";
|
|
25
|
-
import { StateServiceProvider } from "../state/StateServiceProvider";
|
|
30
|
+
AsyncWrappedMethod,
|
|
31
|
+
} from "../method/runtimeMethod";
|
|
26
32
|
import { MethodIdFactory } from "../factories/MethodIdFactory";
|
|
27
33
|
|
|
28
|
-
import { RuntimeModule } from "./RuntimeModule
|
|
34
|
+
import { RuntimeModule } from "./RuntimeModule";
|
|
29
35
|
import { MethodIdResolver } from "./MethodIdResolver";
|
|
36
|
+
import { RuntimeEnvironment } from "./RuntimeEnvironment";
|
|
37
|
+
|
|
38
|
+
export function getAllPropertyNames(obj: any) {
|
|
39
|
+
let currentPrototype: any | undefined = obj;
|
|
40
|
+
let keys: (string | symbol)[] = [];
|
|
41
|
+
// if primitive (primitives still have keys) skip the first iteration
|
|
42
|
+
if (!(obj instanceof Object)) {
|
|
43
|
+
currentPrototype = Object.getPrototypeOf(obj);
|
|
44
|
+
}
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
46
|
+
while (currentPrototype) {
|
|
47
|
+
keys = keys.concat(Reflect.ownKeys(currentPrototype));
|
|
48
|
+
currentPrototype = Object.getPrototypeOf(currentPrototype);
|
|
49
|
+
}
|
|
50
|
+
return keys;
|
|
51
|
+
}
|
|
30
52
|
|
|
31
53
|
/**
|
|
32
54
|
* Record of modules accepted by the Runtime module container.
|
|
@@ -43,66 +65,56 @@ const errors = {
|
|
|
43
65
|
new Error(`Unable to find method with id ${methodKey}`),
|
|
44
66
|
};
|
|
45
67
|
|
|
46
|
-
/**
|
|
47
|
-
* Definition / required arguments for the Runtime class
|
|
48
|
-
*/
|
|
49
|
-
export interface RuntimeDefinition<Modules extends RuntimeModulesRecord> {
|
|
50
|
-
state: StateService;
|
|
51
|
-
modules: Modules;
|
|
52
|
-
config?: ModulesConfig<Modules>;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
68
|
export class RuntimeZkProgrammable<
|
|
56
|
-
Modules extends RuntimeModulesRecord
|
|
69
|
+
Modules extends RuntimeModulesRecord,
|
|
57
70
|
> extends ZkProgrammable<undefined, MethodPublicOutput> {
|
|
58
|
-
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
59
71
|
public constructor(public runtime: Runtime<Modules>) {
|
|
60
72
|
super();
|
|
61
73
|
}
|
|
62
74
|
|
|
63
|
-
public get
|
|
64
|
-
return this.runtime.
|
|
75
|
+
public get areProofsEnabled() {
|
|
76
|
+
return this.runtime.areProofsEnabled;
|
|
65
77
|
}
|
|
66
78
|
|
|
67
|
-
public zkProgramFactory(): PlainZkProgram<undefined, MethodPublicOutput> {
|
|
79
|
+
public zkProgramFactory(): PlainZkProgram<undefined, MethodPublicOutput>[] {
|
|
68
80
|
type Methods = Record<
|
|
69
81
|
string,
|
|
70
82
|
{
|
|
71
83
|
privateInputs: any;
|
|
72
|
-
method:
|
|
84
|
+
method: AsyncWrappedMethod;
|
|
73
85
|
}
|
|
74
86
|
>;
|
|
75
87
|
// We need to use explicit type annotations here,
|
|
76
88
|
// therefore we can't use destructuring
|
|
77
|
-
|
|
78
|
-
// eslint-disable-next-line
|
|
89
|
+
|
|
90
|
+
// eslint-disable-next-line prefer-destructuring
|
|
79
91
|
const runtime: Runtime<Modules> = this.runtime;
|
|
80
92
|
|
|
93
|
+
const MAXIMUM_METHODS_PER_ZK_PROGRAM = 8;
|
|
94
|
+
|
|
81
95
|
const runtimeMethods = runtime.runtimeModuleNames.reduce<Methods>(
|
|
82
96
|
(allMethods, runtimeModuleName) => {
|
|
83
|
-
runtime.isValidModuleName(
|
|
84
|
-
runtime.definition.modules,
|
|
85
|
-
runtimeModuleName
|
|
86
|
-
);
|
|
97
|
+
runtime.isValidModuleName(runtime.definition, runtimeModuleName);
|
|
87
98
|
|
|
88
99
|
/**
|
|
89
100
|
* Couldnt find a better way to circumvent the type assertion
|
|
90
101
|
* regarding resolving only known modules. We assert in the line above
|
|
91
102
|
* but we cast it to any anyways to satisfy the proof system.
|
|
92
103
|
*/
|
|
93
|
-
|
|
104
|
+
|
|
94
105
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
95
106
|
const runtimeModule = runtime.resolve(runtimeModuleName as any);
|
|
96
107
|
|
|
97
|
-
// eslint-disable-next-line max-len
|
|
98
108
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
99
109
|
const modulePrototype = Object.getPrototypeOf(runtimeModule) as Record<
|
|
100
110
|
string,
|
|
101
|
-
|
|
111
|
+
// Technically not all methods have to be async, but for this context it's ok
|
|
112
|
+
(...args: unknown[]) => Promise<unknown>
|
|
102
113
|
>;
|
|
103
114
|
|
|
104
|
-
const modulePrototypeMethods =
|
|
105
|
-
|
|
115
|
+
const modulePrototypeMethods = getAllPropertyNames(runtimeModule).map(
|
|
116
|
+
(method) => method.toString()
|
|
117
|
+
);
|
|
106
118
|
|
|
107
119
|
const moduleMethods = modulePrototypeMethods.reduce<Methods>(
|
|
108
120
|
(allModuleMethods, methodName) => {
|
|
@@ -112,14 +124,17 @@ export class RuntimeZkProgrammable<
|
|
|
112
124
|
methodName
|
|
113
125
|
);
|
|
114
126
|
const method = modulePrototype[methodName];
|
|
115
|
-
const
|
|
116
|
-
|
|
127
|
+
const invocationType = Reflect.getMetadata(
|
|
128
|
+
runtimeMethodTypeMetadataKey,
|
|
117
129
|
runtimeModule,
|
|
118
|
-
|
|
130
|
+
methodName
|
|
119
131
|
);
|
|
120
132
|
|
|
121
|
-
|
|
122
|
-
|
|
133
|
+
const wrappedMethod: AsyncWrappedMethod = Reflect.apply(
|
|
134
|
+
toWrappedMethod,
|
|
135
|
+
runtimeModule,
|
|
136
|
+
[methodName, method, { invocationType }]
|
|
137
|
+
);
|
|
123
138
|
|
|
124
139
|
const privateInputs = Reflect.getMetadata(
|
|
125
140
|
"design:paramtypes",
|
|
@@ -151,30 +166,100 @@ export class RuntimeZkProgrammable<
|
|
|
151
166
|
);
|
|
152
167
|
|
|
153
168
|
const sortedRuntimeMethods = Object.fromEntries(
|
|
154
|
-
// eslint-disable-next-line @typescript-eslint/require-array-sort-compare
|
|
155
169
|
Object.entries(runtimeMethods).sort()
|
|
156
170
|
);
|
|
157
171
|
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
172
|
+
const splitRuntimeMethods = () => {
|
|
173
|
+
const buckets: Array<
|
|
174
|
+
Record<
|
|
175
|
+
string,
|
|
176
|
+
{
|
|
177
|
+
privateInputs: any;
|
|
178
|
+
method: AsyncWrappedMethod;
|
|
179
|
+
}
|
|
180
|
+
>
|
|
181
|
+
> = [];
|
|
182
|
+
Object.entries(sortedRuntimeMethods).forEach(
|
|
183
|
+
async ([methodName, method]) => {
|
|
184
|
+
let methodAdded = false;
|
|
185
|
+
for (const bucket of buckets) {
|
|
186
|
+
if (buckets.length === 0) {
|
|
187
|
+
const record: Record<
|
|
188
|
+
string,
|
|
189
|
+
{
|
|
190
|
+
privateInputs: any;
|
|
191
|
+
method: AsyncWrappedMethod;
|
|
192
|
+
}
|
|
193
|
+
> = {};
|
|
194
|
+
record[methodName] = method;
|
|
195
|
+
buckets.push(record);
|
|
196
|
+
methodAdded = true;
|
|
197
|
+
break;
|
|
198
|
+
} else if (
|
|
199
|
+
Object.keys(bucket).length <=
|
|
200
|
+
MAXIMUM_METHODS_PER_ZK_PROGRAM - 1
|
|
201
|
+
) {
|
|
202
|
+
bucket[methodName] = method;
|
|
203
|
+
methodAdded = true;
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
if (!methodAdded) {
|
|
208
|
+
const record: Record<
|
|
209
|
+
string,
|
|
210
|
+
{
|
|
211
|
+
privateInputs: any;
|
|
212
|
+
method: AsyncWrappedMethod;
|
|
213
|
+
}
|
|
214
|
+
> = {};
|
|
215
|
+
record[methodName] = method;
|
|
216
|
+
buckets.push(record);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
);
|
|
220
|
+
return buckets;
|
|
177
221
|
};
|
|
222
|
+
|
|
223
|
+
return splitRuntimeMethods().map((bucket, index) => {
|
|
224
|
+
const name = `RuntimeProgram-${index}`;
|
|
225
|
+
const wrappedBucket = Object.fromEntries(
|
|
226
|
+
Object.entries(bucket).map(([methodName, methodDef]) => [
|
|
227
|
+
methodName,
|
|
228
|
+
{
|
|
229
|
+
privateInputs: methodDef.privateInputs,
|
|
230
|
+
method: async (...args: any[]) => {
|
|
231
|
+
const publicOutput = await methodDef.method(...args);
|
|
232
|
+
return { publicOutput };
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
])
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
const program = ZkProgram({
|
|
239
|
+
name,
|
|
240
|
+
publicOutput: MethodPublicOutput,
|
|
241
|
+
methods: wrappedBucket,
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
const SelfProof = ZkProgram.Proof(program);
|
|
245
|
+
|
|
246
|
+
const methods = Object.keys(bucket).reduce<Record<string, any>>(
|
|
247
|
+
(boundMethods, methodName) => {
|
|
248
|
+
boundMethods[methodName] = program[methodName].bind(program);
|
|
249
|
+
return boundMethods;
|
|
250
|
+
},
|
|
251
|
+
{}
|
|
252
|
+
);
|
|
253
|
+
|
|
254
|
+
return {
|
|
255
|
+
name,
|
|
256
|
+
compile: program.compile.bind(program),
|
|
257
|
+
verify: program.verify.bind(program),
|
|
258
|
+
analyzeMethods: program.analyzeMethods.bind(program),
|
|
259
|
+
Proof: SelfProof,
|
|
260
|
+
methods,
|
|
261
|
+
};
|
|
262
|
+
});
|
|
178
263
|
}
|
|
179
264
|
}
|
|
180
265
|
|
|
@@ -185,59 +270,59 @@ export class RuntimeZkProgrammable<
|
|
|
185
270
|
@injectable()
|
|
186
271
|
export class Runtime<Modules extends RuntimeModulesRecord>
|
|
187
272
|
extends ModuleContainer<Modules>
|
|
188
|
-
implements
|
|
273
|
+
implements RuntimeEnvironment, CompilableModule
|
|
189
274
|
{
|
|
190
275
|
public static from<Modules extends RuntimeModulesRecord>(
|
|
191
|
-
definition:
|
|
192
|
-
) {
|
|
193
|
-
return
|
|
276
|
+
definition: Modules
|
|
277
|
+
): TypedClass<Runtime<Modules>> {
|
|
278
|
+
return class RuntimeScoped extends Runtime<Modules> {
|
|
279
|
+
public constructor() {
|
|
280
|
+
super(definition);
|
|
281
|
+
}
|
|
282
|
+
};
|
|
194
283
|
}
|
|
195
284
|
|
|
196
285
|
// runtime modules composed into a ZkProgram
|
|
197
|
-
public program?: ReturnType<typeof
|
|
286
|
+
public program?: ReturnType<typeof ZkProgram>;
|
|
198
287
|
|
|
199
|
-
|
|
288
|
+
// No idea why we have to do this, but if we don't re-define it here,
|
|
289
|
+
// js can't access it from the superclass somehow
|
|
290
|
+
public definition: Modules;
|
|
200
291
|
|
|
201
292
|
public zkProgrammable: ZkProgrammable<undefined, MethodPublicOutput>;
|
|
202
293
|
|
|
203
|
-
// eslint-disable-next-line no-warning-comments
|
|
204
|
-
// TODO DI
|
|
205
|
-
private readonly stateServiceProviderInstance = new StateServiceProvider(
|
|
206
|
-
this.definition.state
|
|
207
|
-
);
|
|
208
|
-
|
|
209
294
|
/**
|
|
210
295
|
* Creates a new Runtime from the provided config
|
|
211
296
|
*
|
|
212
297
|
* @param modules - Configuration object for the constructed Runtime
|
|
213
298
|
*/
|
|
214
|
-
public constructor(definition:
|
|
299
|
+
public constructor(definition: Modules) {
|
|
215
300
|
super(definition);
|
|
216
301
|
this.definition = definition;
|
|
217
302
|
this.zkProgrammable = new RuntimeZkProgrammable<Modules>(this);
|
|
218
|
-
|
|
219
|
-
// this.registerDependencyFactories([MethodIdFactory]);
|
|
220
303
|
}
|
|
221
304
|
|
|
222
|
-
// eslint-disable-next-line no-warning-comments
|
|
223
305
|
// TODO Remove after changing DFs to type-based approach
|
|
224
|
-
public
|
|
225
|
-
|
|
226
|
-
Runtime: this,
|
|
227
|
-
});
|
|
228
|
-
this.registerDependencyFactories([MethodIdFactory]);
|
|
229
|
-
}
|
|
306
|
+
public create(childContainerProvider: ChildContainerProvider) {
|
|
307
|
+
super.create(childContainerProvider);
|
|
230
308
|
|
|
231
|
-
|
|
232
|
-
return this.container.resolve<AreProofsEnabled>("AppChain");
|
|
309
|
+
this.useDependencyFactory(MethodIdFactory);
|
|
233
310
|
}
|
|
234
311
|
|
|
235
|
-
public get
|
|
236
|
-
return this.
|
|
312
|
+
public get areProofsEnabled(): AreProofsEnabled | undefined {
|
|
313
|
+
return this.container.resolve<AreProofsEnabled>("AreProofsEnabled");
|
|
237
314
|
}
|
|
238
315
|
|
|
239
316
|
public get stateServiceProvider(): StateServiceProvider {
|
|
240
|
-
return this.
|
|
317
|
+
return this.container.resolve<StateServiceProvider>("StateServiceProvider");
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
public get stateService(): SimpleAsyncStateService {
|
|
321
|
+
return this.stateServiceProvider.stateService;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
public get methodIdResolver(): MethodIdResolver {
|
|
325
|
+
return this.container.resolve<MethodIdResolver>("MethodIdResolver");
|
|
241
326
|
}
|
|
242
327
|
|
|
243
328
|
/**
|
|
@@ -253,28 +338,26 @@ export class Runtime<Modules extends RuntimeModulesRecord>
|
|
|
253
338
|
*/
|
|
254
339
|
public getMethodById(
|
|
255
340
|
methodId: bigint
|
|
256
|
-
): ((...args: unknown[]) => unknown) | undefined {
|
|
257
|
-
const methodDescriptor =
|
|
258
|
-
.
|
|
259
|
-
.getMethodNameFromId(methodId);
|
|
341
|
+
): ((...args: unknown[]) => Promise<unknown>) | undefined {
|
|
342
|
+
const methodDescriptor =
|
|
343
|
+
this.methodIdResolver.getMethodNameFromId(methodId);
|
|
260
344
|
|
|
261
345
|
if (methodDescriptor === undefined) {
|
|
262
346
|
return undefined;
|
|
263
347
|
}
|
|
264
348
|
const [moduleName, methodName] = methodDescriptor;
|
|
265
349
|
|
|
266
|
-
this.
|
|
350
|
+
this.assertIsValidModuleName(moduleName);
|
|
267
351
|
const module = this.resolve(moduleName);
|
|
268
352
|
|
|
269
|
-
// eslint-disable-next-line
|
|
270
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions,@typescript-eslint/no-unsafe-member-access
|
|
353
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
271
354
|
const method = (module as any)[methodName];
|
|
272
355
|
if (method === undefined) {
|
|
273
356
|
throw errors.methodNotFound(`${moduleName}.${methodName}`);
|
|
274
357
|
}
|
|
275
358
|
|
|
276
359
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
277
|
-
return (method as (...args: unknown[]) => unknown).bind(module);
|
|
360
|
+
return (method as (...args: unknown[]) => Promise<unknown>).bind(module);
|
|
278
361
|
}
|
|
279
362
|
|
|
280
363
|
/**
|
|
@@ -289,7 +372,7 @@ export class Runtime<Modules extends RuntimeModulesRecord>
|
|
|
289
372
|
containedModule: InstanceType<Modules[StringKeyOf<Modules>]>
|
|
290
373
|
) {
|
|
291
374
|
containedModule.name = moduleName;
|
|
292
|
-
containedModule.
|
|
375
|
+
containedModule.parent = this;
|
|
293
376
|
|
|
294
377
|
super.decorateModule(moduleName, containedModule);
|
|
295
378
|
}
|
|
@@ -298,6 +381,16 @@ export class Runtime<Modules extends RuntimeModulesRecord>
|
|
|
298
381
|
* @returns A list of names of all the registered module names
|
|
299
382
|
*/
|
|
300
383
|
public get runtimeModuleNames() {
|
|
301
|
-
return
|
|
384
|
+
return this.moduleNames;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
public async compile(registry: CompileRegistry) {
|
|
388
|
+
const context = container.resolve(RuntimeMethodExecutionContext);
|
|
389
|
+
context.setup({
|
|
390
|
+
transaction: RuntimeTransaction.dummyTransaction(),
|
|
391
|
+
networkState: NetworkState.empty(),
|
|
392
|
+
});
|
|
393
|
+
return await this.zkProgrammable.compile(registry);
|
|
302
394
|
}
|
|
303
395
|
}
|
|
396
|
+
/* eslint-enable @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-argument */
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { AreProofsEnabled, WithZkProgrammable } from "@proto-kit/common";
|
|
2
|
+
import {
|
|
3
|
+
MethodPublicOutput,
|
|
4
|
+
SimpleAsyncStateService,
|
|
5
|
+
StateServiceProvider,
|
|
6
|
+
} from "@proto-kit/protocol";
|
|
7
|
+
|
|
8
|
+
import { MethodIdResolver } from "./MethodIdResolver";
|
|
9
|
+
|
|
10
|
+
export interface RuntimeEnvironment
|
|
11
|
+
extends WithZkProgrammable<undefined, MethodPublicOutput> {
|
|
12
|
+
get areProofsEnabled(): AreProofsEnabled | undefined;
|
|
13
|
+
get stateService(): SimpleAsyncStateService;
|
|
14
|
+
get stateServiceProvider(): StateServiceProvider;
|
|
15
|
+
get methodIdResolver(): MethodIdResolver;
|
|
16
|
+
}
|
|
@@ -1,40 +1,68 @@
|
|
|
1
|
-
import { ConfigurableModule, Presets } from "@proto-kit/common";
|
|
1
|
+
import { ConfigurableModule, NoConfig, Presets } from "@proto-kit/common";
|
|
2
2
|
import { container, injectable } from "tsyringe";
|
|
3
|
-
import { NetworkState, RuntimeTransaction } from "@proto-kit/protocol";
|
|
4
|
-
|
|
5
3
|
import {
|
|
4
|
+
NetworkState,
|
|
5
|
+
RuntimeTransaction,
|
|
6
6
|
RuntimeMethodExecutionContext,
|
|
7
7
|
RuntimeMethodExecutionData,
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
RuntimeMethodExecutionDataStruct,
|
|
9
|
+
} from "@proto-kit/protocol";
|
|
10
|
+
import { FlexibleProvablePure, Provable, Bool } from "o1js";
|
|
11
|
+
|
|
10
12
|
import { runtimeMethodNamesMetadataKey } from "../method/runtimeMethod";
|
|
13
|
+
import {
|
|
14
|
+
OutgoingMessages,
|
|
15
|
+
OutgoingMessagesRecord,
|
|
16
|
+
} from "../messages/OutgoingMessages";
|
|
11
17
|
|
|
12
|
-
import
|
|
13
|
-
Runtime,
|
|
14
|
-
RuntimeDefinition,
|
|
15
|
-
RuntimeModulesRecord,
|
|
16
|
-
} from "./Runtime";
|
|
18
|
+
import { RuntimeEnvironment } from "./RuntimeEnvironment";
|
|
17
19
|
|
|
18
20
|
const errors = {
|
|
19
21
|
inputDataNotSet: () => new Error("Input data for runtime execution not set"),
|
|
20
22
|
};
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
type EventRecord = Record<string, FlexibleProvablePure<any>>;
|
|
25
|
+
|
|
26
|
+
type InferProvable<T extends FlexibleProvablePure<any>> =
|
|
27
|
+
T extends Provable<infer U> ? U : never;
|
|
28
|
+
|
|
29
|
+
export class RuntimeEvents<Events extends EventRecord> {
|
|
30
|
+
public constructor(private readonly events: Events) {}
|
|
31
|
+
|
|
32
|
+
public emitIf<Key extends keyof Events>(
|
|
33
|
+
condition: Bool,
|
|
34
|
+
eventName: Key,
|
|
35
|
+
event: InferProvable<Events[Key]>
|
|
36
|
+
) {
|
|
37
|
+
if (this.events === undefined) {
|
|
38
|
+
throw new Error(
|
|
39
|
+
"'events' property not defined, make sure to define the event types on your runtimemodule"
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
const eventType: FlexibleProvablePure<any> = this.events[eventName];
|
|
43
|
+
if (typeof eventName !== "string") {
|
|
44
|
+
throw new Error("Only string");
|
|
45
|
+
}
|
|
46
|
+
return container
|
|
47
|
+
.resolve(RuntimeMethodExecutionContext)
|
|
48
|
+
.addEvent(eventType, event, eventName, condition);
|
|
49
|
+
}
|
|
29
50
|
|
|
30
|
-
|
|
51
|
+
public emit<Key extends keyof Events>(
|
|
52
|
+
eventName: Key,
|
|
53
|
+
event: InferProvable<Events[Key]>
|
|
54
|
+
) {
|
|
55
|
+
this.emitIf(Bool(true), eventName, event);
|
|
56
|
+
}
|
|
31
57
|
}
|
|
32
58
|
|
|
33
59
|
/**
|
|
34
60
|
* Base class for runtime modules providing the necessary utilities.
|
|
35
61
|
*/
|
|
36
62
|
@injectable()
|
|
37
|
-
export class RuntimeModule<
|
|
63
|
+
export class RuntimeModule<
|
|
64
|
+
Config = NoConfig,
|
|
65
|
+
> extends ConfigurableModule<Config> {
|
|
38
66
|
public static presets: Presets<unknown> = {};
|
|
39
67
|
|
|
40
68
|
/**
|
|
@@ -51,9 +79,11 @@ export class RuntimeModule<Config> extends ConfigurableModule<Config> {
|
|
|
51
79
|
|
|
52
80
|
public name?: string;
|
|
53
81
|
|
|
54
|
-
public
|
|
82
|
+
public parent?: RuntimeEnvironment;
|
|
55
83
|
|
|
56
|
-
public
|
|
84
|
+
public events?: RuntimeEvents<any> = undefined;
|
|
85
|
+
|
|
86
|
+
public messages?: OutgoingMessages<OutgoingMessagesRecord> = undefined;
|
|
57
87
|
|
|
58
88
|
public constructor() {
|
|
59
89
|
super();
|
|
@@ -65,15 +95,17 @@ export class RuntimeModule<Config> extends ConfigurableModule<Config> {
|
|
|
65
95
|
this.runtimeMethodNames = methodNames ?? [];
|
|
66
96
|
}
|
|
67
97
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
RuntimeMethodExecutionContext
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
98
|
+
public getInputs(): RuntimeMethodExecutionData {
|
|
99
|
+
return Provable.witness(RuntimeMethodExecutionDataStruct, () => {
|
|
100
|
+
const { input } = container.resolve<RuntimeMethodExecutionContext>(
|
|
101
|
+
RuntimeMethodExecutionContext
|
|
102
|
+
);
|
|
103
|
+
if (input === undefined) {
|
|
104
|
+
throw errors.inputDataNotSet();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return input;
|
|
108
|
+
});
|
|
77
109
|
}
|
|
78
110
|
|
|
79
111
|
public get transaction(): RuntimeTransaction {
|
|
@@ -1,27 +1,23 @@
|
|
|
1
|
-
import { Field } from "
|
|
2
|
-
|
|
3
|
-
export interface StateService {
|
|
4
|
-
get: (key: Field) => Field[] | undefined;
|
|
5
|
-
set: (key: Field, value: Field[] | undefined) => void;
|
|
6
|
-
}
|
|
1
|
+
import { Field } from "o1js";
|
|
2
|
+
import { SimpleAsyncStateService } from "@proto-kit/protocol";
|
|
7
3
|
|
|
8
4
|
/**
|
|
9
|
-
* Naive implementation of
|
|
5
|
+
* Naive implementation of an in-memory variant of the StateService interface
|
|
10
6
|
*/
|
|
11
|
-
export class InMemoryStateService implements
|
|
12
|
-
|
|
7
|
+
export class InMemoryStateService implements SimpleAsyncStateService {
|
|
8
|
+
/**
|
|
9
|
+
* This mapping container null values if the specific entry has been deleted.
|
|
10
|
+
* This is used by the CachedState service to keep track of deletions
|
|
11
|
+
*/
|
|
12
|
+
public values: Record<string, Field[] | null> = {};
|
|
13
13
|
|
|
14
|
-
public get(key: Field): Field[] | undefined {
|
|
15
|
-
return this.values[key.toString()];
|
|
14
|
+
public async get(key: Field): Promise<Field[] | undefined> {
|
|
15
|
+
return this.values[key.toString()] ?? undefined;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
public set(key: Field, value: Field[] | undefined) {
|
|
19
|
-
if (
|
|
20
|
-
|
|
21
|
-
Object.prototype.hasOwnProperty.call(this.values, key.toString())
|
|
22
|
-
) {
|
|
23
|
-
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
|
24
|
-
delete this.values[key.toString()];
|
|
18
|
+
public async set(key: Field, value: Field[] | undefined) {
|
|
19
|
+
if (value === undefined) {
|
|
20
|
+
this.values[key.toString()] = null;
|
|
25
21
|
} else {
|
|
26
22
|
this.values[key.toString()] = value;
|
|
27
23
|
}
|