ARCH3.md (2841B)
1 # ARCH3 - Type Safety Improvements 2 3 ## Goals 4 5 - Encode fixed-size byte invariants into the type system. 6 - Enforce TLV stream ordering at construction time. 7 - Eliminate runtime validation where possible via smart constructors. 8 9 ## New Types 10 11 ### ChannelId 12 13 32-byte channel identifier used in Error and Warning messages. 14 15 ```haskell 16 newtype ChannelId = ChannelId { unChannelId :: BS.ByteString } 17 18 channelId :: BS.ByteString -> Maybe ChannelId 19 channelId bs 20 | BS.length bs == 32 = Just (ChannelId bs) 21 | otherwise = Nothing 22 23 -- | The all-zeros channel ID (refers to all channels). 24 allChannels :: ChannelId 25 ``` 26 27 Replaces raw `ByteString` in `Error` and `Warning` message types. 28 29 ### ChainHash 30 31 32-byte chain hash used in Init TLV networks field. 32 33 ```haskell 34 newtype ChainHash = ChainHash { unChainHash :: BS.ByteString } 35 36 chainHash :: BS.ByteString -> Maybe ChainHash 37 chainHash bs 38 | BS.length bs == 32 = Just (ChainHash bs) 39 | otherwise = Nothing 40 ``` 41 42 `InitNetworks` changes from `[BS.ByteString]` to `[ChainHash]`. 43 44 ### Ordered TlvStream 45 46 TLV streams must have strictly increasing type values. Currently 47 validated at decode time but not enforced at construction. 48 49 ```haskell 50 newtype TlvStream = TlvStream { unTlvStream :: [TlvRecord] } 51 52 -- | Smart constructor that validates ordering. 53 tlvStream :: [TlvRecord] -> Maybe TlvStream 54 55 -- | Build from records known to be ordered (internal use). 56 unsafeTlvStream :: [TlvRecord] -> TlvStream 57 ``` 58 59 The raw constructor becomes internal; external code uses the smart 60 constructor or decode functions (which validate ordering). 61 62 ## Module Changes 63 64 ### Lightning.Protocol.BOLT1.Message 65 66 - Add `ChannelId` newtype + smart constructor + `allChannels`. 67 - Update `Error` and `Warning` to use `ChannelId`. 68 - Update `InitNetworks` to use `[ChainHash]`. 69 - Add `ChainHash` newtype + smart constructor. 70 71 ### Lightning.Protocol.BOLT1.TLV 72 73 - Hide `TlvStream` constructor from public API. 74 - Export `tlvStream` smart constructor. 75 - Export `unsafeTlvStream` for internal/advanced use. 76 - Decoders already validate ordering; no changes needed there. 77 78 ### Lightning.Protocol.BOLT1.Codec 79 80 - Update Error/Warning encode/decode to use `ChannelId`. 81 - Update Init TLV encode/decode to use `ChainHash`. 82 83 ### Lightning.Protocol.BOLT1 84 85 - Re-export new types and constructors. 86 87 ## Validation Strategy 88 89 - `ChannelId` and `ChainHash`: validate length at construction. 90 - `TlvStream`: validate strictly-increasing types at construction. 91 - Decoders produce validated types directly. 92 - Encoders accept only validated types (no runtime checks needed). 93 94 ## API Impact 95 96 Breaking changes to: 97 - `Error` and `Warning` record fields (ByteString -> ChannelId). 98 - `InitNetworks` constructor (ByteString list -> ChainHash list). 99 - `TlvStream` constructor (now hidden; use smart constructor). 100 101 These are source-breaking but type-safe migrations.