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 }