This repository has been archived by the owner on Nov 2, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 440
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add RPC call Metadata requesting sector IDs
This is second attempt of #2321 The whole list of IDs can be expensive for a host to provide for free, but a short list of sector IDs (up to 2^17) is cheap. At the same time it opens doors for stateless clients, i.e. recovering everything from seed only.
- Loading branch information
Showing
7 changed files
with
251 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package host | ||
|
||
import ( | ||
"errors" | ||
"net" | ||
|
||
"github.com/NebulousLabs/Sia/encoding" | ||
"github.com/NebulousLabs/Sia/modules" | ||
) | ||
|
||
// managedRPCMetadata accepts a request to get list of sector ids. | ||
func (h *Host) managedRPCMetadata(conn net.Conn) error { | ||
// Perform the file contract revision exchange, giving the renter the most | ||
// recent file contract revision and getting the storage obligation that | ||
// will be used to get sector ids. | ||
_, so, err := h.managedRPCRecentRevision(conn) | ||
if err != nil { | ||
return extendErr("RPCRecentRevision failed: ", err) | ||
} | ||
// The storage obligation is received with a lock on it. Defer a call to | ||
// unlock the storage obligation. | ||
defer func() { | ||
h.managedUnlockStorageObligation(so.id()) | ||
}() | ||
// Receive boundaries of so.SectorRoots to return. | ||
var begin, end uint64 | ||
err = encoding.ReadObject(conn, &begin, 8) | ||
if err != nil { | ||
return extendErr("unable to read 'begin': ", ErrorConnection(err.Error())) | ||
} | ||
err = encoding.ReadObject(conn, &end, 8) | ||
if err != nil { | ||
return extendErr("unable to read 'end': ", ErrorConnection(err.Error())) | ||
} | ||
if end < begin { | ||
err = errors.New("Range error") | ||
modules.WriteNegotiationRejection(conn, err) | ||
return err | ||
} | ||
if end > uint64(len(so.SectorRoots)) { | ||
err = errors.New("Range out of bounds error") | ||
modules.WriteNegotiationRejection(conn, err) | ||
return err | ||
} | ||
if end-begin > modules.NegotiateMetadataMaxSliceSize { | ||
err = errors.New("The range is too long") | ||
modules.WriteNegotiationRejection(conn, err) | ||
return err | ||
} | ||
if err = modules.WriteNegotiationAcceptance(conn); err != nil { | ||
return extendErr("failed to write [begin,end) acceptance: ", ErrorConnection(err.Error())) | ||
} | ||
// Write roots of all sectors. | ||
err = encoding.WriteObject(conn, so.SectorRoots[begin:end]) | ||
if err != nil { | ||
return extendErr("cound not write sectors: ", ErrorConnection(err.Error())) | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package proto | ||
|
||
import ( | ||
"errors" | ||
"net" | ||
"time" | ||
|
||
"github.com/NebulousLabs/Sia/crypto" | ||
"github.com/NebulousLabs/Sia/encoding" | ||
"github.com/NebulousLabs/Sia/modules" | ||
"github.com/NebulousLabs/Sia/types" | ||
) | ||
|
||
// GetMetadata downloads sector IDs from the host. | ||
func GetMetadata(host modules.HostDBEntry, fcid types.FileContractID, sk crypto.SecretKey, windowStart types.BlockHeight, begin, end uint64, cancel <-chan struct{}) (lastRevision types.FileContractRevision, ids []crypto.Hash, err error) { | ||
conn, err := (&net.Dialer{ | ||
Cancel: cancel, | ||
Timeout: 15 * time.Second, | ||
}).Dial("tcp", string(host.NetAddress)) | ||
if err != nil { | ||
return | ||
} | ||
defer conn.Close() | ||
// allot 2 minutes for RPC request + revision exchange | ||
extendDeadline(conn, modules.NegotiateMetadataTime) | ||
if err = encoding.WriteObject(conn, modules.RPCMetadata); err != nil { | ||
err = errors.New("couldn't initiate RPC: " + err.Error()) | ||
return | ||
} | ||
lastRevision, err = getRecentRevision(conn, fcid, sk, windowStart, host.Version) | ||
if err != nil { | ||
return | ||
} | ||
if err = encoding.WriteObject(conn, begin); err != nil { | ||
err = errors.New("unable to write 'begin': " + err.Error()) | ||
return | ||
} | ||
if err = encoding.WriteObject(conn, end); err != nil { | ||
err = errors.New("unable to write 'end': " + err.Error()) | ||
return | ||
} | ||
// read acceptance | ||
if err = modules.ReadNegotiationAcceptance(conn); err != nil { | ||
err = errors.New("host did not accept [begin,end): " + err.Error()) | ||
return | ||
} | ||
numSectors := end - begin | ||
if err = encoding.ReadObject(conn, &ids, numSectors*crypto.HashSize+8); err != nil { | ||
err = errors.New("unable to read 'ids': " + err.Error()) | ||
return | ||
} | ||
if uint64(len(ids)) != end-begin { | ||
err = errors.New("the host returned too short list of sector IDs") | ||
return | ||
} | ||
return | ||
} |