Explorar el Código

contract/test-harness/vks: updated hashes and modify inject to work over an overlay not the actual db so we ensure native zkas can be included in all genesis monotrees

skoupidi hace 6 meses
padre
commit
b78ca1d796

+ 1 - 1
bin/darkfid/genesis_block_localnet

@@ -1 +1 @@
-AYa7rEMKSzoYLxJbN6SG6cSGu/o02E70pmtKI+XwxiWxAAAAAAAAAADNGW5pAAAAADs822+Z8eocSeM2cBLVQuRsIQzi4hikKA26/mTDYRMI3B26eM431XcoU3nvP3rIX5PBf+lWoUENTTZy5HiNw8wAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+AYa7rEMKSzoYLxJbN6SG6cSGu/o02E70pmtKI+XwxiWxAAAAAAAAAADVem5pAAAAADs822+Z8eocSeM2cBLVQuRsIQzi4hikKA26/mTDYRMI3B26eM431XcoU3nvP3rIX5PBf+lWoUENTTZy5HiNw8wAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=

+ 1 - 1
bin/darkfid/genesis_block_mainnet

@@ -1 +1 @@
-AYa7rEMKSzoYLxJbN6SG6cSGu/o02E70pmtKI+XwxiWxAAAAAAAAAAAXGm5pAAAAADs822+Z8eocSeM2cBLVQuRsIQzi4hikKA26/mTDYRMI3B26eM431XcoU3nvP3rIX5PBf+lWoUENTTZy5HiNw8wAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+AYa7rEMKSzoYLxJbN6SG6cSGu/o02E70pmtKI+XwxiWxAAAAAAAAAADfem5pAAAAADs822+Z8eocSeM2cBLVQuRsIQzi4hikKA26/mTDYRMI3B26eM431XcoU3nvP3rIX5PBf+lWoUENTTZy5HiNw8wAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=

+ 1 - 1
bin/darkfid/genesis_block_testnet

@@ -1 +1 @@
-AYa7rEMKSzoYLxJbN6SG6cSGu/o02E70pmtKI+XwxiWxAAAAAAAAAADxGW5pAAAAADs822+Z8eocSeM2cBLVQuRsIQzi4hikKA26/mTDYRMI3B26eM431XcoU3nvP3rIX5PBf+lWoUENTTZy5HiNw8wAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+AYa7rEMKSzoYLxJbN6SG6cSGu/o02E70pmtKI+XwxiWxAAAAAAAAAADaem5pAAAAADs822+Z8eocSeM2cBLVQuRsIQzi4hikKA26/mTDYRMI3B26eM431XcoU3nvP3rIX5PBf+lWoUENTTZy5HiNw8wAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=

+ 8 - 4
bin/darkfid/src/tests/harness.rs

