gitlab.com/SiaPrime/SiaPrime@v1.4.1/node/api/hostdb_test.go (about)

     1  package api
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"net/url"
     9  	"path/filepath"
    10  	"testing"
    11  	"time"
    12  
    13  	"gitlab.com/SiaPrime/SiaPrime/build"
    14  	"gitlab.com/SiaPrime/SiaPrime/crypto"
    15  	"gitlab.com/SiaPrime/SiaPrime/modules"
    16  	"gitlab.com/SiaPrime/SiaPrime/modules/consensus"
    17  	"gitlab.com/SiaPrime/SiaPrime/modules/gateway"
    18  	"gitlab.com/SiaPrime/SiaPrime/modules/host"
    19  	"gitlab.com/SiaPrime/SiaPrime/modules/miner"
    20  	"gitlab.com/SiaPrime/SiaPrime/modules/renter"
    21  	"gitlab.com/SiaPrime/SiaPrime/modules/transactionpool"
    22  	"gitlab.com/SiaPrime/SiaPrime/modules/wallet"
    23  )
    24  
    25  // TestHostDBHostsActiveHandler checks the behavior of the call to
    26  // /hostdb/active.
    27  func TestHostDBHostsActiveHandler(t *testing.T) {
    28  	if testing.Short() {
    29  		t.SkipNow()
    30  	}
    31  	st, err := createServerTester(t.Name())
    32  	if err != nil {
    33  		t.Fatal(err)
    34  	}
    35  	defer st.server.panicClose()
    36  
    37  	// Try the call with numhosts unset, and set to -1, 0, and 1.
    38  	var ah HostdbActiveGET
    39  	err = st.getAPI("/hostdb/active", &ah)
    40  	if err != nil {
    41  		t.Fatal(err)
    42  	}
    43  	if len(ah.Hosts) != 0 {
    44  		t.Fatal(len(ah.Hosts))
    45  	}
    46  	err = st.getAPI("/hostdb/active?numhosts=-1", &ah)
    47  	if err == nil {
    48  		t.Fatal("expecting an error, got:", err)
    49  	}
    50  	err = st.getAPI("/hostdb/active?numhosts=0", &ah)
    51  	if err != nil {
    52  		t.Fatal(err)
    53  	}
    54  	if len(ah.Hosts) != 0 {
    55  		t.Fatal(len(ah.Hosts))
    56  	}
    57  	err = st.getAPI("/hostdb/active?numhosts=1", &ah)
    58  	if err != nil {
    59  		t.Fatal(err)
    60  	}
    61  	if len(ah.Hosts) != 0 {
    62  		t.Fatal(len(ah.Hosts))
    63  	}
    64  
    65  	// announce the host and start accepting contracts
    66  	err = st.setHostStorage()
    67  	if err != nil {
    68  		t.Fatal(err)
    69  	}
    70  	err = st.announceHost()
    71  	if err != nil {
    72  		t.Fatal(err)
    73  	}
    74  	err = st.acceptContracts()
    75  	if err != nil {
    76  		t.Fatal(err)
    77  	}
    78  
    79  	// Try the call with with numhosts unset, and set to -1, 0, 1, and 2.
    80  	err = st.getAPI("/hostdb/active", &ah)
    81  	if err != nil {
    82  		t.Fatal(err)
    83  	}
    84  	if len(ah.Hosts) != 1 {
    85  		t.Fatal(len(ah.Hosts))
    86  	}
    87  	err = st.getAPI("/hostdb/active?numhosts=-1", &ah)
    88  	if err == nil {
    89  		t.Fatal("expecting an error, got:", err)
    90  	}
    91  	err = st.getAPI("/hostdb/active?numhosts=0", &ah)
    92  	if err != nil {
    93  		t.Fatal(err)
    94  	}
    95  	if len(ah.Hosts) != 0 {
    96  		t.Fatal(len(ah.Hosts))
    97  	}
    98  	err = st.getAPI("/hostdb/active?numhosts=1", &ah)
    99  	if err != nil {
   100  		t.Fatal(err)
   101  	}
   102  	if len(ah.Hosts) != 1 {
   103  		t.Fatal(len(ah.Hosts))
   104  	}
   105  	err = st.getAPI("/hostdb/active?numhosts=2", &ah)
   106  	if err != nil {
   107  		t.Fatal(err)
   108  	}
   109  	if len(ah.Hosts) != 1 {
   110  		t.Fatal(len(ah.Hosts))
   111  	}
   112  }
   113  
   114  // TestHostDBHostsAllHandler checks that announcing a host adds it to the list
   115  // of all hosts.
   116  func TestHostDBHostsAllHandler(t *testing.T) {
   117  	if testing.Short() {
   118  		t.SkipNow()
   119  	}
   120  	st, err := createServerTester(t.Name())
   121  	if err != nil {
   122  		t.Fatal(err)
   123  	}
   124  	defer st.server.panicClose()
   125  
   126  	// Try the call before any hosts have been declared.
   127  	var ah HostdbAllGET
   128  	if err = st.getAPI("/hostdb/all", &ah); err != nil {
   129  		t.Fatal(err)
   130  	}
   131  	if len(ah.Hosts) != 0 {
   132  		t.Fatalf("expected 0 hosts, got %v", len(ah.Hosts))
   133  	}
   134  	// Announce the host and try the call again.
   135  	if err = st.announceHost(); err != nil {
   136  		t.Fatal(err)
   137  	}
   138  	if err = st.getAPI("/hostdb/all", &ah); err != nil {
   139  		t.Fatal(err)
   140  	}
   141  	if len(ah.Hosts) != 1 {
   142  		t.Fatalf("expected 1 host, got %v", len(ah.Hosts))
   143  	}
   144  }
   145  
   146  // TestHostDBHostsHandler checks that the hosts handler is easily able to return
   147  func TestHostDBHostsHandler(t *testing.T) {
   148  	if testing.Short() {
   149  		t.SkipNow()
   150  	}
   151  	st, err := createServerTester(t.Name())
   152  	if err != nil {
   153  		t.Fatal(err)
   154  	}
   155  	defer st.server.panicClose()
   156  
   157  	// Announce the host and then get the list of hosts.
   158  	var ah HostdbActiveGET
   159  	err = st.setHostStorage()
   160  	if err != nil {
   161  		t.Fatal(err)
   162  	}
   163  	if err = st.announceHost(); err != nil {
   164  		t.Fatal(err)
   165  	}
   166  	if err = st.getAPI("/hostdb/active", &ah); err != nil {
   167  		t.Fatal(err)
   168  	}
   169  	if len(ah.Hosts) != 1 {
   170  		t.Fatalf("expected 1 host, got %v", len(ah.Hosts))
   171  	}
   172  
   173  	// Parse the pubkey from the returned list of hosts and use it to form a
   174  	// request regarding the specific host.
   175  	keyString := ah.Hosts[0].PublicKey.String()
   176  	if keyString != ah.Hosts[0].PublicKeyString {
   177  		t.Error("actual key string and provided string do not match")
   178  	}
   179  	query := fmt.Sprintf("/hostdb/hosts/%s", ah.Hosts[0].PublicKeyString)
   180  
   181  	// Get the detailed info for the host.
   182  	var hh HostdbHostsGET
   183  	if err = st.getAPI(query, &hh); err != nil {
   184  		t.Fatal(err)
   185  	}
   186  
   187  	// Check that none of the values equal zero. A value of zero indicates that
   188  	// the field is no longer being tracked/reported, which could break
   189  	// compatibility for some apps. The default needs to be '1', not zero.
   190  	if hh.ScoreBreakdown.Score.IsZero() {
   191  		t.Error("Zero vaue score in score breakdown")
   192  	}
   193  	if hh.ScoreBreakdown.AgeAdjustment == 0 {
   194  		t.Error("Zero value in host score breakdown")
   195  	}
   196  	if hh.ScoreBreakdown.BurnAdjustment == 0 {
   197  		t.Error("Zero value in host score breakdown")
   198  	}
   199  	if hh.ScoreBreakdown.CollateralAdjustment == 0 {
   200  		t.Error("Zero value in host score breakdown")
   201  	}
   202  	if hh.ScoreBreakdown.PriceAdjustment == 0 {
   203  		t.Error("Zero value in host score breakdown")
   204  	}
   205  	if hh.ScoreBreakdown.StorageRemainingAdjustment == 0 {
   206  		t.Error("Zero value in host score breakdown")
   207  	}
   208  	if hh.ScoreBreakdown.UptimeAdjustment == 0 {
   209  		t.Error("Zero value in host score breakdown")
   210  	}
   211  	if hh.ScoreBreakdown.VersionAdjustment == 0 {
   212  		t.Error("Zero value in host score breakdown")
   213  	}
   214  
   215  	// Check that none of the supported values equals 1. A value of 1 indicates
   216  	// that the hostdb is not performing any penalties or rewards for that
   217  	// field, meaning that the calibration for that field is probably incorrect.
   218  	if hh.ScoreBreakdown.AgeAdjustment == 1 {
   219  		t.Error("One value in host score breakdown")
   220  	}
   221  	// Burn adjustment is not yet supported.
   222  	//
   223  	// if hh.ScoreBreakdown.BurnAdjustment == 1 {
   224  	//	t.Error("One value in host score breakdown")
   225  	// }
   226  	if hh.ScoreBreakdown.CollateralAdjustment == 1 {
   227  		t.Error("One value in host score breakdown")
   228  	}
   229  	if hh.ScoreBreakdown.PriceAdjustment == 1 {
   230  		t.Error("One value in host score breakdown")
   231  	}
   232  	if hh.ScoreBreakdown.StorageRemainingAdjustment == 1 {
   233  		t.Error("One value in host score breakdown")
   234  	}
   235  	if hh.ScoreBreakdown.UptimeAdjustment == 1 {
   236  		t.Error("One value in host score breakdown")
   237  	}
   238  	if hh.ScoreBreakdown.VersionAdjustment == 1 {
   239  		t.Error("One value in host score breakdown")
   240  	}
   241  }
   242  
   243  // assembleHostHostname is assembleServerTester but you can specify which
   244  // hostname the host should use.
   245  func assembleHostPort(key crypto.CipherKey, hostHostname string, testdir string) (*serverTester, error) {
   246  	// assembleServerTester should not get called during short tests, as it
   247  	// takes a long time to run.
   248  	if testing.Short() {
   249  		panic("assembleServerTester called during short tests")
   250  	}
   251  
   252  	// Create the modules.
   253  	g, err := gateway.New("localhost:0", false, filepath.Join(testdir, modules.GatewayDir))
   254  	if err != nil {
   255  		return nil, err
   256  	}
   257  	cs, err := consensus.New(g, false, filepath.Join(testdir, modules.ConsensusDir))
   258  	if err != nil {
   259  		return nil, err
   260  	}
   261  	tp, err := transactionpool.New(cs, g, filepath.Join(testdir, modules.TransactionPoolDir))
   262  	if err != nil {
   263  		return nil, err
   264  	}
   265  	w, err := wallet.New(cs, tp, filepath.Join(testdir, modules.WalletDir))
   266  	if err != nil {
   267  		return nil, err
   268  	}
   269  	encrypted, err := w.Encrypted()
   270  	if err != nil {
   271  		return nil, err
   272  	}
   273  	if !encrypted {
   274  		_, err = w.Encrypt(key)
   275  		if err != nil {
   276  			return nil, err
   277  		}
   278  	}
   279  	err = w.Unlock(key)
   280  	if err != nil {
   281  		return nil, err
   282  	}
   283  	m, err := miner.New(cs, tp, w, filepath.Join(testdir, modules.MinerDir))
   284  	if err != nil {
   285  		return nil, err
   286  	}
   287  	h, err := host.New(cs, g, tp, w, hostHostname, filepath.Join(testdir, modules.HostDir))
   288  	if err != nil {
   289  		return nil, err
   290  	}
   291  	r, err := renter.New(g, cs, w, tp, filepath.Join(testdir, modules.RenterDir))
   292  	if err != nil {
   293  		return nil, err
   294  	}
   295  	srv, err := NewServer(testdir, "localhost:0", "Sia-PrimeAgent", "", cs, nil, g, h, m, r, tp, w, nil, nil, nil)
   296  	if err != nil {
   297  		return nil, err
   298  	}
   299  
   300  	// Assemble the serverTester.
   301  	st := &serverTester{
   302  		cs:        cs,
   303  		gateway:   g,
   304  		host:      h,
   305  		miner:     m,
   306  		renter:    r,
   307  		tpool:     tp,
   308  		wallet:    w,
   309  		walletKey: key,
   310  
   311  		server: srv,
   312  
   313  		dir: testdir,
   314  	}
   315  
   316  	// TODO: A more reasonable way of listening for server errors.
   317  	go func() {
   318  		listenErr := srv.Serve()
   319  		if listenErr != nil {
   320  			panic(listenErr)
   321  		}
   322  	}()
   323  	return st, nil
   324  }
   325  
   326  // TestHostDBScanOnlineOffline checks that both online and offline hosts get
   327  // scanned in the hostdb.
   328  func TestHostDBScanOnlineOffline(t *testing.T) {
   329  	if testing.Short() || !build.VLONG {
   330  		t.SkipNow()
   331  	}
   332  	t.Parallel()
   333  	st, err := createServerTester(t.Name())
   334  	if err != nil {
   335  		t.Fatal(err)
   336  	}
   337  	defer st.panicClose()
   338  	stHost, err := blankServerTester(t.Name() + "-Host")
   339  	if err != nil {
   340  		t.Fatal(err)
   341  	}
   342  	sts := []*serverTester{st, stHost}
   343  	err = fullyConnectNodes(sts)
   344  	if err != nil {
   345  		t.Fatal(err)
   346  	}
   347  	err = fundAllNodes(sts)
   348  	if err != nil {
   349  		t.Fatal(err)
   350  	}
   351  
   352  	// Announce the host.
   353  	err = stHost.acceptContracts()
   354  	if err != nil {
   355  		t.Fatal(err)
   356  	}
   357  	err = stHost.setHostStorage()
   358  	if err != nil {
   359  		t.Fatal(err)
   360  	}
   361  	err = stHost.announceHost()
   362  	if err != nil {
   363  		t.Fatal(err)
   364  	}
   365  
   366  	// Verify the host is visible.
   367  	var ah HostdbActiveGET
   368  	for i := 0; i < 50; i++ {
   369  		if err = st.getAPI("/hostdb/active", &ah); err != nil {
   370  			t.Fatal(err)
   371  		}
   372  		if len(ah.Hosts) == 1 {
   373  			break
   374  		}
   375  		time.Sleep(time.Millisecond * 100)
   376  	}
   377  	if len(ah.Hosts) != 1 {
   378  		t.Fatalf("expected 1 host, got %v", len(ah.Hosts))
   379  	}
   380  	hostAddr := ah.Hosts[0].NetAddress
   381  
   382  	// Close the host and wait for a scan to knock the host out of the hostdb.
   383  	err = stHost.server.Close()
   384  	if err != nil {
   385  		t.Fatal(err)
   386  	}
   387  	err = build.Retry(60, time.Second, func() error {
   388  		if err := st.getAPI("/hostdb/active", &ah); err != nil {
   389  			return err
   390  		}
   391  		if len(ah.Hosts) == 0 {
   392  			return nil
   393  		}
   394  		return errors.New("host still in hostdb")
   395  	})
   396  	if err != nil {
   397  		t.Fatal(err)
   398  	}
   399  
   400  	// Reopen the host and wait for a scan to bring the host back into the
   401  	// hostdb.
   402  	stHost, err = assembleHostPort(stHost.walletKey, string(hostAddr), stHost.dir)
   403  	if err != nil {
   404  		t.Fatal(err)
   405  	}
   406  	defer stHost.panicClose()
   407  	sts[1] = stHost
   408  	err = fullyConnectNodes(sts)
   409  	if err != nil {
   410  		t.Fatal(err)
   411  	}
   412  	err = build.Retry(60, time.Second, func() error {
   413  		// Get the hostdb internals.
   414  		if err = st.getAPI("/hostdb/active", &ah); err != nil {
   415  			return err
   416  		}
   417  		if len(ah.Hosts) != 1 {
   418  			return fmt.Errorf("expected 1 host, got %v", len(ah.Hosts))
   419  		}
   420  		return nil
   421  	})
   422  	if err != nil {
   423  		t.Fatal(err)
   424  	}
   425  }
   426  
   427  // TestHostDBAndRenterDownloadDynamicIPs checks that the hostdb and the renter are
   428  // successfully able to follow a host that has changed IP addresses and then
   429  // re-announced.
   430  func TestHostDBAndRenterDownloadDynamicIPs(t *testing.T) {
   431  	if testing.Short() || !build.VLONG {
   432  		t.SkipNow()
   433  	}
   434  	t.Parallel()
   435  	st, err := createServerTester(t.Name())
   436  	if err != nil {
   437  		t.Fatal(err)
   438  	}
   439  	defer st.panicClose()
   440  	stHost, err := blankServerTester(t.Name() + "-Host")
   441  	if err != nil {
   442  		t.Fatal(err)
   443  	}
   444  	sts := []*serverTester{st, stHost}
   445  	err = fullyConnectNodes(sts)
   446  	if err != nil {
   447  		t.Fatal(err)
   448  	}
   449  	err = fundAllNodes(sts)
   450  	if err != nil {
   451  		t.Fatal(err)
   452  	}
   453  
   454  	// Announce the host.
   455  	err = stHost.acceptContracts()
   456  	if err != nil {
   457  		t.Fatal(err)
   458  	}
   459  	err = stHost.setHostStorage()
   460  	if err != nil {
   461  		t.Fatal(err)
   462  	}
   463  	err = stHost.announceHost()
   464  	if err != nil {
   465  		t.Fatal(err)
   466  	}
   467  
   468  	// Pull the host's net address and pubkey from the hostdb.
   469  	var ah HostdbActiveGET
   470  	for i := 0; i < 50; i++ {
   471  		if err = st.getAPI("/hostdb/active", &ah); err != nil {
   472  			t.Fatal(err)
   473  		}
   474  		if len(ah.Hosts) == 1 {
   475  			break
   476  		}
   477  		time.Sleep(time.Millisecond * 100)
   478  	}
   479  	if len(ah.Hosts) != 1 {
   480  		t.Fatalf("expected 1 host, got %v", len(ah.Hosts))
   481  	}
   482  	addr := ah.Hosts[0].NetAddress
   483  	pks := ah.Hosts[0].PublicKeyString
   484  
   485  	// Upload a file to the host.
   486  	allowanceValues := url.Values{}
   487  	testFunds := "10000000000000000000000000000" // 10k SC
   488  	testPeriod := "10"
   489  	testPeriodInt := 10
   490  	allowanceValues.Set("funds", testFunds)
   491  	allowanceValues.Set("period", testPeriod)
   492  	err = st.stdPostAPI("/renter", allowanceValues)
   493  	if err != nil {
   494  		t.Fatal(err)
   495  	}
   496  	// Create a file.
   497  	path := filepath.Join(st.dir, "test.dat")
   498  	err = createRandFile(path, 1024)
   499  	if err != nil {
   500  		t.Fatal(err)
   501  	}
   502  	// Upload the file to the renter.
   503  	uploadValues := url.Values{}
   504  	uploadValues.Set("source", path)
   505  	err = st.stdPostAPI("/renter/upload/test", uploadValues)
   506  	if err != nil {
   507  		t.Fatal(err)
   508  	}
   509  	// Only one piece will be uploaded (10% at current redundancy).
   510  	var rf RenterFiles
   511  	for i := 0; i < 200 && (len(rf.Files) != 1 || rf.Files[0].UploadProgress < 10); i++ {
   512  		st.getAPI("/renter/files", &rf)
   513  		time.Sleep(100 * time.Millisecond)
   514  	}
   515  	if len(rf.Files) != 1 || rf.Files[0].UploadProgress < 10 {
   516  		t.Fatal("the uploading is not succeeding for some reason:", rf.Files[0])
   517  	}
   518  
   519  	// Try downloading the file.
   520  	downpath := filepath.Join(st.dir, "testdown.dat")
   521  	err = st.stdGetAPI("/renter/download/test?destination=" + downpath)
   522  	if err != nil {
   523  		t.Fatal(err)
   524  	}
   525  	// Check that the download has the right contents.
   526  	orig, err := ioutil.ReadFile(path)
   527  	if err != nil {
   528  		t.Fatal(err)
   529  	}
   530  	download, err := ioutil.ReadFile(downpath)
   531  	if err != nil {
   532  		t.Fatal(err)
   533  	}
   534  	if !bytes.Equal(orig, download) {
   535  		t.Fatal("data mismatch when downloading a file")
   536  	}
   537  
   538  	// Mine a block before resetting the host, so that the host doesn't lose
   539  	// it's contracts when the transaction pool resets.
   540  	_, err = st.miner.AddBlock()
   541  	if err != nil {
   542  		t.Fatal(err)
   543  	}
   544  	_, err = synchronizationCheck(sts)
   545  	if err != nil {
   546  		t.Fatal(err)
   547  	}
   548  	// Give time for the upgrade to happen.
   549  	time.Sleep(time.Second * 3)
   550  
   551  	// Close and re-open the host. This should reset the host's address, as the
   552  	// host should now be on a new port.
   553  	err = stHost.server.Close()
   554  	if err != nil {
   555  		t.Fatal(err)
   556  	}
   557  	stHost, err = assembleServerTester(stHost.walletKey, stHost.dir)
   558  	if err != nil {
   559  		t.Fatal(err)
   560  	}
   561  	defer stHost.panicClose()
   562  	sts[1] = stHost
   563  	err = fullyConnectNodes(sts)
   564  	if err != nil {
   565  		t.Fatal(err)
   566  	}
   567  	err = stHost.announceHost()
   568  	if err != nil {
   569  		t.Fatal(err)
   570  	}
   571  	// Pull the host's net address and pubkey from the hostdb.
   572  	err = build.Retry(100, time.Millisecond*200, func() error {
   573  		// Get the hostdb internals.
   574  		if err = st.getAPI("/hostdb/active", &ah); err != nil {
   575  			return err
   576  		}
   577  
   578  		// Get the host's internals.
   579  		var hg HostGET
   580  		if err = stHost.getAPI("/host", &hg); err != nil {
   581  			return err
   582  		}
   583  
   584  		if len(ah.Hosts) != 1 {
   585  			return fmt.Errorf("expected 1 host, got %v", len(ah.Hosts))
   586  		}
   587  		if ah.Hosts[0].NetAddress != hg.ExternalSettings.NetAddress {
   588  			return fmt.Errorf("hostdb net address doesn't match host net address: %v : %v", ah.Hosts[0].NetAddress, hg.ExternalSettings.NetAddress)
   589  		}
   590  		return nil
   591  	})
   592  	if err != nil {
   593  		t.Fatal(err)
   594  	}
   595  	if ah.Hosts[0].PublicKeyString != pks {
   596  		t.Error("public key appears to have changed for host")
   597  	}
   598  	if ah.Hosts[0].NetAddress == addr {
   599  		t.Log("NetAddress did not change for the new host")
   600  	}
   601  
   602  	// Try downloading the file.
   603  	err = st.stdGetAPI("/renter/download/test?destination=" + downpath)
   604  	if err != nil {
   605  		t.Fatal(err)
   606  	}
   607  	// Check that the download has the right contents.
   608  	download, err = ioutil.ReadFile(downpath)
   609  	if err != nil {
   610  		t.Fatal(err)
   611  	}
   612  	if !bytes.Equal(orig, download) {
   613  		t.Fatal("data mismatch when downloading a file")
   614  	}
   615  
   616  	// Mine enough blocks that multiple renew cylces happen. After the renewing
   617  	// happens, the file should still be downloadable. This is to check that the
   618  	// renewal doesn't throw things off.
   619  	for i := 0; i < testPeriodInt; i++ {
   620  		_, err = st.miner.AddBlock()
   621  		if err != nil {
   622  			t.Fatal(err)
   623  		}
   624  		_, err = synchronizationCheck(sts)
   625  		if err != nil {
   626  			t.Fatal(err)
   627  		}
   628  	}
   629  	err = build.Retry(100, time.Millisecond*100, func() error {
   630  		err = st.stdGetAPI("/renter/download/test?destination=" + downpath)
   631  		if err != nil {
   632  			return err
   633  		}
   634  		// Try downloading the file.
   635  		// Check that the download has the right contents.
   636  		download, err = ioutil.ReadFile(downpath)
   637  		if err != nil {
   638  			return err
   639  		}
   640  		if !bytes.Equal(orig, download) {
   641  			return errors.New("downloaded file does not equal the original")
   642  		}
   643  		return nil
   644  	})
   645  	if err != nil {
   646  		t.Fatal(err)
   647  	}
   648  }
   649  
   650  // TestHostDBAndRenterUploadDynamicIPs checks that the hostdb and the renter are
   651  // successfully able to follow a host that has changed IP addresses and then
   652  // re-announced.
   653  func TestHostDBAndRenterUploadDynamicIPs(t *testing.T) {
   654  	if testing.Short() || !build.VLONG {
   655  		t.SkipNow()
   656  	}
   657  	t.Parallel()
   658  	st, err := createServerTester(t.Name())
   659  	if err != nil {
   660  		t.Fatal(err)
   661  	}
   662  	defer st.panicClose()
   663  	stHost, err := blankServerTester(t.Name() + "-Host")
   664  	if err != nil {
   665  		t.Fatal(err)
   666  	}
   667  	sts := []*serverTester{st, stHost}
   668  	err = fullyConnectNodes(sts)
   669  	if err != nil {
   670  		t.Fatal(err)
   671  	}
   672  	err = fundAllNodes(sts)
   673  	if err != nil {
   674  		t.Fatal(err)
   675  	}
   676  
   677  	// Announce the host.
   678  	err = stHost.acceptContracts()
   679  	if err != nil {
   680  		t.Fatal(err)
   681  	}
   682  	err = stHost.setHostStorage()
   683  	if err != nil {
   684  		t.Fatal(err)
   685  	}
   686  	err = stHost.announceHost()
   687  	if err != nil {
   688  		t.Fatal(err)
   689  	}
   690  
   691  	// Pull the host's net address and pubkey from the hostdb.
   692  	var ah HostdbActiveGET
   693  	for i := 0; i < 50; i++ {
   694  		if err = st.getAPI("/hostdb/active", &ah); err != nil {
   695  			t.Fatal(err)
   696  		}
   697  		if len(ah.Hosts) == 1 {
   698  			break
   699  		}
   700  		time.Sleep(time.Millisecond * 100)
   701  	}
   702  	if len(ah.Hosts) != 1 {
   703  		t.Fatalf("expected 1 host, got %v", len(ah.Hosts))
   704  	}
   705  	addr := ah.Hosts[0].NetAddress
   706  	pks := ah.Hosts[0].PublicKeyString
   707  
   708  	// Upload a file to the host.
   709  	allowanceValues := url.Values{}
   710  	testFunds := "10000000000000000000000000000" // 10k SC
   711  	testPeriod := "10"
   712  	testPeriodInt := 10
   713  	allowanceValues.Set("funds", testFunds)
   714  	allowanceValues.Set("period", testPeriod)
   715  	err = st.stdPostAPI("/renter", allowanceValues)
   716  	if err != nil {
   717  		t.Fatal(err)
   718  	}
   719  	// Create a file.
   720  	path := filepath.Join(st.dir, "test.dat")
   721  	err = createRandFile(path, 1024)
   722  	if err != nil {
   723  		t.Fatal(err)
   724  	}
   725  	// Upload the file to the renter.
   726  	uploadValues := url.Values{}
   727  	uploadValues.Set("source", path)
   728  	err = st.stdPostAPI("/renter/upload/test", uploadValues)
   729  	if err != nil {
   730  		t.Fatal(err)
   731  	}
   732  	// Only one piece will be uploaded (10% at current redundancy).
   733  	var rf RenterFiles
   734  	for i := 0; i < 200 && (len(rf.Files) != 1 || rf.Files[0].UploadProgress < 10); i++ {
   735  		st.getAPI("/renter/files", &rf)
   736  		time.Sleep(100 * time.Millisecond)
   737  	}
   738  	if len(rf.Files) != 1 || rf.Files[0].UploadProgress < 10 {
   739  		t.Fatal("the uploading is not succeeding for some reason:", rf.Files[0])
   740  	}
   741  
   742  	// Mine a block before resetting the host, so that the host doesn't lose
   743  	// it's contracts when the transaction pool resets.
   744  	_, err = st.miner.AddBlock()
   745  	if err != nil {
   746  		t.Fatal(err)
   747  	}
   748  	_, err = synchronizationCheck(sts)
   749  	if err != nil {
   750  		t.Fatal(err)
   751  	}
   752  	// Give time for the upgrade to happen.
   753  	time.Sleep(time.Second * 3)
   754  
   755  	// Close and re-open the host. This should reset the host's address, as the
   756  	// host should now be on a new port.
   757  	err = stHost.server.Close()
   758  	if err != nil {
   759  		t.Fatal(err)
   760  	}
   761  	stHost, err = assembleServerTester(stHost.walletKey, stHost.dir)
   762  	if err != nil {
   763  		t.Fatal(err)
   764  	}
   765  	defer stHost.panicClose()
   766  	sts[1] = stHost
   767  	err = fullyConnectNodes(sts)
   768  	if err != nil {
   769  		t.Fatal(err)
   770  	}
   771  	err = stHost.announceHost()
   772  	if err != nil {
   773  		t.Fatal(err)
   774  	}
   775  	// Pull the host's net address and pubkey from the hostdb.
   776  	err = build.Retry(50, time.Millisecond*100, func() error {
   777  		// Get the hostdb internals.
   778  		if err = st.getAPI("/hostdb/active", &ah); err != nil {
   779  			return err
   780  		}
   781  
   782  		// Get the host's internals.
   783  		var hg HostGET
   784  		if err = stHost.getAPI("/host", &hg); err != nil {
   785  			return err
   786  		}
   787  
   788  		if len(ah.Hosts) != 1 {
   789  			return fmt.Errorf("expected 1 host, got %v", len(ah.Hosts))
   790  		}
   791  		if ah.Hosts[0].NetAddress != hg.ExternalSettings.NetAddress {
   792  			return fmt.Errorf("hostdb net address doesn't match host net address: %v : %v", ah.Hosts[0].NetAddress, hg.ExternalSettings.NetAddress)
   793  		}
   794  		return nil
   795  	})
   796  	if err != nil {
   797  		t.Fatal(err)
   798  	}
   799  	if ah.Hosts[0].PublicKeyString != pks {
   800  		t.Error("public key appears to have changed for host")
   801  	}
   802  	if ah.Hosts[0].NetAddress == addr {
   803  		t.Log("NetAddress did not change for the new host")
   804  	}
   805  
   806  	// Try uploading a second file.
   807  	path2 := filepath.Join(st.dir, "test2.dat")
   808  	test2Size := modules.SectorSize*2 + 1
   809  	err = createRandFile(path2, int(test2Size))
   810  	if err != nil {
   811  		t.Fatal(err)
   812  	}
   813  	uploadValues = url.Values{}
   814  	uploadValues.Set("source", path2)
   815  	err = st.stdPostAPI("/renter/upload/test2", uploadValues)
   816  	if err != nil {
   817  		t.Fatal(err)
   818  	}
   819  	// Only one piece will be uploaded (10% at current redundancy).
   820  	for i := 0; i < 200 && (len(rf.Files) != 2 || rf.Files[0].UploadProgress < 10 || rf.Files[1].UploadProgress < 10); i++ {
   821  		st.getAPI("/renter/files", &rf)
   822  		time.Sleep(100 * time.Millisecond)
   823  	}
   824  	if len(rf.Files) != 2 || rf.Files[0].UploadProgress < 10 || rf.Files[1].UploadProgress < 10 {
   825  		t.Fatal("the uploading is not succeeding for some reason:", rf.Files[0], rf.Files[1])
   826  	}
   827  
   828  	// Try downloading the second file.
   829  	downpath2 := filepath.Join(st.dir, "testdown2.dat")
   830  	err = st.stdGetAPI("/renter/download/test2?destination=" + downpath2)
   831  	if err != nil {
   832  		t.Fatal(err)
   833  	}
   834  	// Check that the download has the right contents.
   835  	orig2, err := ioutil.ReadFile(path2)
   836  	if err != nil {
   837  		t.Fatal(err)
   838  	}
   839  	download2, err := ioutil.ReadFile(downpath2)
   840  	if err != nil {
   841  		t.Fatal(err)
   842  	}
   843  	if !bytes.Equal(orig2, download2) {
   844  		t.Fatal("data mismatch when downloading a file")
   845  	}
   846  
   847  	// Mine enough blocks that multiple renew cylces happen. After the renewing
   848  	// happens, the file should still be downloadable. This is to check that the
   849  	// renewal doesn't throw things off.
   850  	for i := 0; i < testPeriodInt; i++ {
   851  		_, err = st.miner.AddBlock()
   852  		if err != nil {
   853  			t.Fatal(err)
   854  		}
   855  		_, err = synchronizationCheck(sts)
   856  		if err != nil {
   857  			t.Fatal(err)
   858  		}
   859  		// Give time for the upgrade to happen.
   860  		time.Sleep(time.Second * 3)
   861  	}
   862  
   863  	// Try downloading the file.
   864  	downpath := filepath.Join(st.dir, "testdown.dat")
   865  	err = st.stdGetAPI("/renter/download/test?destination=" + downpath)
   866  	if err != nil {
   867  		t.Fatal(err)
   868  	}
   869  	// Check that the download has the right contents.
   870  	download, err := ioutil.ReadFile(downpath)
   871  	if err != nil {
   872  		t.Fatal(err)
   873  	}
   874  	orig, err := ioutil.ReadFile(path)
   875  	if err != nil {
   876  		t.Fatal(err)
   877  	}
   878  	if !bytes.Equal(orig, download) {
   879  		t.Fatal("data mismatch when downloading a file")
   880  	}
   881  
   882  	// Try downloading the second file.
   883  	err = st.stdGetAPI("/renter/download/test2?destination=" + downpath2)
   884  	if err != nil {
   885  		t.Fatal(err)
   886  	}
   887  	// Check that the download has the right contents.
   888  	orig2, err = ioutil.ReadFile(path2)
   889  	if err != nil {
   890  		t.Fatal(err)
   891  	}
   892  	download2, err = ioutil.ReadFile(downpath2)
   893  	if err != nil {
   894  		t.Fatal(err)
   895  	}
   896  	if !bytes.Equal(orig2, download2) {
   897  		t.Fatal("data mismatch when downloading a file")
   898  	}
   899  }
   900  
   901  // TestHostDBAndRenterFormDynamicIPs checks that the hostdb and the renter are
   902  // successfully able to follow a host that has changed IP addresses and then
   903  // re-announced.
   904  func TestHostDBAndRenterFormDynamicIPs(t *testing.T) {
   905  	if testing.Short() || !build.VLONG {
   906  		t.SkipNow()
   907  	}
   908  	t.Parallel()
   909  	st, err := createServerTester(t.Name())
   910  	if err != nil {
   911  		t.Fatal(err)
   912  	}
   913  	defer st.panicClose()
   914  	stHost, err := blankServerTester(t.Name() + "-Host")
   915  	if err != nil {
   916  		t.Fatal(err)
   917  	}
   918  	sts := []*serverTester{st, stHost}
   919  	err = fullyConnectNodes(sts)
   920  	if err != nil {
   921  		t.Fatal(err)
   922  	}
   923  	err = fundAllNodes(sts)
   924  	if err != nil {
   925  		t.Fatal(err)
   926  	}
   927  
   928  	// Announce the host.
   929  	err = stHost.acceptContracts()
   930  	if err != nil {
   931  		t.Fatal(err)
   932  	}
   933  	err = stHost.setHostStorage()
   934  	if err != nil {
   935  		t.Fatal(err)
   936  	}
   937  	err = stHost.announceHost()
   938  	if err != nil {
   939  		t.Fatal(err)
   940  	}
   941  
   942  	// Pull the host's net address and pubkey from the hostdb.
   943  	var ah HostdbActiveGET
   944  	for i := 0; i < 50; i++ {
   945  		if err = st.getAPI("/hostdb/active", &ah); err != nil {
   946  			t.Fatal(err)
   947  		}
   948  		if len(ah.Hosts) == 1 {
   949  			break
   950  		}
   951  		time.Sleep(time.Millisecond * 100)
   952  	}
   953  	if len(ah.Hosts) != 1 {
   954  		t.Fatalf("expected 1 host, got %v", len(ah.Hosts))
   955  	}
   956  	addr := ah.Hosts[0].NetAddress
   957  	pks := ah.Hosts[0].PublicKeyString
   958  
   959  	// Mine a block before resetting the host, so that the host doesn't lose
   960  	// it's contracts when the transaction pool resets.
   961  	_, err = st.miner.AddBlock()
   962  	if err != nil {
   963  		t.Fatal(err)
   964  	}
   965  	_, err = synchronizationCheck(sts)
   966  	if err != nil {
   967  		t.Fatal(err)
   968  	}
   969  	// Give time for the upgrade to happen.
   970  	time.Sleep(time.Second * 3)
   971  
   972  	// Close and re-open the host. This should reset the host's address, as the
   973  	// host should now be on a new port.
   974  	err = stHost.server.Close()
   975  	if err != nil {
   976  		t.Fatal(err)
   977  	}
   978  	stHost, err = assembleServerTester(stHost.walletKey, stHost.dir)
   979  	if err != nil {
   980  		t.Fatal(err)
   981  	}
   982  	defer stHost.panicClose()
   983  	sts[1] = stHost
   984  	err = fullyConnectNodes(sts)
   985  	if err != nil {
   986  		t.Fatal(err)
   987  	}
   988  	err = stHost.announceHost()
   989  	if err != nil {
   990  		t.Fatal(err)
   991  	}
   992  	// Pull the host's net address and pubkey from the hostdb.
   993  	err = build.Retry(50, time.Millisecond*100, func() error {
   994  		// Get the hostdb internals.
   995  		if err = st.getAPI("/hostdb/active", &ah); err != nil {
   996  			return err
   997  		}
   998  
   999  		// Get the host's internals.
  1000  		var hg HostGET
  1001  		if err = stHost.getAPI("/host", &hg); err != nil {
  1002  			return err
  1003  		}
  1004  
  1005  		if len(ah.Hosts) != 1 {
  1006  			return fmt.Errorf("expected 1 host, got %v", len(ah.Hosts))
  1007  		}
  1008  		if ah.Hosts[0].NetAddress != hg.ExternalSettings.NetAddress {
  1009  			return fmt.Errorf("hostdb net address doesn't match host net address: %v : %v", ah.Hosts[0].NetAddress, hg.ExternalSettings.NetAddress)
  1010  		}
  1011  		return nil
  1012  	})
  1013  	if err != nil {
  1014  		t.Fatal(err)
  1015  	}
  1016  	if ah.Hosts[0].PublicKeyString != pks {
  1017  		t.Error("public key appears to have changed for host")
  1018  	}
  1019  	if ah.Hosts[0].NetAddress == addr {
  1020  		t.Log("NetAddress did not change for the new host")
  1021  	}
  1022  
  1023  	// Upload a file to the host.
  1024  	allowanceValues := url.Values{}
  1025  	testFunds := "10000000000000000000000000000" // 10k SC
  1026  	testPeriod := "10"
  1027  	testPeriodInt := 10
  1028  	allowanceValues.Set("funds", testFunds)
  1029  	allowanceValues.Set("period", testPeriod)
  1030  	err = st.stdPostAPI("/renter", allowanceValues)
  1031  	if err != nil {
  1032  		t.Fatal(err)
  1033  	}
  1034  	// Create a file.
  1035  	path := filepath.Join(st.dir, "test.dat")
  1036  	err = createRandFile(path, 1024)
  1037  	if err != nil {
  1038  		t.Fatal(err)
  1039  	}
  1040  	// Upload the file to the renter.
  1041  	uploadValues := url.Values{}
  1042  	uploadValues.Set("source", path)
  1043  	err = st.stdPostAPI("/renter/upload/test", uploadValues)
  1044  	if err != nil {
  1045  		t.Fatal(err)
  1046  	}
  1047  	// Only one piece will be uploaded (10% at current redundancy).
  1048  	var rf RenterFiles
  1049  	for i := 0; i < 200 && (len(rf.Files) != 1 || rf.Files[0].UploadProgress < 10); i++ {
  1050  		st.getAPI("/renter/files", &rf)
  1051  		time.Sleep(100 * time.Millisecond)
  1052  	}
  1053  	if len(rf.Files) != 1 || rf.Files[0].UploadProgress < 10 {
  1054  		t.Fatal("the uploading is not succeeding for some reason:", rf.Files[0])
  1055  	}
  1056  
  1057  	// Try downloading the file.
  1058  	downpath := filepath.Join(st.dir, "testdown.dat")
  1059  	err = st.stdGetAPI("/renter/download/test?destination=" + downpath)
  1060  	if err != nil {
  1061  		t.Fatal(err)
  1062  	}
  1063  	// Check that the download has the right contents.
  1064  	orig, err := ioutil.ReadFile(path)
  1065  	if err != nil {
  1066  		t.Fatal(err)
  1067  	}
  1068  	download, err := ioutil.ReadFile(downpath)
  1069  	if err != nil {
  1070  		t.Fatal(err)
  1071  	}
  1072  	if !bytes.Equal(orig, download) {
  1073  		t.Fatal("data mismatch when downloading a file")
  1074  	}
  1075  
  1076  	// Mine enough blocks that multiple renew cylces happen. After the renewing
  1077  	// happens, the file should still be downloadable. This is to check that the
  1078  	// renewal doesn't throw things off.
  1079  	for i := 0; i < testPeriodInt; i++ {
  1080  		_, err = st.miner.AddBlock()
  1081  		if err != nil {
  1082  			t.Fatal(err)
  1083  		}
  1084  		_, err = synchronizationCheck(sts)
  1085  		if err != nil {
  1086  			t.Fatal(err)
  1087  		}
  1088  		// Give time for the upgrade to happen.
  1089  		time.Sleep(time.Second * 3)
  1090  	}
  1091  
  1092  	// Try downloading the file.
  1093  	err = st.stdGetAPI("/renter/download/test?destination=" + downpath)
  1094  	if err != nil {
  1095  		t.Fatal(err)
  1096  	}
  1097  	// Check that the download has the right contents.
  1098  	download, err = ioutil.ReadFile(downpath)
  1099  	if err != nil {
  1100  		t.Fatal(err)
  1101  	}
  1102  	if !bytes.Equal(orig, download) {
  1103  		t.Fatal("data mismatch when downloading a file")
  1104  	}
  1105  }
  1106  
  1107  // TestHostDBAndRenterRenewDynamicIPs checks that the hostdb and the renter are
  1108  // successfully able to follow a host that has changed IP addresses and then
  1109  // re-announced.
  1110  func TestHostDBAndRenterRenewDynamicIPs(t *testing.T) {
  1111  	if testing.Short() || !build.VLONG {
  1112  		t.SkipNow()
  1113  	}
  1114  	t.Parallel()
  1115  	st, err := createServerTester(t.Name())
  1116  	if err != nil {
  1117  		t.Fatal(err)
  1118  	}
  1119  	defer st.panicClose()
  1120  	stHost, err := blankServerTester(t.Name() + "-Host")
  1121  	if err != nil {
  1122  		t.Fatal(err)
  1123  	}
  1124  	sts := []*serverTester{st, stHost}
  1125  	err = fullyConnectNodes(sts)
  1126  	if err != nil {
  1127  		t.Fatal(err)
  1128  	}
  1129  	err = fundAllNodes(sts)
  1130  	if err != nil {
  1131  		t.Fatal(err)
  1132  	}
  1133  
  1134  	// Announce the host.
  1135  	err = stHost.acceptContracts()
  1136  	if err != nil {
  1137  		t.Fatal(err)
  1138  	}
  1139  	err = stHost.setHostStorage()
  1140  	if err != nil {
  1141  		t.Fatal(err)
  1142  	}
  1143  	err = stHost.announceHost()
  1144  	if err != nil {
  1145  		t.Fatal(err)
  1146  	}
  1147  	var ah HostdbActiveGET
  1148  	err = build.Retry(50, 100*time.Millisecond, func() error {
  1149  		if err := st.getAPI("/hostdb/active", &ah); err != nil {
  1150  			return err
  1151  		}
  1152  		if len(ah.Hosts) != 1 {
  1153  			return errors.New("host not found in hostdb")
  1154  		}
  1155  		return nil
  1156  	})
  1157  
  1158  	// Upload a file to the host.
  1159  	allowanceValues := url.Values{}
  1160  	testFunds := "10000000000000000000000000000" // 10k SC
  1161  	testPeriod := "10"
  1162  	testPeriodInt := 10
  1163  	allowanceValues.Set("funds", testFunds)
  1164  	allowanceValues.Set("period", testPeriod)
  1165  	err = st.stdPostAPI("/renter", allowanceValues)
  1166  	if err != nil {
  1167  		t.Fatal(err)
  1168  	}
  1169  	// Create a file.
  1170  	path := filepath.Join(st.dir, "test.dat")
  1171  	err = createRandFile(path, 1024)
  1172  	if err != nil {
  1173  		t.Fatal(err)
  1174  	}
  1175  	// Upload the file to the renter.
  1176  	uploadValues := url.Values{}
  1177  	uploadValues.Set("source", path)
  1178  	err = st.stdPostAPI("/renter/upload/test", uploadValues)
  1179  	if err != nil {
  1180  		t.Fatal(err)
  1181  	}
  1182  	// Only one piece will be uploaded (10% at current redundancy).
  1183  	var rf RenterFiles
  1184  	for i := 0; i < 200 && (len(rf.Files) != 1 || rf.Files[0].UploadProgress < 10); i++ {
  1185  		st.getAPI("/renter/files", &rf)
  1186  		time.Sleep(100 * time.Millisecond)
  1187  	}
  1188  	if len(rf.Files) != 1 || rf.Files[0].UploadProgress < 10 {
  1189  		t.Fatal("the uploading is not succeeding for some reason:", rf.Files[0])
  1190  	}
  1191  
  1192  	// Try downloading the file.
  1193  	downpath := filepath.Join(st.dir, "testdown.dat")
  1194  	err = st.stdGetAPI("/renter/download/test?destination=" + downpath)
  1195  	if err != nil {
  1196  		t.Fatal(err)
  1197  	}
  1198  	// Check that the download has the right contents.
  1199  	orig, err := ioutil.ReadFile(path)
  1200  	if err != nil {
  1201  		t.Fatal(err)
  1202  	}
  1203  	download, err := ioutil.ReadFile(downpath)
  1204  	if err != nil {
  1205  		t.Fatal(err)
  1206  	}
  1207  	if !bytes.Equal(orig, download) {
  1208  		t.Fatal("data mismatch when downloading a file")
  1209  	}
  1210  
  1211  	// Mine a block before resetting the host, so that the host doesn't lose
  1212  	// it's contracts when the transaction pool resets.
  1213  	_, err = st.miner.AddBlock()
  1214  	if err != nil {
  1215  		t.Fatal(err)
  1216  	}
  1217  	_, err = synchronizationCheck(sts)
  1218  	if err != nil {
  1219  		t.Fatal(err)
  1220  	}
  1221  	// Give time for the upgrade to happen.
  1222  	time.Sleep(time.Second * 3)
  1223  
  1224  	// Close and re-open the host. This should reset the host's address, as the
  1225  	// host should now be on a new port.
  1226  	err = stHost.server.Close()
  1227  	if err != nil {
  1228  		t.Fatal(err)
  1229  	}
  1230  	stHost, err = assembleServerTester(stHost.walletKey, stHost.dir)
  1231  	if err != nil {
  1232  		t.Fatal(err)
  1233  	}
  1234  	defer stHost.panicClose()
  1235  	sts[1] = stHost
  1236  	err = fullyConnectNodes(sts)
  1237  	if err != nil {
  1238  		t.Fatal(err)
  1239  	}
  1240  	err = stHost.announceHost()
  1241  	if err != nil {
  1242  		t.Fatal(err)
  1243  	}
  1244  	err = waitForBlock(stHost.cs.CurrentBlock().ID(), st)
  1245  	if err != nil {
  1246  		t.Fatal()
  1247  	}
  1248  	// Pull the host's net address and pubkey from the hostdb.
  1249  	err = build.Retry(50, time.Millisecond*100, func() error {
  1250  		// Get the hostdb internals.
  1251  		if err = st.getAPI("/hostdb/active", &ah); err != nil {
  1252  			return err
  1253  		}
  1254  
  1255  		// Get the host's internals.
  1256  		var hg HostGET
  1257  		if err = stHost.getAPI("/host", &hg); err != nil {
  1258  			return err
  1259  		}
  1260  
  1261  		if len(ah.Hosts) != 1 {
  1262  			return fmt.Errorf("expected 1 host, got %v", len(ah.Hosts))
  1263  		}
  1264  		if ah.Hosts[0].NetAddress != hg.ExternalSettings.NetAddress {
  1265  			return fmt.Errorf("hostdb net address doesn't match host net address: %v : %v", ah.Hosts[0].NetAddress, hg.ExternalSettings.NetAddress)
  1266  		}
  1267  		return nil
  1268  	})
  1269  	if err != nil {
  1270  		t.Fatal(err)
  1271  	}
  1272  
  1273  	// Mine enough blocks that multiple renew cylces happen. After the renewing
  1274  	// happens, the file should still be downloadable.
  1275  	for i := 0; i < testPeriodInt; i++ {
  1276  		_, err = st.miner.AddBlock()
  1277  		if err != nil {
  1278  			t.Fatal(err)
  1279  		}
  1280  		_, err = synchronizationCheck(sts)
  1281  		if err != nil {
  1282  			t.Fatal(err)
  1283  		}
  1284  		// Give time for the upgrade to happen.
  1285  		time.Sleep(time.Second * 3)
  1286  	}
  1287  
  1288  	// Try downloading the file.
  1289  	err = st.stdGetAPI("/renter/download/test?destination=" + downpath)
  1290  	if err != nil {
  1291  		t.Fatal(err)
  1292  	}
  1293  	// Check that the download has the right contents.
  1294  	download, err = ioutil.ReadFile(downpath)
  1295  	if err != nil {
  1296  		t.Fatal(err)
  1297  	}
  1298  	if !bytes.Equal(orig, download) {
  1299  		t.Fatal("data mismatch when downloading a file")
  1300  	}
  1301  }