@proto-kit/protocol 0.1.1-develop.456 → 0.1.1-develop.600
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/blockmodules/AccountStateModule.d.ts.map +1 -1
- package/dist/blockmodules/AccountStateModule.js +10 -3
- package/dist/blockmodules/BlockHeightHook.d.ts +3 -3
- package/dist/blockmodules/BlockHeightHook.d.ts.map +1 -1
- package/dist/blockmodules/BlockHeightHook.js +5 -6
- package/dist/blockmodules/LastStateRootBlockHook.d.ts +8 -0
- package/dist/blockmodules/LastStateRootBlockHook.d.ts.map +1 -0
- package/dist/blockmodules/LastStateRootBlockHook.js +15 -0
- package/dist/blockmodules/NoopBlockHook.d.ts +6 -4
- package/dist/blockmodules/NoopBlockHook.d.ts.map +1 -1
- package/dist/blockmodules/NoopBlockHook.js +4 -4
- package/dist/blockmodules/NoopSettlementHook.d.ts +6 -0
- package/dist/blockmodules/NoopSettlementHook.d.ts.map +1 -0
- package/dist/blockmodules/NoopSettlementHook.js +18 -0
- package/dist/hooks/AccountStateHook.d.ts.map +1 -1
- package/dist/hooks/AccountStateHook.js +7 -2
- package/dist/hooks/BlockHeightHook.d.ts.map +1 -1
- package/dist/index.d.ts +9 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -3
- package/dist/model/MethodPublicOutput.d.ts +8 -0
- package/dist/model/MethodPublicOutput.d.ts.map +1 -1
- package/dist/model/MethodPublicOutput.js +1 -0
- package/dist/model/network/NetworkState.d.ts +40 -0
- package/dist/model/network/NetworkState.d.ts.map +1 -1
- package/dist/model/network/NetworkState.js +14 -2
- package/dist/model/transaction/RuntimeTransaction.d.ts +45 -20
- package/dist/model/transaction/RuntimeTransaction.d.ts.map +1 -1
- package/dist/model/transaction/RuntimeTransaction.js +68 -11
- package/dist/model/transaction/SignedTransaction.d.ts +71 -0
- package/dist/model/transaction/SignedTransaction.d.ts.map +1 -0
- package/dist/model/transaction/SignedTransaction.js +33 -0
- package/dist/model/transaction/ValueOption.d.ts +119 -0
- package/dist/model/transaction/ValueOption.d.ts.map +1 -0
- package/dist/model/transaction/ValueOption.js +24 -0
- package/dist/protocol/Protocol.d.ts +7 -3
- package/dist/protocol/Protocol.d.ts.map +1 -1
- package/dist/protocol/Protocol.js +26 -16
- package/dist/protocol/ProvableBlockHook.d.ts +2 -10
- package/dist/protocol/ProvableBlockHook.d.ts.map +1 -1
- package/dist/protocol/ProvableBlockHook.js +1 -1
- package/dist/protocol/ProvableTransactionHook.d.ts +1 -1
- package/dist/protocol/ProvableTransactionHook.d.ts.map +1 -1
- package/dist/protocol/TransitioningProtocolModule.d.ts +3 -2
- package/dist/protocol/TransitioningProtocolModule.d.ts.map +1 -1
- package/dist/protocol/TransitioningProtocolModule.js +3 -2
- package/dist/prover/block/BlockProvable.d.ts +106 -28
- package/dist/prover/block/BlockProvable.d.ts.map +1 -1
- package/dist/prover/block/BlockProvable.js +23 -5
- package/dist/prover/block/BlockProver.d.ts +29 -8
- package/dist/prover/block/BlockProver.d.ts.map +1 -1
- package/dist/prover/block/BlockProver.js +241 -77
- package/dist/prover/block/accummulators/BlockHashMerkleTree.d.ts +45 -0
- package/dist/prover/block/accummulators/BlockHashMerkleTree.d.ts.map +1 -0
- package/dist/prover/block/accummulators/BlockHashMerkleTree.js +16 -0
- package/dist/settlement/ProvableSettlementHook.d.ts +26 -0
- package/dist/settlement/ProvableSettlementHook.d.ts.map +1 -0
- package/dist/settlement/ProvableSettlementHook.js +3 -0
- package/dist/settlement/SettlementContract.d.ts +230 -0
- package/dist/settlement/SettlementContract.d.ts.map +1 -0
- package/dist/settlement/SettlementContract.js +346 -0
- package/dist/settlement/modules/NetworkStateSettlementModule.d.ts +11 -0
- package/dist/settlement/modules/NetworkStateSettlementModule.d.ts.map +1 -0
- package/dist/settlement/modules/NetworkStateSettlementModule.js +12 -0
- package/dist/state/context/RuntimeMethodExecutionContext.d.ts +75 -1
- package/dist/state/context/RuntimeMethodExecutionContext.d.ts.map +1 -1
- package/dist/state/context/RuntimeMethodExecutionContext.js +19 -1
- package/dist/utils/MinaPrefixedProvableHashList.d.ts +24 -0
- package/dist/utils/MinaPrefixedProvableHashList.d.ts.map +1 -0
- package/dist/utils/MinaPrefixedProvableHashList.js +51 -0
- package/package.json +2 -2
- package/src/blockmodules/AccountStateModule.ts +17 -6
- package/src/blockmodules/BlockHeightHook.ts +5 -8
- package/src/blockmodules/LastStateRootBlockHook.ts +26 -0
- package/src/blockmodules/NoopBlockHook.ts +15 -11
- package/src/blockmodules/NoopSettlementHook.ts +21 -0
- package/src/blockmodules/SequenceStateTransactionModule.ts +25 -0
- package/src/index.ts +9 -3
- package/src/model/MethodPublicOutput.ts +3 -2
- package/src/model/network/NetworkState.ts +15 -3
- package/src/model/transaction/RuntimeTransaction.ts +90 -16
- package/src/model/transaction/SignedTransaction.ts +54 -0
- package/src/model/transaction/ValueOption.ts +28 -0
- package/src/protocol/Protocol.ts +49 -31
- package/src/protocol/ProvableBlockHook.ts +10 -13
- package/src/protocol/ProvableTransactionHook.ts +2 -1
- package/src/protocol/TransitioningProtocolModule.ts +3 -2
- package/src/prover/block/BlockProvable.ts +39 -6
- package/src/prover/block/BlockProver.ts +473 -143
- package/src/prover/block/accummulators/BlockHashMerkleTree.ts +16 -0
- package/src/settlement/ProvableSettlementHook.ts +37 -0
- package/src/settlement/SettlementContract.ts +444 -0
- package/src/settlement/modules/NetworkStateSettlementModule.ts +39 -0
- package/src/state/context/RuntimeMethodExecutionContext.ts +18 -1
- package/src/utils/MinaPrefixedProvableHashList.ts +72 -0
- package/test/BlockProver.test.ts +2 -3
- package/src/model/transaction/ProtocolTransaction.ts +0 -25
- package/src/prover/block/BlockTransactionPosition.ts +0 -34
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
import {
|
|
3
3
|
Bool,
|
|
4
4
|
Experimental,
|
|
5
|
-
Field,
|
|
5
|
+
Field, Poseidon,
|
|
6
6
|
type Proof,
|
|
7
7
|
Provable,
|
|
8
|
-
SelfProof
|
|
9
|
-
Struct,
|
|
8
|
+
SelfProof
|
|
10
9
|
} from "o1js";
|
|
11
10
|
import { container, inject, injectable, injectAll } from "tsyringe";
|
|
12
11
|
import {
|
|
13
12
|
AreProofsEnabled,
|
|
13
|
+
hashWithPrefix,
|
|
14
14
|
PlainZkProgram,
|
|
15
15
|
provableMethod,
|
|
16
16
|
WithZkProgrammable,
|
|
@@ -26,6 +26,16 @@ import {
|
|
|
26
26
|
StateTransitionProverPublicOutput,
|
|
27
27
|
} from "../statetransition/StateTransitionProvable";
|
|
28
28
|
import { RuntimeTransaction } from "../../model/transaction/RuntimeTransaction";
|
|
29
|
+
import {
|
|
30
|
+
ProvableStateTransition,
|
|
31
|
+
StateTransition,
|
|
32
|
+
} from "../../model/StateTransition";
|
|
33
|
+
import { ProvableTransactionHook } from "../../protocol/ProvableTransactionHook";
|
|
34
|
+
import { RuntimeMethodExecutionContext } from "../../state/context/RuntimeMethodExecutionContext";
|
|
35
|
+
import { ProvableBlockHook } from "../../protocol/ProvableBlockHook";
|
|
36
|
+
import { NetworkState } from "../../model/network/NetworkState";
|
|
37
|
+
import { SignedTransaction } from "../../model/transaction/SignedTransaction";
|
|
38
|
+
import { MinaActions, MinaActionsHashList } from "../../utils/MinaPrefixedProvableHashList";
|
|
29
39
|
|
|
30
40
|
import {
|
|
31
41
|
BlockProvable,
|
|
@@ -34,12 +44,10 @@ import {
|
|
|
34
44
|
BlockProverPublicInput,
|
|
35
45
|
BlockProverPublicOutput,
|
|
36
46
|
} from "./BlockProvable";
|
|
37
|
-
import {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
import { NetworkState } from "../../model/network/NetworkState";
|
|
42
|
-
import { BlockTransactionPosition } from "./BlockTransactionPosition";
|
|
47
|
+
import {
|
|
48
|
+
BlockHashMerkleTreeWitness,
|
|
49
|
+
BlockHashTreeEntry,
|
|
50
|
+
} from "./accummulators/BlockHashMerkleTree";
|
|
43
51
|
|
|
44
52
|
const errors = {
|
|
45
53
|
stateProofNotStartingAtZero: () =>
|
|
@@ -48,16 +56,26 @@ const errors = {
|
|
|
48
56
|
stateTransitionsHashNotEqual: () =>
|
|
49
57
|
"StateTransition list commitments are not equal",
|
|
50
58
|
|
|
59
|
+
propertyNotMatchingStep: (propertyName: string, step: string) =>
|
|
60
|
+
`${propertyName} not matching: ${step}`,
|
|
61
|
+
|
|
51
62
|
propertyNotMatching: (propertyName: string) => `${propertyName} not matching`,
|
|
52
63
|
|
|
53
|
-
stateRootNotMatching: (step: string) =>
|
|
64
|
+
stateRootNotMatching: (step: string) =>
|
|
65
|
+
errors.propertyNotMatchingStep("StateRoots", step),
|
|
54
66
|
|
|
55
67
|
transactionsHashNotMatching: (step: string) =>
|
|
56
|
-
|
|
68
|
+
errors.propertyNotMatchingStep("Transactions hash", step),
|
|
69
|
+
|
|
70
|
+
networkStateHashNotMatching: (step: string) =>
|
|
71
|
+
errors.propertyNotMatchingStep("Network state hash", step),
|
|
57
72
|
};
|
|
58
73
|
|
|
74
|
+
// Should be equal to BlockProver.PublicInput
|
|
59
75
|
export interface BlockProverState {
|
|
60
|
-
|
|
76
|
+
/**
|
|
77
|
+
* The current state root of the block prover
|
|
78
|
+
*/
|
|
61
79
|
stateRoot: Field;
|
|
62
80
|
|
|
63
81
|
/**
|
|
@@ -71,8 +89,30 @@ export interface BlockProverState {
|
|
|
71
89
|
* This value is the same for the whole batch (L2 block)
|
|
72
90
|
*/
|
|
73
91
|
networkStateHash: Field;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* The root of the merkle tree encoding all block hashes,
|
|
95
|
+
* see `BlockHashMerkleTree`
|
|
96
|
+
*/
|
|
97
|
+
blockHashRoot: Field;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* A variant of the transactionsHash that is never reset.
|
|
101
|
+
* Thought for usage in the sequence state mempool.
|
|
102
|
+
* In comparison, transactionsHash restarts at 0 for every new block
|
|
103
|
+
*/
|
|
104
|
+
eternalTransactionsHash: Field;
|
|
105
|
+
|
|
106
|
+
incomingMessagesHash: Field;
|
|
74
107
|
}
|
|
75
108
|
|
|
109
|
+
function maxField() {
|
|
110
|
+
return Field(Field.ORDER - 1n);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export type BlockProof = Proof<BlockProverPublicInput, BlockProverPublicOutput>;
|
|
114
|
+
export type RuntimeProof = Proof<void, MethodPublicOutput>;
|
|
115
|
+
|
|
76
116
|
export class BlockProverProgrammable extends ZkProgrammable<
|
|
77
117
|
BlockProverPublicInput,
|
|
78
118
|
BlockProverPublicOutput
|
|
@@ -101,7 +141,7 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
101
141
|
*
|
|
102
142
|
* @param state The from-state of the BlockProver
|
|
103
143
|
* @param stateTransitionProof
|
|
104
|
-
* @param
|
|
144
|
+
* @param runtimeProof
|
|
105
145
|
* @param executionData
|
|
106
146
|
* @returns The new BlockProver-state to be used as public output
|
|
107
147
|
*/
|
|
@@ -111,12 +151,14 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
111
151
|
StateTransitionProverPublicInput,
|
|
112
152
|
StateTransitionProverPublicOutput
|
|
113
153
|
>,
|
|
114
|
-
|
|
154
|
+
runtimeProof: RuntimeProof,
|
|
115
155
|
executionData: BlockProverExecutionData
|
|
116
156
|
): BlockProverState {
|
|
117
|
-
const { transaction, networkState } = executionData;
|
|
157
|
+
const { transaction, networkState, signature } = executionData;
|
|
158
|
+
|
|
159
|
+
const isMessage = runtimeProof.publicOutput.isMessage;
|
|
118
160
|
|
|
119
|
-
|
|
161
|
+
runtimeProof.verify();
|
|
120
162
|
stateTransitionProof.verify();
|
|
121
163
|
|
|
122
164
|
const stateTo = { ...state };
|
|
@@ -126,8 +168,12 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
126
168
|
Field(0),
|
|
127
169
|
errors.stateProofNotStartingAtZero()
|
|
128
170
|
);
|
|
171
|
+
stateTransitionProof.publicInput.protocolTransitionsHash.assertEquals(
|
|
172
|
+
Field(0),
|
|
173
|
+
errors.stateProofNotStartingAtZero()
|
|
174
|
+
);
|
|
129
175
|
|
|
130
|
-
|
|
176
|
+
runtimeProof.publicOutput.stateTransitionsHash.assertEquals(
|
|
131
177
|
stateTransitionProof.publicOutput.stateTransitionsHash,
|
|
132
178
|
errors.stateTransitionsHashNotEqual()
|
|
133
179
|
);
|
|
@@ -142,33 +188,43 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
142
188
|
errors.propertyNotMatching("from protocol state root")
|
|
143
189
|
);
|
|
144
190
|
|
|
191
|
+
// Apply protocol state transitions
|
|
192
|
+
this.assertProtocolTransitions(
|
|
193
|
+
stateTransitionProof,
|
|
194
|
+
executionData,
|
|
195
|
+
runtimeProof
|
|
196
|
+
);
|
|
197
|
+
|
|
145
198
|
// Apply state if status success
|
|
146
199
|
stateTo.stateRoot = Provable.if(
|
|
147
|
-
|
|
200
|
+
runtimeProof.publicOutput.status,
|
|
148
201
|
stateTransitionProof.publicOutput.stateRoot,
|
|
149
202
|
stateTransitionProof.publicOutput.protocolStateRoot
|
|
150
203
|
);
|
|
151
204
|
|
|
152
|
-
// Apply protocol state transitions
|
|
153
|
-
this.assertProtocolTransitions(stateTransitionProof, executionData);
|
|
154
|
-
|
|
155
|
-
// Check transaction signature
|
|
156
|
-
transaction
|
|
157
|
-
.validateSignature()
|
|
158
|
-
.assertTrue("Transaction signature not valid");
|
|
159
|
-
|
|
160
205
|
// Check transaction integrity against appProof
|
|
161
|
-
const blockTransactionHash =
|
|
162
|
-
RuntimeTransaction.fromProtocolTransaction(transaction).hash();
|
|
206
|
+
const blockTransactionHash = transaction.hash();
|
|
163
207
|
|
|
164
208
|
blockTransactionHash.assertEquals(
|
|
165
|
-
|
|
209
|
+
runtimeProof.publicOutput.transactionHash,
|
|
166
210
|
"Transactions provided in AppProof and BlockProof do not match"
|
|
167
211
|
);
|
|
168
212
|
|
|
213
|
+
// Check transaction signature
|
|
214
|
+
new SignedTransaction({
|
|
215
|
+
transaction,
|
|
216
|
+
signature,
|
|
217
|
+
})
|
|
218
|
+
.validateSignature()
|
|
219
|
+
.or(isMessage)
|
|
220
|
+
.assertTrue("Transaction signature not valid");
|
|
221
|
+
|
|
222
|
+
// Validate layout of transaction witness
|
|
223
|
+
transaction.assertTransactionType(isMessage);
|
|
224
|
+
|
|
169
225
|
// Check network state integrity against appProof
|
|
170
226
|
state.networkStateHash.assertEquals(
|
|
171
|
-
|
|
227
|
+
runtimeProof.publicOutput.networkStateHash,
|
|
172
228
|
"Network state does not match state used in AppProof"
|
|
173
229
|
);
|
|
174
230
|
state.networkStateHash.assertEquals(
|
|
@@ -187,7 +243,8 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
187
243
|
StateTransitionProverPublicInput,
|
|
188
244
|
StateTransitionProverPublicOutput
|
|
189
245
|
>,
|
|
190
|
-
executionData: BlockProverExecutionData
|
|
246
|
+
executionData: BlockProverExecutionData,
|
|
247
|
+
runtimeProof: Proof<void, MethodPublicOutput>
|
|
191
248
|
) {
|
|
192
249
|
const executionContext = container.resolve(RuntimeMethodExecutionContext);
|
|
193
250
|
executionContext.clear();
|
|
@@ -196,10 +253,8 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
196
253
|
// This way they can use this.transaction etc. while still having provable
|
|
197
254
|
// integrity between data
|
|
198
255
|
executionContext.setup({
|
|
199
|
-
transaction
|
|
200
|
-
|
|
201
|
-
),
|
|
202
|
-
|
|
256
|
+
// That is why we should probably hide it from the transaction context inputs
|
|
257
|
+
transaction: executionData.transaction,
|
|
203
258
|
networkState: executionData.networkState,
|
|
204
259
|
});
|
|
205
260
|
executionContext.beforeMethod("", "", []);
|
|
@@ -234,60 +289,62 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
234
289
|
);
|
|
235
290
|
}
|
|
236
291
|
|
|
237
|
-
private
|
|
292
|
+
private executeBlockHooks(
|
|
238
293
|
state: BlockProverState,
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
294
|
+
inputNetworkState: NetworkState,
|
|
295
|
+
type: "afterBlock" | "beforeBlock"
|
|
296
|
+
): {
|
|
297
|
+
networkState: NetworkState;
|
|
298
|
+
stateTransitions: StateTransition<unknown>[];
|
|
299
|
+
} {
|
|
300
|
+
const executionContext = container.resolve(RuntimeMethodExecutionContext);
|
|
301
|
+
executionContext.clear();
|
|
302
|
+
executionContext.beforeMethod("", "", []);
|
|
248
303
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
304
|
+
const resultingNetworkState = this.blockHooks.reduce<NetworkState>(
|
|
305
|
+
(networkState, blockHook) => {
|
|
306
|
+
// Setup context for potential calls to runtime methods.
|
|
307
|
+
// With the special case that we set the new networkstate for every hook
|
|
308
|
+
// We also have to put in a dummy transaction for network.transaction
|
|
309
|
+
executionContext.setup({
|
|
310
|
+
transaction: RuntimeTransaction.dummyTransaction(),
|
|
311
|
+
networkState,
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
if (type === "beforeBlock") {
|
|
315
|
+
return blockHook.beforeBlock(networkState, state);
|
|
316
|
+
} else if (type === "afterBlock") {
|
|
317
|
+
return blockHook.afterBlock(networkState, state);
|
|
318
|
+
} else {
|
|
319
|
+
throw new Error("Unreachable");
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
inputNetworkState
|
|
323
|
+
);
|
|
324
|
+
|
|
325
|
+
executionContext.afterMethod();
|
|
326
|
+
|
|
327
|
+
const { stateTransitions, status, statusMessage } =
|
|
328
|
+
executionContext.current().result;
|
|
329
|
+
|
|
330
|
+
status.assertTrue(`Block hook call failed: ${statusMessage ?? "-"}`);
|
|
331
|
+
|
|
332
|
+
return {
|
|
333
|
+
networkState: resultingNetworkState,
|
|
334
|
+
stateTransitions,
|
|
335
|
+
};
|
|
259
336
|
}
|
|
260
337
|
|
|
261
338
|
private addTransactionToBundle(
|
|
262
339
|
state: BlockProverState,
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
): {
|
|
267
|
-
state: BlockProverState;
|
|
268
|
-
networkState: NetworkState;
|
|
269
|
-
bundleOpened: Bool;
|
|
270
|
-
bundleClosed: Bool;
|
|
271
|
-
} {
|
|
272
|
-
const { transactionPosition, networkState } = executionData;
|
|
340
|
+
isMessage: Bool,
|
|
341
|
+
transaction: RuntimeTransaction
|
|
342
|
+
): BlockProverState {
|
|
273
343
|
const stateTo = {
|
|
274
344
|
...state,
|
|
275
345
|
};
|
|
276
346
|
|
|
277
|
-
|
|
278
|
-
const beforeHookResult = this.getBeforeBlockNetworkState(
|
|
279
|
-
state,
|
|
280
|
-
networkState
|
|
281
|
-
);
|
|
282
|
-
const bundleOpened = transactionPosition.equals(
|
|
283
|
-
BlockTransactionPosition.fromPositionType("FIRST")
|
|
284
|
-
);
|
|
285
|
-
const resultingNetworkState = new NetworkState(
|
|
286
|
-
Provable.if(bundleOpened, NetworkState, beforeHookResult, networkState)
|
|
287
|
-
);
|
|
288
|
-
stateTo.networkStateHash = resultingNetworkState.hash();
|
|
289
|
-
|
|
290
|
-
// TODO Modify bundle merkle tree as per specs
|
|
347
|
+
const transactionHash = transaction.hash();
|
|
291
348
|
|
|
292
349
|
// Append tx to transaction list
|
|
293
350
|
const transactionList = new DefaultProvableHashList(
|
|
@@ -295,75 +352,248 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
295
352
|
state.transactionsHash
|
|
296
353
|
);
|
|
297
354
|
|
|
298
|
-
|
|
299
|
-
transactionList.push(transactionHash);
|
|
300
|
-
|
|
355
|
+
transactionList.pushIf(transactionHash, isMessage.not());
|
|
301
356
|
stateTo.transactionsHash = transactionList.commitment;
|
|
302
357
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
358
|
+
// Append tx to eternal transaction list
|
|
359
|
+
// eslint-disable-next-line no-warning-comments
|
|
360
|
+
// TODO Change that to the a sequence-state compatible transaction struct
|
|
361
|
+
const eternalTransactionList = new DefaultProvableHashList(
|
|
362
|
+
Field,
|
|
363
|
+
state.eternalTransactionsHash
|
|
364
|
+
);
|
|
307
365
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
366
|
+
eternalTransactionList.pushIf(transactionHash, isMessage.not());
|
|
367
|
+
stateTo.eternalTransactionsHash = eternalTransactionList.commitment;
|
|
368
|
+
|
|
369
|
+
// Append tx to incomingMessagesHash
|
|
370
|
+
const actionHash = MinaActions.actionHash(transaction.hashData());
|
|
371
|
+
|
|
372
|
+
const incomingMessagesList = new MinaActionsHashList(state.incomingMessagesHash);
|
|
373
|
+
incomingMessagesList.pushIf(actionHash, isMessage);
|
|
374
|
+
|
|
375
|
+
stateTo.incomingMessagesHash = incomingMessagesList.commitment;
|
|
376
|
+
|
|
377
|
+
return stateTo;
|
|
312
378
|
}
|
|
313
379
|
|
|
314
380
|
@provableMethod()
|
|
315
381
|
public proveTransaction(
|
|
316
382
|
publicInput: BlockProverPublicInput,
|
|
317
383
|
stateProof: StateTransitionProof,
|
|
318
|
-
|
|
384
|
+
runtimeProof: RuntimeProof,
|
|
319
385
|
executionData: BlockProverExecutionData
|
|
320
386
|
): BlockProverPublicOutput {
|
|
321
387
|
const state: BlockProverState = {
|
|
322
|
-
|
|
323
|
-
stateRoot: publicInput.stateRoot,
|
|
324
|
-
networkStateHash: publicInput.networkStateHash,
|
|
388
|
+
...publicInput,
|
|
325
389
|
};
|
|
326
390
|
|
|
327
|
-
|
|
391
|
+
state.networkStateHash.assertEquals(
|
|
392
|
+
executionData.networkState.hash(),
|
|
393
|
+
"ExecutionData Networkstate doesn't equal public input hash"
|
|
394
|
+
);
|
|
395
|
+
|
|
396
|
+
const bundleInclusionState = this.addTransactionToBundle(
|
|
328
397
|
state,
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
executionData
|
|
398
|
+
runtimeProof.publicOutput.isMessage,
|
|
399
|
+
executionData.transaction
|
|
332
400
|
);
|
|
333
401
|
|
|
334
402
|
const stateTo = this.applyTransaction(
|
|
335
|
-
|
|
403
|
+
bundleInclusionState,
|
|
336
404
|
stateProof,
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
405
|
+
runtimeProof,
|
|
406
|
+
executionData
|
|
407
|
+
);
|
|
408
|
+
|
|
409
|
+
return new BlockProverPublicOutput({
|
|
410
|
+
...stateTo,
|
|
411
|
+
blockNumber: maxField(),
|
|
412
|
+
closed: Bool(false),
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
private assertSTProofInput(
|
|
417
|
+
stateTransitionProof: StateTransitionProof,
|
|
418
|
+
stateRoot: Field
|
|
419
|
+
) {
|
|
420
|
+
stateTransitionProof.publicInput.stateTransitionsHash.assertEquals(
|
|
421
|
+
Field(0),
|
|
422
|
+
errors.stateProofNotStartingAtZero()
|
|
423
|
+
);
|
|
424
|
+
stateTransitionProof.publicInput.protocolTransitionsHash.assertEquals(
|
|
425
|
+
Field(0),
|
|
426
|
+
errors.stateProofNotStartingAtZero()
|
|
427
|
+
);
|
|
428
|
+
|
|
429
|
+
// Assert from state roots
|
|
430
|
+
stateRoot.assertEquals(
|
|
431
|
+
stateTransitionProof.publicInput.stateRoot,
|
|
432
|
+
errors.propertyNotMatching("from state root")
|
|
433
|
+
);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
@provableMethod()
|
|
437
|
+
public proveBlock(
|
|
438
|
+
publicInput: BlockProverPublicInput,
|
|
439
|
+
networkState: NetworkState,
|
|
440
|
+
blockWitness: BlockHashMerkleTreeWitness,
|
|
441
|
+
stateTransitionProof: StateTransitionProof,
|
|
442
|
+
transactionProof: BlockProverProof
|
|
443
|
+
): BlockProverPublicOutput {
|
|
444
|
+
const state: BlockProverState = {
|
|
445
|
+
...publicInput,
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
// 1. Make assertions about the inputs
|
|
449
|
+
publicInput.transactionsHash.assertEquals(
|
|
450
|
+
Field(0),
|
|
451
|
+
"Transactionshash has to start at 0"
|
|
452
|
+
);
|
|
453
|
+
publicInput.networkStateHash.assertEquals(
|
|
454
|
+
networkState.hash(),
|
|
455
|
+
"Wrong NetworkState supplied"
|
|
456
|
+
);
|
|
457
|
+
|
|
458
|
+
transactionProof.publicInput.transactionsHash.assertEquals(
|
|
459
|
+
Field(0),
|
|
460
|
+
"TransactionProof transactionshash has to start at 0"
|
|
461
|
+
);
|
|
462
|
+
transactionProof.publicInput.blockHashRoot.assertEquals(
|
|
463
|
+
Field(0),
|
|
464
|
+
"TransactionProof cannot carry the blockHashRoot - publicInput"
|
|
465
|
+
);
|
|
466
|
+
transactionProof.publicOutput.blockHashRoot.assertEquals(
|
|
467
|
+
Field(0),
|
|
468
|
+
"TransactionProof cannot carry the blockHashRoot - publicOutput"
|
|
469
|
+
);
|
|
470
|
+
transactionProof.publicInput.networkStateHash.assertEquals(
|
|
471
|
+
transactionProof.publicOutput.networkStateHash,
|
|
472
|
+
"TransactionProof cannot alter the network state"
|
|
473
|
+
);
|
|
474
|
+
transactionProof.publicInput.eternalTransactionsHash.assertEquals(
|
|
475
|
+
state.eternalTransactionsHash,
|
|
476
|
+
"TransactionProof starting eternalTransactionHash not matching"
|
|
477
|
+
);
|
|
478
|
+
transactionProof.publicInput.incomingMessagesHash.assertEquals(
|
|
479
|
+
state.incomingMessagesHash,
|
|
480
|
+
"TransactionProof starting incomingMessagesHash not matching"
|
|
481
|
+
);
|
|
482
|
+
|
|
483
|
+
// Verify ST Proof only if STs have been emitted,
|
|
484
|
+
// otherwise we can input a dummy proof
|
|
485
|
+
const stsEmitted = stateTransitionProof.publicOutput.stateTransitionsHash
|
|
486
|
+
.equals(0)
|
|
487
|
+
.and(stateTransitionProof.publicOutput.protocolTransitionsHash.equals(0))
|
|
488
|
+
.not();
|
|
489
|
+
stateTransitionProof.verifyIf(stsEmitted);
|
|
490
|
+
|
|
491
|
+
// Verify Transaction proof if it has at least 1 tx
|
|
492
|
+
// We have to compare the whole input and output because we can make no
|
|
493
|
+
// assumptions about the values, since it can be an arbitrary dummy-proof
|
|
494
|
+
const txProofOutput = transactionProof.publicOutput;
|
|
495
|
+
const verifyTransactionProof = txProofOutput.equals(
|
|
496
|
+
transactionProof.publicInput,
|
|
497
|
+
txProofOutput.closed,
|
|
498
|
+
txProofOutput.blockNumber
|
|
499
|
+
);
|
|
500
|
+
transactionProof.verifyIf(verifyTransactionProof);
|
|
501
|
+
|
|
502
|
+
// 2. Execute beforeBlock hooks
|
|
503
|
+
const beforeBlockResult = this.executeBlockHooks(
|
|
504
|
+
state,
|
|
505
|
+
networkState,
|
|
506
|
+
"beforeBlock"
|
|
507
|
+
);
|
|
508
|
+
|
|
509
|
+
const beforeBlockHashList = new DefaultProvableHashList(
|
|
510
|
+
ProvableStateTransition
|
|
511
|
+
);
|
|
512
|
+
beforeBlockResult.stateTransitions.forEach((st) => {
|
|
513
|
+
beforeBlockHashList.push(st.toProvable());
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
// We are reusing protocolSTs here as beforeBlock STs
|
|
517
|
+
// TODO Not possible atm bcs we can't have a seperation between protocol/runtime state roots,
|
|
518
|
+
// which we would for both before and after to be able to emit STs
|
|
519
|
+
|
|
520
|
+
// stateTransitionProof.publicInput.protocolTransitionsHash.assertEquals(
|
|
521
|
+
// beforeBlockHashList.commitment
|
|
522
|
+
// );
|
|
523
|
+
// state.stateRoot = stateTransitionProof.publicInput.protocolStateRoot;
|
|
524
|
+
|
|
525
|
+
// TODO Only for now
|
|
526
|
+
beforeBlockHashList.commitment.assertEquals(
|
|
527
|
+
Field(0),
|
|
528
|
+
"beforeBlock() cannot emit state transitions yet"
|
|
529
|
+
);
|
|
530
|
+
|
|
531
|
+
// 4. Apply TX-type BlockProof
|
|
532
|
+
transactionProof.publicInput.networkStateHash.assertEquals(
|
|
533
|
+
beforeBlockResult.networkState.hash(),
|
|
534
|
+
"TransactionProof networkstate hash not matching beforeBlock hook result"
|
|
535
|
+
);
|
|
536
|
+
transactionProof.publicInput.stateRoot.assertEquals(
|
|
537
|
+
state.stateRoot,
|
|
538
|
+
"TransactionProof input state root not matching blockprover state root"
|
|
343
539
|
);
|
|
344
540
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
541
|
+
state.stateRoot = transactionProof.publicOutput.stateRoot;
|
|
542
|
+
state.transactionsHash = transactionProof.publicOutput.transactionsHash;
|
|
543
|
+
state.eternalTransactionsHash =
|
|
544
|
+
transactionProof.publicOutput.eternalTransactionsHash;
|
|
545
|
+
state.incomingMessagesHash =
|
|
546
|
+
transactionProof.publicOutput.incomingMessagesHash;
|
|
547
|
+
|
|
548
|
+
// 5. Execute afterBlock hooks
|
|
549
|
+
this.assertSTProofInput(stateTransitionProof, state.stateRoot);
|
|
550
|
+
|
|
551
|
+
const afterBlockResult = this.executeBlockHooks(
|
|
552
|
+
state,
|
|
553
|
+
beforeBlockResult.networkState,
|
|
554
|
+
"afterBlock"
|
|
349
555
|
);
|
|
350
|
-
|
|
351
|
-
|
|
556
|
+
|
|
557
|
+
const afterBlockHashList = new DefaultProvableHashList(
|
|
558
|
+
ProvableStateTransition
|
|
352
559
|
);
|
|
560
|
+
afterBlockResult.stateTransitions.forEach((st) => {
|
|
561
|
+
afterBlockHashList.push(st.toProvable());
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
state.networkStateHash = afterBlockResult.networkState.hash();
|
|
353
565
|
|
|
354
|
-
// We
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
566
|
+
// We are reusing runtime STs here as afterBlock STs
|
|
567
|
+
stateTransitionProof.publicInput.stateTransitionsHash.assertEquals(
|
|
568
|
+
afterBlockHashList.commitment,
|
|
569
|
+
"STProof from-ST-hash not matching generated ST-hash from afterBlock hooks"
|
|
570
|
+
);
|
|
571
|
+
state.stateRoot = stateTransitionProof.publicInput.stateRoot;
|
|
572
|
+
|
|
573
|
+
// 6. Close block
|
|
574
|
+
|
|
575
|
+
// Calculate the new block index
|
|
576
|
+
const blockIndex = blockWitness.calculateIndex();
|
|
577
|
+
|
|
578
|
+
blockWitness
|
|
579
|
+
.calculateRoot(Field(0))
|
|
580
|
+
.assertEquals(
|
|
581
|
+
publicInput.blockHashRoot,
|
|
582
|
+
"Supplied block hash witness not matching state root"
|
|
583
|
+
);
|
|
584
|
+
|
|
585
|
+
state.blockHashRoot = blockWitness.calculateRoot(
|
|
586
|
+
new BlockHashTreeEntry({
|
|
587
|
+
// Mirroring UnprovenBlock.hash()
|
|
588
|
+
blockHash: Poseidon.hash([blockIndex, state.transactionsHash]),
|
|
589
|
+
closed: Bool(true),
|
|
590
|
+
}).hash()
|
|
360
591
|
);
|
|
361
592
|
|
|
362
593
|
return new BlockProverPublicOutput({
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
networkStateHash: resultingNetworkStateHash,
|
|
594
|
+
...state,
|
|
595
|
+
blockNumber: blockIndex,
|
|
596
|
+
closed: Bool(true),
|
|
367
597
|
});
|
|
368
598
|
}
|
|
369
599
|
|
|
@@ -386,30 +616,117 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
386
616
|
errors.stateRootNotMatching("proof1.to -> proof2.from")
|
|
387
617
|
);
|
|
388
618
|
|
|
389
|
-
// Check transaction list
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
619
|
+
// Check transaction list hash.
|
|
620
|
+
// Only assert them if these are tx proofs, skip for closed proofs
|
|
621
|
+
publicInput.transactionsHash
|
|
622
|
+
.equals(proof1.publicInput.transactionsHash)
|
|
623
|
+
.or(proof1.publicOutput.closed)
|
|
624
|
+
.assertTrue(
|
|
625
|
+
errors.transactionsHashNotMatching("publicInput.from -> proof1.from")
|
|
626
|
+
);
|
|
627
|
+
proof1.publicOutput.transactionsHash
|
|
628
|
+
.equals(proof2.publicInput.transactionsHash)
|
|
629
|
+
.or(proof1.publicOutput.closed)
|
|
630
|
+
.assertTrue(
|
|
631
|
+
errors.transactionsHashNotMatching("proof1.to -> proof2.from")
|
|
632
|
+
);
|
|
398
633
|
|
|
399
634
|
// Check networkhash
|
|
400
635
|
publicInput.networkStateHash.assertEquals(
|
|
401
636
|
proof1.publicInput.networkStateHash,
|
|
402
|
-
errors.
|
|
637
|
+
errors.networkStateHashNotMatching("publicInput.from -> proof1.from")
|
|
403
638
|
);
|
|
404
639
|
proof1.publicOutput.networkStateHash.assertEquals(
|
|
405
640
|
proof2.publicInput.networkStateHash,
|
|
641
|
+
errors.networkStateHashNotMatching("proof1.to -> proof2.from")
|
|
642
|
+
);
|
|
643
|
+
|
|
644
|
+
// Check blockHashRoot
|
|
645
|
+
publicInput.blockHashRoot.assertEquals(
|
|
646
|
+
proof1.publicInput.blockHashRoot,
|
|
647
|
+
errors.transactionsHashNotMatching("publicInput.from -> proof1.from")
|
|
648
|
+
);
|
|
649
|
+
proof1.publicOutput.blockHashRoot.assertEquals(
|
|
650
|
+
proof2.publicInput.blockHashRoot,
|
|
406
651
|
errors.transactionsHashNotMatching("proof1.to -> proof2.from")
|
|
407
652
|
);
|
|
408
653
|
|
|
654
|
+
// Check eternalTransactionsHash
|
|
655
|
+
publicInput.eternalTransactionsHash.assertEquals(
|
|
656
|
+
proof1.publicInput.eternalTransactionsHash,
|
|
657
|
+
errors.transactionsHashNotMatching("publicInput.from -> proof1.from")
|
|
658
|
+
);
|
|
659
|
+
proof1.publicOutput.eternalTransactionsHash.assertEquals(
|
|
660
|
+
proof2.publicInput.eternalTransactionsHash,
|
|
661
|
+
errors.transactionsHashNotMatching("proof1.to -> proof2.from")
|
|
662
|
+
);
|
|
663
|
+
|
|
664
|
+
// Check incomingMessagesHash
|
|
665
|
+
publicInput.incomingMessagesHash.assertEquals(
|
|
666
|
+
proof1.publicInput.incomingMessagesHash,
|
|
667
|
+
errors.propertyNotMatchingStep(
|
|
668
|
+
"IncomingMessagesHash",
|
|
669
|
+
"publicInput.from -> proof1.from"
|
|
670
|
+
)
|
|
671
|
+
);
|
|
672
|
+
proof1.publicOutput.incomingMessagesHash.assertEquals(
|
|
673
|
+
proof2.publicInput.incomingMessagesHash,
|
|
674
|
+
errors.propertyNotMatchingStep(
|
|
675
|
+
"IncomingMessagesHash",
|
|
676
|
+
"proof1.to -> proof2.from"
|
|
677
|
+
)
|
|
678
|
+
);
|
|
679
|
+
|
|
680
|
+
// Assert closed indicator matches
|
|
681
|
+
// (i.e. we can only merge TX-Type and Block-Type with each other)
|
|
682
|
+
proof1.publicOutput.closed.assertEquals(
|
|
683
|
+
proof2.publicOutput.closed,
|
|
684
|
+
"Closed indicators not matching"
|
|
685
|
+
);
|
|
686
|
+
|
|
687
|
+
// Either
|
|
688
|
+
// blockNumbers are unset and proofs are unclosed or
|
|
689
|
+
// both blocks are closed, then they have to increment or
|
|
690
|
+
// one block is closed, then height has to be the same
|
|
691
|
+
|
|
692
|
+
// Imperative algo would look like
|
|
693
|
+
// if(proof1.height == MAX && proof2.height == MAX){
|
|
694
|
+
// assert !proof1.closed && !proof2.closed;
|
|
695
|
+
// }else if(proof1.closed && proof2.closed){
|
|
696
|
+
// assert proof1.height + 1 == proof2.height
|
|
697
|
+
// // next one is omitted for now
|
|
698
|
+
// }else if(proof1.closed || proof2.closed{
|
|
699
|
+
// assert proof1.height == proof2.height
|
|
700
|
+
// }
|
|
701
|
+
|
|
702
|
+
const proof1Height = proof1.publicOutput.blockNumber;
|
|
703
|
+
const proof1Closed = proof1.publicOutput.closed;
|
|
704
|
+
const proof2Height = proof2.publicOutput.blockNumber;
|
|
705
|
+
const proof2Closed = proof2.publicOutput.closed;
|
|
706
|
+
|
|
707
|
+
const isValidTransactionMerge = proof1Height
|
|
708
|
+
.equals(maxField())
|
|
709
|
+
.and(proof2Height.equals(proof1Height))
|
|
710
|
+
.and(proof1Closed.or(proof2Closed).not());
|
|
711
|
+
|
|
712
|
+
const isValidClosedMerge = proof1Closed
|
|
713
|
+
.and(proof2Closed)
|
|
714
|
+
.and(proof1Height.add(1).equals(proof2Height));
|
|
715
|
+
|
|
716
|
+
isValidTransactionMerge
|
|
717
|
+
.or(isValidClosedMerge)
|
|
718
|
+
.assertTrue("Invalid BlockProof merge");
|
|
719
|
+
|
|
409
720
|
return new BlockProverPublicOutput({
|
|
410
721
|
stateRoot: proof2.publicOutput.stateRoot,
|
|
411
722
|
transactionsHash: proof2.publicOutput.transactionsHash,
|
|
412
723
|
networkStateHash: proof2.publicOutput.networkStateHash,
|
|
724
|
+
blockHashRoot: proof2.publicOutput.blockHashRoot,
|
|
725
|
+
eternalTransactionsHash: proof2.publicOutput.eternalTransactionsHash,
|
|
726
|
+
incomingMessagesHash: proof2.publicOutput.incomingMessagesHash,
|
|
727
|
+
// Provable.if(isValidClosedMerge, Bool(true), Bool(false));
|
|
728
|
+
closed: isValidClosedMerge,
|
|
729
|
+
blockNumber: proof2Height,
|
|
413
730
|
});
|
|
414
731
|
}
|
|
415
732
|
|
|
@@ -495,10 +812,7 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
495
812
|
* then be merged to be committed to the base-layer contract
|
|
496
813
|
*/
|
|
497
814
|
@injectable()
|
|
498
|
-
export class BlockProver
|
|
499
|
-
extends ProtocolModule
|
|
500
|
-
implements BlockProvable
|
|
501
|
-
{
|
|
815
|
+
export class BlockProver extends ProtocolModule implements BlockProvable {
|
|
502
816
|
public zkProgrammable: BlockProverProgrammable;
|
|
503
817
|
|
|
504
818
|
public constructor(
|
|
@@ -524,14 +838,6 @@ export class BlockProver
|
|
|
524
838
|
);
|
|
525
839
|
}
|
|
526
840
|
|
|
527
|
-
public merge(
|
|
528
|
-
publicInput: BlockProverPublicInput,
|
|
529
|
-
proof1: BlockProverProof,
|
|
530
|
-
proof2: BlockProverProof
|
|
531
|
-
): BlockProverPublicOutput {
|
|
532
|
-
return this.zkProgrammable.merge(publicInput, proof1, proof2);
|
|
533
|
-
}
|
|
534
|
-
|
|
535
841
|
public proveTransaction(
|
|
536
842
|
publicInput: BlockProverPublicInput,
|
|
537
843
|
stateProof: StateTransitionProof,
|
|
@@ -545,4 +851,28 @@ export class BlockProver
|
|
|
545
851
|
executionData
|
|
546
852
|
);
|
|
547
853
|
}
|
|
854
|
+
|
|
855
|
+
public proveBlock(
|
|
856
|
+
publicInput: BlockProverPublicInput,
|
|
857
|
+
networkState: NetworkState,
|
|
858
|
+
blockWitness: BlockHashMerkleTreeWitness,
|
|
859
|
+
stateTransitionProof: StateTransitionProof,
|
|
860
|
+
transactionProof: BlockProverProof
|
|
861
|
+
): BlockProverPublicOutput {
|
|
862
|
+
return this.zkProgrammable.proveBlock(
|
|
863
|
+
publicInput,
|
|
864
|
+
networkState,
|
|
865
|
+
blockWitness,
|
|
866
|
+
stateTransitionProof,
|
|
867
|
+
transactionProof
|
|
868
|
+
);
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
public merge(
|
|
872
|
+
publicInput: BlockProverPublicInput,
|
|
873
|
+
proof1: BlockProverProof,
|
|
874
|
+
proof2: BlockProverProof
|
|
875
|
+
): BlockProverPublicOutput {
|
|
876
|
+
return this.zkProgrammable.merge(publicInput, proof1, proof2);
|
|
877
|
+
}
|
|
548
878
|
}
|