Skip to content

unroll: drop zero-tree-depth gate that can block legitimate proofs (#372) - #455

Closed
ellemouton wants to merge 1 commit into
mainfrom
fix/372-zero-tree-depth-blocks-unroll
Closed

unroll: drop zero-tree-depth gate that can block legitimate proofs (#372)#455
ellemouton wants to merge 1 commit into
mainfrom
fix/372-zero-tree-depth-blocks-unroll

Conversation

@ellemouton

Copy link
Copy Markdown
Member

Closes #372.

Summary

unroll/proof_assembler.go::validateProofDescriptorShape rejected any Ancestry fragment with TreeDepth == 0. But TreeDepth is expiry-timing metadata — only consumed by vtxo.Descriptor.MaxTreeDepth() in vtxo/expiry.go. The proof assembler walks TreePath.Root directly via addTreePathNodes and never reads the scalar. With a malicious-indexer-poisoned TreeDepth = 0 already persisted (or legacy data from before stricter ingest validation), the unroll path would refuse to assemble a perfectly recoverable proof — stranding the VTXO whenever the operator is unavailable.

Fix

Removed the TreeDepth == 0 arm in validateProofDescriptorShape. The unroll boundary stays liberal about the scalar because the proof material is the TreePath, not the depth claim. Updated explanatory comments in proof_assembler.go and descriptor_resolver.go to document where the proper ingest-time check belongs (the sibling #370 fix at arkrpc.ValidateAncestryPathDepth).

Test plan

  • new TestValidateProofDescriptorAcceptsZeroTreeDepth — two-call form locks in "no sticky state" retry semantics
  • test fails when the gate is restored; passes with the gate removed
  • make lint-native — 0 issues
  • go test ./unroll/... ./oor/... ./vtxo/... — pass

Relationship to #370

Complementary, not conflicting. #370 (indexer-supplied zero tree depth can strand OOR VTXOs) installs the ingest-time validator at arkrpc.ValidateAncestryPathDepth so zero/under-reported values never reach persistence. #372 (this PR) ensures the unroll path stays liberal so legacy/pre-fix data still recovers. The new comment cross-references the #370 ingest path so a future tuner doesn't re-add the gate.

The per-fragment validateProofDescriptorShape rejected any Ancestry
fragment whose TreeDepth scalar was zero. TreeDepth is expiry-timing
metadata (see vtxo.Descriptor.MaxTreeDepth and vtxo/expiry.go); the
proof assembler walks TreePath.Root directly and never reads the
scalar. Because incoming OOR ancestry is built from indexer RPC data
by copying p.GetTreeDepth() verbatim, a malicious or version-skewed
indexer that supplies a non-empty TreePath with TreeDepth omitted or
forged to zero can persist a VTXO that accepts and validates fine on
receive but is permanently rejected at unroll time. That turns an
indexer-controlled scalar into a fund-stranding lever on the
cooperative-operator-unavailable path, which is the exact threat
model unilateral exit exists to defend against.

Drop the gate so a zero TreeDepth no longer blocks proof assembly,
and document the receive-side ingest boundary as the proper place to
validate the scalar against TreePath.Depth() (issue #370).

Closes #372.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request modifies the proof validation logic to stop requiring a non-zero TreeDepth in ancestry fragments. This change prevents a malicious or faulty indexer from blocking unilateral exits by providing a zeroed TreeDepth scalar, as the proof assembler relies on the TreePath instead. The PR includes updated documentation and a regression test to ensure zero tree depth is accepted. I have no feedback to provide.

@ellemouton
ellemouton marked this pull request as ready for review May 15, 2026 12:31
@ellemouton

Copy link
Copy Markdown
Member Author

Superseded by consolidated PR #459. Closing to reduce CI load.

@ellemouton ellemouton closed this May 15, 2026
ellemouton pushed a commit that referenced this pull request May 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[security][high] Untrusted zero tree depth can block unroll proofs

1 participant