github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/swarm/storage/mru/resource_test.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 // 10 // 11 // 12 // 13 // 14 // 15 // 16 // 17 // 18 // 19 // 20 // 21 // 22 // 23 // 24 25 package mru 26 27 import ( 28 "bytes" 29 "context" 30 "crypto/rand" 31 "encoding/binary" 32 "flag" 33 "io/ioutil" 34 "os" 35 "testing" 36 "time" 37 38 "github.com/ethereum/go-ethereum/contracts/ens" 39 "github.com/ethereum/go-ethereum/crypto" 40 "github.com/ethereum/go-ethereum/log" 41 "github.com/ethereum/go-ethereum/swarm/chunk" 42 "github.com/ethereum/go-ethereum/swarm/multihash" 43 "github.com/ethereum/go-ethereum/swarm/storage" 44 ) 45 46 var ( 47 loglevel = flag.Int("loglevel", 3, "loglevel") 48 testHasher = storage.MakeHashFunc(resourceHashAlgorithm)() 49 startTime = Timestamp{ 50 Time: uint64(4200), 51 } 52 resourceFrequency = uint64(42) 53 cleanF func() 54 resourceName = "føø.bar" 55 hashfunc = storage.MakeHashFunc(storage.DefaultHash) 56 ) 57 58 func init() { 59 flag.Parse() 60 log.Root().SetHandler(log.CallerFileHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(os.Stderr, log.TerminalFormat(true))))) 61 } 62 63 // 64 type fakeTimeProvider struct { 65 currentTime uint64 66 } 67 68 func (f *fakeTimeProvider) Tick() { 69 f.currentTime++ 70 } 71 72 func (f *fakeTimeProvider) Now() Timestamp { 73 return Timestamp{ 74 Time: f.currentTime, 75 } 76 } 77 78 func TestUpdateChunkSerializationErrorChecking(t *testing.T) { 79 80 // 81 var r SignedResourceUpdate 82 if err := r.fromChunk(storage.ZeroAddr, make([]byte, minimumUpdateDataLength-1)); err == nil { 83 t.Fatalf("Expected parseUpdate to fail when chunkData contains less than %d bytes", minimumUpdateDataLength) 84 } 85 86 r = SignedResourceUpdate{} 87 // 88 fakeChunk := make([]byte, 150) 89 binary.LittleEndian.PutUint16(fakeChunk, 44) 90 if err := r.fromChunk(storage.ZeroAddr, fakeChunk); err == nil { 91 t.Fatal("Expected parseUpdate to fail when the header length does not match the actual data array passed in") 92 } 93 94 r = SignedResourceUpdate{ 95 resourceUpdate: resourceUpdate{ 96 updateHeader: updateHeader{ 97 UpdateLookup: UpdateLookup{ 98 99 rootAddr: make([]byte, 79), // 100 }, 101 metaHash: nil, 102 multihash: false, 103 }, 104 }, 105 } 106 _, err := r.toChunk() 107 if err == nil { 108 t.Fatal("Expected newUpdateChunk to fail when rootAddr or metaHash have the wrong length") 109 } 110 r.rootAddr = make([]byte, storage.KeyLength) 111 r.metaHash = make([]byte, storage.KeyLength) 112 _, err = r.toChunk() 113 if err == nil { 114 t.Fatal("Expected newUpdateChunk to fail when there is no data") 115 } 116 r.data = make([]byte, 79) // 117 _, err = r.toChunk() 118 if err == nil { 119 t.Fatal("expected newUpdateChunk to fail when there is no signature", err) 120 } 121 122 alice := newAliceSigner() 123 if err := r.Sign(alice); err != nil { 124 t.Fatalf("error signing:%s", err) 125 126 } 127 _, err = r.toChunk() 128 if err != nil { 129 t.Fatalf("error creating update chunk:%s", err) 130 } 131 132 r.multihash = true 133 r.data[1] = 79 // 134 if err := r.Sign(alice); err == nil { 135 t.Fatal("expected Sign() to fail when an invalid multihash is in data and multihash=true", err) 136 } 137 } 138 139 // 140 func TestReverse(t *testing.T) { 141 142 period := uint32(4) 143 version := uint32(2) 144 145 // 146 timeProvider := &fakeTimeProvider{ 147 currentTime: startTime.Time, 148 } 149 150 // 151 signer := newAliceSigner() 152 153 // 154 _, _, teardownTest, err := setupTest(timeProvider, signer) 155 if err != nil { 156 t.Fatal(err) 157 } 158 defer teardownTest() 159 160 metadata := ResourceMetadata{ 161 Name: resourceName, 162 StartTime: startTime, 163 Frequency: resourceFrequency, 164 Owner: signer.Address(), 165 } 166 167 rootAddr, metaHash, _, err := metadata.serializeAndHash() 168 if err != nil { 169 t.Fatal(err) 170 } 171 172 // 173 data := make([]byte, 8) 174 _, err = rand.Read(data) 175 if err != nil { 176 t.Fatal(err) 177 } 178 testHasher.Reset() 179 testHasher.Write(data) 180 181 update := &SignedResourceUpdate{ 182 resourceUpdate: resourceUpdate{ 183 updateHeader: updateHeader{ 184 UpdateLookup: UpdateLookup{ 185 period: period, 186 version: version, 187 rootAddr: rootAddr, 188 }, 189 metaHash: metaHash, 190 }, 191 data: data, 192 }, 193 } 194 // 195 key := update.UpdateAddr() 196 197 if err = update.Sign(signer); err != nil { 198 t.Fatal(err) 199 } 200 201 chunk, err := update.toChunk() 202 if err != nil { 203 t.Fatal(err) 204 } 205 206 // 207 var checkUpdate SignedResourceUpdate 208 if err := checkUpdate.fromChunk(chunk.Addr, chunk.SData); err != nil { 209 t.Fatal(err) 210 } 211 checkdigest, err := checkUpdate.GetDigest() 212 if err != nil { 213 t.Fatal(err) 214 } 215 recoveredaddress, err := getOwner(checkdigest, *checkUpdate.signature) 216 if err != nil { 217 t.Fatalf("Retrieve address from signature fail: %v", err) 218 } 219 originaladdress := crypto.PubkeyToAddress(signer.PrivKey.PublicKey) 220 221 // 222 if recoveredaddress != originaladdress { 223 t.Fatalf("addresses dont match: %x != %x", originaladdress, recoveredaddress) 224 } 225 226 if !bytes.Equal(key[:], chunk.Addr[:]) { 227 t.Fatalf("Expected chunk key '%x', was '%x'", key, chunk.Addr) 228 } 229 if period != checkUpdate.period { 230 t.Fatalf("Expected period '%d', was '%d'", period, checkUpdate.period) 231 } 232 if version != checkUpdate.version { 233 t.Fatalf("Expected version '%d', was '%d'", version, checkUpdate.version) 234 } 235 if !bytes.Equal(data, checkUpdate.data) { 236 t.Fatalf("Expectedn data '%x', was '%x'", data, checkUpdate.data) 237 } 238 } 239 240 // 241 func TestResourceHandler(t *testing.T) { 242 243 // 244 timeProvider := &fakeTimeProvider{ 245 currentTime: startTime.Time, 246 } 247 248 // 249 signer := newAliceSigner() 250 251 rh, datadir, teardownTest, err := setupTest(timeProvider, signer) 252 if err != nil { 253 t.Fatal(err) 254 } 255 defer teardownTest() 256 257 // 258 ctx, cancel := context.WithCancel(context.Background()) 259 defer cancel() 260 261 metadata := &ResourceMetadata{ 262 Name: resourceName, 263 Frequency: resourceFrequency, 264 StartTime: Timestamp{Time: timeProvider.Now().Time}, 265 Owner: signer.Address(), 266 } 267 268 request, err := NewCreateUpdateRequest(metadata) 269 if err != nil { 270 t.Fatal(err) 271 } 272 request.Sign(signer) 273 if err != nil { 274 t.Fatal(err) 275 } 276 err = rh.New(ctx, request) 277 if err != nil { 278 t.Fatal(err) 279 } 280 281 chunk, err := rh.chunkStore.Get(context.TODO(), storage.Address(request.rootAddr)) 282 if err != nil { 283 t.Fatal(err) 284 } else if len(chunk.SData) < 16 { 285 t.Fatalf("chunk data must be minimum 16 bytes, is %d", len(chunk.SData)) 286 } 287 288 var recoveredMetadata ResourceMetadata 289 290 recoveredMetadata.binaryGet(chunk.SData) 291 if err != nil { 292 t.Fatal(err) 293 } 294 if recoveredMetadata.StartTime.Time != timeProvider.currentTime { 295 t.Fatalf("stored startTime %d does not match provided startTime %d", recoveredMetadata.StartTime.Time, timeProvider.currentTime) 296 } 297 if recoveredMetadata.Frequency != resourceFrequency { 298 t.Fatalf("stored frequency %d does not match provided frequency %d", recoveredMetadata.Frequency, resourceFrequency) 299 } 300 301 // 302 updates := []string{ 303 "blinky", 304 "pinky", 305 "inky", 306 "clyde", 307 } 308 309 // 310 resourcekey := make(map[string]storage.Address) 311 fwdClock(int(resourceFrequency/2), timeProvider) 312 data := []byte(updates[0]) 313 request.SetData(data, false) 314 if err := request.Sign(signer); err != nil { 315 t.Fatal(err) 316 } 317 resourcekey[updates[0]], err = rh.Update(ctx, &request.SignedResourceUpdate) 318 if err != nil { 319 t.Fatal(err) 320 } 321 322 // 323 request, err = rh.NewUpdateRequest(ctx, request.rootAddr) 324 if err != nil { 325 t.Fatal(err) 326 } 327 if request.version != 2 || request.period != 1 { 328 t.Fatal("Suggested period should be 1 and version should be 2") 329 } 330 331 request.version = 1 // 332 data = []byte(updates[1]) 333 request.SetData(data, false) 334 if err := request.Sign(signer); err != nil { 335 t.Fatal(err) 336 } 337 resourcekey[updates[1]], err = rh.Update(ctx, &request.SignedResourceUpdate) 338 if err == nil { 339 t.Fatal("Expected update to fail since this version already exists") 340 } 341 342 // 343 fwdClock(int(resourceFrequency/2), timeProvider) 344 request, err = rh.NewUpdateRequest(ctx, request.rootAddr) 345 if err != nil { 346 t.Fatal(err) 347 } 348 request.SetData(data, false) 349 if err := request.Sign(signer); err != nil { 350 t.Fatal(err) 351 } 352 resourcekey[updates[1]], err = rh.Update(ctx, &request.SignedResourceUpdate) 353 if err != nil { 354 t.Fatal(err) 355 } 356 357 fwdClock(int(resourceFrequency), timeProvider) 358 // 359 request, err = rh.NewUpdateRequest(ctx, request.rootAddr) 360 if err != nil { 361 t.Fatal(err) 362 } 363 data = []byte(updates[2]) 364 request.SetData(data, false) 365 if err := request.Sign(signer); err != nil { 366 t.Fatal(err) 367 } 368 resourcekey[updates[2]], err = rh.Update(ctx, &request.SignedResourceUpdate) 369 if err != nil { 370 t.Fatal(err) 371 } 372 373 // 374 fwdClock(1, timeProvider) 375 request, err = rh.NewUpdateRequest(ctx, request.rootAddr) 376 if err != nil { 377 t.Fatal(err) 378 } 379 if request.period != 3 || request.version != 2 { 380 t.Fatal("Suggested period should be 3 and version should be 2") 381 } 382 data = []byte(updates[3]) 383 request.SetData(data, false) 384 385 if err := request.Sign(signer); err != nil { 386 t.Fatal(err) 387 } 388 resourcekey[updates[3]], err = rh.Update(ctx, &request.SignedResourceUpdate) 389 if err != nil { 390 t.Fatal(err) 391 } 392 393 time.Sleep(time.Second) 394 rh.Close() 395 396 // 397 // 398 fwdClock(int(resourceFrequency*2)-1, timeProvider) 399 400 rhparams := &HandlerParams{} 401 402 rh2, err := NewTestHandler(datadir, rhparams) 403 if err != nil { 404 t.Fatal(err) 405 } 406 407 rsrc2, err := rh2.Load(context.TODO(), request.rootAddr) 408 if err != nil { 409 t.Fatal(err) 410 } 411 412 _, err = rh2.Lookup(ctx, LookupLatest(request.rootAddr)) 413 if err != nil { 414 t.Fatal(err) 415 } 416 417 // 418 if !bytes.Equal(rsrc2.data, []byte(updates[len(updates)-1])) { 419 t.Fatalf("resource data was %v, expected %v", string(rsrc2.data), updates[len(updates)-1]) 420 } 421 if rsrc2.version != 2 { 422 t.Fatalf("resource version was %d, expected 2", rsrc2.version) 423 } 424 if rsrc2.period != 3 { 425 t.Fatalf("resource period was %d, expected 3", rsrc2.period) 426 } 427 log.Debug("Latest lookup", "period", rsrc2.period, "version", rsrc2.version, "data", rsrc2.data) 428 429 // 430 rsrc, err := rh2.Lookup(ctx, LookupLatestVersionInPeriod(request.rootAddr, 3)) 431 if err != nil { 432 t.Fatal(err) 433 } 434 // 435 if !bytes.Equal(rsrc.data, []byte(updates[len(updates)-1])) { 436 t.Fatalf("resource data (historical) was %v, expected %v", string(rsrc2.data), updates[len(updates)-1]) 437 } 438 log.Debug("Historical lookup", "period", rsrc2.period, "version", rsrc2.version, "data", rsrc2.data) 439 440 // 441 lookupParams := LookupVersion(request.rootAddr, 3, 1) 442 rsrc, err = rh2.Lookup(ctx, lookupParams) 443 if err != nil { 444 t.Fatal(err) 445 } 446 // 447 if !bytes.Equal(rsrc.data, []byte(updates[2])) { 448 t.Fatalf("resource data (historical) was %v, expected %v", string(rsrc2.data), updates[2]) 449 } 450 log.Debug("Specific version lookup", "period", rsrc2.period, "version", rsrc2.version, "data", rsrc2.data) 451 452 // 453 // 454 for i := 1; i >= 0; i-- { 455 rsrc, err := rh2.LookupPrevious(ctx, lookupParams) 456 if err != nil { 457 t.Fatal(err) 458 } 459 if !bytes.Equal(rsrc.data, []byte(updates[i])) { 460 t.Fatalf("resource data (previous) was %v, expected %v", rsrc.data, updates[i]) 461 462 } 463 } 464 465 // 466 rsrc, err = rh2.LookupPrevious(ctx, lookupParams) 467 if err == nil { 468 t.Fatalf("expected previous to fail, returned period %d version %d data %v", rsrc.period, rsrc.version, rsrc.data) 469 } 470 471 } 472 473 func TestMultihash(t *testing.T) { 474 475 // 476 timeProvider := &fakeTimeProvider{ 477 currentTime: startTime.Time, 478 } 479 480 // 481 signer := newAliceSigner() 482 483 // 484 rh, datadir, teardownTest, err := setupTest(timeProvider, signer) 485 if err != nil { 486 t.Fatal(err) 487 } 488 defer teardownTest() 489 490 // 491 ctx, cancel := context.WithCancel(context.Background()) 492 defer cancel() 493 494 metadata := &ResourceMetadata{ 495 Name: resourceName, 496 Frequency: resourceFrequency, 497 StartTime: Timestamp{Time: timeProvider.Now().Time}, 498 Owner: signer.Address(), 499 } 500 501 mr, err := NewCreateRequest(metadata) 502 if err != nil { 503 t.Fatal(err) 504 } 505 err = rh.New(ctx, mr) 506 if err != nil { 507 t.Fatal(err) 508 } 509 510 // 511 // 512 multihashbytes := ens.EnsNode("foo") 513 multihashmulti := multihash.ToMultihash(multihashbytes.Bytes()) 514 if err != nil { 515 t.Fatal(err) 516 } 517 mr.SetData(multihashmulti, true) 518 mr.Sign(signer) 519 if err != nil { 520 t.Fatal(err) 521 } 522 multihashkey, err := rh.Update(ctx, &mr.SignedResourceUpdate) 523 if err != nil { 524 t.Fatal(err) 525 } 526 527 sha1bytes := make([]byte, multihash.MultihashLength) 528 sha1multi := multihash.ToMultihash(sha1bytes) 529 if err != nil { 530 t.Fatal(err) 531 } 532 mr, err = rh.NewUpdateRequest(ctx, mr.rootAddr) 533 if err != nil { 534 t.Fatal(err) 535 } 536 mr.SetData(sha1multi, true) 537 mr.Sign(signer) 538 if err != nil { 539 t.Fatal(err) 540 } 541 sha1key, err := rh.Update(ctx, &mr.SignedResourceUpdate) 542 if err != nil { 543 t.Fatal(err) 544 } 545 546 // 547 mr, err = rh.NewUpdateRequest(ctx, mr.rootAddr) 548 if err != nil { 549 t.Fatal(err) 550 } 551 mr.SetData(multihashmulti[1:], true) 552 mr.Sign(signer) 553 if err != nil { 554 t.Fatal(err) 555 } 556 _, err = rh.Update(ctx, &mr.SignedResourceUpdate) 557 if err == nil { 558 t.Fatalf("Expected update to fail with first byte skipped") 559 } 560 mr, err = rh.NewUpdateRequest(ctx, mr.rootAddr) 561 if err != nil { 562 t.Fatal(err) 563 } 564 mr.SetData(multihashmulti[:len(multihashmulti)-2], true) 565 mr.Sign(signer) 566 if err != nil { 567 t.Fatal(err) 568 } 569 570 _, err = rh.Update(ctx, &mr.SignedResourceUpdate) 571 if err == nil { 572 t.Fatalf("Expected update to fail with last byte skipped") 573 } 574 575 data, err := getUpdateDirect(rh.Handler, multihashkey) 576 if err != nil { 577 t.Fatal(err) 578 } 579 multihashdecode, err := multihash.FromMultihash(data) 580 if err != nil { 581 t.Fatal(err) 582 } 583 if !bytes.Equal(multihashdecode, multihashbytes.Bytes()) { 584 t.Fatalf("Decoded hash '%x' does not match original hash '%x'", multihashdecode, multihashbytes.Bytes()) 585 } 586 data, err = getUpdateDirect(rh.Handler, sha1key) 587 if err != nil { 588 t.Fatal(err) 589 } 590 shadecode, err := multihash.FromMultihash(data) 591 if err != nil { 592 t.Fatal(err) 593 } 594 if !bytes.Equal(shadecode, sha1bytes) { 595 t.Fatalf("Decoded hash '%x' does not match original hash '%x'", shadecode, sha1bytes) 596 } 597 rh.Close() 598 599 rhparams := &HandlerParams{} 600 // 601 rh2, err := NewTestHandler(datadir, rhparams) 602 if err != nil { 603 t.Fatal(err) 604 } 605 mr, err = NewCreateRequest(metadata) 606 if err != nil { 607 t.Fatal(err) 608 } 609 err = rh2.New(ctx, mr) 610 if err != nil { 611 t.Fatal(err) 612 } 613 614 mr.SetData(multihashmulti, true) 615 mr.Sign(signer) 616 617 if err != nil { 618 t.Fatal(err) 619 } 620 multihashsignedkey, err := rh2.Update(ctx, &mr.SignedResourceUpdate) 621 if err != nil { 622 t.Fatal(err) 623 } 624 625 mr, err = rh2.NewUpdateRequest(ctx, mr.rootAddr) 626 if err != nil { 627 t.Fatal(err) 628 } 629 mr.SetData(sha1multi, true) 630 mr.Sign(signer) 631 if err != nil { 632 t.Fatal(err) 633 } 634 635 sha1signedkey, err := rh2.Update(ctx, &mr.SignedResourceUpdate) 636 if err != nil { 637 t.Fatal(err) 638 } 639 640 data, err = getUpdateDirect(rh2.Handler, multihashsignedkey) 641 if err != nil { 642 t.Fatal(err) 643 } 644 multihashdecode, err = multihash.FromMultihash(data) 645 if err != nil { 646 t.Fatal(err) 647 } 648 if !bytes.Equal(multihashdecode, multihashbytes.Bytes()) { 649 t.Fatalf("Decoded hash '%x' does not match original hash '%x'", multihashdecode, multihashbytes.Bytes()) 650 } 651 data, err = getUpdateDirect(rh2.Handler, sha1signedkey) 652 if err != nil { 653 t.Fatal(err) 654 } 655 shadecode, err = multihash.FromMultihash(data) 656 if err != nil { 657 t.Fatal(err) 658 } 659 if !bytes.Equal(shadecode, sha1bytes) { 660 t.Fatalf("Decoded hash '%x' does not match original hash '%x'", shadecode, sha1bytes) 661 } 662 } 663 664 // 665 func TestValidator(t *testing.T) { 666 667 // 668 timeProvider := &fakeTimeProvider{ 669 currentTime: startTime.Time, 670 } 671 672 // 673 signer := newAliceSigner() 674 675 // 676 falseSigner := newBobSigner() 677 678 // 679 rh, _, teardownTest, err := setupTest(timeProvider, signer) 680 if err != nil { 681 t.Fatal(err) 682 } 683 defer teardownTest() 684 685 // 686 ctx, cancel := context.WithCancel(context.Background()) 687 defer cancel() 688 metadata := &ResourceMetadata{ 689 Name: resourceName, 690 Frequency: resourceFrequency, 691 StartTime: Timestamp{Time: timeProvider.Now().Time}, 692 Owner: signer.Address(), 693 } 694 mr, err := NewCreateRequest(metadata) 695 if err != nil { 696 t.Fatal(err) 697 } 698 mr.Sign(signer) 699 700 err = rh.New(ctx, mr) 701 if err != nil { 702 t.Fatalf("Create resource fail: %v", err) 703 } 704 705 // 706 data := []byte("foo") 707 mr.SetData(data, false) 708 if err := mr.Sign(signer); err != nil { 709 t.Fatalf("sign fail: %v", err) 710 } 711 chunk, err := mr.SignedResourceUpdate.toChunk() 712 if err != nil { 713 t.Fatal(err) 714 } 715 if !rh.Validate(chunk.Addr, chunk.SData) { 716 t.Fatal("Chunk validator fail on update chunk") 717 } 718 719 // 720 if err := mr.Sign(falseSigner); err == nil { 721 t.Fatalf("Expected Sign to fail since we are using a different OwnerAddr: %v", err) 722 } 723 724 // 725 mr.metadata.Owner = zeroAddr // 726 if err := mr.Sign(falseSigner); err != nil { 727 t.Fatalf("sign fail: %v", err) 728 } 729 730 chunk, err = mr.SignedResourceUpdate.toChunk() 731 if err != nil { 732 t.Fatal(err) 733 } 734 735 if rh.Validate(chunk.Addr, chunk.SData) { 736 t.Fatal("Chunk validator did not fail on update chunk with false address") 737 } 738 739 ctx, cancel = context.WithTimeout(context.Background(), time.Second) 740 defer cancel() 741 742 metadata = &ResourceMetadata{ 743 Name: resourceName, 744 StartTime: TimestampProvider.Now(), 745 Frequency: resourceFrequency, 746 Owner: signer.Address(), 747 } 748 chunk, _, err = metadata.newChunk() 749 if err != nil { 750 t.Fatal(err) 751 } 752 753 if !rh.Validate(chunk.Addr, chunk.SData) { 754 t.Fatal("Chunk validator fail on metadata chunk") 755 } 756 } 757 758 // 759 // 760 // 761 // 762 func TestValidatorInStore(t *testing.T) { 763 764 // 765 TimestampProvider = &fakeTimeProvider{ 766 currentTime: startTime.Time, 767 } 768 769 // 770 signer := newAliceSigner() 771 772 // 773 datadir, err := ioutil.TempDir("", "storage-testresourcevalidator") 774 if err != nil { 775 t.Fatal(err) 776 } 777 defer os.RemoveAll(datadir) 778 779 params := storage.NewDefaultLocalStoreParams() 780 params.Init(datadir) 781 store, err := storage.NewLocalStore(params, nil) 782 if err != nil { 783 t.Fatal(err) 784 } 785 786 // 787 rhParams := &HandlerParams{} 788 rh := NewHandler(rhParams) 789 store.Validators = append(store.Validators, rh) 790 791 // 792 chunks := storage.GenerateRandomChunks(chunk.DefaultSize, 2) 793 goodChunk := chunks[0] 794 badChunk := chunks[1] 795 badChunk.SData = goodChunk.SData 796 797 metadata := &ResourceMetadata{ 798 StartTime: startTime, 799 Name: "xyzzy", 800 Frequency: resourceFrequency, 801 Owner: signer.Address(), 802 } 803 804 rootChunk, metaHash, err := metadata.newChunk() 805 if err != nil { 806 t.Fatal(err) 807 } 808 // 809 updateLookup := UpdateLookup{ 810 period: 42, 811 version: 1, 812 rootAddr: rootChunk.Addr, 813 } 814 815 updateAddr := updateLookup.UpdateAddr() 816 data := []byte("bar") 817 818 r := SignedResourceUpdate{ 819 updateAddr: updateAddr, 820 resourceUpdate: resourceUpdate{ 821 updateHeader: updateHeader{ 822 UpdateLookup: updateLookup, 823 metaHash: metaHash, 824 }, 825 data: data, 826 }, 827 } 828 829 r.Sign(signer) 830 831 uglyChunk, err := r.toChunk() 832 if err != nil { 833 t.Fatal(err) 834 } 835 836 // 837 storage.PutChunks(store, goodChunk) 838 if goodChunk.GetErrored() == nil { 839 t.Fatal("expected error on good content address chunk with resource validator only, but got nil") 840 } 841 storage.PutChunks(store, badChunk) 842 if badChunk.GetErrored() == nil { 843 t.Fatal("expected error on bad content address chunk with resource validator only, but got nil") 844 } 845 storage.PutChunks(store, uglyChunk) 846 if err := uglyChunk.GetErrored(); err != nil { 847 t.Fatalf("expected no error on resource update chunk with resource validator only, but got: %s", err) 848 } 849 } 850 851 // 852 func fwdClock(count int, timeProvider *fakeTimeProvider) { 853 for i := 0; i < count; i++ { 854 timeProvider.Tick() 855 } 856 } 857 858 // 859 func setupTest(timeProvider timestampProvider, signer Signer) (rh *TestHandler, datadir string, teardown func(), err error) { 860 861 var fsClean func() 862 var rpcClean func() 863 cleanF = func() { 864 if fsClean != nil { 865 fsClean() 866 } 867 if rpcClean != nil { 868 rpcClean() 869 } 870 } 871 872 // 873 datadir, err = ioutil.TempDir("", "rh") 874 if err != nil { 875 return nil, "", nil, err 876 } 877 fsClean = func() { 878 os.RemoveAll(datadir) 879 } 880 881 TimestampProvider = timeProvider 882 rhparams := &HandlerParams{} 883 rh, err = NewTestHandler(datadir, rhparams) 884 return rh, datadir, cleanF, err 885 } 886 887 func newAliceSigner() *GenericSigner { 888 privKey, _ := crypto.HexToECDSA("deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef") 889 return NewGenericSigner(privKey) 890 } 891 892 func newBobSigner() *GenericSigner { 893 privKey, _ := crypto.HexToECDSA("accedeaccedeaccedeaccedeaccedeaccedeaccedeaccedeaccedeaccedecaca") 894 return NewGenericSigner(privKey) 895 } 896 897 func newCharlieSigner() *GenericSigner { 898 privKey, _ := crypto.HexToECDSA("facadefacadefacadefacadefacadefacadefacadefacadefacadefacadefaca") 899 return NewGenericSigner(privKey) 900 } 901 902 func getUpdateDirect(rh *Handler, addr storage.Address) ([]byte, error) { 903 chunk, err := rh.chunkStore.Get(context.TODO(), addr) 904 if err != nil { 905 return nil, err 906 } 907 var r SignedResourceUpdate 908 if err := r.fromChunk(addr, chunk.SData); err != nil { 909 return nil, err 910 } 911 return r.data, nil 912 }