aboutsummaryrefslogtreecommitdiffstats
path: root/p2p
diff options
context:
space:
mode:
Diffstat (limited to 'p2p')
-rw-r--r--p2p/discover/node.go33
-rw-r--r--p2p/discover/table.go10
2 files changed, 38 insertions, 5 deletions
diff --git a/p2p/discover/node.go b/p2p/discover/node.go
index 3e79ddb53..0ec9630d3 100644
--- a/p2p/discover/node.go
+++ b/p2p/discover/node.go
@@ -325,12 +325,13 @@ func newNodeDB(path string, version int64) (db *nodeDB, err error) {
if path == "" {
db.ldb, err = leveldb.Open(storage.NewMemStorage(), opts)
} else {
- db.ldb, err = openLDB(path, opts, version)
+ db.ldb, err = openNodeDB(path, opts, version)
}
return db, err
}
-func openLDB(path string, opts *opt.Options, version int64) (*leveldb.DB, error) {
+// openNodeDB opens a persistent seed cache, flushing old versions.
+func openNodeDB(path string, opts *opt.Options, version int64) (*leveldb.DB, error) {
ldb, err := leveldb.OpenFile(path, opts)
if _, iscorrupted := err.(leveldb.ErrCorrupted); iscorrupted {
ldb, err = leveldb.RecoverFile(path, opts)
@@ -353,7 +354,7 @@ func openLDB(path string, opts *opt.Options, version int64) (*leveldb.DB, error)
if err = os.RemoveAll(path); err != nil {
return nil, err
}
- return openLDB(path, opts, version)
+ return openNodeDB(path, opts, version)
}
if err != nil {
ldb.Close()
@@ -362,6 +363,7 @@ func openLDB(path string, opts *opt.Options, version int64) (*leveldb.DB, error)
return ldb, err
}
+// get retrieves a node with a given id from the seed da
func (db *nodeDB) get(id NodeID) *Node {
v, err := db.ldb.Get(id[:], nil)
if err != nil {
@@ -374,6 +376,24 @@ func (db *nodeDB) get(id NodeID) *Node {
return n
}
+// list retrieves a batch of nodes from the database.
+func (db *nodeDB) list(n int) []*Node {
+ it := db.ldb.NewIterator(nil, nil)
+ defer it.Release()
+
+ nodes := make([]*Node, 0, n)
+ for i := 0; i < n && it.Next(); i++ {
+ var id NodeID
+ copy(id[:], it.Key())
+
+ if node := db.get(id); node != nil {
+ nodes = append(nodes, node)
+ }
+ }
+ return nodes
+}
+
+// update inserts - potentially overwriting - a node in the seed database.
func (db *nodeDB) update(n *Node) error {
v, err := rlp.EncodeToBytes(n)
if err != nil {
@@ -382,12 +402,19 @@ func (db *nodeDB) update(n *Node) error {
return db.ldb.Put(n.ID[:], v, nil)
}
+// add inserts a new node into the seed database.
func (db *nodeDB) add(id NodeID, addr *net.UDPAddr, tcpPort uint16) *Node {
n := &Node{ID: id, IP: addr.IP, DiscPort: addr.Port, TCPPort: int(tcpPort)}
db.update(n)
return n
}
+// delete removes a node from the database.
+func (db *nodeDB) delete(id NodeID) error {
+ return db.ldb.Delete(id[:], nil)
+}
+
+// close flushes and closes the database files.
func (db *nodeDB) close() {
db.ldb.Close()
}
diff --git a/p2p/discover/table.go b/p2p/discover/table.go
index 3702a2114..fa791c9f3 100644
--- a/p2p/discover/table.go
+++ b/p2p/discover/table.go
@@ -177,8 +177,14 @@ func (tab *Table) refresh() {
result := tab.Lookup(randomID(tab.self.ID, ld))
if len(result) == 0 {
- // bootstrap the table with a self lookup
- all := tab.bondall(tab.nursery)
+ // Pick a batch of previously know seeds to lookup with and discard them (will come back if they are still live)
+ seeds := tab.db.list(10)
+ for _, seed := range seeds {
+ glog.V(logger.Debug).Infoln("Seeding network with:", seed)
+ tab.db.delete(seed.ID)
+ }
+ // Bootstrap the table with a self lookup
+ all := tab.bondall(append(tab.nursery, seeds...))
tab.mutex.Lock()
tab.add(all)
tab.mutex.Unlock()