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-kbucket
Commits
ae212638
Commit
ae212638
authored
Aug 01, 2019
by
Aarsh Shah
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
k-bucket support for peoper kad bootstrapping
parent
146e1744
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
94 additions
and
0 deletions
+94
-0
bucket.go
bucket.go
+19
-0
table.go
table.go
+40
-0
table_test.go
table_test.go
+35
-0
No files found.
bucket.go
View file @
ae212638
...
...
@@ -3,6 +3,7 @@ package kbucket
import
(
"container/list"
"sync"
"time"
"github.com/libp2p/go-libp2p-core/peer"
)
...
...
@@ -11,14 +12,32 @@ import (
type
Bucket
struct
{
lk
sync
.
RWMutex
list
*
list
.
List
lastQueriedAtLk
sync
.
RWMutex
lastQueriedAt
time
.
Time
}
func
newBucket
()
*
Bucket
{
b
:=
new
(
Bucket
)
b
.
list
=
list
.
New
()
b
.
lastQueriedAt
=
time
.
Now
()
return
b
}
func
(
b
*
Bucket
)
GetLastQueriedAt
()
time
.
Time
{
b
.
lastQueriedAtLk
.
RLock
()
defer
b
.
lastQueriedAtLk
.
RUnlock
()
return
b
.
lastQueriedAt
}
func
(
b
*
Bucket
)
ResetLastQueriedAt
(
newTime
time
.
Time
)
{
b
.
lastQueriedAtLk
.
Lock
()
defer
b
.
lastQueriedAtLk
.
Unlock
()
b
.
lastQueriedAt
=
newTime
}
func
(
b
*
Bucket
)
Peers
()
[]
peer
.
ID
{
b
.
lk
.
RLock
()
defer
b
.
lk
.
RUnlock
()
...
...
table.go
View file @
ae212638
...
...
@@ -4,11 +4,14 @@ package kbucket
import
(
"errors"
"fmt"
"io"
"math/rand"
"sync"
"time"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p-core/peerstore"
mh
"github.com/multiformats/go-multihash"
logging
"github.com/ipfs/go-log"
)
...
...
@@ -17,6 +20,7 @@ var log = logging.Logger("table")
var
ErrPeerRejectedHighLatency
=
errors
.
New
(
"peer rejected; latency too high"
)
var
ErrPeerRejectedNoCapacity
=
errors
.
New
(
"peer rejected; insufficient capacity"
)
var
ErrGenRandPeerIDFailed
=
errors
.
New
(
"failed to generate random peerID in bucket: exhausted attempts"
)
// RoutingTable defines the routing table.
type
RoutingTable
struct
{
...
...
@@ -57,6 +61,42 @@ func NewRoutingTable(bucketsize int, localID ID, latency time.Duration, m peerst
return
rt
}
func
(
rt
*
RoutingTable
)
GenRandPeerID
(
bucketID
int
)
(
peer
.
ID
,
error
)
{
rt
.
tabLock
.
RLock
()
bucketLen
:=
len
(
rt
.
Buckets
)
rt
.
tabLock
.
RUnlock
()
var
targetCpl
int
if
bucketID
>=
bucketLen
-
1
{
targetCpl
=
bucketLen
}
else
{
targetCpl
=
bucketID
}
// should give up after a fixed number of attempts so we don't take up too much time/cpu
for
i
:=
0
;
i
<
200
;
i
++
{
peerID
,
err
:=
randPeerID
()
if
err
!=
nil
{
log
.
Debugf
(
"failed to generate random peerID in bucket %d, error is %+v"
,
bucketID
,
err
)
continue
}
if
CommonPrefixLen
(
ConvertPeerID
(
peerID
),
rt
.
local
)
==
targetCpl
{
return
peerID
,
err
}
}
return
""
,
ErrGenRandPeerIDFailed
}
func
randPeerID
()
(
peer
.
ID
,
error
)
{
r
:=
rand
.
New
(
rand
.
NewSource
(
time
.
Now
()
.
UnixNano
()))
buf
:=
make
([]
byte
,
16
)
if
_
,
err
:=
io
.
ReadFull
(
r
,
buf
);
err
!=
nil
{
return
""
,
err
}
h
,
_
:=
mh
.
Sum
(
buf
,
mh
.
SHA2_256
,
-
1
)
return
peer
.
ID
(
h
),
nil
}
// Update adds or moves the given peer to the front of its respective bucket
func
(
rt
*
RoutingTable
)
Update
(
p
peer
.
ID
)
(
evicted
peer
.
ID
,
err
error
)
{
peerID
:=
ConvertPeerID
(
p
)
...
...
table_test.go
View file @
ae212638
...
...
@@ -48,6 +48,41 @@ func TestBucket(t *testing.T) {
}
}
func
TestGenRandPeerID
(
t
*
testing
.
T
)
{
local
:=
test
.
RandPeerIDFatal
(
t
)
m
:=
pstore
.
NewMetrics
()
rt
:=
NewRoutingTable
(
1
,
ConvertPeerID
(
local
),
time
.
Hour
,
m
)
// create 3 buckets
for
i
:=
0
;
i
<
5
;
i
++
{
for
{
if
p
:=
test
.
RandPeerIDFatal
(
t
);
CommonPrefixLen
(
ConvertPeerID
(
local
),
ConvertPeerID
(
p
))
==
i
{
rt
.
Update
(
p
)
break
}
}
}
for
i
:=
0
;
i
<
5
;
i
++
{
peerID
,
err
:=
rt
.
GenRandPeerID
(
i
)
if
err
!=
nil
||
len
(
peerID
)
==
0
{
t
.
Fatalf
(
"error %+v & peerID %s for bucket %d"
,
err
,
peerID
,
i
)
}
var
expectedCpl
int
if
i
<
len
(
rt
.
Buckets
)
-
1
{
expectedCpl
=
i
}
else
{
expectedCpl
=
len
(
rt
.
Buckets
)
}
if
CommonPrefixLen
(
ConvertPeerID
(
peerID
),
rt
.
local
)
!=
expectedCpl
{
t
.
Fatalf
(
"cpl should be %d for bucket %d, generated peerID is %s"
,
expectedCpl
,
i
,
peerID
)
}
}
}
func
TestTableCallbacks
(
t
*
testing
.
T
)
{
local
:=
test
.
RandPeerIDFatal
(
t
)
m
:=
pstore
.
NewMetrics
()
...
...
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