mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-08 22:28:12 -05:00
validator: validate blocks based on their version
This commit is contained in:
@@ -20,47 +20,63 @@ use darkfi::{
|
||||
blockchain::{BlockInfo, Blockchain, BlockchainOverlay, Header},
|
||||
validator::{
|
||||
pid::slot_pid_output,
|
||||
pow::PoWModule,
|
||||
validation::{validate_block, validate_blockchain},
|
||||
},
|
||||
Error, Result,
|
||||
};
|
||||
use darkfi_sdk::{
|
||||
blockchain::{expected_reward, PidOutput, PreviousSlot, Slot},
|
||||
blockchain::{expected_reward, PidOutput, PreviousSlot, Slot, POS_START},
|
||||
pasta::{group::ff::Field, pallas},
|
||||
};
|
||||
|
||||
const POW_TARGET: Option<usize> = Some(10);
|
||||
|
||||
struct Node {
|
||||
blockchain: Blockchain,
|
||||
module: PoWModule,
|
||||
}
|
||||
|
||||
impl Node {
|
||||
fn new() -> Result<Self> {
|
||||
let blockchain = Blockchain::new(&sled::Config::new().temporary(true).open()?)?;
|
||||
let module = PoWModule::new(blockchain.clone(), None, POW_TARGET);
|
||||
Ok(Self { blockchain, module })
|
||||
}
|
||||
}
|
||||
|
||||
struct Harness {
|
||||
pub alice: Blockchain,
|
||||
pub bob: Blockchain,
|
||||
pub alice: Node,
|
||||
pub bob: Node,
|
||||
}
|
||||
|
||||
impl Harness {
|
||||
fn new() -> Result<Self> {
|
||||
let alice = Blockchain::new(&sled::Config::new().temporary(true).open()?)?;
|
||||
let bob = Blockchain::new(&sled::Config::new().temporary(true).open()?)?;
|
||||
let alice = Node::new()?;
|
||||
let bob = Node::new()?;
|
||||
Ok(Self { alice, bob })
|
||||
}
|
||||
|
||||
fn is_empty(&self) {
|
||||
assert!(self.alice.is_empty());
|
||||
assert!(self.bob.is_empty());
|
||||
assert!(self.alice.blockchain.is_empty());
|
||||
assert!(self.bob.blockchain.is_empty());
|
||||
}
|
||||
|
||||
fn validate_chains(&self) -> Result<()> {
|
||||
validate_blockchain(&self.alice)?;
|
||||
validate_blockchain(&self.bob)?;
|
||||
validate_blockchain(&self.alice.blockchain, POW_TARGET)?;
|
||||
validate_blockchain(&self.bob.blockchain, POW_TARGET)?;
|
||||
|
||||
assert_eq!(self.alice.len(), self.bob.len());
|
||||
assert_eq!(self.alice.blockchain.len(), self.bob.blockchain.len());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn generate_next_block(&self, previous: &BlockInfo) -> Result<BlockInfo> {
|
||||
fn generate_next_pos_block(&self, previous: &BlockInfo) -> Result<BlockInfo> {
|
||||
let previous_hash = previous.hash()?;
|
||||
|
||||
// Generate slot
|
||||
let previous_slot = previous.slots.last().unwrap();
|
||||
let id = previous_slot.id + 1;
|
||||
let id = if previous_slot.id < POS_START { POS_START } else { previous_slot.id + 1 };
|
||||
let producers = 1;
|
||||
let previous_slot_info = PreviousSlot::new(
|
||||
producers,
|
||||
@@ -94,17 +110,17 @@ impl Harness {
|
||||
Ok(block)
|
||||
}
|
||||
|
||||
fn add_blocks(&self, blocks: &[BlockInfo]) -> Result<()> {
|
||||
self.add_blocks_to_chain(&self.alice, blocks)?;
|
||||
self.add_blocks_to_chain(&self.bob, blocks)?;
|
||||
fn add_pos_blocks(&mut self, blocks: &[BlockInfo]) -> Result<()> {
|
||||
Self::add_pos_blocks_to_chain(&mut self.alice, blocks)?;
|
||||
Self::add_pos_blocks_to_chain(&mut self.bob, blocks)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// This is what the validator will execute when it receives a block.
|
||||
fn add_blocks_to_chain(&self, blockchain: &Blockchain, blocks: &[BlockInfo]) -> Result<()> {
|
||||
fn add_pos_blocks_to_chain(node: &mut Node, blocks: &[BlockInfo]) -> Result<()> {
|
||||
// Create overlay
|
||||
let blockchain_overlay = BlockchainOverlay::new(blockchain)?;
|
||||
let blockchain_overlay = BlockchainOverlay::new(&node.blockchain)?;
|
||||
let lock = blockchain_overlay.lock().unwrap();
|
||||
|
||||
// When we insert genesis, chain is empty
|
||||
@@ -123,7 +139,12 @@ impl Harness {
|
||||
let expected_reward = expected_reward(block.header.height);
|
||||
|
||||
// Validate block
|
||||
validate_block(block, &p, expected_reward)?;
|
||||
validate_block(block, &p, expected_reward, &node.module)?;
|
||||
|
||||
// Update PoW module
|
||||
if block.header.version == 1 {
|
||||
node.module.append(block.header.timestamp.0, &node.module.next_difficulty());
|
||||
}
|
||||
}
|
||||
|
||||
// Insert block
|
||||
@@ -141,30 +162,30 @@ impl Harness {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn blockchain_add_blocks() -> Result<()> {
|
||||
fn blockchain_add_pos_blocks() -> Result<()> {
|
||||
smol::block_on(async {
|
||||
// Initialize harness
|
||||
let th = Harness::new()?;
|
||||
let mut th = Harness::new()?;
|
||||
|
||||
// Check that nothing exists
|
||||
th.is_empty();
|
||||
|
||||
// We generate some blocks
|
||||
// We generate some pos blocks
|
||||
let mut blocks = vec![];
|
||||
|
||||
let genesis_block = BlockInfo::default();
|
||||
blocks.push(genesis_block.clone());
|
||||
|
||||
let block = th.generate_next_block(&genesis_block)?;
|
||||
let block = th.generate_next_pos_block(&genesis_block)?;
|
||||
blocks.push(block.clone());
|
||||
|
||||
let block = th.generate_next_block(&block)?;
|
||||
let block = th.generate_next_pos_block(&block)?;
|
||||
blocks.push(block.clone());
|
||||
|
||||
let block = th.generate_next_block(&block)?;
|
||||
let block = th.generate_next_pos_block(&block)?;
|
||||
blocks.push(block.clone());
|
||||
|
||||
th.add_blocks(&blocks)?;
|
||||
th.add_pos_blocks(&blocks)?;
|
||||
|
||||
// Validate chains
|
||||
th.validate_chains()?;
|
||||
|
||||
Reference in New Issue
Block a user