@@ -19,7 +19,9 @@ use crate::cpu::columns::CpuColumnsView;
1919use crate :: cpu:: kernel:: aggregator:: KERNEL ;
2020use crate :: cpu:: kernel:: constants:: global_metadata:: GlobalMetadata ;
2121use crate :: generation:: debug_inputs;
22+ use crate :: generation:: jumpdest:: { ContextJumpDests , JumpDestTableProcessed , JumpDestTableWitness } ;
2223use crate :: generation:: mpt:: { load_linked_lists_and_txn_and_receipt_mpts, TrieRootPtrs } ;
24+ use crate :: generation:: prover_input:: { get_proofs_and_jumpdests, CodeMap } ;
2325use crate :: generation:: rlp:: all_rlp_prover_inputs_reversed;
2426use crate :: generation:: state:: {
2527 all_ger_prover_inputs_reversed, all_withdrawals_prover_inputs_reversed, GenerationState ,
@@ -56,6 +58,7 @@ pub(crate) struct Interpreter<F: Field> {
5658 /// Counts the number of appearances of each opcode. For debugging purposes.
5759 #[ allow( unused) ]
5860 pub ( crate ) opcode_count : [ usize ; 0x100 ] ,
61+ /// A table of contexts and their reached JUMPDESTs.
5962 jumpdest_table : HashMap < usize , BTreeSet < usize > > ,
6063 /// `true` if the we are currently carrying out a jumpdest analysis.
6164 pub ( crate ) is_jumpdest_analysis : bool ,
@@ -71,9 +74,10 @@ pub(crate) struct Interpreter<F: Field> {
7174pub ( crate ) fn simulate_cpu_and_get_user_jumps < F : Field > (
7275 final_label : & str ,
7376 state : & GenerationState < F > ,
74- ) -> Option < HashMap < usize , Vec < usize > > > {
77+ // TODO(einar): remove second component of pair.
78+ ) -> ( Option < JumpDestTableProcessed > , ContextJumpDests ) {
7579 match state. jumpdest_table {
76- Some ( _) => None ,
80+ Some ( _) => Default :: default ( ) ,
7781 None => {
7882 let halt_pc = KERNEL . global_labels [ final_label] ;
7983 let initial_context = state. registers . context ;
@@ -94,14 +98,16 @@ pub(crate) fn simulate_cpu_and_get_user_jumps<F: Field>(
9498
9599 interpreter
96100 . generation_state
97- . set_jumpdest_analysis_inputs ( interpreter. jumpdest_table ) ;
101+ . set_jumpdest_analysis_inputs ( interpreter. jumpdest_table . clone ( ) ) ;
98102
99103 log:: debug!(
100104 "Simulated CPU for jumpdest analysis halted after {:?} cycles." ,
101105 clock
102106 ) ;
103-
104- interpreter. generation_state . jumpdest_table
107+ (
108+ interpreter. generation_state . jumpdest_table ,
109+ ContextJumpDests ( interpreter. jumpdest_table ) ,
110+ )
105111 }
106112 }
107113}
@@ -114,7 +120,7 @@ pub(crate) struct ExtraSegmentData {
114120 pub ( crate ) withdrawal_prover_inputs : Vec < U256 > ,
115121 pub ( crate ) ger_prover_inputs : Vec < U256 > ,
116122 pub ( crate ) trie_root_ptrs : TrieRootPtrs ,
117- pub ( crate ) jumpdest_table : Option < HashMap < usize , Vec < usize > > > ,
123+ pub ( crate ) jumpdest_table : Option < JumpDestTableProcessed > ,
118124 pub ( crate ) next_txn_index : usize ,
119125}
120126
@@ -148,6 +154,49 @@ pub(crate) fn set_registers_and_run<F: Field>(
148154 interpreter. run ( )
149155}
150156
157+ /// Computes the JUMPDEST proofs for each context.
158+ ///
159+ /// # Arguments
160+ ///
161+ /// - `jumpdest_table_rpc`: The raw table received from RPC.
162+ /// - `code_db`: The corresponding database of contract code used in the trace.
163+ pub ( crate ) fn set_jumpdest_analysis_inputs_rpc (
164+ jumpdest_table_rpc : & JumpDestTableWitness ,
165+ code_map : & CodeMap ,
166+ ) -> JumpDestTableProcessed {
167+ let ctx_proofs = jumpdest_table_rpc
168+ . 0
169+ . iter ( )
170+ . flat_map ( |( code_addr, ctx_jumpdests) | {
171+ prove_context_jumpdests ( & code_map. 0 [ code_addr] , ctx_jumpdests)
172+ } )
173+ . collect ( ) ;
174+ JumpDestTableProcessed ( ctx_proofs)
175+ }
176+
177+ /// Orchestrates the proving of all contexts in a specific bytecode.
178+ ///
179+ /// # Arguments
180+ ///
181+ /// - `ctx_jumpdests`: Map from `ctx` to its list of offsets to reached
182+ /// `JUMPDEST`s.
183+ /// - `code`: The bytecode for the contexts. This is the same for all contexts.
184+ fn prove_context_jumpdests (
185+ code : & [ u8 ] ,
186+ ctx_jumpdests : & ContextJumpDests ,
187+ ) -> HashMap < usize , Vec < usize > > {
188+ ctx_jumpdests
189+ . 0
190+ . iter ( )
191+ . map ( |( & ctx, jumpdests) | {
192+ let proofs = jumpdests. last ( ) . map_or ( Vec :: default ( ) , |& largest_address| {
193+ get_proofs_and_jumpdests ( code, largest_address, jumpdests. clone ( ) )
194+ } ) ;
195+ ( ctx, proofs)
196+ } )
197+ . collect ( )
198+ }
199+
151200impl < F : Field > Interpreter < F > {
152201 /// Returns an instance of `Interpreter` given `GenerationInputs`, and
153202 /// assuming we are initializing with the `KERNEL` code.
0 commit comments