@@ -8,57 +8,35 @@ use std::marker::PhantomData;
8
8
use ln:: msgs:: DecodeError ;
9
9
use util:: ser:: { Readable , Writeable , Writer } ;
10
10
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
+ }
58
36
59
37
/// Tracks the set of features which a node implements, templated by the context in which it
60
38
/// appears.
61
- pub struct Features < T : FeatureContext > {
39
+ pub struct Features < T : sealed :: FeatureContext > {
62
40
#[ cfg( not( test) ) ]
63
41
/// Note that, for convinience, flags is LITTLE endian (despite being big-endian on the wire)
64
42
flags : Vec < u8 > ,
@@ -72,69 +50,111 @@ pub struct Features<T: FeatureContext> {
72
50
pub mark : PhantomData < T > ,
73
51
}
74
52
75
- impl < T : FeatureContext > Clone for Features < T > {
53
+ impl < T : sealed :: FeatureContext > Clone for Features < T > {
76
54
fn clone ( & self ) -> Self {
77
55
Self {
78
56
flags : self . flags . clone ( ) ,
79
57
mark : PhantomData ,
80
58
}
81
59
}
82
60
}
83
- impl < T : FeatureContext > PartialEq for Features < T > {
61
+ impl < T : sealed :: FeatureContext > PartialEq for Features < T > {
84
62
fn eq ( & self , o : & Self ) -> bool {
85
63
self . flags . eq ( & o. flags )
86
64
}
87
65
}
88
- impl < T : FeatureContext > fmt:: Debug for Features < T > {
66
+ impl < T : sealed :: FeatureContext > fmt:: Debug for Features < T > {
89
67
fn fmt ( & self , fmt : & mut fmt:: Formatter ) -> Result < ( ) , fmt:: Error > {
90
68
self . flags . fmt ( fmt)
91
69
}
92
70
}
93
71
94
72
/// A feature message as it appears in an init message
95
- pub type InitFeatures = Features < FeatureContextInit > ;
73
+ pub type InitFeatures = Features < sealed :: FeatureContextInit > ;
96
74
/// A feature message as it appears in a node_announcement message
97
- pub type NodeFeatures = Features < FeatureContextNode > ;
75
+ pub type NodeFeatures = Features < sealed :: FeatureContextNode > ;
98
76
/// A feature message as it appears in a channel_announcement message
99
- pub type ChannelFeatures = Features < FeatureContextChannel > ;
77
+ pub type ChannelFeatures = Features < sealed :: FeatureContextChannel > ;
100
78
101
- impl < T : FeatureContextInitNode > Features < T > {
79
+ impl InitFeatures {
102
80
/// Create a Features with the features we support
103
81
#[ cfg( not( feature = "fuzztarget" ) ) ]
104
- pub ( crate ) fn our_features ( ) -> Features < T > {
105
- Features {
82
+ pub ( crate ) fn our_features ( ) -> InitFeatures {
83
+ InitFeatures {
106
84
flags : vec ! [ 2 | 1 << 5 ] ,
107
85
mark : PhantomData ,
108
86
}
109
87
}
110
88
#[ cfg( feature = "fuzztarget" ) ]
111
- pub fn our_features ( ) -> Features < T > {
112
- Features {
89
+ pub fn our_features ( ) -> InitFeatures {
90
+ InitFeatures {
113
91
flags : vec ! [ 2 | 1 << 5 ] ,
114
92
mark : PhantomData ,
115
93
}
116
94
}
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
+ }
117
119
}
118
120
119
- impl Features < FeatureContextChannel > {
121
+ impl ChannelFeatures {
120
122
/// Create a Features with the features we support
121
123
#[ cfg( not( feature = "fuzztarget" ) ) ]
122
- pub ( crate ) fn our_features ( ) -> Features < FeatureContextChannel > {
123
- Features {
124
+ pub ( crate ) fn our_features ( ) -> ChannelFeatures {
125
+ ChannelFeatures {
124
126
flags : Vec :: new ( ) ,
125
127
mark : PhantomData ,
126
128
}
127
129
}
128
130
#[ cfg( feature = "fuzztarget" ) ]
129
- pub fn our_features ( ) -> Features < FeatureContextChannel > {
130
- Features {
131
+ pub fn our_features ( ) -> ChannelFeatures {
132
+ ChannelFeatures {
131
133
flags : Vec :: new ( ) ,
132
134
mark : PhantomData ,
133
135
}
134
136
}
135
137
}
136
138
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 > {
138
158
/// Create a blank Features with no fetures set
139
159
pub fn empty ( ) -> Features < T > {
140
160
Features {
@@ -179,11 +199,13 @@ impl<T: FeatureContext> Features<T> {
179
199
}
180
200
}
181
201
182
- impl < T : FeatureContextInitNode > Features < T > {
202
+ impl < T : sealed :: DataLossProtect > Features < T > {
183
203
pub ( crate ) fn supports_data_loss_protect ( & self ) -> bool {
184
204
self . flags . len ( ) > 0 && ( self . flags [ 0 ] & 3 ) != 0
185
205
}
206
+ }
186
207
208
+ impl < T : sealed:: UpfrontShutdownScript > Features < T > {
187
209
pub ( crate ) fn supports_upfront_shutdown_script ( & self ) -> bool {
188
210
self . flags . len ( ) > 0 && ( self . flags [ 0 ] & ( 3 << 4 ) ) != 0
189
211
}
@@ -193,7 +215,7 @@ impl<T: FeatureContextInitNode> Features<T> {
193
215
}
194
216
}
195
217
196
- impl Features < FeatureContextInit > {
218
+ impl < T : sealed :: InitialRoutingSync > Features < T > {
197
219
pub ( crate ) fn initial_routing_sync ( & self ) -> bool {
198
220
self . flags . len ( ) > 0 && ( self . flags [ 0 ] & ( 1 << 3 ) ) != 0
199
221
}
@@ -204,33 +226,9 @@ impl Features<FeatureContextInit> {
204
226
self . flags [ 0 ] |= 1 << 3 ;
205
227
}
206
228
}
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
- }
231
229
}
232
230
233
- impl < T : FeatureContext > Writeable for Features < T > {
231
+ impl < T : sealed :: FeatureContext > Writeable for Features < T > {
234
232
fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , :: std:: io:: Error > {
235
233
w. size_hint ( self . flags . len ( ) + 2 ) ;
236
234
( self . flags . len ( ) as u16 ) . write ( w) ?;
@@ -241,7 +239,7 @@ impl<T: FeatureContext> Writeable for Features<T> {
241
239
}
242
240
}
243
241
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 > {
245
243
fn read ( r : & mut R ) -> Result < Self , DecodeError > {
246
244
let mut flags: Vec < u8 > = Readable :: read ( r) ?;
247
245
flags. reverse ( ) ; // Swap to big-endian
0 commit comments