@@ -8,57 +8,32 @@ 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 InitContext { }
13+ pub struct NodeContext { }
14+ pub struct ChannelContext { }
15+
16+ /// An internal trait capturing the various feature context types
17+ pub trait Context { }
18+ impl Context for InitContext { }
19+ impl Context for NodeContext { }
20+ impl Context for ChannelContext { }
21+
22+ pub trait DataLossProtect : Context { }
23+ impl DataLossProtect for InitContext { }
24+ impl DataLossProtect for NodeContext { }
25+
26+ pub trait InitialRoutingSync : Context { }
27+ impl InitialRoutingSync for InitContext { }
28+
29+ pub trait UpfrontShutdownScript : Context { }
30+ impl UpfrontShutdownScript for InitContext { }
31+ impl UpfrontShutdownScript for NodeContext { }
32+ }
5833
5934/// Tracks the set of features which a node implements, templated by the context in which it
6035/// appears.
61- pub struct Features < T : FeatureContext > {
36+ pub struct Features < T : sealed :: Context > {
6237 #[ cfg( not( test) ) ]
6338 /// Note that, for convinience, flags is LITTLE endian (despite being big-endian on the wire)
6439 flags : Vec < u8 > ,
@@ -72,69 +47,112 @@ pub struct Features<T: FeatureContext> {
7247 pub mark : PhantomData < T > ,
7348}
7449
75- impl < T : FeatureContext > Clone for Features < T > {
50+ impl < T : sealed :: Context > Clone for Features < T > {
7651 fn clone ( & self ) -> Self {
7752 Self {
7853 flags : self . flags . clone ( ) ,
7954 mark : PhantomData ,
8055 }
8156 }
8257}
83- impl < T : FeatureContext > PartialEq for Features < T > {
58+ impl < T : sealed :: Context > PartialEq for Features < T > {
8459 fn eq ( & self , o : & Self ) -> bool {
8560 self . flags . eq ( & o. flags )
8661 }
8762}
88- impl < T : FeatureContext > fmt:: Debug for Features < T > {
63+ impl < T : sealed :: Context > fmt:: Debug for Features < T > {
8964 fn fmt ( & self , fmt : & mut fmt:: Formatter ) -> Result < ( ) , fmt:: Error > {
9065 self . flags . fmt ( fmt)
9166 }
9267}
9368
9469/// A feature message as it appears in an init message
95- pub type InitFeatures = Features < FeatureContextInit > ;
70+ pub type InitFeatures = Features < sealed :: InitContext > ;
9671/// A feature message as it appears in a node_announcement message
97- pub type NodeFeatures = Features < FeatureContextNode > ;
72+ pub type NodeFeatures = Features < sealed :: NodeContext > ;
9873/// A feature message as it appears in a channel_announcement message
99- pub type ChannelFeatures = Features < FeatureContextChannel > ;
74+ pub type ChannelFeatures = Features < sealed :: ChannelContext > ;
10075
101- impl < T : FeatureContextInitNode > Features < T > {
76+ impl InitFeatures {
10277 /// Create a Features with the features we support
10378 #[ cfg( not( feature = "fuzztarget" ) ) ]
104- pub ( crate ) fn our_features ( ) -> Features < T > {
105- Features {
79+ pub ( crate ) fn our_features ( ) -> InitFeatures {
80+ InitFeatures {
10681 flags : vec ! [ 2 | 1 << 5 ] ,
10782 mark : PhantomData ,
10883 }
10984 }
11085 #[ cfg( feature = "fuzztarget" ) ]
111- pub fn our_features ( ) -> Features < T > {
112- Features {
86+ pub fn our_features ( ) -> InitFeatures {
87+ InitFeatures {
11388 flags : vec ! [ 2 | 1 << 5 ] ,
11489 mark : PhantomData ,
11590 }
11691 }
92+
93+ /// Writes all features present up to, and including, 13.
94+ pub ( crate ) fn write_up_to_13 < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , :: std:: io:: Error > {
95+ let len = cmp:: min ( 2 , self . flags . len ( ) ) ;
96+ w. size_hint ( len + 2 ) ;
97+ ( len as u16 ) . write ( w) ?;
98+ for i in ( 0 ..len) . rev ( ) {
99+ if i == 0 {
100+ self . flags [ i] . write ( w) ?;
101+ } else {
102+ // On byte 1, check (1 << 14) - 1 up all bits-up-to-but-not-including-bit-14.
103+ ( self . flags [ i] & ( ( 1 << ( 14 - 8 ) ) - 1 ) ) . write ( w) ?;
104+ }
105+ }
106+ Ok ( ( ) )
107+ }
108+
109+ /// or's another InitFeatures into this one.
110+ pub ( crate ) fn or ( & mut self , o : & InitFeatures ) {
111+ let total_feature_len = cmp:: max ( self . flags . len ( ) , o. flags . len ( ) ) ;
112+ self . flags . resize ( total_feature_len, 0u8 ) ;
113+ for ( byte, o_byte) in self . flags . iter_mut ( ) . zip ( o. flags . iter ( ) ) {
114+ * byte |= * o_byte;
115+ }
116+ }
117117}
118118
119- impl Features < FeatureContextChannel > {
119+ impl ChannelFeatures {
120120 /// Create a Features with the features we support
121121 #[ cfg( not( feature = "fuzztarget" ) ) ]
122- pub ( crate ) fn our_features ( ) -> Features < FeatureContextChannel > {
123- Features {
122+ pub ( crate ) fn our_features ( ) -> ChannelFeatures {
123+ ChannelFeatures {
124124 flags : Vec :: new ( ) ,
125125 mark : PhantomData ,
126126 }
127127 }
128128 #[ cfg( feature = "fuzztarget" ) ]
129- pub fn our_features ( ) -> Features < FeatureContextChannel > {
130- Features {
129+ pub fn our_features ( ) -> ChannelFeatures {
130+ ChannelFeatures {
131131 flags : Vec :: new ( ) ,
132132 mark : PhantomData ,
133133 }
134134 }
135135}
136136
137- impl < T : FeatureContext > Features < T > {
137+ impl NodeFeatures {
138+ /// Create a Features with the features we support
139+ #[ cfg( not( feature = "fuzztarget" ) ) ]
140+ pub ( crate ) fn our_features ( ) -> NodeFeatures {
141+ NodeFeatures {
142+ flags : vec ! [ 2 | 1 << 5 ] ,
143+ mark : PhantomData ,
144+ }
145+ }
146+ #[ cfg( feature = "fuzztarget" ) ]
147+ pub fn our_features ( ) -> NodeFeatures {
148+ NodeFeatures {
149+ flags : vec ! [ 2 | 1 << 5 ] ,
150+ mark : PhantomData ,
151+ }
152+ }
153+ }
154+
155+ impl < T : sealed:: FeatureContext > Features < T > {
138156 /// Create a blank Features with no fetures set
139157 pub fn empty ( ) -> Features < T > {
140158 Features {
@@ -179,11 +197,13 @@ impl<T: FeatureContext> Features<T> {
179197 }
180198}
181199
182- impl < T : FeatureContextInitNode > Features < T > {
200+ impl < T : sealed :: DataLossProtect > Features < T > {
183201 pub ( crate ) fn supports_data_loss_protect ( & self ) -> bool {
184202 self . flags . len ( ) > 0 && ( self . flags [ 0 ] & 3 ) != 0
185203 }
204+ }
186205
206+ impl < T : sealed:: UpfrontShutdownScript > Features < T > {
187207 pub ( crate ) fn supports_upfront_shutdown_script ( & self ) -> bool {
188208 self . flags . len ( ) > 0 && ( self . flags [ 0 ] & ( 3 << 4 ) ) != 0
189209 }
@@ -193,7 +213,7 @@ impl<T: FeatureContextInitNode> Features<T> {
193213 }
194214}
195215
196- impl Features < FeatureContextInit > {
216+ impl < T : sealed :: InitialRoutingSync > Features < T > {
197217 pub ( crate ) fn initial_routing_sync ( & self ) -> bool {
198218 self . flags . len ( ) > 0 && ( self . flags [ 0 ] & ( 1 << 3 ) ) != 0
199219 }
@@ -204,33 +224,9 @@ impl Features<FeatureContextInit> {
204224 self . flags [ 0 ] |= 1 << 3 ;
205225 }
206226 }
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- }
231227}
232228
233- impl < T : FeatureContext > Writeable for Features < T > {
229+ impl < T : sealed :: Context > Writeable for Features < T > {
234230 fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , :: std:: io:: Error > {
235231 w. size_hint ( self . flags . len ( ) + 2 ) ;
236232 ( self . flags . len ( ) as u16 ) . write ( w) ?;
@@ -241,7 +237,7 @@ impl<T: FeatureContext> Writeable for Features<T> {
241237 }
242238}
243239
244- impl < R : :: std:: io:: Read , T : FeatureContext > Readable < R > for Features < T > {
240+ impl < R : :: std:: io:: Read , T : sealed :: Context > Readable < R > for Features < T > {
245241 fn read ( r : & mut R ) -> Result < Self , DecodeError > {
246242 let mut flags: Vec < u8 > = Readable :: read ( r) ?;
247243 flags. reverse ( ) ; // Swap to little-endian
0 commit comments