#[non_exhaustive]pub enum InboundDelegateMsg<'a> {
ApplicationMessage(ApplicationMessage),
UserResponse(UserInputResponse<'a>),
GetContractResponse(GetContractResponse),
PutContractResponse(PutContractResponse),
UpdateContractResponse(UpdateContractResponse),
SubscribeContractResponse(SubscribeContractResponse),
ContractNotification(ContractNotification),
DelegateMessage(DelegateMessage),
UnsubscribeContractResponse(UnsubscribeContractResponse),
WakeupFired {
tag: Vec<u8>,
},
}Expand description
Messages delivered into a delegate’s process() function.
This is the inbound counterpart of OutboundDelegateMsg and sits on the
host↔delegate wire boundary.
Marked #[non_exhaustive] so future variants can be added without a
source-level break; downstream match sites must include a wildcard arm.
OutboundDelegateMsg is deliberately not marked, and the asymmetry is
the point — see the rationale on that enum. (An earlier version of this
comment asserted that OutboundDelegateMsg already carried the attribute.
It never has.)
§Wire format and compatibility
bincode, variant index 0..=N in declaration order. Two rules follow, and the compiler enforces neither:
- Never insert or reorder a variant. That silently reassigns every later
tag, so delegate WASM compiled against an older stdlib decodes the same
bytes into a different variant — no error, just a message quietly
reinterpreted as another one.
delegate_msg_variant_tags_are_pinnedpins the tag of every variant of both enums so a reorder fails CI instead. - Appending is compatible in exactly one direction. An old sender’s old
variant always decodes on a new receiver. A new sender’s new
variant does not decode on an old receiver: bincode rejects the
unknown tag — as
ErrorKind::Custom("invalid value: integerN, expected variant index 0 <= i < M"), since bincode hands the index to serde’s derived visitor rather than validating it itself. (NotInvalidTagEncoding, which bincode only ever produces for a badOptiondiscriminant.)#[non_exhaustive]does not change this — it is a source-level attribute with no effect on the encoding, and serde has no unknown-variant fallback to fall back to.
For this enum the incompatible direction is a new host → old delegate,
and it is mostly unreachable in practice: the host emits a response variant
only in reply to the matching request variant, so a delegate that never
emits a request added in stdlib version X never receives the response added
in X. Deployed delegate WASM therefore keeps working against an upgraded
node. The genuinely constrained direction is delegate → host; see
OutboundDelegateMsg.
The compatibility claims above are asserted, not merely asserted-in-prose,
by the delegate_wire_compat test module at the bottom of this file.
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
ApplicationMessage(ApplicationMessage)
UserResponse(UserInputResponse<'a>)
GetContractResponse(GetContractResponse)
PutContractResponse(PutContractResponse)
UpdateContractResponse(UpdateContractResponse)
SubscribeContractResponse(SubscribeContractResponse)
ContractNotification(ContractNotification)
DelegateMessage(DelegateMessage)
UnsubscribeContractResponse(UnsubscribeContractResponse)
WakeupFired
Delivered by the host when a wakeup previously requested via
DelegateCtx::schedule_wakeup fires. tag is the opaque
value the delegate supplied when scheduling, echoed back verbatim so
the delegate can identify which wakeup fired. Owned ('static).
§What the context cache holds during a wakeup
Nothing the delegate should read. freenet-core’s delegate context cache
is keyed per delegate, not per conversation, and entries are pruned
after DELEGATE_CONTEXT_TTL (10 minutes). Two consequences, both
arguing the same way:
- Any wakeup worth scheduling is far longer than 10 minutes, so whatever context existed when it was scheduled is gone by the time it fires.
- If the delegate happens to have a live context from some other in-flight exchange inside that window, it belongs to that exchange. Reading it during a wakeup would be reading another conversation’s working state.
This is why the variant carries no DelegateContext: there is no
coherent value to put in it. A delegate needing state across a wakeup
reads it from its secrets, which is what core’s own cache doc
recommends for exactly this case.
Appended at tag 9, after UnsubscribeContractResponse at tag 8.
Implementations§
Source§impl InboundDelegateMsg<'_>
impl InboundDelegateMsg<'_>
pub fn into_owned(self) -> InboundDelegateMsg<'static>
pub fn get_context(&self) -> Option<&DelegateContext>
pub fn get_mut_context(&mut self) -> Option<&mut DelegateContext>
Trait Implementations§
Source§impl<'a> Clone for InboundDelegateMsg<'a>
impl<'a> Clone for InboundDelegateMsg<'a>
Source§fn clone(&self) -> InboundDelegateMsg<'a>
fn clone(&self) -> InboundDelegateMsg<'a>
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more