Преглед изворни кода

validator: preperation cleanup for PoW blocks integration

aggstam пре 2 година
родитељ
комит
8d7a2bde7c

+ 3 - 6
bin/darkfid2/src/tests/harness.rs

@@ -23,15 +23,12 @@ use darkfi::{
     net::Settings,
     rpc::jsonrpc::JsonSubscriber,
     util::time::TimeKeeper,
-    validator::{
-        consensus::{next_block_reward, pid::slot_pid_output},
-        Validator, ValidatorConfig,
-    },
+    validator::{pid::slot_pid_output, Validator, ValidatorConfig},
     Result,
 };
 use darkfi_contract_test_harness::{vks, Holder, TestHarness};
 use darkfi_sdk::{
-    blockchain::{PidOutput, PreviousSlot, Slot},
+    blockchain::{expected_reward, PidOutput, PreviousSlot, Slot},
     pasta::{group::ff::Field, pallas},
 };
 use url::Url;
@@ -182,7 +179,7 @@ impl Harness {
             let pid = PidOutput::new(f, error, sigma1, sigma2);
             let total_tokens = previous_slot.total_tokens + previous_slot.reward;
             // Only last slot in the sequence has a reward
-            let reward = if i == slots_count - 1 { next_block_reward() } else { 0 };
+            let reward = if i == slots_count - 1 { expected_reward(id) } else { 0 };
             let slot = Slot::new(id, previous, pid, pallas::Base::ZERO, total_tokens, reward);
             slots.push(slot.clone());
             previous_slot = slot;

+ 0 - 17
src/blockchain/mod.rs

@@ -103,23 +103,6 @@ impl Blockchain {
         })
     }
 
-    /* TODO: FIXME: This should not be part of `Blockchain`
-    /// A blockchain is considered valid, when every block is valid,
-    /// based on validate_block checks.
-    /// Be careful as this will try to load everything in memory.
-    pub fn validate(&self) -> Result<()> {
-        // We use block order store here so we have all blocks in order
-        let blocks = self.order.get_all()?;
-        for (index, block) in blocks[1..].iter().enumerate() {
-            let full_blocks = self.get_blocks_by_hash(&[blocks[index].1, block.1])?;
-            let expected_reward = next_block_reward();
-            full_blocks[1].validate(&full_blocks[0], expected_reward)?;
-        }
-
-        Ok(())
-    }
-    */
-
     /// Insert a given [`BlockInfo`] into the blockchain database.
     /// This functions wraps all the logic of separating the block into specific
     /// data that can be fed into the different trees of the database.

+ 2 - 2
src/contract/money/src/client/pow_reward_v1.rs

@@ -22,7 +22,7 @@ use darkfi::{
     Result,
 };
 use darkfi_sdk::{
-    blockchain::pow_expected_reward,
+    blockchain::expected_reward,
     crypto::{note::AeadEncryptedNote, pasta_prelude::*, Keypair, PublicKey, DARK_TOKEN_ID},
     pasta::pallas,
 };
@@ -148,7 +148,7 @@ impl PoWRewardCallBuilder {
     }
 
     pub fn build(&self) -> Result<PoWRewardCallDebris> {
-        let reward = pow_expected_reward(self.slot);
+        let reward = expected_reward(self.slot);
         assert!(reward != 0);
         self._build(reward)
     }

+ 2 - 2
src/contract/money/src/entrypoint/pow_reward_v1.rs

