openvm_deferral_circuit/
adapters.rs

1use openvm_circuit::system::memory::online::{GuestMemory, TracingMemory};
2use openvm_instructions::DEFERRAL_AS;
3use openvm_stark_backend::p3_field::PrimeField32;
4
5#[inline(always)]
6pub fn memory_read_deferral<F, const N: usize>(memory: &GuestMemory, ptr: u32) -> [F; N]
7where
8    F: PrimeField32,
9{
10    // SAFETY:
11    // - address space `DEFERRAL_AS` has cell type `F`
12    unsafe { memory.read::<F, N>(DEFERRAL_AS, ptr) }
13}
14
15#[inline(always)]
16pub fn memory_write_deferral<F, const N: usize>(memory: &mut GuestMemory, ptr: u32, data: [F; N])
17where
18    F: PrimeField32,
19{
20    // SAFETY:
21    // - address space `DEFERRAL_AS` has cell type `F`
22    unsafe { memory.write::<F, N>(DEFERRAL_AS, ptr, data) }
23}
24
25/// Atomic read operation which increments the timestamp by 1.
26/// Returns `(t_prev, [ptr:BLOCK_SIZE]_4)` where `t_prev` is the timestamp of the last memory
27/// access.
28#[inline(always)]
29pub fn timed_read_deferral<F, const BLOCK_SIZE: usize>(
30    memory: &mut TracingMemory,
31    ptr: u32,
32) -> (u32, [F; BLOCK_SIZE])
33where
34    F: PrimeField32,
35{
36    // SAFETY:
37    // - deferral address space has cell type `F`
38    unsafe { memory.read::<F, BLOCK_SIZE>(DEFERRAL_AS, ptr) }
39}
40
41#[inline(always)]
42pub fn timed_write_deferral<F, const BLOCK_SIZE: usize>(
43    memory: &mut TracingMemory,
44    ptr: u32,
45    vals: [F; BLOCK_SIZE],
46) -> (u32, [F; BLOCK_SIZE])
47where
48    F: PrimeField32,
49{
50    // SAFETY:
51    // - deferral address space has cell type `F`
52    unsafe { memory.write::<F, BLOCK_SIZE>(DEFERRAL_AS, ptr, vals) }
53}
54
55/// Reads register value at `ptr` from memory and records the previous timestamp.
56/// Reads are only done from address space [DEFERRAL_AS].
57#[inline(always)]
58pub fn tracing_read_deferral<F, const BLOCK_SIZE: usize>(
59    memory: &mut TracingMemory,
60    ptr: u32,
61    prev_timestamp: &mut u32,
62) -> [F; BLOCK_SIZE]
63where
64    F: PrimeField32,
65{
66    let (t_prev, data) = timed_read_deferral(memory, ptr);
67    *prev_timestamp = t_prev;
68    data
69}
70
71/// Writes `ptr, vals` into memory and records the previous timestamp and data.
72/// Writes are only done to address space [DEFERRAL_AS].
73#[inline(always)]
74pub fn tracing_write_deferral<F, const BLOCK_SIZE: usize>(
75    memory: &mut TracingMemory,
76    ptr: u32,
77    vals: [F; BLOCK_SIZE],
78    prev_timestamp: &mut u32,
79    prev_data: &mut [F; BLOCK_SIZE],
80) where
81    F: PrimeField32,
82{
83    let (t_prev, data_prev) = timed_write_deferral(memory, ptr, vals);
84    *prev_timestamp = t_prev;
85    *prev_data = data_prev;
86}