Skip to content

Commit b88afdb

Browse files
committed
Merge branch 'develop' into feature/enable-proving
# Conflicts: # packages/protocol/src/prover/block/BlockProver.ts # packages/protocol/src/prover/statetransition/StateTransitionProver.ts # packages/sequencer/src/protocol/production/BlockTaskFlowService.ts # packages/sequencer/src/protocol/production/tasks/StateTransitionTask.ts
2 parents 4726371 + 2d5ca04 commit b88afdb

23 files changed

+468
-209
lines changed

packages/common/src/utils.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,3 +164,5 @@ type NonMethodKeys<Type> = {
164164
[Key in keyof Type]: Type[Key] extends Function ? never : Key;
165165
}[keyof Type];
166166
export type NonMethods<Type> = Pick<Type, NonMethodKeys<Type>>;
167+
168+
export const MAX_FIELD = Field(Field.ORDER - 1n);

packages/library/src/hooks/RuntimeFeeAnalyzerService.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ export class RuntimeFeeAnalyzerService extends ConfigurableModule<RuntimeFeeAnal
8181
});
8282

8383
container.resolve(RuntimeMethodExecutionContext).clear();
84-
84+
let methodCounter = 0;
8585
const [values, indexes] =
8686
await this.runtime.zkProgrammable.zkProgram.reduce<
8787
Promise<[FeeTreeValues, FeeIndexes]>
@@ -93,7 +93,7 @@ export class RuntimeFeeAnalyzerService extends ConfigurableModule<RuntimeFeeAnal
9393
[FeeTreeValues, FeeIndexes]
9494
>(
9595
// eslint-disable-next-line @typescript-eslint/no-shadow
96-
([values, indexes], combinedMethodName, index) => {
96+
([values, indexes], combinedMethodName) => {
9797
const { rows } = analyzedMethods[combinedMethodName];
9898
// const rows = 1000;
9999
const [moduleName, methodName] = combinedMethodName.split(".");
@@ -128,7 +128,8 @@ export class RuntimeFeeAnalyzerService extends ConfigurableModule<RuntimeFeeAnal
128128
},
129129
{
130130
...indexes,
131-
[methodId.toString()]: BigInt(index),
131+
// eslint-disable-next-line no-plusplus
132+
[methodId.toString()]: BigInt(methodCounter++),
132133
},
133134
];
134135
},

packages/protocol/src/index.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ export * from "./prover/block/accummulators/BlockHashMerkleTree";
2424
export * from "./prover/block/services/RuntimeVerificationKeyRootService";
2525
export * from "./prover/statetransition/StateTransitionProver";
2626
export * from "./prover/statetransition/StateTransitionProvable";
27-
export * from "./prover/statetransition/StateTransitionWitnessProvider";
28-
export * from "./prover/statetransition/StateTransitionWitnessProviderReference";
2927
export * from "./protocol/Protocol";
3028
export * from "./protocol/ProtocolModule";
3129
export * from "./protocol/ProtocolEnvironment";

packages/protocol/src/model/StateTransitionProvableBatch.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import { Bool, Provable, Struct } from "o1js";
2-
import { range } from "@proto-kit/common";
2+
import {
3+
InMemoryMerkleTreeStorage,
4+
range,
5+
RollupMerkleTree,
6+
RollupMerkleTreeWitness,
7+
} from "@proto-kit/common";
38

49
import { constants } from "../Constants";
510

