Skip to content
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
27 changes: 6 additions & 21 deletions runtime/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,49 +6,34 @@ edition = "2021"


[features]
default = ["std", "json_rpc"]
default = ["std"]

# `contract` needs only `serde`'s core traits. `alloc` adds owned generated
# types and `Vec`-backed buffers; `std` adds the transport / async / setup
# layer (`setup`, `package_abi`) and everything it pulls in.
# `contract` + `wire` need only `serde`'s core traits and no allocation.
# `alloc` adds owned generated types, the frame `transport`, and the `serve`
# loop. `std` adds the MessagePack `format` and the in-memory transport, plus
# the dylib ABI.
alloc = ["serde/alloc"]
std = [
"alloc",
"serde/std",
"dep:eyre",
"dep:downcast-rs",
"dep:async-trait",
"dep:tokio",
"dep:abi_stable",
"dep:libloading",
"dep:serde_json",
"dep:rmp",
"dep:rmp-serde",
]

# Call Systems (all in the `std` layer today)
open_rpc = ["std"]
json_rpc = ["std", "dep:json-rpc-types"]


[dependencies]
# `contract` — no_std, no alloc
# `contract` / `wire` — no_std, no alloc
serde = { version = "1.0.190", default-features = false }
bytemuck = { version = "1.14.0", features = ["derive"] }

# `std` layer
eyre = { version = "0.6.8", optional = true }
downcast-rs = { version = "1.2.0", optional = true }
async-trait = { version = "0.1.74", optional = true }
tokio = { version = "1.33.0", features = ["net", "rt-multi-thread", "sync", "io-util"], default-features = false, optional = true }
abi_stable = { version = "0.11.2", optional = true }
libloading = { version = "0.8.0", optional = true }
json-rpc-types = { version = "1.3.4", optional = true }
rmp = { version = "0.8.12", optional = true }
rmp-serde = { version = "1.1.2", optional = true }
serde_json = { version = "1.0.104", optional = true }


[dev-dependencies]
tokio = { version = "1.33.0", features = ["full"] }
serde = { version = "1.0.190", features = ["derive"] }
15 changes: 11 additions & 4 deletions runtime/core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// `no_std`-first: the crate is `#![no_std]` unless the `std` feature is on
// (it is, by default). `--no-default-features` builds just `contract`.
// (it is, by default). `--no-default-features` builds `contract` + `wire`.
#![cfg_attr(not(feature = "std"), no_std)]

#[cfg(feature = "alloc")]
Expand All @@ -8,12 +8,19 @@ extern crate alloc;
// The `core ↔ target` contract — `no_std`, allocation-free.
pub mod contract;

// Request / response framing — `no_std`, allocation-free.
pub mod wire;

// `WireFormat` implementations (`std`-gated for now — see the module).
#[cfg(feature = "std")]
pub mod format;

// The `std` layer: transport, async, the setup builders, the dylib ABI.
// The frame transport and the provider serve loop.
#[cfg(feature = "alloc")]
pub mod serve;
#[cfg(feature = "alloc")]
pub mod transport;

// The Comline-package dynamic-library ABI.
#[cfg(feature = "std")]
pub mod package_abi;
#[cfg(feature = "std")]
pub mod setup;
56 changes: 56 additions & 0 deletions runtime/core/src/serve.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//! Provider-side serving: read a request frame, dispatch it, write the
//! response frame.

use alloc::vec::Vec;

use crate::contract::{Dispatch, Kind, RuntimeError, WireFormat};
use crate::transport::Transport;
use crate::wire;

/// Serves one protocol implementation over a [`Transport`], reusing its buffers
/// across calls (§4.6 — no per-call allocation on the frame path).
pub struct Server<D, W> {
dispatch: D,
format: W,
recv: Vec<u8>,
envelope: Vec<u8>,
response: Vec<u8>,
}

impl<D: Dispatch, W: WireFormat> Server<D, W> {
pub fn new(dispatch: D, format: W) -> Self {
Self {
dispatch,
format,
recv: Vec::new(),
envelope: Vec::new(),
response: Vec::new(),
}
}

/// Handle one call. `Ok(true)` — a call was served; `Ok(false)` — the
/// transport closed.
pub fn serve_one<T: Transport>(&mut self, transport: &mut T) -> Result<bool, RuntimeError> {
if transport.recv(&mut self.recv).is_err() {
return Ok(false);
}

let (call_id, request_id, params) =
wire::decode_request(&self.recv).ok_or(RuntimeError::Framing)?;

self.envelope.clear();
self.dispatch
.dispatch(Kind::Id(call_id), params, &self.format, &mut self.envelope)?;

self.response.clear();
wire::encode_response(request_id, &self.envelope, &mut self.response);
transport.send(&self.response)?;
Ok(true)
}

/// Serve calls until the transport closes.
pub fn serve<T: Transport>(&mut self, transport: &mut T) -> Result<(), RuntimeError> {
while self.serve_one(transport)? {}
Ok(())
}
}
54 changes: 0 additions & 54 deletions runtime/core/src/setup/abstract_call.rs

This file was deleted.

38 changes: 0 additions & 38 deletions runtime/core/src/setup/call_system/consumer.rs

This file was deleted.

26 changes: 0 additions & 26 deletions runtime/core/src/setup/call_system/meta.rs

This file was deleted.

66 changes: 0 additions & 66 deletions runtime/core/src/setup/call_system/mod.rs

This file was deleted.

23 changes: 0 additions & 23 deletions runtime/core/src/setup/call_system/provider.rs

This file was deleted.

Loading
Loading