bolt3

Lightning transaction and script formats, per BOLT #3 (docs.ppad.tech/bolt3).
git clone git://git.ppad.tech/bolt3.git
Log | Files | Refs | README | LICENSE

commit b466c9ba5dde63ebce973c11a47b96836bb7a9a6
parent 616042bd8a482ae36d7dd8a4e6a616aa56eca0ac
Author: Jared Tobin <jared@jtobin.io>
Date:   Mon, 20 Apr 2026 15:15:29 +0800

add Internal module, hide constructors from public API

Create Lightning.Protocol.BOLT3.Internal with unsafe constructors
for test/benchmark use (unsafePubkey, unsafeSeckey,
unsafeCommitmentNumber, unsafeSequence, unsafeLocktime).

Hide constructors for validated types (Pubkey, Seckey, Point,
PaymentHash, PaymentPreimage, CommitmentNumber,
PerCommitmentPoint, PerCommitmentSecret) from the top-level
BOLT3 module, exposing only smart constructors and accessors.
Types.hs retains full constructor exports for internal lib use.

Update test and benchmark imports to use Types module for
constructor access.

Diffstat:
Mbench/Main.hs | 5+++++
Mbench/Weight.hs | 5+++++
Mlib/Lightning/Protocol/BOLT3.hs | 24++++++++++++++++--------
Alib/Lightning/Protocol/BOLT3/Internal.hs | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mlib/Lightning/Protocol/BOLT3/Types.hs | 11++++++++---
Mppad-bolt3.cabal | 1+
Mtest/Main.hs | 4++++
7 files changed, 95 insertions(+), 11 deletions(-)

