Repository: CosmWasm/cosmwasm (Rust)

Issue:
Remove `print_debug` flag from cosmwasm-vm
With the new `set_debug_handler` coming in CosmWasm 1.4, there is no need to have a default implementation of the debug handler anymore. This code

```rust
            if print_debug {
                e.set_debug_handler(Some(Rc::new(RefCell::new(
                    |msg: &str, _gas_remaining: DebugInfo<'_>| {
                        eprintln!("{msg}");
                    },
                ))))
            }
```

can move into libwasmvm. Then cosmwasm-vm by default has no debug implementation and callers (libwasmvm, integration tests, cw-sdk, ...) can just do something like

```rust
    deps.set_debug_handler(move |msg, _info| {
        eprintln!("{msg}");
    });
```

if this is what they want to do. This might create a bit of work here and there, but dumping to STDERR from low level code is certainly not better.


Discussion:
In https://github.com/CosmWasm/wasmvm/pull/453, libwasmvm sets the debug handler it wants on its own. So we can remove the default implementation and leave it up to the caller to set one. By default, `None` is used.



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 447c4d4e1e..3fdfb4f53d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -76,6 +76,8 @@ and this project adheres to
 - cosmwasm-storage: Removed, use [cw-storage-plus] instead. ([#1936])
 - cosmwasm-std: Remove `IbcReceiveResponse`'s `Default` implementation. Use
   `IbcReceiveResponse::new` instead. ([#1942])
+- cosmwasm-vm: Remove `InstanceOptions::print_debug` flag. Set your own handler
+  using `Instance::set_debug_handler`. ([#1953])
 
 [cw-storage-plus]: https://github.com/CosmWasm/cw-storage-plus
 [#1875]: https://github.com/CosmWasm/cosmwasm/pull/1875
@@ -83,6 +85,7 @@ and this project adheres to
 [#1896]: https://github.com/CosmWasm/cosmwasm/pull/1896
 [#1936]: https://github.com/CosmWasm/cosmwasm/pull/1936
 [#1942]: https://github.com/CosmWasm/cosmwasm/pull/1942
+[#1953]: https://github.com/CosmWasm/cosmwasm/pull/1953
 
 ## [1.5.0] - 2023-10-31
 
diff --git a/packages/vm/benches/main.rs b/packages/vm/benches/main.rs
index 7bdd75ad51..f171c7bec5 100644
--- a/packages/vm/benches/main.rs
+++ b/packages/vm/benches/main.rs
@@ -20,7 +20,6 @@ const DEFAULT_MEMORY_LIMIT: Size = Size::mebi(64);
 const DEFAULT_GAS_LIMIT: u64 = 1_000_000_000; // ~1ms
 const DEFAULT_INSTANCE_OPTIONS: InstanceOptions = InstanceOptions {
     gas_limit: DEFAULT_GAS_LIMIT,
-    print_debug: false,
 };
 const HIGH_GAS_LIMIT: u64 = 20_000_000_000_000; // ~20s, allows many calls on one instance
 
@@ -50,7 +49,6 @@ fn bench_instance(c: &mut Criterion) {
         let backend = mock_backend(&[]);
         let much_gas: InstanceOptions = InstanceOptions {
             gas_limit: HIGH_GAS_LIMIT,
-            ..DEFAULT_INSTANCE_OPTIONS
         };
         let mut instance =
             Instance::from_code(CONTRACT, backend, much_gas, Some(DEFAULT_MEMORY_LIMIT)).unwrap();
@@ -68,7 +66,6 @@ fn bench_instance(c: &mut Criterion) {
         let backend = mock_backend(&[]);
         let much_gas: InstanceOptions = InstanceOptions {
             gas_limit: HIGH_GAS_LIMIT,
-            ..DEFAULT_INSTANCE_OPTIONS
         };
         let mut instance =
             Instance::from_code(CONTRACT, backend, much_gas, Some(DEFAULT_MEMORY_LIMIT)).unwrap();
@@ -92,7 +89,6 @@ fn bench_instance(c: &mut Criterion) {
         let backend = mock_backend(&[]);
         let much_gas: InstanceOptions = InstanceOptions {
             gas_limit: HIGH_GAS_LIMIT,
-            ..DEFAULT_INSTANCE_OPTIONS
         };
         let mut instance =
             Instance::from_code(CYBERPUNK, backend, much_gas, Some(DEFAULT_MEMORY_LIMIT)).unwrap();
diff --git a/packages/vm/examples/multi_threaded_cache.rs b/packages/vm/examples/multi_threaded_cache.rs
index 1cc5b98131..f0926d489d 100644
--- a/packages/vm/examples/multi_threaded_cache.rs
+++ b/packages/vm/examples/multi_threaded_cache.rs
@@ -14,7 +14,6 @@ const DEFAULT_MEMORY_LIMIT: Size = Size::mebi(64);
 const DEFAULT_GAS_LIMIT: u64 = 400_000 * 150;
 const DEFAULT_INSTANCE_OPTIONS: InstanceOptions = InstanceOptions {
     gas_limit: DEFAULT_GAS_LIMIT,
-    print_debug: false,
 };
 // Cache
 const MEMORY_CACHE_SIZE: Size = Size::mebi(200);
diff --git a/packages/vm/src/cache.rs b/packages/vm/src/cache.rs
index b4d1d9ea8e..b764ab6acb 100644
--- a/packages/vm/src/cache.rs
+++ b/packages/vm/src/cache.rs
@@ -357,7 +357,6 @@ where
             &cached.module,
             backend,
             options.gas_limit,
-            options.print_debug,
             None,
             Some(&self.instantiation_lock),
         )?;
@@ -532,7 +531,6 @@ mod tests {
     const TESTING_MEMORY_LIMIT: Size = Size::mebi(16);
     const TESTING_OPTIONS: InstanceOptions = InstanceOptions {
         gas_limit: TESTING_GAS_LIMIT,
-        print_debug: false,
     };
     const TESTING_MEMORY_CACHE_SIZE: Size = Size::mebi(200);
 
@@ -1180,10 +1178,7 @@ mod tests {
         let backend2 = mock_backend(&[]);
 
         // Init from module cache
-        let options = InstanceOptions {
-            gas_limit: 10,
-            print_debug: false,
-        };
+        let options = InstanceOptions { gas_limit: 10 };
         let mut instance1 = cache.get_instance(&checksum, backend1, options).unwrap();
         assert_eq!(cache.stats().hits_fs_cache, 1);
         assert_eq!(cache.stats().misses, 0);
@@ -1202,7 +1197,6 @@ mod tests {
         // Init from memory cache
         let options = InstanceOptions {
             gas_limit: TESTING_GAS_LIMIT,
-            print_debug: false,
         };
         let mut instance2 = cache.get_instance(&checksum, backend2, options).unwrap();
         assert_eq!(cache.stats().hits_pinned_memory_cache, 0);
diff --git a/packages/vm/src/instance.rs b/packages/vm/src/instance.rs
index b5f26c875e..617d2aa4a1 100644
--- a/packages/vm/src/instance.rs
+++ b/packages/vm/src/instance.rs
@@ -43,7 +43,6 @@ pub struct GasReport {
 pub struct InstanceOptions {
     /// Gas limit measured in [CosmWasm gas](https://github.com/CosmWasm/cosmwasm/blob/main/docs/GAS.md).
     pub gas_limit: u64,
-    pub print_debug: bool,
 }
 
 pub struct Instance<A: BackendApi, S: Storage, Q: Querier> {
@@ -74,15 +73,7 @@ where
         let engine = make_compiling_engine(memory_limit);
         let module = compile(&engine, code)?;
         let store = Store::new(engine);
-        Instance::from_module(
-            store,
-            &module,
-            backend,
-            options.gas_limit,
-            options.print_debug,
-            None,
-            None,
-        )
+        Instance::from_module(store, &module, backend, options.gas_limit, None, None)
     }
 
     #[allow(clippy::too_many_arguments)]
@@ -91,21 +82,10 @@ where
         module: &Module,
         backend: Backend<A, S, Q>,
         gas_limit: u64,
-        print_debug: bool,
         extra_imports: Option<HashMap<&str, Exports>>,
         instantiation_lock: Option<&Mutex<()>>,
     ) -> VmResult<Self> {
-        let fe = FunctionEnv::new(&mut store, {
-            let e = Environment::new(backend.api, gas_limit);
-            if print_debug {
-                e.set_debug_handler(Some(Rc::new(RefCell::new(
-                    |msg: &str, _info: DebugInfo<'_>| {
-                        eprintln!("{msg}");
-                    },
-                ))))
-            }
-            e
-        });
+        let fe = FunctionEnv::new(&mut store, Environment::new(backend.api, gas_limit));
 
         let mut import_obj = Imports::new();
         let mut env_imports = Exports::new();
@@ -480,7 +460,6 @@ pub fn instance_from_module<A, S, Q>(
     module: &Module,
     backend: Backend<A, S, Q>,
     gas_limit: u64,
-    print_debug: bool,
     extra_imports: Option<HashMap<&str, Exports>>,
 ) -> VmResult<Instance<A, S, Q>>
 where
@@ -488,15 +467,7 @@ where
     S: Storage + 'static, // 'static is needed here to allow using this in an Environment that is cloned into closures
     Q: Querier + 'static,
 {
-    Instance::from_module(
-        store,
-        module,
-        backend,
-        gas_limit,
-        print_debug,
-        extra_imports,
-        None,
-    )
+    Instance::from_module(store, module, backend, gas_limit, extra_imports, None)
 }
 
 #[cfg(test)]
@@ -655,7 +626,6 @@ mod tests {
             &module,
             backend,
             instance_options.gas_limit,
-            false,
             Some(extra_imports),
             None,
         )


Test patch:
diff --git a/packages/vm/src/testing/instance.rs b/packages/vm/src/testing/instance.rs
index bf5c200a95..c89e4e237f 100644
--- a/packages/vm/src/testing/instance.rs
+++ b/packages/vm/src/testing/instance.rs
@@ -19,7 +19,6 @@ use super::storage::MockStorage;
 /// higher than the limit for a single execution that we have in the production setup.
 const DEFAULT_GAS_LIMIT: u64 = 500_000_000; // ~0.5ms
 const DEFAULT_MEMORY_LIMIT: Option<Size> = Some(Size::mebi(16));
-const DEFAULT_PRINT_DEBUG: bool = true;
 
 pub fn mock_instance(
     wasm: &[u8],
@@ -90,7 +89,6 @@ pub struct MockInstanceOptions<'a> {
     pub available_capabilities: HashSet<String>,
     /// Gas limit measured in [CosmWasm gas](https://github.com/CosmWasm/cosmwasm/blob/main/docs/GAS.md).
     pub gas_limit: u64,
-    pub print_debug: bool,
     /// Memory limit in bytes. Use a value that is divisible by the Wasm page size 65536, e.g. full MiBs.
     pub memory_limit: Option<Size>,
 }
@@ -118,7 +116,6 @@ impl Default for MockInstanceOptions<'_> {
             // instance
             available_capabilities: Self::default_capabilities(),
             gas_limit: DEFAULT_GAS_LIMIT,
-            print_debug: DEFAULT_PRINT_DEBUG,
             memory_limit: DEFAULT_MEMORY_LIMIT,
         }
     }
@@ -155,7 +152,6 @@ pub fn mock_instance_with_options(
     let memory_limit = options.memory_limit;
     let options = InstanceOptions {
         gas_limit: options.gas_limit,
-        print_debug: options.print_debug,
     };
     Instance::from_code(wasm, backend, options, memory_limit).unwrap()
 }
@@ -165,7 +161,6 @@ pub fn mock_instance_options() -> (InstanceOptions, Option<Size>) {
     (
         InstanceOptions {
             gas_limit: DEFAULT_GAS_LIMIT,
-            print_debug: DEFAULT_PRINT_DEBUG,
         },
         DEFAULT_MEMORY_LIMIT,
     )