@@ -8,125 +8,145 @@ 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 { }
11
+ mod sealed { // You should just use the type aliases instead.
12
+ pub struct InitContext { }
13
+ pub struct NodeContext { }
14
+ pub struct ChannelContext { }
46
15
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 { }
53
21
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
+ }
58
33
59
34
/// Tracks the set of features which a node implements, templated by the context in which it
60
35
/// appears.
61
- pub struct Features < T : FeatureContext > {
36
+ pub struct Features < T : sealed :: Context > {
62
37
/// Note that, for convinience, flags is LITTLE endian (despite being big-endian on the wire)
63
38
flags : Vec < u8 > ,
64
39
mark : PhantomData < T > ,
65
40
}
66
41
67
- impl < T : FeatureContext > Clone for Features < T > {
42
+ impl < T : sealed :: Context > Clone for Features < T > {
68
43
fn clone ( & self ) -> Self {
69
44
Self {
70
45
flags : self . flags . clone ( ) ,
71
46
mark : PhantomData ,
72
47
}
73
48
}
74
49
}
75
- impl < T : FeatureContext > PartialEq for Features < T > {
50
+ impl < T : sealed :: Context > PartialEq for Features < T > {
76
51
fn eq ( & self , o : & Self ) -> bool {
77
52
self . flags . eq ( & o. flags )
78
53
}
79
54
}
80
- impl < T : FeatureContext > fmt:: Debug for Features < T > {
55
+ impl < T : sealed :: Context > fmt:: Debug for Features < T > {
81
56
fn fmt ( & self , fmt : & mut fmt:: Formatter ) -> Result < ( ) , fmt:: Error > {
82
57
self . flags . fmt ( fmt)
83
58
}
84
59
}
85
60
86
61
/// A feature message as it appears in an init message
87
- pub type InitFeatures = Features < FeatureContextInit > ;
62
+ pub type InitFeatures = Features < sealed :: InitContext > ;
88
63
/// A feature message as it appears in a node_announcement message
89
- pub type NodeFeatures = Features < FeatureContextNode > ;
64
+ pub type NodeFeatures = Features < sealed :: NodeContext > ;
90
65
/// A feature message as it appears in a channel_announcement message
91
- pub type ChannelFeatures = Features < FeatureContextChannel > ;
66
+ pub type ChannelFeatures = Features < sealed :: ChannelContext > ;
92
67
93
- impl < T : FeatureContextInitNode > Features < T > {
68
+ impl InitFeatures {
94
69
/// Create a Features with the features we support
95
70
#[ cfg( not( feature = "fuzztarget" ) ) ]
96
- pub ( crate ) fn our_features ( ) -> Features < T > {
97
- Features {
71
+ pub ( crate ) fn our_features ( ) -> InitFeatures {
72
+ InitFeatures {
98
73
flags : vec ! [ 2 | 1 << 5 ] ,
99
74
mark : PhantomData ,
100
75
}
101
76
}
102
77
#[ cfg( feature = "fuzztarget" ) ]
103
- pub fn our_features ( ) -> Features < T > {
104
- Features {
78
+ pub fn our_features ( ) -> InitFeatures {
79
+ InitFeatures {
105
80
flags : vec ! [ 2 | 1 << 5 ] ,
106
81
mark : PhantomData ,
107
82
}
108
83
}
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
+ }
109
111
}
110
112
111
- impl Features < FeatureContextChannel > {
113
+ impl ChannelFeatures {
112
114
/// Create a Features with the features we support
113
115
#[ cfg( not( feature = "fuzztarget" ) ) ]
114
- pub ( crate ) fn our_features ( ) -> Features < FeatureContextChannel > {
115
- Features {
116
+ pub ( crate ) fn our_features ( ) -> ChannelFeatures {
117
+ ChannelFeatures {
116
118
flags : Vec :: new ( ) ,
117
119
mark : PhantomData ,
118
120
}
119
121
}
120
122
#[ cfg( feature = "fuzztarget" ) ]
121
- pub fn our_features ( ) -> Features < FeatureContextChannel > {
122
- Features {
123
+ pub fn our_features ( ) -> ChannelFeatures {
124
+ ChannelFeatures {
123
125
flags : Vec :: new ( ) ,
124
126
mark : PhantomData ,
125
127
}
126
128
}
127
129
}
128
130
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 our_features ( ) -> NodeFeatures {
135
+ NodeFeatures {
136
+ flags : vec ! [ 2 | 1 << 5 ] ,
137
+ mark : PhantomData ,
138
+ }
139
+ }
140
+ #[ cfg( feature = "fuzztarget" ) ]
141
+ pub fn our_features ( ) -> NodeFeatures {
142
+ NodeFeatures {
143
+ flags : vec ! [ 2 | 1 << 5 ] ,
144
+ mark : PhantomData ,
145
+ }
146
+ }
147
+ }
148
+
149
+ impl < T : sealed:: Context > Features < T > {
130
150
/// Create a blank Features with no features set
131
151
pub fn empty ( ) -> Features < T > {
132
152
Features {
@@ -186,11 +206,13 @@ impl<T: FeatureContext> Features<T> {
186
206
}
187
207
}
188
208
189
- impl < T : FeatureContextInitNode > Features < T > {
209
+ impl < T : sealed :: DataLossProtect > Features < T > {
190
210
pub ( crate ) fn supports_data_loss_protect ( & self ) -> bool {
191
211
self . flags . len ( ) > 0 && ( self . flags [ 0 ] & 3 ) != 0
192
212
}
213
+ }
193
214
215
+ impl < T : sealed:: UpfrontShutdownScript > Features < T > {
194
216
pub ( crate ) fn supports_upfront_shutdown_script ( & self ) -> bool {
195
217
self . flags . len ( ) > 0 && ( self . flags [ 0 ] & ( 3 << 4 ) ) != 0
196
218
}
@@ -200,7 +222,7 @@ impl<T: FeatureContextInitNode> Features<T> {
200
222
}
201
223
}
202
224
203
- impl Features < FeatureContextInit > {
225
+ impl < T : sealed :: InitialRoutingSync > Features < T > {
204
226
pub ( crate ) fn initial_routing_sync ( & self ) -> bool {
205
227
self . flags . len ( ) > 0 && ( self . flags [ 0 ] & ( 1 << 3 ) ) != 0
206
228
}
@@ -211,34 +233,9 @@ impl Features<FeatureContextInit> {
211
233
self . flags [ 0 ] |= 1 << 3 ;
212
234
}
213
235
}
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
- }
239
236
}
240
237
241
- impl < T : FeatureContext > Writeable for Features < T > {
238
+ impl < T : sealed :: Context > Writeable for Features < T > {
242
239
fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , :: std:: io:: Error > {
243
240
w. size_hint ( self . flags . len ( ) + 2 ) ;
244
241
( self . flags . len ( ) as u16 ) . write ( w) ?;
@@ -249,7 +246,7 @@ impl<T: FeatureContext> Writeable for Features<T> {
249
246
}
250
247
}
251
248
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 > {
253
250
fn read ( r : & mut R ) -> Result < Self , DecodeError > {
254
251
let mut flags: Vec < u8 > = Readable :: read ( r) ?;
255
252
flags. reverse ( ) ; // Swap to little-endian
0 commit comments