commit 022e022a7106edc07d390c4d1d6a1249e94f2f57
parent 32f758166843be8f40c47cb10c6697acfa2a6641
Author: Jared Tobin <jared@jtobin.io>
Date: Sun, 19 Apr 2026 12:56:59 +0800
test: add missing unit tests from review
Adds 11 new tests covering: extract_preimage_htlc_success wrong
length, anchor output classification, remote non-HTLC classification,
unmatched HTLC fallback to Resolved, spend_remote nSequence
without anchors, spend_remote_htlc_preimage nSequence,
spend_revoked_htlc_output structure, spend_revoked_batch single
element and mixed types, and fee underflow guards for
spend_to_local and spend_revoked_batch.
Diffstat:
| M | test/Main.hs | | | 165 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 165 insertions(+), 0 deletions(-)
diff --git a/test/Main.hs b/test/Main.hs
@@ -272,6 +272,16 @@ detect_tests = testGroup "Detect" [
let wit = Witness [BS.empty, dummyPreimage]
B5.extract_preimage_htlc_success wit @?= Nothing
+ , testCase "extract_preimage_htlc_success - wrong length" $
+ do
+ let zero = BS.empty
+ remoteSig = BS.replicate 72 0x30
+ localSig = BS.replicate 72 0x30
+ badPreimage = BS.replicate 31 0xBB
+ wit = Witness
+ [zero, remoteSig, localSig, badPreimage]
+ B5.extract_preimage_htlc_success wit @?= Nothing
+
, testCase "htlc_timed_out - at expiry" $ do
let htlc = dummyHTLC
{ htlc_cltv_expiry = CltvExpiry 500000 }
@@ -418,6 +428,62 @@ classify_tests = testGroup "Classify" [
<> show other
_ -> assertFailure "expected 4 outputs"
+ , testCase "classify_local - anchor outputs" $ do
+ let anchorScript = to_p2wsh $
+ anchor_script dummyFundingPubkey
+ remoteFundPk = ck_remote_funding dummyKeys
+ remoteAnchorScript = to_p2wsh $
+ anchor_script remoteFundPk
+ commitTx = CommitmentTx
+ { ctx_version = 2
+ , ctx_locktime = Locktime 0
+ , ctx_input_outpoint = dummyOutPoint
+ , ctx_input_sequence = Sequence 0
+ , ctx_outputs =
+ [ TxOutput (Satoshi 330) anchorScript
+ OutputLocalAnchor
+ , TxOutput (Satoshi 330) remoteAnchorScript
+ OutputRemoteAnchor
+ ]
+ , ctx_funding_script = dummyDestScript
+ }
+ outs = B5.classify_local_commit_outputs
+ commitTx dummyKeys dummyDelay
+ dummyFeaturesAnchors []
+ length outs @?= 2
+ case outs of
+ [o1, o2] -> do
+ case B5.uo_type o1 of
+ B5.AnchorSpend _ -> pure ()
+ other -> assertFailure $
+ "expected AnchorSpend, got "
+ <> show other
+ B5.uo_type o2 @?= B5.Resolved
+ _ -> assertFailure "expected 2 outputs"
+
+ , testCase "classify_remote - non-HTLC outputs" $ do
+ let outs = B5.classify_remote_commit_outputs
+ dummyRemoteCommitTx dummyKeys
+ dummyFeatures []
+ length outs @?= 2
+ case outs of
+ [o1, o2] -> do
+ B5.uo_type o1 @?= B5.Resolved
+ B5.uo_type o2 @?= B5.Resolved
+ _ -> assertFailure "expected 2 outputs"
+
+ , testCase "classify_local - unmatched HTLC" $ do
+ let outs = B5.classify_local_commit_outputs
+ dummyLocalCommitWithHTLCs dummyKeys
+ dummyDelay dummyFeatures []
+ -- With no HTLCs passed, HTLC outputs -> Resolved
+ length outs @?= 4
+ case outs of
+ [_, _, o3, o4] -> do
+ B5.uo_type o3 @?= B5.Resolved
+ B5.uo_type o4 @?= B5.Resolved
+ _ -> assertFailure "expected 4 outputs"
+
, testCase "classify_local - empty commit" $ do
let emptyCommit = CommitmentTx
{ ctx_version = 2
@@ -555,6 +621,71 @@ spend_tests = testGroup "Spend" [
(outVal < 80000)
-- Should have 2 inputs
length (tx_inputs tx) @?= 2
+
+ , testCase "spend_revoked_batch single element" $ do
+ let uo = B5.UnresolvedOutput
+ dummyOutPoint (Satoshi 50000)
+ (B5.Revoke dummyRevocationPubkey)
+ pctx = B5.PenaltyContext
+ { B5.pc_outputs = uo :| []
+ , B5.pc_revocation_key =
+ dummyRevocationPubkey
+ , B5.pc_destination = dummyDestScript
+ , B5.pc_feerate = dummyFeerate
+ }
+ stx <- assertJust "spend_revoked_batch" $
+ B5.spend_revoked_batch pctx
+ let tx = B5.stx_tx stx
+ length (tx_inputs tx) @?= 1
+ length (tx_outputs tx) @?= 1
+
+ , testCase "spend_revoked_batch mixed types" $ do
+ let op1 = OutPoint dummyTxId 0
+ op2 = OutPoint dummyTxId 1
+ op3 = OutPoint dummyTxId 2
+ uo1 = B5.UnresolvedOutput op1
+ (Satoshi 50000)
+ (B5.Revoke dummyRevocationPubkey)
+ uo2 = B5.UnresolvedOutput op2
+ (Satoshi 10000)
+ (B5.RevokeHTLC dummyRevocationPubkey
+ (OutputOfferedHTLC (CltvExpiry 500000)))
+ uo3 = B5.UnresolvedOutput op3
+ (Satoshi 10000)
+ (B5.RevokeHTLC dummyRevocationPubkey
+ (OutputReceivedHTLC (CltvExpiry 500000)))
+ pctx = B5.PenaltyContext
+ { B5.pc_outputs = uo1 :| [uo2, uo3]
+ , B5.pc_revocation_key =
+ dummyRevocationPubkey
+ , B5.pc_destination = dummyDestScript
+ , B5.pc_feerate = dummyFeerate
+ }
+ stx <- assertJust "spend_revoked_batch" $
+ B5.spend_revoked_batch pctx
+ let tx = B5.stx_tx stx
+ length (tx_inputs tx) @?= 3
+
+ , testCase "spend_to_local fee underflow" $ do
+ B5.spend_to_local
+ dummyOutPoint (Satoshi 1)
+ dummyRevocationPubkey dummyDelay
+ dummyLocalDelayedPubkey
+ dummyDestScript dummyFeerate
+ @?= Nothing
+
+ , testCase "spend_revoked_batch fee underflow" $ do
+ let uo = B5.UnresolvedOutput
+ dummyOutPoint (Satoshi 1)
+ (B5.Revoke dummyRevocationPubkey)
+ pctx = B5.PenaltyContext
+ { B5.pc_outputs = uo :| []
+ , B5.pc_revocation_key =
+ dummyRevocationPubkey
+ , B5.pc_destination = dummyDestScript
+ , B5.pc_feerate = dummyFeerate
+ }
+ B5.spend_revoked_batch pctx @?= Nothing
]
-- htlc spend tests ---------------------------------------------------
@@ -649,6 +780,27 @@ remote_spend_tests = testGroup "Remote Spend" [
let tx = B5.stx_tx stx
inp = head' (tx_inputs tx)
txin_sequence inp @?= 1
+
+ , testCase "spend_remote_htlc_timeout no-anchor seq" $
+ do
+ stx <- assertJust "spend_remote_htlc_timeout" $
+ B5.spend_remote_htlc_timeout
+ dummyOutPoint (Satoshi 50000)
+ dummyHTLC dummyKeys dummyFeatures
+ dummyDestScript dummyFeerate
+ let tx = B5.stx_tx stx
+ inp = head' (tx_inputs tx)
+ txin_sequence inp @?= 0
+
+ , testCase "spend_remote_htlc_preimage nSequence" $ do
+ stx <- assertJust "spend_remote_htlc_preimage" $
+ B5.spend_remote_htlc_preimage
+ dummyOutPoint (Satoshi 50000)
+ dummyReceivedHTLC dummyKeys
+ dummyFeatures dummyDestScript dummyFeerate
+ let tx = B5.stx_tx stx
+ inp = head' (tx_inputs tx)
+ txin_sequence inp @?= 0
]
-- revoked htlc spend tests ------------------------------------------
@@ -694,6 +846,19 @@ revoked_htlc_spend_tests = testGroup "Revoked HTLC Spend" [
dummyFeatures dummyPaymentHash
dummyDestScript dummyFeerate
@?= Nothing
+
+ , testCase "spend_revoked_htlc_output structure" $ do
+ stx <- assertJust "spend_revoked_htlc_output" $
+ B5.spend_revoked_htlc_output
+ dummyOutPoint (Satoshi 50000)
+ dummyRevocationPubkey dummyDelay
+ dummyLocalDelayedPubkey
+ dummyDestScript dummyFeerate
+ let tx = B5.stx_tx stx
+ tx_version tx @?= 2
+ B5.stx_sighash_type stx @?= SIGHASH_ALL
+ let inp = head' (tx_inputs tx)
+ txin_sequence inp @?= 0xFFFFFFFF
]
-- weight tests -------------------------------------------------------