github.com/NebulousLabs/Sia@v1.3.7/modules/renter/contractor/update_test.go (about) 1 package contractor 2 3 import ( 4 "testing" 5 "time" 6 7 "github.com/NebulousLabs/Sia/build" 8 "github.com/NebulousLabs/Sia/crypto" 9 "github.com/NebulousLabs/Sia/modules" 10 "github.com/NebulousLabs/Sia/types" 11 12 "github.com/NebulousLabs/errors" 13 "github.com/NebulousLabs/fastrand" 14 ) 15 16 // TestIntegrationAutoRenew tests that contracts are automatically renewed at 17 // the expected block height. 18 func TestIntegrationAutoRenew(t *testing.T) { 19 if testing.Short() { 20 t.SkipNow() 21 } 22 t.Parallel() 23 // create testing trio 24 _, c, m, err := newTestingTrio(t.Name()) 25 if err != nil { 26 t.Fatal(err) 27 } 28 29 // form a contract with the host 30 a := modules.Allowance{ 31 Funds: types.SiacoinPrecision.Mul64(100), // 100 SC 32 Hosts: 1, 33 Period: 50, 34 RenewWindow: 10, 35 } 36 err = c.SetAllowance(a) 37 if err != nil { 38 t.Fatal(err) 39 } 40 err = build.Retry(50, 100*time.Millisecond, func() error { 41 if len(c.Contracts()) == 0 { 42 return errors.New("contracts were not formed") 43 } 44 return nil 45 }) 46 if err != nil { 47 t.Fatal(err) 48 } 49 contract := c.Contracts()[0] 50 51 // revise the contract 52 editor, err := c.Editor(contract.HostPublicKey, nil) 53 if err != nil { 54 t.Fatal(err) 55 } 56 data := fastrand.Bytes(int(modules.SectorSize)) 57 // insert the sector 58 _, err = editor.Upload(data) 59 if err != nil { 60 t.Fatal(err) 61 } 62 err = editor.Close() 63 if err != nil { 64 t.Fatal(err) 65 } 66 67 // mine until we enter the renew window 68 renewHeight := contract.EndHeight - c.allowance.RenewWindow 69 for c.blockHeight < renewHeight { 70 _, err := m.AddBlock() 71 if err != nil { 72 t.Fatal(err) 73 } 74 } 75 // wait for goroutine in ProcessConsensusChange to finish 76 time.Sleep(100 * time.Millisecond) 77 c.maintenanceLock.Lock() 78 c.maintenanceLock.Unlock() 79 80 // check renewed contract 81 contract = c.Contracts()[0] 82 endHeight := c.CurrentPeriod() + c.allowance.Period 83 if contract.EndHeight != endHeight { 84 t.Fatalf("Wrong end height, expected %v got %v\n", endHeight, contract.EndHeight) 85 } 86 } 87 88 // TestIntegrationRenewInvalidate tests that editors and downloaders are 89 // properly invalidated when a renew is queued. 90 func TestIntegrationRenewInvalidate(t *testing.T) { 91 if testing.Short() { 92 t.SkipNow() 93 } 94 t.Parallel() 95 // create testing trio 96 _, c, m, err := newTestingTrio(t.Name()) 97 if err != nil { 98 t.Fatal(err) 99 } 100 101 // form a contract with the host 102 a := modules.Allowance{ 103 Funds: types.SiacoinPrecision.Mul64(100), // 100 SC 104 Hosts: 1, 105 Period: 50, 106 RenewWindow: 10, 107 } 108 err = c.SetAllowance(a) 109 if err != nil { 110 t.Fatal(err) 111 } 112 err = build.Retry(50, 100*time.Millisecond, func() error { 113 if len(c.Contracts()) == 0 { 114 return errors.New("contracts were not formed") 115 } 116 return nil 117 }) 118 if err != nil { 119 t.Fatal(err) 120 } 121 contract := c.Contracts()[0] 122 123 // revise the contract 124 editor, err := c.Editor(contract.HostPublicKey, nil) 125 if err != nil { 126 t.Fatal(err) 127 } 128 data := fastrand.Bytes(int(modules.SectorSize)) 129 // insert the sector 130 _, err = editor.Upload(data) 131 if err != nil { 132 t.Fatal(err) 133 } 134 135 // mine until we enter the renew window; the editor should be invalidated 136 renewHeight := contract.EndHeight - c.allowance.RenewWindow 137 for c.blockHeight < renewHeight { 138 _, err := m.AddBlock() 139 if err != nil { 140 t.Fatal(err) 141 } 142 } 143 // wait for goroutine in ProcessConsensusChange to finish 144 time.Sleep(100 * time.Millisecond) 145 c.maintenanceLock.Lock() 146 c.maintenanceLock.Unlock() 147 148 // check renewed contract 149 contract = c.Contracts()[0] 150 endHeight := c.CurrentPeriod() + c.allowance.Period 151 c.mu.Lock() 152 if contract.EndHeight != endHeight { 153 t.Fatalf("Wrong end height, expected %v got %v\n", endHeight, contract.EndHeight) 154 } 155 c.mu.Unlock() 156 157 // editor should have been invalidated 158 _, err = editor.Upload(make([]byte, modules.SectorSize)) 159 if err != errInvalidEditor { 160 t.Error("expected invalid editor error; got", err) 161 } 162 editor.Close() 163 164 // create a downloader 165 downloader, err := c.Downloader(contract.HostPublicKey, nil) 166 if err != nil { 167 t.Fatal(err) 168 } 169 // mine until we enter the renew window 170 renewHeight = contract.EndHeight - c.allowance.RenewWindow 171 for c.blockHeight < renewHeight { 172 _, err := m.AddBlock() 173 if err != nil { 174 t.Fatal(err) 175 } 176 } 177 178 // downloader should have been invalidated 179 err = build.Retry(50, 100*time.Millisecond, func() error { 180 // wait for goroutine in ProcessConsensusChange to finish 181 c.maintenanceLock.Lock() 182 c.maintenanceLock.Unlock() 183 _, err2 := downloader.Sector(crypto.Hash{}) 184 if err2 != errInvalidDownloader { 185 return errors.AddContext(err, "expected invalid downloader error") 186 } 187 return downloader.Close() 188 }) 189 if err != nil { 190 t.Fatal(err) 191 } 192 }