IMPL2a.md (2996B)
1 # IMPL2a: Smart Constructors for Type Safety 2 3 Implements the type-level invariant enforcement from ARCH2.md. 4 5 ## Scope 6 7 - Add smart constructors for size-constrained ByteString newtypes 8 - Add smart constructor for CommitmentNumber (48-bit range) 9 - Update exports in Types.hs and BOLT3.hs 10 11 ## Tasks 12 13 ### 1. Add smart constructors to Types.hs 14 15 Add the following smart constructors in `lib/Lightning/Protocol/BOLT3/Types.hs`: 16 17 ```haskell 18 -- 33-byte types 19 pubkey :: BS.ByteString -> Maybe Pubkey 20 point :: BS.ByteString -> Maybe Point 21 22 -- 32-byte types 23 seckey :: BS.ByteString -> Maybe Seckey 24 txid :: BS.ByteString -> Maybe TxId 25 payment_hash :: BS.ByteString -> Maybe PaymentHash 26 payment_preimage :: BS.ByteString -> Maybe PaymentPreimage 27 per_commitment_secret :: BS.ByteString -> Maybe PerCommitmentSecret 28 29 -- 48-bit range 30 commitment_number :: Word64 -> Maybe CommitmentNumber 31 ``` 32 33 Implementation pattern: 34 35 ```haskell 36 -- | Parse a 33-byte compressed public key. 37 -- 38 -- Returns Nothing if the input is not exactly 33 bytes. 39 -- 40 -- >>> pubkey (BS.replicate 33 0x02) 41 -- Just (Pubkey ...) 42 -- >>> pubkey (BS.replicate 32 0x02) 43 -- Nothing 44 pubkey :: BS.ByteString -> Maybe Pubkey 45 pubkey bs 46 | BS.length bs == 33 = Just (Pubkey bs) 47 | otherwise = Nothing 48 {-# INLINE pubkey #-} 49 ``` 50 51 ### 2. Update Types.hs exports 52 53 Add the smart constructors to the export list, grouped with their 54 corresponding types: 55 56 ```haskell 57 -- * Keys and points 58 , Pubkey(..) 59 , pubkey 60 , Seckey(..) 61 , seckey 62 , Point(..) 63 , point 64 ... 65 ``` 66 67 ### 3. Update BOLT3.hs re-exports 68 69 Add the new smart constructors to the main module's export list: 70 71 ```haskell 72 -- ** Keys and points 73 , Pubkey(..) 74 , pubkey 75 , Seckey(..) 76 , seckey 77 , Point(..) 78 , point 79 ... 80 ``` 81 82 ### 4. Add tests for smart constructors 83 84 Add test cases to `test/Main.hs`: 85 86 ```haskell 87 smartConstructorTests :: TestTree 88 smartConstructorTests = testGroup "Smart constructors" [ 89 testCase "pubkey accepts 33 bytes" $ do 90 let bs = BS.replicate 33 0x02 91 isJust (pubkey bs) @?= True 92 , testCase "pubkey rejects 32 bytes" $ do 93 let bs = BS.replicate 32 0x02 94 isNothing (pubkey bs) @?= True 95 , testCase "commitment_number accepts 2^48-1" $ do 96 isJust (commitment_number 281474976710655) @?= True 97 , testCase "commitment_number rejects 2^48" $ do 98 isNothing (commitment_number 281474976710656) @?= True 99 ... 100 ] 101 ``` 102 103 ### 5. Verify build and tests pass 104 105 ```bash 106 nix develop -c cabal build all 107 nix develop -c cabal test 108 ``` 109 110 ## Files Modified 111 112 - `lib/Lightning/Protocol/BOLT3/Types.hs` 113 - `lib/Lightning/Protocol/BOLT3.hs` 114 - `test/Main.hs` 115 116 ## Commit Message 117 118 ``` 119 Add smart constructors for type-safe parsing 120 121 - pubkey/point: validate 33-byte compressed EC points 122 - seckey/txid/payment_hash/payment_preimage: validate 32-byte values 123 - per_commitment_secret: validate 32-byte secrets 124 - commitment_number: validate 48-bit range 125 126 Raw constructors remain exported for internal use where size is 127 already guaranteed by construction. 128 ```