p2p/discovery: use the seed table for finding nodes, auto drop stale ones
This commit is contained in:
parent
5f735d6fce
commit
af923c965f
@ -325,12 +325,13 @@ func newNodeDB(path string, version int64) (db *nodeDB, err error) {
|
|||||||
if path == "" {
|
if path == "" {
|
||||||
db.ldb, err = leveldb.Open(storage.NewMemStorage(), opts)
|
db.ldb, err = leveldb.Open(storage.NewMemStorage(), opts)
|
||||||
} else {
|
} else {
|
||||||
db.ldb, err = openLDB(path, opts, version)
|
db.ldb, err = openNodeDB(path, opts, version)
|
||||||
}
|
}
|
||||||
return db, err
|
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)
|
ldb, err := leveldb.OpenFile(path, opts)
|
||||||
if _, iscorrupted := err.(leveldb.ErrCorrupted); iscorrupted {
|
if _, iscorrupted := err.(leveldb.ErrCorrupted); iscorrupted {
|
||||||
ldb, err = leveldb.RecoverFile(path, opts)
|
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 {
|
if err = os.RemoveAll(path); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return openLDB(path, opts, version)
|
return openNodeDB(path, opts, version)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ldb.Close()
|
ldb.Close()
|
||||||
@ -362,6 +363,7 @@ func openLDB(path string, opts *opt.Options, version int64) (*leveldb.DB, error)
|
|||||||
return ldb, err
|
return ldb, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get retrieves a node with a given id from the seed da
|
||||||
func (db *nodeDB) get(id NodeID) *Node {
|
func (db *nodeDB) get(id NodeID) *Node {
|
||||||
v, err := db.ldb.Get(id[:], nil)
|
v, err := db.ldb.Get(id[:], nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -374,6 +376,24 @@ func (db *nodeDB) get(id NodeID) *Node {
|
|||||||
return n
|
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 {
|
func (db *nodeDB) update(n *Node) error {
|
||||||
v, err := rlp.EncodeToBytes(n)
|
v, err := rlp.EncodeToBytes(n)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -382,12 +402,19 @@ func (db *nodeDB) update(n *Node) error {
|
|||||||
return db.ldb.Put(n.ID[:], v, nil)
|
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 {
|
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)}
|
n := &Node{ID: id, IP: addr.IP, DiscPort: addr.Port, TCPPort: int(tcpPort)}
|
||||||
db.update(n)
|
db.update(n)
|
||||||
return 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() {
|
func (db *nodeDB) close() {
|
||||||
db.ldb.Close()
|
db.ldb.Close()
|
||||||
}
|
}
|
||||||
|
@ -177,8 +177,14 @@ func (tab *Table) refresh() {
|
|||||||
|
|
||||||
result := tab.Lookup(randomID(tab.self.ID, ld))
|
result := tab.Lookup(randomID(tab.self.ID, ld))
|
||||||
if len(result) == 0 {
|
if len(result) == 0 {
|
||||||
// bootstrap the table with a self lookup
|
// Pick a batch of previously know seeds to lookup with and discard them (will come back if they are still live)
|
||||||
all := tab.bondall(tab.nursery)
|
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.mutex.Lock()
|
||||||
tab.add(all)
|
tab.add(all)
|
||||||
tab.mutex.Unlock()
|
tab.mutex.Unlock()
|
||||||
|
Loading…
Reference in New Issue
Block a user