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
dms3
go-dms3
Commits
cb3a8bfc
Commit
cb3a8bfc
authored
Oct 28, 2014
by
Juan Batiz-Benet
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #216 from jbenet/fix/bsmsg-duplicates
fix(bitswap/message) duplicate entries
parents
e8ec8ce9
42dfc502
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
87 additions
and
45 deletions
+87
-45
exchange/bitswap/bitswap.go
exchange/bitswap/bitswap.go
+5
-6
exchange/bitswap/message/message.go
exchange/bitswap/message/message.go
+46
-20
exchange/bitswap/message/message_test.go
exchange/bitswap/message/message_test.go
+30
-13
exchange/bitswap/strategy/strategy_test.go
exchange/bitswap/strategy/strategy_test.go
+2
-2
exchange/bitswap/testnet/network_test.go
exchange/bitswap/testnet/network_test.go
+4
-4
No files found.
exchange/bitswap/bitswap.go
View file @
cb3a8bfc
...
...
@@ -78,9 +78,8 @@ func (bs *bitswap) Block(parent context.Context, k u.Key) (*blocks.Block, error)
go
func
()
{
message
:=
bsmsg
.
New
()
for
_
,
wanted
:=
range
bs
.
wantlist
.
Keys
()
{
message
.
A
ppen
dWanted
(
wanted
)
message
.
A
d
dWanted
(
wanted
)
}
message
.
AppendWanted
(
k
)
for
peerToQuery
:=
range
peersToQuery
{
log
.
Debugf
(
"bitswap got peersToQuery: %s"
,
peerToQuery
)
go
func
(
p
peer
.
Peer
)
{
...
...
@@ -168,7 +167,7 @@ func (bs *bitswap) ReceiveMessage(ctx context.Context, p peer.Peer, incoming bsm
message
:=
bsmsg
.
New
()
for
_
,
wanted
:=
range
bs
.
wantlist
.
Keys
()
{
message
.
A
ppen
dWanted
(
wanted
)
message
.
A
d
dWanted
(
wanted
)
}
for
_
,
key
:=
range
incoming
.
Wantlist
()
{
// TODO: might be better to check if we have the block before checking
...
...
@@ -177,7 +176,7 @@ func (bs *bitswap) ReceiveMessage(ctx context.Context, p peer.Peer, incoming bsm
if
block
,
errBlockNotFound
:=
bs
.
blockstore
.
Get
(
key
);
errBlockNotFound
!=
nil
{
continue
}
else
{
message
.
A
ppen
dBlock
(
*
block
)
message
.
A
d
dBlock
(
*
block
)
}
}
}
...
...
@@ -207,9 +206,9 @@ func (bs *bitswap) sendToPeersThatWant(ctx context.Context, block blocks.Block)
log
.
Debugf
(
"%v wants %v"
,
p
,
block
.
Key
())
if
bs
.
strategy
.
ShouldSendBlockToPeer
(
block
.
Key
(),
p
)
{
message
:=
bsmsg
.
New
()
message
.
A
ppen
dBlock
(
block
)
message
.
A
d
dBlock
(
block
)
for
_
,
wanted
:=
range
bs
.
wantlist
.
Keys
()
{
message
.
A
ppen
dWanted
(
wanted
)
message
.
A
d
dWanted
(
wanted
)
}
go
bs
.
send
(
ctx
,
p
,
message
)
}
...
...
exchange/bitswap/message/message.go
View file @
cb3a8bfc
...
...
@@ -14,10 +14,25 @@ import (
// TODO move bs/msg/internal/pb to bs/internal/pb and rename pb package to bitswap_pb
type
BitSwapMessage
interface
{
// Wantlist returns a slice of unique keys that represent data wanted by
// the sender.
Wantlist
()
[]
u
.
Key
// Blocks returns a slice of unique blocks
Blocks
()
[]
blocks
.
Block
AppendWanted
(
k
u
.
Key
)
AppendBlock
(
b
blocks
.
Block
)
// AddWanted adds the key to the Wantlist.
//
// Insertion order determines priority. That is, earlier insertions are
// deemed higher priority than keys inserted later.
//
// t = 0, msg.AddWanted(A)
// t = 1, msg.AddWanted(B)
//
// implies Priority(A) > Priority(B)
AddWanted
(
u
.
Key
)
AddBlock
(
blocks
.
Block
)
Exportable
}
...
...
@@ -26,44 +41,55 @@ type Exportable interface {
ToNet
(
p
peer
.
Peer
)
(
nm
.
NetMessage
,
error
)
}
// message wraps a proto message for convenience
type
message
struct
{
wantlist
[]
u
.
Key
blocks
[]
blocks
.
Block
type
impl
struct
{
existsInWantlist
map
[
u
.
Key
]
struct
{}
// map to detect duplicates
wantlist
[]
u
.
Key
// slice to preserve ordering
blocks
map
[
u
.
Key
]
blocks
.
Block
// map to detect duplicates
}
func
New
()
*
message
{
return
new
(
message
)
func
New
()
BitSwapMessage
{
return
&
impl
{
blocks
:
make
(
map
[
u
.
Key
]
blocks
.
Block
),
existsInWantlist
:
make
(
map
[
u
.
Key
]
struct
{}),
wantlist
:
make
([]
u
.
Key
,
0
),
}
}
func
newMessageFromProto
(
pbm
pb
.
Message
)
BitSwapMessage
{
m
:=
New
()
for
_
,
s
:=
range
pbm
.
GetWantlist
()
{
m
.
A
ppen
dWanted
(
u
.
Key
(
s
))
m
.
A
d
dWanted
(
u
.
Key
(
s
))
}
for
_
,
d
:=
range
pbm
.
GetBlocks
()
{
b
:=
blocks
.
NewBlock
(
d
)
m
.
A
ppen
dBlock
(
*
b
)
m
.
A
d
dBlock
(
*
b
)
}
return
m
}
// TODO(brian): convert these into keys
func
(
m
*
message
)
Wantlist
()
[]
u
.
Key
{
func
(
m
*
impl
)
Wantlist
()
[]
u
.
Key
{
return
m
.
wantlist
}
// TODO(brian): convert these into blocks
func
(
m
*
message
)
Blocks
()
[]
blocks
.
Block
{
return
m
.
blocks
func
(
m
*
impl
)
Blocks
()
[]
blocks
.
Block
{
bs
:=
make
([]
blocks
.
Block
,
0
)
for
_
,
block
:=
range
m
.
blocks
{
bs
=
append
(
bs
,
block
)
}
return
bs
}
func
(
m
*
message
)
AppendWanted
(
k
u
.
Key
)
{
func
(
m
*
impl
)
AddWanted
(
k
u
.
Key
)
{
_
,
exists
:=
m
.
existsInWantlist
[
k
]
if
exists
{
return
}
m
.
existsInWantlist
[
k
]
=
struct
{}{}
m
.
wantlist
=
append
(
m
.
wantlist
,
k
)
}
func
(
m
*
message
)
Appen
dBlock
(
b
blocks
.
Block
)
{
m
.
blocks
=
append
(
m
.
blocks
,
b
)
func
(
m
*
impl
)
Ad
dBlock
(
b
blocks
.
Block
)
{
m
.
blocks
[
b
.
Key
()]
=
b
}
func
FromNet
(
nmsg
netmsg
.
NetMessage
)
(
BitSwapMessage
,
error
)
{
...
...
@@ -75,7 +101,7 @@ func FromNet(nmsg netmsg.NetMessage) (BitSwapMessage, error) {
return
m
,
nil
}
func
(
m
*
message
)
ToProto
()
*
pb
.
Message
{
func
(
m
*
impl
)
ToProto
()
*
pb
.
Message
{
pb
:=
new
(
pb
.
Message
)
for
_
,
k
:=
range
m
.
Wantlist
()
{
pb
.
Wantlist
=
append
(
pb
.
Wantlist
,
string
(
k
))
...
...
@@ -86,6 +112,6 @@ func (m *message) ToProto() *pb.Message {
return
pb
}
func
(
m
*
message
)
ToNet
(
p
peer
.
Peer
)
(
nm
.
NetMessage
,
error
)
{
func
(
m
*
impl
)
ToNet
(
p
peer
.
Peer
)
(
nm
.
NetMessage
,
error
)
{
return
nm
.
FromObject
(
p
,
m
.
ToProto
())
}
exchange/bitswap/message/message_test.go
View file @
cb3a8bfc
...
...
@@ -13,7 +13,7 @@ import (
func
TestAppendWanted
(
t
*
testing
.
T
)
{
const
str
=
"foo"
m
:=
New
()
m
.
A
ppen
dWanted
(
u
.
Key
(
str
))
m
.
A
d
dWanted
(
u
.
Key
(
str
))
if
!
contains
(
m
.
ToProto
()
.
GetWantlist
(),
str
)
{
t
.
Fail
()
...
...
@@ -42,7 +42,7 @@ func TestAppendBlock(t *testing.T) {
m
:=
New
()
for
_
,
str
:=
range
strs
{
block
:=
blocks
.
NewBlock
([]
byte
(
str
))
m
.
A
ppen
dBlock
(
*
block
)
m
.
A
d
dBlock
(
*
block
)
}
// assert strings are in proto message
...
...
@@ -58,7 +58,7 @@ func TestWantlist(t *testing.T) {
keystrs
:=
[]
string
{
"foo"
,
"bar"
,
"baz"
,
"bat"
}
m
:=
New
()
for
_
,
s
:=
range
keystrs
{
m
.
A
ppen
dWanted
(
u
.
Key
(
s
))
m
.
A
d
dWanted
(
u
.
Key
(
s
))
}
exported
:=
m
.
Wantlist
()
...
...
@@ -81,7 +81,7 @@ func TestCopyProtoByValue(t *testing.T) {
const
str
=
"foo"
m
:=
New
()
protoBeforeAppend
:=
m
.
ToProto
()
m
.
A
ppen
dWanted
(
u
.
Key
(
str
))
m
.
A
d
dWanted
(
u
.
Key
(
str
))
if
contains
(
protoBeforeAppend
.
GetWantlist
(),
str
)
{
t
.
Fail
()
}
...
...
@@ -101,11 +101,11 @@ func TestToNetMethodSetsPeer(t *testing.T) {
func
TestToNetFromNetPreservesWantList
(
t
*
testing
.
T
)
{
original
:=
New
()
original
.
A
ppen
dWanted
(
u
.
Key
(
"M"
))
original
.
A
ppen
dWanted
(
u
.
Key
(
"B"
))
original
.
A
ppen
dWanted
(
u
.
Key
(
"D"
))
original
.
A
ppen
dWanted
(
u
.
Key
(
"T"
))
original
.
A
ppen
dWanted
(
u
.
Key
(
"F"
))
original
.
A
d
dWanted
(
u
.
Key
(
"M"
))
original
.
A
d
dWanted
(
u
.
Key
(
"B"
))
original
.
A
d
dWanted
(
u
.
Key
(
"D"
))
original
.
A
d
dWanted
(
u
.
Key
(
"T"
))
original
.
A
d
dWanted
(
u
.
Key
(
"F"
))
p
:=
peer
.
WithIDString
(
"X"
)
netmsg
,
err
:=
original
.
ToNet
(
p
)
...
...
@@ -133,10 +133,10 @@ func TestToNetFromNetPreservesWantList(t *testing.T) {
func
TestToAndFromNetMessage
(
t
*
testing
.
T
)
{
original
:=
New
()
original
.
A
ppen
dBlock
(
*
blocks
.
NewBlock
([]
byte
(
"W"
)))
original
.
A
ppen
dBlock
(
*
blocks
.
NewBlock
([]
byte
(
"E"
)))
original
.
A
ppen
dBlock
(
*
blocks
.
NewBlock
([]
byte
(
"F"
)))
original
.
A
ppen
dBlock
(
*
blocks
.
NewBlock
([]
byte
(
"M"
)))
original
.
A
d
dBlock
(
*
blocks
.
NewBlock
([]
byte
(
"W"
)))
original
.
A
d
dBlock
(
*
blocks
.
NewBlock
([]
byte
(
"E"
)))
original
.
A
d
dBlock
(
*
blocks
.
NewBlock
([]
byte
(
"F"
)))
original
.
A
d
dBlock
(
*
blocks
.
NewBlock
([]
byte
(
"M"
)))
p
:=
peer
.
WithIDString
(
"X"
)
netmsg
,
err
:=
original
.
ToNet
(
p
)
...
...
@@ -169,3 +169,20 @@ func contains(s []string, x string) bool {
}
return
false
}
func
TestDuplicates
(
t
*
testing
.
T
)
{
b
:=
blocks
.
NewBlock
([]
byte
(
"foo"
))
msg
:=
New
()
msg
.
AddWanted
(
b
.
Key
())
msg
.
AddWanted
(
b
.
Key
())
if
len
(
msg
.
Wantlist
())
!=
1
{
t
.
Fatal
(
"Duplicate in BitSwapMessage"
)
}
msg
.
AddBlock
(
*
b
)
msg
.
AddBlock
(
*
b
)
if
len
(
msg
.
Blocks
())
!=
1
{
t
.
Fatal
(
"Duplicate in BitSwapMessage"
)
}
}
exchange/bitswap/strategy/strategy_test.go
View file @
cb3a8bfc
...
...
@@ -30,7 +30,7 @@ func TestConsistentAccounting(t *testing.T) {
m
:=
message
.
New
()
content
:=
[]
string
{
"this"
,
"is"
,
"message"
,
"i"
}
m
.
A
ppen
dBlock
(
*
blocks
.
NewBlock
([]
byte
(
strings
.
Join
(
content
,
" "
))))
m
.
A
d
dBlock
(
*
blocks
.
NewBlock
([]
byte
(
strings
.
Join
(
content
,
" "
))))
sender
.
MessageSent
(
receiver
.
Peer
,
m
)
receiver
.
MessageReceived
(
sender
.
Peer
,
m
)
...
...
@@ -60,7 +60,7 @@ func TestBlockRecordedAsWantedAfterMessageReceived(t *testing.T) {
block
:=
blocks
.
NewBlock
([]
byte
(
"data wanted by beggar"
))
messageFromBeggarToChooser
:=
message
.
New
()
messageFromBeggarToChooser
.
A
ppen
dWanted
(
block
.
Key
())
messageFromBeggarToChooser
.
A
d
dWanted
(
block
.
Key
())
chooser
.
MessageReceived
(
beggar
.
Peer
,
messageFromBeggarToChooser
)
// for this test, doesn't matter if you record that beggar sent
...
...
exchange/bitswap/testnet/network_test.go
View file @
cb3a8bfc
...
...
@@ -33,7 +33,7 @@ func TestSendRequestToCooperativePeer(t *testing.T) {
// TODO test contents of incoming message
m
:=
bsmsg
.
New
()
m
.
A
ppen
dBlock
(
*
blocks
.
NewBlock
([]
byte
(
expectedStr
)))
m
.
A
d
dBlock
(
*
blocks
.
NewBlock
([]
byte
(
expectedStr
)))
return
from
,
m
}))
...
...
@@ -41,7 +41,7 @@ func TestSendRequestToCooperativePeer(t *testing.T) {
t
.
Log
(
"Build a message and send a synchronous request to recipient"
)
message
:=
bsmsg
.
New
()
message
.
A
ppen
dBlock
(
*
blocks
.
NewBlock
([]
byte
(
"data"
)))
message
.
A
d
dBlock
(
*
blocks
.
NewBlock
([]
byte
(
"data"
)))
response
,
err
:=
initiator
.
SendRequest
(
context
.
Background
(),
peer
.
WithID
(
idOfRecipient
),
message
)
if
err
!=
nil
{
...
...
@@ -77,7 +77,7 @@ func TestSendMessageAsyncButWaitForResponse(t *testing.T) {
peer
.
Peer
,
bsmsg
.
BitSwapMessage
)
{
msgToWaiter
:=
bsmsg
.
New
()
msgToWaiter
.
A
ppen
dBlock
(
*
blocks
.
NewBlock
([]
byte
(
expectedStr
)))
msgToWaiter
.
A
d
dBlock
(
*
blocks
.
NewBlock
([]
byte
(
expectedStr
)))
return
fromWaiter
,
msgToWaiter
}))
...
...
@@ -105,7 +105,7 @@ func TestSendMessageAsyncButWaitForResponse(t *testing.T) {
}))
messageSentAsync
:=
bsmsg
.
New
()
messageSentAsync
.
A
ppen
dBlock
(
*
blocks
.
NewBlock
([]
byte
(
"data"
)))
messageSentAsync
.
A
d
dBlock
(
*
blocks
.
NewBlock
([]
byte
(
"data"
)))
errSending
:=
waiter
.
SendMessage
(
context
.
Background
(),
peer
.
WithID
(
idOfResponder
),
messageSentAsync
)
if
errSending
!=
nil
{
...
...
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