Просмотр исходного кода

consensus: created single-node mode for local testing

aggstam 3 лет назад
Родитель
Сommit
dc9c6c377f

+ 3 - 0
bin/darkfid/darkfid_config.toml

@@ -24,6 +24,9 @@ rpc_listen = "tcp://127.0.0.1:8340"
 # Participate in the consensus protocol
 consensus = false
 
+# Enable single-node mode for local testing
+single_node = false
+
 # P2P accept addresses for the consensus protocol
 #consensus_p2p_accept = ["tls://127.0.0.1:8341"]
 

+ 9 - 0
bin/darkfid/src/main.rs

@@ -75,6 +75,10 @@ struct Args {
     /// Participate in consensus
     consensus: bool,
 
+    #[structopt(long)]
+    /// Enable single-node mode for local testing
+    single_node: bool,
+
     #[structopt(long, default_value = "~/.config/darkfi/darkfid_wallet.db")]
     /// Path to wallet database
     wallet_path: String,
@@ -327,6 +331,10 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'_>>) -> Result<()> {
         faucet_pubkeys.push(pk);
     }
 
+    if args.single_node {
+        info!("Node is configured to tun in single-node mode!");
+    }
+
     // Initialize validator state
     let state = ValidatorState::new(
         &sled_db,
@@ -337,6 +345,7 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'_>>) -> Result<()> {
         wallet.clone(),
         faucet_pubkeys,
         args.consensus,
+        args.single_node,
     )
     .await?;
 

+ 1 - 0
bin/faucetd/src/main.rs

@@ -574,6 +574,7 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'_>>) -> Result<()> {
         wallet.clone(),
         faucet_pubkeys,
         false,
+        false,
     )
     .await?;
 

+ 3 - 0
contrib/localnet/darkfid-five-nodes/darkfid0.toml

@@ -24,6 +24,9 @@ rpc_listen = "tcp://127.0.0.1:8340"
 # Participate in the consensus protocol
 consensus = true
 
+# Enable single-node mode for local testing
+single_node = false
+
 # P2P accept addresses for the consensus protocol
 consensus_p2p_accept = ["tcp://127.0.0.1:8341"]
 

+ 3 - 0
contrib/localnet/darkfid-five-nodes/darkfid1.toml

@@ -24,6 +24,9 @@ rpc_listen = "tcp://127.0.0.1:8440"
 # Participate in the consensus protocol
 consensus = true
 
+# Enable single-node mode for local testing
+single_node = false
+
 # P2P accept addresses for the consensus protocol
 consensus_p2p_accept = ["tcp://127.0.0.1:8441"]
 

+ 3 - 0
contrib/localnet/darkfid-five-nodes/darkfid2.toml

@@ -24,6 +24,9 @@ rpc_listen = "tcp://127.0.0.1:8540"
 # Participate in the consensus protocol
 consensus = true
 
+# Enable single-node mode for local testing
+single_node = false
+
 # P2P accept addresses for the consensus protocol
 consensus_p2p_accept = ["tcp://127.0.0.1:8541"]
 

+ 3 - 0
contrib/localnet/darkfid-five-nodes/darkfid3.toml

@@ -24,6 +24,9 @@ rpc_listen = "tcp://127.0.0.1:8640"
 # Participate in the consensus protocol
 consensus = true
 
+# Enable single-node mode for local testing
+single_node = false
+
 # P2P accept addresses for the consensus protocol
 consensus_p2p_accept = ["tcp://127.0.0.1:8641"]
 

+ 3 - 0
contrib/localnet/darkfid-five-nodes/darkfid4.toml

@@ -24,6 +24,9 @@ rpc_listen = "tcp://127.0.0.1:8740"
 # Participate in the consensus protocol
 consensus = true
 
+# Enable single-node mode for local testing
+single_node = false
+
 # P2P accept addresses for the consensus protocol
 consensus_p2p_accept = ["tcp://127.0.0.1:8741"]
 

+ 3 - 0
contrib/localnet/darkfid-single-node/darkfid0.toml

@@ -24,6 +24,9 @@ rpc_listen = "tcp://127.0.0.1:8340"
 # Participate in the consensus protocol
 consensus = true
 
+# Enable single-node mode for local testing
+single_node = true
+
 # P2P accept addresses for the consensus protocol
 consensus_p2p_accept = ["tcp://127.0.0.1:8341"]
 

+ 3 - 0
contrib/localnet/darkfid-small/darkfid0.toml

@@ -24,6 +24,9 @@ rpc_listen = "tcp://127.0.0.1:8340"
 # Participate in the consensus protocol
 consensus = true
 
+# Enable single-node mode for local testing
+single_node = false
+
 # P2P accept addresses for the consensus protocol
 consensus_p2p_accept = ["tcp://127.0.0.1:8341"]
 

+ 3 - 0
contrib/localnet/darkfid-small/darkfid1.toml

@@ -24,6 +24,9 @@ rpc_listen = "tcp://127.0.0.1:8440"
 # Participate in the consensus protocol
 consensus = true
 
+# Enable single-node mode for local testing
+single_node = false
+
 # P2P accept addresses for the consensus protocol
 consensus_p2p_accept = ["tcp://127.0.0.1:8441"]
 

