Просмотр исходного кода

book: Document Consensus::Unstake

parazyd 3 лет назад
Родитель
Сommit
aec4ed8a53

+ 1 - 0
doc/src/SUMMARY.md

@@ -24,6 +24,7 @@
     - [Stake](architecture/consensus/stake.md)
     - [Stake](architecture/consensus/stake.md)
     - [Proposal](architecture/consensus/proposal.md)
     - [Proposal](architecture/consensus/proposal.md)
     - [UnstakeRequest](architecture/consensus/unstake_request.md)
     - [UnstakeRequest](architecture/consensus/unstake_request.md)
+    - [Unstake](architecture/consensus/unstake.md)
   - [Transactions](architecture/tx_lifetime.md)
   - [Transactions](architecture/tx_lifetime.md)
   - [Smart Contracts](architecture/smart_contracts.md)
   - [Smart Contracts](architecture/smart_contracts.md)
   - [Bridge](architecture/bridge.md)
   - [Bridge](architecture/bridge.md)

+ 13 - 4
doc/src/architecture/consensus.md

@@ -1,5 +1,14 @@
 # Consensus
 # Consensus
 
 
+To understand how the consensus smart contract works and how anonymous
+staking and unstaking is achieved, read the following chapters:
+
+* [Genesis stake](consensus/genesis_stake.md)
+* [Stake](consensus/stake.md)
+* [Proposal](consensus/proposal.md)
+* [Unstake request](consensus/unstake_request.md)
+* [Unstake](consensus/unstake.md)
+
 This section of the book describes how nodes participating in the DarkFi
 This section of the book describes how nodes participating in the DarkFi
 blockchain achieve consensus.
 blockchain achieve consensus.
 
 
@@ -8,13 +17,13 @@ blockchain achieve consensus.
 | Name                   | Description                                                                               |
 | Name                   | Description                                                                               |
 |------------------------|-------------------------------------------------------------------------------------------|
 |------------------------|-------------------------------------------------------------------------------------------|
 | Consensus              | Algorithm for reaching blockchain consensus between participating nodes                   |
 | Consensus              | Algorithm for reaching blockchain consensus between participating nodes                   |
-| Node                   | darkfid daemon participating in the network                                               |
-| Slot                   | Specified timeframe for block production, measured in seconds(default=90)                 |
-| Epoch                  | Specified timeframe for blockchain events, measured in slots(default=10)                  |
+| Node                   | DarkFi daemon participating in the network                                                |
+| Slot                   | Specified timeframe for block production, measured in seconds (default=90)                |
+| Epoch                  | Specified timeframe for blockchain events, measured in slots (default=10)                 |
 | Leader                 | Block producer                                                                            |
 | Leader                 | Block producer                                                                            |
 | Unproposed Transaction | Transaction that exists in the memory pool but has not yet been included in a block       |
 | Unproposed Transaction | Transaction that exists in the memory pool but has not yet been included in a block       |
 | Block proposal         | Block that has not yet been appended onto the canonical blockchain                        |
 | Block proposal         | Block that has not yet been appended onto the canonical blockchain                        |
-| P2P network            | Peer-to-peer network on which nodes communicate with each other                            |
+| P2P network            | Peer-to-peer network on which Nodes communicate with each other                            |
 | Finalization           | State achieved when a block and its contents are appended to the canonical blockchain     |
 | Finalization           | State achieved when a block and its contents are appended to the canonical blockchain     |
 | Fork                   | Chain of block proposals that begins with the last block of the canonical blockchain      |
 | Fork                   | Chain of block proposals that begins with the last block of the canonical blockchain      |
 
 

+ 1 - 1
doc/src/architecture/consensus/stake.md

@@ -99,7 +99,7 @@ transition. We enforce that:
   the previous call (essentially copying it)
   the previous call (essentially copying it)
 * The value commitments in the `Input` and `ConsensusOutput` match
 * The value commitments in the `Input` and `ConsensusOutput` match
 * The `Input` coin's Merkle inclusion proof is valid in the _Money_ state
 * The `Input` coin's Merkle inclusion proof is valid in the _Money_ state
-* The input's _nullifier_ wasn't revealed before in the _Money_ state
+* The input's _nullifier_ is revealed and exists in the _Money_ state
 * The `ConsensusOutput` coin hasn't existed in the _Consensus_ state before
 * The `ConsensusOutput` coin hasn't existed in the _Consensus_ state before
 * The `ConsensusOutput` coin hasn't existed in the _Unstaked Consensus_ state before
 * The `ConsensusOutput` coin hasn't existed in the _Unstaked Consensus_ state before
 
 

+ 112 - 0
doc/src/architecture/consensus/unstake.md

