forked from NebulousLabs/Sia
-
Notifications
You must be signed in to change notification settings - Fork 0
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
Currently it only supports requesting entire list of sector ids. In future it is planned to request a slice of sector ids by specifying [begin, end) indices. The slice is accompanied with a proof, that can be verified against the contract merkle root. The implementation of proofs for slices is in review: NebulousLabs/merkletree#17 That is why currently we support only the case begin=0 end=size. In this case proof is empty. That is why the protocol in forward compatible with the future plan.
- Loading branch information
Boris Nagaev
committed
Sep 15, 2017
1 parent
bb39873
commit a5083ff
Showing
8 changed files
with
189 additions
and
1 deletion.
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
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,51 @@ | ||
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 begin != 0 || end != uint64(len(so.SectorRoots)) { | ||
// TODO: support slices with proofs. Blocked by | ||
// https://github.com/NebulousLabs/merkletree/pull/17/ | ||
err = errors.New("Requesting a slice is not supported") | ||
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) | ||
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,63 @@ | ||
package proto | ||
|
||
import ( | ||
"errors" | ||
"net" | ||
"time" | ||
|
||
"github.com/NebulousLabs/Sia/crypto" | ||
"github.com/NebulousLabs/Sia/encoding" | ||
"github.com/NebulousLabs/Sia/modules" | ||
) | ||
|
||
// GetMetadata downloads sector ids from the host. | ||
func GetMetadata(host modules.HostDBEntry, contract modules.RenterContract, cancel <-chan struct{}) ([]crypto.Hash, error) { | ||
conn, err := (&net.Dialer{ | ||
Cancel: cancel, | ||
Timeout: 15 * time.Second, | ||
}).Dial("tcp", string(host.NetAddress)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer conn.Close() | ||
// allot 2 minutes for RPC request + revision exchange | ||
extendDeadline(conn, modules.NegotiateMetadataTime) | ||
if err := encoding.WriteObject(conn, modules.RPCMetadata); err != nil { | ||
return nil, errors.New("couldn't initiate RPC: " + err.Error()) | ||
} | ||
lastRevision, err := getRecentRevision(conn, contract, host.Version) | ||
if err != nil { | ||
return nil, err | ||
} | ||
numSectors := lastRevision.NewFileSize / modules.SectorSize | ||
begin, end := uint64(0), uint64(numSectors) | ||
if err := encoding.WriteObject(conn, begin); err != nil { | ||
return nil, errors.New("unable to write 'begin': " + err.Error()) | ||
} | ||
if err := encoding.WriteObject(conn, end); err != nil { | ||
return nil, errors.New("unable to write 'end': " + err.Error()) | ||
} | ||
// read acceptance | ||
if err := modules.ReadNegotiationAcceptance(conn); err != nil { | ||
return nil, errors.New("host did not accept [begin,end): " + err.Error()) | ||
} | ||
var ids []crypto.Hash | ||
if err := encoding.ReadObject(conn, &ids, numSectors*crypto.HashSize+8); err != nil { | ||
return nil, errors.New("unable to read 'ids': " + err.Error()) | ||
} | ||
// Calculate Merkle root from the ids, compare with the real root. | ||
log2SectorSize := uint64(0) | ||
for 1<<log2SectorSize < (modules.SectorSize / crypto.SegmentSize) { | ||
log2SectorSize++ | ||
} | ||
tree := crypto.NewCachedTree(log2SectorSize) | ||
for _, sectorRoot := range ids { | ||
tree.Push(sectorRoot) | ||
} | ||
got := tree.Root() | ||
want := lastRevision.NewFileMerkleRoot | ||
if got != want { | ||
return nil, errors.New("sector ids do not match Merkle root") | ||
} | ||
return ids, nil | ||
} |