@@ -8,125 +8,145 @@ 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 { }
11+ mod sealed { // You should just use the type aliases instead.
12+ pub struct InitContext { }
13+ pub struct NodeContext { }
14+ pub struct ChannelContext { }
4615
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 { }
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 { }
5321
54- /// An internal trait capturing FeatureContextInit and FeatureContextNode
55- pub trait FeatureContextInitNode : FeatureContext { }
56- impl FeatureContextInitNode for FeatureContextInit { }
57- impl FeatureContextInitNode for FeatureContextNode { }
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 /// Note that, for convinience, flags is LITTLE endian (despite being big-endian on the wire)
6338 flags : Vec < u8 > ,
6439 mark : PhantomData < T > ,
6540}
6641
67- impl < T : FeatureContext > Clone for Features < T > {
42+ impl < T : sealed :: Context > Clone for Features < T > {
6843 fn clone ( & self ) -> Self {
6944 Self {
7045 flags : self . flags . clone ( ) ,
7146 mark : PhantomData ,
7247 }
7348 }
7449}
75- impl < T : FeatureContext > PartialEq for Features < T > {
50+ impl < T : sealed :: Context > PartialEq for Features < T > {
7651 fn eq ( & self , o : & Self ) -> bool {
7752 self . flags . eq ( & o. flags )
7853 }
7954}
80- impl < T : FeatureContext > fmt:: Debug for Features < T > {
55+ impl < T : sealed :: Context > fmt:: Debug for Features < T > {
8156 fn fmt ( & self , fmt : & mut fmt:: Formatter ) -> Result < ( ) , fmt:: Error > {
8257 self . flags . fmt ( fmt)
8358 }
8459}
8560
8661/// A feature message as it appears in an init message
87- pub type InitFeatures = Features < FeatureContextInit > ;
62+ pub type InitFeatures = Features < sealed :: InitContext > ;
8863/// A feature message as it appears in a node_announcement message
89- pub type NodeFeatures = Features < FeatureContextNode > ;
64+ pub type NodeFeatures = Features < sealed :: NodeContext > ;
9065/// A feature message as it appears in a channel_announcement message
91- pub type ChannelFeatures = Features < FeatureContextChannel > ;
66+ pub type ChannelFeatures = Features < sealed :: ChannelContext > ;
9267
93- impl < T : FeatureContextInitNode > Features < T > {
68+ impl InitFeatures {
9469 /// Create a Features with the features we support
9570 #[ cfg( not( feature = "fuzztarget" ) ) ]
96- pub ( crate ) fn supported ( ) -> Features < T > {
97- Features {
71+ pub ( crate ) fn supported ( ) -> InitFeatures {
72+ InitFeatures {
9873 flags : vec ! [ 2 | 1 << 5 ] ,
9974 mark : PhantomData ,
10075 }
10176 }
10277 #[ cfg( feature = "fuzztarget" ) ]
103- pub fn supported ( ) -> Features < T > {
104- Features {
78+ pub fn supported ( ) -> InitFeatures {
79+ InitFeatures {
10580 flags : vec ! [ 2 | 1 << 5 ] ,
10681 mark : PhantomData ,
10782 }
10883 }
84+
85+ /// Writes all features present up to, and including, 13.
86+ pub ( crate ) fn write_up_to_13 < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , :: std:: io:: Error > {
87+ let len = cmp:: min ( 2 , self . flags . len ( ) ) ;
88+ w. size_hint ( len + 2 ) ;
89+ ( len as u16 ) . write ( w) ?;
90+ for i in ( 0 ..len) . rev ( ) {
91+ if i == 0 {
92+ self . flags [ i] . write ( w) ?;
93+ } else {
94+ // On byte 1, we want up-to-and-including-bit-13, 0-indexed, which is
95+ // up-to-and-including-bit-5, 0-indexed, on this byte:
96+ ( self . flags [ i] & 0b00_11_11_11 ) . write ( w) ?;
97+ }
98+ }
99+ Ok ( ( ) )
100+ }
101+
102+ /// or's another InitFeatures into this one.
103+ pub ( crate ) fn or ( mut self , o : InitFeatures ) -> InitFeatures {
104+ let total_feature_len = cmp:: max ( self . flags . len ( ) , o. flags . len ( ) ) ;
105+ self . flags . resize ( total_feature_len, 0u8 ) ;
106+ for ( byte, o_byte) in self . flags . iter_mut ( ) . zip ( o. flags . iter ( ) ) {
107+ * byte |= * o_byte;
108+ }
109+ self
110+ }
109111}
110112
111- impl Features < FeatureContextChannel > {
113+ impl ChannelFeatures {
112114 /// Create a Features with the features we support
113115 #[ cfg( not( feature = "fuzztarget" ) ) ]
114- pub ( crate ) fn supported ( ) -> Features < FeatureContextChannel > {
115- Features {
116+ pub ( crate ) fn supported ( ) -> ChannelFeatures {
117+ ChannelFeatures {
116118 flags : Vec :: new ( ) ,
117119 mark : PhantomData ,
118120 }
119121 }
120122 #[ cfg( feature = "fuzztarget" ) ]
121- pub fn supported ( ) -> Features < FeatureContextChannel > {
122- Features {
123+ pub fn supported ( ) -> ChannelFeatures {
124+ ChannelFeatures {
123125 flags : Vec :: new ( ) ,
124126 mark : PhantomData ,
125127 }
126128 }
127129}
128130
129- impl < T : FeatureContext > Features < T > {
131+ impl NodeFeatures {
132+ /// Create a Features with the features we support
133+ #[ cfg( not( feature = "fuzztarget" ) ) ]
134+ pub ( crate ) fn supported ( ) -> NodeFeatures {
135+ NodeFeatures {
136+ flags : vec ! [ 2 | 1 << 5 ] ,
137+ mark : PhantomData ,
138+ }
139+ }
140+ #[ cfg( feature = "fuzztarget" ) ]
141+ pub fn supported ( ) -> NodeFeatures {
142+ NodeFeatures {
143+ flags : vec ! [ 2 | 1 << 5 ] ,
144+ mark : PhantomData ,
145+ }
146+ }
147+ }
148+
149+ impl < T : sealed:: Context > Features < T > {
130150 /// Create a blank Features with no features set
131151 pub fn empty ( ) -> Features < T > {
132152 Features {
@@ -186,11 +206,13 @@ impl<T: FeatureContext> Features<T> {
186206 }
187207}
188208
189- impl < T : FeatureContextInitNode > Features < T > {
209+ impl < T : sealed :: DataLossProtect > Features < T > {
190210 pub ( crate ) fn supports_data_loss_protect ( & self ) -> bool {
191211 self . flags . len ( ) > 0 && ( self . flags [ 0 ] & 3 ) != 0
192212 }
213+ }
193214
215+ impl < T : sealed:: UpfrontShutdownScript > Features < T > {
194216 pub ( crate ) fn supports_upfront_shutdown_script ( & self ) -> bool {
195217 self . flags . len ( ) > 0 && ( self . flags [ 0 ] & ( 3 << 4 ) ) != 0
196218 }
@@ -200,7 +222,7 @@ impl<T: FeatureContextInitNode> Features<T> {
200222 }
201223}
202224
203- impl Features < FeatureContextInit > {
225+ impl < T : sealed :: InitialRoutingSync > Features < T > {
204226 pub ( crate ) fn initial_routing_sync ( & self ) -> bool {
205227 self . flags . len ( ) > 0 && ( self . flags [ 0 ] & ( 1 << 3 ) ) != 0
206228 }
@@ -211,34 +233,9 @@ impl Features<FeatureContextInit> {
211233 self . flags [ 0 ] |= 1 << 3 ;
212234 }
213235 }
214-
215- /// Writes all features present up to, and including, 13.
216- pub ( crate ) fn write_up_to_13 < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , :: std:: io:: Error > {
217- let len = cmp:: min ( 2 , self . flags . len ( ) ) ;
218- w. size_hint ( len + 2 ) ;
219- ( len as u16 ) . write ( w) ?;
220- for i in ( 0 ..len) . rev ( ) {
221- if i == 0 {
222- self . flags [ i] . write ( w) ?;
223- } else {
224- ( self . flags [ i] & ( ( 1 << ( 14 - 8 ) ) - 1 ) ) . write ( w) ?;
225- }
226- }
227- Ok ( ( ) )
228- }
229-
230- /// or's another InitFeatures into this one.
231- pub ( crate ) fn or ( mut self , o : InitFeatures ) -> InitFeatures {
232- let total_feature_len = cmp:: max ( self . flags . len ( ) , o. flags . len ( ) ) ;
233- self . flags . resize ( total_feature_len, 0u8 ) ;
234- for ( feature, o_feature) in self . flags . iter_mut ( ) . zip ( o. flags . iter ( ) ) {
235- * feature |= * o_feature;
236- }
237- self
238- }
239236}
240237
241- impl < T : FeatureContext > Writeable for Features < T > {
238+ impl < T : sealed :: Context > Writeable for Features < T > {
242239 fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , :: std:: io:: Error > {
243240 w. size_hint ( self . flags . len ( ) + 2 ) ;
244241 ( self . flags . len ( ) as u16 ) . write ( w) ?;
@@ -249,7 +246,7 @@ impl<T: FeatureContext> Writeable for Features<T> {
249246 }
250247}
251248
252- impl < R : :: std:: io:: Read , T : FeatureContext > Readable < R > for Features < T > {
249+ impl < R : :: std:: io:: Read , T : sealed :: Context > Readable < R > for Features < T > {
253250 fn read ( r : & mut R ) -> Result < Self , DecodeError > {
254251 let mut flags: Vec < u8 > = Readable :: read ( r) ?;
255252 flags. reverse ( ) ; // Swap to little-endian
0 commit comments