@@ -32,6 +32,8 @@ use itertools::Itertools;
32
32
use log:: error;
33
33
34
34
use crate :: {
35
+ evm_circuit:: EvmCircuit ,
36
+ keccak_circuit:: KeccakCircuit ,
35
37
table:: { EccTable , LookupTable } ,
36
38
util:: { Challenges , SubCircuit , SubCircuitConfig } ,
37
39
witness:: Block ,
@@ -47,6 +49,12 @@ use util::{
47
49
48
50
use self :: util:: LOG_TOTAL_NUM_ROWS ;
49
51
52
+ macro_rules! log_context_cursor {
53
+ ( $ctx: ident) => { {
54
+ log:: trace!( "Ctx cell pos: {:?}" , $ctx. advice_alloc) ;
55
+ } } ;
56
+ }
57
+
50
58
/// Arguments accepted to configure the EccCircuitConfig.
51
59
#[ derive( Clone , Debug ) ]
52
60
pub struct EccCircuitConfigArgs < F : Field > {
@@ -405,10 +413,16 @@ impl<F: Field, const XI_0: i64> EccCircuit<F, XI_0> {
405
413
powers_of_rand : & [ QuantumCell < F > ] ,
406
414
op : & EcAddOp ,
407
415
) -> EcAddAssigned < F > {
416
+ log:: trace!( "[ECC] ==> EcAdd Assignmnet START:" ) ;
417
+ log_context_cursor ! ( ctx) ;
418
+
408
419
let point_p = self . assign_g1 ( ctx, ecc_chip, op. p , powers_of_rand) ;
409
420
let point_q = self . assign_g1 ( ctx, ecc_chip, op. q , powers_of_rand) ;
410
421
let point_r = self . assign_g1 ( ctx, ecc_chip, op. r , powers_of_rand) ;
411
422
423
+ log:: trace!( "[ECC] EcAdd Inputs Assigned:" ) ;
424
+ log_context_cursor ! ( ctx) ;
425
+
412
426
// We follow the approach mentioned below to handle many edge cases for the points P, Q and
413
427
// R so that we can maintain the same fixed and permutation columns and reduce the overall
414
428
// validation process from the EVM Circuit.
@@ -472,6 +486,8 @@ impl<F: Field, const XI_0: i64> EccCircuit<F, XI_0> {
472
486
473
487
ecc_chip. assert_equal ( ctx, & rand_point, & sum3) ;
474
488
489
+ log:: trace!( "[ECC] EcAdd Assignmnet END:" ) ;
490
+ log_context_cursor ! ( ctx) ;
475
491
EcAddAssigned {
476
492
point_p,
477
493
point_q,
@@ -490,9 +506,16 @@ impl<F: Field, const XI_0: i64> EccCircuit<F, XI_0> {
490
506
powers_of_rand : & [ QuantumCell < F > ] ,
491
507
op : & EcMulOp ,
492
508
) -> EcMulAssigned < F > {
509
+ log:: trace!( "[ECC] ==> EcMul Assignmnet START:" ) ;
510
+ log_context_cursor ! ( ctx) ;
511
+
493
512
let point_p = self . assign_g1 ( ctx, ecc_chip, op. p , powers_of_rand) ;
494
513
let scalar_s = self . assign_fr ( ctx, fr_chip, op. s ) ;
495
514
let point_r = self . assign_g1 ( ctx, ecc_chip, op. r , powers_of_rand) ;
515
+
516
+ log:: trace!( "[ECC] EcMul Inputs Assigned:" ) ;
517
+ log_context_cursor ! ( ctx) ;
518
+
496
519
let point_r_got = ecc_chip. scalar_mult (
497
520
ctx,
498
521
& point_p. decomposed . ec_point ,
@@ -501,6 +524,10 @@ impl<F: Field, const XI_0: i64> EccCircuit<F, XI_0> {
501
524
4 , // TODO: window bits?
502
525
) ;
503
526
ecc_chip. assert_equal ( ctx, & point_r. decomposed . ec_point , & point_r_got) ;
527
+
528
+ log:: trace!( "[ECC] EcMul Assignmnet END:" ) ;
529
+ log_context_cursor ! ( ctx) ;
530
+
504
531
EcMulAssigned {
505
532
point_p,
506
533
scalar_s,
@@ -519,6 +546,9 @@ impl<F: Field, const XI_0: i64> EccCircuit<F, XI_0> {
519
546
powers_of_rand : & [ QuantumCell < F > ] ,
520
547
op : & EcPairingOp ,
521
548
) -> EcPairingAssigned < F > {
549
+ log:: trace!( "[ECC] ==> EcPairing Assignment START:" ) ;
550
+ log_context_cursor ! ( ctx) ;
551
+
522
552
let g1s = op
523
553
. pairs
524
554
. iter ( )
@@ -544,6 +574,10 @@ impl<F: Field, const XI_0: i64> EccCircuit<F, XI_0> {
544
574
}
545
575
} )
546
576
. collect_vec ( ) ;
577
+
578
+ log:: trace!( "[ECC] EcPairing g1s Assigned:" ) ;
579
+ log_context_cursor ! ( ctx) ;
580
+
547
581
let g2s = op
548
582
. pairs
549
583
. iter ( )
@@ -583,6 +617,9 @@ impl<F: Field, const XI_0: i64> EccCircuit<F, XI_0> {
583
617
} )
584
618
. collect_vec ( ) ;
585
619
620
+ log:: trace!( "[ECC] EcPairing g2s Assigned:" ) ;
621
+ log_context_cursor ! ( ctx) ;
622
+
586
623
// RLC over the entire input bytes.
587
624
let input_cells = g1s
588
625
. iter ( )
@@ -606,6 +643,9 @@ impl<F: Field, const XI_0: i64> EccCircuit<F, XI_0> {
606
643
powers_of_rand. iter ( ) . cloned ( ) ,
607
644
) ;
608
645
646
+ log:: trace!( "[ECC] EcPairing Inputs RLC Assigned:" ) ;
647
+ log_context_cursor ! ( ctx) ;
648
+
609
649
let pairs = g1s
610
650
. iter ( )
611
651
. zip ( g2s. iter ( ) )
@@ -630,6 +670,9 @@ impl<F: Field, const XI_0: i64> EccCircuit<F, XI_0> {
630
670
) ) ,
631
671
) ;
632
672
673
+ log:: trace!( "[ECC] EcPairingAssignment END:" ) ;
674
+ log_context_cursor ! ( ctx) ;
675
+
633
676
EcPairingAssigned {
634
677
g1s,
635
678
g2s,
@@ -732,6 +775,19 @@ impl<F: Field, const XI_0: i64> SubCircuit<F> for EccCircuit<F, XI_0> {
732
775
}
733
776
}
734
777
778
+ /// Returns number of unusable rows of the SubCircuit, which should be
779
+ /// `meta.blinding_factors() + 1`.
780
+ fn unusable_rows ( ) -> usize {
781
+ [
782
+ KeccakCircuit :: < F > :: unusable_rows ( ) ,
783
+ EvmCircuit :: < F > :: unusable_rows ( ) ,
784
+ // may include additional subcircuits here
785
+ ]
786
+ . into_iter ( )
787
+ . max ( )
788
+ . unwrap ( )
789
+ }
790
+
735
791
fn synthesize_sub (
736
792
& self ,
737
793
config : & Self :: Config ,
@@ -743,7 +799,33 @@ impl<F: Field, const XI_0: i64> SubCircuit<F> for EccCircuit<F, XI_0> {
743
799
Ok ( ( ) )
744
800
}
745
801
746
- fn min_num_rows_block ( _block : & Block < F > ) -> ( usize , usize ) {
747
- unimplemented ! ( )
802
+ fn min_num_rows_block ( block : & Block < F > ) -> ( usize , usize ) {
803
+ // EccCircuit can't determine usable rows independently.
804
+ // Instead, the blinding area is determined by other advise columns with most counts of
805
+ // rotation queries. This value is typically determined by either the Keccak or EVM
806
+ // circuit.
807
+
808
+ let max_blinding_factor = Self :: unusable_rows ( ) - 1 ;
809
+
810
+ // same formula as halo2-lib's FlexGate
811
+ let row_num = ( 1 << LOG_TOTAL_NUM_ROWS ) - ( max_blinding_factor + 3 ) ;
812
+
813
+ let ec_adds = block. get_ec_add_ops ( ) . len ( ) ;
814
+ let ec_muls = block. get_ec_mul_ops ( ) . len ( ) ;
815
+ let ec_pairings = block. get_ec_pairing_ops ( ) . len ( ) ;
816
+
817
+ // Instead of showing actual minimum row usage,
818
+ // halo2-lib based circuits use min_row_num to represent a percentage of total-used capacity
819
+ // This functionality allows l2geth to decide if additional ops can be added.
820
+ let min_row_num = [
821
+ ( row_num / block. circuits_params . max_ec_ops . ec_add ) * ec_adds,
822
+ ( row_num / block. circuits_params . max_ec_ops . ec_mul ) * ec_muls,
823
+ ( row_num / block. circuits_params . max_ec_ops . ec_pairing ) * ec_pairings,
824
+ ]
825
+ . into_iter ( )
826
+ . max ( )
827
+ . unwrap ( ) ;
828
+
829
+ ( min_row_num, row_num)
748
830
}
749
831
}
0 commit comments