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 (7176B)


      1 {-# OPTIONS_HADDOCK hide #-}
      2 {-# LANGUAGE DeriveGeneric #-}
      3 
      4 -- |
      5 -- Module: Lightning.Protocol.BOLT7.Messages
      6 -- Copyright: (c) 2025 Jared Tobin
      7 -- License: MIT
      8 -- Maintainer: Jared Tobin <jared@ppad.tech>
      9 --
     10 -- The messages defined by BOLT #7.
     11 
     12 module Lightning.Protocol.BOLT7.Messages (
     13     Message(..)
     14   , message_type
     15   , ChannelAnnouncement(..)
     16   , NodeAnnouncement(..)
     17   , ChannelUpdate(..)
     18   , AnnouncementSignatures(..)
     19   , QueryShortChannelIds(..)
     20   , ReplyShortChannelIdsEnd(..)
     21   , QueryChannelRange(..)
     22   , ReplyChannelRange(..)
     23   , GossipTimestampFilter(..)
     24   ) where
     25 
     26 import Control.DeepSeq (NFData)
     27 import qualified Data.ByteString as BS
     28 import Data.Word (Word16, Word32)
     29 import GHC.Generics (Generic)
     30 import Lightning.Protocol.BOLT1
     31   ( ChainHash, ChannelId, MilliSatoshi, Point, ShortChannelId
     32   , Signature, TlvStream )
     33 import qualified Lightning.Protocol.BOLT9 as BOLT9
     34 import Lightning.Protocol.BOLT7.Types
     35 
     36 -- | The @channel_announcement@ message (type 256).
     37 data ChannelAnnouncement = ChannelAnnouncement
     38   { ca_node_signature_1    :: !Signature
     39   , ca_node_signature_2    :: !Signature
     40   , ca_bitcoin_signature_1 :: !Signature
     41   , ca_bitcoin_signature_2 :: !Signature
     42   , ca_features            :: !BOLT9.FeatureVector
     43   , ca_chain_hash          :: !ChainHash
     44   , ca_short_channel_id    :: {-# UNPACK #-} !ShortChannelId
     45   , ca_node_id_1           :: !Point
     46     -- ^ the lexicographically lesser node id
     47   , ca_node_id_2           :: !Point
     48   , ca_bitcoin_key_1       :: !Point
     49   , ca_bitcoin_key_2       :: !Point
     50   , ca_tlvs                :: !TlvStream
     51     -- ^ extension TLV records (all unknown odd)
     52   } deriving (Eq, Show, Generic)
     53 
     54 instance NFData ChannelAnnouncement
     55 
     56 -- | The @node_announcement@ message (type 257).
     57 data NodeAnnouncement = NodeAnnouncement
     58   { na_signature         :: !Signature
     59   , na_features          :: !BOLT9.FeatureVector
     60   , na_timestamp         :: {-# UNPACK #-} !Word32
     61   , na_node_id           :: !Point
     62   , na_rgb_color         :: !RgbColor
     63   , na_alias             :: !Alias
     64   , na_addresses         :: ![Address]
     65     -- ^ address descriptors of known types, in order
     66   , na_unknown_addresses :: !BS.ByteString
     67     -- ^ the address bytes from the first descriptor of an unknown type
     68     --   on (empty if there is none), kept as received
     69   , na_tlvs              :: !TlvStream
     70     -- ^ extension TLV records (all unknown odd)
     71   } deriving (Eq, Show, Generic)
     72 
     73 instance NFData NodeAnnouncement
     74 
     75 -- | The @channel_update@ message (type 258).
     76 data ChannelUpdate = ChannelUpdate
     77   { cu_signature                   :: !Signature
     78   , cu_chain_hash                  :: !ChainHash
     79   , cu_short_channel_id            :: {-# UNPACK #-} !ShortChannelId
     80   , cu_timestamp                   :: {-# UNPACK #-} !Word32
     81   , cu_message_flags               :: {-# UNPACK #-} !MessageFlags
     82   , cu_channel_flags               :: {-# UNPACK #-} !ChannelFlags
     83   , cu_cltv_expiry_delta           :: {-# UNPACK #-} !Word16
     84   , cu_htlc_minimum_msat           :: {-# UNPACK #-} !MilliSatoshi
     85   , cu_fee_base_msat               :: {-# UNPACK #-} !Word32
     86   , cu_fee_proportional_millionths :: {-# UNPACK #-} !Word32
     87   , cu_htlc_maximum_msat           :: {-# UNPACK #-} !MilliSatoshi
     88   , cu_tlvs                        :: !TlvStream
     89     -- ^ extension TLV records (all unknown odd)
     90   } deriving (Eq, Show, Generic)
     91 
     92 instance NFData ChannelUpdate
     93 
     94 -- | The @announcement_signatures@ message (type 259).
     95 data AnnouncementSignatures = AnnouncementSignatures
     96   { as_channel_id        :: !ChannelId
     97   , as_short_channel_id  :: {-# UNPACK #-} !ShortChannelId
     98   , as_node_signature    :: !Signature
     99   , as_bitcoin_signature :: !Signature
    100   , as_tlvs              :: !TlvStream
    101     -- ^ extension TLV records (all unknown odd)
    102   } deriving (Eq, Show, Generic)
    103 
    104 instance NFData AnnouncementSignatures
    105 
    106 -- | The @query_short_channel_ids@ message (type 261).
    107 data QueryShortChannelIds = QueryShortChannelIds
    108   { qsci_chain_hash        :: !ChainHash
    109   , qsci_short_channel_ids :: ![ShortChannelId]
    110   , qsci_query_flags       :: !(Maybe [QueryFlags])
    111     -- ^ @query_flags@ (TLV type 1): one per short channel id
    112   , qsci_tlvs              :: !TlvStream
    113     -- ^ unknown odd TLV records
    114   } deriving (Eq, Show, Generic)
    115 
    116 instance NFData QueryShortChannelIds
    117 
    118 -- | The @reply_short_channel_ids_end@ message (type 262).
    119 data ReplyShortChannelIdsEnd = ReplyShortChannelIdsEnd
    120   { rsce_chain_hash       :: !ChainHash
    121   , rsce_full_information :: !Bool
    122   , rsce_tlvs             :: !TlvStream
    123     -- ^ extension TLV records (all unknown odd)
    124   } deriving (Eq, Show, Generic)
    125 
    126 instance NFData ReplyShortChannelIdsEnd
    127 
    128 -- | The @query_channel_range@ message (type 263).
    129 data QueryChannelRange = QueryChannelRange
    130   { qcr_chain_hash       :: !ChainHash
    131   , qcr_first_blocknum   :: {-# UNPACK #-} !Word32
    132   , qcr_number_of_blocks :: {-# UNPACK #-} !Word32
    133   , qcr_query_option     :: !(Maybe QueryOption)
    134     -- ^ @query_option@ (TLV type 1)
    135   , qcr_tlvs             :: !TlvStream
    136     -- ^ unknown odd TLV records
    137   } deriving (Eq, Show, Generic)
    138 
    139 instance NFData QueryChannelRange
    140 
    141 -- | The @reply_channel_range@ message (type 264).
    142 data ReplyChannelRange = ReplyChannelRange
    143   { rcr_chain_hash        :: !ChainHash
    144   , rcr_first_blocknum    :: {-# UNPACK #-} !Word32
    145   , rcr_number_of_blocks  :: {-# UNPACK #-} !Word32
    146   , rcr_sync_complete     :: !Bool
    147   , rcr_short_channel_ids :: ![ShortChannelId]
    148   , rcr_timestamps        :: !(Maybe [ChannelUpdateTimestamps])
    149     -- ^ @timestamps_tlv@ (TLV type 1): one per short channel id
    150   , rcr_checksums         :: !(Maybe [ChannelUpdateChecksums])
    151     -- ^ @checksums_tlv@ (TLV type 3): one per short channel id
    152   , rcr_tlvs              :: !TlvStream
    153     -- ^ unknown odd TLV records
    154   } deriving (Eq, Show, Generic)
    155 
    156 instance NFData ReplyChannelRange
    157 
    158 -- | The @gossip_timestamp_filter@ message (type 265).
    159 data GossipTimestampFilter = GossipTimestampFilter
    160   { gtf_chain_hash      :: !ChainHash
    161   , gtf_first_timestamp :: {-# UNPACK #-} !Word32
    162   , gtf_timestamp_range :: {-# UNPACK #-} !Word32
    163   , gtf_tlvs            :: !TlvStream
    164     -- ^ extension TLV records (all unknown odd)
    165   } deriving (Eq, Show, Generic)
    166 
    167 instance NFData GossipTimestampFilter
    168 
    169 -- | A BOLT #7 message.
    170 data Message
    171   = MsgChannelAnnouncement !ChannelAnnouncement
    172   | MsgNodeAnnouncement !NodeAnnouncement
    173   | MsgChannelUpdate !ChannelUpdate
    174   | MsgAnnouncementSignatures !AnnouncementSignatures
    175   | MsgQueryShortChannelIds !QueryShortChannelIds
    176   | MsgReplyShortChannelIdsEnd !ReplyShortChannelIdsEnd
    177   | MsgQueryChannelRange !QueryChannelRange
    178   | MsgReplyChannelRange !ReplyChannelRange
    179   | MsgGossipTimestampFilter !GossipTimestampFilter
    180   deriving (Eq, Show, Generic)
    181 
    182 instance NFData Message
    183 
    184 -- | The message type of a 'Message'.
    185 message_type :: Message -> Word16
    186 message_type m = case m of
    187   MsgChannelAnnouncement _     -> 256
    188   MsgNodeAnnouncement _        -> 257
    189   MsgChannelUpdate _           -> 258
    190   MsgAnnouncementSignatures _  -> 259
    191   MsgQueryShortChannelIds _    -> 261
    192   MsgReplyShortChannelIdsEnd _ -> 262
    193   MsgQueryChannelRange _       -> 263
    194   MsgReplyChannelRange _       -> 264
    195   MsgGossipTimestampFilter _   -> 265