allow multiple topics in mailserver requests (#1240)

* allow multiple topics in mailserver requests

* simplify topicsToBloom function

* create test topics simply from the string without hash

* add deprecated comment to MessagesRequest.Topic
This commit is contained in:
Andrea Franz 2018-10-15 23:15:04 +02:00 committed by GitHub
parent 20f8f1f2cc
commit c86f8bf6ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 71 additions and 1 deletions

View File

@ -7,6 +7,7 @@ import (
"encoding/hex" "encoding/hex"
"errors" "errors"
"fmt" "fmt"
"math/big"
"time" "time"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@ -63,8 +64,12 @@ type MessagesRequest struct {
Cursor string `json:"cursor"` Cursor string `json:"cursor"`
// Topic is a regular Whisper topic. // Topic is a regular Whisper topic.
// DEPRECATED
Topic whisper.TopicType `json:"topic"` Topic whisper.TopicType `json:"topic"`
// Topics is a list of Whisper topics.
Topics []whisper.TopicType `json:"topics"`
// SymKeyID is an ID of a symmetric key to authenticate to MailServer. // SymKeyID is an ID of a symmetric key to authenticate to MailServer.
// It's derived from MailServer password. // It's derived from MailServer password.
// //
@ -427,7 +432,7 @@ func makePayload(r MessagesRequest) []byte {
// to // to
binary.BigEndian.PutUint32(data[4:], r.To) binary.BigEndian.PutUint32(data[4:], r.To)
// bloom // bloom
copy(data[8:], whisper.TopicToBloom(r.Topic)) copy(data[8:], createBloomFilter(r))
// limit // limit
binary.BigEndian.PutUint32(data[8+whisper.BloomFilterSize:], r.Limit) binary.BigEndian.PutUint32(data[8+whisper.BloomFilterSize:], r.Limit)
@ -441,3 +446,25 @@ func makePayload(r MessagesRequest) []byte {
return append(data, cursorBytes...) return append(data, cursorBytes...)
} }
func createBloomFilter(r MessagesRequest) []byte {
if len(r.Topics) > 0 {
return topicsToBloom(r.Topics...)
}
return whisper.TopicToBloom(r.Topic)
}
func topicsToBloom(topics ...whisper.TopicType) []byte {
i := new(big.Int)
for _, topic := range topics {
bloom := whisper.TopicToBloom(topic)
i.Or(i, new(big.Int).SetBytes(bloom[:]))
}
combined := make([]byte, whisper.BloomFilterSize)
data := i.Bytes()
copy(combined[whisper.BloomFilterSize-len(data):], data[:])
return combined
}

View File

@ -5,6 +5,8 @@ import (
"testing" "testing"
"time" "time"
whisper "github.com/status-im/whisper/whisperv6"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -52,3 +54,44 @@ func TestMessagesRequest_setDefaults(t *testing.T) {
}) })
} }
} }
func TestTopicsToBloom(t *testing.T) {
t1 := stringToTopic("t1")
b1 := whisper.TopicToBloom(t1)
t2 := stringToTopic("t2")
b2 := whisper.TopicToBloom(t2)
t3 := stringToTopic("t3")
b3 := whisper.TopicToBloom(t3)
reqBloom := topicsToBloom(t1)
assert.True(t, whisper.BloomFilterMatch(reqBloom, b1))
assert.False(t, whisper.BloomFilterMatch(reqBloom, b2))
assert.False(t, whisper.BloomFilterMatch(reqBloom, b3))
reqBloom = topicsToBloom(t1, t2)
assert.True(t, whisper.BloomFilterMatch(reqBloom, b1))
assert.True(t, whisper.BloomFilterMatch(reqBloom, b2))
assert.False(t, whisper.BloomFilterMatch(reqBloom, b3))
reqBloom = topicsToBloom(t1, t2, t3)
assert.True(t, whisper.BloomFilterMatch(reqBloom, b1))
assert.True(t, whisper.BloomFilterMatch(reqBloom, b2))
assert.True(t, whisper.BloomFilterMatch(reqBloom, b3))
}
func TestCreateBloomFilter(t *testing.T) {
t1 := stringToTopic("t1")
t2 := stringToTopic("t2")
req := MessagesRequest{Topic: t1}
bloom := createBloomFilter(req)
assert.Equal(t, topicsToBloom(t1), bloom)
req = MessagesRequest{Topics: []whisper.TopicType{t1, t2}}
bloom = createBloomFilter(req)
assert.Equal(t, topicsToBloom(t1, t2), bloom)
}
func stringToTopic(s string) whisper.TopicType {
return whisper.BytesToTopic([]byte(s))
}