github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/whisper/mailserver/server_test.go (about)

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