@@ -3,16 +3,22 @@ package dht
3
3
import (
4
4
"context"
5
5
"crypto/rand"
6
- "github.com/libp2p/go-libp2p-core/test"
7
6
"testing"
8
7
"time"
9
8
9
+ "github.com/ipfs/go-cid"
10
+ "github.com/libp2p/go-libp2p-core/test"
11
+ "github.com/multiformats/go-multihash"
12
+ "github.com/stretchr/testify/assert"
13
+
14
+ ds "github.com/ipfs/go-datastore"
10
15
u "github.com/ipfs/go-ipfs-util"
11
16
ci "github.com/libp2p/go-libp2p-core/crypto"
12
17
"github.com/libp2p/go-libp2p-core/peer"
13
18
"github.com/libp2p/go-libp2p-core/routing"
14
- record "github.com/libp2p/go-libp2p-record"
15
- tnet "github.com/libp2p/go-libp2p-testing/net"
19
+ pb "github.com/libp2p/go-libp2p-kad-dht/pb"
20
+ "github.com/libp2p/go-libp2p-record"
21
+ "github.com/libp2p/go-libp2p-testing/net"
16
22
)
17
23
18
24
// Check that GetPublicKey() correctly extracts a public key
@@ -305,3 +311,97 @@ func TestPubkeyGoodKeyFromDHTGoodKeyDirect(t *testing.T) {
305
311
t .Fatal ("got incorrect public key" )
306
312
}
307
313
}
314
+
315
+ func TestExpireNonProviderRecords (t * testing.T ) {
316
+ sVal := defaultRecordsSweepInterval
317
+ defer func () { defaultRecordsSweepInterval = sVal }()
318
+
319
+ defaultRecordsSweepInterval = 20 * time .Millisecond
320
+
321
+ // create dht
322
+ ctx , cancel := context .WithCancel (context .Background ())
323
+ defer cancel ()
324
+ d := setupDHT (ctx , t , false )
325
+
326
+ putRecord := func (key string , value []byte ) error {
327
+ rec := record .MakePutRecord (key , value )
328
+ pmes := pb .NewMessage (pb .Message_PUT_VALUE , rec .Key , 0 )
329
+ pmes .Record = rec
330
+ _ , err := d .handlePutValue (ctx , "testpeer" , pmes )
331
+ return err
332
+ }
333
+
334
+ addProv := func (c cid.Cid ) error {
335
+ msg , err := d .makeProvRecord (c )
336
+ pi := peer.AddrInfo {
337
+ ID : "testpeer" ,
338
+ Addrs : d .host .Addrs (),
339
+ }
340
+ msg .ProviderPeers = pb .RawPeerInfosToPBPeers ([]peer.AddrInfo {pi })
341
+ assert .NoError (t , err )
342
+
343
+ _ , err = d .handleAddProvider (ctx , "testpeer" , msg )
344
+ return err
345
+ }
346
+
347
+ getProv := func (c cid.Cid ) (* pb.Message , error ) {
348
+ pmes := pb .NewMessage (pb .Message_GET_PROVIDERS , c .Bytes (), 0 )
349
+ m , err := d .handleGetProviders (ctx , "test peer" , pmes )
350
+ return m , err
351
+ }
352
+
353
+ // put non-provider record 1 with current time
354
+ key1 := "/v/key1"
355
+ value1 := []byte ("v1" )
356
+ assert .NoError (t , putRecord (key1 , value1 ))
357
+
358
+ // put non-provider record 2 with current time
359
+ key2 := "/v/key2"
360
+ value2 := []byte ("v2" )
361
+ assert .NoError (t , putRecord (key2 , value2 ))
362
+
363
+ // add provider with current time
364
+ mh , err := multihash .Sum ([]byte ("data" ), multihash .SHA2_256 , - 1 )
365
+ assert .NoError (t , err )
366
+ c := cid .NewCidV0 (mh )
367
+ assert .NoError (t , addProv (c ))
368
+
369
+ // sweep will not delete any of them
370
+ time .Sleep (100 * time .Millisecond )
371
+
372
+ // get & verify all are present
373
+
374
+ // we need to check the datastore for non-provider records to test the expiry Proc
375
+ // because a side-effect of handle get value is also that it deletes records which are beyond MaxAge
376
+ // & we do not want to hit that path
377
+ _ , err = d .datastore .Get (convertToDsKey ([]byte (key1 )))
378
+ assert .NoError (t , err )
379
+
380
+ _ , err = d .datastore .Get (convertToDsKey ([]byte (key2 )))
381
+ assert .NoError (t , err )
382
+
383
+ // ensure provider record is still available
384
+ m , err := getProv (c )
385
+ assert .NoError (t , err )
386
+ assert .NotEmpty (t , m .ProviderPeers )
387
+
388
+ // change max age to 100 millisecond
389
+ mVal := maxNonProviderRecordAge
390
+ maxNonProviderRecordAge = 100 * time .Millisecond
391
+ defer func () { maxNonProviderRecordAge = mVal }()
392
+
393
+ // sweep will remove non-provider both records now
394
+ time .Sleep (100 * time .Millisecond )
395
+
396
+ // verify both non-provider records are absent
397
+ _ , err = d .datastore .Get (convertToDsKey ([]byte (key1 )))
398
+ assert .Equal (t , ds .ErrNotFound , err )
399
+
400
+ _ , err = d .datastore .Get (convertToDsKey ([]byte (key2 )))
401
+ assert .Equal (t , ds .ErrNotFound , err )
402
+
403
+ // but, provider record will still be available
404
+ m , err = getProv (c )
405
+ assert .NoError (t , err )
406
+ assert .NotEmpty (t , m .ProviderPeers )
407
+ }
0 commit comments