lightninglabs / lightninglabs/taproot-assets

Make STXO (V1) transition proofs mandatory

Open
#2,240 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement tap-channels
Dominant language
Go
Stars
525
Forks
150
Avg merge
2d 15h
Merged PRs (30d)
31

Description

## Background

STXO proofs (`TransitionV1`) commit an alt leaf for every input an asset transition spends, alongside the created outputs, in the anchor commitment. They currently sit behind the `STXOOptional` feature bit: a node produces and demands V1 proofs only when its counterparty advertises the bit, and falls back to `TransitionV0` otherwise (e.g. `tapchannel/aux_funding_controller.go`, `GetPeerFeatures` → `HasFeature(tapfeatures.STXOOptional)`).

Because the counterparty chooses whether the bit is advertised, none of the STXO invariants can currently be *relied* upon: any peer can opt out unilaterally and be served the V0 path. As long as that is true, STXO is an optimization for honest peers rather than a guarantee.

Two properties in particular are only enforced on the V1 path:

- Duplicate spent-input rejection at commitment construction: `commitment.MergeAltLeaves` rejects colliding alt-leaf keys (`asset.ErrDuplicateAltLeafKey`), so a commitment cannot commit two transitions consuming the same input. PR #2236 adds explicit, version-independent input-uniqueness checks to channel funding; a mandatory STXO path would extend the same property to every V1 commitment as defense in depth.
- STXO exclusion proofs: the verifier demands STXO proofs only for `IsVersionV1()` proofs, so V0 transitions carry no spent-input commitments at all.

## Proposal

Make V1/STXO proofs mandatory in v0.9:

1. Always advertise `STXOOptional`.
2. Asset channels: require the peer to advertise the bit and reject funding flows (and `TransitionV0` funding suffixes) when it does not. This is the security-relevant surface, since channel funding accepts peer-authored transitions.
3. Transfers: produce `TransitionV1` unconditionally for new transitions. Continue to *verify* V0 proofs indefinitely — historical lineages must keep validating.
4. Rename or supersede the feature bit (`STXORequired`?) so the policy is explicit in negotiation rather than implied.

## Compatibility

- v0.8 and earlier peers that do not advertise `STXOOptional` will be unable to open new asset channels against v0.9 nodes. Existing channels are unaffected.
- Receiving transfers from old senders: V0 proofs remain verifiable; whether new *incoming* V0 transitions should be rejected after a deprecation window is an open question below.

## Open questions

- Deprecation window for non-channel V0 transitions, if any.
- Whether the channel requirement should be a hard reject at funding or negotiated via a new required feature bit.
- Interaction with backward-compat test coverage (`TestBackwardsCompatChannels`): the v0.8 compat pairing will need a carve-out or a pinned expectation once funding requires the bit.

## Acceptance criteria

- A v0.9 node never produces a `TransitionV0` proof for a new transition.
- Asset channel funding fails cleanly (clear error to lnd and the peer) when the counterparty does not support STXO.
- All V0 lineages produced before the cutover still verify.
- itest coverage for the new rejection path and for V0→V1 mixed lineages.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing tapchannel/aux_funding_controller.go and GetPeerFeatures, then inspect commitment.MergeAltLeaves and TestBackwardsCompatChannels. Resolve the open negotiation and deprecation questions before changing funding and transition production; done means no new TransitionV0 proofs, clear rejection for unsupported channel peers, historical V0 verification, and itest coverage for rejection and mixed lineages.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
backend, security
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.