github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/whisper/mailserver/server_test.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 12:09:51</date>
    10  //</624342688057004032>
    11  
    12  //
    13  //
    14  //
    15  //
    16  //
    17  //
    18  //
    19  //
    20  //
    21  //
    22  //
    23  //
    24  //
    25  //
    26  //
    27  
    28  package mailserver
    29  
    30  import (
    31  	"bytes"
    32  	"crypto/ecdsa"
    33  	"encoding/binary"
    34  	"io/ioutil"
    35  	"math/rand"
    36  	"testing"
    37  	"time"
    38  
    39  	"github.com/ethereum/go-ethereum/common"
    40  	"github.com/ethereum/go-ethereum/crypto"
    41  	whisper "github.com/ethereum/go-ethereum/whisper/whisperv6"
    42  )
    43  
    44  const powRequirement = 0.00001
    45  
    46  var keyID string
    47  var shh *whisper.Whisper
    48  var seed = time.Now().Unix()
    49  
    50  type ServerTestParams struct {
    51  	topic whisper.TopicType
    52  	low   uint32
    53  	upp   uint32
    54  	key   *ecdsa.PrivateKey
    55  }
    56  
    57  func assert(statement bool, text string, t *testing.T) {
    58  	if !statement {
    59  		t.Fatal(text)
    60  	}
    61  }
    62  
    63  func TestDBKey(t *testing.T) {
    64  	var h common.Hash
    65  	i := uint32(time.Now().Unix())
    66  	k := NewDbKey(i, h)
    67  	assert(len(k.raw) == common.HashLength+4, "wrong DB key length", t)
    68  	assert(byte(i%0x100) == k.raw[3], "raw representation should be big endian", t)
    69  	assert(byte(i/0x1000000) == k.raw[0], "big endian expected", t)
    70  }
    71  
    72  func generateEnvelope(t *testing.T) *whisper.Envelope {
    73  	h := crypto.Keccak256Hash([]byte("test sample data"))
    74  	params := &whisper.MessageParams{
    75  		KeySym:   h[:],
    76  		Topic:    whisper.TopicType{0x1F, 0x7E, 0xA1, 0x7F},
    77  		Payload:  []byte("test payload"),
    78  		PoW:      powRequirement,
    79  		WorkTime: 2,
    80  	}
    81  
    82  	msg, err := whisper.NewSentMessage(params)
    83  	if err != nil {
    84  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
    85  	}
    86  	env, err := msg.Wrap(params)
    87  	if err != nil {
    88  		t.Fatalf("failed to wrap with seed %d: %s.", seed, err)
    89  	}
    90  	return env
    91  }
    92  
    93  func TestMailServer(t *testing.T) {
    94  	const password = "password_for_this_test"
    95  	const dbPath = "whisper-server-test"
    96  
    97  	dir, err := ioutil.TempDir("", dbPath)
    98  	if err != nil {
    99  		t.Fatal(err)
   100  	}
   101  
   102  	var server WMailServer
   103  	shh = whisper.New(&whisper.DefaultConfig)
   104  	shh.RegisterServer(&server)
   105  
   106  	err = server.Init(shh, dir, password, powRequirement)
   107  	if err != nil {
   108  		t.Fatal(err)
   109  	}
   110  	defer server.Close()
   111  
   112  	keyID, err = shh.AddSymKeyFromPassword(password)
   113  	if err != nil {
   114  		t.Fatalf("Failed to create symmetric key for mail request: %s", err)
   115  	}
   116  
   117  	rand.Seed(seed)
   118  	env := generateEnvelope(t)
   119  	server.Archive(env)
   120  	deliverTest(t, &server, env)
   121  }
   122  
   123  func deliverTest(t *testing.T, server *WMailServer, env *whisper.Envelope) {
   124  	id, err := shh.NewKeyPair()
   125  	if err != nil {
   126  		t.Fatalf("failed to generate new key pair with seed %d: %s.", seed, err)
   127  	}
   128  	testPeerID, err := shh.GetPrivateKey(id)
   129  	if err != nil {
   130  		t.Fatalf("failed to retrieve new key pair with seed %d: %s.", seed, err)
   131  	}
   132  	birth := env.Expiry - env.TTL
   133  	p := &ServerTestParams{
   134  		topic: env.Topic,
   135  		low:   birth - 1,
   136  		upp:   birth + 1,
   137  		key:   testPeerID,
   138  	}
   139  
   140  	singleRequest(t, server, env, p, true)
   141  
   142  	p.low, p.upp = birth+1, 0xffffffff
   143  	singleRequest(t, server, env, p, false)
   144  
   145  	p.low, p.upp = 0, birth-1
   146  	singleRequest(t, server, env, p, false)
   147  
   148  	p.low = birth - 1
   149  	p.upp = birth + 1
   150  	p.topic[0] = 0xFF
   151  	singleRequest(t, server, env, p, false)
   152  }
   153  
   154  func singleRequest(t *testing.T, server *WMailServer, env *whisper.Envelope, p *ServerTestParams, expect bool) {
   155  	request := createRequest(t, p)
   156  	src := crypto.FromECDSAPub(&p.key.PublicKey)
   157  	ok, lower, upper, bloom := server.validateRequest(src, request)
   158  	if !ok {
   159  		t.Fatalf("request validation failed, seed: %d.", seed)
   160  	}
   161  	if lower != p.low {
   162  		t.Fatalf("request validation failed (lower bound), seed: %d.", seed)
   163  	}
   164  	if upper != p.upp {
   165  		t.Fatalf("request validation failed (upper bound), seed: %d.", seed)
   166  	}
   167  	expectedBloom := whisper.TopicToBloom(p.topic)
   168  	if !bytes.Equal(bloom, expectedBloom) {
   169  		t.Fatalf("request validation failed (topic), seed: %d.", seed)
   170  	}
   171  
   172  	var exist bool
   173  	mail := server.processRequest(nil, p.low, p.upp, bloom)
   174  	for _, msg := range mail {
   175  		if msg.Hash() == env.Hash() {
   176  			exist = true
   177  			break
   178  		}
   179  	}
   180  
   181  	if exist != expect {
   182  		t.Fatalf("error: exist = %v, seed: %d.", exist, seed)
   183  	}
   184  
   185  	src[0]++
   186  	ok, lower, upper, bloom = server.validateRequest(src, request)
   187  	if !ok {
   188  //
   189  		t.Fatalf("request validation false negative, seed: %d (lower: %d, upper: %d).", seed, lower, upper)
   190  	}
   191  }
   192  
   193  func createRequest(t *testing.T, p *ServerTestParams) *whisper.Envelope {
   194  	bloom := whisper.TopicToBloom(p.topic)
   195  	data := make([]byte, 8)
   196  	binary.BigEndian.PutUint32(data, p.low)
   197  	binary.BigEndian.PutUint32(data[4:], p.upp)
   198  	data = append(data, bloom...)
   199  
   200  	key, err := shh.GetSymKey(keyID)
   201  	if err != nil {
   202  		t.Fatalf("failed to retrieve sym key with seed %d: %s.", seed, err)
   203  	}
   204  
   205  	params := &whisper.MessageParams{
   206  		KeySym:   key,
   207  		Topic:    p.topic,
   208  		Payload:  data,
   209  		PoW:      powRequirement * 2,
   210  		WorkTime: 2,
   211  		Src:      p.key,
   212  	}
   213  
   214  	msg, err := whisper.NewSentMessage(params)
   215  	if err != nil {
   216  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   217  	}
   218  	env, err := msg.Wrap(params)
   219  	if err != nil {
   220  		t.Fatalf("failed to wrap with seed %d: %s.", seed, err)
   221  	}
   222  	return env
   223  }
   224