forked from cerc-io/plugeth
p2p/discover: parametrize nodedb version, add persistency tests
This commit is contained in:
parent
75fd738dea
commit
a136e2bb22
@ -39,11 +39,11 @@ var (
|
||||
// newNodeDB creates a new node database for storing and retrieving infos about
|
||||
// known peers in the network. If no path is given, an in-memory, temporary
|
||||
// database is constructed.
|
||||
func newNodeDB(path string) (*nodeDB, error) {
|
||||
func newNodeDB(path string, version int) (*nodeDB, error) {
|
||||
if path == "" {
|
||||
return newMemoryNodeDB()
|
||||
}
|
||||
return newPersistentNodeDB(path)
|
||||
return newPersistentNodeDB(path, version)
|
||||
}
|
||||
|
||||
// newMemoryNodeDB creates a new in-memory node database without a persistent
|
||||
@ -58,7 +58,7 @@ func newMemoryNodeDB() (*nodeDB, error) {
|
||||
|
||||
// newPersistentNodeDB creates/opens a leveldb backed persistent node database,
|
||||
// also flushing its contents in case of a version mismatch.
|
||||
func newPersistentNodeDB(path string) (*nodeDB, error) {
|
||||
func newPersistentNodeDB(path string, version int) (*nodeDB, error) {
|
||||
// Try to open the cache, recovering any corruption
|
||||
db, err := leveldb.OpenFile(path, nil)
|
||||
if _, iscorrupted := err.(leveldb.ErrCorrupted); iscorrupted {
|
||||
@ -70,7 +70,7 @@ func newPersistentNodeDB(path string) (*nodeDB, error) {
|
||||
// The nodes contained in the cache correspond to a certain protocol version.
|
||||
// Flush all nodes if the version doesn't match.
|
||||
currentVer := make([]byte, binary.MaxVarintLen64)
|
||||
currentVer = currentVer[:binary.PutVarint(currentVer, Version)]
|
||||
currentVer = currentVer[:binary.PutVarint(currentVer, int64(version))]
|
||||
|
||||
blob, err := db.Get(nodeDBVersionKey, nil)
|
||||
switch err {
|
||||
@ -88,7 +88,7 @@ func newPersistentNodeDB(path string) (*nodeDB, error) {
|
||||
if err = os.RemoveAll(path); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newPersistentNodeDB(path)
|
||||
return newPersistentNodeDB(path, version)
|
||||
}
|
||||
}
|
||||
return &nodeDB{lvl: db}, nil
|
||||
|
@ -2,7 +2,10 @@ package discover
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
@ -59,7 +62,8 @@ var nodeDBInt64Tests = []struct {
|
||||
}
|
||||
|
||||
func TestNodeDBInt64(t *testing.T) {
|
||||
db, _ := newNodeDB("")
|
||||
db, _ := newNodeDB("", Version)
|
||||
defer db.close()
|
||||
|
||||
tests := nodeDBInt64Tests
|
||||
for i := 0; i < len(tests); i++ {
|
||||
@ -87,7 +91,9 @@ func TestNodeDBFetchStore(t *testing.T) {
|
||||
TCPPort: 30303,
|
||||
}
|
||||
inst := time.Now()
|
||||
db, _ := newNodeDB("")
|
||||
|
||||
db, _ := newNodeDB("", Version)
|
||||
defer db.close()
|
||||
|
||||
// Check fetch/store operations on a node ping object
|
||||
if stored := db.lastPing(node.ID); stored.Unix() != 0 {
|
||||
@ -151,7 +157,8 @@ var nodeDBSeedQueryNodes = []struct {
|
||||
}
|
||||
|
||||
func TestNodeDBSeedQuery(t *testing.T) {
|
||||
db, _ := newNodeDB("")
|
||||
db, _ := newNodeDB("", Version)
|
||||
defer db.close()
|
||||
|
||||
// Insert a batch of nodes for querying
|
||||
for i, seed := range nodeDBSeedQueryNodes {
|
||||
@ -190,7 +197,8 @@ func TestNodeDBSeedQuery(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNodeDBSeedQueryContinuation(t *testing.T) {
|
||||
db, _ := newNodeDB("")
|
||||
db, _ := newNodeDB("", Version)
|
||||
defer db.close()
|
||||
|
||||
// Insert a batch of nodes for querying
|
||||
for i, seed := range nodeDBSeedQueryNodes {
|
||||
@ -213,3 +221,46 @@ func TestNodeDBSeedQueryContinuation(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNodeDBPersistency(t *testing.T) {
|
||||
root, err := ioutil.TempDir("", "nodedb-")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create temporary data folder: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(root)
|
||||
|
||||
var (
|
||||
testKey = []byte("somekey")
|
||||
testInt = int64(314)
|
||||
)
|
||||
|
||||
// Create a persistent database and store some values
|
||||
db, err := newNodeDB(filepath.Join("root", "database"), Version)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create persistent database: %v", err)
|
||||
}
|
||||
if err := db.storeInt64(testKey, testInt); err != nil {
|
||||
t.Fatalf("failed to store value: %v.", err)
|
||||
}
|
||||
db.close()
|
||||
|
||||
// Reopen the database and check the value
|
||||
db, err = newNodeDB(filepath.Join("root", "database"), Version)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to open persistent database: %v", err)
|
||||
}
|
||||
if val := db.fetchInt64(testKey); val != testInt {
|
||||
t.Fatalf("value mismatch: have %v, want %v", val, testInt)
|
||||
}
|
||||
db.close()
|
||||
|
||||
// Change the database version and check flush
|
||||
db, err = newNodeDB(filepath.Join("root", "database"), Version+1)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to open persistent database: %v", err)
|
||||
}
|
||||
if val := db.fetchInt64(testKey); val != 0 {
|
||||
t.Fatalf("value mismatch: have %v, want %v", val, 0)
|
||||
}
|
||||
db.close()
|
||||
}
|
||||
|
@ -63,10 +63,10 @@ type bucket struct {
|
||||
|
||||
func newTable(t transport, ourID NodeID, ourAddr *net.UDPAddr, nodeDBPath string) *Table {
|
||||
// If no node database was given, use an in-memory one
|
||||
db, err := newNodeDB(nodeDBPath)
|
||||
db, err := newNodeDB(nodeDBPath, Version)
|
||||
if err != nil {
|
||||
glog.V(logger.Warn).Infoln("Failed to open node database:", err)
|
||||
db, _ = newNodeDB("")
|
||||
db, _ = newNodeDB("", Version)
|
||||
}
|
||||
tab := &Table{
|
||||
net: t,
|
||||
|
Loading…
Reference in New Issue
Block a user