diff --git a/src/kernel_sdk/CHANGES.md b/src/kernel_sdk/CHANGES.md index 77c0494a59bc5388a83013d97ad316a52cb2be81..4dab2515d6e6743f66a03456e86af4603e29f4d4 100644 --- a/src/kernel_sdk/CHANGES.md +++ b/src/kernel_sdk/CHANGES.md @@ -16,6 +16,7 @@ - Add `tezos-smart-rollup-utils`, for tooling that interacts with non-kernel related standards in the Smart Rollup ecosystem. - Add `tezos_smart_rollup_utils::inbox` module, constructing inboxes for testing, and manipulating `inbox.json` files. - Add `extra` feature flag, for functionalility not-expected to be used by kernels directly. +- Add a `queue_raw_buffer` to the `OutboxQueue` allowing queueing serialized/encoded messages. ### Installer client/kernel diff --git a/src/kernel_sdk/sdk/src/outbox.rs b/src/kernel_sdk/sdk/src/outbox.rs index 7098466e9f0fc0ce31a2ecf3409d8fd50f55bd0c..199a2e0dd8c0752626628db1661a762d2e845132 100644 --- a/src/kernel_sdk/sdk/src/outbox.rs +++ b/src/kernel_sdk/sdk/src/outbox.rs @@ -145,14 +145,6 @@ impl<'a, P: Path> OutboxQueue<'a, P> { host: &mut impl Runtime, message: impl Into>, ) -> Result { - let (start, len) = self.read_meta(host); - - if len >= self.max { - return Err(RuntimeError::HostErr(Error::FullOutbox)); - } - - let end = start.wrapping_add(len); - let message: OutboxMessage = message.into(); // could remove the allocation if bin_write supported encoding into a buffer directly. @@ -161,13 +153,32 @@ impl<'a, P: Path> OutboxQueue<'a, P> { .bin_write(&mut buffer) .expect("outbox message always serializable"); + self.queue_raw_buffer(host, &buffer) + } + + /// Queues an encoded message as a raw bytes buffer into the outbox queue. + /// + /// Returns the current length of the queue. + pub fn queue_raw_buffer( + &self, + host: &mut impl Runtime, + buffer: &[u8], + ) -> Result { + let (start, len) = self.read_meta(host); + + if len >= self.max { + return Err(RuntimeError::HostErr(Error::FullOutbox)); + } + + let end = start.wrapping_add(len); + if buffer.len() > MAX_OUTPUT_SIZE { return Err(RuntimeError::HostErr(Error::InputOutputTooLarge)); } let path = self.message_path(end); - host.store_write_all(&path, buffer.as_slice())?; + host.store_write_all(&path, buffer)?; let len = len.saturating_add(1); self.save_meta(host, start, len); @@ -369,6 +380,23 @@ mod test { assert!(matches!(host.store_has(&root), Ok(None))); } + #[test] + fn push_and_flush_raw_buffer() { + let mut host = MockHost::default(); + let mut buffer = Vec::with_capacity(MAX_OUTPUT_SIZE); + make_outbox_message(vec![0]) + .bin_write(&mut buffer) + .expect("outbox message always serializable"); + assert!(matches!( + OUTBOX_QUEUE.queue_raw_buffer(&mut host, &buffer), + Ok(1) + )); + + assert_eq!(1, OUTBOX_QUEUE.flush_queue(&mut host)); + let level = host.run_level(|_| {}); + assert_eq!(1, host.outbox_at(level).len()); + } + fn make_outbox_message(msg: Vec) -> OutboxMessageTransaction { OutboxMessageTransaction { parameters: msg.into(),