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