validator/pow: introduced fixed difficulty for testing purposes

This commit is contained in:
aggstam
2023-11-21 14:41:56 +02:00
parent 75353cb0b5
commit cb06356c46
14 changed files with 83 additions and 16 deletions

1
Cargo.lock generated
View File

@@ -1934,6 +1934,7 @@ dependencies = [
"darkfi-serial",
"easy-parallel",
"log",
"num-bigint",
"rand 0.8.5",
"serde",
"signal-hook",

View File

@@ -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"

View File

@@ -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

View File

@@ -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![],

View File

@@ -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)?;

View File

@@ -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?;

View File

@@ -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());

View File

@@ -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(),

View File

@@ -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;

View File

@@ -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,

View File

@@ -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)?;

View File

@@ -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();

View File

@@ -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() {

View File

@@ -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());