diff --git a/basic/src/bin/valida.rs b/basic/src/bin/valida.rs index c59b45e..d6b9cea 100644 --- a/basic/src/bin/valida.rs +++ b/basic/src/bin/valida.rs @@ -9,7 +9,10 @@ use p3_baby_bear::BabyBear; use p3_fri::{FriConfig, TwoAdicFriPcs, TwoAdicFriPcsConfig}; use valida_cpu::MachineWithCpuChip; -use valida_machine::{Machine, MachineProof, ProgramROM, StdinAdviceProvider, StoppingFlag}; +use valida_machine::{ + AdviceProvider, GlobalAdviceProvider, Machine, MachineProof, ProgramROM, StdinAdviceProvider, + StoppingFlag, +}; use valida_memory::MachineWithMemoryChip; use valida_elf::{load_executable_file, Program}; @@ -51,6 +54,10 @@ struct Args { /// Stack height (which is also the initial frame pointer value) #[arg(long, default_value = "16777216")] stack_height: u32, + + /// Advice file + #[arg(name = "Advice file")] + advice: Option, } struct Context { @@ -61,6 +68,7 @@ struct Context { last_fp_: u32, recorded_current_fp_: u32, last_fp_size_: u32, + advice: GlobalAdviceProvider, } impl Context { @@ -73,6 +81,7 @@ impl Context { last_fp_: args.stack_height, recorded_current_fp_: args.stack_height, last_fp_size_: 0, + advice: GlobalAdviceProvider::new(&args.advice), }; let Program { code, data } = load_executable_file( @@ -93,7 +102,7 @@ impl Context { if self.stopped_ == StoppingFlag::DidStop { return (StoppingFlag::DidStop, 0); } - let state = self.machine_.step(&mut StdinAdviceProvider); + let state = self.machine_.step(&mut self.advice); let pc = self.machine_.cpu().pc; let fp = self.machine_.cpu().fp; @@ -332,7 +341,7 @@ fn main() { machine.static_data_mut().load(data); // Run the program - machine.run(&code, &mut StdinAdviceProvider); + machine.run(&code, &mut GlobalAdviceProvider::new(&args.advice)); type Val = BabyBear; type Challenge = BinomialExtensionField; diff --git a/machine/src/advice.rs b/machine/src/advice.rs index 05ae7b4..7edfefa 100644 --- a/machine/src/advice.rs +++ b/machine/src/advice.rs @@ -1,4 +1,5 @@ use core::slice; +use std::fs::File; use std::io; use std::io::Read; @@ -12,6 +13,20 @@ pub struct FixedAdviceProvider { index: usize, } +enum AdviceProviderType { + Stdin(StdinAdviceProvider), + Fixed(FixedAdviceProvider), +} + +impl AdviceProviderType { + fn get_advice(&mut self) -> Option { + match self { + AdviceProviderType::Stdin(provider) => provider.get_advice(), + AdviceProviderType::Fixed(provider) => provider.get_advice(), + } + } +} + impl FixedAdviceProvider { pub fn empty() -> Self { Self::new(vec![]) @@ -20,6 +35,12 @@ impl FixedAdviceProvider { pub fn new(advice: Vec) -> Self { Self { advice, index: 0 } } + pub fn from_file(file: &mut File) -> Self { + // read the entire file into self::advice: + let mut advice = Vec::new(); + file.read_to_end(&mut advice).unwrap(); + Self { advice, index: 0 } + } } impl AdviceProvider for FixedAdviceProvider { @@ -47,3 +68,28 @@ impl AdviceProvider for StdinAdviceProvider { } } } + +pub struct GlobalAdviceProvider { + provider: AdviceProviderType, +} +impl GlobalAdviceProvider { + pub fn new(file_name: &Option) -> Self { + match file_name { + Some(file_name) => { + let mut file = File::open(file_name).unwrap(); + let provider = AdviceProviderType::Fixed(FixedAdviceProvider::from_file(&mut file)); + Self { provider } + } + None => { + let provider = AdviceProviderType::Stdin(StdinAdviceProvider); + Self { provider } + } + } + } +} + +impl AdviceProvider for GlobalAdviceProvider { + fn get_advice(&mut self) -> Option { + self.provider.get_advice() + } +}