@@ -357,7 +357,7 @@ impl<'a, C: CircuitsParams> CircuitInputBuilder<C> {
357
357
// Optain the first op of the next GethExecStep, for fixed case also lookahead
358
358
let ( mut cib, mut tx, mut tx_ctx) = ( self . clone ( ) , tx, tx_ctx) ;
359
359
let mut cib_ref = cib. state_ref ( & mut tx, & mut tx_ctx) ;
360
- let next_ops = if let Some ( ( i, step) ) = next_geth_step {
360
+ let mut next_ops = if let Some ( ( i, step) ) = next_geth_step {
361
361
log:: trace!( "chunk at {}th opcode {:?} " , i, step. op) ;
362
362
gen_associated_ops ( & step. op , & mut cib_ref, & geth_trace. struct_logs [ i..] ) ?. remove ( 0 )
363
363
} else {
@@ -368,10 +368,14 @@ impl<'a, C: CircuitsParams> CircuitInputBuilder<C> {
368
368
let last_copy = self . block . copy_events . len ( ) ;
369
369
// Generate EndChunk and proceed to the next if it's not the last chunk
370
370
// Set next step pre-state as end_chunk state
371
- self . set_end_chunk ( & next_ops) ;
371
+ self . set_end_chunk ( & next_ops, Some ( & tx) ) ;
372
+
373
+ // need to update next_ops.rwc to catch block_ctx.rwc in `set_end_chunk`
374
+ next_ops. rwc = self . block_ctx . rwc ;
375
+
372
376
// tx.id start from 1, so it's equivalent to `next_tx_index`
373
377
self . commit_chunk_ctx ( true , tx. id as usize , last_copy, last_call) ;
374
- self . set_begin_chunk ( & next_ops) ;
378
+ self . set_begin_chunk ( & next_ops, Some ( & tx ) ) ;
375
379
376
380
Ok ( ( ) )
377
381
}
@@ -394,13 +398,12 @@ impl<'a, C: CircuitsParams> CircuitInputBuilder<C> {
394
398
let mut tx_ctx = TransactionContext :: new ( eth_tx, geth_trace, is_last_tx) ?;
395
399
396
400
let res = if !geth_trace. invalid {
397
- let mut last_call = None ;
398
-
399
401
// Generate BeginTx step
400
402
let begin_tx_step = gen_associated_steps (
401
403
& mut self . state_ref ( & mut tx, & mut tx_ctx) ,
402
404
ExecState :: BeginTx ,
403
405
) ?;
406
+ let mut last_call = Some ( tx. calls ( ) . get ( begin_tx_step. call_index ) . unwrap ( ) . clone ( ) ) ;
404
407
tx. steps_mut ( ) . push ( begin_tx_step) ;
405
408
406
409
let mut trace = geth_trace. struct_logs . iter ( ) . enumerate ( ) . peekable ( ) ;
@@ -416,9 +419,10 @@ impl<'a, C: CircuitsParams> CircuitInputBuilder<C> {
416
419
// Proceed to the next step
417
420
let ( i, step) = trace. next ( ) . expect ( "Peeked step should exist" ) ;
418
421
log:: trace!(
419
- "handle {}th opcode {:?} rws = {:?}" ,
422
+ "handle {}th opcode {:?} {:?} rws = {:?}" ,
420
423
i,
421
424
step. op,
425
+ step,
422
426
self . chunk_rws( )
423
427
) ;
424
428
let exec_steps = gen_associated_ops (
@@ -466,9 +470,13 @@ impl<'a, C: CircuitsParams> CircuitInputBuilder<C> {
466
470
Ok ( res)
467
471
}
468
472
469
- // TODO Fix this, for current logic on processing `call` is incorrect
470
- // TODO re-design `gen_chunk_associated_steps` to separate RW
471
- fn gen_chunk_associated_steps ( & mut self , step : & mut ExecStep , rw : RW ) {
473
+ // generate chunk related steps
474
+ fn gen_chunk_associated_steps (
475
+ & mut self ,
476
+ step : & mut ExecStep ,
477
+ rw : RW ,
478
+ tx : Option < & Transaction > ,
479
+ ) {
472
480
let STEP_STATE_LEN = 10 ;
473
481
let mut dummy_tx = Transaction :: default ( ) ;
474
482
let mut dummy_tx_ctx = TransactionContext :: default ( ) ;
@@ -483,12 +491,10 @@ impl<'a, C: CircuitsParams> CircuitInputBuilder<C> {
483
491
484
492
let tags = {
485
493
let state = self . state_ref ( & mut dummy_tx, & mut dummy_tx_ctx) ;
486
- let last_call = state
487
- . block
488
- . txs
489
- . last ( )
490
- . map ( |tx| tx. calls [ 0 ] . clone ( ) )
491
- . unwrap_or_else ( Call :: default) ;
494
+ let last_call = tx
495
+ . map ( |tx| tx. calls ( ) [ step. call_index ] . clone ( ) )
496
+ . or_else ( || state. block . txs . last ( ) . map ( |tx| tx. calls [ 0 ] . clone ( ) ) )
497
+ . unwrap ( ) ;
492
498
[
493
499
( StepStateField :: CodeHash , last_call. code_hash . to_word ( ) ) ,
494
500
( StepStateField :: CallID , Word :: from ( last_call. call_id ) ) ,
@@ -551,24 +557,44 @@ impl<'a, C: CircuitsParams> CircuitInputBuilder<C> {
551
557
self . chunk_ctx . end_copy_index = next_copy_index;
552
558
self . cur_chunk_mut ( ) . ctx = self . chunk_ctx . clone ( ) ;
553
559
if to_next {
560
+ // here use `-1` to include previous set
554
561
self . chunk_ctx
555
- . bump ( self . block_ctx . rwc . 0 , next_tx_index, next_copy_index) ;
562
+ . bump ( self . block_ctx . rwc . 0 , next_tx_index - 1 , next_copy_index) ;
563
+ // println!("bump last_call {:?}", last_call);
564
+ if last_call. is_none ( ) {
565
+ panic ! ( "??" )
566
+ }
556
567
self . cur_chunk_mut ( ) . prev_last_call = last_call;
557
568
}
558
569
}
559
570
560
- fn set_begin_chunk ( & mut self , first_step : & ExecStep ) {
561
- let mut begin_chunk = first_step. clone ( ) ;
562
- begin_chunk. exec_state = ExecState :: BeginChunk ;
563
- self . gen_chunk_associated_steps ( & mut begin_chunk, RW :: READ ) ;
571
+ fn set_begin_chunk ( & mut self , first_step : & ExecStep , tx : Option < & Transaction > ) {
572
+ let mut begin_chunk = ExecStep {
573
+ exec_state : ExecState :: BeginChunk ,
574
+ rwc : first_step. rwc ,
575
+ gas_left : first_step. gas_left ,
576
+ call_index : first_step. call_index ,
577
+ ..ExecStep :: default ( )
578
+ } ;
579
+ self . gen_chunk_associated_steps ( & mut begin_chunk, RW :: READ , tx) ;
580
+ println ! ( "in set begin chunk {:?}" , begin_chunk) ;
564
581
self . chunks [ self . chunk_ctx . idx ] . begin_chunk = Some ( begin_chunk) ;
565
582
}
566
583
567
- fn set_end_chunk ( & mut self , next_step : & ExecStep ) {
568
- let mut end_chunk = next_step. clone ( ) ;
569
- end_chunk. exec_state = ExecState :: EndChunk ;
570
- self . gen_chunk_associated_steps ( & mut end_chunk, RW :: WRITE ) ;
584
+ fn set_end_chunk ( & mut self , next_step : & ExecStep , tx : Option < & Transaction > ) {
585
+ println ! ( "before self.block_ctx.rwc.0 {}" , self . block_ctx. rwc. 0 ) ;
586
+ // println!("next step {:?}", next_step);
587
+ let mut end_chunk = ExecStep {
588
+ exec_state : ExecState :: EndChunk ,
589
+ rwc : next_step. rwc ,
590
+ rwc_inner_chunk : next_step. rwc_inner_chunk ,
591
+ gas_left : next_step. gas_left ,
592
+ call_index : next_step. call_index ,
593
+ ..ExecStep :: default ( )
594
+ } ;
595
+ self . gen_chunk_associated_steps ( & mut end_chunk, RW :: WRITE , tx) ;
571
596
self . gen_chunk_padding ( & mut end_chunk) ;
597
+ println ! ( "after self.block_ctx.rwc.0 {}" , self . block_ctx. rwc. 0 ) ;
572
598
self . chunks [ self . chunk_ctx . idx ] . end_chunk = Some ( end_chunk) ;
573
599
}
574
600
@@ -578,8 +604,6 @@ impl<'a, C: CircuitsParams> CircuitInputBuilder<C> {
578
604
let total_rws = end_rwc - 1 ;
579
605
let max_rws = self . cur_chunk ( ) . fixed_param . max_rws ;
580
606
581
- // We need at least 1 extra row at offset 0 for chunk continuous
582
- // FIXME(Cecilia): adding + 1 fail some tests
583
607
assert ! (
584
608
total_rws < max_rws,
585
609
"total_rws <= max_rws, total_rws={}, max_rws={}" ,
@@ -707,17 +731,26 @@ impl CircuitInputBuilder<FixedCParams> {
707
731
eth_block : & EthBlock ,
708
732
geth_traces : & [ eth_types:: GethExecTrace ] ,
709
733
) -> Result < CircuitInputBuilder < FixedCParams > , Error > {
710
- println ! ( "--------------{:?}" , self . circuits_params) ;
711
734
// accumulates gas across all txs in the block
712
735
let ( last_step, last_call) = self . begin_handle_block ( eth_block, geth_traces) ?;
713
- let last_step = last_step. unwrap_or_default ( ) ;
736
+ // since there is no next step, we cook dummy next step from last step to reuse
737
+ // existing field while update its `rwc`.
738
+ let mut dummy_next_step = {
739
+ let mut dummy_next_step = last_step. unwrap_or_default ( ) ;
740
+ // raise last step rwc to match with next step
741
+ ( 0 ..dummy_next_step. rw_indices_len ( ) ) . for_each ( |_| {
742
+ dummy_next_step. rwc . inc_pre ( ) ;
743
+ dummy_next_step. rwc_inner_chunk . inc_pre ( ) ;
744
+ } ) ;
745
+ dummy_next_step
746
+ } ;
714
747
715
748
assert ! ( self . circuits_params. max_rws( ) . is_some( ) ) ;
716
749
717
750
let last_copy = self . block . copy_events . len ( ) ;
718
751
719
752
// TODO figure out and resolve generic param type and move fixed_param set inside
720
- // commit_chunk_ctx After fixed, then we can set fixed_param on all chunks
753
+ // commit_chunk_ctx. After fixed, then we can set fixed_param on all chunks
721
754
( 0 ..self . circuits_params . total_chunks ( ) ) . for_each ( |idx| {
722
755
self . get_chunk_mut ( idx) . fixed_param = self . circuits_params ;
723
756
} ) ;
@@ -734,16 +767,29 @@ impl CircuitInputBuilder<FixedCParams> {
734
767
last_call. clone ( ) ,
735
768
) ;
736
769
} else {
737
- // it doent matter what step was put to set_end_chunk/set_begin_chunk on no-used
738
- // chunks before end_block. Just need to make sure it's step lookup is consistency.
739
- self . set_end_chunk ( & last_step) ;
770
+ self . set_end_chunk ( & dummy_next_step, None ) ;
771
+
740
772
self . commit_chunk_ctx (
741
773
true ,
742
774
eth_block. transactions . len ( ) ,
743
775
last_copy,
744
776
last_call. clone ( ) ,
745
777
) ;
746
- self . set_begin_chunk ( & last_step) ;
778
+ // update dummy_next_step rwc to be used for next
779
+ dummy_next_step. rwc = self . block_ctx . rwc ;
780
+ dummy_next_step. rwc_inner_chunk = self . chunk_ctx . rwc ;
781
+ self . set_begin_chunk ( & dummy_next_step, None ) ;
782
+ dummy_next_step. rwc = self . block_ctx . rwc ;
783
+ dummy_next_step. rwc_inner_chunk = self . chunk_ctx . rwc ;
784
+ // update virtual step: end_block/padding so it can carry state context correctly
785
+ // TODO: enhance virtual step updating mechanism by having `running_next_step`
786
+ // defined in circuit_input_builder, so we dont need to
787
+ self . block . end_block = dummy_next_step. clone ( ) ;
788
+ self . cur_chunk_mut ( ) . padding = {
789
+ let mut padding = dummy_next_step. clone ( ) ;
790
+ padding. exec_state = ExecState :: Padding ;
791
+ Some ( padding)
792
+ } ;
747
793
}
748
794
Ok :: < ( ) , Error > ( ( ) )
749
795
} ) ?;
@@ -773,6 +819,7 @@ impl CircuitInputBuilder<FixedCParams> {
773
819
fn set_end_block ( & mut self ) -> Result < ( ) , Error > {
774
820
let mut end_block = self . block . end_block . clone ( ) ;
775
821
end_block. rwc = self . block_ctx . rwc ;
822
+ end_block. exec_state = ExecState :: EndBlock ;
776
823
end_block. rwc_inner_chunk = self . chunk_ctx . rwc ;
777
824
778
825
let mut dummy_tx = Transaction :: default ( ) ;
0 commit comments