mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-09 22:57:59 -05:00
validator/pow: introduced fixed difficulty for testing purposes
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -1934,6 +1934,7 @@ dependencies = [
|
||||
"darkfi-serial",
|
||||
"easy-parallel",
|
||||
"log",
|
||||
"num-bigint",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"signal-hook",
|
||||
|
||||
@@ -21,6 +21,7 @@ darkfi-serial = {path = "../../src/serial"}
|
||||
blake3 = "1.5.0"
|
||||
bs58 = "0.5.0"
|
||||
log = "0.4.20"
|
||||
num-bigint = "0.4.4"
|
||||
sled = "0.34.7"
|
||||
rand = "0.8.5"
|
||||
|
||||
|
||||
@@ -26,6 +26,9 @@ pow_threads = 4
|
||||
# PoW block production target, in seconds
|
||||
pow_target = 10
|
||||
|
||||
# Optional fixed PoW difficulty, used for testing
|
||||
pow_fixed_difficulty = 1
|
||||
|
||||
# Epoch duration, denominated by number of blocks/slots
|
||||
epoch_length = 10
|
||||
|
||||
|
||||
@@ -133,6 +133,10 @@ pub struct BlockchainNetwork {
|
||||
/// PoW block production target, in seconds
|
||||
pub pow_target: usize,
|
||||
|
||||
#[structopt(long)]
|
||||
/// Optional fixed PoW difficulty, used for testing
|
||||
pub pow_fixed_difficulty: Option<usize>,
|
||||
|
||||
#[structopt(long, default_value = "10")]
|
||||
/// Epoch duration, denominated by number of blocks/slots
|
||||
pub epoch_length: u64,
|
||||
@@ -236,11 +240,18 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
|
||||
blockchain_config.slot_time,
|
||||
0,
|
||||
);
|
||||
let pow_fixed_difficulty = if let Some(diff) = blockchain_config.pow_fixed_difficulty {
|
||||
info!(target: "darkfid", "Node is configured to run with fixed PoW difficulty: {}", diff);
|
||||
Some(diff.into())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let config = ValidatorConfig::new(
|
||||
time_keeper,
|
||||
blockchain_config.threshold,
|
||||
blockchain_config.pow_threads,
|
||||
blockchain_config.pow_target,
|
||||
pow_fixed_difficulty,
|
||||
genesis_block,
|
||||
genesis_txs_total,
|
||||
vec![],
|
||||
|
||||
@@ -30,7 +30,7 @@ fn forks() -> Result<()> {
|
||||
|
||||
// Create a temporary blockchain and a PoW module
|
||||
let blockchain = Blockchain::new(&sled::Config::new().temporary(true).open()?)?;
|
||||
let module = PoWModule::new(blockchain.clone(), 2, 90)?;
|
||||
let module = PoWModule::new(blockchain.clone(), 2, 90, None)?;
|
||||
|
||||
// Create a fork
|
||||
let fork = Fork::new(&blockchain, module)?;
|
||||
|
||||
@@ -32,6 +32,7 @@ use darkfi_sdk::{
|
||||
blockchain::{expected_reward, PidOutput, PreviousSlot, Slot, POS_START},
|
||||
pasta::{group::ff::Field, pallas},
|
||||
};
|
||||
use num_bigint::BigUint;
|
||||
use url::Url;
|
||||
|
||||
use crate::{
|
||||
@@ -44,6 +45,7 @@ use crate::{
|
||||
pub struct HarnessConfig {
|
||||
pub pow_threads: usize,
|
||||
pub pow_target: usize,
|
||||
pub pow_fixed_difficulty: Option<BigUint>,
|
||||
pub testing_node: bool,
|
||||
pub alice_initial: u64,
|
||||
pub bob_initial: u64,
|
||||
@@ -86,6 +88,7 @@ impl Harness {
|
||||
3,
|
||||
config.pow_threads,
|
||||
config.pow_target,
|
||||
config.pow_fixed_difficulty.clone(),
|
||||
genesis_block,
|
||||
genesis_txs_total,
|
||||
vec![],
|
||||
@@ -145,6 +148,7 @@ impl Harness {
|
||||
vec![],
|
||||
self.config.pow_threads,
|
||||
self.config.pow_target,
|
||||
self.config.pow_fixed_difficulty.clone(),
|
||||
)
|
||||
.await?;
|
||||
bob.validate_blockchain(
|
||||
@@ -152,6 +156,7 @@ impl Harness {
|
||||
vec![],
|
||||
self.config.pow_threads,
|
||||
self.config.pow_target,
|
||||
self.config.pow_fixed_difficulty.clone(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
|
||||
@@ -34,9 +34,11 @@ async fn sync_pos_blocks_real(ex: Arc<Executor<'static>>) -> Result<()> {
|
||||
// Initialize harness in testing mode
|
||||
let pow_threads = 2;
|
||||
let pow_target = 90;
|
||||
let pow_fixed_difficulty = None;
|
||||
let config = HarnessConfig {
|
||||
pow_threads,
|
||||
pow_target,
|
||||
pow_fixed_difficulty: pow_fixed_difficulty.clone(),
|
||||
testing_node: true,
|
||||
alice_initial: 1000,
|
||||
bob_initial: 500,
|
||||
@@ -73,7 +75,15 @@ async fn sync_pos_blocks_real(ex: Arc<Executor<'static>>) -> Result<()> {
|
||||
let genesis_txs_total = th.config.alice_initial + th.config.bob_initial;
|
||||
let alice = &th.alice.validator.read().await;
|
||||
let charlie = &charlie.validator.read().await;
|
||||
charlie.validate_blockchain(genesis_txs_total, vec![], pow_threads, pow_target).await?;
|
||||
charlie
|
||||
.validate_blockchain(
|
||||
genesis_txs_total,
|
||||
vec![],
|
||||
pow_threads,
|
||||
pow_target,
|
||||
pow_fixed_difficulty,
|
||||
)
|
||||
.await?;
|
||||
assert_eq!(alice.blockchain.len(), charlie.blockchain.len());
|
||||
assert_eq!(alice.blockchain.slots.len(), charlie.blockchain.slots.len());
|
||||
|
||||
|
||||
@@ -76,8 +76,8 @@ pub fn init_logger() {
|
||||
// We check this error so we can execute same file tests in parallel,
|
||||
// otherwise second one fails to init logger here.
|
||||
if simplelog::TermLogger::init(
|
||||
//simplelog::LevelFilter::Info,
|
||||
simplelog::LevelFilter::Debug,
|
||||
simplelog::LevelFilter::Info,
|
||||
//simplelog::LevelFilter::Debug,
|
||||
//simplelog::LevelFilter::Trace,
|
||||
cfg.build(),
|
||||
simplelog::TerminalMode::Mixed,
|
||||
@@ -160,6 +160,7 @@ impl Wallet {
|
||||
3,
|
||||
1,
|
||||
90,
|
||||
None,
|
||||
genesis_block.clone(),
|
||||
0,
|
||||
faucet_pubkeys.to_vec(),
|
||||
|
||||
@@ -48,8 +48,8 @@ use darkfi_serial::{deserialize, serialize};
|
||||
use log::debug;
|
||||
|
||||
/// Update this if any circuits are changed
|
||||
const VKS_HASH: &str = "f6b536bd601d6f0b709800da4cb46f026e3292be05eea1b407fab3146738c80e";
|
||||
const PKS_HASH: &str = "d0297ba167bae9d74a05f0a57b3e3985591d092d096939f71d3fea9ab11bc96f";
|
||||
const VKS_HASH: &str = "ac136b465c4df655d9e77f59884a105f5ade175681ba9cf1cc5abd69ad0f17f8";
|
||||
const PKS_HASH: &str = "0e6eeccea48a982ff40fc66b94af9c60efd69e827985e3d5e93c49d679a4f6d8";
|
||||
|
||||
fn pks_path(typ: &str) -> Result<PathBuf> {
|
||||
let output = Command::new("git").arg("rev-parse").arg("--show-toplevel").output()?.stdout;
|
||||
|
||||
@@ -23,6 +23,7 @@ use darkfi_sdk::{
|
||||
};
|
||||
use darkfi_serial::{async_trait, serialize, SerialDecodable, SerialEncodable};
|
||||
use log::{debug, error, info};
|
||||
use num_bigint::BigUint;
|
||||
|
||||
use crate::{
|
||||
blockchain::{BlockInfo, Blockchain, BlockchainOverlay, BlockchainOverlayPtr, Header},
|
||||
@@ -67,9 +68,11 @@ impl Consensus {
|
||||
finalization_threshold: usize,
|
||||
pow_threads: usize,
|
||||
pow_target: usize,
|
||||
pow_fixed_difficulty: Option<BigUint>,
|
||||
testing_mode: bool,
|
||||
) -> Result<Self> {
|
||||
let module = PoWModule::new(blockchain.clone(), pow_threads, pow_target)?;
|
||||
let module =
|
||||
PoWModule::new(blockchain.clone(), pow_threads, pow_target, pow_fixed_difficulty)?;
|
||||
Ok(Self {
|
||||
blockchain,
|
||||
time_keeper,
|
||||
|
||||
@@ -24,6 +24,7 @@ use darkfi_sdk::{
|
||||
};
|
||||
use darkfi_serial::serialize;
|
||||
use log::{debug, error, info, warn};
|
||||
use num_bigint::BigUint;
|
||||
use smol::lock::RwLock;
|
||||
|
||||
use crate::{
|
||||
@@ -76,6 +77,8 @@ pub struct ValidatorConfig {
|
||||
pub pow_threads: usize,
|
||||
/// Currently configured PoW target
|
||||
pub pow_target: usize,
|
||||
/// Optional fixed difficulty, for testing purposes
|
||||
pub pow_fixed_difficulty: Option<BigUint>,
|
||||
/// Genesis block
|
||||
pub genesis_block: BlockInfo,
|
||||
/// Total amount of minted tokens in genesis block
|
||||
@@ -93,6 +96,7 @@ impl ValidatorConfig {
|
||||
finalization_threshold: usize,
|
||||
pow_threads: usize,
|
||||
pow_target: usize,
|
||||
pow_fixed_difficulty: Option<BigUint>,
|
||||
genesis_block: BlockInfo,
|
||||
genesis_txs_total: u64,
|
||||
faucet_pubkeys: Vec<PublicKey>,
|
||||
@@ -103,6 +107,7 @@ impl ValidatorConfig {
|
||||
finalization_threshold,
|
||||
pow_threads,
|
||||
pow_target,
|
||||
pow_fixed_difficulty,
|
||||
genesis_block,
|
||||
genesis_txs_total,
|
||||
faucet_pubkeys,
|
||||
@@ -162,6 +167,7 @@ impl Validator {
|
||||
config.finalization_threshold,
|
||||
config.pow_threads,
|
||||
config.pow_target,
|
||||
config.pow_fixed_difficulty,
|
||||
testing_mode,
|
||||
)?;
|
||||
|
||||
@@ -540,6 +546,7 @@ impl Validator {
|
||||
faucet_pubkeys: Vec<PublicKey>,
|
||||
pow_threads: usize,
|
||||
pow_target: usize,
|
||||
pow_fixed_difficulty: Option<BigUint>,
|
||||
) -> Result<()> {
|
||||
let blocks = self.blockchain.get_all()?;
|
||||
|
||||
@@ -558,7 +565,8 @@ impl Validator {
|
||||
|
||||
// Create a time keeper and a PoW module to validate each block
|
||||
let mut time_keeper = self.consensus.time_keeper.clone();
|
||||
let mut module = PoWModule::new(blockchain.clone(), pow_threads, pow_target)?;
|
||||
let mut module =
|
||||
PoWModule::new(blockchain.clone(), pow_threads, pow_target, pow_fixed_difficulty)?;
|
||||
|
||||
// Deploy native wasm contracts
|
||||
deploy_native_contracts(&overlay, &time_keeper, &faucet_pubkeys)?;
|
||||
|
||||
@@ -81,6 +81,8 @@ pub struct PoWModule {
|
||||
pub threads: usize,
|
||||
/// Target block time, in seconds
|
||||
pub target: usize,
|
||||
/// Optional fixed difficulty
|
||||
pub fixed_difficulty: Option<BigUint>,
|
||||
/// Latest block timestamps ringbuffer
|
||||
pub timestamps: RingBuffer<u64, BUF_SIZE>,
|
||||
/// Latest block cummulative difficulties ringbuffer
|
||||
@@ -93,7 +95,12 @@ pub struct PoWModule {
|
||||
}
|
||||
|
||||
impl PoWModule {
|
||||
pub fn new(blockchain: Blockchain, threads: usize, target: usize) -> Result<Self> {
|
||||
pub fn new(
|
||||
blockchain: Blockchain,
|
||||
threads: usize,
|
||||
target: usize,
|
||||
fixed_difficulty: Option<BigUint>,
|
||||
) -> Result<Self> {
|
||||
// Retrieving last BUF_ZISE difficulties from blockchain to build the buffers
|
||||
let mut timestamps = RingBuffer::<u64, BUF_SIZE>::new();
|
||||
let mut difficulties = RingBuffer::<BigUint, BUF_SIZE>::new();
|
||||
@@ -105,11 +112,20 @@ impl PoWModule {
|
||||
cummulative_difficulty = difficulty.cummulative_difficulty;
|
||||
}
|
||||
|
||||
Ok(Self { threads, target, timestamps, difficulties, cummulative_difficulty })
|
||||
Ok(Self {
|
||||
threads,
|
||||
target,
|
||||
fixed_difficulty,
|
||||
timestamps,
|
||||
difficulties,
|
||||
cummulative_difficulty,
|
||||
})
|
||||
}
|
||||
|
||||
/// Compute the next mining difficulty, based on current ring buffers.
|
||||
/// If ring buffers contain 2 or less items, difficulty 1 is returned.
|
||||
/// If a fixed difficulty has been set, this function will always
|
||||
/// return that after first 2 difficulties.
|
||||
pub fn next_difficulty(&self) -> Result<BigUint> {
|
||||
// Retrieve first DIFFICULTY_WINDOW timestamps from the ring buffer
|
||||
let mut timestamps: Vec<u64> =
|
||||
@@ -121,6 +137,11 @@ impl PoWModule {
|
||||
return Ok(BigUint::one())
|
||||
}
|
||||
|
||||
// If a fixed difficulty has been set, return that
|
||||
if let Some(diff) = &self.fixed_difficulty {
|
||||
return Ok(diff.clone())
|
||||
}
|
||||
|
||||
// Sort the timestamps vector
|
||||
timestamps.sort_unstable();
|
||||
|
||||
@@ -384,7 +405,7 @@ mod tests {
|
||||
let sled_db = sled::Config::new().temporary(true).open()?;
|
||||
let blockchain = Blockchain::new(&sled_db)?;
|
||||
let mut module =
|
||||
PoWModule::new(blockchain, DEFAULT_TEST_THREADS, DEFAULT_TEST_DIFFICULTY_TARGET)?;
|
||||
PoWModule::new(blockchain, DEFAULT_TEST_THREADS, DEFAULT_TEST_DIFFICULTY_TARGET, None)?;
|
||||
|
||||
let output = Command::new("./script/research/pow/gen_wide_data.py").output().unwrap();
|
||||
let reader = Cursor::new(output.stdout);
|
||||
@@ -418,7 +439,7 @@ mod tests {
|
||||
let sled_db = sled::Config::new().temporary(true).open()?;
|
||||
let blockchain = Blockchain::new(&sled_db)?;
|
||||
let module =
|
||||
PoWModule::new(blockchain, DEFAULT_TEST_THREADS, DEFAULT_TEST_DIFFICULTY_TARGET)?;
|
||||
PoWModule::new(blockchain, DEFAULT_TEST_THREADS, DEFAULT_TEST_DIFFICULTY_TARGET, None)?;
|
||||
let (_, recvr) = smol::channel::bounded(1);
|
||||
let genesis_block = BlockInfo::default();
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ use darkfi_sdk::{
|
||||
blockchain::{block_version, expected_reward, Slot},
|
||||
pasta::{group::ff::Field, pallas},
|
||||
};
|
||||
use num_bigint::BigUint;
|
||||
|
||||
use crate::{
|
||||
blockchain::{BlockInfo, Blockchain},
|
||||
@@ -337,9 +338,11 @@ pub fn validate_blockchain(
|
||||
blockchain: &Blockchain,
|
||||
pow_threads: usize,
|
||||
pow_target: usize,
|
||||
pow_fixed_difficulty: Option<BigUint>,
|
||||
) -> Result<()> {
|
||||
// Generate a PoW module
|
||||
let mut module = PoWModule::new(blockchain.clone(), pow_threads, pow_target)?;
|
||||
let mut module =
|
||||
PoWModule::new(blockchain.clone(), pow_threads, pow_target, pow_fixed_difficulty)?;
|
||||
// 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() {
|
||||
|
||||
@@ -41,7 +41,7 @@ struct Node {
|
||||
impl Node {
|
||||
fn new() -> Result<Self> {
|
||||
let blockchain = Blockchain::new(&sled::Config::new().temporary(true).open()?)?;
|
||||
let module = PoWModule::new(blockchain.clone(), POW_THREADS, POW_TARGET)?;
|
||||
let module = PoWModule::new(blockchain.clone(), POW_THREADS, POW_TARGET, None)?;
|
||||
Ok(Self { blockchain, module })
|
||||
}
|
||||
}
|
||||
@@ -64,8 +64,8 @@ impl Harness {
|
||||
}
|
||||
|
||||
fn validate_chains(&self) -> Result<()> {
|
||||
validate_blockchain(&self.alice.blockchain, POW_THREADS, POW_TARGET)?;
|
||||
validate_blockchain(&self.bob.blockchain, POW_THREADS, POW_TARGET)?;
|
||||
validate_blockchain(&self.alice.blockchain, POW_THREADS, POW_TARGET, None)?;
|
||||
validate_blockchain(&self.bob.blockchain, POW_THREADS, POW_TARGET, None)?;
|
||||
|
||||
assert_eq!(self.alice.blockchain.len(), self.bob.blockchain.len());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user