Main.hs (4801B)
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.UnresolvedOutput where 70 rnf (B5.UnresolvedOutput op v t) = 71 rnf op `seq` rnf v `seq` rnf t 72 73 instance NFData B5.SpendingTx where 74 rnf (B5.SpendingTx tx scr val sh) = 75 rnf tx `seq` rnf scr `seq` rnf val `seq` rnf sh 76 77 instance NFData B5.PenaltyContext where 78 rnf (B5.PenaltyContext os rk d f) = 79 rnf os `seq` rnf rk `seq` rnf d `seq` rnf f 80 81 main :: IO () 82 main = defaultMain [ 83 spend_benchmarks 84 , classify_benchmarks 85 ] 86 87 -- fixtures ----------------------------------------------------------- 88 89 dummyPubkey :: Pubkey 90 dummyPubkey = case pubkey (BS.pack (0x02 : replicate 32 0x01)) of 91 Just pk -> pk 92 Nothing -> error "impossible" 93 94 dummyTxId :: TxId 95 dummyTxId = case mkTxId (BS.replicate 32 0x00) of 96 Just tid -> tid 97 Nothing -> error "impossible" 98 99 dummyOutPoint :: OutPoint 100 dummyOutPoint = OutPoint dummyTxId 0 101 102 dummyRevPk :: RevocationPubkey 103 dummyRevPk = RevocationPubkey dummyPubkey 104 105 dummyDelayedPk :: LocalDelayedPubkey 106 dummyDelayedPk = LocalDelayedPubkey dummyPubkey 107 108 dummyFundPk :: FundingPubkey 109 dummyFundPk = FundingPubkey dummyPubkey 110 111 dummyDest :: Script 112 dummyDest = Script $ BS.pack [0x00, 0x14] <> 113 BS.replicate 20 0xCC 114 115 dummyFeerate :: FeeratePerKw 116 dummyFeerate = FeeratePerKw 253 117 118 dummyDelay :: ToSelfDelay 119 dummyDelay = ToSelfDelay 144 120 121 mkRevokedOutputs :: Int -> NE.NonEmpty B5.UnresolvedOutput 122 mkRevokedOutputs n = 123 let uo i = B5.UnresolvedOutput 124 (OutPoint dummyTxId (fromIntegral i)) 125 (Satoshi 10000) 126 (B5.Revoke dummyRevPk) 127 in uo 0 NE.:| [ uo i | i <- [1..n-1] ] 128 129 -- benchmarks --------------------------------------------------------- 130 131 spend_benchmarks :: Benchmark 132 spend_benchmarks = bgroup "spend" [ 133 bench "spend_to_local" $ 134 nf (\v -> B5.spend_to_local 135 dummyOutPoint v dummyRevPk dummyDelay 136 dummyDelayedPk dummyDest dummyFeerate) 137 (Satoshi 100000) 138 139 , bench "spend_revoked_to_local" $ 140 nf (\v -> B5.spend_revoked_to_local 141 dummyOutPoint v dummyRevPk dummyDelay 142 dummyDelayedPk dummyDest dummyFeerate) 143 (Satoshi 100000) 144 145 , bench "spend_anchor_owner" $ 146 nf (\v -> B5.spend_anchor_owner 147 dummyOutPoint v dummyFundPk dummyDest) 148 (Satoshi 330) 149 150 , bench "spend_revoked_batch/10" $ 151 nf B5.spend_revoked_batch 152 (B5.PenaltyContext 153 (mkRevokedOutputs 10) 154 dummyRevPk dummyDest dummyFeerate) 155 156 , bench "spend_revoked_batch/100" $ 157 nf B5.spend_revoked_batch 158 (B5.PenaltyContext 159 (mkRevokedOutputs 100) 160 dummyRevPk dummyDest dummyFeerate) 161 162 , bench "spend_revoked_batch/483" $ 163 nf B5.spend_revoked_batch 164 (B5.PenaltyContext 165 (mkRevokedOutputs 483) 166 dummyRevPk dummyDest dummyFeerate) 167 ] 168 169 classify_benchmarks :: Benchmark 170 classify_benchmarks = bgroup "classify" [ 171 bench "spending_fee" $ 172 nf (B5.spending_fee dummyFeerate) 538 173 174 , bench "htlc_timed_out" $ 175 nf (B5.htlc_timed_out 500001) 176 (HTLC HTLCOffered (MilliSatoshi 1000000) 177 dummyPaymentHash (CltvExpiry 500000)) 178 ] 179 where 180 dummyPaymentHash = case paymentHash 181 (BS.replicate 32 0xAA) of 182 Just ph -> ph 183 Nothing -> error "impossible"