Merge pull request #2871 from dunxen/2024-02-msgcommonfields

Combine common fields for OpenChannel and AcceptChannel V1 & V2
This commit is contained in:
Matt Corallo 2024-02-08 21:50:27 +00:00 committed by GitHub
commit c93b59e13d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 759 additions and 559 deletions

View file

@ -197,7 +197,7 @@ fn test_async_commitment_signature_for_funding_signed_0conf() {
// nodes[0] <-- accept_channel --- nodes[1]
let accept_channel = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
assert_eq!(accept_channel.minimum_depth, 0, "Expected minimum depth of 0");
assert_eq!(accept_channel.common_fields.minimum_depth, 0, "Expected minimum depth of 0");
nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &accept_channel);
// nodes[0] --- funding_created --> nodes[1]

View file

@ -6955,29 +6955,31 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
let keys = self.context.get_holder_pubkeys();
msgs::OpenChannel {
chain_hash,
temporary_channel_id: self.context.channel_id,
funding_satoshis: self.context.channel_value_satoshis,
common_fields: msgs::CommonOpenChannelFields {
chain_hash,
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,
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,
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()),
}
}
@ -6992,58 +6994,58 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
if !matches!(self.context.channel_state, ChannelState::NegotiatingFunding(flags) if flags == NegotiatingFundingFlags::OUR_INIT_SENT) {
return Err(ChannelError::Close("Got an accept_channel message at a strange time".to_owned()));
}
if msg.dust_limit_satoshis > 21000000 * 100000000 {
return Err(ChannelError::Close(format!("Peer never wants payout outputs? dust_limit_satoshis was {}", msg.dust_limit_satoshis)));
if msg.common_fields.dust_limit_satoshis > 21000000 * 100000000 {
return Err(ChannelError::Close(format!("Peer never wants payout outputs? dust_limit_satoshis was {}", msg.common_fields.dust_limit_satoshis)));
}
if msg.channel_reserve_satoshis > self.context.channel_value_satoshis {
return Err(ChannelError::Close(format!("Bogus channel_reserve_satoshis ({}). Must not be greater than ({})", msg.channel_reserve_satoshis, self.context.channel_value_satoshis)));
}
if msg.dust_limit_satoshis > self.context.holder_selected_channel_reserve_satoshis {
return Err(ChannelError::Close(format!("Dust limit ({}) is bigger than our channel reserve ({})", msg.dust_limit_satoshis, self.context.holder_selected_channel_reserve_satoshis)));
if msg.common_fields.dust_limit_satoshis > self.context.holder_selected_channel_reserve_satoshis {
return Err(ChannelError::Close(format!("Dust limit ({}) is bigger than our channel reserve ({})", msg.common_fields.dust_limit_satoshis, self.context.holder_selected_channel_reserve_satoshis)));
}
if msg.channel_reserve_satoshis > self.context.channel_value_satoshis - self.context.holder_selected_channel_reserve_satoshis {
return Err(ChannelError::Close(format!("Bogus channel_reserve_satoshis ({}). Must not be greater than channel value minus our reserve ({})",
msg.channel_reserve_satoshis, self.context.channel_value_satoshis - self.context.holder_selected_channel_reserve_satoshis)));
}
let full_channel_value_msat = (self.context.channel_value_satoshis - msg.channel_reserve_satoshis) * 1000;
if msg.htlc_minimum_msat >= full_channel_value_msat {
return Err(ChannelError::Close(format!("Minimum htlc value ({}) is full channel value ({})", 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 ({}) is full channel value ({})", msg.common_fields.htlc_minimum_msat, full_channel_value_msat)));
}
let max_delay_acceptable = u16::min(peer_limits.their_to_self_delay, MAX_LOCAL_BREAKDOWN_TIMEOUT);
if msg.to_self_delay > max_delay_acceptable {
return Err(ChannelError::Close(format!("They wanted our payments to be delayed by a needlessly long period. Upper limit: {}. Actual: {}", max_delay_acceptable, msg.to_self_delay)));
if msg.common_fields.to_self_delay > max_delay_acceptable {
return Err(ChannelError::Close(format!("They wanted our payments to be delayed by a needlessly long period. Upper limit: {}. Actual: {}", max_delay_acceptable, 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()));
}
if msg.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)));
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.common_fields.max_accepted_htlcs, MAX_HTLCS)));
}
// Now check against optional parameters as set by config...
if msg.htlc_minimum_msat > peer_limits.max_htlc_minimum_msat {
return Err(ChannelError::Close(format!("htlc_minimum_msat ({}) is higher than the user specified limit ({})", msg.htlc_minimum_msat, peer_limits.max_htlc_minimum_msat)));
if msg.common_fields.htlc_minimum_msat > peer_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, peer_limits.max_htlc_minimum_msat)));
}
if msg.max_htlc_value_in_flight_msat < peer_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, peer_limits.min_max_htlc_value_in_flight_msat)));
if msg.common_fields.max_htlc_value_in_flight_msat < peer_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, peer_limits.min_max_htlc_value_in_flight_msat)));
}
if msg.channel_reserve_satoshis > peer_limits.max_channel_reserve_satoshis {
return Err(ChannelError::Close(format!("channel_reserve_satoshis ({}) is higher than the user specified limit ({})", msg.channel_reserve_satoshis, peer_limits.max_channel_reserve_satoshis)));
}
if msg.max_accepted_htlcs < peer_limits.min_max_accepted_htlcs {
return Err(ChannelError::Close(format!("max_accepted_htlcs ({}) is less than the user specified limit ({})", msg.max_accepted_htlcs, peer_limits.min_max_accepted_htlcs)));
if msg.common_fields.max_accepted_htlcs < peer_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, peer_limits.min_max_accepted_htlcs)));
}
if msg.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)));
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.common_fields.dust_limit_satoshis, MIN_CHAN_DUST_LIMIT_SATOSHIS)));
}
if msg.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)));
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.common_fields.dust_limit_satoshis, MAX_CHAN_DUST_LIMIT_SATOSHIS)));
}
if msg.minimum_depth > peer_limits.max_minimum_depth {
return Err(ChannelError::Close(format!("We consider the minimum depth to be unreasonably large. Expected minimum: ({}). Actual: ({})", peer_limits.max_minimum_depth, msg.minimum_depth)));
if msg.common_fields.minimum_depth > peer_limits.max_minimum_depth {
return Err(ChannelError::Close(format!("We consider the minimum depth to be unreasonably large. Expected minimum: ({}). Actual: ({})", peer_limits.max_minimum_depth, msg.common_fields.minimum_depth)));
}
if let Some(ty) = &msg.channel_type {
if let Some(ty) = &msg.common_fields.channel_type {
if *ty != self.context.channel_type {
return Err(ChannelError::Close("Channel Type in accept_channel didn't match the one sent in open_channel.".to_owned()));
}
@ -7059,7 +7061,7 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
}
let counterparty_shutdown_scriptpubkey = if their_features.supports_upfront_shutdown_script() {
match &msg.shutdown_scriptpubkey {
match &msg.common_fields.shutdown_scriptpubkey {
&Some(ref script) => {
// Peer is signaling upfront_shutdown and has opt-out with a 0-length script. We don't enforce anything
if script.len() == 0 {
@ -7078,32 +7080,32 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
}
} else { None };
self.context.counterparty_dust_limit_satoshis = msg.dust_limit_satoshis;
self.context.counterparty_max_htlc_value_in_flight_msat = cmp::min(msg.max_htlc_value_in_flight_msat, self.context.channel_value_satoshis * 1000);
self.context.counterparty_dust_limit_satoshis = msg.common_fields.dust_limit_satoshis;
self.context.counterparty_max_htlc_value_in_flight_msat = cmp::min(msg.common_fields.max_htlc_value_in_flight_msat, self.context.channel_value_satoshis * 1000);
self.context.counterparty_selected_channel_reserve_satoshis = Some(msg.channel_reserve_satoshis);
self.context.counterparty_htlc_minimum_msat = msg.htlc_minimum_msat;
self.context.counterparty_max_accepted_htlcs = msg.max_accepted_htlcs;
self.context.counterparty_htlc_minimum_msat = msg.common_fields.htlc_minimum_msat;
self.context.counterparty_max_accepted_htlcs = msg.common_fields.max_accepted_htlcs;
if peer_limits.trust_own_funding_0conf {
self.context.minimum_depth = Some(msg.minimum_depth);
self.context.minimum_depth = Some(msg.common_fields.minimum_depth);
} else {
self.context.minimum_depth = Some(cmp::max(1, msg.minimum_depth));
self.context.minimum_depth = Some(cmp::max(1, msg.common_fields.minimum_depth));
}
let counterparty_pubkeys = ChannelPublicKeys {
funding_pubkey: msg.funding_pubkey,
revocation_basepoint: RevocationBasepoint::from(msg.revocation_basepoint),
payment_point: msg.payment_point,
delayed_payment_basepoint: DelayedPaymentBasepoint::from(msg.delayed_payment_basepoint),
htlc_basepoint: HtlcBasepoint::from(msg.htlc_basepoint)
funding_pubkey: msg.common_fields.funding_pubkey,
revocation_basepoint: RevocationBasepoint::from(msg.common_fields.revocation_basepoint),
payment_point: msg.common_fields.payment_basepoint,
delayed_payment_basepoint: DelayedPaymentBasepoint::from(msg.common_fields.delayed_payment_basepoint),
htlc_basepoint: HtlcBasepoint::from(msg.common_fields.htlc_basepoint)
};
self.context.channel_transaction_parameters.counterparty_parameters = Some(CounterpartyChannelTransactionParameters {
selected_contest_delay: msg.to_self_delay,
selected_contest_delay: msg.common_fields.to_self_delay,
pubkeys: counterparty_pubkeys,
});
self.context.counterparty_cur_commitment_point = Some(msg.first_per_commitment_point);
self.context.counterparty_cur_commitment_point = Some(msg.common_fields.first_per_commitment_point);
self.context.counterparty_shutdown_scriptpubkey = counterparty_shutdown_scriptpubkey;
self.context.channel_state = ChannelState::NegotiatingFunding(
@ -7233,7 +7235,7 @@ pub(super) fn channel_type_from_open_channel(
msg: &msgs::OpenChannel, their_features: &InitFeatures,
our_supported_features: &ChannelTypeFeatures
) -> 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() {
return Err(ChannelError::Close("Channel Type field contained optional bits - this is not allowed".to_owned()));
}
@ -7248,7 +7250,7 @@ pub(super) fn channel_type_from_open_channel(
if !channel_type.is_subset(our_supported_features) {
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 {
return Err(ChannelError::Close("SCID Alias/Privacy Channel Type cannot be set on a public channel".to_owned()));
}
@ -7275,22 +7277,22 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
F::Target: FeeEstimator,
L::Target: Logger,
{
let logger = WithContext::from(logger, Some(counterparty_node_id), Some(msg.temporary_channel_id));
let announced_channel = if (msg.channel_flags & 1) == 1 { true } else { false };
let logger = WithContext::from(logger, Some(counterparty_node_id), Some(msg.common_fields.temporary_channel_id));
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
// support this channel type.
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 holder_signer = signer_provider.derive_channel_signer(msg.funding_satoshis, channel_keys_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.common_fields.funding_satoshis, channel_keys_id);
let pubkeys = holder_signer.pubkeys().clone();
let counterparty_pubkeys = ChannelPublicKeys {
funding_pubkey: msg.funding_pubkey,
revocation_basepoint: RevocationBasepoint::from(msg.revocation_basepoint),
payment_point: msg.payment_point,
delayed_payment_basepoint: DelayedPaymentBasepoint::from(msg.delayed_payment_basepoint),
htlc_basepoint: HtlcBasepoint::from(msg.htlc_basepoint)
funding_pubkey: msg.common_fields.funding_pubkey,
revocation_basepoint: RevocationBasepoint::from(msg.common_fields.revocation_basepoint),
payment_point: msg.common_fields.payment_basepoint,
delayed_payment_basepoint: DelayedPaymentBasepoint::from(msg.common_fields.delayed_payment_basepoint),
htlc_basepoint: HtlcBasepoint::from(msg.common_fields.htlc_basepoint)
};
if config.channel_handshake_config.our_to_self_delay < BREAKDOWN_TIMEOUT {
@ -7298,59 +7300,59 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
}
// Check sanity of message fields:
if msg.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)));
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.common_fields.funding_satoshis)));
}
if msg.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)));
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.common_fields.funding_satoshis)));
}
if 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.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.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 {
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 {
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)));
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.common_fields.dust_limit_satoshis, msg.common_fields.funding_satoshis)));
}
if msg.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)));
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.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);
if msg.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)));
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.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()));
}
if msg.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)));
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.common_fields.max_accepted_htlcs, MAX_HTLCS)));
}
// Now check against optional parameters as set by config...
if 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.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.common_fields.funding_satoshis, config.channel_handshake_limits.min_funding_satoshis)));
}
if 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.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.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 {
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)));
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.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 {
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 {
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)));
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.common_fields.max_accepted_htlcs, config.channel_handshake_limits.min_max_accepted_htlcs)));
}
if msg.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)));
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.common_fields.dust_limit_satoshis, MIN_CHAN_DUST_LIMIT_SATOSHIS)));
}
if msg.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)));
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.common_fields.dust_limit_satoshis, MAX_CHAN_DUST_LIMIT_SATOSHIS)));
}
// Convert things into internal flags and prep our state:
@ -7361,7 +7363,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 {
// Protocol level safety check in place, although it should never happen because
// of `MIN_THEIR_CHAN_RESERVE_SATOSHIS`
@ -7374,8 +7376,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.",
msg.channel_reserve_satoshis, MIN_CHAN_DUST_LIMIT_SATOSHIS);
}
if holder_selected_channel_reserve_satoshis < msg.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)));
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.common_fields.dust_limit_satoshis, holder_selected_channel_reserve_satoshis)));
}
// check if the funder's amount for the initial commitment tx is sufficient
@ -7385,8 +7387,8 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
} else {
0
};
let funders_amount_msat = msg.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 funders_amount_msat = msg.common_fields.funding_satoshis * 1000 - msg.push_msat;
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 {
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)));
}
@ -7399,7 +7401,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
}
let counterparty_shutdown_scriptpubkey = if their_features.supports_upfront_shutdown_script() {
match &msg.shutdown_scriptpubkey {
match &msg.common_fields.shutdown_scriptpubkey {
&Some(ref script) => {
// Peer is signaling upfront_shutdown and has opt-out with a 0-length script. We don't enforce anything
if script.len() == 0 {
@ -7459,8 +7461,8 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
inbound_handshake_limits_override: None,
temporary_channel_id: Some(msg.temporary_channel_id),
channel_id: msg.temporary_channel_id,
temporary_channel_id: Some(msg.common_fields.temporary_channel_id),
channel_id: msg.common_fields.temporary_channel_id,
channel_state: ChannelState::NegotiatingFunding(
NegotiatingFundingFlags::OUR_INIT_SENT | NegotiatingFundingFlags::THEIR_INIT_SENT
),
@ -7499,9 +7501,9 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
signer_pending_funding: false,
#[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)]
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,
pending_counterparty_closing_signed: None,
@ -7514,17 +7516,17 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
short_channel_id: None,
channel_creation_height: current_chain_height,
feerate_per_kw: msg.feerate_per_kw,
channel_value_satoshis: msg.funding_satoshis,
counterparty_dust_limit_satoshis: msg.dust_limit_satoshis,
feerate_per_kw: msg.common_fields.commitment_feerate_sat_per_1000_weight,
channel_value_satoshis: msg.common_fields.funding_satoshis,
counterparty_dust_limit_satoshis: msg.common_fields.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),
holder_max_htlc_value_in_flight_msat: get_holder_max_htlc_value_in_flight_msat(msg.funding_satoshis, &config.channel_handshake_config),
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.common_fields.funding_satoshis, &config.channel_handshake_config),
counterparty_selected_channel_reserve_satoshis: Some(msg.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 },
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),
minimum_depth,
@ -7535,7 +7537,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
holder_selected_contest_delay: config.channel_handshake_config.our_to_self_delay,
is_outbound_from_holder: false,
counterparty_parameters: Some(CounterpartyChannelTransactionParameters {
selected_contest_delay: msg.to_self_delay,
selected_contest_delay: msg.common_fields.to_self_delay,
pubkeys: counterparty_pubkeys,
}),
funding_outpoint: None,
@ -7544,7 +7546,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
funding_transaction: 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_node_id,
@ -7618,25 +7620,27 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
let keys = self.context.get_holder_pubkeys();
msgs::AcceptChannel {
temporary_channel_id: self.context.channel_id,
dust_limit_satoshis: self.context.holder_dust_limit_satoshis,
max_htlc_value_in_flight_msat: self.context.holder_max_htlc_value_in_flight_msat,
common_fields: msgs::CommonAcceptChannelFields {
temporary_channel_id: self.context.channel_id,
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,
minimum_depth: self.context.minimum_depth.unwrap(),
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,
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()),
},
channel_reserve_satoshis: self.context.holder_selected_channel_reserve_satoshis,
htlc_minimum_msat: self.context.holder_htlc_minimum_msat,
minimum_depth: self.context.minimum_depth.unwrap(),
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,
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()),
#[cfg(taproot)]
next_local_nonce: None,
}
@ -8873,7 +8877,7 @@ mod tests {
// same as the old fee.
fee_est.fee_est = 500;
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]
@ -8904,7 +8908,7 @@ mod tests {
// Node B --> Node A: accept channel, explicitly setting B's dust limit.
let mut accept_channel_msg = node_b_chan.accept_inbound_channel();
accept_channel_msg.dust_limit_satoshis = 546;
accept_channel_msg.common_fields.dust_limit_satoshis = 546;
node_a_chan.accept_channel(&accept_channel_msg, &config.channel_handshake_limits, &channelmanager::provided_init_features(&config)).unwrap();
node_a_chan.context.holder_dust_limit_satoshis = 1560;
@ -9222,7 +9226,7 @@ mod tests {
// Node B --> Node A: accept channel, explicitly setting B's dust limit.
let mut accept_channel_msg = node_b_chan.accept_inbound_channel();
accept_channel_msg.dust_limit_satoshis = 546;
accept_channel_msg.common_fields.dust_limit_satoshis = 546;
node_a_chan.accept_channel(&accept_channel_msg, &config.channel_handshake_limits, &channelmanager::provided_init_features(&config)).unwrap();
node_a_chan.context.holder_dust_limit_satoshis = 1560;
@ -10195,7 +10199,7 @@ mod tests {
channel_type_features.set_zero_conf_required();
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 res = InboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider,
node_b_node_id, &channelmanager::provided_channel_type_features(&config),
@ -10278,7 +10282,7 @@ mod tests {
// 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));
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
// `static_remote_key`, it will fail the channel.
@ -10324,7 +10328,7 @@ mod tests {
).unwrap();
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(
&fee_estimator, &&keys_provider, &&keys_provider, node_id_a,
@ -10351,7 +10355,7 @@ mod tests {
).unwrap();
let mut accept_channel_msg = channel_b.get_accept_channel_message();
accept_channel_msg.channel_type = Some(simple_anchors_channel_type.clone());
accept_channel_msg.common_fields.channel_type = Some(simple_anchors_channel_type.clone());
let res = channel_a.accept_channel(
&accept_channel_msg, &config.channel_handshake_limits, &simple_anchors_init

View file

@ -6194,12 +6194,14 @@ where
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
// likely to be lost on restart!
if msg.chain_hash != self.chain_hash {
return Err(MsgHandleErrInternal::send_err_msg_no_close("Unknown genesis block hash".to_owned(), msg.temporary_channel_id.clone()));
if msg.common_fields.chain_hash != self.chain_hash {
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 {
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
@ -6212,7 +6214,9 @@ where
let peer_state_mutex = per_peer_state.get(counterparty_node_id)
.ok_or_else(|| {
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 peer_state = &mut *peer_state_lock;
@ -6226,20 +6230,22 @@ where
{
return Err(MsgHandleErrInternal::send_err_msg_no_close(
"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();
if Self::unfunded_channel_count(peer_state, best_block_height) >= MAX_UNFUNDED_CHANS_PER_PEER {
return Err(MsgHandleErrInternal::send_err_msg_no_close(
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);
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.
@ -6247,13 +6253,13 @@ where
let channel_type = channel::channel_type_from_open_channel(
&msg, &peer_state.latest_features, &self.channel_type_features()
).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();
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(),
funding_satoshis: msg.funding_satoshis,
funding_satoshis: msg.common_fields.funding_satoshis,
push_msat: msg.push_msat,
channel_type,
}, None));
@ -6273,17 +6279,21 @@ where
&self.default_configuration, best_block_height, &self.logger, /*is_0conf=*/false)
{
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
};
let channel_type = channel.context.get_channel_type();
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() {
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();
@ -6305,11 +6315,11 @@ where
let peer_state_mutex = per_peer_state.get(counterparty_node_id)
.ok_or_else(|| {
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)
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)
})?;
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
let peer_state = &mut *peer_state_lock;
match peer_state.channel_by_id.entry(msg.temporary_channel_id) {
match peer_state.channel_by_id.entry(msg.common_fields.temporary_channel_id) {
hash_map::Entry::Occupied(mut phase) => {
match phase.get_mut() {
ChannelPhase::UnfundedOutboundV1(chan) => {
@ -6317,16 +6327,16 @@ where
(chan.context.get_value_satoshis(), chan.context.get_funding_redeemscript().to_v0_p2wsh(), chan.context.get_user_id())
},
_ => {
return Err(MsgHandleErrInternal::send_err_msg_no_close(format!("Got an unexpected accept_channel message from peer with counterparty_node_id {}", counterparty_node_id), msg.temporary_channel_id));
return Err(MsgHandleErrInternal::send_err_msg_no_close(format!("Got an unexpected accept_channel message from peer with counterparty_node_id {}", counterparty_node_id), msg.common_fields.temporary_channel_id));
}
}
},
hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close(format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", counterparty_node_id), msg.temporary_channel_id))
hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close(format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", counterparty_node_id), msg.common_fields.temporary_channel_id))
}
};
let mut pending_events = self.pending_events.lock().unwrap();
pending_events.push_back((events::Event::FundingGenerationReady {
temporary_channel_id: msg.temporary_channel_id,
temporary_channel_id: msg.common_fields.temporary_channel_id,
counterparty_node_id: *counterparty_node_id,
channel_value_satoshis: value,
output_script,
@ -8713,7 +8723,7 @@ where
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(
"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) {
@ -8729,7 +8739,7 @@ where
fn handle_accept_channel_v2(&self, counterparty_node_id: &PublicKey, msg: &msgs::AcceptChannelV2) {
let _: Result<(), _> = handle_error!(self, Err(MsgHandleErrInternal::send_err_msg_no_close(
"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_funding_created(&self, counterparty_node_id: &PublicKey, msg: &msgs::FundingCreated) {
@ -12033,14 +12043,15 @@ mod tests {
check_added_monitors!(nodes[0], 1);
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
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);
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,
// it doesn't count as a "protected" peer, i.e. it counts towards the MAX_NO_CHANNEL_PEERS
@ -12088,11 +12099,11 @@ mod tests {
for i in 0..super::MAX_UNFUNDED_CHANNEL_PEERS - 1 {
nodes[1].node.handle_open_channel(&peer_pks[i], &open_channel_msg);
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);
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
nodes[1].node.create_channel(last_random_pk, 100_000, 0, 42, None, None).unwrap();
@ -12128,14 +12139,14 @@ mod tests {
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);
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
// rejected.
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,
open_channel_msg.temporary_channel_id);
open_channel_msg.common_fields.temporary_channel_id);
// 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();
@ -12144,7 +12155,7 @@ mod tests {
// 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);
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]
@ -12180,7 +12191,7 @@ mod tests {
_ => panic!("Unexpected event"),
}
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.
@ -12202,7 +12213,7 @@ mod tests {
_ => panic!("Unexpected event"),
}
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.
nodes[1].node.handle_open_channel(&last_random_pk, &open_channel_msg);
@ -12347,7 +12358,7 @@ mod tests {
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());
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);
let events = nodes[1].node.get_and_clear_pending_events();
@ -12362,7 +12373,7 @@ mod tests {
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());
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
// not have generated any events.

View file

@ -1203,7 +1203,7 @@ pub fn open_zero_conf_channel<'a, 'b, 'c, 'd>(initiator: &'a Node<'b, 'c, 'd>, r
};
let accept_channel = get_event_msg!(receiver, MessageSendEvent::SendAcceptChannel, initiator.node.get_our_node_id());
assert_eq!(accept_channel.minimum_depth, 0);
assert_eq!(accept_channel.common_fields.minimum_depth, 0);
initiator.node.handle_accept_channel(&receiver.node.get_our_node_id(), &accept_channel);
let (temporary_channel_id, tx, _) = create_funding_transaction(&initiator, &receiver.node.get_our_node_id(), 100_000, 42);
@ -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 {
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());
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);
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 {
@ -1270,7 +1270,7 @@ pub fn exchange_open_accept_chan<'a, 'b, 'c>(node_a: &Node<'a, 'b, 'c>, node_b:
};
}
let accept_channel_msg = get_event_msg!(node_b, MessageSendEvent::SendAcceptChannel, node_a.node.get_our_node_id());
assert_eq!(accept_channel_msg.temporary_channel_id, create_chan_id);
assert_eq!(accept_channel_msg.common_fields.temporary_channel_id, create_chan_id);
node_a.node.handle_accept_channel(&node_b.node.get_our_node_id(), &accept_channel_msg);
assert_ne!(node_b.node.list_channels().iter().find(|channel| channel.channel_id == create_chan_id).unwrap().user_channel_id, 0);

View file

@ -107,22 +107,22 @@ fn test_insane_channel_opens() {
use crate::ln::channelmanager::MAX_LOCAL_BREAKDOWN_TIMEOUT;
// 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!("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!("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.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]
@ -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());
if !send_from_initiator {
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);
@ -174,7 +174,7 @@ fn do_test_counterparty_no_reserve(send_from_initiator: bool) {
let mut accept_channel_message = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
if send_from_initiator {
accept_channel_message.channel_reserve_satoshis = 0;
accept_channel_message.max_htlc_value_in_flight_msat = 100_000_000;
accept_channel_message.common_fields.max_htlc_value_in_flight_msat = 100_000_000;
}
nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &accept_channel_message);
{
@ -5841,26 +5841,26 @@ fn bolt2_open_channel_sending_node_checks_part2() {
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
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
// 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.
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.
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.
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.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.payment_point.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.funding_pubkey.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.common_fields.htlc_basepoint.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.common_fields.delayed_payment_basepoint.serialize()).is_ok());
}
#[test]
@ -5874,7 +5874,7 @@ fn bolt2_open_channel_sane_dust_limit() {
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();
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;
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &node0_to_1_send_open_channel);
@ -7214,7 +7214,7 @@ fn test_user_configurable_csv_delay() {
// 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();
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) }),
&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)
@ -7229,7 +7229,7 @@ fn test_user_configurable_csv_delay() {
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 1000000, 1000000, 42, None, None).unwrap();
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id()));
let mut accept_channel = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
accept_channel.to_self_delay = 200;
accept_channel.common_fields.to_self_delay = 200;
nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &accept_channel);
let reason_msg;
if let MessageSendEvent::HandleError { ref action, .. } = nodes[0].node.get_and_clear_pending_msg_events()[0] {
@ -7246,7 +7246,7 @@ fn test_user_configurable_csv_delay() {
// 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();
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) }),
&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)
@ -7931,8 +7931,8 @@ fn test_override_channel_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());
assert_eq!(res.channel_flags, 0);
assert_eq!(res.to_self_delay, 200);
assert_eq!(res.common_fields.channel_flags, 0);
assert_eq!(res.common_fields.to_self_delay, 200);
}
#[test]
@ -7946,11 +7946,11 @@ 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();
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);
let res = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
assert_eq!(res.htlc_minimum_msat, 1);
assert_eq!(res.common_fields.htlc_minimum_msat, 1);
}
#[test]
@ -8962,7 +8962,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
// `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
// `temporary_channel_id` as they are from different peers.
@ -8973,7 +8973,7 @@ fn test_duplicate_temporary_channel_id_from_different_peers() {
match &events[0] {
MessageSendEvent::SendAcceptChannel { node_id, msg } => {
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.common_fields.temporary_channel_id, open_chan_msg_chan_1_0.common_fields.temporary_channel_id);
},
_ => panic!("Unexpected event"),
}
@ -8986,7 +8986,7 @@ fn test_duplicate_temporary_channel_id_from_different_peers() {
match &events[0] {
MessageSendEvent::SendAcceptChannel { node_id, msg } => {
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.common_fields.temporary_channel_id, open_chan_msg_chan_1_0.common_fields.temporary_channel_id);
},
_ => panic!("Unexpected event"),
}
@ -9106,11 +9106,11 @@ 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();
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;
open_chan_msg.temporary_channel_id = real_channel_id;
let node_c_temp_chan_id = open_chan_msg.common_fields.temporary_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);
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.common_fields.temporary_channel_id = node_c_temp_chan_id;
nodes[2].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &accept_chan_msg);
// Now that we have a second channel with the same funding txo, send a bogus funding message
@ -9168,7 +9168,7 @@ fn test_duplicate_chan_id() {
// 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
// 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());
},
_ => panic!("Unexpected event"),
@ -9202,7 +9202,7 @@ fn test_duplicate_chan_id() {
// 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
// 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);
{
let events = nodes[1].node.get_and_clear_pending_msg_events();
@ -9211,7 +9211,7 @@ fn test_duplicate_chan_id() {
MessageSendEvent::HandleError { action: ErrorAction::SendErrorMessage { ref msg }, node_id } => {
// 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.
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());
},
_ => panic!("Unexpected event"),
@ -9232,7 +9232,7 @@ fn test_duplicate_chan_id() {
// 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
// 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) => {
let logger = test_utils::TestLogger::new();
chan.get_funding_created(tx.clone(), funding_outpoint, false, &&logger).map_err(|_| ()).unwrap()
@ -9899,10 +9899,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();
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.max_accepted_htlcs = 60;
open_channel.common_fields.max_htlc_value_in_flight_msat = 50_000_000;
open_channel.common_fields.max_accepted_htlcs = 60;
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);
let mut accept_channel = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
@ -9947,10 +9947,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_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_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_htlc_on_counterparty_tx: u64 = 4;

View file

@ -172,76 +172,20 @@ pub struct Pong {
pub byteslen: u16,
}
/// An [`open_channel`] message to be sent to or received from a peer.
///
/// Used in V1 channel establishment
/// Contains fields that are both common to [`open_channel`] and `open_channel2` messages.
///
/// [`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`.
#[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
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,
/// The feerate for the funding transaction set by the channel initiator
pub funding_feerate_sat_per_1000_weight: u32,
/// 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
/// For V1 channels: The channel value
/// For V2 channels: Part of the channel value contributed by the channel initiator
pub funding_satoshis: u64,
/// The threshold below which outputs on transactions broadcast by the channel initiator will be
/// omitted
@ -250,13 +194,14 @@ pub struct OpenChannelV2 {
pub max_htlc_value_in_flight_msat: u64,
/// The minimum HTLC size incoming to channel initiator, in milli-satoshi
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
/// broadcast a commitment transaction
pub to_self_delay: u16,
/// The maximum number of inbound HTLCs towards channel initiator
pub max_accepted_htlcs: u16,
/// The locktime for the funding transaction
pub locktime: u32,
/// The channel initiator's key controlling the funding transaction
pub funding_pubkey: PublicKey,
/// Used to derive a revocation key for transactions broadcast by counterparty
@ -270,84 +215,64 @@ pub struct OpenChannelV2 {
pub htlc_basepoint: PublicKey,
/// The first to-be-broadcast-by-channel-initiator transaction's per commitment point
pub first_per_commitment_point: PublicKey,
/// The second to-be-broadcast-by-channel-initiator transaction's per commitment point
pub second_per_commitment_point: PublicKey,
/// Channel flags
/// The channel flags to be used
pub channel_flags: u8,
/// Optionally, a request to pre-set the to-channel-initiator output's scriptPubkey for when we
/// collaboratively close
pub shutdown_scriptpubkey: Option<ScriptBuf>,
/// The channel type that this channel will represent. If none is set, we derive the channel
/// type from the intersection of our feature bits with our counterparty's feature bits from
/// the Init message.
/// 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_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
pub require_confirmed_inputs: Option<()>,
}
/// An [`accept_channel`] message to be sent to or received from a peer.
///
/// Used in V1 channel establishment
/// Contains fields that are both common to [`accept_channel`] and `accept_channel2` messages.
///
/// [`accept_channel`]: https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#the-accept_channel-message
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct AcceptChannel {
/// A temporary channel ID, until the funding outpoint is announced
pub temporary_channel_id: ChannelId,
/// 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,
/// Minimum depth of the funding transaction before the channel is considered open
pub minimum_depth: 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 for transactions broadcast by counterparty
pub htlc_basepoint: PublicKey,
/// The first to-be-broadcast-by-sender transaction's per commitment point
pub first_per_commitment_point: PublicKey,
/// 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.
/// This is required to match the equivalent field in [`OpenChannel::channel_type`].
pub channel_type: Option<ChannelTypeFeatures>,
#[cfg(taproot)]
/// Next nonce the channel initiator should use to create a funding output signature against
pub next_local_nonce: Option<musig2::types::PublicNonce>,
}
/// An accept_channel2 message to be sent by or received from the channel accepter.
///
/// Used in V2 channel establishment
///
// TODO(dual_funding): Add spec link for `accept_channel2`.
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct AcceptChannelV2 {
/// The same `temporary_channel_id` received from the initiator's `open_channel2` message.
pub struct CommonAcceptChannelFields {
/// The same `temporary_channel_id` received from the initiator's `open_channel2` or `open_channel` message.
pub temporary_channel_id: ChannelId,
/// Part of the channel value contributed by the channel acceptor
pub funding_satoshis: u64,
/// The threshold below which outputs on transactions broadcast by the channel acceptor will be
/// omitted
pub dust_limit_satoshis: u64,
/// The maximum inbound HTLC value in flight towards channel acceptor, in milli-satoshi
/// The maximum inbound HTLC value in flight towards sender, in milli-satoshi
pub max_htlc_value_in_flight_msat: u64,
/// The minimum HTLC size incoming to channel acceptor, in milli-satoshi
pub htlc_minimum_msat: u64,
@ -371,8 +296,6 @@ pub struct AcceptChannelV2 {
pub htlc_basepoint: PublicKey,
/// The first to-be-broadcast-by-channel-acceptor transaction's per commitment point
pub first_per_commitment_point: PublicKey,
/// The second to-be-broadcast-by-channel-acceptor transaction's per commitment point
pub second_per_commitment_point: PublicKey,
/// Optionally, a request to pre-set the to-channel-acceptor output's scriptPubkey for when we
/// collaboratively close
pub shutdown_scriptpubkey: Option<ScriptBuf>,
@ -380,8 +303,40 @@ pub struct AcceptChannelV2 {
/// type from the intersection of our feature bits with our counterparty's feature bits from
/// the Init message.
///
/// This is required to match the equivalent field in [`OpenChannelV2::channel_type`].
/// This is required to match the equivalent field in [`OpenChannel`] or [`OpenChannelV2`]'s
/// [`CommonOpenChannelFields::channel_type`].
pub channel_type: Option<ChannelTypeFeatures>,
}
/// An [`accept_channel`] message to be sent to or received from a peer.
///
/// Used in V1 channel establishment
///
/// [`accept_channel`]: https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#the-accept_channel-message
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct AcceptChannel {
/// Common fields of `accept_channel(2)`-like messages
pub common_fields: CommonAcceptChannelFields,
/// The minimum value unencumbered by HTLCs for the counterparty to keep in the channel
pub channel_reserve_satoshis: u64,
#[cfg(taproot)]
/// Next nonce the channel initiator should use to create a funding output signature against
pub next_local_nonce: Option<musig2::types::PublicNonce>,
}
/// An accept_channel2 message to be sent by or received from the channel accepter.
///
/// Used in V2 channel establishment
///
// TODO(dual_funding): Add spec link for `accept_channel2`.
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct AcceptChannelV2 {
/// Common fields of `accept_channel(2)`-like messages
pub common_fields: CommonAcceptChannelFields,
/// Part of the channel value contributed by the channel acceptor
pub funding_satoshis: u64,
/// The second to-be-broadcast-by-channel-acceptor transaction's per commitment point
pub second_per_commitment_point: PublicKey,
/// Optionally, a requirement that only confirmed inputs can be added
pub require_confirmed_inputs: Option<()>,
}
@ -1831,70 +1786,173 @@ impl From<io::Error> for DecodeError {
}
}
#[cfg(not(taproot))]
impl_writeable_msg!(AcceptChannel, {
temporary_channel_id,
dust_limit_satoshis,
max_htlc_value_in_flight_msat,
channel_reserve_satoshis,
htlc_minimum_msat,
minimum_depth,
to_self_delay,
max_accepted_htlcs,
funding_pubkey,
revocation_basepoint,
payment_point,
delayed_payment_basepoint,
htlc_basepoint,
first_per_commitment_point,
}, {
(0, shutdown_scriptpubkey, (option, encoding: (ScriptBuf, WithoutLength))), // Don't encode length twice.
(1, channel_type, option),
});
impl Writeable for AcceptChannel {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
self.common_fields.temporary_channel_id.write(w)?;
self.common_fields.dust_limit_satoshis.write(w)?;
self.common_fields.max_htlc_value_in_flight_msat.write(w)?;
self.channel_reserve_satoshis.write(w)?;
self.common_fields.htlc_minimum_msat.write(w)?;
self.common_fields.minimum_depth.write(w)?;
self.common_fields.to_self_delay.write(w)?;
self.common_fields.max_accepted_htlcs.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)?;
#[cfg(not(taproot))]
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),
});
#[cfg(taproot)]
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),
(4, self.next_local_nonce, option),
});
Ok(())
}
}
#[cfg(taproot)]
impl_writeable_msg!(AcceptChannel, {
temporary_channel_id,
dust_limit_satoshis,
max_htlc_value_in_flight_msat,
channel_reserve_satoshis,
htlc_minimum_msat,
minimum_depth,
to_self_delay,
max_accepted_htlcs,
funding_pubkey,
revocation_basepoint,
payment_point,
delayed_payment_basepoint,
htlc_basepoint,
first_per_commitment_point,
}, {
(0, shutdown_scriptpubkey, (option, encoding: (ScriptBuf, WithoutLength))), // Don't encode length twice.
(1, channel_type, option),
(4, next_local_nonce, option),
});
impl Readable for AcceptChannel {
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
let temporary_channel_id: ChannelId = Readable::read(r)?;
let dust_limit_satoshis: u64 = Readable::read(r)?;
let max_htlc_value_in_flight_msat: u64 = Readable::read(r)?;
let channel_reserve_satoshis: u64 = Readable::read(r)?;
let htlc_minimum_msat: u64 = Readable::read(r)?;
let minimum_depth: u32 = Readable::read(r)?;
let to_self_delay: u16 = Readable::read(r)?;
let max_accepted_htlcs: u16 = 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)?;
impl_writeable_msg!(AcceptChannelV2, {
temporary_channel_id,
funding_satoshis,
dust_limit_satoshis,
max_htlc_value_in_flight_msat,
htlc_minimum_msat,
minimum_depth,
to_self_delay,
max_accepted_htlcs,
funding_pubkey,
revocation_basepoint,
payment_basepoint,
delayed_payment_basepoint,
htlc_basepoint,
first_per_commitment_point,
second_per_commitment_point,
}, {
(0, shutdown_scriptpubkey, option),
(1, channel_type, option),
(2, require_confirmed_inputs, option),
});
let mut shutdown_scriptpubkey: Option<ScriptBuf> = None;
let mut channel_type: Option<ChannelTypeFeatures> = None;
#[cfg(not(taproot))]
decode_tlv_stream!(r, {
(0, shutdown_scriptpubkey, (option, encoding: (ScriptBuf, WithoutLength))),
(1, channel_type, option),
});
#[cfg(taproot)]
let mut next_local_nonce: Option<musig2::types::PublicNonce> = None;
#[cfg(taproot)]
decode_tlv_stream!(r, {
(0, shutdown_scriptpubkey, (option, encoding: (ScriptBuf, WithoutLength))),
(1, channel_type, option),
(4, next_local_nonce, option),
});
Ok(AcceptChannel {
common_fields: CommonAcceptChannelFields {
temporary_channel_id,
dust_limit_satoshis,
max_htlc_value_in_flight_msat,
htlc_minimum_msat,
minimum_depth,
to_self_delay,
max_accepted_htlcs,
funding_pubkey,
revocation_basepoint,
payment_basepoint,
delayed_payment_basepoint,
htlc_basepoint,
first_per_commitment_point,
shutdown_scriptpubkey,
channel_type,
},
channel_reserve_satoshis,
#[cfg(taproot)]
next_local_nonce,
})
}
}
impl Writeable for AcceptChannelV2 {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
self.common_fields.temporary_channel_id.write(w)?;
self.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.minimum_depth.write(w)?;
self.common_fields.to_self_delay.write(w)?;
self.common_fields.max_accepted_htlcs.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)?;
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 AcceptChannelV2 {
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
let temporary_channel_id: ChannelId = 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 minimum_depth: u32 = Readable::read(r)?;
let to_self_delay: u16 = Readable::read(r)?;
let max_accepted_htlcs: u16 = 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 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(AcceptChannelV2 {
common_fields: CommonAcceptChannelFields {
temporary_channel_id,
dust_limit_satoshis,
max_htlc_value_in_flight_msat,
htlc_minimum_msat,
minimum_depth,
to_self_delay,
max_accepted_htlcs,
funding_pubkey,
revocation_basepoint,
payment_basepoint,
delayed_payment_basepoint,
htlc_basepoint,
first_per_commitment_point,
shutdown_scriptpubkey,
channel_type,
},
funding_satoshis,
second_per_commitment_point,
require_confirmed_inputs,
})
}
}
impl_writeable_msg!(Stfu, {
channel_id,
@ -2095,55 +2153,176 @@ impl Readable for Init {
}
}
impl_writeable_msg!(OpenChannel, {
chain_hash,
temporary_channel_id,
funding_satoshis,
push_msat,
dust_limit_satoshis,
max_htlc_value_in_flight_msat,
channel_reserve_satoshis,
htlc_minimum_msat,
feerate_per_kw,
to_self_delay,
max_accepted_htlcs,
funding_pubkey,
revocation_basepoint,
payment_point,
delayed_payment_basepoint,
htlc_basepoint,
first_per_commitment_point,
channel_flags,
}, {
(0, shutdown_scriptpubkey, (option, encoding: (ScriptBuf, WithoutLength))), // Don't encode length twice.
(1, channel_type, option),
});
impl Writeable for OpenChannel {
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.common_fields.funding_satoshis.write(w)?;
self.push_msat.write(w)?;
self.common_fields.dust_limit_satoshis.write(w)?;
self.common_fields.max_htlc_value_in_flight_msat.write(w)?;
self.channel_reserve_satoshis.write(w)?;
self.common_fields.htlc_minimum_msat.write(w)?;
self.common_fields.commitment_feerate_sat_per_1000_weight.write(w)?;
self.common_fields.to_self_delay.write(w)?;
self.common_fields.max_accepted_htlcs.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.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),
});
Ok(())
}
}
impl_writeable_msg!(OpenChannelV2, {
chain_hash,
temporary_channel_id,
funding_feerate_sat_per_1000_weight,
commitment_feerate_sat_per_1000_weight,
funding_satoshis,
dust_limit_satoshis,
max_htlc_value_in_flight_msat,
htlc_minimum_msat,
to_self_delay,
max_accepted_htlcs,
locktime,
funding_pubkey,
revocation_basepoint,
payment_basepoint,
delayed_payment_basepoint,
htlc_basepoint,
first_per_commitment_point,
second_per_commitment_point,
channel_flags,
}, {
(0, shutdown_scriptpubkey, option),
(1, channel_type, option),
(2, require_confirmed_inputs, option),
});
impl Readable for OpenChannel {
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_satoshis: u64 = Readable::read(r)?;
let push_msat: u64 = Readable::read(r)?;
let dust_limit_satoshis: u64 = Readable::read(r)?;
let max_htlc_value_in_flight_msat: u64 = Readable::read(r)?;
let channel_reserve_satoshis: u64 = Readable::read(r)?;
let htlc_minimum_msat: u64 = Readable::read(r)?;
let commitment_feerate_sat_per_1000_weight: u32 = Readable::read(r)?;
let to_self_delay: u16 = Readable::read(r)?;
let max_accepted_htlcs: u16 = 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 channel_flags: u8 = Readable::read(r)?;
let mut shutdown_scriptpubkey: Option<ScriptBuf> = None;
let mut channel_type: Option<ChannelTypeFeatures> = None;
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))]
impl_writeable_msg!(RevokeAndACK, {
@ -2854,7 +3033,7 @@ mod tests {
use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
use crate::ln::ChannelId;
use crate::ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures};
use crate::ln::msgs::{self, FinalOnionHopData, OnionErrorPacket};
use crate::ln::msgs::{self, FinalOnionHopData, OnionErrorPacket, CommonOpenChannelFields, CommonAcceptChannelFields};
use crate::ln::msgs::SocketAddress;
use crate::routing::gossip::{NodeAlias, NodeId};
use crate::util::ser::{Writeable, Readable, ReadableArgs, Hostname, TransactionU16LenLimited};
@ -3206,26 +3385,28 @@ mod tests {
let (_, pubkey_5) = get_keys_from!("0505050505050505050505050505050505050505050505050505050505050505", secp_ctx);
let (_, pubkey_6) = get_keys_from!("0606060606060606060606060606060606060606060606060606060606060606", secp_ctx);
let open_channel = msgs::OpenChannel {
chain_hash: ChainHash::using_genesis_block(Network::Bitcoin),
temporary_channel_id: ChannelId::from_bytes([2; 32]),
funding_satoshis: 1311768467284833366,
common_fields: CommonOpenChannelFields {
chain_hash: ChainHash::using_genesis_block(Network::Bitcoin),
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,
dust_limit_satoshis: 3608586615801332854,
max_htlc_value_in_flight_msat: 8517154655701053848,
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 mut target_value = Vec::new();
@ -3267,27 +3448,29 @@ mod tests {
let (_, pubkey_6) = get_keys_from!("0606060606060606060606060606060606060606060606060606060606060606", secp_ctx);
let (_, pubkey_7) = get_keys_from!("0707070707070707070707070707070707070707070707070707070707070707", secp_ctx);
let open_channelv2 = msgs::OpenChannelV2 {
chain_hash: ChainHash::using_genesis_block(Network::Bitcoin),
temporary_channel_id: ChannelId::from_bytes([2; 32]),
common_fields: CommonOpenChannelFields {
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,
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,
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,
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 },
};
let encoded_value = open_channelv2.encode();
@ -3317,7 +3500,6 @@ mod tests {
target_value.append(&mut <Vec<u8>>::from_hex("00").unwrap());
}
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());
}
if incl_chan_type {
@ -3358,22 +3540,24 @@ mod tests {
let (_, pubkey_5) = get_keys_from!("0505050505050505050505050505050505050505050505050505050505050505", secp_ctx);
let (_, pubkey_6) = get_keys_from!("0606060606060606060606060606060606060606060606060606060606060606", secp_ctx);
let accept_channel = msgs::AcceptChannel {
temporary_channel_id: ChannelId::from_bytes([2; 32]),
dust_limit_satoshis: 1311768467284833366,
max_htlc_value_in_flight_msat: 2536655962884945560,
common_fields: CommonAcceptChannelFields {
temporary_channel_id: ChannelId::from_bytes([2; 32]),
dust_limit_satoshis: 1311768467284833366,
max_htlc_value_in_flight_msat: 2536655962884945560,
htlc_minimum_msat: 2316138423780173,
minimum_depth: 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,
shutdown_scriptpubkey: if shutdown { Some(Address::p2pkh(&::bitcoin::PublicKey{compressed: true, inner: pubkey_1}, Network::Testnet).script_pubkey()) } else { None },
channel_type: None,
},
channel_reserve_satoshis: 3608586615801332854,
htlc_minimum_msat: 2316138423780173,
minimum_depth: 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,
shutdown_scriptpubkey: if shutdown { Some(Address::p2pkh(&::bitcoin::PublicKey{compressed: true, inner: pubkey_1}, Network::Testnet).script_pubkey()) } else { None },
channel_type: None,
#[cfg(taproot)]
next_local_nonce: None,
};
@ -3401,23 +3585,25 @@ mod tests {
let (_, pubkey_6) = get_keys_from!("0606060606060606060606060606060606060606060606060606060606060606", secp_ctx);
let (_, pubkey_7) = get_keys_from!("0707070707070707070707070707070707070707070707070707070707070707", secp_ctx);
let accept_channelv2 = msgs::AcceptChannelV2 {
temporary_channel_id: ChannelId::from_bytes([2; 32]),
common_fields: CommonAcceptChannelFields {
temporary_channel_id: ChannelId::from_bytes([2; 32]),
dust_limit_satoshis: 1311768467284833366,
max_htlc_value_in_flight_msat: 2536655962884945560,
htlc_minimum_msat: 2316138423780173,
minimum_depth: 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,
shutdown_scriptpubkey: if shutdown { Some(Address::p2pkh(&::bitcoin::PublicKey{compressed: true, inner: pubkey_1}, Network::Testnet).script_pubkey()) } else { None },
channel_type: None,
},
funding_satoshis: 1311768467284833366,
dust_limit_satoshis: 1311768467284833366,
max_htlc_value_in_flight_msat: 2536655962884945560,
htlc_minimum_msat: 2316138423780173,
minimum_depth: 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,
second_per_commitment_point: pubkey_7,
shutdown_scriptpubkey: if shutdown { Some(Address::p2pkh(&::bitcoin::PublicKey{compressed: true, inner: pubkey_1}, Network::Testnet).script_pubkey()) } else { None },
channel_type: None,
require_confirmed_inputs: None,
};
let encoded_value = accept_channelv2.encode();
@ -3437,7 +3623,6 @@ mod tests {
target_value.append(&mut <Vec<u8>>::from_hex("03f006a18d5653c4edf5391ff23a61f03ff83d237e880ee61187fa9f379a028e0a").unwrap()); // first_per_commitment_point
target_value.append(&mut <Vec<u8>>::from_hex("02989c0b76cb563971fdc9bef31ec06c3560f3249d6ee9e5d83c57625596e05f6f").unwrap()); // second_per_commitment_point
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());
}
assert_eq!(encoded_value, target_value);

View file

@ -222,10 +222,10 @@ impl ChannelMessageHandler for ErroringMessageHandler {
// Any messages which are related to a specific channel generate an error message to let the
// peer know we don't care about channels.
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) {
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_funding_created(&self, their_node_id: &PublicKey, msg: &msgs::FundingCreated) {
ErroringMessageHandler::push_error(self, their_node_id, msg.temporary_channel_id);
@ -315,11 +315,11 @@ impl ChannelMessageHandler for ErroringMessageHandler {
}
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) {
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_tx_add_input(&self, their_node_id: &PublicKey, msg: &msgs::TxAddInput) {
@ -1979,27 +1979,27 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
for event in events_generated.drain(..) {
match event {
MessageSendEvent::SendAcceptChannel { ref node_id, ref msg } => {
log_debug!(WithContext::from(&self.logger, Some(*node_id), Some(msg.temporary_channel_id)), "Handling SendAcceptChannel 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 SendAcceptChannel event in peer_handler for node {} for channel {}",
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);
},
MessageSendEvent::SendAcceptChannelV2 { ref node_id, ref msg } => {
log_debug!(WithContext::from(&self.logger, Some(*node_id), Some(msg.temporary_channel_id)), "Handling SendAcceptChannelV2 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 SendAcceptChannelV2 event in peer_handler for node {} for channel {}",
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);
},
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),
&msg.temporary_channel_id);
&msg.common_fields.temporary_channel_id);
self.enqueue_message(&mut *get_peer_for_forwarding!(node_id), 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),
&msg.temporary_channel_id);
&msg.common_fields.temporary_channel_id);
self.enqueue_message(&mut *get_peer_for_forwarding!(node_id), msg);
},
MessageSendEvent::SendFundingCreated { ref node_id, ref msg } => {

View file

@ -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();
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
open_channel.channel_type.as_mut().unwrap().set_scid_privacy_required();
assert_eq!(open_channel.channel_flags & 1, 1); // The `announce_channel` bit is set.
assert!(!open_channel.common_fields.channel_type.as_ref().unwrap().supports_scid_privacy()); // we ignore `negotiate_scid_privacy` on pub channels
open_channel.common_fields.channel_type.as_mut().unwrap().set_scid_privacy_required();
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);
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();
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
// now simulate nodes[1] responding with an Error message, indicating it doesn't understand
// SCID alias.
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()
});
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());
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[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();
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);
let accept_channel = get_event_msg!(nodes[2], MessageSendEvent::SendAcceptChannel, nodes[1].node.get_our_node_id());
@ -605,7 +605,7 @@ fn test_0conf_channel_with_async_monitor() {
};
let mut accept_channel = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
assert_eq!(accept_channel.minimum_depth, 0);
assert_eq!(accept_channel.common_fields.minimum_depth, 0);
nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &accept_channel);
let (temporary_channel_id, tx, funding_output) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 42);
@ -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();
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);
@ -913,7 +913,7 @@ fn test_zero_conf_accept_reject() {
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);
@ -945,7 +945,7 @@ fn test_zero_conf_accept_reject() {
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);
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);
@ -996,7 +996,7 @@ fn test_connect_before_funding() {
};
let mut accept_channel = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
assert_eq!(accept_channel.minimum_depth, 0);
assert_eq!(accept_channel.common_fields.minimum_depth, 0);
nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &accept_channel);
let events = nodes[0].node.get_and_clear_pending_events();

View file

@ -275,7 +275,7 @@ fn shutdown_on_unfunded_channel() {
.into_script();
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);
}
@ -831,7 +831,7 @@ fn test_unsupported_anysegwit_upfront_shutdown_script() {
// 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();
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);
let events = nodes[1].node.get_and_clear_pending_msg_events();
@ -856,7 +856,7 @@ fn test_unsupported_anysegwit_upfront_shutdown_script() {
let open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
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());
accept_channel.shutdown_scriptpubkey = Some(anysegwit_shutdown_script.clone());
accept_channel.common_fields.shutdown_scriptpubkey = Some(anysegwit_shutdown_script.clone());
nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), &accept_channel);
let events = nodes[0].node.get_and_clear_pending_msg_events();
@ -883,7 +883,7 @@ fn test_invalid_upfront_shutdown_script() {
// 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());
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])
.into_script());
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &open_channel);