@proto-kit/protocol 0.1.1-develop.1316 → 0.1.1-develop.1347

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 (145) hide show
  1. package/dist/hooks/AccountStateHook.d.ts +3 -3
  2. package/dist/hooks/AccountStateHook.d.ts.map +1 -1
  3. package/dist/hooks/AccountStateHook.js +6 -2
  4. package/dist/hooks/AccountStateHook.js.map +1 -1
  5. package/dist/hooks/LastStateRootBlockHook.d.ts +3 -4
  6. package/dist/hooks/LastStateRootBlockHook.d.ts.map +1 -1
  7. package/dist/hooks/LastStateRootBlockHook.js +4 -4
  8. package/dist/hooks/LastStateRootBlockHook.js.map +1 -1
  9. package/dist/hooks/NoopBlockHook.d.ts +3 -4
  10. package/dist/hooks/NoopBlockHook.d.ts.map +1 -1
  11. package/dist/hooks/NoopBlockHook.js +1 -1
  12. package/dist/hooks/NoopBlockHook.js.map +1 -1
  13. package/dist/hooks/NoopTransactionHook.d.ts +2 -2
  14. package/dist/hooks/NoopTransactionHook.d.ts.map +1 -1
  15. package/dist/hooks/NoopTransactionHook.js +4 -1
  16. package/dist/hooks/NoopTransactionHook.js.map +1 -1
  17. package/dist/index.d.ts +6 -1
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +6 -1
  20. package/dist/index.js.map +1 -1
  21. package/dist/model/AppliedStateTransitionBatch.d.ts +114 -0
  22. package/dist/model/AppliedStateTransitionBatch.d.ts.map +1 -0
  23. package/dist/model/AppliedStateTransitionBatch.js +16 -0
  24. package/dist/model/AppliedStateTransitionBatch.js.map +1 -0
  25. package/dist/model/StateTransition.d.ts +1 -0
  26. package/dist/model/StateTransition.d.ts.map +1 -1
  27. package/dist/model/StateTransition.js +5 -0
  28. package/dist/model/StateTransition.js.map +1 -1
  29. package/dist/model/StateTransitionProvableBatch.d.ts +249 -97
  30. package/dist/model/StateTransitionProvableBatch.d.ts.map +1 -1
  31. package/dist/model/StateTransitionProvableBatch.js +72 -65
  32. package/dist/model/StateTransitionProvableBatch.js.map +1 -1
  33. package/dist/model/transaction/RuntimeTransaction.d.ts +1 -0
  34. package/dist/model/transaction/RuntimeTransaction.d.ts.map +1 -1
  35. package/dist/model/transaction/RuntimeTransaction.js +3 -0
  36. package/dist/model/transaction/RuntimeTransaction.js.map +1 -1
  37. package/dist/protocol/ProvableBlockHook.d.ts +13 -3
  38. package/dist/protocol/ProvableBlockHook.d.ts.map +1 -1
  39. package/dist/protocol/ProvableBlockHook.js +16 -0
  40. package/dist/protocol/ProvableBlockHook.js.map +1 -1
  41. package/dist/protocol/ProvableTransactionHook.d.ts +29 -2
  42. package/dist/protocol/ProvableTransactionHook.d.ts.map +1 -1
  43. package/dist/protocol/ProvableTransactionHook.js +9 -0
  44. package/dist/protocol/ProvableTransactionHook.js.map +1 -1
  45. package/dist/prover/accumulators/AppliedBatchHashList.d.ts +18 -0
  46. package/dist/prover/accumulators/AppliedBatchHashList.d.ts.map +1 -0
  47. package/dist/prover/accumulators/AppliedBatchHashList.js +25 -0
  48. package/dist/prover/accumulators/AppliedBatchHashList.js.map +1 -0
  49. package/dist/{utils → prover/accumulators}/StateTransitionReductionList.d.ts +3 -2
  50. package/dist/prover/accumulators/StateTransitionReductionList.d.ts.map +1 -0
  51. package/dist/{utils → prover/accumulators}/StateTransitionReductionList.js +6 -3
  52. package/dist/prover/accumulators/StateTransitionReductionList.js.map +1 -0
  53. package/dist/prover/accumulators/TransactionHashList.d.ts +6 -0
  54. package/dist/prover/accumulators/TransactionHashList.d.ts.map +1 -0
  55. package/dist/prover/accumulators/TransactionHashList.js +8 -0
  56. package/dist/prover/accumulators/TransactionHashList.js.map +1 -0
  57. package/dist/prover/accumulators/WitnessedRootHashList.d.ts +137 -0
  58. package/dist/prover/accumulators/WitnessedRootHashList.d.ts.map +1 -0
  59. package/dist/prover/accumulators/WitnessedRootHashList.js +50 -0
  60. package/dist/prover/accumulators/WitnessedRootHashList.js.map +1 -0
  61. package/dist/prover/block/BlockProvable.d.ts +579 -35
  62. package/dist/prover/block/BlockProvable.d.ts.map +1 -1
  63. package/dist/prover/block/BlockProvable.js +55 -3
  64. package/dist/prover/block/BlockProvable.js.map +1 -1
  65. package/dist/prover/block/BlockProver.d.ts +52 -50
  66. package/dist/prover/block/BlockProver.d.ts.map +1 -1
  67. package/dist/prover/block/BlockProver.js +289 -209
  68. package/dist/prover/block/BlockProver.js.map +1 -1
  69. package/dist/prover/block/accummulators/BlockHashMerkleTree.d.ts +55 -13
  70. package/dist/prover/block/accummulators/BlockHashMerkleTree.d.ts.map +1 -1
  71. package/dist/prover/block/accummulators/BlockHashMerkleTree.js +11 -3
  72. package/dist/prover/block/accummulators/BlockHashMerkleTree.js.map +1 -1
  73. package/dist/prover/statetransition/StateTransitionProvable.d.ts +107 -106
  74. package/dist/prover/statetransition/StateTransitionProvable.d.ts.map +1 -1
  75. package/dist/prover/statetransition/StateTransitionProvable.js +8 -8
  76. package/dist/prover/statetransition/StateTransitionProvable.js.map +1 -1
  77. package/dist/prover/statetransition/StateTransitionProver.d.ts +14 -11
  78. package/dist/prover/statetransition/StateTransitionProver.d.ts.map +1 -1
  79. package/dist/prover/statetransition/StateTransitionProver.js +116 -62
  80. package/dist/prover/statetransition/StateTransitionProver.js.map +1 -1
  81. package/dist/settlement/contracts/DispatchContractProtocolModule.d.ts +1 -1
  82. package/dist/settlement/contracts/DispatchSmartContract.d.ts +1 -1
  83. package/dist/settlement/contracts/SettlementSmartContract.d.ts.map +1 -1
  84. package/dist/settlement/contracts/SettlementSmartContract.js +1 -0
  85. package/dist/settlement/contracts/SettlementSmartContract.js.map +1 -1
  86. package/dist/state/assert/assert.d.ts.map +1 -1
  87. package/dist/state/assert/assert.js +5 -3
  88. package/dist/state/assert/assert.js.map +1 -1
  89. package/dist/state/context/RuntimeMethodExecutionContext.d.ts +3 -3
  90. package/dist/state/context/RuntimeMethodExecutionContext.d.ts.map +1 -1
  91. package/dist/state/context/RuntimeMethodExecutionContext.js +7 -4
  92. package/dist/state/context/RuntimeMethodExecutionContext.js.map +1 -1
  93. package/dist/utils/FieldOptions.d.ts +62 -0
  94. package/dist/utils/FieldOptions.d.ts.map +1 -0
  95. package/dist/utils/FieldOptions.js +13 -0
  96. package/dist/utils/FieldOptions.js.map +1 -0
  97. package/dist/utils/ProvableHashList.d.ts +21 -2
  98. package/dist/utils/ProvableHashList.d.ts.map +1 -1
  99. package/dist/utils/ProvableHashList.js +37 -2
  100. package/dist/utils/ProvableHashList.js.map +1 -1
  101. package/dist/utils/ProvableReductionHashList.d.ts +7 -3
  102. package/dist/utils/ProvableReductionHashList.d.ts.map +1 -1
  103. package/dist/utils/ProvableReductionHashList.js +8 -5
  104. package/dist/utils/ProvableReductionHashList.js.map +1 -1
  105. package/dist/utils/utils.d.ts +10 -1
  106. package/dist/utils/utils.d.ts.map +1 -1
  107. package/dist/utils/utils.js +6 -0
  108. package/dist/utils/utils.js.map +1 -1
  109. package/package.json +2 -2
  110. package/src/hooks/AccountStateHook.ts +12 -3
  111. package/src/hooks/LastStateRootBlockHook.ts +7 -8
  112. package/src/hooks/NoopBlockHook.ts +7 -4
  113. package/src/hooks/NoopTransactionHook.ts +5 -2
  114. package/src/index.ts +6 -1
  115. package/src/model/AppliedStateTransitionBatch.ts +16 -0
  116. package/src/model/StateTransition.ts +6 -0
  117. package/src/model/StateTransitionProvableBatch.ts +94 -105
  118. package/src/model/transaction/RuntimeTransaction.ts +4 -0
  119. package/src/protocol/ProvableBlockHook.ts +51 -3
  120. package/src/protocol/ProvableTransactionHook.ts +67 -3
  121. package/src/prover/accumulators/AppliedBatchHashList.ts +32 -0
  122. package/src/{utils → prover/accumulators}/StateTransitionReductionList.ts +7 -4
  123. package/src/prover/accumulators/TransactionHashList.ts +9 -0
  124. package/src/prover/accumulators/WitnessedRootHashList.ts +61 -0
  125. package/src/prover/block/BlockProvable.ts +128 -9
  126. package/src/prover/block/BlockProver.ts +531 -383
  127. package/src/prover/block/accummulators/BlockHashMerkleTree.ts +11 -3
  128. package/src/prover/statetransition/StateTransitionProvable.ts +17 -11
  129. package/src/prover/statetransition/StateTransitionProver.ts +219 -144
  130. package/src/settlement/contracts/SettlementSmartContract.ts +4 -0
  131. package/src/state/assert/assert.ts +6 -3
  132. package/src/state/context/RuntimeMethodExecutionContext.ts +15 -7
  133. package/src/utils/FieldOptions.ts +13 -0
  134. package/src/utils/ProvableHashList.ts +77 -2
  135. package/src/utils/ProvableReductionHashList.ts +12 -3
  136. package/src/utils/utils.ts +18 -1
  137. package/test/BlockProver.test.ts +2 -0
  138. package/test/TestingProtocol.ts +5 -0
  139. package/test/model/StateTransitionProvableBatch.test.ts +137 -0
  140. package/test/prover/block/BlockProver.test.ts +18 -0
  141. package/test/prover/statetransition/StateTransitionProver.test.ts +240 -0
  142. package/test/utils/ProvableHashList.test.ts +44 -0
  143. package/test/utils/ProvableReductionHashList.test.ts +1 -1
  144. package/dist/utils/StateTransitionReductionList.d.ts.map +0 -1
  145. package/dist/utils/StateTransitionReductionList.js.map +0 -1
