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