Guest User

Untitled

a guest
Nov 29th, 2023
216
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 6.34 KB | None | 0 0
  1. diff --git a/examples/hello-world/methods/guest/Cargo.toml b/examples/hello-world/methods/guest/Cargo.toml
  2. index 11940b93..a3c1d315 100644
  3. --- a/examples/hello-world/methods/guest/Cargo.toml
  4. +++ b/examples/hello-world/methods/guest/Cargo.toml
  5. @@ -7,3 +7,4 @@ edition = "2021"
  6.  
  7.  [dependencies]
  8.  risc0-zkvm = { path = "../../../../risc0/zkvm", default-features = false }
  9. +nes = { git = "https://github.com/koute/pinky.git", rev = "5a9d4ff5f22731191cffd7d6202a1d144aacd740", default-features = false, features = ["softfloat"] }
  10. diff --git a/examples/hello-world/methods/guest/src/main.rs b/examples/hello-world/methods/guest/src/main.rs
  11. index 2ddce6e2..43682564 100644
  12. --- a/examples/hello-world/methods/guest/src/main.rs
  13. +++ b/examples/hello-world/methods/guest/src/main.rs
  14. @@ -15,20 +15,102 @@
  15.  #![no_main]
  16.  #![no_std]
  17.  
  18. +extern crate alloc;
  19. +use alloc::boxed::Box;
  20. +
  21.  use risc0_zkvm::guest::env;
  22.  
  23.  risc0_zkvm::guest::entry!(main);
  24.  
  25. +use nes::Interface;
  26. +
  27. +struct Emulator {
  28. +    state: nes::State,
  29. +}
  30. +
  31. +impl nes::Context for Emulator {
  32. +    fn state(&self) -> &nes::State {
  33. +        &self.state
  34. +    }
  35. +
  36. +    fn state_mut(&mut self) -> &mut nes::State {
  37. +        &mut self.state
  38. +    }
  39. +}
  40. +
  41. +// Source of the ROM: https://github.com/christopherpow/nes-test-roms/tree/97720008e51db15dd281a2a1e64d4c65cf1bca4c/nes15-1.0.0
  42. +// Licensed under a BSD-style license.
  43. +const ROM: &[u8] = core::include_bytes!("nes15-NTSC.nes");
  44. +
  45. +struct State {
  46. +    nes: Emulator,
  47. +    framebuffer: Option<Box<[u32; 256 * 240]>>,
  48. +}
  49. +
  50. +#[inline]
  51. +unsafe fn alloc_zeroed_box<T>() -> Box<T> {
  52. +    Box::from_raw(alloc::alloc::alloc_zeroed(alloc::alloc::Layout::new::<T>()) as *mut T)
  53. +}
  54. +
  55. +fn benchmark_initialize(state: &mut State) {
  56. +    state.framebuffer = Some(unsafe { alloc_zeroed_box() });
  57. +    state.nes.load_rom(ROM).unwrap();
  58. +
  59. +    // By default the game which we're emulating stays on the main menu
  60. +    // screen without anything happening on screen; it doesn't even try
  61. +    // to play any music.
  62. +    //
  63. +    // Pressing any button on the gamepad actually starts the game, and
  64. +    // once the game is started pressing the select button triggers
  65. +    // an autosolve mechanism which makes the game automatically play itself.
  66. +    //
  67. +    // So let's trigger this here.
  68. +
  69. +    // We need to wait for four frames until the game accepts any input.
  70. +    //
  71. +    // I don't know why; I just started to empirically increase the number
  72. +    // of frames until it worked.
  73. +    for _ in 0..4 {
  74. +        state.nes.execute_until_vblank().unwrap();
  75. +    }
  76. +
  77. +    // Now we can press a button to start the game.
  78. +    state.nes.press(nes::ControllerPort::First, nes::Button::Select);
  79. +    state.nes.execute_until_vblank().unwrap();
  80. +    state.nes.release(nes::ControllerPort::First, nes::Button::Select);
  81. +
  82. +    // We need to wait for at least three frames until we can trigger
  83. +    // the autosolve mechanism.
  84. +    for _ in 0..3 {
  85. +        state.nes.execute_until_vblank().unwrap();
  86. +    }
  87. +
  88. +    // Now we can press select to make the game start playing itself.
  89. +    state.nes.press(nes::ControllerPort::First, nes::Button::Select);
  90. +    state.nes.execute_until_vblank().unwrap();
  91. +    state.nes.release(nes::ControllerPort::First, nes::Button::Select);
  92. +}
  93. +
  94. +fn benchmark_run(state: &mut State) {
  95. +    state.nes.execute_until_vblank().unwrap();
  96. +    state
  97. +        .nes
  98. +        .framebuffer()
  99. +        .convert_to_abgr(&nes::Palette::default(), &mut state.framebuffer.as_mut().unwrap()[..]);
  100. +}
  101. +
  102.  pub fn main() {
  103. -    // Load the first number from the host
  104. -    let a: u64 = env::read();
  105. -    // Load the second number from the host
  106. -    let b: u64 = env::read();
  107. -    // Verify that neither of them are 1 (i.e. nontrivial factors)
  108. -    if a == 1 || b == 1 {
  109. -        panic!("Trivial factors")
  110. +    let mut state = State {
  111. +        nes: Emulator { state: nes::State::new() },
  112. +        framebuffer: None,
  113. +    };
  114. +
  115. +    benchmark_initialize(&mut state);
  116. +    benchmark_run(&mut state);
  117. +
  118. +    let mut sum: u32 = 0;
  119. +    for &value in state.framebuffer.as_ref().unwrap()[..].iter() {
  120. +        sum = sum.wrapping_add(value);
  121.      }
  122. -    // Compute the product while being careful with integer overflow
  123. -    let product = a.checked_mul(b).expect("Integer overflow");
  124. -    env::commit(&product);
  125. +    env::commit(&sum);
  126.  }
  127. diff --git a/examples/hello-world/src/lib.rs b/examples/hello-world/src/lib.rs
  128. index 35424f83..3931d87c 100644
  129. --- a/examples/hello-world/src/lib.rs
  130. +++ b/examples/hello-world/src/lib.rs
  131. @@ -22,13 +22,9 @@ use risc0_zkvm::{default_prover, ExecutorEnv, Receipt};
  132.  // The factors a and b are kept secret.
  133.  
  134.  // Compute the product a*b inside the zkVM
  135. -pub fn multiply(a: u64, b: u64) -> (Receipt, u64) {
  136. +pub fn multiply() -> (Receipt, u32) {
  137.      let env = ExecutorEnv::builder()
  138.          // Send a & b to the guest
  139. -        .write(&a)
  140. -        .unwrap()
  141. -        .write(&b)
  142. -        .unwrap()
  143.          .build()
  144.          .unwrap();
  145.  
  146. @@ -39,7 +35,7 @@ pub fn multiply(a: u64, b: u64) -> (Receipt, u64) {
  147.      let receipt = prover.prove_elf(env, MULTIPLY_ELF).unwrap();
  148.  
  149.      // Extract journal of receipt (i.e. output c, where c = a * b)
  150. -    let c: u64 = receipt.journal.decode().expect(
  151. +    let c: u32 = receipt.journal.decode().expect(
  152.          "Journal output should deserialize into the same types (& order) that it was written",
  153.      );
  154.  
  155. diff --git a/examples/hello-world/src/main.rs b/examples/hello-world/src/main.rs
  156. index b66b131c..ee7b4381 100644
  157. --- a/examples/hello-world/src/main.rs
  158. +++ b/examples/hello-world/src/main.rs
  159. @@ -15,14 +15,23 @@
  160.  use hello_world::multiply;
  161.  use hello_world_methods::MULTIPLY_ID;
  162.  
  163. +use std::time::Instant;
  164. +
  165.  fn main() {
  166. +    let start = Instant::now();
  167.      // Pick two numbers
  168. -    let (receipt, _) = multiply(17, 23);
  169. +    let (receipt, _) = multiply();
  170. +
  171. +    let elapsed = start.elapsed();
  172. +    println!("Finished in: {}", elapsed.as_secs_f64() * 1000.0);
  173.  
  174.      // Here is where one would send 'receipt' over the network...
  175.  
  176. +    let start = Instant::now();
  177.      // Verify receipt, panic if it's wrong
  178.      receipt.verify(MULTIPLY_ID).expect(
  179.          "Code you have proven should successfully verify; did you specify the correct image ID?",
  180.      );
  181. +    let elapsed = start.elapsed();
  182. +    println!("Verified in: {}", elapsed.as_secs_f64() * 1000.0);
  183.  }
  184.  
Advertisement
Add Comment
Please, Sign In to add comment