@proto-kit/protocol 0.1.1-develop.457 → 0.1.1-develop.651

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