bolt1

Base Lightning protocol, per BOLT #1 (docs.ppad.tech/bolt1).
git clone git://git.ppad.tech/bolt1.git
Log | Files | Refs | README | LICENSE

Fixtures.hs (13414B)


      1 {-# LANGUAGE BangPatterns #-}
      2 {-# LANGUAGE OverloadedStrings #-}
      3 
      4 -- |
      5 -- Module: Fixtures
      6 -- Copyright: (c) 2025 Jared Tobin
      7 -- License: MIT
      8 -- Maintainer: Jared Tobin <jared@ppad.tech>
      9 --
     10 -- Test fixtures for BOLT #1 benchmarks.
     11 
     12 module Fixtures where
     13 
     14 import qualified Data.ByteString as BS
     15 import Data.Maybe (fromJust)
     16 import Lightning.Protocol.BOLT1
     17 
     18 -- Sample ByteStrings -----------------------------------------------------
     19 
     20 -- | 64-byte sample data.
     21 bytes64 :: BS.ByteString
     22 bytes64 = BS.replicate 64 0xAB
     23 {-# NOINLINE bytes64 #-}
     24 
     25 -- | 1KB sample data.
     26 bytes1k :: BS.ByteString
     27 bytes1k = BS.replicate 1024 0xCD
     28 {-# NOINLINE bytes1k #-}
     29 
     30 -- | 16KB sample data.
     31 bytes16k :: BS.ByteString
     32 bytes16k = BS.replicate 16384 0xEF
     33 {-# NOINLINE bytes16k #-}
     34 
     35 -- Sample chain hashes (32 bytes each) ------------------------------------
     36 
     37 -- | Bitcoin mainnet genesis block hash (reversed, as used in LN).
     38 mainnetChainHash :: ChainHash
     39 mainnetChainHash = fromJust $ chainHash $ BS.pack
     40   [ 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72
     41   , 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f
     42   , 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c
     43   , 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00
     44   ]
     45 {-# NOINLINE mainnetChainHash #-}
     46 
     47 -- | Bitcoin testnet genesis block hash (reversed, as used in LN).
     48 testnetChainHash :: ChainHash
     49 testnetChainHash = fromJust $ chainHash $ BS.pack
     50   [ 0x43, 0x49, 0x7f, 0xd7, 0xf8, 0x26, 0x95, 0x71
     51   , 0x08, 0xf4, 0xa3, 0x0f, 0xd9, 0xce, 0xc3, 0xae
     52   , 0xba, 0x79, 0x97, 0x20, 0x84, 0xe9, 0x0e, 0xad
     53   , 0x01, 0xea, 0x33, 0x09, 0x00, 0x00, 0x00, 0x00
     54   ]
     55 {-# NOINLINE testnetChainHash #-}
     56 
     57 -- Sample channel IDs (32 bytes each) -------------------------------------
     58 
     59 -- | Sample channel ID (non-zero).
     60 sampleChannelId :: ChannelId
     61 sampleChannelId = fromJust $ channelId $ BS.pack
     62   [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
     63   , 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
     64   , 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18
     65   , 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20
     66   ]
     67 {-# NOINLINE sampleChannelId #-}
     68 
     69 -- Sample Init messages ---------------------------------------------------
     70 
     71 -- | Minimal Init message (empty features, no TLVs).
     72 minimalInit :: Init
     73 minimalInit = Init
     74   { initGlobalFeatures = BS.empty
     75   , initFeatures       = BS.empty
     76   , initTlvs           = []
     77   }
     78 {-# NOINLINE minimalInit #-}
     79 
     80 -- | Init with feature bits set.
     81 initWithFeatures :: Init
     82 initWithFeatures = Init
     83   { initGlobalFeatures = BS.pack [0x00, 0x01]  -- 2 bytes
     84   , initFeatures       = BS.pack [0x02, 0xa2]  -- data_loss_protect, etc.
     85   , initTlvs           = []
     86   }
     87 {-# NOINLINE initWithFeatures #-}
     88 
     89 -- | Init with TLV extensions.
     90 initWithTlvs :: Init
     91 initWithTlvs = Init
     92   { initGlobalFeatures = BS.empty
     93   , initFeatures       = BS.pack [0x02, 0xa2]
     94   , initTlvs           = [InitNetworks [mainnetChainHash]]
     95   }
     96 {-# NOINLINE initWithTlvs #-}
     97 
     98 -- | Init with multiple chain hashes.
     99 initWithMultipleChains :: Init
    100 initWithMultipleChains = Init
    101   { initGlobalFeatures = BS.empty
    102   , initFeatures       = BS.pack [0x02, 0xa2]
    103   , initTlvs           = [InitNetworks [mainnetChainHash, testnetChainHash]]
    104   }
    105 {-# NOINLINE initWithMultipleChains #-}
    106 
    107 -- | Full Init with features and remote_addr TLV.
    108 fullInit :: Init
    109 fullInit = Init
    110   { initGlobalFeatures = BS.pack [0x00, 0x01]
    111   , initFeatures       = BS.pack [0x02, 0xa2, 0x01]
    112   , initTlvs           =
    113       [ InitNetworks [mainnetChainHash]
    114       , InitRemoteAddr (BS.pack [0x01, 0x7f, 0x00, 0x00, 0x01, 0x27, 0x10])
    115       ]
    116   }
    117 {-# NOINLINE fullInit #-}
    118 
    119 -- Sample Error messages --------------------------------------------------
    120 
    121 -- | Minimal Error message (connection-level, empty data).
    122 minimalError :: Error
    123 minimalError = Error
    124   { errorChannelId = allChannels
    125   , errorData      = BS.empty
    126   }
    127 {-# NOINLINE minimalError #-}
    128 
    129 -- | Error with channel ID and message.
    130 errorWithData :: Error
    131 errorWithData = Error
    132   { errorChannelId = sampleChannelId
    133   , errorData      = "funding transaction failed"
    134   }
    135 {-# NOINLINE errorWithData #-}
    136 
    137 -- | Error with longer data.
    138 errorWithLongData :: Error
    139 errorWithLongData = Error
    140   { errorChannelId = sampleChannelId
    141   , errorData      = bytes1k
    142   }
    143 {-# NOINLINE errorWithLongData #-}
    144 
    145 -- Sample Warning messages ------------------------------------------------
    146 
    147 -- | Minimal Warning message.
    148 minimalWarning :: Warning
    149 minimalWarning = Warning
    150   { warningChannelId = allChannels
    151   , warningData      = BS.empty
    152   }
    153 {-# NOINLINE minimalWarning #-}
    154 
    155 -- | Warning with message.
    156 warningWithData :: Warning
    157 warningWithData = Warning
    158   { warningChannelId = sampleChannelId
    159   , warningData      = "channel fee too low"
    160   }
    161 {-# NOINLINE warningWithData #-}
    162 
    163 -- Sample Ping messages ---------------------------------------------------
    164 
    165 -- | Minimal Ping (no padding, no response requested).
    166 minimalPing :: Ping
    167 minimalPing = Ping
    168   { pingNumPongBytes = 0
    169   , pingIgnored      = BS.empty
    170   }
    171 {-# NOINLINE minimalPing #-}
    172 
    173 -- | Ping with response requested but no padding.
    174 pingWithResponse :: Ping
    175 pingWithResponse = Ping
    176   { pingNumPongBytes = 64
    177   , pingIgnored      = BS.empty
    178   }
    179 {-# NOINLINE pingWithResponse #-}
    180 
    181 -- | Ping with padding (64 bytes).
    182 pingWithPadding :: Ping
    183 pingWithPadding = Ping
    184   { pingNumPongBytes = 64
    185   , pingIgnored      = bytes64
    186   }
    187 {-# NOINLINE pingWithPadding #-}
    188 
    189 -- | Ping with large padding (1KB).
    190 pingWithLargePadding :: Ping
    191 pingWithLargePadding = Ping
    192   { pingNumPongBytes = 128
    193   , pingIgnored      = bytes1k
    194   }
    195 {-# NOINLINE pingWithLargePadding #-}
    196 
    197 -- Sample Pong messages ---------------------------------------------------
    198 
    199 -- | Minimal Pong (no ignored bytes).
    200 minimalPong :: Pong
    201 minimalPong = Pong
    202   { pongIgnored = BS.empty
    203   }
    204 {-# NOINLINE minimalPong #-}
    205 
    206 -- | Pong with padding (64 bytes).
    207 pongWithPadding :: Pong
    208 pongWithPadding = Pong
    209   { pongIgnored = bytes64
    210   }
    211 {-# NOINLINE pongWithPadding #-}
    212 
    213 -- | Pong with large padding (1KB).
    214 pongWithLargePadding :: Pong
    215 pongWithLargePadding = Pong
    216   { pongIgnored = bytes1k
    217   }
    218 {-# NOINLINE pongWithLargePadding #-}
    219 
    220 -- Sample PeerStorage messages --------------------------------------------
    221 
    222 -- | Minimal PeerStorage (empty blob).
    223 minimalPeerStorage :: PeerStorage
    224 minimalPeerStorage = PeerStorage
    225   { peerStorageBlob = BS.empty
    226   }
    227 {-# NOINLINE minimalPeerStorage #-}
    228 
    229 -- | PeerStorage with 1KB blob.
    230 peerStorageSmall :: PeerStorage
    231 peerStorageSmall = PeerStorage
    232   { peerStorageBlob = bytes1k
    233   }
    234 {-# NOINLINE peerStorageSmall #-}
    235 
    236 -- | PeerStorage with 16KB blob.
    237 peerStorageLarge :: PeerStorage
    238 peerStorageLarge = PeerStorage
    239   { peerStorageBlob = bytes16k
    240   }
    241 {-# NOINLINE peerStorageLarge #-}
    242 
    243 -- Sample PeerStorageRetrieval messages -----------------------------------
    244 
    245 -- | Minimal PeerStorageRetrieval (empty blob).
    246 minimalPeerStorageRetrieval :: PeerStorageRetrieval
    247 minimalPeerStorageRetrieval = PeerStorageRetrieval
    248   { peerStorageRetrievalBlob = BS.empty
    249   }
    250 {-# NOINLINE minimalPeerStorageRetrieval #-}
    251 
    252 -- | PeerStorageRetrieval with 1KB blob.
    253 peerStorageRetrievalSmall :: PeerStorageRetrieval
    254 peerStorageRetrievalSmall = PeerStorageRetrieval
    255   { peerStorageRetrievalBlob = bytes1k
    256   }
    257 {-# NOINLINE peerStorageRetrievalSmall #-}
    258 
    259 -- | PeerStorageRetrieval with 16KB blob.
    260 peerStorageRetrievalLarge :: PeerStorageRetrieval
    261 peerStorageRetrievalLarge = PeerStorageRetrieval
    262   { peerStorageRetrievalBlob = bytes16k
    263   }
    264 {-# NOINLINE peerStorageRetrievalLarge #-}
    265 
    266 -- Sample TLV streams -----------------------------------------------------
    267 
    268 -- | Empty TLV stream.
    269 emptyTlvStream :: TlvStream
    270 emptyTlvStream = unsafeTlvStream []
    271 {-# NOINLINE emptyTlvStream #-}
    272 
    273 -- | TLV stream with 1 record.
    274 smallTlvStream :: TlvStream
    275 smallTlvStream = unsafeTlvStream
    276   [ TlvRecord 1 (BS.replicate 32 0x01)
    277   ]
    278 {-# NOINLINE smallTlvStream #-}
    279 
    280 -- | TLV stream with 5 records.
    281 mediumTlvStream :: TlvStream
    282 mediumTlvStream = unsafeTlvStream
    283   [ TlvRecord 1 (BS.replicate 8 0x01)
    284   , TlvRecord 3 (BS.replicate 16 0x03)
    285   , TlvRecord 5 (BS.replicate 32 0x05)
    286   , TlvRecord 7 (BS.replicate 64 0x07)
    287   , TlvRecord 9 (BS.replicate 128 0x09)
    288   ]
    289 {-# NOINLINE mediumTlvStream #-}
    290 
    291 -- | TLV stream with 20 records.
    292 largeTlvStream :: TlvStream
    293 largeTlvStream = unsafeTlvStream
    294   [ TlvRecord 1  (BS.replicate 8 0x01)
    295   , TlvRecord 3  (BS.replicate 16 0x02)
    296   , TlvRecord 5  (BS.replicate 8 0x03)
    297   , TlvRecord 7  (BS.replicate 16 0x04)
    298   , TlvRecord 9  (BS.replicate 8 0x05)
    299   , TlvRecord 11 (BS.replicate 16 0x06)
    300   , TlvRecord 13 (BS.replicate 8 0x07)
    301   , TlvRecord 15 (BS.replicate 16 0x08)
    302   , TlvRecord 17 (BS.replicate 8 0x09)
    303   , TlvRecord 19 (BS.replicate 16 0x0a)
    304   , TlvRecord 21 (BS.replicate 8 0x0b)
    305   , TlvRecord 23 (BS.replicate 16 0x0c)
    306   , TlvRecord 25 (BS.replicate 8 0x0d)
    307   , TlvRecord 27 (BS.replicate 16 0x0e)
    308   , TlvRecord 29 (BS.replicate 8 0x0f)
    309   , TlvRecord 31 (BS.replicate 16 0x10)
    310   , TlvRecord 33 (BS.replicate 8 0x11)
    311   , TlvRecord 35 (BS.replicate 16 0x12)
    312   , TlvRecord 37 (BS.replicate 8 0x13)
    313   , TlvRecord 39 (BS.replicate 16 0x14)
    314   ]
    315 {-# NOINLINE largeTlvStream #-}
    316 
    317 -- Encoded message bytes (for decode benchmarks) --------------------------
    318 
    319 -- Helper to encode or fail.
    320 encodeOrFail :: Either EncodeError BS.ByteString -> BS.ByteString
    321 encodeOrFail (Right bs) = bs
    322 encodeOrFail (Left _)   = error "encodeOrFail: encoding failed"
    323 
    324 -- | Encoded minimal Init.
    325 encodedMinimalInit :: BS.ByteString
    326 encodedMinimalInit = encodeOrFail $ encodeEnvelope (MsgInitVal minimalInit) Nothing
    327 {-# NOINLINE encodedMinimalInit #-}
    328 
    329 -- | Encoded Init with TLVs.
    330 encodedInitWithTlvs :: BS.ByteString
    331 encodedInitWithTlvs = encodeOrFail $ encodeEnvelope (MsgInitVal initWithTlvs) Nothing
    332 {-# NOINLINE encodedInitWithTlvs #-}
    333 
    334 -- | Encoded full Init.
    335 encodedFullInit :: BS.ByteString
    336 encodedFullInit = encodeOrFail $ encodeEnvelope (MsgInitVal fullInit) Nothing
    337 {-# NOINLINE encodedFullInit #-}
    338 
    339 -- | Encoded minimal Error.
    340 encodedMinimalError :: BS.ByteString
    341 encodedMinimalError = encodeOrFail $ encodeEnvelope (MsgErrorVal minimalError) Nothing
    342 {-# NOINLINE encodedMinimalError #-}
    343 
    344 -- | Encoded Error with data.
    345 encodedErrorWithData :: BS.ByteString
    346 encodedErrorWithData = encodeOrFail $ encodeEnvelope (MsgErrorVal errorWithData) Nothing
    347 {-# NOINLINE encodedErrorWithData #-}
    348 
    349 -- | Encoded minimal Warning.
    350 encodedMinimalWarning :: BS.ByteString
    351 encodedMinimalWarning = encodeOrFail $
    352   encodeEnvelope (MsgWarningVal minimalWarning) Nothing
    353 {-# NOINLINE encodedMinimalWarning #-}
    354 
    355 -- | Encoded Warning with data.
    356 encodedWarningWithData :: BS.ByteString
    357 encodedWarningWithData = encodeOrFail $
    358   encodeEnvelope (MsgWarningVal warningWithData) Nothing
    359 {-# NOINLINE encodedWarningWithData #-}
    360 
    361 -- | Encoded minimal Ping.
    362 encodedMinimalPing :: BS.ByteString
    363 encodedMinimalPing = encodeOrFail $ encodeEnvelope (MsgPingVal minimalPing) Nothing
    364 {-# NOINLINE encodedMinimalPing #-}
    365 
    366 -- | Encoded Ping with padding.
    367 encodedPingWithPadding :: BS.ByteString
    368 encodedPingWithPadding = encodeOrFail $
    369   encodeEnvelope (MsgPingVal pingWithPadding) Nothing
    370 {-# NOINLINE encodedPingWithPadding #-}
    371 
    372 -- | Encoded Ping with large padding.
    373 encodedPingWithLargePadding :: BS.ByteString
    374 encodedPingWithLargePadding = encodeOrFail $
    375   encodeEnvelope (MsgPingVal pingWithLargePadding) Nothing
    376 {-# NOINLINE encodedPingWithLargePadding #-}
    377 
    378 -- | Encoded minimal Pong.
    379 encodedMinimalPong :: BS.ByteString
    380 encodedMinimalPong = encodeOrFail $ encodeEnvelope (MsgPongVal minimalPong) Nothing
    381 {-# NOINLINE encodedMinimalPong #-}
    382 
    383 -- | Encoded Pong with padding.
    384 encodedPongWithPadding :: BS.ByteString
    385 encodedPongWithPadding = encodeOrFail $
    386   encodeEnvelope (MsgPongVal pongWithPadding) Nothing
    387 {-# NOINLINE encodedPongWithPadding #-}
    388 
    389 -- | Encoded minimal PeerStorage.
    390 encodedMinimalPeerStorage :: BS.ByteString
    391 encodedMinimalPeerStorage = encodeOrFail $
    392   encodeEnvelope (MsgPeerStorageVal minimalPeerStorage) Nothing
    393 {-# NOINLINE encodedMinimalPeerStorage #-}
    394 
    395 -- | Encoded PeerStorage with 1KB blob.
    396 encodedPeerStorageSmall :: BS.ByteString
    397 encodedPeerStorageSmall = encodeOrFail $
    398   encodeEnvelope (MsgPeerStorageVal peerStorageSmall) Nothing
    399 {-# NOINLINE encodedPeerStorageSmall #-}
    400 
    401 -- | Encoded minimal PeerStorageRetrieval.
    402 encodedMinimalPeerStorageRetrieval :: BS.ByteString
    403 encodedMinimalPeerStorageRetrieval = encodeOrFail $
    404   encodeEnvelope (MsgPeerStorageRetrievalVal minimalPeerStorageRetrieval) Nothing
    405 {-# NOINLINE encodedMinimalPeerStorageRetrieval #-}
    406 
    407 -- | Encoded PeerStorageRetrieval with 1KB blob.
    408 encodedPeerStorageRetrievalSmall :: BS.ByteString
    409 encodedPeerStorageRetrievalSmall = encodeOrFail $
    410   encodeEnvelope (MsgPeerStorageRetrievalVal peerStorageRetrievalSmall) Nothing
    411 {-# NOINLINE encodedPeerStorageRetrievalSmall #-}
    412 
    413 -- Encoded TLV streams (for decode benchmarks) ----------------------------
    414 
    415 -- | Encoded empty TLV stream.
    416 encodedEmptyTlvStream :: BS.ByteString
    417 encodedEmptyTlvStream = encodeTlvStream emptyTlvStream
    418 {-# NOINLINE encodedEmptyTlvStream #-}
    419 
    420 -- | Encoded small TLV stream (1 record).
    421 encodedSmallTlvStream :: BS.ByteString
    422 encodedSmallTlvStream = encodeTlvStream smallTlvStream
    423 {-# NOINLINE encodedSmallTlvStream #-}
    424 
    425 -- | Encoded medium TLV stream (5 records).
    426 encodedMediumTlvStream :: BS.ByteString
    427 encodedMediumTlvStream = encodeTlvStream mediumTlvStream
    428 {-# NOINLINE encodedMediumTlvStream #-}
    429 
    430 -- | Encoded large TLV stream (20 records).
    431 encodedLargeTlvStream :: BS.ByteString
    432 encodedLargeTlvStream = encodeTlvStream largeTlvStream
    433 {-# NOINLINE encodedLargeTlvStream #-}