Skip to content

Commit 8ad36ea

Browse files
committed
Add htlc_maximum_msat field
1 parent 168302f commit 8ad36ea

File tree

7 files changed

+79
-8
lines changed

7 files changed

+79
-8
lines changed

lightning/src/ln/channel.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3127,6 +3127,14 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
31273127
self.our_htlc_minimum_msat
31283128
}
31293129

3130+
/// Allowed in any state (including after shutdown)
3131+
pub fn get_announced_htlc_max_msat(&self) -> u64 {
3132+
return cmp::min(
3133+
self.channel_value_satoshis * 9 / 10, // upper bound by capacity
3134+
Channel::<ChanSigner>::get_our_max_htlc_value_in_flight_msat(self.channel_value_satoshis)
3135+
);
3136+
}
3137+
31303138
/// Allowed in any state (including after shutdown)
31313139
pub fn get_their_htlc_minimum_msat(&self) -> u64 {
31323140
self.our_htlc_minimum_msat

lightning/src/ln/channelmanager.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use ln::features::{InitFeatures, NodeFeatures};
3434
use routing::router::{Route, RouteHop};
3535
use ln::msgs;
3636
use ln::onion_utils;
37-
use ln::msgs::{ChannelMessageHandler, DecodeError, LightningError};
37+
use ln::msgs::{ChannelMessageHandler, DecodeError, LightningError, OptionalField};
3838
use chain::keysinterface::{ChannelKeys, KeysInterface, KeysManager, InMemoryChannelKeys};
3939
use util::config::UserConfig;
4040
use util::{byte_utils, events};
@@ -1211,9 +1211,10 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
12111211
chain_hash: self.genesis_hash,
12121212
short_channel_id: short_channel_id,
12131213
timestamp: chan.get_update_time_counter(),
1214-
flags: (!were_node_one) as u16 | ((!chan.is_live() as u16) << 1),
1214+
flags: (!were_node_one) as u16 | ((!chan.is_live() as u16) << 1) | (1 << 8),
12151215
cltv_expiry_delta: CLTV_EXPIRY_DELTA,
12161216
htlc_minimum_msat: chan.get_our_htlc_minimum_msat(),
1217+
htlc_maximum_msat: OptionalField::Present(chan.get_announced_htlc_max_msat()),
12171218
fee_base_msat: chan.get_our_fee_base_msat(&self.fee_estimator),
12181219
fee_proportional_millionths: chan.get_fee_proportional_millionths(),
12191220
excess_data: Vec::new(),

lightning/src/ln/functional_tests.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use ln::{chan_utils, onion_utils};
1515
use routing::router::{Route, RouteHop, get_route};
1616
use ln::features::{ChannelFeatures, InitFeatures, NodeFeatures};
1717
use ln::msgs;
18-
use ln::msgs::{ChannelMessageHandler,RoutingMessageHandler,HTLCFailChannelUpdate, ErrorAction};
18+
use ln::msgs::{ChannelMessageHandler,RoutingMessageHandler,HTLCFailChannelUpdate, ErrorAction, OptionalField};
1919
use util::enforcing_trait_impls::EnforcingChannelKeys;
2020
use util::{byte_utils, test_utils};
2121
use util::events::{Event, EventsProvider, MessageSendEvent, MessageSendEventsProvider};
@@ -6055,6 +6055,7 @@ impl msgs::ChannelUpdate {
60556055
flags: 0,
60566056
cltv_expiry_delta: 0,
60576057
htlc_minimum_msat: 0,
6058+
htlc_maximum_msat: OptionalField::Absent,
60586059
fee_base_msat: 0,
60596060
fee_proportional_millionths: 0,
60606061
excess_data: vec![],

lightning/src/ln/msgs.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,7 @@ pub(crate) struct UnsignedChannelUpdate {
430430
pub(crate) flags: u16,
431431
pub(crate) cltv_expiry_delta: u16,
432432
pub(crate) htlc_minimum_msat: u64,
433+
pub(crate) htlc_maximum_msat: OptionalField<u64>,
433434
pub(crate) fee_base_msat: u32,
434435
pub(crate) fee_proportional_millionths: u32,
435436
pub(crate) excess_data: Vec<u8>,
@@ -517,7 +518,7 @@ pub enum HTLCFailChannelUpdate {
517518
/// As we wish to serialize these differently from Option<T>s (Options get a tag byte, but
518519
/// OptionalFeild simply gets Present if there are enough bytes to read into it), we have a
519520
/// separate enum type for them.
520-
#[derive(Clone, PartialEq)]
521+
#[derive(Clone, PartialEq, Debug)]
521522
pub enum OptionalField<T> {
522523
/// Optional field is included in message
523524
Present(T),
@@ -742,6 +743,26 @@ impl Readable for OptionalField<Script> {
742743
}
743744
}
744745

746+
impl Writeable for OptionalField<u64> {
747+
fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
748+
match *self {
749+
OptionalField::Present(ref value) => {
750+
value.write(w)?;
751+
},
752+
OptionalField::Absent => {}
753+
}
754+
Ok(())
755+
}
756+
}
757+
758+
impl Readable for OptionalField<u64> {
759+
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
760+
let value: u64 = Readable::read(r)?;
761+
Ok(OptionalField::Present(value))
762+
}
763+
}
764+
765+
745766
impl_writeable_len_match!(AcceptChannel, {
746767
{AcceptChannel{ shutdown_scriptpubkey: OptionalField::Present(ref script), .. }, 270 + 2 + script.len()},
747768
{_, 270}
@@ -1189,22 +1210,30 @@ impl Writeable for UnsignedChannelUpdate {
11891210
self.htlc_minimum_msat.write(w)?;
11901211
self.fee_base_msat.write(w)?;
11911212
self.fee_proportional_millionths.write(w)?;
1213+
self.htlc_maximum_msat.write(w)?;
11921214
w.write_all(&self.excess_data[..])?;
11931215
Ok(())
11941216
}
11951217
}
11961218

11971219
impl Readable for UnsignedChannelUpdate {
11981220
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
1221+
let has_htlc_maximum_msat;
11991222
Ok(Self {
12001223
chain_hash: Readable::read(r)?,
12011224
short_channel_id: Readable::read(r)?,
12021225
timestamp: Readable::read(r)?,
1203-
flags: Readable::read(r)?,
1226+
flags: {
1227+
let flags = Readable::read(r)?;
1228+
let message_flags = flags >> 8;
1229+
has_htlc_maximum_msat = (message_flags as i32 & 1) == 1;
1230+
flags
1231+
},
12041232
cltv_expiry_delta: Readable::read(r)?,
12051233
htlc_minimum_msat: Readable::read(r)?,
12061234
fee_base_msat: Readable::read(r)?,
12071235
fee_proportional_millionths: Readable::read(r)?,
1236+
htlc_maximum_msat: if has_htlc_maximum_msat { Readable::read(r)? } else { OptionalField::Absent },
12081237
excess_data: {
12091238
let mut excess_data = vec![];
12101239
r.read_to_end(&mut excess_data)?;
@@ -1608,6 +1637,7 @@ mod tests {
16081637
flags: if direction { 1 } else { 0 } | if disable { 1 << 1 } else { 0 } | if htlc_maximum_msat { 1 << 8 } else { 0 },
16091638
cltv_expiry_delta: 144,
16101639
htlc_minimum_msat: 1000000,
1640+
htlc_maximum_msat: OptionalField::Absent,
16111641
fee_base_msat: 10000,
16121642
fee_proportional_millionths: 20,
16131643
excess_data: if htlc_maximum_msat { vec![0, 0, 0, 0, 59, 154, 202, 0] } else { Vec::new() }

lightning/src/routing/network_graph.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use bitcoin::blockdata::opcodes;
1111

1212
use chain::chaininterface::{ChainError, ChainWatchInterface};
1313
use ln::features::{ChannelFeatures, NodeFeatures};
14-
use ln::msgs::{DecodeError,ErrorAction,LightningError,RoutingMessageHandler,NetAddress};
14+
use ln::msgs::{DecodeError, ErrorAction, LightningError, RoutingMessageHandler, NetAddress, OptionalField};
1515
use ln::msgs;
1616
use util::ser::{Writeable, Readable, Writer};
1717
use util::logger::Logger;
@@ -214,6 +214,8 @@ pub struct DirectionalChannelInfo {
214214
pub cltv_expiry_delta: u16,
215215
/// The minimum value, which must be relayed to the next hop via the channel
216216
pub htlc_minimum_msat: u64,
217+
/// The maximum value which may be relayed to the next hop via the channel.
218+
pub htlc_maximum_msat: Option<u64>,
217219
/// Fees charged when the channel is used for routing
218220
pub fees: RoutingFees,
219221
/// Most recent update for the channel received from the network
@@ -235,6 +237,7 @@ impl_writeable!(DirectionalChannelInfo, 0, {
235237
enabled,
236238
cltv_expiry_delta,
237239
htlc_minimum_msat,
240+
htlc_maximum_msat,
238241
fees,
239242
last_update_message
240243
});
@@ -680,6 +683,7 @@ impl NetworkGraph {
680683
last_update: msg.contents.timestamp,
681684
cltv_expiry_delta: msg.contents.cltv_expiry_delta,
682685
htlc_minimum_msat: msg.contents.htlc_minimum_msat,
686+
htlc_maximum_msat: if let OptionalField::Present(max_value) = msg.contents.htlc_maximum_msat { Some(max_value) } else { None },
683687
fees: RoutingFees {
684688
base_msat: msg.contents.fee_base_msat,
685689
proportional_millionths: msg.contents.fee_proportional_millionths,
@@ -773,7 +777,7 @@ mod tests {
773777
use chain::chaininterface;
774778
use ln::features::{ChannelFeatures, NodeFeatures};
775779
use routing::network_graph::{NetGraphMsgHandler, NetworkGraph};
776-
use ln::msgs::{RoutingMessageHandler, UnsignedNodeAnnouncement, NodeAnnouncement,
780+
use ln::msgs::{OptionalField, RoutingMessageHandler, UnsignedNodeAnnouncement, NodeAnnouncement,
777781
UnsignedChannelAnnouncement, ChannelAnnouncement, UnsignedChannelUpdate, ChannelUpdate, HTLCFailChannelUpdate};
778782
use util::test_utils;
779783
use util::logger::Logger;
@@ -1155,6 +1159,7 @@ mod tests {
11551159
flags: 0,
11561160
cltv_expiry_delta: 144,
11571161
htlc_minimum_msat: 1000000,
1162+
htlc_maximum_msat: OptionalField::Absent,
11581163
fee_base_msat: 10000,
11591164
fee_proportional_millionths: 20,
11601165
excess_data: Vec::new()
@@ -1289,6 +1294,7 @@ mod tests {
12891294
flags: 0,
12901295
cltv_expiry_delta: 144,
12911296
htlc_minimum_msat: 1000000,
1297+
htlc_maximum_msat: OptionalField::Absent,
12921298
fee_base_msat: 10000,
12931299
fee_proportional_millionths: 20,
12941300
excess_data: Vec::new()
@@ -1416,6 +1422,7 @@ mod tests {
14161422
flags: 0,
14171423
cltv_expiry_delta: 144,
14181424
htlc_minimum_msat: 1000000,
1425+
htlc_maximum_msat: OptionalField::Absent,
14191426
fee_base_msat: 10000,
14201427
fee_proportional_millionths: 20,
14211428
excess_data: Vec::new()
@@ -1452,6 +1459,7 @@ mod tests {
14521459
flags: 0,
14531460
cltv_expiry_delta: 144,
14541461
htlc_minimum_msat: 1000000,
1462+
htlc_maximum_msat: OptionalField::Absent,
14551463
fee_base_msat: 10000,
14561464
fee_proportional_millionths: 20,
14571465
excess_data: [1; 3].to_vec()

lightning/src/routing/router.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ mod tests {
405405
use routing::router::{get_route, RouteHint, RoutingFees};
406406
use routing::network_graph::NetGraphMsgHandler;
407407
use ln::features::{ChannelFeatures, InitFeatures, NodeFeatures};
408-
use ln::msgs::{ErrorAction, LightningError, UnsignedChannelAnnouncement, ChannelAnnouncement, RoutingMessageHandler,
408+
use ln::msgs::{ErrorAction, LightningError, OptionalField, UnsignedChannelAnnouncement, ChannelAnnouncement, RoutingMessageHandler,
409409
NodeAnnouncement, UnsignedNodeAnnouncement, ChannelUpdate, UnsignedChannelUpdate};
410410
use ln::channelmanager;
411411
use util::test_utils;
@@ -604,6 +604,7 @@ mod tests {
604604
flags: 1,
605605
cltv_expiry_delta: 0,
606606
htlc_minimum_msat: 0,
607+
htlc_maximum_msat: OptionalField::Absent,
607608
fee_base_msat: 0,
608609
fee_proportional_millionths: 0,
609610
excess_data: Vec::new()
@@ -618,6 +619,7 @@ mod tests {
618619
flags: 0,
619620
cltv_expiry_delta: u16::max_value(),
620621
htlc_minimum_msat: 0,
622+
htlc_maximum_msat: OptionalField::Absent,
621623
fee_base_msat: u32::max_value(),
622624
fee_proportional_millionths: u32::max_value(),
623625
excess_data: Vec::new()
@@ -629,6 +631,7 @@ mod tests {
629631
flags: 1,
630632
cltv_expiry_delta: 0,
631633
htlc_minimum_msat: 0,
634+
htlc_maximum_msat: OptionalField::Absent,
632635
fee_base_msat: 0,
633636
fee_proportional_millionths: 0,
634637
excess_data: Vec::new()
@@ -644,6 +647,7 @@ mod tests {
644647
flags: 0,
645648
cltv_expiry_delta: u16::max_value(),
646649
htlc_minimum_msat: 0,
650+
htlc_maximum_msat: OptionalField::Absent,
647651
fee_base_msat: u32::max_value(),
648652
fee_proportional_millionths: u32::max_value(),
649653
excess_data: Vec::new()
@@ -655,6 +659,7 @@ mod tests {
655659
flags: 1,
656660
cltv_expiry_delta: 0,
657661
htlc_minimum_msat: 0,
662+
htlc_maximum_msat: OptionalField::Absent,
658663
fee_base_msat: 0,
659664
fee_proportional_millionths: 0,
660665
excess_data: Vec::new()
@@ -671,6 +676,7 @@ mod tests {
671676
flags: 0,
672677
cltv_expiry_delta: (3 << 8) | 1,
673678
htlc_minimum_msat: 0,
679+
htlc_maximum_msat: OptionalField::Absent,
674680
fee_base_msat: 0,
675681
fee_proportional_millionths: 0,
676682
excess_data: Vec::new()
@@ -682,6 +688,7 @@ mod tests {
682688
flags: 1,
683689
cltv_expiry_delta: (3 << 8) | 2,
684690
htlc_minimum_msat: 0,
691+
htlc_maximum_msat: OptionalField::Absent,
685692
fee_base_msat: 100,
686693
fee_proportional_millionths: 0,
687694
excess_data: Vec::new()
@@ -696,6 +703,7 @@ mod tests {
696703
flags: 0,
697704
cltv_expiry_delta: (4 << 8) | 1,
698705
htlc_minimum_msat: 0,
706+
htlc_maximum_msat: OptionalField::Absent,
699707
fee_base_msat: 0,
700708
fee_proportional_millionths: 1000000,
701709
excess_data: Vec::new()
@@ -707,6 +715,7 @@ mod tests {
707715
flags: 1,
708716
cltv_expiry_delta: (4 << 8) | 2,
709717
htlc_minimum_msat: 0,
718+
htlc_maximum_msat: OptionalField::Absent,
710719
fee_base_msat: 0,
711720
fee_proportional_millionths: 0,
712721
excess_data: Vec::new()
@@ -720,6 +729,7 @@ mod tests {
720729
flags: 0,
721730
cltv_expiry_delta: (13 << 8) | 1,
722731
htlc_minimum_msat: 0,
732+
htlc_maximum_msat: OptionalField::Absent,
723733
fee_base_msat: 0,
724734
fee_proportional_millionths: 2000000,
725735
excess_data: Vec::new()
@@ -731,6 +741,7 @@ mod tests {
731741
flags: 1,
732742
cltv_expiry_delta: (13 << 8) | 2,
733743
htlc_minimum_msat: 0,
744+
htlc_maximum_msat: OptionalField::Absent,
734745
fee_base_msat: 0,
735746
fee_proportional_millionths: 0,
736747
excess_data: Vec::new()
@@ -745,6 +756,7 @@ mod tests {
745756
flags: 0,
746757
cltv_expiry_delta: (6 << 8) | 1,
747758
htlc_minimum_msat: 0,
759+
htlc_maximum_msat: OptionalField::Absent,
748760
fee_base_msat: 0,
749761
fee_proportional_millionths: 0,
750762
excess_data: Vec::new()
@@ -756,6 +768,7 @@ mod tests {
756768
flags: 1,
757769
cltv_expiry_delta: (6 << 8) | 2,
758770
htlc_minimum_msat: 0,
771+
htlc_maximum_msat: OptionalField::Absent,
759772
fee_base_msat: 0,
760773
fee_proportional_millionths: 0,
761774
excess_data: Vec::new()
@@ -769,6 +782,7 @@ mod tests {
769782
flags: 0,
770783
cltv_expiry_delta: (11 << 8) | 1,
771784
htlc_minimum_msat: 0,
785+
htlc_maximum_msat: OptionalField::Absent,
772786
fee_base_msat: 0,
773787
fee_proportional_millionths: 0,
774788
excess_data: Vec::new()
@@ -780,6 +794,7 @@ mod tests {
780794
flags: 1,
781795
cltv_expiry_delta: (11 << 8) | 2,
782796
htlc_minimum_msat: 0,
797+
htlc_maximum_msat: OptionalField::Absent,
783798
fee_base_msat: 0,
784799
fee_proportional_millionths: 0,
785800
excess_data: Vec::new()
@@ -796,6 +811,7 @@ mod tests {
796811
flags: 0,
797812
cltv_expiry_delta: (7 << 8) | 1,
798813
htlc_minimum_msat: 0,
814+
htlc_maximum_msat: OptionalField::Absent,
799815
fee_base_msat: 0,
800816
fee_proportional_millionths: 1000000,
801817
excess_data: Vec::new()
@@ -807,6 +823,7 @@ mod tests {
807823
flags: 1,
808824
cltv_expiry_delta: (7 << 8) | 2,
809825
htlc_minimum_msat: 0,
826+
htlc_maximum_msat: OptionalField::Absent,
810827
fee_base_msat: 0,
811828
fee_proportional_millionths: 0,
812829
excess_data: Vec::new()
@@ -841,6 +858,7 @@ mod tests {
841858
flags: 2, // to disable
842859
cltv_expiry_delta: 0,
843860
htlc_minimum_msat: 0,
861+
htlc_maximum_msat: OptionalField::Absent,
844862
fee_base_msat: 0,
845863
fee_proportional_millionths: 0,
846864
excess_data: Vec::new()
@@ -852,6 +870,7 @@ mod tests {
852870
flags: 2, // to disable
853871
cltv_expiry_delta: 0,
854872
htlc_minimum_msat: 0,
873+
htlc_maximum_msat: OptionalField::Absent,
855874
fee_base_msat: 0,
856875
fee_proportional_millionths: 0,
857876
excess_data: Vec::new()
@@ -899,6 +918,7 @@ mod tests {
899918
flags: 0, // to enable
900919
cltv_expiry_delta: (4 << 8) | 1,
901920
htlc_minimum_msat: 0,
921+
htlc_maximum_msat: OptionalField::Absent,
902922
fee_base_msat: 0,
903923
fee_proportional_millionths: 1000000,
904924
excess_data: Vec::new()
@@ -910,6 +930,7 @@ mod tests {
910930
flags: 0, // to enable
911931
cltv_expiry_delta: u16::max_value(),
912932
htlc_minimum_msat: 0,
933+
htlc_maximum_msat: OptionalField::Absent,
913934
fee_base_msat: u32::max_value(),
914935
fee_proportional_millionths: u32::max_value(),
915936
excess_data: Vec::new()

0 commit comments

Comments
 (0)