Add millisatoshi truncation 0FC test vectors from the spec
What changed, and why it matters
This commit only adds new test cases to the project's test suite. It does not change any production code. The tests verify that the software correctly handles tiny fractions of Bitcoin (millisatoshis) when building special zero-fee Lightning commitment transactions, including cases where dust amounts add up. There is no indication of a security fix or vulnerability being patched here.
No action required. This is a test-only commit adding spec test vectors. Continue normal review and testing processes.
Security signals we found
No production code changes
Test-only addition of spec compliance vectors
No bug fix, bounds check, or input validation change
No memory safety, cryptographic, or authorization change
Evidence from the diff
The commit adds test vectors to lightning/src/ln/channel.rs under the zero-fee commitment (0FC) test module. It introduces scenarios covering millisatoshi truncation’s effect on the anchor output value and dust HTLC amounts that sum to less than, exactly, and more than one satoshi. The diff is entirely additions to test data and assertions; no implementation logic is modified.
Changed components
lightning/src/ln/channel.rs (test module only)Inspect captured patch +166 / −0
diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs
index 0595d6d..0da128f 100644
--- a/lightning/src/ln/channel.rs
+++ b/lightning/src/ln/channel.rs
@@ -17574,6 +17574,61 @@ mod tests {
"03000000000101c3b4fad51418c874498af12060d49477c154845040e3584104ae641c542c013506000000000000000001a861000000000000220020f2d298ffcfd6d899a3abada37bfc6f42ce0b7b66f3e39e903e8419ac97dca75a0500473044022061b73271a1b6b5a1bd8e15c58b08320c72da0a1db19493abbfc6f74b5fa80c2c022030ff309d3413b9661fc8f8f2b5fd14bc733c239cc7ba8b971fd562263e62bf3b8347304402207559852cd036af82658949c28e4922f7351756616f8d04703e8060889b4b484e022050d997e1684826dc61bf0d88d9d08c01b8fcf67958ac7a177c320a1a70305fb001008576a914ef8968bbfe34ad740642784d7b1efaebfd5b23ec8763ac672103d8507a026fb30bcd48ee9c765c7346470d0d397661d43dd2eb601f661ab92a0b7c820120876475527c2103c26117339025855b87deda5e138d438b2098881a5e6f81f72a60310faef473c652ae67a914488ed834d26f1a1dc5e3428e1e1a214f743e6a2488ac68684d0a0e00", None::<PaymentPreimage> }
});
+ // Commitment transaction with all HTLCs above dust limit and millisatoshi truncation
+ chan.context.pending_inbound_htlcs.clear();
+ chan.context.pending_outbound_htlcs.clear();
+
+ chan.context.pending_inbound_htlcs.extend([(7, 10000650), (9, 6000320)].map(
+ |(htlc_id, amount_msat)| InboundHTLCOutput {
+ htlc_id,
+ amount_msat,
+ cltv_expiry: 920150,
+ payment_hash: PaymentHash::from(htlc_in_preimage),
+ state: InboundHTLCState::Committed,
+ },
+ ));
+
+ chan.context.pending_outbound_htlcs.extend(
+ [
+ (5, 25000821, "72c9386ba5a9d97b821d855930236d39c48dab5b1c2efe9ada44e2fbadcff983"),
+ (8, 25000210, "10b879729e8ddd44f2cfcf3cad6d62be535ca74e293c5ed4a59bd0dcbdad7ca1"),
+ ]
+ .map(|(htlc_id, amount_msat, hash_str)| OutboundHTLCOutput {
+ htlc_id,
+ amount_msat,
+ cltv_expiry: 920141,
+ payment_hash: payment_hash_from_hex(hash_str),
+ state: OutboundHTLCState::Committed,
+ source: HTLCSource::dummy(),
+ skimmed_fee_msat: None,
+ blinding_point: None,
+ send_timestamp: None,
+ hold_htlc: None,
+ }),
+ );
+
+ test_commitment_with_zero_fee!(
+ "304402207077d60a004f42171b99c66b1b6b1799910d8f2cb72b0ef6d6500cd2f937c28a022016464954f0c05ae083bf559bc603c89f014006c44258d054a06ded667166a1f7",
+ "3045022100cb78620afa0efd40d480286b59545e2e00379e78f6fb8c31d0d3659880176ed102201218323fbc8e0cd1184c7a164fad4cecb841f3eb75a3fc7d11208acbcb663865",
+ "03000000000101ae1e3c841378cf9e4c383bfdd033d4b3c6945e0587ff16635a00b347eea2704b0100000000340fef800703000000000000000451024e73701700000000000022002075254560bb02c207015847abfda36d3a1b882e78c3f04b08325aac21c53989dc102700000000000022002075254560bb02c207015847abfda36d3a1b882e78c3f04b08325aac21c53989dca8610000000000002200200963a1f3e47b8d2a35664f70de49d3331b4499da201004868a9104271f0cd93ba8610000000000002200205b138be4da633f087be191275d3ce30828ae32d1630853fcbf66d22ca6fe2636ff451e0000000000160014f2123f1a4b67887f2e5f02eda73e6327010152eaae4e790000000000220020f2d298ffcfd6d899a3abada37bfc6f42ce0b7b66f3e39e903e8419ac97dca75a040047304402207077d60a004f42171b99c66b1b6b1799910d8f2cb72b0ef6d6500cd2f937c28a022016464954f0c05ae083bf559bc603c89f014006c44258d054a06ded667166a1f701483045022100cb78620afa0efd40d480286b59545e2e00379e78f6fb8c31d0d3659880176ed102201218323fbc8e0cd1184c7a164fad4cecb841f3eb75a3fc7d11208acbcb66386501475221027eb9596a68740445fb151ff37d5422e7f65f2c497c90fda63e738eb606c15bd62103bbc16dc8851bece603322f06b3c8da329401b7be7e9fdd3f3090ad19aed0807052aec50fbb20", {
+ {0,
+ "3045022100d53dbf9e7479d48322eda78cd96c0d3d6a53c55c7c0d629a2b11e1b1a02d6b95022031a06dda013ee5a26db181552499816de0a9786c71cbefd1614f8b2e6bcb9131",
+ "304402204e4fd2e36058ed515f36cc609e636989fa89bf0b1d0e968fe642fcca7e2ceb1e022055a69e1e9be2799ae57ebae59792c9f50ca3943e6c154b4b3aabce6b08000930",
+ "0300000000010122daaec93bca3ee6bee9c78cf7885e538a56d0cbd63e3df086bbac22b4f5455d010000000000000000017017000000000000220020f2d298ffcfd6d899a3abada37bfc6f42ce0b7b66f3e39e903e8419ac97dca75a0500483045022100d53dbf9e7479d48322eda78cd96c0d3d6a53c55c7c0d629a2b11e1b1a02d6b95022031a06dda013ee5a26db181552499816de0a9786c71cbefd1614f8b2e6bcb91318347304402204e4fd2e36058ed515f36cc609e636989fa89bf0b1d0e968fe642fcca7e2ceb1e022055a69e1e9be2799ae57ebae59792c9f50ca3943e6c154b4b3aabce6b080009300120108cd7067c8ed6f3734b7b67ec153cfa83c40755b75c65e414e934099e6993aa8b76a914ef8968bbfe34ad740642784d7b1efaebfd5b23ec8763ac672103d8507a026fb30bcd48ee9c765c7346470d0d397661d43dd2eb601f661ab92a0b7c8201208763a914f4c8e88504a23ed3e390ea80300c834f0eb79a6c88527c2103c26117339025855b87deda5e138d438b2098881a5e6f81f72a60310faef473c652ae677503560a0eb175ac686800000000", Some(htlc_in_preimage) },
+ {1,
+ "304402206556f3ae8fb62fd764f1a65fcc238bfc7cd629872c52ba7ee7b91e34aed4f9de022008545d9f5477371f940d8719270cc1b22d04497f53a97bf75dfb6a9ec5e5b49e",
+ "304402205aa6b8143ef46e644157c4f4ad2ff439ae3c2e0cd76c2d3050aa6a1f5a31d33d022072f430949c2996233c5e832c3957f4f9bbf5586af3d62ebf3c0621cf92511b1a",
+ "0300000000010122daaec93bca3ee6bee9c78cf7885e538a56d0cbd63e3df086bbac22b4f5455d020000000000000000011027000000000000220020f2d298ffcfd6d899a3abada37bfc6f42ce0b7b66f3e39e903e8419ac97dca75a050047304402206556f3ae8fb62fd764f1a65fcc238bfc7cd629872c52ba7ee7b91e34aed4f9de022008545d9f5477371f940d8719270cc1b22d04497f53a97bf75dfb6a9ec5e5b49e8347304402205aa6b8143ef46e644157c4f4ad2ff439ae3c2e0cd76c2d3050aa6a1f5a31d33d022072f430949c2996233c5e832c3957f4f9bbf5586af3d62ebf3c0621cf92511b1a0120108cd7067c8ed6f3734b7b67ec153cfa83c40755b75c65e414e934099e6993aa8b76a914ef8968bbfe34ad740642784d7b1efaebfd5b23ec8763ac672103d8507a026fb30bcd48ee9c765c7346470d0d397661d43dd2eb601f661ab92a0b7c8201208763a914f4c8e88504a23ed3e390ea80300c834f0eb79a6c88527c2103c26117339025855b87deda5e138d438b2098881a5e6f81f72a60310faef473c652ae677503560a0eb175ac686800000000", Some(htlc_in_preimage) },
+ {2,
+ "30450221009d775b6e196693171a41c69337de17bd6c7846dd677d0f9db8595faedb3f621f022060eb980ee28effaa38515b31691ec522fef90db0f6b83c07cf3cf3aebc1302c0",
+ "3045022100e93e04871634a1eded25a6721bb6005787e92cfea09831f7af99433891d5373202204ec63ff8fd536518eca98e068d05d562d7be9465cb4d72a52a35308a4b3d8430",
+ "0300000000010122daaec93bca3ee6bee9c78cf7885e538a56d0cbd63e3df086bbac22b4f5455d03000000000000000001a861000000000000220020f2d298ffcfd6d899a3abada37bfc6f42ce0b7b66f3e39e903e8419ac97dca75a05004830450221009d775b6e196693171a41c69337de17bd6c7846dd677d0f9db8595faedb3f621f022060eb980ee28effaa38515b31691ec522fef90db0f6b83c07cf3cf3aebc1302c083483045022100e93e04871634a1eded25a6721bb6005787e92cfea09831f7af99433891d5373202204ec63ff8fd536518eca98e068d05d562d7be9465cb4d72a52a35308a4b3d843001008576a914ef8968bbfe34ad740642784d7b1efaebfd5b23ec8763ac672103d8507a026fb30bcd48ee9c765c7346470d0d397661d43dd2eb601f661ab92a0b7c820120876475527c2103c26117339025855b87deda5e138d438b2098881a5e6f81f72a60310faef473c652ae67a914504170790db95d43716b136806e6a0fdf06e39e488ac68684d0a0e00", None::<PaymentPreimage> },
+ {3,
+ "3045022100c86ebf7f229be7b621a34a3fac39cfe20ea6b26e078eca782c136e635077b47a02205866ca91ef3eb8bc8dd8190c25d8a70dd101b067cc038d367ef2ee5a67c1beea",
+ "304402203f81e6064b5a57bdc9a8759a0906dd8ee767063878f10133c435198c89c575a2022045d4e28f14aad0be1f03e43b3c6bd994d95b18b7ee979b4166c50659d4c02fa6",
+ "0300000000010122daaec93bca3ee6bee9c78cf7885e538a56d0cbd63e3df086bbac22b4f5455d04000000000000000001a861000000000000220020f2d298ffcfd6d899a3abada37bfc6f42ce0b7b66f3e39e903e8419ac97dca75a0500483045022100c86ebf7f229be7b621a34a3fac39cfe20ea6b26e078eca782c136e635077b47a02205866ca91ef3eb8bc8dd8190c25d8a70dd101b067cc038d367ef2ee5a67c1beea8347304402203f81e6064b5a57bdc9a8759a0906dd8ee767063878f10133c435198c89c575a2022045d4e28f14aad0be1f03e43b3c6bd994d95b18b7ee979b4166c50659d4c02fa601008576a914ef8968bbfe34ad740642784d7b1efaebfd5b23ec8763ac672103d8507a026fb30bcd48ee9c765c7346470d0d397661d43dd2eb601f661ab92a0b7c820120876475527c2103c26117339025855b87deda5e138d438b2098881a5e6f81f72a60310faef473c652ae67a914488ed834d26f1a1dc5e3428e1e1a214f743e6a2488ac68684d0a0e00", None::<PaymentPreimage> }
+ });
+
// Commitment transaction with dust HTLCs below maximum anchor amount
chan.context.holder_dust_limit_satoshis = 1000;
chan.funding.value_to_self_msat = 8000000000;
@@ -17695,6 +17750,117 @@ mod tests {
"30450221009c820c376715329110045b3cf90f59838fd2f86b16774cb5ccccbd6a62830d9602205f2d970bef2589a5e37035937ab7db0461223e429b943b38ecf577e32b7b4572",
"03000000000101ae1e3c841378cf9e4c383bfdd033d4b3c6945e0587ff16635a00b347eea2704b0100000000340fef8003b4000000000000000451024e7344841e0000000000160014f2123f1a4b67887f2e5f02eda73e6327010152ea88117a0000000000220020f2d298ffcfd6d899a3abada37bfc6f42ce0b7b66f3e39e903e8419ac97dca75a0400473044022034f22696dd7501d65fc117af3edcfed535eb301317fe35eef08658b571fca4d0022030ff6276cff9e22968f8b08f92a1d4f2c37fe4da29de095df4841d32bdaa501b014830450221009c820c376715329110045b3cf90f59838fd2f86b16774cb5ccccbd6a62830d9602205f2d970bef2589a5e37035937ab7db0461223e429b943b38ecf577e32b7b457201475221027eb9596a68740445fb151ff37d5422e7f65f2c497c90fda63e738eb606c15bd62103bbc16dc8851bece603322f06b3c8da329401b7be7e9fdd3f3090ad19aed0807052aec50fbb20", {});
+ // Commitment transaction with millisatoshi dust HTLCs adding to less than 1 satoshi"
+ chan.context.holder_dust_limit_satoshis = 330;
+ chan.context.pending_inbound_htlcs.clear();
+ chan.context.pending_outbound_htlcs.clear();
+
+ chan.context.pending_inbound_htlcs.extend([(0, htlc_0_in_hash)].map(
+ |(htlc_id, payment_hash)| InboundHTLCOutput {
+ htlc_id,
+ amount_msat: 29525,
+ payment_hash,
+ cltv_expiry: 920125,
+ state: InboundHTLCState::Committed,
+ },
+ ));
+
+ chan.context.pending_outbound_htlcs.extend(
+ [(0, "29a74a69c5941d402838f7e1a95c2b2ec534d79524b2582f48df7bc519ebaecf")].map(
+ |(id, hash)| OutboundHTLCOutput {
+ htlc_id: id,
+ amount_msat: 21474,
+ cltv_expiry: 920125,
+ payment_hash: payment_hash_from_hex(hash),
+ state: OutboundHTLCState::Committed,
+ source: HTLCSource::dummy(),
+ skimmed_fee_msat: None,
+ blinding_point: None,
+ send_timestamp: None,
+ hold_htlc: None,
+ },
+ ),
+ );
+
+ test_commitment_with_zero_fee!(
+ "304402201368dc415e11647edbfc1faaaccbe4717e5fdb88c4220a0bb19969781c9f757f02203fad3a7578fcfdc428b527b97f918b639ff07941b3b42c44f58b1364fdc57177",
+ "30440220338a338e0d477b63d2a7a00baca06c45b74bdd63d02e7d198cd8435180e9317e022014d0b95c9fde3409678417ee1a71d1d4d755f28db66a83eb10bea56de83d628d",
+ "03000000000101ae1e3c841378cf9e4c383bfdd033d4b3c6945e0587ff16635a00b347eea2704b0100000000340fef800334000000000000000451024e7362841e0000000000160014f2123f1a4b67887f2e5f02eda73e6327010152eaea117a0000000000220020f2d298ffcfd6d899a3abada37bfc6f42ce0b7b66f3e39e903e8419ac97dca75a040047304402201368dc415e11647edbfc1faaaccbe4717e5fdb88c4220a0bb19969781c9f757f02203fad3a7578fcfdc428b527b97f918b639ff07941b3b42c44f58b1364fdc57177014730440220338a338e0d477b63d2a7a00baca06c45b74bdd63d02e7d198cd8435180e9317e022014d0b95c9fde3409678417ee1a71d1d4d755f28db66a83eb10bea56de83d628d01475221027eb9596a68740445fb151ff37d5422e7f65f2c497c90fda63e738eb606c15bd62103bbc16dc8851bece603322f06b3c8da329401b7be7e9fdd3f3090ad19aed0807052aec50fbb20", {});
+
+ // Commitment transaction with millisatoshi dust HTLCs adding to 1 satoshi"
+ chan.context.holder_dust_limit_satoshis = 330;
+ chan.context.pending_inbound_htlcs.clear();
+ chan.context.pending_outbound_htlcs.clear();
+
+ chan.context.pending_inbound_htlcs.extend([(0, htlc_0_in_hash)].map(
+ |(htlc_id, payment_hash)| InboundHTLCOutput {
+ htlc_id,
+ amount_msat: 29525,
+ payment_hash,
+ cltv_expiry: 920125,
+ state: InboundHTLCState::Committed,
+ },
+ ));
+
+ chan.context.pending_outbound_htlcs.extend(
+ [(0, "29a74a69c5941d402838f7e1a95c2b2ec534d79524b2582f48df7bc519ebaecf")].map(
+ |(id, hash)| OutboundHTLCOutput {
+ htlc_id: id,
+ amount_msat: 21475,
+ cltv_expiry: 920125,
+ payment_hash: payment_hash_from_hex(hash),
+ state: OutboundHTLCState::Committed,
+ source: HTLCSource::dummy(),
+ skimmed_fee_msat: None,
+ blinding_point: None,
+ send_timestamp: None,
+ hold_htlc: None,
+ },
+ ),
+ );
+
+ test_commitment_with_zero_fee!(
+ "304402201368dc415e11647edbfc1faaaccbe4717e5fdb88c4220a0bb19969781c9f757f02203fad3a7578fcfdc428b527b97f918b639ff07941b3b42c44f58b1364fdc57177",
+ "30440220338a338e0d477b63d2a7a00baca06c45b74bdd63d02e7d198cd8435180e9317e022014d0b95c9fde3409678417ee1a71d1d4d755f28db66a83eb10bea56de83d628d",
+ "03000000000101ae1e3c841378cf9e4c383bfdd033d4b3c6945e0587ff16635a00b347eea2704b0100000000340fef800334000000000000000451024e7362841e0000000000160014f2123f1a4b67887f2e5f02eda73e6327010152eaea117a0000000000220020f2d298ffcfd6d899a3abada37bfc6f42ce0b7b66f3e39e903e8419ac97dca75a040047304402201368dc415e11647edbfc1faaaccbe4717e5fdb88c4220a0bb19969781c9f757f02203fad3a7578fcfdc428b527b97f918b639ff07941b3b42c44f58b1364fdc57177014730440220338a338e0d477b63d2a7a00baca06c45b74bdd63d02e7d198cd8435180e9317e022014d0b95c9fde3409678417ee1a71d1d4d755f28db66a83eb10bea56de83d628d01475221027eb9596a68740445fb151ff37d5422e7f65f2c497c90fda63e738eb606c15bd62103bbc16dc8851bece603322f06b3c8da329401b7be7e9fdd3f3090ad19aed0807052aec50fbb20", {});
+
+ // Commitment transaction with millisatoshi dust HTLCs adding to more than 1 satoshi"
+ chan.context.holder_dust_limit_satoshis = 330;
+ chan.context.pending_inbound_htlcs.clear();
+ chan.context.pending_outbound_htlcs.clear();
+
+ chan.context.pending_inbound_htlcs.extend([(0, htlc_0_in_hash)].map(
+ |(htlc_id, payment_hash)| InboundHTLCOutput {
+ htlc_id,
+ amount_msat: 29753,
+ payment_hash,
+ cltv_expiry: 920125,
+ state: InboundHTLCState::Committed,
+ },
+ ));
+
+ chan.context.pending_outbound_htlcs.extend(
+ [(0, "29a74a69c5941d402838f7e1a95c2b2ec534d79524b2582f48df7bc519ebaecf")].map(
+ |(id, hash)| OutboundHTLCOutput {
+ htlc_id: id,
+ amount_msat: 21712,
+ cltv_expiry: 920125,
+ payment_hash: payment_hash_from_hex(hash),
+ state: OutboundHTLCState::Committed,
+ source: HTLCSource::dummy(),
+ skimmed_fee_msat: None,
+ blinding_point: None,
+ send_timestamp: None,
+ hold_htlc: None,
+ },
+ ),
+ );
+
+ test_commitment_with_zero_fee!(
+ "304402201368dc415e11647edbfc1faaaccbe4717e5fdb88c4220a0bb19969781c9f757f02203fad3a7578fcfdc428b527b97f918b639ff07941b3b42c44f58b1364fdc57177",
+ "30440220338a338e0d477b63d2a7a00baca06c45b74bdd63d02e7d198cd8435180e9317e022014d0b95c9fde3409678417ee1a71d1d4d755f28db66a83eb10bea56de83d628d",
+ "03000000000101ae1e3c841378cf9e4c383bfdd033d4b3c6945e0587ff16635a00b347eea2704b0100000000340fef800334000000000000000451024e7362841e0000000000160014f2123f1a4b67887f2e5f02eda73e6327010152eaea117a0000000000220020f2d298ffcfd6d899a3abada37bfc6f42ce0b7b66f3e39e903e8419ac97dca75a040047304402201368dc415e11647edbfc1faaaccbe4717e5fdb88c4220a0bb19969781c9f757f02203fad3a7578fcfdc428b527b97f918b639ff07941b3b42c44f58b1364fdc57177014730440220338a338e0d477b63d2a7a00baca06c45b74bdd63d02e7d198cd8435180e9317e022014d0b95c9fde3409678417ee1a71d1d4d755f28db66a83eb10bea56de83d628d01475221027eb9596a68740445fb151ff37d5422e7f65f2c497c90fda63e738eb606c15bd62103bbc16dc8851bece603322f06b3c8da329401b7be7e9fdd3f3090ad19aed0807052aec50fbb20", {});
+
// Commitment transaction with dust HTLCs above maximum anchor amount
chan.context.holder_dust_limit_satoshis = 2500;
chan.funding.value_to_self_msat = 8000000000;
Why this scored 12/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.