Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 5 additions & 15 deletions fuzz/src/chanmon_consistency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1504,7 +1504,6 @@ pub fn do_test<Out: Output + MaybeSend + MaybeSync>(data: &[u8], out: Out) {
counterparty_node_id: &PublicKey,
channel_id: &ChannelId,
wallet: &TestWalletSource,
logger: Arc<dyn Logger + MaybeSend + MaybeSync>,
funding_feerate_sat_per_kw: FeeRate| {
// We conditionally splice out `MAX_STD_OUTPUT_DUST_LIMIT_SATOSHIS` only when the node
// has double the balance required to send a payment upon a `0xff` byte. We do this to
Expand All @@ -1524,12 +1523,7 @@ pub fn do_test<Out: Output + MaybeSend + MaybeSync>(data: &[u8], out: Out) {
value: Amount::from_sat(MAX_STD_OUTPUT_DUST_LIMIT_SATOSHIS),
script_pubkey: wallet.get_change_script().unwrap(),
}];
funding_template.splice_out_sync(
outputs,
feerate,
FeeRate::MAX,
&WalletSync::new(wallet, logger.clone()),
)
funding_template.splice_out(outputs, feerate, FeeRate::MAX)
});
};

Expand Down Expand Up @@ -2450,30 +2444,26 @@ pub fn do_test<Out: Output + MaybeSend + MaybeSync>(data: &[u8], out: Out) {
0xa4 => {
let cp_node_id = nodes[1].get_our_node_id();
let wallet = &wallets[0];
let logger = Arc::clone(&loggers[0]);
let feerate_sat_per_kw = fee_estimators[0].feerate_sat_per_kw();
splice_out(&nodes[0], &cp_node_id, &chan_a_id, wallet, logger, feerate_sat_per_kw);
splice_out(&nodes[0], &cp_node_id, &chan_a_id, wallet, feerate_sat_per_kw);
},
0xa5 => {
let cp_node_id = nodes[0].get_our_node_id();
let wallet = &wallets[1];
let logger = Arc::clone(&loggers[1]);
let feerate_sat_per_kw = fee_estimators[1].feerate_sat_per_kw();
splice_out(&nodes[1], &cp_node_id, &chan_a_id, wallet, logger, feerate_sat_per_kw);
splice_out(&nodes[1], &cp_node_id, &chan_a_id, wallet, feerate_sat_per_kw);
},
0xa6 => {
let cp_node_id = nodes[2].get_our_node_id();
let wallet = &wallets[1];
let logger = Arc::clone(&loggers[1]);
let feerate_sat_per_kw = fee_estimators[1].feerate_sat_per_kw();
splice_out(&nodes[1], &cp_node_id, &chan_b_id, wallet, logger, feerate_sat_per_kw);
splice_out(&nodes[1], &cp_node_id, &chan_b_id, wallet, feerate_sat_per_kw);
},
0xa7 => {
let cp_node_id = nodes[1].get_our_node_id();
let wallet = &wallets[2];
let logger = Arc::clone(&loggers[2]);
let feerate_sat_per_kw = fee_estimators[2].feerate_sat_per_kw();
splice_out(&nodes[2], &cp_node_id, &chan_b_id, wallet, logger, feerate_sat_per_kw);
splice_out(&nodes[2], &cp_node_id, &chan_b_id, wallet, feerate_sat_per_kw);
},

// Sync node by 1 block to cover confirmation of a transaction.
Expand Down
28 changes: 12 additions & 16 deletions fuzz/src/full_stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1083,13 +1083,9 @@ pub fn do_test(mut data: &[u8], logger: &Arc<dyn Logger + MaybeSend + MaybeSync>
value: Amount::from_sat(splice_out_sats),
script_pubkey: wallet.get_change_script().unwrap(),
}];
let wallet_sync = WalletSync::new(&wallet, Arc::clone(&logger));
if let Ok(contribution) = funding_template.splice_out_sync(
outputs,
feerate,
FeeRate::MAX,
&wallet_sync,
) {
if let Ok(contribution) =
funding_template.splice_out(outputs, feerate, FeeRate::MAX)
{
let _ = channelmanager.funding_contributed(
&chan_id,
&counterparty,
Expand Down Expand Up @@ -1890,8 +1886,8 @@ fn splice_seed() -> Vec<u8> {
// CommitmentSigned message with proper signature (r=f7, s=01...) and funding_txid TLV
// signature r encodes sighash first byte f7, s follows the pattern from funding_created
// TLV type 1 (odd/optional) for funding_txid as per impl_writeable_msg!(CommitmentSigned, ...)
// Note: txid is encoded in reverse byte order (Bitcoin standard), so to get display 0000...0033, encode 3300...0000
ext_from_hex("0084 c000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000f7 0100000000000000000000000000000000000000000000000000000000000000 0000 01 20 3300000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000", &mut test);
// Note: txid is encoded in reverse byte order (Bitcoin standard), so to get display 0000...0031, encode 3100...0000
ext_from_hex("0084 c000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000f7 0100000000000000000000000000000000000000000000000000000000000000 0000 01 20 3100000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000", &mut test);

// After commitment_signed exchange, we need to exchange tx_signatures.
// Message type IDs: TxSignatures = 71 (0x0047)
Expand All @@ -1904,19 +1900,19 @@ fn splice_seed() -> Vec<u8> {
// inbound read from peer id 0 of len 150 (134 message + 16 MAC)
ext_from_hex("030096", &mut test);
// TxSignatures message with shared_input_signature TLV (type 0)
// txid must match the splice funding txid (0x33 in reverse byte order)
// txid must match the splice funding txid (0x31 in reverse byte order)
// shared_input_signature: 64-byte fuzz signature for the shared input
ext_from_hex("0047 c000000000000000000000000000000000000000000000000000000000000000 3300000000000000000000000000000000000000000000000000000000000000 0000 00 40 00000000000000000000000000000000000000000000000000000000000000dc 0100000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000", &mut test);
ext_from_hex("0047 c000000000000000000000000000000000000000000000000000000000000000 3100000000000000000000000000000000000000000000000000000000000000 0000 00 40 00000000000000000000000000000000000000000000000000000000000000dc 0100000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000", &mut test);

// Connect a block with the splice funding transaction to confirm it
// The splice funding tx: version(4) + input_count(1) + txid(32) + vout(4) + script_len(1) + sequence(4)
// + output_count(1) + value(8) + script_len(1) + script(34) + locktime(4) = 94 bytes = 0x5e
// Transaction structure from FundingTransactionReadyForSigning:
// - Input: spending c000...00:0 with sequence 0xfffffffd
// - Output: 115536 sats to OP_0 PUSH32 6e00...00
// - Output: 115538 sats to OP_0 PUSH32 6e00...00
// - Locktime: 13
ext_from_hex("0c005e", &mut test);
ext_from_hex("02000000 01 c000000000000000000000000000000000000000000000000000000000000000 00000000 00 fdffffff 01 50c3010000000000 22 00206e00000000000000000000000000000000000000000000000000000000000000 0d000000", &mut test);
ext_from_hex("02000000 01 c000000000000000000000000000000000000000000000000000000000000000 00000000 00 fdffffff 01 52c3010000000000 22 00206e00000000000000000000000000000000000000000000000000000000000000 0d000000", &mut test);

// Connect additional blocks to reach minimum_depth confirmations
for _ in 0..5 {
Expand All @@ -1933,8 +1929,8 @@ fn splice_seed() -> Vec<u8> {
// inbound read from peer id 0 of len 82 (66 message + 16 MAC)
ext_from_hex("030052", &mut test);
// SpliceLocked message (type 77 = 0x004d): channel_id + splice_txid + mac
// splice_txid must match the splice funding txid (0x33 in reverse byte order)
ext_from_hex("004d c000000000000000000000000000000000000000000000000000000000000000 3300000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000", &mut test);
// splice_txid must match the splice funding txid (0x31 in reverse byte order)
ext_from_hex("004d c000000000000000000000000000000000000000000000000000000000000000 3100000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000", &mut test);

test
}
Expand Down Expand Up @@ -2064,6 +2060,6 @@ mod tests {

// Splice locked
assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendSpliceLocked event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000002 for channel c000000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1));
assert_eq!(log_entries.get(&("lightning::ln::channel".to_string(), "Promoting splice funding txid 0000000000000000000000000000000000000000000000000000000000000033".to_string())), Some(&1));
assert_eq!(log_entries.get(&("lightning::ln::channel".to_string(), "Promoting splice funding txid 0000000000000000000000000000000000000000000000000000000000000031".to_string())), Some(&1));
}
}
74 changes: 32 additions & 42 deletions lightning/src/ln/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12441,7 +12441,7 @@ where
};

if let Err(e) =
contribution.net_value_for_initiator_at_feerate(min_rbf_feerate, holder_balance)
contribution.net_value_for_initiator_at_feerate(min_rbf_feerate, Some(holder_balance))
{
log_info!(
logger,
Expand All @@ -12462,7 +12462,7 @@ where
min_rbf_feerate,
);
contribution
.for_initiator_at_feerate(min_rbf_feerate, holder_balance)
.for_initiator_at_feerate(min_rbf_feerate, Some(holder_balance))
.expect("feerate compatibility already checked")
}

Expand Down Expand Up @@ -12532,14 +12532,12 @@ where
};
}

