@proto-kit/protocol 0.1.1-develop.1316 → 0.1.1-develop.1343
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/hooks/AccountStateHook.d.ts +3 -3
- package/dist/hooks/AccountStateHook.d.ts.map +1 -1
- package/dist/hooks/AccountStateHook.js +6 -2
- package/dist/hooks/AccountStateHook.js.map +1 -1
- package/dist/hooks/LastStateRootBlockHook.d.ts +3 -4
- package/dist/hooks/LastStateRootBlockHook.d.ts.map +1 -1
- package/dist/hooks/LastStateRootBlockHook.js +4 -4
- package/dist/hooks/LastStateRootBlockHook.js.map +1 -1
- package/dist/hooks/NoopBlockHook.d.ts +3 -4
- package/dist/hooks/NoopBlockHook.d.ts.map +1 -1
- package/dist/hooks/NoopBlockHook.js +1 -1
- package/dist/hooks/NoopBlockHook.js.map +1 -1
- package/dist/hooks/NoopTransactionHook.d.ts +2 -2
- package/dist/hooks/NoopTransactionHook.d.ts.map +1 -1
- package/dist/hooks/NoopTransactionHook.js +4 -1
- package/dist/hooks/NoopTransactionHook.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/model/AppliedStateTransitionBatch.d.ts +114 -0
- package/dist/model/AppliedStateTransitionBatch.d.ts.map +1 -0
- package/dist/model/AppliedStateTransitionBatch.js +16 -0
- package/dist/model/AppliedStateTransitionBatch.js.map +1 -0
- package/dist/model/StateTransition.d.ts +1 -0
- package/dist/model/StateTransition.d.ts.map +1 -1
- package/dist/model/StateTransition.js +5 -0
- package/dist/model/StateTransition.js.map +1 -1
- package/dist/model/StateTransitionProvableBatch.d.ts +249 -97
- package/dist/model/StateTransitionProvableBatch.d.ts.map +1 -1
- package/dist/model/StateTransitionProvableBatch.js +72 -65
- package/dist/model/StateTransitionProvableBatch.js.map +1 -1
- package/dist/model/transaction/RuntimeTransaction.d.ts +1 -0
- package/dist/model/transaction/RuntimeTransaction.d.ts.map +1 -1
- package/dist/model/transaction/RuntimeTransaction.js +3 -0
- package/dist/model/transaction/RuntimeTransaction.js.map +1 -1
- package/dist/protocol/ProvableBlockHook.d.ts +13 -3
- package/dist/protocol/ProvableBlockHook.d.ts.map +1 -1
- package/dist/protocol/ProvableBlockHook.js +16 -0
- package/dist/protocol/ProvableBlockHook.js.map +1 -1
- package/dist/protocol/ProvableTransactionHook.d.ts +29 -2
- package/dist/protocol/ProvableTransactionHook.d.ts.map +1 -1
- package/dist/protocol/ProvableTransactionHook.js +9 -0
- package/dist/protocol/ProvableTransactionHook.js.map +1 -1
- package/dist/prover/accumulators/AppliedBatchHashList.d.ts +18 -0
- package/dist/prover/accumulators/AppliedBatchHashList.d.ts.map +1 -0
- package/dist/prover/accumulators/AppliedBatchHashList.js +25 -0
- package/dist/prover/accumulators/AppliedBatchHashList.js.map +1 -0
- package/dist/{utils → prover/accumulators}/StateTransitionReductionList.d.ts +3 -2
- package/dist/prover/accumulators/StateTransitionReductionList.d.ts.map +1 -0
- package/dist/{utils → prover/accumulators}/StateTransitionReductionList.js +6 -3
- package/dist/prover/accumulators/StateTransitionReductionList.js.map +1 -0
- package/dist/prover/accumulators/TransactionHashList.d.ts +6 -0
- package/dist/prover/accumulators/TransactionHashList.d.ts.map +1 -0
- package/dist/prover/accumulators/TransactionHashList.js +8 -0
- package/dist/prover/accumulators/TransactionHashList.js.map +1 -0
- package/dist/prover/accumulators/WitnessedRootHashList.d.ts +137 -0
- package/dist/prover/accumulators/WitnessedRootHashList.d.ts.map +1 -0
- package/dist/prover/accumulators/WitnessedRootHashList.js +50 -0
- package/dist/prover/accumulators/WitnessedRootHashList.js.map +1 -0
- package/dist/prover/block/BlockProvable.d.ts +579 -35
- package/dist/prover/block/BlockProvable.d.ts.map +1 -1
- package/dist/prover/block/BlockProvable.js +55 -3
- package/dist/prover/block/BlockProvable.js.map +1 -1
- package/dist/prover/block/BlockProver.d.ts +52 -50
- package/dist/prover/block/BlockProver.d.ts.map +1 -1
- package/dist/prover/block/BlockProver.js +289 -209
- package/dist/prover/block/BlockProver.js.map +1 -1
- package/dist/prover/block/accummulators/BlockHashMerkleTree.d.ts +55 -13
- package/dist/prover/block/accummulators/BlockHashMerkleTree.d.ts.map +1 -1
- package/dist/prover/block/accummulators/BlockHashMerkleTree.js +11 -3
- package/dist/prover/block/accummulators/BlockHashMerkleTree.js.map +1 -1
- package/dist/prover/statetransition/StateTransitionProvable.d.ts +107 -106
- package/dist/prover/statetransition/StateTransitionProvable.d.ts.map +1 -1
- package/dist/prover/statetransition/StateTransitionProvable.js +8 -8
- package/dist/prover/statetransition/StateTransitionProvable.js.map +1 -1
- package/dist/prover/statetransition/StateTransitionProver.d.ts +14 -11
- package/dist/prover/statetransition/StateTransitionProver.d.ts.map +1 -1
- package/dist/prover/statetransition/StateTransitionProver.js +116 -62
- package/dist/prover/statetransition/StateTransitionProver.js.map +1 -1
- package/dist/settlement/contracts/DispatchContractProtocolModule.d.ts +1 -1
- package/dist/settlement/contracts/DispatchSmartContract.d.ts +1 -1
- package/dist/settlement/contracts/SettlementSmartContract.d.ts.map +1 -1
- package/dist/settlement/contracts/SettlementSmartContract.js +1 -0
- package/dist/settlement/contracts/SettlementSmartContract.js.map +1 -1
- package/dist/state/assert/assert.d.ts.map +1 -1
- package/dist/state/assert/assert.js +5 -3
- package/dist/state/assert/assert.js.map +1 -1
- package/dist/state/context/RuntimeMethodExecutionContext.d.ts +3 -3
- package/dist/state/context/RuntimeMethodExecutionContext.d.ts.map +1 -1
- package/dist/state/context/RuntimeMethodExecutionContext.js +7 -4
- package/dist/state/context/RuntimeMethodExecutionContext.js.map +1 -1
- package/dist/utils/FieldOptions.d.ts +62 -0
- package/dist/utils/FieldOptions.d.ts.map +1 -0
- package/dist/utils/FieldOptions.js +13 -0
- package/dist/utils/FieldOptions.js.map +1 -0
- package/dist/utils/ProvableHashList.d.ts +21 -2
- package/dist/utils/ProvableHashList.d.ts.map +1 -1
- package/dist/utils/ProvableHashList.js +37 -2
- package/dist/utils/ProvableHashList.js.map +1 -1
- package/dist/utils/ProvableReductionHashList.d.ts +7 -3
- package/dist/utils/ProvableReductionHashList.d.ts.map +1 -1
- package/dist/utils/ProvableReductionHashList.js +8 -5
- package/dist/utils/ProvableReductionHashList.js.map +1 -1
- package/dist/utils/utils.d.ts +10 -1
- package/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +6 -0
- package/dist/utils/utils.js.map +1 -1
- package/package.json +2 -2
- package/src/hooks/AccountStateHook.ts +12 -3
- package/src/hooks/LastStateRootBlockHook.ts +7 -8
- package/src/hooks/NoopBlockHook.ts +7 -4
- package/src/hooks/NoopTransactionHook.ts +5 -2
- package/src/index.ts +6 -1
- package/src/model/AppliedStateTransitionBatch.ts +16 -0
- package/src/model/StateTransition.ts +6 -0
- package/src/model/StateTransitionProvableBatch.ts +94 -105
- package/src/model/transaction/RuntimeTransaction.ts +4 -0
- package/src/protocol/ProvableBlockHook.ts +51 -3
- package/src/protocol/ProvableTransactionHook.ts +67 -3
- package/src/prover/accumulators/AppliedBatchHashList.ts +32 -0
- package/src/{utils → prover/accumulators}/StateTransitionReductionList.ts +7 -4
- package/src/prover/accumulators/TransactionHashList.ts +9 -0
- package/src/prover/accumulators/WitnessedRootHashList.ts +61 -0
- package/src/prover/block/BlockProvable.ts +128 -9
- package/src/prover/block/BlockProver.ts +531 -383
- package/src/prover/block/accummulators/BlockHashMerkleTree.ts +11 -3
- package/src/prover/statetransition/StateTransitionProvable.ts +17 -11
- package/src/prover/statetransition/StateTransitionProver.ts +219 -144
- package/src/settlement/contracts/SettlementSmartContract.ts +4 -0
- package/src/state/assert/assert.ts +6 -3
- package/src/state/context/RuntimeMethodExecutionContext.ts +15 -7
- package/src/utils/FieldOptions.ts +13 -0
- package/src/utils/ProvableHashList.ts +77 -2
- package/src/utils/ProvableReductionHashList.ts +12 -3
- package/src/utils/utils.ts +18 -1
- package/test/BlockProver.test.ts +2 -0
- package/test/TestingProtocol.ts +5 -0
- package/test/model/StateTransitionProvableBatch.test.ts +137 -0
- package/test/prover/block/BlockProver.test.ts +18 -0
- package/test/prover/statetransition/StateTransitionProver.test.ts +240 -0
- package/test/utils/ProvableHashList.test.ts +44 -0
- package/test/utils/ProvableReductionHashList.test.ts +1 -1
- package/dist/utils/StateTransitionReductionList.d.ts.map +0 -1
- package/dist/utils/StateTransitionReductionList.js.map +0 -1
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Bool,
|
|
3
|
-
DynamicProof,
|
|
4
3
|
Field,
|
|
5
|
-
Poseidon,
|
|
6
4
|
Proof,
|
|
7
5
|
Provable,
|
|
8
6
|
SelfProof,
|
|
@@ -15,6 +13,7 @@ import {
|
|
|
15
13
|
CompilableModule,
|
|
16
14
|
CompileArtifact,
|
|
17
15
|
CompileRegistry,
|
|
16
|
+
log,
|
|
18
17
|
MAX_FIELD,
|
|
19
18
|
PlainZkProgram,
|
|
20
19
|
provableMethod,
|
|
@@ -22,7 +21,6 @@ import {
|
|
|
22
21
|
ZkProgrammable,
|
|
23
22
|
} from "@proto-kit/common";
|
|
24
23
|
|
|
25
|
-
import { DefaultProvableHashList } from "../../utils/ProvableHashList";
|
|
26
24
|
import { MethodPublicOutput } from "../../model/MethodPublicOutput";
|
|
27
25
|
import { ProtocolModule } from "../../protocol/ProtocolModule";
|
|
28
26
|
import {
|
|
@@ -36,24 +34,43 @@ import {
|
|
|
36
34
|
ProvableStateTransition,
|
|
37
35
|
StateTransition,
|
|
38
36
|
} from "../../model/StateTransition";
|
|
39
|
-
import {
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
import {
|
|
38
|
+
AfterTransactionHookArguments,
|
|
39
|
+
BeforeTransactionHookArguments,
|
|
40
|
+
ProvableTransactionHook,
|
|
41
|
+
toProvableHookBlockState,
|
|
42
|
+
} from "../../protocol/ProvableTransactionHook";
|
|
43
|
+
import {
|
|
44
|
+
RuntimeMethodExecutionContext,
|
|
45
|
+
RuntimeMethodExecutionData,
|
|
46
|
+
} from "../../state/context/RuntimeMethodExecutionContext";
|
|
47
|
+
import {
|
|
48
|
+
AfterBlockHookArguments,
|
|
49
|
+
BeforeBlockHookArguments,
|
|
50
|
+
ProvableBlockHook,
|
|
51
|
+
toAfterTransactionHookArgument,
|
|
52
|
+
toBeforeTransactionHookArgument,
|
|
53
|
+
} from "../../protocol/ProvableBlockHook";
|
|
42
54
|
import { NetworkState } from "../../model/network/NetworkState";
|
|
43
55
|
import { SignedTransaction } from "../../model/transaction/SignedTransaction";
|
|
44
|
-
import {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
} from "
|
|
48
|
-
import {
|
|
56
|
+
import { MinaActions } from "../../utils/MinaPrefixedProvableHashList";
|
|
57
|
+
import { StateTransitionReductionList } from "../accumulators/StateTransitionReductionList";
|
|
58
|
+
import { assertEqualsIf } from "../../utils/utils";
|
|
59
|
+
import { WitnessedRootWitness } from "../accumulators/WitnessedRootHashList";
|
|
60
|
+
import { StateServiceProvider } from "../../state/StateServiceProvider";
|
|
61
|
+
import { AppliedStateTransitionBatch } from "../../model/AppliedStateTransitionBatch";
|
|
49
62
|
|
|
50
63
|
import {
|
|
51
64
|
BlockProvable,
|
|
52
|
-
BlockProverExecutionData,
|
|
53
65
|
BlockProverProof,
|
|
54
66
|
BlockProverPublicInput,
|
|
55
67
|
BlockProverPublicOutput,
|
|
56
68
|
DynamicRuntimeProof,
|
|
69
|
+
BlockProverMultiTransactionExecutionData,
|
|
70
|
+
BlockProverTransactionArguments,
|
|
71
|
+
BlockProverSingleTransactionExecutionData,
|
|
72
|
+
BlockProverState,
|
|
73
|
+
BlockProverStateCommitments,
|
|
57
74
|
} from "./BlockProvable";
|
|
58
75
|
import {
|
|
59
76
|
BlockHashMerkleTreeWitness,
|
|
@@ -67,12 +84,6 @@ import {
|
|
|
67
84
|
import { RuntimeVerificationKeyRootService } from "./services/RuntimeVerificationKeyRootService";
|
|
68
85
|
|
|
69
86
|
const errors = {
|
|
70
|
-
stateProofNotStartingAtZero: () =>
|
|
71
|
-
"StateProof not starting ST-commitment at zero",
|
|
72
|
-
|
|
73
|
-
stateTransitionsHashNotEqual: () =>
|
|
74
|
-
"StateTransition list commitments are not equal",
|
|
75
|
-
|
|
76
87
|
propertyNotMatchingStep: (propertyName: string, step: string) =>
|
|
77
88
|
`${propertyName} not matching: ${step}`,
|
|
78
89
|
|
|
@@ -89,48 +100,14 @@ const errors = {
|
|
|
89
100
|
|
|
90
101
|
invalidZkProgramTreeRoot: () =>
|
|
91
102
|
"Root hash of the provided zkProgram config witness is invalid",
|
|
92
|
-
|
|
93
|
-
invalidZkProgramConfigMethodId: () =>
|
|
94
|
-
"Method id of the provided zkProgram config does not match the executed transaction method id",
|
|
95
103
|
};
|
|
96
104
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
*/
|
|
102
|
-
stateRoot: Field;
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* The current commitment of the transaction-list which
|
|
106
|
-
* will at the end equal the bundle hash
|
|
107
|
-
*/
|
|
108
|
-
transactionsHash: Field;
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* The network state which gives access to values such as blockHeight
|
|
112
|
-
* This value is the same for the whole batch (L2 block)
|
|
113
|
-
*/
|
|
114
|
-
networkStateHash: Field;
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* The root of the merkle tree encoding all block hashes,
|
|
118
|
-
* see `BlockHashMerkleTree`
|
|
119
|
-
*/
|
|
120
|
-
blockHashRoot: Field;
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* A variant of the transactionsHash that is never reset.
|
|
124
|
-
* Thought for usage in the sequence state mempool.
|
|
125
|
-
* In comparison, transactionsHash restarts at 0 for every new block
|
|
126
|
-
*/
|
|
127
|
-
eternalTransactionsHash: Field;
|
|
128
|
-
|
|
129
|
-
incomingMessagesHash: Field;
|
|
130
|
-
}
|
|
105
|
+
type ApplyTransactionArguments = Omit<
|
|
106
|
+
BlockProverTransactionArguments,
|
|
107
|
+
"verificationKeyAttestation"
|
|
108
|
+
>;
|
|
131
109
|
|
|
132
110
|
export type BlockProof = Proof<BlockProverPublicInput, BlockProverPublicOutput>;
|
|
133
|
-
export type RuntimeProof = Proof<void, MethodPublicOutput>;
|
|
134
111
|
|
|
135
112
|
export class BlockProverProgrammable extends ZkProgrammable<
|
|
136
113
|
BlockProverPublicInput,
|
|
@@ -142,9 +119,9 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
142
119
|
StateTransitionProverPublicInput,
|
|
143
120
|
StateTransitionProverPublicOutput
|
|
144
121
|
>,
|
|
145
|
-
public readonly runtime: ZkProgrammable<undefined, MethodPublicOutput>,
|
|
146
122
|
private readonly transactionHooks: ProvableTransactionHook<unknown>[],
|
|
147
123
|
private readonly blockHooks: ProvableBlockHook<unknown>[],
|
|
124
|
+
private readonly stateServiceProvider: StateServiceProvider,
|
|
148
125
|
private readonly verificationKeyService: MinimalVKTreeService
|
|
149
126
|
) {
|
|
150
127
|
super();
|
|
@@ -158,78 +135,80 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
158
135
|
|
|
159
136
|
/**
|
|
160
137
|
* Applies and checks the two proofs and applies the corresponding state
|
|
161
|
-
* changes to the given state
|
|
138
|
+
* changes to the given state.
|
|
139
|
+
*
|
|
140
|
+
* The rough high level workflow of this function:
|
|
141
|
+
* 1. Execute beforeTransaction hooks, pushing the ST batch
|
|
142
|
+
* 2. Add Transaction to bundle, meaning appending it to all the respective commitments
|
|
143
|
+
* 3. Push the runtime ST batch
|
|
144
|
+
* 4. Execute afterTransaction hooks, pushing the ST batch
|
|
145
|
+
* 5. Some consistency checks and signature verification
|
|
162
146
|
*
|
|
163
|
-
* @param
|
|
164
|
-
* @param
|
|
165
|
-
* @param runtimeProof
|
|
147
|
+
* @param fromState The from-state of the BlockProver
|
|
148
|
+
* @param runtimeOutput
|
|
166
149
|
* @param executionData
|
|
167
|
-
* @param
|
|
150
|
+
* @param networkState
|
|
168
151
|
* @returns The new BlockProver-state to be used as public output
|
|
169
152
|
*/
|
|
170
153
|
public async applyTransaction(
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
>,
|
|
176
|
-
runtimeProof: DynamicRuntimeProof,
|
|
177
|
-
executionData: BlockProverExecutionData,
|
|
178
|
-
verificationKey: VerificationKey
|
|
154
|
+
fromState: BlockProverState,
|
|
155
|
+
runtimeOutput: MethodPublicOutput,
|
|
156
|
+
executionData: ApplyTransactionArguments,
|
|
157
|
+
networkState: NetworkState
|
|
179
158
|
): Promise<BlockProverState> {
|
|
180
|
-
const { transaction,
|
|
159
|
+
const { transaction, signature } = executionData;
|
|
181
160
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
runtimeProof.verify(verificationKey);
|
|
185
|
-
stateTransitionProof.verify();
|
|
161
|
+
let state = { ...fromState };
|
|
186
162
|
|
|
187
|
-
const
|
|
163
|
+
const { isMessage } = runtimeOutput;
|
|
188
164
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
);
|
|
194
|
-
stateTransitionProof.publicInput.protocolTransitionsHash.assertEquals(
|
|
195
|
-
Field(0),
|
|
196
|
-
errors.stateProofNotStartingAtZero()
|
|
165
|
+
const beforeTxHookArguments = toBeforeTransactionHookArgument(
|
|
166
|
+
executionData,
|
|
167
|
+
networkState,
|
|
168
|
+
state
|
|
197
169
|
);
|
|
198
170
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
171
|
+
// Apply beforeTransaction hook state transitions
|
|
172
|
+
const beforeBatch = await this.executeTransactionHooks(
|
|
173
|
+
async (module, args) => await module.beforeTransaction(args),
|
|
174
|
+
beforeTxHookArguments
|
|
202
175
|
);
|
|
203
176
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
);
|
|
209
|
-
state.stateRoot.assertEquals(
|
|
210
|
-
stateTransitionProof.publicInput.protocolStateRoot,
|
|
211
|
-
errors.propertyNotMatching("from protocol state root")
|
|
177
|
+
state = this.addTransactionToBundle(
|
|
178
|
+
state,
|
|
179
|
+
runtimeOutput.isMessage,
|
|
180
|
+
transaction
|
|
212
181
|
);
|
|
213
182
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
183
|
+
state.pendingSTBatches.push(beforeBatch);
|
|
184
|
+
|
|
185
|
+
state.pendingSTBatches.push({
|
|
186
|
+
batchHash: runtimeOutput.stateTransitionsHash,
|
|
187
|
+
applied: runtimeOutput.status,
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
// Apply afterTransaction hook state transitions
|
|
191
|
+
const afterTxHookArguments = toAfterTransactionHookArgument(
|
|
217
192
|
executionData,
|
|
218
|
-
|
|
193
|
+
networkState,
|
|
194
|
+
state,
|
|
195
|
+
runtimeOutput
|
|
219
196
|
);
|
|
220
197
|
|
|
221
|
-
//
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
198
|
+
// Switch to different state set for afterTx hooks
|
|
199
|
+
this.stateServiceProvider.popCurrentStateService();
|
|
200
|
+
|
|
201
|
+
const afterBatch = await this.executeTransactionHooks(
|
|
202
|
+
async (module, args) => await module.afterTransaction(args),
|
|
203
|
+
afterTxHookArguments
|
|
226
204
|
);
|
|
205
|
+
state.pendingSTBatches.push(afterBatch);
|
|
227
206
|
|
|
228
207
|
// Check transaction integrity against appProof
|
|
229
208
|
const blockTransactionHash = transaction.hash();
|
|
230
209
|
|
|
231
210
|
blockTransactionHash.assertEquals(
|
|
232
|
-
|
|
211
|
+
runtimeOutput.transactionHash,
|
|
233
212
|
"Transactions provided in AppProof and BlockProof do not match"
|
|
234
213
|
);
|
|
235
214
|
|
|
@@ -246,236 +225,333 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
246
225
|
transaction.assertTransactionType(isMessage);
|
|
247
226
|
|
|
248
227
|
// Check network state integrity against appProof
|
|
249
|
-
state.
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
"Network state provided to BlockProver does not match the publicInput"
|
|
256
|
-
);
|
|
228
|
+
state.networkState
|
|
229
|
+
.hash()
|
|
230
|
+
.assertEquals(
|
|
231
|
+
runtimeOutput.networkStateHash,
|
|
232
|
+
"Network state does not match state used in AppProof"
|
|
233
|
+
);
|
|
257
234
|
|
|
258
|
-
return
|
|
235
|
+
return state;
|
|
259
236
|
}
|
|
260
237
|
|
|
261
238
|
// eslint-disable-next-line max-len
|
|
262
239
|
// TODO How does this interact with the RuntimeMethodExecutionContext when executing runtimemethods?
|
|
263
240
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
241
|
+
/**
|
|
242
|
+
* Constructs a AppliedBatch based on a list of STs and the flag whether to
|
|
243
|
+
* be applied or not. The AppliedBatch is a condensed commitment to a batch
|
|
244
|
+
* of STs.
|
|
245
|
+
*/
|
|
246
|
+
private constructBatch(
|
|
247
|
+
stateTransitions: StateTransition<any>[],
|
|
248
|
+
applied: Bool
|
|
271
249
|
) {
|
|
272
|
-
const executionContext = container.resolve(RuntimeMethodExecutionContext);
|
|
273
|
-
executionContext.clear();
|
|
274
|
-
|
|
275
|
-
// Setup context for potential calls to runtime methods.
|
|
276
|
-
// This way they can use this.transaction etc. while still having provable
|
|
277
|
-
// integrity between data
|
|
278
|
-
executionContext.setup({
|
|
279
|
-
// That is why we should probably hide it from the transaction context inputs
|
|
280
|
-
transaction: executionData.transaction,
|
|
281
|
-
networkState: executionData.networkState,
|
|
282
|
-
});
|
|
283
|
-
executionContext.beforeMethod("", "", []);
|
|
284
|
-
|
|
285
|
-
for (const module of this.transactionHooks) {
|
|
286
|
-
// eslint-disable-next-line no-await-in-loop
|
|
287
|
-
await module.onTransaction(executionData);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
executionContext.afterMethod();
|
|
291
|
-
|
|
292
|
-
const { stateTransitions, status, statusMessage } =
|
|
293
|
-
executionContext.current().result;
|
|
294
|
-
|
|
295
|
-
status.assertTrue(statusMessage);
|
|
296
|
-
|
|
297
250
|
const transitions = stateTransitions.map((transition) =>
|
|
298
251
|
transition.toProvable()
|
|
299
252
|
);
|
|
300
253
|
|
|
301
|
-
const hashList = new StateTransitionReductionList(
|
|
302
|
-
ProvableStateTransition,
|
|
303
|
-
stateTransitionProof.publicInput.protocolTransitionsHash
|
|
304
|
-
);
|
|
305
|
-
|
|
254
|
+
const hashList = new StateTransitionReductionList(ProvableStateTransition);
|
|
306
255
|
transitions.forEach((transition) => {
|
|
307
256
|
hashList.push(transition);
|
|
308
257
|
});
|
|
309
258
|
|
|
310
|
-
|
|
311
|
-
hashList.commitment,
|
|
312
|
-
|
|
313
|
-
);
|
|
259
|
+
return new AppliedStateTransitionBatch({
|
|
260
|
+
batchHash: hashList.commitment,
|
|
261
|
+
applied,
|
|
262
|
+
});
|
|
314
263
|
}
|
|
315
264
|
|
|
316
|
-
private async
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
265
|
+
private async executeTransactionHooks<
|
|
266
|
+
T extends BeforeTransactionHookArguments | AfterTransactionHookArguments,
|
|
267
|
+
>(
|
|
268
|
+
hook: (module: ProvableTransactionHook<unknown>, args: T) => Promise<void>,
|
|
269
|
+
hookArguments: T
|
|
270
|
+
) {
|
|
271
|
+
const { batch } = await this.executeHooks(hookArguments, async () => {
|
|
272
|
+
for (const module of this.transactionHooks) {
|
|
273
|
+
// eslint-disable-next-line no-await-in-loop
|
|
274
|
+
await hook(module, hookArguments);
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
return batch;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
private async executeHooks<T>(
|
|
281
|
+
contextArguments: RuntimeMethodExecutionData,
|
|
282
|
+
method: () => Promise<T>
|
|
283
|
+
) {
|
|
324
284
|
const executionContext = container.resolve(RuntimeMethodExecutionContext);
|
|
325
285
|
executionContext.clear();
|
|
286
|
+
|
|
287
|
+
// Setup context for potential calls to runtime methods.
|
|
288
|
+
// This way they can use this.transaction etc. while still having provable
|
|
289
|
+
// integrity between data
|
|
290
|
+
executionContext.setup(contextArguments);
|
|
326
291
|
executionContext.beforeMethod("", "", []);
|
|
327
292
|
|
|
328
|
-
const
|
|
329
|
-
Promise<NetworkState>
|
|
330
|
-
>(async (networkStatePromise, blockHook) => {
|
|
331
|
-
const networkState = await networkStatePromise;
|
|
332
|
-
// Setup context for potential calls to runtime methods.
|
|
333
|
-
// With the special case that we set the new networkstate for every hook
|
|
334
|
-
// We also have to put in a dummy transaction for network.transaction
|
|
335
|
-
executionContext.setup({
|
|
336
|
-
transaction: RuntimeTransaction.dummyTransaction(),
|
|
337
|
-
networkState,
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
if (type === "beforeBlock") {
|
|
341
|
-
return await blockHook.beforeBlock(networkState, state);
|
|
342
|
-
}
|
|
343
|
-
if (type === "afterBlock") {
|
|
344
|
-
return await blockHook.afterBlock(networkState, state);
|
|
345
|
-
}
|
|
346
|
-
throw new Error("Unreachable");
|
|
347
|
-
}, Promise.resolve(inputNetworkState));
|
|
293
|
+
const result = await method();
|
|
348
294
|
|
|
349
295
|
executionContext.afterMethod();
|
|
350
296
|
|
|
351
297
|
const { stateTransitions, status, statusMessage } =
|
|
352
298
|
executionContext.current().result;
|
|
353
299
|
|
|
354
|
-
status.assertTrue(`
|
|
300
|
+
status.assertTrue(`Transaction hook call failed: ${statusMessage ?? "-"}`);
|
|
355
301
|
|
|
356
302
|
return {
|
|
357
|
-
|
|
358
|
-
|
|
303
|
+
batch: this.constructBatch(stateTransitions, Bool(true)),
|
|
304
|
+
result,
|
|
359
305
|
};
|
|
360
306
|
}
|
|
361
307
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
308
|
+
public async executeBlockHooks<
|
|
309
|
+
T extends BeforeBlockHookArguments | AfterBlockHookArguments,
|
|
310
|
+
>(
|
|
311
|
+
hook: (
|
|
312
|
+
module: ProvableBlockHook<unknown>,
|
|
313
|
+
networkState: NetworkState,
|
|
314
|
+
args: T
|
|
315
|
+
) => Promise<NetworkState>,
|
|
316
|
+
hookArguments: T,
|
|
317
|
+
inputNetworkState: NetworkState
|
|
318
|
+
) {
|
|
319
|
+
const transaction = RuntimeTransaction.dummyTransaction();
|
|
320
|
+
const startingInputs = {
|
|
321
|
+
transaction,
|
|
322
|
+
networkState: inputNetworkState,
|
|
369
323
|
};
|
|
370
324
|
|
|
325
|
+
return await this.executeHooks(startingInputs, async () => {
|
|
326
|
+
const executionContext = container.resolve(RuntimeMethodExecutionContext);
|
|
327
|
+
|
|
328
|
+
return await this.blockHooks.reduce<Promise<NetworkState>>(
|
|
329
|
+
async (networkStatePromise, blockHook) => {
|
|
330
|
+
const networkState = await networkStatePromise;
|
|
331
|
+
|
|
332
|
+
// Setup context for potential calls to runtime methods.
|
|
333
|
+
// With the special case that we set the new networkstate for every hook
|
|
334
|
+
// We also have to put in a dummy transaction for network.transaction
|
|
335
|
+
executionContext.setup({
|
|
336
|
+
transaction: RuntimeTransaction.dummyTransaction(),
|
|
337
|
+
networkState,
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
return await hook(blockHook, networkState, hookArguments);
|
|
341
|
+
},
|
|
342
|
+
Promise.resolve(inputNetworkState)
|
|
343
|
+
);
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
public addTransactionToBundle<
|
|
348
|
+
T extends Pick<
|
|
349
|
+
BlockProverState,
|
|
350
|
+
"transactionList" | "eternalTransactionsList" | "incomingMessages"
|
|
351
|
+
>,
|
|
352
|
+
>(state: T, isMessage: Bool, transaction: RuntimeTransaction): T {
|
|
371
353
|
const transactionHash = transaction.hash();
|
|
372
354
|
|
|
373
355
|
// Append tx to transaction list
|
|
374
|
-
|
|
375
|
-
Field,
|
|
376
|
-
state.transactionsHash
|
|
377
|
-
);
|
|
378
|
-
|
|
379
|
-
transactionList.pushIf(transactionHash, isMessage.not());
|
|
380
|
-
stateTo.transactionsHash = transactionList.commitment;
|
|
356
|
+
state.transactionList.pushIf(transactionHash, isMessage.not());
|
|
381
357
|
|
|
382
358
|
// Append tx to eternal transaction list
|
|
383
359
|
// TODO Change that to the a sequence-state compatible transaction struct
|
|
384
|
-
|
|
385
|
-
Field,
|
|
386
|
-
state.eternalTransactionsHash
|
|
387
|
-
);
|
|
388
|
-
|
|
389
|
-
eternalTransactionList.pushIf(transactionHash, isMessage.not());
|
|
390
|
-
stateTo.eternalTransactionsHash = eternalTransactionList.commitment;
|
|
360
|
+
state.eternalTransactionsList.pushIf(transactionHash, isMessage.not());
|
|
391
361
|
|
|
392
362
|
// Append tx to incomingMessagesHash
|
|
393
363
|
const actionHash = MinaActions.actionHash(transaction.hashData());
|
|
394
364
|
|
|
395
|
-
|
|
396
|
-
state.incomingMessagesHash
|
|
397
|
-
);
|
|
398
|
-
incomingMessagesList.pushIf(actionHash, isMessage);
|
|
365
|
+
state.incomingMessages.pushIf(actionHash, isMessage);
|
|
399
366
|
|
|
400
|
-
|
|
367
|
+
return state;
|
|
368
|
+
}
|
|
401
369
|
|
|
402
|
-
|
|
370
|
+
private verifyVerificationKeyAttestation(
|
|
371
|
+
attestation: RuntimeVerificationKeyAttestation,
|
|
372
|
+
methodId: Field
|
|
373
|
+
): VerificationKey {
|
|
374
|
+
// Verify the [methodId, vk] tuple against the baked-in vk tree root
|
|
375
|
+
const { verificationKey, witness: verificationKeyTreeWitness } =
|
|
376
|
+
attestation;
|
|
377
|
+
|
|
378
|
+
const root = Field(this.verificationKeyService.getRoot());
|
|
379
|
+
const calculatedRoot = verificationKeyTreeWitness.calculateRoot(
|
|
380
|
+
new MethodVKConfigData({
|
|
381
|
+
methodId: methodId,
|
|
382
|
+
vkHash: verificationKey.hash,
|
|
383
|
+
}).hash()
|
|
384
|
+
);
|
|
385
|
+
root.assertEquals(calculatedRoot, errors.invalidZkProgramTreeRoot());
|
|
386
|
+
|
|
387
|
+
return verificationKey;
|
|
403
388
|
}
|
|
404
389
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
publicInput: BlockProverPublicInput,
|
|
408
|
-
stateProof: StateTransitionProof,
|
|
390
|
+
public async proveTransactionInternal(
|
|
391
|
+
fromState: BlockProverState,
|
|
409
392
|
runtimeProof: DynamicRuntimeProof,
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
393
|
+
{ transaction, networkState }: BlockProverSingleTransactionExecutionData
|
|
394
|
+
): Promise<BlockProverState> {
|
|
395
|
+
const verificationKey = this.verifyVerificationKeyAttestation(
|
|
396
|
+
transaction.verificationKeyAttestation,
|
|
397
|
+
transaction.transaction.methodId
|
|
398
|
+
);
|
|
416
399
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
400
|
+
runtimeProof.verify(verificationKey);
|
|
401
|
+
|
|
402
|
+
return await this.applyTransaction(
|
|
403
|
+
fromState,
|
|
404
|
+
runtimeProof.publicOutput,
|
|
405
|
+
transaction,
|
|
406
|
+
networkState
|
|
420
407
|
);
|
|
408
|
+
}
|
|
421
409
|
|
|
410
|
+
private staticChecks(publicInput: BlockProverPublicInput) {
|
|
422
411
|
publicInput.blockNumber.assertEquals(
|
|
423
412
|
MAX_FIELD,
|
|
424
413
|
"blockNumber has to be MAX for transaction proofs"
|
|
425
414
|
);
|
|
415
|
+
}
|
|
426
416
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
}).hash()
|
|
417
|
+
@provableMethod()
|
|
418
|
+
public async proveTransaction(
|
|
419
|
+
publicInput: BlockProverPublicInput,
|
|
420
|
+
runtimeProof: DynamicRuntimeProof,
|
|
421
|
+
executionData: BlockProverSingleTransactionExecutionData
|
|
422
|
+
): Promise<BlockProverPublicOutput> {
|
|
423
|
+
const state = BlockProverStateCommitments.toBlockProverState(
|
|
424
|
+
publicInput,
|
|
425
|
+
executionData.networkState
|
|
437
426
|
);
|
|
438
|
-
root.assertEquals(calculatedRoot, errors.invalidZkProgramTreeRoot());
|
|
439
427
|
|
|
440
|
-
|
|
428
|
+
this.staticChecks(publicInput);
|
|
429
|
+
|
|
430
|
+
const stateTo = await this.proveTransactionInternal(
|
|
441
431
|
state,
|
|
442
|
-
runtimeProof
|
|
443
|
-
executionData
|
|
432
|
+
runtimeProof,
|
|
433
|
+
executionData
|
|
444
434
|
);
|
|
445
435
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
436
|
+
return new BlockProverPublicOutput({
|
|
437
|
+
...BlockProverStateCommitments.fromBlockProverState(stateTo),
|
|
438
|
+
closed: Bool(false),
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
@provableMethod()
|
|
443
|
+
public async proveTransactions(
|
|
444
|
+
publicInput: BlockProverPublicInput,
|
|
445
|
+
runtimeProof1: DynamicRuntimeProof,
|
|
446
|
+
runtimeProof2: DynamicRuntimeProof,
|
|
447
|
+
executionData: BlockProverMultiTransactionExecutionData
|
|
448
|
+
): Promise<BlockProverPublicOutput> {
|
|
449
|
+
const state = BlockProverStateCommitments.toBlockProverState(
|
|
450
|
+
publicInput,
|
|
451
|
+
executionData.networkState
|
|
452
452
|
);
|
|
453
453
|
|
|
454
|
+
this.staticChecks(publicInput);
|
|
455
|
+
|
|
456
|
+
const state1 = await this.proveTransactionInternal(state, runtimeProof1, {
|
|
457
|
+
transaction: executionData.transaction1,
|
|
458
|
+
networkState: executionData.networkState,
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
// Switch to next state record for 2nd tx beforeTx hook
|
|
462
|
+
// TODO Can be prevented by merging 1st afterTx + 2nd beforeTx
|
|
463
|
+
this.stateServiceProvider.popCurrentStateService();
|
|
464
|
+
|
|
465
|
+
const stateTo = await this.proveTransactionInternal(state1, runtimeProof2, {
|
|
466
|
+
transaction: executionData.transaction2,
|
|
467
|
+
networkState: executionData.networkState,
|
|
468
|
+
});
|
|
469
|
+
|
|
454
470
|
return new BlockProverPublicOutput({
|
|
455
|
-
...stateTo,
|
|
456
|
-
blockNumber: publicInput.blockNumber,
|
|
471
|
+
...BlockProverStateCommitments.fromBlockProverState(stateTo),
|
|
457
472
|
closed: Bool(false),
|
|
458
473
|
});
|
|
459
474
|
}
|
|
460
475
|
|
|
461
|
-
|
|
476
|
+
public includeSTProof(
|
|
462
477
|
stateTransitionProof: StateTransitionProof,
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
478
|
+
apply: Bool,
|
|
479
|
+
stateRoot: Field,
|
|
480
|
+
pendingSTBatchesHash: Field,
|
|
481
|
+
witnessedRootsHash: Field
|
|
482
|
+
): {
|
|
483
|
+
stateRoot: Field;
|
|
484
|
+
pendingSTBatchesHash: Field;
|
|
485
|
+
witnessedRootsHash: Field;
|
|
486
|
+
} {
|
|
487
|
+
assertEqualsIf(
|
|
488
|
+
stateTransitionProof.publicInput.currentBatchStateHash,
|
|
466
489
|
Field(0),
|
|
467
|
-
|
|
490
|
+
apply,
|
|
491
|
+
"State for STProof has to be empty at the start"
|
|
468
492
|
);
|
|
469
|
-
|
|
493
|
+
assertEqualsIf(
|
|
494
|
+
stateTransitionProof.publicOutput.currentBatchStateHash,
|
|
470
495
|
Field(0),
|
|
471
|
-
|
|
496
|
+
apply,
|
|
497
|
+
"State for STProof has to be empty at the end"
|
|
498
|
+
);
|
|
499
|
+
|
|
500
|
+
assertEqualsIf(
|
|
501
|
+
stateTransitionProof.publicInput.batchesHash,
|
|
502
|
+
Field(0),
|
|
503
|
+
apply,
|
|
504
|
+
"Batcheshash doesn't start at 0"
|
|
472
505
|
);
|
|
473
506
|
|
|
474
507
|
// Assert from state roots
|
|
475
|
-
|
|
476
|
-
|
|
508
|
+
assertEqualsIf(
|
|
509
|
+
stateRoot,
|
|
510
|
+
stateTransitionProof.publicInput.root,
|
|
511
|
+
apply,
|
|
512
|
+
errors.propertyNotMatching("from state root")
|
|
513
|
+
);
|
|
514
|
+
// Assert the stBatchesHash executed is the same
|
|
515
|
+
assertEqualsIf(
|
|
516
|
+
pendingSTBatchesHash,
|
|
517
|
+
stateTransitionProof.publicOutput.batchesHash,
|
|
518
|
+
apply,
|
|
519
|
+
"Pending STBatches are not the same that have been executed by the ST proof"
|
|
520
|
+
);
|
|
521
|
+
|
|
522
|
+
// Assert root Accumulator
|
|
523
|
+
assertEqualsIf(
|
|
524
|
+
Field(0),
|
|
525
|
+
stateTransitionProof.publicInput.witnessedRootsHash,
|
|
526
|
+
apply,
|
|
477
527
|
errors.propertyNotMatching("from state root")
|
|
478
528
|
);
|
|
529
|
+
// Assert the witnessedRootsHash created is the same
|
|
530
|
+
assertEqualsIf(
|
|
531
|
+
witnessedRootsHash,
|
|
532
|
+
stateTransitionProof.publicOutput.witnessedRootsHash,
|
|
533
|
+
apply,
|
|
534
|
+
"Root accumulator Commitment is not the same that have been executed by the ST proof"
|
|
535
|
+
);
|
|
536
|
+
|
|
537
|
+
// update root only if we didn't defer
|
|
538
|
+
const newRoot = Provable.if(
|
|
539
|
+
apply,
|
|
540
|
+
stateTransitionProof.publicOutput.root,
|
|
541
|
+
stateRoot
|
|
542
|
+
);
|
|
543
|
+
// Reset only if we didn't defer
|
|
544
|
+
const newBatchesHash = Provable.if(apply, Field(0), pendingSTBatchesHash);
|
|
545
|
+
const newWitnessedRootsHash = Provable.if(
|
|
546
|
+
apply,
|
|
547
|
+
Field(0),
|
|
548
|
+
witnessedRootsHash
|
|
549
|
+
);
|
|
550
|
+
return {
|
|
551
|
+
stateRoot: newRoot,
|
|
552
|
+
pendingSTBatchesHash: newBatchesHash,
|
|
553
|
+
witnessedRootsHash: newWitnessedRootsHash,
|
|
554
|
+
};
|
|
479
555
|
}
|
|
480
556
|
|
|
481
557
|
@provableMethod()
|
|
@@ -483,27 +559,18 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
483
559
|
publicInput: BlockProverPublicInput,
|
|
484
560
|
networkState: NetworkState,
|
|
485
561
|
blockWitness: BlockHashMerkleTreeWitness,
|
|
486
|
-
|
|
562
|
+
stateTransitionProof: StateTransitionProof,
|
|
563
|
+
deferSTProof: Bool,
|
|
564
|
+
afterBlockRootWitness: WitnessedRootWitness,
|
|
487
565
|
transactionProof: BlockProverProof
|
|
488
566
|
): Promise<BlockProverPublicOutput> {
|
|
489
|
-
const state: BlockProverState = {
|
|
490
|
-
...publicInput,
|
|
491
|
-
};
|
|
492
|
-
|
|
493
567
|
// 1. Make assertions about the inputs
|
|
494
568
|
publicInput.transactionsHash.assertEquals(
|
|
495
569
|
Field(0),
|
|
496
570
|
"Transactionshash has to start at 0"
|
|
497
571
|
);
|
|
498
|
-
publicInput.networkStateHash.assertEquals(
|
|
499
|
-
networkState.hash(),
|
|
500
|
-
"Wrong NetworkState supplied"
|
|
501
|
-
);
|
|
502
572
|
|
|
503
|
-
|
|
504
|
-
Field(0),
|
|
505
|
-
"TransactionProof transactionshash has to start at 0"
|
|
506
|
-
);
|
|
573
|
+
// TransactionProof format checks
|
|
507
574
|
transactionProof.publicInput.blockHashRoot.assertEquals(
|
|
508
575
|
Field(0),
|
|
509
576
|
"TransactionProof cannot carry the blockHashRoot - publicInput"
|
|
@@ -516,25 +583,11 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
516
583
|
transactionProof.publicOutput.networkStateHash,
|
|
517
584
|
"TransactionProof cannot alter the network state"
|
|
518
585
|
);
|
|
519
|
-
transactionProof.publicInput.eternalTransactionsHash.assertEquals(
|
|
520
|
-
state.eternalTransactionsHash,
|
|
521
|
-
"TransactionProof starting eternalTransactionHash not matching"
|
|
522
|
-
);
|
|
523
|
-
transactionProof.publicInput.incomingMessagesHash.assertEquals(
|
|
524
|
-
state.incomingMessagesHash,
|
|
525
|
-
"TransactionProof starting incomingMessagesHash not matching"
|
|
526
|
-
);
|
|
527
586
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
// .equals(0)
|
|
533
|
-
// .and(stateTransitionProof.publicOutput.protocolTransitionsHash.equals(0))
|
|
534
|
-
// .not();
|
|
535
|
-
// Provable.log("VerifyIf 1", stsEmitted);
|
|
536
|
-
// stateTransitionProof.verifyIf(Bool(false));
|
|
537
|
-
// stateTransitionProof.verifyIf(stsEmitted);
|
|
587
|
+
const state = BlockProverStateCommitments.toBlockProverState(
|
|
588
|
+
publicInput,
|
|
589
|
+
networkState
|
|
590
|
+
);
|
|
538
591
|
|
|
539
592
|
// Verify Transaction proof if it has at least 1 tx - i.e. the
|
|
540
593
|
// input and output doesn't match fully
|
|
@@ -545,87 +598,75 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
545
598
|
transactionProof.publicInput,
|
|
546
599
|
txProofOutput.closed
|
|
547
600
|
);
|
|
548
|
-
|
|
549
|
-
|
|
601
|
+
const skipTransactionProofVerification = isEmptyTransition;
|
|
602
|
+
const verifyTransactionProof = isEmptyTransition.not();
|
|
603
|
+
log.provable.debug("VerifyIf TxProof", verifyTransactionProof);
|
|
604
|
+
transactionProof.verifyIf(verifyTransactionProof);
|
|
550
605
|
|
|
551
606
|
// 2. Execute beforeBlock hooks
|
|
607
|
+
const beforeBlockArgs = toProvableHookBlockState(state);
|
|
552
608
|
const beforeBlockResult = await this.executeBlockHooks(
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
609
|
+
async (module, networkStateArg, args) =>
|
|
610
|
+
await module.beforeBlock(networkStateArg, args),
|
|
611
|
+
beforeBlockArgs,
|
|
612
|
+
networkState
|
|
556
613
|
);
|
|
557
614
|
|
|
558
|
-
|
|
559
|
-
// ProvableStateTransition
|
|
560
|
-
// );
|
|
561
|
-
// beforeBlockResult.stateTransitions.forEach((st) => {
|
|
562
|
-
// beforeBlockHashList.push(st.toProvable());
|
|
563
|
-
// });
|
|
564
|
-
|
|
565
|
-
// We are reusing protocolSTs here as beforeBlock STs
|
|
566
|
-
// TODO Not possible atm bcs we can't have a seperation between protocol/runtime state roots,
|
|
567
|
-
// which we would for both before and after to be able to emit STs
|
|
568
|
-
|
|
569
|
-
// stateTransitionProof.publicInput.protocolTransitionsHash.assertEquals(
|
|
570
|
-
// beforeBlockHashList.commitment
|
|
571
|
-
// );
|
|
572
|
-
// state.stateRoot = stateTransitionProof.publicInput.protocolStateRoot;
|
|
573
|
-
|
|
574
|
-
// TODO Only for now
|
|
575
|
-
// beforeBlockHashList.commitment.assertEquals(
|
|
576
|
-
// Field(0),
|
|
577
|
-
// "beforeBlock() cannot emit state transitions yet"
|
|
578
|
-
// );
|
|
615
|
+
state.pendingSTBatches.push(beforeBlockResult.batch);
|
|
579
616
|
|
|
580
617
|
// 4. Apply TX-type BlockProof
|
|
581
|
-
transactionProof.publicInput.networkStateHash
|
|
582
|
-
beforeBlockResult.
|
|
583
|
-
|
|
584
|
-
|
|
618
|
+
transactionProof.publicInput.networkStateHash
|
|
619
|
+
.equals(beforeBlockResult.result.hash())
|
|
620
|
+
.or(skipTransactionProofVerification)
|
|
621
|
+
.assertTrue(
|
|
622
|
+
"TransactionProof networkstate hash not matching beforeBlock hook result"
|
|
623
|
+
);
|
|
585
624
|
transactionProof.publicInput.stateRoot.assertEquals(
|
|
586
|
-
|
|
587
|
-
"
|
|
625
|
+
transactionProof.publicOutput.stateRoot,
|
|
626
|
+
"TransactionProofs can't change the state root"
|
|
588
627
|
);
|
|
589
628
|
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
state.incomingMessagesHash =
|
|
595
|
-
transactionProof.publicOutput.incomingMessagesHash;
|
|
596
|
-
|
|
597
|
-
// 5. Execute afterBlock hooks
|
|
598
|
-
// this.assertSTProofInput(stateTransitionProof, state.stateRoot);
|
|
599
|
-
|
|
600
|
-
const afterBlockResult = await this.executeBlockHooks(
|
|
601
|
-
state,
|
|
602
|
-
beforeBlockResult.networkState,
|
|
603
|
-
"afterBlock"
|
|
629
|
+
// Check that the transaction proof's STs start after the beforeBlock hook
|
|
630
|
+
transactionProof.publicInput.pendingSTBatchesHash.assertEquals(
|
|
631
|
+
state.pendingSTBatches.commitment,
|
|
632
|
+
"Transaction proof doesn't start their STs after the beforeBlockHook"
|
|
604
633
|
);
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
634
|
+
// Fast-forward the stBatchHashList to after all transactions appended
|
|
635
|
+
state.pendingSTBatches.commitment =
|
|
636
|
+
transactionProof.publicOutput.pendingSTBatchesHash;
|
|
637
|
+
|
|
638
|
+
// Fast-forward block content commitments by the results of the aggregated transaction proof
|
|
639
|
+
// Implicitly, the 'from' values here are asserted against the publicInput, since the hashlists
|
|
640
|
+
// are created out of the public input
|
|
641
|
+
state.transactionList.fastForward({
|
|
642
|
+
from: transactionProof.publicInput.transactionsHash,
|
|
643
|
+
to: transactionProof.publicOutput.transactionsHash,
|
|
644
|
+
});
|
|
645
|
+
state.eternalTransactionsList.fastForward({
|
|
646
|
+
from: transactionProof.publicInput.eternalTransactionsHash,
|
|
647
|
+
to: transactionProof.publicOutput.eternalTransactionsHash,
|
|
648
|
+
});
|
|
649
|
+
state.incomingMessages.fastForward({
|
|
650
|
+
from: transactionProof.publicInput.incomingMessagesHash,
|
|
651
|
+
to: transactionProof.publicOutput.incomingMessagesHash,
|
|
611
652
|
});
|
|
612
653
|
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
// "STProof from-ST-hash not matching generated ST-hash from afterBlock hooks"
|
|
619
|
-
// );
|
|
620
|
-
// state.stateRoot = Provable.if(
|
|
621
|
-
// stsEmitted,
|
|
622
|
-
// stateTransitionProof.publicOutput.stateRoot,
|
|
623
|
-
// state.stateRoot
|
|
624
|
-
// );
|
|
654
|
+
// Witness root
|
|
655
|
+
const isEmpty = state.pendingSTBatches.commitment.equals(0);
|
|
656
|
+
isEmpty
|
|
657
|
+
.implies(state.stateRoot.equals(afterBlockRootWitness.witnessedRoot))
|
|
658
|
+
.assertTrue();
|
|
625
659
|
|
|
626
|
-
|
|
660
|
+
state.witnessedRoots.witnessRoot(
|
|
661
|
+
{
|
|
662
|
+
appliedBatchListState: state.pendingSTBatches.commitment,
|
|
663
|
+
root: afterBlockRootWitness.witnessedRoot,
|
|
664
|
+
},
|
|
665
|
+
afterBlockRootWitness.preimage,
|
|
666
|
+
isEmpty.not()
|
|
667
|
+
);
|
|
627
668
|
|
|
628
|
-
// Calculate the new block
|
|
669
|
+
// 5. Calculate the new block tree hash
|
|
629
670
|
const blockIndex = blockWitness.calculateIndex();
|
|
630
671
|
|
|
631
672
|
blockIndex.assertEquals(publicInput.blockNumber);
|
|
@@ -639,15 +680,60 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
639
680
|
|
|
640
681
|
state.blockHashRoot = blockWitness.calculateRoot(
|
|
641
682
|
new BlockHashTreeEntry({
|
|
642
|
-
|
|
643
|
-
|
|
683
|
+
block: {
|
|
684
|
+
index: blockIndex,
|
|
685
|
+
transactionListHash: state.transactionList.commitment,
|
|
686
|
+
},
|
|
644
687
|
closed: Bool(true),
|
|
645
688
|
}).hash()
|
|
646
689
|
);
|
|
647
690
|
|
|
691
|
+
// 6. Execute afterBlock hooks
|
|
692
|
+
|
|
693
|
+
// Switch state service to afterBlock one
|
|
694
|
+
this.stateServiceProvider.popCurrentStateService();
|
|
695
|
+
|
|
696
|
+
const afterBlockHookArgs = toProvableHookBlockState(state);
|
|
697
|
+
const afterBlockResult = await this.executeBlockHooks(
|
|
698
|
+
async (module, networkStateArg, args) =>
|
|
699
|
+
await module.afterBlock(networkStateArg, args),
|
|
700
|
+
{
|
|
701
|
+
...afterBlockHookArgs,
|
|
702
|
+
stateRoot: afterBlockRootWitness.witnessedRoot,
|
|
703
|
+
},
|
|
704
|
+
beforeBlockResult.result
|
|
705
|
+
);
|
|
706
|
+
|
|
707
|
+
state.pendingSTBatches.push(afterBlockResult.batch);
|
|
708
|
+
|
|
709
|
+
state.networkState = afterBlockResult.result;
|
|
710
|
+
|
|
711
|
+
// 7. Close block
|
|
712
|
+
|
|
713
|
+
// Verify ST Proof only if STs have been emitted,
|
|
714
|
+
// and we don't defer the verification of the STs
|
|
715
|
+
// otherwise we can input a dummy proof
|
|
716
|
+
const batchesEmpty = state.pendingSTBatches.commitment.equals(Field(0));
|
|
717
|
+
const verifyStProof = deferSTProof.not().and(batchesEmpty.not());
|
|
718
|
+
log.provable.debug("Verify STProof", verifyStProof);
|
|
719
|
+
stateTransitionProof.verifyIf(verifyStProof);
|
|
720
|
+
|
|
721
|
+
// Apply STProof if not deferred
|
|
722
|
+
const stateProofResult = this.includeSTProof(
|
|
723
|
+
stateTransitionProof,
|
|
724
|
+
verifyStProof,
|
|
725
|
+
state.stateRoot,
|
|
726
|
+
state.pendingSTBatches.commitment,
|
|
727
|
+
state.witnessedRoots.commitment
|
|
728
|
+
);
|
|
729
|
+
state.stateRoot = stateProofResult.stateRoot;
|
|
730
|
+
state.pendingSTBatches.commitment = stateProofResult.pendingSTBatchesHash;
|
|
731
|
+
state.witnessedRoots.commitment = stateProofResult.witnessedRootsHash;
|
|
732
|
+
|
|
733
|
+
state.blockNumber = blockIndex.add(1);
|
|
734
|
+
|
|
648
735
|
return new BlockProverPublicOutput({
|
|
649
|
-
...state,
|
|
650
|
-
blockNumber: blockIndex.add(1),
|
|
736
|
+
...BlockProverStateCommitments.fromBlockProverState(state),
|
|
651
737
|
closed: Bool(true),
|
|
652
738
|
});
|
|
653
739
|
}
|
|
@@ -732,6 +818,26 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
732
818
|
)
|
|
733
819
|
);
|
|
734
820
|
|
|
821
|
+
// Check pendingSTBatchesHash
|
|
822
|
+
publicInput.pendingSTBatchesHash.assertEquals(
|
|
823
|
+
proof1.publicInput.pendingSTBatchesHash,
|
|
824
|
+
errors.transactionsHashNotMatching("publicInput.from -> proof1.from")
|
|
825
|
+
);
|
|
826
|
+
proof1.publicOutput.pendingSTBatchesHash.assertEquals(
|
|
827
|
+
proof2.publicInput.pendingSTBatchesHash,
|
|
828
|
+
errors.transactionsHashNotMatching("proof1.to -> proof2.from")
|
|
829
|
+
);
|
|
830
|
+
|
|
831
|
+
// Check witnessedRootsHash
|
|
832
|
+
publicInput.witnessedRootsHash.assertEquals(
|
|
833
|
+
proof1.publicInput.witnessedRootsHash,
|
|
834
|
+
errors.transactionsHashNotMatching("publicInput.from -> proof1.from")
|
|
835
|
+
);
|
|
836
|
+
proof1.publicOutput.witnessedRootsHash.assertEquals(
|
|
837
|
+
proof2.publicInput.witnessedRootsHash,
|
|
838
|
+
errors.transactionsHashNotMatching("proof1.to -> proof2.from")
|
|
839
|
+
);
|
|
840
|
+
|
|
735
841
|
// Assert closed indicator matches
|
|
736
842
|
// (i.e. we can only merge TX-Type and Block-Type with each other)
|
|
737
843
|
proof1.publicOutput.closed.assertEquals(
|
|
@@ -787,6 +893,8 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
787
893
|
incomingMessagesHash: proof2.publicOutput.incomingMessagesHash,
|
|
788
894
|
closed: isValidClosedMerge,
|
|
789
895
|
blockNumber: proof2.publicOutput.blockNumber,
|
|
896
|
+
pendingSTBatchesHash: proof2.publicOutput.pendingSTBatchesHash,
|
|
897
|
+
witnessedRootsHash: proof2.publicOutput.witnessedRootsHash,
|
|
790
898
|
});
|
|
791
899
|
}
|
|
792
900
|
|
|
@@ -802,6 +910,7 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
802
910
|
const { prover, stateTransitionProver } = this;
|
|
803
911
|
const StateTransitionProofClass = stateTransitionProver.zkProgram[0].Proof;
|
|
804
912
|
const proveTransaction = prover.proveTransaction.bind(prover);
|
|
913
|
+
const proveTransactions = prover.proveTransactions.bind(prover);
|
|
805
914
|
const proveBlock = prover.proveBlock.bind(prover);
|
|
806
915
|
const merge = prover.merge.bind(prover);
|
|
807
916
|
|
|
@@ -813,25 +922,41 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
813
922
|
methods: {
|
|
814
923
|
proveTransaction: {
|
|
815
924
|
privateInputs: [
|
|
816
|
-
StateTransitionProofClass,
|
|
817
925
|
DynamicRuntimeProof,
|
|
818
|
-
|
|
819
|
-
RuntimeVerificationKeyAttestation,
|
|
926
|
+
BlockProverSingleTransactionExecutionData,
|
|
820
927
|
],
|
|
821
928
|
|
|
822
929
|
async method(
|
|
823
930
|
publicInput: BlockProverPublicInput,
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
executionData: BlockProverExecutionData,
|
|
827
|
-
verificationKeyAttestation: RuntimeVerificationKeyAttestation
|
|
931
|
+
runtimeProof: DynamicRuntimeProof,
|
|
932
|
+
executionData: BlockProverSingleTransactionExecutionData
|
|
828
933
|
) {
|
|
829
934
|
return await proveTransaction(
|
|
830
935
|
publicInput,
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
936
|
+
runtimeProof,
|
|
937
|
+
executionData
|
|
938
|
+
);
|
|
939
|
+
},
|
|
940
|
+
},
|
|
941
|
+
|
|
942
|
+
proveTransactions: {
|
|
943
|
+
privateInputs: [
|
|
944
|
+
DynamicRuntimeProof,
|
|
945
|
+
DynamicRuntimeProof,
|
|
946
|
+
BlockProverMultiTransactionExecutionData,
|
|
947
|
+
],
|
|
948
|
+
|
|
949
|
+
async method(
|
|
950
|
+
publicInput: BlockProverPublicInput,
|
|
951
|
+
runtimeProof1: DynamicRuntimeProof,
|
|
952
|
+
runtimeProof2: DynamicRuntimeProof,
|
|
953
|
+
executionData: BlockProverMultiTransactionExecutionData
|
|
954
|
+
) {
|
|
955
|
+
return await proveTransactions(
|
|
956
|
+
publicInput,
|
|
957
|
+
runtimeProof1,
|
|
958
|
+
runtimeProof2,
|
|
959
|
+
executionData
|
|
835
960
|
);
|
|
836
961
|
},
|
|
837
962
|
},
|
|
@@ -840,21 +965,27 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
840
965
|
privateInputs: [
|
|
841
966
|
NetworkState,
|
|
842
967
|
BlockHashMerkleTreeWitness,
|
|
843
|
-
|
|
968
|
+
StateTransitionProofClass,
|
|
969
|
+
Bool,
|
|
970
|
+
WitnessedRootWitness,
|
|
844
971
|
SelfProof<BlockProverPublicInput, BlockProverPublicOutput>,
|
|
845
972
|
],
|
|
846
973
|
async method(
|
|
847
974
|
publicInput: BlockProverPublicInput,
|
|
848
975
|
networkState: NetworkState,
|
|
849
976
|
blockWitness: BlockHashMerkleTreeWitness,
|
|
850
|
-
|
|
977
|
+
stateTransitionProof: StateTransitionProof,
|
|
978
|
+
deferSTs: Bool,
|
|
979
|
+
afterBlockRootWitness: WitnessedRootWitness,
|
|
851
980
|
transactionProof: BlockProverProof
|
|
852
981
|
) {
|
|
853
982
|
return await proveBlock(
|
|
854
983
|
publicInput,
|
|
855
984
|
networkState,
|
|
856
985
|
blockWitness,
|
|
857
|
-
|
|
986
|
+
stateTransitionProof,
|
|
987
|
+
deferSTs,
|
|
988
|
+
afterBlockRootWitness,
|
|
858
989
|
transactionProof
|
|
859
990
|
);
|
|
860
991
|
},
|
|
@@ -879,6 +1010,7 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
879
1010
|
|
|
880
1011
|
const methods = {
|
|
881
1012
|
proveTransaction: program.proveTransaction,
|
|
1013
|
+
proveTransactions: program.proveTransactions,
|
|
882
1014
|
proveBlock: program.proveBlock,
|
|
883
1015
|
merge: program.merge,
|
|
884
1016
|
};
|
|
@@ -924,15 +1056,17 @@ export class BlockProver
|
|
|
924
1056
|
transactionHooks: ProvableTransactionHook<unknown>[],
|
|
925
1057
|
@injectAll("ProvableBlockHook")
|
|
926
1058
|
blockHooks: ProvableBlockHook<unknown>[],
|
|
1059
|
+
@inject("StateServiceProvider")
|
|
1060
|
+
stateServiceProvider: StateServiceProvider,
|
|
927
1061
|
verificationKeyService: RuntimeVerificationKeyRootService
|
|
928
1062
|
) {
|
|
929
1063
|
super();
|
|
930
1064
|
this.zkProgrammable = new BlockProverProgrammable(
|
|
931
1065
|
this,
|
|
932
1066
|
stateTransitionProver.zkProgrammable,
|
|
933
|
-
runtime.zkProgrammable,
|
|
934
1067
|
transactionHooks,
|
|
935
1068
|
blockHooks,
|
|
1069
|
+
stateServiceProvider,
|
|
936
1070
|
verificationKeyService
|
|
937
1071
|
);
|
|
938
1072
|
}
|
|
@@ -950,17 +1084,27 @@ export class BlockProver
|
|
|
950
1084
|
|
|
951
1085
|
public proveTransaction(
|
|
952
1086
|
publicInput: BlockProverPublicInput,
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
executionData: BlockProverExecutionData,
|
|
956
|
-
verificationKeyAttestation: RuntimeVerificationKeyAttestation
|
|
1087
|
+
runtimeProof: DynamicRuntimeProof,
|
|
1088
|
+
executionData: BlockProverSingleTransactionExecutionData
|
|
957
1089
|
): Promise<BlockProverPublicOutput> {
|
|
958
1090
|
return this.zkProgrammable.proveTransaction(
|
|
959
1091
|
publicInput,
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
1092
|
+
runtimeProof,
|
|
1093
|
+
executionData
|
|
1094
|
+
);
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
public proveTransactions(
|
|
1098
|
+
publicInput: BlockProverPublicInput,
|
|
1099
|
+
runtimeProof1: DynamicRuntimeProof,
|
|
1100
|
+
runtimeProof2: DynamicRuntimeProof,
|
|
1101
|
+
executionData: BlockProverMultiTransactionExecutionData
|
|
1102
|
+
): Promise<BlockProverPublicOutput> {
|
|
1103
|
+
return this.zkProgrammable.proveTransactions(
|
|
1104
|
+
publicInput,
|
|
1105
|
+
runtimeProof1,
|
|
1106
|
+
runtimeProof2,
|
|
1107
|
+
executionData
|
|
964
1108
|
);
|
|
965
1109
|
}
|
|
966
1110
|
|
|
@@ -968,14 +1112,18 @@ export class BlockProver
|
|
|
968
1112
|
publicInput: BlockProverPublicInput,
|
|
969
1113
|
networkState: NetworkState,
|
|
970
1114
|
blockWitness: BlockHashMerkleTreeWitness,
|
|
971
|
-
|
|
1115
|
+
stateTransitionProof: StateTransitionProof,
|
|
1116
|
+
deferSTs: Bool,
|
|
1117
|
+
afterBlockRootWitness: WitnessedRootWitness,
|
|
972
1118
|
transactionProof: BlockProverProof
|
|
973
1119
|
): Promise<BlockProverPublicOutput> {
|
|
974
1120
|
return this.zkProgrammable.proveBlock(
|
|
975
1121
|
publicInput,
|
|
976
1122
|
networkState,
|
|
977
1123
|
blockWitness,
|
|
978
|
-
|
|
1124
|
+
stateTransitionProof,
|
|
1125
|
+
deferSTs,
|
|
1126
|
+
afterBlockRootWitness,
|
|
979
1127
|
transactionProof
|
|
980
1128
|
);
|
|
981
1129
|
}
|