فهرست منبع

book: Document consensus GenesisStake functionality.

parazyd 3 سال پیش
والد
کامیت
212d04bbc7

+ 1 - 0
doc/src/SUMMARY.md

@@ -20,6 +20,7 @@
   - [Anonymous assets](architecture/anonymous_assets.md)
   - [Blockchain](architecture/blockchain.md)
   - [Consensus](architecture/consensus.md)
+    - [GenesisStake](architecture/consensus/genesis_stake.md)
   - [Transactions](architecture/tx_lifetime.md)
   - [Smart Contracts](architecture/smart_contracts.md)
   - [Bridge](architecture/bridge.md)

+ 66 - 0
doc/src/architecture/consensus/genesis_stake.md

@@ -0,0 +1,66 @@
+Genesis stake
+=============
+
+The `Consensus::GenesisStake` function is used for bootstrapping the
+Proof of Stake (PoS) network. Using this, we are able to create an
+initial staking coin that participates in consensus and is able to
+propose blocks. We can gather any number of these calls/transactions
+and hardcode them into a constant genesis block, so anyone is able
+to deterministically reproduce the genesis block and begin syncing
+the blockchain.
+
+The parameters to execute this function are a single clear input,
+and a single anonymous output:
+
+```rust,no_run,no_playground
+{{#include ../../../../src/contract/consensus/src/model.rs:ConsensusGenesisStakeParams}}
+```
+
+For transparency, we use a clear input in order to show how many
+tokens are initially minted at genesis, and an anonymous output
+in order to anonymise the staker.
+
+The ZK proof we use to prove the minting of the anonymous output
+is the `ConsensusMint_V1` circuit:
+
+```
+{{#include ../../../../src/contract/consensus/proof/consensus_mint_v1.zk}}
+```
+
+Important to note here is that in the case of genesis, this mint will
+have `epoch` set to 0 (zero) in order for these stakers to be able to
+immediately propose blocks without a grace period in order to advance
+the blockchain.
+
+## Contract logic
+
+### [`get_metadata()`](https://github.com/darkrenaissance/darkfi/blob/master/src/contract/consensus/src/entrypoint/genesis_stake_v1.rs#L39)
+
+In the `consensus_genesis_stake_get_metadata_v1` function, we gather
+the public key used to verify the transaction signature from the clear
+input, and we extract the necessary public inputs that go into the
+`ConsensusMint_V1` proof verification.
+
+### [`process_instruction()`](https://github.com/darkrenaissance/darkfi/blob/master/src/contract/consensus/src/entrypoint/genesis_stake_v1.rs#L73)
+
+In the `consensus_genesis_stake_process_instruction_v1` function, we
+perform the state transition. We enforce that:
+
+* The verifying slot for this function is actually the genesis slot (0)
+* The _token ID_ from the clear input is the native network token
+* The output coin was not already seen in the set of staked or unstaked coins
+* The value commitments in the clear input and anon output match
+
+If these checks pass, we create a state update with the output coin:
+
+```rust,no_run,no_playground
+{{#include ../../../../src/contract/money/src/model.rs:ConsensusStakeUpdate}}
+```
+
+### [`process_update()`](https://github.com/darkrenaissance/darkfi/blob/master/src/contract/consensus/src/entrypoint/stake_v1.rs#L176)
+
+For the state update, we use the `consensus_stake_process_update_v1`
+function. This will simply take the state update produced by
+`consensus_genesis_stake_process_instruction_v1` and add the coin to
+the set of seen coins in the consensus state, and append it to the
+Merkle tree of coins in the consensus Merkle tree of coins.

+ 1 - 1
src/contract/money/src/client/mod.rs

@@ -27,7 +27,7 @@
 //! are able to abstract away any wallet interfaces to client implementations.
 
 use darkfi_sdk::{
-    crypto::{MerklePosition, Nullifier, SecretKey, TokenId, DARK_TOKEN_ID},
+    crypto::{pasta_prelude::*, MerklePosition, Nullifier, SecretKey, TokenId, DARK_TOKEN_ID},
     pasta::pallas,
 };
 use darkfi_serial::{SerialDecodable, SerialEncodable};

+ 4 - 2
src/contract/money/src/entrypoint/swap_v1.rs

@@ -17,10 +17,12 @@
  */
 
 use darkfi_sdk::{
-    crypto::ContractId,
+    crypto::{pasta_prelude::*, ContractId},
     db::{db_contains_key, db_lookup},
     error::{ContractError, ContractResult},
-    msg, ContractCall,
+    msg,
+    pasta::pallas,
+    ContractCall,
 };
 use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};