github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/whisper/mailserver/server_test.go (about)

     1  // This file is part of the go-sberex library. The go-sberex library is 
     2  // free software: you can redistribute it and/or modify it under the terms 
     3  // of the GNU Lesser General Public License as published by the Free 
     4  // Software Foundation, either version 3 of the License, or (at your option)
     5  // any later version.
     6  //
     7  // The go-sberex library is distributed in the hope that it will be useful, 
     8  // but WITHOUT ANY WARRANTY; without even the implied warranty of
     9  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 
    10  // General Public License <http://www.gnu.org/licenses/> for more details.
    11  
    12  package mailserver
    13  
    14  import (
    15  	"crypto/ecdsa"
    16  	"encoding/binary"
    17  	"io/ioutil"
    18  	"math/rand"
    19  	"testing"
    20  	"time"
    21  
    22  	"github.com/Sberex/go-sberex/common"
    23  	"github.com/Sberex/go-sberex/crypto"
    24  	whisper "github.com/Sberex/go-sberex/whisper/whisperv6"
    25  )
    26  
    27  const powRequirement = 0.00001
    28  
    29  var keyID string
    30  var shh *whisper.Whisper
    31  var seed = time.Now().Unix()
    32  
    33  type ServerTestParams struct {
    34  	topic whisper.TopicType
    35  	low   uint32
    36  	upp   uint32
    37  	key   *ecdsa.PrivateKey
    38  }
    39  
    40  func assert(statement bool, text string, t *testing.T) {
    41  	if !statement {
    42  		t.Fatal(text)
    43  	}
    44  }
    45  
    46  func TestDBKey(t *testing.T) {
    47  	var h common.Hash
    48  	i := uint32(time.Now().Unix())
    49  	k := NewDbKey(i, h)
    50  	assert(len(k.raw) == common.HashLength+4, "wrong DB key length", t)
    51  	assert(byte(i%0x100) == k.raw[3], "raw representation should be big endian", t)
    52  	assert(byte(i/0x1000000) == k.raw[0], "big endian expected", t)
    53  }
    54  
    55  func generateEnvelope(t *testing.T) *whisper.Envelope {
    56  	h := crypto.Keccak256Hash([]byte("test sample data"))
    57  	params := &whisper.MessageParams{
    58  		KeySym:   h[:],
    59  		Topic:    whisper.TopicType{},
    60  		Payload:  []byte("test payload"),
    61  		PoW:      powRequirement,
    62  		WorkTime: 2,
    63  	}
    64  
    65  	msg, err := whisper.NewSentMessage(params)
    66  	if err != nil {
    67  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
    68  	}
    69  	env, err := msg.Wrap(params)
    70  	if err != nil {
    71  		t.Fatalf("failed to wrap with seed %d: %s.", seed, err)
    72  	}
    73  	return env
    74  }
    75  
    76  func TestMailServer(t *testing.T) {
    77  	const password = "password_for_this_test"
    78  	const dbPath = "whisper-server-test"
    79  
    80  	dir, err := ioutil.TempDir("", dbPath)
    81  	if err != nil {
    82  		t.Fatal(err)
    83  	}
    84  
    85  	var server WMailServer
    86  	shh = whisper.New(&whisper.DefaultConfig)
    87  	shh.RegisterServer(&server)
    88  
    89  	server.Init(shh, dir, password, powRequirement)
    90  	defer server.Close()
    91  
    92  	keyID, err = shh.AddSymKeyFromPassword(password)
    93  	if err != nil {
    94  		t.Fatalf("Failed to create symmetric key for mail request: %s", err)
    95  	}
    96  
    97  	rand.Seed(seed)
    98  	env := generateEnvelope(t)
    99  	server.Archive(env)
   100  	deliverTest(t, &server, env)
   101  }
   102  
   103  func deliverTest(t *testing.T, server *WMailServer, env *whisper.Envelope) {
   104  	id, err := shh.NewKeyPair()
   105  	if err != nil {
   106  		t.Fatalf("failed to generate new key pair with seed %d: %s.", seed, err)
   107  	}
   108  	testPeerID, err := shh.GetPrivateKey(id)
   109  	if err != nil {
   110  		t.Fatalf("failed to retrieve new key pair with seed %d: %s.", seed, err)
   111  	}
   112  	birth := env.Expiry - env.TTL
   113  	p := &ServerTestParams{
   114  		topic: env.Topic,
   115  		low:   birth - 1,
   116  		upp:   birth + 1,
   117  		key:   testPeerID,
   118  	}
   119  	singleRequest(t, server, env, p, true)
   120  
   121  	p.low, p.upp = birth+1, 0xffffffff
   122  	singleRequest(t, server, env, p, false)
   123  
   124  	p.low, p.upp = 0, birth-1
   125  	singleRequest(t, server, env, p, false)
   126  
   127  	p.low = birth - 1
   128  	p.upp = birth + 1
   129  	p.topic[0]++
   130  	singleRequest(t, server, env, p, false)
   131  }
   132  
   133  func singleRequest(t *testing.T, server *WMailServer, env *whisper.Envelope, p *ServerTestParams, expect bool) {
   134  	request := createRequest(t, p)
   135  	src := crypto.FromECDSAPub(&p.key.PublicKey)
   136  	ok, lower, upper, topic := server.validateRequest(src, request)
   137  	if !ok {
   138  		t.Fatalf("request validation failed, seed: %d.", seed)
   139  	}
   140  	if lower != p.low {
   141  		t.Fatalf("request validation failed (lower bound), seed: %d.", seed)
   142  	}
   143  	if upper != p.upp {
   144  		t.Fatalf("request validation failed (upper bound), seed: %d.", seed)
   145  	}
   146  	if topic != p.topic {
   147  		t.Fatalf("request validation failed (topic), seed: %d.", seed)
   148  	}
   149  
   150  	var exist bool
   151  	mail := server.processRequest(nil, p.low, p.upp, p.topic)
   152  	for _, msg := range mail {
   153  		if msg.Hash() == env.Hash() {
   154  			exist = true
   155  			break
   156  		}
   157  	}
   158  
   159  	if exist != expect {
   160  		t.Fatalf("error: exist = %v, seed: %d.", exist, seed)
   161  	}
   162  
   163  	src[0]++
   164  	ok, lower, upper, topic = server.validateRequest(src, request)
   165  	if ok {
   166  		t.Fatalf("request validation false positive, seed: %d (lower: %d, upper: %d).", seed, lower, upper)
   167  	}
   168  }
   169  
   170  func createRequest(t *testing.T, p *ServerTestParams) *whisper.Envelope {
   171  	data := make([]byte, 8+whisper.TopicLength)
   172  	binary.BigEndian.PutUint32(data, p.low)
   173  	binary.BigEndian.PutUint32(data[4:], p.upp)
   174  	copy(data[8:], p.topic[:])
   175  
   176  	key, err := shh.GetSymKey(keyID)
   177  	if err != nil {
   178  		t.Fatalf("failed to retrieve sym key with seed %d: %s.", seed, err)
   179  	}
   180  
   181  	params := &whisper.MessageParams{
   182  		KeySym:   key,
   183  		Topic:    p.topic,
   184  		Payload:  data,
   185  		PoW:      powRequirement * 2,
   186  		WorkTime: 2,
   187  		Src:      p.key,
   188  	}
   189  
   190  	msg, err := whisper.NewSentMessage(params)
   191  	if err != nil {
   192  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   193  	}
   194  	env, err := msg.Wrap(params)
   195  	if err != nil {
   196  		t.Fatalf("failed to wrap with seed %d: %s.", seed, err)
   197  	}
   198  	return env
   199  }