pub enum StreamError {
NotFound,
Declined,
Unfunded,
VoucherRejected {
reason: VoucherRejectReason,
bundle: Option<WatermarkBundle>,
},
}Expand description
A stream failure code (ADR 005 §Open-time refusal classes).
NotFound, Declined, and Unfunded are the open-time refusal classes and
ride in StreamResponseExt::error alongside ok: false.
VoucherRejected is the only variant delivered mid-stream, inside a
ClientMessage::StreamError. All codes are unsigned and informational,
never on-chain evidence. A node keeps its finer refusal reason in its own
per-reason metrics. The wire carries only the class, because a requester
acts on the class alone.
Every refusal scopes to the node that sent it, for the current fetch. A requester never ends a fetch on the word of one node.
Postcard encodes a struct variant’s payload positionally, in declaration
order, so VoucherRejected’s bundle field sits after reason and any
further field appends after bundle.
Variants§
NotFound
“No”: this node cannot serve the request now. The requester tries other nodes. This node can answer differently later.
Declined
“No, and stop asking”: this node will not serve this hash or request during this fetch. The requester removes it from the candidates for the hash for the rest of the fetch.
Unfunded
“No at the current funding”: this node will not serve this request at the requester’s current pool deposit or signer capability (ADR 003 §Funding recovery). The requester parks it at the current funding for this fetch, and asks it again only after a funding recovery step.
Spoken ONLY to a requester that passed the lane-ownership proof or holds
a verified signer binding. Any other requester gets Self::NotFound
for the same state, so pool and signer state stay unmappable off the
wire.
VoucherRejected
Mid-stream payment-voucher rejection carried in a
ClientMessage::StreamError message (never in the initial
StreamResponse).
Fields
reason: VoucherRejectReasonThe specific validation failure.
bundle: Option<WatermarkBundle>The node’s true watermark plus the client’s own last-accepted
signature, attached ONLY on the watermark-gated reasons
(VoucherRejectReason::is_watermark_gated) and ONLY
when the rejected voucher’s signature recovers to the
capability’s pinned voucher_signer (issue #1481 §5 security
property — otherwise anyone who guessed the chain-derivable
pool_id could pull the node’s watermark). A wallet-less client
cannot reconstruct its watermark from chain (the claim watermark
is 0 until settlement), so this lets it self-heal: re-seed the
ledger’s PAYMENT BASELINE to bytes_delivered (a pool-cumulative
counter, NOT a blob byte_offset) and re-sign from the new
baseline. None for every reason that is not watermark-gated and
whenever the signer does not recover to voucher_signer.
Implementations§
Source§impl StreamError
impl StreamError
Sourcepub const fn is_delivery_side(&self) -> bool
pub const fn is_delivery_side(&self) -> bool
true for the delivery-side codes that ride in StreamResponseExt::error
alongside ok: false — everything except VoucherRejected. Expresses
the enum’s domain split in code rather than only in prose, and backs the
StreamResponseExt::validate mid-stream-only exclusion.
Sourcepub const fn is_mid_stream(&self) -> bool
pub const fn is_mid_stream(&self) -> bool
true for the mid-stream-only StreamError::VoucherRejected, which
rides exclusively in ClientMessage::StreamError.