New RPC Loop
Some unresolved questions from !3237 (merged):
-
Should the RPC Session pertain to a single contract, or should the renter be able to modify multiple contracts within a single Session? The latter is more flexible, but implies that most RPC request objects would need to contain a contract ID, and has negative performance implications.(Resolved: single contract) -
Should the RPC Session have an "initial setup phase"/"handshake" where the renter and host agree upon an encryption cipher, or should this agreement be a normal, separate RPC that can be called at any time? If we do implement an initial handshake, are there other things we would like to exchange at that point?(Resolved: handshake implemented) -
How do we authenticate the renter before providing them with the latest contract revision? Seems like two round-trips are required to achieve this. Could we make it part of the "initial handshake," possibly saving a round-trip?(Resolved: authentication added to handshake without extra round-trip) - How should payment codes be handled? Is this another piece of information that could included in the initial handshake?
-
HostSettings
are currently encoded in Sia's binary encoding, which makes them difficult to extend. Should the settings be encoded with a more flexible format, or should the renter simply use theVersion
field to determine what type of object it's receiving? -
The code in !3237 (merged) does not implement the(Resolved: RPCError implemented)RPCError
object described in #3191 (closed); instead, it uses a simple string. Do we want to adopt theRPCError
type as described, or are opaque strings sufficient? - How should the renter determine which RPCs a host supports? Should every host support a
ListRPCs
RPC, or is it sufficient to use theVersion
field of theHostSettings
? ThisVersion
is actually the version ofsiad
; what if the host is third-party? -
The new(Resolved: no change)Upload
andDownload
RPC request objects only contain a small subset of theFileContractRevision
fields, in order to minimize the number of bytes transferred. Is this something we're okay committing to? What if the renter wants to change other fields, like theUnlockHash
for its payout? Sending the entire revision would allow for greater flexibility. (Counter-argument: if the renter wants to change a field, the host has to agree to it; so if we release new code where the renter changes theUnlockHash
, the host will also need to be updated. But if we continue using the same RPC ID, how do you tell whether a host supports the change or not? Wouldn't it be easier and clearer to use a new RPC?) -
How should the protocol be versioned? Should it share a version withShould the host settings contain a vanity string that identifies the software used (and thus technically allows for third-party extensions?)siad
, or should it have its own version? Should the version be a semantic version?
Agreed-upon changes to be made (as per discussion below):
-
Add a "minimum download price" to HostSettings
. The renter must pay at least this minimum price for all downloads. UpdateRPCLoopDownload
andRPCLoopSectorRoots
to respect this price. -
Change the semantics of the Version
field ofHostSettings
to mean "version of renter-host protocol" rather than "version ofsiad
". -
Encode the HostSettings as JSON. -
Switch to the more robust RPC error type. -
Keep the new Upload
andDownload
RPCs restricted to only changing a small subset of the revision fields. -
Add authentication to RPCLoopRecentRevision
andRPCLoopSectorRoots
. -
Add maxLen
restrictions to all RPCs, to prevent DoS. -
Change host to recognize bare RPCLoopEnter
without a legacy length prefix -
Implement AEAD encryption of all RPCs, initially supporting only ChaCha20-Poly1305 -
Move the key exchange step as early in the protocol as possible, even if this incurs an extra round-trip. This ensures that we don't leak any session-specific data, such as the contract ID, challenge data, or even the version of the protocol being used. -
Mandate that key-exchange protocol use X25519 + blake2b. If we ever decide to change this, we'll change it via a new RPC ID, i.e. LoopEnter1
instead ofLoopEnter
. -
Provide proper error types and descriptions for each possible error in the protocol. -
Add new payment RPCs and add payment codes to (nearly) all RPCs.
Edited by Luke Champine