Skip to content

Commit 5cfe19e

Browse files
Enable wumbo channels to be created
Also redefine MAX_FUNDING_SATOSHIS_NO_WUMBO to no longer be off-by-one.
1 parent e49f738 commit 5cfe19e

File tree

3 files changed

+46
-9
lines changed

3 files changed

+46
-9
lines changed

lightning/src/ln/channel.rs

+12-6
Original file line numberDiff line numberDiff line change
@@ -736,8 +736,8 @@ pub const ANCHOR_OUTPUT_VALUE_SATOSHI: u64 = 330;
736736

737737
/// Maximum `funding_satoshis` value according to the BOLT #2 specification, if
738738
/// `option_support_large_channel` (aka wumbo channels) is not supported.
739-
/// It's 2^24.
740-
pub const MAX_FUNDING_SATOSHIS_NO_WUMBO: u64 = 1 << 24;
739+
/// It's 2^24 - 1.
740+
pub const MAX_FUNDING_SATOSHIS_NO_WUMBO: u64 = (1 << 24) - 1;
741741

742742
/// Total bitcoin supply in satoshis.
743743
pub const TOTAL_BITCOIN_SUPPLY_SATOSHIS: u64 = 21_000_000 * 1_0000_0000;
@@ -854,8 +854,11 @@ impl<Signer: Sign> Channel<Signer> {
854854
let holder_signer = keys_provider.get_channel_signer(false, channel_value_satoshis);
855855
let pubkeys = holder_signer.pubkeys().clone();
856856

857-
if channel_value_satoshis >= MAX_FUNDING_SATOSHIS_NO_WUMBO {
858-
return Err(APIError::APIMisuseError{err: format!("funding_value must be smaller than {}, it was {}", MAX_FUNDING_SATOSHIS_NO_WUMBO, channel_value_satoshis)});
857+
if !their_features.supports_wumbo() && channel_value_satoshis > MAX_FUNDING_SATOSHIS_NO_WUMBO {
858+
return Err(APIError::APIMisuseError{err: format!("funding_value must not exceed {}, it was {}", MAX_FUNDING_SATOSHIS_NO_WUMBO, channel_value_satoshis)});
859+
}
860+
if channel_value_satoshis >= TOTAL_BITCOIN_SUPPLY_SATOSHIS {
861+
return Err(APIError::APIMisuseError{err: format!("funding_value must be smaller than the total bitcoin supply, it was {}", channel_value_satoshis)});
859862
}
860863
let channel_value_msat = channel_value_satoshis * 1000;
861864
if push_msat > channel_value_msat {
@@ -1080,8 +1083,11 @@ impl<Signer: Sign> Channel<Signer> {
10801083
}
10811084

10821085
// Check sanity of message fields:
1083-
if msg.funding_satoshis >= MAX_FUNDING_SATOSHIS_NO_WUMBO {
1084-
return Err(ChannelError::Close(format!("Funding must be smaller than {}. It was {}", MAX_FUNDING_SATOSHIS_NO_WUMBO, msg.funding_satoshis)));
1086+
if msg.funding_satoshis > config.peer_channel_config_limits.max_funding_satoshis {
1087+
return Err(ChannelError::Close(format!("Per our config, funding must be at most {}. It was {}", config.peer_channel_config_limits.max_funding_satoshis, msg.funding_satoshis)));
1088+
}
1089+
if msg.funding_satoshis >= TOTAL_BITCOIN_SUPPLY_SATOSHIS {
1090+
return Err(ChannelError::Close(format!("Funding must be smaller than the total bitcoin supply. It was {}", msg.funding_satoshis)));
10851091
}
10861092
if msg.channel_reserve_satoshis > msg.funding_satoshis {
10871093
return Err(ChannelError::Close(format!("Bogus channel_reserve_satoshis ({}). Must be not greater than funding_satoshis: {}", msg.channel_reserve_satoshis, msg.funding_satoshis)));

lightning/src/ln/features.rs

+9
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,15 @@ impl<T: sealed::ShutdownAnySegwit> Features<T> {
743743
self
744744
}
745745
}
746+
747+
impl<T: sealed::Wumbo> Features<T> {
748+
#[cfg(test)]
749+
pub(crate) fn clear_wumbo(mut self) -> Self {
750+
<T as sealed::Wumbo>::clear_bits(&mut self.flags);
751+
self
752+
}
753+
}
754+
746755
macro_rules! impl_feature_len_prefixed_write {
747756
($features: ident) => {
748757
impl Writeable for $features {

lightning/src/ln/functional_tests.rs

+25-3
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,12 @@ use ln::chan_utils::CommitmentTransaction;
5858
#[test]
5959
fn test_insane_channel_opens() {
6060
// Stand up a network of 2 nodes
61+
use ln::channel::TOTAL_BITCOIN_SUPPLY_SATOSHIS;
62+
let mut cfg = UserConfig::default();
63+
cfg.peer_channel_config_limits.max_funding_satoshis = TOTAL_BITCOIN_SUPPLY_SATOSHIS + 1;
6164
let chanmon_cfgs = create_chanmon_cfgs(2);
6265
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
63-
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
66+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, Some(cfg)]);
6467
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
6568

6669
// Instantiate channel parameters where we push the maximum msats given our
@@ -92,11 +95,11 @@ fn test_insane_channel_opens() {
9295
} else { assert!(false); }
9396
};
9497

95-
use ln::channel::MAX_FUNDING_SATOSHIS_NO_WUMBO;
9698
use ln::channelmanager::MAX_LOCAL_BREAKDOWN_TIMEOUT;
9799

98100
// Test all mutations that would make the channel open message insane
99-
insane_open_helper(format!("Funding must be smaller than {}. It was {}", MAX_FUNDING_SATOSHIS_NO_WUMBO, MAX_FUNDING_SATOSHIS_NO_WUMBO).as_str(), |mut msg| { msg.funding_satoshis = MAX_FUNDING_SATOSHIS_NO_WUMBO; msg });
101+
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 });
102+
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 });
100103

101104
insane_open_helper("Bogus channel_reserve_satoshis", |mut msg| { msg.channel_reserve_satoshis = msg.funding_satoshis + 1; msg });
102105

@@ -113,6 +116,25 @@ fn test_insane_channel_opens() {
113116
insane_open_helper("max_accepted_htlcs was 484. It must not be larger than 483", |mut msg| { msg.max_accepted_htlcs = 484; msg });
114117
}
115118

119+
#[test]
120+
fn test_funding_exceeds_no_wumbo_limit() {
121+
// Test that if a peer does not support wumbo channels, we'll refuse to open a wumbo channel to
122+
// them.
123+
use ln::channel::MAX_FUNDING_SATOSHIS_NO_WUMBO;
124+
let chanmon_cfgs = create_chanmon_cfgs(2);
125+
let mut node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
126+
node_cfgs[1].features = InitFeatures::known().clear_wumbo();
127+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
128+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
129+
130+
match nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), MAX_FUNDING_SATOSHIS_NO_WUMBO + 1, 0, 42, None) {
131+
Err(APIError::APIMisuseError { err }) => {
132+
assert_eq!(format!("funding_value must not exceed {}, it was {}", MAX_FUNDING_SATOSHIS_NO_WUMBO, MAX_FUNDING_SATOSHIS_NO_WUMBO + 1), err);
133+
},
134+
_ => panic!()
135+
}
136+
}
137+
116138
fn do_test_counterparty_no_reserve(send_from_initiator: bool) {
117139
// A peer providing a channel_reserve_satoshis of 0 (or less than our dust limit) is insecure,
118140
// but only for them. Because some LSPs do it with some level of trust of the clients (for a

0 commit comments

Comments
 (0)