pub enum CollateralBufferResult {
Known {
epoch: u64,
protocol_version: u16,
funding_state: CollateralFundingState,
recommended_buffer_dig_base_units: u64,
spendable_dig_base_units: u64,
pairs_served_by_this_node: u64,
required_per_store_dig_base_units: u64,
margin_bp: u64,
overlap_dig_base_units: u64,
escalation_headroom_dig_base_units: u64,
horizon_epochs: u32,
escalation_ceiling_micros: u64,
},
Unknown {
reason: CollateralBufferUnknownReason,
},
}Expand description
control.collateral.buffer — the $DIG this node recommends holding, and where it stands against
that figure.
Every amount here is in DIG BASE UNITS. $DIG carries 3 decimals, so one base unit is
0.001 DIG. It is NOT a mojo: a mojo is XCH’s base unit at 1e-12 XCH, nine orders of magnitude
away. margin_bp is the one field that is not an amount and is in BASIS POINTS (100 is +1%),
the unit the collateral crate’s own presets and rounding use, never converted.
UNKNOWN is a first-class answer, and a zero here is the money lie in its purest form. On
control.collateral.requirement a fabricated zero reads as a free requirement; here it reads as
no buffer needed, which is worse, because an operator acting on it would post nothing and lose
the epoch. A node that cannot enumerate the pairs it serves, cannot read its reclaim state, or
cannot see its balance says so WITH the reason — the tagged variant means there is no
representable state in which a client holds a figure it was never given.
The horizon travels with the buffer, because a buffer without one is a magic number. The
escalation of the per-store requirement is bounded at +12.5% per epoch and COMPOUNDS: about
x1.12 at one epoch, x1.60 at four, x4.62 at thirteen. Two nodes quoting a buffer over different
horizons are answering different questions, and neither figure can be checked without knowing
which. escalation_ceiling_micros states the multiplier this node assumed, and it is a WORST
CASE, not a forecast: inside the controller’s dead band the multiplier does not move at all.
The total is authoritative; the terms are the working. recommended_buffer_dig_base_units
is the figure to hold and the figure funding_state was decided against. The other fields exist
so a client can show WHY that number is what it is — which is the difference between a figure an
operator can weigh and one they can only accept — and a client MUST NOT re-add them and prefer
its own sum, because rounding lives in the node’s arithmetic, not the client’s.
Why this is not part of CollateralRequirementResult. The requirement is consensus-derived
and every node derives it identically; the buffer is LOCAL — it depends on the pairs this
particular node serves, on an operator preference (the margin), and on a horizon this node chose.
0.23.0 kept the margin out of the requirement on exactly that grounds, and the same reasoning
binds harder here, because a buffer folded into the requirement’s result would make one node’s
preferences look like the network’s price.
Variants§
Known
The node can state its buffer and its position against it.
Fields
protocol_version: u16The collateral protocol version that COMPUTED that epoch, carried for the same reason
CollateralRequirementResult::Known carries it: a client holding only numbers cannot
tell a disagreement from a rule change.
funding_state: CollateralFundingStateWhere this node stands against recommended_buffer_dig_base_units.
recommended_buffer_dig_base_units: u64The $DIG this node recommends holding, in DIG base units. The authoritative figure.
spendable_dig_base_units: u64The spendable $DIG the node compared against the buffer, in DIG base units.
Carried so funding_state is checkable rather than merely assertive: a client can show
the two numbers the verdict came from. It is what is SPENDABLE — collateral already
locked is not in it.
pairs_served_by_this_node: u64Qualifying (owner, store, root) pairs THIS NODE serves.
This node’s own set, never the census stores count, which is a network-wide
advertisement count. Multiplying the census figure by the requirement is the confident,
badly wrong number this field exists to prevent.
required_per_store_dig_base_units: u64The epoch’s per-store requirement, in DIG base units, BEFORE any local safety margin —
the same value control.collateral.requirement returns.
overlap_dig_base_units: u64Collateral still locked against positions this node has not yet reclaimed, in DIG base units.
A transition overlap: during the changeover the node must be able to cover the new
epoch while the previous epoch’s posting is not yet back. It is NOT derivable from any
other field here, which is why a node that cannot read its reclaim state answers
ReclaimStateUnknown rather than
omitting the term.
escalation_headroom_dig_base_units: u64The headroom included for the requirement escalating over horizon_epochs, in DIG base
units. Also not derivable client-side, because it depends on the horizon and ceiling
this node chose.
horizon_epochs: u32How many future epochs the headroom covers. Never implied, never defaulted by a reader: the same buffer over a different horizon is a different claim.
escalation_ceiling_micros: u64The compounded WORST-CASE escalation multiplier assumed over horizon_epochs, in
millionths (1_000_000 is x1.0).
A ceiling, not a forecast. Escalation is capped at +12.5% per epoch, so four epochs
bound at roughly 1_601_806 (x1.60); in the dead band the multiplier does not move at
all and the realised figure is 1_000_000. A surface presenting this as an expectation
would tell an operator to hold money for a rise the controller may never make.
Unknown
The node cannot state the buffer, and names which fact is missing.
Fields
reason: CollateralBufferUnknownReasonWhich fact the node is missing.
Trait Implementations§
Source§impl Clone for CollateralBufferResult
impl Clone for CollateralBufferResult
Source§fn clone(&self) -> CollateralBufferResult
fn clone(&self) -> CollateralBufferResult
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more