lightninglabs / lightninglabs/wavelength

testing: contested unroll outcomes and operator fraud-response race tests

Open
#271 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

P2 safety tests unroll
Dominant language
Go
Stars
47
Forks
14
Avg merge
2d 6h
Merged PRs (30d)
103

Description

## Summary

The current unilateral exit test suite covers happy-path completion:
client unrolls → VTXO materializes → CSV wait → sweep → funds in wallet.
There is no coverage for **contested outcomes** where the operator
broadcasts a checkpoint or forfeit transaction that races the client's
unilateral exit.

These tests are critical because they exercise the most adversarial code
paths in the protocol — the scenarios where real money is at stake.

## Missing Test Scenarios

### 1. Operator Checkpoint Wins Race

Client spent a VTXO via OOR, then tries to unilateral exit the same VTXO.
The operator detects the fraud and broadcasts a checkpoint tx that races
the client's CSV delay.

Expected outcome: the checkpoint confirms first (no CSV delay), the
client's VTXO output is consumed, and the client's unroll actor should
detect the external spend and terminate gracefully.

```
Test flow:
1. Alice sends VTXO to Bob via OOR (VTXO now "spent")
2. Alice triggers unroll on the spent VTXO
3. Alice's unroll broadcasts tree path → VTXO appears on-chain
4. Operator detects and broadcasts checkpoint (collaborative path, no CSV)
5. Checkpoint confirms → VTXO output consumed by checkpoint
6. Alice's unroll actor detects external spend → job terminates
7. Assert: job status = FAILED, reason = "spent externally"
8. Assert: operator checkpoint output exists on-chain
```

### 2. Operator Forfeit Wins Race

Same setup but the VTXO was forfeited (used as input in a new round).
The operator broadcasts the connector tree + forfeit tx.

### 3. Client Wins Race (Operator Too Slow)

The client's CSV delay elapses before the operator responds. The client
sweeps the VTXO. The operator's belated checkpoint broadcast fails because
the VTXO output is already spent.

```
Test flow:
1. Setup same as #1, but disable/delay operator fraud response
2. Mine csv_delay blocks
3. Client sweeps successfully
4. Operator's checkpoint broadcast fails (output already spent)
5. Assert: client funds in wallet, operator has fraud proof but lost race
```

### 4. Simultaneous Client Exit of Multiple VTXOs

Client triggers unroll on two VTXOs from the same batch. One is legitimate
(Live), one is fraudulent (Spent). The operator responds to the fraudulent
one but not the legitimate one.

Expected: legitimate unroll completes, fraudulent one is preempted.

### 5. External Spend During CSV Wait

After the VTXO is on-chain and the client is waiting for CSV maturity,
the output is spent externally (operator broadcasts checkpoint/forfeit).

PR #263's unroll actor mentions "A spend watch on the target outpoint
detects external spends early, terminating the job with a clear 'spent
externally' reason." This needs explicit test coverage.

### 6. External Spend During Proof Materialization

While the client is still broadcasting the tree path (before the VTXO
even materializes), the operator pre-emptively broadcasts a competing
tree path that results in a different VTXO output. The client's tree
path broadcast should detect the conflict.

## Test Infrastructure Needed

These tests require:
- A way to control operator fraud response timing (delay/disable/enable)
- A way to advance the chain (mine blocks) at specific points
- Access to both client and server harness state
- Server PR #219's `ArkHarness` with real-daemon clients

The server-side integration test harness from PR #219 supports this
pattern — the tests should live alongside `itest/unroll_test.go`.

## Acceptance Criteria

- [ ] Test: operator checkpoint beats client CSV → client job fails gracefully
- [ ] Test: client CSV elapses before operator responds → client wins
- [ ] Test: external spend during CSV wait → client detects and terminates
- [ ] Test: mixed legitimate + fraudulent unroll → correct outcomes
- [ ] All "spent externally" paths produce clear error messages
- [ ] No panics, deadlocks, or goroutine leaks in contested paths

## Related

- PR #263 (`unroll/actor.go` — external spend detection)
- PR #219 (`itest/unroll_test.go` — happy-path tests)
- darepo#252 (server-side fraud response integration tests)
- ARK-04 §"Fraud Response Protocol" (operator's perspective)
- ARK-05 §"Unilateral Exit Procedure" (client's perspective)

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 with itest/unroll_test.go and the server PR #219 ArkHarness, then read unroll/actor.go for the external-spend behavior described by PR #263. Add coverage for checkpoint and forfeit races, client wins, mixed unrolls, and spends during CSV wait or proof materialization. Done means the acceptance scenarios pass without panics, deadlocks, or goroutine leaks and report clear "spent externally" errors.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
distributed-systems, testing-qa
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.