commit 89df0389196ed8ba5c010320ad4002741dd98771
parent e7ef9d53a92063b1c9129d2f811606795a5440cf
Author: Jared Tobin <jared@jtobin.io>
Date: Sat, 10 Oct 2026 14:19:38 +0400
bench: rewrite for the new API
Criterion and weigh suites over the payload codecs of representative
messages (open_channel, accept_channel2, tx_signatures,
closing_complete, update_add_htlc, update_fulfill_htlc,
commitment_signed with 0 and 483 HTLCs, revoke_and_ack,
channel_reestablish) and the message dispatcher, forcing results with
nf. Fixtures are built without partial functions.
Diffstat:
| A | bench/Fixtures.hs | | | 126 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | bench/Main.hs | | | 346 | +++++++++++++------------------------------------------------------------------ |
| M | bench/Weight.hs | | | 381 | +++++++++---------------------------------------------------------------------- |
3 files changed, 224 insertions(+), 629 deletions(-)
diff --git a/bench/Fixtures.hs b/bench/Fixtures.hs
@@ -0,0 +1,126 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Fixtures (
+ Fixtures(..)
+ , fixtures
+ ) where
+
+import qualified Bitcoin.Prim.Tx as Tx
+import qualified Data.ByteString as BS
+import qualified Lightning.Protocol.BOLT1 as BOLT1
+import Lightning.Protocol.BOLT2
+import qualified Lightning.Protocol.BOLT9 as BOLT9
+
+-- representative messages, with their encoded payloads
+data Fixtures = Fixtures
+ { fx_open_channel :: !OpenChannel
+ , fx_open_channel_bytes :: !BS.ByteString
+ , fx_accept_channel2 :: !AcceptChannel2
+ , fx_accept_channel2_bytes :: !BS.ByteString
+ , fx_tx_signatures :: !TxSignatures
+ , fx_tx_signatures_bytes :: !BS.ByteString
+ , fx_closing_complete :: !ClosingComplete
+ , fx_closing_complete_bytes :: !BS.ByteString
+ , fx_update_add_htlc :: !UpdateAddHtlc
+ , fx_update_add_htlc_bytes :: !BS.ByteString
+ , fx_update_add_htlc_wire :: !BS.ByteString
+ , fx_update_fulfill_htlc :: !UpdateFulfillHtlc
+ , fx_update_fulfill_htlc_bytes :: !BS.ByteString
+ , fx_commitment_signed :: !CommitmentSigned
+ , fx_commitment_signed_bytes :: !BS.ByteString
+ , fx_commitment_signed_483 :: !CommitmentSigned
+ , fx_commitment_signed_483_bytes :: !BS.ByteString
+ , fx_revoke_and_ack :: !RevokeAndAck
+ , fx_revoke_and_ack_bytes :: !BS.ByteString
+ , fx_channel_reestablish :: !ChannelReestablish
+ , fx_channel_reestablish_bytes :: !BS.ByteString
+ }
+
+ok :: Either e a -> Maybe a
+ok = either (const Nothing) Just
+
+empty :: BOLT1.TlvStream
+empty = BOLT1.empty_tlv_stream
+
+fixtures :: Maybe Fixtures
+fixtures = do
+ ch <- BOLT1.chain_hash (BS.replicate 32 0x6f)
+ cid <- BOLT1.channel_id (BS.replicate 32 0xab)
+ pts <- traverse (\b -> BOLT1.point (BS.cons 0x02 (BS.replicate 32 b)))
+ [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77]
+ sig <- BOLT1.signature (BS.replicate 64 0xa1)
+ txid <- Tx.mkTxId (BS.replicate 32 0x7e)
+ spk <- script_pubkey ("\x00\x14" <> BS.replicate 20 0x88)
+ fund <- BOLT1.satoshi 1000000
+ dust <- BOLT1.satoshi 546
+ res <- BOLT1.satoshi 10000
+ push <- BOLT1.milli_satoshi 0
+ hmin <- BOLT1.milli_satoshi 1000
+ amt <- BOLT1.milli_satoshi 100000
+ fee <- BOLT1.satoshi 500
+ ph <- BOLT1.payment_hash (BS.replicate 32 0x9a)
+ pre <- BOLT1.payment_preimage (BS.replicate 32 0x50)
+ sec <- BOLT1.per_commitment_secret (BS.replicate 32 0x5e)
+ onion <- onion_routing_packet (BS.replicate 1366 0x44)
+ att <- attribution_data (BS.replicate 920 0x0b)
+ ws <- traverse witness
+ [ "\x02\x47" <> BS.replicate 71 0x30 <> "\x21"
+ <> BS.replicate 33 0x02
+ , "\x01\x40" <> BS.replicate 64 0x01 ]
+ ext <- BOLT1.tlv_stream [BOLT1.TlvRecord 43 (BS.replicate 16 0x2a)]
+ (p1, p2, p3, p4, p5, p6, p7) <- case pts of
+ [a, b, c, d, e, f, g] -> Just (a, b, c, d, e, f, g)
+ _ -> Nothing
+ let ctype = BOLT9.channel_type_features
+ (BOLT9.ChannelType BOLT9.BasicAnchors False False)
+
+ oc = OpenChannel ch cid fund push dust maxBound res hmin 253 144 483
+ p1 p2 p3 p4 p5 p6 1 (Just spk) (Just ctype) empty
+ ac2 = AcceptChannel2 cid fund dust maxBound hmin 3 144 483
+ p1 p2 p3 p4 p5 p6 p7 (Just spk) (Just ctype) True ext
+ txs = TxSignatures cid txid ws empty
+ cc = ClosingComplete cid spk spk fee 0 (Just sig) Nothing (Just sig)
+ empty
+ add = UpdateAddHtlc cid (HtlcId 42) amt ph 800000 onion (Just p1)
+ empty
+ ful = UpdateFulfillHtlc cid (HtlcId 42) pre (Just att) Nothing empty
+ cs0 = CommitmentSigned cid sig [] (Just txid) empty
+ cs483 = CommitmentSigned cid sig (replicate 483 sig) (Just txid)
+ empty
+ raa = RevokeAndAck cid sec p1 empty
+ rst = ChannelReestablish cid 5 4 sec p1 (Just (NextFunding txid 1))
+ empty
+
+ oc_b <- ok (encode_open_channel oc)
+ ac2_b <- ok (encode_accept_channel2 ac2)
+ txs_b <- ok (encode_tx_signatures txs)
+ cc_b <- ok (encode_closing_complete cc)
+ add_b <- ok (encode_update_add_htlc add)
+ add_w <- ok (encode_message (MsgUpdateAddHtlc add))
+ ful_b <- ok (encode_update_fulfill_htlc ful)
+ cs0_b <- ok (encode_commitment_signed cs0)
+ cs483_b <- ok (encode_commitment_signed cs483)
+ rst_b <- ok (encode_channel_reestablish rst)
+ pure Fixtures
+ { fx_open_channel = oc
+ , fx_open_channel_bytes = oc_b
+ , fx_accept_channel2 = ac2
+ , fx_accept_channel2_bytes = ac2_b
+ , fx_tx_signatures = txs
+ , fx_tx_signatures_bytes = txs_b
+ , fx_closing_complete = cc
+ , fx_closing_complete_bytes = cc_b
+ , fx_update_add_htlc = add
+ , fx_update_add_htlc_bytes = add_b
+ , fx_update_add_htlc_wire = add_w
+ , fx_update_fulfill_htlc = ful
+ , fx_update_fulfill_htlc_bytes = ful_b
+ , fx_commitment_signed = cs0
+ , fx_commitment_signed_bytes = cs0_b
+ , fx_commitment_signed_483 = cs483
+ , fx_commitment_signed_483_bytes = cs483_b
+ , fx_revoke_and_ack = raa
+ , fx_revoke_and_ack_bytes = encode_revoke_and_ack raa
+ , fx_channel_reestablish = rst
+ , fx_channel_reestablish_bytes = rst_b
+ }
diff --git a/bench/Main.hs b/bench/Main.hs
@@ -1,301 +1,65 @@
-{-# LANGUAGE BangPatterns #-}
-{-# LANGUAGE OverloadedStrings #-}
-
--- |
--- Module: Main
--- Copyright: (c) 2025 Jared Tobin
--- License: MIT
--- Maintainer: Jared Tobin <jared@ppad.tech>
---
--- Criterion timing benchmarks for BOLT #2 message codecs.
-
module Main where
import Criterion.Main
-import qualified Data.ByteString as BS
-import Lightning.Protocol.BOLT1 (TlvStream, unsafeTlvStream)
+import Fixtures
import Lightning.Protocol.BOLT2
--- Test data construction ------------------------------------------------------
-
--- | 32 zero bytes for channel IDs, chain hashes, etc.
-zeroBytes32 :: BS.ByteString
-zeroBytes32 = BS.replicate 32 0x00
-{-# NOINLINE zeroBytes32 #-}
-
--- | 33-byte compressed public key (02 prefix + 32 zero bytes).
-testPoint :: Point
-testPoint = case point (BS.cons 0x02 zeroBytes32) of
- Just p -> p
- Nothing -> error "testPoint: invalid"
-{-# NOINLINE testPoint #-}
-
--- | 64-byte signature.
-testSignature :: Signature
-testSignature = case signature (BS.replicate 64 0x01) of
- Just s -> s
- Nothing -> error "testSignature: invalid"
-{-# NOINLINE testSignature #-}
-
--- | 32-byte channel ID.
-testChannelId :: ChannelId
-testChannelId = case channelId zeroBytes32 of
- Just c -> c
- Nothing -> error "testChannelId: invalid"
-{-# NOINLINE testChannelId #-}
-
--- | 32-byte chain hash.
-testChainHash :: ChainHash
-testChainHash = case chainHash zeroBytes32 of
- Just h -> h
- Nothing -> error "testChainHash: invalid"
-{-# NOINLINE testChainHash #-}
-
--- | 32-byte txid.
-testTxId :: TxId
-testTxId = case mkTxId zeroBytes32 of
- Just t -> t
- Nothing -> error "testTxId: invalid"
-{-# NOINLINE testTxId #-}
-
--- | 32-byte payment hash.
-testPaymentHash :: PaymentHash
-testPaymentHash = case paymentHash zeroBytes32 of
- Just h -> h
- Nothing -> error "testPaymentHash: invalid"
-{-# NOINLINE testPaymentHash #-}
-
--- | 1366-byte onion packet.
-testOnionPacket :: OnionPacket
-testOnionPacket = case onionPacket (BS.replicate 1366 0x00) of
- Just o -> o
- Nothing -> error "testOnionPacket: invalid"
-{-# NOINLINE testOnionPacket #-}
-
--- | Empty TLV stream.
-emptyTlvs :: TlvStream
-emptyTlvs = unsafeTlvStream []
-{-# NOINLINE emptyTlvs #-}
-
--- V1 messages -----------------------------------------------------------------
-
--- | Test OpenChannel message.
-testOpenChannel :: OpenChannel
-testOpenChannel = OpenChannel
- { openChannelChainHash = testChainHash
- , openChannelTempChannelId = testChannelId
- , openChannelFundingSatoshi = Satoshi 1000000
- , openChannelPushMsat = MilliSatoshi 0
- , openChannelDustLimitSatoshi = Satoshi 546
- , openChannelMaxHtlcValueInFlight = MilliSatoshi 1000000000
- , openChannelChannelReserveSat = Satoshi 10000
- , openChannelHtlcMinimumMsat = MilliSatoshi 1000
- , openChannelFeeratePerKw = 250
- , openChannelToSelfDelay = 144
- , openChannelMaxAcceptedHtlcs = 30
- , openChannelFundingPubkey = testPoint
- , openChannelRevocationBasepoint = testPoint
- , openChannelPaymentBasepoint = testPoint
- , openChannelDelayedPaymentBase = testPoint
- , openChannelHtlcBasepoint = testPoint
- , openChannelFirstPerCommitPoint = testPoint
- , openChannelChannelFlags = 0x00
- , openChannelTlvs = emptyTlvs
- }
-{-# NOINLINE testOpenChannel #-}
-
--- | Encoded OpenChannel for decode benchmarks.
-encodedOpenChannel :: BS.ByteString
-encodedOpenChannel = encodeOpenChannel testOpenChannel
-{-# NOINLINE encodedOpenChannel #-}
-
--- V2 messages -----------------------------------------------------------------
-
--- | Test OpenChannel2 message.
-testOpenChannel2 :: OpenChannel2
-testOpenChannel2 = OpenChannel2
- { openChannel2ChainHash = testChainHash
- , openChannel2TempChannelId = testChannelId
- , openChannel2FundingFeeratePerkw = 2500
- , openChannel2CommitFeeratePerkw = 250
- , openChannel2FundingSatoshi = Satoshi 1000000
- , openChannel2DustLimitSatoshi = Satoshi 546
- , openChannel2MaxHtlcValueInFlight = MilliSatoshi 1000000000
- , openChannel2HtlcMinimumMsat = MilliSatoshi 1000
- , openChannel2ToSelfDelay = 144
- , openChannel2MaxAcceptedHtlcs = 30
- , openChannel2Locktime = 0
- , openChannel2FundingPubkey = testPoint
- , openChannel2RevocationBasepoint = testPoint
- , openChannel2PaymentBasepoint = testPoint
- , openChannel2DelayedPaymentBase = testPoint
- , openChannel2HtlcBasepoint = testPoint
- , openChannel2FirstPerCommitPoint = testPoint
- , openChannel2SecondPerCommitPoint = testPoint
- , openChannel2ChannelFlags = 0x00
- , openChannel2Tlvs = emptyTlvs
- }
-{-# NOINLINE testOpenChannel2 #-}
-
--- | Encoded OpenChannel2 for decode benchmarks.
-encodedOpenChannel2 :: BS.ByteString
-encodedOpenChannel2 = encodeOpenChannel2 testOpenChannel2
-{-# NOINLINE encodedOpenChannel2 #-}
-
--- | Test witness data (simulated P2WPKH signature + pubkey).
-testWitness :: Witness
-testWitness = Witness (BS.replicate 107 0xab)
-{-# NOINLINE testWitness #-}
-
--- | TxSignatures with multiple witnesses.
-testTxSignatures :: TxSignatures
-testTxSignatures = TxSignatures
- { txSignaturesChannelId = testChannelId
- , txSignaturesTxid = testTxId
- , txSignaturesWitnesses = replicate 5 testWitness
- }
-{-# NOINLINE testTxSignatures #-}
-
--- | Encoded TxSignatures for decode benchmarks.
-encodedTxSignatures :: BS.ByteString
-encodedTxSignatures = case encodeTxSignatures testTxSignatures of
- Right bs -> bs
- Left e -> error $ "encodedTxSignatures: " ++ show e
-{-# NOINLINE encodedTxSignatures #-}
-
--- Close messages --------------------------------------------------------------
-
--- | Test ClosingSigned message.
-testClosingSigned :: ClosingSigned
-testClosingSigned = ClosingSigned
- { closingSignedChannelId = testChannelId
- , closingSignedFeeSatoshi = Satoshi 1000
- , closingSignedSignature = testSignature
- , closingSignedTlvs = emptyTlvs
- }
-{-# NOINLINE testClosingSigned #-}
-
--- | Encoded ClosingSigned for decode benchmarks.
-encodedClosingSigned :: BS.ByteString
-encodedClosingSigned = encodeClosingSigned testClosingSigned
-{-# NOINLINE encodedClosingSigned #-}
-
--- Normal operation messages ---------------------------------------------------
-
--- | Test UpdateAddHtlc message.
-testUpdateAddHtlc :: UpdateAddHtlc
-testUpdateAddHtlc = UpdateAddHtlc
- { updateAddHtlcChannelId = testChannelId
- , updateAddHtlcId = htlcId 0
- , updateAddHtlcAmountMsat = MilliSatoshi 10000000
- , updateAddHtlcPaymentHash = testPaymentHash
- , updateAddHtlcCltvExpiry = 800000
- , updateAddHtlcOnionPacket = testOnionPacket
- , updateAddHtlcTlvs = emptyTlvs
- }
-{-# NOINLINE testUpdateAddHtlc #-}
-
--- | Encoded UpdateAddHtlc for decode benchmarks.
-encodedUpdateAddHtlc :: BS.ByteString
-encodedUpdateAddHtlc = encodeUpdateAddHtlc testUpdateAddHtlc
-{-# NOINLINE encodedUpdateAddHtlc #-}
-
--- | Test CommitmentSigned message with HTLC signatures (10 sigs).
-testCommitmentSigned :: CommitmentSigned
-testCommitmentSigned = CommitmentSigned
- { commitmentSignedChannelId = testChannelId
- , commitmentSignedSignature = testSignature
- , commitmentSignedHtlcSignatures = replicate 10 testSignature
- }
-{-# NOINLINE testCommitmentSigned #-}
-
--- | Encoded CommitmentSigned for decode benchmarks.
-encodedCommitmentSigned :: BS.ByteString
-encodedCommitmentSigned = case encodeCommitmentSigned testCommitmentSigned of
- Right bs -> bs
- Left e -> error $ "encodedCommitmentSigned: " ++ show e
-{-# NOINLINE encodedCommitmentSigned #-}
-
--- | Test CommitmentSigned with many HTLC signatures (100 sigs).
-testCommitmentSignedLarge :: CommitmentSigned
-testCommitmentSignedLarge = CommitmentSigned
- { commitmentSignedChannelId = testChannelId
- , commitmentSignedSignature = testSignature
- , commitmentSignedHtlcSignatures = replicate 100 testSignature
- }
-{-# NOINLINE testCommitmentSignedLarge #-}
-
--- | Encoded large CommitmentSigned for decode benchmarks.
-encodedCommitmentSignedLarge :: BS.ByteString
-encodedCommitmentSignedLarge =
- case encodeCommitmentSigned testCommitmentSignedLarge of
- Right bs -> bs
- Left e -> error $ "encodedCommitmentSignedLarge: " ++ show e
-{-# NOINLINE encodedCommitmentSignedLarge #-}
-
--- | Test CommitmentSigned with max HTLC signatures (483 sigs).
-testCommitmentSignedMax :: CommitmentSigned
-testCommitmentSignedMax = CommitmentSigned
- { commitmentSignedChannelId = testChannelId
- , commitmentSignedSignature = testSignature
- , commitmentSignedHtlcSignatures = replicate 483 testSignature
- }
-{-# NOINLINE testCommitmentSignedMax #-}
-
--- | Encoded max CommitmentSigned for decode benchmarks.
-encodedCommitmentSignedMax :: BS.ByteString
-encodedCommitmentSignedMax =
- case encodeCommitmentSigned testCommitmentSignedMax of
- Right bs -> bs
- Left e -> error $ "encodedCommitmentSignedMax: " ++ show e
-{-# NOINLINE encodedCommitmentSignedMax #-}
-
--- Benchmark groups ------------------------------------------------------------
-
main :: IO ()
-main = defaultMain
- [ bgroup "v1"
- [ bgroup "open_channel"
- [ bench "encode" $ nf encodeOpenChannel testOpenChannel
- , bench "decode" $ nf decodeOpenChannel encodedOpenChannel
- ]
+main = case fixtures of
+ Nothing -> fail "invalid fixtures"
+ Just fx -> defaultMain [
+ bgroup "open_channel" [
+ bench "encode" $ nf encode_open_channel (fx_open_channel fx)
+ , bench "decode" $ nf decode_open_channel (fx_open_channel_bytes fx)
+ ]
+ , bgroup "accept_channel2" [
+ bench "encode" $ nf encode_accept_channel2 (fx_accept_channel2 fx)
+ , bench "decode" $
+ nf decode_accept_channel2 (fx_accept_channel2_bytes fx)
+ ]
+ , bgroup "tx_signatures" [
+ bench "encode" $ nf encode_tx_signatures (fx_tx_signatures fx)
+ , bench "decode" $ nf decode_tx_signatures (fx_tx_signatures_bytes fx)
+ ]
+ , bgroup "closing_complete" [
+ bench "encode" $ nf encode_closing_complete (fx_closing_complete fx)
+ , bench "decode" $
+ nf decode_closing_complete (fx_closing_complete_bytes fx)
+ ]
+ , bgroup "update_add_htlc" [
+ bench "encode" $ nf encode_update_add_htlc (fx_update_add_htlc fx)
+ , bench "decode" $
+ nf decode_update_add_htlc (fx_update_add_htlc_bytes fx)
+ , bench "encode_message" $
+ nf encode_message (MsgUpdateAddHtlc (fx_update_add_htlc fx))
+ , bench "decode_message" $
+ nf decode_message (fx_update_add_htlc_wire fx)
+ ]
+ , bgroup "update_fulfill_htlc" [
+ bench "encode" $
+ nf encode_update_fulfill_htlc (fx_update_fulfill_htlc fx)
+ , bench "decode" $
+ nf decode_update_fulfill_htlc (fx_update_fulfill_htlc_bytes fx)
]
- , bgroup "v2"
- [ bgroup "open_channel2"
- [ bench "encode" $ nf encodeOpenChannel2 testOpenChannel2
- , bench "decode" $ nf decodeOpenChannel2 encodedOpenChannel2
- ]
- , bgroup "tx_signatures"
- [ bench "encode" $ nf encodeTxSignatures testTxSignatures
- , bench "decode" $ nf decodeTxSignatures encodedTxSignatures
- ]
+ , bgroup "commitment_signed" [
+ bench "encode (0 htlcs)" $
+ nf encode_commitment_signed (fx_commitment_signed fx)
+ , bench "decode (0 htlcs)" $
+ nf decode_commitment_signed (fx_commitment_signed_bytes fx)
+ , bench "encode (483 htlcs)" $
+ nf encode_commitment_signed (fx_commitment_signed_483 fx)
+ , bench "decode (483 htlcs)" $
+ nf decode_commitment_signed (fx_commitment_signed_483_bytes fx)
]
- , bgroup "close"
- [ bgroup "closing_signed"
- [ bench "encode" $ nf encodeClosingSigned testClosingSigned
- , bench "decode" $ nf decodeClosingSigned encodedClosingSigned
- ]
+ , bgroup "revoke_and_ack" [
+ bench "encode" $ nf encode_revoke_and_ack (fx_revoke_and_ack fx)
+ , bench "decode" $
+ nf decode_revoke_and_ack (fx_revoke_and_ack_bytes fx)
]
- , bgroup "normal"
- [ bgroup "update_add_htlc"
- [ bench "encode" $ nf encodeUpdateAddHtlc testUpdateAddHtlc
- , bench "decode" $ nf decodeUpdateAddHtlc encodedUpdateAddHtlc
- ]
- , bgroup "commitment_signed"
- [ bench "encode" $ nf encodeCommitmentSigned testCommitmentSigned
- , bench "decode" $ nf decodeCommitmentSigned encodedCommitmentSigned
- ]
- , bgroup "commitment_signed_100"
- [ bench "encode" $
- nf encodeCommitmentSigned testCommitmentSignedLarge
- , bench "decode" $
- nf decodeCommitmentSigned encodedCommitmentSignedLarge
- ]
- , bgroup "commitment_signed_483"
- [ bench "encode" $
- nf encodeCommitmentSigned testCommitmentSignedMax
- , bench "decode" $
- nf decodeCommitmentSigned encodedCommitmentSignedMax
- ]
+ , bgroup "channel_reestablish" [
+ bench "encode" $
+ nf encode_channel_reestablish (fx_channel_reestablish fx)
+ , bench "decode" $
+ nf decode_channel_reestablish (fx_channel_reestablish_bytes fx)
]
- ]
+ ]
diff --git a/bench/Weight.hs b/bench/Weight.hs
@@ -1,344 +1,49 @@
-{-# LANGUAGE BangPatterns #-}
-{-# LANGUAGE OverloadedStrings #-}
-
--- |
--- Module: Main
--- Copyright: (c) 2025 Jared Tobin
--- License: MIT
--- Maintainer: Jared Tobin <jared@ppad.tech>
---
--- Weigh allocation benchmarks for BOLT #2 message codecs.
-
module Main where
-import qualified Data.ByteString as BS
-import Lightning.Protocol.BOLT1 (TlvStream, unsafeTlvStream)
+import Fixtures
import Lightning.Protocol.BOLT2
import Weigh
--- | Wrapper for encoding functions that return Either.
-forceEncode :: Either EncodeError BS.ByteString -> BS.ByteString
-forceEncode (Right bs) = bs
-forceEncode (Left e) = error $ "forceEncode: " ++ show e
-{-# INLINE forceEncode #-}
-
--- Test data construction ------------------------------------------------------
-
--- | 32 zero bytes for channel IDs, chain hashes, etc.
-zeroBytes32 :: BS.ByteString
-zeroBytes32 = BS.replicate 32 0x00
-{-# NOINLINE zeroBytes32 #-}
-
--- | 33-byte compressed public key (02 prefix + 32 zero bytes).
-testPoint :: Point
-testPoint = case point (BS.cons 0x02 zeroBytes32) of
- Just p -> p
- Nothing -> error "testPoint: invalid"
-{-# NOINLINE testPoint #-}
-
--- | 64-byte signature.
-testSignature :: Signature
-testSignature = case signature (BS.replicate 64 0x01) of
- Just s -> s
- Nothing -> error "testSignature: invalid"
-{-# NOINLINE testSignature #-}
-
--- | 32-byte channel ID.
-testChannelId :: ChannelId
-testChannelId = case channelId zeroBytes32 of
- Just c -> c
- Nothing -> error "testChannelId: invalid"
-{-# NOINLINE testChannelId #-}
-
--- | 32-byte chain hash.
-testChainHash :: ChainHash
-testChainHash = case chainHash zeroBytes32 of
- Just h -> h
- Nothing -> error "testChainHash: invalid"
-{-# NOINLINE testChainHash #-}
-
--- | 32-byte txid.
-testTxId :: TxId
-testTxId = case mkTxId zeroBytes32 of
- Just t -> t
- Nothing -> error "testTxId: invalid"
-{-# NOINLINE testTxId #-}
-
--- | 32-byte payment hash.
-testPaymentHash :: PaymentHash
-testPaymentHash = case paymentHash zeroBytes32 of
- Just h -> h
- Nothing -> error "testPaymentHash: invalid"
-{-# NOINLINE testPaymentHash #-}
-
--- | 1366-byte onion packet.
-testOnionPacket :: OnionPacket
-testOnionPacket = case onionPacket (BS.replicate 1366 0x00) of
- Just o -> o
- Nothing -> error "testOnionPacket: invalid"
-{-# NOINLINE testOnionPacket #-}
-
--- | Empty TLV stream.
-emptyTlvs :: TlvStream
-emptyTlvs = unsafeTlvStream []
-{-# NOINLINE emptyTlvs #-}
-
--- Message constructors --------------------------------------------------------
-
--- | Construct OpenChannel message.
-mkOpenChannel :: ChainHash -> ChannelId -> Point -> TlvStream -> OpenChannel
-mkOpenChannel !ch !cid !pt !tlvs = OpenChannel
- { openChannelChainHash = ch
- , openChannelTempChannelId = cid
- , openChannelFundingSatoshi = Satoshi 1000000
- , openChannelPushMsat = MilliSatoshi 0
- , openChannelDustLimitSatoshi = Satoshi 546
- , openChannelMaxHtlcValueInFlight = MilliSatoshi 1000000000
- , openChannelChannelReserveSat = Satoshi 10000
- , openChannelHtlcMinimumMsat = MilliSatoshi 1000
- , openChannelFeeratePerKw = 250
- , openChannelToSelfDelay = 144
- , openChannelMaxAcceptedHtlcs = 30
- , openChannelFundingPubkey = pt
- , openChannelRevocationBasepoint = pt
- , openChannelPaymentBasepoint = pt
- , openChannelDelayedPaymentBase = pt
- , openChannelHtlcBasepoint = pt
- , openChannelFirstPerCommitPoint = pt
- , openChannelChannelFlags = 0x00
- , openChannelTlvs = tlvs
- }
-
--- | Construct OpenChannel2 message.
-mkOpenChannel2 :: ChainHash -> ChannelId -> Point -> TlvStream -> OpenChannel2
-mkOpenChannel2 !ch !cid !pt !tlvs = OpenChannel2
- { openChannel2ChainHash = ch
- , openChannel2TempChannelId = cid
- , openChannel2FundingFeeratePerkw = 2500
- , openChannel2CommitFeeratePerkw = 250
- , openChannel2FundingSatoshi = Satoshi 1000000
- , openChannel2DustLimitSatoshi = Satoshi 546
- , openChannel2MaxHtlcValueInFlight = MilliSatoshi 1000000000
- , openChannel2HtlcMinimumMsat = MilliSatoshi 1000
- , openChannel2ToSelfDelay = 144
- , openChannel2MaxAcceptedHtlcs = 30
- , openChannel2Locktime = 0
- , openChannel2FundingPubkey = pt
- , openChannel2RevocationBasepoint = pt
- , openChannel2PaymentBasepoint = pt
- , openChannel2DelayedPaymentBase = pt
- , openChannel2HtlcBasepoint = pt
- , openChannel2FirstPerCommitPoint = pt
- , openChannel2SecondPerCommitPoint = pt
- , openChannel2ChannelFlags = 0x00
- , openChannel2Tlvs = tlvs
- }
-
--- | Construct TxSignatures message.
-mkTxSignatures :: ChannelId -> TxId -> [Witness] -> TxSignatures
-mkTxSignatures !cid !tid !ws = TxSignatures
- { txSignaturesChannelId = cid
- , txSignaturesTxid = tid
- , txSignaturesWitnesses = ws
- }
-
--- | Construct ClosingSigned message.
-mkClosingSigned :: ChannelId -> Signature -> TlvStream -> ClosingSigned
-mkClosingSigned !cid !sig !tlvs = ClosingSigned
- { closingSignedChannelId = cid
- , closingSignedFeeSatoshi = Satoshi 1000
- , closingSignedSignature = sig
- , closingSignedTlvs = tlvs
- }
-
--- | Construct UpdateAddHtlc message.
-mkUpdateAddHtlc
- :: ChannelId -> PaymentHash -> OnionPacket -> TlvStream -> UpdateAddHtlc
-mkUpdateAddHtlc !cid !ph !onion !tlvs = UpdateAddHtlc
- { updateAddHtlcChannelId = cid
- , updateAddHtlcId = htlcId 0
- , updateAddHtlcAmountMsat = MilliSatoshi 10000000
- , updateAddHtlcPaymentHash = ph
- , updateAddHtlcCltvExpiry = 800000
- , updateAddHtlcOnionPacket = onion
- , updateAddHtlcTlvs = tlvs
- }
-
--- | Construct CommitmentSigned message.
-mkCommitmentSigned :: ChannelId -> Signature -> [Signature] -> CommitmentSigned
-mkCommitmentSigned !cid !sig !htlcSigs = CommitmentSigned
- { commitmentSignedChannelId = cid
- , commitmentSignedSignature = sig
- , commitmentSignedHtlcSignatures = htlcSigs
- }
-
--- Pre-constructed messages ----------------------------------------------------
-
--- | Test OpenChannel message.
-testOpenChannel :: OpenChannel
-testOpenChannel =
- mkOpenChannel testChainHash testChannelId testPoint emptyTlvs
-{-# NOINLINE testOpenChannel #-}
-
--- | Encoded OpenChannel for decode benchmarks.
-encodedOpenChannel :: BS.ByteString
-encodedOpenChannel = encodeOpenChannel testOpenChannel
-{-# NOINLINE encodedOpenChannel #-}
-
--- | Test OpenChannel2 message.
-testOpenChannel2 :: OpenChannel2
-testOpenChannel2 =
- mkOpenChannel2 testChainHash testChannelId testPoint emptyTlvs
-{-# NOINLINE testOpenChannel2 #-}
-
--- | Encoded OpenChannel2 for decode benchmarks.
-encodedOpenChannel2 :: BS.ByteString
-encodedOpenChannel2 = encodeOpenChannel2 testOpenChannel2
-{-# NOINLINE encodedOpenChannel2 #-}
-
--- | Test witness data.
-testWitness :: Witness
-testWitness = Witness (BS.replicate 107 0xab)
-{-# NOINLINE testWitness #-}
-
--- | Multiple witnesses for TxSignatures.
-testWitnesses :: [Witness]
-testWitnesses = replicate 5 testWitness
-{-# NOINLINE testWitnesses #-}
-
--- | Test TxSignatures message.
-testTxSignatures :: TxSignatures
-testTxSignatures = mkTxSignatures testChannelId testTxId testWitnesses
-{-# NOINLINE testTxSignatures #-}
-
--- | Encoded TxSignatures for decode benchmarks.
-encodedTxSignatures :: BS.ByteString
-encodedTxSignatures = case encodeTxSignatures testTxSignatures of
- Right bs -> bs
- Left e -> error $ "encodedTxSignatures: " ++ show e
-{-# NOINLINE encodedTxSignatures #-}
-
--- | Test ClosingSigned message.
-testClosingSigned :: ClosingSigned
-testClosingSigned = mkClosingSigned testChannelId testSignature emptyTlvs
-{-# NOINLINE testClosingSigned #-}
-
--- | Encoded ClosingSigned for decode benchmarks.
-encodedClosingSigned :: BS.ByteString
-encodedClosingSigned = encodeClosingSigned testClosingSigned
-{-# NOINLINE encodedClosingSigned #-}
-
--- | Test UpdateAddHtlc message.
-testUpdateAddHtlc :: UpdateAddHtlc
-testUpdateAddHtlc =
- mkUpdateAddHtlc testChannelId testPaymentHash testOnionPacket emptyTlvs
-{-# NOINLINE testUpdateAddHtlc #-}
-
--- | Encoded UpdateAddHtlc for decode benchmarks.
-encodedUpdateAddHtlc :: BS.ByteString
-encodedUpdateAddHtlc = encodeUpdateAddHtlc testUpdateAddHtlc
-{-# NOINLINE encodedUpdateAddHtlc #-}
-
--- | HTLC signatures for CommitmentSigned.
-testHtlcSigs :: [Signature]
-testHtlcSigs = replicate 10 testSignature
-{-# NOINLINE testHtlcSigs #-}
-
--- | Test CommitmentSigned message.
-testCommitmentSigned :: CommitmentSigned
-testCommitmentSigned =
- mkCommitmentSigned testChannelId testSignature testHtlcSigs
-{-# NOINLINE testCommitmentSigned #-}
-
--- | Encoded CommitmentSigned for decode benchmarks.
-encodedCommitmentSigned :: BS.ByteString
-encodedCommitmentSigned = case encodeCommitmentSigned testCommitmentSigned of
- Right bs -> bs
- Left e -> error $ "encodedCommitmentSigned: " ++ show e
-{-# NOINLINE encodedCommitmentSigned #-}
-
--- | Large HTLC signatures for CommitmentSigned (100).
-testHtlcSigsLarge :: [Signature]
-testHtlcSigsLarge = replicate 100 testSignature
-{-# NOINLINE testHtlcSigsLarge #-}
-
--- | Test CommitmentSigned message (100 sigs).
-testCommitmentSignedLarge :: CommitmentSigned
-testCommitmentSignedLarge =
- mkCommitmentSigned testChannelId testSignature testHtlcSigsLarge
-{-# NOINLINE testCommitmentSignedLarge #-}
-
--- | Encoded large CommitmentSigned for decode benchmarks.
-encodedCommitmentSignedLarge :: BS.ByteString
-encodedCommitmentSignedLarge =
- case encodeCommitmentSigned testCommitmentSignedLarge of
- Right bs -> bs
- Left e -> error $ "encodedCommitmentSignedLarge: " ++ show e
-{-# NOINLINE encodedCommitmentSignedLarge #-}
-
--- | Max HTLC signatures for CommitmentSigned (483).
-testHtlcSigsMax :: [Signature]
-testHtlcSigsMax = replicate 483 testSignature
-{-# NOINLINE testHtlcSigsMax #-}
-
--- | Test CommitmentSigned message (483 sigs).
-testCommitmentSignedMax :: CommitmentSigned
-testCommitmentSignedMax =
- mkCommitmentSigned testChannelId testSignature testHtlcSigsMax
-{-# NOINLINE testCommitmentSignedMax #-}
-
--- | Encoded max CommitmentSigned for decode benchmarks.
-encodedCommitmentSignedMax :: BS.ByteString
-encodedCommitmentSignedMax =
- case encodeCommitmentSigned testCommitmentSignedMax of
- Right bs -> bs
- Left e -> error $ "encodedCommitmentSignedMax: " ++ show e
-{-# NOINLINE encodedCommitmentSignedMax #-}
-
--- Weigh benchmarks ------------------------------------------------------------
-
main :: IO ()
-main = mainWith $ do
- -- V1 message construction and encoding
- wgroup "v1/open_channel" $ do
- func "construct" (mkOpenChannel testChainHash testChannelId testPoint)
- emptyTlvs
- func "encode" encodeOpenChannel testOpenChannel
- func "decode" decodeOpenChannel encodedOpenChannel
-
- -- V2 message construction and encoding
- wgroup "v2/open_channel2" $ do
- func "construct" (mkOpenChannel2 testChainHash testChannelId testPoint)
- emptyTlvs
- func "encode" encodeOpenChannel2 testOpenChannel2
- func "decode" decodeOpenChannel2 encodedOpenChannel2
-
- wgroup "v2/tx_signatures" $ do
- func "construct" (mkTxSignatures testChannelId testTxId) testWitnesses
- func "encode" (forceEncode . encodeTxSignatures) testTxSignatures
- func "decode" decodeTxSignatures encodedTxSignatures
-
- -- Close messages
- wgroup "close/closing_signed" $ do
- func "construct" (mkClosingSigned testChannelId testSignature) emptyTlvs
- func "encode" encodeClosingSigned testClosingSigned
- func "decode" decodeClosingSigned encodedClosingSigned
-
- -- Normal operation (hot paths)
- wgroup "normal/update_add_htlc" $ do
- func "construct"
- (mkUpdateAddHtlc testChannelId testPaymentHash testOnionPacket) emptyTlvs
- func "encode" encodeUpdateAddHtlc testUpdateAddHtlc
- func "decode" decodeUpdateAddHtlc encodedUpdateAddHtlc
-
- wgroup "normal/commitment_signed" $ do
- func "construct" (mkCommitmentSigned testChannelId testSignature)
- testHtlcSigs
- func "encode" (forceEncode . encodeCommitmentSigned) testCommitmentSigned
- func "decode" decodeCommitmentSigned encodedCommitmentSigned
-
- wgroup "normal/commitment_signed_100" $ do
- func "decode" decodeCommitmentSigned encodedCommitmentSignedLarge
-
- wgroup "normal/commitment_signed_483" $ do
- func "decode" decodeCommitmentSigned encodedCommitmentSignedMax
+main = case fixtures of
+ Nothing -> fail "invalid fixtures"
+ Just fx -> mainWith $ do
+ func "baseline (weigh overhead)" (+ (1 :: Int)) 1
+ wgroup "open_channel" $ do
+ func "encode" encode_open_channel (fx_open_channel fx)
+ func "decode" decode_open_channel (fx_open_channel_bytes fx)
+ wgroup "accept_channel2" $ do
+ func "encode" encode_accept_channel2 (fx_accept_channel2 fx)
+ func "decode" decode_accept_channel2 (fx_accept_channel2_bytes fx)
+ wgroup "tx_signatures" $ do
+ func "encode" encode_tx_signatures (fx_tx_signatures fx)
+ func "decode" decode_tx_signatures (fx_tx_signatures_bytes fx)
+ wgroup "closing_complete" $ do
+ func "encode" encode_closing_complete (fx_closing_complete fx)
+ func "decode" decode_closing_complete (fx_closing_complete_bytes fx)
+ wgroup "update_add_htlc" $ do
+ func "encode" encode_update_add_htlc (fx_update_add_htlc fx)
+ func "decode" decode_update_add_htlc (fx_update_add_htlc_bytes fx)
+ func "encode_message" encode_message
+ (MsgUpdateAddHtlc (fx_update_add_htlc fx))
+ func "decode_message" decode_message (fx_update_add_htlc_wire fx)
+ wgroup "update_fulfill_htlc" $ do
+ func "encode" encode_update_fulfill_htlc (fx_update_fulfill_htlc fx)
+ func "decode" decode_update_fulfill_htlc
+ (fx_update_fulfill_htlc_bytes fx)
+ wgroup "commitment_signed" $ do
+ func "encode (0 htlcs)" encode_commitment_signed
+ (fx_commitment_signed fx)
+ func "decode (0 htlcs)" decode_commitment_signed
+ (fx_commitment_signed_bytes fx)
+ func "encode (483 htlcs)" encode_commitment_signed
+ (fx_commitment_signed_483 fx)
+ func "decode (483 htlcs)" decode_commitment_signed
+ (fx_commitment_signed_483_bytes fx)
+ wgroup "revoke_and_ack" $ do
+ func "encode" encode_revoke_and_ack (fx_revoke_and_ack fx)
+ func "decode" decode_revoke_and_ack (fx_revoke_and_ack_bytes fx)
+ wgroup "channel_reestablish" $ do
+ func "encode" encode_channel_reestablish (fx_channel_reestablish fx)
+ func "decode" decode_channel_reestablish
+ (fx_channel_reestablish_bytes fx)