gitlab.com/SiaPrime/SiaPrime@v1.4.1/modules/host/contractmanager/storagefoldershrink_test.go (about)

     1  package contractmanager
     2  
     3  import (
     4  	"bytes"
     5  	"os"
     6  	"path/filepath"
     7  	"sync"
     8  	"sync/atomic"
     9  	"testing"
    10  
    11  	"gitlab.com/SiaPrime/SiaPrime/crypto"
    12  	"gitlab.com/SiaPrime/SiaPrime/modules"
    13  )
    14  
    15  // TestShrinkStorageFolder checks that a storage folder can be successfully
    16  // decreased in size.
    17  func TestShrinkStorageFolder(t *testing.T) {
    18  	if testing.Short() {
    19  		t.SkipNow()
    20  	}
    21  	t.Parallel()
    22  	cmt, err := newContractManagerTester("TestShrinkStorageFolder")
    23  	if err != nil {
    24  		t.Fatal(err)
    25  	}
    26  	defer cmt.panicClose()
    27  
    28  	// Add a storage folder.
    29  	storageFolderOne := filepath.Join(cmt.persistDir, "storageFolderOne")
    30  	// Create the storage folder dir.
    31  	err = os.MkdirAll(storageFolderOne, 0700)
    32  	if err != nil {
    33  		t.Fatal(err)
    34  	}
    35  	err = cmt.cm.AddStorageFolder(storageFolderOne, modules.SectorSize*storageFolderGranularity*8)
    36  	if err != nil {
    37  		t.Fatal(err)
    38  	}
    39  
    40  	// Get the index of the storage folder.
    41  	sfs := cmt.cm.StorageFolders()
    42  	if len(sfs) != 1 {
    43  		t.Fatal("there should only be one storage folder")
    44  	}
    45  	sfIndex := sfs[0].Index
    46  	// Verify that the storage folder has the correct capacity.
    47  	if sfs[0].Capacity != modules.SectorSize*storageFolderGranularity*8 {
    48  		t.Error("new storage folder is reporting the wrong capacity")
    49  	}
    50  	// Verify that the on-disk files are the right size.
    51  	mfn := filepath.Join(storageFolderOne, metadataFile)
    52  	sfn := filepath.Join(storageFolderOne, sectorFile)
    53  	mfi, err := os.Stat(mfn)
    54  	if err != nil {
    55  		t.Fatal(err)
    56  	}
    57  	sfi, err := os.Stat(sfn)
    58  	if err != nil {
    59  		t.Fatal(err)
    60  	}
    61  	if uint64(mfi.Size()) != sectorMetadataDiskSize*storageFolderGranularity*8 {
    62  		t.Error("metadata file is the wrong size")
    63  	}
    64  	if uint64(sfi.Size()) != modules.SectorSize*storageFolderGranularity*8 {
    65  		t.Error("sector file is the wrong size")
    66  	}
    67  
    68  	// Decrease the size of the storage folder.
    69  	err = cmt.cm.ResizeStorageFolder(sfIndex, modules.SectorSize*storageFolderGranularity*2, false)
    70  	if err != nil {
    71  		t.Fatal(err)
    72  	}
    73  	// Verify that the capacity and file sizes are correct.
    74  	sfs = cmt.cm.StorageFolders()
    75  	if sfs[0].Capacity != modules.SectorSize*storageFolderGranularity*2 {
    76  		t.Error("new storage folder is reporting the wrong capacity")
    77  	}
    78  	mfi, err = os.Stat(mfn)
    79  	if err != nil {
    80  		t.Fatal(err)
    81  	}
    82  	sfi, err = os.Stat(sfn)
    83  	if err != nil {
    84  		t.Fatal(err)
    85  	}
    86  	if uint64(mfi.Size()) != sectorMetadataDiskSize*storageFolderGranularity*2 {
    87  		t.Error("metadata file is the wrong size")
    88  	}
    89  	if uint64(sfi.Size()) != modules.SectorSize*storageFolderGranularity*2 {
    90  		t.Error("sector file is the wrong size")
    91  	}
    92  
    93  	// Restart the contract manager to see that the change is persistent.
    94  	err = cmt.cm.Close()
    95  	if err != nil {
    96  		t.Fatal(err)
    97  	}
    98  	cmt.cm, err = New(filepath.Join(cmt.persistDir, modules.ContractManagerDir))
    99  	if err != nil {
   100  		t.Fatal(err)
   101  	}
   102  
   103  	// Verify that the capacity and file sizes are correct.
   104  	sfs = cmt.cm.StorageFolders()
   105  	if sfs[0].Capacity != modules.SectorSize*storageFolderGranularity*2 {
   106  		t.Error("new storage folder is reporting the wrong capacity")
   107  	}
   108  	mfi, err = os.Stat(mfn)
   109  	if err != nil {
   110  		t.Fatal(err)
   111  	}
   112  	sfi, err = os.Stat(sfn)
   113  	if err != nil {
   114  		t.Fatal(err)
   115  	}
   116  	if uint64(mfi.Size()) != sectorMetadataDiskSize*storageFolderGranularity*2 {
   117  		t.Error("metadata file is the wrong size")
   118  	}
   119  	if uint64(sfi.Size()) != modules.SectorSize*storageFolderGranularity*2 {
   120  		t.Error("sector file is the wrong size")
   121  	}
   122  }
   123  
   124  // TestShrinkStorageFolderWithSectors checks that a storage folder can be
   125  // successfully decreased in size when it has sectors which would need to be
   126  // moved.
   127  func TestShrinkStorageFolderWithSectors(t *testing.T) {
   128  	if testing.Short() {
   129  		t.SkipNow()
   130  	}
   131  	t.Parallel()
   132  	cmt, err := newContractManagerTester(t.Name())
   133  	if err != nil {
   134  		t.Fatal(err)
   135  	}
   136  	defer cmt.panicClose()
   137  
   138  	// Add a storage folder.
   139  	storageFolderOne := filepath.Join(cmt.persistDir, "storageFolderOne")
   140  	// Create the storage folder dir.
   141  	err = os.MkdirAll(storageFolderOne, 0700)
   142  	if err != nil {
   143  		t.Fatal(err)
   144  	}
   145  	err = cmt.cm.AddStorageFolder(storageFolderOne, modules.SectorSize*storageFolderGranularity*8)
   146  	if err != nil {
   147  		t.Fatal(err)
   148  	}
   149  
   150  	// Get the index of the storage folder.
   151  	sfs := cmt.cm.StorageFolders()
   152  	if len(sfs) != 1 {
   153  		t.Fatal("there should only be one storage folder")
   154  	}
   155  	sfIndex := sfs[0].Index
   156  	// Verify that the storage folder has the correct capacity.
   157  	if sfs[0].Capacity != modules.SectorSize*storageFolderGranularity*8 {
   158  		t.Error("new storage folder is reporting the wrong capacity")
   159  	}
   160  	// Verify that the on-disk files are the right size.
   161  	mfn := filepath.Join(storageFolderOne, metadataFile)
   162  	sfn := filepath.Join(storageFolderOne, sectorFile)
   163  	mfi, err := os.Stat(mfn)
   164  	if err != nil {
   165  		t.Fatal(err)
   166  	}
   167  	sfi, err := os.Stat(sfn)
   168  	if err != nil {
   169  		t.Fatal(err)
   170  	}
   171  	if uint64(mfi.Size()) != sectorMetadataDiskSize*storageFolderGranularity*8 {
   172  		t.Error("metadata file is the wrong size")
   173  	}
   174  	if uint64(sfi.Size()) != modules.SectorSize*storageFolderGranularity*8 {
   175  		t.Error("sector file is the wrong size")
   176  	}
   177  
   178  	// Create some sectors and add them to the storage folder.
   179  	roots := make([]crypto.Hash, storageFolderGranularity*3)
   180  	datas := make([][]byte, storageFolderGranularity*3)
   181  	for i := 0; i < storageFolderGranularity*3; i++ {
   182  		root, data := randSector()
   183  		roots[i] = root
   184  		datas[i] = data
   185  	}
   186  	// Add all of the sectors.
   187  	var wg sync.WaitGroup
   188  	wg.Add(len(roots))
   189  	for i := 0; i < len(roots); i++ {
   190  		go func(i int) {
   191  			err := cmt.cm.AddSector(roots[i], datas[i])
   192  			if err != nil {
   193  				t.Error(err)
   194  			}
   195  			wg.Done()
   196  		}(i)
   197  	}
   198  	wg.Wait()
   199  
   200  	// Add a second storage folder so that the displaced sectors have somewhere
   201  	// to go.
   202  	storageFolderTwo := filepath.Join(cmt.persistDir, "storageFolderTwo")
   203  	// Create the storage folder dir.
   204  	err = os.MkdirAll(storageFolderTwo, 0700)
   205  	if err != nil {
   206  		t.Fatal(err)
   207  	}
   208  	err = cmt.cm.AddStorageFolder(storageFolderTwo, modules.SectorSize*storageFolderGranularity*3)
   209  	if err != nil {
   210  		t.Fatal(err)
   211  	}
   212  
   213  	// Verify that every single sector is readable and has the correct data.
   214  	wg.Add(len(roots))
   215  	var misses uint64
   216  	for i := 0; i < len(roots); i++ {
   217  		go func(i int) {
   218  			data, err := cmt.cm.ReadSector(roots[i])
   219  			if err != nil || !bytes.Equal(data, datas[i]) {
   220  				atomic.AddUint64(&misses, 1)
   221  			}
   222  			wg.Done()
   223  		}(i)
   224  	}
   225  	wg.Wait()
   226  	if misses != 0 {
   227  		t.Errorf("Could not find all %v sectors: %v\n", len(roots), misses)
   228  	}
   229  
   230  	// Decrease the size of the storage folder.
   231  	err = cmt.cm.ResizeStorageFolder(sfIndex, modules.SectorSize*storageFolderGranularity*2, false)
   232  	if err != nil {
   233  		t.Fatal(err)
   234  	}
   235  	// Verify that the capacity and file sizes are correct.
   236  	sfs = cmt.cm.StorageFolders()
   237  	capacity := sfs[0].Capacity + sfs[1].Capacity
   238  	capacityRemaining := sfs[0].CapacityRemaining + sfs[1].CapacityRemaining
   239  	if capacity != modules.SectorSize*storageFolderGranularity*5 {
   240  		t.Error("new storage folder is reporting the wrong capacity")
   241  	}
   242  	if capacityRemaining != modules.SectorSize*storageFolderGranularity*2 {
   243  		t.Error("new storage folder capacity remaining is reporting the wrong remaining capacity")
   244  	}
   245  	mfi, err = os.Stat(mfn)
   246  	if err != nil {
   247  		t.Fatal(err)
   248  	}
   249  	sfi, err = os.Stat(sfn)
   250  	if err != nil {
   251  		t.Fatal(err)
   252  	}
   253  	if uint64(mfi.Size()) != sectorMetadataDiskSize*storageFolderGranularity*2 {
   254  		t.Error("metadata file is the wrong size")
   255  	}
   256  	if uint64(sfi.Size()) != modules.SectorSize*storageFolderGranularity*2 {
   257  		t.Error("sector file is the wrong size")
   258  	}
   259  
   260  	// Verify that every single sector is readable and has the correct data.
   261  	wg.Add(len(roots))
   262  	misses = 0
   263  	for i := 0; i < len(roots); i++ {
   264  		go func(i int) {
   265  			data, err := cmt.cm.ReadSector(roots[i])
   266  			if err != nil || !bytes.Equal(data, datas[i]) {
   267  				atomic.AddUint64(&misses, 1)
   268  			}
   269  			wg.Done()
   270  		}(i)
   271  	}
   272  	wg.Wait()
   273  	if misses != 0 {
   274  		t.Errorf("Could not find all %v sectors: %v\n", len(roots), misses)
   275  	}
   276  
   277  	// Restart the contract manager to see that the change is persistent.
   278  	err = cmt.cm.Close()
   279  	if err != nil {
   280  		t.Fatal(err)
   281  	}
   282  	cmt.cm, err = New(filepath.Join(cmt.persistDir, modules.ContractManagerDir))
   283  	if err != nil {
   284  		t.Fatal(err)
   285  	}
   286  
   287  	// Verify that the capacity and file sizes are correct.
   288  	sfs = cmt.cm.StorageFolders()
   289  	capacity = sfs[0].Capacity + sfs[1].Capacity
   290  	capacityRemaining = sfs[0].CapacityRemaining + sfs[1].CapacityRemaining
   291  	if capacity != modules.SectorSize*storageFolderGranularity*5 {
   292  		t.Error("new storage folder is reporting the wrong capacity")
   293  	}
   294  	if capacityRemaining != modules.SectorSize*storageFolderGranularity*2 {
   295  		t.Error("new storage folder capacity remaining is reporting the wrong remaining capacity")
   296  	}
   297  	mfi, err = os.Stat(mfn)
   298  	if err != nil {
   299  		t.Fatal(err)
   300  	}
   301  	sfi, err = os.Stat(sfn)
   302  	if err != nil {
   303  		t.Fatal(err)
   304  	}
   305  	if uint64(mfi.Size()) != sectorMetadataDiskSize*storageFolderGranularity*2 {
   306  		t.Error("metadata file is the wrong size")
   307  	}
   308  	if uint64(sfi.Size()) != modules.SectorSize*storageFolderGranularity*2 {
   309  		t.Error("sector file is the wrong size")
   310  	}
   311  
   312  	// Verify that every single sector is readable and has the correct data.
   313  	wg.Add(len(roots))
   314  	misses = 0
   315  	for i := 0; i < len(roots); i++ {
   316  		go func(i int) {
   317  			data, err := cmt.cm.ReadSector(roots[i])
   318  			if err != nil || !bytes.Equal(data, datas[i]) {
   319  				atomic.AddUint64(&misses, 1)
   320  			}
   321  			wg.Done()
   322  		}(i)
   323  	}
   324  	wg.Wait()
   325  	if misses != 0 {
   326  		t.Errorf("Could not find all %v sectors: %v\n", len(roots), misses)
   327  	}
   328  }
   329  
   330  // TestShrinkStorageFolderIncopmleteWrite checks that shrinkStorageFolder
   331  // operates as intended when the writing to move sectors cannot complete fully.
   332  func TestShrinkStorageFolderIncompleteWrite(t *testing.T) {
   333  	if testing.Short() {
   334  		t.SkipNow()
   335  	}
   336  	t.Parallel()
   337  	d := new(dependencyIncompleteGrow)
   338  	cmt, err := newMockedContractManagerTester(d, "TestShrinkStorageFolderIncompleteWrite")
   339  	if err != nil {
   340  		t.Fatal(err)
   341  	}
   342  	defer cmt.panicClose()
   343  
   344  	// Add a storage folder.
   345  	storageFolderOne := filepath.Join(cmt.persistDir, "storageFolderOne")
   346  	// Create the storage folder dir.
   347  	err = os.MkdirAll(storageFolderOne, 0700)
   348  	if err != nil {
   349  		t.Fatal(err)
   350  	}
   351  	err = cmt.cm.AddStorageFolder(storageFolderOne, modules.SectorSize*storageFolderGranularity*8)
   352  	if err != nil {
   353  		t.Fatal(err)
   354  	}
   355  
   356  	// Get the index of the storage folder.
   357  	sfs := cmt.cm.StorageFolders()
   358  	if len(sfs) != 1 {
   359  		t.Fatal("there should only be one storage folder")
   360  	}
   361  	sfIndex := sfs[0].Index
   362  
   363  	// Create some sectors and add them to the storage folder.
   364  	roots := make([]crypto.Hash, storageFolderGranularity*3)
   365  	datas := make([][]byte, storageFolderGranularity*3)
   366  	for i := 0; i < storageFolderGranularity*3; i++ {
   367  		root, data := randSector()
   368  		roots[i] = root
   369  		datas[i] = data
   370  	}
   371  	// Add all of the sectors.
   372  	var wg sync.WaitGroup
   373  	wg.Add(len(roots))
   374  	for i := 0; i < len(roots); i++ {
   375  		go func(i int) {
   376  			err := cmt.cm.AddSector(roots[i], datas[i])
   377  			if err != nil {
   378  				t.Error(err)
   379  			}
   380  			wg.Done()
   381  		}(i)
   382  	}
   383  	wg.Wait()
   384  
   385  	// Add a second storage folder so that the displaced sectors have somewhere
   386  	// to go.
   387  	storageFolderTwo := filepath.Join(cmt.persistDir, "storageFolderTwo")
   388  	// Create the storage folder dir.
   389  	err = os.MkdirAll(storageFolderTwo, 0700)
   390  	if err != nil {
   391  		t.Fatal(err)
   392  	}
   393  	err = cmt.cm.AddStorageFolder(storageFolderTwo, modules.SectorSize*storageFolderGranularity*3)
   394  	if err != nil {
   395  		t.Fatal(err)
   396  	}
   397  
   398  	// Trigger some failures.
   399  	d.mu.Lock()
   400  	d.threshold = 1 << 15
   401  	d.triggered = true
   402  	d.mu.Unlock()
   403  
   404  	// Decrease the size of the storage folder.
   405  	err = cmt.cm.ResizeStorageFolder(sfIndex, modules.SectorSize*storageFolderGranularity*2, false)
   406  	if err == nil {
   407  		t.Fatal("expected a failure")
   408  	}
   409  	// Verify that the capacity and file sizes are correct.
   410  	sfs = cmt.cm.StorageFolders()
   411  	capacity := sfs[0].Capacity + sfs[1].Capacity
   412  	capacityRemaining := sfs[0].CapacityRemaining + sfs[1].CapacityRemaining
   413  	if capacity != modules.SectorSize*storageFolderGranularity*11 {
   414  		t.Error("new storage folder is reporting the wrong capacity")
   415  	}
   416  	if capacityRemaining != modules.SectorSize*storageFolderGranularity*8 {
   417  		t.Error("new storage folder capacity remaining is reporting the wrong remaining capacity")
   418  	}
   419  	mfn := filepath.Join(storageFolderOne, metadataFile)
   420  	sfn := filepath.Join(storageFolderOne, sectorFile)
   421  	mfi, err := os.Stat(mfn)
   422  	if err != nil {
   423  		t.Fatal(err)
   424  	}
   425  	sfi, err := os.Stat(sfn)
   426  	if err != nil {
   427  		t.Fatal(err)
   428  	}
   429  	if uint64(mfi.Size()) != sectorMetadataDiskSize*storageFolderGranularity*8 {
   430  		t.Error("metadata file is the wrong size")
   431  	}
   432  	if uint64(sfi.Size()) != modules.SectorSize*storageFolderGranularity*8 {
   433  		t.Error("sector file is the wrong size")
   434  	}
   435  
   436  	// Verify that every single sector is readable and has the correct data.
   437  	wg.Add(len(roots))
   438  	var misses uint64
   439  	for i := 0; i < len(roots); i++ {
   440  		go func(i int) {
   441  			data, err := cmt.cm.ReadSector(roots[i])
   442  			if err != nil || !bytes.Equal(data, datas[i]) {
   443  				atomic.AddUint64(&misses, 1)
   444  			}
   445  			wg.Done()
   446  		}(i)
   447  	}
   448  	wg.Wait()
   449  	if misses != 0 {
   450  		t.Errorf("Could not find all %v sectors: %v\n", len(roots), misses)
   451  	}
   452  
   453  	// Restart the contract manager to see that the change is persistent.
   454  	err = cmt.cm.Close()
   455  	if err != nil {
   456  		t.Fatal(err)
   457  	}
   458  	cmt.cm, err = New(filepath.Join(cmt.persistDir, modules.ContractManagerDir))
   459  	if err != nil {
   460  		t.Fatal(err)
   461  	}
   462  
   463  	// Verify that the capacity and file sizes are correct.
   464  	sfs = cmt.cm.StorageFolders()
   465  	capacity = sfs[0].Capacity + sfs[1].Capacity
   466  	capacityRemaining = sfs[0].CapacityRemaining + sfs[1].CapacityRemaining
   467  	if capacity != modules.SectorSize*storageFolderGranularity*11 {
   468  		t.Error("new storage folder is reporting the wrong capacity")
   469  	}
   470  	if capacityRemaining != modules.SectorSize*storageFolderGranularity*8 {
   471  		t.Error("new storage folder capacity remaining is reporting the wrong remaining capacity")
   472  	}
   473  	mfi, err = os.Stat(mfn)
   474  	if err != nil {
   475  		t.Fatal(err)
   476  	}
   477  	sfi, err = os.Stat(sfn)
   478  	if err != nil {
   479  		t.Fatal(err)
   480  	}
   481  	if uint64(mfi.Size()) != sectorMetadataDiskSize*storageFolderGranularity*8 {
   482  		t.Error("metadata file is the wrong size")
   483  	}
   484  	if uint64(sfi.Size()) != modules.SectorSize*storageFolderGranularity*8 {
   485  		t.Error("sector file is the wrong size")
   486  	}
   487  
   488  	// Verify that every single sector is readable and has the correct data.
   489  	wg.Add(len(roots))
   490  	misses = 0
   491  	for i := 0; i < len(roots); i++ {
   492  		go func(i int) {
   493  			data, err := cmt.cm.ReadSector(roots[i])
   494  			if err != nil || !bytes.Equal(data, datas[i]) {
   495  				atomic.AddUint64(&misses, 1)
   496  			}
   497  			wg.Done()
   498  		}(i)
   499  	}
   500  	wg.Wait()
   501  	if misses != 0 {
   502  		t.Errorf("Could not find all %v sectors: %v\n", len(roots), misses)
   503  	}
   504  }
   505  
   506  // TestShrinkStorageFolderIncopmleteWriteForce checks that shrinkStorageFolder
   507  // operates as intended when the writing to move sectors cannot complete fully,
   508  // but the 'force' flag is set.
   509  // capacity and capacity remaining.
   510  func TestShrinkStorageFolderIncompleteWriteForce(t *testing.T) {
   511  	if testing.Short() {
   512  		t.SkipNow()
   513  	}
   514  	t.Parallel()
   515  	d := new(dependencyIncompleteGrow)
   516  	cmt, err := newMockedContractManagerTester(d, "TestShrinkStorageFolderIncompleteWriteForce")
   517  	if err != nil {
   518  		t.Fatal(err)
   519  	}
   520  	defer cmt.panicClose()
   521  
   522  	// Add a storage folder.
   523  	storageFolderOne := filepath.Join(cmt.persistDir, "storageFolderOne")
   524  	// Create the storage folder dir.
   525  	err = os.MkdirAll(storageFolderOne, 0700)
   526  	if err != nil {
   527  		t.Fatal(err)
   528  	}
   529  	err = cmt.cm.AddStorageFolder(storageFolderOne, modules.SectorSize*storageFolderGranularity*8)
   530  	if err != nil {
   531  		t.Fatal(err)
   532  	}
   533  
   534  	// Get the index of the storage folder.
   535  	sfs := cmt.cm.StorageFolders()
   536  	if len(sfs) != 1 {
   537  		t.Fatal("there should only be one storage folder")
   538  	}
   539  	sfIndex := sfs[0].Index
   540  
   541  	// Create some sectors and add them to the storage folder.
   542  	roots := make([]crypto.Hash, 6)
   543  	datas := make([][]byte, 6)
   544  	for i := 0; i < len(roots); i++ {
   545  		root, data := randSector()
   546  		roots[i] = root
   547  		datas[i] = data
   548  	}
   549  	// Add all of the sectors.
   550  	var wg sync.WaitGroup
   551  	wg.Add(len(roots))
   552  	for i := 0; i < len(roots); i++ {
   553  		go func(i int) {
   554  			err := cmt.cm.AddSector(roots[i], datas[i])
   555  			if err != nil {
   556  				t.Error(err)
   557  			}
   558  			wg.Done()
   559  		}(i)
   560  	}
   561  	wg.Wait()
   562  
   563  	// Add a second storage folder so that the displaced sectors have somewhere
   564  	// to go.
   565  	storageFolderTwo := filepath.Join(cmt.persistDir, "storageFolderTwo")
   566  	// Create the storage folder dir.
   567  	err = os.MkdirAll(storageFolderTwo, 0700)
   568  	if err != nil {
   569  		t.Fatal(err)
   570  	}
   571  	err = cmt.cm.AddStorageFolder(storageFolderTwo, modules.SectorSize*storageFolderGranularity*3)
   572  	if err != nil {
   573  		t.Fatal(err)
   574  	}
   575  
   576  	// Trigger some failures.
   577  	d.mu.Lock()
   578  	d.threshold = 1 << 11
   579  	d.triggered = true
   580  	d.mu.Unlock()
   581  
   582  	// Decrease the size of the storage folder.
   583  	err = cmt.cm.ResizeStorageFolder(sfIndex, modules.SectorSize*storageFolderGranularity*2, true)
   584  	if err != nil {
   585  		t.Fatal("expected a failure")
   586  	}
   587  	// Verify that the capacity and file sizes are correct.
   588  	sfs = cmt.cm.StorageFolders()
   589  	capacity := sfs[0].Capacity + sfs[1].Capacity
   590  	capacityRemaining := sfs[0].CapacityRemaining + sfs[1].CapacityRemaining
   591  	if capacity != modules.SectorSize*storageFolderGranularity*5 {
   592  		t.Error("new storage folder is reporting the wrong capacity")
   593  	}
   594  	mfn := filepath.Join(storageFolderOne, metadataFile)
   595  	sfn := filepath.Join(storageFolderOne, sectorFile)
   596  	mfi, err := os.Stat(mfn)
   597  	if err != nil {
   598  		t.Fatal(err)
   599  	}
   600  	sfi, err := os.Stat(sfn)
   601  	if err != nil {
   602  		t.Fatal(err)
   603  	}
   604  	if uint64(mfi.Size()) != sectorMetadataDiskSize*storageFolderGranularity*2 {
   605  		t.Error("metadata file is the wrong size")
   606  	}
   607  	if uint64(sfi.Size()) != modules.SectorSize*storageFolderGranularity*2 {
   608  		t.Error("sector file is the wrong size")
   609  	}
   610  
   611  	// Data was lost. Count the number of sectors that are still available.
   612  	wg.Add(len(roots))
   613  	var remainingSectors uint64
   614  	for i := 0; i < len(roots); i++ {
   615  		go func(i int) {
   616  			defer wg.Done()
   617  
   618  			data, err := cmt.cm.ReadSector(roots[i])
   619  			if err != nil {
   620  				// Sector probably destroyed.
   621  				return
   622  			}
   623  			if !bytes.Equal(data, datas[i]) {
   624  				t.Error("ReadSector has returned the wrong data")
   625  			}
   626  
   627  			atomic.AddUint64(&remainingSectors, 1)
   628  		}(i)
   629  	}
   630  	wg.Wait()
   631  
   632  	// Check that the capacity remaining matches the number of reachable
   633  	// sectors.
   634  	if capacityRemaining != capacity-remainingSectors*modules.SectorSize {
   635  		t.Error(capacityRemaining/modules.SectorSize, capacity/modules.SectorSize, remainingSectors)
   636  	}
   637  
   638  	// Restart the contract manager to see that the change is persistent.
   639  	err = cmt.cm.Close()
   640  	if err != nil {
   641  		t.Fatal(err)
   642  	}
   643  	cmt.cm, err = New(filepath.Join(cmt.persistDir, modules.ContractManagerDir))
   644  	if err != nil {
   645  		t.Fatal(err)
   646  	}
   647  
   648  	// Verify that the capacity and file sizes are correct.
   649  	sfs = cmt.cm.StorageFolders()
   650  	capacity = sfs[0].Capacity + sfs[1].Capacity
   651  	capacityRemaining = sfs[0].CapacityRemaining + sfs[1].CapacityRemaining
   652  	if capacity != modules.SectorSize*storageFolderGranularity*5 {
   653  		t.Error("new storage folder is reporting the wrong capacity")
   654  	}
   655  	mfi, err = os.Stat(mfn)
   656  	if err != nil {
   657  		t.Fatal(err)
   658  	}
   659  	sfi, err = os.Stat(sfn)
   660  	if err != nil {
   661  		t.Fatal(err)
   662  	}
   663  	if uint64(mfi.Size()) != sectorMetadataDiskSize*storageFolderGranularity*2 {
   664  		t.Error("metadata file is the wrong size")
   665  	}
   666  	if uint64(sfi.Size()) != modules.SectorSize*storageFolderGranularity*2 {
   667  		t.Error("sector file is the wrong size")
   668  	}
   669  
   670  	// Check that the same number of sectors are still available.
   671  	wg.Add(len(roots))
   672  	var nowRemainingSectors uint64
   673  	for i := 0; i < len(roots); i++ {
   674  		go func(i int) {
   675  			defer wg.Done()
   676  
   677  			data, err := cmt.cm.ReadSector(roots[i])
   678  			if err != nil {
   679  				// Sector probably destroyed.
   680  				return
   681  			}
   682  			if !bytes.Equal(data, datas[i]) {
   683  				t.Error("ReadSector has returned the wrong data")
   684  			}
   685  
   686  			atomic.AddUint64(&nowRemainingSectors, 1)
   687  		}(i)
   688  	}
   689  	wg.Wait()
   690  
   691  	// Check that the capacity remaining matches the number of reachable
   692  	// sectors.
   693  	if capacityRemaining != capacity-remainingSectors*modules.SectorSize {
   694  		t.Error(capacityRemaining/modules.SectorSize, capacity/modules.SectorSize, remainingSectors)
   695  	}
   696  	if remainingSectors != nowRemainingSectors {
   697  		t.Error("available sector set changed after restart", remainingSectors, nowRemainingSectors)
   698  	}
   699  }
   700  
   701  // dependencyShrinkNoFinalize will not add a confirmation to the WAL that a
   702  // shrink storage folder operation has completed.
   703  type dependencyShrinkNoFinalize struct {
   704  	modules.ProductionDependencies
   705  }
   706  
   707  // disrupt will prevent the growStorageFolder operation from committing a
   708  // finalized growStorageFolder operation to the WAL.
   709  func (*dependencyShrinkNoFinalize) Disrupt(s string) bool {
   710  	if s == "incompleteShrinkStorageFolder" {
   711  		return true
   712  	}
   713  	if s == "cleanWALFile" {
   714  		return true
   715  	}
   716  	return false
   717  }
   718  
   719  // TestShrinkStorageFolderShutdownAfterMove simulates an unclean shutdown that
   720  // occurs after the storage folder sector move has completed, but before it has
   721  // established through the WAL that the move has completed. The result should
   722  // be that the storage folder shirnk is not accepted after restart.
   723  func TestShrinkStorageFolderShutdownAfterMove(t *testing.T) {
   724  	if testing.Short() {
   725  		t.SkipNow()
   726  	}
   727  	t.Parallel()
   728  	d := new(dependencyShrinkNoFinalize)
   729  	cmt, err := newMockedContractManagerTester(d, "TestShrinkStorageFolderShutdownAfterMove")
   730  	if err != nil {
   731  		t.Fatal(err)
   732  	}
   733  	defer cmt.panicClose()
   734  
   735  	// Add a storage folder.
   736  	storageFolderOne := filepath.Join(cmt.persistDir, "storageFolderOne")
   737  	// Create the storage folder dir.
   738  	err = os.MkdirAll(storageFolderOne, 0700)
   739  	if err != nil {
   740  		t.Fatal(err)
   741  	}
   742  	err = cmt.cm.AddStorageFolder(storageFolderOne, modules.SectorSize*storageFolderGranularity*8)
   743  	if err != nil {
   744  		t.Fatal(err)
   745  	}
   746  
   747  	// Get the index of the storage folder.
   748  	sfs := cmt.cm.StorageFolders()
   749  	if len(sfs) != 1 {
   750  		t.Fatal("there should only be one storage folder")
   751  	}
   752  	sfIndex := sfs[0].Index
   753  	// Verify that the storage folder has the correct capacity.
   754  	if sfs[0].Capacity != modules.SectorSize*storageFolderGranularity*8 {
   755  		t.Error("new storage folder is reporting the wrong capacity")
   756  	}
   757  	// Verify that the on-disk files are the right size.
   758  	mfn := filepath.Join(storageFolderOne, metadataFile)
   759  	sfn := filepath.Join(storageFolderOne, sectorFile)
   760  	mfi, err := os.Stat(mfn)
   761  	if err != nil {
   762  		t.Fatal(err)
   763  	}
   764  	sfi, err := os.Stat(sfn)
   765  	if err != nil {
   766  		t.Fatal(err)
   767  	}
   768  	if uint64(mfi.Size()) != sectorMetadataDiskSize*storageFolderGranularity*8 {
   769  		t.Error("metadata file is the wrong size")
   770  	}
   771  	if uint64(sfi.Size()) != modules.SectorSize*storageFolderGranularity*8 {
   772  		t.Error("sector file is the wrong size")
   773  	}
   774  
   775  	// Create some sectors and add them to the storage folder.
   776  	roots := make([]crypto.Hash, storageFolderGranularity*3)
   777  	datas := make([][]byte, storageFolderGranularity*3)
   778  	for i := 0; i < storageFolderGranularity*3; i++ {
   779  		root, data := randSector()
   780  		roots[i] = root
   781  		datas[i] = data
   782  	}
   783  	// Add all of the sectors.
   784  	var wg sync.WaitGroup
   785  	wg.Add(len(roots))
   786  	for i := 0; i < len(roots); i++ {
   787  		go func(i int) {
   788  			err := cmt.cm.AddSector(roots[i], datas[i])
   789  			if err != nil {
   790  				t.Error(err)
   791  			}
   792  			wg.Done()
   793  		}(i)
   794  	}
   795  	wg.Wait()
   796  
   797  	// Add a second storage folder so that the displaced sectors have somewhere
   798  	// to go.
   799  	storageFolderTwo := filepath.Join(cmt.persistDir, "storageFolderTwo")
   800  	// Create the storage folder dir.
   801  	err = os.MkdirAll(storageFolderTwo, 0700)
   802  	if err != nil {
   803  		t.Fatal(err)
   804  	}
   805  	err = cmt.cm.AddStorageFolder(storageFolderTwo, modules.SectorSize*storageFolderGranularity*3)
   806  	if err != nil {
   807  		t.Fatal(err)
   808  	}
   809  
   810  	// Verify that every single sector is readable and has the correct data.
   811  	wg.Add(len(roots))
   812  	var misses uint64
   813  	for i := 0; i < len(roots); i++ {
   814  		go func(i int) {
   815  			data, err := cmt.cm.ReadSector(roots[i])
   816  			if err != nil || !bytes.Equal(data, datas[i]) {
   817  				atomic.AddUint64(&misses, 1)
   818  			}
   819  			wg.Done()
   820  		}(i)
   821  	}
   822  	wg.Wait()
   823  	if misses != 0 {
   824  		t.Errorf("Could not find all %v sectors: %v\n", len(roots), misses)
   825  	}
   826  
   827  	// Decrease the size of the storage folder.
   828  	err = cmt.cm.ResizeStorageFolder(sfIndex, modules.SectorSize*storageFolderGranularity*2, false)
   829  	if err != nil {
   830  		t.Fatal(err)
   831  	}
   832  	// Verify that the capacity and file sizes are correct.
   833  	sfs = cmt.cm.StorageFolders()
   834  	capacity := sfs[0].Capacity + sfs[1].Capacity
   835  	capacityRemaining := sfs[0].CapacityRemaining + sfs[1].CapacityRemaining
   836  	if capacity != modules.SectorSize*storageFolderGranularity*11 {
   837  		t.Error("new storage folder is reporting the wrong capacity")
   838  	}
   839  	if capacityRemaining != modules.SectorSize*storageFolderGranularity*8 {
   840  		t.Error("new storage folder capacity remaining is reporting the wrong remaining capacity")
   841  	}
   842  	mfi, err = os.Stat(mfn)
   843  	if err != nil {
   844  		t.Fatal(err)
   845  	}
   846  	sfi, err = os.Stat(sfn)
   847  	if err != nil {
   848  		t.Fatal(err)
   849  	}
   850  	if uint64(mfi.Size()) != sectorMetadataDiskSize*storageFolderGranularity*8 {
   851  		t.Error("metadata file is the wrong size")
   852  	}
   853  	if uint64(sfi.Size()) != modules.SectorSize*storageFolderGranularity*8 {
   854  		t.Error("sector file is the wrong size")
   855  	}
   856  
   857  	// Verify that every single sector is readable and has the correct data.
   858  	wg.Add(len(roots))
   859  	misses = 0
   860  	for i := 0; i < len(roots); i++ {
   861  		go func(i int) {
   862  			data, err := cmt.cm.ReadSector(roots[i])
   863  			if err != nil || !bytes.Equal(data, datas[i]) {
   864  				atomic.AddUint64(&misses, 1)
   865  			}
   866  			wg.Done()
   867  		}(i)
   868  	}
   869  	wg.Wait()
   870  	if misses != 0 {
   871  		t.Errorf("Could not find all %v sectors: %v\n", len(roots), misses)
   872  	}
   873  
   874  	// Restart the contract manager. WAL update was not completed, so changes
   875  	// should not have persisted. All sectors should still be available though,
   876  	// and they may have moved around but the capacity reporting should align
   877  	// correctly.
   878  	err = cmt.cm.Close()
   879  	if err != nil {
   880  		t.Fatal(err)
   881  	}
   882  	cmt.cm, err = New(filepath.Join(cmt.persistDir, modules.ContractManagerDir))
   883  	if err != nil {
   884  		t.Fatal(err)
   885  	}
   886  
   887  	// Verify that the capacity and file sizes are correct.
   888  	sfs = cmt.cm.StorageFolders()
   889  	capacity = sfs[0].Capacity + sfs[1].Capacity
   890  	capacityRemaining = sfs[0].CapacityRemaining + sfs[1].CapacityRemaining
   891  	if capacity != modules.SectorSize*storageFolderGranularity*11 {
   892  		t.Error("new storage folder is reporting the wrong capacity", capacity/modules.SectorSize, storageFolderGranularity*11)
   893  	}
   894  	if capacityRemaining != modules.SectorSize*storageFolderGranularity*8 {
   895  		t.Error("new storage folder capacity remaining is reporting the wrong remaining capacity")
   896  	}
   897  	mfi, err = os.Stat(mfn)
   898  	if err != nil {
   899  		t.Fatal(err)
   900  	}
   901  	sfi, err = os.Stat(sfn)
   902  	if err != nil {
   903  		t.Fatal(err)
   904  	}
   905  	if uint64(mfi.Size()) != sectorMetadataDiskSize*storageFolderGranularity*8 {
   906  		t.Error("metadata file is the wrong size")
   907  	}
   908  	if uint64(sfi.Size()) != modules.SectorSize*storageFolderGranularity*8 {
   909  		t.Error("sector file is the wrong size")
   910  	}
   911  
   912  	// Verify that every single sector is readable and has the correct data.
   913  	wg.Add(len(roots))
   914  	misses = 0
   915  	for i := 0; i < len(roots); i++ {
   916  		go func(i int) {
   917  			data, err := cmt.cm.ReadSector(roots[i])
   918  			if err != nil || !bytes.Equal(data, datas[i]) {
   919  				atomic.AddUint64(&misses, 1)
   920  			}
   921  			wg.Done()
   922  		}(i)
   923  	}
   924  	wg.Wait()
   925  	if misses != 0 {
   926  		t.Errorf("Could not find all %v sectors: %v\n", len(roots), misses)
   927  	}
   928  }
   929  
   930  // TestShrinkStorageFolderWAL completes a storage folder shrinking, but leaves
   931  // the WAL behind so that a commit is necessary to finalize things.
   932  func TestShrinkStorageFolderWAL(t *testing.T) {
   933  	if testing.Short() {
   934  		t.SkipNow()
   935  	}
   936  	t.Parallel()
   937  	d := new(dependencyLeaveWAL)
   938  	cmt, err := newMockedContractManagerTester(d, "TestShrinkStorageFolderWAL")
   939  	if err != nil {
   940  		t.Fatal(err)
   941  	}
   942  	defer cmt.panicClose()
   943  
   944  	// Add a storage folder.
   945  	storageFolderOne := filepath.Join(cmt.persistDir, "storageFolderOne")
   946  	// Create the storage folder dir.
   947  	err = os.MkdirAll(storageFolderOne, 0700)
   948  	if err != nil {
   949  		t.Fatal(err)
   950  	}
   951  	err = cmt.cm.AddStorageFolder(storageFolderOne, modules.SectorSize*storageFolderGranularity*8)
   952  	if err != nil {
   953  		t.Fatal(err)
   954  	}
   955  
   956  	// Get the index of the storage folder.
   957  	sfs := cmt.cm.StorageFolders()
   958  	if len(sfs) != 1 {
   959  		t.Fatal("there should only be one storage folder")
   960  	}
   961  	sfIndex := sfs[0].Index
   962  	// Verify that the storage folder has the correct capacity.
   963  	if sfs[0].Capacity != modules.SectorSize*storageFolderGranularity*8 {
   964  		t.Error("new storage folder is reporting the wrong capacity")
   965  	}
   966  	// Verify that the on-disk files are the right size.
   967  	mfn := filepath.Join(storageFolderOne, metadataFile)
   968  	sfn := filepath.Join(storageFolderOne, sectorFile)
   969  	mfi, err := os.Stat(mfn)
   970  	if err != nil {
   971  		t.Fatal(err)
   972  	}
   973  	sfi, err := os.Stat(sfn)
   974  	if err != nil {
   975  		t.Fatal(err)
   976  	}
   977  	if uint64(mfi.Size()) != sectorMetadataDiskSize*storageFolderGranularity*8 {
   978  		t.Error("metadata file is the wrong size")
   979  	}
   980  	if uint64(sfi.Size()) != modules.SectorSize*storageFolderGranularity*8 {
   981  		t.Error("sector file is the wrong size")
   982  	}
   983  
   984  	// Create some sectors and add them to the storage folder.
   985  	roots := make([]crypto.Hash, storageFolderGranularity*3)
   986  	datas := make([][]byte, storageFolderGranularity*3)
   987  	for i := 0; i < storageFolderGranularity*3; i++ {
   988  		root, data := randSector()
   989  		roots[i] = root
   990  		datas[i] = data
   991  	}
   992  	// Add all of the sectors.
   993  	var wg sync.WaitGroup
   994  	wg.Add(len(roots))
   995  	for i := 0; i < len(roots); i++ {
   996  		go func(i int) {
   997  			err := cmt.cm.AddSector(roots[i], datas[i])
   998  			if err != nil {
   999  				t.Error(err)
  1000  			}
  1001  			wg.Done()
  1002  		}(i)
  1003  	}
  1004  	wg.Wait()
  1005  
  1006  	// Add a second storage folder so that the displaced sectors have somewhere
  1007  	// to go.
  1008  	storageFolderTwo := filepath.Join(cmt.persistDir, "storageFolderTwo")
  1009  	// Create the storage folder dir.
  1010  	err = os.MkdirAll(storageFolderTwo, 0700)
  1011  	if err != nil {
  1012  		t.Fatal(err)
  1013  	}
  1014  	err = cmt.cm.AddStorageFolder(storageFolderTwo, modules.SectorSize*storageFolderGranularity*3)
  1015  	if err != nil {
  1016  		t.Fatal(err)
  1017  	}
  1018  
  1019  	// Verify that every single sector is readable and has the correct data.
  1020  	wg.Add(len(roots))
  1021  	var misses uint64
  1022  	for i := 0; i < len(roots); i++ {
  1023  		go func(i int) {
  1024  			data, err := cmt.cm.ReadSector(roots[i])
  1025  			if err != nil || !bytes.Equal(data, datas[i]) {
  1026  				atomic.AddUint64(&misses, 1)
  1027  			}
  1028  			wg.Done()
  1029  		}(i)
  1030  	}
  1031  	wg.Wait()
  1032  	if misses != 0 {
  1033  		t.Errorf("Could not find all %v sectors: %v\n", len(roots), misses)
  1034  	}
  1035  
  1036  	// Decrease the size of the storage folder.
  1037  	err = cmt.cm.ResizeStorageFolder(sfIndex, modules.SectorSize*storageFolderGranularity*2, false)
  1038  	if err != nil {
  1039  		t.Fatal(err)
  1040  	}
  1041  	// Verify that the capacity and file sizes are correct.
  1042  	sfs = cmt.cm.StorageFolders()
  1043  	capacity := sfs[0].Capacity + sfs[1].Capacity
  1044  	capacityRemaining := sfs[0].CapacityRemaining + sfs[1].CapacityRemaining
  1045  	if capacity != modules.SectorSize*storageFolderGranularity*5 {
  1046  		t.Error("new storage folder is reporting the wrong capacity")
  1047  	}
  1048  	if capacityRemaining != modules.SectorSize*storageFolderGranularity*2 {
  1049  		t.Error("new storage folder capacity remaining is reporting the wrong remaining capacity")
  1050  	}
  1051  	mfi, err = os.Stat(mfn)
  1052  	if err != nil {
  1053  		t.Fatal(err)
  1054  	}
  1055  	sfi, err = os.Stat(sfn)
  1056  	if err != nil {
  1057  		t.Fatal(err)
  1058  	}
  1059  	if uint64(mfi.Size()) != sectorMetadataDiskSize*storageFolderGranularity*2 {
  1060  		t.Error("metadata file is the wrong size")
  1061  	}
  1062  	if uint64(sfi.Size()) != modules.SectorSize*storageFolderGranularity*2 {
  1063  		t.Error("sector file is the wrong size")
  1064  	}
  1065  
  1066  	// Verify that every single sector is readable and has the correct data.
  1067  	wg.Add(len(roots))
  1068  	misses = 0
  1069  	for i := 0; i < len(roots); i++ {
  1070  		go func(i int) {
  1071  			data, err := cmt.cm.ReadSector(roots[i])
  1072  			if err != nil || !bytes.Equal(data, datas[i]) {
  1073  				atomic.AddUint64(&misses, 1)
  1074  			}
  1075  			wg.Done()
  1076  		}(i)
  1077  	}
  1078  	wg.Wait()
  1079  	if misses != 0 {
  1080  		t.Errorf("Could not find all %v sectors: %v\n", len(roots), misses)
  1081  	}
  1082  
  1083  	// Restart the contract manager to see that the change is persistent.
  1084  	err = cmt.cm.Close()
  1085  	if err != nil {
  1086  		t.Fatal(err)
  1087  	}
  1088  	cmt.cm, err = New(filepath.Join(cmt.persistDir, modules.ContractManagerDir))
  1089  	if err != nil {
  1090  		t.Fatal(err)
  1091  	}
  1092  
  1093  	// Verify that the capacity and file sizes are correct.
  1094  	sfs = cmt.cm.StorageFolders()
  1095  	capacity = sfs[0].Capacity + sfs[1].Capacity
  1096  	capacityRemaining = sfs[0].CapacityRemaining + sfs[1].CapacityRemaining
  1097  	if capacity != modules.SectorSize*storageFolderGranularity*5 {
  1098  		t.Error("new storage folder is reporting the wrong capacity")
  1099  	}
  1100  	if capacityRemaining != modules.SectorSize*storageFolderGranularity*2 {
  1101  		t.Error("new storage folder capacity remaining is reporting the wrong remaining capacity")
  1102  	}
  1103  	mfi, err = os.Stat(mfn)
  1104  	if err != nil {
  1105  		t.Fatal(err)
  1106  	}
  1107  	sfi, err = os.Stat(sfn)
  1108  	if err != nil {
  1109  		t.Fatal(err)
  1110  	}
  1111  	if uint64(mfi.Size()) != sectorMetadataDiskSize*storageFolderGranularity*2 {
  1112  		t.Error("metadata file is the wrong size")
  1113  	}
  1114  	if uint64(sfi.Size()) != modules.SectorSize*storageFolderGranularity*2 {
  1115  		t.Error("sector file is the wrong size")
  1116  	}
  1117  
  1118  	// Verify that every single sector is readable and has the correct data.
  1119  	wg.Add(len(roots))
  1120  	misses = 0
  1121  	for i := 0; i < len(roots); i++ {
  1122  		go func(i int) {
  1123  			data, err := cmt.cm.ReadSector(roots[i])
  1124  			if err != nil || !bytes.Equal(data, datas[i]) {
  1125  				atomic.AddUint64(&misses, 1)
  1126  			}
  1127  			wg.Done()
  1128  		}(i)
  1129  	}
  1130  	wg.Wait()
  1131  	if misses != 0 {
  1132  		t.Errorf("Could not find all %v sectors: %v\n", len(roots), misses)
  1133  	}
  1134  }
  1135  
  1136  // TestShrinkSingleStorageFolder verifies that it's possible to shirnk a single
  1137  // storage folder with no destination for the sectors.
  1138  func TestShrinkSingleStorageFolder(t *testing.T) {
  1139  	// TODO: Supporting in-place storage folder shrinking requires the
  1140  	// move-sector function to be able to recognize the storage folder that it
  1141  	// is currently using - right now it needs a storage folder lock to migrate
  1142  	// a sector in, and a storage folder lock to migrate a sector out, and
  1143  	// these locks are independent, so it cannot move a sector into the folder
  1144  	// that the sector is being moved out of.
  1145  	t.Skip("In-place shrinking not currently supported")
  1146  	if testing.Short() {
  1147  		t.SkipNow()
  1148  	}
  1149  	t.Parallel()
  1150  	cmt, err := newContractManagerTester(t.Name())
  1151  	if err != nil {
  1152  		t.Fatal(err)
  1153  	}
  1154  	defer cmt.panicClose()
  1155  
  1156  	// Add a storage folder.
  1157  	storageFolderOne := filepath.Join(cmt.persistDir, "storageFolderOne")
  1158  	mfn := filepath.Join(storageFolderOne, metadataFile)
  1159  	sfn := filepath.Join(storageFolderOne, sectorFile)
  1160  	// Create the storage folder dir.
  1161  	err = os.MkdirAll(storageFolderOne, 0700)
  1162  	if err != nil {
  1163  		t.Fatal(err)
  1164  	}
  1165  	err = cmt.cm.AddStorageFolder(storageFolderOne, modules.SectorSize*storageFolderGranularity*8)
  1166  	if err != nil {
  1167  		t.Fatal(err)
  1168  	}
  1169  	// Get the index of the storage folder.
  1170  	sfs := cmt.cm.StorageFolders()
  1171  	if len(sfs) != 1 {
  1172  		t.Fatal("there should only be one storage folder")
  1173  	}
  1174  	sfIndex := sfs[0].Index
  1175  
  1176  	// Create some sectors and add them to the storage folder.
  1177  	roots := make([]crypto.Hash, storageFolderGranularity*3)
  1178  	datas := make([][]byte, storageFolderGranularity*3)
  1179  	for i := 0; i < storageFolderGranularity*3; i++ {
  1180  		root, data := randSector()
  1181  		roots[i] = root
  1182  		datas[i] = data
  1183  	}
  1184  	// Add all of the sectors.
  1185  	var wg sync.WaitGroup
  1186  	wg.Add(len(roots))
  1187  	for i := 0; i < len(roots); i++ {
  1188  		go func(i int) {
  1189  			err := cmt.cm.AddSector(roots[i], datas[i])
  1190  			if err != nil {
  1191  				t.Error(err)
  1192  			}
  1193  			wg.Done()
  1194  		}(i)
  1195  	}
  1196  	wg.Wait()
  1197  
  1198  	// Decrease the size of the storage folder.
  1199  	err = cmt.cm.ResizeStorageFolder(sfIndex, modules.SectorSize*storageFolderGranularity*4, false)
  1200  	if err != nil {
  1201  		t.Fatal(err)
  1202  	}
  1203  	// Verify that the capacity and file sizes are correct.
  1204  	sfs = cmt.cm.StorageFolders()
  1205  	if sfs[0].Capacity != modules.SectorSize*storageFolderGranularity*4 {
  1206  		t.Error("new storage folder is reporting the wrong capacity")
  1207  	}
  1208  	if sfs[0].CapacityRemaining != modules.SectorSize*storageFolderGranularity*1 {
  1209  		t.Error("new storage folder capacity remaining is reporting the wrong remaining capacity")
  1210  	}
  1211  	mfi, err := os.Stat(mfn)
  1212  	if err != nil {
  1213  		t.Fatal(err)
  1214  	}
  1215  	sfi, err := os.Stat(sfn)
  1216  	if err != nil {
  1217  		t.Fatal(err)
  1218  	}
  1219  	if uint64(mfi.Size()) != sectorMetadataDiskSize*storageFolderGranularity*4 {
  1220  		t.Error("metadata file is the wrong size")
  1221  	}
  1222  	if uint64(sfi.Size()) != modules.SectorSize*storageFolderGranularity*4 {
  1223  		t.Error("sector file is the wrong size")
  1224  	}
  1225  
  1226  	// Verify that every single sector is readable and has the correct data.
  1227  	wg.Add(len(roots))
  1228  	misses := uint64(0)
  1229  	for i := 0; i < len(roots); i++ {
  1230  		go func(i int) {
  1231  			data, err := cmt.cm.ReadSector(roots[i])
  1232  			if err != nil || !bytes.Equal(data, datas[i]) {
  1233  				atomic.AddUint64(&misses, 1)
  1234  			}
  1235  			wg.Done()
  1236  		}(i)
  1237  	}
  1238  	wg.Wait()
  1239  	if misses != 0 {
  1240  		t.Errorf("Could not find all %v sectors: %v\n", len(roots), misses)
  1241  	}
  1242  
  1243  	// Restart the contract manager to see that the change is persistent.
  1244  	err = cmt.cm.Close()
  1245  	if err != nil {
  1246  		t.Fatal(err)
  1247  	}
  1248  	cmt.cm, err = New(filepath.Join(cmt.persistDir, modules.ContractManagerDir))
  1249  	if err != nil {
  1250  		t.Fatal(err)
  1251  	}
  1252  
  1253  	// Verify that the capacity and file sizes are correct.
  1254  	sfs = cmt.cm.StorageFolders()
  1255  	if sfs[0].Capacity != modules.SectorSize*storageFolderGranularity*4 {
  1256  		t.Error("new storage folder is reporting the wrong capacity")
  1257  	}
  1258  	if sfs[0].CapacityRemaining != modules.SectorSize*storageFolderGranularity*1 {
  1259  		t.Error("new storage folder capacity remaining is reporting the wrong remaining capacity")
  1260  	}
  1261  	mfi, err = os.Stat(mfn)
  1262  	if err != nil {
  1263  		t.Fatal(err)
  1264  	}
  1265  	sfi, err = os.Stat(sfn)
  1266  	if err != nil {
  1267  		t.Fatal(err)
  1268  	}
  1269  	if uint64(mfi.Size()) != sectorMetadataDiskSize*storageFolderGranularity*4 {
  1270  		t.Error("metadata file is the wrong size")
  1271  	}
  1272  	if uint64(sfi.Size()) != modules.SectorSize*storageFolderGranularity*4 {
  1273  		t.Error("sector file is the wrong size")
  1274  	}
  1275  
  1276  	// Verify that every single sector is readable and has the correct data.
  1277  	wg.Add(len(roots))
  1278  	misses = 0
  1279  	for i := 0; i < len(roots); i++ {
  1280  		go func(i int) {
  1281  			data, err := cmt.cm.ReadSector(roots[i])
  1282  			if err != nil || !bytes.Equal(data, datas[i]) {
  1283  				atomic.AddUint64(&misses, 1)
  1284  			}
  1285  			wg.Done()
  1286  		}(i)
  1287  	}
  1288  	wg.Wait()
  1289  	if misses != 0 {
  1290  		t.Errorf("Could not find all %v sectors: %v\n", len(roots), misses)
  1291  	}
  1292  }