commit e57497a6b623ca08f068bf6238f82ef66304a097
parent 698b5a1cb601f52c8668d2e4342459682c5b2db2
Author: Jared Tobin <jared@jtobin.io>
Date: Mon, 20 Apr 2026 15:53:49 +0800
test: add property tests
Add 4 property tests:
- htlcOutputType preserves CLTV expiry
- htlcOutputType rejects non-HTLC output types
- revoked_output_weight matches constants per type
- spend_revoked_batch input count matches output count
Diffstat:
| M | test/Main.hs | | | 66 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 66 insertions(+), 0 deletions(-)
diff --git a/test/Main.hs b/test/Main.hs
@@ -1023,6 +1023,72 @@ property_tests = testGroup "Properties" [
let inp = head'
(tx_inputs (B5.stx_tx stx))
in txin_sequence inp == 0xFFFFFFFF
+
+ , testProperty "htlcOutputType preserves expiry" $
+ \expiry ->
+ let ce = CltvExpiry expiry
+ in B5.htlcOutputType (OutputOfferedHTLC ce)
+ == Just (B5.HTLCOfferedOutput ce)
+ &&
+ B5.htlcOutputType (OutputReceivedHTLC ce)
+ == Just (B5.HTLCReceivedOutput ce)
+
+ , testProperty "htlcOutputType rejects non-HTLC" $
+ property $
+ B5.htlcOutputType OutputToLocal == Nothing
+ && B5.htlcOutputType OutputToRemote == Nothing
+ && B5.htlcOutputType OutputLocalAnchor == Nothing
+ && B5.htlcOutputType OutputRemoteAnchor
+ == Nothing
+
+ , testProperty "revoked_output_weight by type" $
+ \expiry ->
+ let ce = CltvExpiry expiry
+ roLocal = B5.RevokedOutput
+ dummyOutPoint (Satoshi 1000)
+ B5.RevokedToLocal
+ roOffered = B5.RevokedOutput
+ dummyOutPoint (Satoshi 1000)
+ (B5.RevokedHTLC
+ (B5.HTLCOfferedOutput ce))
+ roReceived = B5.RevokedOutput
+ dummyOutPoint (Satoshi 1000)
+ (B5.RevokedHTLC
+ (B5.HTLCReceivedOutput ce))
+ in B5.revoked_output_weight roLocal
+ == B5.to_local_penalty_input_weight
+ &&
+ B5.revoked_output_weight roOffered
+ == B5.offered_htlc_penalty_input_weight
+ &&
+ B5.revoked_output_weight roReceived
+ == B5.accepted_htlc_penalty_input_weight
+
+ , testProperty "spend_revoked_batch input count" $
+ \(Positive n') ->
+ let n = min (n' :: Int) 5
+ ros = [ B5.RevokedOutput
+ (OutPoint dummyTxId
+ (fromIntegral i))
+ (Satoshi 1000000)
+ B5.RevokedToLocal
+ | i <- [0..n-1] ]
+ in case ros of
+ [] -> True -- impossible with Positive
+ (r:rs) ->
+ let pctx = B5.PenaltyContext
+ { B5.pc_outputs = r :| rs
+ , B5.pc_revocation_key =
+ dummyRevocationPubkey
+ , B5.pc_destination =
+ dummyDestScript
+ , B5.pc_feerate = FeeratePerKw 253
+ }
+ in case B5.spend_revoked_batch pctx of
+ Nothing -> False
+ Just stx ->
+ length (tx_inputs (B5.stx_tx stx))
+ == n
]
-- helpers ------------------------------------------------------------