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