Types.hs (11505B)
1 {-# OPTIONS_HADDOCK hide #-} 2 {-# LANGUAGE BangPatterns #-} 3 {-# LANGUAGE DeriveGeneric #-} 4 5 -- | 6 -- Module: Lightning.Protocol.BOLT3.Types 7 -- Copyright: (c) 2025 Jared Tobin 8 -- License: MIT 9 -- Maintainer: Jared Tobin <jared@ppad.tech> 10 -- 11 -- Types for BOLT #3 transaction and script formats. 12 13 module Lightning.Protocol.BOLT3.Types ( 14 -- * Points and keys 15 PerCommitmentPoint(..) 16 , RevocationBasepoint(..) 17 , PaymentBasepoint(..) 18 , DelayedPaymentBasepoint(..) 19 , HtlcBasepoint(..) 20 , Basepoints(..) 21 , RevocationPubkey(..) 22 , LocalDelayedPubkey(..) 23 , LocalHtlcPubkey(..) 24 , RemoteHtlcPubkey(..) 25 , RemotePubkey(..) 26 , FundingPubkey(..) 27 , Seckey(..) 28 , seckey 29 , un_seckey 30 31 -- * Per-commitment secrets 32 , Seed(..) 33 , seed 34 , un_seed 35 , SecretIndex(..) 36 , secret_index 37 , un_secret_index 38 , commitment_secret_index 39 40 -- * Channel parameters 41 , CommitmentNumber(..) 42 , commitment_number 43 , un_commitment_number 44 , next_commitment_number 45 , ToSelfDelay(..) 46 , CltvExpiry(..) 47 , DustLimit(..) 48 , FeeratePerKw(..) 49 , Locktime(..) 50 , Sequence(..) 51 , CommitmentFormat(..) 52 53 -- * HTLCs 54 , HTLC(..) 55 , HTLCDirection(..) 56 57 -- * Scripts 58 , Script(..) 59 60 -- * Dust thresholds 61 , dust_p2pkh 62 , dust_p2sh 63 , dust_p2wpkh 64 , dust_p2wsh 65 , anchor_output_value 66 67 -- * Internal 68 , sat 69 , internal_error 70 ) where 71 72 import Control.DeepSeq (NFData(..)) 73 import qualified Crypto.Curve.Secp256k1 as S 74 import qualified Data.ByteString as BS 75 import Data.Word (Word16, Word32, Word64) 76 import GHC.Generics (Generic) 77 import Lightning.Protocol.BOLT1 (Point, Satoshi, MilliSatoshi, PaymentHash) 78 import qualified Lightning.Protocol.BOLT1 as BOLT1 79 80 -- internal ------------------------------------------------------------------ 81 82 -- Abort on a state that the surrounding code rules out. 83 internal_error :: a 84 internal_error = error "ppad-bolt3: internal error, please report a bug!" 85 {-# NOINLINE internal_error #-} 86 87 -- A 'Satoshi' amount known to be at most 21 million BTC (a constant, 88 -- or a value bounded by construction). 89 sat :: Word64 -> Satoshi 90 sat w = case BOLT1.satoshi w of 91 Just s -> s 92 Nothing -> internal_error 93 {-# INLINE sat #-} 94 95 -- points and keys ------------------------------------------------------------ 96 97 -- | A per-commitment point, from which a commitment's keys are 98 -- derived. 99 newtype PerCommitmentPoint = PerCommitmentPoint Point 100 deriving (Eq, Ord, Show, Generic) 101 102 instance NFData PerCommitmentPoint 103 104 -- | A @revocation_basepoint@. 105 newtype RevocationBasepoint = RevocationBasepoint Point 106 deriving (Eq, Ord, Show, Generic) 107 108 instance NFData RevocationBasepoint 109 110 -- | A @payment_basepoint@. 111 newtype PaymentBasepoint = PaymentBasepoint Point 112 deriving (Eq, Ord, Show, Generic) 113 114 instance NFData PaymentBasepoint 115 116 -- | A @delayed_payment_basepoint@. 117 newtype DelayedPaymentBasepoint = DelayedPaymentBasepoint Point 118 deriving (Eq, Ord, Show, Generic) 119 120 instance NFData DelayedPaymentBasepoint 121 122 -- | An @htlc_basepoint@. 123 newtype HtlcBasepoint = HtlcBasepoint Point 124 deriving (Eq, Ord, Show, Generic) 125 126 instance NFData HtlcBasepoint 127 128 -- | The four basepoints a party announces in @open_channel@ or 129 -- @accept_channel@. 130 data Basepoints = Basepoints 131 { bp_revocation :: !RevocationBasepoint 132 , bp_payment :: !PaymentBasepoint 133 , bp_delayed_payment :: !DelayedPaymentBasepoint 134 , bp_htlc :: !HtlcBasepoint 135 } deriving (Eq, Show, Generic) 136 137 instance NFData Basepoints 138 139 -- | A commitment's @revocationpubkey@. 140 newtype RevocationPubkey = RevocationPubkey Point 141 deriving (Eq, Ord, Show, Generic) 142 143 instance NFData RevocationPubkey 144 145 -- | A commitment's @local_delayedpubkey@: the owner's key for its 146 -- delayed outputs. 147 newtype LocalDelayedPubkey = LocalDelayedPubkey Point 148 deriving (Eq, Ord, Show, Generic) 149 150 instance NFData LocalDelayedPubkey 151 152 -- | A commitment's @local_htlcpubkey@: the owner's HTLC key. 153 newtype LocalHtlcPubkey = LocalHtlcPubkey Point 154 deriving (Eq, Ord, Show, Generic) 155 156 instance NFData LocalHtlcPubkey 157 158 -- | A commitment's @remote_htlcpubkey@: the other party's HTLC key. 159 newtype RemoteHtlcPubkey = RemoteHtlcPubkey Point 160 deriving (Eq, Ord, Show, Generic) 161 162 instance NFData RemoteHtlcPubkey 163 164 -- | A commitment's @remotepubkey@: the other party's 165 -- @payment_basepoint@, which its @to_remote@ output pays. 166 newtype RemotePubkey = RemotePubkey Point 167 deriving (Eq, Ord, Show, Generic) 168 169 instance NFData RemotePubkey 170 171 -- | A @funding_pubkey@. 172 newtype FundingPubkey = FundingPubkey Point 173 deriving (Eq, Ord, Show, Generic) 174 175 instance NFData FundingPubkey 176 177 -- | A secp256k1 secret key: 32 bytes encoding an integer in 178 -- [1, n), for n the group order. 179 -- 180 -- This is secret material: its 'Show' instance is redacted, and it 181 -- has no 'Eq' instance. 182 newtype Seckey = Seckey BS.ByteString 183 184 instance Show Seckey where 185 showsPrec d _ = showParen (d > 10) $ showString "Seckey <redacted>" 186 187 instance NFData Seckey where 188 rnf (Seckey bs) = rnf bs 189 190 -- | Construct a 'Seckey' from 32 big-endian bytes. Fails unless the 191 -- bytes encode an integer in [1, n). 192 -- 193 -- >>> fmap (BS.length . un_seckey) (seckey (BS.replicate 32 0x01)) 194 -- Just 32 195 -- >>> seckey (BS.replicate 32 0x00) 196 -- Nothing 197 -- >>> seckey (BS.replicate 32 0xff) 198 -- Nothing 199 seckey :: BS.ByteString -> Maybe Seckey 200 seckey bs = do 201 w <- S.parse_int256 bs 202 if S.ge w 203 then Just (Seckey bs) 204 else Nothing 205 206 -- | The bytes of a 'Seckey'. 207 un_seckey :: Seckey -> BS.ByteString 208 un_seckey (Seckey bs) = bs 209 {-# INLINE un_seckey #-} 210 211 -- per-commitment secrets ----------------------------------------------------- 212 213 -- | The 32-byte seed from which a party generates its per-commitment 214 -- secrets. 215 -- 216 -- This is secret material: its 'Show' instance is redacted, and it 217 -- has no 'Eq' instance. 218 newtype Seed = Seed BS.ByteString 219 220 instance Show Seed where 221 showsPrec d _ = showParen (d > 10) $ showString "Seed <redacted>" 222 223 instance NFData Seed where 224 rnf (Seed bs) = rnf bs 225 226 -- | Construct a 'Seed' from exactly 32 bytes. 227 -- 228 -- >>> fmap (BS.length . un_seed) (seed (BS.replicate 32 0xff)) 229 -- Just 32 230 -- >>> seed (BS.replicate 31 0xff) 231 -- Nothing 232 seed :: BS.ByteString -> Maybe Seed 233 seed bs 234 | BS.length bs == 32 = Just (Seed bs) 235 | otherwise = Nothing 236 {-# INLINE seed #-} 237 238 -- | The bytes of a 'Seed'. 239 un_seed :: Seed -> BS.ByteString 240 un_seed (Seed bs) = bs 241 {-# INLINE un_seed #-} 242 243 -- | The 48-bit index /I/ of a per-commitment secret. Secrets are 244 -- used from index 2^48 - 1 downwards. 245 newtype SecretIndex = SecretIndex Word64 246 deriving (Eq, Ord, Show, Generic) 247 248 instance NFData SecretIndex 249 250 -- | Construct a 'SecretIndex'. Fails at or above 2^48. 251 -- 252 -- >>> secret_index 281474976710655 253 -- Just (SecretIndex 281474976710655) 254 -- >>> secret_index 281474976710656 255 -- Nothing 256 secret_index :: Word64 -> Maybe SecretIndex 257 secret_index w 258 | w <= 0xFFFFFFFFFFFF = Just (SecretIndex w) 259 | otherwise = Nothing 260 {-# INLINE secret_index #-} 261 262 -- | The value of a 'SecretIndex'. 263 un_secret_index :: SecretIndex -> Word64 264 un_secret_index (SecretIndex w) = w 265 {-# INLINE un_secret_index #-} 266 267 -- | The index of the per-commitment secret for a commitment number: 268 -- 2^48 - 1 - n. 269 -- 270 -- >>> fmap commitment_secret_index (commitment_number 0) 271 -- Just (SecretIndex 281474976710655) 272 commitment_secret_index :: CommitmentNumber -> SecretIndex 273 commitment_secret_index (CommitmentNumber n) = SecretIndex (0xFFFFFFFFFFFF - n) 274 {-# INLINE commitment_secret_index #-} 275 276 -- channel parameters --------------------------------------------------------- 277 278 -- | A 48-bit commitment number. 279 newtype CommitmentNumber = CommitmentNumber Word64 280 deriving (Eq, Ord, Show, Generic) 281 282 instance NFData CommitmentNumber 283 284 -- | Construct a 'CommitmentNumber'. Fails at or above 2^48. 285 -- 286 -- >>> commitment_number 42 287 -- Just (CommitmentNumber 42) 288 -- >>> commitment_number 281474976710656 289 -- Nothing 290 commitment_number :: Word64 -> Maybe CommitmentNumber 291 commitment_number n 292 | n <= 0xFFFFFFFFFFFF = Just (CommitmentNumber n) 293 | otherwise = Nothing 294 {-# INLINE commitment_number #-} 295 296 -- | The value of a 'CommitmentNumber'. 297 un_commitment_number :: CommitmentNumber -> Word64 298 un_commitment_number (CommitmentNumber n) = n 299 {-# INLINE un_commitment_number #-} 300 301 -- | The next commitment number. Fails past 2^48 - 1. 302 -- 303 -- >>> commitment_number 0 >>= next_commitment_number 304 -- Just (CommitmentNumber 1) 305 -- >>> commitment_number 281474976710655 >>= next_commitment_number 306 -- Nothing 307 next_commitment_number :: CommitmentNumber -> Maybe CommitmentNumber 308 next_commitment_number (CommitmentNumber n) 309 | n < 0xFFFFFFFFFFFF = Just (CommitmentNumber (n + 1)) 310 | otherwise = Nothing 311 {-# INLINE next_commitment_number #-} 312 313 -- | The CSV delay (@to_self_delay@) on a commitment owner's outputs. 314 newtype ToSelfDelay = ToSelfDelay Word16 315 deriving (Eq, Ord, Show, Generic) 316 317 instance NFData ToSelfDelay 318 319 -- | An HTLC's absolute CLTV expiry. 320 newtype CltvExpiry = CltvExpiry Word32 321 deriving (Eq, Ord, Show, Generic) 322 323 instance NFData CltvExpiry 324 325 -- | A @dust_limit_satoshis@ threshold. 326 newtype DustLimit = DustLimit Satoshi 327 deriving (Eq, Ord, Show, Generic) 328 329 instance NFData DustLimit 330 331 -- | A fee rate, in satoshis per 1000 weight units. 332 newtype FeeratePerKw = FeeratePerKw Word32 333 deriving (Eq, Ord, Show, Generic) 334 335 instance NFData FeeratePerKw 336 337 -- | A transaction locktime. 338 newtype Locktime = Locktime Word32 339 deriving (Eq, Ord, Show, Generic) 340 341 instance NFData Locktime 342 343 -- | A transaction input's sequence number. 344 newtype Sequence = Sequence Word32 345 deriving (Eq, Ord, Show, Generic) 346 347 instance NFData Sequence 348 349 -- | The commitment format a channel uses, as fixed by its 350 -- @channel_type@. 351 data CommitmentFormat 352 = StaticRemotekey 353 -- ^ @option_static_remotekey@ without anchors: @to_remote@ is 354 -- P2WPKH and HTLC transactions pay their own fees. 355 | Anchors 356 -- ^ @option_anchors@: two anchor outputs, a CSV-locked 357 -- @to_remote@, and zero-fee HTLC transactions. 358 deriving (Eq, Ord, Show, Generic) 359 360 instance NFData CommitmentFormat 361 362 -- HTLCs ---------------------------------------------------------------------- 363 364 -- | The direction of an HTLC, from the commitment owner's point of 365 -- view. 366 data HTLCDirection 367 = HTLCOffered -- ^ offered by the owner 368 | HTLCReceived -- ^ received by the owner 369 deriving (Eq, Ord, Show, Generic) 370 371 instance NFData HTLCDirection 372 373 -- | An HTLC committed to a commitment transaction. 374 data HTLC = HTLC 375 { htlc_direction :: !HTLCDirection 376 , htlc_amount_msat :: {-# UNPACK #-} !MilliSatoshi 377 , htlc_payment_hash :: !PaymentHash 378 , htlc_cltv_expiry :: {-# UNPACK #-} !CltvExpiry 379 } deriving (Eq, Show, Generic) 380 381 instance NFData HTLC 382 383 -- scripts -------------------------------------------------------------------- 384 385 -- | A serialized Bitcoin script. 386 newtype Script = Script BS.ByteString 387 deriving (Eq, Ord, Show, Generic) 388 389 instance NFData Script 390 391 -- dust thresholds ------------------------------------------------------------ 392 393 -- | Bitcoin Core's P2PKH dust threshold (546 satoshis). 394 dust_p2pkh :: Satoshi 395 dust_p2pkh = sat 546 396 397 -- | Bitcoin Core's P2SH dust threshold (540 satoshis). 398 dust_p2sh :: Satoshi 399 dust_p2sh = sat 540 400 401 -- | Bitcoin Core's P2WPKH dust threshold (294 satoshis). 402 dust_p2wpkh :: Satoshi 403 dust_p2wpkh = sat 294 404 405 -- | Bitcoin Core's P2WSH dust threshold (330 satoshis). 406 dust_p2wsh :: Satoshi 407 dust_p2wsh = sat 330 408 409 -- | The value of each anchor output (330 satoshis). 410 anchor_output_value :: Satoshi 411 anchor_output_value = sat 330