Skip to content

Commit 17b7611

Browse files
committed
Added config file to allow users to specify channel limits as per bolt 2
1 parent b297d5b commit 17b7611

File tree

5 files changed

+198
-56
lines changed

5 files changed

+198
-56
lines changed

fuzz/fuzz_targets/full_stack_target.rs

Lines changed: 5 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::configurations::UserConfig;
2728

2829
mod utils;
2930

@@ -283,7 +284,10 @@ pub fn do_test(data: &[u8], logger: &Arc<Logger>) {
283284
let monitor = channelmonitor::SimpleManyChannelMonitor::new(watch.clone(), broadcast.clone());
284285

285286
let keys_manager = Arc::new(KeyProvider { node_secret: our_network_key.clone() });
286-
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();
287+
let mut config = UserConfig::new();
288+
config.channel_options.fee_proportional_millionths = slice_to_be32(get_slice!(4));
289+
config.channel_options.announced_channel = (get_slice!(1)[0] != 0);
290+
let channelmanager = ChannelManager::new(Network::Bitcoin, fee_est.clone(), monitor.clone(), watch.clone(), broadcast.clone(), Arc::clone(&logger),keys_manager.clone(), config).unwrap();
287291
let router = Arc::new(Router::new(PublicKey::from_secret_key(&secp_ctx, &keys_manager.get_node_secret()), watch.clone(), Arc::clone(&logger)));
288292

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

src/ln/channel.rs

Lines changed: 68 additions & 34 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::configurations::{UserConfig,ChannelConfig};
3132

3233
use std;
3334
use std::default::Default;
@@ -225,18 +226,20 @@ const MULTI_STATE_FLAGS: u32 = (BOTH_SIDES_SHUTDOWN_MASK | ChannelState::PeerDis
225226

226227
const INITIAL_COMMITMENT_NUMBER: u64 = (1 << 48) - 1;
227228

229+
228230
// TODO: We should refactor this to be an Inbound/OutboundChannel until initial setup handshaking
229231
// has been completed, and then turn into a Channel to get compiler-time enforcement of things like
230232
// calling channel_id() before we're set up or things like get_outbound_funding_signed on an
231233
// inbound channel.
232234
pub(super) struct Channel {
235+
config : ChannelConfig,
236+
233237
user_id: u64,
234238

235239
channel_id: [u8; 32],
236240
channel_state: u32,
237241
channel_outbound: bool,
238242
secp_ctx: Secp256k1<secp256k1::All>,
239-
announce_publicly: bool,
240243
channel_value_satoshis: u64,
241244

242245
local_keys: ChannelKeys,
@@ -391,15 +394,21 @@ impl Channel {
391394
}
392395

393396
/// Returns a minimum channel reserve value **they** need to maintain
394-
///
395397
/// Guaranteed to return a value no larger than channel_value_satoshis
396398
fn get_our_channel_reserve_satoshis(channel_value_satoshis: u64) -> u64 {
397399
let (q, _) = channel_value_satoshis.overflowing_div(100);
398400
cmp::min(channel_value_satoshis, cmp::max(q, 1000)) //TODO
399401
}
400402

401403
fn derive_our_dust_limit_satoshis(at_open_background_feerate: u64) -> u64 {
402-
at_open_background_feerate * B_OUTPUT_PLUS_SPENDING_INPUT_WEIGHT / 1000 //TODO
404+
#[cfg(test)]
405+
{
406+
547
407+
}
408+
#[cfg(not(test))]
409+
{
410+
at_open_background_feerate * B_OUTPUT_PLUS_SPENDING_INPUT_WEIGHT / 1000 //TODO
411+
}
403412
}
404413

405414
fn derive_our_htlc_minimum_msat(_at_open_channel_feerate_per_kw: u64) -> u64 {
@@ -419,13 +428,12 @@ impl Channel {
419428
}
420429

421430
// Constructors:
422-
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> {
431+
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> {
423432
let chan_keys = keys_provider.get_channel_keys(false);
424433

425434
if channel_value_satoshis >= MAX_FUNDING_SATOSHIS {
426435
return Err(APIError::APIMisuseError{err: "funding value > 2^24"});
427436
}
428-
429437
if push_msat > channel_value_satoshis * 1000 {
430438
return Err(APIError::APIMisuseError{err: "push value > channel value"});
431439
}
@@ -445,12 +453,12 @@ impl Channel {
445453

446454
Ok(Channel {
447455
user_id: user_id,
456+
config: config.channel_options.clone(),
448457

449458
channel_id: rng::rand_u832(),
450459
channel_state: ChannelState::OurInitSent as u32,
451460
channel_outbound: true,
452461
secp_ctx: secp_ctx,
453-
announce_publicly: announce_publicly,
454462
channel_value_satoshis: channel_value_satoshis,
455463

456464
local_keys: chan_keys,
@@ -529,8 +537,10 @@ impl Channel {
529537

530538
/// Creates a new channel from a remote sides' request for one.
531539
/// Assumes chain_hash has already been checked and corresponds with what we expect!
532-
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> {
540+
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> {
533541
let chan_keys = keys_provider.get_channel_keys(true);
542+
let mut local_config = (*config).channel_options.clone();
543+
534544

535545
// Check sanity of message fields:
536546
if msg.funding_satoshis >= MAX_FUNDING_SATOSHIS {
@@ -562,23 +572,48 @@ impl Channel {
562572
if msg.max_accepted_htlcs > 483 {
563573
return Err(ChannelError::Close("max_accpted_htlcs > 483"));
564574
}
575+
//optional parameter checking
576+
// MAY fail the channel if
577+
if msg.funding_satoshis < config.channel_limits.min_funding_satoshis {
578+
return Err(ChannelError::Close("funding satoshis is less than the user specified limit"));
579+
}
580+
if msg.htlc_minimum_msat > config.channel_limits.max_htlc_minimum_msat {
581+
return Err(ChannelError::Close("htlc minimum msat is higher than the user specified limit"));
582+
}
583+
if msg.max_htlc_value_in_flight_msat < config.channel_limits.min_max_htlc_value_in_flight_msat {
584+
return Err(ChannelError::Close("max htlc value in flight msat is less than the user specified limit"));
585+
}
586+
if msg.channel_reserve_satoshis > config.channel_limits.max_channel_reserve_satoshis {
587+
return Err(ChannelError::Close("channel reserve satoshis is higher than the user specified limit"));
588+
}
589+
if msg.max_accepted_htlcs < config.channel_limits.min_max_accepted_htlcs {
590+
return Err(ChannelError::Close("max accepted htlcs is less than the user specified limit"));
591+
}
592+
if msg.dust_limit_satoshis < config.channel_limits.min_dust_limit_satoshis {
593+
println!("{:?}", msg.dust_limit_satoshis);
594+
return Err(ChannelError::Close("dust limit satoshis is less than the user specified limit"));
595+
}
596+
if msg.dust_limit_satoshis > config.channel_limits.max_dust_limit_satoshis {
597+
return Err(ChannelError::Close("dust limit satoshis is greater than the user specified limit"));
598+
}
565599

566600
// Convert things into internal flags and prep our state:
567601

568602
let their_announce = if (msg.channel_flags & 1) == 1 { true } else { false };
569-
if require_announce && !their_announce {
570-
return Err(ChannelError::Close("Peer tried to open unannounced channel, but we require public ones"));
571-
}
572-
if !allow_announce && their_announce {
573-
return Err(ChannelError::Close("Peer tried to open announced channel, but we require private ones"));
603+
if config.channel_limits.force_announced_channel_preference{
604+
if local_config.announced_channel != their_announce {
605+
return Err(ChannelError::Close("Peer tried to open channel but their announcement preference is different from ours"));
606+
}
574607
}
608+
//we either accept their preference or the preferences match
609+
local_config.announced_channel = their_announce;
575610

576611
let background_feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background);
577612

578613
let our_dust_limit_satoshis = Channel::derive_our_dust_limit_satoshis(background_feerate);
579614
let our_channel_reserve_satoshis = Channel::get_our_channel_reserve_satoshis(msg.funding_satoshis);
580615
if our_channel_reserve_satoshis < our_dust_limit_satoshis {
581-
return Err(ChannelError::Close("Suitalbe channel reserve not found. aborting"));
616+
return Err(ChannelError::Close("Suitable channel reserve not found. aborting"));
582617
}
583618
if msg.channel_reserve_satoshis < our_dust_limit_satoshis {
584619
return Err(ChannelError::Close("channel_reserve_satoshis too small"));
@@ -609,12 +644,12 @@ impl Channel {
609644

610645
let mut chan = Channel {
611646
user_id: user_id,
647+
config: local_config,
612648

613649
channel_id: msg.temporary_channel_id,
614650
channel_state: (ChannelState::OurInitSent as u32) | (ChannelState::TheirInitSent as u32),
615651
channel_outbound: false,
616652
secp_ctx: secp_ctx,
617-
announce_publicly: their_announce,
618653

619654
local_keys: chan_keys,
620655
shutdown_pubkey: keys_provider.get_shutdown_pubkey(),
@@ -1264,7 +1299,7 @@ impl Channel {
12641299

12651300
// Message handlers:
12661301

1267-
pub fn accept_channel(&mut self, msg: &msgs::AcceptChannel) -> Result<(), ChannelError> {
1302+
pub fn accept_channel(&mut self, msg: &msgs::AcceptChannel, config : &UserConfig) -> Result<(), ChannelError> {
12681303
// Check sanity of message fields:
12691304
if !self.channel_outbound {
12701305
return Err(ChannelError::Close("Got an accept_channel message from an inbound peer"));
@@ -1302,16 +1337,10 @@ impl Channel {
13021337
if msg.max_accepted_htlcs > 483 {
13031338
return Err(ChannelError::Close("max_accpted_htlcs > 483"));
13041339
}
1305-
1306-
// TODO: Optional additional constraints mentioned in the spec
1307-
// MAY fail the channel if
1308-
// funding_satoshi is too small
1309-
// htlc_minimum_msat too large
1310-
// max_htlc_value_in_flight_msat too small
1311-
// channel_reserve_satoshis too large
1312-
// max_accepted_htlcs too small
1313-
// dust_limit_satoshis too small
1314-
1340+
//Optional user definined limits
1341+
if msg.minimum_depth > config.channel_limits.minimum_depth {
1342+
return Err(ChannelError::Close("We consider the minimum depth to be unreasonably large"));
1343+
}
13151344
self.channel_monitor.set_their_base_keys(&msg.htlc_basepoint, &msg.delayed_payment_basepoint);
13161345

13171346
self.their_dust_limit_satoshis = msg.dust_limit_satoshis;
@@ -2575,6 +2604,10 @@ impl Channel {
25752604
self.channel_value_satoshis
25762605
}
25772606

2607+
pub fn get_fee_proportional_millionths(&self) -> u32{
2608+
self.config.fee_proportional_millionths
2609+
}
2610+
25782611
#[cfg(test)]
25792612
pub fn get_feerate(&self) -> u64 {
25802613
self.feerate_per_kw
@@ -2628,7 +2661,7 @@ impl Channel {
26282661
}
26292662

26302663
pub fn should_announce(&self) -> bool {
2631-
self.announce_publicly
2664+
self.config.announced_channel
26322665
}
26332666

26342667
pub fn is_outbound(&self) -> bool {
@@ -2827,7 +2860,7 @@ impl Channel {
28272860
delayed_payment_basepoint: PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.delayed_payment_base_key),
28282861
htlc_basepoint: PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.htlc_base_key),
28292862
first_per_commitment_point: PublicKey::from_secret_key(&self.secp_ctx, &local_commitment_secret),
2830-
channel_flags: if self.announce_publicly {1} else {0},
2863+
channel_flags: if self.config.announced_channel {1} else {0},
28312864
shutdown_scriptpubkey: None,
28322865
}
28332866
}
@@ -2931,7 +2964,7 @@ impl Channel {
29312964
/// Note that the "channel must be funded" requirement is stricter than BOLT 7 requires - see
29322965
/// https://github.com/lightningnetwork/lightning-rfc/issues/468
29332966
pub fn get_channel_announcement(&self, our_node_id: PublicKey, chain_hash: Sha256dHash) -> Result<(msgs::UnsignedChannelAnnouncement, Signature), ChannelError> {
2934-
if !self.announce_publicly {
2967+
if !self.config.announced_channel {
29352968
return Err(ChannelError::Ignore("Channel is not available for public announcements"));
29362969
}
29372970
if self.channel_state & (ChannelState::ChannelFunded as u32) == 0 {
@@ -3307,11 +3340,11 @@ impl Writeable for Channel {
33073340
writer.write_all(&[MIN_SERIALIZATION_VERSION; 1])?;
33083341

33093342
self.user_id.write(writer)?;
3343+
self.config.write(writer)?;
33103344

33113345
self.channel_id.write(writer)?;
33123346
(self.channel_state | ChannelState::PeerDisconnected as u32).write(writer)?;
33133347
self.channel_outbound.write(writer)?;
3314-
self.announce_publicly.write(writer)?;
33153348
self.channel_value_satoshis.write(writer)?;
33163349

33173350
self.local_keys.write(writer)?;
@@ -3509,11 +3542,10 @@ impl<R : ::std::io::Read> ReadableArgs<R, Arc<Logger>> for Channel {
35093542
}
35103543

35113544
let user_id = Readable::read(reader)?;
3512-
3545+
let config : ChannelConfig = Readable::read(reader)?;
35133546
let channel_id = Readable::read(reader)?;
35143547
let channel_state = Readable::read(reader)?;
35153548
let channel_outbound = Readable::read(reader)?;
3516-
let announce_publicly = Readable::read(reader)?;
35173549
let channel_value_satoshis = Readable::read(reader)?;
35183550

35193551
let local_keys = Readable::read(reader)?;
@@ -3676,12 +3708,11 @@ impl<R : ::std::io::Read> ReadableArgs<R, Arc<Logger>> for Channel {
36763708

36773709
Ok(Channel {
36783710
user_id,
3679-
3711+
config,
36803712
channel_id,
36813713
channel_state,
36823714
channel_outbound,
36833715
secp_ctx: Secp256k1::new(),
3684-
announce_publicly,
36853716
channel_value_satoshis,
36863717

36873718
local_keys,
@@ -3813,6 +3844,7 @@ mod tests {
38133844

38143845
#[test]
38153846
fn outbound_commitment_test() {
3847+
use util::configurations::UserConfig;
38163848
// Test vectors from BOLT 3 Appendix C:
38173849
let feeest = TestFeeEstimator{fee_est: 15000};
38183850
let logger : Arc<Logger> = Arc::new(test_utils::TestLogger::new());
@@ -3833,7 +3865,9 @@ mod tests {
38333865
let keys_provider: Arc<KeysInterface> = Arc::new(Keys { chan_keys });
38343866

38353867
let their_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap());
3836-
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
3868+
let mut config = UserConfig::new();
3869+
config.channel_options.announced_channel= false;
3870+
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
38373871
chan.their_to_self_delay = 144;
38383872
chan.our_dust_limit_satoshis = 546;
38393873

0 commit comments

Comments
 (0)