فهرست منبع

blockchain: overlay pointers handling

aggstam 3 سال پیش
والد
کامیت
2a35e0af83
4فایلهای تغییر یافته به همراه94 افزوده شده و 0 حذف شده
  1. 58 0
      bin/darkfid2/src/tests/forks.rs
  2. 2 0
      bin/darkfid2/src/tests/mod.rs
  3. 24 0
      src/blockchain/mod.rs
  4. 10 0
      src/validator/consensus/mod.rs

+ 58 - 0
bin/darkfid2/src/tests/forks.rs

@@ -0,0 +1,58 @@
+/* This file is part of DarkFi (https://dark.fi)
+ *
+ * Copyright (C) 2020-2023 Dyne.org foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+use darkfi::{blockchain::Blockchain, validator::consensus::Fork, Result};
+
+#[test]
+fn forks() -> Result<()> {
+    // Dummy records we will insert
+    let record0 = blake3::hash(b"Let there be dark!");
+    let record1 = blake3::hash(b"Never skip brain day.");
+
+    // Create a temporary blockchain
+    let blockchain = Blockchain::new(&sled::Config::new().temporary(true).open()?)?;
+
+    // Create a fork
+    let fork = Fork::new(&blockchain)?;
+
+    // Add a dummy record to fork
+    fork.overlay.lock().unwrap().order.insert(&[0], &[record0])?;
+
+    // Verify blockchain doesn't contain the record
+    assert_eq!(blockchain.order.get(&[0], false)?, [None]);
+    assert_eq!(fork.overlay.lock().unwrap().order.get(&[0], true)?, [Some(record0)]);
+
+    // Now we are going to clone the fork
+    let fork_clone = fork.full_clone()?;
+
+    // Verify it cointains the original record
+    assert_eq!(fork_clone.overlay.lock().unwrap().order.get(&[0], true)?, [Some(record0)]);
+
+    // Add another dummy record to cloned fork
+    fork_clone.overlay.lock().unwrap().order.insert(&[1], &[record1])?;
+
+    // Verify blockchain and original fork don't contain the record
+    assert_eq!(blockchain.order.get(&[0], false)?, [None]);
+    assert_eq!(fork.overlay.lock().unwrap().order.get(&[0, 1], false)?, [Some(record0), None]);
+    assert_eq!(
+        fork_clone.overlay.lock().unwrap().order.get(&[0, 1], true)?,
+        [Some(record0), Some(record1)]
+    );
+
+    Ok(())
+}

+ 2 - 0
bin/darkfid2/src/tests/mod.rs

@@ -25,6 +25,8 @@ use url::Url;
 mod harness;
 mod harness;
 use harness::{generate_node, Harness, HarnessConfig};
 use harness::{generate_node, Harness, HarnessConfig};
 
 
+mod forks;
+
 async fn sync_blocks_real(ex: Arc<Executor<'_>>) -> Result<()> {
 async fn sync_blocks_real(ex: Arc<Executor<'_>>) -> Result<()> {
     init_logger();
     init_logger();
 
 

+ 24 - 0
src/blockchain/mod.rs

@@ -540,6 +540,30 @@ impl BlockchainOverlay {
 
 
         Ok(())
         Ok(())
     }
     }
+
+    /// Auxiliary function to create a full clone using SledDbOverlay::clone,
+    /// and creating new pointers of underlying overlays.
+    pub fn full_clone(&self) -> Result<BlockchainOverlayPtr> {
+        let overlay = Arc::new(Mutex::new(self.overlay.lock().unwrap().clone()));
+        let headers = HeaderStoreOverlay::new(&overlay)?;
+        let blocks = BlockStoreOverlay::new(&overlay)?;
+        let order = BlockOrderStoreOverlay::new(&overlay)?;
+        let slots = SlotStoreOverlay::new(&overlay)?;
+        let transactions = TxStoreOverlay::new(&overlay)?;
+        let contracts = ContractStateStoreOverlay::new(&overlay)?;
+        let wasm_bincode = WasmStoreOverlay::new(&overlay)?;
+
+        Ok(Arc::new(Mutex::new(Self {
+            overlay,
+            headers,
+            blocks,
+            order,
+            slots,
+            transactions,
+            contracts,
+            wasm_bincode,
+        })))
+    }
 }
 }
 
 
 /// Parse a sled record with a u64 keyin the form of a tuple (`key`, `value`).
 /// Parse a sled record with a u64 keyin the form of a tuple (`key`, `value`).

+ 10 - 0
src/validator/consensus/mod.rs

@@ -95,6 +95,16 @@ impl Fork {
         let overlay = BlockchainOverlay::new(blockchain)?;
         let overlay = BlockchainOverlay::new(blockchain)?;
         Ok(Self { overlay, proposals: vec![] })
         Ok(Self { overlay, proposals: vec![] })
     }
     }
+
+    /// Auxiliary function to create a full clone using BlockchainOverlay::full_clone.
+    /// Changes to this clone don't affect original record, since underlying overlay
+    /// is cloned and pointers have been updated to the new one.
+    pub fn full_clone(&self) -> Result<Self> {
+        let overlay = self.overlay.lock().unwrap().full_clone()?;
+        let proposals = self.proposals.clone();
+
+        Ok(Self { overlay, proposals })
+    }
 }
 }
 
 
 /// Block producer reward.
 /// Block producer reward.