@@ -15,6 +15,7 @@ import {
15
15
CompilableModule ,
16
16
CompileArtifact ,
17
17
CompileRegistry ,
18
+ MAX_FIELD ,
18
19
PlainZkProgram ,
19
20
provableMethod ,
20
21
WithZkProgrammable ,
@@ -128,10 +129,6 @@ export interface BlockProverState {
128
129
incomingMessagesHash : Field ;
129
130
}
130
131
131
- function maxField ( ) {
132
- return Field ( Field . ORDER - 1n ) ;
133
- }
134
-
135
132
export type BlockProof = Proof < BlockProverPublicInput , BlockProverPublicOutput > ;
136
133
export type RuntimeProof = Proof < void , MethodPublicOutput > ;
137
134
@@ -422,6 +419,11 @@ export class BlockProverProgrammable extends ZkProgrammable<
422
419
"ExecutionData Networkstate doesn't equal public input hash"
423
420
) ;
424
421
422
+ publicInput . blockNumber . assertEquals (
423
+ MAX_FIELD ,
424
+ "blockNumber has to be MAX for transaction proofs"
425
+ ) ;
426
+
425
427
// Verify the [methodId, vk] tuple against the baked-in vk tree root
426
428
const { verificationKey, witness : verificationKeyTreeWitness } =
427
429
verificationKeyWitness ;
@@ -451,7 +453,7 @@ export class BlockProverProgrammable extends ZkProgrammable<
451
453
452
454
return new BlockProverPublicOutput ( {
453
455
...stateTo ,
454
- blockNumber : maxField ( ) ,
456
+ blockNumber : publicInput . blockNumber ,
455
457
closed : Bool ( false ) ,
456
458
} ) ;
457
459
}
@@ -534,14 +536,14 @@ export class BlockProverProgrammable extends ZkProgrammable<
534
536
// stateTransitionProof.verifyIf(Bool(false));
535
537
// stateTransitionProof.verifyIf(stsEmitted);
536
538
537
- // Verify Transaction proof if it has at least 1 tx
539
+ // Verify Transaction proof if it has at least 1 tx - i.e. the
540
+ // input and output doesn't match fully
538
541
// We have to compare the whole input and output because we can make no
539
542
// assumptions about the values, since it can be an arbitrary dummy-proof
540
543
const txProofOutput = transactionProof . publicOutput ;
541
544
const isEmptyTransition = txProofOutput . equals (
542
545
transactionProof . publicInput ,
543
- txProofOutput . closed ,
544
- txProofOutput . blockNumber
546
+ txProofOutput . closed
545
547
) ;
546
548
Provable . log ( "VerifyIf 2" , isEmptyTransition . not ( ) ) ;
547
549
transactionProof . verifyIf ( isEmptyTransition . not ( ) ) ;
@@ -626,6 +628,8 @@ export class BlockProverProgrammable extends ZkProgrammable<
626
628
// Calculate the new block index
627
629
const blockIndex = blockWitness . calculateIndex ( ) ;
628
630
631
+ blockIndex . assertEquals ( publicInput . blockNumber ) ;
632
+
629
633
blockWitness
630
634
. calculateRoot ( Field ( 0 ) )
631
635
. assertEquals (
@@ -643,7 +647,7 @@ export class BlockProverProgrammable extends ZkProgrammable<
643
647
644
648
return new BlockProverPublicOutput ( {
645
649
...state ,
646
- blockNumber : blockIndex ,
650
+ blockNumber : blockIndex . add ( 1 ) ,
647
651
closed : Bool ( true ) ,
648
652
} ) ;
649
653
}
@@ -750,19 +754,25 @@ export class BlockProverProgrammable extends ZkProgrammable<
750
754
// assert proof1.height == proof2.height
751
755
// }
752
756
753
- const proof1Height = proof1 . publicOutput . blockNumber ;
754
757
const proof1Closed = proof1 . publicOutput . closed ;
755
- const proof2Height = proof2 . publicOutput . blockNumber ;
756
758
const proof2Closed = proof2 . publicOutput . closed ;
757
759
758
- const isValidTransactionMerge = proof1Height
759
- . equals ( maxField ( ) )
760
- . and ( proof2Height . equals ( proof1Height ) )
760
+ const blockNumberProgressionValid = publicInput . blockNumber
761
+ . equals ( proof1 . publicInput . blockNumber )
762
+ . and (
763
+ proof1 . publicOutput . blockNumber . equals ( proof2 . publicInput . blockNumber )
764
+ ) ;
765
+
766
+ // For tx proofs, we check that the progression starts and end with MAX
767
+ // in addition to that both proofs are non-closed
768
+ const isValidTransactionMerge = publicInput . blockNumber
769
+ . equals ( MAX_FIELD )
770
+ . and ( blockNumberProgressionValid )
761
771
. and ( proof1Closed . or ( proof2Closed ) . not ( ) ) ;
762
772
763
773
const isValidClosedMerge = proof1Closed
764
774
. and ( proof2Closed )
765
- . and ( proof1Height . add ( 1 ) . equals ( proof2Height ) ) ;
775
+ . and ( blockNumberProgressionValid ) ;
766
776
767
777
isValidTransactionMerge
768
778
. or ( isValidClosedMerge )
@@ -775,9 +785,8 @@ export class BlockProverProgrammable extends ZkProgrammable<
775
785
blockHashRoot : proof2 . publicOutput . blockHashRoot ,
776
786
eternalTransactionsHash : proof2 . publicOutput . eternalTransactionsHash ,
777
787
incomingMessagesHash : proof2 . publicOutput . incomingMessagesHash ,
778
- // Provable.if(isValidClosedMerge, Bool(true), Bool(false));
779
788
closed : isValidClosedMerge ,
780
- blockNumber : proof2Height ,
789
+ blockNumber : proof2 . publicOutput . blockNumber ,
781
790
} ) ;
782
791
}
783
792
0 commit comments