if let Err(e) = contribution.validate().and_then(|()| {
// For splice-out, our_funding_contribution is adjusted to cover fees if there
// aren't any inputs.
let our_funding_contribution = contribution.net_value();
let our_funding_contribution = contribution.net_value();

if let Err(e) =
self.validate_splice_contributions(our_funding_contribution, SignedAmount::ZERO)
}) {
{
log_error!(logger, "Channel {} cannot be funded: {}", self.context.channel_id(), e);

return Err(QuiescentError::FailSplice(self.splice_funding_failed_for(contribution)));
}

Expand Down Expand Up @@ -12863,23 +12861,21 @@ where
.ok();

let net_value = match holder_balance.and_then(|_| self.queued_funding_contribution()) {
Some(c) => {
match c.net_value_for_acceptor_at_feerate(feerate, holder_balance.unwrap()) {
Ok(net_value) => Some(net_value),
Err(FeeRateAdjustmentError::FeeRateTooHigh { .. }) => {
return Err(ChannelError::Abort(AbortReason::FeeRateTooHigh));
},
Err(e) => {
log_info!(
logger,
"Cannot accommodate initiator's feerate ({}) for channel {}: {}",
feerate,
self.context.channel_id(),
e,
);
None
},
}
Some(c) => match c.net_value_for_acceptor_at_feerate(feerate, holder_balance) {
Ok(net_value) => Some(net_value),
Err(FeeRateAdjustmentError::FeeRateTooHigh { .. }) => {
return Err(ChannelError::Abort(AbortReason::FeeRateTooHigh));
},
Err(e) => {
log_info!(
logger,
"Cannot accommodate initiator's feerate ({}) for channel {}: {}",
feerate,
self.context.channel_id(),
e,
);
None
},
},
None => None,
};
Expand All @@ -12904,7 +12900,7 @@ where
let adjusted_contribution = self
.take_queued_funding_contribution()
.expect("queued_funding_contribution was Some")
.for_acceptor_at_feerate(feerate, holder_balance.unwrap())
.for_acceptor_at_feerate(feerate, holder_balance)
.expect("feerate compatibility already checked");
let (inputs, outputs) = adjusted_contribution.clone().into_tx_parts();
(Some(adjusted_contribution), inputs, outputs)
Expand Down Expand Up @@ -13062,13 +13058,9 @@ where
.as_ref()
.and_then(|pending_splice| pending_splice.contributions.last())
{
let net_value = holder_balance
.ok_or_else(|| ChannelError::Abort(AbortReason::InsufficientRbfFeerate))
.and_then(|holder_balance| {
prior
.net_value_for_acceptor_at_feerate(feerate, holder_balance)
.map_err(|_| ChannelError::Abort(AbortReason::InsufficientRbfFeerate))
})?;
let net_value = prior
.net_value_for_acceptor_at_feerate(feerate, holder_balance)
.map_err(|_| ChannelError::Abort(AbortReason::InsufficientRbfFeerate))?;
Some(net_value)
} else {
None
Expand All @@ -13087,7 +13079,7 @@ where
let adjusted_contribution = self
.take_queued_funding_contribution()
.expect("queued_funding_contribution was Some")
.for_acceptor_at_feerate(feerate, holder_balance.unwrap())
.for_acceptor_at_feerate(feerate, holder_balance)
.expect("feerate compatibility already checked");
self.pending_splice
.as_mut()
Expand All @@ -13105,7 +13097,7 @@ where
.expect("prior_net_value was Some")
.clone();
let adjusted_contribution = prior_contribution
.for_acceptor_at_feerate(feerate, holder_balance.unwrap())
.for_acceptor_at_feerate(feerate, holder_balance)
.expect("feerate compatibility already checked");
self.pending_splice
.as_mut()
Expand Down Expand Up @@ -14101,13 +14093,11 @@ where
// funding_contributed and quiescence, reducing the holder's
// balance. If invalid, disconnect and return the contribution so
// the user can reclaim their inputs.
if let Err(e) = contribution.validate().and_then(|()| {
let our_funding_contribution = contribution.net_value();
self.validate_splice_contributions(
our_funding_contribution,
SignedAmount::ZERO,
)
}) {
let our_funding_contribution = contribution.net_value();
if let Err(e) = self.validate_splice_contributions(
our_funding_contribution,
SignedAmount::ZERO,
) {
let failed = self.splice_funding_failed_for(contribution);
return Err((
ChannelError::WarnAndDisconnect(format!(
Expand Down
Loading
Loading