mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 06:36:43 +00:00
whisper: filter tests added
This commit is contained in:
parent
ab7c1e0e25
commit
b1de5d8fa5
4 changed files with 699 additions and 32 deletions
|
|
@ -44,8 +44,9 @@ type Envelope struct {
|
||||||
Data []byte
|
Data []byte
|
||||||
EnvNonce uint64
|
EnvNonce uint64
|
||||||
|
|
||||||
hash common.Hash // Cached hash of the envelope to avoid rehashing every time
|
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.
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewEnvelope wraps a Whisper message with expiration and destination data
|
// NewEnvelope wraps a Whisper message with expiration and destination data
|
||||||
|
|
@ -225,7 +226,7 @@ func (e *Envelope) Open(watcher *Filter) (msg *ReceivedMessage) {
|
||||||
msg.PoW = e.PoW()
|
msg.PoW = e.PoW()
|
||||||
msg.TTL = e.TTL
|
msg.TTL = e.TTL
|
||||||
msg.Sent = e.Expiry - e.TTL
|
msg.Sent = e.Expiry - e.TTL
|
||||||
msg.EnvelopeHash = e.hash
|
msg.EnvelopeHash = e.Hash()
|
||||||
msg.EnvelopeVersion = e.Ver()
|
msg.EnvelopeVersion = e.Ver()
|
||||||
}
|
}
|
||||||
return msg
|
return msg
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,6 @@ func (f *Filter) MatchMessage(msg *ReceivedMessage) bool {
|
||||||
if f.PoW > 0 && msg.PoW < f.PoW {
|
if f.PoW > 0 && msg.PoW < f.PoW {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.Src != nil && !isPubKeyEqual(msg.Src, f.Src) {
|
if f.Src != nil && !isPubKeyEqual(msg.Src, f.Src) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
@ -165,7 +164,8 @@ func (f *Filter) MatchEnvelope(envelope *Envelope) bool {
|
||||||
if f.expectsAsymmetricEncryption() && envelope.isAsymmetric() {
|
if f.expectsAsymmetricEncryption() && envelope.isAsymmetric() {
|
||||||
encryptionMethodMatch = true
|
encryptionMethodMatch = true
|
||||||
if f.Topics == nil {
|
if f.Topics == nil {
|
||||||
return true // wildcard
|
// wildcard
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
} else if f.expectsSymmetricEncryption() && envelope.IsSymmetric() {
|
} else if f.expectsSymmetricEncryption() && envelope.IsSymmetric() {
|
||||||
encryptionMethodMatch = true
|
encryptionMethodMatch = true
|
||||||
|
|
|
||||||
|
|
@ -16,17 +16,690 @@
|
||||||
|
|
||||||
package whisperv5
|
package whisperv5
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"math/big"
|
||||||
|
"math/rand"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
func TestFilters(x *testing.T) {
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
)
|
||||||
|
|
||||||
|
var seed int64
|
||||||
|
|
||||||
|
// InitSingleTest should be called in the beginning of every
|
||||||
|
// test, which uses RNG, in order to make the tests
|
||||||
|
// reproduciblity independent of their sequence.
|
||||||
|
func InitSingleTest() {
|
||||||
|
seed = time.Now().Unix()
|
||||||
|
rand.Seed(seed)
|
||||||
|
}
|
||||||
|
|
||||||
|
func InitDebugTest(i int64) {
|
||||||
|
seed = i
|
||||||
|
rand.Seed(seed)
|
||||||
|
}
|
||||||
|
|
||||||
|
type FilterTestCase struct {
|
||||||
|
f *Filter
|
||||||
|
id int
|
||||||
|
alive bool
|
||||||
|
msgCnt int
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateFilter(x *testing.T, symmetric bool) (*Filter, error) {
|
||||||
|
var f Filter
|
||||||
|
f.Messages = make(map[common.Hash]*ReceivedMessage)
|
||||||
|
|
||||||
|
const topicNum = 8
|
||||||
|
f.Topics = make([]TopicType, topicNum)
|
||||||
|
for i := 0; i < topicNum; i++ {
|
||||||
|
randomize(f.Topics[i][:])
|
||||||
|
f.Topics[i][0] = 0x01
|
||||||
|
}
|
||||||
|
|
||||||
|
key, err := crypto.GenerateKey()
|
||||||
|
if err != nil {
|
||||||
|
x.Errorf("generateFilter failed 1 with seed %d.", seed)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
f.Src = &key.PublicKey
|
||||||
|
|
||||||
|
if symmetric {
|
||||||
|
f.KeySym = make([]byte, 12)
|
||||||
|
randomize(f.KeySym)
|
||||||
|
f.SymKeyHash = crypto.Keccak256Hash(f.KeySym)
|
||||||
|
} else {
|
||||||
|
f.KeyAsym, err = crypto.GenerateKey()
|
||||||
|
if err != nil {
|
||||||
|
x.Errorf("generateFilter failed 2 with seed %d.", seed)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AcceptP2P & PoW are not set
|
||||||
|
return &f, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateTestCases(x *testing.T, SizeTestFilters int) []FilterTestCase {
|
||||||
|
cases := make([]FilterTestCase, SizeTestFilters)
|
||||||
|
for i := 0; i < SizeTestFilters; i++ {
|
||||||
|
f, _ := generateFilter(x, true)
|
||||||
|
cases[i].f = f
|
||||||
|
cases[i].alive = (rand.Int()&int(1) == 0)
|
||||||
|
}
|
||||||
|
return cases
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInstallFilters(x *testing.T) {
|
||||||
|
InitSingleTest()
|
||||||
|
|
||||||
|
const SizeTestFilters = 256
|
||||||
filters := NewFilters(nil)
|
filters := NewFilters(nil)
|
||||||
f := Filter{}
|
tst := generateTestCases(x, SizeTestFilters)
|
||||||
filters.Install(&f)
|
|
||||||
i := filters.Install(&f)
|
var j int
|
||||||
if i == 0 {
|
for i := 0; i < SizeTestFilters; i++ {
|
||||||
x.Errorf("failed install")
|
j = filters.Install(tst[i].f)
|
||||||
|
tst[i].id = j
|
||||||
|
}
|
||||||
|
|
||||||
|
if j < SizeTestFilters-1 {
|
||||||
|
x.Errorf("seed %d: wrong index %d", seed, j)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: test Install, Uninstall, Get
|
for _, t := range tst {
|
||||||
|
if !t.alive {
|
||||||
|
filters.Uninstall(t.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, t := range tst {
|
||||||
|
fil := filters.Get(t.id)
|
||||||
|
exist := (fil != nil)
|
||||||
|
if exist != t.alive {
|
||||||
|
x.Errorf("seed %d: failed alive: %d, %v, %v", seed, i, exist, t.alive)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if exist && fil.PoW != t.f.PoW {
|
||||||
|
x.Errorf("seed %d: failed Get: %d, %v, %v", seed, i, exist, t.alive)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestComparePubKey(x *testing.T) {
|
||||||
|
InitSingleTest()
|
||||||
|
|
||||||
|
key1, err := crypto.GenerateKey()
|
||||||
|
if err != nil {
|
||||||
|
x.Errorf("failed GenerateKey 1 with seed %d: %s.", seed, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
key2, err := crypto.GenerateKey()
|
||||||
|
if err != nil {
|
||||||
|
x.Errorf("failed GenerateKey 2 with seed %d: %s.", seed, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if isPubKeyEqual(&key1.PublicKey, &key2.PublicKey) {
|
||||||
|
x.Errorf("failed !equal with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate key3 == key1
|
||||||
|
rand.Seed(seed)
|
||||||
|
key3, err := crypto.GenerateKey()
|
||||||
|
if err != nil {
|
||||||
|
x.Errorf("failed GenerateKey 3 with seed %d: %s.", seed, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if isPubKeyEqual(&key1.PublicKey, &key3.PublicKey) {
|
||||||
|
x.Errorf("failed equal with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMatchEnvelope(x *testing.T) {
|
||||||
|
InitSingleTest()
|
||||||
|
|
||||||
|
fsym, err := generateFilter(x, true)
|
||||||
|
if err != nil {
|
||||||
|
x.Errorf("failed generateFilter 1 with seed %d: %s.", seed, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fasym, err := generateFilter(x, false)
|
||||||
|
if err != nil {
|
||||||
|
x.Errorf("failed generateFilter 2 with seed %d: %s.", seed, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
params, err := generateMessageParams()
|
||||||
|
if err != nil {
|
||||||
|
x.Errorf("failed generateMessageParams 3 with seed %d: %s.", seed, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
params.Topic[0] = 0xFF // ensure mismatch
|
||||||
|
|
||||||
|
// mismatch with pseudo-random data
|
||||||
|
msg := NewSentMessage(params)
|
||||||
|
env, err := msg.Wrap(params)
|
||||||
|
if err != nil {
|
||||||
|
x.Errorf("failed Wrap 4 with seed %d: %s.", seed, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
match := fsym.MatchEnvelope(env)
|
||||||
|
if match {
|
||||||
|
x.Errorf("failed test case 5 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
match = fasym.MatchEnvelope(env)
|
||||||
|
if match {
|
||||||
|
x.Errorf("failed test case 6 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// encrypt symmetrically
|
||||||
|
i := rand.Int() % 4
|
||||||
|
fsym.Topics[i] = params.Topic
|
||||||
|
fasym.Topics[i] = params.Topic
|
||||||
|
msg = NewSentMessage(params)
|
||||||
|
env, err = msg.Wrap(params)
|
||||||
|
if err != nil {
|
||||||
|
x.Errorf("failed test case 7 with seed %d, test case 3: %s.", seed, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// symmetric + matching topic: match
|
||||||
|
match = fsym.MatchEnvelope(env)
|
||||||
|
if !match {
|
||||||
|
x.Errorf("failed test case 8 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// asymmetric + matching topic: mismatch
|
||||||
|
match = fasym.MatchEnvelope(env)
|
||||||
|
if match {
|
||||||
|
x.Errorf("failed test case 9 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// symmetric + matching topic + insufficient PoW: mismatch
|
||||||
|
fsym.PoW = env.PoW() + 1.0
|
||||||
|
match = fsym.MatchEnvelope(env)
|
||||||
|
if match {
|
||||||
|
x.Errorf("failed test case 10 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// symmetric + matching topic + sufficient PoW: match
|
||||||
|
fsym.PoW = env.PoW() / 2
|
||||||
|
match = fsym.MatchEnvelope(env)
|
||||||
|
if !match {
|
||||||
|
x.Errorf("failed test case 11 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// symmetric + topics are nil: mismatch
|
||||||
|
prevTopics := fsym.Topics
|
||||||
|
fsym.Topics = nil
|
||||||
|
match = fasym.MatchEnvelope(env)
|
||||||
|
if match {
|
||||||
|
x.Errorf("failed test case 12 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fsym.Topics = prevTopics
|
||||||
|
|
||||||
|
// encrypt asymmetrically
|
||||||
|
key, err := crypto.GenerateKey()
|
||||||
|
if err != nil {
|
||||||
|
x.Errorf("failed GenerateKey 13 with seed %d: %s.", seed, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
params.KeySym = nil
|
||||||
|
params.Dst = &key.PublicKey
|
||||||
|
msg = NewSentMessage(params)
|
||||||
|
env, err = msg.Wrap(params)
|
||||||
|
if err != nil {
|
||||||
|
x.Errorf("failed test case 14 with seed %d, test case 3: %s.", seed, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// encryption method mismatch
|
||||||
|
match = fsym.MatchEnvelope(env)
|
||||||
|
if match {
|
||||||
|
x.Errorf("failed test case 15 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// asymmetric + mismatching topic: mismatch
|
||||||
|
match = fasym.MatchEnvelope(env)
|
||||||
|
if !match {
|
||||||
|
x.Errorf("failed test case 16 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// asymmetric + matching topic: match
|
||||||
|
fasym.Topics[i] = fasym.Topics[i+1]
|
||||||
|
match = fasym.MatchEnvelope(env)
|
||||||
|
if match {
|
||||||
|
x.Errorf("failed test case 17 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// asymmetric + topic is nil (wildcard): match
|
||||||
|
fasym.Topics = nil
|
||||||
|
match = fasym.MatchEnvelope(env)
|
||||||
|
if !match {
|
||||||
|
x.Errorf("failed test case 18 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// asymmetric + insufficient PoW: mismatch
|
||||||
|
fasym.PoW = env.PoW() + 1.0
|
||||||
|
match = fasym.MatchEnvelope(env)
|
||||||
|
if match {
|
||||||
|
x.Errorf("failed test case 19 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// asymmetric + sufficient PoW: match
|
||||||
|
fasym.PoW = env.PoW() / 2
|
||||||
|
match = fasym.MatchEnvelope(env)
|
||||||
|
if !match {
|
||||||
|
x.Errorf("failed test case 20 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMatchMessageSym(x *testing.T) {
|
||||||
|
InitSingleTest()
|
||||||
|
|
||||||
|
params, err := generateMessageParams()
|
||||||
|
if err != nil {
|
||||||
|
x.Errorf("failed generateMessageParams with seed %d: %s.", seed, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := generateFilter(x, true)
|
||||||
|
if err != nil {
|
||||||
|
x.Errorf("failed generateFilter 1 with seed %d: %s.", seed, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const index = 1
|
||||||
|
params.KeySym = f.KeySym
|
||||||
|
params.Topic = f.Topics[index]
|
||||||
|
|
||||||
|
sentMessage := NewSentMessage(params)
|
||||||
|
env, err := sentMessage.Wrap(params)
|
||||||
|
if err != nil {
|
||||||
|
x.Errorf("failed Wrap 2 with seed %d: %s.", seed, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := env.Open(f)
|
||||||
|
if msg == nil {
|
||||||
|
x.Errorf("failed to open 3 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Src mismatch
|
||||||
|
if f.MatchMessage(msg) {
|
||||||
|
x.Errorf("failed test case 4 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Src: match
|
||||||
|
*f.Src.X = *params.Src.PublicKey.X
|
||||||
|
*f.Src.Y = *params.Src.PublicKey.Y
|
||||||
|
if !f.MatchMessage(msg) {
|
||||||
|
x.Errorf("failed test case 5 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// insufficient PoW: mismatch
|
||||||
|
f.PoW = msg.PoW + 1.0
|
||||||
|
if f.MatchMessage(msg) {
|
||||||
|
x.Errorf("failed test case 6 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// sufficient PoW: match
|
||||||
|
f.PoW = msg.PoW / 2
|
||||||
|
if !f.MatchMessage(msg) {
|
||||||
|
x.Errorf("failed test case 7 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// topic mismatch
|
||||||
|
f.Topics[index][0]++
|
||||||
|
if f.MatchMessage(msg) {
|
||||||
|
x.Errorf("failed test case 8 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f.Topics[index][0]--
|
||||||
|
|
||||||
|
// key mismatch
|
||||||
|
f.SymKeyHash[0]++
|
||||||
|
if f.MatchMessage(msg) {
|
||||||
|
x.Errorf("failed test case 9 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f.SymKeyHash[0]--
|
||||||
|
|
||||||
|
// Src absent: match
|
||||||
|
f.Src = nil
|
||||||
|
if !f.MatchMessage(msg) {
|
||||||
|
x.Errorf("failed test case 10 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// key hash mismatch mismatch
|
||||||
|
h := f.SymKeyHash
|
||||||
|
f.SymKeyHash = common.Hash{}
|
||||||
|
if f.MatchMessage(msg) {
|
||||||
|
x.Errorf("failed test case 11 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f.SymKeyHash = h
|
||||||
|
if !f.MatchMessage(msg) {
|
||||||
|
x.Errorf("failed test case 12 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// encryption method mismatch
|
||||||
|
f.KeySym = nil
|
||||||
|
f.KeyAsym, err = crypto.GenerateKey()
|
||||||
|
if err != nil {
|
||||||
|
x.Errorf("failed GenerateKey 13 with seed %d: %s.", seed, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if f.MatchMessage(msg) {
|
||||||
|
x.Errorf("failed test case 14 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMatchMessageAsym(x *testing.T) {
|
||||||
|
InitSingleTest()
|
||||||
|
|
||||||
|
f, err := generateFilter(x, false)
|
||||||
|
if err != nil {
|
||||||
|
x.Errorf("failed generateFilter with seed %d: %s.", seed, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
params, err := generateMessageParams()
|
||||||
|
if err != nil {
|
||||||
|
x.Errorf("failed generateMessageParams with seed %d: %s.", seed, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const index = 1
|
||||||
|
params.Topic = f.Topics[index]
|
||||||
|
params.Dst = &f.KeyAsym.PublicKey
|
||||||
|
keySymOrig := params.KeySym
|
||||||
|
params.KeySym = nil
|
||||||
|
|
||||||
|
sentMessage := NewSentMessage(params)
|
||||||
|
env, err := sentMessage.Wrap(params)
|
||||||
|
if err != nil {
|
||||||
|
x.Errorf("failed Wrap with seed %d: %s.", seed, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := env.Open(f)
|
||||||
|
if msg == nil {
|
||||||
|
x.Errorf("failed to open with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Src mismatch
|
||||||
|
if f.MatchMessage(msg) {
|
||||||
|
x.Errorf("failed test case 4 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Src: match
|
||||||
|
*f.Src.X = *params.Src.PublicKey.X
|
||||||
|
*f.Src.Y = *params.Src.PublicKey.Y
|
||||||
|
if !f.MatchMessage(msg) {
|
||||||
|
x.Errorf("failed test case 5 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// insufficient PoW: mismatch
|
||||||
|
f.PoW = msg.PoW + 1.0
|
||||||
|
if f.MatchMessage(msg) {
|
||||||
|
x.Errorf("failed test case 6 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// sufficient PoW: match
|
||||||
|
f.PoW = msg.PoW / 2
|
||||||
|
if !f.MatchMessage(msg) {
|
||||||
|
x.Errorf("failed test case 7 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// topic mismatch, but still match, because for asymmetric encryption
|
||||||
|
// only private key matters (in case the message is already decrypted)
|
||||||
|
f.Topics[index][0]++
|
||||||
|
if !f.MatchMessage(msg) {
|
||||||
|
x.Errorf("failed test case 8 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f.Topics[index][0]--
|
||||||
|
|
||||||
|
// key mismatch
|
||||||
|
prev := *f.KeyAsym.PublicKey.X
|
||||||
|
zero := *big.NewInt(0)
|
||||||
|
*f.KeyAsym.PublicKey.X = zero
|
||||||
|
if f.MatchMessage(msg) {
|
||||||
|
x.Errorf("failed test case 9 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
*f.KeyAsym.PublicKey.X = prev
|
||||||
|
|
||||||
|
// Src absent: match
|
||||||
|
f.Src = nil
|
||||||
|
if !f.MatchMessage(msg) {
|
||||||
|
x.Errorf("failed test case 10 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// encryption method mismatch
|
||||||
|
f.KeySym = keySymOrig
|
||||||
|
f.KeyAsym = nil
|
||||||
|
if f.MatchMessage(msg) {
|
||||||
|
x.Errorf("failed test case 11 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func cloneFilter(orig *Filter) *Filter {
|
||||||
|
var clone Filter
|
||||||
|
clone.Messages = make(map[common.Hash]*ReceivedMessage)
|
||||||
|
clone.Src = orig.Src
|
||||||
|
clone.KeyAsym = orig.KeyAsym
|
||||||
|
clone.KeySym = orig.KeySym
|
||||||
|
clone.Topics = orig.Topics
|
||||||
|
clone.PoW = orig.PoW
|
||||||
|
clone.AcceptP2P = orig.AcceptP2P
|
||||||
|
clone.SymKeyHash = orig.SymKeyHash
|
||||||
|
return &clone
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateCompatibeEnvelope(x *testing.T, f *Filter) *Envelope {
|
||||||
|
params, err := generateMessageParams()
|
||||||
|
if err != nil {
|
||||||
|
x.Errorf("failed generateMessageParams 77 with seed %d: %s.", seed, err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
params.KeySym = f.KeySym
|
||||||
|
params.Topic = f.Topics[2]
|
||||||
|
sentMessage := NewSentMessage(params)
|
||||||
|
env, err := sentMessage.Wrap(params)
|
||||||
|
if err != nil {
|
||||||
|
x.Errorf("failed Wrap 78 with seed %d: %s.", seed, err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return env
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWatchers(x *testing.T) {
|
||||||
|
InitSingleTest()
|
||||||
|
|
||||||
|
const NumFilters = 16
|
||||||
|
const NumMessages = 256
|
||||||
|
var i, j int
|
||||||
|
var e *Envelope
|
||||||
|
|
||||||
|
filters := NewFilters(nil)
|
||||||
|
tst := generateTestCases(x, NumFilters)
|
||||||
|
for i = 0; i < NumFilters; i++ {
|
||||||
|
tst[i].f.Src = nil
|
||||||
|
j = filters.Install(tst[i].f)
|
||||||
|
tst[i].id = j
|
||||||
|
}
|
||||||
|
|
||||||
|
last := j
|
||||||
|
|
||||||
|
var envelopes [NumMessages]*Envelope
|
||||||
|
for i = 0; i < NumMessages; i++ {
|
||||||
|
j = rand.Int() % NumFilters
|
||||||
|
e = generateCompatibeEnvelope(x, tst[j].f)
|
||||||
|
envelopes[i] = e
|
||||||
|
tst[j].msgCnt++
|
||||||
|
}
|
||||||
|
|
||||||
|
for i = 0; i < NumMessages; i++ {
|
||||||
|
filters.NotifyWatchers(envelopes[i], messagesCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
var total int
|
||||||
|
var mail []*ReceivedMessage
|
||||||
|
var count [NumFilters]int
|
||||||
|
|
||||||
|
for i = 0; i < NumFilters; i++ {
|
||||||
|
mail = tst[i].f.Retrieve()
|
||||||
|
count[i] = len(mail)
|
||||||
|
total += len(mail)
|
||||||
|
}
|
||||||
|
|
||||||
|
if total != NumMessages {
|
||||||
|
x.Errorf("failed test case 1 with seed %d: total = %d, want: %d.", seed, total, NumMessages)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for i = 0; i < NumFilters; i++ {
|
||||||
|
mail = tst[i].f.Retrieve()
|
||||||
|
if len(mail) != 0 {
|
||||||
|
x.Errorf("failed test case 2 with seed %d: i = %d.", seed, i)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if tst[i].msgCnt != count[i] {
|
||||||
|
x.Errorf("failed test case 3 with seed %d: i = %d, get %d, want %d.", seed, i, tst[i].msgCnt, count[i])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// another round with a cloned filter
|
||||||
|
|
||||||
|
clone := cloneFilter(tst[0].f)
|
||||||
|
filters.Uninstall(last)
|
||||||
|
total = 0
|
||||||
|
last = NumFilters - 1
|
||||||
|
tst[last].f = clone
|
||||||
|
filters.Install(clone)
|
||||||
|
for i = 0; i < NumFilters; i++ {
|
||||||
|
tst[i].msgCnt = 0
|
||||||
|
count[i] = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure that the first watcher receives at least one message
|
||||||
|
e = generateCompatibeEnvelope(x, tst[0].f)
|
||||||
|
envelopes[0] = e
|
||||||
|
tst[0].msgCnt++
|
||||||
|
for i = 1; i < NumMessages; i++ {
|
||||||
|
j = rand.Int() % NumFilters
|
||||||
|
e = generateCompatibeEnvelope(x, tst[j].f)
|
||||||
|
envelopes[i] = e
|
||||||
|
tst[j].msgCnt++
|
||||||
|
}
|
||||||
|
|
||||||
|
for i = 0; i < NumMessages; i++ {
|
||||||
|
filters.NotifyWatchers(envelopes[i], messagesCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i = 0; i < NumFilters; i++ {
|
||||||
|
mail = tst[i].f.Retrieve()
|
||||||
|
count[i] = len(mail)
|
||||||
|
total += len(mail)
|
||||||
|
}
|
||||||
|
|
||||||
|
combined := tst[0].msgCnt + tst[last].msgCnt
|
||||||
|
if total != NumMessages+count[0] {
|
||||||
|
x.Errorf("failed test case 4 with seed %d: total = %d, count[0] = %d.", seed, total, count[0])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if combined != count[0] {
|
||||||
|
x.Errorf("failed test case 5 with seed %d: combined = %d, count[0] = %d.", seed, combined, count[0])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if combined != count[last] {
|
||||||
|
x.Errorf("failed test case 6 with seed %d: combined = %d, count[last] = %d.", seed, combined, count[last])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for i = 1; i < NumFilters-1; i++ {
|
||||||
|
mail = tst[i].f.Retrieve()
|
||||||
|
if len(mail) != 0 {
|
||||||
|
x.Errorf("failed test case 7 with seed %d: i = %d.", seed, i)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if tst[i].msgCnt != count[i] {
|
||||||
|
x.Errorf("failed test case 8 with seed %d: i = %d, get %d, want %d.", seed, i, tst[i].msgCnt, count[i])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// test AcceptP2P
|
||||||
|
|
||||||
|
total = 0
|
||||||
|
filters.NotifyWatchers(envelopes[0], p2pCode)
|
||||||
|
|
||||||
|
for i = 0; i < NumFilters; i++ {
|
||||||
|
mail = tst[i].f.Retrieve()
|
||||||
|
total += len(mail)
|
||||||
|
}
|
||||||
|
|
||||||
|
if total != 0 {
|
||||||
|
x.Errorf("failed test case 9 with seed %d.", seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
f := filters.Get(0)
|
||||||
|
f.AcceptP2P = true
|
||||||
|
total = 0
|
||||||
|
filters.NotifyWatchers(envelopes[0], p2pCode)
|
||||||
|
|
||||||
|
for i = 0; i < NumFilters; i++ {
|
||||||
|
mail = tst[i].f.Retrieve()
|
||||||
|
total += len(mail)
|
||||||
|
}
|
||||||
|
|
||||||
|
if total != 1 {
|
||||||
|
x.Errorf("failed test case 10 with seed %d: total = %d.", seed, total)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
)
|
)
|
||||||
|
|
@ -54,10 +53,11 @@ func generateMessageParams() (*MessageParams, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// p.Dst, p.PoW, p.WorkTime are not set
|
// p.Dst, p.PoW, p.WorkTime are not set
|
||||||
|
p.PoW = 0.01
|
||||||
return &p, nil
|
return &p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func singleMessageTest(x *testing.T, seed int64, symmetric bool) {
|
func singleMessageTest(x *testing.T, symmetric bool) {
|
||||||
params, err := generateMessageParams()
|
params, err := generateMessageParams()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
x.Errorf("failed generateMessageParams with seed %d: %s.", seed, err)
|
x.Errorf("failed generateMessageParams with seed %d: %s.", seed, err)
|
||||||
|
|
@ -130,18 +130,17 @@ func singleMessageTest(x *testing.T, seed int64, symmetric bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMessageEncryption(x *testing.T) {
|
func TestMessageEncryption(x *testing.T) {
|
||||||
seed := time.Now().Unix()
|
InitSingleTest()
|
||||||
rand.Seed(seed)
|
|
||||||
var symmetric bool
|
|
||||||
|
|
||||||
|
var symmetric bool
|
||||||
for i := 0; i < 256; i++ {
|
for i := 0; i < 256; i++ {
|
||||||
singleMessageTest(x, seed, symmetric)
|
singleMessageTest(x, symmetric)
|
||||||
symmetric = !symmetric
|
symmetric = !symmetric
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMessageWrap(x *testing.T) {
|
func TestMessageWrap(x *testing.T) {
|
||||||
seed := int64(1777444222)
|
seed = int64(1777444222)
|
||||||
rand.Seed(seed)
|
rand.Seed(seed)
|
||||||
target := 128.0
|
target := 128.0
|
||||||
|
|
||||||
|
|
@ -169,7 +168,8 @@ func TestMessageWrap(x *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMessageSeal(x *testing.T) {
|
func TestMessageSeal(x *testing.T) {
|
||||||
seed := int64(1976726903)
|
// this test depends on deterministic choice of seed (1976726903)
|
||||||
|
seed = int64(1976726903)
|
||||||
rand.Seed(seed)
|
rand.Seed(seed)
|
||||||
|
|
||||||
params, err := generateMessageParams()
|
params, err := generateMessageParams()
|
||||||
|
|
@ -210,24 +210,22 @@ func TestMessageSeal(x *testing.T) {
|
||||||
env.calculatePoW(0)
|
env.calculatePoW(0)
|
||||||
pow = env.PoW()
|
pow = env.PoW()
|
||||||
if pow < 2*target {
|
if pow < 2*target {
|
||||||
// this depends on deterministic choice of seed (1976726903)
|
|
||||||
x.Errorf("failed Wrap with seed %d: pow too small %f.", seed, pow)
|
x.Errorf("failed Wrap with seed %d: pow too small %f.", seed, pow)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEnvelopeOpen(x *testing.T) {
|
func TestEnvelopeOpen(x *testing.T) {
|
||||||
seed := time.Now().Unix()
|
InitSingleTest()
|
||||||
rand.Seed(seed)
|
|
||||||
var symmetric bool
|
|
||||||
|
|
||||||
|
var symmetric bool
|
||||||
for i := 0; i < 256; i++ {
|
for i := 0; i < 256; i++ {
|
||||||
singleEnvelopeOpenTest(x, seed, symmetric)
|
singleEnvelopeOpenTest(x, symmetric)
|
||||||
symmetric = !symmetric
|
symmetric = !symmetric
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func singleEnvelopeOpenTest(x *testing.T, seed int64, symmetric bool) {
|
func singleEnvelopeOpenTest(x *testing.T, symmetric bool) {
|
||||||
params, err := generateMessageParams()
|
params, err := generateMessageParams()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
x.Errorf("failed generateMessageParams with seed %d: %s.", seed, err)
|
x.Errorf("failed generateMessageParams with seed %d: %s.", seed, err)
|
||||||
|
|
@ -266,11 +264,6 @@ func singleEnvelopeOpenTest(x *testing.T, seed int64, symmetric bool) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !decrypted.Validate() {
|
|
||||||
x.Errorf("failed to validate with seed %d.", seed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
padsz := len(decrypted.Padding)
|
padsz := len(decrypted.Padding)
|
||||||
if bytes.Compare(steg[:padsz], decrypted.Padding) != 0 {
|
if bytes.Compare(steg[:padsz], decrypted.Padding) != 0 {
|
||||||
x.Errorf("failed with seed %d: compare padding.", seed)
|
x.Errorf("failed with seed %d: compare padding.", seed)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue