Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
fd869dc8
Commit
fd869dc8
authored
Jan 12, 2018
by
gluk256
Committed by
Felix Lange
Jan 12, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
whisper/whisperv6: implement pow/bloom exchange protocol (#15802)
This is the main feature of v6.
parent
56152b31
Changes
7
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
451 additions
and
75 deletions
+451
-75
api.go
whisper/whisperv6/api.go
+7
-2
doc.go
whisper/whisperv6/doc.go
+10
-10
envelope.go
whisper/whisperv6/envelope.go
+32
-3
peer.go
whisper/whisperv6/peer.go
+50
-4
peer_test.go
whisper/whisperv6/peer_test.go
+85
-20
whisper.go
whisper/whisperv6/whisper.go
+206
-36
whisper_test.go
whisper/whisperv6/whisper_test.go
+61
-0
No files found.
whisper/whisperv6/api.go
View file @
fd869dc8
...
@@ -116,12 +116,17 @@ func (api *PublicWhisperAPI) SetMaxMessageSize(ctx context.Context, size uint32)
...
@@ -116,12 +116,17 @@ func (api *PublicWhisperAPI) SetMaxMessageSize(ctx context.Context, size uint32)
return
true
,
api
.
w
.
SetMaxMessageSize
(
size
)
return
true
,
api
.
w
.
SetMaxMessageSize
(
size
)
}
}
// SetMinPow sets the minimum PoW
for a message before it is accepted
.
// SetMinPow sets the minimum PoW
, and notifies the peers
.
func
(
api
*
PublicWhisperAPI
)
SetMinPoW
(
ctx
context
.
Context
,
pow
float64
)
(
bool
,
error
)
{
func
(
api
*
PublicWhisperAPI
)
SetMinPoW
(
ctx
context
.
Context
,
pow
float64
)
(
bool
,
error
)
{
return
true
,
api
.
w
.
SetMinimumPoW
(
pow
)
return
true
,
api
.
w
.
SetMinimumPoW
(
pow
)
}
}
// MarkTrustedPeer marks a peer trusted. , which will allow it to send historic (expired) messages.
// SetBloomFilter sets the new value of bloom filter, and notifies the peers.
func
(
api
*
PublicWhisperAPI
)
SetBloomFilter
(
ctx
context
.
Context
,
bloom
hexutil
.
Bytes
)
(
bool
,
error
)
{
return
true
,
api
.
w
.
SetBloomFilter
(
bloom
)
}
// MarkTrustedPeer marks a peer trusted, which will allow it to send historic (expired) messages.
// Note: This function is not adding new nodes, the node needs to exists as a peer.
// Note: This function is not adding new nodes, the node needs to exists as a peer.
func
(
api
*
PublicWhisperAPI
)
MarkTrustedPeer
(
ctx
context
.
Context
,
enode
string
)
(
bool
,
error
)
{
func
(
api
*
PublicWhisperAPI
)
MarkTrustedPeer
(
ctx
context
.
Context
,
enode
string
)
(
bool
,
error
)
{
n
,
err
:=
discover
.
ParseNode
(
enode
)
n
,
err
:=
discover
.
ParseNode
(
enode
)
...
...
whisper/whisperv6/doc.go
View file @
fd869dc8
...
@@ -35,7 +35,6 @@ import (
...
@@ -35,7 +35,6 @@ import (
)
)
const
(
const
(
EnvelopeVersion
=
uint64
(
0
)
ProtocolVersion
=
uint64
(
6
)
ProtocolVersion
=
uint64
(
6
)
ProtocolVersionStr
=
"6.0"
ProtocolVersionStr
=
"6.0"
ProtocolName
=
"shh"
ProtocolName
=
"shh"
...
@@ -52,11 +51,14 @@ const (
...
@@ -52,11 +51,14 @@ const (
paddingMask
=
byte
(
3
)
paddingMask
=
byte
(
3
)
signatureFlag
=
byte
(
4
)
signatureFlag
=
byte
(
4
)
TopicLength
=
4
TopicLength
=
4
// in bytes
signatureLength
=
65
signatureLength
=
65
// in bytes
aesKeyLength
=
32
aesKeyLength
=
32
// in bytes
AESNonceLength
=
12
AESNonceLength
=
12
// in bytes
keyIdSize
=
32
keyIdSize
=
32
// in bytes
bloomFilterSize
=
64
// in bytes
EnvelopeHeaderLength
=
20
MaxMessageSize
=
uint32
(
10
*
1024
*
1024
)
// maximum accepted size of a message.
MaxMessageSize
=
uint32
(
10
*
1024
*
1024
)
// maximum accepted size of a message.
DefaultMaxMessageSize
=
uint32
(
1024
*
1024
)
DefaultMaxMessageSize
=
uint32
(
1024
*
1024
)
...
@@ -68,10 +70,8 @@ const (
...
@@ -68,10 +70,8 @@ const (
expirationCycle
=
time
.
Second
expirationCycle
=
time
.
Second
transmissionCycle
=
300
*
time
.
Millisecond
transmissionCycle
=
300
*
time
.
Millisecond
DefaultTTL
=
50
// seconds
DefaultTTL
=
50
// seconds
SynchAllowance
=
10
// seconds
DefaultSyncAllowance
=
10
// seconds
EnvelopeHeaderLength
=
20
)
)
type
unknownVersionError
uint64
type
unknownVersionError
uint64
...
...
whisper/whisperv6/envelope.go
View file @
fd869dc8
...
@@ -42,9 +42,11 @@ type Envelope struct {
...
@@ -42,9 +42,11 @@ type Envelope struct {
Data
[]
byte
Data
[]
byte
Nonce
uint64
Nonce
uint64
pow
float64
// Message-specific PoW as described in the Whisper specification.
pow
float64
// Message-specific PoW as described in the Whisper specification.
hash
common
.
Hash
// Cached hash of the envelope to avoid rehashing every time.
// Don't access hash directly, use Hash() function instead.
// the following variables should not be accessed directly, use the corresponding function instead: Hash(), Bloom()
hash
common
.
Hash
// Cached hash of the envelope to avoid rehashing every time.
bloom
[]
byte
}
}
// size returns the size of envelope as it is sent (i.e. public fields only)
// size returns the size of envelope as it is sent (i.e. public fields only)
...
@@ -227,3 +229,30 @@ func (e *Envelope) Open(watcher *Filter) (msg *ReceivedMessage) {
...
@@ -227,3 +229,30 @@ func (e *Envelope) Open(watcher *Filter) (msg *ReceivedMessage) {
}
}
return
msg
return
msg
}
}
// Bloom maps 4-bytes Topic into 64-byte bloom filter with 3 bits set (at most).
func
(
e
*
Envelope
)
Bloom
()
[]
byte
{
if
e
.
bloom
==
nil
{
e
.
bloom
=
TopicToBloom
(
e
.
Topic
)
}
return
e
.
bloom
}
// TopicToBloom converts the topic (4 bytes) to the bloom filter (64 bytes)
func
TopicToBloom
(
topic
TopicType
)
[]
byte
{
b
:=
make
([]
byte
,
bloomFilterSize
)
var
index
[
3
]
int
for
j
:=
0
;
j
<
3
;
j
++
{
index
[
j
]
=
int
(
topic
[
j
])
if
(
topic
[
3
]
&
(
1
<<
uint
(
j
)))
!=
0
{
index
[
j
]
+=
256
}
}
for
j
:=
0
;
j
<
3
;
j
++
{
byteIndex
:=
index
[
j
]
/
8
bitIndex
:=
index
[
j
]
%
8
b
[
byteIndex
]
=
(
1
<<
uint
(
bitIndex
))
}
return
b
}
whisper/whisperv6/peer.go
View file @
fd869dc8
...
@@ -36,6 +36,7 @@ type Peer struct {
...
@@ -36,6 +36,7 @@ type Peer struct {
trusted
bool
trusted
bool
powRequirement
float64
powRequirement
float64
bloomFilter
[]
byte
// may contain nil in case of full node
known
*
set
.
Set
// Messages already known by the peer to avoid wasting bandwidth
known
*
set
.
Set
// Messages already known by the peer to avoid wasting bandwidth
...
@@ -74,8 +75,12 @@ func (p *Peer) handshake() error {
...
@@ -74,8 +75,12 @@ func (p *Peer) handshake() error {
// Send the handshake status message asynchronously
// Send the handshake status message asynchronously
errc
:=
make
(
chan
error
,
1
)
errc
:=
make
(
chan
error
,
1
)
go
func
()
{
go
func
()
{
errc
<-
p2p
.
Send
(
p
.
ws
,
statusCode
,
ProtocolVersion
)
pow
:=
p
.
host
.
MinPow
()
powConverted
:=
math
.
Float64bits
(
pow
)
bloom
:=
p
.
host
.
BloomFilter
()
errc
<-
p2p
.
SendItems
(
p
.
ws
,
statusCode
,
ProtocolVersion
,
powConverted
,
bloom
)
}()
}()
// Fetch the remote status packet and verify protocol match
// Fetch the remote status packet and verify protocol match
packet
,
err
:=
p
.
ws
.
ReadMsg
()
packet
,
err
:=
p
.
ws
.
ReadMsg
()
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -85,14 +90,42 @@ func (p *Peer) handshake() error {
...
@@ -85,14 +90,42 @@ func (p *Peer) handshake() error {
return
fmt
.
Errorf
(
"peer [%x] sent packet %x before status packet"
,
p
.
ID
(),
packet
.
Code
)
return
fmt
.
Errorf
(
"peer [%x] sent packet %x before status packet"
,
p
.
ID
(),
packet
.
Code
)
}
}
s
:=
rlp
.
NewStream
(
packet
.
Payload
,
uint64
(
packet
.
Size
))
s
:=
rlp
.
NewStream
(
packet
.
Payload
,
uint64
(
packet
.
Size
))
peerVersion
,
err
:=
s
.
Uin
t
()
_
,
err
=
s
.
Lis
t
()
if
err
!=
nil
{
if
err
!=
nil
{
return
fmt
.
Errorf
(
"peer [%x] sent bad status message: %v"
,
p
.
ID
(),
err
)
return
fmt
.
Errorf
(
"peer [%x] sent bad status message: %v"
,
p
.
ID
(),
err
)
}
}
peerVersion
,
err
:=
s
.
Uint
()
if
err
!=
nil
{
return
fmt
.
Errorf
(
"peer [%x] sent bad status message (unable to decode version): %v"
,
p
.
ID
(),
err
)
}
if
peerVersion
!=
ProtocolVersion
{
if
peerVersion
!=
ProtocolVersion
{
return
fmt
.
Errorf
(
"peer [%x]: protocol version mismatch %d != %d"
,
p
.
ID
(),
peerVersion
,
ProtocolVersion
)
return
fmt
.
Errorf
(
"peer [%x]: protocol version mismatch %d != %d"
,
p
.
ID
(),
peerVersion
,
ProtocolVersion
)
}
}
// Wait until out own status is consumed too
// only version is mandatory, subsequent parameters are optional
powRaw
,
err
:=
s
.
Uint
()
if
err
==
nil
{
pow
:=
math
.
Float64frombits
(
powRaw
)
if
math
.
IsInf
(
pow
,
0
)
||
math
.
IsNaN
(
pow
)
||
pow
<
0.0
{
return
fmt
.
Errorf
(
"peer [%x] sent bad status message: invalid pow"
,
p
.
ID
())
}
p
.
powRequirement
=
pow
var
bloom
[]
byte
err
=
s
.
Decode
(
&
bloom
)
if
err
==
nil
{
sz
:=
len
(
bloom
)
if
sz
!=
bloomFilterSize
&&
sz
!=
0
{
return
fmt
.
Errorf
(
"peer [%x] sent bad status message: wrong bloom filter size %d"
,
p
.
ID
(),
sz
)
}
if
isFullNode
(
bloom
)
{
p
.
bloomFilter
=
nil
}
else
{
p
.
bloomFilter
=
bloom
}
}
}
if
err
:=
<-
errc
;
err
!=
nil
{
if
err
:=
<-
errc
;
err
!=
nil
{
return
fmt
.
Errorf
(
"peer [%x] failed to send status packet: %v"
,
p
.
ID
(),
err
)
return
fmt
.
Errorf
(
"peer [%x] failed to send status packet: %v"
,
p
.
ID
(),
err
)
}
}
...
@@ -156,7 +189,7 @@ func (p *Peer) broadcast() error {
...
@@ -156,7 +189,7 @@ func (p *Peer) broadcast() error {
envelopes
:=
p
.
host
.
Envelopes
()
envelopes
:=
p
.
host
.
Envelopes
()
bundle
:=
make
([]
*
Envelope
,
0
,
len
(
envelopes
))
bundle
:=
make
([]
*
Envelope
,
0
,
len
(
envelopes
))
for
_
,
envelope
:=
range
envelopes
{
for
_
,
envelope
:=
range
envelopes
{
if
!
p
.
marked
(
envelope
)
&&
envelope
.
PoW
()
>=
p
.
powRequirement
{
if
!
p
.
marked
(
envelope
)
&&
envelope
.
PoW
()
>=
p
.
powRequirement
&&
p
.
bloomMatch
(
envelope
)
{
bundle
=
append
(
bundle
,
envelope
)
bundle
=
append
(
bundle
,
envelope
)
}
}
}
}
...
@@ -186,3 +219,16 @@ func (p *Peer) notifyAboutPowRequirementChange(pow float64) error {
...
@@ -186,3 +219,16 @@ func (p *Peer) notifyAboutPowRequirementChange(pow float64) error {
i
:=
math
.
Float64bits
(
pow
)
i
:=
math
.
Float64bits
(
pow
)
return
p2p
.
Send
(
p
.
ws
,
powRequirementCode
,
i
)
return
p2p
.
Send
(
p
.
ws
,
powRequirementCode
,
i
)
}
}
func
(
p
*
Peer
)
notifyAboutBloomFilterChange
(
bloom
[]
byte
)
error
{
return
p2p
.
Send
(
p
.
ws
,
bloomFilterExCode
,
bloom
)
}
func
(
p
*
Peer
)
bloomMatch
(
env
*
Envelope
)
bool
{
if
p
.
bloomFilter
==
nil
{
// no filter - full node, accepts all envelops
return
true
}
return
bloomFilterMatch
(
p
.
bloomFilter
,
env
.
Bloom
())
}
whisper/whisperv6/peer_test.go
View file @
fd869dc8
...
@@ -20,6 +20,7 @@ import (
...
@@ -20,6 +20,7 @@ import (
"bytes"
"bytes"
"crypto/ecdsa"
"crypto/ecdsa"
"fmt"
"fmt"
mrand
"math/rand"
"net"
"net"
"sync"
"sync"
"testing"
"testing"
...
@@ -87,6 +88,9 @@ var nodes [NumNodes]*TestNode
...
@@ -87,6 +88,9 @@ var nodes [NumNodes]*TestNode
var
sharedKey
[]
byte
=
[]
byte
(
"some arbitrary data here"
)
var
sharedKey
[]
byte
=
[]
byte
(
"some arbitrary data here"
)
var
sharedTopic
TopicType
=
TopicType
{
0xF
,
0x1
,
0x2
,
0
}
var
sharedTopic
TopicType
=
TopicType
{
0xF
,
0x1
,
0x2
,
0
}
var
expectedMessage
[]
byte
=
[]
byte
(
"per rectum ad astra"
)
var
expectedMessage
[]
byte
=
[]
byte
(
"per rectum ad astra"
)
var
masterBloomFilter
[]
byte
var
masterPow
=
0.00000001
var
round
int
=
1
func
TestSimulation
(
t
*
testing
.
T
)
{
func
TestSimulation
(
t
*
testing
.
T
)
{
// create a chain of whisper nodes,
// create a chain of whisper nodes,
...
@@ -104,8 +108,13 @@ func TestSimulation(t *testing.T) {
...
@@ -104,8 +108,13 @@ func TestSimulation(t *testing.T) {
// check if each node have received and decrypted exactly one message
// check if each node have received and decrypted exactly one message
checkPropagation
(
t
,
true
)
checkPropagation
(
t
,
true
)
// send protocol-level messages (powRequirementCode) and check the new PoW requirement values
// check if Status message was correctly decoded
powReqExchange
(
t
)
checkBloomFilterExchange
(
t
)
checkPowExchange
(
t
)
// send new pow and bloom exchange messages
resetParams
(
t
)
round
++
// node #1 sends one expected (decryptable) message
// node #1 sends one expected (decryptable) message
sendMsg
(
t
,
true
,
1
)
sendMsg
(
t
,
true
,
1
)
...
@@ -113,18 +122,65 @@ func TestSimulation(t *testing.T) {
...
@@ -113,18 +122,65 @@ func TestSimulation(t *testing.T) {
// check if each node (except node #0) have received and decrypted exactly one message
// check if each node (except node #0) have received and decrypted exactly one message
checkPropagation
(
t
,
false
)
checkPropagation
(
t
,
false
)
for
i
:=
1
;
i
<
NumNodes
;
i
++
{
time
.
Sleep
(
20
*
time
.
Millisecond
)
sendMsg
(
t
,
true
,
i
)
}
// check if corresponding protocol-level messages were correctly decoded
checkPowExchangeForNodeZero
(
t
)
checkBloomFilterExchange
(
t
)
stopServers
()
stopServers
()
}
}
func
resetParams
(
t
*
testing
.
T
)
{
// change pow only for node zero
masterPow
=
7777777.0
nodes
[
0
]
.
shh
.
SetMinimumPoW
(
masterPow
)
// change bloom for all nodes
masterBloomFilter
=
TopicToBloom
(
sharedTopic
)
for
i
:=
0
;
i
<
NumNodes
;
i
++
{
nodes
[
i
]
.
shh
.
SetBloomFilter
(
masterBloomFilter
)
}
}
func
initBloom
(
t
*
testing
.
T
)
{
masterBloomFilter
=
make
([]
byte
,
bloomFilterSize
)
_
,
err
:=
mrand
.
Read
(
masterBloomFilter
)
if
err
!=
nil
{
t
.
Fatalf
(
"rand failed: %s."
,
err
)
}
msgBloom
:=
TopicToBloom
(
sharedTopic
)
masterBloomFilter
=
addBloom
(
masterBloomFilter
,
msgBloom
)
for
i
:=
0
;
i
<
32
;
i
++
{
masterBloomFilter
[
i
]
=
0xFF
}
if
!
bloomFilterMatch
(
masterBloomFilter
,
msgBloom
)
{
t
.
Fatalf
(
"bloom mismatch on initBloom."
)
}
}
func
initialize
(
t
*
testing
.
T
)
{
func
initialize
(
t
*
testing
.
T
)
{
initBloom
(
t
)
var
err
error
var
err
error
ip
:=
net
.
IPv4
(
127
,
0
,
0
,
1
)
ip
:=
net
.
IPv4
(
127
,
0
,
0
,
1
)
port0
:=
30303
port0
:=
30303
for
i
:=
0
;
i
<
NumNodes
;
i
++
{
for
i
:=
0
;
i
<
NumNodes
;
i
++
{
var
node
TestNode
var
node
TestNode
b
:=
make
([]
byte
,
bloomFilterSize
)
copy
(
b
,
masterBloomFilter
)
node
.
shh
=
New
(
&
DefaultConfig
)
node
.
shh
=
New
(
&
DefaultConfig
)
node
.
shh
.
SetMinimumPowTest
(
0.00000001
)
node
.
shh
.
SetMinimumPoW
(
masterPow
)
node
.
shh
.
SetBloomFilter
(
b
)
if
!
bytes
.
Equal
(
node
.
shh
.
BloomFilter
(),
masterBloomFilter
)
{
t
.
Fatalf
(
"bloom mismatch on init."
)
}
node
.
shh
.
Start
(
nil
)
node
.
shh
.
Start
(
nil
)
topics
:=
make
([]
TopicType
,
0
)
topics
:=
make
([]
TopicType
,
0
)
topics
=
append
(
topics
,
sharedTopic
)
topics
=
append
(
topics
,
sharedTopic
)
...
@@ -206,7 +262,7 @@ func checkPropagation(t *testing.T, includingNodeZero bool) {
...
@@ -206,7 +262,7 @@ func checkPropagation(t *testing.T, includingNodeZero bool) {
for
i
:=
first
;
i
<
NumNodes
;
i
++
{
for
i
:=
first
;
i
<
NumNodes
;
i
++
{
f
:=
nodes
[
i
]
.
shh
.
GetFilter
(
nodes
[
i
]
.
filerId
)
f
:=
nodes
[
i
]
.
shh
.
GetFilter
(
nodes
[
i
]
.
filerId
)
if
f
==
nil
{
if
f
==
nil
{
t
.
Fatalf
(
"failed to get filterId %s from node %d
."
,
nodes
[
i
]
.
filerId
,
i
)
t
.
Fatalf
(
"failed to get filterId %s from node %d
, round %d."
,
nodes
[
i
]
.
filerId
,
i
,
round
)
}
}
mail
:=
f
.
Retrieve
()
mail
:=
f
.
Retrieve
()
...
@@ -332,34 +388,43 @@ func TestPeerBasic(t *testing.T) {
...
@@ -332,34 +388,43 @@ func TestPeerBasic(t *testing.T) {
}
}
}
}
func
powReqExchange
(
t
*
testing
.
T
)
{
func
checkPowExchangeForNodeZero
(
t
*
testing
.
T
)
{
cnt
:=
0
for
i
,
node
:=
range
nodes
{
for
i
,
node
:=
range
nodes
{
for
peer
:=
range
node
.
shh
.
peers
{
for
peer
:=
range
node
.
shh
.
peers
{
if
peer
.
powRequirement
>
1000.0
{
if
peer
.
peer
.
ID
()
==
discover
.
PubkeyID
(
&
nodes
[
0
]
.
id
.
PublicKey
)
{
t
.
Fatalf
(
"node %d: one of the peers' pow requirement is too big (%f)."
,
i
,
peer
.
powRequirement
)
cnt
++
if
peer
.
powRequirement
!=
masterPow
{
t
.
Fatalf
(
"node %d: failed to set the new pow requirement."
,
i
)
}
}
}
}
}
}
}
if
cnt
==
0
{
t
.
Fatalf
(
"no matching peers found."
)
}
}
const
pow
float64
=
7777777.0
func
checkPowExchange
(
t
*
testing
.
T
)
{
nodes
[
0
]
.
shh
.
SetMinimumPoW
(
pow
)
// wait until all the messages are delivered
time
.
Sleep
(
64
*
time
.
Millisecond
)
cnt
:=
0
for
i
,
node
:=
range
nodes
{
for
i
,
node
:=
range
nodes
{
for
peer
:=
range
node
.
shh
.
peers
{
for
peer
:=
range
node
.
shh
.
peers
{
if
peer
.
peer
.
ID
()
=
=
discover
.
PubkeyID
(
&
nodes
[
0
]
.
id
.
PublicKey
)
{
if
peer
.
peer
.
ID
()
!
=
discover
.
PubkeyID
(
&
nodes
[
0
]
.
id
.
PublicKey
)
{
cnt
++
if
peer
.
powRequirement
!=
masterPow
{
if
peer
.
powRequirement
!=
pow
{
t
.
Fatalf
(
"node %d: failed to exchange pow requirement in round %d; expected %f, got %f"
,
t
.
Fatalf
(
"node %d: failed to set the new pow requirement."
,
i
)
i
,
round
,
masterPow
,
peer
.
powRequirement
)
}
}
}
}
}
}
}
}
}
if
cnt
==
0
{
func
checkBloomFilterExchange
(
t
*
testing
.
T
)
{
t
.
Fatalf
(
"no matching peers found."
)
for
i
,
node
:=
range
nodes
{
for
peer
:=
range
node
.
shh
.
peers
{
if
!
bytes
.
Equal
(
peer
.
bloomFilter
,
masterBloomFilter
)
{
t
.
Fatalf
(
"node %d: failed to exchange bloom filter requirement in round %d.
\n
%x expected
\n
%x got"
,
i
,
round
,
masterBloomFilter
,
peer
.
bloomFilter
)
}
}
}
}
}
}
whisper/whisperv6/whisper.go
View file @
fd869dc8
This diff is collapsed.
Click to expand it.
whisper/whisperv6/whisper_test.go
View file @
fd869dc8
...
@@ -843,3 +843,64 @@ func TestSymmetricSendKeyMismatch(t *testing.T) {
...
@@ -843,3 +843,64 @@ func TestSymmetricSendKeyMismatch(t *testing.T) {
t
.
Fatalf
(
"received a message when keys weren't matching"
)
t
.
Fatalf
(
"received a message when keys weren't matching"
)
}
}
}
}
func
TestBloom
(
t
*
testing
.
T
)
{
topic
:=
TopicType
{
0
,
0
,
255
,
6
}
b
:=
TopicToBloom
(
topic
)
x
:=
make
([]
byte
,
bloomFilterSize
)
x
[
0
]
=
byte
(
1
)
x
[
32
]
=
byte
(
1
)
x
[
bloomFilterSize
-
1
]
=
byte
(
128
)
if
!
bloomFilterMatch
(
x
,
b
)
||
!
bloomFilterMatch
(
b
,
x
)
{
t
.
Fatalf
(
"bloom filter does not match the mask"
)
}
_
,
err
:=
mrand
.
Read
(
b
)
if
err
!=
nil
{
t
.
Fatalf
(
"math rand error"
)
}
_
,
err
=
mrand
.
Read
(
x
)
if
err
!=
nil
{
t
.
Fatalf
(
"math rand error"
)
}
if
!
bloomFilterMatch
(
b
,
b
)
{
t
.
Fatalf
(
"bloom filter does not match self"
)
}
x
=
addBloom
(
x
,
b
)
if
!
bloomFilterMatch
(
x
,
b
)
{
t
.
Fatalf
(
"bloom filter does not match combined bloom"
)
}
if
!
isFullNode
(
nil
)
{
t
.
Fatalf
(
"isFullNode did not recognize nil as full node"
)
}
x
[
17
]
=
254
if
isFullNode
(
x
)
{
t
.
Fatalf
(
"isFullNode false positive"
)
}
for
i
:=
0
;
i
<
bloomFilterSize
;
i
++
{
b
[
i
]
=
byte
(
255
)
}
if
!
isFullNode
(
b
)
{
t
.
Fatalf
(
"isFullNode false negative"
)
}
if
bloomFilterMatch
(
x
,
b
)
{
t
.
Fatalf
(
"bloomFilterMatch false positive"
)
}
if
!
bloomFilterMatch
(
b
,
x
)
{
t
.
Fatalf
(
"bloomFilterMatch false negative"
)
}
w
:=
New
(
&
DefaultConfig
)
f
:=
w
.
BloomFilter
()
if
f
!=
nil
{
t
.
Fatalf
(
"wrong bloom on creation"
)
}
err
=
w
.
SetBloomFilter
(
x
)
if
err
!=
nil
{
t
.
Fatalf
(
"failed to set bloom filter: %s"
,
err
)
}
f
=
w
.
BloomFilter
()
if
!
bloomFilterMatch
(
f
,
x
)
||
!
bloomFilterMatch
(
x
,
f
)
{
t
.
Fatalf
(
"retireved wrong bloom filter"
)
}
}
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