Skip to content

collateral buffer: is a Disabled bond bondable? the count excludes only Withheld #429

Description

@MichaelTaylor3d

Parent epic: https://github.com/DIG-Network/dig_ecosystem/issues/3166
Sibling: #412 (the lifecycle family this came out of)

Task

bondable_pairs counts every served row except BondState::Withheld. Establish whether
BondState::Disabled belongs in that exclusion too, and make the answer explicit in code and in the
doc — either by excluding it, or by stating why a Disabled row still locks collateral.

Context

Found by the PR #419 gate round, out of that re-gate's scope, so it was left rather than guessed at.

  • bondable_pairscrates/dig-node-service/src/control.rs, the count that feeds
    control.collateral.buffer.
  • BondState::Disabledcrates/dig-node-service/src/mirror/pass.rs:104.
  • The function's own doc asserts "every state except Withheld", so this is a contract
    question rather than an obvious bug. Nothing currently in the tree establishes that Disabled
    is bondable
    — it is asserted by the doc and by nothing else.

Disabled describes a capsule this node deliberately does not advertise and whose coin is
being reclaimed — which is, on its face, the same situation as Withheld: nothing to lock
collateral against.

Why this is a ticket and not a comment

It fails in the money-inflating direction, and it is the same direction as the defect the
Withheld exclusion was added to fix. If a Disabled row locks nothing, the buffer advice
over-states what the operator must hold — telling someone to reserve $DIG against a bond that is
on its way out. A collateral figure that is wrong upward is a surface making a claim about the
operator's money.

Scope

Answer the contract question first, then encode it. If Disabled is excluded, the test at
control.rs:3773 extends with a fifth row; if it is not excluded, the doc gains the sentence
saying why, so the next reader does not re-open this.

Do not widen it into a general audit of the state machine.

Evidence

The existing test is load-bearing and shows the shape to copy — reverting the filter to
observation.states.len() is red at left: 4 / right: 3. Whichever way this resolves, it needs a
test that distinguishes the contract from "count everything" and from "count the last row" — a
two-row fixture answers 1 under several wrong predicates, which is why the current test uses four
rows carrying three distinct states.

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