Skip to content

the adaptive derivation window is steerable by a peer — peer-supplied coins widen the set that admits peer-supplied coins #297

Description

@MichaelTaylor3d

Task

The adaptive derivation window is steerable by a peer. Bound it against peer-supplied input, or make
the window's growth depend on something the peer cannot choose.

Mechanism

occupied_puzzle_hashes() reads coins, which sync::apply_coin_states fills from unverified peer
frames
, filtered only by subscription membership — and the subscribed set is the window, which the
node hands the peer. So the peer learns exactly which hashes will be accepted, and coins it sends widen
the set it is then allowed to send more into.

Measured shape: a Corroborated peer can ratchet to MAX_DERIVATION_COUNT over roughly 98 unlocks, at
~12.5s per unlock, producing ~50k-hash subscription frames.

Severity, stated honestly

LOW-MEDIUM, defense-in-depth. No money is at risk and the growth is boundedMAX_DERIVATION_COUNT
clamps it, so this is resource inflation rather than a custody defect. Filed because the feedback loop
(peer input widens the set that admits peer input) is the property worth removing, not because anything is
currently broken.

Found during the pre-merge security audit of dig-node PR #295, which PASSED — this was explicitly
non-gating.

Shape questions

  • What should growth actually key on? Occupancy is the natural signal and it is exactly the
    peer-supplied one. A window driven by confirmed-on-chain coins rather than by frames a peer asserts
    would break the loop, at the cost of lag.
  • Is a 50k-hash subscription frame acceptable on its own terms? Independently of the ratchet, that is
    a large frame to send and to be asked to process.
  • NC-12 binds: every dialled peer is untrusted, and Corroborated is a state a peer reaches, not a
    guarantee about it.

Related findings from the same audit, worth folding in or splitting

  • release_spend has no production caller — dead code on a custody-adjacent path. Wire it or delete
    it; leaving it is worse than either.
  • MAX_DERIVATION_COUNT's comment names a hand-edited-manifest channel that does not exist
    (derivation_count is a compile-time constant). The clamp is correct; its stated rationale is not, and a
    false rationale is what justifies leaving a real bound unexamined.
  • Reservation is gated on an untrusted accepted — fail-open if a source denies relaying what it
    relayed, fail-closed for 10 min if it over-claims. Follow-up: treat post-transmit transport failure as
    possibly-in-flight.
  • Resident secret-key count rises ~20x by defaultchia-bls 0.22 SecretKey has no Drop/zeroize.
    Upstream, not fixable here; recorded so it is not rediscovered as a local defect.

Parent

https://github.com/DIG-Network/dig_ecosystem/issues/2760

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind:maintenancereal work that changes nothing a user can perceive

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions