mirror of
https://github.com/PeernetOfficial/core.git
synced 2026-07-16 18:37:51 +01:00
Kademlia: Initial bucket refresh implementation. This might be improved down the road.
This commit is contained in:
@@ -98,7 +98,7 @@ func (peer *rootPeer) contact() {
|
||||
contactArbitraryPeer(peer.publicKey, peer.addresses)
|
||||
}
|
||||
|
||||
// bootstrap connects to the initial set of peers. It will also start the routine for ongoing sending of multicast/broadcast messages.
|
||||
// bootstrap connects to the initial set of peers.
|
||||
func bootstrap() {
|
||||
if len(rootPeers) == 0 {
|
||||
log.Printf("bootstrap warning: Empty list of root peers. Connectivity relies on local peer discovery and incoming connections.\n")
|
||||
|
||||
45
Kademlia.go
45
Kademlia.go
@@ -56,20 +56,43 @@ func initKademlia() {
|
||||
node.Info.(*PeerInfo).sendAnnouncementFindValue(request)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Refresh buckets every 5 minutes to meet the alpha nodes per bucket target. Force full refresh every hour.
|
||||
go func() {
|
||||
for minute := 5; ; minute += 5 {
|
||||
time.Sleep(time.Minute * 5)
|
||||
// autoBucketRefresh refreshes buckets every 5 minutes to meet the alpha nodes per bucket target. Force full refresh every hour.
|
||||
func autoBucketRefresh() {
|
||||
for minute := 5; ; minute += 5 {
|
||||
time.Sleep(time.Minute * 5)
|
||||
|
||||
target := alpha
|
||||
if minute%60 == 0 {
|
||||
target = 0
|
||||
}
|
||||
|
||||
nodesDHT.RefreshBuckets(target)
|
||||
target := alpha
|
||||
if minute%60 == 0 {
|
||||
target = 0
|
||||
}
|
||||
}()
|
||||
|
||||
nodesDHT.RefreshBuckets(target)
|
||||
}
|
||||
}
|
||||
|
||||
// bootstrapKademlia bootstraps the Kademlia bucket list
|
||||
func bootstrapKademlia() {
|
||||
monitor := make(chan *PeerInfo)
|
||||
registerPeerMonitor(monitor)
|
||||
|
||||
// Wait until there are at least 2 peers connected.
|
||||
for {
|
||||
<-monitor
|
||||
if nodesDHT.NumNodes() >= 2 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
unregisterPeerMonitor(monitor)
|
||||
|
||||
// Refresh every 10 seconds 3 times
|
||||
for n := 0; n < 3; n++ {
|
||||
nodesDHT.RefreshBuckets(alpha)
|
||||
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
// Future sendAnnouncementX: If it detects that announcements are sent out to the same peer within 50ms it should activate a wait-and-group scheme.
|
||||
|
||||
35
Peer ID.go
35
Peer ID.go
@@ -113,6 +113,14 @@ func PeerlistAdd(PublicKey *btcec.PublicKey, connections ...*Connection) (peer *
|
||||
// add to Kademlia
|
||||
nodesDHT.AddNode(&dht.Node{ID: peer.NodeID, Info: peer})
|
||||
|
||||
// send to all channels non-blocking
|
||||
for _, monitor := range peerMonitor {
|
||||
select {
|
||||
case monitor <- peer:
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
return peer, true
|
||||
}
|
||||
|
||||
@@ -201,3 +209,30 @@ func selfPeerRecord(network *Network) (result PeerRecord) {
|
||||
LastContact: 0,
|
||||
}
|
||||
}
|
||||
|
||||
var peerMonitor []chan<- *PeerInfo
|
||||
|
||||
// registerPeerMonitor registers a channel to receive all new peers
|
||||
func registerPeerMonitor(channel chan<- *PeerInfo) {
|
||||
peerlistMutex.Lock()
|
||||
defer peerlistMutex.Unlock()
|
||||
|
||||
peerMonitor = append(peerMonitor, channel)
|
||||
}
|
||||
|
||||
// unregisterPeerMonitor unregisters a channel
|
||||
func unregisterPeerMonitor(channel chan<- *PeerInfo) {
|
||||
peerlistMutex.Lock()
|
||||
defer peerlistMutex.Unlock()
|
||||
|
||||
for n, channel2 := range peerMonitor {
|
||||
if channel == channel2 {
|
||||
peerMonitorNew := peerMonitor[:n]
|
||||
if n < len(peerMonitor)-1 {
|
||||
peerMonitorNew = append(peerMonitorNew, peerMonitor[n+1:]...)
|
||||
}
|
||||
peerMonitor = peerMonitorNew
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,10 @@ func Init() {
|
||||
|
||||
// Connect starts bootstrapping and local peer discovery.
|
||||
func Connect() {
|
||||
go bootstrapKademlia()
|
||||
go bootstrap()
|
||||
go autoMulticastBroadcast()
|
||||
go autoPingAll()
|
||||
go networkChangeMonitor()
|
||||
go autoBucketRefresh()
|
||||
}
|
||||
|
||||
@@ -83,6 +83,8 @@ The Private Key is required to make any changes to the user's blockchain, includ
|
||||
* Check every 10 seconds for new/removed network interfaces and for new/removed IPs.
|
||||
* Automatically listen on any newly detected network interfaces and IPs.
|
||||
* Start a full Kademlia bucket refresh in case of a new network interface or IP.
|
||||
* Kademlia bootstrap:
|
||||
* As soon as there are at least 2 peers, keep refreshing buckets (target number is alpha) every 10 seconds 3 times.
|
||||
|
||||
### Ping
|
||||
|
||||
|
||||
2
go.mod
2
go.mod
@@ -3,7 +3,7 @@ module github.com/PeernetOfficial/core
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/PeernetOfficial/core/dht v0.0.0-20210424204239-6693d442a6e2
|
||||
github.com/PeernetOfficial/core/dht v0.0.0-20210425014452-611dfa3b1ce9
|
||||
github.com/btcsuite/btcd v0.21.0-beta.0.20210401013323-36a96f6a0025
|
||||
github.com/pkg/errors v0.9.1
|
||||
golang.org/x/crypto v0.0.0-20210415154028-4f45737414dc
|
||||
|
||||
4
go.sum
4
go.sum
@@ -1,5 +1,5 @@
|
||||
github.com/PeernetOfficial/core/dht v0.0.0-20210424204239-6693d442a6e2 h1:h4EP52078qatwYoW1DztuQhg5Y8i9wwDbkdO92usM+o=
|
||||
github.com/PeernetOfficial/core/dht v0.0.0-20210424204239-6693d442a6e2/go.mod h1:sb2H21VIVTohCXVrDFo/Skl2tN8Yzba+MXSS6NgCYXw=
|
||||
github.com/PeernetOfficial/core/dht v0.0.0-20210425014452-611dfa3b1ce9 h1:kcjoWZl9GZ9uSajS6t0tiKDpaatUQ64tl3OqXPc+YsY=
|
||||
github.com/PeernetOfficial/core/dht v0.0.0-20210425014452-611dfa3b1ce9/go.mod h1:sb2H21VIVTohCXVrDFo/Skl2tN8Yzba+MXSS6NgCYXw=
|
||||
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
|
||||
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
|
||||
github.com/btcsuite/btcd v0.21.0-beta.0.20210401013323-36a96f6a0025 h1:aoVqvZk4mLyF3WZbqEVPq+vXnwL2wekZg4P4mjYJNLs=
|
||||
|
||||
Reference in New Issue
Block a user