github.com/n1ghtfa1l/go-vnt@v0.6.4-alpha.6/whisper/mailserver/server_test.go (about) 1 // Copyright 2017 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package mailserver 18 19 import ( 20 "bytes" 21 "crypto/ecdsa" 22 "encoding/binary" 23 "io/ioutil" 24 "math/rand" 25 "testing" 26 "time" 27 28 libp2p "github.com/libp2p/go-libp2p-peer" 29 "github.com/vntchain/go-vnt/common" 30 "github.com/vntchain/go-vnt/crypto" 31 whisper "github.com/vntchain/go-vnt/whisper/whisperv6" 32 ) 33 34 const powRequirement = 0.00001 35 36 var keyID string 37 var shh *whisper.Whisper 38 var seed = time.Now().Unix() 39 40 type ServerTestParams struct { 41 topic whisper.TopicType 42 low uint32 43 upp uint32 44 key *ecdsa.PrivateKey 45 } 46 47 func assert(statement bool, text string, t *testing.T) { 48 if !statement { 49 t.Fatal(text) 50 } 51 } 52 53 func TestDBKey(t *testing.T) { 54 var h common.Hash 55 i := uint32(time.Now().Unix()) 56 k := NewDbKey(i, h) 57 assert(len(k.raw) == common.HashLength+4, "wrong DB key length", t) 58 assert(byte(i%0x100) == k.raw[3], "raw representation should be big endian", t) 59 assert(byte(i/0x1000000) == k.raw[0], "big endian expected", t) 60 } 61 62 func generateEnvelope(t *testing.T) *whisper.Envelope { 63 h := crypto.Keccak256Hash([]byte("test sample data")) 64 params := &whisper.MessageParams{ 65 KeySym: h[:], 66 Topic: whisper.TopicType{0x1F, 0x7E, 0xA1, 0x7F}, 67 Payload: []byte("test payload"), 68 PoW: powRequirement, 69 WorkTime: 2, 70 } 71 72 msg, err := whisper.NewSentMessage(params) 73 if err != nil { 74 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 75 } 76 env, err := msg.Wrap(params) 77 if err != nil { 78 t.Fatalf("failed to wrap with seed %d: %s.", seed, err) 79 } 80 return env 81 } 82 83 func TestMailServer(t *testing.T) { 84 const password = "password_for_this_test" 85 const dbPath = "whisper-server-test" 86 87 dir, err := ioutil.TempDir("", dbPath) 88 if err != nil { 89 t.Fatal(err) 90 } 91 92 var server WMailServer 93 shh = whisper.New(&whisper.DefaultConfig) 94 shh.RegisterServer(&server) 95 96 err = server.Init(shh, dir, password, powRequirement) 97 if err != nil { 98 t.Fatal(err) 99 } 100 defer server.Close() 101 102 keyID, err = shh.AddSymKeyFromPassword(password) 103 if err != nil { 104 t.Fatalf("Failed to create symmetric key for mail request: %s", err) 105 } 106 107 rand.Seed(seed) 108 env := generateEnvelope(t) 109 server.Archive(env) 110 deliverTest(t, &server, env) 111 } 112 113 func deliverTest(t *testing.T, server *WMailServer, env *whisper.Envelope) { 114 id, err := shh.NewKeyPair() 115 if err != nil { 116 t.Fatalf("failed to generate new key pair with seed %d: %s.", seed, err) 117 } 118 testPeerID, err := shh.GetPrivateKey(id) 119 if err != nil { 120 t.Fatalf("failed to retrieve new key pair with seed %d: %s.", seed, err) 121 } 122 birth := env.Expiry - env.TTL 123 p := &ServerTestParams{ 124 topic: env.Topic, 125 low: birth - 1, 126 upp: birth + 1, 127 key: testPeerID, 128 } 129 130 singleRequest(t, server, env, p, true) 131 132 p.low, p.upp = birth+1, 0xffffffff 133 singleRequest(t, server, env, p, false) 134 135 p.low, p.upp = 0, birth-1 136 singleRequest(t, server, env, p, false) 137 138 p.low = birth - 1 139 p.upp = birth + 1 140 p.topic[0] = 0xFF 141 singleRequest(t, server, env, p, false) 142 } 143 144 func singleRequest(t *testing.T, server *WMailServer, env *whisper.Envelope, p *ServerTestParams, expect bool) { 145 request := createRequest(t, p) 146 src := crypto.FromECDSAPub(&p.key.PublicKey) 147 ok, lower, upper, bloom := server.validateRequest(libp2p.ID(src), request) 148 if !ok { 149 t.Fatalf("request validation failed, seed: %d.", seed) 150 } 151 if lower != p.low { 152 t.Fatalf("request validation failed (lower bound), seed: %d.", seed) 153 } 154 if upper != p.upp { 155 t.Fatalf("request validation failed (upper bound), seed: %d.", seed) 156 } 157 expectedBloom := whisper.TopicToBloom(p.topic) 158 if !bytes.Equal(bloom, expectedBloom) { 159 t.Fatalf("request validation failed (topic), seed: %d.", seed) 160 } 161 162 var exist bool 163 mail := server.processRequest(nil, p.low, p.upp, bloom) 164 for _, msg := range mail { 165 if msg.Hash() == env.Hash() { 166 exist = true 167 break 168 } 169 } 170 171 if exist != expect { 172 t.Fatalf("error: exist = %v, seed: %d.", exist, seed) 173 } 174 175 src[0]++ 176 ok, lower, upper, bloom = server.validateRequest(libp2p.ID(src), request) 177 if !ok { 178 // request should be valid regardless of signature 179 t.Fatalf("request validation false negative, seed: %d (lower: %d, upper: %d).", seed, lower, upper) 180 } 181 } 182 183 func createRequest(t *testing.T, p *ServerTestParams) *whisper.Envelope { 184 bloom := whisper.TopicToBloom(p.topic) 185 data := make([]byte, 8) 186 binary.BigEndian.PutUint32(data, p.low) 187 binary.BigEndian.PutUint32(data[4:], p.upp) 188 data = append(data, bloom...) 189 190 key, err := shh.GetSymKey(keyID) 191 if err != nil { 192 t.Fatalf("failed to retrieve sym key with seed %d: %s.", seed, err) 193 } 194 195 params := &whisper.MessageParams{ 196 KeySym: key, 197 Topic: p.topic, 198 Payload: data, 199 PoW: powRequirement * 2, 200 WorkTime: 2, 201 Src: p.key, 202 } 203 204 msg, err := whisper.NewSentMessage(params) 205 if err != nil { 206 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 207 } 208 env, err := msg.Wrap(params) 209 if err != nil { 210 t.Fatalf("failed to wrap with seed %d: %s.", seed, err) 211 } 212 return env 213 }