blockchain: overlay pointers handling

This commit is contained in:
aggstam
2023-07-27 18:42:31 +03:00
parent d74360ac84
commit 2a35e0af83
4 changed files with 94 additions and 0 deletions

View File

@@ -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(())
}

View File

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

View File

@@ -540,6 +540,30 @@ impl BlockchainOverlay {
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`).

View File

@@ -95,6 +95,16 @@ impl Fork {
let overlay = BlockchainOverlay::new(blockchain)?;
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.