@@ -17,7 +17,7 @@
  */
 
 use darkfi_sdk::{
-    blockchain::{pow_expected_reward, POW_CUTOFF},
+    blockchain::{expected_reward, POW_CUTOFF},
     crypto::{
         pasta_prelude::*, pedersen_commitment_u64, poseidon_hash, ContractId, MerkleNode,
         DARK_TOKEN_ID,
@@ -102,7 +102,7 @@ pub(crate) fn money_pow_reward_process_instruction_v1(
     }
 
     // Verify reward value matches the expected one for this slot(block height)
-    let expected_reward = pow_expected_reward(verifying_slot);
+    let expected_reward = expected_reward(verifying_slot);
     if params.input.value != expected_reward {
         msg!(
             "[PoWRewardV1] Error: Reward value({}) is not the block height({}) expected one: {}",

+ 2 - 2
src/contract/money/tests/pow_reward.rs

@@ -26,7 +26,7 @@
 
 use darkfi::Result;
 use darkfi_contract_test_harness::{init_logger, Holder, TestHarness, TxAction};
-use darkfi_sdk::{blockchain::pow_expected_reward, crypto::DARK_TOKEN_ID};
+use darkfi_sdk::{blockchain::expected_reward, crypto::DARK_TOKEN_ID};
 use log::info;
 
 #[test]
@@ -68,7 +68,7 @@ fn pow_reward() -> Result<()> {
         current_slot += 1;
         th.generate_slot(current_slot).await?;
 
-        let alice_reward = pow_expected_reward(current_slot);
+        let alice_reward = expected_reward(current_slot);
         info!(target: "money", "[Malicious] ================================");
         info!(target: "money", "[Malicious] Building erroneous PoW reward tx");
         info!(target: "money", "[Malicious] ================================");

+ 20 - 17
src/sdk/src/blockchain.rs

@@ -121,23 +121,26 @@ impl Default for Slot {
 // TODO: This values are experimental, should be replaced with the proper ones once defined
 pub const POW_CUTOFF: u64 = 1000000;
 pub const POS_START: u64 = 1000001;
-/// Auxiliary function to calculate provided block height(slot) expected PoW reward value.
-/// Genesis block(0) always returns reward value 0.
-/// A cut-off is used, signalling PoS start, after which reward value 0 is returned.
-pub fn pow_expected_reward(block_height: u64) -> u64 {
-    match block_height {
+/// Auxiliary function to calculate provided slot(block height) expected reward value.
+/// Genesis slot(0) always returns reward value 0.
+/// We use PoW bootstrap, configured to reduce rewards at fixed slot numbers, until a cutoff.
+/// Once cut-off is reached, signalling PoS start, reward value is based on DARK token-economics.
+pub fn expected_reward(slot: u64) -> u64 {
+    // Configured block rewards (1 DRK == 1 * 10^8)
+    match slot {
         0 => 0,
-        1..=1000 => 20,
-        1001..=2000 => 18,
-        2001..=3000 => 16,
-        3001..=4000 => 14,
-        4001..=5000 => 12,
-        5001..=6000 => 10,
-        6001..=7000 => 8,
-        7001..=8000 => 6,
-        8001..=9000 => 4,
-        9001..=10000 => 2,
-        10001..=POW_CUTOFF => 1,
-        POS_START.. => 0,
+        1..=1000 => 2_000_000_000,         // 20 DRK
+        1001..=2000 => 1_800_000_000,      // 18 DRK
+        2001..=3000 => 1_600_000_000,      // 16 DRK
+        3001..=4000 => 1_400_000_000,      // 14 DRK
+        4001..=5000 => 1_200_000_000,      // 12 DRK
+        5001..=6000 => 1_000_000_000,      // 10 DRK
+        6001..=7000 => 800_000_000,        // 8 DRK
+        7001..=8000 => 600_000_000,        // 6 DRK
+        8001..=9000 => 400_000_000,        // 4 DRK
+        9001..=10000 => 200_000_000,       // 2 DRK
+        10001..=POW_CUTOFF => 100_000_000, // 1 DRK
+        // TODO (res) implement reward mechanism with accord to DRK, DARK token-economics.
+        POS_START.. => 100_000_000, // 1 DRK
     }
 }

+ 4 - 18
src/validator/consensus/mod.rs → src/validator/consensus.rs

@@ -17,7 +17,7 @@
  */
 
 use darkfi_sdk::{
-    blockchain::{PidOutput, PreviousSlot, Slot},
+    blockchain::{expected_reward, PidOutput, PreviousSlot, Slot},
     crypto::{schnorr::SchnorrSecret, MerkleNode, MerkleTree, SecretKey},
     pasta::{group::ff::PrimeField, pallas},
 };
@@ -31,16 +31,10 @@ use crate::{
     },
     tx::Transaction,
     util::time::{TimeKeeper, Timestamp},
-    validator::{consensus::pid::slot_pid_output, verify_block, verify_transactions},
+    validator::{pid::slot_pid_output, verify_block, verify_transactions},
     Error, Result,
 };
 
-/// DarkFi consensus PID controller
-pub mod pid;
-
-/// Base 10 big float implementation for high precision arithmetics
-pub mod float_10;
-
 /// Consensus configuration
 const TXS_CAP: usize = 50;
 
@@ -247,7 +241,7 @@ impl Consensus {
         let previous = fork.overlay.lock().unwrap().last_block()?;
 
         // Retrieve expected reward
-        let expected_reward = next_block_reward();
+        let expected_reward = expected_reward(time_keeper.verifying_slot);
 
         // Verify proposal block (6)
         if verify_block(
@@ -343,7 +337,7 @@ impl Consensus {
             time_keeper.verifying_slot = block.header.slot;
 
             // Retrieve expected reward
-            let expected_reward = next_block_reward();
+            let expected_reward = expected_reward(time_keeper.verifying_slot);
 
             // Verify block
             if verify_block(
@@ -595,11 +589,3 @@ impl Fork {
         Ok(Self { overlay, proposals, slots, mempool })
     }
 }
-
-/// Block producer reward.
-/// TODO (res) implement reward mechanism with accord to DRK, DARK token-economics.
-pub fn next_block_reward() -> u64 {
-    // Configured block reward (1 DRK == 1 * 10^8)
-    let reward: u64 = 100_000_000;
-    reward
-}

+ 0 - 0
src/validator/consensus/float_10.rs → src/validator/float_10.rs


+ 13 - 4
src/validator/mod.rs

@@ -18,7 +18,10 @@
 
 use std::sync::Arc;
 
-use darkfi_sdk::{blockchain::Slot, crypto::PublicKey};
+use darkfi_sdk::{
+    blockchain::{expected_reward, Slot},
+    crypto::PublicKey,
+};
 use darkfi_serial::serialize;
 use log::{debug, error, info, warn};
 use smol::lock::RwLock;
@@ -33,7 +36,10 @@ use crate::{
 
 /// DarkFi consensus module
 pub mod consensus;
-use consensus::{next_block_reward, Consensus};
+use consensus::Consensus;
+
+/// DarkFi consensus PID controller
+pub mod pid;
 
 /// Verification functions
 pub mod verification;
@@ -43,6 +49,9 @@ use verification::{verify_block, verify_genesis_block, verify_transactions};
 pub mod utils;
 use utils::deploy_native_contracts;
 
+/// Base 10 big float implementation for high precision arithmetics
+pub mod float_10;
+
 /// Configuration for initializing [`Validator`]
 #[derive(Clone)]
 pub struct ValidatorConfig {
@@ -291,7 +300,7 @@ impl Validator {
             time_keeper.verifying_slot = block.header.slot;
 
             // Retrieve expected reward
-            let expected_reward = next_block_reward();
+            let expected_reward = expected_reward(time_keeper.verifying_slot);
 
             // Verify block
             if verify_block(
@@ -419,7 +428,7 @@ impl Validator {
             time_keeper.verifying_slot = block.header.slot;
 
             // Retrieve expected reward
-            let expected_reward = next_block_reward();
+            let expected_reward = expected_reward(time_keeper.verifying_slot);
 
             // Verify block
             if verify_block(

+ 0 - 0
src/validator/consensus/pid.rs → src/validator/pid.rs


+ 17 - 1
src/validator/verification.rs

@@ -19,6 +19,7 @@
 use std::{collections::HashMap, io::Cursor};
 
 use darkfi_sdk::{
+    blockchain::expected_reward,
     crypto::{PublicKey, CONSENSUS_CONTRACT_ID},
     pasta::pallas,
 };
@@ -26,7 +27,7 @@ use darkfi_serial::{Decodable, Encodable, WriteExt};
 use log::{debug, error, warn};
 
 use crate::{
-    blockchain::{BlockInfo, BlockchainOverlayPtr},
+    blockchain::{BlockInfo, Blockchain, BlockchainOverlayPtr},
     error::TxVerifyFailed,
     runtime::vm_runtime::Runtime,
     tx::Transaction,
@@ -328,3 +329,18 @@ pub async fn verify_transactions(
 
     Ok(erroneous_txs)
 }
+
+/// A blockchain is considered valid, when every block is valid,
+/// based on validate_block checks.
+/// Be careful as this will try to load everything in memory.
+pub fn validate_blockchain(blockchain: &Blockchain) -> Result<()> {
+    // We use block order store here so we have all blocks in order
+    let blocks = blockchain.order.get_all()?;
+    for (index, block) in blocks[1..].iter().enumerate() {
+        let full_blocks = blockchain.get_blocks_by_hash(&[blocks[index].1, block.1])?;
+        let expected_reward = expected_reward(full_blocks[1].header.slot);
+        full_blocks[1].validate(&full_blocks[0], expected_reward)?;
+    }
+
+    Ok(())
+}

+ 6 - 8
tests/blockchain.rs

@@ -18,11 +18,11 @@
 
 use darkfi::{
     blockchain::{BlockInfo, Blockchain, BlockchainOverlay, Header},
-    validator::consensus::{next_block_reward, pid::slot_pid_output},
+    validator::{pid::slot_pid_output, verification::validate_blockchain},
     Error, Result,
 };
 use darkfi_sdk::{
-    blockchain::{PidOutput, PreviousSlot, Slot},
+    blockchain::{expected_reward, PidOutput, PreviousSlot, Slot},
     pasta::{group::ff::Field, pallas},
 };
 
@@ -44,10 +44,8 @@ impl Harness {
     }
 
     fn validate_chains(&self) -> Result<()> {
-        /* FIXME: see blockchain fixme
-        self.alice.validate()?;
-        self.bob.validate()?;
-        */
+        validate_blockchain(&self.alice)?;
+        validate_blockchain(&self.bob)?;
 
         assert_eq!(self.alice.len(), self.bob.len());
 
@@ -70,7 +68,7 @@ impl Harness {
         let (f, error, sigma1, sigma2) = slot_pid_output(previous_slot, producers);
         let pid = PidOutput::new(f, error, sigma1, sigma2);
         let total_tokens = previous_slot.total_tokens + previous_slot.reward;
-        let reward = next_block_reward();
+        let reward = expected_reward(id);
         let slot = Slot::new(id, previous_slot_info, pid, pallas::Base::ZERO, total_tokens, reward);
 
         // We increment timestamp so we don't have to use sleep
@@ -110,7 +108,7 @@ impl Harness {
             // This will be true for every insert, apart from genesis
             if let Some(p) = previous {
                 // Retrieve expected reward
-                let expected_reward = next_block_reward();
+                let expected_reward = expected_reward(block.header.slot);
 
                 // Validate block
                 block.validate(&p, expected_reward)?;