@@ -5,12 +5,20 @@ export class BlockHashMerkleTree extends createMerkleTree(40) {}
5
5
  export class BlockHashMerkleTreeWitness extends BlockHashMerkleTree.WITNESS {}
6
6
 
7
7
  export class BlockHashTreeEntry extends Struct({
8
- blockHash: Field,
8
+ block: Struct({
9
+ index: Field,
10
+ transactionListHash: Field,
11
+ }),
9
12
  closed: Bool,
10
13
  // TODO We could add startingEternalTransactionsHash here to offer
11
- // a more trivial connection to the sequence state
14
+ // a more trivial connection to the sequence state
12
15
  }) {
13
16
  public hash(): Field {
14
- return Poseidon.hash([this.blockHash, ...this.closed.toFields()]);
17
+ // Mirroring Block.hash()
18
+ const blockHash = Poseidon.hash([
19
+ this.block.index,
20
+ this.block.transactionListHash,
21
+ ]);
22
+ return Poseidon.hash([blockHash, ...this.closed.toFields()]);
15
23
  }
16
24
  }
@@ -1,20 +1,24 @@
1
1
  import { Field, Proof, Struct } from "o1js";
2
2
  import { WithZkProgrammable, CompilableModule } from "@proto-kit/common";
3
3
 