@@ -88,10 +88,10 @@ impl Harness {
         genesis_block.append_txs(vec![producer_tx]);
 
         // Compute genesis contracts states monotree root
-        let (_, vks) = vks::get_cached_pks_and_vks()?;
         let sled_db = sled::Config::new().temporary(true).open()?;
-        vks::inject(&sled_db, &vks)?;
         let overlay = BlockchainOverlay::new(&Blockchain::new(&sled_db)?)?;
+        let (_, vks) = vks::get_cached_pks_and_vks()?;
+        vks::inject(&overlay, &vks)?;
         deploy_native_contracts(&overlay, config.pow_target).await?;
         let diff = overlay.lock().unwrap().overlay.lock().unwrap().diff(&[])?;
         genesis_block.header.state_root =
@@ -282,8 +282,12 @@ pub async fn generate_node(
     checkpoint: Option<(u32, HeaderHash)>,
 ) -> Result<DarkfiNodePtr> {
     let sled_db = sled::Config::new().temporary(true).open()?;
-    vks::inject(&sled_db, vks)?;
-
+    let overlay = BlockchainOverlay::new(&Blockchain::new(&sled_db)?)?;
+    vks::inject(&overlay, vks)?;
+    deploy_native_contracts(&overlay, config.pow_target).await?;
+    let diff = overlay.lock().unwrap().overlay.lock().unwrap().diff(&[])?;
+    overlay.lock().unwrap().contracts.update_state_monotree(&diff)?;
+    overlay.lock().unwrap().overlay.lock().unwrap().apply()?;
     let validator = Validator::new(&sled_db, config).await?;
 
     let mut subscribers = HashMap::new();

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

@@ -252,12 +252,12 @@ fn darkfid_programmatic_control() -> Result<()> {
                 let producer_tx = genesis_block.txs.pop().unwrap();
                 genesis_block.append_txs(vec![producer_tx]);
                 let sled_db = sled_overlay::sled::Config::new().temporary(true).open().unwrap();
-                let (_, vks) = darkfi_contract_test_harness::vks::get_cached_pks_and_vks().unwrap();
-                darkfi_contract_test_harness::vks::inject(&sled_db, &vks).unwrap();
                 let overlay = darkfi::blockchain::BlockchainOverlay::new(
                     &darkfi::blockchain::Blockchain::new(&sled_db).unwrap(),
                 )
                 .unwrap();
+                let (_, vks) = darkfi_contract_test_harness::vks::get_cached_pks_and_vks().unwrap();
+                darkfi_contract_test_harness::vks::inject(&overlay, &vks).unwrap();
                 darkfi::validator::utils::deploy_native_contracts(&overlay, 20).await.unwrap();
                 let diff = overlay.lock().unwrap().overlay.lock().unwrap().diff(&[]).unwrap();
                 genesis_block.header.state_root =

+ 10 - 5
script/research/gg/src/main.rs

@@ -135,12 +135,12 @@ fn main() -> Result<()> {
 
                 // Initialize a temporary sled database
                 let sled_db = sled::Config::new().temporary(true).open()?;
-                let (_, vks) = vks::get_cached_pks_and_vks()?;
-                vks::inject(&sled_db, &vks)?;
 
                 // Create an overlay over whole blockchain
                 let blockchain = Blockchain::new(&sled_db)?;
                 let overlay = BlockchainOverlay::new(&blockchain)?;
+                let (_, vks) = vks::get_cached_pks_and_vks()?;
+                vks::inject(&overlay, &vks)?;
                 deploy_native_contracts(&overlay, 0).await?;
 
                 // Grab genesis transactions from folder
@@ -187,15 +187,20 @@ fn main() -> Result<()> {
 
                 // Initialize a temporary sled database
                 let sled_db = sled::Config::new().temporary(true).open()?;
-                let (_, vks) = vks::get_cached_pks_and_vks()?;
-                vks::inject(&sled_db, &vks)?;
 
                 // Create an overlay over whole blockchain
                 let blockchain = Blockchain::new(&sled_db)?;
                 let overlay = BlockchainOverlay::new(&blockchain)?;
+                let (_, vks) = vks::get_cached_pks_and_vks()?;
+                vks::inject(&overlay, &vks)?;
                 deploy_native_contracts(&overlay, 0).await?;
 
-                verify_genesis_block(&overlay, &genesis_block, 0).await?;
+                // Update the contracts states monotree
+                let diff = overlay.lock().unwrap().overlay.lock().unwrap().diff(&[])?;
+                overlay.lock().unwrap().contracts.update_state_monotree(&diff)?;
+
+                // Validate genesis block
+                verify_genesis_block(&overlay, &[diff], &genesis_block, 0).await?;
 
                 println!("Genesis block {hash} verified successfully!");
             }

+ 7 - 5
src/blockchain/contract_store.rs

@@ -472,11 +472,11 @@ impl ContractStoreOverlay {
 
         // Iterate over diff caches to find all contracts updates
         let mut contracts_updates: BTreeMap<[u8; 32], ContractMonotreeUpdates> = BTreeMap::new();
-        for (state_key, state_cache) in &diff.caches {
+        for (state_key, (state_cache, _)) in &diff.caches {
             // Grab new/redeployed contracts wasm bincodes to include them
             // in their monotrees, excluding native ones.
             if state_key == SLED_BINCODE_TREE {
-                for (contract_id_bytes, (_, value)) in &state_cache.0.cache {
+                for (contract_id_bytes, (_, value)) in &state_cache.cache {
                     // Grab the actual contract ID bytes
                     let contract_id_bytes = deserialize(contract_id_bytes)?;
 
@@ -539,7 +539,7 @@ impl ContractStoreOverlay {
             // Handle the contract zkas tree
             if contract_id.hash_state_id(SMART_CONTRACT_ZKAS_DB_NAME) == state_key {
                 // Grab the new/updated keys
-                for (key, (_, value)) in &state_cache.0.cache {
+                for (key, (_, value)) in &state_cache.cache {
                     // Prefix key with its tree name
                     let mut hasher = blake3::Hasher::new();
                     hasher.update(&state_key);
@@ -558,7 +558,7 @@ impl ContractStoreOverlay {
             }
 
             // Grab the new/updated keys
-            for (key, (_, value)) in &state_cache.0.cache {
+            for (key, (_, value)) in &state_cache.cache {
                 // Prefix key with its tree name
                 let mut hasher = blake3::Hasher::new();
                 hasher.update(&state_key);
@@ -569,7 +569,7 @@ impl ContractStoreOverlay {
             }
 
             // Grab the dropped keys
-            for key in state_cache.0.removed.keys() {
+            for key in state_cache.removed.keys() {
                 // Prefix key with its tree name
                 let mut hasher = blake3::Hasher::new();
                 hasher.update(&state_key);
@@ -635,6 +635,8 @@ impl ContractStoreOverlay {
 
         // Insert new/updated contracts monotrees roots
         for (contract_id_bytes, contract_monotree_root) in &contracts_roots {
+            let contract_id: ContractId = deserialize(contract_id_bytes)?;
+            debug!(target: "blockchain::contractstoreoverlay::update_state_monotree", "Inserting key {contract_id} with value: {}", blake3::Hash::from(*contract_monotree_root));
             monotree_root = monotree.insert(
                 monotree_root.as_ref(),
                 contract_id_bytes,

+ 4 - 2
src/contract/test-harness/src/lib.rs

@@ -164,7 +164,9 @@ impl Wallet {
         let sled_db = sled::Config::new().temporary(true).open()?;
 
         // Inject the cached VKs into the database
-        vks::inject(&sled_db, vks)?;
+        let overlay = BlockchainOverlay::new(&Blockchain::new(&sled_db)?)?;
+        vks::inject(&overlay, vks)?;
+        overlay.lock().unwrap().overlay.lock().unwrap().apply()?;
 
         // Create the `Validator` instance
         let validator_config = ValidatorConfig {
@@ -274,8 +276,8 @@ impl TestHarness {
 
         // Compute genesis contracts states monotree root
         let sled_db = sled::Config::new().temporary(true).open()?;
-        vks::inject(&sled_db, &vks)?;
         let overlay = BlockchainOverlay::new(&Blockchain::new(&sled_db)?)?;
+        vks::inject(&overlay, &vks)?;
         deploy_native_contracts(&overlay, 90).await?;
         let diff = overlay.lock().unwrap().overlay.lock().unwrap().diff(&[])?;
         genesis_block.header.state_root =

+ 15 - 10
src/contract/test-harness/src/vks.rs

@@ -24,6 +24,7 @@ use std::{
 };
 
 use darkfi::{
+    blockchain::BlockchainOverlayPtr,
     zk::{empty_witnesses, ProvingKey, VerifyingKey, ZkCircuit},
     zkas::ZkBinary,
     Result,
@@ -44,13 +45,12 @@ use darkfi_sdk::crypto::contract_id::{
 };
 use darkfi_serial::{deserialize, serialize};
 
-use sled_overlay::sled;
 use tracing::debug;
 
 /// Update these if any circuits are changed.
 /// Delete the existing cachefiles, and enable debug logging, you will see the new hashes.
-const PKS_HASH: &str = "46a30a57bd14b6bc5851bbde8b011ba2e12765bba7901c5e42f511bdb68b3255";
-const VKS_HASH: &str = "4e6f5326b3acc7fd4f6525914be8076276b16c5601940d034de0617c94b1170f";
+const PKS_HASH: &str = "35ce1debf6ab12d1ec6db2b8c0c2a8a9b1fd25c2ff15c1258548923ce00f781f";
+const VKS_HASH: &str = "415cb6ae64917b4dac078ac47d49408549799b71a39603d5fa4d3e6934eeece9";
 
 /// Build a `PathBuf` to a cachefile
 fn cache_path(typ: &str) -> Result<PathBuf> {
@@ -177,15 +177,20 @@ pub fn get_cached_pks_and_vks() -> Result<(Pks, Vks)> {
     Ok((pks, vks))
 }
 
-/// Inject cached VKs into a given blockchain database reference
-pub fn inject(sled_db: &sled::Db, vks: &Vks) -> Result<()> {
+/// Inject cached VKs into a given blockchain database overlay
+/// reference.
+pub fn inject(overlay: &BlockchainOverlayPtr, vks: &Vks) -> Result<()> {
+    // Grab a lock over the blockchain overlay
+    let lock = overlay.lock().unwrap();
+    let mut overlay = lock.overlay.lock().unwrap();
+
     // Derive the database names for the specific contracts
     let money_db_name = MONEY_CONTRACT_ID.hash_state_id(SMART_CONTRACT_ZKAS_DB_NAME);
     let dao_db_name = DAO_CONTRACT_ID.hash_state_id(SMART_CONTRACT_ZKAS_DB_NAME);
 
-    // Create the db trees
-    let money_tree = sled_db.open_tree(money_db_name)?;
-    let dao_tree = sled_db.open_tree(dao_db_name)?;
+    // Ensure they are open in the overlay
+    overlay.open_tree(&money_db_name, false)?;
+    overlay.open_tree(&dao_db_name, false)?;
 
     for (bincode, namespace, vk) in vks.iter() {
         match namespace.as_str() {
@@ -197,7 +202,7 @@ pub fn inject(sled_db: &sled::Db, vks: &Vks) -> Result<()> {
             MONEY_CONTRACT_ZKAS_AUTH_TOKEN_MINT_NS_V1 => {
                 let key = serialize(&namespace.as_str());
                 let value = serialize(&(bincode.clone(), vk.clone()));
-                money_tree.insert(key, value)?;
+                overlay.insert(&money_db_name, &key, &value)?;
             }
 
             // DAO contract circuits
@@ -212,7 +217,7 @@ pub fn inject(sled_db: &sled::Db, vks: &Vks) -> Result<()> {
             DAO_CONTRACT_ZKAS_AUTH_MONEY_TRANSFER_ENC_COIN_NS => {
                 let key = serialize(&namespace.as_str());
                 let value = serialize(&(bincode.clone(), vk.clone()));
-                dao_tree.insert(key, value)?;
+                overlay.insert(&dao_db_name, &key, &value)?;
             }
 
             x => panic!("Found unhandled zkas namespace {x}"),

+ 3 - 2
src/validator/mod.rs

@@ -113,7 +113,8 @@ impl Validator {
         // Add genesis block if blockchain is empty
         if blockchain.genesis().is_err() {
             info!(target: "validator::new", "Appending genesis block");
-            verify_genesis_block(&overlay, &config.genesis_block, config.pow_target).await?;
+            verify_genesis_block(&overlay, &[diff], &config.genesis_block, config.pow_target)
+                .await?;
         };
 
         // Write the changes to the actual chain db
@@ -763,7 +764,7 @@ impl Validator {
         overlay.lock().unwrap().contracts.update_state_monotree(&diff)?;
 
         // Validate genesis block
-        verify_genesis_block(&overlay, &previous, pow_target).await?;
+        verify_genesis_block(&overlay, &[diff], &previous, pow_target).await?;
         info!(target: "validator::validate_blockchain", "Genesis block validated successfully!");
 
         // Write the changes to the in memory db

+ 2 - 1
src/validator/verification.rs

@@ -54,6 +54,7 @@ use crate::{
 /// Verify given genesis [`BlockInfo`], and apply it to the provided overlay.
 pub async fn verify_genesis_block(
     overlay: &BlockchainOverlayPtr,
+    diffs: &[SledDbOverlayStateDiff],
     block: &BlockInfo,
     block_target: u32,
 ) -> Result<()> {
@@ -116,7 +117,7 @@ pub async fn verify_genesis_block(
     }
 
     // Update the contracts states monotree and verify header contracts states root
-    let diff = overlay.lock().unwrap().overlay.lock().unwrap().diff(&[])?;
+    let diff = overlay.lock().unwrap().overlay.lock().unwrap().diff(diffs)?;
     let state_root = overlay.lock().unwrap().contracts.update_state_monotree(&diff)?;
     if state_root != block.header.state_root {
         return Err(Error::ContractsStatesRootError(