@@ -60,16 +65,22 @@ export class StateTransitionProvableBatch extends Struct({
6065
ProvableStateTransitionType,
6166
constants.stateTransitionProverBatchSize
6267
),
68+
69+
merkleWitnesses: Provable.Array(
70+
RollupMerkleTreeWitness,
71+
constants.stateTransitionProverBatchSize
72+
),
6373
}) {
6474
public static fromMappings(
6575
transitions: {
6676
transition: ProvableStateTransition;
6777
type: ProvableStateTransitionType;
68-
}[]
78+
}[],
79+
merkleWitnesses: RollupMerkleTreeWitness[]
6980
): StateTransitionProvableBatch {
7081
const batch = transitions.map((entry) => entry.transition);
7182
const transitionTypes = transitions.map((entry) => entry.type);
72-
83+
const witnesses = merkleWitnesses.slice();
7384
// Check that order is correct
7485
let normalSTsStarted = false;
7586
transitionTypes.forEach((x) => {
@@ -84,16 +95,23 @@ export class StateTransitionProvableBatch extends Struct({
8495
while (batch.length < constants.stateTransitionProverBatchSize) {
8596
batch.push(ProvableStateTransition.dummy());
8697
transitionTypes.push(ProvableStateTransitionType.normal);
98+
witnesses.push(
99+
new RollupMerkleTree(new InMemoryMerkleTreeStorage()).getWitness(
100+
BigInt(0)
101+
)
102+
);
87103
}
88104
return new StateTransitionProvableBatch({
89105
batch,
90106
transitionTypes,
107+
merkleWitnesses: witnesses,
91108
});
92109
}
93110

94111
public static fromTransitions(
95112
transitions: ProvableStateTransition[],
96-
protocolTransitions: ProvableStateTransition[]
113+
protocolTransitions: ProvableStateTransition[],
114+
merkleWitnesses: RollupMerkleTreeWitness[]
97115
): StateTransitionProvableBatch {
98116
const array = transitions.slice().concat(protocolTransitions);
99117

@@ -113,12 +131,14 @@ export class StateTransitionProvableBatch extends Struct({
113131
return new StateTransitionProvableBatch({
114132
batch: array,
115133
transitionTypes,
134+
merkleWitnesses,
116135
});
117136
}
118137

119138
private constructor(object: {
120139
batch: ProvableStateTransition[];
121140
transitionTypes: ProvableStateTransitionType[];
141+
merkleWitnesses: RollupMerkleTreeWitness[];
122142
}) {
123143
super(object);
124144
}

packages/protocol/src/prover/block/BlockProvable.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export class BlockProverPublicInput extends Struct({
2424
blockHashRoot: Field,
2525
eternalTransactionsHash: Field,
2626
incomingMessagesHash: Field,
27+
blockNumber: Field,
2728
}) {}
2829

2930
export class BlockProverPublicOutput extends Struct({
@@ -36,15 +37,10 @@ export class BlockProverPublicOutput extends Struct({
3637
closed: Bool,
3738
blockNumber: Field,
3839
}) {
39-
public equals(
40-
input: BlockProverPublicInput,
41-
closed: Bool,
42-
blockNumber: Field
43-
): Bool {
40+
public equals(input: BlockProverPublicInput, closed: Bool): Bool {
4441
const output2 = BlockProverPublicOutput.toFields({
4542
...input,
4643
closed,
47-
blockNumber,
4844
});
4945
const output1 = BlockProverPublicOutput.toFields(this);
5046
return output1

packages/protocol/src/prover/block/BlockProver.ts

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
import { container, inject, injectable, injectAll } from "tsyringe";
1313
import {
1414
AreProofsEnabled,
15+
MAX_FIELD,
1516
PlainZkProgram,
1617
provableMethod,
1718
WithZkProgrammable,
@@ -124,10 +125,6 @@ export interface BlockProverState {
124125
incomingMessagesHash: Field;
125126
}
126127

127-
function maxField() {
128-
return Field(Field.ORDER - 1n);
129-
}
130-
131128
export type BlockProof = Proof<BlockProverPublicInput, BlockProverPublicOutput>;
132129
export type RuntimeProof = Proof<void, MethodPublicOutput>;
133130

@@ -416,6 +413,11 @@ export class BlockProverProgrammable extends ZkProgrammable<
416413
"ExecutionData Networkstate doesn't equal public input hash"
417414
);
418415

416+
publicInput.blockNumber.assertEquals(
417+
MAX_FIELD,
418+
"blockNumber has to be MAX for transaction proofs"
419+
);
420+
419421
// Verify the [methodId, vk] tuple against the baked-in vk tree root
420422
const { verificationKey, witness: verificationKeyTreeWitness } =
421423
verificationKeyWitness;
@@ -445,7 +447,7 @@ export class BlockProverProgrammable extends ZkProgrammable<
445447

446448
return new BlockProverPublicOutput({
447449
...stateTo,
448-
blockNumber: maxField(),
450+
blockNumber: publicInput.blockNumber,
449451
closed: Bool(false),
450452
});
451453
}
@@ -528,14 +530,14 @@ export class BlockProverProgrammable extends ZkProgrammable<
528530
// stateTransitionProof.verifyIf(Bool(false));
529531
// stateTransitionProof.verifyIf(stsEmitted);
530532

531-
// Verify Transaction proof if it has at least 1 tx
533+
// Verify Transaction proof if it has at least 1 tx - i.e. the
534+
// input and output doesn't match fully
532535
// We have to compare the whole input and output because we can make no
533536
// assumptions about the values, since it can be an arbitrary dummy-proof
534537
const txProofOutput = transactionProof.publicOutput;
535538
const isEmptyTransition = txProofOutput.equals(
536539
transactionProof.publicInput,
537-
txProofOutput.closed,
538-
txProofOutput.blockNumber
540+
txProofOutput.closed
539541
);
540542
Provable.log("VerifyIf 2", isEmptyTransition.not());
541543
transactionProof.verifyIf(isEmptyTransition.not());
@@ -620,6 +622,8 @@ export class BlockProverProgrammable extends ZkProgrammable<
620622
// Calculate the new block index
621623
const blockIndex = blockWitness.calculateIndex();
622624

625+
blockIndex.assertEquals(publicInput.blockNumber);
626+
623627
blockWitness
624628
.calculateRoot(Field(0))
625629
.assertEquals(
@@ -637,7 +641,7 @@ export class BlockProverProgrammable extends ZkProgrammable<
637641

638642
return new BlockProverPublicOutput({
639643
...state,
640-
blockNumber: blockIndex,
644+
blockNumber: blockIndex.add(1),
641645
closed: Bool(true),
642646
});
643647
}
@@ -744,19 +748,25 @@ export class BlockProverProgrammable extends ZkProgrammable<
744748
// assert proof1.height == proof2.height
745749
// }
746750

747-
const proof1Height = proof1.publicOutput.blockNumber;
748751
const proof1Closed = proof1.publicOutput.closed;
749-
const proof2Height = proof2.publicOutput.blockNumber;
750752
const proof2Closed = proof2.publicOutput.closed;
751753

752-
const isValidTransactionMerge = proof1Height
753-
.equals(maxField())
754-
.and(proof2Height.equals(proof1Height))
754+
const blockNumberProgressionValid = publicInput.blockNumber
755+
.equals(proof1.publicInput.blockNumber)
756+
.and(
757+
proof1.publicOutput.blockNumber.equals(proof2.publicInput.blockNumber)
758+
);
759+
760+
// For tx proofs, we check that the progression starts and end with MAX
761+
// in addition to that both proofs are non-closed
762+
const isValidTransactionMerge = publicInput.blockNumber
763+
.equals(MAX_FIELD)
764+
.and(blockNumberProgressionValid)
755765
.and(proof1Closed.or(proof2Closed).not());
756766

757767
const isValidClosedMerge = proof1Closed
758768
.and(proof2Closed)
759-
.and(proof1Height.add(1).equals(proof2Height));
769+
.and(blockNumberProgressionValid);
760770

761771
isValidTransactionMerge
762772
.or(isValidClosedMerge)
@@ -769,9 +779,8 @@ export class BlockProverProgrammable extends ZkProgrammable<
769779
blockHashRoot: proof2.publicOutput.blockHashRoot,
770780
eternalTransactionsHash: proof2.publicOutput.eternalTransactionsHash,
771781
incomingMessagesHash: proof2.publicOutput.incomingMessagesHash,
772-
// Provable.if(isValidClosedMerge, Bool(true), Bool(false));
773782
closed: isValidClosedMerge,
774-
blockNumber: proof2Height,
783+
blockNumber: proof2.publicOutput.blockNumber,
775784
});
776785
}
777786

packages/protocol/src/prover/statetransition/StateTransitionProvable.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ import { WithZkProgrammable } from "@proto-kit/common";
33

44
import { StateTransitionProvableBatch } from "../../model/StateTransitionProvableBatch";
55

6-
import { StateTransitionWitnessProviderReference } from "./StateTransitionWitnessProviderReference";
7-
86
export class StateTransitionProverPublicInput extends Struct({
97
stateTransitionsHash: Field,
108
protocolTransitionsHash: Field,
@@ -29,8 +27,6 @@ export interface StateTransitionProvable
2927
StateTransitionProverPublicInput,
3028
StateTransitionProverPublicOutput
3129
> {
32-
witnessProviderReference: StateTransitionWitnessProviderReference;
33-
3430
runBatch: (
3531
publicInput: StateTransitionProverPublicInput,
3632
batch: StateTransitionProvableBatch

packages/protocol/src/prover/statetransition/StateTransitionProver.ts

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ import {
2727
StateTransitionProverPublicInput,
2828
StateTransitionProverPublicOutput,
2929
} from "./StateTransitionProvable";
30-
import { StateTransitionWitnessProvider } from "./StateTransitionWitnessProvider";
31-
import { StateTransitionWitnessProviderReference } from "./StateTransitionWitnessProviderReference";
3230

3331
const errors = {
3432
propertyNotMatching: (property: string, step: string) =>
@@ -75,8 +73,7 @@ export class StateTransitionProverProgrammable extends ZkProgrammable<
7573
StateTransitionProverPublicOutput
7674
> {
7775
public constructor(
78-
private readonly stateTransitionProver: StateTransitionProver,
79-
public readonly witnessProviderReference: StateTransitionWitnessProviderReference
76+
private readonly stateTransitionProver: StateTransitionProver
8077
) {
8178
super();
8279
}
@@ -143,14 +140,6 @@ export class StateTransitionProverProgrammable extends ZkProgrammable<
143140
];
144141
}
145142

146-
private get witnessProvider(): StateTransitionWitnessProvider {
147-
const provider = this.witnessProviderReference.getWitnessProvider();
148-
if (provider === undefined) {
149-
throw errors.noWitnessProviderSet();
150-
}
151-
return provider;
152-
}
153-
154143
/**
155144
* Applies the state transitions to the current stateRoot
156145
* and returns the new prover state
@@ -179,12 +168,19 @@ export class StateTransitionProverProgrammable extends ZkProgrammable<
179168

180169
const transitions = transitionBatch.batch;
181170
const types = transitionBatch.transitionTypes;
171+
const merkleWitness = transitionBatch.merkleWitnesses;
182172
for (
183173
let index = 0;
184174
index < constants.stateTransitionProverBatchSize;
185175
index++
186176
) {
187-
this.applyTransition(state, transitions[index], types[index], index);
177+
this.applyTransition(
178+
state,
179+
transitions[index],
180+
types[index],
181+
merkleWitness[index],
182+
index
183+
);
188184
}
189185

190186
return state;
@@ -198,13 +194,10 @@ export class StateTransitionProverProgrammable extends ZkProgrammable<
198194
state: StateTransitionProverExecutionState,
199195
transition: ProvableStateTransition,
200196
type: ProvableStateTransitionType,
197+
merkleWitness: RollupMerkleTreeWitness,
201198
index = 0
202199
) {
203-
const witness = Provable.witness(RollupMerkleTreeWitness, () =>
204-
this.witnessProvider.getWitness(Field(transition.path.toString()))
205-
);
206-
207-
const membershipValid = witness.checkMembership(
200+
const membershipValid = merkleWitness.checkMembership(
208201
state.stateRoot,
209202
transition.path,
210203
transition.from.value
@@ -214,7 +207,7 @@ export class StateTransitionProverProgrammable extends ZkProgrammable<
214207
.or(transition.from.isSome.not())
215208
.assertTrue(errors.merkleWitnessNotCorrect(index, type));
216209

217-
const newRoot = witness.calculateRoot(transition.to.value);
210+
const newRoot = merkleWitness.calculateRoot(transition.to.value);
218211

219212
state.stateRoot = Provable.if(
220213
transition.to.isSome,
@@ -349,15 +342,9 @@ export class StateTransitionProver
349342
{
350343
public zkProgrammable: StateTransitionProverProgrammable;
351344

352-
public constructor(
353-
// Injected
354-
public readonly witnessProviderReference: StateTransitionWitnessProviderReference
355-
) {
345+
public constructor() {
356346
super();
357-
this.zkProgrammable = new StateTransitionProverProgrammable(
358-
this,
359-
witnessProviderReference
360-
);
347+
this.zkProgrammable = new StateTransitionProverProgrammable(this);
361348
}
362349

363350
public runBatch(

0 commit comments

Comments
 (0)