Browse Source

darkfid2/tests: use genesis stake and mint in genesis block

aggstam 3 years ago
parent
commit
361e53af0c

+ 27 - 13
bin/darkfid2/src/tests/harness.rs

@@ -25,7 +25,7 @@ use darkfi::{
     },
     },
     Result,
     Result,
 };
 };
-use darkfi_contract_test_harness::vks;
+use darkfi_contract_test_harness::{vks, Holder, TestHarness};
 use darkfi_sdk::{
 use darkfi_sdk::{
     blockchain::Slot,
     blockchain::Slot,
     pasta::{group::ff::Field, pallas},
     pasta::{group::ff::Field, pallas},
@@ -33,52 +33,66 @@ use darkfi_sdk::{
 
 
 use crate::{utils::genesis_txs_total, Darkfid};
 use crate::{utils::genesis_txs_total, Darkfid};
 
 
+pub struct HarnessConfig {
+    pub testing_node: bool,
+    pub alice_initial: u64,
+    pub bob_initial: u64,
+}
+
 pub struct Harness {
 pub struct Harness {
-    pub genesis_txs_total: u64,
+    pub config: HarnessConfig,
     pub alice: Darkfid,
     pub alice: Darkfid,
     pub bob: Darkfid,
     pub bob: Darkfid,
 }
 }
 
 
 impl Harness {
 impl Harness {
-    pub async fn new(testing_node: bool) -> Result<Self> {
+    pub async fn new(config: HarnessConfig) -> Result<Self> {
+        // Use test harness to generate genesis transactions
+        let mut th = TestHarness::new(&["money".to_string(), "consensus".to_string()]).await?;
+        let (genesis_stake_tx, _) = th.genesis_stake(Holder::Alice, config.alice_initial)?;
+        let (genesis_mint_tx, _) = th.genesis_mint(Holder::Bob, config.bob_initial)?;
+
         // Generate default genesis block
         // Generate default genesis block
-        let genesis_block = BlockInfo::default();
+        let mut genesis_block = BlockInfo::default();
 
 
-        // Generate each node wallet here and add their corresponding
-        // genesis txs
+        // Append genesis transactions and calculate their total
+        genesis_block.txs.push(genesis_stake_tx);
+        genesis_block.txs.push(genesis_mint_tx);
         let genesis_txs_total = genesis_txs_total(&genesis_block.txs)?;
         let genesis_txs_total = genesis_txs_total(&genesis_block.txs)?;
+        genesis_block.slots[0].total_tokens = genesis_txs_total;
 
 
         // Generate validators configuration
         // Generate validators configuration
         // NOTE: we are not using consensus constants here so we
         // NOTE: we are not using consensus constants here so we
         // don't get circular dependencies.
         // don't get circular dependencies.
         let time_keeper = TimeKeeper::new(genesis_block.header.timestamp, 10, 90, 0);
         let time_keeper = TimeKeeper::new(genesis_block.header.timestamp, 10, 90, 0);
-        let config = ValidatorConfig::new(
+        let val_config = ValidatorConfig::new(
             time_keeper,
             time_keeper,
             genesis_block,
             genesis_block,
             genesis_txs_total,
             genesis_txs_total,
             vec![],
             vec![],
-            testing_node,
+            config.testing_node,
         );
         );
 
 
         // Generate validators using pregenerated vks
         // Generate validators using pregenerated vks
         let sled_db = sled::Config::new().temporary(true).open()?;
         let sled_db = sled::Config::new().temporary(true).open()?;
         vks::inject(&sled_db)?;
         vks::inject(&sled_db)?;
-        let validator = Validator::new(&sled_db, config.clone()).await?;
+        let validator = Validator::new(&sled_db, val_config.clone()).await?;
         let alice = Darkfid::new(validator).await;
         let alice = Darkfid::new(validator).await;
         let sled_db = sled::Config::new().temporary(true).open()?;
         let sled_db = sled::Config::new().temporary(true).open()?;
         vks::inject(&sled_db)?;
         vks::inject(&sled_db)?;
-        let validator = Validator::new(&sled_db, config.clone()).await?;
+        let validator = Validator::new(&sled_db, val_config.clone()).await?;
         let bob = Darkfid::new(validator).await;
         let bob = Darkfid::new(validator).await;
 
 
-        Ok(Self { genesis_txs_total, alice, bob })
+        Ok(Self { config, alice, bob })
     }
     }
 
 
     pub async fn validate_chains(&self) -> Result<()> {
     pub async fn validate_chains(&self) -> Result<()> {
+        let genesis_txs_total = self.config.alice_initial + self.config.bob_initial;
         let alice = &self.alice._validator.read().await;
         let alice = &self.alice._validator.read().await;
         let bob = &self.bob._validator.read().await;
         let bob = &self.bob._validator.read().await;
 
 
-        alice.validate_blockchain(self.genesis_txs_total).await?;
-        bob.validate_blockchain(self.genesis_txs_total).await?;
+        alice.validate_blockchain(genesis_txs_total, vec![]).await?;
+        bob.validate_blockchain(genesis_txs_total, vec![]).await?;
 
 
         assert_eq!(alice.blockchain.len(), bob.blockchain.len());
         assert_eq!(alice.blockchain.len(), bob.blockchain.len());
 
 

+ 3 - 2
bin/darkfid2/src/tests/mod.rs

@@ -20,14 +20,15 @@ use darkfi::Result;
 use darkfi_contract_test_harness::init_logger;
 use darkfi_contract_test_harness::init_logger;
 
 
 mod harness;
 mod harness;
-use harness::Harness;
+use harness::{Harness, HarnessConfig};
 
 
 #[async_std::test]
 #[async_std::test]
 async fn add_blocks() -> Result<()> {
 async fn add_blocks() -> Result<()> {
     init_logger();
     init_logger();
 
 
     // Initialize harness in testing mode
     // Initialize harness in testing mode
-    let th = Harness::new(true).await?;
+    let config = HarnessConfig { testing_node: true, alice_initial: 1000, bob_initial: 500 };
+    let th = Harness::new(config).await?;
 
 
     // Retrieve genesis block
     // Retrieve genesis block
     let previous = th.alice._validator.read().await.blockchain.last_block()?;
     let previous = th.alice._validator.read().await.blockchain.last_block()?;

+ 1 - 1
src/contract/dao/tests/harness.rs

@@ -120,7 +120,7 @@ impl DaoTestHarness {
         let genesis_block = BlockInfo::default();
         let genesis_block = BlockInfo::default();
         let time_keeper = TimeKeeper::new(genesis_block.header.timestamp, 10, 90, 0);
         let time_keeper = TimeKeeper::new(genesis_block.header.timestamp, 10, 90, 0);
         let config =
         let config =
-            ValidatorConfig::new(time_keeper, genesis_block, faucet_pubkeys.to_vec(), false);
+            ValidatorConfig::new(time_keeper, genesis_block, 0, faucet_pubkeys.to_vec(), false);
         let alice_validator = Validator::new(&alice_sled_db, config).await?;
         let alice_validator = Validator::new(&alice_sled_db, config).await?;
 
 
         let money_contract_id = *MONEY_CONTRACT_ID;
         let money_contract_id = *MONEY_CONTRACT_ID;

+ 11 - 4
src/validator/mod.rs

@@ -91,6 +91,9 @@ impl Validator {
         // Create an overlay over whole blockchain so we can write stuff
         // Create an overlay over whole blockchain so we can write stuff
         let overlay = BlockchainOverlay::new(&blockchain)?;
         let overlay = BlockchainOverlay::new(&blockchain)?;
 
 
+        // Deploy native wasm contracts
+        deploy_native_contracts(&overlay, &config.time_keeper, &config.faucet_pubkeys)?;
+
         // Add genesis block if blockchain is empty
         // Add genesis block if blockchain is empty
         if blockchain.genesis().is_err() {
         if blockchain.genesis().is_err() {
             info!(target: "validator", "Appending genesis block");
             info!(target: "validator", "Appending genesis block");
@@ -103,9 +106,6 @@ impl Validator {
             .await?;
             .await?;
         };
         };
 
 
-        // Deploy native wasm contracts
-        deploy_native_contracts(&overlay, &config.time_keeper, &config.faucet_pubkeys)?;
-
         // Write the changes to the actual chain db
         // Write the changes to the actual chain db
         overlay.lock().unwrap().overlay.lock().unwrap().apply()?;
         overlay.lock().unwrap().overlay.lock().unwrap().apply()?;
 
 
@@ -231,7 +231,11 @@ impl Validator {
     /// Retrieve all existing blocks and try to apply them
     /// Retrieve all existing blocks and try to apply them
     /// to an in memory overlay to verify their correctness.
     /// to an in memory overlay to verify their correctness.
     /// Be careful as this will try to load everything in memory.
     /// Be careful as this will try to load everything in memory.
-    pub async fn validate_blockchain(&self, genesis_txs_total: u64) -> Result<()> {
+    pub async fn validate_blockchain(
+        &self,
+        genesis_txs_total: u64,
+        faucet_pubkeys: Vec<PublicKey>,
+    ) -> Result<()> {
         let blocks = self.blockchain.get_all()?;
         let blocks = self.blockchain.get_all()?;
 
 
         // An empty blockchain is considered valid
         // An empty blockchain is considered valid
@@ -250,6 +254,9 @@ impl Validator {
         // Create a time keeper to validate each block
         // Create a time keeper to validate each block
         let mut time_keeper = self.consensus.time_keeper.clone();
         let mut time_keeper = self.consensus.time_keeper.clone();
 
 
+        // Deploy native wasm contracts
+        deploy_native_contracts(&overlay, &time_keeper, &faucet_pubkeys)?;
+
         // Validate genesis block
         // Validate genesis block
         verify_genesis_block(&overlay, &time_keeper, previous, genesis_txs_total).await?;
         verify_genesis_block(&overlay, &time_keeper, previous, genesis_txs_total).await?;
 
 

+ 12 - 8
src/validator/verification.rs

@@ -19,7 +19,6 @@
 use std::{collections::HashMap, io::Cursor};
 use std::{collections::HashMap, io::Cursor};
 
 
 use darkfi_sdk::{
 use darkfi_sdk::{
-    blockchain::Slot,
     crypto::{PublicKey, CONSENSUS_CONTRACT_ID},
     crypto::{PublicKey, CONSENSUS_CONTRACT_ID},
     pasta::pallas,
     pasta::pallas,
 };
 };
@@ -64,11 +63,6 @@ pub async fn verify_genesis_block(
     // Retrieve genesis slot
     // Retrieve genesis slot
     let genesis_slot = block.slots.last().unwrap();
     let genesis_slot = block.slots.last().unwrap();
 
 
-    // Genesis slot must be the default one
-    if genesis_slot != &Slot::default() {
-        return Err(Error::SlotIsInvalid(genesis_slot.id))
-    }
-
     // Genesis block slot total token must correspond to the total
     // Genesis block slot total token must correspond to the total
     // of all genesis transactions public inputs (genesis distribution).
     // of all genesis transactions public inputs (genesis distribution).
     if genesis_slot.total_tokens != genesis_txs_total {
     if genesis_slot.total_tokens != genesis_txs_total {
@@ -87,7 +81,12 @@ pub async fn verify_genesis_block(
     }
     }
 
 
     // Verify transactions
     // Verify transactions
-    verify_transactions(overlay, time_keeper, &block.txs).await?;
+    let erroneous_txs = verify_transactions(overlay, time_keeper, &block.txs).await?;
+    if !erroneous_txs.is_empty() {
+        warn!(target: "validator", "Erroneous transactions found in set");
+        overlay.lock().unwrap().overlay.lock().unwrap().purge_new_trees()?;
+        return Err(TxVerifyFailed::ErroneousTxs(erroneous_txs).into())
+    }
 
 
     // Insert block
     // Insert block
     overlay.lock().unwrap().add_block(block)?;
     overlay.lock().unwrap().add_block(block)?;
@@ -127,7 +126,12 @@ pub async fn verify_block(
     }
     }
 
 
     // Verify transactions
     // Verify transactions
-    verify_transactions(overlay, time_keeper, &block.txs).await?;
+    let erroneous_txs = verify_transactions(overlay, time_keeper, &block.txs).await?;
+    if !erroneous_txs.is_empty() {
+        warn!(target: "validator", "Erroneous transactions found in set");
+        overlay.lock().unwrap().overlay.lock().unwrap().purge_new_trees()?;
+        return Err(TxVerifyFailed::ErroneousTxs(erroneous_txs).into())
+    }
 
 
     // Insert block
     // Insert block
     overlay.lock().unwrap().add_block(block)?;
     overlay.lock().unwrap().add_block(block)?;