mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-02-25 15:20:24 +01:00
Combine common fields of OpenChannel
& OpenChannelV2
into struct
This commit is contained in:
parent
3751398518
commit
d3ddf15357
8 changed files with 442 additions and 329 deletions
|
@ -6615,29 +6615,31 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
|
||||||
let keys = self.context.get_holder_pubkeys();
|
let keys = self.context.get_holder_pubkeys();
|
||||||
|
|
||||||
msgs::OpenChannel {
|
msgs::OpenChannel {
|
||||||
chain_hash,
|
common_fields: msgs::CommonOpenChannelFields {
|
||||||
temporary_channel_id: self.context.channel_id,
|
chain_hash,
|
||||||
funding_satoshis: self.context.channel_value_satoshis,
|
temporary_channel_id: self.context.channel_id,
|
||||||
|
funding_satoshis: self.context.channel_value_satoshis,
|
||||||
|
dust_limit_satoshis: self.context.holder_dust_limit_satoshis,
|
||||||
|
max_htlc_value_in_flight_msat: self.context.holder_max_htlc_value_in_flight_msat,
|
||||||
|
htlc_minimum_msat: self.context.holder_htlc_minimum_msat,
|
||||||
|
commitment_feerate_sat_per_1000_weight: self.context.feerate_per_kw as u32,
|
||||||
|
to_self_delay: self.context.get_holder_selected_contest_delay(),
|
||||||
|
max_accepted_htlcs: self.context.holder_max_accepted_htlcs,
|
||||||
|
funding_pubkey: keys.funding_pubkey,
|
||||||
|
revocation_basepoint: keys.revocation_basepoint.to_public_key(),
|
||||||
|
payment_basepoint: keys.payment_point,
|
||||||
|
delayed_payment_basepoint: keys.delayed_payment_basepoint.to_public_key(),
|
||||||
|
htlc_basepoint: keys.htlc_basepoint.to_public_key(),
|
||||||
|
first_per_commitment_point,
|
||||||
|
channel_flags: if self.context.config.announced_channel {1} else {0},
|
||||||
|
shutdown_scriptpubkey: Some(match &self.context.shutdown_scriptpubkey {
|
||||||
|
Some(script) => script.clone().into_inner(),
|
||||||
|
None => Builder::new().into_script(),
|
||||||
|
}),
|
||||||
|
channel_type: Some(self.context.channel_type.clone()),
|
||||||
|
},
|
||||||
push_msat: self.context.channel_value_satoshis * 1000 - self.context.value_to_self_msat,
|
push_msat: self.context.channel_value_satoshis * 1000 - self.context.value_to_self_msat,
|
||||||
dust_limit_satoshis: self.context.holder_dust_limit_satoshis,
|
|
||||||
max_htlc_value_in_flight_msat: self.context.holder_max_htlc_value_in_flight_msat,
|
|
||||||
channel_reserve_satoshis: self.context.holder_selected_channel_reserve_satoshis,
|
channel_reserve_satoshis: self.context.holder_selected_channel_reserve_satoshis,
|
||||||
htlc_minimum_msat: self.context.holder_htlc_minimum_msat,
|
|
||||||
feerate_per_kw: self.context.feerate_per_kw as u32,
|
|
||||||
to_self_delay: self.context.get_holder_selected_contest_delay(),
|
|
||||||
max_accepted_htlcs: self.context.holder_max_accepted_htlcs,
|
|
||||||
funding_pubkey: keys.funding_pubkey,
|
|
||||||
revocation_basepoint: keys.revocation_basepoint.to_public_key(),
|
|
||||||
payment_point: keys.payment_point,
|
|
||||||
delayed_payment_basepoint: keys.delayed_payment_basepoint.to_public_key(),
|
|
||||||
htlc_basepoint: keys.htlc_basepoint.to_public_key(),
|
|
||||||
first_per_commitment_point,
|
|
||||||
channel_flags: if self.context.config.announced_channel {1} else {0},
|
|
||||||
shutdown_scriptpubkey: Some(match &self.context.shutdown_scriptpubkey {
|
|
||||||
Some(script) => script.clone().into_inner(),
|
|
||||||
None => Builder::new().into_script(),
|
|
||||||
}),
|
|
||||||
channel_type: Some(self.context.channel_type.clone()),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6893,7 +6895,7 @@ pub(super) fn channel_type_from_open_channel(
|
||||||
msg: &msgs::OpenChannel, their_features: &InitFeatures,
|
msg: &msgs::OpenChannel, their_features: &InitFeatures,
|
||||||
our_supported_features: &ChannelTypeFeatures
|
our_supported_features: &ChannelTypeFeatures
|
||||||
) -> Result<ChannelTypeFeatures, ChannelError> {
|
) -> Result<ChannelTypeFeatures, ChannelError> {
|
||||||
if let Some(channel_type) = &msg.channel_type {
|
if let Some(channel_type) = &msg.common_fields.channel_type {
|
||||||
if channel_type.supports_any_optional_bits() {
|
if channel_type.supports_any_optional_bits() {
|
||||||
return Err(ChannelError::Close("Channel Type field contained optional bits - this is not allowed".to_owned()));
|
return Err(ChannelError::Close("Channel Type field contained optional bits - this is not allowed".to_owned()));
|
||||||
}
|
}
|
||||||
|
@ -6908,7 +6910,7 @@ pub(super) fn channel_type_from_open_channel(
|
||||||
if !channel_type.is_subset(our_supported_features) {
|
if !channel_type.is_subset(our_supported_features) {
|
||||||
return Err(ChannelError::Close("Channel Type contains unsupported features".to_owned()));
|
return Err(ChannelError::Close("Channel Type contains unsupported features".to_owned()));
|
||||||
}
|
}
|
||||||
let announced_channel = if (msg.channel_flags & 1) == 1 { true } else { false };
|
let announced_channel = if (msg.common_fields.channel_flags & 1) == 1 { true } else { false };
|
||||||
if channel_type.requires_scid_privacy() && announced_channel {
|
if channel_type.requires_scid_privacy() && announced_channel {
|
||||||
return Err(ChannelError::Close("SCID Alias/Privacy Channel Type cannot be set on a public channel".to_owned()));
|
return Err(ChannelError::Close("SCID Alias/Privacy Channel Type cannot be set on a public channel".to_owned()));
|
||||||
}
|
}
|
||||||
|
@ -6935,22 +6937,22 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
|
||||||
F::Target: FeeEstimator,
|
F::Target: FeeEstimator,
|
||||||
L::Target: Logger,
|
L::Target: Logger,
|
||||||
{
|
{
|
||||||
let logger = WithContext::from(logger, Some(counterparty_node_id), Some(msg.temporary_channel_id));
|
let logger = WithContext::from(logger, Some(counterparty_node_id), Some(msg.common_fields.temporary_channel_id));
|
||||||
let announced_channel = if (msg.channel_flags & 1) == 1 { true } else { false };
|
let announced_channel = if (msg.common_fields.channel_flags & 1) == 1 { true } else { false };
|
||||||
|
|
||||||
// First check the channel type is known, failing before we do anything else if we don't
|
// First check the channel type is known, failing before we do anything else if we don't
|
||||||
// support this channel type.
|
// support this channel type.
|
||||||
let channel_type = channel_type_from_open_channel(msg, their_features, our_supported_features)?;
|
let channel_type = channel_type_from_open_channel(msg, their_features, our_supported_features)?;
|
||||||
|
|
||||||
let channel_keys_id = signer_provider.generate_channel_keys_id(true, msg.funding_satoshis, user_id);
|
let channel_keys_id = signer_provider.generate_channel_keys_id(true, msg.common_fields.funding_satoshis, user_id);
|
||||||
let holder_signer = signer_provider.derive_channel_signer(msg.funding_satoshis, channel_keys_id);
|
let holder_signer = signer_provider.derive_channel_signer(msg.common_fields.funding_satoshis, channel_keys_id);
|
||||||
let pubkeys = holder_signer.pubkeys().clone();
|
let pubkeys = holder_signer.pubkeys().clone();
|
||||||
let counterparty_pubkeys = ChannelPublicKeys {
|
let counterparty_pubkeys = ChannelPublicKeys {
|
||||||
funding_pubkey: msg.funding_pubkey,
|
funding_pubkey: msg.common_fields.funding_pubkey,
|
||||||
revocation_basepoint: RevocationBasepoint::from(msg.revocation_basepoint),
|
revocation_basepoint: RevocationBasepoint::from(msg.common_fields.revocation_basepoint),
|
||||||
payment_point: msg.payment_point,
|
payment_point: msg.common_fields.payment_basepoint,
|
||||||
delayed_payment_basepoint: DelayedPaymentBasepoint::from(msg.delayed_payment_basepoint),
|
delayed_payment_basepoint: DelayedPaymentBasepoint::from(msg.common_fields.delayed_payment_basepoint),
|
||||||
htlc_basepoint: HtlcBasepoint::from(msg.htlc_basepoint)
|
htlc_basepoint: HtlcBasepoint::from(msg.common_fields.htlc_basepoint)
|
||||||
};
|
};
|
||||||
|
|
||||||
if config.channel_handshake_config.our_to_self_delay < BREAKDOWN_TIMEOUT {
|
if config.channel_handshake_config.our_to_self_delay < BREAKDOWN_TIMEOUT {
|
||||||
|
@ -6958,59 +6960,59 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check sanity of message fields:
|
// Check sanity of message fields:
|
||||||
if msg.funding_satoshis > config.channel_handshake_limits.max_funding_satoshis {
|
if msg.common_fields.funding_satoshis > config.channel_handshake_limits.max_funding_satoshis {
|
||||||
return Err(ChannelError::Close(format!("Per our config, funding must be at most {}. It was {}", config.channel_handshake_limits.max_funding_satoshis, msg.funding_satoshis)));
|
return Err(ChannelError::Close(format!("Per our config, funding must be at most {}. It was {}", config.channel_handshake_limits.max_funding_satoshis, msg.common_fields.funding_satoshis)));
|
||||||
}
|
}
|
||||||
if msg.funding_satoshis >= TOTAL_BITCOIN_SUPPLY_SATOSHIS {
|
if msg.common_fields.funding_satoshis >= TOTAL_BITCOIN_SUPPLY_SATOSHIS {
|
||||||
return Err(ChannelError::Close(format!("Funding must be smaller than the total bitcoin supply. It was {}", msg.funding_satoshis)));
|
return Err(ChannelError::Close(format!("Funding must be smaller than the total bitcoin supply. It was {}", msg.common_fields.funding_satoshis)));
|
||||||
}
|
}
|
||||||
if msg.channel_reserve_satoshis > msg.funding_satoshis {
|
if msg.channel_reserve_satoshis > msg.common_fields.funding_satoshis {
|
||||||
return Err(ChannelError::Close(format!("Bogus channel_reserve_satoshis ({}). Must be not greater than funding_satoshis: {}", msg.channel_reserve_satoshis, msg.funding_satoshis)));
|
return Err(ChannelError::Close(format!("Bogus channel_reserve_satoshis ({}). Must be not greater than funding_satoshis: {}", msg.channel_reserve_satoshis, msg.common_fields.funding_satoshis)));
|
||||||
}
|
}
|
||||||
let full_channel_value_msat = (msg.funding_satoshis - msg.channel_reserve_satoshis) * 1000;
|
let full_channel_value_msat = (msg.common_fields.funding_satoshis - msg.channel_reserve_satoshis) * 1000;
|
||||||
if msg.push_msat > full_channel_value_msat {
|
if msg.push_msat > full_channel_value_msat {
|
||||||
return Err(ChannelError::Close(format!("push_msat {} was larger than channel amount minus reserve ({})", msg.push_msat, full_channel_value_msat)));
|
return Err(ChannelError::Close(format!("push_msat {} was larger than channel amount minus reserve ({})", msg.push_msat, full_channel_value_msat)));
|
||||||
}
|
}
|
||||||
if msg.dust_limit_satoshis > msg.funding_satoshis {
|
if msg.common_fields.dust_limit_satoshis > msg.common_fields.funding_satoshis {
|
||||||
return Err(ChannelError::Close(format!("dust_limit_satoshis {} was larger than funding_satoshis {}. Peer never wants payout outputs?", msg.dust_limit_satoshis, msg.funding_satoshis)));
|
return Err(ChannelError::Close(format!("dust_limit_satoshis {} was larger than funding_satoshis {}. Peer never wants payout outputs?", msg.common_fields.dust_limit_satoshis, msg.common_fields.funding_satoshis)));
|
||||||
}
|
}
|
||||||
if msg.htlc_minimum_msat >= full_channel_value_msat {
|
if msg.common_fields.htlc_minimum_msat >= full_channel_value_msat {
|
||||||
return Err(ChannelError::Close(format!("Minimum htlc value ({}) was larger than full channel value ({})", msg.htlc_minimum_msat, full_channel_value_msat)));
|
return Err(ChannelError::Close(format!("Minimum htlc value ({}) was larger than full channel value ({})", msg.common_fields.htlc_minimum_msat, full_channel_value_msat)));
|
||||||
}
|
}
|
||||||
Channel::<SP>::check_remote_fee(&channel_type, fee_estimator, msg.feerate_per_kw, None, &&logger)?;
|
Channel::<SP>::check_remote_fee(&channel_type, fee_estimator, msg.common_fields.commitment_feerate_sat_per_1000_weight, None, &&logger)?;
|
||||||
|
|
||||||
let max_counterparty_selected_contest_delay = u16::min(config.channel_handshake_limits.their_to_self_delay, MAX_LOCAL_BREAKDOWN_TIMEOUT);
|
let max_counterparty_selected_contest_delay = u16::min(config.channel_handshake_limits.their_to_self_delay, MAX_LOCAL_BREAKDOWN_TIMEOUT);
|
||||||
if msg.to_self_delay > max_counterparty_selected_contest_delay {
|
if msg.common_fields.to_self_delay > max_counterparty_selected_contest_delay {
|
||||||
return Err(ChannelError::Close(format!("They wanted our payments to be delayed by a needlessly long period. Upper limit: {}. Actual: {}", max_counterparty_selected_contest_delay, msg.to_self_delay)));
|
return Err(ChannelError::Close(format!("They wanted our payments to be delayed by a needlessly long period. Upper limit: {}. Actual: {}", max_counterparty_selected_contest_delay, msg.common_fields.to_self_delay)));
|
||||||
}
|
}
|
||||||
if msg.max_accepted_htlcs < 1 {
|
if msg.common_fields.max_accepted_htlcs < 1 {
|
||||||
return Err(ChannelError::Close("0 max_accepted_htlcs makes for a useless channel".to_owned()));
|
return Err(ChannelError::Close("0 max_accepted_htlcs makes for a useless channel".to_owned()));
|
||||||
}
|
}
|
||||||
if msg.max_accepted_htlcs > MAX_HTLCS {
|
if msg.common_fields.max_accepted_htlcs > MAX_HTLCS {
|
||||||
return Err(ChannelError::Close(format!("max_accepted_htlcs was {}. It must not be larger than {}", msg.max_accepted_htlcs, MAX_HTLCS)));
|
return Err(ChannelError::Close(format!("max_accepted_htlcs was {}. It must not be larger than {}", msg.common_fields.max_accepted_htlcs, MAX_HTLCS)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now check against optional parameters as set by config...
|
// Now check against optional parameters as set by config...
|
||||||
if msg.funding_satoshis < config.channel_handshake_limits.min_funding_satoshis {
|
if msg.common_fields.funding_satoshis < config.channel_handshake_limits.min_funding_satoshis {
|
||||||
return Err(ChannelError::Close(format!("Funding satoshis ({}) is less than the user specified limit ({})", msg.funding_satoshis, config.channel_handshake_limits.min_funding_satoshis)));
|
return Err(ChannelError::Close(format!("Funding satoshis ({}) is less than the user specified limit ({})", msg.common_fields.funding_satoshis, config.channel_handshake_limits.min_funding_satoshis)));
|
||||||
}
|
}
|
||||||
if msg.htlc_minimum_msat > config.channel_handshake_limits.max_htlc_minimum_msat {
|
if msg.common_fields.htlc_minimum_msat > config.channel_handshake_limits.max_htlc_minimum_msat {
|
||||||
return Err(ChannelError::Close(format!("htlc_minimum_msat ({}) is higher than the user specified limit ({})", msg.htlc_minimum_msat, config.channel_handshake_limits.max_htlc_minimum_msat)));
|
return Err(ChannelError::Close(format!("htlc_minimum_msat ({}) is higher than the user specified limit ({})", msg.common_fields.htlc_minimum_msat, config.channel_handshake_limits.max_htlc_minimum_msat)));
|
||||||
}
|
}
|
||||||
if msg.max_htlc_value_in_flight_msat < config.channel_handshake_limits.min_max_htlc_value_in_flight_msat {
|
if msg.common_fields.max_htlc_value_in_flight_msat < config.channel_handshake_limits.min_max_htlc_value_in_flight_msat {
|
||||||
return Err(ChannelError::Close(format!("max_htlc_value_in_flight_msat ({}) is less than the user specified limit ({})", msg.max_htlc_value_in_flight_msat, config.channel_handshake_limits.min_max_htlc_value_in_flight_msat)));
|
return Err(ChannelError::Close(format!("max_htlc_value_in_flight_msat ({}) is less than the user specified limit ({})", msg.common_fields.max_htlc_value_in_flight_msat, config.channel_handshake_limits.min_max_htlc_value_in_flight_msat)));
|
||||||
}
|
}
|
||||||
if msg.channel_reserve_satoshis > config.channel_handshake_limits.max_channel_reserve_satoshis {
|
if msg.channel_reserve_satoshis > config.channel_handshake_limits.max_channel_reserve_satoshis {
|
||||||
return Err(ChannelError::Close(format!("channel_reserve_satoshis ({}) is higher than the user specified limit ({})", msg.channel_reserve_satoshis, config.channel_handshake_limits.max_channel_reserve_satoshis)));
|
return Err(ChannelError::Close(format!("channel_reserve_satoshis ({}) is higher than the user specified limit ({})", msg.channel_reserve_satoshis, config.channel_handshake_limits.max_channel_reserve_satoshis)));
|
||||||
}
|
}
|
||||||
if msg.max_accepted_htlcs < config.channel_handshake_limits.min_max_accepted_htlcs {
|
if msg.common_fields.max_accepted_htlcs < config.channel_handshake_limits.min_max_accepted_htlcs {
|
||||||
return Err(ChannelError::Close(format!("max_accepted_htlcs ({}) is less than the user specified limit ({})", msg.max_accepted_htlcs, config.channel_handshake_limits.min_max_accepted_htlcs)));
|
return Err(ChannelError::Close(format!("max_accepted_htlcs ({}) is less than the user specified limit ({})", msg.common_fields.max_accepted_htlcs, config.channel_handshake_limits.min_max_accepted_htlcs)));
|
||||||
}
|
}
|
||||||
if msg.dust_limit_satoshis < MIN_CHAN_DUST_LIMIT_SATOSHIS {
|
if msg.common_fields.dust_limit_satoshis < MIN_CHAN_DUST_LIMIT_SATOSHIS {
|
||||||
return Err(ChannelError::Close(format!("dust_limit_satoshis ({}) is less than the implementation limit ({})", msg.dust_limit_satoshis, MIN_CHAN_DUST_LIMIT_SATOSHIS)));
|
return Err(ChannelError::Close(format!("dust_limit_satoshis ({}) is less than the implementation limit ({})", msg.common_fields.dust_limit_satoshis, MIN_CHAN_DUST_LIMIT_SATOSHIS)));
|
||||||
}
|
}
|
||||||
if msg.dust_limit_satoshis > MAX_CHAN_DUST_LIMIT_SATOSHIS {
|
if msg.common_fields.dust_limit_satoshis > MAX_CHAN_DUST_LIMIT_SATOSHIS {
|
||||||
return Err(ChannelError::Close(format!("dust_limit_satoshis ({}) is greater than the implementation limit ({})", msg.dust_limit_satoshis, MAX_CHAN_DUST_LIMIT_SATOSHIS)));
|
return Err(ChannelError::Close(format!("dust_limit_satoshis ({}) is greater than the implementation limit ({})", msg.common_fields.dust_limit_satoshis, MAX_CHAN_DUST_LIMIT_SATOSHIS)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert things into internal flags and prep our state:
|
// Convert things into internal flags and prep our state:
|
||||||
|
@ -7021,7 +7023,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let holder_selected_channel_reserve_satoshis = get_holder_selected_channel_reserve_satoshis(msg.funding_satoshis, config);
|
let holder_selected_channel_reserve_satoshis = get_holder_selected_channel_reserve_satoshis(msg.common_fields.funding_satoshis, config);
|
||||||
if holder_selected_channel_reserve_satoshis < MIN_CHAN_DUST_LIMIT_SATOSHIS {
|
if holder_selected_channel_reserve_satoshis < MIN_CHAN_DUST_LIMIT_SATOSHIS {
|
||||||
// Protocol level safety check in place, although it should never happen because
|
// Protocol level safety check in place, although it should never happen because
|
||||||
// of `MIN_THEIR_CHAN_RESERVE_SATOSHIS`
|
// of `MIN_THEIR_CHAN_RESERVE_SATOSHIS`
|
||||||
|
@ -7034,8 +7036,8 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
|
||||||
log_debug!(logger, "channel_reserve_satoshis ({}) is smaller than our dust limit ({}). We can broadcast stale states without any risk, implying this channel is very insecure for our counterparty.",
|
log_debug!(logger, "channel_reserve_satoshis ({}) is smaller than our dust limit ({}). We can broadcast stale states without any risk, implying this channel is very insecure for our counterparty.",
|
||||||
msg.channel_reserve_satoshis, MIN_CHAN_DUST_LIMIT_SATOSHIS);
|
msg.channel_reserve_satoshis, MIN_CHAN_DUST_LIMIT_SATOSHIS);
|
||||||
}
|
}
|
||||||
if holder_selected_channel_reserve_satoshis < msg.dust_limit_satoshis {
|
if holder_selected_channel_reserve_satoshis < msg.common_fields.dust_limit_satoshis {
|
||||||
return Err(ChannelError::Close(format!("Dust limit ({}) too high for the channel reserve we require the remote to keep ({})", msg.dust_limit_satoshis, holder_selected_channel_reserve_satoshis)));
|
return Err(ChannelError::Close(format!("Dust limit ({}) too high for the channel reserve we require the remote to keep ({})", msg.common_fields.dust_limit_satoshis, holder_selected_channel_reserve_satoshis)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the funder's amount for the initial commitment tx is sufficient
|
// check if the funder's amount for the initial commitment tx is sufficient
|
||||||
|
@ -7045,8 +7047,8 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
let funders_amount_msat = msg.funding_satoshis * 1000 - msg.push_msat;
|
let funders_amount_msat = msg.common_fields.funding_satoshis * 1000 - msg.push_msat;
|
||||||
let commitment_tx_fee = commit_tx_fee_msat(msg.feerate_per_kw, MIN_AFFORDABLE_HTLC_COUNT, &channel_type) / 1000;
|
let commitment_tx_fee = commit_tx_fee_msat(msg.common_fields.commitment_feerate_sat_per_1000_weight, MIN_AFFORDABLE_HTLC_COUNT, &channel_type) / 1000;
|
||||||
if (funders_amount_msat / 1000).saturating_sub(anchor_outputs_value) < commitment_tx_fee {
|
if (funders_amount_msat / 1000).saturating_sub(anchor_outputs_value) < commitment_tx_fee {
|
||||||
return Err(ChannelError::Close(format!("Funding amount ({} sats) can't even pay fee for initial commitment transaction fee of {} sats.", (funders_amount_msat / 1000).saturating_sub(anchor_outputs_value), commitment_tx_fee)));
|
return Err(ChannelError::Close(format!("Funding amount ({} sats) can't even pay fee for initial commitment transaction fee of {} sats.", (funders_amount_msat / 1000).saturating_sub(anchor_outputs_value), commitment_tx_fee)));
|
||||||
}
|
}
|
||||||
|
@ -7059,7 +7061,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
let counterparty_shutdown_scriptpubkey = if their_features.supports_upfront_shutdown_script() {
|
let counterparty_shutdown_scriptpubkey = if their_features.supports_upfront_shutdown_script() {
|
||||||
match &msg.shutdown_scriptpubkey {
|
match &msg.common_fields.shutdown_scriptpubkey {
|
||||||
&Some(ref script) => {
|
&Some(ref script) => {
|
||||||
// Peer is signaling upfront_shutdown and has opt-out with a 0-length script. We don't enforce anything
|
// Peer is signaling upfront_shutdown and has opt-out with a 0-length script. We don't enforce anything
|
||||||
if script.len() == 0 {
|
if script.len() == 0 {
|
||||||
|
@ -7119,8 +7121,8 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
|
||||||
|
|
||||||
inbound_handshake_limits_override: None,
|
inbound_handshake_limits_override: None,
|
||||||
|
|
||||||
temporary_channel_id: Some(msg.temporary_channel_id),
|
temporary_channel_id: Some(msg.common_fields.temporary_channel_id),
|
||||||
channel_id: msg.temporary_channel_id,
|
channel_id: msg.common_fields.temporary_channel_id,
|
||||||
channel_state: ChannelState::NegotiatingFunding(
|
channel_state: ChannelState::NegotiatingFunding(
|
||||||
NegotiatingFundingFlags::OUR_INIT_SENT | NegotiatingFundingFlags::THEIR_INIT_SENT
|
NegotiatingFundingFlags::OUR_INIT_SENT | NegotiatingFundingFlags::THEIR_INIT_SENT
|
||||||
),
|
),
|
||||||
|
@ -7159,9 +7161,9 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
|
||||||
signer_pending_funding: false,
|
signer_pending_funding: false,
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
holder_max_commitment_tx_output: Mutex::new((msg.push_msat, msg.funding_satoshis * 1000 - msg.push_msat)),
|
holder_max_commitment_tx_output: Mutex::new((msg.push_msat, msg.common_fields.funding_satoshis * 1000 - msg.push_msat)),
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
counterparty_max_commitment_tx_output: Mutex::new((msg.push_msat, msg.funding_satoshis * 1000 - msg.push_msat)),
|
counterparty_max_commitment_tx_output: Mutex::new((msg.push_msat, msg.common_fields.funding_satoshis * 1000 - msg.push_msat)),
|
||||||
|
|
||||||
last_sent_closing_fee: None,
|
last_sent_closing_fee: None,
|
||||||
pending_counterparty_closing_signed: None,
|
pending_counterparty_closing_signed: None,
|
||||||
|
@ -7174,17 +7176,17 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
|
||||||
short_channel_id: None,
|
short_channel_id: None,
|
||||||
channel_creation_height: current_chain_height,
|
channel_creation_height: current_chain_height,
|
||||||
|
|
||||||
feerate_per_kw: msg.feerate_per_kw,
|
feerate_per_kw: msg.common_fields.commitment_feerate_sat_per_1000_weight,
|
||||||
channel_value_satoshis: msg.funding_satoshis,
|
channel_value_satoshis: msg.common_fields.funding_satoshis,
|
||||||
counterparty_dust_limit_satoshis: msg.dust_limit_satoshis,
|
counterparty_dust_limit_satoshis: msg.common_fields.dust_limit_satoshis,
|
||||||
holder_dust_limit_satoshis: MIN_CHAN_DUST_LIMIT_SATOSHIS,
|
holder_dust_limit_satoshis: MIN_CHAN_DUST_LIMIT_SATOSHIS,
|
||||||
counterparty_max_htlc_value_in_flight_msat: cmp::min(msg.max_htlc_value_in_flight_msat, msg.funding_satoshis * 1000),
|
counterparty_max_htlc_value_in_flight_msat: cmp::min(msg.common_fields.max_htlc_value_in_flight_msat, msg.common_fields.funding_satoshis * 1000),
|
||||||
holder_max_htlc_value_in_flight_msat: get_holder_max_htlc_value_in_flight_msat(msg.funding_satoshis, &config.channel_handshake_config),
|
holder_max_htlc_value_in_flight_msat: get_holder_max_htlc_value_in_flight_msat(msg.common_fields.funding_satoshis, &config.channel_handshake_config),
|
||||||
counterparty_selected_channel_reserve_satoshis: Some(msg.channel_reserve_satoshis),
|
counterparty_selected_channel_reserve_satoshis: Some(msg.channel_reserve_satoshis),
|
||||||
holder_selected_channel_reserve_satoshis,
|
holder_selected_channel_reserve_satoshis,
|
||||||
counterparty_htlc_minimum_msat: msg.htlc_minimum_msat,
|
counterparty_htlc_minimum_msat: msg.common_fields.htlc_minimum_msat,
|
||||||
holder_htlc_minimum_msat: if config.channel_handshake_config.our_htlc_minimum_msat == 0 { 1 } else { config.channel_handshake_config.our_htlc_minimum_msat },
|
holder_htlc_minimum_msat: if config.channel_handshake_config.our_htlc_minimum_msat == 0 { 1 } else { config.channel_handshake_config.our_htlc_minimum_msat },
|
||||||
counterparty_max_accepted_htlcs: msg.max_accepted_htlcs,
|
counterparty_max_accepted_htlcs: msg.common_fields.max_accepted_htlcs,
|
||||||
holder_max_accepted_htlcs: cmp::min(config.channel_handshake_config.our_max_accepted_htlcs, MAX_HTLCS),
|
holder_max_accepted_htlcs: cmp::min(config.channel_handshake_config.our_max_accepted_htlcs, MAX_HTLCS),
|
||||||
minimum_depth,
|
minimum_depth,
|
||||||
|
|
||||||
|
@ -7195,7 +7197,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
|
||||||
holder_selected_contest_delay: config.channel_handshake_config.our_to_self_delay,
|
holder_selected_contest_delay: config.channel_handshake_config.our_to_self_delay,
|
||||||
is_outbound_from_holder: false,
|
is_outbound_from_holder: false,
|
||||||
counterparty_parameters: Some(CounterpartyChannelTransactionParameters {
|
counterparty_parameters: Some(CounterpartyChannelTransactionParameters {
|
||||||
selected_contest_delay: msg.to_self_delay,
|
selected_contest_delay: msg.common_fields.to_self_delay,
|
||||||
pubkeys: counterparty_pubkeys,
|
pubkeys: counterparty_pubkeys,
|
||||||
}),
|
}),
|
||||||
funding_outpoint: None,
|
funding_outpoint: None,
|
||||||
|
@ -7204,7 +7206,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
|
||||||
funding_transaction: None,
|
funding_transaction: None,
|
||||||
is_batch_funding: None,
|
is_batch_funding: None,
|
||||||
|
|
||||||
counterparty_cur_commitment_point: Some(msg.first_per_commitment_point),
|
counterparty_cur_commitment_point: Some(msg.common_fields.first_per_commitment_point),
|
||||||
counterparty_prev_commitment_point: None,
|
counterparty_prev_commitment_point: None,
|
||||||
counterparty_node_id,
|
counterparty_node_id,
|
||||||
|
|
||||||
|
@ -8525,7 +8527,7 @@ mod tests {
|
||||||
// same as the old fee.
|
// same as the old fee.
|
||||||
fee_est.fee_est = 500;
|
fee_est.fee_est = 500;
|
||||||
let open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network));
|
let open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network));
|
||||||
assert_eq!(open_channel_msg.feerate_per_kw, original_fee);
|
assert_eq!(open_channel_msg.common_fields.commitment_feerate_sat_per_1000_weight, original_fee);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -9847,7 +9849,7 @@ mod tests {
|
||||||
channel_type_features.set_zero_conf_required();
|
channel_type_features.set_zero_conf_required();
|
||||||
|
|
||||||
let mut open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network));
|
let mut open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network));
|
||||||
open_channel_msg.channel_type = Some(channel_type_features);
|
open_channel_msg.common_fields.channel_type = Some(channel_type_features);
|
||||||
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
|
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
|
||||||
let res = InboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider,
|
let res = InboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider,
|
||||||
node_b_node_id, &channelmanager::provided_channel_type_features(&config),
|
node_b_node_id, &channelmanager::provided_channel_type_features(&config),
|
||||||
|
@ -9930,7 +9932,7 @@ mod tests {
|
||||||
|
|
||||||
// Set `channel_type` to `None` to force the implicit feature negotiation.
|
// Set `channel_type` to `None` to force the implicit feature negotiation.
|
||||||
let mut open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network));
|
let mut open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network));
|
||||||
open_channel_msg.channel_type = None;
|
open_channel_msg.common_fields.channel_type = None;
|
||||||
|
|
||||||
// Since A supports both `static_remote_key` and `option_anchors`, but B only accepts
|
// Since A supports both `static_remote_key` and `option_anchors`, but B only accepts
|
||||||
// `static_remote_key`, it will fail the channel.
|
// `static_remote_key`, it will fail the channel.
|
||||||
|
@ -9976,7 +9978,7 @@ mod tests {
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
let mut open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network));
|
let mut open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network));
|
||||||
open_channel_msg.channel_type = Some(simple_anchors_channel_type.clone());
|
open_channel_msg.common_fields.channel_type = Some(simple_anchors_channel_type.clone());
|
||||||
|
|
||||||
let res = InboundV1Channel::<&TestKeysInterface>::new(
|
let res = InboundV1Channel::<&TestKeysInterface>::new(
|
||||||
&fee_estimator, &&keys_provider, &&keys_provider, node_id_a,
|
&fee_estimator, &&keys_provider, &&keys_provider, node_id_a,
|
||||||
|
|
|
@ -6178,12 +6178,14 @@ where
|
||||||
fn internal_open_channel(&self, counterparty_node_id: &PublicKey, msg: &msgs::OpenChannel) -> Result<(), MsgHandleErrInternal> {
|
fn internal_open_channel(&self, counterparty_node_id: &PublicKey, msg: &msgs::OpenChannel) -> Result<(), MsgHandleErrInternal> {
|
||||||
// Note that the ChannelManager is NOT re-persisted on disk after this, so any changes are
|
// Note that the ChannelManager is NOT re-persisted on disk after this, so any changes are
|
||||||
// likely to be lost on restart!
|
// likely to be lost on restart!
|
||||||
if msg.chain_hash != self.chain_hash {
|
if msg.common_fields.chain_hash != self.chain_hash {
|
||||||
return Err(MsgHandleErrInternal::send_err_msg_no_close("Unknown genesis block hash".to_owned(), msg.temporary_channel_id.clone()));
|
return Err(MsgHandleErrInternal::send_err_msg_no_close("Unknown genesis block hash".to_owned(),
|
||||||
|
msg.common_fields.temporary_channel_id.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.default_configuration.accept_inbound_channels {
|
if !self.default_configuration.accept_inbound_channels {
|
||||||
return Err(MsgHandleErrInternal::send_err_msg_no_close("No inbound channels accepted".to_owned(), msg.temporary_channel_id.clone()));
|
return Err(MsgHandleErrInternal::send_err_msg_no_close("No inbound channels accepted".to_owned(),
|
||||||
|
msg.common_fields.temporary_channel_id.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the number of peers with channels, but without funded ones. We don't care too much
|
// Get the number of peers with channels, but without funded ones. We don't care too much
|
||||||
|
@ -6196,7 +6198,9 @@ where
|
||||||
let peer_state_mutex = per_peer_state.get(counterparty_node_id)
|
let peer_state_mutex = per_peer_state.get(counterparty_node_id)
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
debug_assert!(false);
|
debug_assert!(false);
|
||||||
MsgHandleErrInternal::send_err_msg_no_close(format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id), msg.temporary_channel_id.clone())
|
MsgHandleErrInternal::send_err_msg_no_close(
|
||||||
|
format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id),
|
||||||
|
msg.common_fields.temporary_channel_id.clone())
|
||||||
})?;
|
})?;
|
||||||
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
|
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
|
||||||
let peer_state = &mut *peer_state_lock;
|
let peer_state = &mut *peer_state_lock;
|
||||||
|
@ -6210,20 +6214,22 @@ where
|
||||||
{
|
{
|
||||||
return Err(MsgHandleErrInternal::send_err_msg_no_close(
|
return Err(MsgHandleErrInternal::send_err_msg_no_close(
|
||||||
"Have too many peers with unfunded channels, not accepting new ones".to_owned(),
|
"Have too many peers with unfunded channels, not accepting new ones".to_owned(),
|
||||||
msg.temporary_channel_id.clone()));
|
msg.common_fields.temporary_channel_id.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let best_block_height = self.best_block.read().unwrap().height();
|
let best_block_height = self.best_block.read().unwrap().height();
|
||||||
if Self::unfunded_channel_count(peer_state, best_block_height) >= MAX_UNFUNDED_CHANS_PER_PEER {
|
if Self::unfunded_channel_count(peer_state, best_block_height) >= MAX_UNFUNDED_CHANS_PER_PEER {
|
||||||
return Err(MsgHandleErrInternal::send_err_msg_no_close(
|
return Err(MsgHandleErrInternal::send_err_msg_no_close(
|
||||||
format!("Refusing more than {} unfunded channels.", MAX_UNFUNDED_CHANS_PER_PEER),
|
format!("Refusing more than {} unfunded channels.", MAX_UNFUNDED_CHANS_PER_PEER),
|
||||||
msg.temporary_channel_id.clone()));
|
msg.common_fields.temporary_channel_id.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let channel_id = msg.temporary_channel_id;
|
let channel_id = msg.common_fields.temporary_channel_id;
|
||||||
let channel_exists = peer_state.has_channel(&channel_id);
|
let channel_exists = peer_state.has_channel(&channel_id);
|
||||||
if channel_exists {
|
if channel_exists {
|
||||||
return Err(MsgHandleErrInternal::send_err_msg_no_close("temporary_channel_id collision for the same peer!".to_owned(), msg.temporary_channel_id.clone()));
|
return Err(MsgHandleErrInternal::send_err_msg_no_close(
|
||||||
|
"temporary_channel_id collision for the same peer!".to_owned(),
|
||||||
|
msg.common_fields.temporary_channel_id.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're doing manual acceptance checks on the channel, then defer creation until we're sure we want to accept.
|
// If we're doing manual acceptance checks on the channel, then defer creation until we're sure we want to accept.
|
||||||
|
@ -6231,13 +6237,13 @@ where
|
||||||
let channel_type = channel::channel_type_from_open_channel(
|
let channel_type = channel::channel_type_from_open_channel(
|
||||||
&msg, &peer_state.latest_features, &self.channel_type_features()
|
&msg, &peer_state.latest_features, &self.channel_type_features()
|
||||||
).map_err(|e|
|
).map_err(|e|
|
||||||
MsgHandleErrInternal::from_chan_no_close(e, msg.temporary_channel_id)
|
MsgHandleErrInternal::from_chan_no_close(e, msg.common_fields.temporary_channel_id)
|
||||||
)?;
|
)?;
|
||||||
let mut pending_events = self.pending_events.lock().unwrap();
|
let mut pending_events = self.pending_events.lock().unwrap();
|
||||||
pending_events.push_back((events::Event::OpenChannelRequest {
|
pending_events.push_back((events::Event::OpenChannelRequest {
|
||||||
temporary_channel_id: msg.temporary_channel_id.clone(),
|
temporary_channel_id: msg.common_fields.temporary_channel_id.clone(),
|
||||||
counterparty_node_id: counterparty_node_id.clone(),
|
counterparty_node_id: counterparty_node_id.clone(),
|
||||||
funding_satoshis: msg.funding_satoshis,
|
funding_satoshis: msg.common_fields.funding_satoshis,
|
||||||
push_msat: msg.push_msat,
|
push_msat: msg.push_msat,
|
||||||
channel_type,
|
channel_type,
|
||||||
}, None));
|
}, None));
|
||||||
|
@ -6257,17 +6263,21 @@ where
|
||||||
&self.default_configuration, best_block_height, &self.logger, /*is_0conf=*/false)
|
&self.default_configuration, best_block_height, &self.logger, /*is_0conf=*/false)
|
||||||
{
|
{
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Err(MsgHandleErrInternal::from_chan_no_close(e, msg.temporary_channel_id));
|
return Err(MsgHandleErrInternal::from_chan_no_close(e, msg.common_fields.temporary_channel_id));
|
||||||
},
|
},
|
||||||
Ok(res) => res
|
Ok(res) => res
|
||||||
};
|
};
|
||||||
|
|
||||||
let channel_type = channel.context.get_channel_type();
|
let channel_type = channel.context.get_channel_type();
|
||||||
if channel_type.requires_zero_conf() {
|
if channel_type.requires_zero_conf() {
|
||||||
return Err(MsgHandleErrInternal::send_err_msg_no_close("No zero confirmation channels accepted".to_owned(), msg.temporary_channel_id.clone()));
|
return Err(MsgHandleErrInternal::send_err_msg_no_close(
|
||||||
|
"No zero confirmation channels accepted".to_owned(),
|
||||||
|
msg.common_fields.temporary_channel_id.clone()));
|
||||||
}
|
}
|
||||||
if channel_type.requires_anchors_zero_fee_htlc_tx() {
|
if channel_type.requires_anchors_zero_fee_htlc_tx() {
|
||||||
return Err(MsgHandleErrInternal::send_err_msg_no_close("No channels with anchor outputs accepted".to_owned(), msg.temporary_channel_id.clone()));
|
return Err(MsgHandleErrInternal::send_err_msg_no_close(
|
||||||
|
"No channels with anchor outputs accepted".to_owned(),
|
||||||
|
msg.common_fields.temporary_channel_id.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let outbound_scid_alias = self.create_and_insert_outbound_scid_alias();
|
let outbound_scid_alias = self.create_and_insert_outbound_scid_alias();
|
||||||
|
@ -8699,7 +8709,7 @@ where
|
||||||
fn handle_open_channel_v2(&self, counterparty_node_id: &PublicKey, msg: &msgs::OpenChannelV2) {
|
fn handle_open_channel_v2(&self, counterparty_node_id: &PublicKey, msg: &msgs::OpenChannelV2) {
|
||||||
let _: Result<(), _> = handle_error!(self, Err(MsgHandleErrInternal::send_err_msg_no_close(
|
let _: Result<(), _> = handle_error!(self, Err(MsgHandleErrInternal::send_err_msg_no_close(
|
||||||
"Dual-funded channels not supported".to_owned(),
|
"Dual-funded channels not supported".to_owned(),
|
||||||
msg.temporary_channel_id.clone())), *counterparty_node_id);
|
msg.common_fields.temporary_channel_id.clone())), *counterparty_node_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_accept_channel(&self, counterparty_node_id: &PublicKey, msg: &msgs::AcceptChannel) {
|
fn handle_accept_channel(&self, counterparty_node_id: &PublicKey, msg: &msgs::AcceptChannel) {
|
||||||
|
@ -11993,14 +12003,15 @@ mod tests {
|
||||||
check_added_monitors!(nodes[0], 1);
|
check_added_monitors!(nodes[0], 1);
|
||||||
expect_channel_pending_event(&nodes[0], &nodes[1].node.get_our_node_id());
|
expect_channel_pending_event(&nodes[0], &nodes[1].node.get_our_node_id());
|
||||||
}
|
}
|
||||||
open_channel_msg.temporary_channel_id = ChannelId::temporary_from_entropy_source(&nodes[0].keys_manager);
|
open_channel_msg.common_fields.temporary_channel_id = ChannelId::temporary_from_entropy_source(&nodes[0].keys_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
// A MAX_UNFUNDED_CHANS_PER_PEER + 1 channel will be summarily rejected
|
// A MAX_UNFUNDED_CHANS_PER_PEER + 1 channel will be summarily rejected
|
||||||
open_channel_msg.temporary_channel_id = ChannelId::temporary_from_entropy_source(&nodes[0].keys_manager);
|
open_channel_msg.common_fields.temporary_channel_id = ChannelId::temporary_from_entropy_source(
|
||||||
|
&nodes[0].keys_manager);
|
||||||
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
|
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
|
||||||
assert_eq!(get_err_msg(&nodes[1], &nodes[0].node.get_our_node_id()).channel_id,
|
assert_eq!(get_err_msg(&nodes[1], &nodes[0].node.get_our_node_id()).channel_id,
|
||||||
open_channel_msg.temporary_channel_id);
|
open_channel_msg.common_fields.temporary_channel_id);
|
||||||
|
|
||||||
// Further, because all of our channels with nodes[0] are inbound, and none of them funded,
|
// Further, because all of our channels with nodes[0] are inbound, and none of them funded,
|
||||||
// it doesn't count as a "protected" peer, i.e. it counts towards the MAX_NO_CHANNEL_PEERS
|
// it doesn't count as a "protected" peer, i.e. it counts towards the MAX_NO_CHANNEL_PEERS
|
||||||
|
@ -12048,11 +12059,11 @@ mod tests {
|
||||||
for i in 0..super::MAX_UNFUNDED_CHANNEL_PEERS - 1 {
|
for i in 0..super::MAX_UNFUNDED_CHANNEL_PEERS - 1 {
|
||||||
nodes[1].node.handle_open_channel(&peer_pks[i], &open_channel_msg);
|
nodes[1].node.handle_open_channel(&peer_pks[i], &open_channel_msg);
|
||||||
get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, peer_pks[i]);
|
get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, peer_pks[i]);
|
||||||
open_channel_msg.temporary_channel_id = ChannelId::temporary_from_entropy_source(&nodes[0].keys_manager);
|
open_channel_msg.common_fields.temporary_channel_id = ChannelId::temporary_from_entropy_source(&nodes[0].keys_manager);
|
||||||
}
|
}
|
||||||
nodes[1].node.handle_open_channel(&last_random_pk, &open_channel_msg);
|
nodes[1].node.handle_open_channel(&last_random_pk, &open_channel_msg);
|
||||||
assert_eq!(get_err_msg(&nodes[1], &last_random_pk).channel_id,
|
assert_eq!(get_err_msg(&nodes[1], &last_random_pk).channel_id,
|
||||||
open_channel_msg.temporary_channel_id);
|
open_channel_msg.common_fields.temporary_channel_id);
|
||||||
|
|
||||||
// Of course, however, outbound channels are always allowed
|
// Of course, however, outbound channels are always allowed
|
||||||
nodes[1].node.create_channel(last_random_pk, 100_000, 0, 42, None, None).unwrap();
|
nodes[1].node.create_channel(last_random_pk, 100_000, 0, 42, None, None).unwrap();
|
||||||
|
@ -12088,14 +12099,14 @@ mod tests {
|
||||||
for _ in 0..super::MAX_UNFUNDED_CHANS_PER_PEER {
|
for _ in 0..super::MAX_UNFUNDED_CHANS_PER_PEER {
|
||||||
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
|
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
|
||||||
get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
|
get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
|
||||||
open_channel_msg.temporary_channel_id = ChannelId::temporary_from_entropy_source(&nodes[0].keys_manager);
|
open_channel_msg.common_fields.temporary_channel_id = ChannelId::temporary_from_entropy_source(&nodes[0].keys_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Once we have MAX_UNFUNDED_CHANS_PER_PEER unfunded channels, new inbound channels will be
|
// Once we have MAX_UNFUNDED_CHANS_PER_PEER unfunded channels, new inbound channels will be
|
||||||
// rejected.
|
// rejected.
|
||||||
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
|
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
|
||||||
assert_eq!(get_err_msg(&nodes[1], &nodes[0].node.get_our_node_id()).channel_id,
|
assert_eq!(get_err_msg(&nodes[1], &nodes[0].node.get_our_node_id()).channel_id,
|
||||||
open_channel_msg.temporary_channel_id);
|
open_channel_msg.common_fields.temporary_channel_id);
|
||||||
|
|
||||||
// but we can still open an outbound channel.
|
// but we can still open an outbound channel.
|
||||||
nodes[1].node.create_channel(nodes[0].node.get_our_node_id(), 100_000, 0, 42, None, None).unwrap();
|
nodes[1].node.create_channel(nodes[0].node.get_our_node_id(), 100_000, 0, 42, None, None).unwrap();
|
||||||
|
@ -12104,7 +12115,7 @@ mod tests {
|
||||||
// but even with such an outbound channel, additional inbound channels will still fail.
|
// but even with such an outbound channel, additional inbound channels will still fail.
|
||||||
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
|
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
|
||||||
assert_eq!(get_err_msg(&nodes[1], &nodes[0].node.get_our_node_id()).channel_id,
|
assert_eq!(get_err_msg(&nodes[1], &nodes[0].node.get_our_node_id()).channel_id,
|
||||||
open_channel_msg.temporary_channel_id);
|
open_channel_msg.common_fields.temporary_channel_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -12140,7 +12151,7 @@ mod tests {
|
||||||
_ => panic!("Unexpected event"),
|
_ => panic!("Unexpected event"),
|
||||||
}
|
}
|
||||||
get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, random_pk);
|
get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, random_pk);
|
||||||
open_channel_msg.temporary_channel_id = ChannelId::temporary_from_entropy_source(&nodes[0].keys_manager);
|
open_channel_msg.common_fields.temporary_channel_id = ChannelId::temporary_from_entropy_source(&nodes[0].keys_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we try to accept a channel from another peer non-0conf it will fail.
|
// If we try to accept a channel from another peer non-0conf it will fail.
|
||||||
|
@ -12162,7 +12173,7 @@ mod tests {
|
||||||
_ => panic!("Unexpected event"),
|
_ => panic!("Unexpected event"),
|
||||||
}
|
}
|
||||||
assert_eq!(get_err_msg(&nodes[1], &last_random_pk).channel_id,
|
assert_eq!(get_err_msg(&nodes[1], &last_random_pk).channel_id,
|
||||||
open_channel_msg.temporary_channel_id);
|
open_channel_msg.common_fields.temporary_channel_id);
|
||||||
|
|
||||||
// ...however if we accept the same channel 0conf it should work just fine.
|
// ...however if we accept the same channel 0conf it should work just fine.
|
||||||
nodes[1].node.handle_open_channel(&last_random_pk, &open_channel_msg);
|
nodes[1].node.handle_open_channel(&last_random_pk, &open_channel_msg);
|
||||||
|
@ -12307,7 +12318,7 @@ mod tests {
|
||||||
|
|
||||||
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100_000, 0, 0, None, None).unwrap();
|
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100_000, 0, 0, None, None).unwrap();
|
||||||
let open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
let open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
||||||
assert!(open_channel_msg.channel_type.as_ref().unwrap().supports_anchors_zero_fee_htlc_tx());
|
assert!(open_channel_msg.common_fields.channel_type.as_ref().unwrap().supports_anchors_zero_fee_htlc_tx());
|
||||||
|
|
||||||
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
|
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
|
||||||
let events = nodes[1].node.get_and_clear_pending_events();
|
let events = nodes[1].node.get_and_clear_pending_events();
|
||||||
|
@ -12322,7 +12333,7 @@ mod tests {
|
||||||
nodes[0].node.handle_error(&nodes[1].node.get_our_node_id(), &error_msg);
|
nodes[0].node.handle_error(&nodes[1].node.get_our_node_id(), &error_msg);
|
||||||
|
|
||||||
let open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
let open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
||||||
assert!(!open_channel_msg.channel_type.unwrap().supports_anchors_zero_fee_htlc_tx());
|
assert!(!open_channel_msg.common_fields.channel_type.unwrap().supports_anchors_zero_fee_htlc_tx());
|
||||||
|
|
||||||
// Since nodes[1] should not have accepted the channel, it should
|
// Since nodes[1] should not have accepted the channel, it should
|
||||||
// not have generated any events.
|
// not have generated any events.
|
||||||
|
|
|
@ -1257,7 +1257,7 @@ pub fn open_zero_conf_channel<'a, 'b, 'c, 'd>(initiator: &'a Node<'b, 'c, 'd>, r
|
||||||
pub fn exchange_open_accept_chan<'a, 'b, 'c>(node_a: &Node<'a, 'b, 'c>, node_b: &Node<'a, 'b, 'c>, channel_value: u64, push_msat: u64) -> ChannelId {
|
pub fn exchange_open_accept_chan<'a, 'b, 'c>(node_a: &Node<'a, 'b, 'c>, node_b: &Node<'a, 'b, 'c>, channel_value: u64, push_msat: u64) -> ChannelId {
|
||||||
let create_chan_id = node_a.node.create_channel(node_b.node.get_our_node_id(), channel_value, push_msat, 42, None, None).unwrap();
|
let create_chan_id = node_a.node.create_channel(node_b.node.get_our_node_id(), channel_value, push_msat, 42, None, None).unwrap();
|
||||||
let open_channel_msg = get_event_msg!(node_a, MessageSendEvent::SendOpenChannel, node_b.node.get_our_node_id());
|
let open_channel_msg = get_event_msg!(node_a, MessageSendEvent::SendOpenChannel, node_b.node.get_our_node_id());
|
||||||
assert_eq!(open_channel_msg.temporary_channel_id, create_chan_id);
|
assert_eq!(open_channel_msg.common_fields.temporary_channel_id, create_chan_id);
|
||||||
assert_eq!(node_a.node.list_channels().iter().find(|channel| channel.channel_id == create_chan_id).unwrap().user_channel_id, 42);
|
assert_eq!(node_a.node.list_channels().iter().find(|channel| channel.channel_id == create_chan_id).unwrap().user_channel_id, 42);
|
||||||
node_b.node.handle_open_channel(&node_a.node.get_our_node_id(), &open_channel_msg);
|
node_b.node.handle_open_channel(&node_a.node.get_our_node_id(), &open_channel_msg);
|
||||||
if node_b.node.get_current_default_configuration().manually_accept_inbound_channels {
|
if node_b.node.get_current_default_configuration().manually_accept_inbound_channels {
|
||||||
|
|
|
@ -107,22 +107,22 @@ fn test_insane_channel_opens() {
|
||||||
use crate::ln::channelmanager::MAX_LOCAL_BREAKDOWN_TIMEOUT;
|
use crate::ln::channelmanager::MAX_LOCAL_BREAKDOWN_TIMEOUT;
|
||||||
|
|
||||||
// Test all mutations that would make the channel open message insane
|
// Test all mutations that would make the channel open message insane
|
||||||
insane_open_helper(format!("Per our config, funding must be at most {}. It was {}", TOTAL_BITCOIN_SUPPLY_SATOSHIS + 1, TOTAL_BITCOIN_SUPPLY_SATOSHIS + 2).as_str(), |mut msg| { msg.funding_satoshis = TOTAL_BITCOIN_SUPPLY_SATOSHIS + 2; msg });
|
insane_open_helper(format!("Per our config, funding must be at most {}. It was {}", TOTAL_BITCOIN_SUPPLY_SATOSHIS + 1, TOTAL_BITCOIN_SUPPLY_SATOSHIS + 2).as_str(), |mut msg| { msg.common_fields.funding_satoshis = TOTAL_BITCOIN_SUPPLY_SATOSHIS + 2; msg });
|
||||||
insane_open_helper(format!("Funding must be smaller than the total bitcoin supply. It was {}", TOTAL_BITCOIN_SUPPLY_SATOSHIS).as_str(), |mut msg| { msg.funding_satoshis = TOTAL_BITCOIN_SUPPLY_SATOSHIS; msg });
|
insane_open_helper(format!("Funding must be smaller than the total bitcoin supply. It was {}", TOTAL_BITCOIN_SUPPLY_SATOSHIS).as_str(), |mut msg| { msg.common_fields.funding_satoshis = TOTAL_BITCOIN_SUPPLY_SATOSHIS; msg });
|
||||||
|
|
||||||
insane_open_helper("Bogus channel_reserve_satoshis", |mut msg| { msg.channel_reserve_satoshis = msg.funding_satoshis + 1; msg });
|
insane_open_helper("Bogus channel_reserve_satoshis", |mut msg| { msg.channel_reserve_satoshis = msg.common_fields.funding_satoshis + 1; msg });
|
||||||
|
|
||||||
insane_open_helper(r"push_msat \d+ was larger than channel amount minus reserve \(\d+\)", |mut msg| { msg.push_msat = (msg.funding_satoshis - msg.channel_reserve_satoshis) * 1000 + 1; msg });
|
insane_open_helper(r"push_msat \d+ was larger than channel amount minus reserve \(\d+\)", |mut msg| { msg.push_msat = (msg.common_fields.funding_satoshis - msg.channel_reserve_satoshis) * 1000 + 1; msg });
|
||||||
|
|
||||||
insane_open_helper("Peer never wants payout outputs?", |mut msg| { msg.dust_limit_satoshis = msg.funding_satoshis + 1 ; msg });
|
insane_open_helper("Peer never wants payout outputs?", |mut msg| { msg.common_fields.dust_limit_satoshis = msg.common_fields.funding_satoshis + 1 ; msg });
|
||||||
|
|
||||||
insane_open_helper(r"Minimum htlc value \(\d+\) was larger than full channel value \(\d+\)", |mut msg| { msg.htlc_minimum_msat = (msg.funding_satoshis - msg.channel_reserve_satoshis) * 1000; msg });
|
insane_open_helper(r"Minimum htlc value \(\d+\) was larger than full channel value \(\d+\)", |mut msg| { msg.common_fields.htlc_minimum_msat = (msg.common_fields.funding_satoshis - msg.channel_reserve_satoshis) * 1000; msg });
|
||||||
|
|
||||||
insane_open_helper("They wanted our payments to be delayed by a needlessly long period", |mut msg| { msg.to_self_delay = MAX_LOCAL_BREAKDOWN_TIMEOUT + 1; msg });
|
insane_open_helper("They wanted our payments to be delayed by a needlessly long period", |mut msg| { msg.common_fields.to_self_delay = MAX_LOCAL_BREAKDOWN_TIMEOUT + 1; msg });
|
||||||
|
|
||||||
insane_open_helper("0 max_accepted_htlcs makes for a useless channel", |mut msg| { msg.max_accepted_htlcs = 0; msg });
|
insane_open_helper("0 max_accepted_htlcs makes for a useless channel", |mut msg| { msg.common_fields.max_accepted_htlcs = 0; msg });
|
||||||
|
|
||||||
insane_open_helper("max_accepted_htlcs was 484. It must not be larger than 483", |mut msg| { msg.max_accepted_htlcs = 484; msg });
|
insane_open_helper("max_accepted_htlcs was 484. It must not be larger than 483", |mut msg| { msg.common_fields.max_accepted_htlcs = 484; msg });
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -166,7 +166,7 @@ fn do_test_counterparty_no_reserve(send_from_initiator: bool) {
|
||||||
let mut open_channel_message = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
let mut open_channel_message = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
||||||
if !send_from_initiator {
|
if !send_from_initiator {
|
||||||
open_channel_message.channel_reserve_satoshis = 0;
|
open_channel_message.channel_reserve_satoshis = 0;
|
||||||
open_channel_message.max_htlc_value_in_flight_msat = 100_000_000;
|
open_channel_message.common_fields.max_htlc_value_in_flight_msat = 100_000_000;
|
||||||
}
|
}
|
||||||
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_message);
|
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_message);
|
||||||
|
|
||||||
|
@ -5834,26 +5834,26 @@ fn bolt2_open_channel_sending_node_checks_part2() {
|
||||||
let push_msat=10001;
|
let push_msat=10001;
|
||||||
assert!(nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), channel_value_satoshis, push_msat, 42, None, None).is_ok()); //Create a valid channel
|
assert!(nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), channel_value_satoshis, push_msat, 42, None, None).is_ok()); //Create a valid channel
|
||||||
let node0_to_1_send_open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
let node0_to_1_send_open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
||||||
assert!(node0_to_1_send_open_channel.channel_reserve_satoshis>=node0_to_1_send_open_channel.dust_limit_satoshis);
|
assert!(node0_to_1_send_open_channel.channel_reserve_satoshis>=node0_to_1_send_open_channel.common_fields.dust_limit_satoshis);
|
||||||
|
|
||||||
// BOLT #2 spec: Sending node must set undefined bits in channel_flags to 0
|
// BOLT #2 spec: Sending node must set undefined bits in channel_flags to 0
|
||||||
// Only the least-significant bit of channel_flags is currently defined resulting in channel_flags only having one of two possible states 0 or 1
|
// Only the least-significant bit of channel_flags is currently defined resulting in channel_flags only having one of two possible states 0 or 1
|
||||||
assert!(node0_to_1_send_open_channel.channel_flags<=1);
|
assert!(node0_to_1_send_open_channel.common_fields.channel_flags<=1);
|
||||||
|
|
||||||
// BOLT #2 spec: Sending node should set to_self_delay sufficient to ensure the sender can irreversibly spend a commitment transaction output, in case of misbehaviour by the receiver.
|
// BOLT #2 spec: Sending node should set to_self_delay sufficient to ensure the sender can irreversibly spend a commitment transaction output, in case of misbehaviour by the receiver.
|
||||||
assert!(BREAKDOWN_TIMEOUT>0);
|
assert!(BREAKDOWN_TIMEOUT>0);
|
||||||
assert!(node0_to_1_send_open_channel.to_self_delay==BREAKDOWN_TIMEOUT);
|
assert!(node0_to_1_send_open_channel.common_fields.to_self_delay==BREAKDOWN_TIMEOUT);
|
||||||
|
|
||||||
// BOLT #2 spec: Sending node must ensure the chain_hash value identifies the chain it wishes to open the channel within.
|
// BOLT #2 spec: Sending node must ensure the chain_hash value identifies the chain it wishes to open the channel within.
|
||||||
let chain_hash = ChainHash::using_genesis_block(Network::Testnet);
|
let chain_hash = ChainHash::using_genesis_block(Network::Testnet);
|
||||||
assert_eq!(node0_to_1_send_open_channel.chain_hash, chain_hash);
|
assert_eq!(node0_to_1_send_open_channel.common_fields.chain_hash, chain_hash);
|
||||||
|
|
||||||
// BOLT #2 spec: Sending node must set funding_pubkey, revocation_basepoint, htlc_basepoint, payment_basepoint, and delayed_payment_basepoint to valid DER-encoded, compressed, secp256k1 pubkeys.
|
// BOLT #2 spec: Sending node must set funding_pubkey, revocation_basepoint, htlc_basepoint, payment_basepoint, and delayed_payment_basepoint to valid DER-encoded, compressed, secp256k1 pubkeys.
|
||||||
assert!(PublicKey::from_slice(&node0_to_1_send_open_channel.funding_pubkey.serialize()).is_ok());
|
assert!(PublicKey::from_slice(&node0_to_1_send_open_channel.common_fields.funding_pubkey.serialize()).is_ok());
|
||||||
assert!(PublicKey::from_slice(&node0_to_1_send_open_channel.revocation_basepoint.serialize()).is_ok());
|
assert!(PublicKey::from_slice(&node0_to_1_send_open_channel.common_fields.revocation_basepoint.serialize()).is_ok());
|
||||||
assert!(PublicKey::from_slice(&node0_to_1_send_open_channel.htlc_basepoint.serialize()).is_ok());
|
assert!(PublicKey::from_slice(&node0_to_1_send_open_channel.common_fields.htlc_basepoint.serialize()).is_ok());
|
||||||
assert!(PublicKey::from_slice(&node0_to_1_send_open_channel.payment_point.serialize()).is_ok());
|
assert!(PublicKey::from_slice(&node0_to_1_send_open_channel.common_fields.payment_basepoint.serialize()).is_ok());
|
||||||
assert!(PublicKey::from_slice(&node0_to_1_send_open_channel.delayed_payment_basepoint.serialize()).is_ok());
|
assert!(PublicKey::from_slice(&node0_to_1_send_open_channel.common_fields.delayed_payment_basepoint.serialize()).is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -5867,7 +5867,7 @@ fn bolt2_open_channel_sane_dust_limit() {
|
||||||
let push_msat=10001;
|
let push_msat=10001;
|
||||||
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), channel_value_satoshis, push_msat, 42, None, None).unwrap();
|
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), channel_value_satoshis, push_msat, 42, None, None).unwrap();
|
||||||
let mut node0_to_1_send_open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
let mut node0_to_1_send_open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
||||||
node0_to_1_send_open_channel.dust_limit_satoshis = 547;
|
node0_to_1_send_open_channel.common_fields.dust_limit_satoshis = 547;
|
||||||
node0_to_1_send_open_channel.channel_reserve_satoshis = 100001;
|
node0_to_1_send_open_channel.channel_reserve_satoshis = 100001;
|
||||||
|
|
||||||
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &node0_to_1_send_open_channel);
|
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &node0_to_1_send_open_channel);
|
||||||
|
@ -7207,7 +7207,7 @@ fn test_user_configurable_csv_delay() {
|
||||||
// We test config.our_to_self > BREAKDOWN_TIMEOUT is enforced in InboundV1Channel::new()
|
// We test config.our_to_self > BREAKDOWN_TIMEOUT is enforced in InboundV1Channel::new()
|
||||||
nodes[1].node.create_channel(nodes[0].node.get_our_node_id(), 1000000, 1000000, 42, None, None).unwrap();
|
nodes[1].node.create_channel(nodes[0].node.get_our_node_id(), 1000000, 1000000, 42, None, None).unwrap();
|
||||||
let mut open_channel = get_event_msg!(nodes[1], MessageSendEvent::SendOpenChannel, nodes[0].node.get_our_node_id());
|
let mut open_channel = get_event_msg!(nodes[1], MessageSendEvent::SendOpenChannel, nodes[0].node.get_our_node_id());
|
||||||
open_channel.to_self_delay = 200;
|
open_channel.common_fields.to_self_delay = 200;
|
||||||
if let Err(error) = InboundV1Channel::new(&LowerBoundedFeeEstimator::new(&test_utils::TestFeeEstimator { sat_per_kw: Mutex::new(253) }),
|
if let Err(error) = InboundV1Channel::new(&LowerBoundedFeeEstimator::new(&test_utils::TestFeeEstimator { sat_per_kw: Mutex::new(253) }),
|
||||||
&nodes[0].keys_manager, &nodes[0].keys_manager, nodes[1].node.get_our_node_id(), &nodes[0].node.channel_type_features(), &nodes[1].node.init_features(), &open_channel, 0,
|
&nodes[0].keys_manager, &nodes[0].keys_manager, nodes[1].node.get_our_node_id(), &nodes[0].node.channel_type_features(), &nodes[1].node.init_features(), &open_channel, 0,
|
||||||
&low_our_to_self_config, 0, &nodes[0].logger, /*is_0conf=*/false)
|
&low_our_to_self_config, 0, &nodes[0].logger, /*is_0conf=*/false)
|
||||||
|
@ -7239,7 +7239,7 @@ fn test_user_configurable_csv_delay() {
|
||||||
// We test msg.to_self_delay <= config.their_to_self_delay is enforced in InboundV1Channel::new()
|
// We test msg.to_self_delay <= config.their_to_self_delay is enforced in InboundV1Channel::new()
|
||||||
nodes[1].node.create_channel(nodes[0].node.get_our_node_id(), 1000000, 1000000, 42, None, None).unwrap();
|
nodes[1].node.create_channel(nodes[0].node.get_our_node_id(), 1000000, 1000000, 42, None, None).unwrap();
|
||||||
let mut open_channel = get_event_msg!(nodes[1], MessageSendEvent::SendOpenChannel, nodes[0].node.get_our_node_id());
|
let mut open_channel = get_event_msg!(nodes[1], MessageSendEvent::SendOpenChannel, nodes[0].node.get_our_node_id());
|
||||||
open_channel.to_self_delay = 200;
|
open_channel.common_fields.to_self_delay = 200;
|
||||||
if let Err(error) = InboundV1Channel::new(&LowerBoundedFeeEstimator::new(&test_utils::TestFeeEstimator { sat_per_kw: Mutex::new(253) }),
|
if let Err(error) = InboundV1Channel::new(&LowerBoundedFeeEstimator::new(&test_utils::TestFeeEstimator { sat_per_kw: Mutex::new(253) }),
|
||||||
&nodes[0].keys_manager, &nodes[0].keys_manager, nodes[1].node.get_our_node_id(), &nodes[0].node.channel_type_features(), &nodes[1].node.init_features(), &open_channel, 0,
|
&nodes[0].keys_manager, &nodes[0].keys_manager, nodes[1].node.get_our_node_id(), &nodes[0].node.channel_type_features(), &nodes[1].node.init_features(), &open_channel, 0,
|
||||||
&high_their_to_self_config, 0, &nodes[0].logger, /*is_0conf=*/false)
|
&high_their_to_self_config, 0, &nodes[0].logger, /*is_0conf=*/false)
|
||||||
|
@ -7924,8 +7924,8 @@ fn test_override_channel_config() {
|
||||||
|
|
||||||
// Assert the channel created by node0 is using the override config.
|
// Assert the channel created by node0 is using the override config.
|
||||||
let res = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
let res = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
||||||
assert_eq!(res.channel_flags, 0);
|
assert_eq!(res.common_fields.channel_flags, 0);
|
||||||
assert_eq!(res.to_self_delay, 200);
|
assert_eq!(res.common_fields.to_self_delay, 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -7939,7 +7939,7 @@ fn test_override_0msat_htlc_minimum() {
|
||||||
|
|
||||||
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 16_000_000, 12_000_000, 42, None, Some(zero_config)).unwrap();
|
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 16_000_000, 12_000_000, 42, None, Some(zero_config)).unwrap();
|
||||||
let res = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
let res = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
||||||
assert_eq!(res.htlc_minimum_msat, 1);
|
assert_eq!(res.common_fields.htlc_minimum_msat, 1);
|
||||||
|
|
||||||
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &res);
|
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &res);
|
||||||
let res = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
|
let res = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
|
||||||
|
@ -8955,7 +8955,7 @@ fn test_duplicate_temporary_channel_id_from_different_peers() {
|
||||||
|
|
||||||
// Modify the `OpenChannel` from `nodes[2]` to `nodes[0]` to ensure that it uses the same
|
// Modify the `OpenChannel` from `nodes[2]` to `nodes[0]` to ensure that it uses the same
|
||||||
// `temporary_channel_id` as the `OpenChannel` from nodes[1] to nodes[0].
|
// `temporary_channel_id` as the `OpenChannel` from nodes[1] to nodes[0].
|
||||||
open_chan_msg_chan_2_0.temporary_channel_id = open_chan_msg_chan_1_0.temporary_channel_id;
|
open_chan_msg_chan_2_0.common_fields.temporary_channel_id = open_chan_msg_chan_1_0.common_fields.temporary_channel_id;
|
||||||
|
|
||||||
// Assert that `nodes[0]` can accept both `OpenChannel` requests, even though they use the same
|
// Assert that `nodes[0]` can accept both `OpenChannel` requests, even though they use the same
|
||||||
// `temporary_channel_id` as they are from different peers.
|
// `temporary_channel_id` as they are from different peers.
|
||||||
|
@ -8966,7 +8966,7 @@ fn test_duplicate_temporary_channel_id_from_different_peers() {
|
||||||
match &events[0] {
|
match &events[0] {
|
||||||
MessageSendEvent::SendAcceptChannel { node_id, msg } => {
|
MessageSendEvent::SendAcceptChannel { node_id, msg } => {
|
||||||
assert_eq!(node_id, &nodes[1].node.get_our_node_id());
|
assert_eq!(node_id, &nodes[1].node.get_our_node_id());
|
||||||
assert_eq!(msg.temporary_channel_id, open_chan_msg_chan_1_0.temporary_channel_id);
|
assert_eq!(msg.temporary_channel_id, open_chan_msg_chan_1_0.common_fields.temporary_channel_id);
|
||||||
},
|
},
|
||||||
_ => panic!("Unexpected event"),
|
_ => panic!("Unexpected event"),
|
||||||
}
|
}
|
||||||
|
@ -8979,7 +8979,7 @@ fn test_duplicate_temporary_channel_id_from_different_peers() {
|
||||||
match &events[0] {
|
match &events[0] {
|
||||||
MessageSendEvent::SendAcceptChannel { node_id, msg } => {
|
MessageSendEvent::SendAcceptChannel { node_id, msg } => {
|
||||||
assert_eq!(node_id, &nodes[2].node.get_our_node_id());
|
assert_eq!(node_id, &nodes[2].node.get_our_node_id());
|
||||||
assert_eq!(msg.temporary_channel_id, open_chan_msg_chan_1_0.temporary_channel_id);
|
assert_eq!(msg.temporary_channel_id, open_chan_msg_chan_1_0.common_fields.temporary_channel_id);
|
||||||
},
|
},
|
||||||
_ => panic!("Unexpected event"),
|
_ => panic!("Unexpected event"),
|
||||||
}
|
}
|
||||||
|
@ -9099,8 +9099,8 @@ fn test_duplicate_funding_err_in_funding() {
|
||||||
|
|
||||||
nodes[2].node.create_channel(nodes[1].node.get_our_node_id(), 100_000, 0, 42, None, None).unwrap();
|
nodes[2].node.create_channel(nodes[1].node.get_our_node_id(), 100_000, 0, 42, None, None).unwrap();
|
||||||
let mut open_chan_msg = get_event_msg!(nodes[2], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
let mut open_chan_msg = get_event_msg!(nodes[2], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
||||||
let node_c_temp_chan_id = open_chan_msg.temporary_channel_id;
|
let node_c_temp_chan_id = open_chan_msg.common_fields.temporary_channel_id;
|
||||||
open_chan_msg.temporary_channel_id = real_channel_id;
|
open_chan_msg.common_fields.temporary_channel_id = real_channel_id;
|
||||||
nodes[1].node.handle_open_channel(&nodes[2].node.get_our_node_id(), &open_chan_msg);
|
nodes[1].node.handle_open_channel(&nodes[2].node.get_our_node_id(), &open_chan_msg);
|
||||||
let mut accept_chan_msg = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[2].node.get_our_node_id());
|
let mut accept_chan_msg = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[2].node.get_our_node_id());
|
||||||
accept_chan_msg.temporary_channel_id = node_c_temp_chan_id;
|
accept_chan_msg.temporary_channel_id = node_c_temp_chan_id;
|
||||||
|
@ -9161,7 +9161,7 @@ fn test_duplicate_chan_id() {
|
||||||
// first (valid) and second (invalid) channels are closed, given they both have
|
// first (valid) and second (invalid) channels are closed, given they both have
|
||||||
// the same non-temporary channel_id. However, currently we do not, so we just
|
// the same non-temporary channel_id. However, currently we do not, so we just
|
||||||
// move forward with it.
|
// move forward with it.
|
||||||
assert_eq!(msg.channel_id, open_chan_msg.temporary_channel_id);
|
assert_eq!(msg.channel_id, open_chan_msg.common_fields.temporary_channel_id);
|
||||||
assert_eq!(node_id, nodes[0].node.get_our_node_id());
|
assert_eq!(node_id, nodes[0].node.get_our_node_id());
|
||||||
},
|
},
|
||||||
_ => panic!("Unexpected event"),
|
_ => panic!("Unexpected event"),
|
||||||
|
@ -9195,7 +9195,7 @@ fn test_duplicate_chan_id() {
|
||||||
// First try to open a second channel with a temporary channel id equal to the txid-based one.
|
// First try to open a second channel with a temporary channel id equal to the txid-based one.
|
||||||
// Technically this is allowed by the spec, but we don't support it and there's little reason
|
// Technically this is allowed by the spec, but we don't support it and there's little reason
|
||||||
// to. Still, it shouldn't cause any other issues.
|
// to. Still, it shouldn't cause any other issues.
|
||||||
open_chan_msg.temporary_channel_id = channel_id;
|
open_chan_msg.common_fields.temporary_channel_id = channel_id;
|
||||||
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_chan_msg);
|
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_chan_msg);
|
||||||
{
|
{
|
||||||
let events = nodes[1].node.get_and_clear_pending_msg_events();
|
let events = nodes[1].node.get_and_clear_pending_msg_events();
|
||||||
|
@ -9204,7 +9204,7 @@ fn test_duplicate_chan_id() {
|
||||||
MessageSendEvent::HandleError { action: ErrorAction::SendErrorMessage { ref msg }, node_id } => {
|
MessageSendEvent::HandleError { action: ErrorAction::SendErrorMessage { ref msg }, node_id } => {
|
||||||
// Technically, at this point, nodes[1] would be justified in thinking both
|
// Technically, at this point, nodes[1] would be justified in thinking both
|
||||||
// channels are closed, but currently we do not, so we just move forward with it.
|
// channels are closed, but currently we do not, so we just move forward with it.
|
||||||
assert_eq!(msg.channel_id, open_chan_msg.temporary_channel_id);
|
assert_eq!(msg.channel_id, open_chan_msg.common_fields.temporary_channel_id);
|
||||||
assert_eq!(node_id, nodes[0].node.get_our_node_id());
|
assert_eq!(node_id, nodes[0].node.get_our_node_id());
|
||||||
},
|
},
|
||||||
_ => panic!("Unexpected event"),
|
_ => panic!("Unexpected event"),
|
||||||
|
@ -9225,7 +9225,7 @@ fn test_duplicate_chan_id() {
|
||||||
// another channel in the ChannelManager - an invalid state. Thus, we'd panic later when we
|
// another channel in the ChannelManager - an invalid state. Thus, we'd panic later when we
|
||||||
// try to create another channel. Instead, we drop the channel entirely here (leaving the
|
// try to create another channel. Instead, we drop the channel entirely here (leaving the
|
||||||
// channelmanager in a possibly nonsense state instead).
|
// channelmanager in a possibly nonsense state instead).
|
||||||
match a_peer_state.channel_by_id.remove(&open_chan_2_msg.temporary_channel_id).unwrap() {
|
match a_peer_state.channel_by_id.remove(&open_chan_2_msg.common_fields.temporary_channel_id).unwrap() {
|
||||||
ChannelPhase::UnfundedOutboundV1(mut chan) => {
|
ChannelPhase::UnfundedOutboundV1(mut chan) => {
|
||||||
let logger = test_utils::TestLogger::new();
|
let logger = test_utils::TestLogger::new();
|
||||||
chan.get_funding_created(tx.clone(), funding_outpoint, false, &&logger).map_err(|_| ()).unwrap()
|
chan.get_funding_created(tx.clone(), funding_outpoint, false, &&logger).map_err(|_| ()).unwrap()
|
||||||
|
@ -9892,10 +9892,10 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
|
||||||
|
|
||||||
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 1_000_000, 500_000_000, 42, None, None).unwrap();
|
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 1_000_000, 500_000_000, 42, None, None).unwrap();
|
||||||
let mut open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
let mut open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
||||||
open_channel.max_htlc_value_in_flight_msat = 50_000_000;
|
open_channel.common_fields.max_htlc_value_in_flight_msat = 50_000_000;
|
||||||
open_channel.max_accepted_htlcs = 60;
|
open_channel.common_fields.max_accepted_htlcs = 60;
|
||||||
if on_holder_tx {
|
if on_holder_tx {
|
||||||
open_channel.dust_limit_satoshis = 546;
|
open_channel.common_fields.dust_limit_satoshis = 546;
|
||||||
}
|
}
|
||||||
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel);
|
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel);
|
||||||
let mut accept_channel = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
|
let mut accept_channel = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
|
||||||
|
@ -9940,10 +9940,10 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
|
||||||
(chan.context().get_dust_buffer_feerate(None) as u64,
|
(chan.context().get_dust_buffer_feerate(None) as u64,
|
||||||
chan.context().get_max_dust_htlc_exposure_msat(&LowerBoundedFeeEstimator(nodes[0].fee_estimator)))
|
chan.context().get_max_dust_htlc_exposure_msat(&LowerBoundedFeeEstimator(nodes[0].fee_estimator)))
|
||||||
};
|
};
|
||||||
let dust_outbound_htlc_on_holder_tx_msat: u64 = (dust_buffer_feerate * htlc_timeout_tx_weight(&channel_type_features) / 1000 + open_channel.dust_limit_satoshis - 1) * 1000;
|
let dust_outbound_htlc_on_holder_tx_msat: u64 = (dust_buffer_feerate * htlc_timeout_tx_weight(&channel_type_features) / 1000 + open_channel.common_fields.dust_limit_satoshis - 1) * 1000;
|
||||||
let dust_outbound_htlc_on_holder_tx: u64 = max_dust_htlc_exposure_msat / dust_outbound_htlc_on_holder_tx_msat;
|
let dust_outbound_htlc_on_holder_tx: u64 = max_dust_htlc_exposure_msat / dust_outbound_htlc_on_holder_tx_msat;
|
||||||
|
|
||||||
let dust_inbound_htlc_on_holder_tx_msat: u64 = (dust_buffer_feerate * htlc_success_tx_weight(&channel_type_features) / 1000 + open_channel.dust_limit_satoshis - 1) * 1000;
|
let dust_inbound_htlc_on_holder_tx_msat: u64 = (dust_buffer_feerate * htlc_success_tx_weight(&channel_type_features) / 1000 + open_channel.common_fields.dust_limit_satoshis - 1) * 1000;
|
||||||
let dust_inbound_htlc_on_holder_tx: u64 = max_dust_htlc_exposure_msat / dust_inbound_htlc_on_holder_tx_msat;
|
let dust_inbound_htlc_on_holder_tx: u64 = max_dust_htlc_exposure_msat / dust_inbound_htlc_on_holder_tx_msat;
|
||||||
|
|
||||||
let dust_htlc_on_counterparty_tx: u64 = 4;
|
let dust_htlc_on_counterparty_tx: u64 = 4;
|
||||||
|
|
|
@ -172,76 +172,20 @@ pub struct Pong {
|
||||||
pub byteslen: u16,
|
pub byteslen: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An [`open_channel`] message to be sent to or received from a peer.
|
/// Contains fields that are both common to [`open_channel`] and `open_channel2` messages.
|
||||||
///
|
|
||||||
/// Used in V1 channel establishment
|
|
||||||
///
|
///
|
||||||
/// [`open_channel`]: https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#the-open_channel-message
|
/// [`open_channel`]: https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#the-open_channel-message
|
||||||
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
|
||||||
pub struct OpenChannel {
|
|
||||||
/// The genesis hash of the blockchain where the channel is to be opened
|
|
||||||
pub chain_hash: ChainHash,
|
|
||||||
/// A temporary channel ID, until the funding outpoint is announced
|
|
||||||
pub temporary_channel_id: ChannelId,
|
|
||||||
/// The channel value
|
|
||||||
pub funding_satoshis: u64,
|
|
||||||
/// The amount to push to the counterparty as part of the open, in milli-satoshi
|
|
||||||
pub push_msat: u64,
|
|
||||||
/// The threshold below which outputs on transactions broadcast by sender will be omitted
|
|
||||||
pub dust_limit_satoshis: u64,
|
|
||||||
/// The maximum inbound HTLC value in flight towards sender, in milli-satoshi
|
|
||||||
pub max_htlc_value_in_flight_msat: u64,
|
|
||||||
/// The minimum value unencumbered by HTLCs for the counterparty to keep in the channel
|
|
||||||
pub channel_reserve_satoshis: u64,
|
|
||||||
/// The minimum HTLC size incoming to sender, in milli-satoshi
|
|
||||||
pub htlc_minimum_msat: u64,
|
|
||||||
/// The feerate per 1000-weight of sender generated transactions, until updated by
|
|
||||||
/// [`UpdateFee`]
|
|
||||||
pub feerate_per_kw: u32,
|
|
||||||
/// The number of blocks which the counterparty will have to wait to claim on-chain funds if
|
|
||||||
/// they broadcast a commitment transaction
|
|
||||||
pub to_self_delay: u16,
|
|
||||||
/// The maximum number of inbound HTLCs towards sender
|
|
||||||
pub max_accepted_htlcs: u16,
|
|
||||||
/// The sender's key controlling the funding transaction
|
|
||||||
pub funding_pubkey: PublicKey,
|
|
||||||
/// Used to derive a revocation key for transactions broadcast by counterparty
|
|
||||||
pub revocation_basepoint: PublicKey,
|
|
||||||
/// A payment key to sender for transactions broadcast by counterparty
|
|
||||||
pub payment_point: PublicKey,
|
|
||||||
/// Used to derive a payment key to sender for transactions broadcast by sender
|
|
||||||
pub delayed_payment_basepoint: PublicKey,
|
|
||||||
/// Used to derive an HTLC payment key to sender
|
|
||||||
pub htlc_basepoint: PublicKey,
|
|
||||||
/// The first to-be-broadcast-by-sender transaction's per commitment point
|
|
||||||
pub first_per_commitment_point: PublicKey,
|
|
||||||
/// The channel flags to be used
|
|
||||||
pub channel_flags: u8,
|
|
||||||
/// A request to pre-set the to-sender output's `scriptPubkey` for when we collaboratively close
|
|
||||||
pub shutdown_scriptpubkey: Option<ScriptBuf>,
|
|
||||||
/// The channel type that this channel will represent
|
|
||||||
///
|
|
||||||
/// If this is `None`, we derive the channel type from the intersection of our
|
|
||||||
/// feature bits with our counterparty's feature bits from the [`Init`] message.
|
|
||||||
pub channel_type: Option<ChannelTypeFeatures>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An open_channel2 message to be sent by or received from the channel initiator.
|
|
||||||
///
|
|
||||||
/// Used in V2 channel establishment
|
|
||||||
///
|
|
||||||
// TODO(dual_funding): Add spec link for `open_channel2`.
|
// TODO(dual_funding): Add spec link for `open_channel2`.
|
||||||
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
||||||
pub struct OpenChannelV2 {
|
pub struct CommonOpenChannelFields {
|
||||||
/// The genesis hash of the blockchain where the channel is to be opened
|
/// The genesis hash of the blockchain where the channel is to be opened
|
||||||
pub chain_hash: ChainHash,
|
pub chain_hash: ChainHash,
|
||||||
/// A temporary channel ID derived using a zeroed out value for the channel acceptor's revocation basepoint
|
/// A temporary channel ID
|
||||||
|
/// For V2 channels: derived using a zeroed out value for the channel acceptor's revocation basepoint
|
||||||
|
/// For V1 channels: a temporary channel ID, until the funding outpoint is announced
|
||||||
pub temporary_channel_id: ChannelId,
|
pub temporary_channel_id: ChannelId,
|
||||||
/// The feerate for the funding transaction set by the channel initiator
|
/// For V1 channels: The channel value
|
||||||
pub funding_feerate_sat_per_1000_weight: u32,
|
/// For V2 channels: Part of the channel value contributed by the channel initiator
|
||||||
/// The feerate for the commitment transaction set by the channel initiator
|
|
||||||
pub commitment_feerate_sat_per_1000_weight: u32,
|
|
||||||
/// Part of the channel value contributed by the channel initiator
|
|
||||||
pub funding_satoshis: u64,
|
pub funding_satoshis: u64,
|
||||||
/// The threshold below which outputs on transactions broadcast by the channel initiator will be
|
/// The threshold below which outputs on transactions broadcast by the channel initiator will be
|
||||||
/// omitted
|
/// omitted
|
||||||
|
@ -250,13 +194,14 @@ pub struct OpenChannelV2 {
|
||||||
pub max_htlc_value_in_flight_msat: u64,
|
pub max_htlc_value_in_flight_msat: u64,
|
||||||
/// The minimum HTLC size incoming to channel initiator, in milli-satoshi
|
/// The minimum HTLC size incoming to channel initiator, in milli-satoshi
|
||||||
pub htlc_minimum_msat: u64,
|
pub htlc_minimum_msat: u64,
|
||||||
|
/// The feerate for the commitment transaction set by the channel initiator until updated by
|
||||||
|
/// [`UpdateFee`]
|
||||||
|
pub commitment_feerate_sat_per_1000_weight: u32,
|
||||||
/// The number of blocks which the counterparty will have to wait to claim on-chain funds if they
|
/// The number of blocks which the counterparty will have to wait to claim on-chain funds if they
|
||||||
/// broadcast a commitment transaction
|
/// broadcast a commitment transaction
|
||||||
pub to_self_delay: u16,
|
pub to_self_delay: u16,
|
||||||
/// The maximum number of inbound HTLCs towards channel initiator
|
/// The maximum number of inbound HTLCs towards channel initiator
|
||||||
pub max_accepted_htlcs: u16,
|
pub max_accepted_htlcs: u16,
|
||||||
/// The locktime for the funding transaction
|
|
||||||
pub locktime: u32,
|
|
||||||
/// The channel initiator's key controlling the funding transaction
|
/// The channel initiator's key controlling the funding transaction
|
||||||
pub funding_pubkey: PublicKey,
|
pub funding_pubkey: PublicKey,
|
||||||
/// Used to derive a revocation key for transactions broadcast by counterparty
|
/// Used to derive a revocation key for transactions broadcast by counterparty
|
||||||
|
@ -270,17 +215,48 @@ pub struct OpenChannelV2 {
|
||||||
pub htlc_basepoint: PublicKey,
|
pub htlc_basepoint: PublicKey,
|
||||||
/// The first to-be-broadcast-by-channel-initiator transaction's per commitment point
|
/// The first to-be-broadcast-by-channel-initiator transaction's per commitment point
|
||||||
pub first_per_commitment_point: PublicKey,
|
pub first_per_commitment_point: PublicKey,
|
||||||
/// The second to-be-broadcast-by-channel-initiator transaction's per commitment point
|
/// The channel flags to be used
|
||||||
pub second_per_commitment_point: PublicKey,
|
|
||||||
/// Channel flags
|
|
||||||
pub channel_flags: u8,
|
pub channel_flags: u8,
|
||||||
/// Optionally, a request to pre-set the to-channel-initiator output's scriptPubkey for when we
|
/// Optionally, a request to pre-set the to-channel-initiator output's scriptPubkey for when we
|
||||||
/// collaboratively close
|
/// collaboratively close
|
||||||
pub shutdown_scriptpubkey: Option<ScriptBuf>,
|
pub shutdown_scriptpubkey: Option<ScriptBuf>,
|
||||||
/// The channel type that this channel will represent. If none is set, we derive the channel
|
/// The channel type that this channel will represent
|
||||||
/// type from the intersection of our feature bits with our counterparty's feature bits from
|
///
|
||||||
/// the Init message.
|
/// If this is `None`, we derive the channel type from the intersection of our
|
||||||
|
/// feature bits with our counterparty's feature bits from the [`Init`] message.
|
||||||
pub channel_type: Option<ChannelTypeFeatures>,
|
pub channel_type: Option<ChannelTypeFeatures>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An [`open_channel`] message to be sent to or received from a peer.
|
||||||
|
///
|
||||||
|
/// Used in V1 channel establishment
|
||||||
|
///
|
||||||
|
/// [`open_channel`]: https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#the-open_channel-message
|
||||||
|
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
||||||
|
pub struct OpenChannel {
|
||||||
|
/// Common fields of `open_channel(2)`-like messages
|
||||||
|
pub common_fields: CommonOpenChannelFields,
|
||||||
|
/// The amount to push to the counterparty as part of the open, in milli-satoshi
|
||||||
|
pub push_msat: u64,
|
||||||
|
/// The minimum value unencumbered by HTLCs for the counterparty to keep in the channel
|
||||||
|
pub channel_reserve_satoshis: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An open_channel2 message to be sent by or received from the channel initiator.
|
||||||
|
///
|
||||||
|
/// Used in V2 channel establishment
|
||||||
|
///
|
||||||
|
// TODO(dual_funding): Add spec link for `open_channel2`.
|
||||||
|
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
||||||
|
pub struct OpenChannelV2 {
|
||||||
|
/// Common fields of `open_channel(2)`-like messages
|
||||||
|
pub common_fields: CommonOpenChannelFields,
|
||||||
|
/// The feerate for the funding transaction set by the channel initiator
|
||||||
|
pub funding_feerate_sat_per_1000_weight: u32,
|
||||||
|
/// The locktime for the funding transaction
|
||||||
|
pub locktime: u32,
|
||||||
|
/// The second to-be-broadcast-by-channel-initiator transaction's per commitment point
|
||||||
|
pub second_per_commitment_point: PublicKey,
|
||||||
/// Optionally, a requirement that only confirmed inputs can be added
|
/// Optionally, a requirement that only confirmed inputs can be added
|
||||||
pub require_confirmed_inputs: Option<()>,
|
pub require_confirmed_inputs: Option<()>,
|
||||||
}
|
}
|
||||||
|
@ -326,7 +302,7 @@ pub struct AcceptChannel {
|
||||||
///
|
///
|
||||||
/// If this is `None`, we derive the channel type from the intersection of
|
/// If this is `None`, we derive the channel type from the intersection of
|
||||||
/// our feature bits with our counterparty's feature bits from the [`Init`] message.
|
/// our feature bits with our counterparty's feature bits from the [`Init`] message.
|
||||||
/// This is required to match the equivalent field in [`OpenChannel::channel_type`].
|
/// This is required to match the equivalent field in [`OpenChannel`]'s [`CommonOpenChannelFields::channel_type`].
|
||||||
pub channel_type: Option<ChannelTypeFeatures>,
|
pub channel_type: Option<ChannelTypeFeatures>,
|
||||||
#[cfg(taproot)]
|
#[cfg(taproot)]
|
||||||
/// Next nonce the channel initiator should use to create a funding output signature against
|
/// Next nonce the channel initiator should use to create a funding output signature against
|
||||||
|
@ -380,7 +356,7 @@ pub struct AcceptChannelV2 {
|
||||||
/// type from the intersection of our feature bits with our counterparty's feature bits from
|
/// type from the intersection of our feature bits with our counterparty's feature bits from
|
||||||
/// the Init message.
|
/// the Init message.
|
||||||
///
|
///
|
||||||
/// This is required to match the equivalent field in [`OpenChannelV2::channel_type`].
|
/// This is required to match the equivalent field in [`OpenChannelV2`]'s [`CommonOpenChannelFields::channel_type`].
|
||||||
pub channel_type: Option<ChannelTypeFeatures>,
|
pub channel_type: Option<ChannelTypeFeatures>,
|
||||||
/// Optionally, a requirement that only confirmed inputs can be added
|
/// Optionally, a requirement that only confirmed inputs can be added
|
||||||
pub require_confirmed_inputs: Option<()>,
|
pub require_confirmed_inputs: Option<()>,
|
||||||
|
@ -2095,55 +2071,176 @@ impl Readable for Init {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_writeable_msg!(OpenChannel, {
|
impl Writeable for OpenChannel {
|
||||||
chain_hash,
|
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
|
||||||
temporary_channel_id,
|
self.common_fields.chain_hash.write(w)?;
|
||||||
funding_satoshis,
|
self.common_fields.temporary_channel_id.write(w)?;
|
||||||
push_msat,
|
self.common_fields.funding_satoshis.write(w)?;
|
||||||
dust_limit_satoshis,
|
self.push_msat.write(w)?;
|
||||||
max_htlc_value_in_flight_msat,
|
self.common_fields.dust_limit_satoshis.write(w)?;
|
||||||
channel_reserve_satoshis,
|
self.common_fields.max_htlc_value_in_flight_msat.write(w)?;
|
||||||
htlc_minimum_msat,
|
self.channel_reserve_satoshis.write(w)?;
|
||||||
feerate_per_kw,
|
self.common_fields.htlc_minimum_msat.write(w)?;
|
||||||
to_self_delay,
|
self.common_fields.commitment_feerate_sat_per_1000_weight.write(w)?;
|
||||||
max_accepted_htlcs,
|
self.common_fields.to_self_delay.write(w)?;
|
||||||
funding_pubkey,
|
self.common_fields.max_accepted_htlcs.write(w)?;
|
||||||
revocation_basepoint,
|
self.common_fields.funding_pubkey.write(w)?;
|
||||||
payment_point,
|
self.common_fields.revocation_basepoint.write(w)?;
|
||||||
delayed_payment_basepoint,
|
self.common_fields.payment_basepoint.write(w)?;
|
||||||
htlc_basepoint,
|
self.common_fields.delayed_payment_basepoint.write(w)?;
|
||||||
first_per_commitment_point,
|
self.common_fields.htlc_basepoint.write(w)?;
|
||||||
channel_flags,
|
self.common_fields.first_per_commitment_point.write(w)?;
|
||||||
}, {
|
self.common_fields.channel_flags.write(w)?;
|
||||||
(0, shutdown_scriptpubkey, (option, encoding: (ScriptBuf, WithoutLength))), // Don't encode length twice.
|
encode_tlv_stream!(w, {
|
||||||
(1, channel_type, option),
|
(0, self.common_fields.shutdown_scriptpubkey.as_ref().map(|s| WithoutLength(s)), option), // Don't encode length twice.
|
||||||
});
|
(1, self.common_fields.channel_type, option),
|
||||||
|
});
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl_writeable_msg!(OpenChannelV2, {
|
impl Readable for OpenChannel {
|
||||||
chain_hash,
|
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
|
||||||
temporary_channel_id,
|
let chain_hash: ChainHash = Readable::read(r)?;
|
||||||
funding_feerate_sat_per_1000_weight,
|
let temporary_channel_id: ChannelId = Readable::read(r)?;
|
||||||
commitment_feerate_sat_per_1000_weight,
|
let funding_satoshis: u64 = Readable::read(r)?;
|
||||||
funding_satoshis,
|
let push_msat: u64 = Readable::read(r)?;
|
||||||
dust_limit_satoshis,
|
let dust_limit_satoshis: u64 = Readable::read(r)?;
|
||||||
max_htlc_value_in_flight_msat,
|
let max_htlc_value_in_flight_msat: u64 = Readable::read(r)?;
|
||||||
htlc_minimum_msat,
|
let channel_reserve_satoshis: u64 = Readable::read(r)?;
|
||||||
to_self_delay,
|
let htlc_minimum_msat: u64 = Readable::read(r)?;
|
||||||
max_accepted_htlcs,
|
let commitment_feerate_sat_per_1000_weight: u32 = Readable::read(r)?;
|
||||||
locktime,
|
let to_self_delay: u16 = Readable::read(r)?;
|
||||||
funding_pubkey,
|
let max_accepted_htlcs: u16 = Readable::read(r)?;
|
||||||
revocation_basepoint,
|
let funding_pubkey: PublicKey = Readable::read(r)?;
|
||||||
payment_basepoint,
|
let revocation_basepoint: PublicKey = Readable::read(r)?;
|
||||||
delayed_payment_basepoint,
|
let payment_basepoint: PublicKey = Readable::read(r)?;
|
||||||
htlc_basepoint,
|
let delayed_payment_basepoint: PublicKey = Readable::read(r)?;
|
||||||
first_per_commitment_point,
|
let htlc_basepoint: PublicKey = Readable::read(r)?;
|
||||||
second_per_commitment_point,
|
let first_per_commitment_point: PublicKey = Readable::read(r)?;
|
||||||
channel_flags,
|
let channel_flags: u8 = Readable::read(r)?;
|
||||||
}, {
|
|
||||||
(0, shutdown_scriptpubkey, option),
|
let mut shutdown_scriptpubkey: Option<ScriptBuf> = None;
|
||||||
(1, channel_type, option),
|
let mut channel_type: Option<ChannelTypeFeatures> = None;
|
||||||
(2, require_confirmed_inputs, option),
|
decode_tlv_stream!(r, {
|
||||||
});
|
(0, shutdown_scriptpubkey, (option, encoding: (ScriptBuf, WithoutLength))),
|
||||||
|
(1, channel_type, option),
|
||||||
|
});
|
||||||
|
Ok(OpenChannel {
|
||||||
|
common_fields: CommonOpenChannelFields {
|
||||||
|
chain_hash,
|
||||||
|
temporary_channel_id,
|
||||||
|
funding_satoshis,
|
||||||
|
dust_limit_satoshis,
|
||||||
|
max_htlc_value_in_flight_msat,
|
||||||
|
htlc_minimum_msat,
|
||||||
|
commitment_feerate_sat_per_1000_weight,
|
||||||
|
to_self_delay,
|
||||||
|
max_accepted_htlcs,
|
||||||
|
funding_pubkey,
|
||||||
|
revocation_basepoint,
|
||||||
|
payment_basepoint,
|
||||||
|
delayed_payment_basepoint,
|
||||||
|
htlc_basepoint,
|
||||||
|
first_per_commitment_point,
|
||||||
|
channel_flags,
|
||||||
|
shutdown_scriptpubkey,
|
||||||
|
channel_type,
|
||||||
|
},
|
||||||
|
push_msat,
|
||||||
|
channel_reserve_satoshis,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Writeable for OpenChannelV2 {
|
||||||
|
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
|
||||||
|
self.common_fields.chain_hash.write(w)?;
|
||||||
|
self.common_fields.temporary_channel_id.write(w)?;
|
||||||
|
self.funding_feerate_sat_per_1000_weight.write(w)?;
|
||||||
|
self.common_fields.commitment_feerate_sat_per_1000_weight.write(w)?;
|
||||||
|
self.common_fields.funding_satoshis.write(w)?;
|
||||||
|
self.common_fields.dust_limit_satoshis.write(w)?;
|
||||||
|
self.common_fields.max_htlc_value_in_flight_msat.write(w)?;
|
||||||
|
self.common_fields.htlc_minimum_msat.write(w)?;
|
||||||
|
self.common_fields.to_self_delay.write(w)?;
|
||||||
|
self.common_fields.max_accepted_htlcs.write(w)?;
|
||||||
|
self.locktime.write(w)?;
|
||||||
|
self.common_fields.funding_pubkey.write(w)?;
|
||||||
|
self.common_fields.revocation_basepoint.write(w)?;
|
||||||
|
self.common_fields.payment_basepoint.write(w)?;
|
||||||
|
self.common_fields.delayed_payment_basepoint.write(w)?;
|
||||||
|
self.common_fields.htlc_basepoint.write(w)?;
|
||||||
|
self.common_fields.first_per_commitment_point.write(w)?;
|
||||||
|
self.second_per_commitment_point.write(w)?;
|
||||||
|
self.common_fields.channel_flags.write(w)?;
|
||||||
|
encode_tlv_stream!(w, {
|
||||||
|
(0, self.common_fields.shutdown_scriptpubkey.as_ref().map(|s| WithoutLength(s)), option), // Don't encode length twice.
|
||||||
|
(1, self.common_fields.channel_type, option),
|
||||||
|
(2, self.require_confirmed_inputs, option),
|
||||||
|
});
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Readable for OpenChannelV2 {
|
||||||
|
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
|
||||||
|
let chain_hash: ChainHash = Readable::read(r)?;
|
||||||
|
let temporary_channel_id: ChannelId = Readable::read(r)?;
|
||||||
|
let funding_feerate_sat_per_1000_weight: u32 = Readable::read(r)?;
|
||||||
|
let commitment_feerate_sat_per_1000_weight: u32 = Readable::read(r)?;
|
||||||
|
let funding_satoshis: u64 = Readable::read(r)?;
|
||||||
|
let dust_limit_satoshis: u64 = Readable::read(r)?;
|
||||||
|
let max_htlc_value_in_flight_msat: u64 = Readable::read(r)?;
|
||||||
|
let htlc_minimum_msat: u64 = Readable::read(r)?;
|
||||||
|
let to_self_delay: u16 = Readable::read(r)?;
|
||||||
|
let max_accepted_htlcs: u16 = Readable::read(r)?;
|
||||||
|
let locktime: u32 = Readable::read(r)?;
|
||||||
|
let funding_pubkey: PublicKey = Readable::read(r)?;
|
||||||
|
let revocation_basepoint: PublicKey = Readable::read(r)?;
|
||||||
|
let payment_basepoint: PublicKey = Readable::read(r)?;
|
||||||
|
let delayed_payment_basepoint: PublicKey = Readable::read(r)?;
|
||||||
|
let htlc_basepoint: PublicKey = Readable::read(r)?;
|
||||||
|
let first_per_commitment_point: PublicKey = Readable::read(r)?;
|
||||||
|
let second_per_commitment_point: PublicKey = Readable::read(r)?;
|
||||||
|
let channel_flags: u8 = Readable::read(r)?;
|
||||||
|
|
||||||
|
let mut shutdown_scriptpubkey: Option<ScriptBuf> = None;
|
||||||
|
let mut channel_type: Option<ChannelTypeFeatures> = None;
|
||||||
|
let mut require_confirmed_inputs: Option<()> = None;
|
||||||
|
decode_tlv_stream!(r, {
|
||||||
|
(0, shutdown_scriptpubkey, (option, encoding: (ScriptBuf, WithoutLength))),
|
||||||
|
(1, channel_type, option),
|
||||||
|
(2, require_confirmed_inputs, option),
|
||||||
|
});
|
||||||
|
Ok(OpenChannelV2 {
|
||||||
|
common_fields: CommonOpenChannelFields {
|
||||||
|
chain_hash,
|
||||||
|
temporary_channel_id,
|
||||||
|
funding_satoshis,
|
||||||
|
dust_limit_satoshis,
|
||||||
|
max_htlc_value_in_flight_msat,
|
||||||
|
htlc_minimum_msat,
|
||||||
|
commitment_feerate_sat_per_1000_weight,
|
||||||
|
to_self_delay,
|
||||||
|
max_accepted_htlcs,
|
||||||
|
funding_pubkey,
|
||||||
|
revocation_basepoint,
|
||||||
|
payment_basepoint,
|
||||||
|
delayed_payment_basepoint,
|
||||||
|
htlc_basepoint,
|
||||||
|
first_per_commitment_point,
|
||||||
|
channel_flags,
|
||||||
|
shutdown_scriptpubkey,
|
||||||
|
channel_type,
|
||||||
|
},
|
||||||
|
funding_feerate_sat_per_1000_weight,
|
||||||
|
locktime,
|
||||||
|
second_per_commitment_point,
|
||||||
|
require_confirmed_inputs,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(taproot))]
|
#[cfg(not(taproot))]
|
||||||
impl_writeable_msg!(RevokeAndACK, {
|
impl_writeable_msg!(RevokeAndACK, {
|
||||||
|
@ -2854,7 +2951,7 @@ mod tests {
|
||||||
use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
|
use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
|
||||||
use crate::ln::ChannelId;
|
use crate::ln::ChannelId;
|
||||||
use crate::ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures};
|
use crate::ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures};
|
||||||
use crate::ln::msgs::{self, FinalOnionHopData, OnionErrorPacket};
|
use crate::ln::msgs::{self, FinalOnionHopData, OnionErrorPacket, CommonOpenChannelFields};
|
||||||
use crate::ln::msgs::SocketAddress;
|
use crate::ln::msgs::SocketAddress;
|
||||||
use crate::routing::gossip::{NodeAlias, NodeId};
|
use crate::routing::gossip::{NodeAlias, NodeId};
|
||||||
use crate::util::ser::{Writeable, Readable, ReadableArgs, Hostname, TransactionU16LenLimited};
|
use crate::util::ser::{Writeable, Readable, ReadableArgs, Hostname, TransactionU16LenLimited};
|
||||||
|
@ -3206,26 +3303,28 @@ mod tests {
|
||||||
let (_, pubkey_5) = get_keys_from!("0505050505050505050505050505050505050505050505050505050505050505", secp_ctx);
|
let (_, pubkey_5) = get_keys_from!("0505050505050505050505050505050505050505050505050505050505050505", secp_ctx);
|
||||||
let (_, pubkey_6) = get_keys_from!("0606060606060606060606060606060606060606060606060606060606060606", secp_ctx);
|
let (_, pubkey_6) = get_keys_from!("0606060606060606060606060606060606060606060606060606060606060606", secp_ctx);
|
||||||
let open_channel = msgs::OpenChannel {
|
let open_channel = msgs::OpenChannel {
|
||||||
chain_hash: ChainHash::using_genesis_block(Network::Bitcoin),
|
common_fields: CommonOpenChannelFields {
|
||||||
temporary_channel_id: ChannelId::from_bytes([2; 32]),
|
chain_hash: ChainHash::using_genesis_block(Network::Bitcoin),
|
||||||
funding_satoshis: 1311768467284833366,
|
temporary_channel_id: ChannelId::from_bytes([2; 32]),
|
||||||
|
funding_satoshis: 1311768467284833366,
|
||||||
|
dust_limit_satoshis: 3608586615801332854,
|
||||||
|
max_htlc_value_in_flight_msat: 8517154655701053848,
|
||||||
|
htlc_minimum_msat: 2316138423780173,
|
||||||
|
commitment_feerate_sat_per_1000_weight: 821716,
|
||||||
|
to_self_delay: 49340,
|
||||||
|
max_accepted_htlcs: 49340,
|
||||||
|
funding_pubkey: pubkey_1,
|
||||||
|
revocation_basepoint: pubkey_2,
|
||||||
|
payment_basepoint: pubkey_3,
|
||||||
|
delayed_payment_basepoint: pubkey_4,
|
||||||
|
htlc_basepoint: pubkey_5,
|
||||||
|
first_per_commitment_point: pubkey_6,
|
||||||
|
channel_flags: if random_bit { 1 << 5 } else { 0 },
|
||||||
|
shutdown_scriptpubkey: if shutdown { Some(Address::p2pkh(&::bitcoin::PublicKey{compressed: true, inner: pubkey_1}, Network::Testnet).script_pubkey()) } else { None },
|
||||||
|
channel_type: if incl_chan_type { Some(ChannelTypeFeatures::empty()) } else { None },
|
||||||
|
},
|
||||||
push_msat: 2536655962884945560,
|
push_msat: 2536655962884945560,
|
||||||
dust_limit_satoshis: 3608586615801332854,
|
|
||||||
max_htlc_value_in_flight_msat: 8517154655701053848,
|
|
||||||
channel_reserve_satoshis: 8665828695742877976,
|
channel_reserve_satoshis: 8665828695742877976,
|
||||||
htlc_minimum_msat: 2316138423780173,
|
|
||||||
feerate_per_kw: 821716,
|
|
||||||
to_self_delay: 49340,
|
|
||||||
max_accepted_htlcs: 49340,
|
|
||||||
funding_pubkey: pubkey_1,
|
|
||||||
revocation_basepoint: pubkey_2,
|
|
||||||
payment_point: pubkey_3,
|
|
||||||
delayed_payment_basepoint: pubkey_4,
|
|
||||||
htlc_basepoint: pubkey_5,
|
|
||||||
first_per_commitment_point: pubkey_6,
|
|
||||||
channel_flags: if random_bit { 1 << 5 } else { 0 },
|
|
||||||
shutdown_scriptpubkey: if shutdown { Some(Address::p2pkh(&::bitcoin::PublicKey{compressed: true, inner: pubkey_1}, Network::Testnet).script_pubkey()) } else { None },
|
|
||||||
channel_type: if incl_chan_type { Some(ChannelTypeFeatures::empty()) } else { None },
|
|
||||||
};
|
};
|
||||||
let encoded_value = open_channel.encode();
|
let encoded_value = open_channel.encode();
|
||||||
let mut target_value = Vec::new();
|
let mut target_value = Vec::new();
|
||||||
|
@ -3267,27 +3366,29 @@ mod tests {
|
||||||
let (_, pubkey_6) = get_keys_from!("0606060606060606060606060606060606060606060606060606060606060606", secp_ctx);
|
let (_, pubkey_6) = get_keys_from!("0606060606060606060606060606060606060606060606060606060606060606", secp_ctx);
|
||||||
let (_, pubkey_7) = get_keys_from!("0707070707070707070707070707070707070707070707070707070707070707", secp_ctx);
|
let (_, pubkey_7) = get_keys_from!("0707070707070707070707070707070707070707070707070707070707070707", secp_ctx);
|
||||||
let open_channelv2 = msgs::OpenChannelV2 {
|
let open_channelv2 = msgs::OpenChannelV2 {
|
||||||
chain_hash: ChainHash::using_genesis_block(Network::Bitcoin),
|
common_fields: CommonOpenChannelFields {
|
||||||
temporary_channel_id: ChannelId::from_bytes([2; 32]),
|
chain_hash: ChainHash::using_genesis_block(Network::Bitcoin),
|
||||||
|
temporary_channel_id: ChannelId::from_bytes([2; 32]),
|
||||||
|
commitment_feerate_sat_per_1000_weight: 821716,
|
||||||
|
funding_satoshis: 1311768467284833366,
|
||||||
|
dust_limit_satoshis: 3608586615801332854,
|
||||||
|
max_htlc_value_in_flight_msat: 8517154655701053848,
|
||||||
|
htlc_minimum_msat: 2316138423780173,
|
||||||
|
to_self_delay: 49340,
|
||||||
|
max_accepted_htlcs: 49340,
|
||||||
|
funding_pubkey: pubkey_1,
|
||||||
|
revocation_basepoint: pubkey_2,
|
||||||
|
payment_basepoint: pubkey_3,
|
||||||
|
delayed_payment_basepoint: pubkey_4,
|
||||||
|
htlc_basepoint: pubkey_5,
|
||||||
|
first_per_commitment_point: pubkey_6,
|
||||||
|
channel_flags: if random_bit { 1 << 5 } else { 0 },
|
||||||
|
shutdown_scriptpubkey: if shutdown { Some(Address::p2pkh(&::bitcoin::PublicKey{compressed: true, inner: pubkey_1}, Network::Testnet).script_pubkey()) } else { None },
|
||||||
|
channel_type: if incl_chan_type { Some(ChannelTypeFeatures::empty()) } else { None },
|
||||||
|
},
|
||||||
funding_feerate_sat_per_1000_weight: 821716,
|
funding_feerate_sat_per_1000_weight: 821716,
|
||||||
commitment_feerate_sat_per_1000_weight: 821716,
|
|
||||||
funding_satoshis: 1311768467284833366,
|
|
||||||
dust_limit_satoshis: 3608586615801332854,
|
|
||||||
max_htlc_value_in_flight_msat: 8517154655701053848,
|
|
||||||
htlc_minimum_msat: 2316138423780173,
|
|
||||||
to_self_delay: 49340,
|
|
||||||
max_accepted_htlcs: 49340,
|
|
||||||
locktime: 305419896,
|
locktime: 305419896,
|
||||||
funding_pubkey: pubkey_1,
|
|
||||||
revocation_basepoint: pubkey_2,
|
|
||||||
payment_basepoint: pubkey_3,
|
|
||||||
delayed_payment_basepoint: pubkey_4,
|
|
||||||
htlc_basepoint: pubkey_5,
|
|
||||||
first_per_commitment_point: pubkey_6,
|
|
||||||
second_per_commitment_point: pubkey_7,
|
second_per_commitment_point: pubkey_7,
|
||||||
channel_flags: if random_bit { 1 << 5 } else { 0 },
|
|
||||||
shutdown_scriptpubkey: if shutdown { Some(Address::p2pkh(&::bitcoin::PublicKey{compressed: true, inner: pubkey_1}, Network::Testnet).script_pubkey()) } else { None },
|
|
||||||
channel_type: if incl_chan_type { Some(ChannelTypeFeatures::empty()) } else { None },
|
|
||||||
require_confirmed_inputs: if require_confirmed_inputs { Some(()) } else { None },
|
require_confirmed_inputs: if require_confirmed_inputs { Some(()) } else { None },
|
||||||
};
|
};
|
||||||
let encoded_value = open_channelv2.encode();
|
let encoded_value = open_channelv2.encode();
|
||||||
|
@ -3317,7 +3418,6 @@ mod tests {
|
||||||
target_value.append(&mut <Vec<u8>>::from_hex("00").unwrap());
|
target_value.append(&mut <Vec<u8>>::from_hex("00").unwrap());
|
||||||
}
|
}
|
||||||
if shutdown {
|
if shutdown {
|
||||||
target_value.append(&mut <Vec<u8>>::from_hex("001b").unwrap()); // Type 0 + Length 27
|
|
||||||
target_value.append(&mut <Vec<u8>>::from_hex("001976a91479b000887626b294a914501a4cd226b58b23598388ac").unwrap());
|
target_value.append(&mut <Vec<u8>>::from_hex("001976a91479b000887626b294a914501a4cd226b58b23598388ac").unwrap());
|
||||||
}
|
}
|
||||||
if incl_chan_type {
|
if incl_chan_type {
|
||||||
|
|
|
@ -222,7 +222,7 @@ impl ChannelMessageHandler for ErroringMessageHandler {
|
||||||
// Any messages which are related to a specific channel generate an error message to let the
|
// Any messages which are related to a specific channel generate an error message to let the
|
||||||
// peer know we don't care about channels.
|
// peer know we don't care about channels.
|
||||||
fn handle_open_channel(&self, their_node_id: &PublicKey, msg: &msgs::OpenChannel) {
|
fn handle_open_channel(&self, their_node_id: &PublicKey, msg: &msgs::OpenChannel) {
|
||||||
ErroringMessageHandler::push_error(self, their_node_id, msg.temporary_channel_id);
|
ErroringMessageHandler::push_error(self, their_node_id, msg.common_fields.temporary_channel_id);
|
||||||
}
|
}
|
||||||
fn handle_accept_channel(&self, their_node_id: &PublicKey, msg: &msgs::AcceptChannel) {
|
fn handle_accept_channel(&self, their_node_id: &PublicKey, msg: &msgs::AcceptChannel) {
|
||||||
ErroringMessageHandler::push_error(self, their_node_id, msg.temporary_channel_id);
|
ErroringMessageHandler::push_error(self, their_node_id, msg.temporary_channel_id);
|
||||||
|
@ -315,7 +315,7 @@ impl ChannelMessageHandler for ErroringMessageHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_open_channel_v2(&self, their_node_id: &PublicKey, msg: &msgs::OpenChannelV2) {
|
fn handle_open_channel_v2(&self, their_node_id: &PublicKey, msg: &msgs::OpenChannelV2) {
|
||||||
ErroringMessageHandler::push_error(self, their_node_id, msg.temporary_channel_id);
|
ErroringMessageHandler::push_error(self, their_node_id, msg.common_fields.temporary_channel_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_accept_channel_v2(&self, their_node_id: &PublicKey, msg: &msgs::AcceptChannelV2) {
|
fn handle_accept_channel_v2(&self, their_node_id: &PublicKey, msg: &msgs::AcceptChannelV2) {
|
||||||
|
@ -1991,15 +1991,15 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
|
||||||
self.enqueue_message(&mut *get_peer_for_forwarding!(node_id), msg);
|
self.enqueue_message(&mut *get_peer_for_forwarding!(node_id), msg);
|
||||||
},
|
},
|
||||||
MessageSendEvent::SendOpenChannel { ref node_id, ref msg } => {
|
MessageSendEvent::SendOpenChannel { ref node_id, ref msg } => {
|
||||||
log_debug!(WithContext::from(&self.logger, Some(*node_id), Some(msg.temporary_channel_id)), "Handling SendOpenChannel event in peer_handler for node {} for channel {}",
|
log_debug!(WithContext::from(&self.logger, Some(*node_id), Some(msg.common_fields.temporary_channel_id)), "Handling SendOpenChannel event in peer_handler for node {} for channel {}",
|
||||||
log_pubkey!(node_id),
|
log_pubkey!(node_id),
|
||||||
&msg.temporary_channel_id);
|
&msg.common_fields.temporary_channel_id);
|
||||||
self.enqueue_message(&mut *get_peer_for_forwarding!(node_id), msg);
|
self.enqueue_message(&mut *get_peer_for_forwarding!(node_id), msg);
|
||||||
},
|
},
|
||||||
MessageSendEvent::SendOpenChannelV2 { ref node_id, ref msg } => {
|
MessageSendEvent::SendOpenChannelV2 { ref node_id, ref msg } => {
|
||||||
log_debug!(WithContext::from(&self.logger, Some(*node_id), Some(msg.temporary_channel_id)), "Handling SendOpenChannelV2 event in peer_handler for node {} for channel {}",
|
log_debug!(WithContext::from(&self.logger, Some(*node_id), Some(msg.common_fields.temporary_channel_id)), "Handling SendOpenChannelV2 event in peer_handler for node {} for channel {}",
|
||||||
log_pubkey!(node_id),
|
log_pubkey!(node_id),
|
||||||
&msg.temporary_channel_id);
|
&msg.common_fields.temporary_channel_id);
|
||||||
self.enqueue_message(&mut *get_peer_for_forwarding!(node_id), msg);
|
self.enqueue_message(&mut *get_peer_for_forwarding!(node_id), msg);
|
||||||
},
|
},
|
||||||
MessageSendEvent::SendFundingCreated { ref node_id, ref msg } => {
|
MessageSendEvent::SendFundingCreated { ref node_id, ref msg } => {
|
||||||
|
|
|
@ -293,9 +293,9 @@ fn test_scid_privacy_on_pub_channel() {
|
||||||
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, None, Some(scid_privacy_cfg)).unwrap();
|
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, None, Some(scid_privacy_cfg)).unwrap();
|
||||||
let mut open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
let mut open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
||||||
|
|
||||||
assert!(!open_channel.channel_type.as_ref().unwrap().supports_scid_privacy()); // we ignore `negotiate_scid_privacy` on pub channels
|
assert!(!open_channel.common_fields.channel_type.as_ref().unwrap().supports_scid_privacy()); // we ignore `negotiate_scid_privacy` on pub channels
|
||||||
open_channel.channel_type.as_mut().unwrap().set_scid_privacy_required();
|
open_channel.common_fields.channel_type.as_mut().unwrap().set_scid_privacy_required();
|
||||||
assert_eq!(open_channel.channel_flags & 1, 1); // The `announce_channel` bit is set.
|
assert_eq!(open_channel.common_fields.channel_flags & 1, 1); // The `announce_channel` bit is set.
|
||||||
|
|
||||||
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel);
|
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel);
|
||||||
let err = get_err_msg(&nodes[1], &nodes[0].node.get_our_node_id());
|
let err = get_err_msg(&nodes[1], &nodes[0].node.get_our_node_id());
|
||||||
|
@ -317,19 +317,19 @@ fn test_scid_privacy_negotiation() {
|
||||||
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, None, Some(scid_privacy_cfg)).unwrap();
|
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, None, Some(scid_privacy_cfg)).unwrap();
|
||||||
|
|
||||||
let init_open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
let init_open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
||||||
assert!(init_open_channel.channel_type.as_ref().unwrap().supports_scid_privacy());
|
assert!(init_open_channel.common_fields.channel_type.as_ref().unwrap().supports_scid_privacy());
|
||||||
assert!(nodes[0].node.list_channels()[0].channel_type.is_none()); // channel_type is none until counterparty accepts
|
assert!(nodes[0].node.list_channels()[0].channel_type.is_none()); // channel_type is none until counterparty accepts
|
||||||
|
|
||||||
// now simulate nodes[1] responding with an Error message, indicating it doesn't understand
|
// now simulate nodes[1] responding with an Error message, indicating it doesn't understand
|
||||||
// SCID alias.
|
// SCID alias.
|
||||||
nodes[0].node.handle_error(&nodes[1].node.get_our_node_id(), &msgs::ErrorMessage {
|
nodes[0].node.handle_error(&nodes[1].node.get_our_node_id(), &msgs::ErrorMessage {
|
||||||
channel_id: init_open_channel.temporary_channel_id,
|
channel_id: init_open_channel.common_fields.temporary_channel_id,
|
||||||
data: "Yo, no SCID aliases, no privacy here!".to_string()
|
data: "Yo, no SCID aliases, no privacy here!".to_string()
|
||||||
});
|
});
|
||||||
assert!(nodes[0].node.list_channels()[0].channel_type.is_none()); // channel_type is none until counterparty accepts
|
assert!(nodes[0].node.list_channels()[0].channel_type.is_none()); // channel_type is none until counterparty accepts
|
||||||
|
|
||||||
let second_open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
let second_open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
||||||
assert!(!second_open_channel.channel_type.as_ref().unwrap().supports_scid_privacy());
|
assert!(!second_open_channel.common_fields.channel_type.as_ref().unwrap().supports_scid_privacy());
|
||||||
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &second_open_channel);
|
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &second_open_channel);
|
||||||
nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()));
|
nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()));
|
||||||
|
|
||||||
|
@ -363,7 +363,7 @@ fn test_inbound_scid_privacy() {
|
||||||
nodes[1].node.create_channel(nodes[2].node.get_our_node_id(), 100_000, 10_000, 42, None, Some(no_announce_cfg)).unwrap();
|
nodes[1].node.create_channel(nodes[2].node.get_our_node_id(), 100_000, 10_000, 42, None, Some(no_announce_cfg)).unwrap();
|
||||||
let mut open_channel = get_event_msg!(nodes[1], MessageSendEvent::SendOpenChannel, nodes[2].node.get_our_node_id());
|
let mut open_channel = get_event_msg!(nodes[1], MessageSendEvent::SendOpenChannel, nodes[2].node.get_our_node_id());
|
||||||
|
|
||||||
assert!(open_channel.channel_type.as_ref().unwrap().requires_scid_privacy());
|
assert!(open_channel.common_fields.channel_type.as_ref().unwrap().requires_scid_privacy());
|
||||||
|
|
||||||
nodes[2].node.handle_open_channel(&nodes[1].node.get_our_node_id(), &open_channel);
|
nodes[2].node.handle_open_channel(&nodes[1].node.get_our_node_id(), &open_channel);
|
||||||
let accept_channel = get_event_msg!(nodes[2], MessageSendEvent::SendAcceptChannel, nodes[1].node.get_our_node_id());
|
let accept_channel = get_event_msg!(nodes[2], MessageSendEvent::SendAcceptChannel, nodes[1].node.get_our_node_id());
|
||||||
|
@ -885,7 +885,7 @@ fn test_zero_conf_accept_reject() {
|
||||||
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, None, None).unwrap();
|
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, None, None).unwrap();
|
||||||
let mut open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
let mut open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
||||||
|
|
||||||
open_channel_msg.channel_type = Some(channel_type_features.clone());
|
open_channel_msg.common_fields.channel_type = Some(channel_type_features.clone());
|
||||||
|
|
||||||
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
|
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
|
||||||
|
|
||||||
|
@ -913,7 +913,7 @@ fn test_zero_conf_accept_reject() {
|
||||||
let mut open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel,
|
let mut open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel,
|
||||||
nodes[1].node.get_our_node_id());
|
nodes[1].node.get_our_node_id());
|
||||||
|
|
||||||
open_channel_msg.channel_type = Some(channel_type_features.clone());
|
open_channel_msg.common_fields.channel_type = Some(channel_type_features.clone());
|
||||||
|
|
||||||
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
|
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
|
||||||
|
|
||||||
|
@ -945,7 +945,7 @@ fn test_zero_conf_accept_reject() {
|
||||||
let mut open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel,
|
let mut open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel,
|
||||||
nodes[1].node.get_our_node_id());
|
nodes[1].node.get_our_node_id());
|
||||||
|
|
||||||
open_channel_msg.channel_type = Some(channel_type_features);
|
open_channel_msg.common_fields.channel_type = Some(channel_type_features);
|
||||||
|
|
||||||
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
|
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel_msg);
|
||||||
|
|
||||||
|
|
|
@ -275,7 +275,7 @@ fn shutdown_on_unfunded_channel() {
|
||||||
.into_script();
|
.into_script();
|
||||||
|
|
||||||
nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &msgs::Shutdown {
|
nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &msgs::Shutdown {
|
||||||
channel_id: open_chan.temporary_channel_id, scriptpubkey: script,
|
channel_id: open_chan.common_fields.temporary_channel_id, scriptpubkey: script,
|
||||||
});
|
});
|
||||||
check_closed_event!(nodes[0], 1, ClosureReason::CounterpartyCoopClosedUnfundedChannel, [nodes[1].node.get_our_node_id()], 1_000_000);
|
check_closed_event!(nodes[0], 1, ClosureReason::CounterpartyCoopClosedUnfundedChannel, [nodes[1].node.get_our_node_id()], 1_000_000);
|
||||||
}
|
}
|
||||||
|
@ -813,7 +813,7 @@ fn test_unsupported_anysegwit_upfront_shutdown_script() {
|
||||||
// Check script when handling an open_channel message
|
// Check script when handling an open_channel message
|
||||||
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, None, None).unwrap();
|
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, None, None).unwrap();
|
||||||
let mut open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
let mut open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
||||||
open_channel.shutdown_scriptpubkey = Some(anysegwit_shutdown_script.clone());
|
open_channel.common_fields.shutdown_scriptpubkey = Some(anysegwit_shutdown_script.clone());
|
||||||
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel);
|
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel);
|
||||||
|
|
||||||
let events = nodes[1].node.get_and_clear_pending_msg_events();
|
let events = nodes[1].node.get_and_clear_pending_msg_events();
|
||||||
|
@ -865,7 +865,7 @@ fn test_invalid_upfront_shutdown_script() {
|
||||||
|
|
||||||
// Use a segwit v0 script with an unsupported witness program
|
// Use a segwit v0 script with an unsupported witness program
|
||||||
let mut open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
let mut open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
|
||||||
open_channel.shutdown_scriptpubkey = Some(Builder::new().push_int(0)
|
open_channel.common_fields.shutdown_scriptpubkey = Some(Builder::new().push_int(0)
|
||||||
.push_slice(&[0, 0])
|
.push_slice(&[0, 0])
|
||||||
.into_script());
|
.into_script());
|
||||||
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel);
|
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel);
|
||||||
|
|
Loading…
Add table
Reference in a new issue