From 6b2d7a411ffc0e741fecbc5f8ebd2a9b7de60551 Mon Sep 17 00:00:00 2001 From: Mark Spanbroek Date: Tue, 27 Aug 2024 17:31:08 +0200 Subject: [PATCH] Draft design for a storage proof network --- design/proof-network.md | 245 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 design/proof-network.md diff --git a/design/proof-network.md b/design/proof-network.md new file mode 100644 index 0000000..b1509c6 --- /dev/null +++ b/design/proof-network.md @@ -0,0 +1,245 @@ +Storage proof network +===================== + +Authors: Codex Team + +In this document we explore a design for an off-chain network for validating +[storage proofs][1]. Instead of checking each storage proof in a smart contract +on-chain, we let the proof network check these proofs. Only when a proof is +missing we go on-chain to enact slashing. The main goal of this exercise is to +reduce the costs of submitting and validating proofs, which has shown to be a +limiting factor for the profitability of storage providers and the scaling of +the storage network, even when deploying on a [rollup][2] or [sidechain][3]. + +[1]: proof-erasure-coding.md +[2]: ../evaluations/rollups.md +[3]: ../evaluations/sidechains.md + +Overview +-------- + +The main idea is that validators in the network sign off on messages containing +correct storage proofs, and on messages that correctly indicate that a proof is +missing. These validators deposit a stake on-chain. We consider a message to be +validated by the network when a subset of the validators representing > 2/3 of +the total network stake have signed off on it. The assumption here is that less +than 1/3 of the validators are byzantine, meaning that the rest is online and +following protocol. + +Roles in the network are: + +- provers: they are the storage providers that submit storage proofs +- validators: they sign off on submitted proofs and missed proofs +- watchers: they monitor for missing proofs, and trigger slashing on-chain + +They are all connected to the same peer-to-peer gossipsub network in which they +exchange messsages. The provers and watchers also monitor the on-chain +marketplace to check when storage proofs are required. + + + prover validator + + prover <---------> gossipsub <--------------> validator + + prover ^ | validator + \ | + \ | + \ v watcher + \ + \ watcher + \ + \ ^ watcher + \ | + \ | + \ | + \ v + + marketplace + (on-chain) + +Messages +-------- + +The messages that are exchanged over the gossipsub network are: + +- `SubmitProof(slot id, period, inputs, proof)` +- `ProofSigned(slot id, period, inputs, signature)` +- `ProofValidated(slot id, period, inputs, combined signature)` +- `SubmitMissed(slot id, period, inputs)` +- `MissedSigned(slot id, period, inputs, signature)` + +A *slot id* parameters refers to a [slot in a storage request][4] on the +marketplace. It uniquely identifies the data for which a storage proof is +required. The *period* refers to a [time interval][5] in which the storage proof +should be submitted. By *proof* we mean a [zero-knowledge proof][5], and by +*inputs* we mean its public inputs. A *signature* is a BLS validator signature, +and a *combined signature* is a BLS signature that is a combination of multiple +validator signatures. + +#### SubmitProof #### + +A prover broadcasts a `SubmitProof` message to indicate to the network that it +calculated a storage proof as required by the marketplace. + +#### ProofSigned #### + +A validator broadcasts a `ProofSigned` message in response to a `SubmitProof` +message. It only responds with `ProofSigned` after verifying the correctness of +the zero knowledge *proof* w.r.t. its public *inputs*, and checking that the +time *period* has not ended yet. + +#### ProofValidated #### + +A prover broadcasts `ProofValidated` after it collected enough `ProofSigned` +messages from the validators. It combines the BLS *signatures* that it received +into a single *combined signature* which represents > 2/3 stake of the network. + +#### SubmitMissed #### + +A watcher broadcasts a `SubmitMissed` when it notices that a required proof was +not submitted. + +#### MissedSigned #### + +A validator broadcasts `MissedSigned` only when the *period* has ended, and the +validator did not previously broadcast a `ProofSigned` for the same *slot id*, +*period* and *inputs*. + +[4]: marketplace.md +[5]: https://github.com/codex-storage/codex-storage-proofs-circuits#circuit + +Flows +------- + +### Successfull proof submission and validation ### + +Provers monitor the on-chain marketplace to check in which periods they need to +provide a storage proof. When a proof is required in the current *period*, the +prover gathers public *inputs* for the slot, including the random challenge for +the current period and calculates a zero-knowledge storage *proof*. The prover +then broadcast `SubmitProof(slot id, period, inputs, proof)`: + + validator + SubmitProof + prover ---------------------------------------> validator + + validator + +Upon receiving a `SubmitProof` message a validator checks that the *period* +hasn't ended yet and that the *proof* is correct w.r.t. to the *inputs*. If that +is all in order it will sign and broadcast a `ProofSigned(slot id, period, +inputs, signature)` message: + + + validator + ProofSigned + prover <--------------------------------------- validator + + validator + +Provers listen for these `ProofSigned` messages from the validators, and once +they accumulated enough *signature*s from validators to represent > 2/3 stake, +they create a *combined signature* and broadcast `ProofValidated(slot id, +period, inputs, combined signature)`: + + ProofValidated + prover ------------------. + | + | + v watcher + + watcher + + watcher + +### Missing proofs ### + +Watchers monitor the on-chain marketplace to check which slots require a storage +proof to be submitted and what the public *inputs* for the proof are. For each +required proof they then monitor the gossipsub network for `ProofValidated` +messages. If they do not observe a `ProofValidated` message that is signed by > +2/3 stake before the end of the period with the expected *slot id*, *period* and +*inputs* parameters, then they will broadcast a `SubmitMissed(slot id, period, +inputs)` message. + + validator + + .--------------------> validator + | + | validator + | + SubmitMissed | + | + + watcher + +Upon receiving a `SubmitMissed(slot id, period, inputs)` message a validator +checks that the *period* has ended and that it hasn't already sent out a +`ProofSigned` message for the *slot id*, *period* and *inputs*. If it indeed +did not, then it will sign and broadcast a `MissedSigned(slot id, period, +inputs, signature)`. + + validator + MissedSigned + .--------------------- validator + | + | validator + | + | + v + + watcher + +When the watcher receives enough *signature*s to represent > 2/3 stake it can +combine these signatures into a single *combined signature*. The watcher can +then submit *slot id*, *period*, *inputs* and *combined signature* to the +marketplace. + +The marketplace will then verify the correctness of *inputs* for the *slot id* +and *period*, and checks that the *combined signature* is representative for > +2/3 stake. If these conditions are met, it will then slash the storage provider +collateral and reward the watcher. + +### Faulty proofs ### + +The storage proofs that a prover submits can be faulty for a number of reasons: + +1. The zero knowledge *proof* is incorrect +2. The submitted *period* is not the current time period +3. The public *inputs* to the proof do not match the values from the on-chain + marketplace + +Faults 1 and 2 are caught by the validators. Correct validators will not sign +off on invalid zero-knowledge *proofs*, or on a *period* that is not the current +time period. This means that it is not possible to construct a `ProofValidated` +message with a *combined signature* representing > 2/3 stake. Watchers and +Validators are now free to treat the proof as missing, and go through the same +flow that we described in the previous section. + +Fault 3 is caught by the watchers and the on-chain marketplace. Watchers will +look for a `ProofValidated` that has the same *inputs* as specified by the +marketplace. If it doesn't find it because the prover broadcast a +`ProofValidated` with a different value for *inputs*, then it will treat the proof as missing, and go through the same flow as in the previous section. + +Consensus +--------- + +The core of our design consists of the fact that correct validators either sign +off on a `ProofSigned` message -or- on a `MissedSigned` message, but never on +both. We then use a light form of consensus by combining signatures of +validators representing > 2/3 stake. Because we assume that there are < 1/3 +stake byzantine validators, it is always possible to either get enough +signatures to validate a correct proof that was submitted on time, or get enough +signatures to sign off on a missed or faulty proof. + +There is one scenario in which consensus might not be reached. When a proof is +submitted at the end of its time period, and it reached some of the correct +validators before the period ends, and some of the correct validators after the +period ends. In this scenario it can occur that it's not possible to get enough +signatures to validate the proof, and not enough signatures to sign off on a +missed proof. + +We argue that is not a problematic scenario for our storage proof network. The +prover did provide a correct proof to at least one correct validator, meaning +that is still storing the data that it is supposed to. Not being able to slash +it in this case is therefore ok.