Types.hs (6261B)
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 -- * Spending transactions 22 , SpendingTx(..) 23 24 -- * Penalty batching 25 , PenaltyContext(..) 26 27 -- * Weight constants (Appendix A) 28 , to_local_penalty_witness_weight 29 , offered_htlc_penalty_witness_weight 30 , accepted_htlc_penalty_witness_weight 31 , to_local_penalty_input_weight 32 , offered_htlc_penalty_input_weight 33 , accepted_htlc_penalty_input_weight 34 , to_remote_input_weight 35 , penalty_tx_base_weight 36 , max_standard_weight 37 38 -- * Fee calculation 39 , spending_fee 40 ) where 41 42 import Bitcoin.Prim.Tx (Tx(..)) 43 import Bitcoin.Prim.Tx.Sighash (SighashType(..)) 44 import Data.List.NonEmpty (NonEmpty) 45 import Data.Word (Word64) 46 import GHC.Generics (Generic) 47 import Lightning.Protocol.BOLT3.Types 48 import Lightning.Protocol.BOLT3.Tx ( 49 CommitmentKeys(..) 50 , OutputType(..) 51 ) 52 53 -- close identification ----------------------------------------------- 54 55 -- | What kind of close was detected on chain. 56 data CloseType 57 = MutualClose 58 -- ^ Cooperative closure agreed by both parties. 59 | LocalCommitClose 60 -- ^ Our commitment transaction was broadcast. 61 | RemoteCommitClose 62 -- ^ The remote party's commitment transaction was broadcast. 63 | RevokedCommitClose 64 -- ^ A revoked (outdated) commitment transaction was broadcast. 65 deriving (Eq, Show, Generic) 66 67 -- output classification ---------------------------------------------- 68 69 -- | An unresolved commitment transaction output. 70 data UnresolvedOutput = UnresolvedOutput 71 { uo_outpoint :: !OutPoint 72 , uo_value :: {-# UNPACK #-} !Satoshi 73 , uo_type :: !OutputResolution 74 } deriving (Eq, Show, Generic) 75 76 -- | How to resolve an output, per BOLT #5 rules. 77 data OutputResolution 78 = Resolved 79 -- ^ Already resolved (e.g. to_remote on local commit). 80 | SpendToLocal 81 !ToSelfDelay !RevocationPubkey !LocalDelayedPubkey 82 -- ^ Spend to_local after CSV delay. 83 | SpendHTLCTimeout 84 !HTLC !CommitmentKeys !ChannelFeatures 85 -- ^ Spend via HTLC-timeout second-stage tx (local commit, 86 -- local offer). 87 | SpendHTLCSuccess 88 !HTLC !CommitmentKeys !ChannelFeatures 89 -- ^ Spend via HTLC-success second-stage tx (local commit, 90 -- remote offer). 91 | SpendHTLCTimeoutDirect !HTLC 92 -- ^ Spend HTLC directly after timeout (remote commit, 93 -- local offer). 94 | SpendHTLCPreimageDirect !HTLC 95 -- ^ Spend HTLC directly with preimage (remote commit, 96 -- remote offer). 97 | Revoke !RevocationPubkey 98 -- ^ Spend revoked to_local with revocation key. 99 | RevokeHTLC !RevocationPubkey !OutputType 100 -- ^ Spend revoked HTLC output with revocation key. 101 | AnchorSpend !FundingPubkey 102 -- ^ Spend anchor output. 103 deriving (Eq, Show, Generic) 104 105 -- spending transactions ---------------------------------------------- 106 107 -- | Unsigned spending transaction, ready for caller to sign. 108 -- 109 -- The caller uses bolt3 witness constructors to assemble the 110 -- final witness after signing. 111 data SpendingTx = SpendingTx 112 { stx_tx :: !Tx 113 -- ^ The unsigned transaction. 114 , stx_input_script :: !Script 115 -- ^ Witness script for the input being spent. 116 , stx_input_value :: {-# UNPACK #-} !Satoshi 117 -- ^ Value of the input being spent (for sighash). 118 , stx_sighash_type :: !SighashType 119 -- ^ Sighash type to use when signing. 120 } deriving (Eq, Show, Generic) 121 122 -- penalty batching --------------------------------------------------- 123 124 -- | Context for constructing batched penalty transactions. 125 data PenaltyContext = PenaltyContext 126 { pc_outputs :: !(NonEmpty UnresolvedOutput) 127 -- ^ Revoked outputs to sweep (must be non-empty). 128 , pc_revocation_key :: !RevocationPubkey 129 -- ^ Revocation pubkey for all outputs. 130 , pc_destination :: !Script 131 -- ^ Destination scriptPubKey. 132 , pc_feerate :: !FeeratePerKw 133 -- ^ Fee rate for the penalty transaction. 134 } deriving (Eq, Show, Generic) 135 136 -- weight constants (BOLT #5 Appendix A) ------------------------------ 137 138 -- | Expected weight of the to_local penalty transaction witness 139 -- (160 bytes). 140 to_local_penalty_witness_weight :: Word64 141 to_local_penalty_witness_weight = 160 142 143 -- | Expected weight of the offered_htlc penalty transaction 144 -- witness (243 bytes). 145 offered_htlc_penalty_witness_weight :: Word64 146 offered_htlc_penalty_witness_weight = 243 147 148 -- | Expected weight of the accepted_htlc penalty transaction 149 -- witness (249 bytes). 150 accepted_htlc_penalty_witness_weight :: Word64 151 accepted_htlc_penalty_witness_weight = 249 152 153 -- | Weight of a to_local penalty input (164 + 160 = 324 bytes). 154 to_local_penalty_input_weight :: Word64 155 to_local_penalty_input_weight = 324 156 157 -- | Weight of an offered_htlc penalty input 158 -- (164 + 243 = 407 bytes). 159 offered_htlc_penalty_input_weight :: Word64 160 offered_htlc_penalty_input_weight = 407 161 162 -- | Weight of an accepted_htlc penalty input 163 -- (164 + 249 = 413 bytes). 164 accepted_htlc_penalty_input_weight :: Word64 165 accepted_htlc_penalty_input_weight = 413 166 167 -- | Weight of a to_remote P2WPKH input 168 -- (108 + 164 = 272 bytes). 169 to_remote_input_weight :: Word64 170 to_remote_input_weight = 272 171 172 -- | Base weight of a penalty transaction (4*53 + 2 = 214 bytes). 173 -- 174 -- Non-witness: version(4) + input_count(1) + output_count(1) + 175 -- value(8) + script_len(1) + p2wsh_script(34) + locktime(4) = 53 176 -- Witness header: 2 bytes. 177 penalty_tx_base_weight :: Word64 178 penalty_tx_base_weight = 214 179 180 -- | Maximum standard transaction weight (400,000 bytes). 181 max_standard_weight :: Word64 182 max_standard_weight = 400000 183 184 -- fee calculation ---------------------------------------------------- 185 186 -- | Calculate the fee for a spending transaction given its weight. 187 -- 188 -- @fee = feerate_per_kw * weight / 1000@ 189 spending_fee :: FeeratePerKw -> Word64 -> Satoshi 190 spending_fee (FeeratePerKw !rate) !weight = 191 Satoshi ((fromIntegral rate * weight) `div` 1000) 192 {-# INLINE spending_fee #-}