bolt3

Lightning transaction and script formats, per BOLT #3 (docs.ppad.tech/bolt3).
git clone git://git.ppad.tech/bolt3.git
Log | Files | Refs | README | LICENSE

AGENTS.md (4411B)


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