Procházet zdrojové kódy

blockchain/contract_store: exclude native contracts zkas trees in state monotree computation

skoupidi před 1 rokem
rodič
revize
9b90862028

+ 4 - 2
bin/darkfid/src/rpc_blockchain.rs

@@ -18,13 +18,15 @@
 
 use std::str::FromStr;
 
-use darkfi_sdk::{crypto::ContractId, tx::TransactionHash};
+use darkfi_sdk::{
+    crypto::contract_id::{ContractId, SMART_CONTRACT_ZKAS_DB_NAME},
+    tx::TransactionHash,
+};
 use darkfi_serial::{deserialize_async, serialize_async};
 use log::{debug, error};
 use tinyjson::JsonValue;
 
 use darkfi::{
-    blockchain::contract_store::SMART_CONTRACT_ZKAS_DB_NAME,
     rpc::jsonrpc::{
         ErrorCode::{InternalError, InvalidParams, ParseError},
         JsonError, JsonResponse, JsonResult,

+ 26 - 8
src/blockchain/contract_store.rs

@@ -19,7 +19,10 @@ r* This program is distributed in the hope that it will be useful,
 use std::{collections::BTreeMap, io::Cursor};
 
 use darkfi_sdk::{
-    crypto::contract_id::{ContractId, NATIVE_CONTRACT_IDS_BYTES},
+    crypto::contract_id::{
+        ContractId, NATIVE_CONTRACT_IDS_BYTES, NATIVE_CONTRACT_ZKAS_DB_NAMES,
+        SMART_CONTRACT_ZKAS_DB_NAME,
+    },
     monotree::Monotree,
 };
 use darkfi_serial::{deserialize, serialize};
@@ -37,9 +40,6 @@ use super::SledDbOverlayPtr;
 pub const SLED_CONTRACTS_TREE: &[u8] = b"_contracts";
 pub const SLED_BINCODE_TREE: &[u8] = b"_wasm_bincode";
 
-/// The hardcoded db name for the zkas circuits database tree
-pub const SMART_CONTRACT_ZKAS_DB_NAME: &str = "_zkas";
-
 /// The `ContractStore` is a structure representing all `sled` trees related
 /// to storing the blockchain's contracts information.
 #[derive(Clone)]
@@ -260,7 +260,7 @@ impl ContractStore {
     /// Generate a Monotree(SMT) containing all contracts states
     /// checksums, along with the wasm bincodes checksum.
     ///
-    /// Note: native contracts wasm bincodes are excluded.
+    /// Note: native contracts zkas tree and wasm bincodes are excluded.
     pub fn get_state_monotree(&self, db: &sled::Db) -> Result<Monotree> {
         // Initialize the monotree
         let mut root = None;
@@ -272,6 +272,11 @@ impl ContractStore {
             // Iterate over contract states pointers
             let state_pointers: Vec<[u8; 32]> = deserialize(&state_record?)?;
             for state_ptr in state_pointers {
+                // Skip native zkas tree
+                if NATIVE_CONTRACT_ZKAS_DB_NAMES.contains(&state_ptr) {
+                    continue
+                }
+
                 // Grab the state tree
                 let state_tree = db.open_tree(state_ptr)?;
 
@@ -450,7 +455,7 @@ impl ContractStoreOverlay {
     /// checksums, along with the wasm bincodes checksum.
     /// Be carefull as this will open all states trees in the overlay.
     ///
-    /// Note: native contracts wasm bincodes are excluded.
+    /// Note: native contracts zkas tree and wasm bincodes are excluded.
     pub fn get_state_monotree(&self) -> Result<Monotree> {
         let mut lock = self.0.lock().unwrap();
 
@@ -459,6 +464,10 @@ impl ContractStoreOverlay {
         for state_record in lock.iter(SLED_CONTRACTS_TREE)? {
             let state_pointers: Vec<[u8; 32]> = deserialize(&state_record?.1)?;
             for state_ptr in state_pointers {
+                // Skip native zkas tree
+                if NATIVE_CONTRACT_ZKAS_DB_NAMES.contains(&state_ptr) {
+                    continue
+                }
                 states_pointers.push(state_ptr);
             }
         }
@@ -510,6 +519,8 @@ impl ContractStoreOverlay {
     /// Compute all updated contracts states and wasm bincodes
     /// checksums and update their records in the provided
     /// Monotree(SMT).
+    ///
+    /// Note: native contracts zkas tree and wasm bincodes are excluded.
     pub fn update_state_monotree(&self, tree: &mut Monotree) -> Result<()> {
         let lock = self.0.lock().unwrap();
 
@@ -520,11 +531,18 @@ impl ContractStoreOverlay {
             // Check if that cache is a contract state one.
             // Overlay protected trees are all the native/non-contract ones.
             if !lock.state.protected_tree_names.contains(state_key) {
+                let state_key = deserialize(state_key)?;
+
+                // Skip native zkas tree
+                if NATIVE_CONTRACT_ZKAS_DB_NAMES.contains(&state_key) {
+                    continue
+                }
+
                 // Compute its checksum
-                let checksum = sled_overlay_tree_checksum(&lock, state_key)?;
+                let checksum = sled_overlay_tree_checksum(&lock, &state_key)?;
 
                 // Insert record to monotree
-                root = tree.insert(root.as_ref(), &deserialize(state_key)?, &checksum)?;
+                root = tree.insert(root.as_ref(), &state_key, &checksum)?;
                 tree.set_headroot(root.as_ref());
 
                 continue

+ 2 - 2
src/blockchain/mod.rs

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

+ 3 - 2
src/contract/test-harness/src/vks.rs

@@ -24,7 +24,6 @@ use std::{
 };
 
 use darkfi::{
-    blockchain::contract_store::SMART_CONTRACT_ZKAS_DB_NAME,
     zk::{empty_witnesses, ProvingKey, VerifyingKey, ZkCircuit},
     zkas::ZkBinary,
     Result,
@@ -41,7 +40,9 @@ use darkfi_money_contract::{
     MONEY_CONTRACT_ZKAS_FEE_NS_V1, MONEY_CONTRACT_ZKAS_MINT_NS_V1,
     MONEY_CONTRACT_ZKAS_TOKEN_MINT_NS_V1,
 };
-use darkfi_sdk::crypto::{DAO_CONTRACT_ID, MONEY_CONTRACT_ID};
+use darkfi_sdk::crypto::contract_id::{
+    DAO_CONTRACT_ID, MONEY_CONTRACT_ID, SMART_CONTRACT_ZKAS_DB_NAME,
+};
 use darkfi_serial::{deserialize, serialize};
 
 use log::debug;

+ 4 - 2
src/runtime/import/db.rs

@@ -18,14 +18,16 @@
 
 use std::io::Cursor;
 
-use darkfi_sdk::{crypto::ContractId, wasm};
+use darkfi_sdk::{
+    crypto::contract_id::{ContractId, SMART_CONTRACT_ZKAS_DB_NAME},
+    wasm,
+};
 use darkfi_serial::{deserialize, serialize, Decodable};
 use log::{debug, error, info};
 use wasmer::{FunctionEnvMut, WasmPtr};
 
 use super::acl::acl_allow;
 use crate::{
-    blockchain::contract_store::SMART_CONTRACT_ZKAS_DB_NAME,
     runtime::vm_runtime::{ContractSection, Env},
     zk::{empty_witnesses, VerifyingKey, ZkCircuit},
     zkas::ZkBinary,

+ 6 - 5
src/runtime/vm_runtime.rs

@@ -21,7 +21,11 @@ use std::{
     sync::Arc,
 };
 
-use darkfi_sdk::{crypto::ContractId, tx::TransactionHash, wasm, AsHex};
+use darkfi_sdk::{
+    crypto::contract_id::{ContractId, SMART_CONTRACT_ZKAS_DB_NAME},
+    tx::TransactionHash,
+    wasm, AsHex,
+};
 use darkfi_serial::serialize;
 use log::{debug, error, info};
 use wasmer::{
@@ -35,10 +39,7 @@ use wasmer_middlewares::{
 };
 
 use super::{import, import::db::DbHandle, memory::MemoryManipulation};
-use crate::{
-    blockchain::{contract_store::SMART_CONTRACT_ZKAS_DB_NAME, BlockchainOverlayPtr},
-    Error, Result,
-};
+use crate::{blockchain::BlockchainOverlayPtr, Error, Result};
 
 /// Name of the wasm linear memory in our guest module
 const MEMORY: &str = "memory";

+ 10 - 0
src/sdk/src/crypto/contract_id.rs

@@ -25,6 +25,9 @@ use pasta_curves::{group::ff::PrimeField, pallas};
 use super::{poseidon_hash, PublicKey, SecretKey};
 use crate::error::ContractError;
 
+/// The hardcoded db name for the zkas circuits database tree
+pub const SMART_CONTRACT_ZKAS_DB_NAME: &str = "_zkas";
+
 lazy_static! {
     // The idea here is that 0 is not a valid x coordinate for any pallas point,
     // therefore a signature cannot be produced for such IDs. This allows us to
@@ -55,6 +58,13 @@ lazy_static! {
     /// Native contract IDs bytes, for various checks
     pub static ref NATIVE_CONTRACT_IDS_BYTES: [[u8; 32]; 3] =
         [MONEY_CONTRACT_ID.to_bytes(), DAO_CONTRACT_ID.to_bytes(), DEPLOYOOOR_CONTRACT_ID.to_bytes()];
+
+    /// Native contract zkas circuits database trees, for various checks
+    pub static ref NATIVE_CONTRACT_ZKAS_DB_NAMES: [[u8; 32]; 3] = [
+        MONEY_CONTRACT_ID.hash_state_id(SMART_CONTRACT_ZKAS_DB_NAME),
+        DAO_CONTRACT_ID.hash_state_id(SMART_CONTRACT_ZKAS_DB_NAME),
+        DEPLOYOOOR_CONTRACT_ID.hash_state_id(SMART_CONTRACT_ZKAS_DB_NAME),
+    ];
 }
 
 /// ContractId represents an on-chain identifier for a certain smart contract.