-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Clean up after 'WIP: integration test (#368)' #603
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,7 +19,7 @@ use itertools::{Itertools, MinMaxResult, chain, enumerate}; | |
use mpcs::{Basefold, BasefoldRSParams, PolynomialCommitmentScheme}; | ||
use std::{ | ||
collections::{HashMap, HashSet}, | ||
panic, | ||
panic::{self, PanicHookInfo}, | ||
time::Instant, | ||
}; | ||
use tracing_flame::FlameLayer; | ||
|
@@ -35,6 +35,27 @@ struct Args { | |
max_steps: Option<usize>, | ||
} | ||
|
||
/// Temporarily override the panic hook | ||
/// | ||
/// We restore the original hook after we are done. | ||
fn with_panic_hook<F, R>(hook: Box<dyn Fn(&PanicHookInfo<'_>) + Sync + Send + 'static>, f: F) -> R | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel this is a bit cleaner for the reader to extract, then inlining it into the code further down. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might as well go to the root cause and change the assert to a returned error. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Interesting suggestion. Can you make a PR for that, please? I didn't want to change the behaviour here, just conservatively make the code that we have easier to understand. |
||
where | ||
F: FnOnce() -> R, | ||
{ | ||
// Save the current panic hook | ||
let original_hook = panic::take_hook(); | ||
|
||
// Set the new panic hook | ||
panic::set_hook(hook); | ||
|
||
let result = f(); | ||
|
||
// Restore the original panic hook | ||
panic::set_hook(original_hook); | ||
|
||
result | ||
} | ||
|
||
fn main() { | ||
let args = Args::parse(); | ||
|
||
|
@@ -125,7 +146,7 @@ fn main() { | |
|
||
let pk = zkvm_cs | ||
.clone() | ||
.key_gen::<Pcs>(pp.clone(), vp.clone(), zkvm_fixed_traces.clone()) | ||
.key_gen::<Pcs>(pp, vp, zkvm_fixed_traces.clone()) | ||
.expect("keygen failed"); | ||
let vk = pk.get_vk(); | ||
|
||
|
@@ -153,14 +174,14 @@ fn main() { | |
record.insn().codes().kind == EANY | ||
&& record.rs1().unwrap().value == CENO_PLATFORM.ecall_halt() | ||
}) | ||
.and_then(|halt_record| halt_record.rs2()) | ||
.and_then(StepRecord::rs2) | ||
.map(|rs2| rs2.value); | ||
|
||
let final_access = vm.tracer().final_accesses(); | ||
let end_cycle: u32 = vm.tracer().cycle().try_into().unwrap(); | ||
|
||
let pi = PublicValues::new( | ||
exit_code.unwrap_or(0), | ||
exit_code.unwrap_or_default(), | ||
vm.program().entry, | ||
Tracer::SUBCYCLES_PER_INSN as u32, | ||
vm.get_pc().into(), | ||
|
@@ -188,7 +209,7 @@ fn main() { | |
MemFinalRecord { | ||
addr: rec.addr, | ||
value: vm.peek_register(index), | ||
cycle: *final_access.get(&vma).unwrap_or(&0), | ||
cycle: final_access.get(&vma).copied().unwrap_or_default(), | ||
} | ||
} else { | ||
// The table is padded beyond the number of registers. | ||
|
@@ -209,7 +230,7 @@ fn main() { | |
MemFinalRecord { | ||
addr: rec.addr, | ||
value: vm.peek_memory(vma), | ||
cycle: *final_access.get(&vma).unwrap_or(&0), | ||
cycle: final_access.get(&vma).copied().unwrap_or_default(), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 0 is the intended value. No reason to hide it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm fine either way here. |
||
} | ||
}) | ||
.collect_vec(); | ||
|
@@ -218,7 +239,12 @@ fn main() { | |
// Find the final public IO cycles. | ||
let io_final = io_init | ||
.iter() | ||
.map(|rec| *final_access.get(&rec.addr.into()).unwrap_or(&0)) | ||
.map(|rec| { | ||
final_access | ||
.get(&rec.addr.into()) | ||
.copied() | ||
.unwrap_or_default() | ||
}) | ||
.collect_vec(); | ||
|
||
// assign table circuits | ||
|
@@ -269,18 +295,16 @@ fn main() { | |
} | ||
|
||
let transcript = Transcript::new(b"riscv"); | ||
// change public input maliciously should cause verifier to reject proof | ||
// Maliciously changing the public input should cause the verifier to reject the proof. | ||
zkvm_proof.raw_pi[0] = vec![<GoldilocksExt2 as ff_ext::ExtensionField>::BaseField::ONE]; | ||
zkvm_proof.raw_pi[1] = vec![<GoldilocksExt2 as ff_ext::ExtensionField>::BaseField::ONE]; | ||
|
||
// capture panic message, if have | ||
let default_hook = panic::take_hook(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @lispc Here's an example where I had some (minor) trouble understanding what the original code tried to do. So I cleaned it up into its own helper function, in order to make the job of the next reader down the line a bit easier. |
||
panic::set_hook(Box::new(|_info| { | ||
// by default it will print msg to stdout/stderr | ||
// we override it to avoid print msg since we will capture the msg by our own | ||
})); | ||
let result = panic::catch_unwind(|| verifier.verify_proof(zkvm_proof, transcript)); | ||
panic::set_hook(default_hook); | ||
// capture panic message, if any | ||
// by default it will print msg to stdout/stderr | ||
// we override it to avoid print msg since we will capture the msg by ourselves | ||
let result = with_panic_hook(Box::new(|_info| ()), || { | ||
panic::catch_unwind(|| verifier.verify_proof(zkvm_proof, transcript)) | ||
}); | ||
match result { | ||
Ok(res) => { | ||
res.expect_err("verify proof should return with error"); | ||
|
@@ -322,23 +346,24 @@ fn debug_memory_ranges(vm: &VMState, mem_final: &[MemFinalRecord]) { | |
|
||
tracing::debug!( | ||
"Memory range (accessed): {:?}", | ||
format_segments(vm.platform(), accessed_addrs.iter().copied()) | ||
format_segments(vm.platform(), &accessed_addrs) | ||
); | ||
tracing::debug!( | ||
"Memory range (handled): {:?}", | ||
format_segments(vm.platform(), handled_addrs.iter().copied()) | ||
format_segments(vm.platform(), &handled_addrs) | ||
); | ||
|
||
for addr in &accessed_addrs { | ||
assert!(handled_addrs.contains(addr), "unhandled addr: {:?}", addr); | ||
} | ||
} | ||
|
||
fn format_segments( | ||
fn format_segments<'a>( | ||
platform: &Platform, | ||
addrs: impl Iterator<Item = ByteAddr>, | ||
) -> HashMap<String, MinMaxResult<ByteAddr>> { | ||
addrs: impl IntoIterator<Item = &'a ByteAddr>, | ||
) -> HashMap<String, MinMaxResult<&'a ByteAddr>> { | ||
addrs | ||
.into_iter() | ||
.into_grouping_map_by(|addr| format_segment(platform, addr.0)) | ||
.minmax() | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -46,11 +46,7 @@ impl<E: ExtensionField> MmuConfig<E> { | |
io_addrs: &[Addr], | ||
) { | ||
assert!( | ||
chain( | ||
static_mem_init.iter().map(|record| record.addr), | ||
io_addrs.iter().copied(), | ||
) | ||
.all_unique(), | ||
chain(static_mem_init.iter().map(|record| &record.addr), io_addrs,).all_unique(), | ||
"memory addresses must be unique" | ||
); | ||
|
||
|
@@ -142,14 +138,9 @@ impl MemPadder { | |
new_len: usize, | ||
records: Vec<MemInitRecord>, | ||
) -> Vec<MemInitRecord> { | ||
if records.is_empty() { | ||
self.padded(new_len, records) | ||
} else { | ||
self.padded(new_len, records) | ||
.into_iter() | ||
.sorted_by_key(|record| record.addr) | ||
.collect() | ||
} | ||
let mut padded = self.padded(new_len, records); | ||
padded.sort_by_key(|record| record.addr); | ||
padded | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This does extra work without being clearer when we just want the default content. If you really want to remove that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, I didn't actually care that much about the But while I was at it, I also simplified the structured by removing the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ho ok if that was about speed, I think that is zero-cost, it does the same thing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
} | ||
|
||
/// Pad `records` to `new_len` using unused addresses. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not something based on
take_while
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's exactly what I thought as well! But both
halted
andstep
want to borrowself
, so the borrow checker didn't like that.I was very tempted to take that as a suggestion that we should refactor. But that would have been way beyond the narrow scope of what I was trying to do here.
If you make a PR to that effect, I'm happy to review.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it. I suspect I had tried that too back then 🤣
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we should leave a comment to save the next curious person some head scratching.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There would be a lot of comments if we’d start documenting hypothetical things that don’t work.