+ 3 - 0
contrib/localnet/darkfid-small/darkfid2.toml

@@ -24,6 +24,9 @@ rpc_listen = "tcp://127.0.0.1:8540"
 # Participate in the consensus protocol
 consensus = false
 
+# Enable single-node mode for local testing
+single_node = false
+
 # P2P accept addresses for the consensus protocol
 #consensus_p2p_accept = ["tcp://127.0.0.1:8541"]
 

+ 3 - 0
contrib/localnet/darkfid/darkfid0.toml

@@ -24,6 +24,9 @@ rpc_listen = "tcp://127.0.0.1:8340"
 # Participate in the consensus protocol
 consensus = true
 
+# Enable single-node mode for local testing
+single_node = false
+
 # P2P accept addresses for the consensus protocol
 consensus_p2p_accept = ["tcp://127.0.0.1:8341"]
 

+ 3 - 0
contrib/localnet/darkfid/darkfid1.toml

@@ -24,6 +24,9 @@ rpc_listen = "tcp://127.0.0.1:8440"
 # Participate in the consensus protocol
 consensus = true
 
+# Enable single-node mode for local testing
+single_node = false
+
 # P2P accept addresses for the consensus protocol
 consensus_p2p_accept = ["tcp://127.0.0.1:8441"]
 

+ 3 - 0
contrib/localnet/darkfid/darkfid2.toml

@@ -24,6 +24,9 @@ rpc_listen = "tcp://127.0.0.1:8540"
 # Participate in the consensus protocol
 consensus = false
 
+# Enable single-node mode for local testing
+single_node = false
+
 # P2P accept addresses for the consensus protocol
 #consensus_p2p_accept = ["tcp://127.0.0.1:8541"]
 

+ 1 - 0
script/research/nodes-tool/src/main.rs

@@ -328,6 +328,7 @@ async fn generate(localnet: &str, name: &str) -> Result<()> {
         wallet,
         vec![],
         false,
+        false,
     )
     .await?;
     let info = StateInfo::new(&*state.read().await);

+ 13 - 2
src/consensus/state.rs

