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