4
- import { StateTransitionProvableBatch } from "../../model/StateTransitionProvableBatch";
4
+ import {
5
+ MerkleWitnessBatch,
6
+ StateTransitionProvableBatch,
7
+ } from "../../model/StateTransitionProvableBatch";
8
+ import { AppliedStateTransitionBatchState } from "../../model/AppliedStateTransitionBatch";
5
9
 
6
10
  export class StateTransitionProverPublicInput extends Struct({
7
- stateTransitionsHash: Field,
8
- protocolTransitionsHash: Field,
9
- stateRoot: Field,
10
- protocolStateRoot: Field,
11
+ batchesHash: Field,
12
+ currentBatchStateHash: Field,
13
+ root: Field,
14
+ witnessedRootsHash: Field,
11
15
  }) {}
12
16
 
13
17
  export class StateTransitionProverPublicOutput extends Struct({
14
- stateTransitionsHash: Field,
15
- protocolTransitionsHash: Field,
16
- stateRoot: Field,
17
- protocolStateRoot: Field,
18
+ batchesHash: Field,
19
+ currentBatchStateHash: Field,
20
+ root: Field,
21
+ witnessedRootsHash: Field,
18
22
  }) {}
19
23
 
20
24
  export type StateTransitionProof = Proof<
@@ -28,9 +32,11 @@ export interface StateTransitionProvable
28
32
  StateTransitionProverPublicOutput
29
33
  >,
