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 616042bd8a482ae36d7dd8a4e6a616aa56eca0ac
parent 4150228692ae69ce08a07b3a2403888da8bcce20
Author: Jared Tobin <jared@jtobin.io>
Date:   Mon, 20 Apr 2026 15:11:58 +0800

types: drop Num from newtypes, add next_commitment_number

Remove derived Num instances from CommitmentNumber, Sequence,
Locktime, ToSelfDelay, CltvExpiry, and FeeratePerKw. These types
represent domain-specific values where arithmetic operations like
multiplication are nonsensical and could mask bugs.

Add next_commitment_number as the only meaningful arithmetic
operation for commitment numbers: a checked increment that
respects the 48-bit range invariant.

Diffstat:
Mlib/Lightning/Protocol/BOLT3.hs | 1+
Mlib/Lightning/Protocol/BOLT3/Types.hs | 29++++++++++++++++++++++-------
2 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/lib/Lightning/Protocol/BOLT3.hs b/lib/Lightning/Protocol/BOLT3.hs @@ -85,6 +85,7 @@ module Lightning.Protocol.BOLT3 ( -- ** Channel parameters , CommitmentNumber(..) , commitment_number + , next_commitment_number , ToSelfDelay(..) , CltvExpiry(..) , DustLimit(..) diff --git a/lib/Lightning/Protocol/BOLT3/Types.hs b/lib/Lightning/Protocol/BOLT3/Types.hs @@ -1,7 +1,6 @@ {-# OPTIONS_HADDOCK prune #-} {-# LANGUAGE BangPatterns #-} {-# LANGUAGE DeriveGeneric #-} -{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | -- Module: Lightning.Protocol.BOLT3.Types @@ -42,6 +41,7 @@ module Lightning.Protocol.BOLT3.Types ( -- * Channel parameters , CommitmentNumber(..) , commitment_number + , next_commitment_number , ToSelfDelay(..) , CltvExpiry(..) , DustLimit(..) @@ -152,18 +152,18 @@ seckey bs -- | Transaction input sequence number. newtype Sequence = Sequence { unSequence :: Word32 } - deriving (Eq, Ord, Show, Generic, Num) + deriving (Eq, Ord, Show, Generic) -- | Transaction locktime. newtype Locktime = Locktime { unLocktime :: Word32 } - deriving (Eq, Ord, Show, Generic, Num) + deriving (Eq, Ord, Show, Generic) -- channel parameters ---------------------------------------------------------- -- | 48-bit commitment number. newtype CommitmentNumber = CommitmentNumber { unCommitmentNumber :: Word64 } - deriving (Eq, Ord, Show, Generic, Num) + deriving (Eq, Ord, Show, Generic) -- | Parse a 48-bit commitment number. -- @@ -174,13 +174,28 @@ commitment_number n | otherwise = Nothing {-# INLINE commitment_number #-} +-- | Increment a commitment number by one. +-- +-- Returns Nothing if the result would exceed 2^48 - 1. +-- +-- >>> fmap next_commitment_number (commitment_number 0) +-- Just (Just (CommitmentNumber {unCommitmentNumber = 1})) +-- >>> fmap next_commitment_number (commitment_number 281474976710655) +-- Just Nothing +next_commitment_number + :: CommitmentNumber -> Maybe CommitmentNumber +next_commitment_number (CommitmentNumber n) + | n < 281474976710655 = Just (CommitmentNumber (n + 1)) + | otherwise = Nothing +{-# INLINE next_commitment_number #-} + -- | CSV delay for to_local outputs. newtype ToSelfDelay = ToSelfDelay { unToSelfDelay :: Word16 } - deriving (Eq, Ord, Show, Generic, Num) + deriving (Eq, Ord, Show, Generic) -- | CLTV expiry for HTLCs. newtype CltvExpiry = CltvExpiry { unCltvExpiry :: Word32 } - deriving (Eq, Ord, Show, Generic, Num) + deriving (Eq, Ord, Show, Generic) -- | Dust limit threshold. newtype DustLimit = DustLimit { unDustLimit :: Satoshi } @@ -188,7 +203,7 @@ newtype DustLimit = DustLimit { unDustLimit :: Satoshi } -- | Fee rate in satoshis per 1000 weight units. newtype FeeratePerKw = FeeratePerKw { unFeeratePerKw :: Word32 } - deriving (Eq, Ord, Show, Generic, Num) + deriving (Eq, Ord, Show, Generic) -- HTLC types ------------------------------------------------------------------