ソースを参照

util/time: TimeKeeper yeeted

skoupidi 2 年 前
コミット
7ac561fe67

+ 0 - 27
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

+ 1 - 26
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<usize>,
 
-    #[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<String>,
@@ -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<smol::Executor<'static>>) -> 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<smol::Executor<'static>>) -> 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<smol::Executor<'static>>) -> 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
     );
 

+ 0 - 5
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<BigUint>,
-    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,
         );
 

+ 0 - 1
bin/darkfid/src/tests/mod.rs

@@ -37,7 +37,6 @@ async fn sync_blocks_real(ex: Arc<Executor<'static>>) -> Result<()> {
     let config = HarnessConfig {
         pow_target,
         pow_fixed_difficulty: pow_fixed_difficulty.clone(),
-        pos_testing_mode: true,
         alice_initial: 1000,
         bob_initial: 500,
     };

+ 1 - 7
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?;

+ 1 - 256
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<u64> {
-        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<u64> {
-        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]

+ 2 - 21
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<PublicKey>,
-    /// 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<BigUint>,
         genesis_block: BlockInfo,
         genesis_txs_total: u64,
         faucet_pubkeys: Vec<PublicKey>,
-        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<bool>,
-    /// 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<ValidatorPtr> {
         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?;

+ 2 - 2
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<PublicKey>,
 ) -> 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)?;