Repository: dusk-network/rusk (language: rust)

Issue:
vm: Add a `dusk-vm` workspace member
#### Summary
Add a `dusk-vm` workspace member that will wrap around `piecrust` vm, enriching it with features specifically needed by the dusk-network.

#### Detailed Description
The rusk-abi workspace member will be split into two parts:
- [x] the abi part will move to `dusk-core` under an `abi` feature-flag #3198
- [ ] the remaining host part in rusk-abi will be renamed to `dusk-vm` and a specific Dusk `VM` will be added that enriches the piecrust-VM with the host-functions specified by the dusk-ABI #3237




Discussion / hints:

Fix patch:
diff --git a/Cargo.toml b/Cargo.toml
index 3a2655cac6..693f4170a6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,13 +11,13 @@ members = [
     "contracts/transfer",
 
     "core",
+    "vm",
     "wallet-core",
 
     "rusk-prover",
 
     "rusk-recovery",
     "rusk-profile",
-    "rusk-abi",
     "rusk",
 
     "node-data",
@@ -34,9 +34,9 @@ resolver = "2"
 # Workspace internal dependencies
 dusk-consensus = { version = "0.1.1-rc.3", path = "./consensus/" }
 dusk-core = { version = "0.1.0", path = "./core/" }
+dusk-vm = { version = "0.1.0", path = "./vm/" }
 node = { version = "0.1.0", path = "./node/" }
 node-data = { version = "0.1.0", path = "./node-data/" }
-rusk-abi = { version = "0.13.0-rc.0", path = "./rusk-abi/", default-features = false }
 rusk-profile = { version = "0.6.0", path = "./rusk-profile/" }
 rusk-prover = { version = "0.5.0", path = "./rusk-prover/" }
 rusk-recovery = { version = "0.6.0", path = "./rusk-recovery/" }
diff --git a/Makefile b/Makefile
index 93ae39d6a8..b91ae8a25d 100644
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,7 @@ help: ## Display this help screen
 		awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
 
 abi: ## Build the ABI
-	$(MAKE) -C ./rusk-abi all
+	$(MAKE) -C ./vm all
 
 keys: ## Create the keys for the circuits
 	$(MAKE) -C ./rusk recovery-keys
@@ -22,7 +22,7 @@ contracts: ## Execute the test for all contracts
 	$(MAKE) -j1 -C ./contracts all
 
 test: keys wasm ## Run the tests
-	$(MAKE) -C ./rusk-abi/ $@
+	$(MAKE) -C ./vm/ $@
 	$(MAKE) -C ./core/ $@
 	$(MAKE) state
 	$(MAKE) -j1 -C ./contracts $@
@@ -38,7 +38,7 @@ test: keys wasm ## Run the tests
 clippy: ## Run clippy
 	$(MAKE) -C ./core/ $@
 	$(MAKE) -j1 -C ./contracts $@
-	$(MAKE) -C ./rusk-abi $@
+	$(MAKE) -C ./vm $@
 	$(MAKE) -C ./rusk-profile $@
 	$(MAKE) -C ./rusk-recovery $@
 	$(MAKE) -C ./rusk-prover/ $@
@@ -56,7 +56,7 @@ doc: ## Run doc gen
 	$(MAKE) -C ./node $@
 	$(MAKE) -C ./node-data $@
 	$(MAKE) -C ./rusk/ $@
-	$(MAKE) -C ./rusk-abi $@
+	$(MAKE) -C ./vm $@
 	$(MAKE) -C ./rusk-profile $@
 	$(MAKE) -C ./rusk-prover/ $@
 	$(MAKE) -C ./rusk-recovery $@
diff --git a/contracts/stake/Cargo.toml b/contracts/stake/Cargo.toml
index 53189d9d66..d13d99219c 100644
--- a/contracts/stake/Cargo.toml
+++ b/contracts/stake/Cargo.toml
@@ -15,7 +15,7 @@ rkyv = { workspace = true, features = ["size_32"] }
 dusk-core = { workspace = true, features = ["abi-dlmalloc"] }
 
 [dev-dependencies]
-rusk-abi = { workspace = true }
+dusk-vm = { workspace = true }
 dusk-core = { workspace = true, features = ["zk"] }
 rusk-prover = { workspace = true }
 wallet-core = { workspace = true }
diff --git a/contracts/stake/benches/get_provisioners.rs b/contracts/stake/benches/get_provisioners.rs
index 1314d111e4..cb4d8a9933 100644
--- a/contracts/stake/benches/get_provisioners.rs
+++ b/contracts/stake/benches/get_provisioners.rs
@@ -11,9 +11,9 @@ use dusk_core::{
     transfer::TRANSFER_CONTRACT,
     BlsPublicKey, BlsSecretKey,
 };
+use dusk_vm::{ContractData, Error as VMError, Session, VM, VM};
 use rand::rngs::StdRng;
 use rand::{CryptoRng, RngCore, SeedableRng};
-use rusk_abi::{ContractData, PiecrustError, Session, VM};
 use std::sync::mpsc;
 
 const SAMPLE_SIZE: usize = 10;
@@ -27,7 +27,7 @@ fn config() -> Criterion {
     Criterion::default().sample_size(SAMPLE_SIZE)
 }
 
-fn update_root(session: &mut Session) -> Result<(), PiecrustError> {
+fn update_root(session: &mut Session) -> Result<(), VMError> {
     session
         .call(TRANSFER_CONTRACT, "update_root", &(), POINT_LIMIT)
         .map(|r| r.data)
@@ -69,7 +69,7 @@ fn instantiate(vm: &VM) -> Session {
 
 fn do_get_provisioners(
     session: &mut Session,
-) -> Result<impl Iterator<Item = (BlsPublicKey, StakeData)>, PiecrustError> {
+) -> Result<impl Iterator<Item = (BlsPublicKey, StakeData)>, VMError> {
     let (sender, receiver) = mpsc::channel();
     session.feeder_call::<_, ()>(
         STAKE_CONTRACT,
@@ -87,7 +87,7 @@ fn do_get_provisioners(
 fn do_insert_stake<Rng: RngCore + CryptoRng>(
     rng: &mut Rng,
     session: &mut Session,
-) -> Result<(), PiecrustError> {
+) -> Result<(), VMError> {
     let stake_data = StakeData {
         amount: Some((TEST_STAKE, 0)),
         nonce: 1,
@@ -107,8 +107,7 @@ fn do_insert_stake<Rng: RngCore + CryptoRng>(
 fn get_provisioners(c: &mut Criterion) {
     let rng = &mut StdRng::seed_from_u64(0xfeeb);
 
-    let vm = &mut abi::new_ephemeral_vm()
-        .expect("Creating ephemeral VM should work");
+    let vm = &mut VM::ephemeral().expect("Creating ephemeral VM should work");
 
     let mut session = instantiate(vm);
 
diff --git a/contracts/transfer/Cargo.toml b/contracts/transfer/Cargo.toml
index f49071c97a..8430abfd20 100644
--- a/contracts/transfer/Cargo.toml
+++ b/contracts/transfer/Cargo.toml
@@ -14,7 +14,7 @@ ringbuffer = { workspace = true }
 dusk-core = { workspace = true, features = ["abi-dlmalloc"] }
 
 [dev-dependencies]
-rusk-abi = { workspace = true }
+dusk-vm = { workspace = true }
 rusk-profile = { workspace = true }
 rusk-prover = { workspace = true }
 rkyv = { workspace = true, features = ["size_32"] }
diff --git a/rusk-abi/CHANGELOG.md b/rusk-abi/CHANGELOG.md
deleted file mode 100644
index e709b53d06..0000000000
--- a/rusk-abi/CHANGELOG.md
+++ /dev/null
@@ -1,243 +0,0 @@
-# Changelog
-
-All notable changes to this project will be documented in this file.
-
-The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
-and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
-
-## [Unreleased]
-
-### Added
-
-- Add the `verify_groth16_bn254` host function
-- Memoize the `verify_bls` function
-- Memoize the `verify_proof` function [#1228]
-- New ABIs: `owner_raw`, `self_owner_raw` [#1710]
-
-### Changed
-
-- Rename `verify_proof` to `verify_plonk`
-- Update `piecrust` to `0.22`
-- Update `piecrust-uplink` to `0.15`
-- Change dependencies declarations enforce bytecheck [#1371]
-- Update dusk dependencies [#1609]
-- Made owner methods compatible with BLS key [#2230]
-
-## [0.11.0] - 2023-10-12
-
-### Changed
-
-- Update `dusk-bls12_381` from `0.11` to `0.12`
-- Update `dusk-bls12_381-sign` from `0.4` to `0.15`
-- Update `dusk-jubjub` from `0.12` to `0.13`
-- Update `dusk-poseidon` from `0.30` to `0.31`
-- Update `dusk-pki` from `0.12` to `0.13`
-- Update `dusk-plonk` from `0.14` to `0.16`
-
-### Added
-
-- Add `ff` dev-dependency `0.13`
-
-### Changed
-
-- Update `piecrust` from `0.8.0-rc` to `0.10`
-- Update `piecrust` from `0.7` to `0.8.0-rc`
-- Update `piecrust` from `0.6` to `0.7`
-- Update `piecrust-uplink` from `0.6` to `0.7`
-
-## [0.10.0-piecrust.0.6] - 2023-07-06
-
-### Changed
-
-- Update `plonk` from `0.13` to `0.14` [#929]
-
-## [0.9.0-piecrust.0.6] - 2023-07-04
-
-### Changed
-
-- Update `piecrust` to `0.6` [#945]
-- Use `dusk-merkle` instead of `microkelvin` [#937]
-- Update `dusk-poseidon` from `0.28` to `0.29.1-rc.0`
-
-## [0.8.0-piecrust.0.5] - 2023-06-13
-
-### Changed
-
-- Update `piecrust` to `0.1.0`
-
-### Fix
-
-- Fix `rkyv` and `wasmer` deps semver [#874]
-
-## [0.8.0-alpha] - 2023-03-27
-
-### Changed
-
-- Change `rusk-abi` to use `piecrust` [#760]
-- Change `rusk-abi` to use `piecrust-uplink` [#760]
-
-## [0.7.0] - 2022-02-25
-
-### Changed
-
-- Update canonical from `0.6` to `0.7`
-- Update canonical_derive from `0.6` to `0.7`
-- Update dusk-poseidon from `0.23.0-rc` to `0.25.0-rc`
-- Update dusk-bls12_381 from `0.8` fro `0.9`
-- Update dusk-bls12_381-sign `0.1.0-rc` to `0.3.0-rc`
-- Update dusk-abi from `0.10` to `0.11`
-- Update dusk-schnorr from `0.9.0-rc` to `0.10.0-rc`
-- Update dusk-pki from `0.9.0-rc` to `0.10.0-rc`
-- Update dusk-jubjub from `0.10` to `0.11`
-- Update rusk-vm from `0.10.0-rc` to `0.12.0-rc`
-- Update dusk-plonk from `0.9` to `0.10`
-
-## [0.6.3] - 2022-02-19
-
-### Changed
-
-- Update `rusk-vm` from `0.8.0-rc` to `0.10.0-rc`
-
-## [0.6.2] - 2022-01-28
-
-### Added
-
-- Add BLS signature verification to `rusk-abi` [#475]
-
-## [0.6.0] - 2022-01-24
-
-### Changed
-
-- Update dependencies to most recent [#430] [#433]
-- Update `rusk-vm` from `0.7.0-rc` to `0.8.0-rc`
-
-## [0.5.0] - 2022-01-11
-
-### Changed
-
-- Change hashing of transaction to inside the contract [#402]
-- Update to `dusk-plonk` to `0.9` [#392]
-
-## [0.4.1] - 2021-07-28
-
-### Added
-
-- Add `stake_contract` method for host and hosted [#338]
-- Add `transfer_contract` method for host [#338]
-- Add `gen_contract_id` method for host [#337]
-
-### Remove
-
-- Remove `transfer_address` and `stake_address` methods for host [#338]
-
-## [0.4.0] - 2021-07-16
-
-### Added
-
-- Add `transfer_contract` method for hosted [#328]
-- Add `transfer_address` and `stake_address` methods for host [#328]
-
-### Changed
-
-- Update `dusk-abi` from `0.9.0-rc` to `0.9` [#327]
-- Update `dusk-schnorr` from `0.7.0-rc` to `0.8.0-rc` [#327]
-- Update `dusk-pki` from `0.7.0-rc` to `0.8.0-rc` [#327]
-- Update `rusk-vm` from `0.6.0-rc` to `0.7.0-rc` [#327]
-
-## [0.3.0] - 2021-05-14
-
-### Added
-
-- Add `payment_info` host function [#254]
-
-### Changed
-
-- Change `verify_proof` to accept verifier data [#247]
-- Update `canonical` from `0.5` to `0.6`
-- Update `canonical_derive` from `0.5` to `0.6`
-- Update `dusk-poseidon` from `0.20` to `0.21.0-rc`
-- Update `dusk-bls12_381` from `0.26` to `0.8`
-- Update `dusk-abi` from `0.7` to `0.9-rc`
-- Update `dusk-schnorr` from `0.6` to `0.7.0-rc`
-- Update `dusk-pki` from `0.6` to `0.7.0-rc`
-- Update `dusk-jubjub` from `0.8` to `0.10`
-- Update `dusk-plonk` from `0.7` to `0.8`
-- Update `rusk-vm` from `0.5` to `0.6.0-rc`
-- Update `rusk-profile` from `0.3` to `0.4.0-rc`
-- Replace `rand` version `0.7` with `rand_core` version `0.6`
-
-### Remove
-
-- Remove unused `tests/proof_test.bin`
-- Remove unused `tests/vk_test.bin`
-
-### Fix
-
-- Fix the `repository` section in Cargo.toml
-
-## [0.2.0] - 2021-03-12
-
-### Added
-
-- Add `verify_proof` host function [#227]
-- Add `PublicInput` enum wrapper for input types
-- Add `PublicParameters` as field of `RuskModule`
-- Add Schnorr Signature verification host function
-
-### Changed
-
-- Change Build Status shield URL
-
-### Removed
-
-- Remove clippy warnings
-
-## [0.1.0] - 2021-02-19
-
-### Added
-
-- Add ABI infrastracture
-- Add Poseidon Hash host function
-- Add test contract
-- Add CHANGELOG.md
-- Add LICENSE
-- Add README.md
-
-[#2230]: https://github.com/dusk-network/rusk/issues/2230
-[#1710]: https://github.com/dusk-network/rusk/issues/1710
-[#1630]: https://github.com/dusk-network/rusk/issues/1630
-[#1609]: https://github.com/dusk-network/rusk/issues/1609
-[#1371]: https://github.com/dusk-network/rusk/issues/1371
-[#1228]: https://github.com/dusk-network/rusk/issues/1228
-[#945]: https://github.com/dusk-network/rusk/issues/945
-[#937]: https://github.com/dusk-network/rusk/issues/937
-[#874]: https://github.com/dusk-network/rusk/issues/874
-[#760]: https://github.com/dusk-network/rusk/issues/760
-[#475]: https://github.com/dusk-network/rusk/issues/475
-[#433]: https://github.com/dusk-network/rusk/issues/433
-[#430]: https://github.com/dusk-network/rusk/issues/430
-[#402]: https://github.com/dusk-network/rusk/issues/402
-[#392]: https://github.com/dusk-network/rusk/issues/392
-[#338]: https://github.com/dusk-network/rusk/issues/338
-[#337]: https://github.com/dusk-network/rusk/issues/337
-[#328]: https://github.com/dusk-network/rusk/issues/328
-[#327]: https://github.com/dusk-network/rusk/issues/327
-[#227]: https://github.com/dusk-network/rusk/issues/227
-[#254]: https://github.com/dusk-network/rusk/issues/254
-
-[Unreleased]: https://github.com/dusk-network/dusk-abi/compare/rusk-abi-0.11.0...HEAD
-[0.11.0]: https://github.com/dusk-network/dusk-abi/compare/rusk-abi-0.10.0-piecrust.0.6...rusk-abi-0.11.0
-[0.10.0-piecrust.0.6]: https://github.com/dusk-network/dusk-abi/compare/rusk-abi-0.9.0-piecrust.0.6...rusk-abi-0.10.0-piecrust.0.6
-[0.9.0-piecrust.0.6]: https://github.com/dusk-network/dusk-abi/compare/rusk-abi-0.8.0-piecrust.0.5...rusk-abi-0.9.0-piecrust.0.6
-[0.8.0-piecrust.0.5]: https://github.com/dusk-network/dusk-abi/compare/rusk-abi-0.8.0-alpha...rusk-abi-0.8.0-piecrust.0.5
-[0.8.0-alpha]: https://github.com/dusk-network/dusk-abi/compare/rusk-abi-0.7.0...rusk-abi-0.8.0-alpha
-[0.7.0]: https://github.com/dusk-network/dusk-abi/compare/rusk-abi-0.6.3...rusk-abi-0.7.0
-[0.6.3]: https://github.com/dusk-network/dusk-abi/compare/rusk-abi-0.6.2...rusk-abi-0.6.3
-[0.6.2]: https://github.com/dusk-network/dusk-abi/compare/rusk-abi-0.6.0...rusk-abi-0.6.2
-[0.6.0]: https://github.com/dusk-network/dusk-abi/compare/rusk-abi-0.5.0...rusk-abi-0.6.0
-[0.5.0]: https://github.com/dusk-network/dusk-abi/compare/rusk-abi-0.4.1...rusk-abi-0.5.0
-[0.4.1]: https://github.com/dusk-network/dusk-abi/compare/rusk-abi-0.4.0...rusk-abi-0.4.1
-[0.4.0]: https://github.com/dusk-network/dusk-abi/releases/tag/rusk-abi-0.4.0
-[0.3.0]: https://github.com/dusk-network/dusk-abi/releases/tag/rusk-abi-0.3.0
-[0.2.0]: https://github.com/dusk-network/dusk-abi/releases/tag/rusk-abi-0.2.0
-[0.1.0]: https://github.com/dusk-network/dusk-abi/releases/tag/rusk-abi-0.1.0
diff --git a/rusk-abi/src/lib.rs b/rusk-abi/src/lib.rs
deleted file mode 100644
index e17124540a..0000000000
--- a/rusk-abi/src/lib.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-//
-// Copyright (c) DUSK NETWORK. All rights reserved.
-
-//! ![Build Status](https://github.com/dusk-network/rusk/workflows/Continuous%20integration/badge.svg)
-//! [![Repository](https://img.shields.io/badge/github-rusk-blueviolet?logo=github)](https://github.com/dusk-network/rusk)
-//! [![Documentation](https://img.shields.io/badge/docs-rusk--abi-blue?logo=rust)](https://docs.rs/rusk-abi/)
-
-//! # Rusk ABI
-//!
-//! The ABI to develop Dusk Network smart contracts
-
-#![deny(missing_docs)]
-#![deny(clippy::all)]
-#![deny(unused_crate_dependencies)]
-#![deny(unused_extern_crates)]
-
-extern crate alloc;
-
-mod host;
-pub use host::{
-    hash, new_ephemeral_vm, new_genesis_session, new_session, new_vm,
-    poseidon_hash, verify_bls, verify_bls_multisig, verify_plonk,
-    verify_schnorr,
-};
-pub use piecrust::{
-    CallReceipt, CallTree, CallTreeElem, ContractData, Error as PiecrustError,
-    PageOpening, Session, VM,
-};
-
-#[cfg(test)]
-mod tests {
-    // rust doesn't allow for optional dev-dependencies so we need to add this
-    // work-around to satisfy the `unused_crate_dependencies` lint
-    use ff as _;
-    use once_cell as _;
-    use rand as _;
-}
diff --git a/rusk-recovery/Cargo.toml b/rusk-recovery/Cargo.toml
index 665013a877..e2e0dd1474 100644
--- a/rusk-recovery/Cargo.toml
+++ b/rusk-recovery/Cargo.toml
@@ -29,7 +29,7 @@ flate2 = { workspace = true, optional = true }
 hex = { workspace = true, optional = true }
 http_req = { workspace = true, optional = true }
 rand = { workspace = true, optional = true }
-rusk-abi = { workspace = true, optional = true }
+dusk-vm = { workspace = true, optional = true }
 tar = { workspace = true, optional = true }
 url = { workspace = true, optional = true }
 zip = { workspace = true, optional = true }
@@ -56,7 +56,7 @@ state = [
     "hex",
     "http_req",
     "rand",
-    "rusk-abi",
+    "dusk-vm",
     "tar",
     "url",
     "zip",
diff --git a/rusk-recovery/src/state.rs b/rusk-recovery/src/state.rs
index 98e5e4af07..ea60b9bef7 100644
--- a/rusk-recovery/src/state.rs
+++ b/rusk-recovery/src/state.rs
@@ -15,11 +15,11 @@ use dusk_core::stake::{StakeAmount, StakeData, StakeKeys, STAKE_CONTRACT};
 use dusk_core::transfer::phoenix::{Note, PublicKey, Sender};
 use dusk_core::transfer::TRANSFER_CONTRACT;
 use dusk_core::JubJubScalar;
+use dusk_vm::{new_genesis_session, new_session, ContractData, Session, VM};
 use ff::Field;
 use once_cell::sync::Lazy;
 use rand::rngs::StdRng;
 use rand::SeedableRng;
-use rusk_abi::{ContractData, Session, VM};
 
 use tracing::info;
 use url::Url;
@@ -176,8 +176,8 @@ fn generate_empty_state<P: AsRef<Path>>(
 
     let state_dir = state_dir.as_ref();
 
-    let vm = rusk_abi::new_vm(state_dir)?;
-    let mut session = rusk_abi::new_genesis_session(&vm, GENESIS_CHAIN_ID);
+    let vm = VM::new(state_dir)?;
+    let mut session = new_genesis_session(&vm, GENESIS_CHAIN_ID);
 
     let transfer_code = include_bytes!(
         "../../target/dusk/wasm64-unknown-unknown/release/transfer_contract.wasm"
@@ -260,7 +260,7 @@ where
         None => generate_empty_state(state_dir, snapshot),
     }?;
 
-    let mut session = rusk_abi::new_session(
+    let mut session = new_session(
         &vm,
         old_commit_id,
         GENESIS_CHAIN_ID,
@@ -312,7 +312,7 @@ pub fn restore_state<P: AsRef<Path>>(
     let mut commit_id = [0u8; 32];
     commit_id.copy_from_slice(&commit_id_bytes);
 
-    let vm = rusk_abi::new_vm(state_dir)?;
+    let vm = VM::new(state_dir)?;
     Ok((vm, commit_id))
 }
 
diff --git a/rusk/Cargo.toml b/rusk/Cargo.toml
index f897657902..0649132c36 100644
--- a/rusk/Cargo.toml
+++ b/rusk/Cargo.toml
@@ -58,8 +58,8 @@ rustls-pemfile = { workspace = true }
 async-trait = { workspace = true }
 
 dusk-core = { workspace = true, features = ["zk"] }
+dusk-vm = { workspace = true }
 rusk-profile = { workspace = true }
-rusk-abi = { workspace = true }
 rusk-prover = { workspace = true, features = ["std"], optional = true }
 
 ## node dependencies
diff --git a/rusk/src/lib/error.rs b/rusk/src/lib/error.rs
index 2be9e326bf..4da2903a6e 100644
--- a/rusk/src/lib/error.rs
+++ b/rusk/src/lib/error.rs
@@ -11,7 +11,7 @@ use dusk_core::{
     signatures::bls::PublicKey as BlsPublicKey, transfer::phoenix::CoreError,
     BlsScalar, Error as ExecErr,
 };
-use rusk_abi::PiecrustError;
+use dusk_vm::Error as VMError;
 
 #[derive(Debug)]
 pub enum Error {
@@ -44,7 +44,7 @@ pub enum Error {
     /// Originating from Phoenix.
     Phoenix(CoreError),
     /// Piecrust VM internal Errors
-    Vm(PiecrustError),
+    Vm(VMError),
     /// IO Errors
     Io(io::Error),
     /// Failed to produce proper state
@@ -70,8 +70,8 @@ impl From<Box<dyn std::error::Error>> for Error {
     }
 }
 
-impl From<PiecrustError> for Error {
-    fn from(err: PiecrustError) -> Self {
+impl From<VMError> for Error {
+    fn from(err: VMError) -> Self {
         Error::Vm(err)
     }
 }
diff --git a/rusk/src/lib/node.rs b/rusk/src/lib/node.rs
index 593f8f5cb8..2cf27a4bb7 100644
--- a/rusk/src/lib/node.rs
+++ b/rusk/src/lib/node.rs
@@ -14,11 +14,11 @@ use std::time::Duration;
 
 use dusk_core::{dusk, Dusk};
 
+use dusk_vm::VM;
 use node::database::rocksdb::{self, Backend};
 use node::network::Kadcast;
 use node::LongLivedService;
 use parking_lot::RwLock;
-use rusk_abi::VM;
 use tokio::sync::broadcast;
 
 use crate::http::RuesEvent;
diff --git a/rusk/src/lib/node/rusk.rs b/rusk/src/lib/node/rusk.rs
index 45a225f9a7..6f521eb4d8 100644
--- a/rusk/src/lib/node/rusk.rs
+++ b/rusk/src/lib/node/rusk.rs
@@ -27,11 +27,11 @@ use dusk_core::transfer::{
     TRANSFER_CONTRACT,
 };
 use dusk_core::{BlsScalar, Dusk};
+use dusk_vm::{new_session, CallReceipt, Error as VMError, Session, VM};
 use node::vm::bytecode_charge;
 use node_data::events::contract::{ContractEvent, ContractTxEvent};
 use node_data::ledger::{Hash, Slash, SpentTransaction, Transaction};
 use parking_lot::RwLock;
-use rusk_abi::{CallReceipt, PiecrustError, Session};
 use rusk_profile::to_rusk_state_id_path;
 use tokio::sync::broadcast;
 use tracing::info;
@@ -85,7 +85,7 @@ impl Rusk {
         let mut base_commit = [0u8; 32];
         base_commit.copy_from_slice(&base_commit_bytes);
 
-        let vm = Arc::new(rusk_abi::new_vm(dir)?);
+        let vm = Arc::new(VM::new(dir)?);
 
         let tip = Arc::new(RwLock::new(RuskTip {
             current: base_commit,
@@ -219,9 +219,7 @@ impl Rusk {
                         err,
                     });
                 }
-                Err(PiecrustError::Panic(val))
-                    if val == PANIC_NONCE_NOT_READY =>
-                {
+                Err(VMError::Panic(val)) if val == PANIC_NONCE_NOT_READY => {
                     // If the transaction panic due to a not yet valid nonce,
                     // we should not discard the transactions since it can be
                     // included in future.
@@ -537,12 +535,8 @@ impl Rusk {
             tip.current
         });
 
-        let session = rusk_abi::new_session(
-            &self.vm,
-            commit,
-            self.chain_id,
-            block_height,
-        )?;
+        let session =
+            new_session(&self.vm, commit, self.chain_id, block_height)?;
 
         Ok(session)
     }
@@ -769,7 +763,7 @@ fn execute(
     gas_per_deploy_byte: u64,
     min_deploy_points: u64,
     min_deployment_gas_price: u64,
-) -> Result<CallReceipt<Result<Vec<u8>, ContractError>>, PiecrustError> {
+) -> Result<CallReceipt<Result<Vec<u8>, ContractError>>, VMError> {
     // Transaction will be discarded if it is a deployment transaction
     // with gas limit smaller than deploy charge.
     if let Some(deploy) = tx.deploy() {
@@ -779,14 +773,10 @@ fn execute(
             min_deploy_points,
         );
         if tx.gas_price() < min_deployment_gas_price {
-            return Err(PiecrustError::Panic(
-                "gas price too low to deploy".into(),
-            ));
+            return Err(VMError::Panic("gas price too low to deploy".into()));
         }
         if tx.gas_limit() < deploy_charge {
-            return Err(PiecrustError::Panic(
-                "not enough gas to deploy".into(),
-            ));
+            return Err(VMError::Panic("not enough gas to deploy".into()));
         }
     }
 
diff --git a/rusk/src/lib/verifier.rs b/rusk/src/lib/verifier.rs
index a3caf48964..112d7cfce2 100644
--- a/rusk/src/lib/verifier.rs
+++ b/rusk/src/lib/verifier.rs
@@ -13,6 +13,7 @@ use dusk_core::transfer::{
     moonlight::Transaction as MoonlightTransaction,
     phoenix::Transaction as PhoenixTransaction,
 };
+use dusk_vm::host_queries;
 use rusk_profile::Circuit as CircuitProfile;
 
 use std::sync::LazyLock;
@@ -48,7 +49,7 @@ pub fn verify_proof(tx: &PhoenixTransaction) -> Result<bool> {
 
     // Maybe we want to handle internal serialization error too,
     // currently they map to `false`.
-    Ok(rusk_abi::verify_plonk(
+    Ok(host_queries::verify_plonk(
         vd.to_vec(),
         tx.proof().to_vec(),
         tx.public_inputs(),
@@ -57,7 +58,7 @@ pub fn verify_proof(tx: &PhoenixTransaction) -> Result<bool> {
 
 /// Verifies the signature of the incoming transaction.
 pub fn verify_signature(tx: &MoonlightTransaction) -> Result<bool> {
-    Ok(rusk_abi::verify_bls(
+    Ok(host_queries::verify_bls(
         tx.signature_message(),
         *tx.sender(),
         *tx.signature(),
diff --git a/vm/CHANGELOG.md b/vm/CHANGELOG.md
new file mode 100644
index 0000000000..de797f63ff
--- /dev/null
+++ b/vm/CHANGELOG.md
@@ -0,0 +1,17 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## [Unreleased]
+
+### Added
+
+- Add vm to interact with Dusk network [#3235]
+
+[#3235]: https://github.com/dusk-network/rusk/issues/3235
+
+<!-- [Unreleased]: https://github.com/dusk-network/dusk-abi/compare/dusk-vm-0.1.0...HEAD -->
+<!-- [0.1.0]: https://github.com/dusk-network/dusk-abi/releases/tag/dusk-vm-0.1.0 -->
diff --git a/rusk-abi/Cargo.toml b/vm/Cargo.toml
similarity index 85%
rename from rusk-abi/Cargo.toml
rename to vm/Cargo.toml
index c455a63fff..b5fb1ab8fd 100644
--- a/rusk-abi/Cargo.toml
+++ b/vm/Cargo.toml
@@ -1,10 +1,10 @@
 [package]
-name = "rusk-abi"
-version = "0.13.0-rc.0"
+name = "dusk-vm"
+version = "0.1.0"
 edition = "2021"
 
 repository = "https://github.com/dusk-network/rusk"
-description = "The ABI to develop Dusk Network smart contracts"
+description = "The VM to run smart contracts on the Dusk network"
 license = "MPL-2.0"
 exclude = [".github/workflows/ci.yml", ".gitignore"]
 
diff --git a/rusk-abi/LICENSE b/vm/LICENSE
similarity index 100%
rename from rusk-abi/LICENSE
rename to vm/LICENSE
diff --git a/rusk-abi/Makefile b/vm/Makefile
similarity index 100%
rename from rusk-abi/Makefile
rename to vm/Makefile
diff --git a/rusk-abi/README.md b/vm/README.md
similarity index 59%
rename from rusk-abi/README.md
rename to vm/README.md
index 0b27871c7b..ad121e6e4a 100644
--- a/rusk-abi/README.md
+++ b/vm/README.md
@@ -1,9 +1,9 @@
 ![Build Status](https://github.com/dusk-network/rusk/workflows/Continuous%20integration/badge.svg)
-[![Repository](https://img.shields.io/badge/github-rusk--abi-blueviolet?logo=github)](https://github.com/dusk-network/rusk-abi)
-[![Documentation](https://img.shields.io/badge/docs-rusk--abi-blue?logo=rust)](https://docs.rs/rusk-abi/)
+[![Repository](https://img.shields.io/badge/github-rusk--abi-blueviolet?logo=github)](https://github.com/dusk-network/dusk-vm)
+[![Documentation](https://img.shields.io/badge/docs-rusk--abi-blue?logo=rust)](https://docs.rs/dusk-vm/)
 
-## Rusk ABI
+## Dusk VM
 
-The ABI to develop Rusk specific smart-contracts
+The VM to execute smart contracts on the Dusk network.
 
 License: MPL-2.0
diff --git a/rusk-abi/rustfmt.toml b/vm/rustfmt.toml
similarity index 100%
rename from rusk-abi/rustfmt.toml
rename to vm/rustfmt.toml
diff --git a/rusk-abi/src/host/cache.rs b/vm/src/cache.rs
similarity index 100%
rename from rusk-abi/src/host/cache.rs
rename to vm/src/cache.rs
diff --git a/rusk-abi/src/host.rs b/vm/src/host_queries.rs
similarity index 67%
rename from rusk-abi/src/host.rs
rename to vm/src/host_queries.rs
index d2574f8d0f..424812efed 100644
--- a/rusk-abi/src/host.rs
+++ b/vm/src/host_queries.rs
@@ -4,11 +4,11 @@
 //
 // Copyright (c) DUSK NETWORK. All rights reserved.
 
+//! The host-queries registered on the Dusk VM
+
 use alloc::vec::Vec;
-use std::path::{Path, PathBuf};
 
 use dusk_bytes::DeserializableSlice;
-use dusk_core::abi::{Metadata, Query};
 use dusk_core::groth16::bn254::{Bn254, G1Projective};
 use dusk_core::groth16::serialize::CanonicalDeserialize;
 use dusk_core::groth16::{
@@ -24,145 +24,10 @@ use dusk_core::signatures::schnorr::{
 };
 use dusk_core::BlsScalar;
 use dusk_poseidon::{Domain, Hash as PoseidonHash};
-use piecrust::{Error as PiecrustError, Session, SessionData, VM};
 use rkyv::ser::serializers::AllocSerializer;
 use rkyv::{Archive, Deserialize, Serialize};
 
-mod cache;
-
-/// Create a new session based on the given `vm`. The vm *must* have been
-/// created using [`new_vm`] or [`new_ephemeral_vm`].
-pub fn new_session(
-    vm: &VM,
-    base: [u8; 32],
-    chain_id: u8,
-    block_height: u64,
-) -> Result<Session, PiecrustError> {
-    vm.session(
-        SessionData::builder()
-            .base(base)
-            .insert(Metadata::CHAIN_ID, chain_id)?
-            .insert(Metadata::BLOCK_HEIGHT, block_height)?,
-    )
-}
-
-/// Create a new genesis session based on the given `vm`. The vm *must* have
-/// been created using [`new_vm`] or [`new_ephemeral_vm`].
-pub fn new_genesis_session(vm: &VM, chain_id: u8) -> Session {
-    vm.session(
-        SessionData::builder()
-            .insert(Metadata::CHAIN_ID, chain_id)
-            .expect("Inserting chain ID in metadata should succeed")
-            .insert(Metadata::BLOCK_HEIGHT, 0)
-            .expect("Inserting block height in metadata should succeed"),
-    )
-    .expect("Creating a genesis session should always succeed")
-}
-
-/// Create a new [`VM`] compliant with Dusk's specification.
-pub fn new_vm<P: AsRef<Path> + Into<PathBuf>>(
-    root_dir: P,
-) -> Result<VM, PiecrustError> {
-    let mut vm = VM::new(root_dir)?;
-    register_host_queries(&mut vm);
-    Ok(vm)
-}
-
-/// Creates a new [`VM`] with a temporary directory.
-pub fn new_ephemeral_vm() -> Result<VM, PiecrustError> {
-    let mut vm = VM::ephemeral()?;
-    register_host_queries(&mut vm);
-    Ok(vm)
-}
-
-fn register_host_queries(vm: &mut VM) {
-    vm.register_host_query(Query::HASH, host_hash);
-    vm.register_host_query(Query::POSEIDON_HASH, host_poseidon_hash);
-    vm.register_host_query(Query::VERIFY_PLONK, host_verify_plonk);
-    vm.register_host_query(
-        Query::VERIFY_GROTH16_BN254,
-        host_verify_groth16_bn254,
-    );
-    vm.register_host_query(Query::VERIFY_SCHNORR, host_verify_schnorr);
-    vm.register_host_query(Query::VERIFY_BLS, host_verify_bls);
-    vm.register_host_query(
-        Query::VERIFY_BLS_MULTISIG,
-        host_verify_bls_multisig,
-    );
-}
-
-fn wrap_host_query<A, R, F>(arg_buf: &mut [u8], arg_len: u32, closure: F) -> u32
-where
-    F: FnOnce(A) -> R,
-    A: Archive,
-    A::Archived: Deserialize<A, rkyv::Infallible>,
-    R: Serialize<AllocSerializer<1024>>,
-{
-    let root =
-        unsafe { rkyv::archived_root::<A>(&arg_buf[..arg_len as usize]) };
-    let arg: A = root.deserialize(&mut rkyv::Infallible).unwrap();
-
-    let result = closure(arg);
-
-    let bytes = rkyv::to_bytes::<_, 1024>(&result).unwrap();
-
-    arg_buf[..bytes.len()].copy_from_slice(&bytes);
-    bytes.len() as u32
-}
-
-fn host_hash(arg_buf: &mut [u8], arg_len: u32) -> u32 {
-    wrap_host_query(arg_buf, arg_len, hash)
-}
-
-fn host_poseidon_hash(arg_buf: &mut [u8], arg_len: u32) -> u32 {
-    wrap_host_query(arg_buf, arg_len, poseidon_hash)
-}
-
-fn host_verify_plonk(arg_buf: &mut [u8], arg_len: u32) -> u32 {
-    let hash = *blake2b_simd::blake2b(&arg_buf[..arg_len as usize]).as_array();
-    let cached = cache::get_plonk_verification(hash);
-
-    wrap_host_query(arg_buf, arg_len, |(vd, proof, pis)| {
-        let is_valid = cached.unwrap_or_else(|| verify_plonk(vd, proof, pis));
-        cache::put_plonk_verification(hash, is_valid);
-        is_valid
-    })
-}
-
-fn host_verify_groth16_bn254(arg_buf: &mut [u8], arg_len: u32) -> u32 {
-    let hash = *blake2b_simd::blake2b(&arg_buf[..arg_len as usize]).as_array();
-    let cached = cache::get_groth16_verification(hash);
-
-    wrap_host_query(arg_buf, arg_len, |(pvk, proof, inputs)| {
-        let is_valid =
-            cached.unwrap_or_else(|| verify_groth16_bn254(pvk, proof, inputs));
-        cache::put_groth16_verification(hash, is_valid);
-        is_valid
-    })
-}
-
-fn host_verify_schnorr(arg_buf: &mut [u8], arg_len: u32) -> u32 {
-    wrap_host_query(arg_buf, arg_len, |(msg, pk, sig)| {
-        verify_schnorr(msg, pk, sig)
-    })
-}
-
-fn host_verify_bls(arg_buf: &mut [u8], arg_len: u32) -> u32 {
-    let hash = *blake2b_simd::blake2b(&arg_buf[..arg_len as usize]).as_array();
-    let cached = cache::get_bls_verification(hash);
-
-    wrap_host_query(arg_buf, arg_len, |(msg, pk, sig)| {
-        let is_valid = cached.unwrap_or_else(|| verify_bls(msg, pk, sig));
-        cache::put_bls_verification(hash, is_valid);
-        is_valid
-    })
-}
-
-fn host_verify_bls_multisig(arg_buf: &mut [u8], arg_len: u32) -> u32 {
-    wrap_host_query(arg_buf, arg_len, |(msg, keys, sig)| {
-        verify_bls_multisig(msg, keys, sig)
-    })
-}
+use crate::cache;
 
 /// Compute the blake2b hash of the given scalars, returning the resulting
 /// scalar. The hash is computed in such a way that it will always return a
@@ -245,3 +110,82 @@ pub fn verify_bls_multisig(
 
     akey.verify(&sig, &msg).is_ok()
 }
+
+fn wrap_host_query<A, R, F>(arg_buf: &mut [u8], arg_len: u32, closure: F) -> u32
+where
+    F: FnOnce(A) -> R,
+    A: Archive,
+    A::Archived: Deserialize<A, rkyv::Infallible>,
+    R: Serialize<AllocSerializer<1024>>,
+{
+    let root =
+        unsafe { rkyv::archived_root::<A>(&arg_buf[..arg_len as usize]) };
+    let arg: A = root.deserialize(&mut rkyv::Infallible).unwrap();
+
+    let result = closure(arg);
+
+    let bytes = rkyv::to_bytes::<_, 1024>(&result).unwrap();
+
+    arg_buf[..bytes.len()].copy_from_slice(&bytes);
+    bytes.len() as u32
+}
+
+pub(crate) fn host_hash(arg_buf: &mut [u8], arg_len: u32) -> u32 {
+    wrap_host_query(arg_buf, arg_len, hash)
+}
+
+pub(crate) fn host_poseidon_hash(arg_buf: &mut [u8], arg_len: u32) -> u32 {
+    wrap_host_query(arg_buf, arg_len, poseidon_hash)
+}
+
+pub(crate) fn host_verify_plonk(arg_buf: &mut [u8], arg_len: u32) -> u32 {
+    let hash = *blake2b_simd::blake2b(&arg_buf[..arg_len as usize]).as_array();
+    let cached = cache::get_plonk_verification(hash);
+
+    wrap_host_query(arg_buf, arg_len, |(vd, proof, pis)| {
+        let is_valid = cached.unwrap_or_else(|| verify_plonk(vd, proof, pis));
+        cache::put_plonk_verification(hash, is_valid);
+        is_valid
+    })
+}
+
+pub(crate) fn host_verify_groth16_bn254(
+    arg_buf: &mut [u8],
+    arg_len: u32,
+) -> u32 {
+    let hash = *blake2b_simd::blake2b(&arg_buf[..arg_len as usize]).as_array();
+    let cached = cache::get_groth16_verification(hash);
+
+    wrap_host_query(arg_buf, arg_len, |(pvk, proof, inputs)| {
+        let is_valid =
+            cached.unwrap_or_else(|| verify_groth16_bn254(pvk, proof, inputs));
+        cache::put_groth16_verification(hash, is_valid);
+        is_valid
+    })
+}
+
+pub(crate) fn host_verify_schnorr(arg_buf: &mut [u8], arg_len: u32) -> u32 {
+    wrap_host_query(arg_buf, arg_len, |(msg, pk, sig)| {
+        verify_schnorr(msg, pk, sig)
+    })
+}
+
+pub(crate) fn host_verify_bls(arg_buf: &mut [u8], arg_len: u32) -> u32 {
+    let hash = *blake2b_simd::blake2b(&arg_buf[..arg_len as usize]).as_array();
+    let cached = cache::get_bls_verification(hash);
+
+    wrap_host_query(arg_buf, arg_len, |(msg, pk, sig)| {
+        let is_valid = cached.unwrap_or_else(|| verify_bls(msg, pk, sig));
+        cache::put_bls_verification(hash, is_valid);
+        is_valid
+    })
+}
+
+pub(crate) fn host_verify_bls_multisig(
+    arg_buf: &mut [u8],
+    arg_len: u32,
+) -> u32 {
+    wrap_host_query(arg_buf, arg_len, |(msg, keys, sig)| {
+        verify_bls_multisig(msg, keys, sig)
+    })
+}
diff --git a/vm/src/lib.rs b/vm/src/lib.rs
new file mode 100644
index 0000000000..4de3468896
--- /dev/null
+++ b/vm/src/lib.rs
@@ -0,0 +1,182 @@
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+//
+// Copyright (c) DUSK NETWORK. All rights reserved.
+
+//![doc = include_str!("../README.md")]
+
+#![deny(missing_docs)]
+#![deny(clippy::all)]
+#![deny(unused_crate_dependencies)]
+#![deny(unused_extern_crates)]
+
+extern crate alloc;
+
+pub use piecrust::{
+    CallReceipt, CallTree, CallTreeElem, ContractData, Error, PageOpening,
+    Session,
+};
+
+use alloc::vec::Vec;
+use std::fmt::{self, Debug, Formatter};
+use std::path::{Path, PathBuf};
+use std::thread;
+
+use dusk_core::abi::{Metadata, Query};
+use piecrust::{SessionData, VM as PiecrustVM};
+
+use self::host_queries::{
+    host_hash, host_poseidon_hash, host_verify_bls, host_verify_bls_multisig,
+    host_verify_groth16_bn254, host_verify_plonk, host_verify_schnorr,
+};
+
+pub(crate) mod cache;
+pub mod host_queries;
+
+/// Create a new session based on the given `VM`.
+pub fn new_session(
+    vm: &VM,
+    base: [u8; 32],
+    chain_id: u8,
+    block_height: u64,
+) -> Result<Session, Error> {
+    vm.session(
+        SessionData::builder()
+            .base(base)
+            .insert(Metadata::CHAIN_ID, chain_id)?
+            .insert(Metadata::BLOCK_HEIGHT, block_height)?,
+    )
+}
+
+/// Create a new genesis session based on the given [`VM`].
+pub fn new_genesis_session(vm: &VM, chain_id: u8) -> Session {
+    vm.session(
+        SessionData::builder()
+            .insert(Metadata::CHAIN_ID, chain_id)
+            .expect("Inserting chain ID in metadata should succeed")
+            .insert(Metadata::BLOCK_HEIGHT, 0)
+            .expect("Inserting block height in metadata should succeed"),
+    )
+    .expect("Creating a genesis session should always succeed")
+}
+
+/// Dusk VM is a [`PiecrustVM`] enriched with the host functions specified in
+/// Dusk's ABI.
+pub struct VM(PiecrustVM);
+
+impl From<PiecrustVM> for VM {
+    fn from(piecrust_vm: PiecrustVM) -> Self {
+        VM(piecrust_vm)
+    }
+}
+
+impl Debug for VM {
+    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+        self.0.fmt(f)
+    }
+}
+
+impl VM {
+    /// Creates a new `VM`, reading the given directory for existing commits
+    /// and bytecode.
+    ///
+    /// The directory will be used to save any future session commits made by
+    /// this `VM` instance.
+    ///
+    /// # Errors
+    /// If the directory contains unparseable or inconsistent data.
+    pub fn new(
+        root_dir: impl AsRef<Path> + Into<PathBuf>,
+    ) -> Result<Self, Error> {
+        let mut vm: Self = PiecrustVM::new(root_dir)?.into();
+        vm.register_host_queries();
+        Ok(vm)
+    }
+
+    /// Creates a new `VM` using a new temporary directory.
+    ///
+    /// Any session commits made by this machine should be considered discarded
+    /// once this `VM` instance drops.
+    ///
+    /// # Errors
+    /// If creating a temporary directory fails.
+    pub fn ephemeral() -> Result<VM, Error> {
+        let mut vm: Self = PiecrustVM::ephemeral()?.into();
+        vm.register_host_queries();
+        Ok(vm)
+    }
+
+    /// Spawn a [`Session`].
+    ///
+    /// # Errors
+    /// If base commit is provided but does not exist.
+    ///
+    /// [`Session`]: Session
+    pub fn session(
+        &self,
+        data: impl Into<SessionData>,
+    ) -> Result<Session, Error> {
+        self.0.session(data)
+    }
+
+    /// Return all existing commits.
+    pub fn commits(&self) -> Vec<[u8; 32]> {
+        self.0.commits()
+    }
+
+    /// Deletes the given commit from disk.
+    pub fn delete_commit(&self, root: [u8; 32]) -> Result<(), Error> {
+        self.0.delete_commit(root)
+    }
+
+    /// Finalizes the given commit on disk.
+    pub fn finalize_commit(&self, root: [u8; 32]) -> Result<(), Error> {
+        self.0.finalize_commit(root)
+    }
+
+    /// Return the root directory of the virtual machine.
+    ///
+    /// This is either the directory passed in by using [`new`], or the
+    /// temporary directory created using [`ephemeral`].
+    ///
+    /// [`new`]: VM::new
+    /// [`ephemeral`]: VM::ephemeral
+    pub fn root_dir(&self) -> &Path {
+        self.0.root_dir()
+    }
+
+    /// Returns a reference to the synchronization thread.
+    pub fn sync_thread(&self) -> &thread::Thread {
+        self.0.sync_thread()
+    }
+
+    fn register_host_queries(&mut self) {
+        self.0.register_host_query(Query::HASH, host_hash);
+        self.0
+            .register_host_query(Query::POSEIDON_HASH, host_poseidon_hash);
+        self.0
+            .register_host_query(Query::VERIFY_PLONK, host_verify_plonk);
+        self.0.register_host_query(
+            Query::VERIFY_GROTH16_BN254,
+            host_verify_groth16_bn254,
+        );
+        self.0
+            .register_host_query(Query::VERIFY_SCHNORR, host_verify_schnorr);
+        self.0
+            .register_host_query(Query::VERIFY_BLS, host_verify_bls);
+        self.0.register_host_query(
+            Query::VERIFY_BLS_MULTISIG,
+            host_verify_bls_multisig,
+        );
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    // the `unused_crate_dependencies` lint complains for dev-dependencies that
+    // are only used in integration tests, so adding this work-around here
+    use ff as _;
+    use once_cell as _;
+    use rand as _;
+}


Test patch:
diff --git a/contracts/stake/tests/common/assert.rs b/contracts/stake/tests/common/assert.rs
index 3779d21fcb..539a2b748e 100644
--- a/contracts/stake/tests/common/assert.rs
+++ b/contracts/stake/tests/common/assert.rs
@@ -12,8 +12,8 @@ use dusk_core::stake::{
 };
 use dusk_core::transfer::moonlight::AccountData;
 use dusk_core::transfer::TRANSFER_CONTRACT;
+use dusk_vm::Session;
 use rkyv::{check_archived_root, Deserialize, Infallible};
-use rusk_abi::Session;
 
 use super::utils::GAS_LIMIT;
 
diff --git a/contracts/stake/tests/common/init.rs b/contracts/stake/tests/common/init.rs
index 6a89b735fc..3e0ec49d66 100644
--- a/contracts/stake/tests/common/init.rs
+++ b/contracts/stake/tests/common/init.rs
@@ -10,9 +10,9 @@ use dusk_core::transfer::{
     TRANSFER_CONTRACT,
 };
 use dusk_core::JubJubScalar;
+use dusk_vm::{ContractData, Session, VM};
 use ff::Field;
 use rand::{CryptoRng, RngCore};
-use rusk_abi::{ContractData, Session, VM};
 
 use crate::common::utils::{update_root, GAS_LIMIT};
 
@@ -27,7 +27,7 @@ pub fn instantiate<Rng: RngCore + CryptoRng>(
     pk: &PhoenixPublicKey,
     genesis_value: u64,
 ) -> Session {
-    let mut session = rusk_abi::new_genesis_session(vm, CHAIN_ID);
+    let mut session = dusk_vm::new_genesis_session(vm, CHAIN_ID);
 
     // deploy transfer-contract
     let transfer_bytecode = include_bytes!(
@@ -81,6 +81,6 @@ pub fn instantiate<Rng: RngCore + CryptoRng>(
     // sets the block height for all subsequent operations to 1
     let base = session.commit().expect("Committing should succeed");
 
-    rusk_abi::new_session(vm, base, CHAIN_ID, 1)
+    dusk_vm::new_session(vm, base, CHAIN_ID, 1)
         .expect("Instantiating new session should succeed")
 }
diff --git a/contracts/stake/tests/common/utils.rs b/contracts/stake/tests/common/utils.rs
index 5134c49599..ac4b672e36 100644
--- a/contracts/stake/tests/common/utils.rs
+++ b/contracts/stake/tests/common/utils.rs
@@ -15,8 +15,8 @@ use dusk_core::transfer::phoenix::{
 };
 use dusk_core::transfer::{Transaction, TRANSFER_CONTRACT};
 use dusk_core::{BlsScalar, LUX};
+use dusk_vm::{CallReceipt, Error as VMError, Session};
 use rand::rngs::StdRng;
-use rusk_abi::{CallReceipt, PiecrustError, Session};
 use rusk_prover::LocalProver;
 
 pub const GAS_LIMIT: u64 = 0x100_000_000;
@@ -25,7 +25,7 @@ pub const GAS_PRICE: u64 = LUX;
 pub fn leaves_from_height(
     session: &mut Session,
     height: u64,
-) -> Result<Vec<NoteLeaf>, PiecrustError> {
+) -> Result<Vec<NoteLeaf>, VMError> {
     let (feeder, receiver) = mpsc::channel();
 
     session.feeder_call::<_, ()>(
@@ -45,7 +45,7 @@ pub fn leaves_from_height(
 pub fn leaves_from_pos(
     session: &mut Session,
     pos: u64,
-) -> Result<Vec<NoteLeaf>, PiecrustError> {
+) -> Result<Vec<NoteLeaf>, VMError> {
     let (feeder, receiver) = mpsc::channel();
 
     session.feeder_call::<_, ()>(
@@ -62,13 +62,13 @@ pub fn leaves_from_pos(
         .collect())
 }
 
-pub fn update_root(session: &mut Session) -> Result<(), PiecrustError> {
+pub fn update_root(session: &mut Session) -> Result<(), VMError> {
     session
         .call(TRANSFER_CONTRACT, "update_root", &(), GAS_LIMIT)
         .map(|r| r.data)
 }
 
-pub fn root(session: &mut Session) -> Result<BlsScalar, PiecrustError> {
+pub fn root(session: &mut Session) -> Result<BlsScalar, VMError> {
     session
         .call(TRANSFER_CONTRACT, "root", &(), GAS_LIMIT)
         .map(|r| r.data)
@@ -77,13 +77,13 @@ pub fn root(session: &mut Session) -> Result<BlsScalar, PiecrustError> {
 pub fn opening(
     session: &mut Session,
     pos: u64,
-) -> Result<Option<NoteOpening>, PiecrustError> {
+) -> Result<Option<NoteOpening>, VMError> {
     session
         .call(TRANSFER_CONTRACT, "opening", &pos, GAS_LIMIT)
         .map(|r| r.data)
 }
 
-pub fn chain_id(session: &mut Session) -> Result<u8, PiecrustError> {
+pub fn chain_id(session: &mut Session) -> Result<u8, VMError> {
     session
         .call(TRANSFER_CONTRACT, "chain_id", &(), GAS_LIMIT)
         .map(|r| r.data)
@@ -102,7 +102,7 @@ pub fn filter_notes_owned_by<I: IntoIterator<Item = Note>>(
 pub fn execute(
     session: &mut Session,
     tx: impl Into<Transaction>,
-) -> Result<CallReceipt<Result<Vec<u8>, ContractError>>, PiecrustError> {
+) -> Result<CallReceipt<Result<Vec<u8>, ContractError>>, VMError> {
     let tx = tx.into();
 
     // Spend the inputs and execute the call. If this errors the transaction is
diff --git a/contracts/stake/tests/events.rs b/contracts/stake/tests/events.rs
index 3e6e809d47..e157b40998 100644
--- a/contracts/stake/tests/events.rs
+++ b/contracts/stake/tests/events.rs
@@ -23,7 +23,7 @@ use dusk_core::{
         TRANSFER_CONTRACT,
     },
 };
-use rusk_abi::PiecrustError;
+use dusk_vm::{Error as VMError, VM};
 
 use crate::common::assert::assert_reward_event;
 use crate::common::init::instantiate;
@@ -31,11 +31,10 @@ use crate::common::init::instantiate;
 const GENESIS_VALUE: u64 = dusk(1_000_000.0);
 
 #[test]
-fn reward_slash() -> Result<(), PiecrustError> {
+fn reward_slash() -> Result<(), VMError> {
     let rng = &mut StdRng::seed_from_u64(0xfeeb);
 
-    let vm = &mut rusk_abi::new_ephemeral_vm()
-        .expect("Creating ephemeral VM should work");
+    let vm = &mut VM::ephemeral().expect("Creating ephemeral VM should work");
 
     let sk = PhoenixSecretKey::random(rng);
     let pk = PhoenixPublicKey::from(&sk);
@@ -121,11 +120,10 @@ fn reward_slash() -> Result<(), PiecrustError> {
 }
 
 #[test]
-fn stake_hard_slash() -> Result<(), PiecrustError> {
+fn stake_hard_slash() -> Result<(), VMError> {
     let rng = &mut StdRng::seed_from_u64(0xfeeb);
 
-    let vm = &mut rusk_abi::new_ephemeral_vm()
-        .expect("Creating ephemeral VM should work");
+    let vm = &mut VM::ephemeral().expect("Creating ephemeral VM should work");
 
     let sk = PhoenixSecretKey::random(rng);
     let pk = PhoenixPublicKey::from(&sk);
diff --git a/contracts/stake/tests/partial_stake.rs b/contracts/stake/tests/partial_stake.rs
index 8629d0fab8..0db5c20efc 100644
--- a/contracts/stake/tests/partial_stake.rs
+++ b/contracts/stake/tests/partial_stake.rs
@@ -10,9 +10,12 @@ use dusk_core::signatures::bls::{
 };
 use dusk_core::stake::{Reward, RewardReason, EPOCH, STAKE_CONTRACT};
 use dusk_core::transfer::TRANSFER_CONTRACT;
+use dusk_vm::{
+    new_genesis_session, new_session, ContractData, Error as VMError, Session,
+    VM,
+};
 use rand::rngs::StdRng;
 use rand::SeedableRng;
-use rusk_abi::{ContractData, PiecrustError, Session, VM};
 use wallet_core::transaction::{
     moonlight_stake, moonlight_stake_reward, moonlight_unstake,
 };
@@ -28,7 +31,7 @@ const STAKE_VALUE: u64 = GENESIS_VALUE / 2;
 const GENESIS_NONCE: u64 = 0;
 
 #[test]
-fn stake() -> Result<(), PiecrustError> {
+fn stake() -> Result<(), VMError> {
     // ------
     // instantiate the test
 
@@ -40,7 +43,7 @@ fn stake() -> Result<(), PiecrustError> {
     let stake_sk = BlsSecretKey::random(rng);
     let stake_pk = BlsPublicKey::from(&stake_sk);
 
-    let mut vm = &mut rusk_abi::new_ephemeral_vm()?;
+    let mut vm = &mut VM::ephemeral()?;
     let mut session = instantiate(&mut vm, &moonlight_pk);
 
     // ------
@@ -106,7 +109,7 @@ fn stake() -> Result<(), PiecrustError> {
     // in order to test the locking some of the stake during a top-up, we need
     // to start a new session at a block-height on which the stake is eligible
     let base = session.commit()?;
-    let mut session = rusk_abi::new_session(&vm, base, CHAIN_ID, 2 * EPOCH)?;
+    let mut session = new_session(&vm, base, CHAIN_ID, 2 * EPOCH)?;
 
     // execute 3rd stake transaction
     let stake_3 = STAKE_VALUE - stake_1 - stake_2;
@@ -163,7 +166,7 @@ fn stake() -> Result<(), PiecrustError> {
 }
 
 #[test]
-fn unstake() -> Result<(), PiecrustError> {
+fn unstake() -> Result<(), VMError> {
     // ------
     // instantiate the test
 
@@ -175,7 +178,7 @@ fn unstake() -> Result<(), PiecrustError> {
     let stake_sk = BlsSecretKey::random(rng);
     let stake_pk = BlsPublicKey::from(&stake_sk);
 
-    let mut vm = &mut rusk_abi::new_ephemeral_vm()?;
+    let mut vm = &mut VM::ephemeral()?;
     let mut session = instantiate(&mut vm, &moonlight_pk);
 
     // initial stake
@@ -230,7 +233,7 @@ fn unstake() -> Result<(), PiecrustError> {
 
     // re-stake the unstaked value after the stake has become eligible
     let base = session.commit()?;
-    let mut session = rusk_abi::new_session(&vm, base, CHAIN_ID, 2 * EPOCH)?;
+    let mut session = new_session(&vm, base, CHAIN_ID, 2 * EPOCH)?;
     nonce += 1;
     let tx = moonlight_stake(
         &moonlight_sk,
@@ -322,7 +325,7 @@ fn unstake() -> Result<(), PiecrustError> {
 }
 
 #[test]
-fn withdraw_reward() -> Result<(), PiecrustError> {
+fn withdraw_reward() -> Result<(), VMError> {
     // ------
     // instantiate the test
 
@@ -334,7 +337,7 @@ fn withdraw_reward() -> Result<(), PiecrustError> {
     let stake_sk = BlsSecretKey::random(rng);
     let stake_pk = BlsPublicKey::from(&stake_sk);
 
-    let mut vm = &mut rusk_abi::new_ephemeral_vm()?;
+    let mut vm = &mut VM::ephemeral()?;
     let mut session = instantiate(&mut vm, &moonlight_pk);
 
     // initial stake
@@ -435,7 +438,7 @@ fn add_reward(
     session: &mut Session,
     stake_pk: &BlsPublicKey,
     reward: u64,
-) -> Result<(), PiecrustError> {
+) -> Result<(), VMError> {
     let rewards = vec![Reward {
         account: *stake_pk,
         value: reward,
@@ -455,7 +458,7 @@ fn add_reward(
 /// genesis-value.
 fn instantiate(vm: &mut VM, moonlight_pk: &BlsPublicKey) -> Session {
     // create a new session using an ephemeral vm
-    let mut session = rusk_abi::new_genesis_session(vm, CHAIN_ID);
+    let mut session = new_genesis_session(vm, CHAIN_ID);
 
     // deploy transfer-contract
     const OWNER: [u8; 32] = [0; 32];
@@ -499,7 +502,7 @@ fn instantiate(vm: &mut VM, moonlight_pk: &BlsPublicKey) -> Session {
     // sets the block height for all subsequent operations to 1
     let base = session.commit().expect("Committing should succeed");
 
-    let mut session = rusk_abi::new_session(vm, base, CHAIN_ID, 1)
+    let mut session = new_session(vm, base, CHAIN_ID, 1)
         .expect("Instantiating new session should succeed");
 
     // check that the moonlight account is initialized as expected
diff --git a/contracts/stake/tests/stake.rs b/contracts/stake/tests/stake.rs
index 1af234b93b..aed9e0f1c0 100644
--- a/contracts/stake/tests/stake.rs
+++ b/contracts/stake/tests/stake.rs
@@ -21,6 +21,7 @@ use dusk_core::transfer::withdraw::{
     Withdraw, WithdrawReceiver, WithdrawReplayToken,
 };
 use dusk_core::{dusk, JubJubScalar};
+use dusk_vm::{new_session, VM};
 use ff::Field;
 use rand::rngs::StdRng;
 use rand::SeedableRng;
@@ -41,8 +42,7 @@ fn stake_withdraw_unstake() {
 
     let rng = &mut StdRng::seed_from_u64(0xfeeb);
 
-    let vm = &mut rusk_abi::new_ephemeral_vm()
-        .expect("Creating ephemeral VM should work");
+    let vm = &mut VM::ephemeral().expect("Creating ephemeral VM should work");
 
     let phoenix_sender_sk = PhoenixSecretKey::random(rng);
     let phoenix_sender_vk = PhoenixViewKey::from(&phoenix_sender_sk);
@@ -178,7 +178,7 @@ fn stake_withdraw_unstake() {
     // set different block height so that the new notes are easily located and
     // filtered
     let base = session.commit().expect("Committing should succeed");
-    let mut session = rusk_abi::new_session(vm, base, CHAIN_ID, 2)
+    let mut session = new_session(vm, base, CHAIN_ID, 2)
         .expect("Instantiating new session should succeed");
 
     let receipt =
@@ -274,7 +274,7 @@ fn stake_withdraw_unstake() {
     // filtered
     // sets the block height for all subsequent operations to 1
     let base = session.commit().expect("Committing should succeed");
-    let mut session = rusk_abi::new_session(vm, base, CHAIN_ID, 3)
+    let mut session = new_session(vm, base, CHAIN_ID, 3)
         .expect("Instantiating new session should succeed");
 
     let receipt =
diff --git a/contracts/transfer/tests/common/utils.rs b/contracts/transfer/tests/common/utils.rs
index aa6bc40d02..c42bfd22b5 100644
--- a/contracts/transfer/tests/common/utils.rs
+++ b/contracts/transfer/tests/common/utils.rs
@@ -12,20 +12,20 @@ use dusk_core::transfer::moonlight::AccountData;
 use dusk_core::transfer::phoenix::{Note, NoteLeaf, ViewKey as PhoenixViewKey};
 use dusk_core::transfer::{Transaction, TRANSFER_CONTRACT};
 use dusk_core::BlsScalar;
-use rusk_abi::{CallReceipt, PiecrustError, Session};
+use dusk_vm::{CallReceipt, Error as VMError, Session};
 
 const GAS_LIMIT: u64 = 0x10_000_000;
 
 pub fn contract_balance(
     session: &mut Session,
     contract: ContractId,
-) -> Result<u64, PiecrustError> {
+) -> Result<u64, VMError> {
     session
         .call(TRANSFER_CONTRACT, "contract_balance", &contract, GAS_LIMIT)
         .map(|r| r.data)
 }
 
-pub fn chain_id(session: &mut Session) -> Result<u8, PiecrustError> {
+pub fn chain_id(session: &mut Session) -> Result<u8, VMError> {
     session
         .call(TRANSFER_CONTRACT, "chain_id", &(), GAS_LIMIT)
         .map(|r| r.data)
@@ -36,7 +36,7 @@ pub fn chain_id(session: &mut Session) -> Result<u8, PiecrustError> {
 pub fn execute(
     session: &mut Session,
     tx: impl Into<Transaction>,
-) -> Result<CallReceipt<Result<Vec<u8>, ContractError>>, PiecrustError> {
+) -> Result<CallReceipt<Result<Vec<u8>, ContractError>>, VMError> {
     let tx = tx.into();
 
     let mut receipt = session.call::<_, Result<Vec<u8>, ContractError>>(
@@ -70,7 +70,7 @@ pub fn execute(
 pub fn account(
     session: &mut Session,
     pk: &AccountPublicKey,
-) -> Result<AccountData, PiecrustError> {
+) -> Result<AccountData, VMError> {
     session
         .call(TRANSFER_CONTRACT, "account", pk, GAS_LIMIT)
         .map(|r| r.data)
@@ -106,7 +106,7 @@ pub fn owned_notes_value<'a, I: IntoIterator<Item = &'a Note>>(
 pub fn leaves_from_height(
     session: &mut Session,
     height: u64,
-) -> Result<Vec<NoteLeaf>, PiecrustError> {
+) -> Result<Vec<NoteLeaf>, VMError> {
     let (feeder, receiver) = mpsc::channel();
 
     session.feeder_call::<_, ()>(
@@ -123,7 +123,7 @@ pub fn leaves_from_height(
         .collect())
 }
 
-pub fn update_root(session: &mut Session) -> Result<(), PiecrustError> {
+pub fn update_root(session: &mut Session) -> Result<(), VMError> {
     session
         .call(TRANSFER_CONTRACT, "update_root", &(), GAS_LIMIT)
         .map(|r| r.data)
@@ -142,7 +142,7 @@ pub fn filter_notes_owned_by<I: IntoIterator<Item = Note>>(
 pub fn existing_nullifiers(
     session: &mut Session,
     nullifiers: &Vec<BlsScalar>,
-) -> Result<Vec<BlsScalar>, PiecrustError> {
+) -> Result<Vec<BlsScalar>, VMError> {
     session
         .call(
             TRANSFER_CONTRACT,
diff --git a/contracts/transfer/tests/moonlight.rs b/contracts/transfer/tests/moonlight.rs
index 988c132532..5f8f0dfc19 100644
--- a/contracts/transfer/tests/moonlight.rs
+++ b/contracts/transfer/tests/moonlight.rs
@@ -32,7 +32,7 @@ use dusk_core::transfer::{
     ContractToAccount, ContractToContract, TRANSFER_CONTRACT,
 };
 use dusk_core::{dusk, JubJubScalar, LUX};
-use rusk_abi::{ContractData, Session};
+use dusk_vm::{new_genesis_session, new_session, ContractData, Session, VM};
 
 const MOONLIGHT_GENESIS_VALUE: u64 = dusk(1_000.0);
 const MOONLIGHT_GENESIS_NONCE: u64 = 0;
@@ -68,10 +68,9 @@ fn instantiate(moonlight_pk: &AccountPublicKey) -> Session {
         "../../../target/dusk/wasm32-unknown-unknown/release/bob.wasm"
     );
 
-    let vm = &mut rusk_abi::new_ephemeral_vm()
-        .expect("Creating ephemeral VM should work");
+    let vm = &mut VM::ephemeral().expect("Creating ephemeral VM should work");
 
-    let mut session = rusk_abi::new_genesis_session(vm, CHAIN_ID);
+    let mut session = new_genesis_session(vm, CHAIN_ID);
 
     session
         .deploy(
@@ -126,7 +125,7 @@ fn instantiate(moonlight_pk: &AccountPublicKey) -> Session {
     // operations to 1
     let base = session.commit().expect("Committing should succeed");
     // start a new session from that base-commit
-    let mut session = rusk_abi::new_session(vm, base, CHAIN_ID, 1)
+    let mut session = new_session(vm, base, CHAIN_ID, 1)
         .expect("Instantiating new session should succeed");
 
     // check genesis state
diff --git a/contracts/transfer/tests/phoenix.rs b/contracts/transfer/tests/phoenix.rs
index b7172b49fa..97496751cb 100644
--- a/contracts/transfer/tests/phoenix.rs
+++ b/contracts/transfer/tests/phoenix.rs
@@ -27,10 +27,13 @@ use dusk_core::transfer::{
     ContractToAccount, ContractToContract, TRANSFER_CONTRACT,
 };
 use dusk_core::{BlsScalar, JubJubScalar, LUX};
+use dusk_vm::{
+    new_genesis_session, new_session, ContractData, Error as VMError, Session,
+    VM,
+};
 use ff::Field;
 use rand::rngs::StdRng;
 use rand::{CryptoRng, RngCore, SeedableRng};
-use rusk_abi::{ContractData, PiecrustError, Session};
 use rusk_prover::LocalProver;
 
 use crate::common::utils::{
@@ -79,10 +82,9 @@ fn instantiate<const N: u8>(
         "../../../target/dusk/wasm32-unknown-unknown/release/bob.wasm"
     );
 
-    let vm = &mut rusk_abi::new_ephemeral_vm()
-        .expect("Creating ephemeral VM should work");
+    let vm = &mut VM::ephemeral().expect("Creating ephemeral VM should work");
 
-    let mut session = rusk_abi::new_genesis_session(vm, CHAIN_ID);
+    let mut session = new_genesis_session(vm, CHAIN_ID);
 
     session
         .deploy(
@@ -158,7 +160,7 @@ fn instantiate<const N: u8>(
     // operations to 1
     let base = session.commit().expect("Committing should succeed");
     // start a new session from that base-commit
-    let mut session = rusk_abi::new_session(vm, base, CHAIN_ID, 1)
+    let mut session = new_session(vm, base, CHAIN_ID, 1)
         .expect("Instantiating new session should succeed");
 
     // check that the genesis state is correct:
@@ -1513,7 +1515,7 @@ fn contract_to_account() {
 fn leaves_from_pos(
     session: &mut Session,
     pos: u64,
-) -> Result<Vec<NoteLeaf>, PiecrustError> {
+) -> Result<Vec<NoteLeaf>, VMError> {
     let (feeder, receiver) = mpsc::channel();
 
     session.feeder_call::<_, ()>(
@@ -1530,13 +1532,13 @@ fn leaves_from_pos(
         .collect())
 }
 
-fn num_notes(session: &mut Session) -> Result<u64, PiecrustError> {
+fn num_notes(session: &mut Session) -> Result<u64, VMError> {
     session
         .call(TRANSFER_CONTRACT, "num_notes", &(), u64::MAX)
         .map(|r| r.data)
 }
 
-fn root(session: &mut Session) -> Result<BlsScalar, PiecrustError> {
+fn root(session: &mut Session) -> Result<BlsScalar, VMError> {
     session
         .call(TRANSFER_CONTRACT, "root", &(), GAS_LIMIT)
         .map(|r| r.data)
@@ -1545,7 +1547,7 @@ fn root(session: &mut Session) -> Result<BlsScalar, PiecrustError> {
 fn opening(
     session: &mut Session,
     pos: u64,
-) -> Result<Option<NoteOpening>, PiecrustError> {
+) -> Result<Option<NoteOpening>, VMError> {
     session
         .call(TRANSFER_CONTRACT, "opening", &pos, GAS_LIMIT)
         .map(|r| r.data)
diff --git a/rusk/src/lib/test_utils.rs b/rusk/src/lib/test_utils.rs
index c56b79e180..4fe6e2b454 100644
--- a/rusk/src/lib/test_utils.rs
+++ b/rusk/src/lib/test_utils.rs
@@ -26,8 +26,8 @@ use dusk_core::{
     },
     BlsScalar,
 };
+use dusk_vm::VM;
 use parking_lot::RwLockWriteGuard;
-use rusk_abi::VM;
 
 pub type StoredNote = (Note, u64);
 
diff --git a/rusk/tests/rusk-state.rs b/rusk/tests/rusk-state.rs
index bad69e52ae..505978624d 100644
--- a/rusk/tests/rusk-state.rs
+++ b/rusk/tests/rusk-state.rs
@@ -22,13 +22,13 @@ use dusk_core::{
     },
     JubJubScalar, LUX,
 };
+use dusk_vm::VM;
 use ff::Field;
 use parking_lot::RwLockWriteGuard;
 use rand::prelude::*;
 use rand::rngs::StdRng;
 use rusk::node::{Rusk, RuskTip};
 use rusk::Result;
-use rusk_abi::VM;
 use tempfile::tempdir;
 use tracing::info;
 
@@ -84,7 +84,7 @@ where
     rusk.with_tip(|mut tip, vm| {
         let current_commit = tip.current;
         let mut session =
-            rusk_abi::new_session(vm, current_commit, CHAIN_ID, BLOCK_HEIGHT)
+            dusk_vm::new_session(vm, current_commit, CHAIN_ID, BLOCK_HEIGHT)
                 .expect("current commit should exist");
 
         session
diff --git a/rusk/tests/services/contract_deployment.rs b/rusk/tests/services/contract_deployment.rs
index 0d300b5bc4..83c0fdd09d 100644
--- a/rusk/tests/services/contract_deployment.rs
+++ b/rusk/tests/services/contract_deployment.rs
@@ -12,11 +12,11 @@ use dusk_core::abi::ContractId;
 use dusk_core::transfer::data::{
     ContractBytecode, ContractDeploy, TransactionData,
 };
+use dusk_vm::{new_session, ContractData, Error as VMError, VM};
 use rand::prelude::*;
 use rand::rngs::StdRng;
 use rusk::gen_id::gen_contract_id;
 use rusk::{Result, Rusk};
-use rusk_abi::{ContractData, PiecrustError};
 use rusk_recovery_tools::state;
 use tempfile::tempdir;
 use test_wallet::{self as wallet, Wallet};
@@ -230,9 +230,9 @@ impl Fixture {
 
     pub fn assert_bob_contract_is_not_deployed(&self) {
         let commit = self.rusk.state_root();
-        let vm = rusk_abi::new_vm(self.path.as_path())
-            .expect("VM creation should succeed");
-        let mut session = rusk_abi::new_session(&vm, commit, CHAIN_ID, 0)
+        let vm =
+            VM::new(self.path.as_path()).expect("VM creation should succeed");
+        let mut session = new_session(&vm, commit, CHAIN_ID, 0)
             .expect("Session creation should succeed");
         let result = session.call::<_, u64>(
             self.contract_id,
@@ -241,16 +241,16 @@ impl Fixture {
             u64::MAX,
         );
         match result.err() {
-            Some(PiecrustError::ContractDoesNotExist(_)) => (),
+            Some(VMError::ContractDoesNotExist(_)) => (),
             _ => assert!(false),
         }
     }
 
     pub fn assert_bob_contract_is_deployed(&self) {
         let commit = self.rusk.state_root();
-        let vm = rusk_abi::new_vm(self.path.as_path())
-            .expect("VM creation should succeed");
-        let mut session = rusk_abi::new_session(&vm, commit, CHAIN_ID, 0)
+        let vm =
+            VM::new(self.path.as_path()).expect("VM creation should succeed");
+        let mut session = new_session(&vm, commit, CHAIN_ID, 0)
             .expect("Session creation should succeed");
         let result = session.call::<_, u64>(
             self.contract_id,
diff --git a/rusk/tests/services/owner_calls.rs b/rusk/tests/services/owner_calls.rs
index 79684f7a7b..4516141501 100644
--- a/rusk/tests/services/owner_calls.rs
+++ b/rusk/tests/services/owner_calls.rs
@@ -19,9 +19,9 @@ use dusk_core::signatures::bls::{
     PublicKey as BlsPublicKey, SecretKey as BlsSecretKey,
     Signature as BlsSignature,
 };
+use dusk_vm::{new_session, CallReceipt, ContractData, Session, VM};
 use rusk::gen_id::gen_contract_id;
 use rusk::{Error, Result, Rusk};
-use rusk_abi::{CallReceipt, ContractData, Session};
 use rusk_recovery_tools::state;
 use tempfile::tempdir;
 use test_wallet::{self as wallet, Wallet};
@@ -144,9 +144,9 @@ impl Fixture {
     pub fn assert_bob_contract_is_deployed(&self) {
         const BOB_ECHO_VALUE: u64 = 775;
         let commit = self.rusk.state_root();
-        let vm = rusk_abi::new_vm(self.path.as_path())
-            .expect("VM creation should succeed");
-        let mut session = rusk_abi::new_session(&vm, commit, CHAIN_ID, 0)
+        let vm =
+            VM::new(self.path.as_path()).expect("VM creation should succeed");
+        let mut session = new_session(&vm, commit, CHAIN_ID, 0)
             .expect("Session creation should succeed");
         let result = session.call::<_, u64>(
             self.contract_id,
@@ -168,10 +168,10 @@ impl Fixture {
 
     pub fn set_session(&mut self) {
         let commit = self.rusk.state_root();
-        let vm = rusk_abi::new_vm(self.path.as_path())
-            .expect("VM creation should succeed");
+        let vm =
+            VM::new(self.path.as_path()).expect("VM creation should succeed");
         self.session = Some(
-            rusk_abi::new_session(&vm, commit, CHAIN_ID, 0)
+            new_session(&vm, commit, CHAIN_ID, 0)
                 .expect("Session creation should succeed"),
         );
     }
diff --git a/rusk/tests/services/transfer.rs b/rusk/tests/services/transfer.rs
index 0b6ec460d0..c618119e9d 100644
--- a/rusk/tests/services/transfer.rs
+++ b/rusk/tests/services/transfer.rs
@@ -78,7 +78,7 @@ fn wallet_transfer(
     info!("Tx: {}", hex::encode(tx.to_var_bytes()));
 
     let tx_hash_input_bytes = tx.to_hash_input_bytes();
-    let tx_id = rusk_abi::hash(tx_hash_input_bytes);
+    let tx_id = dusk_vm::host_queries::hash(tx_hash_input_bytes);
 
     info!("Tx ID: {}", hex::encode(tx_id.to_bytes()));
     let txs: Vec<SpentTransaction> = generator_procedure(
diff --git a/rusk-abi/tests/pp_test.bin b/vm/tests/pp_test.bin
similarity index 100%
rename from rusk-abi/tests/pp_test.bin
rename to vm/tests/pp_test.bin
diff --git a/rusk-abi/tests/lib.rs b/vm/tests/vm.rs
similarity index 92%
rename from rusk-abi/tests/lib.rs
rename to vm/tests/vm.rs
index 6bd9a6bac4..2a17e6c17d 100644
--- a/rusk-abi/tests/lib.rs
+++ b/vm/tests/vm.rs
@@ -30,9 +30,9 @@ use dusk_core::signatures::schnorr::{
     PublicKey as SchnorrPublicKey, SecretKey as SchnorrSecretKey,
 };
 use dusk_core::BlsScalar;
+use dusk_vm::{ContractData, Session, VM};
 use ff::Field;
 use rand::rngs::OsRng;
-use rusk_abi::{ContractData, Session, VM};
 
 const POINT_LIMIT: u64 = 0x4000000;
 const CHAIN_ID: u8 = 0xFA;
@@ -66,7 +66,7 @@ fn instantiate(vm: &VM, height: u64) -> (Session, ContractId) {
         "../../target/dusk/wasm32-unknown-unknown/release/host_fn.wasm"
     );
 
-    let mut session = rusk_abi::new_genesis_session(vm, CHAIN_ID);
+    let mut session = dusk_vm::new_genesis_session(vm, CHAIN_ID);
 
     let contract_id = session
         .deploy(
@@ -78,7 +78,7 @@ fn instantiate(vm: &VM, height: u64) -> (Session, ContractId) {
 
     let base = session.commit().expect("Committing should succeed");
 
-    let session = rusk_abi::new_session(vm, base, CHAIN_ID, height)
+    let session = dusk_vm::new_session(vm, base, CHAIN_ID, height)
         .expect("Instantiating new session should succeed");
 
     (session, contract_id)
@@ -86,8 +86,7 @@ fn instantiate(vm: &VM, height: u64) -> (Session, ContractId) {
 
 #[test]
 fn hash() {
-    let vm =
-        rusk_abi::new_ephemeral_vm().expect("Instantiating VM should succeed");
+    let vm = VM::ephemeral().expect("Instantiating VM should succeed");
     let (mut session, contract_id) = instantiate(&vm, 0);
 
     let test_inputs = [
@@ -119,8 +118,7 @@ fn hash() {
 
 #[test]
 fn poseidon_hash() {
-    let vm =
-        rusk_abi::new_ephemeral_vm().expect("Instantiating VM should succeed");
+    let vm = VM::ephemeral().expect("Instantiating VM should succeed");
     let (mut session, contract_id) = instantiate(&vm, 0);
 
     let test_inputs = [
@@ -147,8 +145,7 @@ fn poseidon_hash() {
 
 #[test]
 fn schnorr_signature() {
-    let vm =
-        rusk_abi::new_ephemeral_vm().expect("Instantiating VM should succeed");
+    let vm = VM::ephemeral().expect("Instantiating VM should succeed");
     let (mut session, contract_id) = instantiate(&vm, 0);
 
     let sk = SchnorrSecretKey::random(&mut OsRng);
@@ -189,8 +186,7 @@ fn schnorr_signature() {
 
 #[test]
 fn bls_signature() {
-    let vm =
-        rusk_abi::new_ephemeral_vm().expect("Instantiating VM should succeed");
+    let vm = VM::ephemeral().expect("Instantiating VM should succeed");
     let (mut session, contract_id) = instantiate(&vm, 0);
 
     let message = b"some-message".to_vec();
@@ -222,8 +218,7 @@ fn bls_signature() {
 
 #[test]
 fn bls_multisig_signature() {
-    let vm =
-        rusk_abi::new_ephemeral_vm().expect("Instantiating VM should succeed");
+    let vm = VM::ephemeral().expect("Instantiating VM should succeed");
     let (mut session, contract_id) = instantiate(&vm, 0);
 
     let message = b"some-message".to_vec();
@@ -325,8 +320,7 @@ impl Circuit for PlonkTestCircuit {
 
 #[test]
 fn plonk_proof() {
-    let vm =
-        rusk_abi::new_ephemeral_vm().expect("Instantiating VM should succeed");
+    let vm = VM::ephemeral().expect("Instantiating VM should succeed");
     let (mut session, contract_id) = instantiate(&vm, 0);
 
     let pp = include_bytes!("./pp_test.bin");
@@ -404,8 +398,7 @@ impl<F: Groth16Field> ConstraintSynthesizer<F> for Groth16TestCircuit<F> {
 
 #[test]
 fn groth16_proof() {
-    let vm =
-        rusk_abi::new_ephemeral_vm().expect("Instantiating VM should succeed");
+    let vm = VM::ephemeral().expect("Instantiating VM should succeed");
     let (mut session, contract_id) = instantiate(&vm, 0);
 
     let test_circuit = Groth16TestCircuit {
@@ -497,8 +490,7 @@ fn groth16_proof() {
 fn chain_id() {
     const HEIGHT: u64 = 123;
 
-    let vm =
-        rusk_abi::new_ephemeral_vm().expect("Instantiating VM should succeed");
+    let vm = VM::ephemeral().expect("Instantiating VM should succeed");
     let (mut session, contract_id) = instantiate(&vm, HEIGHT);
 
     let chain_id: u8 = session
@@ -513,8 +505,7 @@ fn chain_id() {
 fn block_height() {
     const HEIGHT: u64 = 123;
 
-    let vm =
-        rusk_abi::new_ephemeral_vm().expect("Instantiating VM should succeed");
+    let vm = VM::ephemeral().expect("Instantiating VM should succeed");
     let (mut session, contract_id) = instantiate(&vm, HEIGHT);
 
     let height: u64 = session
@@ -535,8 +526,7 @@ fn get_owner() -> &'static BlsPublicKey {
 
 #[test]
 fn owner_raw() {
-    let vm =
-        rusk_abi::new_ephemeral_vm().expect("Instantiating VM should succeed");
+    let vm = VM::ephemeral().expect("Instantiating VM should succeed");
     let (mut session, contract_id) = instantiate(&vm, 0);
 
     let owner: [u8; 96] = session
@@ -549,8 +539,7 @@ fn owner_raw() {
 
 #[test]
 fn owner() {
-    let vm =
-        rusk_abi::new_ephemeral_vm().expect("Instantiating VM should succeed");
+    let vm = VM::ephemeral().expect("Instantiating VM should succeed");
     let (mut session, contract_id) = instantiate(&vm, 0);
 
     let owner: BlsPublicKey = session