@@ -82,7 +82,7 @@ pub struct RecursionCircuit<ST> {
8282 default_accumulator : KzgAccumulator < G1Affine , NativeLoader > ,
8383 /// The SNARK witness from the k-th BatchCircuit.
8484 app : SnarkWitness ,
85- /// The SNARK witness from the (k-1)-th BatchCircuit.
85+ /// The SNARK witness from the previous RecursionCircuit, i.e. RecursionCircuit up to the (k-1)-th BatchCircuit.
8686 previous : SnarkWitness ,
8787 /// The recursion round, starting at round=0 and incrementing at every subsequent recursion.
8888 round : usize ,
@@ -302,7 +302,7 @@ impl<ST: StateTransition> Circuit<Fr> for RecursionCircuit<ST> {
302302 // The index of the "state", i.e. the state achieved post the current batch.
303303 let index_state = index_init_state + ST :: num_transition_instance ( ) ;
304304 // The index where the "additional" fields required to define the state are
305- // present.
305+ // present. The first field in the "additional" fields is the chain ID.
306306 let index_additional_state = index_state + ST :: num_transition_instance ( ) ;
307307 // The index to find the "round" of recursion in the current instance of the
308308 // Recursion Circuit.
@@ -441,6 +441,28 @@ impl<ST: StateTransition> Circuit<Fr> for RecursionCircuit<ST> {
441441 . map ( |( & st, & app_inst) | ( "passing cur state to app" , st, app_inst) )
442442 . collect :: < Vec < _ > > ( ) ;
443443
444+ // Pick additional inst part in "previous state", verify the items at the front
445+ // is currently propagated to the app inst which is marked as "propagated"
446+ let propagate_app_states = previous_instances[ index_additional_state..index_round]
447+ . iter ( )
448+ . zip (
449+ ST :: propagate_indices ( )
450+ . into_iter ( )
451+ . map ( |i| & app_instances[ i] ) ,
452+ )
453+ . map ( |( & st, & app_propagated_inst) | {
454+ (
455+ "propagate additional states in app (not first round)" ,
456+ main_gate. mul (
457+ & mut ctx,
458+ Existing ( app_propagated_inst) ,
459+ Existing ( not_first_round) ,
460+ ) ,
461+ st,
462+ )
463+ } )
464+ . collect :: < Vec < _ > > ( ) ;
465+
444466 // Verify that the "previous state" (additional state not included) is the same
445467 // as the previous state defined in the current application SNARK. This check is
446468 // meaningful only in subsequent recursion rounds after the first round.
@@ -465,7 +487,7 @@ impl<ST: StateTransition> Circuit<Fr> for RecursionCircuit<ST> {
465487 for ( comment, lhs, rhs) in [
466488 // Propagate the preprocessed digest.
467489 (
468- "chain preprocessed digest" ,
490+ "propagate preprocessed digest" ,
469491 main_gate. mul (
470492 & mut ctx,
471493 Existing ( preprocessed_digest) ,
@@ -475,7 +497,7 @@ impl<ST: StateTransition> Circuit<Fr> for RecursionCircuit<ST> {
475497 ) ,
476498 // Verify that "round" increments by 1 when not the first round of recursion.
477499 (
478- "round increment" ,
500+ "increment recursion round " ,
479501 round,
480502 main_gate. add (
481503 & mut ctx,
@@ -488,6 +510,7 @@ impl<ST: StateTransition> Circuit<Fr> for RecursionCircuit<ST> {
488510 . chain ( initial_state_propagate)
489511 . chain ( verify_app_state)
490512 . chain ( verify_app_init_state)
513+ . chain ( propagate_app_states)
491514 {
492515 use halo2_proofs:: dev:: unwrap_value;
493516 debug_assert_eq ! (
0 commit comments