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

This commit is contained in:
aggstam
2023-07-12 22:03:29 +03:00
parent dce1fb929d
commit 361e53af0c
5 changed files with 55 additions and 29 deletions

View File

@@ -25,7 +25,7 @@ use darkfi::{
},
Result,
};
use darkfi_contract_test_harness::vks;
use darkfi_contract_test_harness::{vks, Holder, TestHarness};
use darkfi_sdk::{
blockchain::Slot,
pasta::{group::ff::Field, pallas},
@@ -33,52 +33,66 @@ use darkfi_sdk::{
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 genesis_txs_total: u64,
pub config: HarnessConfig,
pub alice: Darkfid,
pub bob: Darkfid,
}
impl Harness {
pub async fn new(testing_node: bool) -> Result<Self> {
// Generate default genesis block
let genesis_block = BlockInfo::default();
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 each node wallet here and add their corresponding
// genesis txs
// Generate default genesis block
let mut genesis_block = BlockInfo::default();
// 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)?;
genesis_block.slots[0].total_tokens = genesis_txs_total;
// Generate validators configuration
// NOTE: we are not using consensus constants here so we
// don't get circular dependencies.
let time_keeper = TimeKeeper::new(genesis_block.header.timestamp, 10, 90, 0);
let config = ValidatorConfig::new(
let val_config = ValidatorConfig::new(
time_keeper,
genesis_block,
genesis_txs_total,
vec![],
testing_node,
config.testing_node,
);
// Generate validators using pregenerated vks
let sled_db = sled::Config::new().temporary(true).open()?;
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 sled_db = sled::Config::new().temporary(true).open()?;
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;
Ok(Self { genesis_txs_total, alice, bob })
Ok(Self { config, alice, bob })
}
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 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());

View File

@@ -20,14 +20,15 @@ use darkfi::Result;
use darkfi_contract_test_harness::init_logger;
mod harness;
use harness::Harness;
use harness::{Harness, HarnessConfig};
#[async_std::test]
async fn add_blocks() -> Result<()> {
init_logger();
// 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
let previous = th.alice._validator.read().await.blockchain.last_block()?;

View File

@@ -120,7 +120,7 @@ impl DaoTestHarness {
let genesis_block = BlockInfo::default();
let time_keeper = TimeKeeper::new(genesis_block.header.timestamp, 10, 90, 0);
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 money_contract_id = *MONEY_CONTRACT_ID;

View File

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

View File

@@ -19,7 +19,6 @@
use std::{collections::HashMap, io::Cursor};
use darkfi_sdk::{
blockchain::Slot,
crypto::{PublicKey, CONSENSUS_CONTRACT_ID},
pasta::pallas,
};
@@ -64,11 +63,6 @@ pub async fn verify_genesis_block(
// Retrieve genesis slot
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
// of all genesis transactions public inputs (genesis distribution).
if genesis_slot.total_tokens != genesis_txs_total {
@@ -87,7 +81,12 @@ pub async fn verify_genesis_block(
}
// 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
overlay.lock().unwrap().add_block(block)?;
@@ -127,7 +126,12 @@ pub async fn verify_block(
}
// 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
overlay.lock().unwrap().add_block(block)?;