Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add additional "raw" calls #382

Merged
merged 6 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions contracts/eventer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ impl Eventer {
}
}

/// Emits an event with the given number, using `emit_raw`
pub fn emit_num_raw(&mut self, num: u32) {
for i in 0..num {
uplink::emit_raw("number", i.to_le_bytes());
}
}

pub fn emit_input(&mut self, input: Vec<u8>) -> (u64, u64) {
let spent_before = uplink::spent();
uplink::emit("input", input);
Expand All @@ -41,6 +48,12 @@ unsafe fn emit_events(arg_len: u32) -> u32 {
uplink::wrap_call(arg_len, |num| STATE.emit_num(num))
}

/// Expose `Eventer::emit_num_raw()` to the host
#[no_mangle]
unsafe fn emit_events_raw(arg_len: u32) -> u32 {
uplink::wrap_call(arg_len, |num| STATE.emit_num_raw(num))
}

/// Expose `Eventer::emit_input()` to the host
#[no_mangle]
unsafe fn emit_input(arg_len: u32) -> u32 {
Expand Down
13 changes: 13 additions & 0 deletions contracts/feeder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,23 @@ impl Feeder {
uplink::feed(i);
}
}

/// Feed the host with 32-bit integers sequentially in the `0..num` range.
pub fn feed_num_raw(&self, num: u32) {
for i in 0..num {
uplink::feed_raw(i.to_le_bytes());
}
}
}

/// Expose `Feeder::feed_num()` to the host
#[no_mangle]
unsafe fn feed_num(arg_len: u32) -> u32 {
uplink::wrap_call(arg_len, |num| STATE.feed_num(num))
}

/// Expose `Feeder::feed_num_raw()` to the host
#[no_mangle]
unsafe fn feed_num_raw(arg_len: u32) -> u32 {
uplink::wrap_call(arg_len, |num| STATE.feed_num_raw(num))
}
1 change: 1 addition & 0 deletions piecrust-uplink/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Add `emit_raw` and `feed_raw` functions
- Add `ContractError::DoesNotExist` variant

## [0.16.0] - 2024-08-01
Expand Down
39 changes: 37 additions & 2 deletions piecrust-uplink/src/abi/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ pub fn spent() -> u64 {
unsafe { ext::spent() }
}

/// Emits an event with the given data.
/// Emits an event with the given data, serializing it using [`rkyv`].
pub fn emit<D>(topic: &'static str, data: D)
where
for<'a> D: Serialize<StandardBufSerializer<'a>>,
Expand All @@ -321,7 +321,24 @@ where
});
}

/// Feeds the host with data.
/// Emits an event with the given data.
pub fn emit_raw(topic: &'static str, data: impl AsRef<[u8]>) {
with_arg_buf(|buf| {
let data = data.as_ref();

let arg_len = data.len();
buf[..arg_len].copy_from_slice(&data);

let arg_len = arg_len as u32;

let topic_ptr = topic.as_ptr();
let topic_len = topic.len() as u32;

unsafe { ext::emit(topic_ptr, topic_len, arg_len) }
});
}

/// Feeds the host with data, serializing it using [`rkyv`].
///
/// This is only allowed to be called in the context of a `feed_call`, and
/// will error out otherwise. It is meant for contracts to be able to report
Expand All @@ -343,3 +360,21 @@ where
unsafe { ext::feed(arg_len) }
});
}

/// Feeds the host with data.
///
/// This is only allowed to be called in the context of a `feed_call`, and
/// will error out otherwise. It is meant for contracts to be able to report
/// large amounts of data to the host, in the span of a single call.
pub fn feed_raw(data: impl AsRef<[u8]>) {
with_arg_buf(|buf| {
let data = data.as_ref();

let arg_len = data.len();
buf[..arg_len].copy_from_slice(&data);

let arg_len = arg_len as u32;

unsafe { ext::feed(arg_len) }
});
}
17 changes: 17 additions & 0 deletions piecrust/tests/eventer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,23 @@ pub fn vm_center_events() -> Result<(), Error> {
assert_eq!(events[index].data, i.to_le_bytes());
}

let receipt = session.call::<_, ()>(
eventer_id,
"emit_events_raw",
&EVENT_NUM,
LIMIT,
)?;

let events = receipt.events;
assert_eq!(events.len() as u32, EVENT_NUM);

for i in 0..EVENT_NUM {
let index = i as usize;
assert_eq!(events[index].source, eventer_id);
assert_eq!(events[index].topic, "number");
assert_eq!(events[index].data, i.to_le_bytes());
}

Ok(())
}

Expand Down
38 changes: 35 additions & 3 deletions piecrust/tests/feeder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,42 @@ fn feed() -> Result<(), Error> {
const FEED_NUM: u32 = 10;
const GAS_LIMIT: u64 = 1_000_000;

let (sender, receiver) = mpsc::channel();
let (first_sender, receiver) = mpsc::channel();

session.feeder_call::<_, ()>(
id,
"feed_num",
&FEED_NUM,
GAS_LIMIT,
first_sender,
)?;

session
.feeder_call::<_, ()>(id, "feed_num", &FEED_NUM, GAS_LIMIT, sender)?;
let numbers = receiver
.into_iter()
.map(|data| {
rkyv::from_bytes(&data).expect("Fed data should be a number")
})
.collect::<Vec<u32>>();

assert_eq!(
numbers.len(),
FEED_NUM as usize,
"The correct number of numbers should be fed"
);

for (i, n) in numbers.into_iter().enumerate() {
assert_eq!(i as u32, n, "Numbers should be fed in order");
}

let (second_sender, receiver) = mpsc::channel();

session.feeder_call::<_, ()>(
id,
"feed_num_raw",
&FEED_NUM,
GAS_LIMIT,
second_sender,
)?;

let numbers = receiver
.into_iter()
Expand Down