Types.hs (8759B)
1 {-# OPTIONS_HADDOCK prune #-} 2 {-# LANGUAGE BangPatterns #-} 3 {-# LANGUAGE DeriveGeneric #-} 4 5 -- | 6 -- Module: Lightning.Protocol.BOLT5.Types 7 -- Copyright: (c) 2025 Jared Tobin 8 -- License: MIT 9 -- Maintainer: Jared Tobin <jared@ppad.tech> 10 -- 11 -- Types for BOLT #5 on-chain transaction handling. 12 13 module Lightning.Protocol.BOLT5.Types ( 14 -- * Close identification 15 CloseType(..) 16 17 -- * Output classification 18 , UnresolvedOutput(..) 19 , OutputResolution(..) 20 21 -- * HTLC output type 22 , HTLCOutputType(..) 23 , htlcOutputType 24 , htlcOutputTypeWeight 25 26 -- * Spending transactions 27 , SpendingTx(..) 28 29 -- * Penalty batching 30 , RevokedOutput(..) 31 , RevokedOutputType(..) 32 , PenaltyContext(..) 33 , revoked_output_weight 34 35 -- * Weight constants (Appendix A) 36 , to_local_penalty_witness_weight 37 , offered_htlc_penalty_witness_weight 38 , accepted_htlc_penalty_witness_weight 39 , to_local_penalty_input_weight 40 , offered_htlc_penalty_input_weight 41 , accepted_htlc_penalty_input_weight 42 , to_remote_input_weight 43 , penalty_tx_base_weight 44 , max_standard_weight 45 46 -- * Fee calculation 47 , spending_fee 48 ) where 49 50 import Bitcoin.Prim.Tx (Tx(..)) 51 import Bitcoin.Prim.Tx.Sighash (SighashType(..)) 52 import Data.List.NonEmpty (NonEmpty) 53 import Data.Word (Word64) 54 import GHC.Generics (Generic) 55 import Lightning.Protocol.BOLT3.Types 56 import Lightning.Protocol.BOLT3.Tx ( 57 CommitmentKeys(..) 58 , OutputType(..) 59 ) 60 61 -- close identification ----------------------------------------------- 62 63 -- | What kind of close was detected on chain. 64 data CloseType 65 = MutualClose 66 -- ^ Cooperative closure agreed by both parties. 67 | LocalCommitClose 68 -- ^ Our commitment transaction was broadcast. 69 | RemoteCommitClose 70 -- ^ The remote party's commitment transaction was broadcast. 71 | RevokedCommitClose 72 -- ^ A revoked (outdated) commitment transaction was broadcast. 73 deriving (Eq, Show, Generic) 74 75 -- output classification ---------------------------------------------- 76 77 -- | An unresolved commitment transaction output. 78 data UnresolvedOutput = UnresolvedOutput 79 { uo_outpoint :: !OutPoint 80 , uo_value :: {-# UNPACK #-} !Satoshi 81 , uo_type :: !OutputResolution 82 } deriving (Eq, Show, Generic) 83 84 -- | How to resolve an output, per BOLT #5 rules. 85 data OutputResolution 86 = Resolved 87 -- ^ Already resolved (e.g. to_remote on local commit). 88 | SpendToLocal 89 !ToSelfDelay !RevocationPubkey !LocalDelayedPubkey 90 -- ^ Spend to_local after CSV delay. 91 | SpendHTLCTimeout 92 !HTLC !CommitmentKeys !ChannelFeatures 93 -- ^ Spend via HTLC-timeout second-stage tx (local commit, 94 -- local offer). 95 | SpendHTLCSuccess 96 !HTLC !CommitmentKeys !ChannelFeatures 97 -- ^ Spend via HTLC-success second-stage tx (local commit, 98 -- remote offer). 99 | SpendHTLCTimeoutDirect !HTLC 100 -- ^ Spend HTLC directly after timeout (remote commit, 101 -- local offer). 102 | SpendHTLCPreimageDirect !HTLC 103 -- ^ Spend HTLC directly with preimage (remote commit, 104 -- remote offer). 105 | Revoke !RevocationPubkey 106 -- ^ Spend revoked to_local with revocation key. 107 | RevokeHTLC !RevocationPubkey !HTLCOutputType 108 -- ^ Spend revoked HTLC output with revocation key. 109 | AnchorSpend !FundingPubkey 110 -- ^ Spend anchor output. 111 deriving (Eq, Show, Generic) 112 113 -- HTLC output type ------------------------------------------------- 114 115 -- | Type of HTLC output, restricted to only HTLC variants. 116 -- 117 -- Unlike bolt3's 'OutputType' which includes all six output 118 -- types, this ADT makes it impossible to confuse HTLC outputs 119 -- with to_local, to_remote, or anchor outputs. 120 data HTLCOutputType 121 = HTLCOfferedOutput {-# UNPACK #-} !CltvExpiry 122 -- ^ Offered HTLC output with CLTV expiry. 123 | HTLCReceivedOutput {-# UNPACK #-} !CltvExpiry 124 -- ^ Received HTLC output with CLTV expiry. 125 deriving (Eq, Show, Generic) 126 127 -- | Extract an 'HTLCOutputType' from a bolt3 'OutputType'. 128 -- 129 -- Returns 'Nothing' for non-HTLC output types. 130 -- 131 -- >>> htlcOutputType (OutputOfferedHTLC (CltvExpiry 500)) 132 -- Just (HTLCOfferedOutput (CltvExpiry ...)) 133 -- >>> htlcOutputType OutputToLocal 134 -- Nothing 135 htlcOutputType :: OutputType -> Maybe HTLCOutputType 136 htlcOutputType (OutputOfferedHTLC e) = 137 Just (HTLCOfferedOutput e) 138 htlcOutputType (OutputReceivedHTLC e) = 139 Just (HTLCReceivedOutput e) 140 htlcOutputType _ = Nothing 141 {-# INLINE htlcOutputType #-} 142 143 -- | Penalty input weight for an HTLC output type. 144 htlcOutputTypeWeight :: HTLCOutputType -> Word64 145 htlcOutputTypeWeight (HTLCOfferedOutput _) = 146 offered_htlc_penalty_input_weight 147 htlcOutputTypeWeight (HTLCReceivedOutput _) = 148 accepted_htlc_penalty_input_weight 149 {-# INLINE htlcOutputTypeWeight #-} 150 151 -- spending transactions ---------------------------------------------- 152 153 -- | Unsigned spending transaction, ready for caller to sign. 154 -- 155 -- The caller uses bolt3 witness constructors to assemble the 156 -- final witness after signing. 157 data SpendingTx = SpendingTx 158 { stx_tx :: !Tx 159 -- ^ The unsigned transaction. 160 , stx_input_script :: !Script 161 -- ^ Witness script for the input being spent. 162 , stx_input_value :: {-# UNPACK #-} !Satoshi 163 -- ^ Value of the input being spent (for sighash). 164 , stx_sighash_type :: !SighashType 165 -- ^ Sighash type to use when signing. 166 } deriving (Eq, Show, Generic) 167 168 -- penalty batching --------------------------------------------------- 169 170 -- | A revoked output that can be swept with a revocation key. 171 -- 172 -- This type restricts penalty transaction inputs to only 173 -- valid revocation targets: to_local outputs and HTLC outputs. 174 -- Other output types (to_remote, anchors) cannot appear in 175 -- penalty transactions. 176 data RevokedOutput = RevokedOutput 177 { ro_outpoint :: !OutPoint 178 , ro_value :: {-# UNPACK #-} !Satoshi 179 , ro_type :: !RevokedOutputType 180 } deriving (Eq, Show, Generic) 181 182 -- | What kind of revoked output is being swept. 183 data RevokedOutputType 184 = RevokedToLocal 185 -- ^ Revoked to_local output. 186 | RevokedHTLC !HTLCOutputType 187 -- ^ Revoked HTLC output. 188 deriving (Eq, Show, Generic) 189 190 -- | Penalty input weight for a revoked output. 191 revoked_output_weight :: RevokedOutput -> Word64 192 revoked_output_weight !ro = case ro_type ro of 193 RevokedToLocal -> 194 to_local_penalty_input_weight 195 RevokedHTLC !htype -> 196 htlcOutputTypeWeight htype 197 {-# INLINE revoked_output_weight #-} 198 199 -- | Context for constructing batched penalty transactions. 200 data PenaltyContext = PenaltyContext 201 { pc_outputs :: !(NonEmpty RevokedOutput) 202 -- ^ Revoked outputs to sweep (must be non-empty). 203 , pc_revocation_key :: !RevocationPubkey 204 -- ^ Revocation pubkey for all outputs. 205 , pc_destination :: !Script 206 -- ^ Destination scriptPubKey. 207 , pc_feerate :: !FeeratePerKw 208 -- ^ Fee rate for the penalty transaction. 209 } deriving (Eq, Show, Generic) 210 211 -- weight constants (BOLT #5 Appendix A) ------------------------------ 212 213 -- | Expected weight of the to_local penalty transaction witness 214 -- (160 bytes). 215 to_local_penalty_witness_weight :: Word64 216 to_local_penalty_witness_weight = 160 217 218 -- | Expected weight of the offered_htlc penalty transaction 219 -- witness (243 bytes). 220 offered_htlc_penalty_witness_weight :: Word64 221 offered_htlc_penalty_witness_weight = 243 222 223 -- | Expected weight of the accepted_htlc penalty transaction 224 -- witness (249 bytes). 225 accepted_htlc_penalty_witness_weight :: Word64 226 accepted_htlc_penalty_witness_weight = 249 227 228 -- | Weight of a to_local penalty input (164 + 160 = 324 bytes). 229 to_local_penalty_input_weight :: Word64 230 to_local_penalty_input_weight = 324 231 232 -- | Weight of an offered_htlc penalty input 233 -- (164 + 243 = 407 bytes). 234 offered_htlc_penalty_input_weight :: Word64 235 offered_htlc_penalty_input_weight = 407 236 237 -- | Weight of an accepted_htlc penalty input 238 -- (164 + 249 = 413 bytes). 239 accepted_htlc_penalty_input_weight :: Word64 240 accepted_htlc_penalty_input_weight = 413 241 242 -- | Weight of a to_remote P2WPKH input 243 -- (108 + 164 = 272 bytes). 244 to_remote_input_weight :: Word64 245 to_remote_input_weight = 272 246 247 -- | Base weight of a penalty transaction (4*53 + 2 = 214 bytes). 248 -- 249 -- Non-witness: version(4) + input_count(1) + output_count(1) + 250 -- value(8) + script_len(1) + p2wsh_script(34) + locktime(4) = 53 251 -- Witness header: 2 bytes. 252 penalty_tx_base_weight :: Word64 253 penalty_tx_base_weight = 214 254 255 -- | Maximum standard transaction weight (400,000 bytes). 256 max_standard_weight :: Word64 257 max_standard_weight = 400000 258 259 -- fee calculation ---------------------------------------------------- 260 261 -- | Calculate the fee for a spending transaction given its weight. 262 -- 263 -- @fee = feerate_per_kw * weight / 1000@ 264 spending_fee :: FeeratePerKw -> Word64 -> Satoshi 265 spending_fee (FeeratePerKw !rate) !weight = 266 Satoshi ((fromIntegral rate * weight) `div` 1000) 267 {-# INLINE spending_fee #-}