@@ -0,0 +1,112 @@
+Unstake
+=======
+
+The `Consensus::Unstake` and `Money::Unstake` functions are used in
+order to fully exit from the consensus participation and move back
+the staked funds into the _Money_ state.
+
+The _Unstake_ transaction consists of two contract calls, calling the
+above mentioned functions. The parameters, respectively, are:
+
+```rust,no_run,no_playground
+{{#include ../../../../src/contract/money/src/model.rs:ConsensusUnstakeParams}}
+
+{{#include ../../../../src/contract/money/src/model.rs:MoneyUnstakeParams}}
+```
+
+These two contract calls need to happen atomically, meaning they should
+be part of a single transaction being executed on the network.  On a
+high level, what is happening in the _unstake_ process is burning the
+coin previously created through [`UnstakeRequest`](unstake_request.md)
+in the _Consensus_ state and minting a new coin in the _Money_ state
+where it can then again be used for other functionality outside
+of consensus.
+
+The contract calls execute in sequence:
+
+1. `Consensus::Unstake`
+2. `Money::Unstake`
+
+The ZK proof we use to prove burning of the coin in _Consensus_ is the
+`ConsensusBurn_V1` circuit:
+
+```
+{{#include ../../../../src/contract/consensus/proof/consensus_burn_v1.zk}}
+```
+
+The ZK proof we use to prove minting of the coin in _Money_ is the
+`Mint_V1` circuit:
+
+```
+{{#include ../../../../src/contract/money/proof/mint_v1.zk}}
+```
+
+## Contract logic
+
+### [`Consensus::get_metadata()`](https://github.com/darkrenaissance/darkfi/blob/master/src/contract/consensus/src/entrypoint/unstake_v1.rs#L39)
+
+In the `consensus_unstake_get_metadata_v1` function, we gather the
+public inputs necessary to verify the `ConsensusBurn_V1` ZK proof,
+and additionally the public key used to verify the transaction
+signature. This pubkey is also derived and enforced in ZK.
+
+### [`Consensus::process_instruction()`](https://github.com/darkrenaissance/darkfi/blob/master/src/contract/consensus/src/entrypoint/unstake_v1.rs#L84)
+
+For the _Consensus_ state transition, we use the
+`consensus_unstake_process_instruction_v1` function. We enforce that:
+
+* The next `call_idx` is a call to the `Money::UnstakeV1` function
+* The input in the params to the next function is the same as current input
+* The timelock from [`UnstakeRequest`](unstake_request.md) has expired
+* The input coin Merkle inclusion proof is valid
+* The input nullifier was not published before
+
+If these checks pass, we create a state update with the revealed
+_nullifier_:
+
+```rust,no_run,no_playground
+{{#include ../../../../src/contract/money/src/model.rs:ConsensusUnstakeUpdate}}
+```
+
+### [`Consensus::process_update()`](https://github.com/darkrenaissance/darkfi/blob/master/src/contract/consensus/src/entrypoint/unstake_v1.rs#L169)
+
+For the _Consensus_ state update, we use the
+`consensus_unstake_process_update_v1` function. This will simply
+append the revealed _nullifier_ to the existing set of nullifiers in
+order to prevent double-spending.
+
+After the `Consensus::Unstake` state transition has passed, we move on
+to executing the `Money::Unstake` state transition. This is supposed
+to mint the new coin in the _Money_ state.
+
+### [`Money::get_metadata()`](https://github.com/darkrenaissance/darkfi/blob/master/src/contract/money/src/entrypoint/unstake_v1.rs#L41)
+
+In the `money_unstake_get_metadata_v1` function, we gather the public
+inputs necessary to verify the `Mint_V1` ZK proof. It is not necessary
+to grab any public keys for signature verification, as they're already
+collected in `Consensus::get_metadata()`.
+
+### [`Money::process_instruction()`](https://github.com/darkrenaissance/darkfi/blob/master/src/contract/money/src/entrypoint/unstake_v1.rs#L79)
+
+In the `money_unstake_process_instruction_v1` function, we perform
+the state transition. We enforce that:
+
+* The previous `call_idx` is a call to the `Consensus::UnstakeV1` function
+* The token pedersen commitment is a commitment to the native network token
+* The value pedersen commitments in the input and output match
+* The input coin Merkle inclusion proof is valid for _Consensus_
+* The input nullifier was published in _Consensus_
+* The output coin was not seen before in the set of coins in _Money_
+
+If these checks pass, we create a state update with the revealed
+minted coin:
+
+```rust,no_run,no_playground
+{{#include ../../../../src/contract/money/src/model.rs:MoneyUnstakeUpdate}}
+```
+
+### [`Money::process_update()`](https://github.com/darkrenaissance/darkfi/blob/master/src/contract/money/src/entrypoint/unstake_v1.rs#L194)
+
+In `money_unstake_process_update_v1` we simply append the newly minted
+coin to the set of seen coins in _Money_, and we add it to the Merkle
+tree of coins in _Money_ so further inclusion proofs can be validated.

+ 1 - 1
doc/src/architecture/consensus/unstake_request.md

@@ -54,7 +54,7 @@ with the burned nullifier and the minted coin. Here we use the same
 parameters like we do in [`Proposal`](proposal.md) - a nullifier and
 parameters like we do in [`Proposal`](proposal.md) - a nullifier and
 a coin:
 a coin:
 
 
-```
+```rust,no_run,no_playground
 {{#include ../../../../src/contract/consensus/src/model.rs:ConsensusProposalUpdate}}
 {{#include ../../../../src/contract/consensus/src/model.rs:ConsensusProposalUpdate}}
 ```
 ```