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