bolt7

Routing gossip protocol, per BOLT #7 (docs.ppad.tech/bolt7).
git clone git://git.ppad.tech/bolt7.git
Log | Files | Refs | README | LICENSE

Messages.hs (8607B)


      1 {-# OPTIONS_HADDOCK prune #-}
      2 
      3 {-# LANGUAGE BangPatterns #-}
      4 {-# LANGUAGE DeriveGeneric #-}
      5 
      6 -- |
      7 -- Module: Lightning.Protocol.BOLT7.Messages
      8 -- Copyright: (c) 2025 Jared Tobin
      9 -- License: MIT
     10 -- Maintainer: Jared Tobin <jared@ppad.tech>
     11 --
     12 -- BOLT #7 gossip message type definitions.
     13 
     14 module Lightning.Protocol.BOLT7.Messages (
     15   -- * Message types
     16     MsgType(..)
     17   , msgTypeCode
     18 
     19   -- * Channel announcement
     20   , ChannelAnnouncement(..)
     21 
     22   -- * Node announcement
     23   , NodeAnnouncement(..)
     24 
     25   -- * Channel update
     26   , ChannelUpdate(..)
     27 
     28   -- * Announcement signatures
     29   , AnnouncementSignatures(..)
     30 
     31   -- * Query messages
     32   , QueryShortChannelIds(..)
     33   , ReplyShortChannelIdsEnd(..)
     34   , QueryChannelRange(..)
     35   , ReplyChannelRange(..)
     36   , GossipTimestampFilter(..)
     37 
     38   -- * Union type
     39   , Message(..)
     40   ) where
     41 
     42 import Control.DeepSeq (NFData)
     43 import Data.ByteString (ByteString)
     44 import Data.Word (Word8, Word16, Word32)
     45 import GHC.Generics (Generic)
     46 import Lightning.Protocol.BOLT1 (TlvStream)
     47 import Lightning.Protocol.BOLT7.Types
     48 
     49 -- Message type codes ----------------------------------------------------------
     50 
     51 -- | BOLT #7 message type codes.
     52 data MsgType
     53   = MsgChannelAnnouncement       -- ^ 256
     54   | MsgNodeAnnouncement          -- ^ 257
     55   | MsgChannelUpdate             -- ^ 258
     56   | MsgAnnouncementSignatures    -- ^ 259
     57   | MsgQueryShortChannelIds      -- ^ 261
     58   | MsgReplyShortChannelIdsEnd   -- ^ 262
     59   | MsgQueryChannelRange         -- ^ 263
     60   | MsgReplyChannelRange         -- ^ 264
     61   | MsgGossipTimestampFilter     -- ^ 265
     62   deriving (Eq, Show, Generic)
     63 
     64 instance NFData MsgType
     65 
     66 -- | Get numeric code for message type.
     67 msgTypeCode :: MsgType -> Word16
     68 msgTypeCode MsgChannelAnnouncement     = 256
     69 msgTypeCode MsgNodeAnnouncement        = 257
     70 msgTypeCode MsgChannelUpdate           = 258
     71 msgTypeCode MsgAnnouncementSignatures  = 259
     72 msgTypeCode MsgQueryShortChannelIds    = 261
     73 msgTypeCode MsgReplyShortChannelIdsEnd = 262
     74 msgTypeCode MsgQueryChannelRange       = 263
     75 msgTypeCode MsgReplyChannelRange       = 264
     76 msgTypeCode MsgGossipTimestampFilter   = 265
     77 {-# INLINE msgTypeCode #-}
     78 
     79 -- Channel announcement --------------------------------------------------------
     80 
     81 -- | channel_announcement message (type 256).
     82 --
     83 -- Announces a public channel to the network.
     84 data ChannelAnnouncement = ChannelAnnouncement
     85   { channelAnnNodeSig1     :: !Signature     -- ^ Signature from node_id_1
     86   , channelAnnNodeSig2     :: !Signature     -- ^ Signature from node_id_2
     87   , channelAnnBitcoinSig1  :: !Signature     -- ^ Signature from bitcoin_key_1
     88   , channelAnnBitcoinSig2  :: !Signature     -- ^ Signature from bitcoin_key_2
     89   , channelAnnFeatures     :: !FeatureBits   -- ^ Feature bits
     90   , channelAnnChainHash    :: !ChainHash     -- ^ Chain identifier
     91   , channelAnnShortChanId  :: !ShortChannelId -- ^ Short channel ID
     92   , channelAnnNodeId1      :: !NodeId        -- ^ First node (lexicographically)
     93   , channelAnnNodeId2      :: !NodeId        -- ^ Second node
     94   , channelAnnBitcoinKey1  :: !Point         -- ^ Bitcoin key for node_id_1
     95   , channelAnnBitcoinKey2  :: !Point         -- ^ Bitcoin key for node_id_2
     96   }
     97   deriving (Eq, Show, Generic)
     98 
     99 instance NFData ChannelAnnouncement
    100 
    101 -- Node announcement -----------------------------------------------------------
    102 
    103 -- | node_announcement message (type 257).
    104 --
    105 -- Advertises node metadata to the network.
    106 data NodeAnnouncement = NodeAnnouncement
    107   { nodeAnnSignature  :: !Signature      -- ^ Signature of message
    108   , nodeAnnFeatures   :: !FeatureBits    -- ^ Feature bits
    109   , nodeAnnTimestamp  :: !Timestamp      -- ^ Unix timestamp
    110   , nodeAnnNodeId     :: !NodeId         -- ^ Node public key
    111   , nodeAnnRgbColor   :: !RgbColor       -- ^ RGB color
    112   , nodeAnnAlias      :: !Alias          -- ^ Node alias (32 bytes UTF-8)
    113   , nodeAnnAddresses  :: ![Address]      -- ^ List of addresses
    114   }
    115   deriving (Eq, Show, Generic)
    116 
    117 instance NFData NodeAnnouncement
    118 
    119 -- Channel update --------------------------------------------------------------
    120 
    121 -- | channel_update message (type 258).
    122 --
    123 -- Communicates per-direction routing parameters.
    124 --
    125 -- The message_flags field is derived automatically during
    126 -- encoding: bit 0 is set when 'chanUpdateHtlcMaxMsat' is
    127 -- 'Just'.
    128 data ChannelUpdate = ChannelUpdate
    129   { chanUpdateSignature       :: !Signature
    130     -- ^ Signature of message
    131   , chanUpdateChainHash       :: !ChainHash
    132     -- ^ Chain identifier
    133   , chanUpdateShortChanId     :: !ShortChannelId
    134     -- ^ Short channel ID
    135   , chanUpdateTimestamp       :: !Timestamp
    136     -- ^ Unix timestamp
    137   , chanUpdateChanFlags       :: !ChannelFlags
    138     -- ^ Channel flags
    139   , chanUpdateCltvExpDelta    :: !CltvExpiryDelta
    140     -- ^ CLTV expiry delta
    141   , chanUpdateHtlcMinMsat     :: !HtlcMinimumMsat
    142     -- ^ Minimum HTLC msat
    143   , chanUpdateFeeBaseMsat     :: !FeeBaseMsat
    144     -- ^ Base fee msat
    145   , chanUpdateFeeProportional :: !FeeProportionalMillionths
    146     -- ^ Proportional fee
    147   , chanUpdateHtlcMaxMsat     :: !(Maybe HtlcMaximumMsat)
    148     -- ^ Max HTLC (optional; presence sets message_flags
    149     -- bit 0)
    150   }
    151   deriving (Eq, Show, Generic)
    152 
    153 instance NFData ChannelUpdate
    154 
    155 -- Announcement signatures -----------------------------------------------------
    156 
    157 -- | announcement_signatures message (type 259).
    158 --
    159 -- Sent between channel peers to enable channel announcement.
    160 data AnnouncementSignatures = AnnouncementSignatures
    161   { annSigChannelId     :: !ChannelId       -- ^ Channel ID
    162   , annSigShortChanId   :: !ShortChannelId  -- ^ Short channel ID
    163   , annSigNodeSig       :: !Signature       -- ^ Node signature
    164   , annSigBitcoinSig    :: !Signature       -- ^ Bitcoin signature
    165   }
    166   deriving (Eq, Show, Generic)
    167 
    168 instance NFData AnnouncementSignatures
    169 
    170 -- Query messages --------------------------------------------------------------
    171 
    172 -- | query_short_channel_ids message (type 261).
    173 --
    174 -- Requests information about specific channels.
    175 data QueryShortChannelIds = QueryShortChannelIds
    176   { queryScidsChainHash :: !ChainHash    -- ^ Chain identifier
    177   , queryScidsData      :: !ByteString   -- ^ Encoded short_channel_ids
    178   , queryScidsTlvs      :: !TlvStream    -- ^ Optional TLV (query_flags)
    179   }
    180   deriving (Eq, Show, Generic)
    181 
    182 instance NFData QueryShortChannelIds
    183 
    184 -- | reply_short_channel_ids_end message (type 262).
    185 --
    186 -- Concludes response to query_short_channel_ids.
    187 data ReplyShortChannelIdsEnd = ReplyShortChannelIdsEnd
    188   { replyScidsChainHash    :: !ChainHash  -- ^ Chain identifier
    189   , replyScidsFullInfo     :: !Word8      -- ^ 1 if complete, 0 otherwise
    190   }
    191   deriving (Eq, Show, Generic)
    192 
    193 instance NFData ReplyShortChannelIdsEnd
    194 
    195 -- | query_channel_range message (type 263).
    196 --
    197 -- Queries channels within a block range.
    198 data QueryChannelRange = QueryChannelRange
    199   { queryRangeChainHash  :: !ChainHash    -- ^ Chain identifier
    200   , queryRangeFirstBlock :: !BlockHeight  -- ^ First block number
    201   , queryRangeNumBlocks  :: !BlockCount   -- ^ Number of blocks
    202   , queryRangeTlvs       :: !TlvStream    -- ^ Optional TLV
    203   }
    204   deriving (Eq, Show, Generic)
    205 
    206 instance NFData QueryChannelRange
    207 
    208 -- | reply_channel_range message (type 264).
    209 --
    210 -- Responds to query_channel_range with channel IDs.
    211 data ReplyChannelRange = ReplyChannelRange
    212   { replyRangeChainHash    :: !ChainHash    -- ^ Chain identifier
    213   , replyRangeFirstBlock   :: !BlockHeight  -- ^ First block
    214   , replyRangeNumBlocks    :: !BlockCount   -- ^ Block count
    215   , replyRangeSyncComplete :: !Word8        -- ^ 1 if complete
    216   , replyRangeData         :: !ByteString   -- ^ Encoded SCIDs
    217   , replyRangeTlvs         :: !TlvStream    -- ^ Optional TLVs
    218   }
    219   deriving (Eq, Show, Generic)
    220 
    221 instance NFData ReplyChannelRange
    222 
    223 -- | gossip_timestamp_filter message (type 265).
    224 --
    225 -- Constrains which gossip messages are relayed.
    226 data GossipTimestampFilter = GossipTimestampFilter
    227   { gossipFilterChainHash     :: !ChainHash  -- ^ Chain identifier
    228   , gossipFilterFirstTimestamp :: !Word32    -- ^ First timestamp
    229   , gossipFilterTimestampRange :: !Word32    -- ^ Timestamp range
    230   }
    231   deriving (Eq, Show, Generic)
    232 
    233 instance NFData GossipTimestampFilter
    234 
    235 -- Union type ------------------------------------------------------------------
    236 
    237 -- | Union of all BOLT #7 message types.
    238 data Message
    239   = MsgChanAnn !ChannelAnnouncement
    240   | MsgNodeAnn !NodeAnnouncement
    241   | MsgChanUpd !ChannelUpdate
    242   | MsgAnnSig  !AnnouncementSignatures
    243   | MsgQueryScids !QueryShortChannelIds
    244   | MsgReplyScids !ReplyShortChannelIdsEnd
    245   | MsgQueryRange !QueryChannelRange
    246   | MsgReplyRange !ReplyChannelRange
    247   | MsgGossipFilter !GossipTimestampFilter
    248   deriving (Eq, Show, Generic)
    249 
    250 instance NFData Message