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

validator/verification: verify block timestamp based on sync state

skoupidi 5 hónapja
szülő
commit
89b4dbe4a1

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

@@ -265,6 +265,7 @@ impl Harness {
             &mut fork.module,
             &block,
             &previous,
+            true,
             self.alice.validator.read().await.verify_fees,
         )
         .await?;

+ 10 - 2
bin/darkfid/src/tests/mod.rs

@@ -80,8 +80,16 @@ async fn sync_blocks_real(ex: Arc<Executor<'static>>) -> Result<()> {
     let alice = th.alice.validator.read().await;
     fork = Fork::new(alice.consensus.blockchain.clone(), alice.consensus.module.clone()).await?;
     // Append block3 to fork and generate the next one
-    verify_block(&fork.overlay, &fork.diffs, &mut fork.module, &block3, &block2, alice.verify_fees)
-        .await?;
+    verify_block(
+        &fork.overlay,
+        &fork.diffs,
+        &mut fork.module,
+        &block3,
+        &block2,
+        true,
+        alice.verify_fees,
+    )
+    .await?;
     drop(alice);
     let block6 = th.generate_next_block(&mut fork).await?;
     // Add them to nodes

+ 7 - 2
src/validator/consensus.rs

@@ -127,7 +127,12 @@ impl Consensus {
     /// Given a proposal, the node verifys it and finds which fork it
     /// extends. If the proposal extends the canonical blockchain, a
     /// new fork chain is created.
-    pub async fn append_proposal(&mut self, proposal: &Proposal, verify_fees: bool) -> Result<()> {
+    pub async fn append_proposal(
+        &mut self,
+        proposal: &Proposal,
+        is_new: bool,
+        verify_fees: bool,
+    ) -> Result<()> {
         debug!(target: "validator::consensus::append_proposal", "Appending proposal {}", proposal.hash);
 
         // Check if proposal already exists
@@ -150,7 +155,7 @@ impl Consensus {
         }
 
         // Verify proposal and grab corresponding fork
-        let (mut fork, index) = verify_proposal(self, proposal, verify_fees).await?;
+        let (mut fork, index) = verify_proposal(self, proposal, is_new, verify_fees).await?;
 
         // Append proposal to the fork
         fork.append_proposal(proposal).await?;

+ 21 - 6
src/validator/mod.rs

@@ -322,7 +322,7 @@ impl Validator {
     /// The node tries to append provided proposal to its consensus
     /// state.
     pub async fn append_proposal(&mut self, proposal: &Proposal) -> Result<()> {
-        self.consensus.append_proposal(proposal, self.verify_fees).await
+        self.consensus.append_proposal(proposal, self.synced, self.verify_fees).await
     }
 
     /// The node checks if best fork can be confirmed.
@@ -531,8 +531,16 @@ impl Validator {
         // Validate and insert each block
         for block in blocks {
             // Verify block
-            match verify_block(&overlay, &diffs, &mut module, block, previous, self.verify_fees)
-                .await
+            match verify_block(
+                &overlay,
+                &diffs,
+                &mut module,
+                block,
+                previous,
+                true,
+                self.verify_fees,
+            )
+            .await
             {
                 Ok(()) => { /* Do nothing */ }
                 // Skip already existing block
@@ -759,9 +767,16 @@ impl Validator {
             let block = self.blockchain.get_blocks_by_heights(&[index])?[0].clone();
 
             // Verify block
-            if let Err(e) =
-                verify_block(&overlay, &diffs, &mut module, &block, &previous, self.verify_fees)
-                    .await
+            if let Err(e) = verify_block(
+                &overlay,
+                &diffs,
+                &mut module,
+                &block,
+                &previous,
+                false,
+                self.verify_fees,
+            )
+            .await
             {
                 error!(target: "validator::validate_blockchain", "Erroneous block found in set: {e}");
                 return Err(Error::BlockIsInvalid(block.hash().as_string()))

+ 13 - 3
src/validator/verification.rs

@@ -156,6 +156,7 @@ pub fn validate_block(
     block: &BlockInfo,
     previous: &BlockInfo,
     module: &mut PoWModule,
+    is_new: bool,
 ) -> Result<()> {
     // Check block version (1)
     if block.header.version != block_version(block.header.height) {
@@ -173,7 +174,12 @@ pub fn validate_block(
     }
 
     // Check timestamp validity (4)
-    if !module.verify_timestamp_by_median(block.header.timestamp) {
+    let valid = if is_new {
+        module.verify_current_timestamp(block.header.timestamp)?
+    } else {
+        module.verify_timestamp_by_median(block.header.timestamp)
+    };
+    if !valid {
         return Err(Error::BlockIsInvalid(block.hash().as_string()))
     }
 
@@ -204,7 +210,7 @@ pub fn validate_blockchain(
     for (index, block) in blocks[1..].iter().enumerate() {
         let full_blocks = blockchain.get_blocks_by_hash(&[blocks[index].1, block.1])?;
         let full_block = &full_blocks[1];
-        validate_block(full_block, &full_blocks[0], &mut module)?;
+        validate_block(full_block, &full_blocks[0], &mut module, false)?;
         // Update PoW module
         module.append(&full_block.header, &module.next_difficulty()?)?;
     }
@@ -222,6 +228,7 @@ pub async fn verify_block(
     module: &mut PoWModule,
     block: &BlockInfo,
     previous: &BlockInfo,
+    is_new: bool,
     verify_fees: bool,
 ) -> Result<()> {
     let block_hash = block.hash();
@@ -233,7 +240,7 @@ pub async fn verify_block(
     }
 
     // Validate block, using its previous
-    validate_block(block, previous, module)?;
+    validate_block(block, previous, module, is_new)?;
 
     // Verify transactions vector contains at least one(producers) transaction
     if block.txs.is_empty() {
@@ -1108,6 +1115,7 @@ async fn apply_transactions(
 pub async fn verify_proposal(
     consensus: &Consensus,
     proposal: &Proposal,
+    is_new: bool,
     verify_fees: bool,
 ) -> Result<(Fork, Option<usize>)> {
     // Check if proposal hash matches actual one (1)
@@ -1133,6 +1141,7 @@ pub async fn verify_proposal(
         &mut fork.module,
         &proposal.block,
         &previous,
+        is_new,
         verify_fees,
     )
     .await
@@ -1178,6 +1187,7 @@ pub async fn verify_fork_proposal(
         &mut fork.module,
         &proposal.block,
         &previous,
+        false,
         verify_fees,
     )
     .await