bolt5

On-chain transaction handling for Lightning (docs.ppad.tech/bolt5).
git clone git://git.ppad.tech/bolt5.git
Log | Files | Refs | README | LICENSE

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"