commit 98e8f9cc3d5c4883e91eedeae380654d6a53b8f3
parent 5f3f647e766f29a6d57a199c8e6ec91b593277a1
Author: Jared Tobin <jared@jtobin.io>
Date: Sun, 25 Jan 2026 10:49:52 +0400
Add implementation plan (IMPL1.md)
Outlines milestones for BOLT #3 implementation:
- M0: Types and module stubs
- M1: Keys and Scripts (parallelizable)
- M2: Transaction assembly
- M3: Encode/Decode/Validate (parallelizable)
- M4: Public API
- M5: Tests and benchmarks
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat:
| A | plans/ARCH1.md | | | 91 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | plans/IMPL1.md | | | 65 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
2 files changed, 156 insertions(+), 0 deletions(-)
diff --git a/plans/ARCH1.md b/plans/ARCH1.md
@@ -0,0 +1,91 @@
+# ARCH1: ppad-bolt3 architecture plan
+
+## Goals
+
+- Implement BOLT #3 transaction formats and validation rules in Haskell.
+- Provide total, type-safe constructors and parsers for BOLT #3 data.
+- Keep dependencies minimal (GHC core/boot + ppad-* libraries).
+- Maintain performance with strict fields and unboxed primitives where
+ useful.
+
+## Scope
+
+- Channel funding, commitment, HTLC, and closing transaction formats.
+- Script templates and witness construction per BOLT #3.
+- Parsing and serialization of all BOLT #3 transaction types.
+- Fee/weight accounting and dust checks.
+- Test vectors from the BOLT spec and related references.
+
+## Non-goals (initial)
+
+- Network-level negotiation (BOLT #2).
+- Gossip / routing (BOLT #7, #10).
+- On-chain wallet management.
+- Full Bitcoin scripting engine.
+
+## Module layout
+
+- `Lightning.Protocol.BOLT3`
+ - Re-export public API.
+
+- `Lightning.Protocol.BOLT3.Types`
+ - Newtypes for satoshis, milli-satoshis, txid, outpoint, scripts.
+ - Invariant-encoding ADTs for transaction variants.
+
+- `Lightning.Protocol.BOLT3.Keys`
+ - Key derivation helpers (per-commitment point/secret handling).
+
+- `Lightning.Protocol.BOLT3.Scripts`
+ - Script templates (P2WSH, HTLC scripts, to_remote/to_local).
+ - Witness construction.
+
+- `Lightning.Protocol.BOLT3.Tx`
+ - Transaction assembly for funding/commitment/HTLC/closing.
+ - Weight and fee computation.
+
+- `Lightning.Protocol.BOLT3.Encode`
+ - Serialization to Bitcoin tx format.
+
+- `Lightning.Protocol.BOLT3.Decode`
+ - Parsing from Bitcoin tx format with validation.
+
+- `Lightning.Protocol.BOLT3.Validate`
+ - Stateless validation rules (dust limits, script forms, fee rules).
+
+## Data modeling principles
+
+- Use newtypes for all numeric and hash-like primitives.
+- Encode illegal states as unrepresentable (ADTs for tx variants).
+- Provide smart constructors for all externally supplied data.
+- Avoid partial functions; return `Maybe`/`Either` for fallible ops.
+
+## Performance strategy
+
+- Use strict fields with `!` and `UNPACK` where helpful.
+- Inline small helpers; use `MagicHash` for hot-path primitives only
+ when profiling shows the need.
+- Avoid intermediate allocations in serialization.
+
+## External dependencies
+
+- Prefer GHC core/boot libs (base, bytestring, etc.).
+- Use ppad-* libraries for primitives (hashing, fixed-size types).
+- Ask before adding any external dependency outside policy.
+
+## Testing strategy
+
+- `test/Main.hs` uses tasty.
+- Unit tests for each script/tx type using BOLT #3 vectors.
+- Property tests for invariants (serialization roundtrip, fee bounds).
+
+## Benchmarking strategy
+
+- `bench/Main.hs`: criterion for serialization and tx assembly.
+- `bench/Weight.hs`: weigh for allocations in hot paths.
+- Add NFData instances for benchmarked types.
+
+## Open questions
+
+- Which ppad-* libraries should be preferred for hash/bytes types?
+- Should we expose low-level Bitcoin tx types or keep them internal?
+- Expected API surface: minimal constructors or full builder API?
diff --git a/plans/IMPL1.md b/plans/IMPL1.md
@@ -0,0 +1,65 @@
+# IMPL1: ppad-bolt3 implementation plan
+
+## Milestone 0: groundwork
+
+- Verify project layout and create module stubs under `lib/`.
+- Define core newtypes and ADTs in `Lightning.Protocol.BOLT3.Types`.
+- Add smart constructors and total helpers.
+
+## Milestone 1: scripts and keys
+
+- Implement per-commitment key helpers in
+ `Lightning.Protocol.BOLT3.Keys`.
+- Implement script templates in `Lightning.Protocol.BOLT3.Scripts`:
+ - to_local, to_remote, HTLC offered/received, anchor outputs.
+ - Witness construction helpers.
+
+## Milestone 2: transaction assembly
+
+- Implement tx assembly in `Lightning.Protocol.BOLT3.Tx`:
+ - Funding transaction (if needed for completeness).
+ - Commitment tx (local/remote).
+ - HTLC-timeout and HTLC-success.
+ - Closing tx.
+- Implement weight and fee accounting helpers.
+
+## Milestone 3: encode/decode
+
+- Implement serialization in `Lightning.Protocol.BOLT3.Encode`.
+- Implement parsing + validation in `Lightning.Protocol.BOLT3.Decode`.
+- Implement `Lightning.Protocol.BOLT3.Validate` for stateless rules.
+
+## Milestone 4: public API
+
+- Wire re-exports in `Lightning.Protocol.BOLT3`.
+- Document exported functions with Haddock examples.
+
+## Milestone 5: tests and benchmarks
+
+- Add BOLT #3 vector tests in `test/Main.hs` (tasty-hunit).
+- Add property tests (roundtrip, fee bounds) using tasty-quickcheck.
+- Add benchmarks for serialization + assembly in `bench/Main.hs`.
+- Add allocation tracking in `bench/Weight.hs`.
+
+## Independent work items
+
+- Keys module can proceed in parallel with Scripts.
+- Encode/Decode modules can be developed in parallel after Types.
+- Benchmarks can start after Encode/Tx signatures are stable.
+
+## Risks and mitigations
+
+- Spec ambiguities: annotate with links to BOLT #3 sections.
+- Performance regressions: keep strictness + benchmark early.
+- Validation gaps: cross-check with spec vectors.
+
+## Deliverables
+
+- Full BOLT #3 tx modeling and serialization.
+- Validation helpers with total APIs.
+- Test suite + benchmarks per project conventions.
+
+## Local references
+
+- If other BOLT implementations are needed, prefer local copies in
+ sibling repos (e.g. `../bolt1`) over fetching externally.