From 7ac561fe6798d322d61dd446b1ead78c16b93f6f Mon Sep 17 00:00:00 2001 From: skoupidi Date: Tue, 6 Feb 2024 16:44:28 +0200 Subject: [PATCH] util/time: TimeKeeper yeeted --- bin/darkfid/darkfid_config.toml | 27 --- bin/darkfid/src/main.rs | 27 +-- bin/darkfid/src/tests/harness.rs | 5 - bin/darkfid/src/tests/mod.rs | 1 - src/contract/test-harness/src/lib.rs | 8 +- src/util/time.rs | 257 +-------------------------- src/validator/mod.rs | 23 +-- src/validator/utils.rs | 4 +- 8 files changed, 7 insertions(+), 345 deletions(-) diff --git a/bin/darkfid/darkfid_config.toml b/bin/darkfid/darkfid_config.toml index 3d2ffd473..6f9e6d170 100644 --- a/bin/darkfid/darkfid_config.toml +++ b/bin/darkfid/darkfid_config.toml @@ -29,12 +29,6 @@ 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 - -# PoS slot duration, in seconds -slot_time = 10 - # Whitelisted faucet addresses faucet_pub = [] @@ -49,9 +43,6 @@ recipient = "5ZHfYpt4mpJcwBNxfEyxLzeFJUEeoePs5NQ5jVEgHrMf" # Skip syncing process and start node right away skip_sync = true -# Enable PoS testing mode for local testing -pos_testing_mode = true - ## Localnet sync P2P network settings [network_config."localnet".sync_net] # P2P accept addresses the instance listens on for inbound connections @@ -170,12 +161,6 @@ minerd_endpoint = "tcp://127.0.0.1:28467" # PoW block production target, in seconds pow_target = 90 -# Epoch duration, denominated by number of blocks/slots -epoch_length = 10 - -# PoS slot duration, in seconds -slot_time = 90 - # Whitelisted faucet addresses faucet_pub = ["3ce5xa3PjuQGFtTaF7AvMJp7fGxqeGRJx7zj3LCwNCkP"] @@ -188,9 +173,6 @@ consensus = false # Skip syncing process and start node right away skip_sync = false -# Enable PoS testing mode for local testing -pos_testing_mode = false - ## Testnet sync P2P network settings [network_config."testnet".sync_net] # P2P accept addresses the instance listens on for inbound connections @@ -329,12 +311,6 @@ minerd_endpoint = "tcp://127.0.0.1:28467" # PoW block production target, in seconds pow_target = 90 -# Epoch duration, denominated by number of blocks/slots -epoch_length = 10 - -# PoS slot duration, in seconds -slot_time = 90 - # Whitelisted faucet addresses faucet_pub = [] @@ -347,9 +323,6 @@ consensus = false # Skip syncing process and start node right away skip_sync = false -# Enable PoS testing mode for local testing -pos_testing_mode = false - ## Mainnet sync P2P network settings [network_config."mainnet".sync_net] # P2P accept addresses the instance listens on for inbound connections diff --git a/bin/darkfid/src/main.rs b/bin/darkfid/src/main.rs index 7bfa83f75..f532faff5 100644 --- a/bin/darkfid/src/main.rs +++ b/bin/darkfid/src/main.rs @@ -38,7 +38,7 @@ use darkfi::{ server::{listen_and_serve, RequestHandler}, }, system::{StoppableTask, StoppableTaskPtr}, - util::{path::expand_path, time::TimeKeeper}, + util::path::expand_path, validator::{utils::genesis_txs_total, Validator, ValidatorConfig, ValidatorPtr}, Error, Result, }; @@ -126,14 +126,6 @@ pub struct BlockchainNetwork { /// Optional fixed PoW difficulty, used for testing pub pow_fixed_difficulty: Option, - #[structopt(long, default_value = "10")] - /// Epoch duration, denominated by number of blocks/slots - pub epoch_length: u64, - - #[structopt(long, default_value = "10")] - /// PoS slot duration, in seconds - pub slot_time: u64, - #[structopt(long)] /// Whitelisted faucet public key (repeatable flag) pub faucet_pub: Vec, @@ -150,10 +142,6 @@ pub struct BlockchainNetwork { /// Skip syncing process and start node right away pub skip_sync: bool, - #[structopt(long)] - /// Enable PoS testing mode for local testing - pub pos_testing_mode: bool, - /// Syncing network settings #[structopt(flatten)] pub sync_net: SettingsOpt, @@ -219,10 +207,6 @@ async fn realmain(args: Args, ex: Arc>) -> Result<()> { } }; - if blockchain_config.pos_testing_mode { - info!(target: "darkfid", "Node is configured to run in PoS testing mode!"); - } - // Parse the genesis block let bytes = bs58::decode(&genesis_block.trim()).into_vec()?; let genesis_block: BlockInfo = deserialize_async(&bytes).await?; @@ -234,13 +218,6 @@ async fn realmain(args: Args, ex: Arc>) -> Result<()> { // Initialize validator configuration let genesis_txs_total = genesis_txs_total(&genesis_block.txs).await?; - let time_keeper = TimeKeeper::new( - genesis_block.header.timestamp, - blockchain_config.epoch_length, - 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()) @@ -249,14 +226,12 @@ async fn realmain(args: Args, ex: Arc>) -> Result<()> { }; let config = ValidatorConfig::new( - time_keeper, blockchain_config.threshold, blockchain_config.pow_target, pow_fixed_difficulty, genesis_block, genesis_txs_total, vec![], - blockchain_config.pos_testing_mode, false, // TODO: Make configurable ); diff --git a/bin/darkfid/src/tests/harness.rs b/bin/darkfid/src/tests/harness.rs index eb01290ed..5dd0aaa22 100644 --- a/bin/darkfid/src/tests/harness.rs +++ b/bin/darkfid/src/tests/harness.rs @@ -22,7 +22,6 @@ use darkfi::{ blockchain::BlockInfo, net::Settings, rpc::jsonrpc::JsonSubscriber, - util::time::TimeKeeper, validator::{utils::genesis_txs_total, Validator, ValidatorConfig}, Result, }; @@ -40,7 +39,6 @@ use crate::{ pub struct HarnessConfig { pub pow_target: usize, pub pow_fixed_difficulty: Option, - pub pos_testing_mode: bool, pub alice_initial: u64, pub bob_initial: u64, } @@ -73,16 +71,13 @@ impl Harness { // 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 validator_config = ValidatorConfig::new( - time_keeper, 3, config.pow_target, config.pow_fixed_difficulty.clone(), genesis_block, genesis_txs_total, vec![], - config.pos_testing_mode, verify_fees, ); diff --git a/bin/darkfid/src/tests/mod.rs b/bin/darkfid/src/tests/mod.rs index 7ce76edee..aa8548f5e 100644 --- a/bin/darkfid/src/tests/mod.rs +++ b/bin/darkfid/src/tests/mod.rs @@ -37,7 +37,6 @@ async fn sync_blocks_real(ex: Arc>) -> Result<()> { let config = HarnessConfig { pow_target, pow_fixed_difficulty: pow_fixed_difficulty.clone(), - pos_testing_mode: true, alice_initial: 1000, bob_initial: 500, }; diff --git a/src/contract/test-harness/src/lib.rs b/src/contract/test-harness/src/lib.rs index fee991983..b028df45b 100644 --- a/src/contract/test-harness/src/lib.rs +++ b/src/contract/test-harness/src/lib.rs @@ -21,10 +21,7 @@ use std::{collections::HashMap, io::Cursor, time::Instant}; use darkfi::{ blockchain::BlockInfo, tx::Transaction, - util::{ - pcg::Pcg32, - time::{TimeKeeper, Timestamp}, - }, + util::{pcg::Pcg32, time::Timestamp}, validator::{Validator, ValidatorConfig, ValidatorPtr}, zk::{empty_witnesses, ProvingKey, ZkCircuit}, zkas::ZkBinary, @@ -144,16 +141,13 @@ impl Wallet { // Generate validator // 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( - time_keeper, 3, 90, Some(BigUint::from(1_u8)), genesis_block.clone(), 0, faucet_pubkeys.to_vec(), - false, verify_fees, ); let validator = Validator::new(&sled_db, config).await?; diff --git a/src/util/time.rs b/src/util/time.rs index 6b9eda9c1..c0239a9d1 100644 --- a/src/util/time.rs +++ b/src/util/time.rs @@ -23,225 +23,10 @@ use darkfi_serial::async_trait; use darkfi_serial::{SerialDecodable, SerialEncodable}; -use crate::Result; - const SECS_IN_DAY: u64 = 86400; const MIN_IN_HOUR: u64 = 60; const SECS_IN_HOUR: u64 = 3600; -/// Helper structure providing time related calculations. -/// This struct is optimized for performance. The developer is responsible -/// for ensuring `slot_time` and `epoch_length` are greater than 0. -/// Values of 0 for these fields are incoherent and unsafe in asynchronous -/// context. -/// [`TimeKeeperSafe`] should be used if safety is more important than -/// performance. -#[derive(Clone)] -pub struct TimeKeeper { - /// Genesis block creation timestamp - pub genesis_ts: Timestamp, - /// Currently configured epoch duration - pub epoch_length: u64, - /// Currently configured slot duration - pub slot_time: u64, - /// Block height(slot) number runtime can access to verify against - pub verifying_block_height: u64, -} - -impl TimeKeeper { - pub fn new( - genesis_ts: Timestamp, - epoch_length: u64, - slot_time: u64, - verifying_block_height: u64, - ) -> Self { - Self { genesis_ts, epoch_length, slot_time, verifying_block_height } - } - - /// Generate a TimeKeeper for current slot - pub fn current(&self) -> Self { - Self { - genesis_ts: self.genesis_ts, - epoch_length: self.epoch_length, - slot_time: self.slot_time, - verifying_block_height: self.current_slot(), - } - } - - /// Calculates current epoch. - pub fn current_epoch(&self) -> u64 { - self.slot_epoch(self.current_slot()) - } - - /// Calculates the epoch of the provided slot. - /// Only slot 0 exists in epoch 0, everything - /// else is incremented by one. This practically - /// means that epoch 0 has 1 slot(the genesis slot), - /// epoch 1 has one less slot(the genesis slot) and - /// rest epoch have the normal amount of slots. - pub fn slot_epoch(&self, slot: u64) -> u64 { - if slot == 0 { - return 0 - } - (slot / self.epoch_length) + 1 - } - - /// Calculates current slot, based on elapsed time from the genesis block. - // TODO: Since we are doing a PoW->PoS transition, this should use the last - // PoW block timestamp as genesis, and add POW_CUTTOF slots on top. - pub fn current_slot(&self) -> u64 { - self.genesis_ts.elapsed() / self.slot_time - } - - /// Calculates the relative number of the provided slot. - pub fn relative_slot(&self, slot: u64) -> u64 { - slot % self.epoch_length - } - - /// Calculates the epoch of the verifying slot. - pub fn verifying_block_height_epoch(&self) -> u64 { - self.slot_epoch(self.verifying_block_height) - } - - /// Calculates seconds until next Nth slot starting time. - pub fn next_n_slot_start(&self, n: u64) -> u64 { - assert!(n > 0); - let next_slot_start = self.genesis_ts.0 + (self.current_slot() + n) * self.slot_time; - next_slot_start - Timestamp::current_time().0 - } - - /// Calculate slots until next Nth epoch. - /// Epoch duration is configured using the EPOCH_LENGTH value. - pub fn slots_to_next_n_epoch(&self, n: u64) -> u64 { - assert!(n > 0); - let slots_till_next_epoch = self.epoch_length - self.relative_slot(self.current_slot()); - ((n - 1) * self.epoch_length) + slots_till_next_epoch - } - - /// Calculates seconds until next Nth epoch starting time. - pub fn next_n_epoch_start(&self, n: u64) -> u64 { - self.next_n_slot_start(self.slots_to_next_n_epoch(n)) - } - - /// Calculates current blockchain timestamp. - /// Blockchain timestamp is the time elapsed since - /// Genesis timestamp, based on slot time ticking, - /// therefore representing the starting timestamp of - /// current slot. - pub fn blockchain_timestamp(&self) -> u64 { - self.genesis_ts.0 + self.current_slot() * self.slot_time - } - - /// Calculates current system timestamp. - pub fn system_timestamp(&self) -> Result { - Ok(UNIX_EPOCH.elapsed()?.as_secs()) - } -} -/// Wrapper struct that allows only coherent and safe values for a [`TimeKeeper`]. -#[derive(Clone)] -pub struct TimeKeeperSafe { - timekeeper: TimeKeeper, -} - -impl TimeKeeperSafe { - pub fn new( - genesis_ts: Timestamp, - epoch_length: u64, - slot_time: u64, - verifying_block_height: u64, - ) -> Self { - // TimeKeeper uses epoch_length and slot_time as divisors so they should - // never be zero in this struct. - if epoch_length == 0 { - panic!("Epoch length cannot be zero"); - } - if slot_time == 0 { - panic!("Slot time cannot be zero"); - } - Self { - timekeeper: TimeKeeper { genesis_ts, epoch_length, slot_time, verifying_block_height }, - } - } - /// Generate a TimeKeeperSafe for current slot - pub fn current(&self) -> TimeKeeperSafe { - TimeKeeperSafe::new( - self.timekeeper.genesis_ts, - self.timekeeper.epoch_length, - self.timekeeper.slot_time, - self.timekeeper.verifying_block_height, - ) - } - - /// Calculates current epoch. - pub fn current_epoch(&self) -> u64 { - self.timekeeper.current_epoch() - } - - /// Calculates the epoch of the provided slot. - /// Only slot 0 exists in epoch 0, everything - /// else is incremented by one. This practically - /// means that epoch 0 has 1 slot(the genesis slot), - /// epoch 1 has one less slot(the genesis slot) and - /// rest epoch have the normal amount of slots. - pub fn slot_epoch(&self, slot: u64) -> u64 { - if self.timekeeper.epoch_length == 0 { - panic!("Epoch length cannot be zero"); - } - self.timekeeper.slot_epoch(slot) - } - - /// Calculates current slot, based on elapsed time from the genesis block. - pub fn current_slot(&self) -> u64 { - if self.timekeeper.slot_time == 0 { - panic!("Slot time cannot be zero"); - } - self.timekeeper.current_slot() - } - - /// Calculates the relative number of the provided slot. - pub fn relative_slot(&self, slot: u64) -> u64 { - if self.timekeeper.epoch_length == 0 { - panic!("Epoch length cannot be zero"); - } - self.timekeeper.relative_slot(slot) - } - - /// Calculates the epoch of the verifying slot. - pub fn verifying_block_height_epoch(&self) -> u64 { - self.timekeeper.verifying_block_height_epoch() - } - - /// Calculates seconds until next Nth slot starting time. - pub fn next_n_slot_start(&self, n: u64) -> u64 { - self.timekeeper.next_n_slot_start(n) - } - - /// Calculate slots until next Nth epoch. - /// Epoch duration is configured using the EPOCH_LENGTH value. - pub fn slots_to_next_n_epoch(&self, n: u64) -> u64 { - self.timekeeper.slots_to_next_n_epoch(n) - } - - /// Calculates seconds until next Nth epoch starting time. - pub fn next_n_epoch_start(&self, n: u64) -> u64 { - self.timekeeper.next_n_epoch_start(n) - } - - /// Calculates current blockchain timestamp. - /// Blockchain timestamp is the time elapsed since - /// Genesis timestamp, based on slot time ticking, - /// therefore representing the starting timestamp of - /// current slot. - pub fn blockchain_timestamp(&self) -> u64 { - self.timekeeper.blockchain_timestamp() - } - - /// Calculates current system timestamp. - pub fn system_timestamp(&self) -> Result { - self.timekeeper.system_timestamp() - } -} - /// Wrapper struct to represent system timestamps. #[derive(Hash, Clone, Copy, Debug, SerialEncodable, SerialDecodable, PartialEq, PartialOrd, Eq)] pub struct Timestamp(pub u64); @@ -416,47 +201,7 @@ pub fn timestamp_to_date(timestamp: u64, format: DateFormat) -> String { #[cfg(test)] mod tests { - use super::{TimeKeeper, TimeKeeperSafe, Timestamp}; - - #[test] - #[should_panic] - fn panic_on_unsafe_epoch_length() { - // Ensure panic when epoch_length is 0. - TimeKeeperSafe::new(Timestamp::current_time(), 0, 1, 1); - } - - #[test] - #[should_panic] - fn panic_on_unsafe_slot_time() { - TimeKeeperSafe::new(Timestamp::current_time(), 1, 0, 1); - } - - #[test] - #[should_panic] - fn panic_on_unsafe_call_to_method_current_slot() { - // Test against manual initialization of unsafe TimeKeeper fields. - let tk_unsafe = - TimeKeeperSafe { timekeeper: TimeKeeper::new(Timestamp::current_time(), 0, 0, 0) }; - tk_unsafe.current_slot(); - } - - #[test] - #[should_panic] - fn panic_on_unsafe_call_to_method_relative_slot() { - // Test against manual initialization of unsafe TimeKeeper fields. - let tk_unsafe = - TimeKeeperSafe { timekeeper: TimeKeeper::new(Timestamp::current_time(), 0, 0, 0) }; - tk_unsafe.relative_slot(0); - } - - #[test] - #[should_panic] - fn panic_on_unsafe_call_to_method_slot_epoch() { - // Test against manual initialization of unsafe TimeKeeper fields. - let tk_unsafe = - TimeKeeperSafe { timekeeper: TimeKeeper::new(Timestamp::current_time(), 0, 0, 0) }; - tk_unsafe.slot_epoch(0); - } + use super::Timestamp; #[test] #[should_panic] diff --git a/src/validator/mod.rs b/src/validator/mod.rs index a823e24c7..9553a678c 100644 --- a/src/validator/mod.rs +++ b/src/validator/mod.rs @@ -31,7 +31,6 @@ use crate::{ }, error::TxVerifyFailed, tx::Transaction, - util::time::TimeKeeper, Error, Result, }; @@ -60,8 +59,6 @@ use utils::deploy_native_contracts; /// Configuration for initializing [`Validator`] #[derive(Clone)] pub struct ValidatorConfig { - /// Helper structure to calculate time related operations - pub time_keeper: TimeKeeper, /// Currently configured finalization security threshold pub finalization_threshold: usize, /// Currently configured PoW target @@ -74,34 +71,27 @@ pub struct ValidatorConfig { pub genesis_txs_total: u64, /// Whitelisted faucet pubkeys (testnet stuff) pub faucet_pubkeys: Vec, - /// Flag to enable PoS testing mode - pub pos_testing_mode: bool, /// Flag to enable tx fee verification pub verify_fees: bool, } impl ValidatorConfig { - #[allow(clippy::too_many_arguments)] pub fn new( - time_keeper: TimeKeeper, finalization_threshold: usize, pow_target: usize, pow_fixed_difficulty: Option, genesis_block: BlockInfo, genesis_txs_total: u64, faucet_pubkeys: Vec, - pos_testing_mode: bool, verify_fees: bool, ) -> Self { Self { - time_keeper, finalization_threshold, pow_target, pow_fixed_difficulty, genesis_block, genesis_txs_total, faucet_pubkeys, - pos_testing_mode, verify_fees, } } @@ -118,8 +108,6 @@ pub struct Validator { pub consensus: Consensus, /// Flag signalling node has finished initial sync pub synced: RwLock, - /// Flag to enable PoS testing mode - pub pos_testing_mode: bool, /// Flag to enable tx fee verification pub verify_fees: bool, } @@ -127,7 +115,6 @@ pub struct Validator { impl Validator { pub async fn new(db: &sled::Db, config: ValidatorConfig) -> Result { info!(target: "validator::new", "Initializing Validator"); - let pos_testing_mode = config.pos_testing_mode; info!(target: "validator::new", "Initializing Blockchain"); let blockchain = Blockchain::new(db)?; @@ -136,12 +123,7 @@ impl Validator { let overlay = BlockchainOverlay::new(&blockchain)?; // Deploy native wasm contracts - deploy_native_contracts( - &overlay, - config.time_keeper.verifying_block_height, - &config.faucet_pubkeys, - ) - .await?; + deploy_native_contracts(&overlay, &config.faucet_pubkeys).await?; // Add genesis block if blockchain is empty if blockchain.genesis().is_err() { @@ -165,7 +147,6 @@ impl Validator { blockchain, consensus, synced: RwLock::new(false), - pos_testing_mode, verify_fees: config.verify_fees, }); @@ -536,7 +517,7 @@ impl Validator { let mut module = PoWModule::new(blockchain.clone(), pow_target, pow_fixed_difficulty)?; // Deploy native wasm contracts - deploy_native_contracts(&overlay, 0, &faucet_pubkeys).await?; + deploy_native_contracts(&overlay, &faucet_pubkeys).await?; // Validate genesis block verify_genesis_block(&overlay, previous).await?; diff --git a/src/validator/utils.rs b/src/validator/utils.rs index 7f5f5ccaf..33fe31e1c 100644 --- a/src/validator/utils.rs +++ b/src/validator/utils.rs @@ -48,7 +48,6 @@ use crate::{ /// the actual contract, so make sure the native contracts handle this well. pub async fn deploy_native_contracts( overlay: &BlockchainOverlayPtr, - verifying_block_height: u64, faucet_pubkeys: &Vec, ) -> Result<()> { info!(target: "validator::utils::deploy_native_contracts", "Deploying native WASM contracts"); @@ -87,7 +86,8 @@ pub async fn deploy_native_contracts( for nc in native_contracts { info!(target: "validator::utils::deploy_native_contracts", "Deploying {} with ContractID {}", nc.0, nc.1); - let mut runtime = Runtime::new(&nc.2[..], overlay.clone(), nc.1, verifying_block_height)?; + // Note: Native contracts are always verifying against genesis block height(0) + let mut runtime = Runtime::new(&nc.2[..], overlay.clone(), nc.1, 0)?; runtime.deploy(&nc.3)?;