Forráskód Böngészése

consensus: differentiate bootstrap timestamp from genesis, to not break slot calculation on network restarts

aggstam 3 éve
szülő
commit
034bd2fd4f

+ 10 - 5
bin/darkfid/src/main.rs

@@ -29,8 +29,8 @@ use darkfi::{
     async_daemonize, cli_desc,
     consensus::{
         constants::{
-            MAINNET_GENESIS_HASH_BYTES, MAINNET_GENESIS_TIMESTAMP, TESTNET_GENESIS_HASH_BYTES,
-            TESTNET_GENESIS_TIMESTAMP,
+            MAINNET_BOOTSTRAP_TIMESTAMP, MAINNET_GENESIS_HASH_BYTES, MAINNET_GENESIS_TIMESTAMP,
+            TESTNET_BOOTSTRAP_TIMESTAMP, TESTNET_GENESIS_HASH_BYTES, TESTNET_GENESIS_TIMESTAMP,
         },
         proto::{ProtocolProposal, ProtocolSync, ProtocolSyncConsensus, ProtocolTx},
         task::{block_sync_task, proposal_task},
@@ -298,9 +298,13 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'_>>) -> Result<()> {
     let sled_db = sled::open(&db_path)?;
 
     // Initialize validator state
-    let (genesis_ts, genesis_data) = match args.chain.as_str() {
-        "mainnet" => (*MAINNET_GENESIS_TIMESTAMP, *MAINNET_GENESIS_HASH_BYTES),
-        "testnet" => (*TESTNET_GENESIS_TIMESTAMP, *TESTNET_GENESIS_HASH_BYTES),
+    let (bootstrap_ts, genesis_ts, genesis_data) = match args.chain.as_str() {
+        "mainnet" => {
+            (*MAINNET_BOOTSTRAP_TIMESTAMP, *MAINNET_GENESIS_TIMESTAMP, *MAINNET_GENESIS_HASH_BYTES)
+        }
+        "testnet" => {
+            (*TESTNET_BOOTSTRAP_TIMESTAMP, *TESTNET_GENESIS_TIMESTAMP, *TESTNET_GENESIS_HASH_BYTES)
+        }
         x => {
             error!("Unsupported chain `{}`", x);
             return Err(Error::UnsupportedChain)
@@ -323,6 +327,7 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'_>>) -> Result<()> {
     // Initialize validator state
     let state = ValidatorState::new(
         &sled_db,
+        bootstrap_ts,
         genesis_ts,
         genesis_data,
         wallet.clone(),

+ 10 - 5
bin/faucetd/src/main.rs

@@ -55,8 +55,8 @@ use darkfi::{
     async_daemonize, cli_desc,
     consensus::{
         constants::{
-            MAINNET_GENESIS_HASH_BYTES, MAINNET_GENESIS_TIMESTAMP, TESTNET_GENESIS_HASH_BYTES,
-            TESTNET_GENESIS_TIMESTAMP,
+            MAINNET_BOOTSTRAP_TIMESTAMP, MAINNET_GENESIS_HASH_BYTES, MAINNET_GENESIS_TIMESTAMP,
+            TESTNET_BOOTSTRAP_TIMESTAMP, TESTNET_GENESIS_HASH_BYTES, TESTNET_GENESIS_TIMESTAMP,
         },
         proto::{ProtocolSync, ProtocolTx},
         task::block_sync_task,
@@ -528,9 +528,13 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'_>>) -> Result<()> {
     let sled_db = sled::open(&db_path)?;
 
     // Initialize validator state
-    let (genesis_ts, genesis_data) = match args.chain.as_str() {
-        "mainnet" => (*MAINNET_GENESIS_TIMESTAMP, *MAINNET_GENESIS_HASH_BYTES),
-        "testnet" => (*TESTNET_GENESIS_TIMESTAMP, *TESTNET_GENESIS_HASH_BYTES),
+    let (bootstrap_ts, genesis_ts, genesis_data) = match args.chain.as_str() {
+        "mainnet" => {
+            (*MAINNET_BOOTSTRAP_TIMESTAMP, *MAINNET_GENESIS_TIMESTAMP, *MAINNET_GENESIS_HASH_BYTES)
+        }
+        "testnet" => {
+            (*TESTNET_BOOTSTRAP_TIMESTAMP, *TESTNET_GENESIS_TIMESTAMP, *TESTNET_GENESIS_HASH_BYTES)
+        }
         x => {
             error!("Unsupported chain `{}`", x);
             return Err(Error::UnsupportedChain)
@@ -553,6 +557,7 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'_>>) -> Result<()> {
     // Initialize validator state
     let state = ValidatorState::new(
         &sled_db,
+        bootstrap_ts,
         genesis_ts,
         genesis_data,
         wallet.clone(),

+ 9 - 1
src/consensus/constants.rs

@@ -24,14 +24,22 @@ lazy_static! {
     /// Genesis hash for the mainnet chain
     pub static ref MAINNET_GENESIS_HASH_BYTES: blake3::Hash = blake3::hash(b"darkfi_mainnet");
 
+    // NOTE: On initial network bootstrap, genesis timestamp should be equal to boostrap timestamp.
+    // On network restart only change bootstrap timestamp to schedule when nodes become active.
     /// Genesis timestamp for the mainnet chain
     pub static ref MAINNET_GENESIS_TIMESTAMP: Timestamp = Timestamp(1650887115);
 
+    /// Bootstrap timestamp for the mainnet chain
+    pub static ref MAINNET_BOOTSTRAP_TIMESTAMP: Timestamp = Timestamp(1650887115);
+
     /// Genesis hash for the testnet chain
     pub static ref TESTNET_GENESIS_HASH_BYTES: blake3::Hash = blake3::hash(b"darkfi_testnet");
 
     /// Genesis timestamp for the testnet chain
-    pub static ref TESTNET_GENESIS_TIMESTAMP: Timestamp = Timestamp(1671330180);
+    pub static ref TESTNET_GENESIS_TIMESTAMP: Timestamp = Timestamp(1671546600);
+
+    /// Bootstrap timestamp for the testnet chain
+    pub static ref TESTNET_BOOTSTRAP_TIMESTAMP: Timestamp = Timestamp(1671546600);
 
     // Commonly used Float10
     pub static ref  FLOAT10_ZERO: Float10 = Float10::from_str_native("0").unwrap().with_precision(RADIX_BITS).value();

+ 4 - 0
src/consensus/state.rs

@@ -42,6 +42,8 @@ use dashu::base::Abs;
 pub struct ConsensusState {
     /// Canonical (finalized) blockchain
     pub blockchain: Blockchain,
+    /// Network bootstrap timestamp
+    pub bootstrap_ts: Timestamp,
     /// Genesis block creation timestamp
     pub genesis_ts: Timestamp,
     /// Genesis block hash
@@ -78,12 +80,14 @@ pub struct ConsensusState {
 impl ConsensusState {
     pub fn new(
         blockchain: Blockchain,
+        bootstrap_ts: Timestamp,
         genesis_ts: Timestamp,
         genesis_data: blake3::Hash,
     ) -> Result<Self> {
         let genesis_block = Block::genesis_block(genesis_ts, genesis_data).blockhash();
         Ok(Self {
             blockchain,
+            bootstrap_ts,
             genesis_ts,
             genesis_block,
             bootstrap_slot: 0,

+ 3 - 3
src/consensus/task/proposal.rs

@@ -40,9 +40,9 @@ pub async fn proposal_task(
     // NOTE: Network beign configured to start in the future should always be the case
     // when bootstrapping or restarting a network.
     let current_ts = Timestamp::current_time();
-    let genesis_ts = state.read().await.consensus.genesis_ts;
-    if current_ts < genesis_ts {
-        let diff = genesis_ts.0 - current_ts.0;
+    let bootstrap_ts = state.read().await.consensus.bootstrap_ts;
+    if current_ts < bootstrap_ts {
+        let diff = bootstrap_ts.0 - current_ts.0;
         info!("consensus: Waiting for network bootstrap: {} seconds", diff);
         sleep(diff as u64).await;
     } else {

+ 3 - 1
src/consensus/validator.rs

@@ -92,6 +92,7 @@ pub struct ValidatorState {
 impl ValidatorState {
     pub async fn new(
         db: &sled::Db, // <-- TODO: Avoid this with some wrapping, sled should only be in blockchain
+        bootstrap_ts: Timestamp,
         genesis_ts: Timestamp,
         genesis_data: blake3::Hash,
         wallet: WalletPtr,
@@ -123,7 +124,8 @@ impl ValidatorState {
         };
 
         let blockchain = Blockchain::new(db, genesis_ts, genesis_data)?;
-        let consensus = ConsensusState::new(blockchain.clone(), genesis_ts, genesis_data)?;
+        let consensus =
+            ConsensusState::new(blockchain.clone(), bootstrap_ts, genesis_ts, genesis_data)?;
 
         let unconfirmed_txs = vec![];
 

+ 6 - 1
src/contract/money/tests/harness.rs

@@ -19,7 +19,9 @@ use std::collections::HashMap;
 
 use darkfi::{
     consensus::{
-        constants::{TESTNET_GENESIS_HASH_BYTES, TESTNET_GENESIS_TIMESTAMP},
+        constants::{
+            TESTNET_BOOTSTRAP_TIMESTAMP, TESTNET_GENESIS_HASH_BYTES, TESTNET_GENESIS_TIMESTAMP,
+        },
         ValidatorState, ValidatorStatePtr,
     },
     tx::Transaction,
@@ -100,6 +102,7 @@ impl MoneyTestHarness {
 
         let faucet_state = ValidatorState::new(
             &faucet_sled_db,
+            *TESTNET_BOOTSTRAP_TIMESTAMP,
             *TESTNET_GENESIS_TIMESTAMP,
             *TESTNET_GENESIS_HASH_BYTES,
             faucet_wallet,
@@ -110,6 +113,7 @@ impl MoneyTestHarness {
 
         let alice_state = ValidatorState::new(
             &alice_sled_db,
+            *TESTNET_BOOTSTRAP_TIMESTAMP,
             *TESTNET_GENESIS_TIMESTAMP,
             *TESTNET_GENESIS_HASH_BYTES,
             alice_wallet,
@@ -120,6 +124,7 @@ impl MoneyTestHarness {
 
         let bob_state = ValidatorState::new(
             &bob_sled_db,
+            *TESTNET_BOOTSTRAP_TIMESTAMP,
             *TESTNET_GENESIS_TIMESTAMP,
             *TESTNET_GENESIS_HASH_BYTES,
             bob_wallet,