gitlab.com/jokerrs1/Sia@v1.3.2/modules/renter/contractor/update_test.go (about)

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