aboutsummaryrefslogtreecommitdiffstats
path: root/whisper
diff options
context:
space:
mode:
authorGuillaume Ballet <gballet@gmail.com>2017-10-06 22:04:21 +0800
committerFelix Lange <fjl@users.noreply.github.com>2017-10-06 22:04:21 +0800
commit7a045af05b93c323f63c7af41423ded701ce3890 (patch)
treefcdfe96a65717fd18f3813cd5100d4790a582c1d /whisper
parent36243c7ed8c53e9de92d21bbcf0378d7e1c7a07e (diff)
downloaddexon-7a045af05b93c323f63c7af41423ded701ce3890.tar.gz
dexon-7a045af05b93c323f63c7af41423ded701ce3890.tar.zst
dexon-7a045af05b93c323f63c7af41423ded701ce3890.zip
whisper/whisperv5: set filter SymKeyHash on creation (#15165)
Diffstat (limited to 'whisper')
-rw-r--r--whisper/whisperv5/api.go2
-rw-r--r--whisper/whisperv5/config.go2
-rw-r--r--whisper/whisperv5/filter.go12
-rw-r--r--whisper/whisperv5/filter_test.go107
-rw-r--r--whisper/whisperv5/whisper_test.go225
5 files changed, 331 insertions, 17 deletions
diff --git a/whisper/whisperv5/api.go b/whisper/whisperv5/api.go
index ec22f0d1d..96c4b0e6c 100644
--- a/whisper/whisperv5/api.go
+++ b/whisper/whisperv5/api.go
@@ -104,7 +104,7 @@ func (api *PublicWhisperAPI) Info(ctx context.Context) Info {
stats := api.w.Stats()
return Info{
Memory: stats.memoryUsed,
- Messages: len(api.w.messageQueue) + len(api.w.p2pMsgQueue),
+ Messages: len(api.w.messageQueue) + len(api.w.p2pMsgQueue),
MinPow: api.w.MinPow(),
MaxMessageSize: api.w.MaxMessageSize(),
}
diff --git a/whisper/whisperv5/config.go b/whisper/whisperv5/config.go
index 290bf8962..fcc230704 100644
--- a/whisper/whisperv5/config.go
+++ b/whisper/whisperv5/config.go
@@ -25,5 +25,3 @@ var DefaultConfig = Config{
MaxMessageSize: DefaultMaxMessageSize,
MinimumAcceptedPOW: DefaultMinimumPoW,
}
-
-var ()
diff --git a/whisper/whisperv5/filter.go b/whisper/whisperv5/filter.go
index d571160d7..b5e893e0f 100644
--- a/whisper/whisperv5/filter.go
+++ b/whisper/whisperv5/filter.go
@@ -22,6 +22,7 @@ import (
"sync"
"github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
)
@@ -68,6 +69,10 @@ func (fs *Filters) Install(watcher *Filter) (string, error) {
return "", fmt.Errorf("failed to generate unique ID")
}
+ if watcher.expectsSymmetricEncryption() {
+ watcher.SymKeyHash = crypto.Keccak256Hash(watcher.KeySym)
+ }
+
fs.watchers[id] = watcher
return id, err
}
@@ -119,7 +124,9 @@ func (fs *Filters) NotifyWatchers(env *Envelope, p2pMessage bool) {
if match && msg != nil {
log.Trace("processing message: decrypted", "hash", env.Hash().Hex())
- watcher.Trigger(msg)
+ if watcher.Src == nil || IsPubKeyEqual(msg.Src, watcher.Src) {
+ watcher.Trigger(msg)
+ }
}
}
}
@@ -172,9 +179,6 @@ func (f *Filter) MatchMessage(msg *ReceivedMessage) bool {
if f.PoW > 0 && msg.PoW < f.PoW {
return false
}
- if f.Src != nil && !IsPubKeyEqual(msg.Src, f.Src) {
- return false
- }
if f.expectsAsymmetricEncryption() && msg.isAsymmetricEncryption() {
return IsPubKeyEqual(&f.KeyAsym.PublicKey, msg.Dst) && f.MatchTopic(msg.Topic)
diff --git a/whisper/whisperv5/filter_test.go b/whisper/whisperv5/filter_test.go
index 4ce87eee2..bd35e7f20 100644
--- a/whisper/whisperv5/filter_test.go
+++ b/whisper/whisperv5/filter_test.go
@@ -132,6 +132,103 @@ func TestInstallFilters(t *testing.T) {
}
}
+func TestInstallSymKeyGeneratesHash(t *testing.T) {
+ InitSingleTest()
+
+ w := New(&Config{})
+ filters := NewFilters(w)
+ filter, _ := generateFilter(t, true)
+
+ // save the current SymKeyHash for comparison
+ initialSymKeyHash := filter.SymKeyHash
+
+ // ensure the SymKeyHash is invalid, for Install to recreate it
+ var invalid common.Hash
+ filter.SymKeyHash = invalid
+
+ _, err := filters.Install(filter)
+
+ if err != nil {
+ t.Fatalf("Error installing the filter: %s", err)
+ }
+
+ for i, b := range filter.SymKeyHash {
+ if b != initialSymKeyHash[i] {
+ t.Fatalf("The filter's symmetric key hash was not properly generated by Install")
+ }
+ }
+}
+
+func TestInstallIdenticalFilters(t *testing.T) {
+ InitSingleTest()
+
+ w := New(&Config{})
+ filters := NewFilters(w)
+ filter1, _ := generateFilter(t, true)
+
+ // Copy the first filter since some of its fields
+ // are randomly gnerated.
+ filter2 := &Filter{
+ KeySym: filter1.KeySym,
+ Topics: filter1.Topics,
+ PoW: filter1.PoW,
+ AllowP2P: filter1.AllowP2P,
+ Messages: make(map[common.Hash]*ReceivedMessage),
+ }
+
+ _, err := filters.Install(filter1)
+
+ if err != nil {
+ t.Fatalf("Error installing the first filter with seed %d: %s", seed, err)
+ }
+
+ _, err = filters.Install(filter2)
+
+ if err != nil {
+ t.Fatalf("Error installing the second filter with seed %d: %s", seed, err)
+ }
+
+ params, err := generateMessageParams()
+ if err != nil {
+ t.Fatalf("Error generating message parameters with seed %d: %s", seed, err)
+ }
+
+ params.KeySym = filter1.KeySym
+ params.Topic = BytesToTopic(filter1.Topics[0])
+
+ filter1.Src = &params.Src.PublicKey
+ filter2.Src = &params.Src.PublicKey
+
+ sentMessage, err := NewSentMessage(params)
+ if err != nil {
+ t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
+ }
+ env, err := sentMessage.Wrap(params)
+ if err != nil {
+ t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
+ }
+ msg := env.Open(filter1)
+ if msg == nil {
+ t.Fatalf("failed to Open with filter1")
+ }
+
+ if !filter1.MatchEnvelope(env) {
+ t.Fatalf("failed matching with the first filter")
+ }
+
+ if !filter2.MatchEnvelope(env) {
+ t.Fatalf("failed matching with the first filter")
+ }
+
+ if !filter1.MatchMessage(msg) {
+ t.Fatalf("failed matching with the second filter")
+ }
+
+ if !filter2.MatchMessage(msg) {
+ t.Fatalf("failed matching with the second filter")
+ }
+}
+
func TestComparePubKey(t *testing.T) {
InitSingleTest()
@@ -345,11 +442,6 @@ func TestMatchMessageSym(t *testing.T) {
t.Fatalf("failed Open with seed %d.", seed)
}
- // Src mismatch
- if f.MatchMessage(msg) {
- t.Fatalf("failed MatchMessage(src mismatch) with seed %d.", seed)
- }
-
// Src: match
*f.Src.X = *params.Src.PublicKey.X
*f.Src.Y = *params.Src.PublicKey.Y
@@ -443,11 +535,6 @@ func TestMatchMessageAsym(t *testing.T) {
t.Fatalf("failed to open with seed %d.", seed)
}
- // Src mismatch
- if f.MatchMessage(msg) {
- t.Fatalf("failed MatchMessage(src mismatch) with seed %d.", seed)
- }
-
// Src: match
*f.Src.X = *params.Src.PublicKey.X
*f.Src.Y = *params.Src.PublicKey.Y
diff --git a/whisper/whisperv5/whisper_test.go b/whisper/whisperv5/whisper_test.go
index 025be5b54..8af085292 100644
--- a/whisper/whisperv5/whisper_test.go
+++ b/whisper/whisperv5/whisper_test.go
@@ -22,6 +22,8 @@ import (
mrand "math/rand"
"testing"
"time"
+
+ "github.com/ethereum/go-ethereum/common"
)
func TestWhisperBasic(t *testing.T) {
@@ -624,3 +626,226 @@ func TestCustomization(t *testing.T) {
t.Fatalf("failed to get whisper messages")
}
}
+
+func TestSymmetricSendCycle(t *testing.T) {
+ InitSingleTest()
+
+ w := New(&DefaultConfig)
+ defer w.SetMinimumPoW(DefaultMinimumPoW)
+ defer w.SetMaxMessageSize(DefaultMaxMessageSize)
+ w.Start(nil)
+ defer w.Stop()
+
+ filter1, err := generateFilter(t, true)
+ if err != nil {
+ t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
+ }
+ filter1.PoW = DefaultMinimumPoW
+
+ // Copy the first filter since some of its fields
+ // are randomly gnerated.
+ filter2 := &Filter{
+ KeySym: filter1.KeySym,
+ Topics: filter1.Topics,
+ PoW: filter1.PoW,
+ AllowP2P: filter1.AllowP2P,
+ Messages: make(map[common.Hash]*ReceivedMessage),
+ }
+
+ params, err := generateMessageParams()
+ if err != nil {
+ t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
+ }
+
+ filter1.Src = &params.Src.PublicKey
+ filter2.Src = &params.Src.PublicKey
+
+ params.KeySym = filter1.KeySym
+ params.Topic = BytesToTopic(filter1.Topics[2])
+ params.PoW = filter1.PoW
+ params.WorkTime = 10
+ params.TTL = 50
+ msg, err := NewSentMessage(params)
+ if err != nil {
+ t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
+ }
+ env, err := msg.Wrap(params)
+ if err != nil {
+ t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
+ }
+
+ _, err = w.Subscribe(filter1)
+ if err != nil {
+ t.Fatalf("failed subscribe 1 with seed %d: %s.", seed, err)
+ }
+
+ _, err = w.Subscribe(filter2)
+ if err != nil {
+ t.Fatalf("failed subscribe 2 with seed %d: %s.", seed, err)
+ }
+
+ err = w.Send(env)
+ if err != nil {
+ t.Fatalf("Failed sending envelope with PoW %.06f (seed %d): %s", env.PoW(), seed, err)
+ }
+
+ // wait till received or timeout
+ var received bool
+ for j := 0; j < 200; j++ {
+ time.Sleep(10 * time.Millisecond)
+ if len(w.Envelopes()) > 0 {
+ received = true
+ break
+ }
+ }
+
+ if !received {
+ t.Fatalf("did not receive the sent envelope, seed: %d.", seed)
+ }
+
+ // check w.messages()
+ time.Sleep(5 * time.Millisecond)
+ mail1 := filter1.Retrieve()
+ mail2 := filter2.Retrieve()
+ if len(mail2) == 0 {
+ t.Fatalf("did not receive any email for filter 2")
+ }
+ if len(mail1) == 0 {
+ t.Fatalf("did not receive any email for filter 1")
+ }
+
+}
+
+func TestSymmetricSendWithoutAKey(t *testing.T) {
+ InitSingleTest()
+
+ w := New(&DefaultConfig)
+ defer w.SetMinimumPoW(DefaultMinimumPoW)
+ defer w.SetMaxMessageSize(DefaultMaxMessageSize)
+ w.Start(nil)
+ defer w.Stop()
+
+ filter, err := generateFilter(t, true)
+ if err != nil {
+ t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
+ }
+ filter.PoW = DefaultMinimumPoW
+
+ params, err := generateMessageParams()
+ if err != nil {
+ t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
+ }
+
+ filter.Src = nil
+
+ params.KeySym = filter.KeySym
+ params.Topic = BytesToTopic(filter.Topics[2])
+ params.PoW = filter.PoW
+ params.WorkTime = 10
+ params.TTL = 50
+ msg, err := NewSentMessage(params)
+ if err != nil {
+ t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
+ }
+ env, err := msg.Wrap(params)
+ if err != nil {
+ t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
+ }
+
+ _, err = w.Subscribe(filter)
+ if err != nil {
+ t.Fatalf("failed subscribe 1 with seed %d: %s.", seed, err)
+ }
+
+ err = w.Send(env)
+ if err != nil {
+ t.Fatalf("Failed sending envelope with PoW %.06f (seed %d): %s", env.PoW(), seed, err)
+ }
+
+ // wait till received or timeout
+ var received bool
+ for j := 0; j < 200; j++ {
+ time.Sleep(10 * time.Millisecond)
+ if len(w.Envelopes()) > 0 {
+ received = true
+ break
+ }
+ }
+
+ if !received {
+ t.Fatalf("did not receive the sent envelope, seed: %d.", seed)
+ }
+
+ // check w.messages()
+ time.Sleep(5 * time.Millisecond)
+ mail := filter.Retrieve()
+ if len(mail) == 0 {
+ t.Fatalf("did not receive message in spite of not setting a public key")
+ }
+}
+
+func TestSymmetricSendKeyMismatch(t *testing.T) {
+ InitSingleTest()
+
+ w := New(&DefaultConfig)
+ defer w.SetMinimumPoW(DefaultMinimumPoW)
+ defer w.SetMaxMessageSize(DefaultMaxMessageSize)
+ w.Start(nil)
+ defer w.Stop()
+
+ filter, err := generateFilter(t, true)
+ if err != nil {
+ t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
+ }
+ filter.PoW = DefaultMinimumPoW
+
+ params, err := generateMessageParams()
+ if err != nil {
+ t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
+ }
+
+ params.KeySym = filter.KeySym
+ params.Topic = BytesToTopic(filter.Topics[2])
+ params.PoW = filter.PoW
+ params.WorkTime = 10
+ params.TTL = 50
+ msg, err := NewSentMessage(params)
+ if err != nil {
+ t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
+ }
+ env, err := msg.Wrap(params)
+ if err != nil {
+ t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
+ }
+
+ _, err = w.Subscribe(filter)
+ if err != nil {
+ t.Fatalf("failed subscribe 1 with seed %d: %s.", seed, err)
+ }
+
+ err = w.Send(env)
+ if err != nil {
+ t.Fatalf("Failed sending envelope with PoW %.06f (seed %d): %s", env.PoW(), seed, err)
+ }
+
+ // wait till received or timeout
+ var received bool
+ for j := 0; j < 200; j++ {
+ time.Sleep(10 * time.Millisecond)
+ if len(w.Envelopes()) > 0 {
+ received = true
+ break
+ }
+ }
+
+ if !received {
+ t.Fatalf("did not receive the sent envelope, seed: %d.", seed)
+ }
+
+ // check w.messages()
+ time.Sleep(5 * time.Millisecond)
+ mail := filter.Retrieve()
+ if len(mail) > 0 {
+ t.Fatalf("received a message when keys weren't matching")
+ }
+}