Skip to content

Commit 86c84ed

Browse files
committed
Added config file to allow users to specify channel limits as per bolt 2
1 parent 0d60b0c commit 86c84ed

File tree

6 files changed

+103
-47
lines changed

6 files changed

+103
-47
lines changed

fuzz/fuzz_targets/full_stack_target.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use lightning::util::events::{EventsProvider,Event};
2222
use lightning::util::reset_rng_state;
2323
use lightning::util::logger::Logger;
2424
use lightning::util::sha2::Sha256;
25+
use lightning::util::UserConfigurations;
2526

2627
mod utils;
2728

@@ -235,8 +236,10 @@ pub fn do_test(data: &[u8], logger: &Arc<Logger>) {
235236
let watch = Arc::new(ChainWatchInterfaceUtil::new(Network::Bitcoin, Arc::clone(&logger)));
236237
let broadcast = Arc::new(TestBroadcaster{});
237238
let monitor = channelmonitor::SimpleManyChannelMonitor::new(watch.clone(), broadcast.clone());
238-
239-
let channelmanager = ChannelManager::new(our_network_key, 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)).unwrap();
239+
let mut config = UserConfigurations::new();
240+
config.channel_options.fee_proportional_millionths = slice_to_be32(get_slice!(4));
241+
config.channel_options.announced_channel = (get_slice!(1)[0] != 0);
242+
let channelmanager = ChannelManager::new(our_network_key,Network::Bitcoin, fee_est.clone(), monitor.clone(), watch.clone(), broadcast.clone(), Arc::clone(&logger), config).unwrap();
240243
let router = Arc::new(Router::new(PublicKey::from_secret_key(&secp_ctx, &our_network_key), watch.clone(), Arc::clone(&logger)));
241244

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

src/ln/channel.rs

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use util::ser::Writeable;
2626
use util::sha2::Sha256;
2727
use util::logger::Logger;
2828
use util::errors::APIError;
29-
use util::configurations::UserConfigurations;
29+
use util::configurations::{UserConfigurations,ChannelLimits,ChannelOptions};
3030

