bolt7

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

commit 79540cf45574e0c3e2b4d1e05c8a5b94fa65ebee
parent e33f9460d1e6e7c6174ea9f950c48bfc32fd56af
Author: Jared Tobin <jared@jtobin.io>
Date:   Sat, 10 Oct 2026 13:09:43 +0400

test: htlc_maximum_msat and must_be_one regression tests

Check that the encoder sets must_be_one and always emits
htlc_maximum_msat, that the decoder reads the field with the bit
clear, and that a 128-byte legacy update is rejected.

Diffstat:
Mtest/Main.hs | 40+++++++++++++++++++++++++++++++++++++++-
1 file changed, 39 insertions(+), 1 deletion(-)

diff --git a/test/Main.hs b/test/Main.hs @@ -4,7 +4,7 @@ module Main where import qualified Data.ByteString as BS import Data.Maybe (fromJust) -import Data.Word (Word16, Word32) +import Data.Word (Word8, Word16, Word32) import Lightning.Protocol.BOLT1 (TlvStream, unsafeTlvStream) import Lightning.Protocol.BOLT7 import Lightning.Protocol.BOLT7.CRC32C (crc32c) @@ -79,6 +79,28 @@ mkScid b t o = case shortChannelId b t o of Just s -> s Nothing -> error "mkScid: invalid test fixture" +-- | A channel_update fixture. +testChannelUpdate :: ChannelUpdate +testChannelUpdate = ChannelUpdate + { chanUpdateSignature = testSignature + , chanUpdateChainHash = testChainHash + , chanUpdateShortChanId = testShortChannelId + , chanUpdateTimestamp = 1234567890 + , chanUpdateChanFlags = ChannelFlags + { cfDirection = NodeOne, cfStatus = Enabled } + , chanUpdateCltvExpDelta = CltvExpiryDelta 144 + , chanUpdateHtlcMinMsat = HtlcMinimumMsat 1000 + , chanUpdateFeeBaseMsat = FeeBaseMsat 1000 + , chanUpdateFeeProportional = FeeProportionalMillionths 100 + , chanUpdateHtlcMaxMsat = HtlcMaximumMsat 1000000000 + } + +-- | Replace the byte at an offset (no-op past the end). +setByte :: Int -> Word8 -> BS.ByteString -> BS.ByteString +setByte i w bs + | i < 0 || i >= BS.length bs = bs + | otherwise = BS.take i bs <> BS.singleton w <> BS.drop (i + 1) bs + -- Type Tests ------------------------------------------------------------------ type_tests :: TestTree @@ -237,6 +259,22 @@ channel_update_tests = testGroup "ChannelUpdate" [ case decodeChannelUpdate encoded of Right (decoded, _) -> decoded @?= msg Left e -> assertFailure $ "decode failed: " ++ show e + , testCase "encoder sets must_be_one and emits htlc_maximum_msat" $ do + let encoded = encodeChannelUpdate testChannelUpdate + BS.length encoded @?= 136 + BS.take 1 (BS.drop 108 encoded) @?= BS.singleton 0x01 + BS.drop 128 encoded @?= BS.pack [0, 0, 0, 0, 0x3b, 0x9a, 0xca, 0] + , testCase "decodes htlc_maximum_msat when must_be_one is clear" $ do + -- receivers ignore must_be_one; the field is always present + let wire = setByte 108 0x00 (encodeChannelUpdate testChannelUpdate) + case decodeChannelUpdate wire of + Right (decoded, rest) -> do + decoded @?= testChannelUpdate + rest @?= BS.empty + Left e -> assertFailure $ "decode failed: " ++ show e + , testCase "rejects update without htlc_maximum_msat" $ do + let wire = BS.take 128 (encodeChannelUpdate testChannelUpdate) + decodeChannelUpdate wire @?= Left DecodeInsufficientBytes ] -- Announcement Signatures Tests -----------------------------------------------