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