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