Kademlia: Initial bucket refresh implementation. This might be improved down the road.

This commit is contained in:
Kleissner
2021-04-25 04:22:10 +02:00
parent 611dfa3b1c
commit f13695709f
7 changed files with 77 additions and 15 deletions

View File

@@ -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")

View File

@@ -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.

View File

@@ -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
}
}
}

View File

@@ -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()
}

View File

@@ -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
View File

@@ -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
View File

@@ -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=