-
Notifications
You must be signed in to change notification settings - Fork 464
/
Copy pathio.rs
169 lines (153 loc) · 4.25 KB
/
io.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#![allow(unused_unsafe)]
use crate::{read_vec_raw, syscall_write, ReadVecResult};
use serde::{de::DeserializeOwned, Serialize};
use std::io::{Result, Write};
pub use sp1_primitives::consts::fd::*;
/// A writer that writes to a file descriptor inside the zkVM.
struct SyscallWriter {
fd: u32,
}
impl Write for SyscallWriter {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
let nbytes = buf.len();
let write_buf = buf.as_ptr();
unsafe {
syscall_write(self.fd, write_buf, nbytes);
}
Ok(nbytes)
}
fn flush(&mut self) -> Result<()> {
Ok(())
}
}
/// Read a buffer from the input stream. The buffer is read into uninitialized memory.
///
/// When the `bump` feature is enabled, the buffer is read into a new buffer allocated by the
/// program.
///
/// When the `embedded` feature is enabled, the buffer is read into the reserved input region.
///
/// When there is no allocator selected, the program will fail to compile.
///
/// ### Examples
/// ```ignore
/// let data: Vec<u8> = sp1_zkvm::io::read_vec();
/// ```
#[track_caller]
pub fn read_vec() -> Vec<u8> {
let ReadVecResult { ptr, len, capacity } = unsafe { read_vec_raw() };
if ptr.is_null() {
panic!(
"Tried to read from the input stream, but it was empty @ {} \n
Was the correct data written into SP1Stdin?",
std::panic::Location::caller()
)
}
unsafe { Vec::from_raw_parts(ptr, len, capacity) }
}
/// Read a deserializable object from the input stream.
///
/// ### Examples
/// ```ignore
/// use serde::{Deserialize, Serialize};
///
/// #[derive(Serialize, Deserialize)]
/// struct MyStruct {
/// a: u32,
/// b: u32,
/// }
///
/// let data: MyStruct = sp1_zkvm::io::read();
/// ```
#[track_caller]
pub fn read<T: DeserializeOwned>() -> T {
let ReadVecResult { ptr, len, capacity } = unsafe { read_vec_raw() };
if ptr.is_null() {
panic!(
"Tried to read from the input stream, but it was empty @ {} \n
Was the correct data written into SP1Stdin?",
std::panic::Location::caller()
)
}
// 1. `ptr` was allocated using alloc
// 2. Assume that the allocator in the VM doesn't deallocate in the input space.
// 3. Size and length are correct from above. Length is <= capacity.
let vec = unsafe { Vec::from_raw_parts(ptr, len, capacity) };
bincode::deserialize(&vec).expect("deserialization failed")
}
/// Commit a serializable object to the public values stream.
///
/// ### Examples
/// ```ignore
/// use serde::{Deserialize, Serialize};
///
/// #[derive(Serialize, Deserialize)]
/// struct MyStruct {
/// a: u32,
/// b: u32,
/// }
///
/// let data = MyStruct {
/// a: 1,
/// b: 2,
/// };
/// sp1_zkvm::io::commit(&data);
/// ```
pub fn commit<T: Serialize>(value: &T) {
let writer = SyscallWriter { fd: FD_PUBLIC_VALUES };
bincode::serialize_into(writer, value).expect("serialization failed");
}
/// Commit bytes to the public values stream.
///
/// ### Examples
/// ```ignore
/// let data = vec![1, 2, 3, 4];
/// sp1_zkvm::io::commit_slice(&data);
/// ```
pub fn commit_slice(buf: &[u8]) {
let mut my_writer = SyscallWriter { fd: FD_PUBLIC_VALUES };
my_writer.write_all(buf).unwrap();
}
/// Hint a serializable object to the hint stream.
///
/// ### Examples
/// ```ignore
/// use serde::{Deserialize, Serialize};
///
/// #[derive(Serialize, Deserialize)]
/// struct MyStruct {
/// a: u32,
/// b: u32,
/// }
///
/// let data = MyStruct {
/// a: 1,
/// b: 2,
/// };
/// sp1_zkvm::io::hint(&data);
/// ```
pub fn hint<T: Serialize>(value: &T) {
let writer = SyscallWriter { fd: FD_HINT };
bincode::serialize_into(writer, value).expect("serialization failed");
}
/// Hint bytes to the hint stream.
///
/// ### Examples
/// ```ignore
/// let data = vec![1, 2, 3, 4];
/// sp1_zkvm::io::hint_slice(&data);
/// ```
pub fn hint_slice(buf: &[u8]) {
let mut my_reader = SyscallWriter { fd: FD_HINT };
my_reader.write_all(buf).unwrap();
}
/// Write the data `buf` to the file descriptor `fd`.
///
/// ### Examples
/// ```ignore
/// let data = vec![1, 2, 3, 4];
/// sp1_zkvm::io::write(3, &data);
/// ```
pub fn write(fd: u32, buf: &[u8]) {
SyscallWriter { fd }.write_all(buf).unwrap();
}