Просмотр исходного кода

runtime: Minor comment cleanups and log verbosity.

parazyd 2 лет назад
Родитель
Сommit
e034470611
1 измененных файлов с 57 добавлено и 41 удалено
  1. 57 41
      src/runtime/vm_runtime.rs

+ 57 - 41
src/runtime/vm_runtime.rs

@@ -44,7 +44,7 @@ use crate::{
 /// Name of the wasm linear memory in our guest module
 const MEMORY: &str = "memory";
 
-/// Gas limit for a contract
+/// Gas limit for a single contract call (Single WASM instance)
 const GAS_LIMIT: u64 = 400_000_000;
 
 // ANCHOR: contract-section
@@ -75,7 +75,7 @@ impl ContractSection {
     }
 }
 
-/// The wasm vm runtime instantiated for every smart contract that runs.
+/// The WASM VM runtime environment instantiated for every smart contract that runs.
 pub struct Env {
     /// Blockchain overlay access
     pub blockchain: BlockchainOverlayPtr,
@@ -135,7 +135,7 @@ impl Runtime {
         contract_id: ContractId,
         time_keeper: TimeKeeper,
     ) -> Result<Self> {
-        info!(target: "runtime::vm_runtime", "Instantiating a new runtime");
+        info!(target: "runtime::vm_runtime", "[WASM] Instantiating a new runtime");
         // This function will be called for each `Operator` encountered during
         // the wasm module execution. It should return the cost of the operator
         // that it received as its first argument. For now, every wasm opcode
@@ -306,8 +306,8 @@ impl Runtime {
     }
 
     /// Call a contract method defined by a [`ContractSection`] using a supplied
-    /// payload. Returns a Vector of bytes corresponding to the result data of the call.
-    /// For calls that do not return any data, an empty Vector is returned.
+    /// payload. Returns a `Vec<u8>` corresponding to the result data of the call.
+    /// For calls that do not return any data, an empty `Vec<u8>` is returned.
     fn call(&mut self, section: ContractSection, payload: &[u8]) -> Result<Vec<u8>> {
         debug!(target: "runtime::vm_runtime", "Calling {} method", section.name());
 
@@ -316,10 +316,6 @@ impl Runtime {
         // Verify contract's return data is empty, or quit.
         assert!(env_mut.contract_return_data.take().is_none());
 
-        // This should already be clear, or the assert call above
-        // would prevent the code from reaching this point.
-        // Clear anyway, to be safe.
-        env_mut.contract_return_data.set(None);
         // Clear the logs
         let _ = env_mut.logs.take();
 
@@ -343,14 +339,14 @@ impl Runtime {
         let ret = match entrypoint.call(&mut self.store, &[Value::I32(0_i32)]) {
             Ok(retvals) => {
                 self.print_logs();
-                info!(target: "runtime::vm_runtime", "{}", self.gas_info());
+                info!(target: "runtime::vm_runtime", "[WASM] {}", self.gas_info());
                 retvals
             }
             Err(e) => {
                 self.print_logs();
-                info!(target: "runtime::vm_runtime", "{}", self.gas_info());
+                info!(target: "runtime::vm_runtime", "[WASM] {}", self.gas_info());
                 // WasmerRuntimeError panics are handled here. Return from run() immediately.
-                error!(target: "runtime::vm_runtime", "Wasmer Runtime Error: {:#?}", e);
+                error!(target: "runtime::vm_runtime", "[WASM] Wasmer Runtime Error: {:#?}", e);
                 return Err(e.into())
             }
         };
@@ -392,55 +388,50 @@ impl Runtime {
         // result data. Otherwise, map the integer return value to a [`ContractError`].
         match retval {
             entrypoint::SUCCESS => Ok(retdata),
-            // FIXME: we should be able to see the error returned from the contract
-            // We can put sdk::Error inside of this.
             _ => {
                 let err = darkfi_sdk::error::ContractError::from(retval);
+                error!(target: "runtime::vm_runtime", "[WASM] Contract returned: {:?}", err);
                 Err(Error::ContractError(err))
             }
         }
     }
 
     /// This function runs when a smart contract is initially deployed, or re-deployed.
-    /// The runtime will look for an `INITIALIZE` symbol in the wasm code, and execute
+    ///
+    /// The runtime will look for an `__initialize` symbol in the wasm code, and execute
     /// it if found. Optionally, it is possible to pass in a payload for any kind of special
     /// instructions the developer wants to manage in the initialize function.
+    ///
     /// This process is supposed to set up the overlay trees for storing the smart contract
     /// state, and it can create, delete, modify, read, and write to databases it's allowed to.
     /// The permissions for this are handled by the `ContractId` in the overlay db API so we
     /// assume that the contract is only able to do write operations on its own overlay trees.
-    /// TODO: This should also be in sled-overlay!
     pub fn deploy(&mut self, payload: &[u8]) -> Result<()> {
-        info!(target: "runtime::vm_runtime", "[wasm-runtime] Running deploy");
+        let cid = self.ctx.as_ref(&self.store).contract_id;
+        info!(target: "runtime::vm_runtime", "[WASM] Running deploy() for ContractID: {}", cid);
 
         // Scoped for borrows
         {
             let env_mut = self.ctx.as_mut(&mut self.store);
-
             // We always want to have the zkas db as index 0 in db handles and batches when
             // deploying.
             let contracts = &env_mut.blockchain.lock().unwrap().contracts;
 
+            // Open or create the zkas db tree for this contract
             let zkas_tree_handle =
                 match contracts.lookup(&env_mut.contract_id, SMART_CONTRACT_ZKAS_DB_NAME) {
                     Ok(v) => v,
-                    Err(_) => {
-                        // FIXME: All this is deploy code is "vulnerable" and able to init a
-                        // tree regardless of execution success. We can easily delete the db
-                        // if execution fails though, and we should charge gas for db_init.
-                        // and perhaps also for the zkas database in this specific case.
-                        contracts.init(&env_mut.contract_id, SMART_CONTRACT_ZKAS_DB_NAME)?
-                    }
+                    Err(_) => contracts.init(&env_mut.contract_id, SMART_CONTRACT_ZKAS_DB_NAME)?,
                 };
 
             let mut db_handles = env_mut.db_handles.borrow_mut();
             db_handles.push(DbHandle::new(env_mut.contract_id, zkas_tree_handle));
         }
 
-        //debug!(target: "runtime::vm_runtime", "[wasm-runtime] payload: {:?}", payload);
+        //debug!(target: "runtime::vm_runtime", "[WASM] payload: {:?}", payload);
         let _ = self.call(ContractSection::Deploy, payload)?;
 
-        // Update the wasm bincode in the WasmStore
+        // Update the wasm bincode in the WasmStore if the deploy exec passed successfully.
         let env_mut = self.ctx.as_mut(&mut self.store);
         env_mut
             .blockchain
@@ -449,36 +440,61 @@ impl Runtime {
             .wasm_bincode
             .insert(env_mut.contract_id, &env_mut.contract_bincode)?;
 
+        info!(target: "runtime::vm_runtime", "[WASM] Successfully deployed ContractID: {}", cid);
         Ok(())
     }
 
+    /// This function runs first in the entire scheme of executing a smart contract.
+    ///
+    /// The runtime will look for a `__metadata` symbol in the wasm code and execute it.
+    /// It is supposed to correctly extract public inputs for any ZK proofs included
+    /// in the contract calls, and also extract the public keys used to verify the
+    /// call/transaction signatures.
+    pub fn metadata(&mut self, payload: &[u8]) -> Result<Vec<u8>> {
+        let cid = self.ctx.as_ref(&self.store).contract_id;
+        info!(target: "runtime::vm_runtime", "[WASM] Running metadata() for ContractID: {}", cid);
+
+        debug!(target: "runtime::vm_runtime", "metadata payload: {:?}", payload);
+        let ret = self.call(ContractSection::Metadata, payload)?;
+        debug!(target: "runtime::vm_runtime", "metadata returned: {:?}", ret);
+
+        info!(target: "runtime::vm_runtime", "[WASM] Successfully got metadata ContractID: {}", cid);
+        Ok(ret)
+    }
+
     /// This function runs when someone wants to execute a smart contract.
-    /// The runtime will look for an `ENTRYPOINT` symbol in the wasm code, and
+    ///
+    /// The runtime will look for an `__entrypoint` symbol in the wasm code, and
     /// execute it if found. A payload is also passed as an instruction that can
     /// be used inside the vm by the runtime.
     pub fn exec(&mut self, payload: &[u8]) -> Result<Vec<u8>> {
-        debug!(target: "runtime::vm_runtime", "exec: {:?}", payload);
-        self.call(ContractSection::Exec, payload)
+        let cid = self.ctx.as_ref(&self.store).contract_id;
+        info!(target: "runtime::vm_runtime", "[WASM] Running exec() for ContractID: {}", cid);
+
+        debug!(target: "runtime::vm_runtime", "exec payload: {:?}", payload);
+        let ret = self.call(ContractSection::Exec, payload)?;
+        debug!(target: "runtime::vm_runtime", "exec returned: {:?}", ret);
+
+        info!(target: "runtime::vm_runtime", "[WASM] Successfully executed ContractID: {}", cid);
+        Ok(ret)
     }
 
     /// This function runs after successful execution of `exec` and tries to
     /// apply the state change to the overlay databases.
-    /// The runtime will lok for an `UPDATE` symbol in the wasm code, and execute
+    ///
+    /// The runtime will lok for an `__update` symbol in the wasm code, and execute
     /// it if found. The function does not take an arbitrary payload, but just takes
     /// a state update from `env` and passes it into the wasm runtime.
     pub fn apply(&mut self, update: &[u8]) -> Result<()> {
-        debug!(target: "runtime::vm_runtime", "apply: {:?}", update);
-        let _ = self.call(ContractSection::Update, update)?;
+        let cid = self.ctx.as_ref(&self.store).contract_id;
+        info!(target: "runtime::vm_runtime", "[WASM] Running apply() for ContractID: {}", cid);
 
-        Ok(())
-    }
+        debug!(target: "runtime::vm_runtime", "apply payload: {:?}", update);
+        let ret = self.call(ContractSection::Update, update)?;
+        debug!(target: "runtime::vm_runtime", "apply returned: {:?}", ret);
 
-    /// This function runs first in the entire scheme of executing a smart contract.
-    /// It is supposed to correctly extract public inputs for any ZK proofs included
-    /// in the contract calls, and also extract the public keys used to verify the
-    /// call/transaction signatures.
-    pub fn metadata(&mut self, payload: &[u8]) -> Result<Vec<u8>> {
-        self.call(ContractSection::Metadata, payload)
+        info!(target: "runtime::vm_runtime", "[WASM] Successfully applied ContractID: {}", cid);
+        Ok(())
     }
 
     /// Prints the wasm contract logs.