Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
p2p
go-p2p-kad-dht
Commits
3d294c7a
Unverified
Commit
3d294c7a
authored
May 24, 2020
by
Steven Allen
Committed by
GitHub
May 24, 2020
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #634 from libp2p/fix/protect-useful-peers
fix: protect useful peers in low buckets
parents
c38060f4
6c1d38bc
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
55 additions
and
12 deletions
+55
-12
dht.go
dht.go
+37
-11
query.go
query.go
+18
-1
No files found.
dht.go
View file @
3d294c7a
...
...
@@ -42,9 +42,23 @@ var (
baseLogger
=
logger
.
Desugar
()
)
// BaseConnMgrScore is the base of the score set on the connection manager "kbucket" tag.
// It is added with the common prefix length between two peer IDs.
const
BaseConnMgrScore
=
5
const
(
// BaseConnMgrScore is the base of the score set on the connection
// manager "kbucket" tag. It is added with the common prefix length
// between two peer IDs.
baseConnMgrScore
=
5
// UsefulConnMgrScore is given to peers that are among the first peers
// to respond to a query.
//
// This score is given to peers the first time they're useful and lasts
// until we disconnect from the peer.
usefulConnMgrScore
=
20
// UsefulConnMgrProtectedBuckets is the number of buckets where useful
// peers are _protected_, instead of just given the useful score.
usefulConnMgrProtectedBuckets
=
2
)
type
mode
int
...
...
@@ -58,11 +72,17 @@ const (
kad2
protocol
.
ID
=
"/kad/2.0.0"
)
const
(
dhtUsefulTag
=
"dht-useful"
kbucketTag
=
"kbucket"
)
// IpfsDHT is an implementation of Kademlia with S/Kademlia modifications.
// It is used to implement the base Routing module.
type
IpfsDHT
struct
{
host
host
.
Host
// the network services we need
self
peer
.
ID
// Local peer (yourself)
host
host
.
Host
// the network services we need
self
peer
.
ID
// Local peer (yourself)
selfKey
kb
.
ID
peerstore
peerstore
.
Peerstore
// Peer Registry
datastore
ds
.
Datastore
// Local data
...
...
@@ -250,6 +270,7 @@ func makeDHT(ctx context.Context, h host.Host, cfg config) (*IpfsDHT, error) {
dht
:=
&
IpfsDHT
{
datastore
:
cfg
.
datastore
,
self
:
h
.
ID
(),
selfKey
:
kb
.
ConvertPeerID
(
h
.
ID
()),
peerstore
:
h
.
Peerstore
(),
host
:
h
,
strmap
:
make
(
map
[
peer
.
ID
]
*
messageSender
),
...
...
@@ -337,17 +358,22 @@ func makeRtRefreshManager(dht *IpfsDHT, cfg config, maxLastSuccessfulOutboundThr
}
func
makeRoutingTable
(
dht
*
IpfsDHT
,
cfg
config
,
maxLastSuccessfulOutboundThreshold
time
.
Duration
)
(
*
kb
.
RoutingTable
,
error
)
{
self
:=
kb
.
ConvertPeerID
(
dht
.
host
.
ID
())
rt
,
err
:=
kb
.
NewRoutingTable
(
cfg
.
bucketSize
,
self
,
time
.
Minute
,
dht
.
host
.
Peerstore
(),
maxLastSuccessfulOutboundThreshold
)
rt
,
err
:=
kb
.
NewRoutingTable
(
cfg
.
bucketSize
,
dht
.
selfKey
,
time
.
Minute
,
dht
.
host
.
Peerstore
(),
maxLastSuccessfulOutboundThreshold
)
cmgr
:=
dht
.
host
.
ConnManager
()
rt
.
PeerAdded
=
func
(
p
peer
.
ID
)
{
commonPrefixLen
:=
kb
.
CommonPrefixLen
(
self
,
kb
.
ConvertPeerID
(
p
))
cmgr
.
TagPeer
(
p
,
"kbucket"
,
BaseConnMgrScore
+
commonPrefixLen
)
// We tag our closest peers with higher and higher scores so we
// stay connected to our nearest neighbors.
//
// We _also_ (elsewhere) protect useful peers in the furthest
// buckets (our "core" routing nodes) and give high scores to
// all other useful peers.
commonPrefixLen
:=
kb
.
CommonPrefixLen
(
dht
.
selfKey
,
kb
.
ConvertPeerID
(
p
))
cmgr
.
TagPeer
(
p
,
kbucketTag
,
baseConnMgrScore
+
commonPrefixLen
)
}
rt
.
PeerRemoved
=
func
(
p
peer
.
ID
)
{
cmgr
.
UntagPeer
(
p
,
"kbucket"
)
cmgr
.
Unprotect
(
p
,
dhtUsefulTag
)
cmgr
.
UntagPeer
(
p
,
kbucketTag
)
// try to fix the RT
dht
.
fixRTIfNeeded
()
...
...
query.go
View file @
3d294c7a
...
...
@@ -174,7 +174,24 @@ func (dht *IpfsDHT) runQuery(ctx context.Context, target string, queryFn queryFn
}
func
(
q
*
query
)
recordPeerIsValuable
(
p
peer
.
ID
)
{
q
.
dht
.
routingTable
.
UpdateLastUsefulAt
(
p
,
time
.
Now
())
if
!
q
.
dht
.
routingTable
.
UpdateLastUsefulAt
(
p
,
time
.
Now
())
{
// not in routing table
return
}
// Protect useful peers, when they're actually useful. This will last
// through disconnects. However, we'll still evict them if they keep
// disconnecting from us.
//
// Restrict to buckets 0, 1 (75% of requests, max 40 peers), so we don't
// protect _too_ many peers.
commonPrefixLen
:=
kb
.
CommonPrefixLen
(
q
.
dht
.
selfKey
,
kb
.
ConvertPeerID
(
p
))
cmgr
:=
q
.
dht
.
host
.
ConnManager
()
if
commonPrefixLen
<
usefulConnMgrProtectedBuckets
{
cmgr
.
Protect
(
p
,
dhtUsefulTag
)
}
else
{
cmgr
.
TagPeer
(
p
,
dhtUsefulTag
,
usefulConnMgrScore
)
}
}
func
(
q
*
query
)
recordValuablePeers
()
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment