Skip to content

Commit 7b75169

Browse files
committed
Added config file to allow users to specify channel limits as per bolt 2
1 parent 6c1123c commit 7b75169

File tree

5 files changed

+158
-40
lines changed

5 files changed

+158
-40
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: 50 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +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,ChannelLimits,ChannelOptions};
2930

3031
use std;
3132
use std::default::Default;
@@ -259,18 +260,20 @@ const BOTH_SIDES_SHUTDOWN_MASK: u32 = (ChannelState::LocalShutdownSent as u32 |
259260

260261
const INITIAL_COMMITMENT_NUMBER: u64 = (1 << 48) - 1;
261262

263+
262264
// TODO: We should refactor this to be an Inbound/OutboundChannel until initial setup handshaking
263265
// has been completed, and then turn into a Channel to get compiler-time enforcement of things like
264266
// calling channel_id() before we're set up or things like get_outbound_funding_signed on an
265267
// inbound channel.
266268
pub(super) struct Channel {
269+
config : ChannelOptions,
270+
267271
user_id: u64,
268272

269273
channel_id: [u8; 32],
270274
channel_state: u32,
271275
channel_outbound: bool,
272276
secp_ctx: Secp256k1<secp256k1::All>,
273-
announce_publicly: bool,
274277
channel_value_satoshis: u64,
275278

276279
local_keys: ChannelKeys,
@@ -421,7 +424,7 @@ impl Channel {
421424
}
422425

423426
// Constructors:
424-
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>) -> Result<Channel, APIError> {
427+
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> {
425428
if channel_value_satoshis >= MAX_FUNDING_SATOSHIS {
426429
return Err(APIError::APIMisuseError{err: "funding value > 2^24"});
427430
}
@@ -448,12 +451,12 @@ impl Channel {
448451

449452
Ok(Channel {
450453
user_id: user_id,
454+
config: configurations.channel_options.clone(),
451455

452456
channel_id: rng::rand_u832(),
453457
channel_state: ChannelState::OurInitSent as u32,
454458
channel_outbound: true,
455459
secp_ctx: secp_ctx,
456-
announce_publicly: announce_publicly,
457460
channel_value_satoshis: channel_value_satoshis,
458461

459462
local_keys: chan_keys,
@@ -520,12 +523,13 @@ impl Channel {
520523
/// Assumes chain_hash has already been checked and corresponds with what we expect!
521524
/// Generally prefers to take the DisconnectPeer action on failure, as a notice to the sender
522525
/// that we're rejecting the new channel.
523-
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>) -> Result<Channel, HandleError> {
526+
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> {
524527
macro_rules! return_error_message {
525528
( $msg: expr ) => {
526529
return Err(HandleError{err: $msg, action: Some(msgs::ErrorAction::SendErrorMessage{ msg: msgs::ErrorMessage { channel_id: msg.temporary_channel_id, data: $msg.to_string() }})});
527530
}
528531
}
532+
let mut local_config = (*configurations).channel_options.clone();
529533

530534
// Check sanity of message fields:
531535
if msg.funding_satoshis >= MAX_FUNDING_SATOSHIS {
@@ -559,16 +563,40 @@ impl Channel {
559563
if msg.max_accepted_htlcs > 483 {
560564
return_error_message!("max_accpted_htlcs > 483");
561565
}
566+
//optional parameter checking
567+
// MAY fail the channel if
568+
if msg.funding_satoshis < configurations.channel_limits.funding_satoshis {
569+
return_error_message!("funding satoshis is less than the user specified limit");
570+
}
571+
if msg.htlc_minimum_msat > configurations.channel_limits.htlc_minimum_msat {
572+
return_error_message!("htlc minimum msat is higher than the user specified limit");
573+
}
574+
if msg.max_htlc_value_in_flight_msat < configurations.channel_limits.max_htlc_value_in_flight_msat {
575+
return_error_message!("max htlc value in flight msat is less than the user specified limit");
576+
}
577+
if msg.channel_reserve_satoshis > configurations.channel_limits.channel_reserve_satoshis {
578+
return_error_message!("channel reserve satoshis is higher than the user specified limit");
579+
}
580+
if msg.max_accepted_htlcs < configurations.channel_limits.max_accepted_htlcs {
581+
return_error_message!("max accepted htlcs is less than the user specified limit");
582+
}
583+
if msg.dust_limit_satoshis < configurations.channel_limits.dust_limit_satoshis {
584+
return_error_message!("dust limit satoshis is less than the user specified limit");
585+
}
562586

563587
// Convert things into internal flags and prep our state:
564588

565589
let their_announce = if (msg.channel_flags & 1) == 1 { true } else { false };
566-
if require_announce && !their_announce {
567-
return_error_message!("Peer tried to open unannounced channel, but we require public ones");
568-
}
569-
if !allow_announce && their_announce {
570-
return_error_message!("Peer tried to open announced channel, but we require private ones");
590+
if local_config.force_announced_channel_preference{
591+
if local_config.announced_channel && !their_announce {
592+
return_error_message!("Peer tried to open unannounced channel, but we require public ones");
593+
}
594+
if !local_config.announced_channel && their_announce {
595+
return_error_message!("Peer tried to open announced channel, but we require private ones");
596+
}
571597
}
598+
//we either accept their preference or the preferences match
599+
local_config.announced_channel = their_announce;
572600

573601
let background_feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background);
574602

@@ -609,12 +637,12 @@ impl Channel {
609637

610638
let mut chan = Channel {
611639
user_id: user_id,
640+
config: local_config,
612641

613642
channel_id: msg.temporary_channel_id,
614643
channel_state: (ChannelState::OurInitSent as u32) | (ChannelState::TheirInitSent as u32),
615644
channel_outbound: false,
616645
secp_ctx: secp_ctx,
617-
announce_publicly: their_announce,
618646

619647
local_keys: chan_keys,
620648
cur_local_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
@@ -1224,7 +1252,7 @@ impl Channel {
12241252

12251253
// Message handlers:
12261254

1227-
pub fn accept_channel(&mut self, msg: &msgs::AcceptChannel) -> Result<(), HandleError> {
1255+
pub fn accept_channel(&mut self, msg: &msgs::AcceptChannel, config : &UserConfigurations) -> Result<(), HandleError> {
12281256
macro_rules! return_error_message {
12291257
( $msg: expr ) => {
12301258
return Err(HandleError{err: $msg, action: Some(msgs::ErrorAction::SendErrorMessage{ msg: msgs::ErrorMessage { channel_id: msg.temporary_channel_id, data: $msg.to_string() }})});
@@ -1267,16 +1295,10 @@ impl Channel {
12671295
if msg.max_accepted_htlcs > 483 {
12681296
return_error_message!("max_accpted_htlcs > 483");
12691297
}
1270-
1271-
// TODO: Optional additional constraints mentioned in the spec
1272-
// MAY fail the channel if
1273-
// funding_satoshi is too small
1274-
// htlc_minimum_msat too large
1275-
// max_htlc_value_in_flight_msat too small
1276-
// channel_reserve_satoshis too large
1277-
// max_accepted_htlcs too small
1278-
// dust_limit_satoshis too small
1279-
1298+
//Optional user definined limits
1299+
if msg.minimum_depth > config.channel_limits.minimum_depth {
1300+
return_error_message!("We consider the minimum depth to be unreasonably large");
1301+
}
12801302
self.channel_monitor.set_their_base_keys(&msg.htlc_basepoint, &msg.delayed_payment_basepoint);
12811303

12821304
self.their_dust_limit_satoshis = msg.dust_limit_satoshis;
@@ -2358,7 +2380,7 @@ impl Channel {
23582380
}
23592381

23602382
pub fn should_announce(&self) -> bool {
2361-
self.announce_publicly
2383+
self.config.announced_channel
23622384
}
23632385

23642386
pub fn is_outbound(&self) -> bool {
@@ -2548,7 +2570,7 @@ impl Channel {
25482570
delayed_payment_basepoint: PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.delayed_payment_base_key),
25492571
htlc_basepoint: PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.htlc_base_key),
25502572
first_per_commitment_point: PublicKey::from_secret_key(&self.secp_ctx, &local_commitment_secret),
2551-
channel_flags: if self.announce_publicly {1} else {0},
2573+
channel_flags: if self.config.announced_channel {1} else {0},
25522574
shutdown_scriptpubkey: None,
25532575
}
25542576
}
@@ -2652,7 +2674,7 @@ impl Channel {
26522674
/// Note that the "channel must be funded" requirement is stricter than BOLT 7 requires - see
26532675
/// https://github.com/lightningnetwork/lightning-rfc/issues/468
26542676
pub fn get_channel_announcement(&self, our_node_id: PublicKey, chain_hash: Sha256dHash) -> Result<(msgs::UnsignedChannelAnnouncement, Signature), HandleError> {
2655-
if !self.announce_publicly {
2677+
if !self.config.announced_channel {
26562678
return Err(HandleError{err: "Channel is not available for public announcements", action: Some(msgs::ErrorAction::IgnoreError)});
26572679
}
26582680
if self.channel_state & (ChannelState::ChannelFunded as u32) == 0 {
@@ -2999,6 +3021,7 @@ mod tests {
29993021

30003022
#[test]
30013023
fn outbound_commitment_test() {
3024+
use util::configurations::UserConfigurations;
30023025
// Test vectors from BOLT 3 Appendix C:
30033026
let feeest = TestFeeEstimator{fee_est: 15000};
30043027
let logger : Arc<Logger> = Arc::new(test_utils::TestLogger::new());
@@ -3020,7 +3043,9 @@ mod tests {
30203043
hex::decode("023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb").unwrap()[..]);
30213044

30223045
let their_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap());
3023-
let mut chan = Channel::new_outbound(&feeest, chan_keys, their_node_id, 10000000, 100000, false, 42, Arc::clone(&logger)).unwrap(); // Nothing uses their network key in this test
3046+
let mut config = UserConfigurations::new();
3047+
config.channel_options.announced_channel= false;
3048+
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
30243049
chan.their_to_self_delay = 144;
30253050
chan.our_dust_limit_satoshis = 546;
30263051

src/ln/channelmanager.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use ln::channelmonitor::ManyChannelMonitor;
2727
use ln::router::{Route,RouteHop};
2828
use ln::msgs;
2929
use ln::msgs::{HandleError,ChannelMessageHandler};
30+
use util::configurations::UserConfigurations;
3031
use util::{byte_utils, events, internal_traits, rng};
3132
use util::sha2::Sha256;
3233
use util::ser::{Readable, Writeable};
@@ -229,14 +230,13 @@ const ERR: () = "You need at least 32 bit pointers (well, usize, but we'll assum
229230
/// Implements ChannelMessageHandler, handling the multi-channel parts and passing things through
230231
/// to individual Channels.
231232
pub struct ChannelManager {
233+
configuration : UserConfigurations,
232234
genesis_hash: Sha256dHash,
233235
fee_estimator: Arc<FeeEstimator>,
234236
monitor: Arc<ManyChannelMonitor>,
235237
chain_monitor: Arc<ChainWatchInterface>,
236238
tx_broadcaster: Arc<BroadcasterInterface>,
237239

238-
announce_channels_publicly: bool,
239-
fee_proportional_millionths: u32,
240240
latest_block_height: AtomicUsize,
241241
secp_ctx: Secp256k1<secp256k1::All>,
242242

@@ -293,22 +293,19 @@ impl ChannelManager {
293293
/// This is the main "logic hub" for all channel-related actions, and implements
294294
/// ChannelMessageHandler.
295295
///
296-
/// fee_proportional_millionths is an optional fee to charge any payments routed through us.
297296
/// Non-proportional fees are fixed according to our risk using the provided fee estimator.
298297
///
299298
/// panics if channel_value_satoshis is >= `MAX_FUNDING_SATOSHIS`!
300-
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> {
301300
let secp_ctx = Secp256k1::new();
302-
303301
let res = Arc::new(ChannelManager {
302+
configuration : config.clone(),
304303
genesis_hash: genesis_block(network).header.bitcoin_hash(),
305304
fee_estimator: feeest.clone(),
306305
monitor: monitor.clone(),
307306
chain_monitor,
308307
tx_broadcaster,
309308

310-
announce_channels_publicly,
311-
fee_proportional_millionths,
312309
latest_block_height: AtomicUsize::new(0), //TODO: Get an init value (generally need to replay recent chain on chain_monitor registration)
313310
secp_ctx,
314311

@@ -362,7 +359,7 @@ impl ChannelManager {
362359
}
363360
};
364361

365-
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))?;
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)?;
366363
let res = channel.get_open_channel(self.genesis_hash.clone(), &*self.fee_estimator);
367364
let mut channel_state = self.channel_state.lock().unwrap();
368365
match channel_state.by_id.entry(channel.channel_id()) {
@@ -913,7 +910,7 @@ impl ChannelManager {
913910
if !chan.is_live() {
914911
Some(("Forwarding channel is not in a ready state.", 0x1000 | 7, self.get_channel_update(chan).unwrap()))
915912
} else {
916-
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) });
913+
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) });
917914
if fee.is_none() || msg.amount_msat < fee.unwrap() || (msg.amount_msat - fee.unwrap()) < *amt_to_forward {
918915
Some(("Prior hop has deviated from specified fees parameters or origin node has obsolete ones", 0x1000 | 12, self.get_channel_update(chan).unwrap()))
919916
} else {
@@ -950,7 +947,7 @@ impl ChannelManager {
950947
cltv_expiry_delta: CLTV_EXPIRY_DELTA,
951948
htlc_minimum_msat: chan.get_our_htlc_minimum_msat(),
952949
fee_base_msat: chan.get_our_fee_base_msat(&*self.fee_estimator),
953-
fee_proportional_millionths: self.fee_proportional_millionths,
950+
fee_proportional_millionths: self.configuration.channel_options.fee_proportional_millionths,
954951
excess_data: Vec::new(),
955952
};
956953

@@ -1467,7 +1464,7 @@ impl ChannelManager {
14671464
}
14681465
};
14691466

1470-
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)).map_err(|e| MsgHandleErrInternal::from_no_close(e))?;
1467+
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))?;
14711468
let accept_msg = channel.get_accept_channel();
14721469
channel_state.by_id.insert(channel.channel_id(), channel);
14731470
Ok(accept_msg)
@@ -1482,7 +1479,7 @@ impl ChannelManager {
14821479
//TODO: see issue #153, need a consistent behavior on obnoxious behavior from random node
14831480
return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.temporary_channel_id));
14841481
}
1485-
chan.accept_channel(&msg).map_err(|e| MsgHandleErrInternal::from_maybe_close(e))?;
1482+
chan.accept_channel(&msg, &self.configuration).map_err(|e| MsgHandleErrInternal::from_maybe_close(e))?;
14861483
(chan.get_value_satoshis(), chan.get_funding_redeemscript().to_v0_p2wsh(), chan.get_user_id())
14871484
},
14881485
//TODO: same as above
@@ -3022,6 +3019,8 @@ mod tests {
30223019
}
30233020

30243021
fn create_network(node_count: usize) -> Vec<Node> {
3022+
use util::UserConfigurations;
3023+
30253024
let mut nodes = Vec::new();
30263025
let mut rng = thread_rng();
30273026
let secp_ctx = Secp256k1::new();
@@ -3040,7 +3039,11 @@ mod tests {
30403039
rng.fill_bytes(&mut key_slice);
30413040
SecretKey::from_slice(&secp_ctx, &key_slice).unwrap()
30423041
};
3043-
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();
3042+
let mut config = UserConfigurations::new();
3043+
config.channel_options.announced_channel = true;
3044+
config.channel_options.fee_proportional_millionths = 0;
3045+
config.channel_options.force_announced_channel_preference = false;
3046+
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();
30443047
let router = Router::new(PublicKey::from_secret_key(&secp_ctx, &node_id), chain_monitor.clone(), Arc::clone(&logger));
30453048
nodes.push(Node { chain_monitor, tx_broadcaster, chan_monitor, node, router,
30463049
network_payment_count: payment_count.clone(),

0 commit comments

Comments
 (0)