Skip to main content

MirrorBondState

Enum MirrorBondState 

Source
pub enum MirrorBondState {
    Bonded {
        coin_id: String,
        epoch: u64,
        amount_dig_base_units: u64,
        urls: Vec<String>,
        url_current: bool,
    },
    Pending,
    Unfunded {
        short_dig_base_units: u64,
    },
    Deferred {
        reason: CollateralUnknownReason,
    },
    Withheld,
    Disabled,
    Unadvertised,
    Reclaiming {
        coin_id: String,
        epoch: u64,
        amount_dig_base_units: u64,
    },
}
Expand description

What this node can say about ONE (store, root) bond right now.

§The whole point is that “no coin yet” is never one answer

Seven of these eight variants mean “there is no current-epoch coin”, and every one of them calls for a different response from a person: add funds, wait, do nothing, turn a switch back on, publish an advertise URL, or nothing at all because the capsule was never this node’s to advertise. Collapsing any two of them is what produces an hourly out-of-funds alarm about a perfectly healthy node (dig-app#300), which is the defect this method exists to remove.

§Vocabulary: withheld, disabled and reclaiming are three different things

dig-node’s internal BondState (mirror/pass.rs) used the single word Withheld for the node-wide collateralisation switch being OFF, while dig-node SPEC.md §25.8 used the same word for a capsule of Relayed provenance — one this node holds but deliberately never advertises. They are not the same state. They differ in SCOPE (one switch for the node, versus one capsule’s provenance) and, more importantly, in REMEDY: an operator told “withheld” about a disabled node goes looking at content, and one told “withheld” about a relayed capsule goes looking for a switch. This contract keeps them apart, and neither existing use survives unchanged:

  • Withheld carries §25.8’s meaning — Relayed provenance, per capsule.
  • Disabled is the node-wide switch, which §25.8 could not express at all.
  • Unadvertised is that switch being ON while the node still has nothing publishable to advertise. It is node-wide like disabled and is deliberately NOT the same value: disabled is the operator’s own decision and MUST NOT be shown as a fault, so a node served under it would oblige a conforming client to stay silent about a real failure.
  • Reclaiming is §25.8’s seventh state, which BondState had no variant for even though the money is still locked while it lasts.

So dig-node MUST rename BondState::Withheld to Disabled and add Withheld + Reclaiming, and §25.8 MUST gain disabled. Serving the old enum under §25.8’s words would publish a contract whose terms mean something else — the drift class this crate exists to prevent.

Withheld is VACUOUS until dig-node’s surface enumerates its SERVED set rather than its Held set. A relayed capsule is by construction absent from the desired-bond set, so a derivation keyed on Held bonds can never emit this variant — it would silently answer “no such row” where §25.8 promises “withheld on purpose”. Declaring it here is correct; a producer that cannot reach it MUST say so rather than report the state as satisfied.

Variants§

§

Bonded

A coin bonding this (store, root) for the CURRENT epoch is on chain.

Fields

§coin_id: String

The coin a person can look up, hex, no 0x.

§epoch: u64

The epoch it bonds, one-based.

§amount_dig_base_units: u64

What the coin actually LOCKS, in DIG base units, read from the coin — never from this epoch’s requirement. A coin created under a previous requirement locks the previous amount, and rendering today’s price against yesterday’s coin is a figure nobody holds.

§urls: Vec<String>

The advertise URL(s) THIS COIN’s memo carries — read at the moment it was created, not recomputed. A coin minted before the node’s public address changed still carries its OLD address; this is how a client sees that without decoding the memo itself.

§url_current: bool

Does urls set-equal what this node advertises THIS PASS?

The one field control.mirror.reconcile exists to fix when it goes false. Carried per row, alongside urls, because a client would otherwise need a SECOND call (control.config.get) and a set comparison of its own to answer “is this bond stale” — and would need to repeat that comparison for every row on every render. false here is not a fault by itself: it is exactly the condition control.mirror.reconcile reconciles away, and UrlReconcileStatus::stale_bonds is the count of this flag being false across the WHOLE bond set, not just this page.

§

Pending

A create for this bond has been submitted and has not confirmed.

Nothing is wrong and no money is missing. A client MUST NOT render this as a shortfall.

§

Unfunded

The wallet cannot cover the create for this bond.

The genuine out-of-funds state, and the ONLY one a client may raise a funding alarm on.

Fields

§short_dig_base_units: u64

How many more DIG base units THIS BOND alone needs.

DIG base units — $DIG has 3 decimals, so one unit is 0.001 DIG. It is NOT a mojo, which is XCH’s 1e-12 unit, nine orders of magnitude away. A mirror amount is never quoted in mojos.

Per bond, never a total. “How short is this node overall” is control.collateral.buffer’s question, and it answers it authoritatively.

§

Deferred

The epoch’s collateral requirement is not known, so no create can be PRICED.

NOT an out-of-funds state. The wallet may be full. A client that renders this as a shortfall tells an operator to send money that would change nothing.

Fields

§reason: CollateralUnknownReason

Why the requirement is unknown, in the SAME taxonomy CollateralRequirementResult::Unknown uses.

Reused rather than restated: a second copy of that taxonomy here would drift from the original, and a client already renders these tokens for control.collateral.requirement.

§

Withheld

This node holds the capsule with Relayed provenance: it does not claim to serve it, and deliberately never advertises it.

§25.8’s withheld. Nothing is wrong, nothing is owed, and there is no remedy — which is exactly why conflating it with Unfunded is the dig-app#300 defect.

§

Disabled

Collateralisation is switched OFF for this node, so no bond is advertised regardless of funds, provenance or price.

Node-wide, not per capsule: every row reads disabled together. The remedy is a switch, and it is the operator’s own earlier decision — a client MUST NOT present it as a fault.

§

Unadvertised

This node has nothing publishable to advertise, so it advertises nothing and creates no mirror coin.

The node holds the capsule, its own collateralisation switch is ON, its wallet may be full and the epoch’s requirement may be perfectly well known. It simply has no advertise URL a peer could fetch from – the list is empty, or every entry in it was rejected as non-absolute or reachable only from this machine – and a mirror coin that advertised no URL would bond nothing.

A client MUST surface this as a fault. That is the whole difference between it and Disabled, which is also node-wide and also means “no coin”, but is the operator’s own earlier decision and MUST NOT be presented as one. Here the operator decided the opposite – the switch is ON – and the node is silently unable to honour it. The remedy is a publishable advertise URL, and it is the only remedy: sending $DIG changes nothing, which is why serving this as Unfunded is a false statement about money.

Node-wide like disabled: every row reads unadvertised together, because the URL list is one list for the node rather than a property of any capsule.

§

Reclaiming

A live coin is being reclaimed: the bond is going away and the money is not back yet.

Carries the coin because the funds are STILL LOCKED for the duration. A surface that showed this as unbonded-and-unlocked would report money as available that cannot be spent, and a reclaim that fails leaves the coin exactly where this says it is.

Fields

§coin_id: String

The coin being reclaimed, hex, no 0x.

§epoch: u64

The epoch that coin bonds — frequently a PREVIOUS epoch, which is usually why it is being reclaimed.

§amount_dig_base_units: u64

What it still locks, in DIG base units, read from the coin.

Trait Implementations§

Source§

impl Clone for MirrorBondState

Source§

fn clone(&self) -> MirrorBondState

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for MirrorBondState

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for MirrorBondState

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Eq for MirrorBondState

Source§

impl PartialEq for MirrorBondState

Source§

fn eq(&self, other: &MirrorBondState) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl Serialize for MirrorBondState

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for MirrorBondState

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.