Repository: stellar/rs-soroban-env
Pull request #1280 (2023-12-02 00:58:13)

Bump wasmi and xdr to release versions
Take updates on recent releases of deps


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index c3eb6126..fffe9cd8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1464,8 +1464,8 @@ version = "20.0.0-rc2"
 
 [[package]]
 name = "soroban-wasmi"
-version = "0.31.0-soroban1"
-source = "git+https://github.com/stellar/wasmi?rev=7e63b4c9e08c4163f417d118d81f7ea34789d0be#7e63b4c9e08c4163f417d118d81f7ea34789d0be"
+version = "0.31.1-soroban.20.0.0"
+source = "git+https://github.com/stellar/wasmi?rev=ab29800224d85ee64d4ac127bac84cdbb0276721#ab29800224d85ee64d4ac127bac84cdbb0276721"
 dependencies = [
  "smallvec",
  "spin",
@@ -1509,8 +1509,8 @@ dependencies = [
 
 [[package]]
 name = "stellar-xdr"
-version = "20.0.0-rc1"
-source = "git+https://github.com/stellar/rs-stellar-xdr?rev=97e52f17501fb058ee28bbca3da0ae7897492746#97e52f17501fb058ee28bbca3da0ae7897492746"
+version = "20.0.0"
+source = "git+https://github.com/stellar/rs-stellar-xdr?rev=24dd3c1b9fada6e2b28e8456a915adc212d6c47e#24dd3c1b9fada6e2b28e8456a915adc212d6c47e"
 dependencies = [
  "arbitrary",
  "base64 0.13.1",
@@ -1857,12 +1857,12 @@ dependencies = [
 [[package]]
 name = "wasmi_arena"
 version = "0.4.0"
-source = "git+https://github.com/stellar/wasmi?rev=7e63b4c9e08c4163f417d118d81f7ea34789d0be#7e63b4c9e08c4163f417d118d81f7ea34789d0be"
+source = "git+https://github.com/stellar/wasmi?rev=ab29800224d85ee64d4ac127bac84cdbb0276721#ab29800224d85ee64d4ac127bac84cdbb0276721"
 
 [[package]]
 name = "wasmi_core"
 version = "0.13.0"
-source = "git+https://github.com/stellar/wasmi?rev=7e63b4c9e08c4163f417d118d81f7ea34789d0be#7e63b4c9e08c4163f417d118d81f7ea34789d0be"
+source = "git+https://github.com/stellar/wasmi?rev=ab29800224d85ee64d4ac127bac84cdbb0276721#ab29800224d85ee64d4ac127bac84cdbb0276721"
 dependencies = [
  "downcast-rs",
  "libm",
diff --git a/Cargo.toml b/Cargo.toml
index 8d34a15c..58a24886 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -27,16 +27,16 @@ soroban-builtin-sdk-macros = { version = "=20.0.0-rc2", path = "soroban-builtin-
 
 # NB: When updating, also update the version in rs-soroban-env dev-dependencies
 [workspace.dependencies.stellar-xdr]
-version = "=20.0.0-rc1"
+version = "=20.0.0"
 git = "https://github.com/stellar/rs-stellar-xdr"
-rev = "97e52f17501fb058ee28bbca3da0ae7897492746"
+rev = "24dd3c1b9fada6e2b28e8456a915adc212d6c47e"
 default-features = false
 
 [workspace.dependencies.wasmi]
 package = "soroban-wasmi"
-version = "=0.31.0-soroban1"
+version = "=0.31.1-soroban.20.0.0"
 git = "https://github.com/stellar/wasmi"
-rev = "7e63b4c9e08c4163f417d118d81f7ea34789d0be"
+rev = "ab29800224d85ee64d4ac127bac84cdbb0276721"
 
 # [patch."https://github.com/stellar/rs-stellar-xdr"]
 # stellar-xdr = { path = "../rs-stellar-xdr/" }
diff --git a/cackle.toml b/cackle.toml
index 0628c845..3b69e7d4 100644
--- a/cackle.toml
+++ b/cackle.toml
@@ -125,6 +125,9 @@ allow_unsafe = true
 build.allow_apis = [
     "env",
 ]
+allow_apis = [
+    "time",
+]
 
 [pkg.unicode-ident]
 allow_unsafe = true
diff --git a/soroban-env-host/Cargo.toml b/soroban-env-host/Cargo.toml
index 89c6551d..d69c85de 100644
--- a/soroban-env-host/Cargo.toml
+++ b/soroban-env-host/Cargo.toml
@@ -63,9 +63,9 @@ serde_json = "=1.0.108"
 arbitrary = "=1.3.2"
 
 [dev-dependencies.stellar-xdr]
-version = "=20.0.0-rc1"
+version = "=20.0.0"
 git = "https://github.com/stellar/rs-stellar-xdr"
-rev = "97e52f17501fb058ee28bbca3da0ae7897492746"
+rev = "24dd3c1b9fada6e2b28e8456a915adc212d6c47e"
 default-features = false
 features = ["arbitrary"]
 
diff --git a/soroban-env-host/src/budget.rs b/soroban-env-host/src/budget.rs
index f459d8d6..e628df90 100644
--- a/soroban-env-host/src/budget.rs
+++ b/soroban-env-host/src/budget.rs
@@ -17,7 +17,7 @@ use std::{
 use crate::{
     host::error::TryBorrowOrErr,
     xdr::{ContractCostParams, ContractCostType, ScErrorCode, ScErrorType},
-    Host, HostError,
+    Error, Host, HostError,
 };
 
 use dimension::{BudgetDimension, IsCpu, IsShadowMode};
@@ -40,6 +40,8 @@ struct BudgetTracker {
     meter_count: u32,
     #[cfg(any(test, feature = "testutils", feature = "bench"))]
     wasm_memory: u64,
+    // Tracks the real time (in nsecs) spent on various `CostType`
+    time_tracker: [u64; ContractCostType::variants().len()],
 }
 
 impl Default for BudgetTracker {
@@ -49,6 +51,7 @@ impl Default for BudgetTracker {
             meter_count: Default::default(),
             #[cfg(any(test, feature = "testutils", feature = "bench"))]
             wasm_memory: Default::default(),
+            time_tracker: Default::default(),
         };
         for (ct, tracker) in ContractCostType::variants()
             .iter()
@@ -108,6 +111,24 @@ impl BudgetTracker {
         }
         self.wasm_memory = 0;
     }
+
+    fn track_time(&mut self, ty: ContractCostType, duration: u64) -> Result<(), HostError> {
+        let t = self.time_tracker.get_mut(ty as usize).ok_or_else(|| {
+            HostError::from(Error::from_type_and_code(
+                ScErrorType::Budget,
+                ScErrorCode::InternalError,
+            ))
+        })?;
+        *t += duration;
+        Ok(())
+    }
+
+    fn get_time(&self, ty: ContractCostType) -> Result<u64, HostError> {
+        self.time_tracker
+            .get(ty as usize)
+            .map(|t| *t)
+            .ok_or_else(|| (ScErrorType::Budget, ScErrorCode::InternalError).into())
+    }
 }
 
 #[derive(Clone)]
@@ -717,6 +738,17 @@ impl Budget {
             .ok_or_else(|| (ScErrorType::Budget, ScErrorCode::InternalError).into())
     }
 
+    pub fn get_time(&self, ty: ContractCostType) -> Result<u64, HostError> {
+        self.0.try_borrow_or_err()?.tracker.get_time(ty)
+    }
+
+    pub fn track_time(&self, ty: ContractCostType, duration: u64) -> Result<(), HostError> {
+        self.0
+            .try_borrow_mut_or_err()?
+            .tracker
+            .track_time(ty, duration)
+    }
+
     pub fn get_cpu_insns_consumed(&self) -> Result<u64, HostError> {
         Ok(self.0.try_borrow_or_err()?.cpu_insns.get_total_count())
     }
diff --git a/soroban-env-host/src/vm.rs b/soroban-env-host/src/vm.rs
index 2e320d9f..1696c5f4 100644
--- a/soroban-env-host/src/vm.rs
+++ b/soroban-env-host/src/vm.rs
@@ -24,7 +24,7 @@ use crate::{
     ConversionError, Host, HostError, Symbol, SymbolStr, TryIntoVal, Val, WasmiMarshal,
     DEFAULT_XDR_RW_LIMITS,
 };
-use std::{cell::RefCell, io::Cursor, rc::Rc};
+use std::{cell::RefCell, io::Cursor, rc::Rc, time::Instant};
 
 use fuel_refillable::FuelRefillable;
 use func_info::HOST_FUNCTIONS;
@@ -231,6 +231,7 @@ impl Vm {
         module_wasm_code: &[u8],
     ) -> Result<Rc<Self>, HostError> {
         let _span = tracy_span!("Vm::new");
+        let now = Instant::now();
 
         host.charge_budget(
             ContractCostType::VmInstantiation,
@@ -297,13 +298,19 @@ impl Vm {
         // Here we do _not_ supply the store with any fuel. Fuel is supplied
         // right before the VM is being run, i.e., before crossing the host->VM
         // boundary.
-        Ok(Rc::new(Self {
+        let vm = Rc::new(Self {
             contract_id,
             module,
             store: RefCell::new(store),
             instance,
             memory,
-        }))
+        });
+
+        host.as_budget().track_time(
+            ContractCostType::VmInstantiation,
+            now.elapsed().as_nanos() as u64,
+        )?;
+        Ok(vm)
     }
 
     pub(crate) fn get_memory(&self, host: &Host) -> Result<Memory, HostError> {


Test patch:
diff --git a/soroban-env-host/src/test/invocation.rs b/soroban-env-host/src/test/invocation.rs
index c5a33d5b..dd418a11 100644
--- a/soroban-env-host/src/test/invocation.rs
+++ b/soroban-env-host/src/test/invocation.rs
@@ -33,6 +33,13 @@ fn invoke_single_contract_function() -> Result<(), HostError> {
         host.test_vec_obj(&[a, c])?,
     );
     let code = (ScErrorType::WasmVm, ScErrorCode::InvalidAction);
+
+    eprintln!(
+        "time ellapsed in nano-seconds for VmInstantiation: {}",
+        host.as_budget()
+            .get_time(ContractCostType::VmInstantiation)?
+    );
+
     assert!(HostError::result_matches_err(res, code));
     Ok(())
 }