go-libp2p-kad-dht/records_test.go
2018-08-07 18:50:04 -07:00

327 lines
7.1 KiB
Go

package dht
import (
"context"
"crypto/rand"
"testing"
"time"
u "github.com/ipfs/go-ipfs-util"
ci "github.com/libp2p/go-libp2p-crypto"
peer "github.com/libp2p/go-libp2p-peer"
record "github.com/libp2p/go-libp2p-record"
routing "github.com/libp2p/go-libp2p-routing"
)
// Check that GetPublicKey() correctly extracts a public key
func TestPubkeyExtract(t *testing.T) {
ctx := context.Background()
dht := setupDHT(ctx, t, false)
defer dht.Close()
_, pk, err := ci.GenerateEd25519Key(rand.Reader)
if err != nil {
t.Fatal(err)
}
pid, err := peer.IDFromPublicKey(pk)
if err != nil {
t.Fatal(err)
}
pkOut, err := dht.GetPublicKey(context.Background(), pid)
if err != nil {
t.Fatal(err)
}
if !pkOut.Equals(pk) {
t.Fatal("got incorrect public key out")
}
}
// Check that GetPublicKey() correctly retrieves a public key from the peerstore
func TestPubkeyPeerstore(t *testing.T) {
ctx := context.Background()
dht := setupDHT(ctx, t, false)
r := u.NewSeededRand(15) // generate deterministic keypair
_, pubk, err := ci.GenerateKeyPairWithReader(ci.RSA, 1024, r)
if err != nil {
t.Fatal(err)
}
id, err := peer.IDFromPublicKey(pubk)
if err != nil {
t.Fatal(err)
}
err = dht.peerstore.AddPubKey(id, pubk)
if err != nil {
t.Fatal(err)
}
rpubk, err := dht.GetPublicKey(context.Background(), id)
if err != nil {
t.Fatal(err)
}
if !pubk.Equals(rpubk) {
t.Fatal("got incorrect public key")
}
}
// Check that GetPublicKey() correctly retrieves a public key directly
// from the node it identifies
func TestPubkeyDirectFromNode(t *testing.T) {
ctx := context.Background()
dhtA := setupDHT(ctx, t, false)
dhtB := setupDHT(ctx, t, false)
defer dhtA.Close()
defer dhtB.Close()
defer dhtA.host.Close()
defer dhtB.host.Close()
connect(t, ctx, dhtA, dhtB)
pubk, err := dhtA.GetPublicKey(context.Background(), dhtB.self)
if err != nil {
t.Fatal(err)
}
id, err := peer.IDFromPublicKey(pubk)
if err != nil {
t.Fatal(err)
}
if id != dhtB.self {
t.Fatal("got incorrect public key")
}
}
// Check that GetPublicKey() correctly retrieves a public key
// from the DHT
func TestPubkeyFromDHT(t *testing.T) {
ctx := context.Background()
dhtA := setupDHT(ctx, t, false)
dhtB := setupDHT(ctx, t, false)
defer dhtA.Close()
defer dhtB.Close()
defer dhtA.host.Close()
defer dhtB.host.Close()
connect(t, ctx, dhtA, dhtB)
r := u.NewSeededRand(15) // generate deterministic keypair
_, pubk, err := ci.GenerateKeyPairWithReader(ci.RSA, 1024, r)
if err != nil {
t.Fatal(err)
}
id, err := peer.IDFromPublicKey(pubk)
if err != nil {
t.Fatal(err)
}
pkkey := routing.KeyForPublicKey(id)
pkbytes, err := pubk.Bytes()
if err != nil {
t.Fatal(err)
}
// Store public key on node B
err = dhtB.PutValue(ctx, pkkey, pkbytes)
if err != nil {
t.Fatal(err)
}
// Retrieve public key on node A
rpubk, err := dhtA.GetPublicKey(ctx, id)
if err != nil {
t.Fatal(err)
}
if !pubk.Equals(rpubk) {
t.Fatal("got incorrect public key")
}
}
// Check that GetPublicKey() correctly returns an error when the
// public key is not available directly from the node or on the DHT
func TestPubkeyNotFound(t *testing.T) {
ctx := context.Background()
dhtA := setupDHT(ctx, t, false)
dhtB := setupDHT(ctx, t, false)
defer dhtA.Close()
defer dhtB.Close()
defer dhtA.host.Close()
defer dhtB.host.Close()
connect(t, ctx, dhtA, dhtB)
r := u.NewSeededRand(15) // generate deterministic keypair
_, pubk, err := ci.GenerateKeyPairWithReader(ci.RSA, 1024, r)
if err != nil {
t.Fatal(err)
}
id, err := peer.IDFromPublicKey(pubk)
if err != nil {
t.Fatal(err)
}
// Attempt to retrieve public key on node A (should be not found)
_, err = dhtA.GetPublicKey(ctx, id)
if err == nil {
t.Fatal("Expected not found error")
}
}
// Check that GetPublicKey() returns an error when
// the DHT returns the wrong key
func TestPubkeyBadKeyFromDHT(t *testing.T) {
ctx := context.Background()
dhtA := setupDHT(ctx, t, false)
dhtB := setupDHT(ctx, t, false)
defer dhtA.Close()
defer dhtB.Close()
defer dhtA.host.Close()
defer dhtB.host.Close()
connect(t, ctx, dhtA, dhtB)
r := u.NewSeededRand(15) // generate deterministic keypair
_, pubk, err := ci.GenerateKeyPairWithReader(ci.RSA, 1024, r)
if err != nil {
t.Fatal(err)
}
id, err := peer.IDFromPublicKey(pubk)
if err != nil {
t.Fatal(err)
}
pkkey := routing.KeyForPublicKey(id)
_, wrongpubk, err := ci.GenerateKeyPairWithReader(ci.RSA, 1024, r)
if err != nil {
t.Fatal(err)
}
if pubk == wrongpubk {
t.Fatal("Public keys shouldn't match here")
}
wrongbytes, err := wrongpubk.Bytes()
if err != nil {
t.Fatal(err)
}
// Store incorrect public key on node B
rec := record.MakePutRecord(pkkey, wrongbytes)
rec.TimeReceived = u.FormatRFC3339(time.Now())
err = dhtB.putLocal(pkkey, rec)
if err != nil {
t.Fatal(err)
}
// Retrieve public key from node A
_, err = dhtA.GetPublicKey(ctx, id)
if err == nil {
t.Fatal("Expected error because public key is incorrect")
}
}
// Check that GetPublicKey() returns the correct value
// when the DHT returns the wrong key but the direct
// connection returns the correct key
func TestPubkeyBadKeyFromDHTGoodKeyDirect(t *testing.T) {
ctx := context.Background()
dhtA := setupDHT(ctx, t, false)
dhtB := setupDHT(ctx, t, false)
defer dhtA.Close()
defer dhtB.Close()
defer dhtA.host.Close()
defer dhtB.host.Close()
connect(t, ctx, dhtA, dhtB)
r := u.NewSeededRand(15) // generate deterministic keypair
pkkey := routing.KeyForPublicKey(dhtB.self)
_, wrongpubk, err := ci.GenerateKeyPairWithReader(ci.RSA, 1024, r)
if err != nil {
t.Fatal(err)
}
wrongbytes, err := wrongpubk.Bytes()
if err != nil {
t.Fatal(err)
}
// Store incorrect public key on node B
rec := record.MakePutRecord(pkkey, wrongbytes)
rec.TimeReceived = u.FormatRFC3339(time.Now())
err = dhtB.putLocal(pkkey, rec)
if err != nil {
t.Fatal(err)
}
// Retrieve public key from node A
pubk, err := dhtA.GetPublicKey(ctx, dhtB.self)
if err != nil {
t.Fatal(err)
}
id, err := peer.IDFromPublicKey(pubk)
if err != nil {
t.Fatal(err)
}
// The incorrect public key retrieved from the DHT
// should be ignored in favour of the correct public
// key retieved from the node directly
if id != dhtB.self {
t.Fatal("got incorrect public key")
}
}
// Check that GetPublicKey() returns the correct value
// when both the DHT returns the correct key and the direct
// connection returns the correct key
func TestPubkeyGoodKeyFromDHTGoodKeyDirect(t *testing.T) {
ctx := context.Background()
dhtA := setupDHT(ctx, t, false)
dhtB := setupDHT(ctx, t, false)
defer dhtA.Close()
defer dhtB.Close()
defer dhtA.host.Close()
defer dhtB.host.Close()
connect(t, ctx, dhtA, dhtB)
pubk := dhtB.peerstore.PubKey(dhtB.self)
pkbytes, err := pubk.Bytes()
if err != nil {
t.Fatal(err)
}
// Store public key on node B
pkkey := routing.KeyForPublicKey(dhtB.self)
err = dhtB.PutValue(ctx, pkkey, pkbytes)
if err != nil {
t.Fatal(err)
}
// Retrieve public key on node A
rpubk, err := dhtA.GetPublicKey(ctx, dhtB.self)
if err != nil {
t.Fatal(err)
}
if !pubk.Equals(rpubk) {
t.Fatal("got incorrect public key")
}
}