@@ -53,6 +53,8 @@ pub struct ConsensusState {
     pub genesis_block: blake3::Hash,
     /// Total sum of initial staking coins
     pub initial_distribution: u64,
+    /// Flag to enable single-node mode
+    pub single_node: bool,
     /// Slot the network was bootstrapped
     pub bootstrap_slot: u64,
     /// Participating start slot
@@ -91,6 +93,7 @@ impl ConsensusState {
         genesis_ts: Timestamp,
         genesis_data: blake3::Hash,
         initial_distribution: u64,
+        single_node: bool,
     ) -> Result<Self> {
         let genesis_block = Block::genesis_block(genesis_ts, genesis_data).blockhash();
         Ok(Self {
@@ -99,6 +102,7 @@ impl ConsensusState {
             genesis_ts,
             genesis_block,
             initial_distribution,
+            single_node,
             bootstrap_slot: 0,
             participating: None,
             proposing: false,
@@ -303,9 +307,10 @@ impl ConsensusState {
         // Temporarily, we compete with fixed stake.
         // This stake should be based on how many nodes we want to run, and they all
         // must sum to initial distribution total coins.
-        //let stake = self.initial_distribution;
+        let stake = self.initial_distribution;
+        //let stake = 200;
         let coin = LeadCoin::new(
-            200,
+            stake,
             slot,
             epoch_secrets.secret_keys[0].inner(),
             epoch_secrets.merkle_roots[0],
@@ -453,6 +458,12 @@ impl ConsensusState {
             self.forks[fork_index as usize].sequence.last().unwrap().coins.clone()
         };
 
+        // If on single-node mode, node always proposes by extending the
+        // single fork it holds.
+        if self.single_node {
+            return (true, fork_index, 0)
+        }
+
         let mut won = false;
         let mut highest_stake = 0;
         let mut highest_stake_idx = 0;

+ 58 - 48
src/consensus/validator.rs

@@ -86,6 +86,8 @@ pub struct ValidatorState {
     pub verifying_keys: VerifyingKeyMap,
     /// Wallet interface
     pub wallet: WalletPtr,
+    /// Flag to enable single-node mode
+    pub single_node: bool,
 }
 
 impl ValidatorState {
@@ -98,6 +100,7 @@ impl ValidatorState {
         wallet: WalletPtr,
         faucet_pubkeys: Vec<PublicKey>,
         enable_participation: bool,
+        single_node: bool,
     ) -> Result<ValidatorStatePtr> {
         debug!(target: "consensus::validator", "Initializing ValidatorState");
 
@@ -130,6 +133,7 @@ impl ValidatorState {
             genesis_ts,
             genesis_data,
             initial_distribution,
+            single_node,
         )?;
 
         let unconfirmed_txs = vec![];
@@ -222,6 +226,7 @@ impl ValidatorState {
             subscribers,
             verifying_keys: Arc::new(RwLock::new(verifying_keys)),
             wallet,
+            single_node,
         }));
 
         Ok(state)
@@ -458,59 +463,64 @@ impl ValidatorState {
             return Err(Error::ProposalHeadersMissmatchError)
         }
 
-        // Verify proposal leader proof
-        if let Err(e) = lf.proof.verify(&self.lead_verifying_key, &lf.public_inputs) {
-            error!(target: "consensus::validator", "receive_proposal(): Error during leader proof verification: {}", e);
-            return Err(Error::LeaderProofVerification)
-        };
-        info!(target: "consensus::validator", "receive_proposal(): Leader proof verified successfully!");
-
-        // Validate proposal public value against coin creation slot checkpoint
-        let (mu_y, mu_rho) =
-            LeadCoin::election_seeds_u64(self.consensus.get_eta(), self.consensus.current_slot());
-        // y
-        let prop_mu_y = lf.public_inputs[constants::PI_MU_Y_INDEX];
+        // Ignore node coin validations if we oporate in single-node mode
+        if !self.single_node {
+            // Verify proposal leader proof
+            if let Err(e) = lf.proof.verify(&self.lead_verifying_key, &lf.public_inputs) {
+                error!(target: "consensus::validator", "receive_proposal(): Error during leader proof verification: {}", e);
+                return Err(Error::LeaderProofVerification)
+            };
+            info!(target: "consensus::validator", "receive_proposal(): Leader proof verified successfully!");
 
-        if mu_y != prop_mu_y {
-            error!(
-                target: "consensus::validator",
-                "receive_proposal(): Failed to verify mu_y: {:?}, proposed: {:?}",
-                mu_y, prop_mu_y
+            // Validate proposal public value against coin creation slot checkpoint
+            let (mu_y, mu_rho) = LeadCoin::election_seeds_u64(
+                self.consensus.get_eta(),
+                self.consensus.current_slot(),
             );
-            return Err(Error::ProposalPublicValuesMismatched)
-        }
+            // y
+            let prop_mu_y = lf.public_inputs[constants::PI_MU_Y_INDEX];
 
-        // rho
-        let prop_mu_rho = lf.public_inputs[constants::PI_MU_RHO_INDEX];
+            if mu_y != prop_mu_y {
+                error!(
+                    target: "consensus::validator",
+                    "receive_proposal(): Failed to verify mu_y: {:?}, proposed: {:?}",
+                    mu_y, prop_mu_y
+                );
+                return Err(Error::ProposalPublicValuesMismatched)
+            }
 
-        if mu_rho != prop_mu_rho {
-            error!(
-                target: "consensus::validator",
-                "receive_proposal(): Failed to verify mu_rho: {:?}, proposed: {:?}",
-                mu_rho, prop_mu_rho
-            );
-            return Err(Error::ProposalPublicValuesMismatched)
-        }
+            // rho
+            let prop_mu_rho = lf.public_inputs[constants::PI_MU_RHO_INDEX];
 
-        // Validate proposal coin sigmas against current slot checkpoint
-        let checkpoint = self.consensus.get_slot_checkpoint(current)?;
-        // sigma1
-        let prop_sigma1 = lf.public_inputs[constants::PI_SIGMA1_INDEX];
-        if checkpoint.sigma1 != prop_sigma1 {
-            error!(
-                target: "consensus::validator",
-                "receive_proposal(): Failed to verify public value sigma1: {:?}, to proposed: {:?}",
-                checkpoint.sigma1, prop_sigma1
-            );
-        }
-        // sigma2
-        let prop_sigma2 = lf.public_inputs[constants::PI_SIGMA2_INDEX];
-        if checkpoint.sigma2 != prop_sigma2 {
-            error!(
-                target: "consensus::validator",
-                "receive_proposal(): Failed to verify public value sigma2: {:?}, to proposed: {:?}",
-                checkpoint.sigma2, prop_sigma2
-            );
+            if mu_rho != prop_mu_rho {
+                error!(
+                    target: "consensus::validator",
+                    "receive_proposal(): Failed to verify mu_rho: {:?}, proposed: {:?}",
+                    mu_rho, prop_mu_rho
+                );
+                return Err(Error::ProposalPublicValuesMismatched)
+            }
+
+            // Validate proposal coin sigmas against current slot checkpoint
+            let checkpoint = self.consensus.get_slot_checkpoint(current)?;
+            // sigma1
+            let prop_sigma1 = lf.public_inputs[constants::PI_SIGMA1_INDEX];
+            if checkpoint.sigma1 != prop_sigma1 {
+                error!(
+                    target: "consensus::validator",
+                    "receive_proposal(): Failed to verify public value sigma1: {:?}, to proposed: {:?}",
+                    checkpoint.sigma1, prop_sigma1
+                );
+            }
+            // sigma2
+            let prop_sigma2 = lf.public_inputs[constants::PI_SIGMA2_INDEX];
+            if checkpoint.sigma2 != prop_sigma2 {
+                error!(
+                    target: "consensus::validator",
+                    "receive_proposal(): Failed to verify public value sigma2: {:?}, to proposed: {:?}",
+                    checkpoint.sigma2, prop_sigma2
+                );
+            }
         }
 
         // Create corresponding state checkpoint for validations