bolt2

Lightning peer protocol, per BOLT #2 (docs.ppad.tech/bolt2).
git clone git://git.ppad.tech/bolt2.git
Log | Files | Refs | README | LICENSE

CLAUDE.md (4431B)


      1 # ppad-bolt2
      2 
      3 Haskell implementation of BOLT #2 (Lightning Network peer protocol).
      4 
      5 Specification: https://github.com/lightning/bolts/blob/master/02-peer-protocol.md
      6 (implemented as of lightning/bolts 1aadb719; a copy lives in `etc/`).
      7 
      8 ## Project Structure
      9 
     10 - `lib/` - library source (Lightning.Protocol.BOLT2)
     11 - `test/` - tests (tasty, tasty-hunit, tasty-quickcheck)
     12 - `bench/` - benchmarks (criterion for timing, weigh for allocations)
     13 - `etc/` - reference materials (BOLT spec)
     14 - `flake.nix` - nix flake for dependency and build management
     15 - `ppad-bolt2.cabal` - cabal package definition
     16 - `CLAUDE.md` / `AGENTS.md` - keep these in sync
     17 
     18 ## Build and Test
     19 
     20 Enter devshell and use cabal:
     21 
     22 ```
     23 nix develop
     24 cabal build
     25 cabal test
     26 cabal bench
     27 ```
     28 
     29 Do not use stack. All dependency and build management via nix.
     30 
     31 ## Dependencies
     32 
     33 ### ppad libraries (use freely)
     34 
     35 Use ppad libraries (github.com/ppad-tech, git.ppad.tech) liberally.
     36 Current dependencies: ppad-bolt1 (fundamental types, primitive codecs,
     37 TLV), ppad-bolt9 (feature vectors), ppad-tx (TxId).
     38 
     39 ### External libraries
     40 
     41 Use only minimal external dependencies. Prefer GHC's core/boot libraries
     42 (base, bytestring, primitive, etc.).
     43 
     44 **Ask for explicit confirmation before adding any library outside of:**
     45 - GHC boot/core libraries
     46 - ppad-* libraries
     47 - Test dependencies (tasty, QuickCheck, etc. for test-suite only)
     48 - Benchmark dependencies (criterion, weigh for benchmark only)
     49 
     50 ## Code Style
     51 
     52 ### Performance
     53 
     54 - Use strictness annotations (BangPatterns) liberally
     55 - Prefer UNPACK for strict record fields
     56 - Use MagicHash, UnboxedTuples, GHC.Exts for hot paths
     57 - Do not rely on UNBOX pragmas; implement primitives directly with
     58   MagicHash and GHC.Exts when needed
     59 - Use INLINE pragmas for small functions
     60 - Refer to ppad-sha256 and ppad-fixed for low-level patterns
     61 
     62 ### Type safety
     63 
     64 - Encode invariants into the type system
     65 - Use newtypes liberally (e.g., HtlcId, SerialId, ScriptPubKey)
     66 - Use ADTs to make illegal states unrepresentable
     67 - Prefer smart constructors that validate inputs
     68 
     69 ### Safety
     70 
     71 - Never use partial Prelude functions (head, tail, !!, etc.)
     72 - Avoid brittle partials in tests too (e.g., unchecked indexing). Prefer
     73   bounds checks or total helpers even in test code.
     74 - Avoid non-exhaustive pattern matches and unsafe behavior; use total
     75   helpers and make all constructors explicit.
     76 - Use Maybe/Either for fallible operations
     77 - Validate all inputs at system boundaries
     78 
     79 ### Formatting
     80 
     81 - Keep lines under 80 characters
     82 - Use Haskell2010
     83 - Module header with copyright, license, maintainer
     84 - OPTIONS_HADDOCK prune for public modules
     85 - Haddock examples for exported functions
     86 
     87 ## Testing
     88 
     89 Use tasty to wrap all tests:
     90 - tasty-hunit for unit tests with known vectors
     91 - tasty-quickcheck for property-based tests
     92 - Source test vectors from specifications (RFC, BOLT spec, Wycheproof, etc.)
     93 
     94 Property tests should enforce invariants that can't be encoded in types.
     95 
     96 ## Benchmarking
     97 
     98 Always maintain benchmark suites:
     99 - `bench/Main.hs` - criterion for wall-time benchmarks
    100 - `bench/Weight.hs` - weigh for allocation tracking
    101 
    102 Define NFData instances for types that need benchmarking.
    103 
    104 ## Git Workflow
    105 
    106 - Feature branches for development; commit freely there
    107 - Logical, atomic commits on feature branches
    108 - Master should be mostly merge commits
    109 - Merge to master with `--no-ff` after validation
    110 - Always build and test before creating a merge commit
    111 - Write detailed merge commit messages summarising changes
    112 
    113 ### Worktree flow (for planned work)
    114 
    115 When starting work on an implementation plan:
    116 
    117 ```
    118 git worktree add ./impl-<desc> -b impl/<desc> master
    119 # work in that worktree
    120 # merge to master when complete
    121 git worktree remove ./impl-<desc>
    122 ```
    123 
    124 ### Commits
    125 
    126 - Higher-level descriptions in merge commits
    127 - Never update git config
    128 - Never use destructive git commands (push --force, hard reset) without
    129   explicit request
    130 - Never skip hooks unless explicitly requested
    131 
    132 ## Planning
    133 
    134 When planning work:
    135 - Highlight which steps can be done independently
    136 - Consider forking subagents for concurrent work on independent steps
    137 - Write implementation plans to `plans/IMPL<n>.md` if the project uses
    138   this convention
    139 - Record outstanding design decisions and deferred work to `plans/TODO`
    140 
    141 ## Flake Structure
    142 
    143 The flake.nix follows ppad conventions:
    144 - Uses ppad-nixpkgs as base
    145 - Follows references to avoid duplication
    146 - Provides devShell with ghc, cabal, cc, llvm