Main.hs (5125B)
1 {-# LANGUAGE BangPatterns #-} 2 {-# LANGUAGE OverloadedStrings #-} 3 {-# OPTIONS_GHC -fno-warn-orphans #-} 4 5 module Main where 6 7 import Bitcoin.Prim.Tx.Sighash (SighashType(..)) 8 import Control.DeepSeq (NFData(..)) 9 import Criterion.Main 10 import qualified Data.ByteString as BS 11 import qualified Data.List.NonEmpty as NE 12 import Lightning.Protocol.BOLT3 hiding 13 (txout_value, txout_script) 14 import qualified Lightning.Protocol.BOLT5 as B5 15 16 -- NFData orphan instances for criterion ----------------------------- 17 18 instance NFData Satoshi where 19 rnf (Satoshi x) = rnf x 20 21 instance NFData MilliSatoshi where 22 rnf (MilliSatoshi x) = rnf x 23 24 instance NFData Script where 25 rnf (Script bs) = rnf bs 26 27 instance NFData Pubkey where 28 rnf (Pubkey x) = rnf x 29 30 instance NFData Point where 31 rnf (Point x) = rnf x 32 33 instance NFData RevocationPubkey where 34 rnf (RevocationPubkey x) = rnf x 35 36 instance NFData LocalDelayedPubkey where 37 rnf (LocalDelayedPubkey p) = rnf p 38 39 instance NFData FundingPubkey where 40 rnf (FundingPubkey p) = rnf p 41 42 instance NFData FeeratePerKw where 43 rnf (FeeratePerKw x) = rnf x 44 45 instance NFData ToSelfDelay where 46 rnf (ToSelfDelay x) = rnf x 47 48 instance NFData PaymentHash where 49 rnf (PaymentHash x) = rnf x 50 51 instance NFData CltvExpiry where 52 rnf (CltvExpiry x) = rnf x 53 54 instance NFData HTLCDirection where 55 rnf HTLCOffered = () 56 rnf HTLCReceived = () 57 58 instance NFData HTLC where 59 rnf (HTLC d a h c) = 60 rnf d `seq` rnf a `seq` rnf h `seq` rnf c 61 62 instance NFData SighashType 63 64 instance NFData B5.OutputResolution where 65 rnf B5.Resolved = () 66 rnf (B5.Revoke rk) = rnf rk 67 rnf _ = () 68 69 instance NFData B5.HTLCOutputType where 70 rnf (B5.HTLCOfferedOutput e) = rnf e 71 rnf (B5.HTLCReceivedOutput e) = rnf e 72 73 instance NFData B5.UnresolvedOutput where 74 rnf (B5.UnresolvedOutput op v t) = 75 rnf op `seq` rnf v `seq` rnf t 76 77 instance NFData B5.RevokedOutputType where 78 rnf B5.RevokedToLocal = () 79 rnf (B5.RevokedHTLC h) = rnf h 80 81 instance NFData B5.RevokedOutput where 82 rnf (B5.RevokedOutput op v t) = 83 rnf op `seq` rnf v `seq` rnf t 84 85 instance NFData B5.SpendingTx where 86 rnf (B5.SpendingTx tx scr val sh) = 87 rnf tx `seq` rnf scr `seq` rnf val `seq` rnf sh 88 89 instance NFData B5.PenaltyContext where 90 rnf (B5.PenaltyContext os rk d f) = 91 rnf os `seq` rnf rk `seq` rnf d `seq` rnf f 92 93 main :: IO () 94 main = defaultMain [ 95 spend_benchmarks 96 , classify_benchmarks 97 ] 98 99 -- fixtures ----------------------------------------------------------- 100 101 dummyPubkey :: Pubkey 102 dummyPubkey = case pubkey (BS.pack (0x02 : replicate 32 0x01)) of 103 Just pk -> pk 104 Nothing -> error "impossible" 105 106 dummyTxId :: TxId 107 dummyTxId = case mkTxId (BS.replicate 32 0x00) of 108 Just tid -> tid 109 Nothing -> error "impossible" 110 111 dummyOutPoint :: OutPoint 112 dummyOutPoint = OutPoint dummyTxId 0 113 114 dummyRevPk :: RevocationPubkey 115 dummyRevPk = RevocationPubkey dummyPubkey 116 117 dummyDelayedPk :: LocalDelayedPubkey 118 dummyDelayedPk = LocalDelayedPubkey dummyPubkey 119 120 dummyFundPk :: FundingPubkey 121 dummyFundPk = FundingPubkey dummyPubkey 122 123 dummyDest :: Script 124 dummyDest = Script $ BS.pack [0x00, 0x14] <> 125 BS.replicate 20 0xCC 126 127 dummyFeerate :: FeeratePerKw 128 dummyFeerate = FeeratePerKw 253 129 130 dummyDelay :: ToSelfDelay 131 dummyDelay = ToSelfDelay 144 132 133 mkRevokedOutputs :: Int -> NE.NonEmpty B5.RevokedOutput 134 mkRevokedOutputs n = 135 let ro i = B5.RevokedOutput 136 (OutPoint dummyTxId (fromIntegral i)) 137 (Satoshi 10000) 138 B5.RevokedToLocal 139 in ro 0 NE.:| [ ro i | i <- [1..n-1] ] 140 141 -- benchmarks --------------------------------------------------------- 142 143 spend_benchmarks :: Benchmark 144 spend_benchmarks = bgroup "spend" [ 145 bench "spend_to_local" $ 146 nf (\v -> B5.spend_to_local 147 dummyOutPoint v dummyRevPk dummyDelay 148 dummyDelayedPk dummyDest dummyFeerate) 149 (Satoshi 100000) 150 151 , bench "spend_revoked_to_local" $ 152 nf (\v -> B5.spend_revoked_to_local 153 dummyOutPoint v dummyRevPk dummyDelay 154 dummyDelayedPk dummyDest dummyFeerate) 155 (Satoshi 100000) 156 157 , bench "spend_anchor_owner" $ 158 nf (\v -> B5.spend_anchor_owner 159 dummyOutPoint v dummyFundPk dummyDest) 160 (Satoshi 330) 161 162 , bench "spend_revoked_batch/10" $ 163 nf B5.spend_revoked_batch 164 (B5.PenaltyContext 165 (mkRevokedOutputs 10) 166 dummyRevPk dummyDest dummyFeerate) 167 168 , bench "spend_revoked_batch/100" $ 169 nf B5.spend_revoked_batch 170 (B5.PenaltyContext 171 (mkRevokedOutputs 100) 172 dummyRevPk dummyDest dummyFeerate) 173 174 , bench "spend_revoked_batch/483" $ 175 nf B5.spend_revoked_batch 176 (B5.PenaltyContext 177 (mkRevokedOutputs 483) 178 dummyRevPk dummyDest dummyFeerate) 179 ] 180 181 classify_benchmarks :: Benchmark 182 classify_benchmarks = bgroup "classify" [ 183 bench "spending_fee" $ 184 nf (B5.spending_fee dummyFeerate) 538 185 186 , bench "htlc_timed_out" $ 187 nf (B5.htlc_timed_out 500001) 188 (HTLC HTLCOffered (MilliSatoshi 1000000) 189 dummyPaymentHash (CltvExpiry 500000)) 190 ] 191 where 192 dummyPaymentHash = case paymentHash 193 (BS.replicate 32 0xAA) of 194 Just ph -> ph 195 Nothing -> error "impossible"