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:
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 -----------------------------------------------