Skip to content

Calculate a recommended $DIG buffer from node state, and expose the three funding states #389

Description

@MichaelTaylor3d

Parent epic: https://github.com/DIG-Network/dig_ecosystem/issues/3173
Consumer: DIG-Network/dig-app#306 (raises the notification from these states)
Contract: DIG-Network/dig-node-control-interface#32 (closed, published 0.23.0)

Body corrected 2026-08-28. This ticket was filed carrying dig-app#306's body verbatim — a
double-file. The title was always right; the body described the app-side notification. Rewritten
below to the node-side scope. Nothing about the work changed.

Task

Calculate a recommended $DIG buffer from the node's actual state, and expose the three funding
states
over the control plane. The node computes; dig-app#306 displays and notifies.

User directive, 2026-08-28, verbatim:

"we also need a os notification when we are dangeriously out of DIG, there should be a calculated
recommended buffer of DIG based on the state of the node."

This extends DIG-Network/dig-app#300, which distinguishes only shortfall
from no shortfall. A binary signal cannot say how much to add, which is the only question a
person receiving it actually has.

The subtlety that decides whether the number is useful or alarmist

Collateral is RECLAIMED, not spent. Each epoch the node creates coins for (store, root, epoch n)
and reclaims epoch n-1 — and #377 specifies that
reclaims run first in every pass and are never gated on funds, precisely so returned collateral
funds the creates behind it.

So the steady-state requirement is roughly one epoch's lock, not one per epoch. A buffer computed
as "requirement x epochs of runway" overstates by the number of epochs and tells a user to acquire
many times what they need.

What the buffer must cover:

  1. One epoch's lockpairs x required_per_store x (1 + margin). The standing commitment.
  2. The transition overlap — the window where epoch n coins exist before n-1 is reclaimed, or
    where a reclaim fails or is delayed. This is the real peak, and it is what an operator who has
    never seen a failed reclaim will not have budgeted for.
  3. Escalation headroom — the requirement can rise, bounded at +12.5% per epoch
    (UP_STEP_DENOM = 8 in dig-mirror-collateral).

Escalation compounds, so headroom is a horizon choice, not a constant:

after wall clock factor headroom
1 epoch 7 days x1.12 12.5%
2 epochs 14 days x1.27 26.6%
4 epochs 28 days x1.60 60.2%
8 epochs 56 days x2.57 156.6%
13 epochs 91 days x4.62 362.4%

Pick a horizon and justify it in the output. A quarter of worst-case escalation demands 4.6x the
current lock, which is not advice anyone will follow; around a month reads as prudent. State the
horizon so the number is checkable rather than magic, and say plainly that the ceiling is a worst
case, not a forecast
— in the dead band the multiplier does not move at all.

The three states

state meaning dig-app#306 surface
Short now cannot cover the current epoch; stores are already going uncollateralised notify
Dangerously low covers now, but cannot cover the next epoch at the escalation ceiling notify
Below recommended buffer fine for several epochs, no cushion readout only, never a notification

The third must not notify. A node in normal operation sits below a comfortable buffer much of the
time; notifying on it produces a recurring alert that is usually ignorable, which is how a user learns
to ignore the two that matter. That policy is stated here because this ticket owns the state
classification; the notification behaviour itself is dig-app#306.

Requirements

  • Say the number. The output must support "Add ~N DIG", not "balance low". The whole point of
    a calculated buffer is that it converts an alarm into an action.
  • Show the working — pairs served, current required_per_store, margin, and the horizon used. A
    figure a client cannot render a justification for is a figure a user will not act on.
  • Never report a figure on unknown state. If the node cannot determine its requirement or its
    store set, the answer is unknown — not zero and not a guess. This is the money-lie rule;
    BalanceReading's pending/known/unknown split is the shape to reuse.
  • Use dig-mirror-collateral's required_per_store. Do not restate the arithmetic:
    equilibrium x multiplier - handicap omits the floor clamp and is wrong as a formula.
  • $DIG has 3 decimals; its base unit is 0.001 DIG. A mojo is XCH's base unit (1e-12 XCH). Nine
    orders of magnitude apart — do not let one name touch the other here.

Where it lives

In the node. It needs the store set, the epoch requirement, the margin and the reclaim state, all
of which are node-side. It is a natural fit for the control.collateral.* methods declared in
dig-node-control-interface 0.23.0, so one answer serves the readout, the notification and the margin
cost figure together — and dign can answer the same question on a headless host where no
notification will ever fire.

Acceptance

On a real funded node: the recommended buffer is a specific number the operator can check against
their own arithmetic; the three states are distinguishable over the control plane and from dign; and
a node with unknown state reports unknown rather than a figure.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions