github.com/ylsgit/go-ethereum@v1.6.5/whisper/whisperv5/api_test.go (about) 1 // Copyright 2016 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 whisperv5 18 19 import ( 20 "bytes" 21 "encoding/json" 22 "testing" 23 "time" 24 25 "github.com/ethereum/go-ethereum/common" 26 "github.com/ethereum/go-ethereum/common/hexutil" 27 ) 28 29 func TestBasic(t *testing.T) { 30 var id string = "test" 31 w := New() 32 api := NewPublicWhisperAPI(w) 33 if api == nil { 34 t.Fatalf("failed to create API.") 35 } 36 37 ver, err := api.Version() 38 if err != nil { 39 t.Fatalf("failed generateFilter: %s.", err) 40 } 41 42 if uint64(ver) != ProtocolVersion { 43 t.Fatalf("wrong version: %d.", ver) 44 } 45 46 mail := api.GetNewSubscriptionMessages("non-existent-id") 47 if len(mail) != 0 { 48 t.Fatalf("failed GetFilterChanges: premature result") 49 } 50 51 exist, err := api.HasKeyPair(id) 52 if err != nil { 53 t.Fatalf("failed initial HasIdentity: %s.", err) 54 } 55 if exist { 56 t.Fatalf("failed initial HasIdentity: false positive.") 57 } 58 59 success, err := api.DeleteKeyPair(id) 60 if err != nil { 61 t.Fatalf("failed DeleteIdentity: %s.", err) 62 } 63 if success { 64 t.Fatalf("deleted non-existing identity: false positive.") 65 } 66 67 pub, err := api.NewKeyPair() 68 if err != nil { 69 t.Fatalf("failed NewIdentity: %s.", err) 70 } 71 if len(pub) == 0 { 72 t.Fatalf("failed NewIdentity: empty") 73 } 74 75 exist, err = api.HasKeyPair(pub) 76 if err != nil { 77 t.Fatalf("failed HasIdentity: %s.", err) 78 } 79 if !exist { 80 t.Fatalf("failed HasIdentity: false negative.") 81 } 82 83 success, err = api.DeleteKeyPair(pub) 84 if err != nil { 85 t.Fatalf("failed to delete second identity: %s.", err) 86 } 87 if !success { 88 t.Fatalf("failed to delete second identity.") 89 } 90 91 exist, err = api.HasKeyPair(pub) 92 if err != nil { 93 t.Fatalf("failed HasIdentity(): %s.", err) 94 } 95 if exist { 96 t.Fatalf("failed HasIdentity(): false positive.") 97 } 98 99 id = "arbitrary text" 100 id2 := "another arbitrary string" 101 102 exist, err = api.HasSymmetricKey(id) 103 if err != nil { 104 t.Fatalf("failed HasSymKey: %s.", err) 105 } 106 if exist { 107 t.Fatalf("failed HasSymKey: false positive.") 108 } 109 110 id, err = api.GenerateSymmetricKey() 111 if err != nil { 112 t.Fatalf("failed GenerateSymKey: %s.", err) 113 } 114 115 exist, err = api.HasSymmetricKey(id) 116 if err != nil { 117 t.Fatalf("failed HasSymKey(): %s.", err) 118 } 119 if !exist { 120 t.Fatalf("failed HasSymKey(): false negative.") 121 } 122 123 const password = "some stuff here" 124 id, err = api.AddSymmetricKeyFromPassword(password) 125 if err != nil { 126 t.Fatalf("failed AddSymKey: %s.", err) 127 } 128 129 id2, err = api.AddSymmetricKeyFromPassword(password) 130 if err != nil { 131 t.Fatalf("failed AddSymKey: %s.", err) 132 } 133 134 exist, err = api.HasSymmetricKey(id2) 135 if err != nil { 136 t.Fatalf("failed HasSymKey(id2): %s.", err) 137 } 138 if !exist { 139 t.Fatalf("failed HasSymKey(id2): false negative.") 140 } 141 142 k1, err := api.GetSymmetricKey(id) 143 if err != nil { 144 t.Fatalf("failed GetSymKey(id): %s.", err) 145 } 146 k2, err := api.GetSymmetricKey(id2) 147 if err != nil { 148 t.Fatalf("failed GetSymKey(id2): %s.", err) 149 } 150 151 if !bytes.Equal(k1, k2) { 152 t.Fatalf("installed keys are not equal") 153 } 154 155 exist, err = api.DeleteSymmetricKey(id) 156 if err != nil { 157 t.Fatalf("failed DeleteSymKey(id): %s.", err) 158 } 159 if !exist { 160 t.Fatalf("failed DeleteSymKey(id): false negative.") 161 } 162 163 exist, err = api.HasSymmetricKey(id) 164 if err != nil { 165 t.Fatalf("failed HasSymKey(id): %s.", err) 166 } 167 if exist { 168 t.Fatalf("failed HasSymKey(id): false positive.") 169 } 170 } 171 172 func TestUnmarshalFilterArgs(t *testing.T) { 173 s := []byte(`{ 174 "type":"sym", 175 "key":"0x70c87d191324e6712a591f304b4eedef6ad9bb9d", 176 "sig":"0x9b2055d370f73ec7d8a03e965129118dc8f5bf83", 177 "minPoW":2.34, 178 "topics":["0x00000000", "0x007f80ff", "0xff807f00", "0xf26e7779"], 179 "allowP2P":true 180 }`) 181 182 var f WhisperFilterArgs 183 err := f.UnmarshalJSON(s) 184 if err != nil { 185 t.Fatalf("failed UnmarshalJSON: %s.", err) 186 } 187 188 if !f.Symmetric { 189 t.Fatalf("wrong type.") 190 } 191 if f.Key != "0x70c87d191324e6712a591f304b4eedef6ad9bb9d" { 192 t.Fatalf("wrong key: %s.", f.Key) 193 } 194 if f.Sig != "0x9b2055d370f73ec7d8a03e965129118dc8f5bf83" { 195 t.Fatalf("wrong sig: %s.", f.Sig) 196 } 197 if f.MinPoW != 2.34 { 198 t.Fatalf("wrong MinPoW: %f.", f.MinPoW) 199 } 200 if !f.AllowP2P { 201 t.Fatalf("wrong AllowP2P.") 202 } 203 if len(f.Topics) != 4 { 204 t.Fatalf("wrong topics number: %d.", len(f.Topics)) 205 } 206 207 i := 0 208 if !bytes.Equal(f.Topics[i], []byte{0x00, 0x00, 0x00, 0x00}) { 209 t.Fatalf("wrong topic[%d]: %x.", i, f.Topics[i]) 210 } 211 212 i++ 213 if !bytes.Equal(f.Topics[i], []byte{0x00, 0x7f, 0x80, 0xff}) { 214 t.Fatalf("wrong topic[%d]: %x.", i, f.Topics[i]) 215 } 216 217 i++ 218 if !bytes.Equal(f.Topics[i], []byte{0xff, 0x80, 0x7f, 0x00}) { 219 t.Fatalf("wrong topic[%d]: %x.", i, f.Topics[i]) 220 } 221 222 i++ 223 if !bytes.Equal(f.Topics[i], []byte{0xf2, 0x6e, 0x77, 0x79}) { 224 t.Fatalf("wrong topic[%d]: %x.", i, f.Topics[i]) 225 } 226 } 227 228 func TestUnmarshalPostArgs(t *testing.T) { 229 s := []byte(`{ 230 "type":"sym", 231 "ttl":12345, 232 "sig":"0x70c87d191324e6712a591f304b4eedef6ad9bb9d", 233 "key":"0x9b2055d370f73ec7d8a03e965129118dc8f5bf83", 234 "topic":"0xf26e7779", 235 "padding":"0x74686973206973206D79207465737420737472696E67", 236 "payload":"0x7061796C6F61642073686F756C642062652070736575646F72616E646F6D", 237 "powTime":777, 238 "powTarget":3.1416, 239 "targetPeer":"enode://915533f667b1369793ebb9bda022416b1295235a1420799cd87a969467372546d808ebf59c5c9ce23f103d59b61b97df8af91f0908552485975397181b993461@127.0.0.1:12345" 240 }`) 241 242 var a PostArgs 243 err := json.Unmarshal(s, &a) 244 if err != nil { 245 t.Fatalf("failed UnmarshalJSON: %s.", err) 246 } 247 248 if a.Type != "sym" { 249 t.Fatalf("wrong Type: %s.", a.Type) 250 } 251 if a.TTL != 12345 { 252 t.Fatalf("wrong ttl: %d.", a.TTL) 253 } 254 if a.Sig != "0x70c87d191324e6712a591f304b4eedef6ad9bb9d" { 255 t.Fatalf("wrong From: %s.", a.Sig) 256 } 257 if a.Key != "0x9b2055d370f73ec7d8a03e965129118dc8f5bf83" { 258 t.Fatalf("wrong Key: %s.", a.Key) 259 } 260 261 if BytesToTopic(a.Topic) != (TopicType{0xf2, 0x6e, 0x77, 0x79}) { 262 t.Fatalf("wrong topic: %x.", a.Topic) 263 } 264 if string(a.Padding) != "this is my test string" { 265 t.Fatalf("wrong Padding: %s.", string(a.Padding)) 266 } 267 if string(a.Payload) != "payload should be pseudorandom" { 268 t.Fatalf("wrong Payload: %s.", string(a.Payload)) 269 } 270 if a.PowTime != 777 { 271 t.Fatalf("wrong PowTime: %d.", a.PowTime) 272 } 273 if a.PowTarget != 3.1416 { 274 t.Fatalf("wrong PowTarget: %f.", a.PowTarget) 275 } 276 if a.TargetPeer != "enode://915533f667b1369793ebb9bda022416b1295235a1420799cd87a969467372546d808ebf59c5c9ce23f103d59b61b97df8af91f0908552485975397181b993461@127.0.0.1:12345" { 277 t.Fatalf("wrong PeerID: %s.", a.TargetPeer) 278 } 279 } 280 281 func waitForMessages(api *PublicWhisperAPI, id string, target int) []*WhisperMessage { 282 // timeout: 2 seconds 283 result := make([]*WhisperMessage, 0, target) 284 for i := 0; i < 100; i++ { 285 mail := api.GetNewSubscriptionMessages(id) 286 if len(mail) > 0 { 287 for _, m := range mail { 288 result = append(result, m) 289 } 290 if len(result) >= target { 291 break 292 } 293 } 294 time.Sleep(time.Millisecond * 20) 295 } 296 297 return result 298 } 299 300 func TestIntegrationAsym(t *testing.T) { 301 w := New() 302 api := NewPublicWhisperAPI(w) 303 if api == nil { 304 t.Fatalf("failed to create API.") 305 } 306 307 api.Start() 308 defer api.Stop() 309 310 sig, err := api.NewKeyPair() 311 if err != nil { 312 t.Fatalf("failed NewIdentity: %s.", err) 313 } 314 if len(sig) == 0 { 315 t.Fatalf("wrong signature") 316 } 317 318 exist, err := api.HasKeyPair(sig) 319 if err != nil { 320 t.Fatalf("failed HasIdentity: %s.", err) 321 } 322 if !exist { 323 t.Fatalf("failed HasIdentity: false negative.") 324 } 325 326 sigPubKey, err := api.GetPublicKey(sig) 327 if err != nil { 328 t.Fatalf("failed GetPublicKey: %s.", err) 329 } 330 331 key, err := api.NewKeyPair() 332 if err != nil { 333 t.Fatalf("failed NewIdentity(): %s.", err) 334 } 335 if len(key) == 0 { 336 t.Fatalf("wrong key") 337 } 338 339 dstPubKey, err := api.GetPublicKey(key) 340 if err != nil { 341 t.Fatalf("failed GetPublicKey: %s.", err) 342 } 343 344 var topics [2]TopicType 345 topics[0] = TopicType{0x00, 0x64, 0x00, 0xff} 346 topics[1] = TopicType{0xf2, 0x6e, 0x77, 0x79} 347 var f WhisperFilterArgs 348 f.Symmetric = false 349 f.Key = key 350 f.Sig = sigPubKey.String() 351 f.Topics = make([][]byte, 2) 352 f.Topics[0] = topics[0][:] 353 f.Topics[1] = topics[1][:] 354 f.MinPoW = DefaultMinimumPoW / 2 355 f.AllowP2P = true 356 357 id, err := api.Subscribe(f) 358 if err != nil { 359 t.Fatalf("failed to create new filter: %s.", err) 360 } 361 362 var p PostArgs 363 p.Type = "asym" 364 p.TTL = 2 365 p.Sig = sig 366 p.Key = dstPubKey.String() 367 p.Padding = []byte("test string") 368 p.Payload = []byte("extended test string") 369 p.PowTarget = DefaultMinimumPoW 370 p.PowTime = 2 371 p.Topic = hexutil.Bytes{0xf2, 0x6e, 0x77, 0x79} // topics[1] 372 373 err = api.Post(p) 374 if err != nil { 375 t.Errorf("failed to post message: %s.", err) 376 } 377 378 mail := waitForMessages(api, id, 1) 379 if len(mail) != 1 { 380 t.Fatalf("failed to GetFilterChanges: got %d messages.", len(mail)) 381 } 382 383 text := string(common.FromHex(mail[0].Payload)) 384 if text != string("extended test string") { 385 t.Fatalf("failed to decrypt first message: %s.", text) 386 } 387 388 p.Padding = []byte("new value") 389 p.Payload = []byte("extended new value") 390 err = api.Post(p) 391 if err != nil { 392 t.Fatalf("failed to post next message: %s.", err) 393 } 394 395 mail = waitForMessages(api, id, 1) 396 if len(mail) != 1 { 397 t.Fatalf("failed to GetFilterChanges: got %d messages.", len(mail)) 398 } 399 400 text = string(common.FromHex(mail[0].Payload)) 401 if text != string("extended new value") { 402 t.Fatalf("failed to decrypt second message: %s.", text) 403 } 404 } 405 406 func TestIntegrationSym(t *testing.T) { 407 w := New() 408 api := NewPublicWhisperAPI(w) 409 if api == nil { 410 t.Fatalf("failed to create API.") 411 } 412 413 api.Start() 414 defer api.Stop() 415 416 symKeyID, err := api.GenerateSymmetricKey() 417 if err != nil { 418 t.Fatalf("failed GenerateSymKey: %s.", err) 419 } 420 421 sig, err := api.NewKeyPair() 422 if err != nil { 423 t.Fatalf("failed NewKeyPair: %s.", err) 424 } 425 if len(sig) == 0 { 426 t.Fatalf("wrong signature") 427 } 428 429 sigPubKey, err := api.GetPublicKey(sig) 430 if err != nil { 431 t.Fatalf("failed GetPublicKey: %s.", err) 432 } 433 434 exist, err := api.HasKeyPair(sig) 435 if err != nil { 436 t.Fatalf("failed HasIdentity: %s.", err) 437 } 438 if !exist { 439 t.Fatalf("failed HasIdentity: false negative.") 440 } 441 442 var topics [2]TopicType 443 topics[0] = TopicType{0x00, 0x7f, 0x80, 0xff} 444 topics[1] = TopicType{0xf2, 0x6e, 0x77, 0x79} 445 var f WhisperFilterArgs 446 f.Symmetric = true 447 f.Key = symKeyID 448 f.Topics = make([][]byte, 2) 449 f.Topics[0] = topics[0][:] 450 f.Topics[1] = topics[1][:] 451 f.MinPoW = DefaultMinimumPoW / 2 452 f.Sig = sigPubKey.String() 453 f.AllowP2P = false 454 455 id, err := api.Subscribe(f) 456 if err != nil { 457 t.Fatalf("failed to create new filter: %s.", err) 458 } 459 460 var p PostArgs 461 p.Type = "sym" 462 p.TTL = 1 463 p.Key = symKeyID 464 p.Sig = sig 465 p.Padding = []byte("test string") 466 p.Payload = []byte("extended test string") 467 p.PowTarget = DefaultMinimumPoW 468 p.PowTime = 2 469 p.Topic = hexutil.Bytes{0xf2, 0x6e, 0x77, 0x79} 470 471 err = api.Post(p) 472 if err != nil { 473 t.Fatalf("failed to post first message: %s.", err) 474 } 475 476 mail := waitForMessages(api, id, 1) 477 if len(mail) != 1 { 478 t.Fatalf("failed GetFilterChanges: got %d messages.", len(mail)) 479 } 480 481 text := string(common.FromHex(mail[0].Payload)) 482 if text != string("extended test string") { 483 t.Fatalf("failed to decrypt first message: %s.", text) 484 } 485 486 p.Padding = []byte("new value") 487 p.Payload = []byte("extended new value") 488 err = api.Post(p) 489 if err != nil { 490 t.Fatalf("failed to post second message: %s.", err) 491 } 492 493 mail = waitForMessages(api, id, 1) 494 if len(mail) != 1 { 495 t.Fatalf("failed second GetFilterChanges: got %d messages.", len(mail)) 496 } 497 498 text = string(common.FromHex(mail[0].Payload)) 499 if text != string("extended new value") { 500 t.Fatalf("failed to decrypt second message: %s.", text) 501 } 502 } 503 504 func TestIntegrationSymWithFilter(t *testing.T) { 505 w := New() 506 api := NewPublicWhisperAPI(w) 507 if api == nil { 508 t.Fatalf("failed to create API.") 509 } 510 511 api.Start() 512 defer api.Stop() 513 514 symKeyID, err := api.GenerateSymmetricKey() 515 if err != nil { 516 t.Fatalf("failed to GenerateSymKey: %s.", err) 517 } 518 519 sigKeyID, err := api.NewKeyPair() 520 if err != nil { 521 t.Fatalf("failed NewIdentity: %s.", err) 522 } 523 if len(sigKeyID) == 0 { 524 t.Fatalf("wrong signature.") 525 } 526 527 exist, err := api.HasKeyPair(sigKeyID) 528 if err != nil { 529 t.Fatalf("failed HasIdentity: %s.", err) 530 } 531 if !exist { 532 t.Fatalf("failed HasIdentity: does not exist.") 533 } 534 535 sigPubKey, err := api.GetPublicKey(sigKeyID) 536 if err != nil { 537 t.Fatalf("failed GetPublicKey: %s.", err) 538 } 539 540 var topics [2]TopicType 541 topics[0] = TopicType{0x00, 0x7f, 0x80, 0xff} 542 topics[1] = TopicType{0xf2, 0x6e, 0x77, 0x79} 543 var f WhisperFilterArgs 544 f.Symmetric = true 545 f.Key = symKeyID 546 f.Topics = make([][]byte, 2) 547 f.Topics[0] = topics[0][:] 548 f.Topics[1] = topics[1][:] 549 f.MinPoW = DefaultMinimumPoW / 2 550 f.Sig = sigPubKey.String() 551 f.AllowP2P = false 552 553 id, err := api.Subscribe(f) 554 if err != nil { 555 t.Fatalf("failed to create new filter: %s.", err) 556 } 557 558 var p PostArgs 559 p.Type = "sym" 560 p.TTL = 1 561 p.Key = symKeyID 562 p.Sig = sigKeyID 563 p.Padding = []byte("test string") 564 p.Payload = []byte("extended test string") 565 p.PowTarget = DefaultMinimumPoW 566 p.PowTime = 2 567 p.Topic = hexutil.Bytes{0xf2, 0x6e, 0x77, 0x79} 568 569 err = api.Post(p) 570 if err != nil { 571 t.Fatalf("failed to post message: %s.", err) 572 } 573 574 mail := waitForMessages(api, id, 1) 575 if len(mail) != 1 { 576 t.Fatalf("failed to GetFilterChanges: got %d messages.", len(mail)) 577 } 578 579 text := string(common.FromHex(mail[0].Payload)) 580 if text != string("extended test string") { 581 t.Fatalf("failed to decrypt first message: %s.", text) 582 } 583 584 p.Padding = []byte("new value") 585 p.Payload = []byte("extended new value") 586 err = api.Post(p) 587 if err != nil { 588 t.Fatalf("failed to post next message: %s.", err) 589 } 590 591 mail = waitForMessages(api, id, 1) 592 if len(mail) != 1 { 593 t.Fatalf("failed to GetFilterChanges: got %d messages.", len(mail)) 594 } 595 596 text = string(common.FromHex(mail[0].Payload)) 597 if text != string("extended new value") { 598 t.Fatalf("failed to decrypt second message: %s.", text) 599 } 600 } 601 602 func TestKey(t *testing.T) { 603 w := New() 604 api := NewPublicWhisperAPI(w) 605 if api == nil { 606 t.Fatalf("failed to create API.") 607 } 608 609 k, err := api.AddSymmetricKeyFromPassword("wwww") 610 if err != nil { 611 t.Fatalf("failed to create key: %s.", err) 612 } 613 614 s, err := api.GetSymmetricKey(k) 615 if err != nil { 616 t.Fatalf("failed to get sym key: %s.", err) 617 } 618 619 k2, err := api.AddSymmetricKeyDirect(s) 620 if err != nil { 621 t.Fatalf("failed to add sym key: %s.", err) 622 } 623 624 s2, err := api.GetSymmetricKey(k2) 625 if err != nil { 626 t.Fatalf("failed to get sym key: %s.", err) 627 } 628 629 if s.String() != "0x448652d595bd6ec00b2a9ea220ad6c26592d9bf4cf79023d3c1b30cb681e6e07" { 630 t.Fatalf("wrong key from password: %s", s.String()) 631 } 632 633 if !bytes.Equal(s, s2) { 634 t.Fatalf("wrong key") 635 } 636 } 637 638 func TestSubscribe(t *testing.T) { 639 var err error 640 var s string 641 642 w := New() 643 api := NewPublicWhisperAPI(w) 644 if api == nil { 645 t.Fatalf("failed to create API.") 646 } 647 648 symKeyID, err := api.GenerateSymmetricKey() 649 if err != nil { 650 t.Fatalf("failed to GenerateSymKey: %s.", err) 651 } 652 653 var f WhisperFilterArgs 654 f.Symmetric = true 655 f.Key = symKeyID 656 f.Topics = make([][]byte, 5) 657 f.Topics[0] = []byte{0x21} 658 f.Topics[1] = []byte{0xd2, 0xe3} 659 f.Topics[2] = []byte{0x64, 0x75, 0x76} 660 f.Topics[3] = []byte{0xf8, 0xe9, 0xa0, 0xba} 661 f.Topics[4] = []byte{0xcb, 0x3c, 0xdd, 0xee, 0xff} 662 663 s, err = api.Subscribe(f) 664 if err == nil { 665 t.Fatalf("Subscribe: false positive.") 666 } 667 668 f.Topics[4] = []byte{} 669 if err == nil { 670 t.Fatalf("Subscribe: false positive again.") 671 } 672 673 f.Topics[4] = []byte{0x00} 674 s, err = api.Subscribe(f) 675 if err != nil { 676 t.Fatalf("failed to subscribe: %s.", err) 677 } else { 678 api.Unsubscribe(s) 679 } 680 }