blockchain/contract_store: get_state_monotree now returns the fully updated monotree from the overlay

This commit is contained in:
skoupidi
2025-08-27 16:18:32 +03:00
parent a140ae53b1
commit 0b8d6c25fe
9 changed files with 30 additions and 36 deletions

View File

@@ -89,9 +89,8 @@ impl Harness {
vks::inject(&sled_db, &vks)?;
let overlay = BlockchainOverlay::new(&Blockchain::new(&sled_db)?)?;
deploy_native_contracts(&overlay, config.pow_target).await?;
let mut state_monotree = overlay.lock().unwrap().contracts.get_state_monotree()?;
overlay.lock().unwrap().contracts.update_state_monotree(&mut state_monotree)?;
genesis_block.header.state_root = state_monotree.get_headroot()?.unwrap();
genesis_block.header.state_root =
overlay.lock().unwrap().get_state_monotree()?.get_headroot()?.unwrap();
// Generate validators configuration
// NOTE: we are not using consensus constants here so we
@@ -246,9 +245,8 @@ impl Harness {
&mut MerkleTree::new(1),
)
.await?;
let mut monotree = overlay.lock().unwrap().contracts.get_state_monotree()?;
overlay.lock().unwrap().contracts.update_state_monotree(&mut monotree)?;
block.header.state_root = monotree.get_headroot()?.unwrap();
block.header.state_root =
overlay.lock().unwrap().get_state_monotree()?.get_headroot()?.unwrap();
// Attach signature
block.sign(&keypair.secret);

View File

@@ -259,15 +259,14 @@ fn darkfid_programmatic_control() -> Result<()> {
)
.unwrap();
darkfi::validator::utils::deploy_native_contracts(&overlay, 20).await.unwrap();
let mut state_monotree =
overlay.lock().unwrap().contracts.get_state_monotree().unwrap();
overlay
genesis_block.header.state_root = overlay
.lock()
.unwrap()
.contracts
.update_state_monotree(&mut state_monotree)
.get_state_monotree()
.unwrap()
.get_headroot()
.unwrap()
.unwrap();
genesis_block.header.state_root = state_monotree.get_headroot().unwrap().unwrap();
let bootstrap = genesis_block.header.timestamp.inner();
let config = darkfi::validator::ValidatorConfig {
confirmation_threshold: 1,

View File

@@ -170,8 +170,7 @@ fn main() -> Result<()> {
genesis_block.header.transactions_root = tree.root(0).unwrap();
// Grab the updated contracts states root
let mut state_monotree = overlay.lock().unwrap().get_state_monotree()?;
overlay.lock().unwrap().contracts.update_state_monotree(&mut state_monotree)?;
let state_monotree = overlay.lock().unwrap().get_state_monotree()?;
let Some(state_root) = state_monotree.get_headroot()? else {
return Err(Error::ContractsStatesRootNotFoundError);
};

View File

@@ -490,8 +490,6 @@ impl ContractStoreOverlay {
/// Generate a Monotree(SMT) containing all contracts states
/// roots, along with the wasm bincodes monotree roots.
/// Be carefull as this will open all states monotrees in the overlay.
/// If overlay holds changes the generated monotree must be updated
/// using update_state_monotree().
///
/// Note: native contracts zkas tree and wasm bincodes are excluded.
pub fn get_state_monotree(&self) -> Result<Monotree<MemoryDb>> {
@@ -566,6 +564,10 @@ impl ContractStoreOverlay {
&wasm_monotree_root,
)?;
tree.set_headroot(root.as_ref());
drop(lock);
// Update the monotree to the latest overlay changes
self.update_state_monotree(&mut tree)?;
Ok(tree)
}

View File

@@ -425,7 +425,7 @@ impl Blockchain {
}
/// Generate a Monotree(SMT) containing all contracts states
/// checksums, along with the wasm bincodes checksum.
/// roots, along with the wasm bincodes monotree root.
///
/// Note: native contracts zkas tree and wasm bincodes are excluded.
pub fn get_state_monotree(&self) -> Result<Monotree<monotree::MemoryDb>> {
@@ -693,9 +693,9 @@ impl BlockchainOverlay {
}
/// Generate a Monotree(SMT) containing all contracts states
/// checksums, along with the wasm bincodes checksum.
/// roots, along with the wasm bincodes monotree root.
/// A clone is used so we are not affected by the opened trees
/// during checksum computing.
/// during roots computing.
///
/// Note: native contracts zkas tree and wasm bincodes are excluded.
pub fn get_state_monotree(&self) -> Result<Monotree<monotree::MemoryDb>> {

View File

@@ -276,9 +276,8 @@ impl TestHarness {
vks::inject(&sled_db, &vks)?;
let overlay = BlockchainOverlay::new(&Blockchain::new(&sled_db)?)?;
deploy_native_contracts(&overlay, 90).await?;
let mut state_monotree = overlay.lock().unwrap().contracts.get_state_monotree()?;
overlay.lock().unwrap().contracts.update_state_monotree(&mut state_monotree)?;
genesis_block.header.state_root = state_monotree.get_headroot()?.unwrap();
genesis_block.header.state_root =
overlay.lock().unwrap().get_state_monotree()?.get_headroot()?.unwrap();
// Create `Wallet` instances
let mut holders_map = HashMap::new();

View File

@@ -145,9 +145,8 @@ impl TestHarness {
&mut MerkleTree::new(1),
)
.await?;
let mut monotree = overlay.lock().unwrap().contracts.get_state_monotree()?;
overlay.lock().unwrap().contracts.update_state_monotree(&mut monotree)?;
block.header.state_root = monotree.get_headroot()?.unwrap();
block.header.state_root =
overlay.lock().unwrap().get_state_monotree()?.get_headroot()?.unwrap();
// Attach signature
block.sign(&wallet.keypair.secret);

View File

@@ -644,13 +644,13 @@ impl Consensus {
Ok(())
}
/// Auxiliary function to check current contracts states checksums
/// Auxiliary function to check current contracts states
/// Monotree(SMT) validity in all active forks and canonical.
pub async fn healthcheck(&self) -> Result<()> {
// Grab a lock over current forks
let lock = self.forks.read().await;
// Rebuild current canonical contract states checksums monotree
// Rebuild current canonical contract states monotree
let state_monotree = self.blockchain.get_state_monotree()?;
// Check that the root matches last block header state root
@@ -709,7 +709,7 @@ pub struct Fork {
pub overlay: BlockchainOverlayPtr,
/// Current PoW module state
pub module: PoWModule,
/// Current contracts states checksums Monotree(SMT)
/// Current contracts states Monotree(SMT)
pub state_monotree: Monotree<monotree::MemoryDb>,
/// Fork proposal hashes sequence
pub proposals: Vec<HeaderHash>,
@@ -727,7 +727,7 @@ impl Fork {
pub async fn new(blockchain: Blockchain, module: PoWModule) -> Result<Self> {
let mempool = blockchain.get_pending_txs()?.iter().map(|tx| tx.hash()).collect();
let overlay = BlockchainOverlay::new(&blockchain)?;
// Build current contract states checksums monotree
// Build current contract states monotree
let state_monotree = overlay.lock().unwrap().get_state_monotree()?;
// Retrieve last block difficulty to access current ranks
let last_difficulty = blockchain.last_block_difficulty()?;
@@ -927,22 +927,21 @@ impl Fork {
})
}
/// Build current contract states checksums monotree.
/// Build current contract states monotree.
pub fn compute_monotree(&mut self) -> Result<()> {
self.state_monotree = self.overlay.lock().unwrap().get_state_monotree()?;
Ok(())
}
/// Auxiliary function to check current contracts states checksums
/// Auxiliary function to check current contracts states
/// Monotree(SMT) validity.
///
/// Note: This should be executed on fresh forks and/or when
/// a fork doesn't contain changes over the last appended
// proposal.
pub fn healthcheck(&self) -> Result<()> {
// Rebuild current contract states checksums monotree
let mut state_monotree = self.overlay.lock().unwrap().get_state_monotree()?;
self.overlay.lock().unwrap().contracts.update_state_monotree(&mut state_monotree)?;
// Rebuild current contract states monotree
let state_monotree = self.overlay.lock().unwrap().get_state_monotree()?;
// Check that it matches forks' tree
let Some(state_root) = state_monotree.get_headroot()? else {

View File

@@ -116,8 +116,7 @@ pub async fn verify_genesis_block(
}
// Verify header contracts states root
let mut state_monotree = overlay.lock().unwrap().get_state_monotree()?;
overlay.lock().unwrap().contracts.update_state_monotree(&mut state_monotree)?;
let state_monotree = overlay.lock().unwrap().contracts.get_state_monotree()?;
let Some(state_root) = state_monotree.get_headroot()? else {
return Err(Error::ContractsStatesRootNotFoundError);
};