From 9687fbc67921cd39a3278c655c1245d15e3555ee Mon Sep 17 00:00:00 2001
From: Christopher Schinnerl <chris@sia.tech>
Date: Tue, 6 Mar 2018 13:50:22 -0500
Subject: [PATCH] implemented requested changes

---
 modules/renter/files.go      | 26 ++++++++++++--------------
 modules/renter/files_test.go | 31 ++++++++++++++-----------------
 2 files changed, 26 insertions(+), 31 deletions(-)

diff --git a/modules/renter/files.go b/modules/renter/files.go
index 75b17a2774..861c4d8e88 100644
--- a/modules/renter/files.go
+++ b/modules/renter/files.go
@@ -88,10 +88,10 @@ func (f *file) numChunks() uint64 {
 }
 
 // available indicates whether the file is ready to be downloaded.
-func (f *file) available(isOffline func(types.FileContractID) bool) bool {
+func (f *file) available(contractStatus func(types.FileContractID) (bool, bool)) bool {
 	chunkPieces := make([]int, f.numChunks())
 	for _, fc := range f.contracts {
-		if isOffline(fc.ID) {
+		if offline, _ := contractStatus(fc.ID); offline {
 			continue
 		}
 		for _, p := range fc.Pieces {
@@ -134,7 +134,7 @@ func (f *file) uploadProgress() float64 {
 // becomes available when this redundancy is >= 1. Assumes that every piece is
 // unique within a file contract. -1 is returned if the file has size 0. It
 // takes one argument, a map of offline contracts for this file.
-func (f *file) redundancy(isOffline func(types.FileContractID) bool, goodForRenew func(types.FileContractID) bool) float64 {
+func (f *file) redundancy(contractStatus func(types.FileContractID) (bool, bool)) float64 {
 	if f.size == 0 {
 		return -1
 	}
@@ -148,11 +148,12 @@ func (f *file) redundancy(isOffline func(types.FileContractID) bool, goodForRene
 		return -1
 	}
 	for _, fc := range f.contracts {
+		offline, gfr := contractStatus(fc.ID)
+
 		// do not count pieces from the contract if the contract is offline
-		if isOffline(fc.ID) {
+		if offline {
 			continue
 		}
-		gfr := goodForRenew(fc.ID)
 		for _, p := range fc.Pieces {
 			if gfr {
 				piecesPerChunk[p.Chunk]++
@@ -259,15 +260,12 @@ func (r *Renter) FileList() []modules.FileInfo {
 	}
 	r.mu.RUnlock(lockID)
 
-	isOffline := func(id types.FileContractID) bool {
-		id = r.hostContractor.ResolveID(id)
-		offline := r.hostContractor.IsOffline(id)
-		return offline
-	}
-	goodForRenew := func(id types.FileContractID) bool {
+	contractStatus := func(id types.FileContractID) (offline bool, goodForRenew bool) {
 		id = r.hostContractor.ResolveID(id)
 		cu, ok := r.hostContractor.ContractUtility(id)
-		return ok && cu.GoodForRenew
+		offline = r.hostContractor.IsOffline(id)
+		goodForRenew = ok && cu.GoodForRenew
+		return
 	}
 
 	var fileList []modules.FileInfo
@@ -285,8 +283,8 @@ func (r *Renter) FileList() []modules.FileInfo {
 			LocalPath:      localPath,
 			Filesize:       f.size,
 			Renewing:       renewing,
-			Available:      f.available(isOffline),
-			Redundancy:     f.redundancy(isOffline, goodForRenew),
+			Available:      f.available(contractStatus),
+			Redundancy:     f.redundancy(contractStatus),
 			UploadedBytes:  f.uploadedBytes(),
 			UploadProgress: f.uploadProgress(),
 			Expiration:     f.expiration(),
diff --git a/modules/renter/files_test.go b/modules/renter/files_test.go
index cee1e660d9..cb0b5bc3e6 100644
--- a/modules/renter/files_test.go
+++ b/modules/renter/files_test.go
@@ -44,8 +44,8 @@ func TestFileAvailable(t *testing.T) {
 		erasureCode: rsc,
 		pieceSize:   100,
 	}
-	neverOffline := func(types.FileContractID) bool {
-		return false
+	neverOffline := func(types.FileContractID) (bool, bool) {
+		return false, true
 	}
 
 	if f.available(neverOffline) {
@@ -62,8 +62,8 @@ func TestFileAvailable(t *testing.T) {
 		t.Error("file should be available")
 	}
 
-	specificOffline := func(fcid types.FileContractID) bool {
-		return fcid == fc.ID
+	specificOffline := func(fcid types.FileContractID) (bool, bool) {
+		return fcid == fc.ID, true
 	}
 	if f.available(specificOffline) {
 		t.Error("file should not be available")
@@ -109,11 +109,8 @@ func TestFileUploadProgressPinning(t *testing.T) {
 // with varying number of filecontracts and erasure code settings.
 func TestFileRedundancy(t *testing.T) {
 	nDatas := []int{1, 2, 10}
-	neverOffline := func(types.FileContractID) bool {
-		return false
-	}
-	alwaysRenewable := func(types.FileContractID) bool {
-		return true
+	neverOffline := func(types.FileContractID) (bool, bool) {
+		return false, true
 	}
 	for _, nData := range nDatas {
 		rsc, _ := NewRSCode(nData, 10)
@@ -124,7 +121,7 @@ func TestFileRedundancy(t *testing.T) {
 			erasureCode: rsc,
 		}
 		// Test that an empty file has 0 redundancy.
-		if r := f.redundancy(neverOffline, alwaysRenewable); r != 0 {
+		if r := f.redundancy(neverOffline); r != 0 {
 			t.Error("expected 0 redundancy, got", r)
 		}
 		// Test that a file with 1 filecontract that has a piece for every chunk but
@@ -140,7 +137,7 @@ func TestFileRedundancy(t *testing.T) {
 			fc.Pieces = append(fc.Pieces, pd)
 		}
 		f.contracts[fc.ID] = fc
-		if r := f.redundancy(neverOffline, alwaysRenewable); r != 0 {
+		if r := f.redundancy(neverOffline); r != 0 {
 			t.Error("expected 0 redundancy, got", r)
 		}
 		// Test that adding another filecontract with a piece for every chunk but one
@@ -156,7 +153,7 @@ func TestFileRedundancy(t *testing.T) {
 			fc.Pieces = append(fc.Pieces, pd)
 		}
 		f.contracts[fc.ID] = fc
-		if r := f.redundancy(neverOffline, alwaysRenewable); r != 0 {
+		if r := f.redundancy(neverOffline); r != 0 {
 			t.Error("expected 0 redundancy, got", r)
 		}
 		// Test that adding a file contract with a piece for the missing chunk
@@ -172,7 +169,7 @@ func TestFileRedundancy(t *testing.T) {
 		f.contracts[fc.ID] = fc
 		// 1.0 / MinPieces because the chunk with the least number of pieces has 1 piece.
 		expectedR := 1.0 / float64(f.erasureCode.MinPieces())
-		if r := f.redundancy(neverOffline, alwaysRenewable); r != expectedR {
+		if r := f.redundancy(neverOffline); r != expectedR {
 			t.Errorf("expected %f redundancy, got %f", expectedR, r)
 		}
 		// Test that adding a file contract that has erasureCode.MinPieces() pieces
@@ -191,7 +188,7 @@ func TestFileRedundancy(t *testing.T) {
 		f.contracts[fc.ID] = fc
 		// 1+MinPieces / MinPieces because the chunk with the least number of pieces has 1+MinPieces pieces.
 		expectedR = float64(1+f.erasureCode.MinPieces()) / float64(f.erasureCode.MinPieces())
-		if r := f.redundancy(neverOffline, alwaysRenewable); r != expectedR {
+		if r := f.redundancy(neverOffline); r != expectedR {
 			t.Errorf("expected %f redundancy, got %f", expectedR, r)
 		}
 
@@ -208,10 +205,10 @@ func TestFileRedundancy(t *testing.T) {
 			}
 		}
 		f.contracts[fc.ID] = fc
-		specificOffline := func(fcid types.FileContractID) bool {
-			return fcid == fc.ID
+		specificOffline := func(fcid types.FileContractID) (bool, bool) {
+			return fcid == fc.ID, true
 		}
-		if r := f.redundancy(specificOffline, alwaysRenewable); r != expectedR {
+		if r := f.redundancy(specificOffline); r != expectedR {
 			t.Errorf("expected redundancy to ignore offline file contracts, wanted %f got %f", expectedR, r)
 		}
 	}
-- 
GitLab