Skip to content

Commit a0be4d1

Browse files
SWvheerdenTheBlueMatt
authored andcommitted
Added config interface to allow users to specify channel limits
1 parent 9189d0e commit a0be4d1

File tree

5 files changed

+232
-48
lines changed

5 files changed

+232
-48
lines changed

fuzz/fuzz_targets/full_stack_target.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use lightning::util::events::{EventsProvider,Event};
2424
use lightning::util::reset_rng_state;
2525
use lightning::util::logger::Logger;
2626
use lightning::util::sha2::Sha256;
27+
use lightning::util::config::UserConfig;
2728

2829
mod utils;
2930

@@ -305,7 +306,11 @@ pub fn do_test(data: &[u8], logger: &Arc<Logger>) {
305306
let monitor = channelmonitor::SimpleManyChannelMonitor::new(watch.clone(), broadcast.clone(), Arc::clone(&logger));
306307

307308
let keys_manager = Arc::new(KeyProvider { node_secret: our_network_key.clone() });
308-
let channelmanager = ChannelManager::new(slice_to_be32(get_slice!(4)), get_slice!(1)[0] != 0, Network::Bitcoin, fee_est.clone(), monitor.clone(), watch.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone()).unwrap();
309+
let mut config = UserConfig::new();
310+
config.channel_options.fee_proportional_millionths = slice_to_be32(get_slice!(4));
311+
config.channel_options.announced_channel = get_slice!(1)[0] != 0;
312+
config.channel_limits.min_dust_limit_satoshis = 0;
313+
let channelmanager = ChannelManager::new(Network::Bitcoin, fee_est.clone(), monitor.clone(), watch.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config).unwrap();
309314
let router = Arc::new(Router::new(PublicKey::from_secret_key(&secp_ctx, &keys_manager.get_node_secret()), watch.clone(), Arc::clone(&logger)));
310315

311316
let peers = RefCell::new([false; 256]);

src/ln/channel.rs

Lines changed: 75 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use util::ser::{Readable, ReadableArgs, Writeable, Writer, WriterWriteAdaptor};
2828
use util::sha2::Sha256;
2929
use util::logger::Logger;
3030
use util::errors::APIError;
31+
use util::config::{UserConfig,ChannelConfig};
3132

3233
use std;
3334
use std::default::Default;
@@ -230,13 +231,14 @@ const INITIAL_COMMITMENT_NUMBER: u64 = (1 << 48) - 1;
230231
// calling channel_id() before we're set up or things like get_outbound_funding_signed on an
231232
// inbound channel.
232233
pub(super) struct Channel {
234+
config: ChannelConfig,
235+
233236
user_id: u64,
234237

235238
channel_id: [u8; 32],
236239
channel_state: u32,
237240
channel_outbound: bool,
238241
secp_ctx: Secp256k1<secp256k1::All>,
239-
announce_publicly: bool,
240242
channel_value_satoshis: u64,
241243

242244
local_keys: ChannelKeys,
@@ -415,7 +417,7 @@ impl Channel {
415417
}
416418

417419
// Constructors:
418-
pub fn new_outbound(fee_estimator: &FeeEstimator, keys_provider: &Arc<KeysInterface>, their_node_id: PublicKey, channel_value_satoshis: u64, push_msat: u64, announce_publicly: bool, user_id: u64, logger: Arc<Logger>) -> Result<Channel, APIError> {
420+
pub fn new_outbound(fee_estimator: &FeeEstimator, keys_provider: &Arc<KeysInterface>, their_node_id: PublicKey, channel_value_satoshis: u64, push_msat: u64, user_id: u64, logger: Arc<Logger>, config: &UserConfig) -> Result<Channel, APIError> {
419421
let chan_keys = keys_provider.get_channel_keys(false);
420422

421423
if channel_value_satoshis >= MAX_FUNDING_SATOSHIS {
@@ -441,12 +443,12 @@ impl Channel {
441443

442444
Ok(Channel {
443445
user_id: user_id,
446+
config: config.channel_options.clone(),
444447

445448
channel_id: rng::rand_u832(),
446449
channel_state: ChannelState::OurInitSent as u32,
447450
channel_outbound: true,
448451
secp_ctx: secp_ctx,
449-
announce_publicly: announce_publicly,
450452
channel_value_satoshis: channel_value_satoshis,
451453

452454
local_keys: chan_keys,
@@ -526,8 +528,9 @@ impl Channel {
526528

527529
/// Creates a new channel from a remote sides' request for one.
528530
/// Assumes chain_hash has already been checked and corresponds with what we expect!
529-
pub fn new_from_req(fee_estimator: &FeeEstimator, keys_provider: &Arc<KeysInterface>, their_node_id: PublicKey, msg: &msgs::OpenChannel, user_id: u64, require_announce: bool, allow_announce: bool, logger: Arc<Logger>) -> Result<Channel, ChannelError> {
531+
pub fn new_from_req(fee_estimator: &FeeEstimator, keys_provider: &Arc<KeysInterface>, their_node_id: PublicKey, msg: &msgs::OpenChannel, user_id: u64, logger: Arc<Logger>, config: &UserConfig) -> Result<Channel, ChannelError> {
530532
let chan_keys = keys_provider.get_channel_keys(true);
533+
let mut local_config = (*config).channel_options.clone();
531534

532535
// Check sanity of message fields:
533536
if msg.funding_satoshis >= MAX_FUNDING_SATOSHIS {
@@ -560,22 +563,46 @@ impl Channel {
560563
return Err(ChannelError::Close("max_accpted_htlcs > 483"));
561564
}
562565

566+
// Now check against optional parameters as set by config...
567+
if msg.funding_satoshis < config.channel_limits.min_funding_satoshis {
568+
return Err(ChannelError::Close("funding satoshis is less than the user specified limit"));
569+
}
570+
if msg.htlc_minimum_msat > config.channel_limits.max_htlc_minimum_msat {
571+
return Err(ChannelError::Close("htlc minimum msat is higher than the user specified limit"));
572+
}
573+
if msg.max_htlc_value_in_flight_msat < config.channel_limits.min_max_htlc_value_in_flight_msat {
574+
return Err(ChannelError::Close("max htlc value in flight msat is less than the user specified limit"));
575+
}
576+
if msg.channel_reserve_satoshis > config.channel_limits.max_channel_reserve_satoshis {
577+
return Err(ChannelError::Close("channel reserve satoshis is higher than the user specified limit"));
578+
}
579+
if msg.max_accepted_htlcs < config.channel_limits.min_max_accepted_htlcs {
580+
return Err(ChannelError::Close("max accepted htlcs is less than the user specified limit"));
581+
}
582+
if msg.dust_limit_satoshis < config.channel_limits.min_dust_limit_satoshis {
583+
return Err(ChannelError::Close("dust limit satoshis is less than the user specified limit"));
584+
}
585+
if msg.dust_limit_satoshis > config.channel_limits.max_dust_limit_satoshis {
586+
return Err(ChannelError::Close("dust limit satoshis is greater than the user specified limit"));
587+
}
588+
563589
// Convert things into internal flags and prep our state:
564590

565591
let their_announce = if (msg.channel_flags & 1) == 1 { true } else { false };
566-
if require_announce && !their_announce {
567-
return Err(ChannelError::Close("Peer tried to open unannounced channel, but we require public ones"));
568-
}
569-
if !allow_announce && their_announce {
570-
return Err(ChannelError::Close("Peer tried to open announced channel, but we require private ones"));
592+
if config.channel_limits.force_announced_channel_preference {
593+
if local_config.announced_channel != their_announce {
594+
return Err(ChannelError::Close("Peer tried to open channel but their announcement preference is different from ours"));
595+
}
571596
}
597+
// we either accept their preference or the preferences match
598+
local_config.announced_channel = their_announce;
572599

573600
let background_feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background);
574601

575602
let our_dust_limit_satoshis = Channel::derive_our_dust_limit_satoshis(background_feerate);
576603
let our_channel_reserve_satoshis = Channel::get_our_channel_reserve_satoshis(msg.funding_satoshis);
577604
if our_channel_reserve_satoshis < our_dust_limit_satoshis {
578-
return Err(ChannelError::Close("Suitalbe channel reserve not found. aborting"));
605+
return Err(ChannelError::Close("Suitable channel reserve not found. aborting"));
579606
}
580607
if msg.channel_reserve_satoshis < our_dust_limit_satoshis {
581608
return Err(ChannelError::Close("channel_reserve_satoshis too small"));
@@ -606,12 +633,12 @@ impl Channel {
606633

607634
let mut chan = Channel {
608635
user_id: user_id,
636+
config: local_config,
609637

610638
channel_id: msg.temporary_channel_id,
611639
channel_state: (ChannelState::OurInitSent as u32) | (ChannelState::TheirInitSent as u32),
612640
channel_outbound: false,
613641
secp_ctx: secp_ctx,
614-
announce_publicly: their_announce,
615642

616643
local_keys: chan_keys,
617644
shutdown_pubkey: keys_provider.get_shutdown_pubkey(),
@@ -1262,7 +1289,7 @@ impl Channel {
12621289

12631290
// Message handlers:
12641291

1265-
pub fn accept_channel(&mut self, msg: &msgs::AcceptChannel) -> Result<(), ChannelError> {
1292+
pub fn accept_channel(&mut self, msg: &msgs::AcceptChannel, config: &UserConfig) -> Result<(), ChannelError> {
12661293
// Check sanity of message fields:
12671294
if !self.channel_outbound {
12681295
return Err(ChannelError::Close("Got an accept_channel message from an inbound peer"));
@@ -1298,14 +1325,28 @@ impl Channel {
12981325
return Err(ChannelError::Close("max_accpted_htlcs > 483"));
12991326
}
13001327

1301-
// TODO: Optional additional constraints mentioned in the spec
1302-
// MAY fail the channel if
1303-
// funding_satoshi is too small
1304-
// htlc_minimum_msat too large
1305-
// max_htlc_value_in_flight_msat too small
1306-
// channel_reserve_satoshis too large
1307-
// max_accepted_htlcs too small
1308-
// dust_limit_satoshis too small
1328+
// Now check against optional parameters as set by config...
1329+
if msg.htlc_minimum_msat > config.channel_limits.max_htlc_minimum_msat {
1330+
return Err(ChannelError::Close("htlc minimum msat is higher than the user specified limit"));
1331+
}
1332+
if msg.max_htlc_value_in_flight_msat < config.channel_limits.min_max_htlc_value_in_flight_msat {
1333+
return Err(ChannelError::Close("max htlc value in flight msat is less than the user specified limit"));
1334+
}
1335+
if msg.channel_reserve_satoshis > config.channel_limits.max_channel_reserve_satoshis {
1336+
return Err(ChannelError::Close("channel reserve satoshis is higher than the user specified limit"));
1337+
}
1338+
if msg.max_accepted_htlcs < config.channel_limits.min_max_accepted_htlcs {
1339+
return Err(ChannelError::Close("max accepted htlcs is less than the user specified limit"));
1340+
}
1341+
if msg.dust_limit_satoshis < config.channel_limits.min_dust_limit_satoshis {
1342+
return Err(ChannelError::Close("dust limit satoshis is less than the user specified limit"));
1343+
}
1344+
if msg.dust_limit_satoshis > config.channel_limits.max_dust_limit_satoshis {
1345+
return Err(ChannelError::Close("dust limit satoshis is greater than the user specified limit"));
1346+
}
1347+
if msg.minimum_depth > config.channel_limits.max_minimum_depth {
1348+
return Err(ChannelError::Close("We consider the minimum depth to be unreasonably large"));
1349+
}
13091350

13101351
self.channel_monitor.set_their_base_keys(&msg.htlc_basepoint, &msg.delayed_payment_basepoint);
13111352

@@ -2571,6 +2612,10 @@ impl Channel {
25712612
self.channel_value_satoshis
25722613
}
25732614

2615+
pub fn get_fee_proportional_millionths(&self) -> u32 {
2616+
self.config.fee_proportional_millionths
2617+
}
2618+
25742619
#[cfg(test)]
25752620
pub fn get_feerate(&self) -> u64 {
25762621
self.feerate_per_kw
@@ -2624,7 +2669,7 @@ impl Channel {
26242669
}
26252670

26262671
pub fn should_announce(&self) -> bool {
2627-
self.announce_publicly
2672+
self.config.announced_channel
26282673
}
26292674

26302675
pub fn is_outbound(&self) -> bool {
@@ -2823,7 +2868,7 @@ impl Channel {
28232868
delayed_payment_basepoint: PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.delayed_payment_base_key),
28242869
htlc_basepoint: PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.htlc_base_key),
28252870
first_per_commitment_point: PublicKey::from_secret_key(&self.secp_ctx, &local_commitment_secret),
2826-
channel_flags: if self.announce_publicly {1} else {0},
2871+
channel_flags: if self.config.announced_channel {1} else {0},
28272872
shutdown_scriptpubkey: None,
28282873
}
28292874
}
@@ -2927,7 +2972,7 @@ impl Channel {
29272972
/// Note that the "channel must be funded" requirement is stricter than BOLT 7 requires - see
29282973
/// https://github.com/lightningnetwork/lightning-rfc/issues/468
29292974
pub fn get_channel_announcement(&self, our_node_id: PublicKey, chain_hash: Sha256dHash) -> Result<(msgs::UnsignedChannelAnnouncement, Signature), ChannelError> {
2930-
if !self.announce_publicly {
2975+
if !self.config.announced_channel {
29312976
return Err(ChannelError::Ignore("Channel is not available for public announcements"));
29322977
}
29332978
if self.channel_state & (ChannelState::ChannelFunded as u32) == 0 {
@@ -3303,11 +3348,11 @@ impl Writeable for Channel {
33033348
writer.write_all(&[MIN_SERIALIZATION_VERSION; 1])?;
33043349

33053350
self.user_id.write(writer)?;
3351+
self.config.write(writer)?;
33063352

33073353
self.channel_id.write(writer)?;
33083354
(self.channel_state | ChannelState::PeerDisconnected as u32).write(writer)?;
33093355
self.channel_outbound.write(writer)?;
3310-
self.announce_publicly.write(writer)?;
33113356
self.channel_value_satoshis.write(writer)?;
33123357

33133358
self.local_keys.write(writer)?;
@@ -3506,11 +3551,11 @@ impl<R : ::std::io::Read> ReadableArgs<R, Arc<Logger>> for Channel {
35063551
}
35073552

35083553
let user_id = Readable::read(reader)?;
3554+
let config: ChannelConfig = Readable::read(reader)?;
35093555

35103556
let channel_id = Readable::read(reader)?;
35113557
let channel_state = Readable::read(reader)?;
35123558
let channel_outbound = Readable::read(reader)?;
3513-
let announce_publicly = Readable::read(reader)?;
35143559
let channel_value_satoshis = Readable::read(reader)?;
35153560

35163561
let local_keys = Readable::read(reader)?;
@@ -3675,11 +3720,11 @@ impl<R : ::std::io::Read> ReadableArgs<R, Arc<Logger>> for Channel {
36753720
Ok(Channel {
36763721
user_id,
36773722

3723+
config,
36783724
channel_id,
36793725
channel_state,
36803726
channel_outbound,
36813727
secp_ctx: Secp256k1::new(),
3682-
announce_publicly,
36833728
channel_value_satoshis,
36843729

36853730
local_keys,
@@ -3766,6 +3811,7 @@ mod tests {
37663811
use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
37673812
use chain::keysinterface::KeysInterface;
37683813
use chain::transaction::OutPoint;
3814+
use util::config::UserConfig;
37693815
use util::test_utils;
37703816
use util::logger::Logger;
37713817
use secp256k1::{Secp256k1,Message,Signature};
@@ -3832,7 +3878,9 @@ mod tests {
38323878
let keys_provider: Arc<KeysInterface> = Arc::new(Keys { chan_keys });
38333879

38343880
let their_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap());
3835-
let mut chan = Channel::new_outbound(&feeest, &keys_provider, their_node_id, 10000000, 100000, false, 42, Arc::clone(&logger)).unwrap(); // Nothing uses their network key in this test
3881+
let mut config = UserConfig::new();
3882+
config.channel_options.announced_channel = false;
3883+
let mut chan = Channel::new_outbound(&feeest, &keys_provider, their_node_id, 10000000, 100000, 42, Arc::clone(&logger), &config).unwrap(); // Nothing uses their network key in this test
38363884
chan.their_to_self_delay = 144;
38373885
chan.our_dust_limit_satoshis = 546;
38383886

0 commit comments

Comments
 (0)