{-# OPTIONS_HADDOCK prune #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DeriveGeneric #-}
module Lightning.Protocol.BOLT7.Codec (
EncodeError(..)
, DecodeError(..)
, encodeChannelAnnouncement
, decodeChannelAnnouncement
, encodeNodeAnnouncement
, decodeNodeAnnouncement
, encodeChannelUpdate
, decodeChannelUpdate
, encodeAnnouncementSignatures
, decodeAnnouncementSignatures
, encodeQueryShortChannelIds
, decodeQueryShortChannelIds
, encodeReplyShortChannelIdsEnd
, decodeReplyShortChannelIdsEnd
, encodeQueryChannelRange
, decodeQueryChannelRange
, encodeReplyChannelRange
, decodeReplyChannelRange
, encodeGossipTimestampFilter
, decodeGossipTimestampFilter
, encodeShortChannelIdList
, decodeShortChannelIdList
) where
import Control.DeepSeq (NFData)
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import Data.Word (Word8, Word16, Word32, Word64)
import GHC.Generics (Generic)
import Lightning.Protocol.BOLT1 (unsafeTlvStream)
import qualified Lightning.Protocol.BOLT1.Prim as Prim
import qualified Lightning.Protocol.BOLT1.TLV as TLV
import Lightning.Protocol.BOLT7.Messages
import Lightning.Protocol.BOLT7.Types
data EncodeError
= EncodeLengthOverflow
deriving (EncodeError -> EncodeError -> Bool
(EncodeError -> EncodeError -> Bool)
-> (EncodeError -> EncodeError -> Bool) -> Eq EncodeError
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: EncodeError -> EncodeError -> Bool
== :: EncodeError -> EncodeError -> Bool
$c/= :: EncodeError -> EncodeError -> Bool
/= :: EncodeError -> EncodeError -> Bool
Eq, Int -> EncodeError -> ShowS
[EncodeError] -> ShowS
EncodeError -> String
(Int -> EncodeError -> ShowS)
-> (EncodeError -> String)
-> ([EncodeError] -> ShowS)
-> Show EncodeError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> EncodeError -> ShowS
showsPrec :: Int -> EncodeError -> ShowS
$cshow :: EncodeError -> String
show :: EncodeError -> String
$cshowList :: [EncodeError] -> ShowS
showList :: [EncodeError] -> ShowS
Show, (forall x. EncodeError -> Rep EncodeError x)
-> (forall x. Rep EncodeError x -> EncodeError)
-> Generic EncodeError
forall x. Rep EncodeError x -> EncodeError
forall x. EncodeError -> Rep EncodeError x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. EncodeError -> Rep EncodeError x
from :: forall x. EncodeError -> Rep EncodeError x
$cto :: forall x. Rep EncodeError x -> EncodeError
to :: forall x. Rep EncodeError x -> EncodeError
Generic)
instance NFData EncodeError
data DecodeError
= DecodeInsufficientBytes
| DecodeInvalidSignature
| DecodeInvalidChainHash
| DecodeInvalidShortChannelId
| DecodeInvalidChannelId
| DecodeInvalidNodeId
| DecodeInvalidPoint
| DecodeInvalidRgbColor
| DecodeInvalidAlias
| DecodeInvalidAddress
| DecodeTlvError
deriving (DecodeError -> DecodeError -> Bool
(DecodeError -> DecodeError -> Bool)
-> (DecodeError -> DecodeError -> Bool) -> Eq DecodeError
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DecodeError -> DecodeError -> Bool
== :: DecodeError -> DecodeError -> Bool
$c/= :: DecodeError -> DecodeError -> Bool
/= :: DecodeError -> DecodeError -> Bool
Eq, Int -> DecodeError -> ShowS
[DecodeError] -> ShowS
DecodeError -> String
(Int -> DecodeError -> ShowS)
-> (DecodeError -> String)
-> ([DecodeError] -> ShowS)
-> Show DecodeError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DecodeError -> ShowS
showsPrec :: Int -> DecodeError -> ShowS
$cshow :: DecodeError -> String
show :: DecodeError -> String
$cshowList :: [DecodeError] -> ShowS
showList :: [DecodeError] -> ShowS
Show, (forall x. DecodeError -> Rep DecodeError x)
-> (forall x. Rep DecodeError x -> DecodeError)
-> Generic DecodeError
forall x. Rep DecodeError x -> DecodeError
forall x. DecodeError -> Rep DecodeError x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. DecodeError -> Rep DecodeError x
from :: forall x. DecodeError -> Rep DecodeError x
$cto :: forall x. Rep DecodeError x -> DecodeError
to :: forall x. Rep DecodeError x -> DecodeError
Generic)
instance NFData DecodeError
decodeU8 :: ByteString -> Either DecodeError (Word8, ByteString)
decodeU8 :: ByteString -> Either DecodeError (Word8, ByteString)
decodeU8 ByteString
bs
| ByteString -> Bool
BS.null ByteString
bs = DecodeError -> Either DecodeError (Word8, ByteString)
forall a b. a -> Either a b
Left DecodeError
DecodeInsufficientBytes
| Bool
otherwise = (Word8, ByteString) -> Either DecodeError (Word8, ByteString)
forall a b. b -> Either a b
Right (HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
BS.index ByteString
bs Int
0, Int -> ByteString -> ByteString
BS.drop Int
1 ByteString
bs)
{-# INLINE decodeU8 #-}
decodeU16 :: ByteString -> Either DecodeError (Word16, ByteString)
decodeU16 :: ByteString -> Either DecodeError (Word16, ByteString)
decodeU16 ByteString
bs = case ByteString -> Maybe (Word16, ByteString)
Prim.decodeU16 ByteString
bs of
Maybe (Word16, ByteString)
Nothing -> DecodeError -> Either DecodeError (Word16, ByteString)
forall a b. a -> Either a b
Left DecodeError
DecodeInsufficientBytes
Just (Word16, ByteString)
r -> (Word16, ByteString) -> Either DecodeError (Word16, ByteString)
forall a b. b -> Either a b
Right (Word16, ByteString)
r
{-# INLINE decodeU16 #-}
decodeU32 :: ByteString -> Either DecodeError (Word32, ByteString)
decodeU32 :: ByteString -> Either DecodeError (Word32, ByteString)
decodeU32 ByteString
bs = case ByteString -> Maybe (Word32, ByteString)
Prim.decodeU32 ByteString
bs of
Maybe (Word32, ByteString)
Nothing -> DecodeError -> Either DecodeError (Word32, ByteString)
forall a b. a -> Either a b
Left DecodeError
DecodeInsufficientBytes
Just (Word32, ByteString)
r -> (Word32, ByteString) -> Either DecodeError (Word32, ByteString)
forall a b. b -> Either a b
Right (Word32, ByteString)
r
{-# INLINE decodeU32 #-}
decodeU64 :: ByteString -> Either DecodeError (Word64, ByteString)
decodeU64 :: ByteString -> Either DecodeError (Word64, ByteString)
decodeU64 ByteString
bs = case ByteString -> Maybe (Word64, ByteString)
Prim.decodeU64 ByteString
bs of
Maybe (Word64, ByteString)
Nothing -> DecodeError -> Either DecodeError (Word64, ByteString)
forall a b. a -> Either a b
Left DecodeError
DecodeInsufficientBytes
Just (Word64, ByteString)
r -> (Word64, ByteString) -> Either DecodeError (Word64, ByteString)
forall a b. b -> Either a b
Right (Word64, ByteString)
r
{-# INLINE decodeU64 #-}
decodeBytes :: Int -> ByteString -> Either DecodeError (ByteString, ByteString)
decodeBytes :: Int -> ByteString -> Either DecodeError (ByteString, ByteString)
decodeBytes Int
n ByteString
bs
| ByteString -> Int
BS.length ByteString
bs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
n = DecodeError -> Either DecodeError (ByteString, ByteString)
forall a b. a -> Either a b
Left DecodeError
DecodeInsufficientBytes
| Bool
otherwise = (ByteString, ByteString)
-> Either DecodeError (ByteString, ByteString)
forall a b. b -> Either a b
Right (Int -> ByteString -> (ByteString, ByteString)
BS.splitAt Int
n ByteString
bs)
{-# INLINE decodeBytes #-}
decodeLenPrefixed :: ByteString
-> Either DecodeError (ByteString, ByteString)
decodeLenPrefixed :: ByteString -> Either DecodeError (ByteString, ByteString)
decodeLenPrefixed ByteString
bs = do
(len, rest) <- ByteString -> Either DecodeError (Word16, ByteString)
decodeU16 ByteString
bs
let n = Word16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
len
if BS.length rest < n
then Left DecodeInsufficientBytes
else Right (BS.splitAt n rest)
{-# INLINE decodeLenPrefixed #-}
encodeLenPrefixed :: ByteString -> ByteString
encodeLenPrefixed :: ByteString -> ByteString
encodeLenPrefixed ByteString
bs = Word16 -> ByteString
Prim.encodeU16 (Int -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word16) -> Int -> Word16
forall a b. (a -> b) -> a -> b
$ ByteString -> Int
BS.length ByteString
bs) ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
bs
{-# INLINE encodeLenPrefixed #-}
decodeFixed :: Int -> DecodeError -> (ByteString -> Maybe a)
-> ByteString -> Either DecodeError (a, ByteString)
decodeFixed :: forall a.
Int
-> DecodeError
-> (ByteString -> Maybe a)
-> ByteString
-> Either DecodeError (a, ByteString)
decodeFixed Int
len DecodeError
err ByteString -> Maybe a
mkVal ByteString
bs = do
(bytes, rest) <- Int -> ByteString -> Either DecodeError (ByteString, ByteString)
decodeBytes Int
len ByteString
bs
case mkVal bytes of
Maybe a
Nothing -> DecodeError -> Either DecodeError (a, ByteString)
forall a b. a -> Either a b
Left DecodeError
err
Just a
v -> (a, ByteString) -> Either DecodeError (a, ByteString)
forall a b. b -> Either a b
Right (a
v, ByteString
rest)
{-# INLINE decodeFixed #-}
decodeSignature :: ByteString -> Either DecodeError (Signature, ByteString)
decodeSignature :: ByteString -> Either DecodeError (Signature, ByteString)
decodeSignature = Int
-> DecodeError
-> (ByteString -> Maybe Signature)
-> ByteString
-> Either DecodeError (Signature, ByteString)
forall a.
Int
-> DecodeError
-> (ByteString -> Maybe a)
-> ByteString
-> Either DecodeError (a, ByteString)
decodeFixed Int
signatureLen DecodeError
DecodeInvalidSignature ByteString -> Maybe Signature
signature
{-# INLINE decodeSignature #-}
decodeChainHash :: ByteString -> Either DecodeError (ChainHash, ByteString)
decodeChainHash :: ByteString -> Either DecodeError (ChainHash, ByteString)
decodeChainHash = Int
-> DecodeError
-> (ByteString -> Maybe ChainHash)
-> ByteString
-> Either DecodeError (ChainHash, ByteString)
forall a.
Int
-> DecodeError
-> (ByteString -> Maybe a)
-> ByteString
-> Either DecodeError (a, ByteString)
decodeFixed Int
chainHashLen DecodeError
DecodeInvalidChainHash ByteString -> Maybe ChainHash
chainHash
{-# INLINE decodeChainHash #-}
decodeShortChannelId :: ByteString
-> Either DecodeError (ShortChannelId, ByteString)
decodeShortChannelId :: ByteString -> Either DecodeError (ShortChannelId, ByteString)
decodeShortChannelId =
Int
-> DecodeError
-> (ByteString -> Maybe ShortChannelId)
-> ByteString
-> Either DecodeError (ShortChannelId, ByteString)
forall a.
Int
-> DecodeError
-> (ByteString -> Maybe a)
-> ByteString
-> Either DecodeError (a, ByteString)
decodeFixed Int
shortChannelIdLen DecodeError
DecodeInvalidShortChannelId ByteString -> Maybe ShortChannelId
shortChannelId
{-# INLINE decodeShortChannelId #-}
decodeChannelId :: ByteString -> Either DecodeError (ChannelId, ByteString)
decodeChannelId :: ByteString -> Either DecodeError (ChannelId, ByteString)
decodeChannelId = Int
-> DecodeError
-> (ByteString -> Maybe ChannelId)
-> ByteString
-> Either DecodeError (ChannelId, ByteString)
forall a.
Int
-> DecodeError
-> (ByteString -> Maybe a)
-> ByteString
-> Either DecodeError (a, ByteString)
decodeFixed Int
channelIdLen DecodeError
DecodeInvalidChannelId ByteString -> Maybe ChannelId
channelId
{-# INLINE decodeChannelId #-}
decodeNodeId :: ByteString -> Either DecodeError (NodeId, ByteString)
decodeNodeId :: ByteString -> Either DecodeError (NodeId, ByteString)
decodeNodeId = Int
-> DecodeError
-> (ByteString -> Maybe NodeId)
-> ByteString
-> Either DecodeError (NodeId, ByteString)
forall a.
Int
-> DecodeError
-> (ByteString -> Maybe a)
-> ByteString
-> Either DecodeError (a, ByteString)
decodeFixed Int
nodeIdLen DecodeError
DecodeInvalidNodeId ByteString -> Maybe NodeId
nodeId
{-# INLINE decodeNodeId #-}
decodePoint :: ByteString -> Either DecodeError (Point, ByteString)
decodePoint :: ByteString -> Either DecodeError (Point, ByteString)
decodePoint = Int
-> DecodeError
-> (ByteString -> Maybe Point)
-> ByteString
-> Either DecodeError (Point, ByteString)
forall a.
Int
-> DecodeError
-> (ByteString -> Maybe a)
-> ByteString
-> Either DecodeError (a, ByteString)
decodeFixed Int
pointLen DecodeError
DecodeInvalidPoint ByteString -> Maybe Point
point
{-# INLINE decodePoint #-}
decodeRgbColor :: ByteString -> Either DecodeError (RgbColor, ByteString)
decodeRgbColor :: ByteString -> Either DecodeError (RgbColor, ByteString)
decodeRgbColor = Int
-> DecodeError
-> (ByteString -> Maybe RgbColor)
-> ByteString
-> Either DecodeError (RgbColor, ByteString)
forall a.
Int
-> DecodeError
-> (ByteString -> Maybe a)
-> ByteString
-> Either DecodeError (a, ByteString)
decodeFixed Int
rgbColorLen DecodeError
DecodeInvalidRgbColor ByteString -> Maybe RgbColor
rgbColor
{-# INLINE decodeRgbColor #-}
decodeAlias :: ByteString -> Either DecodeError (Alias, ByteString)
decodeAlias :: ByteString -> Either DecodeError (Alias, ByteString)
decodeAlias = Int
-> DecodeError
-> (ByteString -> Maybe Alias)
-> ByteString
-> Either DecodeError (Alias, ByteString)
forall a.
Int
-> DecodeError
-> (ByteString -> Maybe a)
-> ByteString
-> Either DecodeError (a, ByteString)
decodeFixed Int
aliasLen DecodeError
DecodeInvalidAlias ByteString -> Maybe Alias
alias
{-# INLINE decodeAlias #-}
decodeFeatureBits :: ByteString -> Either DecodeError (FeatureBits, ByteString)
decodeFeatureBits :: ByteString -> Either DecodeError (FeatureBits, ByteString)
decodeFeatureBits ByteString
bs = do
(bytes, rest) <- ByteString -> Either DecodeError (ByteString, ByteString)
decodeLenPrefixed ByteString
bs
Right (featureBits bytes, rest)
{-# INLINE decodeFeatureBits #-}
decodeAddresses :: ByteString -> Either DecodeError ([Address], ByteString)
decodeAddresses :: ByteString -> Either DecodeError ([Address], ByteString)
decodeAddresses ByteString
bs = do
(addrData, rest) <- ByteString -> Either DecodeError (ByteString, ByteString)
decodeLenPrefixed ByteString
bs
addrs <- parseAddrs addrData
Right (addrs, rest)
where
parseAddrs :: ByteString -> Either DecodeError [Address]
parseAddrs :: ByteString -> Either DecodeError [Address]
parseAddrs !ByteString
d
| ByteString -> Bool
BS.null ByteString
d = [Address] -> Either DecodeError [Address]
forall a b. b -> Either a b
Right []
| Bool
otherwise = do
(addr, d') <- ByteString -> Either DecodeError (Address, ByteString)
parseOneAddr ByteString
d
addrs <- parseAddrs d'
Right (addr : addrs)
parseOneAddr :: ByteString -> Either DecodeError (Address, ByteString)
parseOneAddr :: ByteString -> Either DecodeError (Address, ByteString)
parseOneAddr ByteString
d = do
(typ, d1) <- ByteString -> Either DecodeError (Word8, ByteString)
decodeU8 ByteString
d
case typ of
Word8
1 -> do
(addrBytes, d2) <- Int -> ByteString -> Either DecodeError (ByteString, ByteString)
decodeBytes Int
ipv4AddrLen ByteString
d1
(port, d3) <- decodeU16 d2
case ipv4Addr addrBytes of
Maybe IPv4Addr
Nothing -> DecodeError -> Either DecodeError (Address, ByteString)
forall a b. a -> Either a b
Left DecodeError
DecodeInvalidAddress
Just IPv4Addr
a -> (Address, ByteString) -> Either DecodeError (Address, ByteString)
forall a b. b -> Either a b
Right (IPv4Addr -> Word16 -> Address
AddrIPv4 IPv4Addr
a Word16
port, ByteString
d3)
Word8
2 -> do
(addrBytes, d2) <- Int -> ByteString -> Either DecodeError (ByteString, ByteString)
decodeBytes Int
ipv6AddrLen ByteString
d1
(port, d3) <- decodeU16 d2
case ipv6Addr addrBytes of
Maybe IPv6Addr
Nothing -> DecodeError -> Either DecodeError (Address, ByteString)
forall a b. a -> Either a b
Left DecodeError
DecodeInvalidAddress
Just IPv6Addr
a -> (Address, ByteString) -> Either DecodeError (Address, ByteString)
forall a b. b -> Either a b
Right (IPv6Addr -> Word16 -> Address
AddrIPv6 IPv6Addr
a Word16
port, ByteString
d3)
Word8
4 -> do
(addrBytes, d2) <- Int -> ByteString -> Either DecodeError (ByteString, ByteString)
decodeBytes Int
torV3AddrLen ByteString
d1
(port, d3) <- decodeU16 d2
case torV3Addr addrBytes of
Maybe TorV3Addr
Nothing -> DecodeError -> Either DecodeError (Address, ByteString)
forall a b. a -> Either a b
Left DecodeError
DecodeInvalidAddress
Just TorV3Addr
a -> (Address, ByteString) -> Either DecodeError (Address, ByteString)
forall a b. b -> Either a b
Right (TorV3Addr -> Word16 -> Address
AddrTorV3 TorV3Addr
a Word16
port, ByteString
d3)
Word8
5 -> do
(hostLen, d2) <- ByteString -> Either DecodeError (Word8, ByteString)
decodeU8 ByteString
d1
(hostBytes, d3) <- decodeBytes (fromIntegral hostLen) d2
(port, d4) <- decodeU16 d3
Right (AddrDNS hostBytes port, d4)
Word8
_ -> DecodeError -> Either DecodeError (Address, ByteString)
forall a b. a -> Either a b
Left DecodeError
DecodeInvalidAddress
encodeChannelAnnouncement :: ChannelAnnouncement -> ByteString
encodeChannelAnnouncement :: ChannelAnnouncement -> ByteString
encodeChannelAnnouncement ChannelAnnouncement
msg = [ByteString] -> ByteString
forall a. Monoid a => [a] -> a
mconcat
[ Signature -> ByteString
getSignature (ChannelAnnouncement -> Signature
channelAnnNodeSig1 ChannelAnnouncement
msg)
, Signature -> ByteString
getSignature (ChannelAnnouncement -> Signature
channelAnnNodeSig2 ChannelAnnouncement
msg)
, Signature -> ByteString
getSignature (ChannelAnnouncement -> Signature
channelAnnBitcoinSig1 ChannelAnnouncement
msg)
, Signature -> ByteString
getSignature (ChannelAnnouncement -> Signature
channelAnnBitcoinSig2 ChannelAnnouncement
msg)
, ByteString -> ByteString
encodeLenPrefixed (FeatureBits -> ByteString
getFeatureBits (ChannelAnnouncement -> FeatureBits
channelAnnFeatures ChannelAnnouncement
msg))
, ChainHash -> ByteString
getChainHash (ChannelAnnouncement -> ChainHash
channelAnnChainHash ChannelAnnouncement
msg)
, ShortChannelId -> ByteString
getShortChannelId (ChannelAnnouncement -> ShortChannelId
channelAnnShortChanId ChannelAnnouncement
msg)
, NodeId -> ByteString
getNodeId (ChannelAnnouncement -> NodeId
channelAnnNodeId1 ChannelAnnouncement
msg)
, NodeId -> ByteString
getNodeId (ChannelAnnouncement -> NodeId
channelAnnNodeId2 ChannelAnnouncement
msg)
, Point -> ByteString
getPoint (ChannelAnnouncement -> Point
channelAnnBitcoinKey1 ChannelAnnouncement
msg)
, Point -> ByteString
getPoint (ChannelAnnouncement -> Point
channelAnnBitcoinKey2 ChannelAnnouncement
msg)
]
decodeChannelAnnouncement :: ByteString
-> Either DecodeError (ChannelAnnouncement, ByteString)
decodeChannelAnnouncement :: ByteString -> Either DecodeError (ChannelAnnouncement, ByteString)
decodeChannelAnnouncement ByteString
bs = do
(nodeSig1, bs1) <- ByteString -> Either DecodeError (Signature, ByteString)
decodeSignature ByteString
bs
(nodeSig2, bs2) <- decodeSignature bs1
(btcSig1, bs3) <- decodeSignature bs2
(btcSig2, bs4) <- decodeSignature bs3
(features, bs5) <- decodeFeatureBits bs4
(chainH, bs6) <- decodeChainHash bs5
(scid, bs7) <- decodeShortChannelId bs6
(nid1, bs8) <- decodeNodeId bs7
(nid2, bs9) <- decodeNodeId bs8
(btcKey1, bs10) <- decodePoint bs9
(btcKey2, rest) <- decodePoint bs10
let msg = ChannelAnnouncement
{ channelAnnNodeSig1 :: Signature
channelAnnNodeSig1 = Signature
nodeSig1
, channelAnnNodeSig2 :: Signature
channelAnnNodeSig2 = Signature
nodeSig2
, channelAnnBitcoinSig1 :: Signature
channelAnnBitcoinSig1 = Signature
btcSig1
, channelAnnBitcoinSig2 :: Signature
channelAnnBitcoinSig2 = Signature
btcSig2
, channelAnnFeatures :: FeatureBits
channelAnnFeatures = FeatureBits
features
, channelAnnChainHash :: ChainHash
channelAnnChainHash = ChainHash
chainH
, channelAnnShortChanId :: ShortChannelId
channelAnnShortChanId = ShortChannelId
scid
, channelAnnNodeId1 :: NodeId
channelAnnNodeId1 = NodeId
nid1
, channelAnnNodeId2 :: NodeId
channelAnnNodeId2 = NodeId
nid2
, channelAnnBitcoinKey1 :: Point
channelAnnBitcoinKey1 = Point
btcKey1
, channelAnnBitcoinKey2 :: Point
channelAnnBitcoinKey2 = Point
btcKey2
}
Right (msg, rest)
encodeNodeAnnouncement :: NodeAnnouncement -> Either EncodeError ByteString
encodeNodeAnnouncement :: NodeAnnouncement -> Either EncodeError ByteString
encodeNodeAnnouncement NodeAnnouncement
msg = do
addrData <- [Address] -> Either EncodeError ByteString
encodeAddresses (NodeAnnouncement -> [Address]
nodeAnnAddresses NodeAnnouncement
msg)
let features = FeatureBits -> ByteString
getFeatureBits (NodeAnnouncement -> FeatureBits
nodeAnnFeatures NodeAnnouncement
msg)
if BS.length features > 65535
then Left EncodeLengthOverflow
else Right $ mconcat
[ getSignature (nodeAnnSignature msg)
, encodeLenPrefixed features
, Prim.encodeU32 (nodeAnnTimestamp msg)
, getNodeId (nodeAnnNodeId msg)
, getRgbColor (nodeAnnRgbColor msg)
, getAlias (nodeAnnAlias msg)
, encodeLenPrefixed addrData
]
encodeAddresses :: [Address] -> Either EncodeError ByteString
encodeAddresses :: [Address] -> Either EncodeError ByteString
encodeAddresses [Address]
addrs = ByteString -> Either EncodeError ByteString
forall a b. b -> Either a b
Right (ByteString -> Either EncodeError ByteString)
-> ByteString -> Either EncodeError ByteString
forall a b. (a -> b) -> a -> b
$ [ByteString] -> ByteString
forall a. Monoid a => [a] -> a
mconcat ((Address -> ByteString) -> [Address] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
map Address -> ByteString
encodeAddress [Address]
addrs)
where
encodeAddress :: Address -> ByteString
encodeAddress :: Address -> ByteString
encodeAddress (AddrIPv4 IPv4Addr
a Word16
port) = [ByteString] -> ByteString
forall a. Monoid a => [a] -> a
mconcat
[ Word8 -> ByteString
BS.singleton Word8
1
, IPv4Addr -> ByteString
getIPv4Addr IPv4Addr
a
, Word16 -> ByteString
Prim.encodeU16 Word16
port
]
encodeAddress (AddrIPv6 IPv6Addr
a Word16
port) = [ByteString] -> ByteString
forall a. Monoid a => [a] -> a
mconcat
[ Word8 -> ByteString
BS.singleton Word8
2
, IPv6Addr -> ByteString
getIPv6Addr IPv6Addr
a
, Word16 -> ByteString
Prim.encodeU16 Word16
port
]
encodeAddress (AddrTorV3 TorV3Addr
a Word16
port) = [ByteString] -> ByteString
forall a. Monoid a => [a] -> a
mconcat
[ Word8 -> ByteString
BS.singleton Word8
4
, TorV3Addr -> ByteString
getTorV3Addr TorV3Addr
a
, Word16 -> ByteString
Prim.encodeU16 Word16
port
]
encodeAddress (AddrDNS ByteString
host Word16
port) = [ByteString] -> ByteString
forall a. Monoid a => [a] -> a
mconcat
[ Word8 -> ByteString
BS.singleton Word8
5
, Word8 -> ByteString
BS.singleton (Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ ByteString -> Int
BS.length ByteString
host)
, ByteString
host
, Word16 -> ByteString
Prim.encodeU16 Word16
port
]
decodeNodeAnnouncement :: ByteString
-> Either DecodeError (NodeAnnouncement, ByteString)
decodeNodeAnnouncement :: ByteString -> Either DecodeError (NodeAnnouncement, ByteString)
decodeNodeAnnouncement ByteString
bs = do
(sig, bs1) <- ByteString -> Either DecodeError (Signature, ByteString)
decodeSignature ByteString
bs
(features, bs2) <- decodeFeatureBits bs1
(timestamp, bs3) <- decodeU32 bs2
(nid, bs4) <- decodeNodeId bs3
(color, bs5) <- decodeRgbColor bs4
(al, bs6) <- decodeAlias bs5
(addrs, rest) <- decodeAddresses bs6
let msg = NodeAnnouncement
{ nodeAnnSignature :: Signature
nodeAnnSignature = Signature
sig
, nodeAnnFeatures :: FeatureBits
nodeAnnFeatures = FeatureBits
features
, nodeAnnTimestamp :: Word32
nodeAnnTimestamp = Word32
timestamp
, nodeAnnNodeId :: NodeId
nodeAnnNodeId = NodeId
nid
, nodeAnnRgbColor :: RgbColor
nodeAnnRgbColor = RgbColor
color
, nodeAnnAlias :: Alias
nodeAnnAlias = Alias
al
, nodeAnnAddresses :: [Address]
nodeAnnAddresses = [Address]
addrs
}
Right (msg, rest)
encodeChannelUpdate :: ChannelUpdate -> ByteString
encodeChannelUpdate :: ChannelUpdate -> ByteString
encodeChannelUpdate ChannelUpdate
msg = [ByteString] -> ByteString
forall a. Monoid a => [a] -> a
mconcat
[ Signature -> ByteString
getSignature (ChannelUpdate -> Signature
chanUpdateSignature ChannelUpdate
msg)
, ChainHash -> ByteString
getChainHash (ChannelUpdate -> ChainHash
chanUpdateChainHash ChannelUpdate
msg)
, ShortChannelId -> ByteString
getShortChannelId (ChannelUpdate -> ShortChannelId
chanUpdateShortChanId ChannelUpdate
msg)
, Word32 -> ByteString
Prim.encodeU32 (ChannelUpdate -> Word32
chanUpdateTimestamp ChannelUpdate
msg)
, Word8 -> ByteString
BS.singleton (MessageFlags -> Word8
encodeMessageFlags (ChannelUpdate -> MessageFlags
chanUpdateMsgFlags ChannelUpdate
msg))
, Word8 -> ByteString
BS.singleton (ChannelFlags -> Word8
encodeChannelFlags (ChannelUpdate -> ChannelFlags
chanUpdateChanFlags ChannelUpdate
msg))
, Word16 -> ByteString
Prim.encodeU16 (CltvExpiryDelta -> Word16
getCltvExpiryDelta (ChannelUpdate -> CltvExpiryDelta
chanUpdateCltvExpDelta ChannelUpdate
msg))
, Word64 -> ByteString
Prim.encodeU64 (HtlcMinimumMsat -> Word64
getHtlcMinimumMsat (ChannelUpdate -> HtlcMinimumMsat
chanUpdateHtlcMinMsat ChannelUpdate
msg))
, Word32 -> ByteString
Prim.encodeU32 (FeeBaseMsat -> Word32
getFeeBaseMsat (ChannelUpdate -> FeeBaseMsat
chanUpdateFeeBaseMsat ChannelUpdate
msg))
, Word32 -> ByteString
Prim.encodeU32 (FeeProportionalMillionths -> Word32
getFeeProportionalMillionths (ChannelUpdate -> FeeProportionalMillionths
chanUpdateFeeProportional ChannelUpdate
msg))
, case ChannelUpdate -> Maybe HtlcMaximumMsat
chanUpdateHtlcMaxMsat ChannelUpdate
msg of
Maybe HtlcMaximumMsat
Nothing -> ByteString
BS.empty
Just HtlcMaximumMsat
m -> Word64 -> ByteString
Prim.encodeU64 (HtlcMaximumMsat -> Word64
getHtlcMaximumMsat HtlcMaximumMsat
m)
]
decodeChannelUpdate :: ByteString
-> Either DecodeError (ChannelUpdate, ByteString)
decodeChannelUpdate :: ByteString -> Either DecodeError (ChannelUpdate, ByteString)
decodeChannelUpdate ByteString
bs = do
(sig, bs1) <- ByteString -> Either DecodeError (Signature, ByteString)
decodeSignature ByteString
bs
(chainH, bs2) <- decodeChainHash bs1
(scid, bs3) <- decodeShortChannelId bs2
(timestamp, bs4) <- decodeU32 bs3
(msgFlagsRaw, bs5) <- decodeU8 bs4
(chanFlagsRaw, bs6) <- decodeU8 bs5
(cltvDelta, bs7) <- decodeU16 bs6
(htlcMin, bs8) <- decodeU64 bs7
(feeBase, bs9) <- decodeU32 bs8
(feeProp, bs10) <- decodeU32 bs9
let msgFlags' = Word8 -> MessageFlags
decodeMessageFlags Word8
msgFlagsRaw
chanFlags' = Word8 -> ChannelFlags
decodeChannelFlags Word8
chanFlagsRaw
(htlcMax, rest) <- if mfHtlcMaxPresent msgFlags'
then do
(m, r) <- decodeU64 bs10
Right (Just (HtlcMaximumMsat m), r)
else Right (Nothing, bs10)
let msg = ChannelUpdate
{ chanUpdateSignature :: Signature
chanUpdateSignature = Signature
sig
, chanUpdateChainHash :: ChainHash
chanUpdateChainHash = ChainHash
chainH
, chanUpdateShortChanId :: ShortChannelId
chanUpdateShortChanId = ShortChannelId
scid
, chanUpdateTimestamp :: Word32
chanUpdateTimestamp = Word32
timestamp
, chanUpdateMsgFlags :: MessageFlags
chanUpdateMsgFlags = MessageFlags
msgFlags'
, chanUpdateChanFlags :: ChannelFlags
chanUpdateChanFlags = ChannelFlags
chanFlags'
, chanUpdateCltvExpDelta :: CltvExpiryDelta
chanUpdateCltvExpDelta = Word16 -> CltvExpiryDelta
CltvExpiryDelta Word16
cltvDelta
, chanUpdateHtlcMinMsat :: HtlcMinimumMsat
chanUpdateHtlcMinMsat = Word64 -> HtlcMinimumMsat
HtlcMinimumMsat Word64
htlcMin
, chanUpdateFeeBaseMsat :: FeeBaseMsat
chanUpdateFeeBaseMsat = Word32 -> FeeBaseMsat
FeeBaseMsat Word32
feeBase
, chanUpdateFeeProportional :: FeeProportionalMillionths
chanUpdateFeeProportional = Word32 -> FeeProportionalMillionths
FeeProportionalMillionths Word32
feeProp
, chanUpdateHtlcMaxMsat :: Maybe HtlcMaximumMsat
chanUpdateHtlcMaxMsat = Maybe HtlcMaximumMsat
htlcMax
}
Right (msg, rest)
encodeAnnouncementSignatures :: AnnouncementSignatures -> ByteString
encodeAnnouncementSignatures :: AnnouncementSignatures -> ByteString
encodeAnnouncementSignatures AnnouncementSignatures
msg = [ByteString] -> ByteString
forall a. Monoid a => [a] -> a
mconcat
[ ChannelId -> ByteString
getChannelId (AnnouncementSignatures -> ChannelId
annSigChannelId AnnouncementSignatures
msg)
, ShortChannelId -> ByteString
getShortChannelId (AnnouncementSignatures -> ShortChannelId
annSigShortChanId AnnouncementSignatures
msg)
, Signature -> ByteString
getSignature (AnnouncementSignatures -> Signature
annSigNodeSig AnnouncementSignatures
msg)
, Signature -> ByteString
getSignature (AnnouncementSignatures -> Signature
annSigBitcoinSig AnnouncementSignatures
msg)
]
decodeAnnouncementSignatures :: ByteString
-> Either DecodeError
(AnnouncementSignatures, ByteString)
decodeAnnouncementSignatures :: ByteString
-> Either DecodeError (AnnouncementSignatures, ByteString)
decodeAnnouncementSignatures ByteString
bs = do
(cid, bs1) <- ByteString -> Either DecodeError (ChannelId, ByteString)
decodeChannelId ByteString
bs
(scid, bs2) <- decodeShortChannelId bs1
(nodeSig, bs3) <- decodeSignature bs2
(btcSig, rest) <- decodeSignature bs3
let msg = AnnouncementSignatures
{ annSigChannelId :: ChannelId
annSigChannelId = ChannelId
cid
, annSigShortChanId :: ShortChannelId
annSigShortChanId = ShortChannelId
scid
, annSigNodeSig :: Signature
annSigNodeSig = Signature
nodeSig
, annSigBitcoinSig :: Signature
annSigBitcoinSig = Signature
btcSig
}
Right (msg, rest)
encodeQueryShortChannelIds :: QueryShortChannelIds
-> Either EncodeError ByteString
encodeQueryShortChannelIds :: QueryShortChannelIds -> Either EncodeError ByteString
encodeQueryShortChannelIds QueryShortChannelIds
msg = do
let scidData :: ByteString
scidData = QueryShortChannelIds -> ByteString
queryScidsData QueryShortChannelIds
msg
if ByteString -> Int
BS.length ByteString
scidData Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
65535
then EncodeError -> Either EncodeError ByteString
forall a b. a -> Either a b
Left EncodeError
EncodeLengthOverflow
else ByteString -> Either EncodeError ByteString
forall a b. b -> Either a b
Right (ByteString -> Either EncodeError ByteString)
-> ByteString -> Either EncodeError ByteString
forall a b. (a -> b) -> a -> b
$ [ByteString] -> ByteString
forall a. Monoid a => [a] -> a
mconcat
[ ChainHash -> ByteString
getChainHash (QueryShortChannelIds -> ChainHash
queryScidsChainHash QueryShortChannelIds
msg)
, ByteString -> ByteString
encodeLenPrefixed ByteString
scidData
, TlvStream -> ByteString
TLV.encodeTlvStream (QueryShortChannelIds -> TlvStream
queryScidsTlvs QueryShortChannelIds
msg)
]
decodeQueryShortChannelIds :: ByteString
-> Either DecodeError
(QueryShortChannelIds, ByteString)
decodeQueryShortChannelIds :: ByteString -> Either DecodeError (QueryShortChannelIds, ByteString)
decodeQueryShortChannelIds ByteString
bs = do
(chainH, bs1) <- ByteString -> Either DecodeError (ChainHash, ByteString)
decodeChainHash ByteString
bs
(scidData, bs2) <- decodeLenPrefixed bs1
let tlvs = case ByteString -> Either TlvError TlvStream
TLV.decodeTlvStreamRaw ByteString
bs2 of
Left TlvError
_ -> [TlvRecord] -> TlvStream
unsafeTlvStream []
Right TlvStream
t -> TlvStream
t
let msg = QueryShortChannelIds
{ queryScidsChainHash :: ChainHash
queryScidsChainHash = ChainHash
chainH
, queryScidsData :: ByteString
queryScidsData = ByteString
scidData
, queryScidsTlvs :: TlvStream
queryScidsTlvs = TlvStream
tlvs
}
Right (msg, BS.empty)
encodeReplyShortChannelIdsEnd :: ReplyShortChannelIdsEnd -> ByteString
encodeReplyShortChannelIdsEnd :: ReplyShortChannelIdsEnd -> ByteString
encodeReplyShortChannelIdsEnd ReplyShortChannelIdsEnd
msg = [ByteString] -> ByteString
forall a. Monoid a => [a] -> a
mconcat
[ ChainHash -> ByteString
getChainHash (ReplyShortChannelIdsEnd -> ChainHash
replyScidsChainHash ReplyShortChannelIdsEnd
msg)
, Word8 -> ByteString
BS.singleton (ReplyShortChannelIdsEnd -> Word8
replyScidsFullInfo ReplyShortChannelIdsEnd
msg)
]
decodeReplyShortChannelIdsEnd :: ByteString
-> Either DecodeError
(ReplyShortChannelIdsEnd, ByteString)
decodeReplyShortChannelIdsEnd :: ByteString
-> Either DecodeError (ReplyShortChannelIdsEnd, ByteString)
decodeReplyShortChannelIdsEnd ByteString
bs = do
(chainH, bs1) <- ByteString -> Either DecodeError (ChainHash, ByteString)
decodeChainHash ByteString
bs
(fullInfo, rest) <- decodeU8 bs1
let msg = ReplyShortChannelIdsEnd
{ replyScidsChainHash :: ChainHash
replyScidsChainHash = ChainHash
chainH
, replyScidsFullInfo :: Word8
replyScidsFullInfo = Word8
fullInfo
}
Right (msg, rest)
encodeQueryChannelRange :: QueryChannelRange -> ByteString
encodeQueryChannelRange :: QueryChannelRange -> ByteString
encodeQueryChannelRange QueryChannelRange
msg = [ByteString] -> ByteString
forall a. Monoid a => [a] -> a
mconcat
[ ChainHash -> ByteString
getChainHash (QueryChannelRange -> ChainHash
queryRangeChainHash QueryChannelRange
msg)
, Word32 -> ByteString
Prim.encodeU32 (QueryChannelRange -> Word32
queryRangeFirstBlock QueryChannelRange
msg)
, Word32 -> ByteString
Prim.encodeU32 (QueryChannelRange -> Word32
queryRangeNumBlocks QueryChannelRange
msg)
, TlvStream -> ByteString
TLV.encodeTlvStream (QueryChannelRange -> TlvStream
queryRangeTlvs QueryChannelRange
msg)
]
decodeQueryChannelRange :: ByteString
-> Either DecodeError (QueryChannelRange, ByteString)
decodeQueryChannelRange :: ByteString -> Either DecodeError (QueryChannelRange, ByteString)
decodeQueryChannelRange ByteString
bs = do
(chainH, bs1) <- ByteString -> Either DecodeError (ChainHash, ByteString)
decodeChainHash ByteString
bs
(firstBlock, bs2) <- decodeU32 bs1
(numBlocks, bs3) <- decodeU32 bs2
let tlvs = case ByteString -> Either TlvError TlvStream
TLV.decodeTlvStreamRaw ByteString
bs3 of
Left TlvError
_ -> [TlvRecord] -> TlvStream
unsafeTlvStream []
Right TlvStream
t -> TlvStream
t
let msg = QueryChannelRange
{ queryRangeChainHash :: ChainHash
queryRangeChainHash = ChainHash
chainH
, queryRangeFirstBlock :: Word32
queryRangeFirstBlock = Word32
firstBlock
, queryRangeNumBlocks :: Word32
queryRangeNumBlocks = Word32
numBlocks
, queryRangeTlvs :: TlvStream
queryRangeTlvs = TlvStream
tlvs
}
Right (msg, BS.empty)
encodeReplyChannelRange :: ReplyChannelRange -> Either EncodeError ByteString
encodeReplyChannelRange :: ReplyChannelRange -> Either EncodeError ByteString
encodeReplyChannelRange ReplyChannelRange
msg = do
let rangeData :: ByteString
rangeData = ReplyChannelRange -> ByteString
replyRangeData ReplyChannelRange
msg
if ByteString -> Int
BS.length ByteString
rangeData Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
65535
then EncodeError -> Either EncodeError ByteString
forall a b. a -> Either a b
Left EncodeError
EncodeLengthOverflow
else ByteString -> Either EncodeError ByteString
forall a b. b -> Either a b
Right (ByteString -> Either EncodeError ByteString)
-> ByteString -> Either EncodeError ByteString
forall a b. (a -> b) -> a -> b
$ [ByteString] -> ByteString
forall a. Monoid a => [a] -> a
mconcat
[ ChainHash -> ByteString
getChainHash (ReplyChannelRange -> ChainHash
replyRangeChainHash ReplyChannelRange
msg)
, Word32 -> ByteString
Prim.encodeU32 (ReplyChannelRange -> Word32
replyRangeFirstBlock ReplyChannelRange
msg)
, Word32 -> ByteString
Prim.encodeU32 (ReplyChannelRange -> Word32
replyRangeNumBlocks ReplyChannelRange
msg)
, Word8 -> ByteString
BS.singleton (ReplyChannelRange -> Word8
replyRangeSyncComplete ReplyChannelRange
msg)
, ByteString -> ByteString
encodeLenPrefixed ByteString
rangeData
, TlvStream -> ByteString
TLV.encodeTlvStream (ReplyChannelRange -> TlvStream
replyRangeTlvs ReplyChannelRange
msg)
]
decodeReplyChannelRange :: ByteString
-> Either DecodeError (ReplyChannelRange, ByteString)
decodeReplyChannelRange :: ByteString -> Either DecodeError (ReplyChannelRange, ByteString)
decodeReplyChannelRange ByteString
bs = do
(chainH, bs1) <- ByteString -> Either DecodeError (ChainHash, ByteString)
decodeChainHash ByteString
bs
(firstBlock, bs2) <- decodeU32 bs1
(numBlocks, bs3) <- decodeU32 bs2
(syncComplete, bs4) <- decodeU8 bs3
(rangeData, bs5) <- decodeLenPrefixed bs4
let tlvs = case ByteString -> Either TlvError TlvStream
TLV.decodeTlvStreamRaw ByteString
bs5 of
Left TlvError
_ -> [TlvRecord] -> TlvStream
unsafeTlvStream []
Right TlvStream
t -> TlvStream
t
let msg = ReplyChannelRange
{ replyRangeChainHash :: ChainHash
replyRangeChainHash = ChainHash
chainH
, replyRangeFirstBlock :: Word32
replyRangeFirstBlock = Word32
firstBlock
, replyRangeNumBlocks :: Word32
replyRangeNumBlocks = Word32
numBlocks
, replyRangeSyncComplete :: Word8
replyRangeSyncComplete = Word8
syncComplete
, replyRangeData :: ByteString
replyRangeData = ByteString
rangeData
, replyRangeTlvs :: TlvStream
replyRangeTlvs = TlvStream
tlvs
}
Right (msg, BS.empty)
encodeGossipTimestampFilter :: GossipTimestampFilter -> ByteString
encodeGossipTimestampFilter :: GossipTimestampFilter -> ByteString
encodeGossipTimestampFilter GossipTimestampFilter
msg = [ByteString] -> ByteString
forall a. Monoid a => [a] -> a
mconcat
[ ChainHash -> ByteString
getChainHash (GossipTimestampFilter -> ChainHash
gossipFilterChainHash GossipTimestampFilter
msg)
, Word32 -> ByteString
Prim.encodeU32 (GossipTimestampFilter -> Word32
gossipFilterFirstTimestamp GossipTimestampFilter
msg)
, Word32 -> ByteString
Prim.encodeU32 (GossipTimestampFilter -> Word32
gossipFilterTimestampRange GossipTimestampFilter
msg)
]
decodeGossipTimestampFilter :: ByteString
-> Either DecodeError
(GossipTimestampFilter, ByteString)
decodeGossipTimestampFilter :: ByteString
-> Either DecodeError (GossipTimestampFilter, ByteString)
decodeGossipTimestampFilter ByteString
bs = do
(chainH, bs1) <- ByteString -> Either DecodeError (ChainHash, ByteString)
decodeChainHash ByteString
bs
(firstTs, bs2) <- decodeU32 bs1
(tsRange, rest) <- decodeU32 bs2
let msg = GossipTimestampFilter
{ gossipFilterChainHash :: ChainHash
gossipFilterChainHash = ChainHash
chainH
, gossipFilterFirstTimestamp :: Word32
gossipFilterFirstTimestamp = Word32
firstTs
, gossipFilterTimestampRange :: Word32
gossipFilterTimestampRange = Word32
tsRange
}
Right (msg, rest)
encodeShortChannelIdList :: [ShortChannelId] -> ByteString
encodeShortChannelIdList :: [ShortChannelId] -> ByteString
encodeShortChannelIdList [ShortChannelId]
scids = Word8 -> ByteString -> ByteString
BS.cons Word8
0 (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$
[ByteString] -> ByteString
forall a. Monoid a => [a] -> a
mconcat ((ShortChannelId -> ByteString) -> [ShortChannelId] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
map ShortChannelId -> ByteString
getShortChannelId [ShortChannelId]
scids)
{-# INLINE encodeShortChannelIdList #-}
decodeShortChannelIdList :: ByteString
-> Either DecodeError [ShortChannelId]
decodeShortChannelIdList :: ByteString -> Either DecodeError [ShortChannelId]
decodeShortChannelIdList ByteString
bs
| ByteString -> Bool
BS.null ByteString
bs = DecodeError -> Either DecodeError [ShortChannelId]
forall a b. a -> Either a b
Left DecodeError
DecodeInsufficientBytes
| Bool
otherwise = do
let encType :: Word8
encType = HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
BS.index ByteString
bs Int
0
payload :: ByteString
payload = Int -> ByteString -> ByteString
BS.drop Int
1 ByteString
bs
case Word8
encType of
Word8
0 -> ByteString -> Either DecodeError [ShortChannelId]
decodeUncompressedScids ByteString
payload
Word8
_ -> DecodeError -> Either DecodeError [ShortChannelId]
forall a b. a -> Either a b
Left DecodeError
DecodeInvalidShortChannelId
where
decodeUncompressedScids :: ByteString -> Either DecodeError [ShortChannelId]
decodeUncompressedScids :: ByteString -> Either DecodeError [ShortChannelId]
decodeUncompressedScids !ByteString
d
| ByteString -> Bool
BS.null ByteString
d = [ShortChannelId] -> Either DecodeError [ShortChannelId]
forall a b. b -> Either a b
Right []
| ByteString -> Int
BS.length ByteString
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
shortChannelIdLen = DecodeError -> Either DecodeError [ShortChannelId]
forall a b. a -> Either a b
Left DecodeError
DecodeInsufficientBytes
| Bool
otherwise = do
let (ByteString
scidBytes, ByteString
rest) = Int -> ByteString -> (ByteString, ByteString)
BS.splitAt Int
shortChannelIdLen ByteString
d
case ByteString -> Maybe ShortChannelId
shortChannelId ByteString
scidBytes of
Maybe ShortChannelId
Nothing -> DecodeError -> Either DecodeError [ShortChannelId]
forall a b. a -> Either a b
Left DecodeError
DecodeInvalidShortChannelId
Just ShortChannelId
scid -> do
scids <- ByteString -> Either DecodeError [ShortChannelId]
decodeUncompressedScids ByteString
rest
Right (scid : scids)
{-# INLINE decodeShortChannelIdList #-}