3131
use std;
3232
use std::default::Default;
@@ -266,15 +266,14 @@ const INITIAL_COMMITMENT_NUMBER: u64 = (1 << 48) - 1;
266266
// calling channel_id() before we're set up or things like get_outbound_funding_signed on an
267267
// inbound channel.
268268
pub(super) struct Channel {
269+
config : UserConfigurations,
269270

270-
config : UserConfigurations,
271271
user_id: u64,
272272

273273
channel_id: [u8; 32],
274274
channel_state: u32,
275275
channel_outbound: bool,
276276
secp_ctx: Secp256k1<secp256k1::All>,
277-
announce_publicly: bool,
278277
channel_value_satoshis: u64,
279278

280279
local_keys: ChannelKeys,
@@ -407,7 +406,7 @@ impl Channel {
407406
}
408407

409408
// Constructors:
410-
pub fn new_outbound(fee_estimator: &FeeEstimator, chan_keys: ChannelKeys, their_node_id: PublicKey, channel_value_satoshis: u64, push_msat: u64, announce_publicly: bool, user_id: u64, logger: Arc<Logger>, configurations: &UserConfigurations) -> Result<Channel, APIError> {
409+
pub fn new_outbound(fee_estimator: &FeeEstimator, chan_keys: ChannelKeys, their_node_id: PublicKey, channel_value_satoshis: u64, push_msat: u64, user_id: u64, logger: Arc<Logger>, configurations: &UserConfigurations) -> Result<Channel, APIError> {
411410
if channel_value_satoshis >= MAX_FUNDING_SATOSHIS {
412411
return Err(APIError::APIMisuseError{err: "funding value > 2^24"});
413412
}
@@ -434,12 +433,14 @@ impl Channel {
434433

435434
Ok(Channel {
436435
user_id: user_id,
437-
config : configurations.clone(),
436+
config: UserConfigurations{
437+
channel_options: configurations.channel_options.clone(),
438+
channel_limits : Arc::clone(&configurations.channel_limits),},
439+
438440
channel_id: rng::rand_u832(),
439441
channel_state: ChannelState::OurInitSent as u32,
440442
channel_outbound: true,
441443
secp_ctx: secp_ctx,
442-
announce_publicly: announce_publicly,
443444
channel_value_satoshis: channel_value_satoshis,
444445

445446
local_keys: chan_keys,
@@ -504,12 +505,13 @@ impl Channel {
504505
/// Assumes chain_hash has already been checked and corresponds with what we expect!
505506
/// Generally prefers to take the DisconnectPeer action on failure, as a notice to the sender
506507
/// that we're rejecting the new channel.
507-
pub fn new_from_req(fee_estimator: &FeeEstimator, chan_keys: ChannelKeys, their_node_id: PublicKey, msg: &msgs::OpenChannel, user_id: u64, require_announce: bool, allow_announce: bool, logger: Arc<Logger>, configurations : &UserConfigurations) -> Result<Channel, HandleError> {
508+
pub fn new_from_req(fee_estimator: &FeeEstimator, chan_keys: ChannelKeys, their_node_id: PublicKey, msg: &msgs::OpenChannel, user_id: u64, logger: Arc<Logger>, configurations : &UserConfigurations) -> Result<Channel, HandleError> {
508509
macro_rules! return_error_message {
509510
( $msg: expr ) => {
510511
return Err(HandleError{err: $msg, action: Some(msgs::ErrorAction::SendErrorMessage{ msg: msgs::ErrorMessage { channel_id: msg.temporary_channel_id, data: $msg.to_string() }})});
511512
}
512513
}
514+
let mut local_config = (*configurations).channel_options.clone();
513515

514516
// Check sanity of message fields:
515517
if msg.funding_satoshis >= MAX_FUNDING_SATOSHIS {
@@ -543,7 +545,7 @@ impl Channel {
543545
if msg.max_accepted_htlcs > 483 {
544546
return_error_message!("max_accpted_htlcs > 483");
545547
}
546-
//optional parameter checking
548+
//optional parameter checking
547549
// MAY fail the channel if
548550
if msg.funding_satoshis < configurations.channel_limits.funding_satoshis {
549551
return_error_message!("funding satoshis is less than the user specified limit");
@@ -567,12 +569,16 @@ impl Channel {
567569
// Convert things into internal flags and prep our state:
568570

569571
let their_announce = if (msg.channel_flags & 1) == 1 { true } else { false };
570-
if require_announce && !their_announce {
571-
return_error_message!("Peer tried to open unannounced channel, but we require public ones");
572-
}
573-
if !allow_announce && their_announce {
574-
return_error_message!("Peer tried to open announced channel, but we require private ones");
572+
if local_config.force_announced_channel_preference{
573+
if local_config.announced_channel && !their_announce {
574+
return_error_message!("Peer tried to open unannounced channel, but we require public ones");
575+
}
576+
if !local_config.announced_channel && their_announce {
577+
return_error_message!("Peer tried to open announced channel, but we require private ones");
578+
}
575579
}
580+
//we either accept their preference or the preferences match
581+
local_config.announced_channel = their_announce;
576582

577583
let background_feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background);
578584

@@ -613,12 +619,14 @@ impl Channel {
613619

614620
let mut chan = Channel {
615621
user_id: user_id,
616-
config: (*configurations).clone(),
622+
config: UserConfigurations{
623+
channel_options: local_config,
624+
channel_limits : Arc::clone(&configurations.channel_limits),},
625+
617626
channel_id: msg.temporary_channel_id,
618627
channel_state: (ChannelState::OurInitSent as u32) | (ChannelState::TheirInitSent as u32),
619628
channel_outbound: false,
620629
secp_ctx: secp_ctx,
621-
announce_publicly: their_announce,
622630

623631
local_keys: chan_keys,
624632
cur_local_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
@@ -1268,7 +1276,10 @@ impl Channel {
12681276
if msg.max_accepted_htlcs > 483 {
12691277
return_error_message!("max_accpted_htlcs > 483");
12701278
}
1271-
1279+
//Optional user definined limits
1280+
if msg.minimum_depth > self.config.channel_limits.minimum_depth {
1281+
return_error_message!("We consider the minimum depth to be unreasonably large");
1282+
}
12721283
self.channel_monitor.set_their_base_keys(&msg.htlc_basepoint, &msg.delayed_payment_basepoint);
12731284

12741285
self.their_dust_limit_satoshis = msg.dust_limit_satoshis;
@@ -2257,7 +2268,7 @@ impl Channel {
22572268
}
22582269

22592270
pub fn should_announce(&self) -> bool {
2260-
self.announce_publicly
2271+
self.config.channel_options.announced_channel
22612272
}
22622273

22632274
/// Gets the fee we'd want to charge for adding an HTLC output to this Channel
@@ -2443,7 +2454,7 @@ impl Channel {
24432454
delayed_payment_basepoint: PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.delayed_payment_base_key),
24442455
htlc_basepoint: PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.htlc_base_key),
24452456
first_per_commitment_point: PublicKey::from_secret_key(&self.secp_ctx, &local_commitment_secret),
2446-
channel_flags: if self.announce_publicly {1} else {0},
2457+
channel_flags: if self.config.channel_options.announced_channel {1} else {0},
24472458
shutdown_scriptpubkey: None,
24482459
}
24492460
}
@@ -2547,7 +2558,7 @@ impl Channel {
25472558
/// Note that the "channel must be funded" requirement is stricter than BOLT 7 requires - see
25482559
/// https://github.com/lightningnetwork/lightning-rfc/issues/468
25492560
pub fn get_channel_announcement(&self, our_node_id: PublicKey, chain_hash: Sha256dHash) -> Result<(msgs::UnsignedChannelAnnouncement, Signature), HandleError> {
2550-
if !self.announce_publicly {
2561+
if !self.config.channel_options.announced_channel {
25512562
return Err(HandleError{err: "Channel is not available for public announcements", action: Some(msgs::ErrorAction::IgnoreError)});
25522563
}
25532564
if self.channel_state & (ChannelState::ChannelFunded as u32) == 0 {
@@ -2909,7 +2920,9 @@ mod tests {
29092920
hex::decode("023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb").unwrap()[..]);
29102921

29112922
let their_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap());
2912-
let mut chan = Channel::new_outbound(&feeest, chan_keys, their_node_id, 10000000, 100000, false, 42, Arc::clone(&logger), &UserConfigurations::new()).unwrap(); // Nothing uses their network key in this test
2923+
let mut config = UserConfigurations::new();
2924+
config.channel_options.announced_channel= false;
2925+
let mut chan = Channel::new_outbound(&feeest, chan_keys, their_node_id, 10000000, 100000, 42, Arc::clone(&logger), &config).unwrap(); // Nothing uses their network key in this test
29132926
chan.their_to_self_delay = 144;
29142927
chan.our_dust_limit_satoshis = 546;
29152928

src/ln/channelmanager.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,6 @@ pub struct ChannelManager {
237237
chain_monitor: Arc<ChainWatchInterface>,
238238
tx_broadcaster: Arc<BroadcasterInterface>,
239239

240-
announce_channels_publicly: bool,
241-
fee_proportional_millionths: u32,
242240
latest_block_height: AtomicUsize,
243241
secp_ctx: Secp256k1<secp256k1::All>,
244242

@@ -295,23 +293,19 @@ impl ChannelManager {
295293
/// This is the main "logic hub" for all channel-related actions, and implements
296294
/// ChannelMessageHandler.
297295
///
298-
/// fee_proportional_millionths is an optional fee to charge any payments routed through us.
299296
/// Non-proportional fees are fixed according to our risk using the provided fee estimator.
300297
///
301298
/// panics if channel_value_satoshis is >= `MAX_FUNDING_SATOSHIS`!
302-
pub fn new(our_network_key: SecretKey, fee_proportional_millionths: u32, announce_channels_publicly: bool, network: Network, feeest: Arc<FeeEstimator>, monitor: Arc<ManyChannelMonitor>, chain_monitor: Arc<ChainWatchInterface>, tx_broadcaster: Arc<BroadcasterInterface>, logger: Arc<Logger>) -> Result<Arc<ChannelManager>, secp256k1::Error> {
299+
pub fn new(our_network_key: SecretKey, network: Network, feeest: Arc<FeeEstimator>, monitor: Arc<ManyChannelMonitor>, chain_monitor: Arc<ChainWatchInterface>, tx_broadcaster: Arc<BroadcasterInterface>, logger: Arc<Logger>, config : UserConfigurations) -> Result<Arc<ChannelManager>, secp256k1::Error> {
303300
let secp_ctx = Secp256k1::new();
304-
305301
let res = Arc::new(ChannelManager {
306-
configuration : UserConfigurations::new(),
302+
configuration : config.clone(),
307303
genesis_hash: genesis_block(network).header.bitcoin_hash(),
308304
fee_estimator: feeest.clone(),
309305
monitor: monitor.clone(),
310306
chain_monitor,
311307
tx_broadcaster,
312308

313-
announce_channels_publicly,
314-
fee_proportional_millionths,
315309
latest_block_height: AtomicUsize::new(0), //TODO: Get an init value (generally need to replay recent chain on chain_monitor registration)
316310
secp_ctx,
317311

@@ -365,7 +359,7 @@ impl ChannelManager {
365359
}
366360
};
367361

368-
let channel = Channel::new_outbound(&*self.fee_estimator, chan_keys, their_network_key, channel_value_satoshis, push_msat, self.announce_channels_publicly, user_id, Arc::clone(&self.logger), &self.configuration)?;
362+
let channel = Channel::new_outbound(&*self.fee_estimator, chan_keys, their_network_key, channel_value_satoshis, push_msat, user_id, Arc::clone(&self.logger), &self.configuration)?;
369363
let res = channel.get_open_channel(self.genesis_hash.clone(), &*self.fee_estimator);
370364
let mut channel_state = self.channel_state.lock().unwrap();
371365
match channel_state.by_id.insert(channel.channel_id(), channel) {
@@ -910,7 +904,7 @@ impl ChannelManager {
910904
if !chan.is_live() {
911905
Some(("Forwarding channel is not in a ready state.", 0x1000 | 7, self.get_channel_update(chan).unwrap()))
912906
} else {
913-
let fee = amt_to_forward.checked_mul(self.fee_proportional_millionths as u64).and_then(|prop_fee| { (prop_fee / 1000000).checked_add(chan.get_our_fee_base_msat(&*self.fee_estimator) as u64) });
907+
let fee = amt_to_forward.checked_mul(self.configuration.channel_options.fee_proportional_millionths as u64).and_then(|prop_fee| { (prop_fee / 1000000).checked_add(chan.get_our_fee_base_msat(&*self.fee_estimator) as u64) });
914908
if fee.is_none() || msg.amount_msat < fee.unwrap() || (msg.amount_msat - fee.unwrap()) < *amt_to_forward {
915909
Some(("Prior hop has deviated from specified fees parameters or origin node has obsolete ones", 0x1000 | 12, self.get_channel_update(chan).unwrap()))
916910
} else {
@@ -947,7 +941,7 @@ impl ChannelManager {
947941
cltv_expiry_delta: CLTV_EXPIRY_DELTA,
948942
htlc_minimum_msat: chan.get_our_htlc_minimum_msat(),
949943
fee_base_msat: chan.get_our_fee_base_msat(&*self.fee_estimator),
950-
fee_proportional_millionths: self.fee_proportional_millionths,
944+
fee_proportional_millionths: self.configuration.channel_options.fee_proportional_millionths,
951945
excess_data: Vec::new(),
952946
};
953947

@@ -1460,7 +1454,7 @@ impl ChannelManager {
14601454
}
14611455
};
14621456

1463-
let channel = Channel::new_from_req(&*self.fee_estimator, chan_keys, their_node_id.clone(), msg, 0, false, self.announce_channels_publicly, Arc::clone(&self.logger), &self.configuration).map_err(|e| MsgHandleErrInternal::from_no_close(e))?;
1457+
let channel = Channel::new_from_req(&*self.fee_estimator, chan_keys, their_node_id.clone(), msg, 0, Arc::clone(&self.logger), &self.configuration).map_err(|e| MsgHandleErrInternal::from_no_close(e))?;
14641458
let accept_msg = channel.get_accept_channel();
14651459
channel_state.by_id.insert(channel.channel_id(), channel);
14661460
Ok(accept_msg)
@@ -1486,7 +1480,8 @@ impl ChannelManager {
14861480
pending_events.push(events::Event::FundingGenerationReady {
14871481
temporary_channel_id: msg.temporary_channel_id,
14881482
channel_value_satoshis: value,
1489-
output_script: output_script, user_channel_id: user_id,
1483+
output_script: output_script,
1484+
user_channel_id: user_id,
14901485
});
14911486
Ok(())
14921487
}
@@ -2996,6 +2991,8 @@ mod tests {
29962991
}
29972992

29982993
fn create_network(node_count: usize) -> Vec<Node> {
2994+
use util::UserConfigurations;
2995+
29992996
let mut nodes = Vec::new();
30002997
let mut rng = thread_rng();
30012998
let secp_ctx = Secp256k1::new();
@@ -3014,7 +3011,11 @@ mod tests {
30143011
rng.fill_bytes(&mut key_slice);
30153012
SecretKey::from_slice(&secp_ctx, &key_slice).unwrap()
30163013
};
3017-
let node = ChannelManager::new(node_id.clone(), 0, true, Network::Testnet, feeest.clone(), chan_monitor.clone(), chain_monitor.clone(), tx_broadcaster.clone(), Arc::clone(&logger)).unwrap();
3014+
let mut config = UserConfigurations::new();
3015+
config.channel_options.announced_channel = true;
3016+
config.channel_options.fee_proportional_millionths = 0;
3017+
config.channel_options.force_announced_channel_preference = false;
3018+
let node = ChannelManager::new(node_id.clone(), Network::Testnet, feeest.clone(), chan_monitor.clone(), chain_monitor.clone(), tx_broadcaster.clone(), Arc::clone(&logger), config).unwrap();
30183019
let router = Router::new(PublicKey::from_secret_key(&secp_ctx, &node_id), chain_monitor.clone(), Arc::clone(&logger));
30193020
nodes.push(Node { chain_monitor, tx_broadcaster, chan_monitor, node, router,
30203021
network_payment_count: payment_count.clone(),

src/ln/router.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,6 @@ impl std::fmt::Display for ChannelInfo {
7777
}
7878
}
7979

80-
81-
8280
struct NodeInfo {
8381
#[cfg(feature = "non_bitcoin_chain_hash_routing")]
8482
channels: Vec<(u64, Sha256dHash)>,

src/util/configurations.rs

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,47 @@
1-
#[derive(Copy, Clone)]
1+
use std::sync::Arc;
2+
3+
/// This is the main user configuration
4+
/// This struct should contain all user customizable options as this is passed to the channel to be accessed
5+
#[derive(Clone, Debug)]
26
pub struct UserConfigurations{
3-
pub channel_limits : ChannelLimits,
7+
/// optional user spesefied channel limits
8+
/// These are only used on startup of channels, and are referanced to a single instance
9+
pub channel_limits : Arc<ChannelLimits>,
10+
/// Channel options can change afterwords and are unique to each channel
11+
pub channel_options : ChannelOptions,
412
}
513

614
impl UserConfigurations {
715
pub fn new() -> Self{
816
UserConfigurations {
9-
channel_limits : ChannelLimits::new(),
17+
channel_limits : Arc::new(ChannelLimits::new()),
18+
channel_options : ChannelOptions::new(),
1019
}
1120
}
1221
}
1322

14-
#[derive(Copy, Clone)]
15-
pub struct ChannelLimits
16-
{
23+
/// This struct contains all the optional bolt 2 channel limits.
24+
/// If the user wants to check a value, the value needs to be filled in, as by default they are not checked
25+
#[derive(Copy, Clone, Debug)]
26+
pub struct ChannelLimits{
27+
/// minimum allowed funding_satoshis
1728
pub funding_satoshis :u64,
29+
/// maximum allowed htlc_minimum_msat
1830
pub htlc_minimum_msat : u64,
31+
/// min allowed max_htlc_value_in_flight_msat
1932
pub max_htlc_value_in_flight_msat : u64,
33+
/// max allowed channel_reserve_satashis
2034
pub channel_reserve_satoshis : u64,
35+
/// min allowed max_accepted_htlcs
2136
pub max_accepted_htlcs : u16,
37+
/// min allowed dust_limit_satashis
2238
pub dust_limit_satoshis : u64,
39+
///minimum depth to a number of blocks that is considered reasonable to avoid double-spending of the funding transaction
40+
pub minimum_depth : u32,
2341
}
2442

2543
impl ChannelLimits {
26-
//creating max and min possible values because if they are not set, means we should not check them.
44+
//creating max and min possible values because if they are not set, means we should not check them.
2745
pub fn new() -> Self{
2846
ChannelLimits {
2947
funding_satoshis : 0,
@@ -32,6 +50,29 @@ impl ChannelLimits {
3250
channel_reserve_satoshis : <u64>::max_value(),
3351
max_accepted_htlcs : 0,
3452
dust_limit_satoshis : 0,
53+
minimum_depth : <u32>::max_value(),
54+
}
55+
}
56+
}
57+
58+
/// This struct contains all the custom channel options.
59+
#[derive(Copy, Clone, Debug)]
60+
pub struct ChannelOptions{
61+
/// Amount (in millionths of a satoshi) channel will charge per transferred satoshi.
62+
pub fee_proportional_millionths : u32,
63+
///Is this channel an annouced channe;
64+
pub announced_channel : bool,
65+
///do we force the incomming channel to match our announced channel preference
66+
pub force_announced_channel_preference : bool,
67+
}
68+
impl ChannelOptions {
69+
/// creating a struct with values.
70+
/// fee_proportional_millionths should be changed afterwords
71+
pub fn new() -> Self{
72+
ChannelOptions {
73+
fee_proportional_millionths : 0,
74+
announced_channel : true,
75+
force_announced_channel_preference : false,
3576
}
3677
}
3778
}

src/util/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,5 @@ pub use self::rng::reset_rng_state;
2929
#[cfg(test)]
3030
pub(crate) mod test_utils;
3131

32-
pub use self::configurations::{UserConfigurations, ChannelLimits};
33-
pub mod configurations;
32+
pub use self::configurations::UserConfigurations;
33+
pub mod configurations;

0 commit comments

Comments
 (0)