@@ -151,3 +151,246 @@ func TestAccessManRestrictedSlots(t *testing.T) {
151
151
err = a .newPendingCloseChan (peerKey4 )
152
152
require .ErrorIs (t , err , ErrNoMoreRestrictedAccessSlots )
153
153
}
154
+
155
+ // TestAssignPeerPerms asserts that the peer's access status is correctly
156
+ // assigned.
157
+ func TestAssignPeerPerms (t * testing.T ) {
158
+ t .Parallel ()
159
+
160
+ // genPeerPub is a helper closure that generates a random public key.
161
+ genPeerPub := func () * btcec.PublicKey {
162
+ peerPriv , err := btcec .NewPrivateKey ()
163
+ require .NoError (t , err )
164
+
165
+ return peerPriv .PubKey ()
166
+ }
167
+
168
+ disconnect := func (_ * btcec.PublicKey ) (bool , error ) {
169
+ return true , nil
170
+ }
171
+
172
+ noDisconnect := func (_ * btcec.PublicKey ) (bool , error ) {
173
+ return false , nil
174
+ }
175
+
176
+ var testCases = []struct {
177
+ name string
178
+ peerPub * btcec.PublicKey
179
+ chanCount channeldb.ChanCount
180
+ shouldDisconnect func (* btcec.PublicKey ) (bool , error )
181
+ numRestricted int
182
+
183
+ expectedStatus peerAccessStatus
184
+ expectedErr error
185
+ }{
186
+ // peer1 has a channel with us, and we expect it to have a
187
+ // protected status.
188
+ {
189
+ name : "peer with channels" ,
190
+ peerPub : genPeerPub (),
191
+ chanCount : channeldb.ChanCount {
192
+ HasOpenOrClosedChan : true ,
193
+ },
194
+ shouldDisconnect : noDisconnect ,
195
+ expectedStatus : peerStatusProtected ,
196
+ expectedErr : nil ,
197
+ },
198
+ // peer2 has a channel open and a pending channel with us, we
199
+ // expect it to have a protected status.
200
+ {
201
+ name : "peer with channels and pending channels" ,
202
+ peerPub : genPeerPub (),
203
+ chanCount : channeldb.ChanCount {
204
+ HasOpenOrClosedChan : true ,
205
+ PendingOpenCount : 1 ,
206
+ },
207
+ shouldDisconnect : noDisconnect ,
208
+ expectedStatus : peerStatusProtected ,
209
+ expectedErr : nil ,
210
+ },
211
+ // peer3 has a pending channel with us, and we expect it to have
212
+ // a temporary status.
213
+ {
214
+ name : "peer with pending channels" ,
215
+ peerPub : genPeerPub (),
216
+ chanCount : channeldb.ChanCount {
217
+ HasOpenOrClosedChan : false ,
218
+ PendingOpenCount : 1 ,
219
+ },
220
+ shouldDisconnect : noDisconnect ,
221
+ expectedStatus : peerStatusTemporary ,
222
+ expectedErr : nil ,
223
+ },
224
+ // peer4 has no channel with us, and we expect it to have a
225
+ // restricted status.
226
+ {
227
+ name : "peer with no channels" ,
228
+ peerPub : genPeerPub (),
229
+ chanCount : channeldb.ChanCount {
230
+ HasOpenOrClosedChan : false ,
231
+ PendingOpenCount : 0 ,
232
+ },
233
+ shouldDisconnect : noDisconnect ,
234
+ expectedStatus : peerStatusRestricted ,
235
+ expectedErr : nil ,
236
+ },
237
+ // peer5 has no channel with us, and we expect it to have a
238
+ // restricted status. We also expect the error `ErrGossiperBan`
239
+ // to be returned given we will use a mocked `shouldDisconnect`
240
+ // in this test to disconnect on peer5 only.
241
+ {
242
+ name : "peer with no channels and banned" ,
243
+ peerPub : genPeerPub (),
244
+ chanCount : channeldb.ChanCount {
245
+ HasOpenOrClosedChan : false ,
246
+ PendingOpenCount : 0 ,
247
+ },
248
+ shouldDisconnect : disconnect ,
249
+ expectedStatus : peerStatusRestricted ,
250
+ expectedErr : ErrGossiperBan ,
251
+ },
252
+ // peer6 has no channel with us, and we expect it to have a
253
+ // restricted status. We also expect the error
254
+ // `ErrNoMoreRestrictedAccessSlots` to be returned given
255
+ // we only allow 1 restricted peer in this test.
256
+ {
257
+ name : "peer with no channels and restricted" ,
258
+ peerPub : genPeerPub (),
259
+ chanCount : channeldb.ChanCount {
260
+ HasOpenOrClosedChan : false ,
261
+ PendingOpenCount : 0 ,
262
+ },
263
+ shouldDisconnect : noDisconnect ,
264
+ numRestricted : 1 ,
265
+
266
+ expectedStatus : peerStatusRestricted ,
267
+ expectedErr : ErrNoMoreRestrictedAccessSlots ,
268
+ },
269
+ }
270
+
271
+ for _ , tc := range testCases {
272
+ t .Run (tc .name , func (t * testing.T ) {
273
+ t .Parallel ()
274
+
275
+ peerStr := string (tc .peerPub .SerializeCompressed ())
276
+
277
+ initPerms := func () (map [string ]channeldb.ChanCount ,
278
+ error ) {
279
+
280
+ return map [string ]channeldb.ChanCount {
281
+ peerStr : tc .chanCount ,
282
+ }, nil
283
+ }
284
+
285
+ cfg := & accessManConfig {
286
+ initAccessPerms : initPerms ,
287
+ shouldDisconnect : tc .shouldDisconnect ,
288
+ maxRestrictedSlots : 1 ,
289
+ }
290
+
291
+ a , err := newAccessMan (cfg )
292
+ require .NoError (t , err )
293
+
294
+ // Initialize the internal state of the accessman.
295
+ a .numRestricted = int64 (tc .numRestricted )
296
+
297
+ status , err := a .assignPeerPerms (tc .peerPub )
298
+ require .Equal (t , tc .expectedStatus , status )
299
+ require .ErrorIs (t , tc .expectedErr , err )
300
+ })
301
+ }
302
+ }
303
+
304
+ // TestAssignPeerPermsBypassRestriction asserts that when a peer has a channel
305
+ // with us, either it being open, pending, or closed, no restriction is placed
306
+ // on this peer.
307
+ func TestAssignPeerPermsBypassRestriction (t * testing.T ) {
308
+ t .Parallel ()
309
+
310
+ // genPeerPub is a helper closure that generates a random public key.
311
+ genPeerPub := func () * btcec.PublicKey {
312
+ peerPriv , err := btcec .NewPrivateKey ()
313
+ require .NoError (t , err )
314
+
315
+ return peerPriv .PubKey ()
316
+ }
317
+
318
+ // Mock shouldDisconnect to always return true and assert that it has no
319
+ // effect on the peer.
320
+ disconnect := func (_ * btcec.PublicKey ) (bool , error ) {
321
+ return true , nil
322
+ }
323
+
324
+ var testCases = []struct {
325
+ name string
326
+ peerPub * btcec.PublicKey
327
+ chanCount channeldb.ChanCount
328
+ expectedStatus peerAccessStatus
329
+ }{
330
+ // peer1 has a channel with us, and we expect it to have a
331
+ // protected status.
332
+ {
333
+ name : "peer with channels" ,
334
+ peerPub : genPeerPub (),
335
+ chanCount : channeldb.ChanCount {
336
+ HasOpenOrClosedChan : true ,
337
+ },
338
+ expectedStatus : peerStatusProtected ,
339
+ },
340
+ // peer2 has a channel open and a pending channel with us, we
341
+ // expect it to have a protected status.
342
+ {
343
+ name : "peer with channels and pending channels" ,
344
+ peerPub : genPeerPub (),
345
+ chanCount : channeldb.ChanCount {
346
+ HasOpenOrClosedChan : true ,
347
+ PendingOpenCount : 1 ,
348
+ },
349
+ expectedStatus : peerStatusProtected ,
350
+ },
351
+ // peer3 has a pending channel with us, and we expect it to have
352
+ // a temporary status.
353
+ {
354
+ name : "peer with pending channels" ,
355
+ peerPub : genPeerPub (),
356
+ chanCount : channeldb.ChanCount {
357
+ HasOpenOrClosedChan : false ,
358
+ PendingOpenCount : 1 ,
359
+ },
360
+ expectedStatus : peerStatusTemporary ,
361
+ },
362
+ }
363
+
364
+ for _ , tc := range testCases {
365
+ t .Run (tc .name , func (t * testing.T ) {
366
+ t .Parallel ()
367
+
368
+ peerStr := string (tc .peerPub .SerializeCompressed ())
369
+
370
+ initPerms := func () (map [string ]channeldb.ChanCount ,
371
+ error ) {
372
+
373
+ return map [string ]channeldb.ChanCount {
374
+ peerStr : tc .chanCount ,
375
+ }, nil
376
+ }
377
+
378
+ // Config the accessman such that it has zero max slots
379
+ // and always return true on `shouldDisconnect`. We
380
+ // should see the peers in this test are not affected by
381
+ // these checks.
382
+ cfg := & accessManConfig {
383
+ initAccessPerms : initPerms ,
384
+ shouldDisconnect : disconnect ,
385
+ maxRestrictedSlots : 0 ,
386
+ }
387
+
388
+ a , err := newAccessMan (cfg )
389
+ require .NoError (t , err )
390
+
391
+ status , err := a .assignPeerPerms (tc .peerPub )
392
+ require .NoError (t , err )
393
+ require .Equal (t , tc .expectedStatus , status )
394
+ })
395
+ }
396
+ }
0 commit comments