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