Skip to content

Commit

Permalink
♻ Move pipe reading logic into pipe, so that it's shared
Browse files Browse the repository at this point in the history
  • Loading branch information
clabby committed Feb 17, 2024
1 parent f4c6315 commit b819e45
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 65 deletions.
33 changes: 3 additions & 30 deletions crates/preimage/src/hint.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::PipeHandle;
use alloc::vec;
use anyhow::{bail, Result};
use anyhow::Result;

/// A [HintWriter] is a high-level interface to the hint pipe. It provides a way to write hints to the host.
#[derive(Debug, Clone, Copy)]
Expand All @@ -24,38 +24,11 @@ impl HintWriter {
hint_bytes[4..].copy_from_slice(hint.as_bytes());

// Write the hint to the host.
let mut written = 0;
loop {
match self.pipe_handle.write(&hint_bytes[written..]) {
Ok(0) => break,
Ok(n) => {
written += n as usize;
continue;
}
Err(e) => bail!("Failed to write preimage key: {}", e),
}
}
self.pipe_handle.write(&hint_bytes)?;

// Read the hint acknowledgement from the host.
let mut hint_ack = [0u8; 1];
self.read_exact(&mut hint_ack)?;

Ok(())
}

/// Reads bytes into `buf` and returns the number of bytes read.
fn read(&self, buf: &mut [u8]) -> Result<usize> {
let read = self.pipe_handle.read(buf)?;
Ok(read as usize)
}

/// Reads exactly `buf.len()` bytes into `buf`, blocking until all bytes are read.
fn read_exact(&self, buf: &mut [u8]) -> Result<()> {
let mut read = 0;
while read < buf.len() {
let chunk_read = self.read(&mut buf[read..])?;
read += chunk_read;
}
self.pipe_handle.read_exact(&mut hint_ack)?;

Ok(())
}
Expand Down
36 changes: 4 additions & 32 deletions crates/preimage/src/oracle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl OracleReader {
let mut data_buffer = alloc::vec![0; self.length];

// Grab a read lock on the preimage pipe to read the data.
self.read_exact(&mut data_buffer)?;
self.cursor += self.pipe_handle.read_exact(&mut data_buffer)? as usize;

Ok(data_buffer)
}
Expand All @@ -68,7 +68,7 @@ impl OracleReader {
}

// Grab a read lock on the preimage pipe to read the data.
self.read_exact(buf)?;
self.cursor += self.pipe_handle.read_exact(buf)? as usize;

Ok(())
}
Expand All @@ -87,43 +87,15 @@ impl OracleReader {

// Write the key to the host so that it can prepare the preimage.
let key_bytes: [u8; 32] = key.into();
let mut written = 0;
loop {
match self.pipe_handle.write(&key_bytes[written..]) {
Ok(0) => break,
Ok(n) => {
written += n as usize;
continue;
}
Err(e) => bail!("Failed to write preimage key: {}", e),
}
}
self.pipe_handle.write(&key_bytes)?;

// Read the length prefix and reset the cursor.
let mut length_buffer = [0u8; 8];
self.read_exact(&mut length_buffer)?;
self.pipe_handle.read_exact(&mut length_buffer)?;
self.length = u64::from_be_bytes(length_buffer) as usize;
self.cursor = 0;
Ok(())
}

/// Reads bytes into `buf` and returns the number of bytes read.
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let read = self.pipe_handle.read(buf)?;
self.cursor += read as usize;
Ok(read as usize)
}

/// Reads exactly `buf.len()` bytes into `buf`, blocking until all bytes are read.
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
let mut read = 0;
while read < buf.len() {
let chunk_read = self.read(&mut buf[read..])?;
read += chunk_read;
}

Ok(())
}
}

#[cfg(test)]
Expand Down
25 changes: 23 additions & 2 deletions crates/preimage/src/pipe.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! This module contains a rudamentary pipe between two file descriptors, using [kona_common::io] for
//! reading and writing from the file descriptors.
use anyhow::Result;
use anyhow::{bail, Result};
use kona_common::{io, FileDescriptor, RegisterSize};

/// [PipeHandle] is a handle for one end of a bidirectional pipe.
Expand All @@ -27,8 +27,29 @@ impl PipeHandle {
io::read(self.read_handle, buf)
}

/// Reads exactly `buf.len()` bytes into `buf`, blocking until all bytes are read.
pub fn read_exact(&self, buf: &mut [u8]) -> Result<RegisterSize> {
let mut read = 0;
while read < buf.len() {
let chunk_read = self.read(&mut buf[read..])?;
read += chunk_read as usize;
}
Ok(read as RegisterSize)
}

/// Write the given buffer to the pipe.
pub fn write(&self, buf: &[u8]) -> Result<RegisterSize> {
io::write(self.write_handle, buf)
let mut written = 0;
loop {
match io::write(self.write_handle, &buf[written..]) {
Ok(0) => break,
Ok(n) => {
written += n as usize;
continue;
}
Err(e) => bail!("Failed to write preimage key: {}", e),
}
}
Ok(written as RegisterSize)
}
}
2 changes: 1 addition & 1 deletion fpvm-tests/cannon-go-tests/minimal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func TestMinimal(t *testing.T) {
us := mipsevm.NewInstrumentedState(state, oracle, io.MultiWriter(&stdOutBuf, os.Stdout), io.MultiWriter(&stdErrBuf, os.Stderr))

for i := 0; i < 200_000; i++ {
_, err := us.Step(true)
_, err := us.Step(false)
require.NoError(t, err)
if state.Exited {
fmt.Printf("exited @ step #%d\n", state.Step)
Expand Down

0 comments on commit b819e45

Please sign in to comment.