30
34
  CompilableModule {
31
- runBatch: (
35
+ proveBatch: (
32
36
  publicInput: StateTransitionProverPublicInput,
33
- batch: StateTransitionProvableBatch
37
+ batch: StateTransitionProvableBatch,
38
+ witnesses: MerkleWitnessBatch,
39
+ currentAppliedBatch: AppliedStateTransitionBatchState
34
40
  ) => Promise<StateTransitionProverPublicOutput>;
35
41
 
36
42
  merge: (
@@ -14,15 +14,16 @@ import { injectable } from "tsyringe";
14
14
  import { constants } from "../../Constants";
15
15
  import { ProvableStateTransition } from "../../model/StateTransition";
16
16
  import {
17
- ProvableStateTransitionType,
17
+ MerkleWitnessBatch,
18
18
  StateTransitionProvableBatch,
19
+ StateTransitionType,
19
20
  } from "../../model/StateTransitionProvableBatch";
20
21
  import { StateTransitionProverType } from "../../protocol/Protocol";
21
22
  import { ProtocolModule } from "../../protocol/ProtocolModule";
22
- import {
23
- DefaultProvableHashList,
24
- ProvableHashList,
25
- } from "../../utils/ProvableHashList";
23
+ import { DefaultProvableHashList } from "../../utils/ProvableHashList";
24
+ import { WitnessedRootHashList } from "../accumulators/WitnessedRootHashList";
25
+ import { AppliedBatchHashList } from "../accumulators/AppliedBatchHashList";
26
+ import { AppliedStateTransitionBatchState } from "../../model/AppliedStateTransitionBatch";
26
27
 
27
28
  import {
28
29
  StateTransitionProof,
@@ -35,31 +36,15 @@ const errors = {
35
36
  propertyNotMatching: (property: string, step: string) =>
36
37
  `${property} not matching ${step}`,
37
38
 
38
- merkleWitnessNotCorrect: (
39
- index: number,
40
- type: ProvableStateTransitionType
41
- ) => {
42
- let s = `MerkleWitness not valid for StateTransition (${index}, type unknown)`;
43
- Provable.asProver(() => {
44
- s = s.replace(
45
- "unknown",
46
- type.isNormal().toBoolean() ? "normal" : "protocol"
47
- );
48
- });
49
- return s;
50
- },
51
-
52
- noWitnessProviderSet: () =>
53
- new Error(
54
- "WitnessProvider not set, set it before you use StateTransitionProvider"
55
- ),
39
+ merkleWitnessNotCorrect: (index: number) =>
40
+ `MerkleWitness not valid for StateTransition (${index})`,
56
41
  };
57
42
 
58
43
  interface StateTransitionProverExecutionState {
59
- stateRoot: Field;
60
- protocolStateRoot: Field;
61
- stateTransitionList: ProvableHashList<ProvableStateTransition>;
62
- protocolTransitionList: ProvableHashList<ProvableStateTransition>;
44
+ currentBatch: AppliedStateTransitionBatchState;
45
+ batchList: AppliedBatchHashList;
46
+ finalizedRoot: Field;
47
+ witnessedRoots: WitnessedRootHashList;
63
48
  }
64
49
 
65
50
  const StateTransitionSelfProofClass = SelfProof<
@@ -76,7 +61,10 @@ export class StateTransitionProverProgrammable extends ZkProgrammable<
76
61
  StateTransitionProverPublicOutput
77
62
  > {
78
63
  public constructor(
79
- private readonly stateTransitionProver: StateTransitionProver
64
+ private readonly stateTransitionProver: Pick<
65
+ StateTransitionProver,
66
+ "areProofsEnabled"
67
+ >
80
68
  ) {
81
69
  super();
82
70
  }
@@ -97,14 +85,25 @@ export class StateTransitionProverProgrammable extends ZkProgrammable<
97
85
  publicOutput: StateTransitionProverPublicOutput,
98
86
 
99
87
  methods: {
100
- runBatch: {
101
- privateInputs: [StateTransitionProvableBatch],
88
+ proveBatch: {
89
+ privateInputs: [
90
+ StateTransitionProvableBatch,
91
+ MerkleWitnessBatch,
92
+ AppliedStateTransitionBatchState,
93
+ ],
102
94
 
103
95
  async method(
104
96
  publicInput: StateTransitionProverPublicInput,
105
- batch: StateTransitionProvableBatch
97
+ batch: StateTransitionProvableBatch,
98
+ witnesses: MerkleWitnessBatch,
99
+ currentAppliedBatch: AppliedStateTransitionBatchState
106
100
  ) {
107
- return await instance.runBatch(publicInput, batch);
101
+ return await instance.proveBatch(
102
+ publicInput,
103
+ batch,
104
+ witnesses,
105
+ currentAppliedBatch
106
+ );
108
107
  },
109
108
  },
110
109
 
@@ -126,7 +125,7 @@ export class StateTransitionProverProgrammable extends ZkProgrammable<
126
125
  });
127
126
 
128
127
  const methods = {
129
- runBatch: program.runBatch.bind(program),
128
+ proveBatch: program.proveBatch.bind(program),
130
129
  merge: program.merge.bind(program),
131
130
  };
132
131
 
@@ -149,42 +148,94 @@ export class StateTransitionProverProgrammable extends ZkProgrammable<
149
148
  * and returns the new prover state
150
149
  */
151
150
  public applyTransitions(
152
- stateRoot: Field,
153
- protocolStateRoot: Field,
154
- stateTransitionCommitmentFrom: Field,
155
- protocolTransitionCommitmentFrom: Field,
156
- transitionBatch: StateTransitionProvableBatch
157
- ): StateTransitionProverExecutionState {
158
- const state: StateTransitionProverExecutionState = {
159
- stateRoot,
160
- protocolStateRoot,
161
-
162
- stateTransitionList: new DefaultProvableHashList(
163
- ProvableStateTransition,
164
- stateTransitionCommitmentFrom
165
- ),
166
-
167
- protocolTransitionList: new DefaultProvableHashList(
168
- ProvableStateTransition,
169
- protocolTransitionCommitmentFrom
170
- ),
171
- };
151
+ state: StateTransitionProverExecutionState,
152
+ batch: StateTransitionProvableBatch,
153
+ witnesses: MerkleWitnessBatch
154
+ ) {
155
+ const transitions = batch.batch;
172
156
 
173
- const transitions = transitionBatch.batch;
174
- const types = transitionBatch.transitionTypes;
175
- const merkleWitness = transitionBatch.merkleWitnesses;
176
157
  for (
177
158
  let index = 0;
178
159
  index < constants.stateTransitionProverBatchSize;
179
160
  index++
180
161
  ) {
181
- this.applyTransition(
182
- state,
183
- transitions[index],
184
- types[index],
185
- merkleWitness[index],
162
+ const updatedBatchState = this.applyTransition(
163
+ state.currentBatch,
164
+ transitions[index].stateTransition,
165
+ witnesses.witnesses[index],
186
166
  index
187
167
  );
168
+
169
+ // If the current batch is finished, we push it to the list
170
+ // and initialize the next
171
+ const { type, witnessRoot } = transitions[index];
172
+ const closing = type.isClosing();
173
+ const closingAndApply = type.type.equals(
174
+ StateTransitionType.closeAndApply
175
+ );
176
+
177
+ // Create the newBatch
178
+ // The root is based on if the previous batch will be applied or not
179
+ const base = Provable.if(
180
+ closingAndApply,
181
+ updatedBatchState.root,
182
+ state.finalizedRoot
183
+ );
184
+ const newBatchState = new AppliedStateTransitionBatchState({
185
+ batchHash: Field(0),
186
+ root: base,
187
+ });
188
+
189
+ const updatedBatch = {
190
+ applied: closingAndApply,
191
+ batchHash: updatedBatchState.batchHash,
192
+ };
193
+ state.batchList.pushIf(updatedBatch, closing);
194
+ state.finalizedRoot = Provable.if(
195
+ closingAndApply,
196
+ updatedBatchState.root,
197
+ state.finalizedRoot
198
+ );
199
+
200
+ // Add computed root to the witnessed root list if needed
201
+ witnessRoot
202
+ .implies(closing)
203
+ .assertTrue("Can only witness roots at closing batches");
204
+ state.witnessedRoots.pushIf(
205
+ {
206
+ root: state.finalizedRoot,
207
+ appliedBatchListState: state.batchList.commitment,
208
+ },
209
+ witnessRoot
210
+ );
211
+
212
+ const isDummy = ProvableStateTransition.isDummy(
213
+ transitions[index].stateTransition
214
+ );
215
+
216
+ // Dummy STs cannot change any state, as to prevent any
217
+ // dummy-in-the-middle attacks. This is given if the type is nothing.
218
+ isDummy
219
+ .implies(type.isNothing())
220
+ .assertTrue("Dummies have to be of type 'nothing'");
221
+
222
+ isDummy
223
+ .implies(state.currentBatch.batchHash.equals(0))
224
+ .assertTrue("Dummies can only be placed on closed batchLists");
225
+
226
+ // Dummies don't close the batch, but we still want to ignore any
227
+ // updated batch, since we need to result to stay.
228
+ // This will break the pipeline if there is a dummy in the middle,
229
+ // but will only end up to invalid proofs (i.e. mismatched batches)
230
+
231
+ state.currentBatch = new AppliedStateTransitionBatchState(
232
+ Provable.if(
233
+ closing.or(isDummy),
234
+ AppliedStateTransitionBatchState,
235
+ newBatchState,
236
+ updatedBatchState
237
+ )
238
+ );
188
239
  }
189
240
 
190
241
  return state;
@@ -195,71 +246,91 @@ export class StateTransitionProverProgrammable extends ZkProgrammable<
195
246
  * and mutates it in place
196
247
  */
197
248
  public applyTransition(
198
- state: StateTransitionProverExecutionState,
249
+ currentBatch: AppliedStateTransitionBatchState,
199
250
  transition: ProvableStateTransition,
200
- type: ProvableStateTransitionType,
201
- merkleWitness: RollupMerkleTreeWitness,
251
+ witness: RollupMerkleTreeWitness,
202
252
  index = 0
203
253
  ) {
254
+ const impliedRoot = this.applyTransitionToRoot(
255
+ transition,
256
+ currentBatch.root,
257
+ witness,
258
+ index
259
+ );
260
+
261
+ // Append ST to the current batch's ST-list
262
+ const stList = new DefaultProvableHashList(
263
+ ProvableStateTransition,
264
+ currentBatch.batchHash
265
+ );
266
+ stList.push(transition);
267
+
268
+ // Update batch
269
+ return new AppliedStateTransitionBatchState({
270
+ batchHash: stList.commitment,
271
+ root: impliedRoot,
272
+ });
273
+ }
274
+
275
+ private applyTransitionToRoot(
276
+ transition: ProvableStateTransition,
277
+ root: Field,
278
+ merkleWitness: RollupMerkleTreeWitness,
279
+ index: number
280
+ ): Field {
204
281
  const membershipValid = merkleWitness.checkMembership(
205
- state.stateRoot,
282
+ root,
206
283
  transition.path,
207
284
  transition.from.value
208
285
  );
209
286
 
210
287
  membershipValid
211
288
  .or(transition.from.isSome.not())
212
- .assertTrue(errors.merkleWitnessNotCorrect(index, type));
289
+ .assertTrue(errors.merkleWitnessNotCorrect(index));
213
290
 
214
291
  const newRoot = merkleWitness.calculateRoot(transition.to.value);
215
292
 
216
- state.stateRoot = Provable.if(
217
- transition.to.isSome,
218
- newRoot,
219
- state.stateRoot
220
- );
221
-
222
- // Only update protocol state root if ST is also of type protocol
223
- // Since protocol STs are all at the start of the batch, this works
224
- state.protocolStateRoot = Provable.if(
225
- transition.to.isSome.and(type.isProtocol()),
226
- newRoot,
227
- state.protocolStateRoot
228
- );
229
-
230
- const isNotDummy = transition.path.equals(Field(0)).not();
231
-
232
- state.stateTransitionList.pushIf(
233
- transition,
234
- isNotDummy.and(type.isNormal())
235
- );
236
- state.protocolTransitionList.pushIf(
237
- transition,
238
- isNotDummy.and(type.isProtocol())
239
- );
293
+ return Provable.if(transition.to.isSome, newRoot, root);
240
294
  }
241
295
 
242
296
  /**
243
297
  * Applies a whole batch of StateTransitions at once
244
298
  */
245
299
  @provableMethod()
246
- public async runBatch(
300
+ public async proveBatch(
247
301
  publicInput: StateTransitionProverPublicInput,
248
- batch: StateTransitionProvableBatch
302
+ batch: StateTransitionProvableBatch,
303
+ witnesses: MerkleWitnessBatch,
304
+ currentAppliedBatch: AppliedStateTransitionBatchState
249
305
  ): Promise<StateTransitionProverPublicOutput> {
250
- const result = this.applyTransitions(
251
- publicInput.stateRoot,
252
- publicInput.protocolStateRoot,
253
- publicInput.stateTransitionsHash,
254
- publicInput.protocolTransitionsHash,
255
- batch
256
- );
306
+ currentAppliedBatch
307
+ .hashOrZero()
308
+ .assertEquals(
309
+ publicInput.currentBatchStateHash,
310
+ "Provided startingAppliedBatch not matching PI hash"
311
+ );
312
+
313
+ // Assert that either the currentAppliedBatch is somewhere intermediary
314
+ // or the root is the current "finalized" root
315
+ currentAppliedBatch.root
316
+ .equals(publicInput.root)
317
+ .or(publicInput.currentBatchStateHash.equals(0).not())
318
+ .assertTrue();
319
+
320
+ const state: StateTransitionProverExecutionState = {
321
+ batchList: new AppliedBatchHashList(publicInput.batchesHash),
322
+ currentBatch: currentAppliedBatch,
323
+ finalizedRoot: publicInput.root,
324
+ witnessedRoots: new WitnessedRootHashList(publicInput.witnessedRootsHash),
325
+ };
326
+
327
+ const result = this.applyTransitions(state, batch, witnesses);
257
328
 
258
329
  return new StateTransitionProverPublicOutput({
259
- stateRoot: result.stateRoot,
260
- stateTransitionsHash: result.stateTransitionList.commitment,
261
- protocolTransitionsHash: result.protocolTransitionList.commitment,
262
- protocolStateRoot: result.protocolStateRoot,
330
+ batchesHash: result.batchList.commitment,
331
+ currentBatchStateHash: result.currentBatch.hashOrZero(),
332
+ root: result.finalizedRoot,
333
+ witnessedRootsHash: result.witnessedRoots.commitment,
263
334
  });
264
335
  }
265
336
 
@@ -272,69 +343,66 @@ export class StateTransitionProverProgrammable extends ZkProgrammable<
272
343
  proof1.verify();
273
344
  proof2.verify();
274
345
 
275
- // Check state
276
- publicInput.stateRoot.assertEquals(
277
- proof1.publicInput.stateRoot,
278
- errors.propertyNotMatching("stateRoot", "publicInput.from -> proof1.from")
279
- );
280
- proof1.publicOutput.stateRoot.assertEquals(
281
- proof2.publicInput.stateRoot,
282
- errors.propertyNotMatching("stateRoot", "proof1.to -> proof2.from")
283
- );
284
-
285
- // Check ST list
286
- publicInput.stateTransitionsHash.assertEquals(
287
- proof1.publicInput.stateTransitionsHash,
346
+ // Check current batch hash
347
+ publicInput.currentBatchStateHash.assertEquals(
348
+ proof1.publicInput.currentBatchStateHash,
288
349
  errors.propertyNotMatching(
289
- "stateTransitionsHash",
350
+ "currentBatchStateHash",
290
351
  "publicInput.from -> proof1.from"
291
352
  )
292
353
  );
293
- proof1.publicOutput.stateTransitionsHash.assertEquals(
294
- proof2.publicInput.stateTransitionsHash,
354
+ proof1.publicOutput.currentBatchStateHash.assertEquals(
355
+ proof2.publicInput.currentBatchStateHash,
295
356
  errors.propertyNotMatching(
296
- "stateTransitionsHash",
357
+ "currentBatchStateHash",
297
358
  "proof1.to -> proof2.from"
298
359
  )
299
360
  );
300
361
 
301
- // Check Protocol ST list
302
- publicInput.protocolTransitionsHash.assertEquals(
303
- proof1.publicInput.protocolTransitionsHash,
362
+ // Check batches hash
363
+ publicInput.batchesHash.assertEquals(
364
+ proof1.publicInput.batchesHash,
304
365
  errors.propertyNotMatching(
305
- "protocolTransitionsHash",
366
+ "batchesHash",
306
367
  "publicInput.from -> proof1.from"
307
368
  )
308
369
  );
309
- proof1.publicOutput.protocolTransitionsHash.assertEquals(
310
- proof2.publicInput.protocolTransitionsHash,
311
- errors.propertyNotMatching(
312
- "protocolTransitionsHash",
313
- "proof1.to -> proof2.from"
314
- )
370
+ proof1.publicOutput.batchesHash.assertEquals(
371
+ proof2.publicInput.batchesHash,
372
+ errors.propertyNotMatching("batchesHash", "proof1.to -> proof2.from")
315
373
  );
316
374
 
317
- // Check protocol state root
318
- publicInput.protocolStateRoot.assertEquals(
319
- proof1.publicInput.protocolStateRoot,
375
+ // Check root
376
+ publicInput.root.assertEquals(
377
+ proof1.publicInput.root,
378
+ errors.propertyNotMatching("root", "publicInput.from -> proof1.from")
379
+ );
380
+ proof1.publicOutput.root.assertEquals(
381
+ proof2.publicInput.root,
382
+ errors.propertyNotMatching("root", "proof1.to -> proof2.from")
383
+ );
384
+
385
+ // Check root accumulator
386
+ publicInput.witnessedRootsHash.assertEquals(
387
+ proof1.publicInput.witnessedRootsHash,
320
388
  errors.propertyNotMatching(
321
- "protocolStateRoot",
389
+ "witnessedRootsHash",
322
390
  "publicInput.from -> proof1.from"
323
391
  )
324
392
  );
325
- proof1.publicOutput.protocolStateRoot.assertEquals(
326
- proof2.publicInput.protocolStateRoot,
393
+ proof1.publicOutput.witnessedRootsHash.assertEquals(
394
+ proof2.publicInput.witnessedRootsHash,
327
395
  errors.propertyNotMatching(
328
- "protocolStateRoot",
396
+ "witnessedRootsHash",
329
397
  "proof1.to -> proof2.from"
330
398
  )
331
399
  );
332
400
 
333
401
  return new StateTransitionProverPublicInput({
334
- stateRoot: proof2.publicOutput.stateRoot,
335
- stateTransitionsHash: proof2.publicOutput.stateTransitionsHash,
336
- protocolTransitionsHash: proof2.publicOutput.protocolTransitionsHash,
337
- protocolStateRoot: proof2.publicOutput.protocolStateRoot,
402
+ currentBatchStateHash: proof2.publicOutput.currentBatchStateHash,
403
+ batchesHash: proof2.publicOutput.batchesHash,
404
+ root: proof2.publicOutput.root,
405
+ witnessedRootsHash: proof2.publicOutput.witnessedRootsHash,
338
406
  });
339
407
  }
340
408
  }
@@ -360,11 +428,18 @@ export class StateTransitionProver
360
428
  return await this.zkProgrammable.compile(registry);
361
429
  }
362
430
 
363
- public runBatch(
431
+ public proveBatch(
364
432
  publicInput: StateTransitionProverPublicInput,
365
- batch: StateTransitionProvableBatch
433
+ batch: StateTransitionProvableBatch,
434
+ witnesses: MerkleWitnessBatch,
435
+ startingAppliedBatch: AppliedStateTransitionBatchState
366
436
  ): Promise<StateTransitionProverPublicOutput> {
367
- return this.zkProgrammable.runBatch(publicInput, batch);
437
+ return this.zkProgrammable.proveBatch(
438
+ publicInput,
439
+ batch,
440
+ witnesses,
441
+ startingAppliedBatch
442
+ );
368
443
  }
369
444
 
370
445
  public merge(
@@ -362,6 +362,10 @@ export abstract class SettlementSmartContractBase extends TokenContractV2 {
362
362
  Bool(true),
363
363
  "Supplied proof is not a closed BlockProof"
364
364
  );
365
+ blockProof.publicOutput.pendingSTBatchesHash.assertEquals(
366
+ Field(0),
367
+ "Supplied proof is has outstanding STs to be proven"
368
+ );
365
369
 
366
370
  // Execute onSettlementHooks for additional checks
367
371
  const stateRecord: SettlementStateRecord = {
@@ -20,13 +20,16 @@ export function assert(condition: Bool, message?: string | (() => string)) {
20
20
 
21
21
  Provable.asProver(() => {
22
22
  if (!condition.toBoolean()) {
23
- if (!executionContext.current().isSimulated) {
24
- log.debug("Assertion failed: ", message);
25
- }
26
23
  const messageString =
27
24
  message !== undefined && typeof message === "function"
28
25
  ? message()
29
26
  : message;
27
+
28
+ // If no isSimulated was set, we treat it as not simulated,
29
+ // therefore printing the log
30
+ if (!(executionContext.current().isSimulated ?? false)) {
31
+ log.debug("Assertion failed: ", messageString);
32
+ }
30
33
  executionContext.setStatusMessage(messageString, new Error().stack);
31
34
  }
32
35
  });
@@ -56,12 +56,17 @@ export class RuntimeMethodExecutionContext extends ProvableMethodExecutionContex
56
56
 
57
57
  public input: RuntimeMethodExecutionData | undefined;
58
58
 
59
- // The input corresponding to the current result
60
- private lastInput: RuntimeMethodExecutionData | undefined;
59
+ private isSimulated: boolean = false;
61
60
 
62
- public override result = new RuntimeProvableMethodExecutionResult();
61
+ // The inputs corresponding to the current result
62
+ private lastInputs:
63
+ | {
64
+ input: RuntimeMethodExecutionData | undefined;
65
+ isSimulated: boolean;
66
+ }
67
+ | undefined;
63
68
 
64
- private isSimulated: boolean = false;
69
+ public override result = new RuntimeProvableMethodExecutionResult();
65
70
 
66
71
  private assertSetupCalled(): asserts this is {
67
72
  input: RuntimeMethodExecutionData;
@@ -152,7 +157,10 @@ export class RuntimeMethodExecutionContext extends ProvableMethodExecutionContex
152
157
  public afterMethod() {
153
158
  super.afterMethod();
154
159
  if (this.isFinished) {
155
- this.lastInput = this.input;
160
+ this.lastInputs = {
161
+ input: this.input,
162
+ isSimulated: this.isSimulated,
163
+ };
156
164
  // TODO: find out why input isnt set in TransactionFeeHook during assert
157
165
  // this.input = undefined;
158
166
  this.isSimulated = false;
@@ -167,8 +175,8 @@ export class RuntimeMethodExecutionContext extends ProvableMethodExecutionContex
167
175
  return {
168
176
  isFinished: this.isFinished,
169
177
  result: this.result,
170
- input: this.lastInput,
171
- isSimulated: this.isSimulated,
178
+ input: this.lastInputs?.input,
179
+ isSimulated: this.lastInputs?.isSimulated,
172
180
  };
173
181
  }
174
182
  }
@@ -0,0 +1,13 @@
1
+ import { Bool, Field, Provable, Struct } from "o1js";
2
+
3
+ export class FieldOption extends Struct({
4
+ isSome: Bool,
5
+ value: Field,
6
+ }) {
7
+ public static from(isSome: Bool, potentialValue: Field) {
8
+ return {
9
+ isSome,
10
+ value: Provable.if(isSome, potentialValue, Field(0)),
11
+ };
12
+ }
13
+ }