Skip to main content

nodedb_physical/physical_plan/
wire.rs

1// SPDX-License-Identifier: Apache-2.0
2
3//! Wire-format encode/decode helpers for PhysicalPlan.
4//!
5//! MessagePack encoding via zerompk. Used by the cluster layer to ship
6//! physical plans over the wire as part of `ExecuteRequest` RPC.
7
8use super::PhysicalPlan;
9
10/// Errors produced by the wire encode/decode helpers. Self-contained so this
11/// module can move into the shared `nodedb-physical` crate without dragging
12/// Origin's `Error` type along.
13#[derive(Debug, thiserror::Error)]
14pub enum WireError {
15    #[error("{0}")]
16    InvalidPlan(&'static str),
17    #[error("plan codec: {0}")]
18    Codec(String),
19}
20
21/// Encode a `PhysicalPlan` to MessagePack bytes.
22///
23/// Returns an error for `ClusterArray` variants, which are handled on the
24/// Control Plane and must never be shipped over the QUIC wire.
25pub fn encode(plan: &PhysicalPlan) -> Result<Vec<u8>, WireError> {
26    if matches!(plan, PhysicalPlan::ClusterArray(_)) {
27        return Err(WireError::InvalidPlan(
28            "ClusterArray plans must not be sent over the wire",
29        ));
30    }
31    zerompk::to_msgpack_vec(plan).map_err(|e| WireError::Codec(format!("encode: {e}")))
32}
33
34/// Decode a `PhysicalPlan` from MessagePack bytes.
35pub fn decode(bytes: &[u8]) -> Result<PhysicalPlan, WireError> {
36    zerompk::from_msgpack(bytes).map_err(|e| WireError::Codec(format!("decode: {e}")))
37}
38
39/// Encode a `Vec<PhysicalPlan>` to MessagePack bytes.
40///
41/// Used by the Calvin scheduler when building `TxClass::plans` bytes for a
42/// cross-shard transaction that will be shipped through the sequencer.
43pub fn encode_batch(plans: &Vec<PhysicalPlan>) -> Result<Vec<u8>, WireError> {
44    for plan in plans {
45        if matches!(plan, PhysicalPlan::ClusterArray(_)) {
46            return Err(WireError::InvalidPlan(
47                "ClusterArray plans must not be shipped via the sequencer",
48            ));
49        }
50    }
51    zerompk::to_msgpack_vec(plans).map_err(|e| WireError::Codec(format!("batch encode: {e}")))
52}
53
54/// Decode a `Vec<PhysicalPlan>` from MessagePack bytes.
55///
56/// Used by the Calvin scheduler to decode the opaque `TxClass::plans` blob
57/// into executable plans for dispatch via `MetaOp::CalvinExecute`.
58pub fn decode_batch(bytes: &[u8]) -> Result<Vec<PhysicalPlan>, WireError> {
59    zerompk::from_msgpack(bytes).map_err(|e| WireError::Codec(format!("batch decode: {e}")))
60}