@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
@@ -0,0 +1,329 @@
1
+ import { prefixToField, RollupMerkleTree, TypedClass } from "@proto-kit/common";
2
+ import {
3
+ AccountUpdate,
4
+ Bool,
5
+ Field,
6
+ method,
7
+ Mina,
8
+ Poseidon,
9
+ Proof,
10
+ Provable,
11
+ PublicKey,
12
+ Signature,
13
+ SmartContract,
14
+ State,
15
+ state,
16
+ TokenId,
17
+ UInt32,
18
+ UInt64,
19
+ } from "o1js";
20
+ import { NetworkState } from "../../model/network/NetworkState";
21
+ import { Path } from "../../model/Path";
22
+ import { BlockHashMerkleTree } from "../../prover/block/accummulators/BlockHashMerkleTree";
23
+ import {
24
+ BlockProverPublicInput,
25
+ BlockProverPublicOutput,
26
+ } from "../../prover/block/BlockProvable";
27
+ import {
28
+ OUTGOING_MESSAGE_BATCH_SIZE,
29
+ OutgoingMessageArgumentBatch,
30
+ } from "../messages/OutgoingMessageArgument";
31
+ import { Withdrawal } from "../messages/Withdrawal";
32
+ import {
33
+ ProvableSettlementHook,
34
+ SettlementHookInputs,
35
+ SettlementStateRecord,
36
+ } from "../modularity/ProvableSettlementHook";
37
+
38
+ import { DispatchContractType } from "./DispatchSmartContract";
39
+
40
+ export class LazyBlockProof extends Proof<
41
+ BlockProverPublicInput,
42
+ BlockProverPublicOutput
43
+ > {
44
+ public static publicInputType = BlockProverPublicInput;
45
+
46
+ public static publicOutputType = BlockProverPublicOutput;
47
+
48
+ public static tag: () => { name: string } = () => {
49
+ throw new Error("Tag not initialized yet");
50
+ };
51
+ }
52
+
53
+ export interface SettlementContractType {
54
+ initialize: (sequencer: PublicKey, dispatchContract: PublicKey) => void;
55
+ settle: (
56
+ blockProof: LazyBlockProof,
57
+ signature: Signature,
58
+ dispatchContractAddress: PublicKey,
59
+ publicKey: PublicKey,
60
+ inputNetworkState: NetworkState,
61
+ outputNetworkState: NetworkState,
62
+ newPromisedMessagesHash: Field
63
+ ) => void;
64
+ rollupOutgoingMessages: (batch: OutgoingMessageArgumentBatch) => void;
65
+ redeem: (additionUpdate: AccountUpdate) => void;
66
+ }
67
+
68
+ // Some random prefix for the sequencer signature
69
+ export const BATCH_SIGNATURE_PREFIX = prefixToField("pk-batchSignature");
70
+
71
+ export class SettlementSmartContract
72
+ extends SmartContract
73
+ implements SettlementContractType
74
+ {
75
+ // This pattern of injecting args into a smartcontract is currently the only
76
+ // viable solution that works given the inheritance issues of o1js
77
+ public static args: {
78
+ DispatchContract: TypedClass<DispatchContractType & SmartContract>;
79
+ hooks: ProvableSettlementHook<unknown>[];
80
+ withdrawalStatePath: [string, string];
81
+ escapeHatchSlotsInterval: number;
82
+ };
83
+
84
+ @state(Field) public sequencerKey = State<Field>();
85
+ @state(UInt32) public lastSettlementL1Block = State<UInt32>();
86
+
87
+ @state(Field) public stateRoot = State<Field>();
88
+ @state(Field) public networkStateHash = State<Field>();
89
+ @state(Field) public blockHashRoot = State<Field>();
90
+
91
+ @state(Field) public dispatchContractAddressX = State<Field>();
92
+
93
+ @state(Field) public outgoingMessageCursor = State<Field>();
94
+
95
+ @method
96
+ public initialize(sequencer: PublicKey, dispatchContract: PublicKey) {
97
+ this.sequencerKey.getAndAssertEquals().assertEquals(Field(0));
98
+ this.stateRoot.getAndAssertEquals().assertEquals(Field(0));
99
+ this.blockHashRoot.getAndAssertEquals().assertEquals(Field(0));
100
+ this.networkStateHash.getAndAssertEquals().assertEquals(Field(0));
101
+ this.dispatchContractAddressX.getAndAssertEquals().assertEquals(Field(0));
102
+
103
+ this.sequencerKey.set(sequencer.x);
104
+ this.stateRoot.set(Field(RollupMerkleTree.EMPTY_ROOT));
105
+ this.blockHashRoot.set(Field(BlockHashMerkleTree.EMPTY_ROOT));
106
+ this.networkStateHash.set(NetworkState.empty().hash());
107
+ this.dispatchContractAddressX.set(dispatchContract.x);
108
+
109
+ const DispatchContract = SettlementSmartContract.args.DispatchContract;
110
+ new DispatchContract(dispatchContract).initialize(this.address);
111
+ }
112
+
113
+ @method
114
+ public settle(
115
+ blockProof: LazyBlockProof,
116
+ signature: Signature,
117
+ dispatchContractAddress: PublicKey,
118
+ publicKey: PublicKey,
119
+ inputNetworkState: NetworkState,
120
+ outputNetworkState: NetworkState,
121
+ newPromisedMessagesHash: Field
122
+ ) {
123
+ // Verify the blockproof
124
+ blockProof.verify();
125
+
126
+ // Get and assert on-chain values
127
+ const stateRoot = this.stateRoot.getAndAssertEquals();
128
+ const networkStateHash = this.networkStateHash.getAndAssertEquals();
129
+ const blockHashRoot = this.blockHashRoot.getAndAssertEquals();
130
+ const sequencerKey = this.sequencerKey.getAndAssertEquals();
131
+ const lastSettlementL1Block =
132
+ this.lastSettlementL1Block.getAndAssertEquals();
133
+ const onChainDispatchContractAddressX =
134
+ this.dispatchContractAddressX.getAndAssertEquals();
135
+
136
+ onChainDispatchContractAddressX.assertEquals(
137
+ dispatchContractAddress.x,
138
+ "DispatchContract address not provided correctly"
139
+ );
140
+
141
+ const { DispatchContract, escapeHatchSlotsInterval, hooks } =
142
+ SettlementSmartContract.args;
143
+
144
+ // Get dispatch contract values
145
+ // These values are witnesses but will be checked later on the AU
146
+ // call to the dispatch contract via .updateMessagesHash()
147
+ const dispatchContract = new DispatchContract(dispatchContractAddress);
148
+ const promisedMessagesHash = dispatchContract.promisedMessagesHash.get();
149
+
150
+ // Get block height and use the lower bound for all ops
151
+ const minBlockIncluded = this.network.globalSlotSinceGenesis.get();
152
+ this.network.globalSlotSinceGenesis.assertBetween(
153
+ minBlockIncluded,
154
+ // 5 because that is the length the newPromisedMessagesHash will be valid
155
+ minBlockIncluded.add(4)
156
+ );
157
+
158
+ // Check signature/escape catch
159
+ publicKey.x.assertEquals(
160
+ sequencerKey,
161
+ "Sequencer public key witness not matching"
162
+ );
163
+ const signatureValid = signature.verify(publicKey, [
164
+ BATCH_SIGNATURE_PREFIX,
165
+ lastSettlementL1Block.value,
166
+ ]);
167
+ const escapeHatchActivated = lastSettlementL1Block
168
+ .add(UInt32.from(escapeHatchSlotsInterval))
169
+ .lessThan(minBlockIncluded);
170
+ signatureValid
171
+ .or(escapeHatchActivated)
172
+ .assertTrue(
173
+ "Sequencer signature not valid and escape hatch not activated"
174
+ );
175
+
176
+ // Assert correctness of networkState witness
177
+ Provable.log("Network State Hash ", networkStateHash);
178
+ Provable.log("input Hash ", inputNetworkState.hash());
179
+ Provable.log("equals ", inputNetworkState.hash().equals(networkStateHash));
180
+
181
+ inputNetworkState
182
+ .hash()
183
+ .assertEquals(networkStateHash, "InputNetworkState witness not valid");
184
+ outputNetworkState
185
+ .hash()
186
+ .assertEquals(
187
+ blockProof.publicOutput.networkStateHash,
188
+ "OutputNetworkState witness not valid"
189
+ );
190
+
191
+ blockProof.publicOutput.closed.assertEquals(
192
+ Bool(true),
193
+ "Supplied proof is not a closed BlockProof"
194
+ );
195
+
196
+ // Execute onSettlementHooks for additional checks
197
+ const stateRecord: SettlementStateRecord = {
198
+ blockHashRoot,
199
+ stateRoot,
200
+ networkStateHash,
201
+ lastSettlementL1Block,
202
+ sequencerKey: publicKey,
203
+ };
204
+ const inputs: SettlementHookInputs = {
205
+ blockProof,
206
+ contractState: stateRecord,
207
+ newPromisedMessagesHash,
208
+ fromNetworkState: inputNetworkState,
209
+ toNetworkState: outputNetworkState,
210
+ currentL1Block: minBlockIncluded,
211
+ };
212
+ hooks.forEach((hook) => {
213
+ hook.beforeSettlement(this, inputs);
214
+ });
215
+
216
+ // Apply blockProof
217
+ stateRoot.assertEquals(
218
+ blockProof.publicInput.stateRoot,
219
+ "Input state root not matching"
220
+ );
221
+ Provable.log("Network State Hash ", networkStateHash);
222
+ Provable.log("input Hash ", inputNetworkState.hash());
223
+ Provable.log("Proof Hash ", blockProof.publicInput.networkStateHash);
224
+
225
+ networkStateHash.assertEquals(
226
+ blockProof.publicInput.networkStateHash,
227
+ "Input networkStateHash not matching"
228
+ );
229
+ blockHashRoot.assertEquals(
230
+ blockProof.publicInput.blockHashRoot,
231
+ "Input blockHashRoot not matching"
232
+ );
233
+ this.stateRoot.set(blockProof.publicOutput.stateRoot);
234
+ this.networkStateHash.set(blockProof.publicOutput.networkStateHash);
235
+ this.blockHashRoot.set(blockProof.publicOutput.blockHashRoot);
236
+
237
+ // Assert and apply deposit commitments
238
+ promisedMessagesHash.assertEquals(
239
+ blockProof.publicOutput.incomingMessagesHash,
240
+ "Promised messages not honored"
241
+ );
242
+
243
+ // Call DispatchContract
244
+ // This call checks that the promisedMessagesHash, which is already proven
245
+ // to be the blockProofs publicoutput, is actually the current on-chain
246
+ // promisedMessageHash. It also checks the newPromisedMessagesHash to be
247
+ // a current sequencestate value
248
+ dispatchContract.updateMessagesHash(
249
+ promisedMessagesHash,
250
+ newPromisedMessagesHash
251
+ );
252
+
253
+ this.lastSettlementL1Block.set(minBlockIncluded);
254
+ }
255
+
256
+ @method
257
+ public rollupOutgoingMessages(batch: OutgoingMessageArgumentBatch) {
258
+ let counter = this.outgoingMessageCursor.getAndAssertEquals();
259
+ const stateRoot = this.stateRoot.getAndAssertEquals();
260
+
261
+ const [withdrawalModule, withdrawalStateName] =
262
+ SettlementSmartContract.args.withdrawalStatePath;
263
+ const mapPath = Path.fromProperty(withdrawalModule, withdrawalStateName);
264
+
265
+ let accountCreationFeePaid = Field(0);
266
+
267
+ for (let i = 0; i < OUTGOING_MESSAGE_BATCH_SIZE; i++) {
268
+ const args = batch.arguments[i];
269
+
270
+ // Check witness
271
+ const path = Path.fromKey(mapPath, Field, counter);
272
+
273
+ args.witness
274
+ .checkMembership(
275
+ stateRoot,
276
+ path,
277
+ Poseidon.hash(Withdrawal.toFields(args.value))
278
+ )
279
+ .assertTrue("Provided Withdrawal witness not valid");
280
+
281
+ // Process message
282
+ const { address, amount } = args.value;
283
+ const isDummy = address.equals(this.address);
284
+
285
+ const tokenAu = this.token.mint({ address, amount });
286
+ const isNewAccount = tokenAu.account.isNew.getAndAssertEquals();
287
+ tokenAu.body.balanceChange.magnitude =
288
+ tokenAu.body.balanceChange.magnitude.sub(
289
+ Provable.if(
290
+ isNewAccount,
291
+ Mina.accountCreationFee().toConstant(),
292
+ UInt64.zero
293
+ )
294
+ );
295
+
296
+ accountCreationFeePaid = accountCreationFeePaid.add(
297
+ Provable.if(isNewAccount, Field(1e9), Field(0))
298
+ );
299
+
300
+ counter = counter.add(Provable.if(isDummy, Field(0), Field(1)));
301
+ }
302
+
303
+ this.balance.subInPlace(UInt64.from(accountCreationFeePaid));
304
+
305
+ this.outgoingMessageCursor.set(counter);
306
+ }
307
+
308
+ @method
309
+ public redeem(additionUpdate: AccountUpdate) {
310
+ additionUpdate.body.tokenId.assertEquals(
311
+ TokenId.default,
312
+ "Tokenid not default token"
313
+ );
314
+ additionUpdate.body.balanceChange.sgn
315
+ .isPositive()
316
+ .assertTrue("Sign not correct");
317
+ const amount = additionUpdate.body.balanceChange.magnitude;
318
+
319
+ // Burn tokens
320
+ this.token.burn({
321
+ address: additionUpdate.publicKey,
322
+ amount,
323
+ });
324
+
325
+ // Send mina
326
+ this.approve(additionUpdate);
327
+ this.balance.subInPlace(amount);
328
+ }
329
+ }
@@ -0,0 +1,6 @@
1
+ import { PublicKey, Struct, UInt64 } from "o1js";
2
+
3
+ export class Deposit extends Struct({
4
+ address: PublicKey,
5
+ amount: UInt64,
6
+ }) {}
@@ -0,0 +1,41 @@
1
+ import { Bool, Provable, Struct } from "o1js";
2
+ import { RollupMerkleTreeWitness } from "@proto-kit/common";
3
+ import { Withdrawal } from "./Withdrawal";
4
+
5
+ export const OUTGOING_MESSAGE_BATCH_SIZE = 1;
6
+
7
+ export class OutgoingMessageArgument extends Struct({
8
+ witness: RollupMerkleTreeWitness,
9
+ value: Withdrawal,
10
+ }) {
11
+ public static dummy(): OutgoingMessageArgument {
12
+ return new OutgoingMessageArgument({
13
+ witness: RollupMerkleTreeWitness.dummy(),
14
+ value: Withdrawal.dummy(),
15
+ });
16
+ }
17
+ }
18
+
19
+ export class OutgoingMessageArgumentBatch extends Struct({
20
+ arguments: Provable.Array(
21
+ OutgoingMessageArgument,
22
+ OUTGOING_MESSAGE_BATCH_SIZE
23
+ ),
24
+
25
+ isDummys: Provable.Array(Bool, OUTGOING_MESSAGE_BATCH_SIZE),
26
+ }) {
27
+ public static fromMessages(providedArguments: OutgoingMessageArgument[]) {
28
+ const batch = providedArguments.slice();
29
+ const isDummys = batch.map(() => Bool(false));
30
+
31
+ while (batch.length < OUTGOING_MESSAGE_BATCH_SIZE) {
32
+ batch.push(OutgoingMessageArgument.dummy());
33
+ isDummys.push(Bool(true));
34
+ }
35
+
36
+ return new OutgoingMessageArgumentBatch({
37
+ arguments: batch,
38
+ isDummys,
39
+ });
40
+ }
41
+ }
@@ -0,0 +1,14 @@
1
+ import { PublicKey, Struct, UInt64 } from "o1js";
2
+ import { EMPTY_PUBLICKEY } from "@proto-kit/common";
3
+
4
+ export class Withdrawal extends Struct({
5
+ address: PublicKey,
6
+ amount: UInt64,
7
+ }) {
8
+ public static dummy() {
9
+ return new Withdrawal({
10
+ address: EMPTY_PUBLICKEY,
11
+ amount: UInt64.from(0),
12
+ });
13
+ }
14
+ }
@@ -0,0 +1,34 @@
1
+ import { Field, PublicKey, UInt32 } from "o1js";
2
+
3
+ import type { BlockProof } from "../../prover/block/BlockProver";
4
+ import { ProtocolModule } from "../../protocol/ProtocolModule";
5
+ import { NetworkState } from "../../model/network/NetworkState";
6
+
7
+ import type { SettlementSmartContract } from "../contracts/SettlementSmartContract";
8
+
9
+ export type SettlementStateRecord = {
10
+ sequencerKey: PublicKey;
11
+ lastSettlementL1Block: UInt32;
12
+
13
+ stateRoot: Field;
14
+ networkStateHash: Field;
15
+ blockHashRoot: Field;
16
+ };
17
+
18
+ export type SettlementHookInputs = {
19
+ blockProof: BlockProof;
20
+ fromNetworkState: NetworkState;
21
+ toNetworkState: NetworkState;
22
+ newPromisedMessagesHash: Field;
23
+ contractState: SettlementStateRecord;
24
+ currentL1Block: UInt32;
25
+ };
26
+
27
+ export abstract class ProvableSettlementHook<
28
+ Config
29
+ > extends ProtocolModule<Config> {
30
+ public abstract beforeSettlement(
31
+ smartContract: SettlementSmartContract,
32
+ inputs: SettlementHookInputs
33
+ ): void;
34
+ }
@@ -0,0 +1,39 @@
1
+ import { UInt64 } from "o1js";
2
+
3
+ import {
4
+ ProvableSettlementHook,
5
+ SettlementHookInputs,
6
+ } from "../modularity/ProvableSettlementHook";
7
+ import { SettlementSmartContract } from "../contracts/SettlementSmartContract";
8
+
9
+ type NetworkStateSettlementModuleConfig = {
10
+ blocksPerL1Block: UInt64;
11
+ };
12
+
13
+ export class NetworkStateSettlementModule extends ProvableSettlementHook<NetworkStateSettlementModuleConfig> {
14
+ public beforeSettlement(
15
+ smartContract: SettlementSmartContract,
16
+ {
17
+ blockProof,
18
+ fromNetworkState,
19
+ toNetworkState,
20
+ contractState,
21
+ currentL1Block,
22
+ }: SettlementHookInputs
23
+ ): void {
24
+ const { lastSettlementL1Block } = contractState;
25
+
26
+ const blocksPerL1Block = this.config.blocksPerL1Block.toConstant();
27
+
28
+ const numL1Blocks = currentL1Block.sub(lastSettlementL1Block);
29
+ const expectedHeightDiff = numL1Blocks.toUInt64().mul(blocksPerL1Block);
30
+
31
+ const actualHeightDiff = toNetworkState.block.height.sub(
32
+ fromNetworkState.block.height
33
+ );
34
+
35
+ const acceptableDerivation = numL1Blocks.mul(1).div(10);
36
+
37
+ // TODO Check within bounds efficiently
38
+ }
39
+ }
@@ -72,7 +72,8 @@ export class State<Value> extends Mixin(WithPath, WithStateServiceProvider) {
72
72
  .current().result;
73
73
 
74
74
  // First try to find a match inside already created stateTransitions
75
- const previousMutatingTransitions = stateTransitions.filter((transition) =>
75
+ let previousMutatingTransitions: StateTransition<any>[] = [];
76
+ previousMutatingTransitions = stateTransitions.filter((transition) =>
76
77
  transition.path.equals(path).and(transition.to.isSome).toBoolean()
77
78
  );
78
79
  const pmtLength = previousMutatingTransitions.length;
@@ -1,4 +1,4 @@
1
- import { Bool } from "o1js";
1
+ import { Bool, Provable } from "o1js";
2
2
  import { container } from "tsyringe";
3
3
  import { log } from "@proto-kit/common";
4
4
 
@@ -18,12 +18,14 @@ export function assert(condition: Bool, message?: string) {
18
18
  const previousStatus = executionContext.current().result.status;
19
19
  const status = condition.and(previousStatus);
20
20
 
21
- if (!condition.toBoolean()) {
22
- if (!executionContext.current().isSimulated) {
23
- log.debug("Assertion failed: ", message);
21
+ Provable.asProver(() => {
22
+ if (!condition.toBoolean()) {
23
+ if (!executionContext.current().isSimulated) {
24
+ log.debug("Assertion failed: ", message);
25
+ }
26
+ executionContext.setStatusMessage(message);
24
27
  }
25
- executionContext.setStatusMessage(message);
26
- }
28
+ });
27
29
 
28
30
  executionContext.setStatus(status);
29
31
  }
@@ -1,4 +1,4 @@
1
- import { Bool } from "o1js";
1
+ import { Bool, Provable, Struct } from "o1js";
2
2
  import { singleton } from "tsyringe";
3
3
  import {
4
4
  ProvableMethodExecutionContext,
@@ -29,6 +29,13 @@ export interface RuntimeMethodExecutionData {
29
29
  networkState: NetworkState;
30
30
  }
31
31
 
32
+ export class RuntimeMethodExecutionDataStruct
33
+ extends Struct({
34
+ transaction: RuntimeTransaction,
35
+ networkState: NetworkState,
36
+ })
37
+ implements RuntimeMethodExecutionData {}
38
+
32
39
  /**
33
40
  * Execution context used to wrap runtime module methods,
34
41
  * allowing them to post relevant information (such as execution status)
@@ -93,6 +100,18 @@ export class RuntimeMethodExecutionContext extends ProvableMethodExecutionContex
93
100
  this.input = input;
94
101
  }
95
102
 
103
+ public witnessInput(): RuntimeMethodExecutionDataStruct {
104
+ this.assertSetupCalled();
105
+ return Provable.witness(RuntimeMethodExecutionDataStruct, () => {
106
+ // TODO Is that right? Or this.current().input
107
+ const { transaction, networkState } = this.input!;
108
+ return new RuntimeMethodExecutionDataStruct({
109
+ networkState,
110
+ transaction,
111
+ });
112
+ });
113
+ }
114
+
96
115
  public setSimulated(simulated: boolean) {
97
116
  this.isSimulated = simulated;
98
117
  }
@@ -108,7 +127,8 @@ export class RuntimeMethodExecutionContext extends ProvableMethodExecutionContex
108
127
  super.afterMethod();
109
128
  if (this.isFinished) {
110
129
  this.lastInput = this.input;
111
- this.input = undefined;
130
+ // TODO: find out why input isnt set in TransactionFeeHook during assert
131
+ // this.input = undefined;
112
132
  this.isSimulated = false;
113
133
  }
114
134
  }
@@ -0,0 +1,72 @@
1
+ import { Field, Poseidon, ProvablePure } from "o1js";
2
+ import { hashWithPrefix, prefixToField } from "@proto-kit/common";
3
+
4
+ import { ProvableHashList } from "./ProvableHashList";
5
+
6
+ function salt(prefix: string) {
7
+ return Poseidon.update(
8
+ [Field(0), Field(0), Field(0)],
9
+ [prefixToField(prefix)]
10
+ ) as [Field, Field, Field];
11
+ }
12
+
13
+ export const MINA_EVENT_PREFIXES = {
14
+ event: "MinaZkappEvent******",
15
+ events: "MinaZkappEvents*****",
16
+ sequenceEvents: "MinaZkappSeqEvents**",
17
+ } as const;
18
+
19
+ export function emptyActions(): Field {
20
+ return salt("MinaZkappActionsEmpty")[0];
21
+ }
22
+
23
+ export function emptyEvents(): Field {
24
+ return salt("MinaZkappEventsEmpty")[0];
25
+ }
26
+
27
+ export class MinaActions {
28
+ static actionHash(
29
+ action: Field[],
30
+ previousHash: Field = emptyActions()
31
+ ): Field {
32
+ const actionDataHash = hashWithPrefix(MINA_EVENT_PREFIXES.event, action);
33
+ return hashWithPrefix(MINA_EVENT_PREFIXES.sequenceEvents, [
34
+ previousHash,
35
+ actionDataHash,
36
+ ]);
37
+ }
38
+ }
39
+
40
+ export class MinaEvents {
41
+ static eventHash(event: Field[], previousHash: Field = emptyEvents()): Field {
42
+ const actionDataHash = hashWithPrefix(MINA_EVENT_PREFIXES.event, event);
43
+ return hashWithPrefix(MINA_EVENT_PREFIXES.events, [
44
+ previousHash,
45
+ actionDataHash,
46
+ ]);
47
+ }
48
+ }
49
+
50
+ export class MinaPrefixedProvableHashList<
51
+ Value
52
+ > extends ProvableHashList<Value> {
53
+ public constructor(
54
+ valueType: ProvablePure<Value>,
55
+ public readonly prefix: string,
56
+ internalCommitment: Field = Field(0)
57
+ ) {
58
+ super(valueType, internalCommitment);
59
+ }
60
+
61
+ protected hash(elements: Field[]): Field {
62
+ const init = salt(this.prefix);
63
+ const digest = Poseidon.update(init, elements);
64
+ return digest[0];
65
+ }
66
+ }
67
+
68
+ export class MinaActionsHashList extends MinaPrefixedProvableHashList<Field> {
69
+ public constructor(internalCommitment: Field = Field(0)) {
70
+ super(Field, MINA_EVENT_PREFIXES.sequenceEvents, internalCommitment);
71
+ }
72
+ }
@@ -1,4 +1,4 @@
1
- import { Field, FlexibleProvablePure, Poseidon } from "o1js";
1
+ import { Field, ProvablePure, Poseidon } from "o1js";
2
2
 
3
3
  import { ProvableHashList } from "./ProvableHashList.js";
4
4
  import { stringToField } from "./utils";
@@ -7,7 +7,7 @@ export class PrefixedProvableHashList<Value> extends ProvableHashList<Value> {
7
7
  private readonly prefix: Field;
8
8
 
9
9
  public constructor(
10
- valueType: FlexibleProvablePure<Value>,
10
+ valueType: ProvablePure<Value>,
11
11
  prefix: string,
12
12
  internalCommitment: Field = Field(0)
13
13
  ) {
@@ -1,11 +1,11 @@
1
- import { Field, Poseidon, FlexibleProvablePure, Bool, Provable } from "o1js";
1
+ import { Field, Poseidon, Bool, Provable, ProvablePure } from "o1js";
2
2
 
3
3
  /**
4
4
  * Utilities for creating a hash list from a given value type.
5
5
  */
6
6
  export abstract class ProvableHashList<Value> {
7
7
  public constructor(
8
- private readonly valueType: FlexibleProvablePure<Value>,
8
+ protected readonly valueType: ProvablePure<Value>,
9
9
  public commitment: Field = Field(0)
10
10
  ) {}
11
11
 
@@ -47,4 +47,4 @@ export class DefaultProvableHashList<Value> extends ProvableHashList<Value> {
47
47
  public hash(elements: Field[]): Field {
48
48
  return Poseidon.hash(elements);
49
49
  }
50
- }
50
+ }