diff --git a/bench/Main.hs b/bench/Main.hs @@ -8,6 +8,11 @@ import Criterion.Main import Data.Word (Word64) import qualified Data.ByteString as BS import Lightning.Protocol.BOLT3 +import Lightning.Protocol.BOLT3.Types + ( Pubkey(..), Point(..) + , PaymentHash(..), PerCommitmentPoint(..) + , CommitmentNumber(..) + ) -- NFData instances for benchmarking -- (Satoshi, MilliSatoshi, Point, PaymentHash, PerCommitmentSecret diff --git a/bench/Weight.hs b/bench/Weight.hs @@ -7,6 +7,11 @@ import Control.DeepSeq (NFData(..)) import qualified Data.ByteString as BS import Data.Word (Word32, Word64) import Lightning.Protocol.BOLT3 +import Lightning.Protocol.BOLT3.Types + ( Pubkey(..), Point(..) + , PaymentHash(..), PerCommitmentPoint(..) + , CommitmentNumber(..) + ) import Weigh -- NFData instances for weigh diff --git a/lib/Lightning/Protocol/BOLT3.hs b/lib/Lightning/Protocol/BOLT3.hs @@ -62,17 +62,22 @@ module Lightning.Protocol.BOLT3 ( , satToMsat -- ** Keys and points - , Pubkey(..) + , Pubkey + , unPubkey , pubkey - , Seckey(..) + , Seckey + , unSeckey , seckey - , Point(..) + , Point + , unPoint , point -- ** Hashes - , PaymentHash(..) + , PaymentHash + , unPaymentHash , paymentHash - , PaymentPreimage(..) + , PaymentPreimage + , unPaymentPreimage , paymentPreimage -- ** Transaction primitives @@ -83,7 +88,8 @@ module Lightning.Protocol.BOLT3 ( , Locktime(..) -- ** Channel parameters - , CommitmentNumber(..) + , CommitmentNumber + , unCommitmentNumber , commitment_number , next_commitment_number , ToSelfDelay(..) @@ -97,8 +103,10 @@ module Lightning.Protocol.BOLT3 ( -- ** Basepoints , Basepoints(..) - , PerCommitmentPoint(..) - , PerCommitmentSecret(..) + , PerCommitmentPoint + , unPerCommitmentPoint + , PerCommitmentSecret + , unPerCommitmentSecret , perCommitmentSecret , RevocationBasepoint(..) , PaymentBasepoint(..) diff --git a/lib/Lightning/Protocol/BOLT3/Internal.hs b/lib/Lightning/Protocol/BOLT3/Internal.hs @@ -0,0 +1,56 @@ +{-# OPTIONS_HADDOCK hide #-} + +-- | +-- Module: Lightning.Protocol.BOLT3.Internal +-- Copyright: (c) 2025 Jared Tobin +-- License: MIT +-- Maintainer: Jared Tobin <jared@ppad.tech> +-- +-- Internal definitions for BOLT #3. +-- +-- This module exports unsafe constructors that bypass +-- validation. Use only in tests or trusted internal code. + +module Lightning.Protocol.BOLT3.Internal ( + -- * Unsafe constructors (bypass validation) + unsafePubkey + , unsafeSeckey + , unsafeCommitmentNumber + , unsafeSequence + , unsafeLocktime + ) where + +import qualified Data.ByteString as BS +import Data.Word (Word32, Word64) +import Lightning.Protocol.BOLT3.Types + +-- | Construct a 'Pubkey' without length validation. +-- +-- For test use only. +unsafePubkey :: BS.ByteString -> Pubkey +unsafePubkey = Pubkey + +-- | Construct a 'Seckey' without length validation. +-- +-- For test use only. +unsafeSeckey :: BS.ByteString -> Seckey +unsafeSeckey = Seckey + +-- | Construct a 'CommitmentNumber' without range +-- validation. +-- +-- For test use only. +unsafeCommitmentNumber :: Word64 -> CommitmentNumber +unsafeCommitmentNumber = CommitmentNumber + +-- | Construct a 'Sequence' directly. +-- +-- For test use only. +unsafeSequence :: Word32 -> Sequence +unsafeSequence = Sequence + +-- | Construct a 'Locktime' directly. +-- +-- For test use only. +unsafeLocktime :: Word32 -> Locktime +unsafeLocktime = Locktime diff --git a/lib/Lightning/Protocol/BOLT3/Types.hs b/lib/Lightning/Protocol/BOLT3/Types.hs @@ -24,12 +24,15 @@ module Lightning.Protocol.BOLT3.Types ( , seckey , Point(..) , point + , unPoint -- * Hashes (re-exported from BOLT1) , PaymentHash(..) , paymentHash + , unPaymentHash , PaymentPreimage(..) , paymentPreimage + , unPaymentPreimage -- * Transaction primitives , TxId(..) @@ -56,6 +59,7 @@ module Lightning.Protocol.BOLT3.Types ( , PerCommitmentPoint(..) , PerCommitmentSecret(..) , perCommitmentSecret + , unPerCommitmentSecret , RevocationBasepoint(..) , PaymentBasepoint(..) , DelayedPaymentBasepoint(..) @@ -105,10 +109,11 @@ import GHC.Generics (Generic) import Lightning.Protocol.BOLT1.Prim ( Satoshi(..), MilliSatoshi(..) , satToMsat, msatToSat - , Point(..), point - , PaymentHash(..), paymentHash - , PaymentPreimage(..), paymentPreimage + , Point(..), point, unPoint + , PaymentHash(..), paymentHash, unPaymentHash + , PaymentPreimage(..), paymentPreimage, unPaymentPreimage , PerCommitmentSecret(..), perCommitmentSecret + , unPerCommitmentSecret ) -- keys and points ------------------------------------------------------------- diff --git a/ppad-bolt3.cabal b/ppad-bolt3.cabal @@ -27,6 +27,7 @@ library Lightning.Protocol.BOLT3 Lightning.Protocol.BOLT3.Decode Lightning.Protocol.BOLT3.Encode + Lightning.Protocol.BOLT3.Internal Lightning.Protocol.BOLT3.Keys Lightning.Protocol.BOLT3.Scripts Lightning.Protocol.BOLT3.Tx diff --git a/test/Main.hs b/test/Main.hs @@ -8,6 +8,10 @@ import Data.Maybe (isJust, isNothing) import Test.Tasty import Test.Tasty.HUnit import Lightning.Protocol.BOLT3 +import Lightning.Protocol.BOLT3.Types + ( Pubkey(..), Point(..) + , PaymentHash(..), PerCommitmentPoint(..) + ) main :: IO () main = defaultMain $ testGroup "ppad-bolt3" [