commit 5931fdd136928ba8eb85af4a5a71579dc0a62189
parent 34f0b8ed00992cbad48bf244d0cc1a799feeb3cf
Author: Jared Tobin <jared@jtobin.io>
Date: Sun, 25 Jan 2026 16:06:44 +0400
Merge impl/bench: criterion and weigh benchmarks
Adds benchmarks for:
- Parsing (typical, empty, large vectors)
- Rendering
- Bit operations (setBit, testBit, hasFeature)
- Validation (local and remote)
- Feature lookups
Plus allocation tracking via weigh.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat:
4 files changed, 109 insertions(+), 3 deletions(-)
diff --git a/bench/Fixtures.hs b/bench/Fixtures.hs
@@ -0,0 +1,57 @@
+module Fixtures (
+ -- * ByteString fixtures
+ typicalBytes
+ , emptyBytes
+ , largeBytes
+
+ -- * FeatureVector fixtures
+ , typicalFV
+ , emptyFV
+ , validFV
+ , unknownBitsFV
+ ) where
+
+import Data.ByteString (ByteString)
+import qualified Data.ByteString as BS
+import qualified Lightning.Protocol.BOLT9 as B9
+
+-- ByteString fixtures --------------------------------------------------------
+
+-- | A typical 8-byte feature vector with several common features set:
+-- basic_mpp (bit 17), option_anchors (bit 23), option_route_blinding (bit 25)
+typicalBytes :: ByteString
+typicalBytes = BS.pack [0x02, 0x82, 0x00, 0x00]
+
+-- | Empty ByteString for parsing.
+emptyBytes :: ByteString
+emptyBytes = BS.empty
+
+-- | Large 64-byte feature vector for stress testing.
+largeBytes :: ByteString
+largeBytes = BS.pack $ replicate 64 0xAA
+
+-- FeatureVector fixtures -----------------------------------------------------
+
+-- | A typical feature vector with common features set (optional bits):
+-- basic_mpp (17), option_anchors (23), option_route_blinding (25)
+typicalFV :: B9.FeatureVector
+typicalFV = B9.parse typicalBytes
+
+-- | Empty feature vector.
+emptyFV :: B9.FeatureVector
+emptyFV = B9.empty
+
+-- | A valid feature vector for validation benchmarks.
+-- Sets payment_secret (required for basic_mpp dependency) and basic_mpp.
+validFV :: B9.FeatureVector
+validFV = B9.setBit 15 -- payment_secret (optional)
+ $ B9.setBit 17 -- basic_mpp (optional)
+ $ B9.setBit 23 -- option_anchors (optional)
+ $ B9.empty
+
+-- | A feature vector with unknown bits for remote validation.
+-- Contains a known feature plus an unknown odd bit (safe to ignore).
+unknownBitsFV :: B9.FeatureVector
+unknownBitsFV = B9.setBit 15 -- payment_secret (optional, known)
+ $ B9.setBit 99 -- unknown odd bit (should be ignored)
+ $ B9.empty
diff --git a/bench/Main.hs b/bench/Main.hs
@@ -1,8 +1,42 @@
module Main where
import Criterion.Main
+import Data.Maybe (fromJust)
+import qualified Lightning.Protocol.BOLT9 as B9
+import Fixtures
+
+basic_mpp :: B9.Feature
+basic_mpp = fromJust (B9.featureByName "basic_mpp")
main :: IO ()
main = defaultMain [
- -- TODO
+ bgroup "parse" [
+ bench "typical (8 bytes)" $ nf B9.parse typicalBytes
+ , bench "empty" $ nf B9.parse emptyBytes
+ , bench "large (64 bytes)" $ nf B9.parse largeBytes
+ ]
+
+ , bgroup "render" [
+ bench "typical" $ nf B9.render typicalFV
+ , bench "empty" $ nf B9.render emptyFV
+ ]
+
+ , bgroup "bit-ops" [
+ bench "setBit" $ nf (B9.setBit 50) typicalFV
+ , bench "testBit" $ nf (B9.testBit 17) typicalFV
+ , bench "hasFeature" $
+ nf (flip B9.hasFeature typicalFV) basic_mpp
+ ]
+
+ , bgroup "validate" [
+ bench "validateLocal (valid)" $
+ nf (B9.validateLocal B9.Init) validFV
+ , bench "validateRemote (unknown bits)" $
+ nf (B9.validateRemote B9.Init) unknownBitsFV
+ ]
+
+ , bgroup "lookup" [
+ bench "featureByBit" $ nf B9.featureByBit 16
+ , bench "featureByName" $ nf B9.featureByName "basic_mpp"
+ ]
]
diff --git a/bench/Weight.hs b/bench/Weight.hs
@@ -1,8 +1,21 @@
module Main where
import Weigh
+import qualified Lightning.Protocol.BOLT9 as B9
+import Fixtures
main :: IO ()
main = mainWith $ do
- pure ()
- -- TODO
+ func "FeatureVector (5 features)" mkFiveFeatures ()
+ func "validateLocal" (B9.validateLocal B9.Init) validFV
+ func "listFeatures" B9.listFeatures validFV
+
+-- | Create a FeatureVector with 5 features set.
+mkFiveFeatures :: () -> B9.FeatureVector
+mkFiveFeatures _ =
+ B9.setBit 15 -- payment_secret
+ $ B9.setBit 17 -- basic_mpp
+ $ B9.setBit 23 -- option_anchors
+ $ B9.setBit 25 -- option_route_blinding
+ $ B9.setBit 27 -- option_shutdown_anysegwit
+ $ B9.empty
diff --git a/ppad-bolt9.cabal b/ppad-bolt9.cabal
@@ -56,6 +56,7 @@ benchmark bolt9-bench
default-language: Haskell2010
hs-source-dirs: bench
main-is: Main.hs
+ other-modules: Fixtures
ghc-options:
-rtsopts -O2 -Wall -fno-warn-orphans
@@ -72,6 +73,7 @@ benchmark bolt9-weigh
default-language: Haskell2010
hs-source-dirs: bench
main-is: Weight.hs
+ other-modules: Fixtures
ghc-options:
-rtsopts -O2 -Wall -fno-warn-orphans