@@ -8,57 +8,35 @@ use std::marker::PhantomData;
88use ln:: msgs:: DecodeError ;
99use util:: ser:: { Readable , Writeable , Writer } ;
1010
11- /// The context in which a Feature object appears determines which bits of features the node
12- /// supports will be set. We use this when creating our own Feature objects to select which bits to
13- /// set and when passing around Feature objects to ensure the bits we're checking for are
14- /// available.
15- ///
16- /// This Context represents when the Feature appears in the init message, sent between peers and not
17- /// rumored around the P2P network.
18- pub struct FeatureContextInit { }
19- /// The context in which a Feature object appears determines which bits of features the node
20- /// supports will be set. We use this when creating our own Feature objects to select which bits to
21- /// set and when passing around Feature objects to ensure the bits we're checking for are
22- /// available.
23- ///
24- /// This Context represents when the Feature appears in the node_announcement message, as it is
25- /// rumored around the P2P network.
26- pub struct FeatureContextNode { }
27- /// The context in which a Feature object appears determines which bits of features the node
28- /// supports will be set. We use this when creating our own Feature objects to select which bits to
29- /// set and when passing around Feature objects to ensure the bits we're checking for are
30- /// available.
31- ///
32- /// This Context represents when the Feature appears in the ChannelAnnouncement message, as it is
33- /// rumored around the P2P network.
34- pub struct FeatureContextChannel { }
35- /// The context in which a Feature object appears determines which bits of features the node
36- /// supports will be set. We use this when creating our own Feature objects to select which bits to
37- /// set and when passing around Feature objects to ensure the bits we're checking for are
38- /// available.
39- ///
40- /// This Context represents when the Feature appears in an invoice, used to determine the different
41- /// options available for routing a payment.
42- ///
43- /// Note that this is currently unused as invoices come to us via a different crate and are not
44- /// native to rust-lightning directly.
45- pub struct FeatureContextInvoice { }
46-
47- /// An internal trait capturing the various future context types
48- pub trait FeatureContext { }
49- impl FeatureContext for FeatureContextInit { }
50- impl FeatureContext for FeatureContextNode { }
51- impl FeatureContext for FeatureContextChannel { }
52- impl FeatureContext for FeatureContextInvoice { }
53-
54- /// An internal trait capturing FeatureContextInit and FeatureContextNode
55- pub trait FeatureContextInitNode : FeatureContext { }
56- impl FeatureContextInitNode for FeatureContextInit { }
57- impl FeatureContextInitNode for FeatureContextNode { }
11+ mod sealed { // You should just use the type aliases instead.
12+ pub struct FeatureContextInit { }
13+ pub struct FeatureContextNode { }
14+ pub struct FeatureContextChannel { }
15+ //TODO: Figure out what to do with invoice feature sets with the rust-lightning-invoice crate.
16+ //pub struct FeatureContextInvoice {}
17+
18+ /// An internal trait capturing the various future context types
19+ pub trait FeatureContext { }
20+ impl FeatureContext for FeatureContextInit { }
21+ impl FeatureContext for FeatureContextNode { }
22+ impl FeatureContext for FeatureContextChannel { }
23+ //impl FeatureContext for FeatureContextInvoice {}
24+
25+ pub trait DataLossProtect : FeatureContext { }
26+ impl DataLossProtect for FeatureContextInit { }
27+ impl DataLossProtect for FeatureContextNode { }
28+
29+ pub trait InitialRoutingSync : FeatureContext { }
30+ impl InitialRoutingSync for FeatureContextInit { }
31+
32+ pub trait UpfrontShutdownScript : FeatureContext { }
33+ impl UpfrontShutdownScript for FeatureContextInit { }
34+ impl UpfrontShutdownScript for FeatureContextNode { }
35+ }
5836
5937/// Tracks the set of features which a node implements, templated by the context in which it
6038/// appears.
61- pub struct Features < T : FeatureContext > {
39+ pub struct Features < T : sealed :: FeatureContext > {
6240 #[ cfg( not( test) ) ]
6341 /// Note that, for convinience, flags is LITTLE endian (despite being big-endian on the wire)
6442 flags : Vec < u8 > ,
@@ -72,69 +50,111 @@ pub struct Features<T: FeatureContext> {
7250 pub mark : PhantomData < T > ,
7351}
7452
75- impl < T : FeatureContext > Clone for Features < T > {
53+ impl < T : sealed :: FeatureContext > Clone for Features < T > {
7654 fn clone ( & self ) -> Self {
7755 Self {
7856 flags : self . flags . clone ( ) ,
7957 mark : PhantomData ,
8058 }
8159 }
8260}
83- impl < T : FeatureContext > PartialEq for Features < T > {
61+ impl < T : sealed :: FeatureContext > PartialEq for Features < T > {
8462 fn eq ( & self , o : & Self ) -> bool {
8563 self . flags . eq ( & o. flags )
8664 }
8765}
88- impl < T : FeatureContext > fmt:: Debug for Features < T > {
66+ impl < T : sealed :: FeatureContext > fmt:: Debug for Features < T > {
8967 fn fmt ( & self , fmt : & mut fmt:: Formatter ) -> Result < ( ) , fmt:: Error > {
9068 self . flags . fmt ( fmt)
9169 }
9270}
9371
9472/// A feature message as it appears in an init message
95- pub type InitFeatures = Features < FeatureContextInit > ;
73+ pub type InitFeatures = Features < sealed :: FeatureContextInit > ;
9674/// A feature message as it appears in a node_announcement message
97- pub type NodeFeatures = Features < FeatureContextNode > ;
75+ pub type NodeFeatures = Features < sealed :: FeatureContextNode > ;
9876/// A feature message as it appears in a channel_announcement message
99- pub type ChannelFeatures = Features < FeatureContextChannel > ;
77+ pub type ChannelFeatures = Features < sealed :: FeatureContextChannel > ;
10078
101- impl < T : FeatureContextInitNode > Features < T > {
79+ impl InitFeatures {
10280 /// Create a Features with the features we support
10381 #[ cfg( not( feature = "fuzztarget" ) ) ]
104- pub ( crate ) fn our_features ( ) -> Features < T > {
105- Features {
82+ pub ( crate ) fn our_features ( ) -> InitFeatures {
83+ InitFeatures {
10684 flags : vec ! [ 2 | 1 << 5 ] ,
10785 mark : PhantomData ,
10886 }
10987 }
11088 #[ cfg( feature = "fuzztarget" ) ]
111- pub fn our_features ( ) -> Features < T > {
112- Features {
89+ pub fn our_features ( ) -> InitFeatures {
90+ InitFeatures {
11391 flags : vec ! [ 2 | 1 << 5 ] ,
11492 mark : PhantomData ,
11593 }
11694 }
95+
96+ /// Writes all features present up to, and including, 13.
97+ pub ( crate ) fn write_up_to_13 < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , :: std:: io:: Error > {
98+ let len = cmp:: min ( 2 , self . flags . len ( ) ) ;
99+ w. size_hint ( len + 2 ) ;
100+ ( len as u16 ) . write ( w) ?;
101+ for i in ( 0 ..len) . rev ( ) {
102+ if i == 0 {
103+ self . flags [ i] . write ( w) ?;
104+ } else {
105+ ( self . flags [ i] & ( ( 1 << ( 14 - 8 ) ) - 1 ) ) . write ( w) ?;
106+ }
107+ }
108+ Ok ( ( ) )
109+ }
110+
111+ /// or's another InitFeatures into this one.
112+ pub ( crate ) fn or ( & mut self , o : & InitFeatures ) {
113+ let total_feature_len = cmp:: max ( self . flags . len ( ) , o. flags . len ( ) ) ;
114+ self . flags . resize ( total_feature_len, 0u8 ) ;
115+ for ( feature, o_feature) in self . flags . iter_mut ( ) . zip ( o. flags . iter ( ) ) {
116+ * feature |= * o_feature;
117+ }
118+ }
117119}
118120
119- impl Features < FeatureContextChannel > {
121+ impl ChannelFeatures {
120122 /// Create a Features with the features we support
121123 #[ cfg( not( feature = "fuzztarget" ) ) ]
122- pub ( crate ) fn our_features ( ) -> Features < FeatureContextChannel > {
123- Features {
124+ pub ( crate ) fn our_features ( ) -> ChannelFeatures {
125+ ChannelFeatures {
124126 flags : Vec :: new ( ) ,
125127 mark : PhantomData ,
126128 }
127129 }
128130 #[ cfg( feature = "fuzztarget" ) ]
129- pub fn our_features ( ) -> Features < FeatureContextChannel > {
130- Features {
131+ pub fn our_features ( ) -> ChannelFeatures {
132+ ChannelFeatures {
131133 flags : Vec :: new ( ) ,
132134 mark : PhantomData ,
133135 }
134136 }
135137}
136138
137- impl < T : FeatureContext > Features < T > {
139+ impl NodeFeatures {
140+ /// Create a Features with the features we support
141+ #[ cfg( not( feature = "fuzztarget" ) ) ]
142+ pub ( crate ) fn our_features ( ) -> NodeFeatures {
143+ NodeFeatures {
144+ flags : vec ! [ 2 | 1 << 5 ] ,
145+ mark : PhantomData ,
146+ }
147+ }
148+ #[ cfg( feature = "fuzztarget" ) ]
149+ pub fn our_features ( ) -> NodeFeatures {
150+ NodeFeatures {
151+ flags : vec ! [ 2 | 1 << 5 ] ,
152+ mark : PhantomData ,
153+ }
154+ }
155+ }
156+
157+ impl < T : sealed:: FeatureContext > Features < T > {
138158 /// Create a blank Features with no fetures set
139159 pub fn empty ( ) -> Features < T > {
140160 Features {
@@ -179,11 +199,13 @@ impl<T: FeatureContext> Features<T> {
179199 }
180200}
181201
182- impl < T : FeatureContextInitNode > Features < T > {
202+ impl < T : sealed :: DataLossProtect > Features < T > {
183203 pub ( crate ) fn supports_data_loss_protect ( & self ) -> bool {
184204 self . flags . len ( ) > 0 && ( self . flags [ 0 ] & 3 ) != 0
185205 }
206+ }
186207
208+ impl < T : sealed:: UpfrontShutdownScript > Features < T > {
187209 pub ( crate ) fn supports_upfront_shutdown_script ( & self ) -> bool {
188210 self . flags . len ( ) > 0 && ( self . flags [ 0 ] & ( 3 << 4 ) ) != 0
189211 }
@@ -193,7 +215,7 @@ impl<T: FeatureContextInitNode> Features<T> {
193215 }
194216}
195217
196- impl Features < FeatureContextInit > {
218+ impl < T : sealed :: InitialRoutingSync > Features < T > {
197219 pub ( crate ) fn initial_routing_sync ( & self ) -> bool {
198220 self . flags . len ( ) > 0 && ( self . flags [ 0 ] & ( 1 << 3 ) ) != 0
199221 }
@@ -204,33 +226,9 @@ impl Features<FeatureContextInit> {
204226 self . flags [ 0 ] |= 1 << 3 ;
205227 }
206228 }
207-
208- /// Writes all features present up to, and including, 13.
209- pub ( crate ) fn write_up_to_13 < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , :: std:: io:: Error > {
210- let len = cmp:: min ( 2 , self . flags . len ( ) ) ;
211- w. size_hint ( len + 2 ) ;
212- ( len as u16 ) . write ( w) ?;
213- for i in ( 0 ..len) . rev ( ) {
214- if i == 0 {
215- self . flags [ i] . write ( w) ?;
216- } else {
217- ( self . flags [ i] & ( ( 1 << ( 14 - 8 ) ) - 1 ) ) . write ( w) ?;
218- }
219- }
220- Ok ( ( ) )
221- }
222-
223- /// or's another InitFeatures into this one.
224- pub ( crate ) fn or ( & mut self , o : & InitFeatures ) {
225- let total_feature_len = cmp:: max ( self . flags . len ( ) , o. flags . len ( ) ) ;
226- self . flags . resize ( total_feature_len, 0u8 ) ;
227- for ( feature, o_feature) in self . flags . iter_mut ( ) . zip ( o. flags . iter ( ) ) {
228- * feature |= * o_feature;
229- }
230- }
231229}
232230
233- impl < T : FeatureContext > Writeable for Features < T > {
231+ impl < T : sealed :: FeatureContext > Writeable for Features < T > {
234232 fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , :: std:: io:: Error > {
235233 w. size_hint ( self . flags . len ( ) + 2 ) ;
236234 ( self . flags . len ( ) as u16 ) . write ( w) ?;
@@ -241,7 +239,7 @@ impl<T: FeatureContext> Writeable for Features<T> {
241239 }
242240}
243241
244- impl < R : :: std:: io:: Read , T : FeatureContext > Readable < R > for Features < T > {
242+ impl < R : :: std:: io:: Read , T : sealed :: FeatureContext > Readable < R > for Features < T > {
245243 fn read ( r : & mut R ) -> Result < Self , DecodeError > {
246244 let mut flags: Vec < u8 > = Readable :: read ( r) ?;
247245 flags. reverse ( ) ; // Swap to big-endian
0 commit comments