From 4ee42ae3fc7e78f6394592effa80f7e904bc27b6 Mon Sep 17 00:00:00 2001 From: Mathieu Dutour Sikiric Date: Fri, 21 Feb 2025 07:47:13 +0100 Subject: [PATCH 01/16] Introduce the VmRuntime. --- linera-base/src/data_types.rs | 32 +--- linera-chain/src/chain.rs | 6 +- linera-chain/src/unit_tests/chain_tests.rs | 8 +- linera-client/src/client_options.rs | 19 +- linera-client/src/storage.rs | 61 ++----- linera-core/src/chain_worker/actor.rs | 6 +- linera-core/src/chain_worker/state/mod.rs | 7 +- .../chain_worker/state/temporary_changes.rs | 4 +- linera-core/src/client/mod.rs | 6 +- linera-core/src/local_node.rs | 4 +- linera-core/src/unit_tests/client_tests.rs | 50 ++--- linera-core/src/unit_tests/test_utils.rs | 117 +----------- .../src/unit_tests/wasm_client_tests.rs | 113 +++++++----- .../src/unit_tests/wasm_worker_tests.rs | 17 +- linera-core/src/unit_tests/worker_tests.rs | 1 - linera-core/src/worker.rs | 6 +- linera-execution/build.rs | 2 +- linera-execution/src/applications.rs | 6 +- linera-execution/src/execution_state_actor.rs | 5 +- linera-execution/src/lib.rs | 171 +++++++++++++++--- linera-execution/src/runtime.rs | 4 +- linera-execution/src/system.rs | 8 +- linera-execution/src/test_utils/mod.rs | 4 +- .../src/unit_tests/applications_tests.rs | 3 + .../src/unit_tests/system_tests.rs | 2 + linera-execution/src/wasm/system_api.rs | 11 +- .../tests/contract_runtime_apis.rs | 7 +- linera-sdk/src/test/chain.rs | 4 +- linera-sdk/src/test/validator.rs | 14 +- linera-service-graphql-client/src/service.rs | 9 +- linera-service/src/linera/main.rs | 17 +- linera-service/src/node_service.rs | 8 +- linera-service/src/proxy/main.rs | 1 - linera-service/src/schema_export.rs | 2 +- linera-service/src/server.rs | 10 +- linera-storage/Cargo.toml | 1 + linera-storage/build.rs | 1 + linera-storage/src/db_storage.rs | 21 +-- linera-storage/src/lib.rs | 55 +++--- 39 files changed, 429 insertions(+), 394 deletions(-) diff --git a/linera-base/src/data_types.rs b/linera-base/src/data_types.rs index 906e8c1a066a..94dcbfd7deb1 100644 --- a/linera-base/src/data_types.rs +++ b/linera-base/src/data_types.rs @@ -32,8 +32,8 @@ use crate::{ crypto::{BcsHashable, CryptoHash}, doc_scalar, hex_debug, http, identifiers::{ - ApplicationId, BlobId, BlobType, BytecodeId, ChainId, Destination, EventId, - GenericApplicationId, MessageId, StreamId, UserApplicationId, + ApplicationId, BlobId, BlobType, ChainId, Destination, EventId, GenericApplicationId, + StreamId, }, limited_writer::{LimitedWriter, LimitedWriterError}, time::{Duration, SystemTime}, @@ -782,30 +782,6 @@ pub enum OracleResponse { impl<'de> BcsHashable<'de> for OracleResponse {} -/// Description of the necessary information to run a user application. -#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Hash, Serialize)] -pub struct UserApplicationDescription { - /// The unique ID of the bytecode to use for the application. - pub bytecode_id: BytecodeId, - /// The unique ID of the application's creation. - pub creation: MessageId, - /// The parameters of the application. - #[serde(with = "serde_bytes")] - #[debug(with = "hex_debug")] - pub parameters: Vec, - /// Required dependencies. - pub required_application_ids: Vec, -} - -impl From<&UserApplicationDescription> for UserApplicationId { - fn from(description: &UserApplicationDescription) -> Self { - UserApplicationId { - bytecode_id: description.bytecode_id, - creation: description.creation, - } - } -} - /// A WebAssembly module's bytecode. #[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] pub struct Bytecode { @@ -1156,10 +1132,6 @@ doc_scalar!( Blob, "A blob of binary data, with its content-addressed blob ID." ); -doc_scalar!( - UserApplicationDescription, - "Description of the necessary information to run a user application" -); /// The time it takes to compress a bytecode. #[cfg(with_metrics)] diff --git a/linera-chain/src/chain.rs b/linera-chain/src/chain.rs index 05a3a608d998..a35e03f9339a 100644 --- a/linera-chain/src/chain.rs +++ b/linera-chain/src/chain.rs @@ -12,9 +12,7 @@ use async_graphql::SimpleObject; use futures::stream::{self, StreamExt, TryStreamExt}; use linera_base::{ crypto::{CryptoHash, ValidatorPublicKey}, - data_types::{ - Amount, ArithmeticError, BlockHeight, OracleResponse, Timestamp, UserApplicationDescription, - }, + data_types::{Amount, ArithmeticError, BlockHeight, OracleResponse, Timestamp}, ensure, identifiers::{ ChainId, ChannelFullName, Destination, GenericApplicationId, MessageId, Owner, @@ -28,7 +26,7 @@ use linera_execution::{ ExecutionOutcome, ExecutionRuntimeContext, ExecutionStateView, Message, MessageContext, Operation, OperationContext, Query, QueryContext, QueryOutcome, RawExecutionOutcome, RawOutgoingMessage, ResourceController, ResourceTracker, ServiceRuntimeEndpoint, - TransactionTracker, + TransactionTracker, UserApplicationDescription, }; use linera_views::{ context::Context, diff --git a/linera-chain/src/unit_tests/chain_tests.rs b/linera-chain/src/unit_tests/chain_tests.rs index 2a9b68c075cb..d355d436a2df 100644 --- a/linera-chain/src/unit_tests/chain_tests.rs +++ b/linera-chain/src/unit_tests/chain_tests.rs @@ -8,10 +8,7 @@ use std::{collections::BTreeMap, iter}; use assert_matches::assert_matches; use linera_base::{ crypto::{AccountPublicKey, CryptoHash, ValidatorPublicKey}, - data_types::{ - Amount, ApplicationPermissions, Blob, BlockHeight, Bytecode, Timestamp, - UserApplicationDescription, - }, + data_types::{Amount, ApplicationPermissions, Blob, BlockHeight, Bytecode, Timestamp}, hashed::Hashed, identifiers::{ApplicationId, BytecodeId, ChainId, MessageId}, ownership::ChainOwnership, @@ -22,6 +19,7 @@ use linera_execution::{ test_utils::{ExpectedCall, MockApplication}, ExecutionError, ExecutionRuntimeConfig, ExecutionRuntimeContext, Message, MessageKind, Operation, ResourceControlPolicy, SystemMessage, SystemOperation, TestExecutionRuntimeContext, + UserApplicationDescription, VmRuntime, }; use linera_views::{ context::{Context as _, MemoryContext}, @@ -66,11 +64,13 @@ fn make_app_description() -> (UserApplicationDescription, Blob, Blob) { let service = Bytecode::new(b"service".into()); let contract_blob = Blob::new_contract_bytecode(contract.compress()); let service_blob = Blob::new_service_bytecode(service.compress()); + let vm_runtime = VmRuntime::default(); let bytecode_id = BytecodeId::new(contract_blob.id().hash, service_blob.id().hash); ( UserApplicationDescription { bytecode_id, + vm_runtime, creation: make_admin_message_id(BlockHeight(2)), required_application_ids: vec![], parameters: vec![], diff --git a/linera-client/src/client_options.rs b/linera-client/src/client_options.rs index 7bf5f65c8c7b..39b72b4cd55c 100644 --- a/linera-client/src/client_options.rs +++ b/linera-client/src/client_options.rs @@ -19,7 +19,7 @@ use linera_base::{ time::Duration, }; use linera_core::{client::BlanketMessagePolicy, DEFAULT_GRACE_PERIOD}; -use linera_execution::{ResourceControlPolicy, WasmRuntime, WithWasmDefault as _}; +use linera_execution::{ResourceControlPolicy, VmRuntime}; use linera_views::store::CommonStoreConfig; #[cfg(feature = "fs")] @@ -96,10 +96,6 @@ pub struct ClientOptions { #[arg(long, default_value = "10")] pub max_pending_message_bundles: usize, - /// The WebAssembly runtime to use. - #[arg(long)] - pub wasm_runtime: Option, - /// The maximal number of chains loaded in memory at a given time. #[arg(long, default_value = "40")] pub max_loaded_chains: NonZeroUsize, @@ -202,7 +198,6 @@ impl ClientOptions { .add_common_config(self.common_config()) .await?, &genesis_config, - self.wasm_runtime.with_wasm_default(), job, )) .await?; @@ -802,6 +797,10 @@ pub enum ClientCommand { /// The bytecode ID of the application to create. bytecode_id: BytecodeId, + /// The virtual machine runtime to use. + #[arg(long)] + vm_runtime: Option, + /// An optional chain ID to host the application. The default chain of the wallet /// is used otherwise. creator: Option, @@ -835,6 +834,10 @@ pub enum ClientCommand { /// Path to the Wasm file for the application "service" bytecode. service: PathBuf, + /// The virtual machine runtime to use. + #[arg(long)] + vm_runtime: Option, + /// An optional chain ID to publish the bytecode. The default chain of the wallet /// is used otherwise. publisher: Option, @@ -1241,6 +1244,10 @@ pub enum ProjectCommand { /// is used otherwise. publisher: Option, + /// The virtual machine runtime to use. + #[arg(long)] + vm_runtime: Option, + /// The shared parameters as JSON string. #[arg(long)] json_parameters: Option, diff --git a/linera-client/src/storage.rs b/linera-client/src/storage.rs index 493b17fd116f..c27c757852bd 100644 --- a/linera-client/src/storage.rs +++ b/linera-client/src/storage.rs @@ -5,7 +5,6 @@ use std::{fmt, str::FromStr}; use async_trait::async_trait; use linera_base::identifiers::{BlobId, ChainId}; -use linera_execution::WasmRuntime; #[cfg(with_storage)] use linera_storage::{list_all_blob_ids, list_all_chain_ids}; use linera_storage::{DbStorage, Storage}; @@ -637,7 +636,6 @@ pub trait Runnable { pub async fn run_with_storage( config: StoreConfig, genesis_config: &GenesisConfig, - wasm_runtime: Option, job: Job, ) -> Result where @@ -647,37 +645,29 @@ where StoreConfig::Memory(config, namespace) => { let store_config = MemoryStoreConfig::new(config.common_config.max_stream_queries); let mut storage = - DbStorage::::new(store_config, &namespace, ROOT_KEY, wasm_runtime) - .await?; + DbStorage::::new(store_config, &namespace, ROOT_KEY).await?; genesis_config.initialize_storage(&mut storage).await?; Ok(job.run(storage).await) } #[cfg(feature = "storage-service")] StoreConfig::Service(config, namespace) => { let storage = - DbStorage::::new(config, &namespace, ROOT_KEY, wasm_runtime) - .await?; + DbStorage::::new(config, &namespace, ROOT_KEY).await?; Ok(job.run(storage).await) } #[cfg(feature = "rocksdb")] StoreConfig::RocksDb(config, namespace) => { - let storage = - DbStorage::::new(config, &namespace, ROOT_KEY, wasm_runtime) - .await?; + let storage = DbStorage::::new(config, &namespace, ROOT_KEY).await?; Ok(job.run(storage).await) } #[cfg(feature = "dynamodb")] StoreConfig::DynamoDb(config, namespace) => { - let storage = - DbStorage::::new(config, &namespace, ROOT_KEY, wasm_runtime) - .await?; + let storage = DbStorage::::new(config, &namespace, ROOT_KEY).await?; Ok(job.run(storage).await) } #[cfg(feature = "scylladb")] StoreConfig::ScyllaDb(config, namespace) => { - let storage = - DbStorage::::new(config, &namespace, ROOT_KEY, wasm_runtime) - .await?; + let storage = DbStorage::::new(config, &namespace, ROOT_KEY).await?; Ok(job.run(storage).await) } } @@ -694,50 +684,27 @@ pub async fn full_initialize_storage( )), #[cfg(feature = "storage-service")] StoreConfig::Service(config, namespace) => { - let wasm_runtime = None; - let mut storage = DbStorage::::initialize( - config, - &namespace, - ROOT_KEY, - wasm_runtime, - ) - .await?; + let mut storage = + DbStorage::::initialize(config, &namespace, ROOT_KEY) + .await?; Ok(genesis_config.initialize_storage(&mut storage).await?) } #[cfg(feature = "rocksdb")] StoreConfig::RocksDb(config, namespace) => { - let wasm_runtime = None; - let mut storage = DbStorage::::initialize( - config, - &namespace, - ROOT_KEY, - wasm_runtime, - ) - .await?; + let mut storage = + DbStorage::::initialize(config, &namespace, ROOT_KEY).await?; Ok(genesis_config.initialize_storage(&mut storage).await?) } #[cfg(feature = "dynamodb")] StoreConfig::DynamoDb(config, namespace) => { - let wasm_runtime = None; - let mut storage = DbStorage::::initialize( - config, - &namespace, - ROOT_KEY, - wasm_runtime, - ) - .await?; + let mut storage = + DbStorage::::initialize(config, &namespace, ROOT_KEY).await?; Ok(genesis_config.initialize_storage(&mut storage).await?) } #[cfg(feature = "scylladb")] StoreConfig::ScyllaDb(config, namespace) => { - let wasm_runtime = None; - let mut storage = DbStorage::::initialize( - config, - &namespace, - ROOT_KEY, - wasm_runtime, - ) - .await?; + let mut storage = + DbStorage::::initialize(config, &namespace, ROOT_KEY).await?; Ok(genesis_config.initialize_storage(&mut storage).await?) } } diff --git a/linera-core/src/chain_worker/actor.rs b/linera-core/src/chain_worker/actor.rs index eda7933d0a18..7a46d8edf819 100644 --- a/linera-core/src/chain_worker/actor.rs +++ b/linera-core/src/chain_worker/actor.rs @@ -12,7 +12,7 @@ use std::{ use custom_debug_derive::Debug; use linera_base::{ crypto::{CryptoHash, ValidatorPublicKey}, - data_types::{Blob, BlockHeight, Timestamp, UserApplicationDescription}, + data_types::{Blob, BlockHeight, Timestamp}, hashed::Hashed, identifiers::{BlobId, ChainId, UserApplicationId}, }; @@ -22,7 +22,9 @@ use linera_chain::{ ChainStateView, }; use linera_execution::{ - committee::Epoch, Query, QueryContext, QueryOutcome, ServiceRuntimeEndpoint, ServiceSyncRuntime, + committee::{Epoch, ValidatorName}, + Query, QueryContext, QueryOutcome, ServiceRuntimeEndpoint, ServiceSyncRuntime, + UserApplicationDescription, }; use linera_storage::Storage; use tokio::sync::{mpsc, oneshot, OwnedRwLockReadGuard}; diff --git a/linera-core/src/chain_worker/state/mod.rs b/linera-core/src/chain_worker/state/mod.rs index e3c0716a044a..bdcf70c3c8e2 100644 --- a/linera-core/src/chain_worker/state/mod.rs +++ b/linera-core/src/chain_worker/state/mod.rs @@ -14,7 +14,7 @@ use std::{ use linera_base::{ crypto::{CryptoHash, ValidatorPublicKey}, - data_types::{Blob, BlockHeight, UserApplicationDescription}, + data_types::{Blob, BlockHeight}, ensure, hashed::Hashed, identifiers::{BlobId, ChainId, UserApplicationId}, @@ -27,8 +27,9 @@ use linera_chain::{ ChainError, ChainStateView, }; use linera_execution::{ - committee::Epoch, Message, Query, QueryContext, QueryOutcome, ServiceRuntimeEndpoint, - SystemMessage, + committee::{Epoch, ValidatorName}, + Message, Query, QueryContext, QueryOutcome, ServiceRuntimeEndpoint, SystemMessage, + UserApplicationDescription, }; use linera_storage::{Clock as _, Storage}; use linera_views::views::{ClonableView, ViewError}; diff --git a/linera-core/src/chain_worker/state/temporary_changes.rs b/linera-core/src/chain_worker/state/temporary_changes.rs index e10696ff4884..42d2db3b46a7 100644 --- a/linera-core/src/chain_worker/state/temporary_changes.rs +++ b/linera-core/src/chain_worker/state/temporary_changes.rs @@ -4,7 +4,7 @@ //! Operations that don't persist any changes to the chain state. use linera_base::{ - data_types::{ArithmeticError, Timestamp, UserApplicationDescription}, + data_types::{ArithmeticError, Timestamp}, ensure, identifiers::{AccountOwner, ChannelFullName, GenericApplicationId, UserApplicationId}, }; @@ -12,7 +12,7 @@ use linera_chain::data_types::{ BlockExecutionOutcome, ExecutedBlock, IncomingBundle, Medium, MessageAction, ProposalContent, ProposedBlock, }; -use linera_execution::{ChannelSubscription, Query, QueryOutcome}; +use linera_execution::{ChannelSubscription, Query, QueryOutcome, UserApplicationDescription}; use linera_storage::{Clock as _, Storage}; use linera_views::views::View; #[cfg(with_testing)] diff --git a/linera-core/src/client/mod.rs b/linera-core/src/client/mod.rs index 00fbe23e3c29..92f7773a26ed 100644 --- a/linera-core/src/client/mod.rs +++ b/linera-core/src/client/mod.rs @@ -59,7 +59,7 @@ use linera_execution::{ CREATE_APPLICATION_MESSAGE_INDEX, OPEN_CHAIN_MESSAGE_INDEX, }, ExecutionError, Operation, Query, QueryOutcome, QueryResponse, SystemExecutionError, - SystemQuery, SystemResponse, + SystemQuery, SystemResponse, VmRuntime, }; use linera_storage::{Clock as _, Storage}; use linera_views::views::ViewError; @@ -2912,6 +2912,7 @@ where >( &self, bytecode_id: BytecodeId, + vm_runtime: VmRuntime, parameters: &Parameters, instantiation_argument: &InstantiationArgument, required_application_ids: Vec, @@ -2922,6 +2923,7 @@ where Ok(self .create_application_untyped( bytecode_id.forget_abi(), + vm_runtime, parameters, instantiation_argument, required_application_ids, @@ -2944,6 +2946,7 @@ where pub async fn create_application_untyped( &self, bytecode_id: BytecodeId, + vm_runtime: VmRuntime, parameters: Vec, instantiation_argument: Vec, required_application_ids: Vec, @@ -2951,6 +2954,7 @@ where { self.execute_operation(Operation::System(SystemOperation::CreateApplication { bytecode_id, + vm_runtime, parameters, instantiation_argument, required_application_ids, diff --git a/linera-core/src/local_node.rs b/linera-core/src/local_node.rs index 2c4ebb29e888..6d376dcfc59b 100644 --- a/linera-core/src/local_node.rs +++ b/linera-core/src/local_node.rs @@ -10,7 +10,7 @@ use std::{ use futures::{future::Either, stream, StreamExt as _, TryStreamExt as _}; use linera_base::{ crypto::ValidatorPublicKey, - data_types::{ArithmeticError, Blob, BlockHeight, UserApplicationDescription}, + data_types::{ArithmeticError, Blob, BlockHeight}, identifiers::{BlobId, ChainId, MessageId, UserApplicationId}, }; use linera_chain::{ @@ -18,7 +18,7 @@ use linera_chain::{ types::{ConfirmedBlockCertificate, GenericCertificate, LiteCertificate}, ChainStateView, }; -use linera_execution::{Query, QueryOutcome}; +use linera_execution::{Query, QueryOutcome, UserApplicationDescription}; use linera_storage::Storage; use linera_views::views::ViewError; use thiserror::Error; diff --git a/linera-core/src/unit_tests/client_tests.rs b/linera-core/src/unit_tests/client_tests.rs index d7f4eed4e42c..ca52c96365c1 100644 --- a/linera-core/src/unit_tests/client_tests.rs +++ b/linera-core/src/unit_tests/client_tests.rs @@ -77,7 +77,7 @@ fn test_listener_is_send() { } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -131,7 +131,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -260,7 +260,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -297,7 +297,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -343,7 +343,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -448,7 +448,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -510,7 +510,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -591,7 +591,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -665,7 +665,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -721,7 +721,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -813,7 +813,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -848,7 +848,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -951,7 +951,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -997,7 +997,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -1091,7 +1091,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -1218,7 +1218,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] #[test_log::test(tokio::test)] async fn test_insufficient_balance(storage_builder: B) -> anyhow::Result<()> where @@ -1256,7 +1256,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -1446,7 +1446,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -1574,7 +1574,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -1821,7 +1821,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -1935,7 +1935,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -2038,7 +2038,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -2074,7 +2074,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -2180,7 +2180,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] #[test_log::test(tokio::test)] async fn test_message_policy(storage_builder: B) -> anyhow::Result<()> where @@ -2233,7 +2233,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] diff --git a/linera-core/src/unit_tests/test_utils.rs b/linera-core/src/unit_tests/test_utils.rs index 0dc8145abe5c..e883b9aeefc5 100644 --- a/linera-core/src/unit_tests/test_utils.rs +++ b/linera-core/src/unit_tests/test_utils.rs @@ -29,7 +29,7 @@ use linera_chain::{ LiteCertificate, Timeout, ValidatedBlock, }, }; -use linera_execution::{committee::Committee, ResourceControlPolicy, WasmRuntime}; +use linera_execution::{committee::Committee, ResourceControlPolicy}; use linera_storage::{DbStorage, Storage, TestClock}; #[cfg(all(not(target_arch = "wasm32"), feature = "storage-service"))] use linera_storage_service::client::ServiceStoreClient; @@ -1008,7 +1008,6 @@ static ROCKS_DB_SEMAPHORE: Semaphore = Semaphore::const_new(5); pub struct MemoryStorageBuilder { namespace: String, instance_counter: usize, - wasm_runtime: Option, clock: TestClock, } @@ -1024,14 +1023,7 @@ impl StorageBuilder for MemoryStorageBuilder { } let namespace = format!("{}_{}", self.namespace, self.instance_counter); let root_key = &[]; - Ok(DbStorage::new_for_testing( - config, - &namespace, - root_key, - self.wasm_runtime, - self.clock.clone(), - ) - .await?) + Ok(DbStorage::new_for_testing(config, &namespace, root_key, self.clock.clone()).await?) } fn clock(&self) -> &TestClock { @@ -1039,23 +1031,10 @@ impl StorageBuilder for MemoryStorageBuilder { } } -impl MemoryStorageBuilder { - /// Creates a [`MemoryStorageBuilder`] that uses the specified [`WasmRuntime`] to run Wasm - /// applications. - #[allow(dead_code)] - pub fn with_wasm_runtime(wasm_runtime: impl Into>) -> Self { - MemoryStorageBuilder { - wasm_runtime: wasm_runtime.into(), - ..MemoryStorageBuilder::default() - } - } -} - #[cfg(feature = "rocksdb")] pub struct RocksDbStorageBuilder { namespace: String, instance_counter: usize, - wasm_runtime: Option, clock: TestClock, _permit: SemaphorePermit<'static>, } @@ -1066,21 +1045,10 @@ impl RocksDbStorageBuilder { RocksDbStorageBuilder { namespace: String::new(), instance_counter: 0, - wasm_runtime: None, clock: TestClock::default(), _permit: ROCKS_DB_SEMAPHORE.acquire().await.unwrap(), } } - - /// Creates a [`RocksDbStorageBuilder`] that uses the specified [`WasmRuntime`] to run Wasm - /// applications. - #[cfg(any(feature = "wasmer", feature = "wasmtime"))] - pub async fn with_wasm_runtime(wasm_runtime: impl Into>) -> Self { - RocksDbStorageBuilder { - wasm_runtime: wasm_runtime.into(), - ..RocksDbStorageBuilder::new().await - } - } } #[cfg(feature = "rocksdb")] @@ -1096,14 +1064,7 @@ impl StorageBuilder for RocksDbStorageBuilder { } let namespace = format!("{}_{}", self.namespace, self.instance_counter); let root_key = &[]; - Ok(DbStorage::new_for_testing( - config, - &namespace, - root_key, - self.wasm_runtime, - self.clock.clone(), - ) - .await?) + Ok(DbStorage::new_for_testing(config, &namespace, root_key, self.clock.clone()).await?) } fn clock(&self) -> &TestClock { @@ -1116,26 +1077,9 @@ impl StorageBuilder for RocksDbStorageBuilder { pub struct ServiceStorageBuilder { namespace: String, instance_counter: usize, - wasm_runtime: Option, clock: TestClock, } -#[cfg(all(not(target_arch = "wasm32"), feature = "storage-service"))] -impl ServiceStorageBuilder { - /// Creates a `ServiceStorage`. - pub async fn new() -> Self { - Self::with_wasm_runtime(None).await - } - - /// Creates a `ServiceStorage` with the given Wasm runtime. - pub async fn with_wasm_runtime(wasm_runtime: impl Into>) -> Self { - ServiceStorageBuilder { - wasm_runtime: wasm_runtime.into(), - ..ServiceStorageBuilder::default() - } - } -} - #[cfg(all(not(target_arch = "wasm32"), feature = "storage-service"))] #[async_trait] impl StorageBuilder for ServiceStorageBuilder { @@ -1149,14 +1093,7 @@ impl StorageBuilder for ServiceStorageBuilder { } let namespace = format!("{}_{}", self.namespace, self.instance_counter); let root_key = &[]; - Ok(DbStorage::new_for_testing( - config, - &namespace, - root_key, - self.wasm_runtime, - self.clock.clone(), - ) - .await?) + Ok(DbStorage::new_for_testing(config, &namespace, root_key, self.clock.clone()).await?) } fn clock(&self) -> &TestClock { @@ -1169,23 +1106,9 @@ impl StorageBuilder for ServiceStorageBuilder { pub struct DynamoDbStorageBuilder { namespace: String, instance_counter: usize, - wasm_runtime: Option, clock: TestClock, } -#[cfg(feature = "dynamodb")] -impl DynamoDbStorageBuilder { - /// Creates a [`DynamoDbStorageBuilder`] that uses the specified [`WasmRuntime`] to run Wasm - /// applications. - #[allow(dead_code)] - pub fn with_wasm_runtime(wasm_runtime: impl Into>) -> Self { - DynamoDbStorageBuilder { - wasm_runtime: wasm_runtime.into(), - ..DynamoDbStorageBuilder::default() - } - } -} - #[cfg(feature = "dynamodb")] #[async_trait] impl StorageBuilder for DynamoDbStorageBuilder { @@ -1199,14 +1122,7 @@ impl StorageBuilder for DynamoDbStorageBuilder { } let namespace = format!("{}_{}", self.namespace, self.instance_counter); let root_key = &[]; - Ok(DbStorage::new_for_testing( - config, - &namespace, - root_key, - self.wasm_runtime, - self.clock.clone(), - ) - .await?) + Ok(DbStorage::new_for_testing(config, &namespace, root_key, self.clock.clone()).await?) } fn clock(&self) -> &TestClock { @@ -1219,23 +1135,9 @@ impl StorageBuilder for DynamoDbStorageBuilder { pub struct ScyllaDbStorageBuilder { namespace: String, instance_counter: usize, - wasm_runtime: Option, clock: TestClock, } -#[cfg(feature = "scylladb")] -impl ScyllaDbStorageBuilder { - /// Creates a [`ScyllaDbStorageBuilder`] that uses the specified [`WasmRuntime`] to run Wasm - /// applications. - #[allow(dead_code)] - pub fn with_wasm_runtime(wasm_runtime: impl Into>) -> Self { - ScyllaDbStorageBuilder { - wasm_runtime: wasm_runtime.into(), - ..ScyllaDbStorageBuilder::default() - } - } -} - #[cfg(feature = "scylladb")] #[async_trait] impl StorageBuilder for ScyllaDbStorageBuilder { @@ -1249,14 +1151,7 @@ impl StorageBuilder for ScyllaDbStorageBuilder { } let namespace = format!("{}_{}", self.namespace, self.instance_counter); let root_key = &[]; - Ok(DbStorage::new_for_testing( - config, - &namespace, - root_key, - self.wasm_runtime, - self.clock.clone(), - ) - .await?) + Ok(DbStorage::new_for_testing(config, &namespace, root_key, self.clock.clone()).await?) } fn clock(&self) -> &TestClock { diff --git a/linera-core/src/unit_tests/wasm_client_tests.rs b/linera-core/src/unit_tests/wasm_client_tests.rs index 85d0e10b79e9..100bfe0a7d0b 100644 --- a/linera-core/src/unit_tests/wasm_client_tests.rs +++ b/linera-core/src/unit_tests/wasm_client_tests.rs @@ -19,7 +19,7 @@ use assert_matches::assert_matches; use async_graphql::Request; use counter::CounterAbi; use linera_base::{ - data_types::{Amount, Bytecode, Event, OracleResponse, UserApplicationDescription}, + data_types::{Amount, Bytecode, Event, OracleResponse}, identifiers::{AccountOwner, ApplicationId, Destination, Owner, StreamId, StreamName}, ownership::{ChainOwnership, TimeoutConfig}, }; @@ -29,7 +29,7 @@ use linera_chain::{ }; use linera_execution::{ ExecutionError, Message, MessageKind, Operation, QueryOutcome, ResourceControlPolicy, - SystemMessage, WasmRuntime, + SystemMessage, UserApplicationDescription, VmRuntime, WasmRuntime, }; use serde_json::json; use test_case::test_case; @@ -51,7 +51,8 @@ use crate::client::{ #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime ; "wasmtime"))] #[test_log::test(tokio::test(flavor = "multi_thread"))] async fn test_memory_create_application(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - run_test_create_application(MemoryStorageBuilder::with_wasm_runtime(wasm_runtime)).await + let vm_runtime = VmRuntime::Wasm(wasm_runtime); + run_test_create_application(MemoryStorageBuilder::default(), vm_runtime).await } #[ignore] @@ -60,7 +61,8 @@ async fn test_memory_create_application(wasm_runtime: WasmRuntime) -> anyhow::Re #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime ; "wasmtime"))] #[test_log::test(tokio::test(flavor = "multi_thread"))] async fn test_service_create_application(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - run_test_create_application(ServiceStorageBuilder::with_wasm_runtime(wasm_runtime).await).await + let vm_runtime = VmRuntime::Wasm(wasm_runtime); + run_test_create_application(ServiceStorageBuilder::default(), vm_runtime).await } #[ignore] @@ -69,7 +71,8 @@ async fn test_service_create_application(wasm_runtime: WasmRuntime) -> anyhow::R #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime ; "wasmtime"))] #[test_log::test(tokio::test(flavor = "multi_thread"))] async fn test_rocks_db_create_application(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - run_test_create_application(RocksDbStorageBuilder::with_wasm_runtime(wasm_runtime).await).await + let vm_runtime = VmRuntime::Wasm(wasm_runtime); + run_test_create_application(RocksDbStorageBuilder::new().await, vm_runtime).await } #[ignore] @@ -78,7 +81,8 @@ async fn test_rocks_db_create_application(wasm_runtime: WasmRuntime) -> anyhow:: #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime ; "wasmtime"))] #[test_log::test(tokio::test(flavor = "multi_thread"))] async fn test_dynamo_db_create_application(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - run_test_create_application(DynamoDbStorageBuilder::with_wasm_runtime(wasm_runtime)).await + let vm_runtime = VmRuntime::Wasm(wasm_runtime); + run_test_create_application(DynamoDbStorageBuilder::default(), vm_runtime).await } #[ignore] @@ -87,10 +91,14 @@ async fn test_dynamo_db_create_application(wasm_runtime: WasmRuntime) -> anyhow: #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime ; "wasmtime"))] #[test_log::test(tokio::test(flavor = "multi_thread"))] async fn test_scylla_db_create_application(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - run_test_create_application(ScyllaDbStorageBuilder::with_wasm_runtime(wasm_runtime)).await + let vm_runtime = VmRuntime::Wasm(wasm_runtime); + run_test_create_application(ScyllaDbStorageBuilder::default(), vm_runtime).await } -async fn run_test_create_application(storage_builder: B) -> anyhow::Result<()> +async fn run_test_create_application( + storage_builder: B, + vm_runtime: VmRuntime, +) -> anyhow::Result<()> where B: StorageBuilder, { @@ -129,7 +137,7 @@ where let initial_value = 10_u64; let (application_id, _) = creator - .create_application(bytecode_id, &(), &initial_value, vec![]) + .create_application(bytecode_id, vm_runtime, &(), &initial_value, vec![]) .await .unwrap() .unwrap(); @@ -189,8 +197,8 @@ where async fn test_memory_run_application_with_dependency( wasm_runtime: WasmRuntime, ) -> anyhow::Result<()> { - run_test_run_application_with_dependency(MemoryStorageBuilder::with_wasm_runtime(wasm_runtime)) - .await + let vm_runtime = VmRuntime::Wasm(wasm_runtime); + run_test_run_application_with_dependency(MemoryStorageBuilder::default(), vm_runtime).await } #[ignore] @@ -201,10 +209,8 @@ async fn test_memory_run_application_with_dependency( async fn test_service_run_application_with_dependency( wasm_runtime: WasmRuntime, ) -> anyhow::Result<()> { - run_test_run_application_with_dependency( - ServiceStorageBuilder::with_wasm_runtime(wasm_runtime).await, - ) - .await + let vm_runtime = VmRuntime::Wasm(wasm_runtime); + run_test_run_application_with_dependency(ServiceStorageBuilder::default(), vm_runtime).await } #[ignore] @@ -215,10 +221,8 @@ async fn test_service_run_application_with_dependency( async fn test_rocks_db_run_application_with_dependency( wasm_runtime: WasmRuntime, ) -> anyhow::Result<()> { - run_test_run_application_with_dependency( - RocksDbStorageBuilder::with_wasm_runtime(wasm_runtime).await, - ) - .await + let vm_runtime = VmRuntime::Wasm(wasm_runtime); + run_test_run_application_with_dependency(RocksDbStorageBuilder::new().await, vm_runtime).await } #[ignore] @@ -229,10 +233,8 @@ async fn test_rocks_db_run_application_with_dependency( async fn test_dynamo_db_run_application_with_dependency( wasm_runtime: WasmRuntime, ) -> anyhow::Result<()> { - run_test_run_application_with_dependency(DynamoDbStorageBuilder::with_wasm_runtime( - wasm_runtime, - )) - .await + let vm_runtime = VmRuntime::Wasm(wasm_runtime); + run_test_run_application_with_dependency(DynamoDbStorageBuilder::default(), vm_runtime).await } #[ignore] @@ -243,13 +245,14 @@ async fn test_dynamo_db_run_application_with_dependency( async fn test_scylla_db_run_application_with_dependency( wasm_runtime: WasmRuntime, ) -> anyhow::Result<()> { - run_test_run_application_with_dependency(ScyllaDbStorageBuilder::with_wasm_runtime( - wasm_runtime, - )) - .await + let vm_runtime = VmRuntime::Wasm(wasm_runtime); + run_test_run_application_with_dependency(ScyllaDbStorageBuilder::default(), vm_runtime).await } -async fn run_test_run_application_with_dependency(storage_builder: B) -> anyhow::Result<()> +async fn run_test_run_application_with_dependency( + storage_builder: B, + vm_runtime: VmRuntime, +) -> anyhow::Result<()> where B: StorageBuilder, { @@ -317,13 +320,14 @@ where creator.synchronize_from_validators().await.unwrap(); let initial_value = 10_u64; let (application_id1, _) = creator - .create_application(bytecode_id1, &(), &initial_value, vec![]) + .create_application(bytecode_id1, vm_runtime, &(), &initial_value, vec![]) .await .unwrap() .unwrap(); let (application_id2, certificate) = creator .create_application( bytecode_id2, + vm_runtime, &application_id1, &(), vec![application_id1.forget_abi()], @@ -486,7 +490,8 @@ where #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime ; "wasmtime"))] #[test_log::test(tokio::test)] async fn test_memory_cross_chain_message(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - run_test_cross_chain_message(MemoryStorageBuilder::with_wasm_runtime(wasm_runtime)).await + let vm_runtime = VmRuntime::Wasm(wasm_runtime); + run_test_cross_chain_message(MemoryStorageBuilder::default(), vm_runtime).await } #[ignore] @@ -495,7 +500,8 @@ async fn test_memory_cross_chain_message(wasm_runtime: WasmRuntime) -> anyhow::R #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime ; "wasmtime"))] #[test_log::test(tokio::test)] async fn test_service_cross_chain_message(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - run_test_cross_chain_message(ServiceStorageBuilder::with_wasm_runtime(wasm_runtime).await).await + let vm_runtime = VmRuntime::Wasm(wasm_runtime); + run_test_cross_chain_message(ServiceStorageBuilder::default(), vm_runtime).await } #[ignore] @@ -504,7 +510,8 @@ async fn test_service_cross_chain_message(wasm_runtime: WasmRuntime) -> anyhow:: #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime ; "wasmtime"))] #[test_log::test(tokio::test)] async fn test_rocks_db_cross_chain_message(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - run_test_cross_chain_message(RocksDbStorageBuilder::with_wasm_runtime(wasm_runtime).await).await + let vm_runtime = VmRuntime::Wasm(wasm_runtime); + run_test_cross_chain_message(RocksDbStorageBuilder::new().await, vm_runtime).await } #[ignore] @@ -513,7 +520,8 @@ async fn test_rocks_db_cross_chain_message(wasm_runtime: WasmRuntime) -> anyhow: #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime ; "wasmtime"))] #[test_log::test(tokio::test)] async fn test_dynamo_db_cross_chain_message(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - run_test_cross_chain_message(DynamoDbStorageBuilder::with_wasm_runtime(wasm_runtime)).await + let vm_runtime = VmRuntime::Wasm(wasm_runtime); + run_test_cross_chain_message(DynamoDbStorageBuilder::default(), vm_runtime).await } #[ignore] @@ -522,10 +530,14 @@ async fn test_dynamo_db_cross_chain_message(wasm_runtime: WasmRuntime) -> anyhow #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime ; "wasmtime"))] #[test_log::test(tokio::test)] async fn test_scylla_db_cross_chain_message(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - run_test_cross_chain_message(ScyllaDbStorageBuilder::with_wasm_runtime(wasm_runtime)).await + let vm_runtime = VmRuntime::Wasm(wasm_runtime); + run_test_cross_chain_message(ScyllaDbStorageBuilder::default(), vm_runtime).await } -async fn run_test_cross_chain_message(storage_builder: B) -> anyhow::Result<()> +async fn run_test_cross_chain_message( + storage_builder: B, + vm_runtime: VmRuntime, +) -> anyhow::Result<()> where B: StorageBuilder, { @@ -561,7 +573,7 @@ where let state = fungible::InitialState { accounts }; let params = fungible::Parameters::new("FUN"); let (application_id, _cert) = sender - .create_application(bytecode_id, ¶ms, &state, vec![]) + .create_application(bytecode_id, vm_runtime, ¶ms, &state, vec![]) .await .unwrap() .unwrap(); @@ -685,7 +697,8 @@ where #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime; "wasmtime"))] #[test_log::test(tokio::test)] async fn test_memory_user_pub_sub_channels(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - run_test_user_pub_sub_channels(MemoryStorageBuilder::with_wasm_runtime(wasm_runtime)).await + let vm_runtime = VmRuntime::Wasm(wasm_runtime); + run_test_user_pub_sub_channels(MemoryStorageBuilder::default(), vm_runtime).await } #[ignore] @@ -694,8 +707,8 @@ async fn test_memory_user_pub_sub_channels(wasm_runtime: WasmRuntime) -> anyhow: #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime; "wasmtime"))] #[test_log::test(tokio::test)] async fn test_service_user_pub_sub_channels(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - run_test_user_pub_sub_channels(ServiceStorageBuilder::with_wasm_runtime(wasm_runtime).await) - .await + let vm_runtime = VmRuntime::Wasm(wasm_runtime); + run_test_user_pub_sub_channels(ServiceStorageBuilder::default(), vm_runtime).await } #[ignore] @@ -704,8 +717,8 @@ async fn test_service_user_pub_sub_channels(wasm_runtime: WasmRuntime) -> anyhow #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime; "wasmtime"))] #[test_log::test(tokio::test)] async fn test_rocks_db_user_pub_sub_channels(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - run_test_user_pub_sub_channels(RocksDbStorageBuilder::with_wasm_runtime(wasm_runtime).await) - .await + let vm_runtime = VmRuntime::Wasm(wasm_runtime); + run_test_user_pub_sub_channels(RocksDbStorageBuilder::new().await, vm_runtime).await } #[ignore] @@ -714,7 +727,8 @@ async fn test_rocks_db_user_pub_sub_channels(wasm_runtime: WasmRuntime) -> anyho #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime; "wasmtime"))] #[test_log::test(tokio::test)] async fn test_dynamo_db_user_pub_sub_channels(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - run_test_user_pub_sub_channels(DynamoDbStorageBuilder::with_wasm_runtime(wasm_runtime)).await + let vm_runtime = VmRuntime::Wasm(wasm_runtime); + run_test_user_pub_sub_channels(DynamoDbStorageBuilder::default(), vm_runtime).await } #[ignore] @@ -723,10 +737,14 @@ async fn test_dynamo_db_user_pub_sub_channels(wasm_runtime: WasmRuntime) -> anyh #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime; "wasmtime"))] #[test_log::test(tokio::test)] async fn test_scylla_db_user_pub_sub_channels(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - run_test_user_pub_sub_channels(ScyllaDbStorageBuilder::with_wasm_runtime(wasm_runtime)).await + let vm_runtime = VmRuntime::Wasm(wasm_runtime); + run_test_user_pub_sub_channels(ScyllaDbStorageBuilder::default(), vm_runtime).await } -async fn run_test_user_pub_sub_channels(storage_builder: B) -> anyhow::Result<()> +async fn run_test_user_pub_sub_channels( + storage_builder: B, + vm_runtime: VmRuntime, +) -> anyhow::Result<()> where B: StorageBuilder, { @@ -751,7 +769,7 @@ where let bytecode_id = bytecode_id.with_abi::(); let (application_id, _cert) = receiver - .create_application(bytecode_id, &(), &(), vec![]) + .create_application(bytecode_id, vm_runtime, &(), &(), vec![]) .await .unwrap() .unwrap(); @@ -881,7 +899,8 @@ where #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime ; "wasmtime"))] #[test_log::test(tokio::test(flavor = "multi_thread"))] async fn test_memory_fuel_limit(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - let storage_builder = MemoryStorageBuilder::with_wasm_runtime(wasm_runtime); + let vm_runtime = VmRuntime::Wasm(wasm_runtime); + let storage_builder = MemoryStorageBuilder::default(); // Set a fuel limit that is enough to instantiate the application and do one increment // operation, but not ten. let mut builder = @@ -908,7 +927,7 @@ async fn test_memory_fuel_limit(wasm_runtime: WasmRuntime) -> anyhow::Result<()> let initial_value = 10_u64; let (application_id, _) = publisher - .create_application(bytecode_id, &(), &initial_value, vec![]) + .create_application(bytecode_id, vm_runtime, &(), &initial_value, vec![]) .await .unwrap() .unwrap(); diff --git a/linera-core/src/unit_tests/wasm_worker_tests.rs b/linera-core/src/unit_tests/wasm_worker_tests.rs index 5ad39aafaacb..da36246e04f4 100644 --- a/linera-core/src/unit_tests/wasm_worker_tests.rs +++ b/linera-core/src/unit_tests/wasm_worker_tests.rs @@ -15,9 +15,7 @@ use std::collections::BTreeSet; use assert_matches::assert_matches; use linera_base::{ crypto::AccountSecretKey, - data_types::{ - Amount, Blob, BlockHeight, Bytecode, OracleResponse, Timestamp, UserApplicationDescription, - }, + data_types::{Amount, Blob, BlockHeight, Bytecode, OracleResponse, Timestamp}, hashed::Hashed, identifiers::{ BytecodeId, ChainDescription, ChainId, Destination, MessageId, UserApplicationId, @@ -34,7 +32,7 @@ use linera_execution::{ system::{SystemMessage, SystemOperation}, test_utils::SystemExecutionState, Message, MessageKind, Operation, OperationContext, ResourceController, TransactionTracker, - WasmContractModule, WasmRuntime, + UserApplicationDescription, VmRuntime, WasmContractModule, WasmRuntime, }; use linera_storage::{DbStorage, Storage}; #[cfg(feature = "dynamodb")] @@ -55,7 +53,7 @@ use crate::worker::WorkerError; async fn test_memory_handle_certificates_to_create_application( wasm_runtime: WasmRuntime, ) -> anyhow::Result<()> { - let storage = DbStorage::::make_test_storage(Some(wasm_runtime)).await; + let storage = DbStorage::::make_test_storage().await; run_test_handle_certificates_to_create_application(storage, wasm_runtime).await } @@ -66,7 +64,7 @@ async fn test_memory_handle_certificates_to_create_application( async fn test_rocks_db_handle_certificates_to_create_application( wasm_runtime: WasmRuntime, ) -> anyhow::Result<()> { - let storage = DbStorage::::make_test_storage(Some(wasm_runtime)).await; + let storage = DbStorage::::make_test_storage().await; run_test_handle_certificates_to_create_application(storage, wasm_runtime).await } @@ -77,7 +75,7 @@ async fn test_rocks_db_handle_certificates_to_create_application( async fn test_dynamo_db_handle_certificates_to_create_application( wasm_runtime: WasmRuntime, ) -> anyhow::Result<()> { - let storage = DbStorage::::make_test_storage(Some(wasm_runtime)).await; + let storage = DbStorage::::make_test_storage().await; run_test_handle_certificates_to_create_application(storage, wasm_runtime).await } @@ -88,7 +86,7 @@ async fn test_dynamo_db_handle_certificates_to_create_application( async fn test_scylla_db_handle_certificates_to_create_application( wasm_runtime: WasmRuntime, ) -> anyhow::Result<()> { - let storage = DbStorage::::make_test_storage(Some(wasm_runtime)).await; + let storage = DbStorage::::make_test_storage().await; run_test_handle_certificates_to_create_application(storage, wasm_runtime).await } @@ -99,6 +97,7 @@ async fn run_test_handle_certificates_to_create_application( where S: Storage + Clone + Send + Sync + 'static, { + let vm_runtime = VmRuntime::Wasm(wasm_runtime); let admin_id = ChainDescription::Root(0); let publisher_owner = AccountSecretKey::generate().public().into(); let publisher_chain = ChainDescription::Root(1); @@ -189,6 +188,7 @@ where let parameters_bytes = serde_json::to_vec(&())?; let create_operation = SystemOperation::CreateApplication { bytecode_id, + vm_runtime, parameters: parameters_bytes.clone(), instantiation_argument: initial_value_bytes.clone(), required_application_ids: vec![], @@ -203,6 +203,7 @@ where }; let application_description = UserApplicationDescription { bytecode_id, + vm_runtime, creation: application_id.creation, required_application_ids: vec![], parameters: parameters_bytes, diff --git a/linera-core/src/unit_tests/worker_tests.rs b/linera-core/src/unit_tests/worker_tests.rs index eeab1f0c2340..616dc2d69a3c 100644 --- a/linera-core/src/unit_tests/worker_tests.rs +++ b/linera-core/src/unit_tests/worker_tests.rs @@ -3006,7 +3006,6 @@ async fn test_cross_chain_helper() -> anyhow::Result<()> { store_config, &namespace, root_key, - None, TestClock::new(), ) .await?; diff --git a/linera-core/src/worker.rs b/linera-core/src/worker.rs index 501e13a84758..a55a1e7ebe5e 100644 --- a/linera-core/src/worker.rs +++ b/linera-core/src/worker.rs @@ -12,9 +12,7 @@ use std::{ use futures::future::Either; use linera_base::{ crypto::{CryptoError, CryptoHash, ValidatorPublicKey, ValidatorSecretKey}, - data_types::{ - ArithmeticError, Blob, BlockHeight, DecompressionError, Round, UserApplicationDescription, - }, + data_types::{ArithmeticError, Blob, BlockHeight, DecompressionError, Round}, doc_scalar, hashed::Hashed, identifiers::{BlobId, ChainId, Owner, UserApplicationId}, @@ -31,7 +29,7 @@ use linera_chain::{ }, ChainError, ChainStateView, }; -use linera_execution::{committee::Epoch, ExecutionError, Query, QueryOutcome}; +use linera_execution::{committee::Epoch, ExecutionError, Query, QueryOutcome, UserApplicationDescription}; use linera_storage::Storage; use linera_views::views::ViewError; use lru::LruCache; diff --git a/linera-execution/build.rs b/linera-execution/build.rs index 6cecb9aa68d8..ae9a0a85009b 100644 --- a/linera-execution/build.rs +++ b/linera-execution/build.rs @@ -9,8 +9,8 @@ fn main() { with_metrics: { all(not(target_arch = "wasm32"), feature = "metrics") }, with_testing: { any(test, feature = "test") }, with_tokio_multi_thread: { not(target_arch = "wasm32") }, - with_wasmer: { feature = "wasmer" }, with_revm: { feature = "revm" }, + with_wasmer: { feature = "wasmer" }, with_wasmtime: { all(not(target_arch = "wasm32"), feature = "wasmtime") }, // If you change this, don't forget to update `WasmRuntime` and diff --git a/linera-execution/src/applications.rs b/linera-execution/src/applications.rs index 8da936015d32..d3bed6a6955b 100644 --- a/linera-execution/src/applications.rs +++ b/linera-execution/src/applications.rs @@ -3,7 +3,7 @@ use std::collections::HashSet; -use linera_base::{data_types::UserApplicationDescription, identifiers::UserApplicationId}; +use linera_base::identifiers::UserApplicationId; use linera_views::{ context::Context, map_view::HashedMapView, @@ -16,7 +16,7 @@ use { std::collections::BTreeMap, }; -use crate::SystemExecutionError; +use crate::{SystemExecutionError, UserApplicationDescription, VmRuntime}; #[cfg(test)] #[path = "unit_tests/applications_tests.rs"] @@ -66,6 +66,7 @@ where pub async fn register_new_application( &mut self, application_id: UserApplicationId, + vm_runtime: VmRuntime, parameters: Vec, required_application_ids: Vec, ) -> Result<(), SystemExecutionError> { @@ -81,6 +82,7 @@ where let description = UserApplicationDescription { bytecode_id, parameters, + vm_runtime, creation, required_application_ids, }; diff --git a/linera-execution/src/execution_state_actor.rs b/linera-execution/src/execution_state_actor.rs index dd511e6cc3f2..85091a504260 100644 --- a/linera-execution/src/execution_state_actor.rs +++ b/linera-execution/src/execution_state_actor.rs @@ -27,7 +27,7 @@ use crate::{ util::RespondExt, BytecodeId, ExecutionError, ExecutionRuntimeContext, ExecutionStateView, RawExecutionOutcome, RawOutgoingMessage, SystemExecutionError, SystemMessage, UserApplicationDescription, - UserApplicationId, UserContractCode, UserServiceCode, + UserApplicationId, UserContractCode, UserServiceCode, VmRuntime, }; #[cfg(with_metrics)] @@ -308,6 +308,7 @@ where CreateApplication { next_message_id, bytecode_id, + vm_runtime, parameters, required_application_ids, callback, @@ -317,6 +318,7 @@ where .create_application( next_message_id, bytecode_id, + vm_runtime, parameters, required_application_ids, ) @@ -511,6 +513,7 @@ pub enum ExecutionRequest { CreateApplication { next_message_id: MessageId, bytecode_id: BytecodeId, + vm_runtime: VmRuntime, parameters: Vec, required_application_ids: Vec, #[debug(skip)] diff --git a/linera-execution/src/lib.rs b/linera-execution/src/lib.rs index c688ab1e8988..2fe7e844557c 100644 --- a/linera-execution/src/lib.rs +++ b/linera-execution/src/lib.rs @@ -26,7 +26,7 @@ mod wasm; use std::{any::Any, fmt, str::FromStr, sync::Arc}; -use async_graphql::SimpleObject; +use async_graphql::{scalar, SimpleObject}; use async_trait::async_trait; use committee::Epoch; use custom_debug_derive::Debug; @@ -39,7 +39,7 @@ use linera_base::{ crypto::{BcsHashable, CryptoHash}, data_types::{ Amount, ApplicationPermissions, ArithmeticError, Blob, BlockHeight, DecompressionError, - Resources, SendMessageRequest, Timestamp, UserApplicationDescription, + Resources, SendMessageRequest, Timestamp, }, doc_scalar, hex_debug, http, identifiers::{ @@ -50,6 +50,8 @@ use linera_base::{ task, }; use linera_views::{batch::Batch, views::ViewError}; +#[cfg(any(with_wasm_runtime, with_revm))] +use linera_witty::{WitLoad, WitType}; use serde::{Deserialize, Serialize}; use system::OpenChainConfig; use thiserror::Error; @@ -744,6 +746,7 @@ pub trait ContractRuntime: BaseRuntime { fn create_application( &mut self, bytecode_id: BytecodeId, + vm_runtime: VmRuntime, parameters: Vec, argument: Vec, required_application_ids: Vec, @@ -1312,8 +1315,21 @@ pub struct BlobState { } /// The runtime to use for running the application. -#[derive(Clone, Copy, Display)] -#[cfg_attr(with_wasm_runtime, derive(Debug, Default))] +#[cfg(with_wasm_runtime)] +#[derive( + Clone, + Copy, + Display, + Hash, + PartialEq, + Eq, + Serialize, + Deserialize, + WitType, + WitLoad, + Debug, + Default, +)] pub enum WasmRuntime { #[cfg(with_wasmer)] #[default] @@ -1329,20 +1345,76 @@ pub enum WasmRuntime { WasmtimeWithSanitizer, } -#[derive(Clone, Copy, Display)] -#[cfg_attr(with_revm, derive(Debug, Default))] +#[cfg(with_wasm_runtime)] +scalar!(WasmRuntime); + +#[cfg(with_revm)] +#[derive( + Clone, + Copy, + Debug, + Display, + Hash, + PartialEq, + Eq, + Serialize, + Deserialize, + Default, + WitType, + WitLoad, +)] pub enum EvmRuntime { - #[cfg(with_revm)] #[default] #[display("revm")] Revm, } +#[cfg(with_revm)] +scalar!(EvmRuntime); + +#[derive(Clone, Copy, Display, Hash, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(any(with_wasm_runtime, with_revm), derive(WitType, WitLoad))] +pub enum VmRuntime { + #[cfg(with_wasm_runtime)] + Wasm(WasmRuntime), + #[cfg(with_revm)] + Evm(EvmRuntime), +} + +impl fmt::Debug for VmRuntime { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + #[cfg(with_wasm_runtime)] + VmRuntime::Wasm(wasm_runtime) => write!(f, "{wasm_runtime:?}"), + #[cfg(with_revm)] + VmRuntime::Evm(evm_runtime) => write!(f, "{evm_runtime:?}"), + #[cfg(not(any(with_wasm_runtime, with_revm)))] + _ => write!(f, "No virtual machine selected"), + } + } +} + +#[cfg(any(with_wasm_runtime, with_revm))] +impl Default for VmRuntime { + #[cfg(with_wasm_runtime)] + fn default() -> Self { + VmRuntime::Wasm(WasmRuntime::default()) + } + + #[cfg(all(not(with_wasm_runtime), with_revm))] + fn default() -> Self { + VmRuntime::Evm(EvmRuntime::default()) + } +} + +scalar!(VmRuntime); + /// Trait used to select a default `WasmRuntime`, if one is available. -pub trait WithWasmDefault { - fn with_wasm_default(self) -> Self; +pub trait WithVmDefault { + fn with_vm_default(self) -> Self; } +#[cfg(with_wasm_runtime)] impl WasmRuntime { #[cfg(with_wasm_runtime)] pub fn default_with_sanitizer() -> Self { @@ -1369,21 +1441,25 @@ impl WasmRuntime { } } -impl WithWasmDefault for Option { - fn with_wasm_default(self) -> Self { - #[cfg(with_wasm_runtime)] - { - Some(self.unwrap_or_default()) - } - #[cfg(not(with_wasm_runtime))] - { - None - } +impl WithVmDefault for Option { + fn with_vm_default(self) -> Self { + let Some(vm_runtime) = self else { + #[cfg(any(with_wasm_runtime, with_revm))] + { + return Some(VmRuntime::default()); + } + #[cfg(not(any(with_wasm_runtime, with_revm)))] + { + return None; + } + }; + Some(vm_runtime) } } +#[cfg(with_wasm_runtime)] impl FromStr for WasmRuntime { - type Err = InvalidWasmRuntime; + type Err = InvalidVmRuntime; fn from_str(string: &str) -> Result { match string { @@ -1391,15 +1467,62 @@ impl FromStr for WasmRuntime { "wasmer" => Ok(WasmRuntime::Wasmer), #[cfg(with_wasmtime)] "wasmtime" => Ok(WasmRuntime::Wasmtime), - unknown => Err(InvalidWasmRuntime(unknown.to_owned())), + unknown => Err(InvalidVmRuntime(unknown.to_owned())), } } } -/// Attempts to create an invalid [`WasmRuntime`] instance from a string. +impl FromStr for VmRuntime { + type Err = InvalidVmRuntime; + + fn from_str(string: &str) -> Result { + match string { + #[cfg(with_wasmer)] + "wasmer" => Ok(VmRuntime::Wasm(WasmRuntime::Wasmer)), + #[cfg(with_wasmtime)] + "wasmtime" => Ok(VmRuntime::Wasm(WasmRuntime::Wasmtime)), + #[cfg(with_revm)] + "revm" => Ok(VmRuntime::Evm(EvmRuntime::Revm)), + unknown => Err(InvalidVmRuntime(unknown.to_owned())), + } + } +} + +/// Description of the necessary information to run a user application. +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Hash, Serialize)] +pub struct UserApplicationDescription { + /// The unique ID of the bytecode to use for the application. + pub bytecode_id: BytecodeId, + /// The unique ID of the application's creation. + pub creation: MessageId, + /// The virtual runtime being used + pub vm_runtime: VmRuntime, + /// The parameters of the application. + #[serde(with = "serde_bytes")] + #[debug(with = "hex_debug")] + pub parameters: Vec, + /// Required dependencies. + pub required_application_ids: Vec, +} + +impl From<&UserApplicationDescription> for UserApplicationId { + fn from(description: &UserApplicationDescription) -> Self { + UserApplicationId { + bytecode_id: description.bytecode_id, + creation: description.creation, + } + } +} + +doc_scalar!( + UserApplicationDescription, + "Description of the necessary information to run a user application" +); + +/// Attempts to create an invalid [`VmRuntime`] instance from a string. #[derive(Clone, Debug, Error)] -#[error("{0:?} is not a valid WebAssembly runtime")] -pub struct InvalidWasmRuntime(String); +#[error("{0:?} is not a valid virtual machine runtime")] +pub struct InvalidVmRuntime(String); doc_scalar!(Operation, "An operation to be executed in a block"); doc_scalar!( diff --git a/linera-execution/src/runtime.rs b/linera-execution/src/runtime.rs index 01e87c751d3f..4301ef0bc960 100644 --- a/linera-execution/src/runtime.rs +++ b/linera-execution/src/runtime.rs @@ -34,7 +34,7 @@ use crate::{ BaseRuntime, BytecodeId, ContractRuntime, ExecutionError, FinalizeContext, MessageContext, Operation, OperationContext, QueryContext, QueryOutcome, RawExecutionOutcome, ServiceRuntime, TransactionTracker, UserApplicationDescription, UserApplicationId, UserContractCode, - UserContractInstance, UserServiceCode, UserServiceInstance, MAX_EVENT_KEY_LEN, + UserContractInstance, UserServiceCode, UserServiceInstance, VmRuntime, MAX_EVENT_KEY_LEN, MAX_STREAM_NAME_LEN, }; @@ -1444,6 +1444,7 @@ impl ContractRuntime for ContractSyncRuntimeHandle { fn create_application( &mut self, bytecode_id: BytecodeId, + vm_runtime: VmRuntime, parameters: Vec, argument: Vec, required_application_ids: Vec, @@ -1468,6 +1469,7 @@ impl ContractRuntime for ContractSyncRuntimeHandle { .send_request(|callback| ExecutionRequest::CreateApplication { next_message_id: message_id, bytecode_id, + vm_runtime, parameters, required_application_ids, callback, diff --git a/linera-execution/src/system.rs b/linera-execution/src/system.rs index b9bd65a2761d..ec53dfea3dfb 100644 --- a/linera-execution/src/system.rs +++ b/linera-execution/src/system.rs @@ -47,7 +47,7 @@ use crate::{ ApplicationRegistryView, ChannelName, ChannelSubscription, Destination, ExecutionRuntimeContext, MessageContext, MessageKind, OperationContext, QueryContext, QueryOutcome, RawExecutionOutcome, RawOutgoingMessage, TransactionTracker, - UserApplicationDescription, UserApplicationId, + UserApplicationDescription, UserApplicationId, VmRuntime, }; /// The relative index of the `OpenChain` message created by the `OpenChain` operation. @@ -175,6 +175,7 @@ pub enum SystemOperation { /// Creates a new application. CreateApplication { bytecode_id: BytecodeId, + vm_runtime: VmRuntime, #[serde(with = "serde_bytes")] #[debug(with = "hex_debug")] parameters: Vec, @@ -642,6 +643,7 @@ where } CreateApplication { bytecode_id, + vm_runtime, parameters, instantiation_argument, required_application_ids, @@ -655,6 +657,7 @@ where .create_application( next_message_id, bytecode_id, + vm_runtime, parameters, required_application_ids, ) @@ -1030,6 +1033,7 @@ where &mut self, next_message_id: MessageId, bytecode_id: BytecodeId, + vm_runtime: VmRuntime, parameters: Vec, required_application_ids: Vec, ) -> Result { @@ -1051,7 +1055,7 @@ where } } self.registry - .register_new_application(id, parameters, required_application_ids) + .register_new_application(id, vm_runtime, parameters, required_application_ids) .await?; // Send a message to ourself to increment the message ID. let message = RawOutgoingMessage { diff --git a/linera-execution/src/test_utils/mod.rs b/linera-execution/src/test_utils/mod.rs index 9a48e5a1b936..832473c96e32 100644 --- a/linera-execution/src/test_utils/mod.rs +++ b/linera-execution/src/test_utils/mod.rs @@ -32,7 +32,7 @@ use crate::{ ApplicationRegistryView, ExecutionRequest, ExecutionRuntimeContext, ExecutionStateView, MessageContext, OperationContext, QueryContext, ServiceRuntimeEndpoint, ServiceRuntimeRequest, ServiceSyncRuntime, SystemExecutionStateView, TestExecutionRuntimeContext, - UserApplicationDescription, UserApplicationId, + UserApplicationDescription, UserApplicationId, VmRuntime, }; /// Creates a dummy [`UserApplicationDescription`] for use in tests. @@ -47,9 +47,11 @@ pub fn create_dummy_user_application_description( compressed_bytes: b"service".to_vec(), }); + let vm_runtime = VmRuntime::default(); ( UserApplicationDescription { bytecode_id: BytecodeId::new(contract_blob.id().hash, service_blob.id().hash), + vm_runtime, creation: MessageId { chain_id, height: BlockHeight(index), diff --git a/linera-execution/src/unit_tests/applications_tests.rs b/linera-execution/src/unit_tests/applications_tests.rs index 3420c101df6d..ad56a3106a50 100644 --- a/linera-execution/src/unit_tests/applications_tests.rs +++ b/linera-execution/src/unit_tests/applications_tests.rs @@ -9,6 +9,7 @@ use linera_base::{ use super::{ ApplicationRegistry, ApplicationRegistryView, UserApplicationDescription, UserApplicationId, + VmRuntime, }; fn message_id(index: u32) -> MessageId { @@ -34,8 +35,10 @@ fn app_id(index: u32) -> UserApplicationId { } fn app_description(index: u32, deps: Vec) -> UserApplicationDescription { + let vm_runtime = VmRuntime::default(); UserApplicationDescription { bytecode_id: bytecode_id(), + vm_runtime, creation: message_id(index), parameters: vec![], required_application_ids: deps.into_iter().map(app_id).collect(), diff --git a/linera-execution/src/unit_tests/system_tests.rs b/linera-execution/src/unit_tests/system_tests.rs index a7c4304e5908..019d38550d4e 100644 --- a/linera-execution/src/unit_tests/system_tests.rs +++ b/linera-execution/src/unit_tests/system_tests.rs @@ -44,9 +44,11 @@ async fn application_message_index() -> anyhow::Result<()> { let contract_blob = Blob::new_contract_bytecode(contract.compress()); let service_blob = Blob::new_service_bytecode(service.compress()); let bytecode_id = BytecodeId::new(contract_blob.id().hash, service_blob.id().hash); + let vm_runtime = VmRuntime::default(); let operation = SystemOperation::CreateApplication { bytecode_id, + vm_runtime, parameters: vec![], instantiation_argument: vec![], required_application_ids: vec![], diff --git a/linera-execution/src/wasm/system_api.rs b/linera-execution/src/wasm/system_api.rs index 203d39ad4e2c..ceaaa94902ba 100644 --- a/linera-execution/src/wasm/system_api.rs +++ b/linera-execution/src/wasm/system_api.rs @@ -19,7 +19,7 @@ use tracing::log; use super::WasmExecutionError; use crate::{ BaseRuntime, BytecodeId, ContractRuntime, ContractSyncRuntimeHandle, ExecutionError, - ServiceRuntime, ServiceSyncRuntimeHandle, + ServiceRuntime, ServiceSyncRuntimeHandle, VmRuntime, }; /// Common host data used as the `UserData` of the system API implementations. @@ -326,6 +326,7 @@ where fn create_application( caller: &mut Caller, bytecode_id: BytecodeId, + vm_runtime: VmRuntime, parameters: Vec, argument: Vec, required_application_ids: Vec, @@ -333,7 +334,13 @@ where caller .user_data_mut() .runtime - .create_application(bytecode_id, parameters, argument, required_application_ids) + .create_application( + bytecode_id, + vm_runtime, + parameters, + argument, + required_application_ids, + ) .map_err(|error| RuntimeError::Custom(error.into())) } diff --git a/linera-execution/tests/contract_runtime_apis.rs b/linera-execution/tests/contract_runtime_apis.rs index 47f206f700c7..1e65dbc0edf7 100644 --- a/linera-execution/tests/contract_runtime_apis.rs +++ b/linera-execution/tests/contract_runtime_apis.rs @@ -12,9 +12,7 @@ use anyhow::bail; use assert_matches::assert_matches; use linera_base::{ crypto::CryptoHash, - data_types::{ - Amount, Blob, BlockHeight, CompressedBytecode, Timestamp, UserApplicationDescription, - }, + data_types::{Amount, Blob, BlockHeight, CompressedBytecode, Timestamp}, identifiers::{ Account, AccountOwner, ApplicationId, BytecodeId, ChainDescription, ChainId, MessageId, Owner, @@ -29,6 +27,7 @@ use linera_execution::{ BaseRuntime, ContractRuntime, ExecutionError, ExecutionOutcome, Message, MessageContext, Operation, OperationContext, ResourceController, SystemExecutionError, SystemExecutionStateView, TestExecutionRuntimeContext, TransactionOutcome, TransactionTracker, + UserApplicationDescription, VmRuntime, }; use linera_views::context::MemoryContext; use test_case::test_matrix; @@ -658,9 +657,11 @@ impl TransferTestEndpoint { fn sender_application_description() -> UserApplicationDescription { let contract_id = Self::sender_application_contract_blob().id().hash; let service_id = Self::sender_application_service_blob().id().hash; + let vm_runtime = VmRuntime::default(); UserApplicationDescription { bytecode_id: BytecodeId::new(contract_id, service_id), + vm_runtime, creation: MessageId { chain_id: ChainId::root(1000), height: BlockHeight(0), diff --git a/linera-sdk/src/test/chain.rs b/linera-sdk/src/test/chain.rs index 7a81ac03f085..93503f9a6309 100644 --- a/linera-sdk/src/test/chain.rs +++ b/linera-sdk/src/test/chain.rs @@ -21,7 +21,7 @@ use linera_chain::{types::ConfirmedBlockCertificate, ChainError, ChainExecutionC use linera_core::{data_types::ChainInfoQuery, worker::WorkerError}; use linera_execution::{ system::{SystemExecutionError, SystemOperation, CREATE_APPLICATION_MESSAGE_INDEX}, - ExecutionError, Query, QueryOutcome, QueryResponse, + ExecutionError, Query, QueryOutcome, QueryResponse, VmRuntime, }; use linera_storage::Storage as _; use serde::Serialize; @@ -353,6 +353,7 @@ impl ActiveChain { pub async fn create_application( &mut self, bytecode_id: BytecodeId, + vm_runtime: VmRuntime, parameters: Parameters, instantiation_argument: InstantiationArgument, required_application_ids: Vec, @@ -373,6 +374,7 @@ impl ActiveChain { .add_block(|block| { block.with_system_operation(SystemOperation::CreateApplication { bytecode_id: bytecode_id.forget_abi(), + vm_runtime, parameters, instantiation_argument, required_application_ids, diff --git a/linera-sdk/src/test/validator.rs b/linera-sdk/src/test/validator.rs index c1c4440e9548..915469270d9c 100644 --- a/linera-sdk/src/test/validator.rs +++ b/linera-sdk/src/test/validator.rs @@ -20,7 +20,7 @@ use linera_core::worker::WorkerState; use linera_execution::{ committee::{Committee, Epoch}, system::{OpenChainConfig, SystemOperation, OPEN_CHAIN_MESSAGE_INDEX}, - WasmRuntime, + VmRuntime, }; use linera_storage::{DbStorage, Storage, TestClock}; use linera_views::memory::MemoryStore; @@ -69,8 +69,7 @@ impl TestValidator { pub async fn new() -> Self { let key_pair = ValidatorSecretKey::generate(); let committee = Committee::make_simple(vec![key_pair.public()]); - let wasm_runtime = Some(WasmRuntime::default()); - let storage = DbStorage::::make_test_storage(wasm_runtime) + let storage = DbStorage::::make_test_storage() .now_or_never() .expect("execution of DbStorage::new should not await anything"); let clock = storage.clock().clone(); @@ -119,6 +118,7 @@ impl TestValidator { /// Returns the new [`TestValidator`], the [`ApplicationId`] of the created application, and /// the chain on which it was created. pub async fn with_current_application( + vm_runtime: VmRuntime, parameters: Parameters, instantiation_argument: InstantiationArgument, ) -> (TestValidator, ApplicationId, ActiveChain) @@ -133,7 +133,13 @@ impl TestValidator { let mut creator = validator.new_chain().await; let application_id = creator - .create_application(bytecode_id, parameters, instantiation_argument, vec![]) + .create_application( + bytecode_id, + vm_runtime, + parameters, + instantiation_argument, + vec![], + ) .await; (validator, application_id, creator) diff --git a/linera-service-graphql-client/src/service.rs b/linera-service-graphql-client/src/service.rs index 2bfd4b3454f9..cf30ab033c62 100644 --- a/linera-service-graphql-client/src/service.rs +++ b/linera-service-graphql-client/src/service.rs @@ -60,16 +60,15 @@ mod types { #[cfg(not(target_arch = "wasm32"))] mod types { - pub use linera_base::{ - data_types::UserApplicationDescription, identifiers::ChannelFullName, - ownership::ChainOwnership, - }; + pub use linera_base::{identifiers::ChannelFullName, ownership::ChainOwnership}; pub use linera_chain::{ data_types::{MessageAction, MessageBundle, Origin, Target}, manager::ChainManager, }; pub use linera_core::worker::{Notification, Reason}; - pub use linera_execution::{committee::Epoch, Message, MessageKind, Operation}; + pub use linera_execution::{ + committee::Epoch, Message, MessageKind, Operation, UserApplicationDescription, + }; } pub use types::*; diff --git a/linera-service/src/linera/main.rs b/linera-service/src/linera/main.rs index 1184d04f6500..6d3c12e44e86 100644 --- a/linera-service/src/linera/main.rs +++ b/linera-service/src/linera/main.rs @@ -41,7 +41,7 @@ use linera_core::{ }; use linera_execution::{ committee::{Committee, ValidatorState}, - Message, ResourceControlPolicy, SystemMessage, + Message, ResourceControlPolicy, SystemMessage, WithVmDefault as _, }; use linera_faucet_server::FaucetService; use linera_sdk::base::ValidatorPublicKey; @@ -934,6 +934,7 @@ impl Runnable for Job { CreateApplication { bytecode_id, + vm_runtime, creator, json_parameters, json_parameters_path, @@ -948,6 +949,9 @@ impl Runnable for Job { let parameters = read_json(json_parameters, json_parameters_path)?; let argument = read_json(json_argument, json_argument_path)?; + let vm_runtime = vm_runtime + .with_vm_default() + .expect("A virtual machine to be available"); info!("Synchronizing"); let chain_client = chain_client; context.process_inbox(&chain_client).await?; @@ -962,6 +966,7 @@ impl Runnable for Job { chain_client .create_application_untyped( bytecode_id, + vm_runtime, parameters, argument, required_application_ids.unwrap_or_default(), @@ -982,6 +987,7 @@ impl Runnable for Job { PublishAndCreate { contract, service, + vm_runtime, publisher, json_parameters, json_parameters_path, @@ -995,6 +1001,9 @@ impl Runnable for Job { let chain_client = context.make_chain_client(publisher)?; let parameters = read_json(json_parameters, json_parameters_path)?; let argument = read_json(json_argument, json_argument_path)?; + let vm_runtime = vm_runtime + .with_vm_default() + .expect("A virtual machine should be available"); let bytecode_id = context .publish_bytecode(&chain_client, contract, service) @@ -1010,6 +1019,7 @@ impl Runnable for Job { chain_client .create_application_untyped( bytecode_id, + vm_runtime, parameters, argument, required_application_ids.unwrap_or_default(), @@ -1076,6 +1086,7 @@ impl Runnable for Job { ProjectCommand::PublishAndCreate { path, name, + vm_runtime, publisher, json_parameters, json_parameters_path, @@ -1088,6 +1099,9 @@ impl Runnable for Job { info!("Creating application on chain {}", publisher); let chain_client = context.make_chain_client(publisher)?; + let vm_runtime = vm_runtime + .with_vm_default() + .expect("A virtual machine should be available"); let parameters = read_json(json_parameters, json_parameters_path)?; let argument = read_json(json_argument, json_argument_path)?; let project_path = path.unwrap_or_else(|| env::current_dir().unwrap()); @@ -1109,6 +1123,7 @@ impl Runnable for Job { chain_client .create_application_untyped( bytecode_id, + vm_runtime, parameters, argument, required_application_ids.unwrap_or_default(), diff --git a/linera-service/src/node_service.rs b/linera-service/src/node_service.rs index 107c5a38ec37..2f278bb0a39f 100644 --- a/linera-service/src/node_service.rs +++ b/linera-service/src/node_service.rs @@ -15,7 +15,7 @@ use axum::{extract::Path, http::StatusCode, response, response::IntoResponse, Ex use futures::{lock::Mutex, Future}; use linera_base::{ crypto::{CryptoError, CryptoHash}, - data_types::{Amount, ApplicationPermissions, Bytecode, TimeDelta, UserApplicationDescription}, + data_types::{Amount, ApplicationPermissions, Bytecode, TimeDelta}, ensure, hashed::Hashed, identifiers::{ApplicationId, BytecodeId, ChainId, Owner, UserApplicationId}, @@ -35,7 +35,8 @@ use linera_core::{ use linera_execution::{ committee::{Committee, Epoch}, system::{AdminOperation, Recipient, SystemChannel}, - Operation, Query, QueryOutcome, QueryResponse, SystemOperation, + Operation, Query, QueryOutcome, QueryResponse, SystemOperation, UserApplicationDescription, + VmRuntime, }; use linera_sdk::base::BlobContent; use linera_storage::Storage; @@ -597,10 +598,12 @@ where } /// Creates a new application. + #[allow(clippy::too_many_arguments)] async fn create_application( &self, chain_id: ChainId, bytecode_id: BytecodeId, + vm_runtime: VmRuntime, parameters: String, instantiation_argument: String, required_application_ids: Vec, @@ -613,6 +616,7 @@ where let result = client .create_application_untyped( bytecode_id, + vm_runtime, parameters, instantiation_argument, required_application_ids, diff --git a/linera-service/src/proxy/main.rs b/linera-service/src/proxy/main.rs index 7a54b01e7519..26eb16f77284 100644 --- a/linera-service/src/proxy/main.rs +++ b/linera-service/src/proxy/main.rs @@ -392,7 +392,6 @@ impl ProxyOptions { run_with_storage( full_storage_config, &genesis_config, - None, ProxyContext::from_options(self)?, ) .boxed() diff --git a/linera-service/src/schema_export.rs b/linera-service/src/schema_export.rs index 6a7228782085..777ac4138975 100644 --- a/linera-service/src/schema_export.rs +++ b/linera-service/src/schema_export.rs @@ -210,7 +210,7 @@ async fn main() -> std::io::Result<()> { let store_config = MemoryStoreConfig::new(TEST_MEMORY_MAX_STREAM_QUERIES); let namespace = "schema_export"; let root_key = &[]; - let storage = DbStorage::::initialize(store_config, namespace, root_key, None) + let storage = DbStorage::::initialize(store_config, namespace, root_key) .await .expect("storage"); let config = ChainListenerConfig::default(); diff --git a/linera-service/src/server.rs b/linera-service/src/server.rs index 8618b4a5ce20..db11e480f809 100644 --- a/linera-service/src/server.rs +++ b/linera-service/src/server.rs @@ -24,7 +24,7 @@ use linera_client::{ storage::{full_initialize_storage, run_with_storage, Runnable, StorageConfigNamespace}, }; use linera_core::{worker::WorkerState, JoinSetExt as _}; -use linera_execution::{WasmRuntime, WithWasmDefault}; +use linera_execution::committee::ValidatorName; use linera_rpc::{ config::{ CrossChainConfig, NetworkProtocol, NotificationConfig, ShardConfig, ShardId, TlsConfig, @@ -347,10 +347,6 @@ enum ServerCommand { #[arg(long = "grace-period-ms", default_value = "500", value_parser = util::parse_millis)] grace_period: Duration, - /// The WebAssembly runtime to use. - #[arg(long)] - wasm_runtime: Option, - /// The maximal number of chains loaded in memory at a given time. #[arg(long, default_value = "400")] max_loaded_chains: NonZeroUsize, @@ -503,7 +499,6 @@ async fn run(options: ServerOptions) { genesis_config_path, shard, grace_period, - wasm_runtime, max_loaded_chains, max_concurrent_queries, max_stream_queries, @@ -531,7 +526,6 @@ async fn run(options: ServerOptions) { grace_period, max_loaded_chains, }; - let wasm_runtime = wasm_runtime.with_wasm_default(); let common_config = CommonStoreConfig { max_concurrent_queries, max_stream_queries, @@ -541,7 +535,7 @@ async fn run(options: ServerOptions) { .add_common_config(common_config) .await .unwrap(); - run_with_storage(full_storage_config, &genesis_config, wasm_runtime, job) + run_with_storage(full_storage_config, &genesis_config, job) .boxed() .await .unwrap() diff --git a/linera-storage/Cargo.toml b/linera-storage/Cargo.toml index 6fd84d0c58c9..eba1aa75338d 100644 --- a/linera-storage/Cargo.toml +++ b/linera-storage/Cargo.toml @@ -12,6 +12,7 @@ repository.workspace = true version.workspace = true [features] +revm = ["linera-execution/revm"] test = ["linera-execution/test", "linera-views/test"] wasmer = ["linera-execution/wasmer"] wasmtime = ["linera-execution/wasmtime"] diff --git a/linera-storage/build.rs b/linera-storage/build.rs index 3124dc66ba68..02dfd97b26ba 100644 --- a/linera-storage/build.rs +++ b/linera-storage/build.rs @@ -8,6 +8,7 @@ fn main() { with_wasmer: { all(any(feature = "web", not(target_arch = "wasm32")), feature = "wasmer") }, with_wasmtime: { all(not(target_arch = "wasm32"), feature = "wasmtime") }, with_wasm_runtime: { any(with_wasmer, with_wasmtime) }, + with_revm: { feature = "revm" }, web: { all(target_arch = "wasm32", feature = "web") }, }; } diff --git a/linera-storage/src/db_storage.rs b/linera-storage/src/db_storage.rs index 1fdaa4cde70d..8021e54c9845 100644 --- a/linera-storage/src/db_storage.rs +++ b/linera-storage/src/db_storage.rs @@ -19,7 +19,6 @@ use linera_chain::{ }; use linera_execution::{ committee::Epoch, BlobState, ExecutionRuntimeConfig, UserContractCode, UserServiceCode, - WasmRuntime, }; use linera_views::{ backends::dual::{DualStoreRootKeyAssignment, StoreInUse}, @@ -261,7 +260,6 @@ impl BatchExt for Batch { pub struct DbStorage { store: Arc, clock: Clock, - wasm_runtime: Option, user_contracts: Arc>, user_services: Arc>, execution_runtime_config: ExecutionRuntimeConfig, @@ -824,10 +822,6 @@ where } self.write_batch(batch).await } - - fn wasm_runtime(&self) -> Option { - self.wasm_runtime - } } impl DbStorage @@ -870,11 +864,10 @@ where Ok(()) } - fn create(store: Store, wasm_runtime: Option, clock: C) -> Self { + fn create(store: Store, clock: C) -> Self { Self { store: Arc::new(store), clock, - wasm_runtime, user_contracts: Arc::new(DashMap::new()), user_services: Arc::new(DashMap::new()), execution_runtime_config: ExecutionRuntimeConfig::default(), @@ -891,20 +884,18 @@ where config: Store::Config, namespace: &str, root_key: &[u8], - wasm_runtime: Option, ) -> Result { let store = Store::maybe_create_and_connect(&config, namespace, root_key).await?; - Ok(Self::create(store, wasm_runtime, WallClock)) + Ok(Self::create(store, WallClock)) } pub async fn new( config: Store::Config, namespace: &str, root_key: &[u8], - wasm_runtime: Option, ) -> Result { let store = Store::connect(&config, namespace, root_key).await?; - Ok(Self::create(store, wasm_runtime, WallClock)) + Ok(Self::create(store, WallClock)) } } @@ -914,7 +905,7 @@ where Store: TestKeyValueStore + Clone + Send + Sync + 'static, Store::Error: Send + Sync, { - pub async fn make_test_storage(wasm_runtime: Option) -> Self { + pub async fn make_test_storage() -> Self { let config = Store::new_test_config().await.unwrap(); let namespace = generate_test_namespace(); let root_key = &[]; @@ -922,7 +913,6 @@ where config, &namespace, root_key, - wasm_runtime, TestClock::new(), ) .await @@ -933,10 +923,9 @@ where config: Store::Config, namespace: &str, root_key: &[u8], - wasm_runtime: Option, clock: TestClock, ) -> Result { let store = Store::recreate_and_connect(&config, namespace, root_key).await?; - Ok(Self::create(store, wasm_runtime, clock)) + Ok(Self::create(store, clock)) } } diff --git a/linera-storage/src/lib.rs b/linera-storage/src/lib.rs index 1a27f04e2ab3..13b0fb53d1a1 100644 --- a/linera-storage/src/lib.rs +++ b/linera-storage/src/lib.rs @@ -13,7 +13,7 @@ use async_trait::async_trait; use dashmap::{mapref::entry::Entry, DashMap}; use linera_base::{ crypto::CryptoHash, - data_types::{Amount, Blob, BlockHeight, TimeDelta, Timestamp, UserApplicationDescription}, + data_types::{Amount, Blob, BlockHeight, TimeDelta, Timestamp}, hashed::Hashed, identifiers::{BlobId, ChainDescription, ChainId, EventId, Owner, UserApplicationId}, ownership::ChainOwnership, @@ -22,11 +22,15 @@ use linera_chain::{ types::{ConfirmedBlock, ConfirmedBlockCertificate}, ChainError, ChainStateView, }; +#[cfg(with_revm)] +use linera_execution::revm::{EvmContractModule, EvmServiceModule}; +#[cfg(any(with_wasm_runtime, with_revm))] +use linera_execution::VmRuntime; use linera_execution::{ committee::{Committee, Epoch}, system::SystemChannel, BlobState, ChannelSubscription, ExecutionError, ExecutionRuntimeConfig, - ExecutionRuntimeContext, UserContractCode, UserServiceCode, WasmRuntime, + ExecutionRuntimeContext, UserApplicationDescription, UserContractCode, UserServiceCode, }; use linera_views::{ context::Context, @@ -257,19 +261,13 @@ pub trait Storage: Sized { Ok(()) } - /// Selects the WebAssembly runtime to use for applications (if any). - fn wasm_runtime(&self) -> Option; - /// Creates a [`UserContractCode`] instance using the bytecode in storage referenced /// by the `application_description`. - #[cfg(with_wasm_runtime)] + #[cfg(any(with_wasm_runtime, with_revm))] async fn load_contract( &self, application_description: &UserApplicationDescription, ) -> Result { - let Some(wasm_runtime) = self.wasm_runtime() else { - panic!("A Wasm runtime is required to load user applications."); - }; let contract_bytecode_blob_id = BlobId::new( application_description.bytecode_id.contract_blob_hash, BlobType::ContractBytecode, @@ -285,12 +283,22 @@ pub trait Storage: Sized { .await .join() .await?; - Ok(WasmContractModule::new(contract_bytecode, wasm_runtime) - .await? - .into()) + match application_description.vm_runtime { + VmRuntime::Wasm(wasm_runtime) => { + Ok(WasmContractModule::new(contract_bytecode, wasm_runtime) + .await? + .into()) + } + #[cfg(with_revm)] + VmRuntime::Evm(evm_runtime) => { + Ok(EvmContractModule::new(contract_bytecode, evm_runtime) + .await? + .into()) + } + } } - #[cfg(not(with_wasm_runtime))] + #[cfg(not(any(with_wasm_runtime, with_revm)))] #[allow(clippy::diverging_sub_expression)] async fn load_contract( &self, @@ -305,14 +313,11 @@ pub trait Storage: Sized { /// Creates a [`linera-sdk::UserContract`] instance using the bytecode in storage referenced /// by the `application_description`. - #[cfg(with_wasm_runtime)] + #[cfg(any(with_wasm_runtime, with_revm))] async fn load_service( &self, application_description: &UserApplicationDescription, ) -> Result { - let Some(wasm_runtime) = self.wasm_runtime() else { - panic!("A Wasm runtime is required to load user applications."); - }; let service_bytecode_blob_id = BlobId::new( application_description.bytecode_id.service_blob_hash, BlobType::ServiceBytecode, @@ -327,12 +332,20 @@ pub trait Storage: Sized { .await .join() .await?; - Ok(WasmServiceModule::new(service_bytecode, wasm_runtime) - .await? - .into()) + match application_description.vm_runtime { + VmRuntime::Wasm(wasm_runtime) => { + Ok(WasmServiceModule::new(service_bytecode, wasm_runtime) + .await? + .into()) + } + #[cfg(with_revm)] + VmRuntime::Evm(evm_runtime) => Ok(EvmServiceModule::new(service_bytecode, evm_runtime) + .await? + .into()), + } } - #[cfg(not(with_wasm_runtime))] + #[cfg(not(any(with_wasm_runtime, with_revm)))] #[allow(clippy::diverging_sub_expression)] async fn load_service( &self, From 237b07727fe39dc3cfbf1a9f89ed0312ef06fb95 Mon Sep 17 00:00:00 2001 From: Mathieu Dutour Sikiric Date: Fri, 21 Feb 2025 12:39:18 +0100 Subject: [PATCH 02/16] Remove unused types. --- linera-core/src/chain_worker/actor.rs | 5 ++--- linera-core/src/chain_worker/state/mod.rs | 5 ++--- linera-core/src/worker.rs | 4 +++- linera-service/src/server.rs | 1 - 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/linera-core/src/chain_worker/actor.rs b/linera-core/src/chain_worker/actor.rs index 7a46d8edf819..d2dce845f5eb 100644 --- a/linera-core/src/chain_worker/actor.rs +++ b/linera-core/src/chain_worker/actor.rs @@ -22,9 +22,8 @@ use linera_chain::{ ChainStateView, }; use linera_execution::{ - committee::{Epoch, ValidatorName}, - Query, QueryContext, QueryOutcome, ServiceRuntimeEndpoint, ServiceSyncRuntime, - UserApplicationDescription, + committee::Epoch, Query, QueryContext, QueryOutcome, ServiceRuntimeEndpoint, + ServiceSyncRuntime, UserApplicationDescription, }; use linera_storage::Storage; use tokio::sync::{mpsc, oneshot, OwnedRwLockReadGuard}; diff --git a/linera-core/src/chain_worker/state/mod.rs b/linera-core/src/chain_worker/state/mod.rs index bdcf70c3c8e2..cc976b751f34 100644 --- a/linera-core/src/chain_worker/state/mod.rs +++ b/linera-core/src/chain_worker/state/mod.rs @@ -27,9 +27,8 @@ use linera_chain::{ ChainError, ChainStateView, }; use linera_execution::{ - committee::{Epoch, ValidatorName}, - Message, Query, QueryContext, QueryOutcome, ServiceRuntimeEndpoint, SystemMessage, - UserApplicationDescription, + committee::Epoch, Message, Query, QueryContext, QueryOutcome, ServiceRuntimeEndpoint, + SystemMessage, UserApplicationDescription, }; use linera_storage::{Clock as _, Storage}; use linera_views::views::{ClonableView, ViewError}; diff --git a/linera-core/src/worker.rs b/linera-core/src/worker.rs index a55a1e7ebe5e..eb6bdb35e385 100644 --- a/linera-core/src/worker.rs +++ b/linera-core/src/worker.rs @@ -29,7 +29,9 @@ use linera_chain::{ }, ChainError, ChainStateView, }; -use linera_execution::{committee::Epoch, ExecutionError, Query, QueryOutcome, UserApplicationDescription}; +use linera_execution::{ + committee::Epoch, ExecutionError, Query, QueryOutcome, UserApplicationDescription, +}; use linera_storage::Storage; use linera_views::views::ViewError; use lru::LruCache; diff --git a/linera-service/src/server.rs b/linera-service/src/server.rs index db11e480f809..579332db6346 100644 --- a/linera-service/src/server.rs +++ b/linera-service/src/server.rs @@ -24,7 +24,6 @@ use linera_client::{ storage::{full_initialize_storage, run_with_storage, Runnable, StorageConfigNamespace}, }; use linera_core::{worker::WorkerState, JoinSetExt as _}; -use linera_execution::committee::ValidatorName; use linera_rpc::{ config::{ CrossChainConfig, NetworkProtocol, NotificationConfig, ShardConfig, ShardId, TlsConfig, From a53da6efeb92171408c01f6f2e100e7968353a07 Mon Sep 17 00:00:00 2001 From: Mathieu Dutour Sikiric Date: Fri, 21 Feb 2025 17:16:42 +0100 Subject: [PATCH 03/16] Several correction from the CI runs. --- CLI.md | 4 +++- linera-execution/tests/contract_runtime_apis.rs | 2 +- linera-service-graphql-client/gql/service_schema.graphql | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CLI.md b/CLI.md index 6925e5e77179..03f828fb6fc6 100644 --- a/CLI.md +++ b/CLI.md @@ -117,7 +117,6 @@ A Byzantine-fault tolerant sidechain with low-latency finality and high throughp * `--max-pending-message-bundles ` — The maximum number of incoming message bundles to include in a block proposal Default value: `10` -* `--wasm-runtime ` — The WebAssembly runtime to use * `--max-loaded-chains ` — The maximal number of chains loaded in memory at a given time Default value: `40` @@ -651,6 +650,7 @@ Create an application ###### **Options:** +* `--vm-runtime ` — The virtual machine runtime to use * `--json-parameters ` — The shared parameters as JSON string * `--json-parameters-path ` — Path to a JSON file containing the shared parameters * `--json-argument ` — The instantiation argument as a JSON string @@ -673,6 +673,7 @@ Create an application, and publish the required bytecode ###### **Options:** +* `--vm-runtime ` — The virtual machine runtime to use * `--json-parameters ` — The shared parameters as JSON string * `--json-parameters-path ` — Path to a JSON file containing the shared parameters * `--json-argument ` — The instantiation argument as a JSON string @@ -878,6 +879,7 @@ Build and publish a Linera project ###### **Options:** +* `--vm-runtime ` — The virtual machine runtime to use * `--json-parameters ` — The shared parameters as JSON string * `--json-parameters-path ` — Path to a JSON file containing the shared parameters * `--json-argument ` — The instantiation argument as a JSON string diff --git a/linera-execution/tests/contract_runtime_apis.rs b/linera-execution/tests/contract_runtime_apis.rs index 1e65dbc0edf7..0fbe6ae0d445 100644 --- a/linera-execution/tests/contract_runtime_apis.rs +++ b/linera-execution/tests/contract_runtime_apis.rs @@ -653,7 +653,7 @@ impl TransferTestEndpoint { ApplicationId::from(&Self::sender_application_description()) } - /// Returns the [`ApplicationDescription`] used to represent a sender that's an application. + /// Returns the [`UserApplicationDescription`] used to represent a sender that's an application. fn sender_application_description() -> UserApplicationDescription { let contract_id = Self::sender_application_contract_blob().id().hash; let service_id = Self::sender_application_service_blob().id().hash; diff --git a/linera-service-graphql-client/gql/service_schema.graphql b/linera-service-graphql-client/gql/service_schema.graphql index 56e1dd35cf9d..0299a3f7fb38 100644 --- a/linera-service-graphql-client/gql/service_schema.graphql +++ b/linera-service-graphql-client/gql/service_schema.graphql @@ -830,7 +830,7 @@ type MutationRoot { """ Creates a new application. """ - createApplication(chainId: ChainId!, bytecodeId: BytecodeId!, parameters: String!, instantiationArgument: String!, requiredApplicationIds: [ApplicationId!]!): ApplicationId! + createApplication(chainId: ChainId!, bytecodeId: BytecodeId!, vmRuntime: VmRuntime!, parameters: String!, instantiationArgument: String!, requiredApplicationIds: [ApplicationId!]!): ApplicationId! """ Requests a `RegisterApplications` message from another chain so the application can be used on this one. @@ -1215,6 +1215,8 @@ type VersionInfo { witHash: String! } +scalar VmRuntime + directive @include(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT directive @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT schema { From 9570014bb69be3f04bb1af609f05a9c71e7292b8 Mon Sep 17 00:00:00 2001 From: Mathieu Dutour Sikiric Date: Fri, 21 Feb 2025 22:25:53 +0100 Subject: [PATCH 04/16] Move the WasmRuntime / VmRuntime, etc. to linera-base. Integrate the VM type to the BytecodeId. --- Cargo.lock | 3 +- linera-base/Cargo.toml | 4 + linera-base/build.rs | 4 +- linera-base/src/identifiers.rs | 30 ++- linera-base/src/lib.rs | 1 + linera-base/src/unit_tests.rs | 3 + linera-base/src/vm.rs | 154 ++++++++++++++ linera-chain/src/unit_tests/chain_tests.rs | 6 +- linera-client/src/client_context.rs | 4 +- linera-client/src/client_options.rs | 11 +- linera-core/src/client/mod.rs | 13 +- .../src/unit_tests/wasm_client_tests.rs | 25 ++- .../src/unit_tests/wasm_worker_tests.rs | 7 +- linera-execution/Cargo.toml | 1 - linera-execution/build.rs | 3 - linera-execution/src/applications.rs | 4 +- linera-execution/src/execution_state_actor.rs | 5 +- linera-execution/src/lib.rs | 196 ++---------------- linera-execution/src/revm.rs | 4 +- linera-execution/src/runtime.rs | 4 +- linera-execution/src/system.rs | 8 +- linera-execution/src/test_utils/mod.rs | 7 +- .../src/unit_tests/applications_tests.rs | 5 +- .../src/unit_tests/runtime_tests.rs | 2 + .../src/unit_tests/system_tests.rs | 5 +- linera-execution/src/wasm/mod.rs | 53 ++++- linera-execution/src/wasm/system_api.rs | 11 +- .../tests/contract_runtime_apis.rs | 7 +- linera-execution/tests/wasm.rs | 4 +- .../src/contract/conversions_from_wit.rs | 18 ++ linera-sdk/src/contract/conversions_to_wit.rs | 18 ++ .../src/service/conversions_from_wit.rs | 18 ++ linera-sdk/src/service/conversions_to_wit.rs | 18 ++ linera-sdk/src/test/chain.rs | 8 +- linera-sdk/src/test/validator.rs | 10 +- linera-sdk/wit/contract-system-api.wit | 9 + linera-sdk/wit/service-system-api.wit | 9 + linera-service/src/linera/main.rs | 17 +- linera-service/src/node_service.rs | 7 +- linera-storage/Cargo.toml | 1 + linera-storage/src/lib.rs | 135 ++++++------ 41 files changed, 497 insertions(+), 355 deletions(-) create mode 100644 linera-base/src/vm.rs diff --git a/Cargo.lock b/Cargo.lock index f7535318beb9..a979153a0b07 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4391,6 +4391,7 @@ dependencies = [ "cfg_aliases", "chrono", "custom_debug_derive", + "derive_more", "ed25519-dalek", "futures", "getrandom", @@ -4600,7 +4601,6 @@ dependencies = [ "clap", "custom_debug_derive", "dashmap 5.5.3", - "derive_more", "dyn-clone", "futures", "hex", @@ -4992,6 +4992,7 @@ dependencies = [ "anyhow", "async-trait", "bcs", + "cfg-if", "cfg_aliases", "dashmap 5.5.3", "futures", diff --git a/linera-base/Cargo.toml b/linera-base/Cargo.toml index 79c8ea6fd301..95c900e706f9 100644 --- a/linera-base/Cargo.toml +++ b/linera-base/Cargo.toml @@ -12,6 +12,9 @@ repository.workspace = true version.workspace = true [features] +wasmer = [] +wasmtime = [] +revm = [] metrics = ["prometheus"] reqwest = ["dep:reqwest"] test = ["test-strategy", "proptest"] @@ -39,6 +42,7 @@ bcs.workspace = true cfg-if.workspace = true chrono.workspace = true custom_debug_derive.workspace = true +derive_more = { workspace = true, features = ["display"] } ed25519-dalek.workspace = true futures.workspace = true getrandom = { workspace = true, optional = true } diff --git a/linera-base/build.rs b/linera-base/build.rs index de990fb6208c..93bd8a7e56a7 100644 --- a/linera-base/build.rs +++ b/linera-base/build.rs @@ -8,7 +8,9 @@ fn main() { with_metrics: { all(not(target_arch = "wasm32"), feature = "metrics") }, with_reqwest: { feature = "reqwest" }, with_testing: { any(test, feature = "test") }, - + with_revm: { feature = "revm" }, + with_wasmer: { feature = "wasmer" }, + with_wasmtime: { all(not(target_arch = "wasm32"), feature = "wasmtime") }, // the old version of `getrandom` we pin here is available on all targets, but // using it will panic if no suitable source of entropy is found with_getrandom: { any(web, not(target_arch = "wasm32")) }, diff --git a/linera-base/src/identifiers.rs b/linera-base/src/identifiers.rs index cc64398d6cfd..4fb678564d0e 100644 --- a/linera-base/src/identifiers.rs +++ b/linera-base/src/identifiers.rs @@ -21,6 +21,7 @@ use crate::{ crypto::{BcsHashable, CryptoError, CryptoHash}, data_types::BlockHeight, doc_scalar, hex_debug, + vm::VmRuntime, }; /// The owner of a chain. This is currently the hash of the owner's public key used to @@ -350,6 +351,8 @@ pub struct BytecodeId { pub contract_blob_hash: CryptoHash, /// The hash of the blob containing the service bytecode. pub service_blob_hash: CryptoHash, + /// The virtual machine being used. + pub vm_runtime: VmRuntime, #[witty(skip)] #[debug(skip)] _phantom: PhantomData<(Abi, Parameters, InstantiationArgument)>, @@ -568,10 +571,12 @@ impl PartialEq let BytecodeId { contract_blob_hash, service_blob_hash, + vm_runtime, _phantom, } = other; self.contract_blob_hash == *contract_blob_hash && self.service_blob_hash == *service_blob_hash + && self.vm_runtime == *vm_runtime } } @@ -595,10 +600,15 @@ impl Ord let BytecodeId { contract_blob_hash, service_blob_hash, + vm_runtime, _phantom, } = other; - (self.contract_blob_hash, self.service_blob_hash) - .cmp(&(*contract_blob_hash, *service_blob_hash)) + ( + self.contract_blob_hash, + self.service_blob_hash, + self.vm_runtime, + ) + .cmp(&(*contract_blob_hash, *service_blob_hash, *vm_runtime)) } } @@ -609,10 +619,12 @@ impl Hash let BytecodeId { contract_blob_hash: contract_blob_id, service_blob_hash: service_blob_id, + vm_runtime: vm_runtime_id, _phantom, } = self; contract_blob_id.hash(state); service_blob_id.hash(state); + vm_runtime_id.hash(state); } } @@ -621,6 +633,7 @@ impl Hash struct SerializableBytecodeId { contract_blob_hash: CryptoHash, service_blob_hash: CryptoHash, + vm_runtime: VmRuntime, } impl Serialize @@ -633,6 +646,7 @@ impl Serialize let serializable_bytecode_id = SerializableBytecodeId { contract_blob_hash: self.contract_blob_hash, service_blob_hash: self.service_blob_hash, + vm_runtime: self.vm_runtime, }; if serializer.is_human_readable() { let bytes = @@ -659,6 +673,7 @@ impl<'de, Abi, Parameters, InstantiationArgument> Deserialize<'de> Ok(BytecodeId { contract_blob_hash: serializable_bytecode_id.contract_blob_hash, service_blob_hash: serializable_bytecode_id.service_blob_hash, + vm_runtime: serializable_bytecode_id.vm_runtime, _phantom: PhantomData, }) } else { @@ -666,6 +681,7 @@ impl<'de, Abi, Parameters, InstantiationArgument> Deserialize<'de> Ok(BytecodeId { contract_blob_hash: serializable_bytecode_id.contract_blob_hash, service_blob_hash: serializable_bytecode_id.service_blob_hash, + vm_runtime: serializable_bytecode_id.vm_runtime, _phantom: PhantomData, }) } @@ -674,10 +690,15 @@ impl<'de, Abi, Parameters, InstantiationArgument> Deserialize<'de> impl BytecodeId { /// Creates a bytecode ID from contract/service hashes. - pub fn new(contract_blob_hash: CryptoHash, service_blob_hash: CryptoHash) -> Self { + pub fn new( + contract_blob_hash: CryptoHash, + service_blob_hash: CryptoHash, + vm_runtime: VmRuntime, + ) -> Self { BytecodeId { contract_blob_hash, service_blob_hash, + vm_runtime, _phantom: PhantomData, } } @@ -689,6 +710,7 @@ impl BytecodeId { BytecodeId { contract_blob_hash: self.contract_blob_hash, service_blob_hash: self.service_blob_hash, + vm_runtime: self.vm_runtime, _phantom: PhantomData, } } @@ -700,6 +722,7 @@ impl BytecodeId BytecodeId ApplicationId { bytecode_id: BytecodeId::new( CryptoHash::test_hash("contract bytecode"), CryptoHash::test_hash("service bytecode"), + VmRuntime::default(), ), creation: MessageId { chain_id: ChainId::root(0), @@ -117,6 +119,7 @@ fn bytecode_id_test_case() -> BytecodeId { BytecodeId::new( CryptoHash::test_hash("another contract bytecode"), CryptoHash::test_hash("another service bytecode"), + VmRuntime::default(), ) } diff --git a/linera-base/src/vm.rs b/linera-base/src/vm.rs new file mode 100644 index 000000000000..a6a54fa608ea --- /dev/null +++ b/linera-base/src/vm.rs @@ -0,0 +1,154 @@ +// Copyright (c) Zefchain Labs, Inc. +// SPDX-License-Identifier: Apache-2.0 + +//! The virtual machines being supported. + +use std::str::FromStr; + +use async_graphql::scalar; +use derive_more::Display; +use linera_witty::{WitLoad, WitStore, WitType}; +use serde::{Deserialize, Serialize}; +use thiserror::Error; + +/// The runtime to use for running the application. +#[derive( + Clone, + Copy, + Display, + Hash, + PartialEq, + Eq, + PartialOrd, + Ord, + Serialize, + Deserialize, + WitType, + WitStore, + WitLoad, + Debug, +)] +#[cfg_attr(with_testing, derive(test_strategy::Arbitrary))] +pub enum WasmRuntime { + /// The choice of the Wasmer runtime for WebAssembly + #[display("wasmer")] + Wasmer, + /// The choice of the Wasmtime runtime for WebAssembly + #[display("wasmtime")] + Wasmtime, + /// The choice of the Wasmer with sanitizer runtime for WebAssembly + WasmerWithSanitizer, + /// The choice of the Wasmtime with sanitizer runtime for WebAssembly + WasmtimeWithSanitizer, +} + +impl WasmRuntime { + /// Returns whether we need a stabilizer or not. + pub fn needs_sanitizer(self) -> bool { + matches!( + self, + WasmRuntime::WasmerWithSanitizer | WasmRuntime::WasmtimeWithSanitizer + ) + } +} + +impl FromStr for WasmRuntime { + type Err = InvalidVmRuntime; + + fn from_str(string: &str) -> Result { + match string { + "wasmer" => Ok(WasmRuntime::Wasmer), + "wasmtime" => Ok(WasmRuntime::Wasmtime), + unknown => Err(InvalidVmRuntime(unknown.to_owned())), + } + } +} + +scalar!(WasmRuntime); + +#[derive( + Clone, + Copy, + Debug, + Display, + Hash, + PartialEq, + Eq, + PartialOrd, + Ord, + Serialize, + Deserialize, + WitType, + WitStore, + WitLoad, +)] +#[cfg_attr(with_testing, derive(test_strategy::Arbitrary))] +/// The choice of runtime for handling the Evm. +pub enum EvmRuntime { + /// The choice of the Revm runtime for Evm. + Revm, +} + +scalar!(EvmRuntime); + +#[derive( + Clone, + Copy, + Display, + Hash, + PartialEq, + Eq, + PartialOrd, + Ord, + Serialize, + Deserialize, + WitType, + WitStore, + WitLoad, + Debug, +)] +#[cfg_attr(with_testing, derive(test_strategy::Arbitrary))] +/// The virtual machine runtime +pub enum VmRuntime { + /// The Wasm for the virtual machine + Wasm(WasmRuntime), + /// The Evm for the virtual machine + Evm(EvmRuntime), +} + +impl FromStr for VmRuntime { + type Err = InvalidVmRuntime; + + fn from_str(string: &str) -> Result { + match string { + "wasmer" => Ok(VmRuntime::Wasm(WasmRuntime::Wasmer)), + "wasmtime" => Ok(VmRuntime::Wasm(WasmRuntime::Wasmtime)), + "revm" => Ok(VmRuntime::Evm(EvmRuntime::Revm)), + unknown => Err(InvalidVmRuntime(unknown.to_owned())), + } + } +} + +scalar!(VmRuntime); + +#[cfg(with_testing)] +impl Default for VmRuntime { + fn default() -> Self { + cfg_if::cfg_if! { + if #[cfg(with_wasmer)] { + VmRuntime::Wasm(WasmRuntime::Wasmer) + } else if #[cfg(with_wasmtime)] { + VmRuntime::Wasm(WasmRuntime::Wasmtime) + } else if #[cfg(with_revm)] { + VmRuntime::Evm(EvmRuntime::Revm) + } else { + panic!("Cannot call default for VmRuntime without wasmer, or wasmtime or revm features"); + } + } + } +} + +/// Attempts to create an invalid [`VmRuntime`] instance from a string. +#[derive(Clone, Debug, Error)] +#[error("{0:?} is not a valid virtual machine runtime")] +pub struct InvalidVmRuntime(String); diff --git a/linera-chain/src/unit_tests/chain_tests.rs b/linera-chain/src/unit_tests/chain_tests.rs index d355d436a2df..9c8cee798e26 100644 --- a/linera-chain/src/unit_tests/chain_tests.rs +++ b/linera-chain/src/unit_tests/chain_tests.rs @@ -12,6 +12,7 @@ use linera_base::{ hashed::Hashed, identifiers::{ApplicationId, BytecodeId, ChainId, MessageId}, ownership::ChainOwnership, + vm::VmRuntime, }; use linera_execution::{ committee::{Committee, Epoch, ValidatorState}, @@ -19,7 +20,7 @@ use linera_execution::{ test_utils::{ExpectedCall, MockApplication}, ExecutionError, ExecutionRuntimeConfig, ExecutionRuntimeContext, Message, MessageKind, Operation, ResourceControlPolicy, SystemMessage, SystemOperation, TestExecutionRuntimeContext, - UserApplicationDescription, VmRuntime, + UserApplicationDescription, }; use linera_views::{ context::{Context as _, MemoryContext}, @@ -66,11 +67,10 @@ fn make_app_description() -> (UserApplicationDescription, Blob, Blob) { let service_blob = Blob::new_service_bytecode(service.compress()); let vm_runtime = VmRuntime::default(); - let bytecode_id = BytecodeId::new(contract_blob.id().hash, service_blob.id().hash); + let bytecode_id = BytecodeId::new(contract_blob.id().hash, service_blob.id().hash, vm_runtime); ( UserApplicationDescription { bytecode_id, - vm_runtime, creation: make_admin_message_id(BlockHeight(2)), required_application_ids: vec![], parameters: vec![], diff --git a/linera-client/src/client_context.rs b/linera-client/src/client_context.rs index 78dda4b5b0b1..4fb86966435e 100644 --- a/linera-client/src/client_context.rs +++ b/linera-client/src/client_context.rs @@ -13,6 +13,7 @@ use linera_base::{ identifiers::{Account, ChainId}, ownership::ChainOwnership, time::{Duration, Instant}, + vm::VmRuntime, }; use linera_chain::types::ConfirmedBlockCertificate; use linera_core::{ @@ -493,6 +494,7 @@ where chain_client: &ChainClient, contract: PathBuf, service: PathBuf, + vm_runtime: VmRuntime, ) -> Result { info!("Loading bytecode files"); let contract_bytecode = Bytecode::load_from_file(&contract) @@ -504,7 +506,7 @@ where info!("Publishing bytecode"); let (contract_blob, service_blob, bytecode_id) = - create_bytecode_blobs(contract_bytecode, service_bytecode).await; + create_bytecode_blobs(contract_bytecode, service_bytecode, vm_runtime).await; let (bytecode_id, _) = self .apply_client_command(chain_client, |chain_client| { let contract_blob = contract_blob.clone(); diff --git a/linera-client/src/client_options.rs b/linera-client/src/client_options.rs index 39b72b4cd55c..e3be71adf514 100644 --- a/linera-client/src/client_options.rs +++ b/linera-client/src/client_options.rs @@ -17,9 +17,10 @@ use linera_base::{ }, ownership::{ChainOwnership, TimeoutConfig}, time::Duration, + vm::VmRuntime, }; use linera_core::{client::BlanketMessagePolicy, DEFAULT_GRACE_PERIOD}; -use linera_execution::{ResourceControlPolicy, VmRuntime}; +use linera_execution::ResourceControlPolicy; use linera_views::store::CommonStoreConfig; #[cfg(feature = "fs")] @@ -768,6 +769,10 @@ pub enum ClientCommand { /// Path to the Wasm file for the application "service" bytecode. service: PathBuf, + /// The virtual machine runtime to use. + #[arg(long)] + vm_runtime: Option, + /// An optional chain ID to publish the bytecode. The default chain of the wallet /// is used otherwise. publisher: Option, @@ -797,10 +802,6 @@ pub enum ClientCommand { /// The bytecode ID of the application to create. bytecode_id: BytecodeId, - /// The virtual machine runtime to use. - #[arg(long)] - vm_runtime: Option, - /// An optional chain ID to host the application. The default chain of the wallet /// is used otherwise. creator: Option, diff --git a/linera-core/src/client/mod.rs b/linera-core/src/client/mod.rs index 92f7773a26ed..dbd4deee8712 100644 --- a/linera-core/src/client/mod.rs +++ b/linera-core/src/client/mod.rs @@ -39,6 +39,7 @@ use linera_base::{ Owner, UserApplicationId, }, ownership::{ChainOwnership, TimeoutConfig}, + vm::VmRuntime, }; use linera_chain::{ data_types::{ @@ -59,7 +60,7 @@ use linera_execution::{ CREATE_APPLICATION_MESSAGE_INDEX, OPEN_CHAIN_MESSAGE_INDEX, }, ExecutionError, Operation, Query, QueryOutcome, QueryResponse, SystemExecutionError, - SystemQuery, SystemResponse, VmRuntime, + SystemQuery, SystemResponse, }; use linera_storage::{Clock as _, Storage}; use linera_views::views::ViewError; @@ -737,6 +738,7 @@ enum CheckCertificateResult { pub async fn create_bytecode_blobs( contract: Bytecode, service: Bytecode, + vm_runtime: VmRuntime, ) -> (Blob, Blob, BytecodeId) { let (compressed_contract, compressed_service) = tokio::task::spawn_blocking(move || (contract.compress(), service.compress())) @@ -744,7 +746,7 @@ pub async fn create_bytecode_blobs( .expect("Compression should not panic"); let contract_blob = Blob::new_contract_bytecode(compressed_contract); let service_blob = Blob::new_service_bytecode(compressed_service); - let bytecode_id = BytecodeId::new(contract_blob.id().hash, service_blob.id().hash); + let bytecode_id = BytecodeId::new(contract_blob.id().hash, service_blob.id().hash, vm_runtime); (contract_blob, service_blob, bytecode_id) } @@ -2846,9 +2848,10 @@ where &self, contract: Bytecode, service: Bytecode, + vm_runtime: VmRuntime, ) -> Result, ChainClientError> { let (contract_blob, service_blob, bytecode_id) = - create_bytecode_blobs(contract, service).await; + create_bytecode_blobs(contract, service, vm_runtime).await; self.publish_bytecode_blobs(contract_blob, service_blob, bytecode_id) .await } @@ -2912,7 +2915,6 @@ where >( &self, bytecode_id: BytecodeId, - vm_runtime: VmRuntime, parameters: &Parameters, instantiation_argument: &InstantiationArgument, required_application_ids: Vec, @@ -2923,7 +2925,6 @@ where Ok(self .create_application_untyped( bytecode_id.forget_abi(), - vm_runtime, parameters, instantiation_argument, required_application_ids, @@ -2946,7 +2947,6 @@ where pub async fn create_application_untyped( &self, bytecode_id: BytecodeId, - vm_runtime: VmRuntime, parameters: Vec, instantiation_argument: Vec, required_application_ids: Vec, @@ -2954,7 +2954,6 @@ where { self.execute_operation(Operation::System(SystemOperation::CreateApplication { bytecode_id, - vm_runtime, parameters, instantiation_argument, required_application_ids, diff --git a/linera-core/src/unit_tests/wasm_client_tests.rs b/linera-core/src/unit_tests/wasm_client_tests.rs index 100bfe0a7d0b..58a31e075e9b 100644 --- a/linera-core/src/unit_tests/wasm_client_tests.rs +++ b/linera-core/src/unit_tests/wasm_client_tests.rs @@ -22,6 +22,7 @@ use linera_base::{ data_types::{Amount, Bytecode, Event, OracleResponse}, identifiers::{AccountOwner, ApplicationId, Destination, Owner, StreamId, StreamName}, ownership::{ChainOwnership, TimeoutConfig}, + vm::{VmRuntime, WasmRuntime}, }; use linera_chain::{ data_types::{MessageAction, OutgoingMessage}, @@ -29,7 +30,7 @@ use linera_chain::{ }; use linera_execution::{ ExecutionError, Message, MessageKind, Operation, QueryOutcome, ResourceControlPolicy, - SystemMessage, UserApplicationDescription, VmRuntime, WasmRuntime, + SystemMessage, UserApplicationDescription, }; use serde_json::json; use test_case::test_case; @@ -122,7 +123,7 @@ where let creator = builder.add_root_chain(1, Amount::ONE).await?; let (bytecode_id, _cert) = publisher - .publish_bytecode(contract_bytecode, service_bytecode) + .publish_bytecode(contract_bytecode, service_bytecode, vm_runtime) .await .unwrap() .unwrap(); @@ -137,7 +138,7 @@ where let initial_value = 10_u64; let (application_id, _) = creator - .create_application(bytecode_id, vm_runtime, &(), &initial_value, vec![]) + .create_application(bytecode_id, &(), &initial_value, vec![]) .await .unwrap() .unwrap(); @@ -170,7 +171,7 @@ where let small_bytecode = Bytecode::new(vec![]); // Publishing bytecode that exceeds the limit fails. let result = publisher - .publish_bytecode(large_bytecode.clone(), small_bytecode.clone()) + .publish_bytecode(large_bytecode.clone(), small_bytecode.clone(), vm_runtime) .await; assert_matches!( result, @@ -179,7 +180,7 @@ where ))) if matches!(*error, ExecutionError::BytecodeTooLarge) ); let result = publisher - .publish_bytecode(small_bytecode, large_bytecode) + .publish_bytecode(small_bytecode, large_bytecode, vm_runtime) .await; assert_matches!( result, @@ -295,6 +296,7 @@ where .publish_bytecode( Bytecode::load_from_file(contract_path).await?, Bytecode::load_from_file(service_path).await?, + vm_runtime, ) .await .unwrap() @@ -308,6 +310,7 @@ where .publish_bytecode( Bytecode::load_from_file(contract_path).await?, Bytecode::load_from_file(service_path).await?, + vm_runtime, ) .await .unwrap() @@ -320,14 +323,13 @@ where creator.synchronize_from_validators().await.unwrap(); let initial_value = 10_u64; let (application_id1, _) = creator - .create_application(bytecode_id1, vm_runtime, &(), &initial_value, vec![]) + .create_application(bytecode_id1, &(), &initial_value, vec![]) .await .unwrap() .unwrap(); let (application_id2, certificate) = creator .create_application( bytecode_id2, - vm_runtime, &application_id1, &(), vec![application_id1.forget_abi()], @@ -557,6 +559,7 @@ where .publish_bytecode( Bytecode::load_from_file(contract_path).await?, Bytecode::load_from_file(service_path).await?, + vm_runtime, ) .await .unwrap() @@ -573,7 +576,7 @@ where let state = fungible::InitialState { accounts }; let params = fungible::Parameters::new("FUN"); let (application_id, _cert) = sender - .create_application(bytecode_id, vm_runtime, ¶ms, &state, vec![]) + .create_application(bytecode_id, ¶ms, &state, vec![]) .await .unwrap() .unwrap(); @@ -761,6 +764,7 @@ where .publish_bytecode( Bytecode::load_from_file(contract_path).await?, Bytecode::load_from_file(service_path).await?, + vm_runtime, ) .await .unwrap() @@ -769,7 +773,7 @@ where let bytecode_id = bytecode_id.with_abi::(); let (application_id, _cert) = receiver - .create_application(bytecode_id, vm_runtime, &(), &(), vec![]) + .create_application(bytecode_id, &(), &(), vec![]) .await .unwrap() .unwrap(); @@ -919,6 +923,7 @@ async fn test_memory_fuel_limit(wasm_runtime: WasmRuntime) -> anyhow::Result<()> .publish_bytecode( Bytecode::load_from_file(contract_path).await?, Bytecode::load_from_file(service_path).await?, + vm_runtime, ) .await .unwrap() @@ -927,7 +932,7 @@ async fn test_memory_fuel_limit(wasm_runtime: WasmRuntime) -> anyhow::Result<()> let initial_value = 10_u64; let (application_id, _) = publisher - .create_application(bytecode_id, vm_runtime, &(), &initial_value, vec![]) + .create_application(bytecode_id, &(), &initial_value, vec![]) .await .unwrap() .unwrap(); diff --git a/linera-core/src/unit_tests/wasm_worker_tests.rs b/linera-core/src/unit_tests/wasm_worker_tests.rs index da36246e04f4..eba700d87ea0 100644 --- a/linera-core/src/unit_tests/wasm_worker_tests.rs +++ b/linera-core/src/unit_tests/wasm_worker_tests.rs @@ -21,6 +21,7 @@ use linera_base::{ BytecodeId, ChainDescription, ChainId, Destination, MessageId, UserApplicationId, }, ownership::ChainOwnership, + vm::{VmRuntime, WasmRuntime}, }; use linera_chain::{ data_types::{BlockExecutionOutcome, OutgoingMessage}, @@ -32,7 +33,7 @@ use linera_execution::{ system::{SystemMessage, SystemOperation}, test_utils::SystemExecutionState, Message, MessageKind, Operation, OperationContext, ResourceController, TransactionTracker, - UserApplicationDescription, VmRuntime, WasmContractModule, WasmRuntime, + UserApplicationDescription, WasmContractModule, }; use linera_storage::{DbStorage, Storage}; #[cfg(feature = "dynamodb")] @@ -127,7 +128,7 @@ where let contract_blob_hash = contract_blob_id.hash; let service_blob_hash = service_blob_id.hash; - let bytecode_id = BytecodeId::new(contract_blob_hash, service_blob_hash); + let bytecode_id = BytecodeId::new(contract_blob_hash, service_blob_hash, vm_runtime); let contract = WasmContractModule::new(contract_bytecode, wasm_runtime).await?; // Publish some bytecode. @@ -188,7 +189,6 @@ where let parameters_bytes = serde_json::to_vec(&())?; let create_operation = SystemOperation::CreateApplication { bytecode_id, - vm_runtime, parameters: parameters_bytes.clone(), instantiation_argument: initial_value_bytes.clone(), required_application_ids: vec![], @@ -203,7 +203,6 @@ where }; let application_description = UserApplicationDescription { bytecode_id, - vm_runtime, creation: application_id.creation, required_application_ids: vec![], parameters: parameters_bytes, diff --git a/linera-execution/Cargo.toml b/linera-execution/Cargo.toml index d2d2304f84ee..db9bf54ac104 100644 --- a/linera-execution/Cargo.toml +++ b/linera-execution/Cargo.toml @@ -51,7 +51,6 @@ cfg-if.workspace = true clap.workspace = true custom_debug_derive.workspace = true dashmap.workspace = true -derive_more = { workspace = true, features = ["display"] } dyn-clone.workspace = true futures.workspace = true hex = { workspace = true, optional = true } diff --git a/linera-execution/build.rs b/linera-execution/build.rs index ae9a0a85009b..516295bea701 100644 --- a/linera-execution/build.rs +++ b/linera-execution/build.rs @@ -12,9 +12,6 @@ fn main() { with_revm: { feature = "revm" }, with_wasmer: { feature = "wasmer" }, with_wasmtime: { all(not(target_arch = "wasm32"), feature = "wasmtime") }, - - // If you change this, don't forget to update `WasmRuntime` and - // `WasmRuntime::default_with_sanitizer` with_wasm_runtime: { any(with_wasmer, with_wasmtime) }, } } diff --git a/linera-execution/src/applications.rs b/linera-execution/src/applications.rs index d3bed6a6955b..866bfda0aaf1 100644 --- a/linera-execution/src/applications.rs +++ b/linera-execution/src/applications.rs @@ -16,7 +16,7 @@ use { std::collections::BTreeMap, }; -use crate::{SystemExecutionError, UserApplicationDescription, VmRuntime}; +use crate::{SystemExecutionError, UserApplicationDescription}; #[cfg(test)] #[path = "unit_tests/applications_tests.rs"] @@ -66,7 +66,6 @@ where pub async fn register_new_application( &mut self, application_id: UserApplicationId, - vm_runtime: VmRuntime, parameters: Vec, required_application_ids: Vec, ) -> Result<(), SystemExecutionError> { @@ -82,7 +81,6 @@ where let description = UserApplicationDescription { bytecode_id, parameters, - vm_runtime, creation, required_application_ids, }; diff --git a/linera-execution/src/execution_state_actor.rs b/linera-execution/src/execution_state_actor.rs index 85091a504260..dd511e6cc3f2 100644 --- a/linera-execution/src/execution_state_actor.rs +++ b/linera-execution/src/execution_state_actor.rs @@ -27,7 +27,7 @@ use crate::{ util::RespondExt, BytecodeId, ExecutionError, ExecutionRuntimeContext, ExecutionStateView, RawExecutionOutcome, RawOutgoingMessage, SystemExecutionError, SystemMessage, UserApplicationDescription, - UserApplicationId, UserContractCode, UserServiceCode, VmRuntime, + UserApplicationId, UserContractCode, UserServiceCode, }; #[cfg(with_metrics)] @@ -308,7 +308,6 @@ where CreateApplication { next_message_id, bytecode_id, - vm_runtime, parameters, required_application_ids, callback, @@ -318,7 +317,6 @@ where .create_application( next_message_id, bytecode_id, - vm_runtime, parameters, required_application_ids, ) @@ -513,7 +511,6 @@ pub enum ExecutionRequest { CreateApplication { next_message_id: MessageId, bytecode_id: BytecodeId, - vm_runtime: VmRuntime, parameters: Vec, required_application_ids: Vec, #[debug(skip)] diff --git a/linera-execution/src/lib.rs b/linera-execution/src/lib.rs index 2fe7e844557c..66d5e4a102ef 100644 --- a/linera-execution/src/lib.rs +++ b/linera-execution/src/lib.rs @@ -24,16 +24,17 @@ mod transaction_tracker; mod util; mod wasm; -use std::{any::Any, fmt, str::FromStr, sync::Arc}; +use std::{any::Any, fmt, sync::Arc}; -use async_graphql::{scalar, SimpleObject}; +use async_graphql::SimpleObject; use async_trait::async_trait; use committee::Epoch; use custom_debug_derive::Debug; use dashmap::DashMap; -use derive_more::Display; #[cfg(web)] use js_sys::wasm_bindgen::JsValue; +#[cfg(with_wasm_runtime)] +use linera_base::vm::WasmRuntime; use linera_base::{ abi::Abi, crypto::{BcsHashable, CryptoHash}, @@ -48,10 +49,9 @@ use linera_base::{ }, ownership::ChainOwnership, task, + vm::VmRuntime, }; use linera_views::{batch::Batch, views::ViewError}; -#[cfg(any(with_wasm_runtime, with_revm))] -use linera_witty::{WitLoad, WitType}; use serde::{Deserialize, Serialize}; use system::OpenChainConfig; use thiserror::Error; @@ -746,7 +746,6 @@ pub trait ContractRuntime: BaseRuntime { fn create_application( &mut self, bytecode_id: BytecodeId, - vm_runtime: VmRuntime, parameters: Vec, argument: Vec, required_application_ids: Vec, @@ -1314,176 +1313,28 @@ pub struct BlobState { pub epoch: Epoch, } -/// The runtime to use for running the application. -#[cfg(with_wasm_runtime)] -#[derive( - Clone, - Copy, - Display, - Hash, - PartialEq, - Eq, - Serialize, - Deserialize, - WitType, - WitLoad, - Debug, - Default, -)] -pub enum WasmRuntime { - #[cfg(with_wasmer)] - #[default] - #[display("wasmer")] - Wasmer, - #[cfg(with_wasmtime)] - #[cfg_attr(not(with_wasmer), default)] - #[display("wasmtime")] - Wasmtime, - #[cfg(with_wasmer)] - WasmerWithSanitizer, - #[cfg(with_wasmtime)] - WasmtimeWithSanitizer, -} - -#[cfg(with_wasm_runtime)] -scalar!(WasmRuntime); - -#[cfg(with_revm)] -#[derive( - Clone, - Copy, - Debug, - Display, - Hash, - PartialEq, - Eq, - Serialize, - Deserialize, - Default, - WitType, - WitLoad, -)] -pub enum EvmRuntime { - #[default] - #[display("revm")] - Revm, -} - -#[cfg(with_revm)] -scalar!(EvmRuntime); - -#[derive(Clone, Copy, Display, Hash, PartialEq, Eq, Serialize, Deserialize)] -#[cfg_attr(any(with_wasm_runtime, with_revm), derive(WitType, WitLoad))] -pub enum VmRuntime { - #[cfg(with_wasm_runtime)] - Wasm(WasmRuntime), - #[cfg(with_revm)] - Evm(EvmRuntime), -} - -impl fmt::Debug for VmRuntime { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - #[cfg(with_wasm_runtime)] - VmRuntime::Wasm(wasm_runtime) => write!(f, "{wasm_runtime:?}"), - #[cfg(with_revm)] - VmRuntime::Evm(evm_runtime) => write!(f, "{evm_runtime:?}"), - #[cfg(not(any(with_wasm_runtime, with_revm)))] - _ => write!(f, "No virtual machine selected"), - } - } -} - -#[cfg(any(with_wasm_runtime, with_revm))] -impl Default for VmRuntime { - #[cfg(with_wasm_runtime)] - fn default() -> Self { - VmRuntime::Wasm(WasmRuntime::default()) - } - - #[cfg(all(not(with_wasm_runtime), with_revm))] - fn default() -> Self { - VmRuntime::Evm(EvmRuntime::default()) - } -} - -scalar!(VmRuntime); - -/// Trait used to select a default `WasmRuntime`, if one is available. +/// Trait used to select a default `VmRuntime`, if one is available. pub trait WithVmDefault { fn with_vm_default(self) -> Self; } -#[cfg(with_wasm_runtime)] -impl WasmRuntime { - #[cfg(with_wasm_runtime)] - pub fn default_with_sanitizer() -> Self { - cfg_if::cfg_if! { - if #[cfg(with_wasmer)] { - WasmRuntime::WasmerWithSanitizer - } else if #[cfg(with_wasmtime)] { - WasmRuntime::WasmtimeWithSanitizer - } else { - compile_error!("BUG: Wasm runtime unhandled in `WasmRuntime::default_with_sanitizer`") - } - } - } - - pub fn needs_sanitizer(self) -> bool { - match self { - #[cfg(with_wasmer)] - WasmRuntime::WasmerWithSanitizer => true, - #[cfg(with_wasmtime)] - WasmRuntime::WasmtimeWithSanitizer => true, - #[cfg(with_wasm_runtime)] - _ => false, - } - } -} - impl WithVmDefault for Option { fn with_vm_default(self) -> Self { - let Some(vm_runtime) = self else { - #[cfg(any(with_wasm_runtime, with_revm))] - { - return Some(VmRuntime::default()); - } - #[cfg(not(any(with_wasm_runtime, with_revm)))] - { - return None; + match self { + Some(vm_runtime) => Some(vm_runtime), + None => { + cfg_if::cfg_if! { + if #[cfg(with_wasmer)] { + Some(VmRuntime::Wasm(WasmRuntime::Wasmer)) + } else if #[cfg(with_wasmtime)] { + Some(VmRuntime::Wasm(WasmRuntime::Wasmtime)) + } else if #[cfg(with_revm)] { + Some(VmRuntime::Evm(EvmRuntime::Revm)) + } else { + None + } + } } - }; - Some(vm_runtime) - } -} - -#[cfg(with_wasm_runtime)] -impl FromStr for WasmRuntime { - type Err = InvalidVmRuntime; - - fn from_str(string: &str) -> Result { - match string { - #[cfg(with_wasmer)] - "wasmer" => Ok(WasmRuntime::Wasmer), - #[cfg(with_wasmtime)] - "wasmtime" => Ok(WasmRuntime::Wasmtime), - unknown => Err(InvalidVmRuntime(unknown.to_owned())), - } - } -} - -impl FromStr for VmRuntime { - type Err = InvalidVmRuntime; - - fn from_str(string: &str) -> Result { - match string { - #[cfg(with_wasmer)] - "wasmer" => Ok(VmRuntime::Wasm(WasmRuntime::Wasmer)), - #[cfg(with_wasmtime)] - "wasmtime" => Ok(VmRuntime::Wasm(WasmRuntime::Wasmtime)), - #[cfg(with_revm)] - "revm" => Ok(VmRuntime::Evm(EvmRuntime::Revm)), - unknown => Err(InvalidVmRuntime(unknown.to_owned())), } } } @@ -1495,8 +1346,6 @@ pub struct UserApplicationDescription { pub bytecode_id: BytecodeId, /// The unique ID of the application's creation. pub creation: MessageId, - /// The virtual runtime being used - pub vm_runtime: VmRuntime, /// The parameters of the application. #[serde(with = "serde_bytes")] #[debug(with = "hex_debug")] @@ -1519,11 +1368,6 @@ doc_scalar!( "Description of the necessary information to run a user application" ); -/// Attempts to create an invalid [`VmRuntime`] instance from a string. -#[derive(Clone, Debug, Error)] -#[error("{0:?} is not a valid virtual machine runtime")] -pub struct InvalidVmRuntime(String); - doc_scalar!(Operation, "An operation to be executed in a block"); doc_scalar!( Message, diff --git a/linera-execution/src/revm.rs b/linera-execution/src/revm.rs index c5de22bc3c87..32dc52b842cb 100644 --- a/linera-execution/src/revm.rs +++ b/linera-execution/src/revm.rs @@ -9,7 +9,7 @@ use std::{ }; use alloy::primitives::{Address, B256, U256}; -use linera_base::{data_types::Bytecode, ensure, identifiers::StreamName}; +use linera_base::{data_types::Bytecode, ensure, identifiers::StreamName, vm::EvmRuntime}; use linera_views::common::from_bytes_option; use revm::{ db::AccountState, @@ -30,7 +30,7 @@ use { }; use crate::{ - BaseRuntime, Batch, ContractRuntime, ContractSyncRuntimeHandle, EvmRuntime, ExecutionError, + BaseRuntime, Batch, ContractRuntime, ContractSyncRuntimeHandle, ExecutionError, FinalizeContext, MessageContext, OperationContext, QueryContext, ServiceRuntime, ServiceSyncRuntimeHandle, UserContract, UserContractInstance, UserContractModule, UserService, UserServiceInstance, UserServiceModule, ViewError, diff --git a/linera-execution/src/runtime.rs b/linera-execution/src/runtime.rs index 4301ef0bc960..01e87c751d3f 100644 --- a/linera-execution/src/runtime.rs +++ b/linera-execution/src/runtime.rs @@ -34,7 +34,7 @@ use crate::{ BaseRuntime, BytecodeId, ContractRuntime, ExecutionError, FinalizeContext, MessageContext, Operation, OperationContext, QueryContext, QueryOutcome, RawExecutionOutcome, ServiceRuntime, TransactionTracker, UserApplicationDescription, UserApplicationId, UserContractCode, - UserContractInstance, UserServiceCode, UserServiceInstance, VmRuntime, MAX_EVENT_KEY_LEN, + UserContractInstance, UserServiceCode, UserServiceInstance, MAX_EVENT_KEY_LEN, MAX_STREAM_NAME_LEN, }; @@ -1444,7 +1444,6 @@ impl ContractRuntime for ContractSyncRuntimeHandle { fn create_application( &mut self, bytecode_id: BytecodeId, - vm_runtime: VmRuntime, parameters: Vec, argument: Vec, required_application_ids: Vec, @@ -1469,7 +1468,6 @@ impl ContractRuntime for ContractSyncRuntimeHandle { .send_request(|callback| ExecutionRequest::CreateApplication { next_message_id: message_id, bytecode_id, - vm_runtime, parameters, required_application_ids, callback, diff --git a/linera-execution/src/system.rs b/linera-execution/src/system.rs index ec53dfea3dfb..b9bd65a2761d 100644 --- a/linera-execution/src/system.rs +++ b/linera-execution/src/system.rs @@ -47,7 +47,7 @@ use crate::{ ApplicationRegistryView, ChannelName, ChannelSubscription, Destination, ExecutionRuntimeContext, MessageContext, MessageKind, OperationContext, QueryContext, QueryOutcome, RawExecutionOutcome, RawOutgoingMessage, TransactionTracker, - UserApplicationDescription, UserApplicationId, VmRuntime, + UserApplicationDescription, UserApplicationId, }; /// The relative index of the `OpenChain` message created by the `OpenChain` operation. @@ -175,7 +175,6 @@ pub enum SystemOperation { /// Creates a new application. CreateApplication { bytecode_id: BytecodeId, - vm_runtime: VmRuntime, #[serde(with = "serde_bytes")] #[debug(with = "hex_debug")] parameters: Vec, @@ -643,7 +642,6 @@ where } CreateApplication { bytecode_id, - vm_runtime, parameters, instantiation_argument, required_application_ids, @@ -657,7 +655,6 @@ where .create_application( next_message_id, bytecode_id, - vm_runtime, parameters, required_application_ids, ) @@ -1033,7 +1030,6 @@ where &mut self, next_message_id: MessageId, bytecode_id: BytecodeId, - vm_runtime: VmRuntime, parameters: Vec, required_application_ids: Vec, ) -> Result { @@ -1055,7 +1051,7 @@ where } } self.registry - .register_new_application(id, vm_runtime, parameters, required_application_ids) + .register_new_application(id, parameters, required_application_ids) .await?; // Send a message to ourself to increment the message ID. let message = RawOutgoingMessage { diff --git a/linera-execution/src/test_utils/mod.rs b/linera-execution/src/test_utils/mod.rs index 832473c96e32..ff5b474722c7 100644 --- a/linera-execution/src/test_utils/mod.rs +++ b/linera-execution/src/test_utils/mod.rs @@ -50,8 +50,11 @@ pub fn create_dummy_user_application_description( let vm_runtime = VmRuntime::default(); ( UserApplicationDescription { - bytecode_id: BytecodeId::new(contract_blob.id().hash, service_blob.id().hash), - vm_runtime, + bytecode_id: BytecodeId::new( + contract_blob.id().hash, + service_blob.id().hash, + vm_runtime, + ), creation: MessageId { chain_id, height: BlockHeight(index), diff --git a/linera-execution/src/unit_tests/applications_tests.rs b/linera-execution/src/unit_tests/applications_tests.rs index ad56a3106a50..8e05d1319e04 100644 --- a/linera-execution/src/unit_tests/applications_tests.rs +++ b/linera-execution/src/unit_tests/applications_tests.rs @@ -5,11 +5,11 @@ use linera_base::{ crypto::CryptoHash, data_types::BlockHeight, identifiers::{BytecodeId, ChainId, MessageId}, + vm::VmRuntime, }; use super::{ ApplicationRegistry, ApplicationRegistryView, UserApplicationDescription, UserApplicationId, - VmRuntime, }; fn message_id(index: u32) -> MessageId { @@ -24,6 +24,7 @@ fn bytecode_id() -> BytecodeId { BytecodeId::new( CryptoHash::test_hash("contract"), CryptoHash::test_hash("service"), + VmRuntime::default(), ) } @@ -35,10 +36,8 @@ fn app_id(index: u32) -> UserApplicationId { } fn app_description(index: u32, deps: Vec) -> UserApplicationDescription { - let vm_runtime = VmRuntime::default(); UserApplicationDescription { bytecode_id: bytecode_id(), - vm_runtime, creation: message_id(index), parameters: vec![], required_application_ids: deps.into_iter().map(app_id).collect(), diff --git a/linera-execution/src/unit_tests/runtime_tests.rs b/linera-execution/src/unit_tests/runtime_tests.rs index a675e105bfd1..aded8fe5a257 100644 --- a/linera-execution/src/unit_tests/runtime_tests.rs +++ b/linera-execution/src/unit_tests/runtime_tests.rs @@ -15,6 +15,7 @@ use linera_base::{ crypto::CryptoHash, data_types::{BlockHeight, Timestamp}, identifiers::{ApplicationId, BytecodeId, ChainDescription, MessageId}, + vm::VmRuntime, }; use linera_views::batch::Batch; @@ -210,6 +211,7 @@ fn create_dummy_application_id() -> ApplicationId { bytecode_id: BytecodeId::new( CryptoHash::test_hash("contract"), CryptoHash::test_hash("service"), + VmRuntime::default(), ), creation: MessageId { chain_id, diff --git a/linera-execution/src/unit_tests/system_tests.rs b/linera-execution/src/unit_tests/system_tests.rs index 019d38550d4e..ef2585293a4f 100644 --- a/linera-execution/src/unit_tests/system_tests.rs +++ b/linera-execution/src/unit_tests/system_tests.rs @@ -1,6 +1,8 @@ // Copyright (c) Zefchain Labs, Inc. // SPDX-License-Identifier: Apache-2.0 +#[cfg(with_testing)] +use linera_base::vm::VmRuntime; use linera_base::{ data_types::{Blob, BlockHeight, Bytecode}, identifiers::ApplicationId, @@ -43,12 +45,11 @@ async fn application_message_index() -> anyhow::Result<()> { let service = Bytecode::new(b"service".into()); let contract_blob = Blob::new_contract_bytecode(contract.compress()); let service_blob = Blob::new_service_bytecode(service.compress()); - let bytecode_id = BytecodeId::new(contract_blob.id().hash, service_blob.id().hash); let vm_runtime = VmRuntime::default(); + let bytecode_id = BytecodeId::new(contract_blob.id().hash, service_blob.id().hash, vm_runtime); let operation = SystemOperation::CreateApplication { bytecode_id, - vm_runtime, parameters: vec![], instantiation_argument: vec![], required_application_ids: vec![], diff --git a/linera-execution/src/wasm/mod.rs b/linera-execution/src/wasm/mod.rs index 896b32c33cd7..a6fbd1ba991f 100644 --- a/linera-execution/src/wasm/mod.rs +++ b/linera-execution/src/wasm/mod.rs @@ -20,7 +20,7 @@ mod wasmer; #[cfg(with_wasmtime)] mod wasmtime; -use linera_base::data_types::Bytecode; +use linera_base::{data_types::Bytecode, vm::WasmRuntime}; use thiserror::Error; #[cfg(with_wasmer)] use wasmer::{WasmerContractInstance, WasmerServiceInstance}; @@ -40,7 +40,7 @@ pub use self::{ }; use crate::{ ContractSyncRuntimeHandle, ExecutionError, ServiceSyncRuntimeHandle, UserContractInstance, - UserContractModule, UserServiceInstance, UserServiceModule, WasmRuntime, + UserContractModule, UserServiceInstance, UserServiceModule, }; #[cfg(with_metrics)] @@ -89,13 +89,23 @@ impl WasmContractModule { contract_bytecode }; match runtime { - #[cfg(with_wasmer)] WasmRuntime::Wasmer | WasmRuntime::WasmerWithSanitizer => { - Self::from_wasmer(contract_bytecode).await + cfg_if::cfg_if! { + if #[cfg(with_wasmer)] { + Self::from_wasmer(contract_bytecode).await + } else { + panic!("Cannot use WasmRuntime::Wasmer when feature wasmer has not been used"); + } + } } - #[cfg(with_wasmtime)] WasmRuntime::Wasmtime | WasmRuntime::WasmtimeWithSanitizer => { - Self::from_wasmtime(contract_bytecode).await + cfg_if::cfg_if! { + if #[cfg(with_wasmtime)] { + Self::from_wasmtime(contract_bytecode).await + } else { + panic!("Cannot use WasmRuntime::Wasmtime when feature wasmtime has not been used"); + } + } } } } @@ -156,13 +166,23 @@ impl WasmServiceModule { runtime: WasmRuntime, ) -> Result { match runtime { - #[cfg(with_wasmer)] WasmRuntime::Wasmer | WasmRuntime::WasmerWithSanitizer => { - Self::from_wasmer(service_bytecode).await + cfg_if::cfg_if! { + if #[cfg(with_wasmer)] { + Self::from_wasmer(service_bytecode).await + } else { + panic!("Cannot use WasmRuntime::Wasmer when feature wasmer has not been used"); + } + } } - #[cfg(with_wasmtime)] WasmRuntime::Wasmtime | WasmRuntime::WasmtimeWithSanitizer => { - Self::from_wasmtime(service_bytecode).await + cfg_if::cfg_if! { + if #[cfg(with_wasmtime)] { + Self::from_wasmtime(service_bytecode).await + } else { + panic!("Cannot use WasmRuntime::Wasmtime when feature wasmtime has not been used"); + } + } } } } @@ -346,7 +366,18 @@ pub mod test { wasm_runtime: impl Into>, ) -> Result<(WasmContractModule, WasmServiceModule), anyhow::Error> { let (contract_path, service_path) = get_example_bytecode_paths(name)?; - let wasm_runtime = wasm_runtime.into().unwrap_or_default(); + let wasm_runtime = match wasm_runtime.into() { + Some(wasm_runtime) => wasm_runtime, + None => { + cfg_if::cfg_if! { + if #[cfg(with_wasmer)] { + WasmRuntime::Wasmer + } else { + WasmRuntime::Wasmtime + } + } + } + }; let contract = WasmContractModule::from_file(&contract_path, wasm_runtime).await?; let service = WasmServiceModule::from_file(&service_path, wasm_runtime).await?; Ok((contract, service)) diff --git a/linera-execution/src/wasm/system_api.rs b/linera-execution/src/wasm/system_api.rs index ceaaa94902ba..203d39ad4e2c 100644 --- a/linera-execution/src/wasm/system_api.rs +++ b/linera-execution/src/wasm/system_api.rs @@ -19,7 +19,7 @@ use tracing::log; use super::WasmExecutionError; use crate::{ BaseRuntime, BytecodeId, ContractRuntime, ContractSyncRuntimeHandle, ExecutionError, - ServiceRuntime, ServiceSyncRuntimeHandle, VmRuntime, + ServiceRuntime, ServiceSyncRuntimeHandle, }; /// Common host data used as the `UserData` of the system API implementations. @@ -326,7 +326,6 @@ where fn create_application( caller: &mut Caller, bytecode_id: BytecodeId, - vm_runtime: VmRuntime, parameters: Vec, argument: Vec, required_application_ids: Vec, @@ -334,13 +333,7 @@ where caller .user_data_mut() .runtime - .create_application( - bytecode_id, - vm_runtime, - parameters, - argument, - required_application_ids, - ) + .create_application(bytecode_id, parameters, argument, required_application_ids) .map_err(|error| RuntimeError::Custom(error.into())) } diff --git a/linera-execution/tests/contract_runtime_apis.rs b/linera-execution/tests/contract_runtime_apis.rs index 0fbe6ae0d445..d69c603df6c0 100644 --- a/linera-execution/tests/contract_runtime_apis.rs +++ b/linera-execution/tests/contract_runtime_apis.rs @@ -18,6 +18,7 @@ use linera_base::{ Owner, }, ownership::ChainOwnership, + vm::VmRuntime, }; use linera_execution::{ test_utils::{ @@ -27,7 +28,7 @@ use linera_execution::{ BaseRuntime, ContractRuntime, ExecutionError, ExecutionOutcome, Message, MessageContext, Operation, OperationContext, ResourceController, SystemExecutionError, SystemExecutionStateView, TestExecutionRuntimeContext, TransactionOutcome, TransactionTracker, - UserApplicationDescription, VmRuntime, + UserApplicationDescription, }; use linera_views::context::MemoryContext; use test_case::test_matrix; @@ -660,8 +661,7 @@ impl TransferTestEndpoint { let vm_runtime = VmRuntime::default(); UserApplicationDescription { - bytecode_id: BytecodeId::new(contract_id, service_id), - vm_runtime, + bytecode_id: BytecodeId::new(contract_id, service_id, vm_runtime), creation: MessageId { chain_id: ChainId::root(1000), height: BlockHeight(0), @@ -699,6 +699,7 @@ impl TransferTestEndpoint { bytecode_id: BytecodeId::new( CryptoHash::test_hash("recipient contract bytecode"), CryptoHash::test_hash("recipient service bytecode"), + VmRuntime::default(), ), creation: MessageId { chain_id: ChainId::root(2000), diff --git a/linera-execution/tests/wasm.rs b/linera-execution/tests/wasm.rs index b85b8a8383c7..1536eb14969b 100644 --- a/linera-execution/tests/wasm.rs +++ b/linera-execution/tests/wasm.rs @@ -8,13 +8,13 @@ use std::sync::Arc; use linera_base::{ data_types::{Amount, BlockHeight, Timestamp}, identifiers::{Account, ChainDescription, ChainId}, + vm::WasmRuntime, }; use linera_execution::{ test_utils::{create_dummy_user_application_description, SystemExecutionState}, ExecutionOutcome, ExecutionRuntimeConfig, ExecutionRuntimeContext, Operation, OperationContext, Query, QueryContext, QueryOutcome, QueryResponse, RawExecutionOutcome, ResourceControlPolicy, - ResourceController, ResourceTracker, TransactionTracker, WasmContractModule, WasmRuntime, - WasmServiceModule, + ResourceController, ResourceTracker, TransactionTracker, WasmContractModule, WasmServiceModule, }; use linera_views::{context::Context as _, views::View}; use serde_json::json; diff --git a/linera-sdk/src/contract/conversions_from_wit.rs b/linera-sdk/src/contract/conversions_from_wit.rs index 86013f146440..94e8ca6f6447 100644 --- a/linera-sdk/src/contract/conversions_from_wit.rs +++ b/linera-sdk/src/contract/conversions_from_wit.rs @@ -11,6 +11,7 @@ use linera_base::{ ownership::{ ChainOwnership, ChangeApplicationPermissionsError, CloseChainError, TimeoutConfig, }, + vm::{EvmRuntime, VmRuntime, WasmRuntime}, }; use super::wit::contract_system_api as wit_system_api; @@ -45,10 +46,27 @@ impl From for BytecodeId { BytecodeId::new( bytecode_id.contract_blob_hash.into(), bytecode_id.service_blob_hash.into(), + bytecode_id.vm_runtime.into(), ) } } +impl From for VmRuntime { + fn from(vm_runtime: wit_system_api::VmRuntime) -> Self { + match vm_runtime { + wit_system_api::VmRuntime::Wasmer => VmRuntime::Wasm(WasmRuntime::Wasmer), + wit_system_api::VmRuntime::Wasmtime => VmRuntime::Wasm(WasmRuntime::Wasmtime), + wit_system_api::VmRuntime::Wasmerwithsanitizer => { + VmRuntime::Wasm(WasmRuntime::WasmerWithSanitizer) + } + wit_system_api::VmRuntime::Wasmtimewithsanitizer => { + VmRuntime::Wasm(WasmRuntime::WasmtimeWithSanitizer) + } + wit_system_api::VmRuntime::Revm => VmRuntime::Evm(EvmRuntime::Revm), + } + } +} + impl From for ChainId { fn from(chain_id: wit_system_api::ChainId) -> Self { ChainId(chain_id.inner0.into()) diff --git a/linera-sdk/src/contract/conversions_to_wit.rs b/linera-sdk/src/contract/conversions_to_wit.rs index e65c376c09f2..363731980a77 100644 --- a/linera-sdk/src/contract/conversions_to_wit.rs +++ b/linera-sdk/src/contract/conversions_to_wit.rs @@ -15,6 +15,7 @@ use linera_base::{ MessageId, Owner, StreamName, }, ownership::{ChainOwnership, TimeoutConfig}, + vm::{VmRuntime, WasmRuntime}, }; use super::wit::contract_system_api as wit_system_api; @@ -104,6 +105,23 @@ impl From for wit_system_api::BytecodeId { wit_system_api::BytecodeId { contract_blob_hash: bytecode_id.contract_blob_hash.into(), service_blob_hash: bytecode_id.service_blob_hash.into(), + vm_runtime: bytecode_id.vm_runtime.into(), + } + } +} + +impl From for wit_system_api::VmRuntime { + fn from(vm_runtime: VmRuntime) -> Self { + match vm_runtime { + VmRuntime::Wasm(wasm_runtime) => match wasm_runtime { + WasmRuntime::Wasmer => wit_system_api::VmRuntime::Wasmer, + WasmRuntime::Wasmtime => wit_system_api::VmRuntime::Wasmtime, + WasmRuntime::WasmerWithSanitizer => wit_system_api::VmRuntime::Wasmerwithsanitizer, + WasmRuntime::WasmtimeWithSanitizer => { + wit_system_api::VmRuntime::Wasmtimewithsanitizer + } + }, + VmRuntime::Evm(_) => wit_system_api::VmRuntime::Revm, } } } diff --git a/linera-sdk/src/service/conversions_from_wit.rs b/linera-sdk/src/service/conversions_from_wit.rs index 889dad655ce8..4310529e788c 100644 --- a/linera-sdk/src/service/conversions_from_wit.rs +++ b/linera-sdk/src/service/conversions_from_wit.rs @@ -8,6 +8,7 @@ use linera_base::{ data_types::{Amount, BlockHeight, Timestamp}, http, identifiers::{AccountOwner, ApplicationId, BytecodeId, ChainId, MessageId, Owner}, + vm::{EvmRuntime, VmRuntime, WasmRuntime}, }; use super::wit::service_system_api as wit_system_api; @@ -90,10 +91,27 @@ impl From for BytecodeId { BytecodeId::new( bytecode_id.contract_blob_hash.into(), bytecode_id.service_blob_hash.into(), + bytecode_id.vm_runtime.into(), ) } } +impl From for VmRuntime { + fn from(vm_runtime: wit_system_api::VmRuntime) -> Self { + match vm_runtime { + wit_system_api::VmRuntime::Wasmer => VmRuntime::Wasm(WasmRuntime::Wasmer), + wit_system_api::VmRuntime::Wasmtime => VmRuntime::Wasm(WasmRuntime::Wasmtime), + wit_system_api::VmRuntime::Wasmerwithsanitizer => { + VmRuntime::Wasm(WasmRuntime::WasmerWithSanitizer) + } + wit_system_api::VmRuntime::Wasmtimewithsanitizer => { + VmRuntime::Wasm(WasmRuntime::WasmtimeWithSanitizer) + } + wit_system_api::VmRuntime::Revm => VmRuntime::Evm(EvmRuntime::Revm), + } + } +} + impl From for Timestamp { fn from(timestamp: wit_system_api::Timestamp) -> Self { Timestamp::from(timestamp.inner0) diff --git a/linera-sdk/src/service/conversions_to_wit.rs b/linera-sdk/src/service/conversions_to_wit.rs index 8bd32686f626..fbe5e60d7ba9 100644 --- a/linera-sdk/src/service/conversions_to_wit.rs +++ b/linera-sdk/src/service/conversions_to_wit.rs @@ -8,6 +8,7 @@ use linera_base::{ data_types::BlockHeight, http, identifiers::{AccountOwner, ApplicationId, BytecodeId, ChainId, MessageId, Owner}, + vm::{VmRuntime, WasmRuntime}, }; use super::wit::service_system_api as wit_system_api; @@ -86,6 +87,23 @@ impl From for wit_system_api::BytecodeId { wit_system_api::BytecodeId { contract_blob_hash: bytecode_id.contract_blob_hash.into(), service_blob_hash: bytecode_id.service_blob_hash.into(), + vm_runtime: bytecode_id.vm_runtime.into(), + } + } +} + +impl From for wit_system_api::VmRuntime { + fn from(vm_runtime: VmRuntime) -> Self { + match vm_runtime { + VmRuntime::Wasm(wasm_runtime) => match wasm_runtime { + WasmRuntime::Wasmer => wit_system_api::VmRuntime::Wasmer, + WasmRuntime::Wasmtime => wit_system_api::VmRuntime::Wasmtime, + WasmRuntime::WasmerWithSanitizer => wit_system_api::VmRuntime::Wasmerwithsanitizer, + WasmRuntime::WasmtimeWithSanitizer => { + wit_system_api::VmRuntime::Wasmtimewithsanitizer + } + }, + VmRuntime::Evm(_) => wit_system_api::VmRuntime::Revm, } } } diff --git a/linera-sdk/src/test/chain.rs b/linera-sdk/src/test/chain.rs index 93503f9a6309..fdf4e8312f77 100644 --- a/linera-sdk/src/test/chain.rs +++ b/linera-sdk/src/test/chain.rs @@ -16,12 +16,13 @@ use linera_base::{ crypto::{AccountPublicKey, AccountSecretKey}, data_types::{Blob, BlockHeight, Bytecode, CompressedBytecode}, identifiers::{ApplicationId, BytecodeId, ChainDescription, ChainId, MessageId}, + vm::VmRuntime, }; use linera_chain::{types::ConfirmedBlockCertificate, ChainError, ChainExecutionContext}; use linera_core::{data_types::ChainInfoQuery, worker::WorkerError}; use linera_execution::{ system::{SystemExecutionError, SystemOperation, CREATE_APPLICATION_MESSAGE_INDEX}, - ExecutionError, Query, QueryOutcome, QueryResponse, VmRuntime, + ExecutionError, Query, QueryOutcome, QueryResponse, }; use linera_storage::Storage as _; use serde::Serialize; @@ -214,8 +215,9 @@ impl ActiveChain { let service_blob = Blob::new_service_bytecode(service); let contract_blob_hash = contract_blob.id().hash; let service_blob_hash = service_blob.id().hash; + let vm_runtime = VmRuntime::default(); - let bytecode_id = BytecodeId::new(contract_blob_hash, service_blob_hash); + let bytecode_id = BytecodeId::new(contract_blob_hash, service_blob_hash, vm_runtime); let certificate = self .add_block_with_blobs( @@ -353,7 +355,6 @@ impl ActiveChain { pub async fn create_application( &mut self, bytecode_id: BytecodeId, - vm_runtime: VmRuntime, parameters: Parameters, instantiation_argument: InstantiationArgument, required_application_ids: Vec, @@ -374,7 +375,6 @@ impl ActiveChain { .add_block(|block| { block.with_system_operation(SystemOperation::CreateApplication { bytecode_id: bytecode_id.forget_abi(), - vm_runtime, parameters, instantiation_argument, required_application_ids, diff --git a/linera-sdk/src/test/validator.rs b/linera-sdk/src/test/validator.rs index 915469270d9c..b067462b4b27 100644 --- a/linera-sdk/src/test/validator.rs +++ b/linera-sdk/src/test/validator.rs @@ -20,7 +20,6 @@ use linera_core::worker::WorkerState; use linera_execution::{ committee::{Committee, Epoch}, system::{OpenChainConfig, SystemOperation, OPEN_CHAIN_MESSAGE_INDEX}, - VmRuntime, }; use linera_storage::{DbStorage, Storage, TestClock}; use linera_views::memory::MemoryStore; @@ -118,7 +117,6 @@ impl TestValidator { /// Returns the new [`TestValidator`], the [`ApplicationId`] of the created application, and /// the chain on which it was created. pub async fn with_current_application( - vm_runtime: VmRuntime, parameters: Parameters, instantiation_argument: InstantiationArgument, ) -> (TestValidator, ApplicationId, ActiveChain) @@ -133,13 +131,7 @@ impl TestValidator { let mut creator = validator.new_chain().await; let application_id = creator - .create_application( - bytecode_id, - vm_runtime, - parameters, - instantiation_argument, - vec![], - ) + .create_application(bytecode_id, parameters, instantiation_argument, vec![]) .await; (validator, application_id, creator) diff --git a/linera-sdk/wit/contract-system-api.wit b/linera-sdk/wit/contract-system-api.wit index 6d7c89ec6c89..74b98c98dc27 100644 --- a/linera-sdk/wit/contract-system-api.wit +++ b/linera-sdk/wit/contract-system-api.wit @@ -67,6 +67,15 @@ interface contract-system-api { record bytecode-id { contract-blob-hash: crypto-hash, service-blob-hash: crypto-hash, + vm-runtime: vm-runtime, + } + + enum vm-runtime { + wasmer, + wasmtime, + wasmerwithsanitizer, + wasmtimewithsanitizer, + revm, } record chain-id { diff --git a/linera-sdk/wit/service-system-api.wit b/linera-sdk/wit/service-system-api.wit index 18bee9ea510b..90f0c4dd7d46 100644 --- a/linera-sdk/wit/service-system-api.wit +++ b/linera-sdk/wit/service-system-api.wit @@ -41,6 +41,15 @@ interface service-system-api { record bytecode-id { contract-blob-hash: crypto-hash, service-blob-hash: crypto-hash, + vm-runtime: vm-runtime, + } + + enum vm-runtime { + wasmer, + wasmtime, + wasmerwithsanitizer, + wasmtimewithsanitizer, + revm, } record chain-id { diff --git a/linera-service/src/linera/main.rs b/linera-service/src/linera/main.rs index 6d3c12e44e86..b390cffc21c6 100644 --- a/linera-service/src/linera/main.rs +++ b/linera-service/src/linera/main.rs @@ -890,14 +890,18 @@ impl Runnable for Job { PublishBytecode { contract, service, + vm_runtime, publisher, } => { let start_time = Instant::now(); let publisher = publisher.unwrap_or_else(|| context.default_chain()); info!("Publishing bytecode on chain {}", publisher); let chain_client = context.make_chain_client(publisher)?; + let vm_runtime = vm_runtime + .with_vm_default() + .expect("A virtual machine to be available"); let bytecode_id = context - .publish_bytecode(&chain_client, contract, service) + .publish_bytecode(&chain_client, contract, service, vm_runtime) .await?; println!("{}", bytecode_id); info!( @@ -934,7 +938,6 @@ impl Runnable for Job { CreateApplication { bytecode_id, - vm_runtime, creator, json_parameters, json_parameters_path, @@ -949,9 +952,6 @@ impl Runnable for Job { let parameters = read_json(json_parameters, json_parameters_path)?; let argument = read_json(json_argument, json_argument_path)?; - let vm_runtime = vm_runtime - .with_vm_default() - .expect("A virtual machine to be available"); info!("Synchronizing"); let chain_client = chain_client; context.process_inbox(&chain_client).await?; @@ -966,7 +966,6 @@ impl Runnable for Job { chain_client .create_application_untyped( bytecode_id, - vm_runtime, parameters, argument, required_application_ids.unwrap_or_default(), @@ -1006,7 +1005,7 @@ impl Runnable for Job { .expect("A virtual machine should be available"); let bytecode_id = context - .publish_bytecode(&chain_client, contract, service) + .publish_bytecode(&chain_client, contract, service, vm_runtime) .await?; let (application_id, _) = context @@ -1019,7 +1018,6 @@ impl Runnable for Job { chain_client .create_application_untyped( bytecode_id, - vm_runtime, parameters, argument, required_application_ids.unwrap_or_default(), @@ -1110,7 +1108,7 @@ impl Runnable for Job { let (contract_path, service_path) = project.build(name)?; let bytecode_id = context - .publish_bytecode(&chain_client, contract_path, service_path) + .publish_bytecode(&chain_client, contract_path, service_path, vm_runtime) .await?; let (application_id, _) = context @@ -1123,7 +1121,6 @@ impl Runnable for Job { chain_client .create_application_untyped( bytecode_id, - vm_runtime, parameters, argument, required_application_ids.unwrap_or_default(), diff --git a/linera-service/src/node_service.rs b/linera-service/src/node_service.rs index 2f278bb0a39f..d12fcf2ed8a1 100644 --- a/linera-service/src/node_service.rs +++ b/linera-service/src/node_service.rs @@ -20,6 +20,7 @@ use linera_base::{ hashed::Hashed, identifiers::{ApplicationId, BytecodeId, ChainId, Owner, UserApplicationId}, ownership::{ChainOwnership, TimeoutConfig}, + vm::VmRuntime, BcsHexParseError, }; use linera_chain::{ @@ -36,7 +37,6 @@ use linera_execution::{ committee::{Committee, Epoch}, system::{AdminOperation, Recipient, SystemChannel}, Operation, Query, QueryOutcome, QueryResponse, SystemOperation, UserApplicationDescription, - VmRuntime, }; use linera_sdk::base::BlobContent; use linera_storage::Storage; @@ -564,13 +564,14 @@ where chain_id: ChainId, contract: Bytecode, service: Bytecode, + vm_runtime: VmRuntime, ) -> Result { self.apply_client_command(&chain_id, move |client| { let contract = contract.clone(); let service = service.clone(); async move { let result = client - .publish_bytecode(contract, service) + .publish_bytecode(contract, service, vm_runtime) .await .map_err(Error::from) .map(|outcome| outcome.map(|(bytecode_id, _)| bytecode_id)); @@ -603,7 +604,6 @@ where &self, chain_id: ChainId, bytecode_id: BytecodeId, - vm_runtime: VmRuntime, parameters: String, instantiation_argument: String, required_application_ids: Vec, @@ -616,7 +616,6 @@ where let result = client .create_application_untyped( bytecode_id, - vm_runtime, parameters, instantiation_argument, required_application_ids, diff --git a/linera-storage/Cargo.toml b/linera-storage/Cargo.toml index eba1aa75338d..df798bed59d2 100644 --- a/linera-storage/Cargo.toml +++ b/linera-storage/Cargo.toml @@ -32,6 +32,7 @@ web = [ [dependencies] async-trait.workspace = true bcs.workspace = true +cfg-if.workspace = true dashmap.workspace = true futures.workspace = true linera-base.workspace = true diff --git a/linera-storage/src/lib.rs b/linera-storage/src/lib.rs index 13b0fb53d1a1..ef07060fb93d 100644 --- a/linera-storage/src/lib.rs +++ b/linera-storage/src/lib.rs @@ -13,10 +13,11 @@ use async_trait::async_trait; use dashmap::{mapref::entry::Entry, DashMap}; use linera_base::{ crypto::CryptoHash, - data_types::{Amount, Blob, BlockHeight, TimeDelta, Timestamp}, + data_types::{Amount, Blob, BlockHeight, CompressedBytecode, TimeDelta, Timestamp}, hashed::Hashed, - identifiers::{BlobId, ChainDescription, ChainId, EventId, Owner, UserApplicationId}, + identifiers::{BlobId, BlobType, ChainDescription, ChainId, EventId, Owner, UserApplicationId}, ownership::ChainOwnership, + vm::VmRuntime, }; use linera_chain::{ types::{ConfirmedBlock, ConfirmedBlockCertificate}, @@ -24,23 +25,18 @@ use linera_chain::{ }; #[cfg(with_revm)] use linera_execution::revm::{EvmContractModule, EvmServiceModule}; -#[cfg(any(with_wasm_runtime, with_revm))] -use linera_execution::VmRuntime; use linera_execution::{ committee::{Committee, Epoch}, system::SystemChannel, BlobState, ChannelSubscription, ExecutionError, ExecutionRuntimeConfig, ExecutionRuntimeContext, UserApplicationDescription, UserContractCode, UserServiceCode, }; +#[cfg(with_wasm_runtime)] +use linera_execution::{WasmContractModule, WasmServiceModule}; use linera_views::{ context::Context, views::{CryptoHashView, RootView, ViewError}, }; -#[cfg(with_wasm_runtime)] -use { - linera_base::{data_types::CompressedBytecode, identifiers::BlobType}, - linera_execution::{WasmContractModule, WasmServiceModule}, -}; #[cfg(with_testing)] pub use crate::db_storage::TestClock; @@ -263,7 +259,6 @@ pub trait Storage: Sized { /// Creates a [`UserContractCode`] instance using the bytecode in storage referenced /// by the `application_description`. - #[cfg(any(with_wasm_runtime, with_revm))] async fn load_contract( &self, application_description: &UserApplicationDescription, @@ -276,44 +271,49 @@ pub trait Storage: Sized { let compressed_contract_bytecode = CompressedBytecode { compressed_bytes: contract_blob.into_bytes().to_vec(), }; - let contract_bytecode = + let _contract_bytecode = linera_base::task::Blocking::::spawn( move |_| async move { compressed_contract_bytecode.decompress() }, ) .await .join() .await?; - match application_description.vm_runtime { - VmRuntime::Wasm(wasm_runtime) => { - Ok(WasmContractModule::new(contract_bytecode, wasm_runtime) - .await? - .into()) + match application_description.bytecode_id.vm_runtime { + VmRuntime::Wasm(_wasm_runtime) => { + cfg_if::cfg_if! { + if #[cfg(with_wasm_runtime)] { + Ok(WasmContractModule::new(_contract_bytecode, _wasm_runtime) + .await? + .into()) + } else { + panic!( + "A Wasm runtime is required to load user applications. \ + Please enable the `wasmer` or the `wasmtime` feature flags \ + when compiling `linera-storage`." + ); + } + } } - #[cfg(with_revm)] - VmRuntime::Evm(evm_runtime) => { - Ok(EvmContractModule::new(contract_bytecode, evm_runtime) - .await? - .into()) + VmRuntime::Evm(_evm_runtime) => { + cfg_if::cfg_if! { + if #[cfg(with_revm)] { + Ok(EvmContractModule::new(_contract_bytecode, _evm_runtime) + .await? + .into()) + } else { + panic!( + "An Evm runtime is required to load user applications. \ + Please enable the `revm` feature flags \ + when compiling `linera-storage`." + ); + } + } } } } - #[cfg(not(any(with_wasm_runtime, with_revm)))] - #[allow(clippy::diverging_sub_expression)] - async fn load_contract( - &self, - _application_description: &UserApplicationDescription, - ) -> Result { - panic!( - "A Wasm runtime is required to load user applications. \ - Please enable the `wasmer` or the `wasmtime` feature flags \ - when compiling `linera-storage`." - ); - } - /// Creates a [`linera-sdk::UserContract`] instance using the bytecode in storage referenced /// by the `application_description`. - #[cfg(any(with_wasm_runtime, with_revm))] async fn load_service( &self, application_description: &UserApplicationDescription, @@ -326,37 +326,46 @@ pub trait Storage: Sized { let compressed_service_bytecode = CompressedBytecode { compressed_bytes: service_blob.into_bytes().to_vec(), }; - let service_bytecode = linera_base::task::Blocking::::spawn( - move |_| async move { compressed_service_bytecode.decompress() }, - ) - .await - .join() - .await?; - match application_description.vm_runtime { - VmRuntime::Wasm(wasm_runtime) => { - Ok(WasmServiceModule::new(service_bytecode, wasm_runtime) - .await? - .into()) + let _service_bytecode = + linera_base::task::Blocking::::spawn( + move |_| async move { compressed_service_bytecode.decompress() }, + ) + .await + .join() + .await?; + match application_description.bytecode_id.vm_runtime { + VmRuntime::Wasm(_wasm_runtime) => { + cfg_if::cfg_if! { + if #[cfg(with_wasm_runtime)] { + Ok(WasmServiceModule::new(_service_bytecode, _wasm_runtime) + .await? + .into()) + } else { + panic!( + "A Wasm runtime is required to load user applications. \ + Please enable the `wasmer` or the `wasmtime` feature flags \ + when compiling `linera-storage`." + ); + } + } + } + VmRuntime::Evm(_evm_runtime) => { + cfg_if::cfg_if! { + if #[cfg(with_revm)] { + Ok(EvmServiceModule::new(_service_bytecode, _evm_runtime) + .await? + .into()) + } else { + panic!( + "An Evm runtime is required to load user applications. \ + Please enable the `revm` feature flags \ + when compiling `linera-storage`." + ); + } + } } - #[cfg(with_revm)] - VmRuntime::Evm(evm_runtime) => Ok(EvmServiceModule::new(service_bytecode, evm_runtime) - .await? - .into()), } } - - #[cfg(not(any(with_wasm_runtime, with_revm)))] - #[allow(clippy::diverging_sub_expression)] - async fn load_service( - &self, - _application_description: &UserApplicationDescription, - ) -> Result { - panic!( - "A Wasm runtime is required to load user applications. \ - Please enable the `wasmer` or the `wasmtime` feature flags \ - when compiling `linera-storage`." - ); - } } #[derive(Clone)] From a931341c82269881f7ad2b8b9b327ee2cfd3bf4d Mon Sep 17 00:00:00 2001 From: Mathieu Dutour Sikiric Date: Sat, 22 Feb 2025 08:41:21 +0100 Subject: [PATCH 05/16] Some corrections from the CI. --- CLI.md | 7 +++++-- examples/Cargo.lock | 3 ++- linera-core/src/client/mod.rs | 5 ++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/CLI.md b/CLI.md index 03f828fb6fc6..cdc306d2b8d1 100644 --- a/CLI.md +++ b/CLI.md @@ -601,7 +601,7 @@ Run a GraphQL service that exposes a faucet where users can claim tokens. This g Publish bytecode -**Usage:** `linera publish-bytecode [PUBLISHER]` +**Usage:** `linera publish-bytecode [OPTIONS] [PUBLISHER]` ###### **Arguments:** @@ -609,6 +609,10 @@ Publish bytecode * `` — Path to the Wasm file for the application "service" bytecode * `` — An optional chain ID to publish the bytecode. The default chain of the wallet is used otherwise +###### **Options:** + +* `--vm-runtime ` — The virtual machine runtime to use + ## `linera publish-data-blob` @@ -650,7 +654,6 @@ Create an application ###### **Options:** -* `--vm-runtime ` — The virtual machine runtime to use * `--json-parameters ` — The shared parameters as JSON string * `--json-parameters-path ` — Path to a JSON file containing the shared parameters * `--json-argument ` — The instantiation argument as a JSON string diff --git a/examples/Cargo.lock b/examples/Cargo.lock index e2754b3e7d45..6e0e56ccda8f 100644 --- a/examples/Cargo.lock +++ b/examples/Cargo.lock @@ -3503,6 +3503,7 @@ dependencies = [ "cfg_aliases", "chrono", "custom_debug_derive", + "derive_more", "ed25519-dalek", "futures", "hex", @@ -3620,7 +3621,6 @@ dependencies = [ "clap", "custom_debug_derive", "dashmap 5.5.3", - "derive_more", "dyn-clone", "futures", "linera-base", @@ -3691,6 +3691,7 @@ version = "0.14.0" dependencies = [ "async-trait", "bcs", + "cfg-if", "cfg_aliases", "dashmap 5.5.3", "futures", diff --git a/linera-core/src/client/mod.rs b/linera-core/src/client/mod.rs index dbd4deee8712..90e7e0598071 100644 --- a/linera-core/src/client/mod.rs +++ b/linera-core/src/client/mod.rs @@ -22,8 +22,6 @@ use futures::{ future::{self, try_join_all, Either, FusedFuture, Future}, stream::{self, AbortHandle, FusedStream, FuturesUnordered, StreamExt}, }; -#[cfg(not(target_arch = "wasm32"))] -use linera_base::data_types::Bytecode; #[cfg(with_metrics)] use linera_base::prometheus_util::MeasureLatency as _; use linera_base::{ @@ -39,8 +37,9 @@ use linera_base::{ Owner, UserApplicationId, }, ownership::{ChainOwnership, TimeoutConfig}, - vm::VmRuntime, }; +#[cfg(not(target_arch = "wasm32"))] +use linera_base::{data_types::Bytecode, vm::VmRuntime}; use linera_chain::{ data_types::{ BlockProposal, ChainAndHeight, ExecutedBlock, IncomingBundle, LiteVote, MessageAction, From 9ac4250deb303f47ba7cb39411c1211a4a58906c Mon Sep 17 00:00:00 2001 From: Mathieu Dutour Sikiric Date: Sat, 22 Feb 2025 08:49:13 +0100 Subject: [PATCH 06/16] Two corrections from the CI. --- linera-client/src/client_context.rs | 2 +- linera-service-graphql-client/gql/service_schema.graphql | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/linera-client/src/client_context.rs b/linera-client/src/client_context.rs index 4fb86966435e..74c893d0a97a 100644 --- a/linera-client/src/client_context.rs +++ b/linera-client/src/client_context.rs @@ -13,7 +13,6 @@ use linera_base::{ identifiers::{Account, ChainId}, ownership::ChainOwnership, time::{Duration, Instant}, - vm::VmRuntime, }; use linera_chain::types::ConfirmedBlockCertificate; use linera_core::{ @@ -57,6 +56,7 @@ use { linera_base::{ data_types::{BlobContent, Bytecode}, identifiers::BytecodeId, + vm::VmRuntime, }, linera_core::client::create_bytecode_blobs, std::{fs, path::PathBuf}, diff --git a/linera-service-graphql-client/gql/service_schema.graphql b/linera-service-graphql-client/gql/service_schema.graphql index 0299a3f7fb38..b3fa442eb4cd 100644 --- a/linera-service-graphql-client/gql/service_schema.graphql +++ b/linera-service-graphql-client/gql/service_schema.graphql @@ -822,7 +822,7 @@ type MutationRoot { """ Publishes a new application bytecode. """ - publishBytecode(chainId: ChainId!, contract: Bytecode!, service: Bytecode!): BytecodeId! + publishBytecode(chainId: ChainId!, contract: Bytecode!, service: Bytecode!, vmRuntime: VmRuntime!): BytecodeId! """ Publishes a new data blob. """ @@ -830,7 +830,7 @@ type MutationRoot { """ Creates a new application. """ - createApplication(chainId: ChainId!, bytecodeId: BytecodeId!, vmRuntime: VmRuntime!, parameters: String!, instantiationArgument: String!, requiredApplicationIds: [ApplicationId!]!): ApplicationId! + createApplication(chainId: ChainId!, bytecodeId: BytecodeId!, parameters: String!, instantiationArgument: String!, requiredApplicationIds: [ApplicationId!]!): ApplicationId! """ Requests a `RegisterApplications` message from another chain so the application can be used on this one. From fadb489fc3c85535bdf45994664110cdb448a31e Mon Sep 17 00:00:00 2001 From: Mathieu Dutour Sikiric Date: Sat, 22 Feb 2025 09:33:30 +0100 Subject: [PATCH 07/16] Further corrections based on CI. --- linera-core/Cargo.toml | 4 ++-- linera-execution/Cargo.toml | 3 +++ linera-execution/src/lib.rs | 2 ++ linera-sdk/Cargo.toml | 2 ++ 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/linera-core/Cargo.toml b/linera-core/Cargo.toml index 79495233c0c8..65002eaadc38 100644 --- a/linera-core/Cargo.toml +++ b/linera-core/Cargo.toml @@ -12,8 +12,8 @@ repository.workspace = true version.workspace = true [features] -wasmer = ["linera-execution/wasmer", "linera-storage/wasmer"] -wasmtime = ["linera-execution/wasmtime", "linera-storage/wasmtime"] +wasmer = ["linera-execution/wasmer", "linera-storage/wasmer", "linera-base/wasmer"] +wasmtime = ["linera-execution/wasmtime", "linera-storage/wasmtime", "linera-base/wasmtime"] test = [ "anyhow", "linera-base/test", diff --git a/linera-execution/Cargo.toml b/linera-execution/Cargo.toml index db9bf54ac104..78ba5552f8c6 100644 --- a/linera-execution/Cargo.toml +++ b/linera-execution/Cargo.toml @@ -20,6 +20,7 @@ revm = [ "dep:alloy-sol-types", "dep:hex", "dep:tempfile", + "linera-base/revm", ] fs = ["tokio/fs"] metrics = ["prometheus", "linera-views/metrics"] @@ -28,6 +29,7 @@ wasmer = [ "dep:wasmer", "wasmer/enable-serde", "linera-witty/wasmer", + "linera-base/wasmer", "wasm-encoder", "wasm-instrument", "wasmparser", @@ -35,6 +37,7 @@ wasmer = [ wasmtime = [ "dep:wasmtime", "linera-witty/wasmtime", + "linera-base/wasmtime", "wasm-encoder", "wasmparser", ] diff --git a/linera-execution/src/lib.rs b/linera-execution/src/lib.rs index 66d5e4a102ef..25f99958cee6 100644 --- a/linera-execution/src/lib.rs +++ b/linera-execution/src/lib.rs @@ -60,6 +60,8 @@ use thiserror::Error; pub use crate::applications::ApplicationRegistry; #[cfg(with_revm)] use crate::revm::EvmExecutionError; +#[cfg(all(with_revm, not(with_wasmer), not(with_wasmtime)))] +use linera_base::vm::EvmRuntime; use crate::runtime::ContractSyncRuntime; #[cfg(all(with_testing, with_wasm_runtime))] pub use crate::wasm::test as wasm_test; diff --git a/linera-sdk/Cargo.toml b/linera-sdk/Cargo.toml index ddb11566f509..077e5e1c82c6 100644 --- a/linera-sdk/Cargo.toml +++ b/linera-sdk/Cargo.toml @@ -22,12 +22,14 @@ targets = ["wasm32-unknown-unknown", "x86_64-unknown-linux-gnu"] ethereum = ["async-trait", "linera-ethereum"] unstable-oracles = ["linera-core/unstable-oracles", "linera-execution/unstable-oracles"] wasmer = [ + "linera-base/wasmer", "linera-core/wasmer", "linera-execution/wasmer", "linera-storage/wasmer", "linera-witty/wasmer", ] wasmtime = [ + "linera-base/wasmtime", "linera-core/wasmtime", "linera-execution/wasmtime", "linera-storage/wasmtime", From 070fd17d3624fb28e675a5a37a7919ca1c2403ec Mon Sep 17 00:00:00 2001 From: Mathieu Dutour Sikiric Date: Sat, 22 Feb 2025 10:14:43 +0100 Subject: [PATCH 08/16] Two easy corrections for the CI. --- linera-core/Cargo.toml | 6 +++++- linera-execution/src/lib.rs | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/linera-core/Cargo.toml b/linera-core/Cargo.toml index 65002eaadc38..262bed436cb1 100644 --- a/linera-core/Cargo.toml +++ b/linera-core/Cargo.toml @@ -13,7 +13,11 @@ version.workspace = true [features] wasmer = ["linera-execution/wasmer", "linera-storage/wasmer", "linera-base/wasmer"] -wasmtime = ["linera-execution/wasmtime", "linera-storage/wasmtime", "linera-base/wasmtime"] +wasmtime = [ + "linera-execution/wasmtime", + "linera-storage/wasmtime", + "linera-base/wasmtime", +] test = [ "anyhow", "linera-base/test", diff --git a/linera-execution/src/lib.rs b/linera-execution/src/lib.rs index 25f99958cee6..afe57abcff33 100644 --- a/linera-execution/src/lib.rs +++ b/linera-execution/src/lib.rs @@ -33,6 +33,8 @@ use custom_debug_derive::Debug; use dashmap::DashMap; #[cfg(web)] use js_sys::wasm_bindgen::JsValue; +#[cfg(all(with_revm, not(with_wasmer), not(with_wasmtime)))] +use linera_base::vm::EvmRuntime; #[cfg(with_wasm_runtime)] use linera_base::vm::WasmRuntime; use linera_base::{ @@ -60,8 +62,6 @@ use thiserror::Error; pub use crate::applications::ApplicationRegistry; #[cfg(with_revm)] use crate::revm::EvmExecutionError; -#[cfg(all(with_revm, not(with_wasmer), not(with_wasmtime)))] -use linera_base::vm::EvmRuntime; use crate::runtime::ContractSyncRuntime; #[cfg(all(with_testing, with_wasm_runtime))] pub use crate::wasm::test as wasm_test; From 14a4e65b829534051cbc8e283be41fb598305ece Mon Sep 17 00:00:00 2001 From: Mathieu Dutour Sikiric Date: Sat, 22 Feb 2025 11:18:36 +0100 Subject: [PATCH 09/16] Split the VmRuntime into blocks. --- .../src/contract/conversions_from_wit.rs | 30 +++++++++++----- linera-sdk/src/contract/conversions_to_wit.rs | 34 +++++++++++++------ .../src/service/conversions_from_wit.rs | 30 +++++++++++----- linera-sdk/src/service/conversions_to_wit.rs | 34 +++++++++++++------ linera-sdk/wit/contract-system-api.wit | 10 +++++- linera-sdk/wit/service-system-api.wit | 10 +++++- 6 files changed, 110 insertions(+), 38 deletions(-) diff --git a/linera-sdk/src/contract/conversions_from_wit.rs b/linera-sdk/src/contract/conversions_from_wit.rs index 94e8ca6f6447..13a9b60b8da7 100644 --- a/linera-sdk/src/contract/conversions_from_wit.rs +++ b/linera-sdk/src/contract/conversions_from_wit.rs @@ -54,15 +54,29 @@ impl From for BytecodeId { impl From for VmRuntime { fn from(vm_runtime: wit_system_api::VmRuntime) -> Self { match vm_runtime { - wit_system_api::VmRuntime::Wasmer => VmRuntime::Wasm(WasmRuntime::Wasmer), - wit_system_api::VmRuntime::Wasmtime => VmRuntime::Wasm(WasmRuntime::Wasmtime), - wit_system_api::VmRuntime::Wasmerwithsanitizer => { - VmRuntime::Wasm(WasmRuntime::WasmerWithSanitizer) - } - wit_system_api::VmRuntime::Wasmtimewithsanitizer => { - VmRuntime::Wasm(WasmRuntime::WasmtimeWithSanitizer) + wit_system_api::VmRuntime::Wasm(wasm_runtime) => VmRuntime::Wasm(wasm_runtime.into()), + wit_system_api::VmRuntime::Evm(evm_runtime) => VmRuntime::Evm(evm_runtime.into()), + } + } +} + +impl From for WasmRuntime { + fn from(wasm_runtime: wit_system_api::WasmRuntime) -> Self { + match wasm_runtime { + wit_system_api::WasmRuntime::Wasmer => WasmRuntime::Wasmer, + wit_system_api::WasmRuntime::Wasmtime => WasmRuntime::Wasmtime, + wit_system_api::WasmRuntime::Wasmerwithsanitizer => WasmRuntime::WasmerWithSanitizer, + wit_system_api::WasmRuntime::Wasmtimewithsanitizer => { + WasmRuntime::WasmtimeWithSanitizer } - wit_system_api::VmRuntime::Revm => VmRuntime::Evm(EvmRuntime::Revm), + } + } +} + +impl From for EvmRuntime { + fn from(evm_runtime: wit_system_api::EvmRuntime) -> Self { + match evm_runtime { + wit_system_api::EvmRuntime::Revm => EvmRuntime::Revm, } } } diff --git a/linera-sdk/src/contract/conversions_to_wit.rs b/linera-sdk/src/contract/conversions_to_wit.rs index 363731980a77..dc315fc4342f 100644 --- a/linera-sdk/src/contract/conversions_to_wit.rs +++ b/linera-sdk/src/contract/conversions_to_wit.rs @@ -15,7 +15,7 @@ use linera_base::{ MessageId, Owner, StreamName, }, ownership::{ChainOwnership, TimeoutConfig}, - vm::{VmRuntime, WasmRuntime}, + vm::{EvmRuntime, VmRuntime, WasmRuntime}, }; use super::wit::contract_system_api as wit_system_api; @@ -113,15 +113,29 @@ impl From for wit_system_api::BytecodeId { impl From for wit_system_api::VmRuntime { fn from(vm_runtime: VmRuntime) -> Self { match vm_runtime { - VmRuntime::Wasm(wasm_runtime) => match wasm_runtime { - WasmRuntime::Wasmer => wit_system_api::VmRuntime::Wasmer, - WasmRuntime::Wasmtime => wit_system_api::VmRuntime::Wasmtime, - WasmRuntime::WasmerWithSanitizer => wit_system_api::VmRuntime::Wasmerwithsanitizer, - WasmRuntime::WasmtimeWithSanitizer => { - wit_system_api::VmRuntime::Wasmtimewithsanitizer - } - }, - VmRuntime::Evm(_) => wit_system_api::VmRuntime::Revm, + VmRuntime::Wasm(wasm_runtime) => wit_system_api::VmRuntime::Wasm(wasm_runtime.into()), + VmRuntime::Evm(evm_runtime) => wit_system_api::VmRuntime::Evm(evm_runtime.into()), + } + } +} + +impl From for wit_system_api::WasmRuntime { + fn from(wasm_runtime: WasmRuntime) -> Self { + match wasm_runtime { + WasmRuntime::Wasmer => wit_system_api::WasmRuntime::Wasmer, + WasmRuntime::Wasmtime => wit_system_api::WasmRuntime::Wasmtime, + WasmRuntime::WasmerWithSanitizer => wit_system_api::WasmRuntime::Wasmerwithsanitizer, + WasmRuntime::WasmtimeWithSanitizer => { + wit_system_api::WasmRuntime::Wasmtimewithsanitizer + } + } + } +} + +impl From for wit_system_api::EvmRuntime { + fn from(evm_runtime: EvmRuntime) -> Self { + match evm_runtime { + EvmRuntime::Revm => wit_system_api::EvmRuntime::Revm, } } } diff --git a/linera-sdk/src/service/conversions_from_wit.rs b/linera-sdk/src/service/conversions_from_wit.rs index 4310529e788c..9901136a871f 100644 --- a/linera-sdk/src/service/conversions_from_wit.rs +++ b/linera-sdk/src/service/conversions_from_wit.rs @@ -99,15 +99,29 @@ impl From for BytecodeId { impl From for VmRuntime { fn from(vm_runtime: wit_system_api::VmRuntime) -> Self { match vm_runtime { - wit_system_api::VmRuntime::Wasmer => VmRuntime::Wasm(WasmRuntime::Wasmer), - wit_system_api::VmRuntime::Wasmtime => VmRuntime::Wasm(WasmRuntime::Wasmtime), - wit_system_api::VmRuntime::Wasmerwithsanitizer => { - VmRuntime::Wasm(WasmRuntime::WasmerWithSanitizer) - } - wit_system_api::VmRuntime::Wasmtimewithsanitizer => { - VmRuntime::Wasm(WasmRuntime::WasmtimeWithSanitizer) + wit_system_api::VmRuntime::Wasm(wasm_runtime) => VmRuntime::Wasm(wasm_runtime.into()), + wit_system_api::VmRuntime::Evm(evm_runtime) => VmRuntime::Evm(evm_runtime.into()), + } + } +} + +impl From for WasmRuntime { + fn from(wasm_runtime: wit_system_api::WasmRuntime) -> Self { + match wasm_runtime { + wit_system_api::WasmRuntime::Wasmer => WasmRuntime::Wasmer, + wit_system_api::WasmRuntime::Wasmtime => WasmRuntime::Wasmtime, + wit_system_api::WasmRuntime::Wasmerwithsanitizer => WasmRuntime::WasmerWithSanitizer, + wit_system_api::WasmRuntime::Wasmtimewithsanitizer => { + WasmRuntime::WasmtimeWithSanitizer } - wit_system_api::VmRuntime::Revm => VmRuntime::Evm(EvmRuntime::Revm), + } + } +} + +impl From for EvmRuntime { + fn from(evm_runtime: wit_system_api::EvmRuntime) -> Self { + match evm_runtime { + wit_system_api::EvmRuntime::Revm => EvmRuntime::Revm, } } } diff --git a/linera-sdk/src/service/conversions_to_wit.rs b/linera-sdk/src/service/conversions_to_wit.rs index fbe5e60d7ba9..51b89ff78a0e 100644 --- a/linera-sdk/src/service/conversions_to_wit.rs +++ b/linera-sdk/src/service/conversions_to_wit.rs @@ -8,7 +8,7 @@ use linera_base::{ data_types::BlockHeight, http, identifiers::{AccountOwner, ApplicationId, BytecodeId, ChainId, MessageId, Owner}, - vm::{VmRuntime, WasmRuntime}, + vm::{EvmRuntime, VmRuntime, WasmRuntime}, }; use super::wit::service_system_api as wit_system_api; @@ -95,15 +95,29 @@ impl From for wit_system_api::BytecodeId { impl From for wit_system_api::VmRuntime { fn from(vm_runtime: VmRuntime) -> Self { match vm_runtime { - VmRuntime::Wasm(wasm_runtime) => match wasm_runtime { - WasmRuntime::Wasmer => wit_system_api::VmRuntime::Wasmer, - WasmRuntime::Wasmtime => wit_system_api::VmRuntime::Wasmtime, - WasmRuntime::WasmerWithSanitizer => wit_system_api::VmRuntime::Wasmerwithsanitizer, - WasmRuntime::WasmtimeWithSanitizer => { - wit_system_api::VmRuntime::Wasmtimewithsanitizer - } - }, - VmRuntime::Evm(_) => wit_system_api::VmRuntime::Revm, + VmRuntime::Wasm(wasm_runtime) => wit_system_api::VmRuntime::Wasm(wasm_runtime.into()), + VmRuntime::Evm(evm_runtime) => wit_system_api::VmRuntime::Evm(evm_runtime.into()), + } + } +} + +impl From for wit_system_api::WasmRuntime { + fn from(wasm_runtime: WasmRuntime) -> Self { + match wasm_runtime { + WasmRuntime::Wasmer => wit_system_api::WasmRuntime::Wasmer, + WasmRuntime::Wasmtime => wit_system_api::WasmRuntime::Wasmtime, + WasmRuntime::WasmerWithSanitizer => wit_system_api::WasmRuntime::Wasmerwithsanitizer, + WasmRuntime::WasmtimeWithSanitizer => { + wit_system_api::WasmRuntime::Wasmtimewithsanitizer + } + } + } +} + +impl From for wit_system_api::EvmRuntime { + fn from(evm_runtime: EvmRuntime) -> Self { + match evm_runtime { + EvmRuntime::Revm => wit_system_api::EvmRuntime::Revm, } } } diff --git a/linera-sdk/wit/contract-system-api.wit b/linera-sdk/wit/contract-system-api.wit index 74b98c98dc27..7e15375badbb 100644 --- a/linera-sdk/wit/contract-system-api.wit +++ b/linera-sdk/wit/contract-system-api.wit @@ -70,11 +70,19 @@ interface contract-system-api { vm-runtime: vm-runtime, } - enum vm-runtime { + variant vm-runtime { + wasm(wasm-runtime), + evm(evm-runtime), + } + + enum wasm-runtime { wasmer, wasmtime, wasmerwithsanitizer, wasmtimewithsanitizer, + } + + enum evm-runtime { revm, } diff --git a/linera-sdk/wit/service-system-api.wit b/linera-sdk/wit/service-system-api.wit index 90f0c4dd7d46..c3985b2e38ba 100644 --- a/linera-sdk/wit/service-system-api.wit +++ b/linera-sdk/wit/service-system-api.wit @@ -44,11 +44,19 @@ interface service-system-api { vm-runtime: vm-runtime, } - enum vm-runtime { + variant vm-runtime { + wasm(wasm-runtime), + evm(evm-runtime), + } + + enum wasm-runtime { wasmer, wasmtime, wasmerwithsanitizer, wasmtimewithsanitizer, + } + + enum evm-runtime { revm, } From 6928d0a1792b8f218b1ac5107a2a5151de0fbe39 Mon Sep 17 00:00:00 2001 From: Mathieu Dutour Sikiric Date: Sat, 22 Feb 2025 11:24:40 +0100 Subject: [PATCH 10/16] Change to the standard fixed by the "wit-generator". --- .../src/contract/conversions_from_wit.rs | 4 +-- linera-sdk/src/contract/conversions_to_wit.rs | 4 +-- .../src/service/conversions_from_wit.rs | 4 +-- linera-sdk/src/service/conversions_to_wit.rs | 4 +-- linera-sdk/wit/contract-system-api.wit | 32 +++++++++---------- linera-sdk/wit/service-system-api.wit | 32 +++++++++---------- 6 files changed, 40 insertions(+), 40 deletions(-) diff --git a/linera-sdk/src/contract/conversions_from_wit.rs b/linera-sdk/src/contract/conversions_from_wit.rs index 13a9b60b8da7..6c1c9987cba2 100644 --- a/linera-sdk/src/contract/conversions_from_wit.rs +++ b/linera-sdk/src/contract/conversions_from_wit.rs @@ -65,8 +65,8 @@ impl From for WasmRuntime { match wasm_runtime { wit_system_api::WasmRuntime::Wasmer => WasmRuntime::Wasmer, wit_system_api::WasmRuntime::Wasmtime => WasmRuntime::Wasmtime, - wit_system_api::WasmRuntime::Wasmerwithsanitizer => WasmRuntime::WasmerWithSanitizer, - wit_system_api::WasmRuntime::Wasmtimewithsanitizer => { + wit_system_api::WasmRuntime::WasmerWithSanitizer => WasmRuntime::WasmerWithSanitizer, + wit_system_api::WasmRuntime::WasmtimeWithSanitizer => { WasmRuntime::WasmtimeWithSanitizer } } diff --git a/linera-sdk/src/contract/conversions_to_wit.rs b/linera-sdk/src/contract/conversions_to_wit.rs index dc315fc4342f..9de3c05f9130 100644 --- a/linera-sdk/src/contract/conversions_to_wit.rs +++ b/linera-sdk/src/contract/conversions_to_wit.rs @@ -124,9 +124,9 @@ impl From for wit_system_api::WasmRuntime { match wasm_runtime { WasmRuntime::Wasmer => wit_system_api::WasmRuntime::Wasmer, WasmRuntime::Wasmtime => wit_system_api::WasmRuntime::Wasmtime, - WasmRuntime::WasmerWithSanitizer => wit_system_api::WasmRuntime::Wasmerwithsanitizer, + WasmRuntime::WasmerWithSanitizer => wit_system_api::WasmRuntime::WasmerWithSanitizer, WasmRuntime::WasmtimeWithSanitizer => { - wit_system_api::WasmRuntime::Wasmtimewithsanitizer + wit_system_api::WasmRuntime::WasmtimeWithSanitizer } } } diff --git a/linera-sdk/src/service/conversions_from_wit.rs b/linera-sdk/src/service/conversions_from_wit.rs index 9901136a871f..b5ecf6f25337 100644 --- a/linera-sdk/src/service/conversions_from_wit.rs +++ b/linera-sdk/src/service/conversions_from_wit.rs @@ -110,8 +110,8 @@ impl From for WasmRuntime { match wasm_runtime { wit_system_api::WasmRuntime::Wasmer => WasmRuntime::Wasmer, wit_system_api::WasmRuntime::Wasmtime => WasmRuntime::Wasmtime, - wit_system_api::WasmRuntime::Wasmerwithsanitizer => WasmRuntime::WasmerWithSanitizer, - wit_system_api::WasmRuntime::Wasmtimewithsanitizer => { + wit_system_api::WasmRuntime::WasmerWithSanitizer => WasmRuntime::WasmerWithSanitizer, + wit_system_api::WasmRuntime::WasmtimeWithSanitizer => { WasmRuntime::WasmtimeWithSanitizer } } diff --git a/linera-sdk/src/service/conversions_to_wit.rs b/linera-sdk/src/service/conversions_to_wit.rs index 51b89ff78a0e..fc7f6086ff5b 100644 --- a/linera-sdk/src/service/conversions_to_wit.rs +++ b/linera-sdk/src/service/conversions_to_wit.rs @@ -106,9 +106,9 @@ impl From for wit_system_api::WasmRuntime { match wasm_runtime { WasmRuntime::Wasmer => wit_system_api::WasmRuntime::Wasmer, WasmRuntime::Wasmtime => wit_system_api::WasmRuntime::Wasmtime, - WasmRuntime::WasmerWithSanitizer => wit_system_api::WasmRuntime::Wasmerwithsanitizer, + WasmRuntime::WasmerWithSanitizer => wit_system_api::WasmRuntime::WasmerWithSanitizer, WasmRuntime::WasmtimeWithSanitizer => { - wit_system_api::WasmRuntime::Wasmtimewithsanitizer + wit_system_api::WasmRuntime::WasmtimeWithSanitizer } } } diff --git a/linera-sdk/wit/contract-system-api.wit b/linera-sdk/wit/contract-system-api.wit index 7e15375badbb..2ea0c822dd4b 100644 --- a/linera-sdk/wit/contract-system-api.wit +++ b/linera-sdk/wit/contract-system-api.wit @@ -70,22 +70,6 @@ interface contract-system-api { vm-runtime: vm-runtime, } - variant vm-runtime { - wasm(wasm-runtime), - evm(evm-runtime), - } - - enum wasm-runtime { - wasmer, - wasmtime, - wasmerwithsanitizer, - wasmtimewithsanitizer, - } - - enum evm-runtime { - revm, - } - record chain-id { inner0: crypto-hash, } @@ -122,6 +106,10 @@ interface contract-system-api { subscribers(channel-name), } + enum evm-runtime { + revm, + } + record http-header { name: string, value: list, @@ -209,4 +197,16 @@ interface contract-system-api { } type u128 = tuple; + + variant vm-runtime { + wasm(wasm-runtime), + evm(evm-runtime), + } + + enum wasm-runtime { + wasmer, + wasmtime, + wasmer-with-sanitizer, + wasmtime-with-sanitizer, + } } diff --git a/linera-sdk/wit/service-system-api.wit b/linera-sdk/wit/service-system-api.wit index c3985b2e38ba..3e853b1a3c67 100644 --- a/linera-sdk/wit/service-system-api.wit +++ b/linera-sdk/wit/service-system-api.wit @@ -44,22 +44,6 @@ interface service-system-api { vm-runtime: vm-runtime, } - variant vm-runtime { - wasm(wasm-runtime), - evm(evm-runtime), - } - - enum wasm-runtime { - wasmer, - wasmtime, - wasmerwithsanitizer, - wasmtimewithsanitizer, - } - - enum evm-runtime { - revm, - } - record chain-id { inner0: crypto-hash, } @@ -71,6 +55,10 @@ interface service-system-api { part4: u64, } + enum evm-runtime { + revm, + } + record http-header { name: string, value: list, @@ -124,4 +112,16 @@ interface service-system-api { } type u128 = tuple; + + variant vm-runtime { + wasm(wasm-runtime), + evm(evm-runtime), + } + + enum wasm-runtime { + wasmer, + wasmtime, + wasmer-with-sanitizer, + wasmtime-with-sanitizer, + } } From f9cafb81064998d78cdbc84b30b63091fcee74c2 Mon Sep 17 00:00:00 2001 From: Mathieu Dutour Sikiric Date: Sat, 22 Feb 2025 20:28:28 +0100 Subject: [PATCH 11/16] Some further corrections. --- linera-rpc/tests/format.rs | 4 +++ .../tests/snapshots/format__format.yaml.snap | 26 +++++++++++++++++++ linera-service/src/cli_wrappers/wallet.rs | 5 +++- linera-service/tests/linera_net_tests.rs | 13 ++++++++-- 4 files changed, 45 insertions(+), 3 deletions(-) diff --git a/linera-rpc/tests/format.rs b/linera-rpc/tests/format.rs index 32dd1416f51e..3ad2b0353139 100644 --- a/linera-rpc/tests/format.rs +++ b/linera-rpc/tests/format.rs @@ -7,6 +7,7 @@ use linera_base::{ hashed::Hashed, identifiers::{AccountOwner, BlobType, ChainDescription, Destination, GenericApplicationId}, ownership::ChainOwnership, + vm::{EvmRuntime, VmRuntime, WasmRuntime}, }; use linera_chain::{ data_types::{Medium, MessageAction}, @@ -39,6 +40,9 @@ fn get_registry() -> Result { tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; + tracer.trace_type::(&samples)?; + tracer.trace_type::(&samples)?; + tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; diff --git a/linera-rpc/tests/snapshots/format__format.yaml.snap b/linera-rpc/tests/snapshots/format__format.yaml.snap index aa51e6677c4e..7284d34d0e83 100644 --- a/linera-rpc/tests/snapshots/format__format.yaml.snap +++ b/linera-rpc/tests/snapshots/format__format.yaml.snap @@ -160,6 +160,8 @@ BytecodeId: TYPENAME: CryptoHash - service_blob_hash: TYPENAME: CryptoHash + - vm_runtime: + TYPENAME: VmRuntime Certificate: ENUM: 0: @@ -423,6 +425,10 @@ Event: TYPENAME: StreamId - key: BYTES - value: BYTES +EvmRuntime: + ENUM: + 0: + Revm: UNIT GenericApplicationId: ENUM: 0: @@ -1194,3 +1200,23 @@ VersionInfo: - rpc_hash: STR - graphql_hash: STR - wit_hash: STR +VmRuntime: + ENUM: + 0: + Wasm: + NEWTYPE: + TYPENAME: WasmRuntime + 1: + Evm: + NEWTYPE: + TYPENAME: EvmRuntime +WasmRuntime: + ENUM: + 0: + Wasmer: UNIT + 1: + Wasmtime: UNIT + 2: + WasmerWithSanitizer: UNIT + 3: + WasmtimeWithSanitizer: UNIT diff --git a/linera-service/src/cli_wrappers/wallet.rs b/linera-service/src/cli_wrappers/wallet.rs index d309661c4a39..1957e1755e31 100644 --- a/linera-service/src/cli_wrappers/wallet.rs +++ b/linera-service/src/cli_wrappers/wallet.rs @@ -23,6 +23,7 @@ use linera_base::{ crypto::CryptoHash, data_types::{Amount, Bytecode}, identifiers::{Account, ApplicationId, BytecodeId, ChainId, MessageId, Owner}, + vm::VmRuntime, }; use linera_client::wallet::Wallet; use linera_core::worker::Notification; @@ -1165,14 +1166,16 @@ impl NodeService { chain_id: &ChainId, contract: PathBuf, service: PathBuf, + vm_runtime: VmRuntime, ) -> Result> { let contract_code = Bytecode::load_from_file(&contract).await?; let service_code = Bytecode::load_from_file(&service).await?; let query = format!( - "mutation {{ publishBytecode(chainId: {}, contract: {}, service: {}) }}", + "mutation {{ publishBytecode(chainId: {}, contract: {}, service: {}, vmRuntime: {}) }}", chain_id.to_value(), contract_code.to_value(), service_code.to_value(), + vm_runtime.to_value(), ); let data = self.query_node(query).await?; let bytecode_str = data["publishBytecode"] diff --git a/linera-service/tests/linera_net_tests.rs b/linera-service/tests/linera_net_tests.rs index d7288e6beb7d..7f3b52101c0a 100644 --- a/linera-service/tests/linera_net_tests.rs +++ b/linera-service/tests/linera_net_tests.rs @@ -30,6 +30,7 @@ use linera_base::{ crypto::CryptoHash, data_types::Amount, identifiers::{Account, AccountOwner, ApplicationId, ChainId}, + vm::VmRuntime, }; use linera_chain::data_types::{Medium, Origin}; use linera_core::worker::{Notification, Reason}; @@ -1400,6 +1401,7 @@ async fn test_wasm_end_to_end_matching_engine(config: impl LineraNetConfig) -> R let _guard = INTEGRATION_TEST_GUARD.lock().await; tracing::info!("Starting test {}", test_name!()); + let vm_runtime = VmRuntime::default(); let (mut net, client_admin) = config.instantiate().await?; let client_a = net.make_client().await; @@ -1539,6 +1541,7 @@ async fn test_wasm_end_to_end_matching_engine(config: impl LineraNetConfig) -> R &chain_admin, contract_matching, service_matching, + vm_runtime, ) .await?; let application_id_matching = node_service_admin @@ -1691,6 +1694,7 @@ async fn test_wasm_end_to_end_amm(config: impl LineraNetConfig) -> Result<()> { let _guard = INTEGRATION_TEST_GUARD.lock().await; tracing::info!("Starting test {}", test_name!()); + let vm_runtime = VmRuntime::default(); let (mut net, client_amm) = config.instantiate().await?; let client0 = net.make_client().await; @@ -1741,7 +1745,7 @@ async fn test_wasm_end_to_end_amm(config: impl LineraNetConfig) -> Result<()> { fungible::FungibleTokenAbi, fungible::Parameters, fungible::InitialState - >(&chain_amm, contract_fungible, service_fungible).await?; + >(&chain_amm, contract_fungible, service_fungible, vm_runtime).await?; let params0 = fungible::Parameters::new("ZERO"); let token0 = node_service_amm @@ -1880,7 +1884,12 @@ async fn test_wasm_end_to_end_amm(config: impl LineraNetConfig) -> Result<()> { // Create AMM application on Admin chain let bytecode_id = node_service_amm - .publish_bytecode::(&chain_amm, contract_amm, service_amm) + .publish_bytecode::( + &chain_amm, + contract_amm, + service_amm, + vm_runtime, + ) .await?; let application_id_amm = node_service_amm .create_application( From 8f6a561de612874a2eb40a783939ca23cf081d19 Mon Sep 17 00:00:00 2001 From: Mathieu Dutour Sikiric Date: Sun, 23 Feb 2025 09:11:13 +0100 Subject: [PATCH 12/16] More back the UserApplicationDescription. --- linera-base/src/data_types.rs | 32 +++++++++++++++++-- linera-chain/src/chain.rs | 6 ++-- linera-chain/src/unit_tests/chain_tests.rs | 6 ++-- linera-core/src/chain_worker/actor.rs | 5 ++- linera-core/src/chain_worker/state/mod.rs | 4 +-- .../chain_worker/state/temporary_changes.rs | 4 +-- linera-core/src/local_node.rs | 4 +-- .../src/unit_tests/wasm_client_tests.rs | 4 +-- .../src/unit_tests/wasm_worker_tests.rs | 6 ++-- linera-core/src/worker.rs | 8 ++--- linera-execution/src/applications.rs | 4 +-- linera-execution/src/lib.rs | 31 +----------------- .../tests/contract_runtime_apis.rs | 5 +-- linera-service-graphql-client/src/service.rs | 9 +++--- linera-service/src/node_service.rs | 4 +-- linera-storage/src/lib.rs | 7 ++-- 16 files changed, 74 insertions(+), 65 deletions(-) diff --git a/linera-base/src/data_types.rs b/linera-base/src/data_types.rs index 94dcbfd7deb1..906e8c1a066a 100644 --- a/linera-base/src/data_types.rs +++ b/linera-base/src/data_types.rs @@ -32,8 +32,8 @@ use crate::{ crypto::{BcsHashable, CryptoHash}, doc_scalar, hex_debug, http, identifiers::{ - ApplicationId, BlobId, BlobType, ChainId, Destination, EventId, GenericApplicationId, - StreamId, + ApplicationId, BlobId, BlobType, BytecodeId, ChainId, Destination, EventId, + GenericApplicationId, MessageId, StreamId, UserApplicationId, }, limited_writer::{LimitedWriter, LimitedWriterError}, time::{Duration, SystemTime}, @@ -782,6 +782,30 @@ pub enum OracleResponse { impl<'de> BcsHashable<'de> for OracleResponse {} +/// Description of the necessary information to run a user application. +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Hash, Serialize)] +pub struct UserApplicationDescription { + /// The unique ID of the bytecode to use for the application. + pub bytecode_id: BytecodeId, + /// The unique ID of the application's creation. + pub creation: MessageId, + /// The parameters of the application. + #[serde(with = "serde_bytes")] + #[debug(with = "hex_debug")] + pub parameters: Vec, + /// Required dependencies. + pub required_application_ids: Vec, +} + +impl From<&UserApplicationDescription> for UserApplicationId { + fn from(description: &UserApplicationDescription) -> Self { + UserApplicationId { + bytecode_id: description.bytecode_id, + creation: description.creation, + } + } +} + /// A WebAssembly module's bytecode. #[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] pub struct Bytecode { @@ -1132,6 +1156,10 @@ doc_scalar!( Blob, "A blob of binary data, with its content-addressed blob ID." ); +doc_scalar!( + UserApplicationDescription, + "Description of the necessary information to run a user application" +); /// The time it takes to compress a bytecode. #[cfg(with_metrics)] diff --git a/linera-chain/src/chain.rs b/linera-chain/src/chain.rs index a35e03f9339a..05a3a608d998 100644 --- a/linera-chain/src/chain.rs +++ b/linera-chain/src/chain.rs @@ -12,7 +12,9 @@ use async_graphql::SimpleObject; use futures::stream::{self, StreamExt, TryStreamExt}; use linera_base::{ crypto::{CryptoHash, ValidatorPublicKey}, - data_types::{Amount, ArithmeticError, BlockHeight, OracleResponse, Timestamp}, + data_types::{ + Amount, ArithmeticError, BlockHeight, OracleResponse, Timestamp, UserApplicationDescription, + }, ensure, identifiers::{ ChainId, ChannelFullName, Destination, GenericApplicationId, MessageId, Owner, @@ -26,7 +28,7 @@ use linera_execution::{ ExecutionOutcome, ExecutionRuntimeContext, ExecutionStateView, Message, MessageContext, Operation, OperationContext, Query, QueryContext, QueryOutcome, RawExecutionOutcome, RawOutgoingMessage, ResourceController, ResourceTracker, ServiceRuntimeEndpoint, - TransactionTracker, UserApplicationDescription, + TransactionTracker, }; use linera_views::{ context::Context, diff --git a/linera-chain/src/unit_tests/chain_tests.rs b/linera-chain/src/unit_tests/chain_tests.rs index 9c8cee798e26..1ba983d7c3d2 100644 --- a/linera-chain/src/unit_tests/chain_tests.rs +++ b/linera-chain/src/unit_tests/chain_tests.rs @@ -8,7 +8,10 @@ use std::{collections::BTreeMap, iter}; use assert_matches::assert_matches; use linera_base::{ crypto::{AccountPublicKey, CryptoHash, ValidatorPublicKey}, - data_types::{Amount, ApplicationPermissions, Blob, BlockHeight, Bytecode, Timestamp}, + data_types::{ + Amount, ApplicationPermissions, Blob, BlockHeight, Bytecode, Timestamp, + UserApplicationDescription, + }, hashed::Hashed, identifiers::{ApplicationId, BytecodeId, ChainId, MessageId}, ownership::ChainOwnership, @@ -20,7 +23,6 @@ use linera_execution::{ test_utils::{ExpectedCall, MockApplication}, ExecutionError, ExecutionRuntimeConfig, ExecutionRuntimeContext, Message, MessageKind, Operation, ResourceControlPolicy, SystemMessage, SystemOperation, TestExecutionRuntimeContext, - UserApplicationDescription, }; use linera_views::{ context::{Context as _, MemoryContext}, diff --git a/linera-core/src/chain_worker/actor.rs b/linera-core/src/chain_worker/actor.rs index d2dce845f5eb..eda7933d0a18 100644 --- a/linera-core/src/chain_worker/actor.rs +++ b/linera-core/src/chain_worker/actor.rs @@ -12,7 +12,7 @@ use std::{ use custom_debug_derive::Debug; use linera_base::{ crypto::{CryptoHash, ValidatorPublicKey}, - data_types::{Blob, BlockHeight, Timestamp}, + data_types::{Blob, BlockHeight, Timestamp, UserApplicationDescription}, hashed::Hashed, identifiers::{BlobId, ChainId, UserApplicationId}, }; @@ -22,8 +22,7 @@ use linera_chain::{ ChainStateView, }; use linera_execution::{ - committee::Epoch, Query, QueryContext, QueryOutcome, ServiceRuntimeEndpoint, - ServiceSyncRuntime, UserApplicationDescription, + committee::Epoch, Query, QueryContext, QueryOutcome, ServiceRuntimeEndpoint, ServiceSyncRuntime, }; use linera_storage::Storage; use tokio::sync::{mpsc, oneshot, OwnedRwLockReadGuard}; diff --git a/linera-core/src/chain_worker/state/mod.rs b/linera-core/src/chain_worker/state/mod.rs index cc976b751f34..e3c0716a044a 100644 --- a/linera-core/src/chain_worker/state/mod.rs +++ b/linera-core/src/chain_worker/state/mod.rs @@ -14,7 +14,7 @@ use std::{ use linera_base::{ crypto::{CryptoHash, ValidatorPublicKey}, - data_types::{Blob, BlockHeight}, + data_types::{Blob, BlockHeight, UserApplicationDescription}, ensure, hashed::Hashed, identifiers::{BlobId, ChainId, UserApplicationId}, @@ -28,7 +28,7 @@ use linera_chain::{ }; use linera_execution::{ committee::Epoch, Message, Query, QueryContext, QueryOutcome, ServiceRuntimeEndpoint, - SystemMessage, UserApplicationDescription, + SystemMessage, }; use linera_storage::{Clock as _, Storage}; use linera_views::views::{ClonableView, ViewError}; diff --git a/linera-core/src/chain_worker/state/temporary_changes.rs b/linera-core/src/chain_worker/state/temporary_changes.rs index 42d2db3b46a7..e10696ff4884 100644 --- a/linera-core/src/chain_worker/state/temporary_changes.rs +++ b/linera-core/src/chain_worker/state/temporary_changes.rs @@ -4,7 +4,7 @@ //! Operations that don't persist any changes to the chain state. use linera_base::{ - data_types::{ArithmeticError, Timestamp}, + data_types::{ArithmeticError, Timestamp, UserApplicationDescription}, ensure, identifiers::{AccountOwner, ChannelFullName, GenericApplicationId, UserApplicationId}, }; @@ -12,7 +12,7 @@ use linera_chain::data_types::{ BlockExecutionOutcome, ExecutedBlock, IncomingBundle, Medium, MessageAction, ProposalContent, ProposedBlock, }; -use linera_execution::{ChannelSubscription, Query, QueryOutcome, UserApplicationDescription}; +use linera_execution::{ChannelSubscription, Query, QueryOutcome}; use linera_storage::{Clock as _, Storage}; use linera_views::views::View; #[cfg(with_testing)] diff --git a/linera-core/src/local_node.rs b/linera-core/src/local_node.rs index 6d376dcfc59b..2c4ebb29e888 100644 --- a/linera-core/src/local_node.rs +++ b/linera-core/src/local_node.rs @@ -10,7 +10,7 @@ use std::{ use futures::{future::Either, stream, StreamExt as _, TryStreamExt as _}; use linera_base::{ crypto::ValidatorPublicKey, - data_types::{ArithmeticError, Blob, BlockHeight}, + data_types::{ArithmeticError, Blob, BlockHeight, UserApplicationDescription}, identifiers::{BlobId, ChainId, MessageId, UserApplicationId}, }; use linera_chain::{ @@ -18,7 +18,7 @@ use linera_chain::{ types::{ConfirmedBlockCertificate, GenericCertificate, LiteCertificate}, ChainStateView, }; -use linera_execution::{Query, QueryOutcome, UserApplicationDescription}; +use linera_execution::{Query, QueryOutcome}; use linera_storage::Storage; use linera_views::views::ViewError; use thiserror::Error; diff --git a/linera-core/src/unit_tests/wasm_client_tests.rs b/linera-core/src/unit_tests/wasm_client_tests.rs index 58a31e075e9b..984d54b97fae 100644 --- a/linera-core/src/unit_tests/wasm_client_tests.rs +++ b/linera-core/src/unit_tests/wasm_client_tests.rs @@ -19,7 +19,7 @@ use assert_matches::assert_matches; use async_graphql::Request; use counter::CounterAbi; use linera_base::{ - data_types::{Amount, Bytecode, Event, OracleResponse}, + data_types::{Amount, Bytecode, Event, OracleResponse, UserApplicationDescription}, identifiers::{AccountOwner, ApplicationId, Destination, Owner, StreamId, StreamName}, ownership::{ChainOwnership, TimeoutConfig}, vm::{VmRuntime, WasmRuntime}, @@ -30,7 +30,7 @@ use linera_chain::{ }; use linera_execution::{ ExecutionError, Message, MessageKind, Operation, QueryOutcome, ResourceControlPolicy, - SystemMessage, UserApplicationDescription, + SystemMessage, }; use serde_json::json; use test_case::test_case; diff --git a/linera-core/src/unit_tests/wasm_worker_tests.rs b/linera-core/src/unit_tests/wasm_worker_tests.rs index eba700d87ea0..d36419bf3a32 100644 --- a/linera-core/src/unit_tests/wasm_worker_tests.rs +++ b/linera-core/src/unit_tests/wasm_worker_tests.rs @@ -15,7 +15,9 @@ use std::collections::BTreeSet; use assert_matches::assert_matches; use linera_base::{ crypto::AccountSecretKey, - data_types::{Amount, Blob, BlockHeight, Bytecode, OracleResponse, Timestamp}, + data_types::{ + Amount, Blob, BlockHeight, Bytecode, OracleResponse, Timestamp, UserApplicationDescription, + }, hashed::Hashed, identifiers::{ BytecodeId, ChainDescription, ChainId, Destination, MessageId, UserApplicationId, @@ -33,7 +35,7 @@ use linera_execution::{ system::{SystemMessage, SystemOperation}, test_utils::SystemExecutionState, Message, MessageKind, Operation, OperationContext, ResourceController, TransactionTracker, - UserApplicationDescription, WasmContractModule, + WasmContractModule, }; use linera_storage::{DbStorage, Storage}; #[cfg(feature = "dynamodb")] diff --git a/linera-core/src/worker.rs b/linera-core/src/worker.rs index eb6bdb35e385..501e13a84758 100644 --- a/linera-core/src/worker.rs +++ b/linera-core/src/worker.rs @@ -12,7 +12,9 @@ use std::{ use futures::future::Either; use linera_base::{ crypto::{CryptoError, CryptoHash, ValidatorPublicKey, ValidatorSecretKey}, - data_types::{ArithmeticError, Blob, BlockHeight, DecompressionError, Round}, + data_types::{ + ArithmeticError, Blob, BlockHeight, DecompressionError, Round, UserApplicationDescription, + }, doc_scalar, hashed::Hashed, identifiers::{BlobId, ChainId, Owner, UserApplicationId}, @@ -29,9 +31,7 @@ use linera_chain::{ }, ChainError, ChainStateView, }; -use linera_execution::{ - committee::Epoch, ExecutionError, Query, QueryOutcome, UserApplicationDescription, -}; +use linera_execution::{committee::Epoch, ExecutionError, Query, QueryOutcome}; use linera_storage::Storage; use linera_views::views::ViewError; use lru::LruCache; diff --git a/linera-execution/src/applications.rs b/linera-execution/src/applications.rs index 866bfda0aaf1..8da936015d32 100644 --- a/linera-execution/src/applications.rs +++ b/linera-execution/src/applications.rs @@ -3,7 +3,7 @@ use std::collections::HashSet; -use linera_base::identifiers::UserApplicationId; +use linera_base::{data_types::UserApplicationDescription, identifiers::UserApplicationId}; use linera_views::{ context::Context, map_view::HashedMapView, @@ -16,7 +16,7 @@ use { std::collections::BTreeMap, }; -use crate::{SystemExecutionError, UserApplicationDescription}; +use crate::SystemExecutionError; #[cfg(test)] #[path = "unit_tests/applications_tests.rs"] diff --git a/linera-execution/src/lib.rs b/linera-execution/src/lib.rs index afe57abcff33..fad5d3790a5d 100644 --- a/linera-execution/src/lib.rs +++ b/linera-execution/src/lib.rs @@ -42,7 +42,7 @@ use linera_base::{ crypto::{BcsHashable, CryptoHash}, data_types::{ Amount, ApplicationPermissions, ArithmeticError, Blob, BlockHeight, DecompressionError, - Resources, SendMessageRequest, Timestamp, + Resources, SendMessageRequest, Timestamp, UserApplicationDescription, }, doc_scalar, hex_debug, http, identifiers::{ @@ -1341,35 +1341,6 @@ impl WithVmDefault for Option { } } -/// Description of the necessary information to run a user application. -#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Hash, Serialize)] -pub struct UserApplicationDescription { - /// The unique ID of the bytecode to use for the application. - pub bytecode_id: BytecodeId, - /// The unique ID of the application's creation. - pub creation: MessageId, - /// The parameters of the application. - #[serde(with = "serde_bytes")] - #[debug(with = "hex_debug")] - pub parameters: Vec, - /// Required dependencies. - pub required_application_ids: Vec, -} - -impl From<&UserApplicationDescription> for UserApplicationId { - fn from(description: &UserApplicationDescription) -> Self { - UserApplicationId { - bytecode_id: description.bytecode_id, - creation: description.creation, - } - } -} - -doc_scalar!( - UserApplicationDescription, - "Description of the necessary information to run a user application" -); - doc_scalar!(Operation, "An operation to be executed in a block"); doc_scalar!( Message, diff --git a/linera-execution/tests/contract_runtime_apis.rs b/linera-execution/tests/contract_runtime_apis.rs index d69c603df6c0..78d273398560 100644 --- a/linera-execution/tests/contract_runtime_apis.rs +++ b/linera-execution/tests/contract_runtime_apis.rs @@ -12,7 +12,9 @@ use anyhow::bail; use assert_matches::assert_matches; use linera_base::{ crypto::CryptoHash, - data_types::{Amount, Blob, BlockHeight, CompressedBytecode, Timestamp}, + data_types::{ + Amount, Blob, BlockHeight, CompressedBytecode, Timestamp, UserApplicationDescription, + }, identifiers::{ Account, AccountOwner, ApplicationId, BytecodeId, ChainDescription, ChainId, MessageId, Owner, @@ -28,7 +30,6 @@ use linera_execution::{ BaseRuntime, ContractRuntime, ExecutionError, ExecutionOutcome, Message, MessageContext, Operation, OperationContext, ResourceController, SystemExecutionError, SystemExecutionStateView, TestExecutionRuntimeContext, TransactionOutcome, TransactionTracker, - UserApplicationDescription, }; use linera_views::context::MemoryContext; use test_case::test_matrix; diff --git a/linera-service-graphql-client/src/service.rs b/linera-service-graphql-client/src/service.rs index cf30ab033c62..2bfd4b3454f9 100644 --- a/linera-service-graphql-client/src/service.rs +++ b/linera-service-graphql-client/src/service.rs @@ -60,15 +60,16 @@ mod types { #[cfg(not(target_arch = "wasm32"))] mod types { - pub use linera_base::{identifiers::ChannelFullName, ownership::ChainOwnership}; + pub use linera_base::{ + data_types::UserApplicationDescription, identifiers::ChannelFullName, + ownership::ChainOwnership, + }; pub use linera_chain::{ data_types::{MessageAction, MessageBundle, Origin, Target}, manager::ChainManager, }; pub use linera_core::worker::{Notification, Reason}; - pub use linera_execution::{ - committee::Epoch, Message, MessageKind, Operation, UserApplicationDescription, - }; + pub use linera_execution::{committee::Epoch, Message, MessageKind, Operation}; } pub use types::*; diff --git a/linera-service/src/node_service.rs b/linera-service/src/node_service.rs index d12fcf2ed8a1..db04d82ff375 100644 --- a/linera-service/src/node_service.rs +++ b/linera-service/src/node_service.rs @@ -15,7 +15,7 @@ use axum::{extract::Path, http::StatusCode, response, response::IntoResponse, Ex use futures::{lock::Mutex, Future}; use linera_base::{ crypto::{CryptoError, CryptoHash}, - data_types::{Amount, ApplicationPermissions, Bytecode, TimeDelta}, + data_types::{Amount, ApplicationPermissions, Bytecode, TimeDelta, UserApplicationDescription}, ensure, hashed::Hashed, identifiers::{ApplicationId, BytecodeId, ChainId, Owner, UserApplicationId}, @@ -36,7 +36,7 @@ use linera_core::{ use linera_execution::{ committee::{Committee, Epoch}, system::{AdminOperation, Recipient, SystemChannel}, - Operation, Query, QueryOutcome, QueryResponse, SystemOperation, UserApplicationDescription, + Operation, Query, QueryOutcome, QueryResponse, SystemOperation, }; use linera_sdk::base::BlobContent; use linera_storage::Storage; diff --git a/linera-storage/src/lib.rs b/linera-storage/src/lib.rs index ef07060fb93d..3474a387bce0 100644 --- a/linera-storage/src/lib.rs +++ b/linera-storage/src/lib.rs @@ -13,7 +13,10 @@ use async_trait::async_trait; use dashmap::{mapref::entry::Entry, DashMap}; use linera_base::{ crypto::CryptoHash, - data_types::{Amount, Blob, BlockHeight, CompressedBytecode, TimeDelta, Timestamp}, + data_types::{ + Amount, Blob, BlockHeight, CompressedBytecode, TimeDelta, Timestamp, + UserApplicationDescription, + }, hashed::Hashed, identifiers::{BlobId, BlobType, ChainDescription, ChainId, EventId, Owner, UserApplicationId}, ownership::ChainOwnership, @@ -29,7 +32,7 @@ use linera_execution::{ committee::{Committee, Epoch}, system::SystemChannel, BlobState, ChannelSubscription, ExecutionError, ExecutionRuntimeConfig, - ExecutionRuntimeContext, UserApplicationDescription, UserContractCode, UserServiceCode, + ExecutionRuntimeContext, UserContractCode, UserServiceCode, }; #[cfg(with_wasm_runtime)] use linera_execution::{WasmContractModule, WasmServiceModule}; From 276a03f38dfbcf15cfe35e49756734b6758c2041 Mon Sep 17 00:00:00 2001 From: Mathieu Dutour Sikiric Date: Sun, 23 Feb 2025 12:09:12 +0100 Subject: [PATCH 13/16] Revert several changes, make WasmRuntime / EvmRuntime back to linera_execution. --- CLI.md | 1 + Cargo.lock | 1 + examples/Cargo.lock | 1 + linera-base/Cargo.toml | 3 - linera-base/build.rs | 4 +- linera-base/src/vm.rs | 108 +--------------- linera-client/src/client_options.rs | 7 +- linera-client/src/storage.rs | 61 ++++++--- linera-core/Cargo.toml | 3 +- linera-core/src/unit_tests/client_tests.rs | 50 ++++---- linera-core/src/unit_tests/test_utils.rs | 117 +++++++++++++++++- .../src/unit_tests/wasm_client_tests.rs | 107 +++++++--------- .../src/unit_tests/wasm_worker_tests.rs | 14 +-- linera-core/src/unit_tests/worker_tests.rs | 1 + linera-execution/Cargo.toml | 4 +- linera-execution/build.rs | 5 +- linera-execution/src/lib.rs | 97 +++++++++++---- linera-execution/src/revm.rs | 4 +- linera-execution/src/test_utils/mod.rs | 3 +- linera-execution/src/wasm/mod.rs | 40 ++---- linera-execution/tests/wasm.rs | 4 +- linera-rpc/tests/format.rs | 4 +- .../tests/snapshots/format__format.yaml.snap | 22 +--- linera-sdk/Cargo.toml | 2 - .../src/contract/conversions_from_wit.rs | 27 +--- linera-sdk/src/contract/conversions_to_wit.rs | 27 +--- .../src/service/conversions_from_wit.rs | 27 +--- linera-sdk/src/service/conversions_to_wit.rs | 27 +--- linera-sdk/src/test/validator.rs | 4 +- linera-sdk/wit/contract-system-api.wit | 17 +-- linera-sdk/wit/service-system-api.wit | 17 +-- linera-service/src/linera/main.rs | 15 +-- linera-service/src/proxy/main.rs | 1 + linera-service/src/schema_export.rs | 2 +- linera-service/src/server.rs | 9 +- linera-storage/src/db_storage.rs | 21 +++- linera-storage/src/lib.rs | 36 ++++-- 37 files changed, 427 insertions(+), 466 deletions(-) diff --git a/CLI.md b/CLI.md index cdc306d2b8d1..98e837695ff8 100644 --- a/CLI.md +++ b/CLI.md @@ -117,6 +117,7 @@ A Byzantine-fault tolerant sidechain with low-latency finality and high throughp * `--max-pending-message-bundles ` — The maximum number of incoming message bundles to include in a block proposal Default value: `10` +* `--wasm-runtime ` — The WebAssembly runtime to use * `--max-loaded-chains ` — The maximal number of chains loaded in memory at a given time Default value: `40` diff --git a/Cargo.lock b/Cargo.lock index a979153a0b07..1f4b7e2a3319 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4601,6 +4601,7 @@ dependencies = [ "clap", "custom_debug_derive", "dashmap 5.5.3", + "derive_more", "dyn-clone", "futures", "hex", diff --git a/examples/Cargo.lock b/examples/Cargo.lock index 6e0e56ccda8f..2e2f49721b55 100644 --- a/examples/Cargo.lock +++ b/examples/Cargo.lock @@ -3621,6 +3621,7 @@ dependencies = [ "clap", "custom_debug_derive", "dashmap 5.5.3", + "derive_more", "dyn-clone", "futures", "linera-base", diff --git a/linera-base/Cargo.toml b/linera-base/Cargo.toml index 95c900e706f9..9198df101708 100644 --- a/linera-base/Cargo.toml +++ b/linera-base/Cargo.toml @@ -12,9 +12,6 @@ repository.workspace = true version.workspace = true [features] -wasmer = [] -wasmtime = [] -revm = [] metrics = ["prometheus"] reqwest = ["dep:reqwest"] test = ["test-strategy", "proptest"] diff --git a/linera-base/build.rs b/linera-base/build.rs index 93bd8a7e56a7..de990fb6208c 100644 --- a/linera-base/build.rs +++ b/linera-base/build.rs @@ -8,9 +8,7 @@ fn main() { with_metrics: { all(not(target_arch = "wasm32"), feature = "metrics") }, with_reqwest: { feature = "reqwest" }, with_testing: { any(test, feature = "test") }, - with_revm: { feature = "revm" }, - with_wasmer: { feature = "wasmer" }, - with_wasmtime: { all(not(target_arch = "wasm32"), feature = "wasmtime") }, + // the old version of `getrandom` we pin here is available on all targets, but // using it will panic if no suitable source of entropy is found with_getrandom: { any(web, not(target_arch = "wasm32")) }, diff --git a/linera-base/src/vm.rs b/linera-base/src/vm.rs index a6a54fa608ea..363d545e678d 100644 --- a/linera-base/src/vm.rs +++ b/linera-base/src/vm.rs @@ -11,89 +11,10 @@ use linera_witty::{WitLoad, WitStore, WitType}; use serde::{Deserialize, Serialize}; use thiserror::Error; -/// The runtime to use for running the application. -#[derive( - Clone, - Copy, - Display, - Hash, - PartialEq, - Eq, - PartialOrd, - Ord, - Serialize, - Deserialize, - WitType, - WitStore, - WitLoad, - Debug, -)] -#[cfg_attr(with_testing, derive(test_strategy::Arbitrary))] -pub enum WasmRuntime { - /// The choice of the Wasmer runtime for WebAssembly - #[display("wasmer")] - Wasmer, - /// The choice of the Wasmtime runtime for WebAssembly - #[display("wasmtime")] - Wasmtime, - /// The choice of the Wasmer with sanitizer runtime for WebAssembly - WasmerWithSanitizer, - /// The choice of the Wasmtime with sanitizer runtime for WebAssembly - WasmtimeWithSanitizer, -} - -impl WasmRuntime { - /// Returns whether we need a stabilizer or not. - pub fn needs_sanitizer(self) -> bool { - matches!( - self, - WasmRuntime::WasmerWithSanitizer | WasmRuntime::WasmtimeWithSanitizer - ) - } -} - -impl FromStr for WasmRuntime { - type Err = InvalidVmRuntime; - - fn from_str(string: &str) -> Result { - match string { - "wasmer" => Ok(WasmRuntime::Wasmer), - "wasmtime" => Ok(WasmRuntime::Wasmtime), - unknown => Err(InvalidVmRuntime(unknown.to_owned())), - } - } -} - -scalar!(WasmRuntime); - -#[derive( - Clone, - Copy, - Debug, - Display, - Hash, - PartialEq, - Eq, - PartialOrd, - Ord, - Serialize, - Deserialize, - WitType, - WitStore, - WitLoad, -)] -#[cfg_attr(with_testing, derive(test_strategy::Arbitrary))] -/// The choice of runtime for handling the Evm. -pub enum EvmRuntime { - /// The choice of the Revm runtime for Evm. - Revm, -} - -scalar!(EvmRuntime); - #[derive( Clone, Copy, + Default, Display, Hash, PartialEq, @@ -111,9 +32,10 @@ scalar!(EvmRuntime); /// The virtual machine runtime pub enum VmRuntime { /// The Wasm for the virtual machine - Wasm(WasmRuntime), + #[default] + Wasm, /// The Evm for the virtual machine - Evm(EvmRuntime), + Evm, } impl FromStr for VmRuntime { @@ -121,9 +43,8 @@ impl FromStr for VmRuntime { fn from_str(string: &str) -> Result { match string { - "wasmer" => Ok(VmRuntime::Wasm(WasmRuntime::Wasmer)), - "wasmtime" => Ok(VmRuntime::Wasm(WasmRuntime::Wasmtime)), - "revm" => Ok(VmRuntime::Evm(EvmRuntime::Revm)), + "wasm" => Ok(VmRuntime::Wasm), + "revm" => Ok(VmRuntime::Evm), unknown => Err(InvalidVmRuntime(unknown.to_owned())), } } @@ -131,23 +52,6 @@ impl FromStr for VmRuntime { scalar!(VmRuntime); -#[cfg(with_testing)] -impl Default for VmRuntime { - fn default() -> Self { - cfg_if::cfg_if! { - if #[cfg(with_wasmer)] { - VmRuntime::Wasm(WasmRuntime::Wasmer) - } else if #[cfg(with_wasmtime)] { - VmRuntime::Wasm(WasmRuntime::Wasmtime) - } else if #[cfg(with_revm)] { - VmRuntime::Evm(EvmRuntime::Revm) - } else { - panic!("Cannot call default for VmRuntime without wasmer, or wasmtime or revm features"); - } - } - } -} - /// Attempts to create an invalid [`VmRuntime`] instance from a string. #[derive(Clone, Debug, Error)] #[error("{0:?} is not a valid virtual machine runtime")] diff --git a/linera-client/src/client_options.rs b/linera-client/src/client_options.rs index e3be71adf514..3fd7d0ec3c80 100644 --- a/linera-client/src/client_options.rs +++ b/linera-client/src/client_options.rs @@ -20,7 +20,7 @@ use linera_base::{ vm::VmRuntime, }; use linera_core::{client::BlanketMessagePolicy, DEFAULT_GRACE_PERIOD}; -use linera_execution::ResourceControlPolicy; +use linera_execution::{ResourceControlPolicy, WasmRuntime, WithWasmDefault as _}; use linera_views::store::CommonStoreConfig; #[cfg(feature = "fs")] @@ -97,6 +97,10 @@ pub struct ClientOptions { #[arg(long, default_value = "10")] pub max_pending_message_bundles: usize, + /// The WebAssembly runtime to use. + #[arg(long)] + pub wasm_runtime: Option, + /// The maximal number of chains loaded in memory at a given time. #[arg(long, default_value = "40")] pub max_loaded_chains: NonZeroUsize, @@ -199,6 +203,7 @@ impl ClientOptions { .add_common_config(self.common_config()) .await?, &genesis_config, + self.wasm_runtime.with_wasm_default(), job, )) .await?; diff --git a/linera-client/src/storage.rs b/linera-client/src/storage.rs index c27c757852bd..493b17fd116f 100644 --- a/linera-client/src/storage.rs +++ b/linera-client/src/storage.rs @@ -5,6 +5,7 @@ use std::{fmt, str::FromStr}; use async_trait::async_trait; use linera_base::identifiers::{BlobId, ChainId}; +use linera_execution::WasmRuntime; #[cfg(with_storage)] use linera_storage::{list_all_blob_ids, list_all_chain_ids}; use linera_storage::{DbStorage, Storage}; @@ -636,6 +637,7 @@ pub trait Runnable { pub async fn run_with_storage( config: StoreConfig, genesis_config: &GenesisConfig, + wasm_runtime: Option, job: Job, ) -> Result where @@ -645,29 +647,37 @@ where StoreConfig::Memory(config, namespace) => { let store_config = MemoryStoreConfig::new(config.common_config.max_stream_queries); let mut storage = - DbStorage::::new(store_config, &namespace, ROOT_KEY).await?; + DbStorage::::new(store_config, &namespace, ROOT_KEY, wasm_runtime) + .await?; genesis_config.initialize_storage(&mut storage).await?; Ok(job.run(storage).await) } #[cfg(feature = "storage-service")] StoreConfig::Service(config, namespace) => { let storage = - DbStorage::::new(config, &namespace, ROOT_KEY).await?; + DbStorage::::new(config, &namespace, ROOT_KEY, wasm_runtime) + .await?; Ok(job.run(storage).await) } #[cfg(feature = "rocksdb")] StoreConfig::RocksDb(config, namespace) => { - let storage = DbStorage::::new(config, &namespace, ROOT_KEY).await?; + let storage = + DbStorage::::new(config, &namespace, ROOT_KEY, wasm_runtime) + .await?; Ok(job.run(storage).await) } #[cfg(feature = "dynamodb")] StoreConfig::DynamoDb(config, namespace) => { - let storage = DbStorage::::new(config, &namespace, ROOT_KEY).await?; + let storage = + DbStorage::::new(config, &namespace, ROOT_KEY, wasm_runtime) + .await?; Ok(job.run(storage).await) } #[cfg(feature = "scylladb")] StoreConfig::ScyllaDb(config, namespace) => { - let storage = DbStorage::::new(config, &namespace, ROOT_KEY).await?; + let storage = + DbStorage::::new(config, &namespace, ROOT_KEY, wasm_runtime) + .await?; Ok(job.run(storage).await) } } @@ -684,27 +694,50 @@ pub async fn full_initialize_storage( )), #[cfg(feature = "storage-service")] StoreConfig::Service(config, namespace) => { - let mut storage = - DbStorage::::initialize(config, &namespace, ROOT_KEY) - .await?; + let wasm_runtime = None; + let mut storage = DbStorage::::initialize( + config, + &namespace, + ROOT_KEY, + wasm_runtime, + ) + .await?; Ok(genesis_config.initialize_storage(&mut storage).await?) } #[cfg(feature = "rocksdb")] StoreConfig::RocksDb(config, namespace) => { - let mut storage = - DbStorage::::initialize(config, &namespace, ROOT_KEY).await?; + let wasm_runtime = None; + let mut storage = DbStorage::::initialize( + config, + &namespace, + ROOT_KEY, + wasm_runtime, + ) + .await?; Ok(genesis_config.initialize_storage(&mut storage).await?) } #[cfg(feature = "dynamodb")] StoreConfig::DynamoDb(config, namespace) => { - let mut storage = - DbStorage::::initialize(config, &namespace, ROOT_KEY).await?; + let wasm_runtime = None; + let mut storage = DbStorage::::initialize( + config, + &namespace, + ROOT_KEY, + wasm_runtime, + ) + .await?; Ok(genesis_config.initialize_storage(&mut storage).await?) } #[cfg(feature = "scylladb")] StoreConfig::ScyllaDb(config, namespace) => { - let mut storage = - DbStorage::::initialize(config, &namespace, ROOT_KEY).await?; + let wasm_runtime = None; + let mut storage = DbStorage::::initialize( + config, + &namespace, + ROOT_KEY, + wasm_runtime, + ) + .await?; Ok(genesis_config.initialize_storage(&mut storage).await?) } } diff --git a/linera-core/Cargo.toml b/linera-core/Cargo.toml index 262bed436cb1..593b5bdf554d 100644 --- a/linera-core/Cargo.toml +++ b/linera-core/Cargo.toml @@ -12,11 +12,10 @@ repository.workspace = true version.workspace = true [features] -wasmer = ["linera-execution/wasmer", "linera-storage/wasmer", "linera-base/wasmer"] +wasmer = ["linera-execution/wasmer", "linera-storage/wasmer"] wasmtime = [ "linera-execution/wasmtime", "linera-storage/wasmtime", - "linera-base/wasmtime", ] test = [ "anyhow", diff --git a/linera-core/src/unit_tests/client_tests.rs b/linera-core/src/unit_tests/client_tests.rs index ca52c96365c1..d7f4eed4e42c 100644 --- a/linera-core/src/unit_tests/client_tests.rs +++ b/linera-core/src/unit_tests/client_tests.rs @@ -77,7 +77,7 @@ fn test_listener_is_send() { } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -131,7 +131,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -260,7 +260,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -297,7 +297,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -343,7 +343,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -448,7 +448,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -510,7 +510,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -591,7 +591,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -665,7 +665,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -721,7 +721,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -813,7 +813,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -848,7 +848,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -951,7 +951,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -997,7 +997,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -1091,7 +1091,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -1218,7 +1218,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] #[test_log::test(tokio::test)] async fn test_insufficient_balance(storage_builder: B) -> anyhow::Result<()> where @@ -1256,7 +1256,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -1446,7 +1446,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -1574,7 +1574,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -1821,7 +1821,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -1935,7 +1935,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -2038,7 +2038,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -2074,7 +2074,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] @@ -2180,7 +2180,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] #[test_log::test(tokio::test)] async fn test_message_policy(storage_builder: B) -> anyhow::Result<()> where @@ -2233,7 +2233,7 @@ where } #[test_case(MemoryStorageBuilder::default(); "memory")] -#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::default(); "storage_service"))] +#[cfg_attr(feature = "storage-service", test_case(ServiceStorageBuilder::new().await; "storage_service"))] #[cfg_attr(feature = "rocksdb", test_case(RocksDbStorageBuilder::new().await; "rocks_db"))] #[cfg_attr(feature = "dynamodb", test_case(DynamoDbStorageBuilder::default(); "dynamo_db"))] #[cfg_attr(feature = "scylladb", test_case(ScyllaDbStorageBuilder::default(); "scylla_db"))] diff --git a/linera-core/src/unit_tests/test_utils.rs b/linera-core/src/unit_tests/test_utils.rs index e883b9aeefc5..0dc8145abe5c 100644 --- a/linera-core/src/unit_tests/test_utils.rs +++ b/linera-core/src/unit_tests/test_utils.rs @@ -29,7 +29,7 @@ use linera_chain::{ LiteCertificate, Timeout, ValidatedBlock, }, }; -use linera_execution::{committee::Committee, ResourceControlPolicy}; +use linera_execution::{committee::Committee, ResourceControlPolicy, WasmRuntime}; use linera_storage::{DbStorage, Storage, TestClock}; #[cfg(all(not(target_arch = "wasm32"), feature = "storage-service"))] use linera_storage_service::client::ServiceStoreClient; @@ -1008,6 +1008,7 @@ static ROCKS_DB_SEMAPHORE: Semaphore = Semaphore::const_new(5); pub struct MemoryStorageBuilder { namespace: String, instance_counter: usize, + wasm_runtime: Option, clock: TestClock, } @@ -1023,7 +1024,14 @@ impl StorageBuilder for MemoryStorageBuilder { } let namespace = format!("{}_{}", self.namespace, self.instance_counter); let root_key = &[]; - Ok(DbStorage::new_for_testing(config, &namespace, root_key, self.clock.clone()).await?) + Ok(DbStorage::new_for_testing( + config, + &namespace, + root_key, + self.wasm_runtime, + self.clock.clone(), + ) + .await?) } fn clock(&self) -> &TestClock { @@ -1031,10 +1039,23 @@ impl StorageBuilder for MemoryStorageBuilder { } } +impl MemoryStorageBuilder { + /// Creates a [`MemoryStorageBuilder`] that uses the specified [`WasmRuntime`] to run Wasm + /// applications. + #[allow(dead_code)] + pub fn with_wasm_runtime(wasm_runtime: impl Into>) -> Self { + MemoryStorageBuilder { + wasm_runtime: wasm_runtime.into(), + ..MemoryStorageBuilder::default() + } + } +} + #[cfg(feature = "rocksdb")] pub struct RocksDbStorageBuilder { namespace: String, instance_counter: usize, + wasm_runtime: Option, clock: TestClock, _permit: SemaphorePermit<'static>, } @@ -1045,10 +1066,21 @@ impl RocksDbStorageBuilder { RocksDbStorageBuilder { namespace: String::new(), instance_counter: 0, + wasm_runtime: None, clock: TestClock::default(), _permit: ROCKS_DB_SEMAPHORE.acquire().await.unwrap(), } } + + /// Creates a [`RocksDbStorageBuilder`] that uses the specified [`WasmRuntime`] to run Wasm + /// applications. + #[cfg(any(feature = "wasmer", feature = "wasmtime"))] + pub async fn with_wasm_runtime(wasm_runtime: impl Into>) -> Self { + RocksDbStorageBuilder { + wasm_runtime: wasm_runtime.into(), + ..RocksDbStorageBuilder::new().await + } + } } #[cfg(feature = "rocksdb")] @@ -1064,7 +1096,14 @@ impl StorageBuilder for RocksDbStorageBuilder { } let namespace = format!("{}_{}", self.namespace, self.instance_counter); let root_key = &[]; - Ok(DbStorage::new_for_testing(config, &namespace, root_key, self.clock.clone()).await?) + Ok(DbStorage::new_for_testing( + config, + &namespace, + root_key, + self.wasm_runtime, + self.clock.clone(), + ) + .await?) } fn clock(&self) -> &TestClock { @@ -1077,9 +1116,26 @@ impl StorageBuilder for RocksDbStorageBuilder { pub struct ServiceStorageBuilder { namespace: String, instance_counter: usize, + wasm_runtime: Option, clock: TestClock, } +#[cfg(all(not(target_arch = "wasm32"), feature = "storage-service"))] +impl ServiceStorageBuilder { + /// Creates a `ServiceStorage`. + pub async fn new() -> Self { + Self::with_wasm_runtime(None).await + } + + /// Creates a `ServiceStorage` with the given Wasm runtime. + pub async fn with_wasm_runtime(wasm_runtime: impl Into>) -> Self { + ServiceStorageBuilder { + wasm_runtime: wasm_runtime.into(), + ..ServiceStorageBuilder::default() + } + } +} + #[cfg(all(not(target_arch = "wasm32"), feature = "storage-service"))] #[async_trait] impl StorageBuilder for ServiceStorageBuilder { @@ -1093,7 +1149,14 @@ impl StorageBuilder for ServiceStorageBuilder { } let namespace = format!("{}_{}", self.namespace, self.instance_counter); let root_key = &[]; - Ok(DbStorage::new_for_testing(config, &namespace, root_key, self.clock.clone()).await?) + Ok(DbStorage::new_for_testing( + config, + &namespace, + root_key, + self.wasm_runtime, + self.clock.clone(), + ) + .await?) } fn clock(&self) -> &TestClock { @@ -1106,9 +1169,23 @@ impl StorageBuilder for ServiceStorageBuilder { pub struct DynamoDbStorageBuilder { namespace: String, instance_counter: usize, + wasm_runtime: Option, clock: TestClock, } +#[cfg(feature = "dynamodb")] +impl DynamoDbStorageBuilder { + /// Creates a [`DynamoDbStorageBuilder`] that uses the specified [`WasmRuntime`] to run Wasm + /// applications. + #[allow(dead_code)] + pub fn with_wasm_runtime(wasm_runtime: impl Into>) -> Self { + DynamoDbStorageBuilder { + wasm_runtime: wasm_runtime.into(), + ..DynamoDbStorageBuilder::default() + } + } +} + #[cfg(feature = "dynamodb")] #[async_trait] impl StorageBuilder for DynamoDbStorageBuilder { @@ -1122,7 +1199,14 @@ impl StorageBuilder for DynamoDbStorageBuilder { } let namespace = format!("{}_{}", self.namespace, self.instance_counter); let root_key = &[]; - Ok(DbStorage::new_for_testing(config, &namespace, root_key, self.clock.clone()).await?) + Ok(DbStorage::new_for_testing( + config, + &namespace, + root_key, + self.wasm_runtime, + self.clock.clone(), + ) + .await?) } fn clock(&self) -> &TestClock { @@ -1135,9 +1219,23 @@ impl StorageBuilder for DynamoDbStorageBuilder { pub struct ScyllaDbStorageBuilder { namespace: String, instance_counter: usize, + wasm_runtime: Option, clock: TestClock, } +#[cfg(feature = "scylladb")] +impl ScyllaDbStorageBuilder { + /// Creates a [`ScyllaDbStorageBuilder`] that uses the specified [`WasmRuntime`] to run Wasm + /// applications. + #[allow(dead_code)] + pub fn with_wasm_runtime(wasm_runtime: impl Into>) -> Self { + ScyllaDbStorageBuilder { + wasm_runtime: wasm_runtime.into(), + ..ScyllaDbStorageBuilder::default() + } + } +} + #[cfg(feature = "scylladb")] #[async_trait] impl StorageBuilder for ScyllaDbStorageBuilder { @@ -1151,7 +1249,14 @@ impl StorageBuilder for ScyllaDbStorageBuilder { } let namespace = format!("{}_{}", self.namespace, self.instance_counter); let root_key = &[]; - Ok(DbStorage::new_for_testing(config, &namespace, root_key, self.clock.clone()).await?) + Ok(DbStorage::new_for_testing( + config, + &namespace, + root_key, + self.wasm_runtime, + self.clock.clone(), + ) + .await?) } fn clock(&self) -> &TestClock { diff --git a/linera-core/src/unit_tests/wasm_client_tests.rs b/linera-core/src/unit_tests/wasm_client_tests.rs index 984d54b97fae..0de5b7c07416 100644 --- a/linera-core/src/unit_tests/wasm_client_tests.rs +++ b/linera-core/src/unit_tests/wasm_client_tests.rs @@ -22,7 +22,7 @@ use linera_base::{ data_types::{Amount, Bytecode, Event, OracleResponse, UserApplicationDescription}, identifiers::{AccountOwner, ApplicationId, Destination, Owner, StreamId, StreamName}, ownership::{ChainOwnership, TimeoutConfig}, - vm::{VmRuntime, WasmRuntime}, + vm::VmRuntime, }; use linera_chain::{ data_types::{MessageAction, OutgoingMessage}, @@ -30,7 +30,7 @@ use linera_chain::{ }; use linera_execution::{ ExecutionError, Message, MessageKind, Operation, QueryOutcome, ResourceControlPolicy, - SystemMessage, + SystemMessage, WasmRuntime, }; use serde_json::json; use test_case::test_case; @@ -52,8 +52,7 @@ use crate::client::{ #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime ; "wasmtime"))] #[test_log::test(tokio::test(flavor = "multi_thread"))] async fn test_memory_create_application(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - let vm_runtime = VmRuntime::Wasm(wasm_runtime); - run_test_create_application(MemoryStorageBuilder::default(), vm_runtime).await + run_test_create_application(MemoryStorageBuilder::with_wasm_runtime(wasm_runtime)).await } #[ignore] @@ -62,8 +61,7 @@ async fn test_memory_create_application(wasm_runtime: WasmRuntime) -> anyhow::Re #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime ; "wasmtime"))] #[test_log::test(tokio::test(flavor = "multi_thread"))] async fn test_service_create_application(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - let vm_runtime = VmRuntime::Wasm(wasm_runtime); - run_test_create_application(ServiceStorageBuilder::default(), vm_runtime).await + run_test_create_application(ServiceStorageBuilder::with_wasm_runtime(wasm_runtime).await).await } #[ignore] @@ -72,8 +70,7 @@ async fn test_service_create_application(wasm_runtime: WasmRuntime) -> anyhow::R #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime ; "wasmtime"))] #[test_log::test(tokio::test(flavor = "multi_thread"))] async fn test_rocks_db_create_application(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - let vm_runtime = VmRuntime::Wasm(wasm_runtime); - run_test_create_application(RocksDbStorageBuilder::new().await, vm_runtime).await + run_test_create_application(RocksDbStorageBuilder::with_wasm_runtime(wasm_runtime).await).await } #[ignore] @@ -82,8 +79,7 @@ async fn test_rocks_db_create_application(wasm_runtime: WasmRuntime) -> anyhow:: #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime ; "wasmtime"))] #[test_log::test(tokio::test(flavor = "multi_thread"))] async fn test_dynamo_db_create_application(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - let vm_runtime = VmRuntime::Wasm(wasm_runtime); - run_test_create_application(DynamoDbStorageBuilder::default(), vm_runtime).await + run_test_create_application(DynamoDbStorageBuilder::with_wasm_runtime(wasm_runtime)).await } #[ignore] @@ -92,17 +88,14 @@ async fn test_dynamo_db_create_application(wasm_runtime: WasmRuntime) -> anyhow: #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime ; "wasmtime"))] #[test_log::test(tokio::test(flavor = "multi_thread"))] async fn test_scylla_db_create_application(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - let vm_runtime = VmRuntime::Wasm(wasm_runtime); - run_test_create_application(ScyllaDbStorageBuilder::default(), vm_runtime).await + run_test_create_application(ScyllaDbStorageBuilder::with_wasm_runtime(wasm_runtime)).await } -async fn run_test_create_application( - storage_builder: B, - vm_runtime: VmRuntime, -) -> anyhow::Result<()> +async fn run_test_create_application(storage_builder: B) -> anyhow::Result<()> where B: StorageBuilder, { + let vm_runtime = VmRuntime::Wasm; let (contract_path, service_path) = linera_execution::wasm_test::get_example_bytecode_paths("counter")?; let contract_bytecode = Bytecode::load_from_file(contract_path).await?; @@ -198,8 +191,8 @@ where async fn test_memory_run_application_with_dependency( wasm_runtime: WasmRuntime, ) -> anyhow::Result<()> { - let vm_runtime = VmRuntime::Wasm(wasm_runtime); - run_test_run_application_with_dependency(MemoryStorageBuilder::default(), vm_runtime).await + run_test_run_application_with_dependency(MemoryStorageBuilder::with_wasm_runtime(wasm_runtime)) + .await } #[ignore] @@ -210,8 +203,10 @@ async fn test_memory_run_application_with_dependency( async fn test_service_run_application_with_dependency( wasm_runtime: WasmRuntime, ) -> anyhow::Result<()> { - let vm_runtime = VmRuntime::Wasm(wasm_runtime); - run_test_run_application_with_dependency(ServiceStorageBuilder::default(), vm_runtime).await + run_test_run_application_with_dependency( + ServiceStorageBuilder::with_wasm_runtime(wasm_runtime).await, + ) + .await } #[ignore] @@ -222,8 +217,10 @@ async fn test_service_run_application_with_dependency( async fn test_rocks_db_run_application_with_dependency( wasm_runtime: WasmRuntime, ) -> anyhow::Result<()> { - let vm_runtime = VmRuntime::Wasm(wasm_runtime); - run_test_run_application_with_dependency(RocksDbStorageBuilder::new().await, vm_runtime).await + run_test_run_application_with_dependency( + RocksDbStorageBuilder::with_wasm_runtime(wasm_runtime).await, + ) + .await } #[ignore] @@ -234,8 +231,10 @@ async fn test_rocks_db_run_application_with_dependency( async fn test_dynamo_db_run_application_with_dependency( wasm_runtime: WasmRuntime, ) -> anyhow::Result<()> { - let vm_runtime = VmRuntime::Wasm(wasm_runtime); - run_test_run_application_with_dependency(DynamoDbStorageBuilder::default(), vm_runtime).await + run_test_run_application_with_dependency(DynamoDbStorageBuilder::with_wasm_runtime( + wasm_runtime, + )) + .await } #[ignore] @@ -246,17 +245,17 @@ async fn test_dynamo_db_run_application_with_dependency( async fn test_scylla_db_run_application_with_dependency( wasm_runtime: WasmRuntime, ) -> anyhow::Result<()> { - let vm_runtime = VmRuntime::Wasm(wasm_runtime); - run_test_run_application_with_dependency(ScyllaDbStorageBuilder::default(), vm_runtime).await + run_test_run_application_with_dependency(ScyllaDbStorageBuilder::with_wasm_runtime( + wasm_runtime, + )) + .await } -async fn run_test_run_application_with_dependency( - storage_builder: B, - vm_runtime: VmRuntime, -) -> anyhow::Result<()> +async fn run_test_run_application_with_dependency(storage_builder: B) -> anyhow::Result<()> where B: StorageBuilder, { + let vm_runtime = VmRuntime::Wasm; let mut builder = TestBuilder::new(storage_builder, 4, 1) .await? .with_policy(ResourceControlPolicy::all_categories()); @@ -492,8 +491,7 @@ where #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime ; "wasmtime"))] #[test_log::test(tokio::test)] async fn test_memory_cross_chain_message(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - let vm_runtime = VmRuntime::Wasm(wasm_runtime); - run_test_cross_chain_message(MemoryStorageBuilder::default(), vm_runtime).await + run_test_cross_chain_message(MemoryStorageBuilder::with_wasm_runtime(wasm_runtime)).await } #[ignore] @@ -502,8 +500,7 @@ async fn test_memory_cross_chain_message(wasm_runtime: WasmRuntime) -> anyhow::R #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime ; "wasmtime"))] #[test_log::test(tokio::test)] async fn test_service_cross_chain_message(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - let vm_runtime = VmRuntime::Wasm(wasm_runtime); - run_test_cross_chain_message(ServiceStorageBuilder::default(), vm_runtime).await + run_test_cross_chain_message(ServiceStorageBuilder::with_wasm_runtime(wasm_runtime).await).await } #[ignore] @@ -512,8 +509,7 @@ async fn test_service_cross_chain_message(wasm_runtime: WasmRuntime) -> anyhow:: #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime ; "wasmtime"))] #[test_log::test(tokio::test)] async fn test_rocks_db_cross_chain_message(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - let vm_runtime = VmRuntime::Wasm(wasm_runtime); - run_test_cross_chain_message(RocksDbStorageBuilder::new().await, vm_runtime).await + run_test_cross_chain_message(RocksDbStorageBuilder::with_wasm_runtime(wasm_runtime).await).await } #[ignore] @@ -522,8 +518,7 @@ async fn test_rocks_db_cross_chain_message(wasm_runtime: WasmRuntime) -> anyhow: #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime ; "wasmtime"))] #[test_log::test(tokio::test)] async fn test_dynamo_db_cross_chain_message(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - let vm_runtime = VmRuntime::Wasm(wasm_runtime); - run_test_cross_chain_message(DynamoDbStorageBuilder::default(), vm_runtime).await + run_test_cross_chain_message(DynamoDbStorageBuilder::with_wasm_runtime(wasm_runtime)).await } #[ignore] @@ -532,17 +527,14 @@ async fn test_dynamo_db_cross_chain_message(wasm_runtime: WasmRuntime) -> anyhow #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime ; "wasmtime"))] #[test_log::test(tokio::test)] async fn test_scylla_db_cross_chain_message(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - let vm_runtime = VmRuntime::Wasm(wasm_runtime); - run_test_cross_chain_message(ScyllaDbStorageBuilder::default(), vm_runtime).await + run_test_cross_chain_message(ScyllaDbStorageBuilder::with_wasm_runtime(wasm_runtime)).await } -async fn run_test_cross_chain_message( - storage_builder: B, - vm_runtime: VmRuntime, -) -> anyhow::Result<()> +async fn run_test_cross_chain_message(storage_builder: B) -> anyhow::Result<()> where B: StorageBuilder, { + let vm_runtime = VmRuntime::Wasm; let mut builder = TestBuilder::new(storage_builder, 4, 1) .await? .with_policy(ResourceControlPolicy::all_categories()); @@ -700,8 +692,7 @@ where #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime; "wasmtime"))] #[test_log::test(tokio::test)] async fn test_memory_user_pub_sub_channels(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - let vm_runtime = VmRuntime::Wasm(wasm_runtime); - run_test_user_pub_sub_channels(MemoryStorageBuilder::default(), vm_runtime).await + run_test_user_pub_sub_channels(MemoryStorageBuilder::with_wasm_runtime(wasm_runtime)).await } #[ignore] @@ -710,8 +701,8 @@ async fn test_memory_user_pub_sub_channels(wasm_runtime: WasmRuntime) -> anyhow: #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime; "wasmtime"))] #[test_log::test(tokio::test)] async fn test_service_user_pub_sub_channels(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - let vm_runtime = VmRuntime::Wasm(wasm_runtime); - run_test_user_pub_sub_channels(ServiceStorageBuilder::default(), vm_runtime).await + run_test_user_pub_sub_channels(ServiceStorageBuilder::with_wasm_runtime(wasm_runtime).await) + .await } #[ignore] @@ -720,8 +711,8 @@ async fn test_service_user_pub_sub_channels(wasm_runtime: WasmRuntime) -> anyhow #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime; "wasmtime"))] #[test_log::test(tokio::test)] async fn test_rocks_db_user_pub_sub_channels(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - let vm_runtime = VmRuntime::Wasm(wasm_runtime); - run_test_user_pub_sub_channels(RocksDbStorageBuilder::new().await, vm_runtime).await + run_test_user_pub_sub_channels(RocksDbStorageBuilder::with_wasm_runtime(wasm_runtime).await) + .await } #[ignore] @@ -730,8 +721,7 @@ async fn test_rocks_db_user_pub_sub_channels(wasm_runtime: WasmRuntime) -> anyho #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime; "wasmtime"))] #[test_log::test(tokio::test)] async fn test_dynamo_db_user_pub_sub_channels(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - let vm_runtime = VmRuntime::Wasm(wasm_runtime); - run_test_user_pub_sub_channels(DynamoDbStorageBuilder::default(), vm_runtime).await + run_test_user_pub_sub_channels(DynamoDbStorageBuilder::with_wasm_runtime(wasm_runtime)).await } #[ignore] @@ -740,17 +730,14 @@ async fn test_dynamo_db_user_pub_sub_channels(wasm_runtime: WasmRuntime) -> anyh #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime; "wasmtime"))] #[test_log::test(tokio::test)] async fn test_scylla_db_user_pub_sub_channels(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - let vm_runtime = VmRuntime::Wasm(wasm_runtime); - run_test_user_pub_sub_channels(ScyllaDbStorageBuilder::default(), vm_runtime).await + run_test_user_pub_sub_channels(ScyllaDbStorageBuilder::with_wasm_runtime(wasm_runtime)).await } -async fn run_test_user_pub_sub_channels( - storage_builder: B, - vm_runtime: VmRuntime, -) -> anyhow::Result<()> +async fn run_test_user_pub_sub_channels(storage_builder: B) -> anyhow::Result<()> where B: StorageBuilder, { + let vm_runtime = VmRuntime::Wasm; let mut builder = TestBuilder::new(storage_builder, 4, 1) .await? .with_policy(ResourceControlPolicy::all_categories()); @@ -903,8 +890,8 @@ where #[cfg_attr(feature = "wasmtime", test_case(WasmRuntime::Wasmtime ; "wasmtime"))] #[test_log::test(tokio::test(flavor = "multi_thread"))] async fn test_memory_fuel_limit(wasm_runtime: WasmRuntime) -> anyhow::Result<()> { - let vm_runtime = VmRuntime::Wasm(wasm_runtime); - let storage_builder = MemoryStorageBuilder::default(); + let vm_runtime = VmRuntime::Wasm; + let storage_builder = MemoryStorageBuilder::with_wasm_runtime(wasm_runtime); // Set a fuel limit that is enough to instantiate the application and do one increment // operation, but not ten. let mut builder = diff --git a/linera-core/src/unit_tests/wasm_worker_tests.rs b/linera-core/src/unit_tests/wasm_worker_tests.rs index d36419bf3a32..671688361dc1 100644 --- a/linera-core/src/unit_tests/wasm_worker_tests.rs +++ b/linera-core/src/unit_tests/wasm_worker_tests.rs @@ -23,7 +23,7 @@ use linera_base::{ BytecodeId, ChainDescription, ChainId, Destination, MessageId, UserApplicationId, }, ownership::ChainOwnership, - vm::{VmRuntime, WasmRuntime}, + vm::VmRuntime, }; use linera_chain::{ data_types::{BlockExecutionOutcome, OutgoingMessage}, @@ -35,7 +35,7 @@ use linera_execution::{ system::{SystemMessage, SystemOperation}, test_utils::SystemExecutionState, Message, MessageKind, Operation, OperationContext, ResourceController, TransactionTracker, - WasmContractModule, + WasmContractModule, WasmRuntime, }; use linera_storage::{DbStorage, Storage}; #[cfg(feature = "dynamodb")] @@ -56,7 +56,7 @@ use crate::worker::WorkerError; async fn test_memory_handle_certificates_to_create_application( wasm_runtime: WasmRuntime, ) -> anyhow::Result<()> { - let storage = DbStorage::::make_test_storage().await; + let storage = DbStorage::::make_test_storage(Some(wasm_runtime)).await; run_test_handle_certificates_to_create_application(storage, wasm_runtime).await } @@ -67,7 +67,7 @@ async fn test_memory_handle_certificates_to_create_application( async fn test_rocks_db_handle_certificates_to_create_application( wasm_runtime: WasmRuntime, ) -> anyhow::Result<()> { - let storage = DbStorage::::make_test_storage().await; + let storage = DbStorage::::make_test_storage(Some(wasm_runtime)).await; run_test_handle_certificates_to_create_application(storage, wasm_runtime).await } @@ -78,7 +78,7 @@ async fn test_rocks_db_handle_certificates_to_create_application( async fn test_dynamo_db_handle_certificates_to_create_application( wasm_runtime: WasmRuntime, ) -> anyhow::Result<()> { - let storage = DbStorage::::make_test_storage().await; + let storage = DbStorage::::make_test_storage(Some(wasm_runtime)).await; run_test_handle_certificates_to_create_application(storage, wasm_runtime).await } @@ -89,7 +89,7 @@ async fn test_dynamo_db_handle_certificates_to_create_application( async fn test_scylla_db_handle_certificates_to_create_application( wasm_runtime: WasmRuntime, ) -> anyhow::Result<()> { - let storage = DbStorage::::make_test_storage().await; + let storage = DbStorage::::make_test_storage(Some(wasm_runtime)).await; run_test_handle_certificates_to_create_application(storage, wasm_runtime).await } @@ -100,7 +100,7 @@ async fn run_test_handle_certificates_to_create_application( where S: Storage + Clone + Send + Sync + 'static, { - let vm_runtime = VmRuntime::Wasm(wasm_runtime); + let vm_runtime = VmRuntime::Wasm; let admin_id = ChainDescription::Root(0); let publisher_owner = AccountSecretKey::generate().public().into(); let publisher_chain = ChainDescription::Root(1); diff --git a/linera-core/src/unit_tests/worker_tests.rs b/linera-core/src/unit_tests/worker_tests.rs index 616dc2d69a3c..eeab1f0c2340 100644 --- a/linera-core/src/unit_tests/worker_tests.rs +++ b/linera-core/src/unit_tests/worker_tests.rs @@ -3006,6 +3006,7 @@ async fn test_cross_chain_helper() -> anyhow::Result<()> { store_config, &namespace, root_key, + None, TestClock::new(), ) .await?; diff --git a/linera-execution/Cargo.toml b/linera-execution/Cargo.toml index 78ba5552f8c6..d2d2304f84ee 100644 --- a/linera-execution/Cargo.toml +++ b/linera-execution/Cargo.toml @@ -20,7 +20,6 @@ revm = [ "dep:alloy-sol-types", "dep:hex", "dep:tempfile", - "linera-base/revm", ] fs = ["tokio/fs"] metrics = ["prometheus", "linera-views/metrics"] @@ -29,7 +28,6 @@ wasmer = [ "dep:wasmer", "wasmer/enable-serde", "linera-witty/wasmer", - "linera-base/wasmer", "wasm-encoder", "wasm-instrument", "wasmparser", @@ -37,7 +35,6 @@ wasmer = [ wasmtime = [ "dep:wasmtime", "linera-witty/wasmtime", - "linera-base/wasmtime", "wasm-encoder", "wasmparser", ] @@ -54,6 +51,7 @@ cfg-if.workspace = true clap.workspace = true custom_debug_derive.workspace = true dashmap.workspace = true +derive_more = { workspace = true, features = ["display"] } dyn-clone.workspace = true futures.workspace = true hex = { workspace = true, optional = true } diff --git a/linera-execution/build.rs b/linera-execution/build.rs index 516295bea701..6cecb9aa68d8 100644 --- a/linera-execution/build.rs +++ b/linera-execution/build.rs @@ -9,9 +9,12 @@ fn main() { with_metrics: { all(not(target_arch = "wasm32"), feature = "metrics") }, with_testing: { any(test, feature = "test") }, with_tokio_multi_thread: { not(target_arch = "wasm32") }, - with_revm: { feature = "revm" }, with_wasmer: { feature = "wasmer" }, + with_revm: { feature = "revm" }, with_wasmtime: { all(not(target_arch = "wasm32"), feature = "wasmtime") }, + + // If you change this, don't forget to update `WasmRuntime` and + // `WasmRuntime::default_with_sanitizer` with_wasm_runtime: { any(with_wasmer, with_wasmtime) }, } } diff --git a/linera-execution/src/lib.rs b/linera-execution/src/lib.rs index fad5d3790a5d..88b4181ac0e4 100644 --- a/linera-execution/src/lib.rs +++ b/linera-execution/src/lib.rs @@ -24,19 +24,16 @@ mod transaction_tracker; mod util; mod wasm; -use std::{any::Any, fmt, sync::Arc}; +use std::{any::Any, fmt, str::FromStr, sync::Arc}; use async_graphql::SimpleObject; use async_trait::async_trait; use committee::Epoch; use custom_debug_derive::Debug; use dashmap::DashMap; +use derive_more::Display; #[cfg(web)] use js_sys::wasm_bindgen::JsValue; -#[cfg(all(with_revm, not(with_wasmer), not(with_wasmtime)))] -use linera_base::vm::EvmRuntime; -#[cfg(with_wasm_runtime)] -use linera_base::vm::WasmRuntime; use linera_base::{ abi::Abi, crypto::{BcsHashable, CryptoHash}, @@ -51,7 +48,6 @@ use linera_base::{ }, ownership::ChainOwnership, task, - vm::VmRuntime, }; use linera_views::{batch::Batch, views::ViewError}; use serde::{Deserialize, Serialize}; @@ -1315,32 +1311,83 @@ pub struct BlobState { pub epoch: Epoch, } -/// Trait used to select a default `VmRuntime`, if one is available. -pub trait WithVmDefault { - fn with_vm_default(self) -> Self; +/// The runtime to use for running the application. +#[derive(Clone, Copy, Display)] +#[cfg_attr(with_wasm_runtime, derive(Debug, Default))] +pub enum WasmRuntime { + #[cfg(with_wasmer)] + #[default] + #[display("wasmer")] + Wasmer, + #[cfg(with_wasmtime)] + #[cfg_attr(not(with_wasmer), default)] + #[display("wasmtime")] + Wasmtime, + #[cfg(with_wasmer)] + WasmerWithSanitizer, + #[cfg(with_wasmtime)] + WasmtimeWithSanitizer, } -impl WithVmDefault for Option { - fn with_vm_default(self) -> Self { +#[derive(Clone, Copy, Display)] +#[cfg_attr(with_revm, derive(Debug, Default))] +pub enum EvmRuntime { + #[cfg(with_revm)] + #[default] + #[display("revm")] + Revm, +} + +/// Trait used to select a default `WasmRuntime`, if one is available. +pub trait WithWasmDefault { + fn with_wasm_default(self) -> Self; +} + +impl WasmRuntime { + pub fn needs_sanitizer(self) -> bool { match self { - Some(vm_runtime) => Some(vm_runtime), - None => { - cfg_if::cfg_if! { - if #[cfg(with_wasmer)] { - Some(VmRuntime::Wasm(WasmRuntime::Wasmer)) - } else if #[cfg(with_wasmtime)] { - Some(VmRuntime::Wasm(WasmRuntime::Wasmtime)) - } else if #[cfg(with_revm)] { - Some(VmRuntime::Evm(EvmRuntime::Revm)) - } else { - None - } - } - } + #[cfg(with_wasmer)] + WasmRuntime::WasmerWithSanitizer => true, + #[cfg(with_wasmtime)] + WasmRuntime::WasmtimeWithSanitizer => true, + #[cfg(with_wasm_runtime)] + _ => false, + } + } +} + +impl WithWasmDefault for Option { + fn with_wasm_default(self) -> Self { + #[cfg(with_wasm_runtime)] + { + Some(self.unwrap_or_default()) + } + #[cfg(not(with_wasm_runtime))] + { + None } } } +impl FromStr for WasmRuntime { + type Err = InvalidWasmRuntime; + + fn from_str(string: &str) -> Result { + match string { + #[cfg(with_wasmer)] + "wasmer" => Ok(WasmRuntime::Wasmer), + #[cfg(with_wasmtime)] + "wasmtime" => Ok(WasmRuntime::Wasmtime), + unknown => Err(InvalidWasmRuntime(unknown.to_owned())), + } + } +} + +/// Attempts to create an invalid [`WasmRuntime`] instance from a string. +#[derive(Clone, Debug, Error)] +#[error("{0:?} is not a valid WebAssembly runtime")] +pub struct InvalidWasmRuntime(String); + doc_scalar!(Operation, "An operation to be executed in a block"); doc_scalar!( Message, diff --git a/linera-execution/src/revm.rs b/linera-execution/src/revm.rs index 32dc52b842cb..c5de22bc3c87 100644 --- a/linera-execution/src/revm.rs +++ b/linera-execution/src/revm.rs @@ -9,7 +9,7 @@ use std::{ }; use alloy::primitives::{Address, B256, U256}; -use linera_base::{data_types::Bytecode, ensure, identifiers::StreamName, vm::EvmRuntime}; +use linera_base::{data_types::Bytecode, ensure, identifiers::StreamName}; use linera_views::common::from_bytes_option; use revm::{ db::AccountState, @@ -30,7 +30,7 @@ use { }; use crate::{ - BaseRuntime, Batch, ContractRuntime, ContractSyncRuntimeHandle, ExecutionError, + BaseRuntime, Batch, ContractRuntime, ContractSyncRuntimeHandle, EvmRuntime, ExecutionError, FinalizeContext, MessageContext, OperationContext, QueryContext, ServiceRuntime, ServiceSyncRuntimeHandle, UserContract, UserContractInstance, UserContractModule, UserService, UserServiceInstance, UserServiceModule, ViewError, diff --git a/linera-execution/src/test_utils/mod.rs b/linera-execution/src/test_utils/mod.rs index ff5b474722c7..72b2e133d2e8 100644 --- a/linera-execution/src/test_utils/mod.rs +++ b/linera-execution/src/test_utils/mod.rs @@ -16,6 +16,7 @@ use linera_base::{ identifiers::{ AccountOwner, ApplicationId, BlobId, BlobType, BytecodeId, ChainId, MessageId, Owner, }, + vm::VmRuntime, }; use linera_views::{ context::Context, @@ -32,7 +33,7 @@ use crate::{ ApplicationRegistryView, ExecutionRequest, ExecutionRuntimeContext, ExecutionStateView, MessageContext, OperationContext, QueryContext, ServiceRuntimeEndpoint, ServiceRuntimeRequest, ServiceSyncRuntime, SystemExecutionStateView, TestExecutionRuntimeContext, - UserApplicationDescription, UserApplicationId, VmRuntime, + UserApplicationDescription, UserApplicationId, }; /// Creates a dummy [`UserApplicationDescription`] for use in tests. diff --git a/linera-execution/src/wasm/mod.rs b/linera-execution/src/wasm/mod.rs index a6fbd1ba991f..22119bc449ff 100644 --- a/linera-execution/src/wasm/mod.rs +++ b/linera-execution/src/wasm/mod.rs @@ -20,7 +20,7 @@ mod wasmer; #[cfg(with_wasmtime)] mod wasmtime; -use linera_base::{data_types::Bytecode, vm::WasmRuntime}; +use linera_base::data_types::Bytecode; use thiserror::Error; #[cfg(with_wasmer)] use wasmer::{WasmerContractInstance, WasmerServiceInstance}; @@ -40,7 +40,7 @@ pub use self::{ }; use crate::{ ContractSyncRuntimeHandle, ExecutionError, ServiceSyncRuntimeHandle, UserContractInstance, - UserContractModule, UserServiceInstance, UserServiceModule, + UserContractModule, UserServiceInstance, UserServiceModule, WasmRuntime, }; #[cfg(with_metrics)] @@ -89,23 +89,13 @@ impl WasmContractModule { contract_bytecode }; match runtime { + #[cfg(with_wasmer)] WasmRuntime::Wasmer | WasmRuntime::WasmerWithSanitizer => { - cfg_if::cfg_if! { - if #[cfg(with_wasmer)] { - Self::from_wasmer(contract_bytecode).await - } else { - panic!("Cannot use WasmRuntime::Wasmer when feature wasmer has not been used"); - } - } + Self::from_wasmer(contract_bytecode).await } + #[cfg(with_wasmtime)] WasmRuntime::Wasmtime | WasmRuntime::WasmtimeWithSanitizer => { - cfg_if::cfg_if! { - if #[cfg(with_wasmtime)] { - Self::from_wasmtime(contract_bytecode).await - } else { - panic!("Cannot use WasmRuntime::Wasmtime when feature wasmtime has not been used"); - } - } + Self::from_wasmtime(contract_bytecode).await } } } @@ -166,23 +156,13 @@ impl WasmServiceModule { runtime: WasmRuntime, ) -> Result { match runtime { + #[cfg(with_wasmer)] WasmRuntime::Wasmer | WasmRuntime::WasmerWithSanitizer => { - cfg_if::cfg_if! { - if #[cfg(with_wasmer)] { - Self::from_wasmer(service_bytecode).await - } else { - panic!("Cannot use WasmRuntime::Wasmer when feature wasmer has not been used"); - } - } + Self::from_wasmer(service_bytecode).await } + #[cfg(with_wasmtime)] WasmRuntime::Wasmtime | WasmRuntime::WasmtimeWithSanitizer => { - cfg_if::cfg_if! { - if #[cfg(with_wasmtime)] { - Self::from_wasmtime(service_bytecode).await - } else { - panic!("Cannot use WasmRuntime::Wasmtime when feature wasmtime has not been used"); - } - } + Self::from_wasmtime(service_bytecode).await } } } diff --git a/linera-execution/tests/wasm.rs b/linera-execution/tests/wasm.rs index 1536eb14969b..b85b8a8383c7 100644 --- a/linera-execution/tests/wasm.rs +++ b/linera-execution/tests/wasm.rs @@ -8,13 +8,13 @@ use std::sync::Arc; use linera_base::{ data_types::{Amount, BlockHeight, Timestamp}, identifiers::{Account, ChainDescription, ChainId}, - vm::WasmRuntime, }; use linera_execution::{ test_utils::{create_dummy_user_application_description, SystemExecutionState}, ExecutionOutcome, ExecutionRuntimeConfig, ExecutionRuntimeContext, Operation, OperationContext, Query, QueryContext, QueryOutcome, QueryResponse, RawExecutionOutcome, ResourceControlPolicy, - ResourceController, ResourceTracker, TransactionTracker, WasmContractModule, WasmServiceModule, + ResourceController, ResourceTracker, TransactionTracker, WasmContractModule, WasmRuntime, + WasmServiceModule, }; use linera_views::{context::Context as _, views::View}; use serde_json::json; diff --git a/linera-rpc/tests/format.rs b/linera-rpc/tests/format.rs index 3ad2b0353139..7f91702bc96d 100644 --- a/linera-rpc/tests/format.rs +++ b/linera-rpc/tests/format.rs @@ -7,7 +7,7 @@ use linera_base::{ hashed::Hashed, identifiers::{AccountOwner, BlobType, ChainDescription, Destination, GenericApplicationId}, ownership::ChainOwnership, - vm::{EvmRuntime, VmRuntime, WasmRuntime}, + vm::VmRuntime, }; use linera_chain::{ data_types::{Medium, MessageAction}, @@ -41,8 +41,6 @@ fn get_registry() -> Result { tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; - tracer.trace_type::(&samples)?; - tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; diff --git a/linera-rpc/tests/snapshots/format__format.yaml.snap b/linera-rpc/tests/snapshots/format__format.yaml.snap index 7284d34d0e83..cfe3644b1622 100644 --- a/linera-rpc/tests/snapshots/format__format.yaml.snap +++ b/linera-rpc/tests/snapshots/format__format.yaml.snap @@ -425,10 +425,6 @@ Event: TYPENAME: StreamId - key: BYTES - value: BYTES -EvmRuntime: - ENUM: - 0: - Revm: UNIT GenericApplicationId: ENUM: 0: @@ -1203,20 +1199,6 @@ VersionInfo: VmRuntime: ENUM: 0: - Wasm: - NEWTYPE: - TYPENAME: WasmRuntime + Wasm: UNIT 1: - Evm: - NEWTYPE: - TYPENAME: EvmRuntime -WasmRuntime: - ENUM: - 0: - Wasmer: UNIT - 1: - Wasmtime: UNIT - 2: - WasmerWithSanitizer: UNIT - 3: - WasmtimeWithSanitizer: UNIT + Evm: UNIT diff --git a/linera-sdk/Cargo.toml b/linera-sdk/Cargo.toml index 077e5e1c82c6..ddb11566f509 100644 --- a/linera-sdk/Cargo.toml +++ b/linera-sdk/Cargo.toml @@ -22,14 +22,12 @@ targets = ["wasm32-unknown-unknown", "x86_64-unknown-linux-gnu"] ethereum = ["async-trait", "linera-ethereum"] unstable-oracles = ["linera-core/unstable-oracles", "linera-execution/unstable-oracles"] wasmer = [ - "linera-base/wasmer", "linera-core/wasmer", "linera-execution/wasmer", "linera-storage/wasmer", "linera-witty/wasmer", ] wasmtime = [ - "linera-base/wasmtime", "linera-core/wasmtime", "linera-execution/wasmtime", "linera-storage/wasmtime", diff --git a/linera-sdk/src/contract/conversions_from_wit.rs b/linera-sdk/src/contract/conversions_from_wit.rs index 6c1c9987cba2..d73ee2bc9c18 100644 --- a/linera-sdk/src/contract/conversions_from_wit.rs +++ b/linera-sdk/src/contract/conversions_from_wit.rs @@ -11,7 +11,7 @@ use linera_base::{ ownership::{ ChainOwnership, ChangeApplicationPermissionsError, CloseChainError, TimeoutConfig, }, - vm::{EvmRuntime, VmRuntime, WasmRuntime}, + vm::VmRuntime, }; use super::wit::contract_system_api as wit_system_api; @@ -54,29 +54,8 @@ impl From for BytecodeId { impl From for VmRuntime { fn from(vm_runtime: wit_system_api::VmRuntime) -> Self { match vm_runtime { - wit_system_api::VmRuntime::Wasm(wasm_runtime) => VmRuntime::Wasm(wasm_runtime.into()), - wit_system_api::VmRuntime::Evm(evm_runtime) => VmRuntime::Evm(evm_runtime.into()), - } - } -} - -impl From for WasmRuntime { - fn from(wasm_runtime: wit_system_api::WasmRuntime) -> Self { - match wasm_runtime { - wit_system_api::WasmRuntime::Wasmer => WasmRuntime::Wasmer, - wit_system_api::WasmRuntime::Wasmtime => WasmRuntime::Wasmtime, - wit_system_api::WasmRuntime::WasmerWithSanitizer => WasmRuntime::WasmerWithSanitizer, - wit_system_api::WasmRuntime::WasmtimeWithSanitizer => { - WasmRuntime::WasmtimeWithSanitizer - } - } - } -} - -impl From for EvmRuntime { - fn from(evm_runtime: wit_system_api::EvmRuntime) -> Self { - match evm_runtime { - wit_system_api::EvmRuntime::Revm => EvmRuntime::Revm, + wit_system_api::VmRuntime::Wasm => VmRuntime::Wasm, + wit_system_api::VmRuntime::Evm => VmRuntime::Evm, } } } diff --git a/linera-sdk/src/contract/conversions_to_wit.rs b/linera-sdk/src/contract/conversions_to_wit.rs index 9de3c05f9130..443a8a75ba67 100644 --- a/linera-sdk/src/contract/conversions_to_wit.rs +++ b/linera-sdk/src/contract/conversions_to_wit.rs @@ -15,7 +15,7 @@ use linera_base::{ MessageId, Owner, StreamName, }, ownership::{ChainOwnership, TimeoutConfig}, - vm::{EvmRuntime, VmRuntime, WasmRuntime}, + vm::VmRuntime, }; use super::wit::contract_system_api as wit_system_api; @@ -113,29 +113,8 @@ impl From for wit_system_api::BytecodeId { impl From for wit_system_api::VmRuntime { fn from(vm_runtime: VmRuntime) -> Self { match vm_runtime { - VmRuntime::Wasm(wasm_runtime) => wit_system_api::VmRuntime::Wasm(wasm_runtime.into()), - VmRuntime::Evm(evm_runtime) => wit_system_api::VmRuntime::Evm(evm_runtime.into()), - } - } -} - -impl From for wit_system_api::WasmRuntime { - fn from(wasm_runtime: WasmRuntime) -> Self { - match wasm_runtime { - WasmRuntime::Wasmer => wit_system_api::WasmRuntime::Wasmer, - WasmRuntime::Wasmtime => wit_system_api::WasmRuntime::Wasmtime, - WasmRuntime::WasmerWithSanitizer => wit_system_api::WasmRuntime::WasmerWithSanitizer, - WasmRuntime::WasmtimeWithSanitizer => { - wit_system_api::WasmRuntime::WasmtimeWithSanitizer - } - } - } -} - -impl From for wit_system_api::EvmRuntime { - fn from(evm_runtime: EvmRuntime) -> Self { - match evm_runtime { - EvmRuntime::Revm => wit_system_api::EvmRuntime::Revm, + VmRuntime::Wasm => wit_system_api::VmRuntime::Wasm, + VmRuntime::Evm => wit_system_api::VmRuntime::Evm, } } } diff --git a/linera-sdk/src/service/conversions_from_wit.rs b/linera-sdk/src/service/conversions_from_wit.rs index b5ecf6f25337..0efdc50cc583 100644 --- a/linera-sdk/src/service/conversions_from_wit.rs +++ b/linera-sdk/src/service/conversions_from_wit.rs @@ -8,7 +8,7 @@ use linera_base::{ data_types::{Amount, BlockHeight, Timestamp}, http, identifiers::{AccountOwner, ApplicationId, BytecodeId, ChainId, MessageId, Owner}, - vm::{EvmRuntime, VmRuntime, WasmRuntime}, + vm::VmRuntime, }; use super::wit::service_system_api as wit_system_api; @@ -99,29 +99,8 @@ impl From for BytecodeId { impl From for VmRuntime { fn from(vm_runtime: wit_system_api::VmRuntime) -> Self { match vm_runtime { - wit_system_api::VmRuntime::Wasm(wasm_runtime) => VmRuntime::Wasm(wasm_runtime.into()), - wit_system_api::VmRuntime::Evm(evm_runtime) => VmRuntime::Evm(evm_runtime.into()), - } - } -} - -impl From for WasmRuntime { - fn from(wasm_runtime: wit_system_api::WasmRuntime) -> Self { - match wasm_runtime { - wit_system_api::WasmRuntime::Wasmer => WasmRuntime::Wasmer, - wit_system_api::WasmRuntime::Wasmtime => WasmRuntime::Wasmtime, - wit_system_api::WasmRuntime::WasmerWithSanitizer => WasmRuntime::WasmerWithSanitizer, - wit_system_api::WasmRuntime::WasmtimeWithSanitizer => { - WasmRuntime::WasmtimeWithSanitizer - } - } - } -} - -impl From for EvmRuntime { - fn from(evm_runtime: wit_system_api::EvmRuntime) -> Self { - match evm_runtime { - wit_system_api::EvmRuntime::Revm => EvmRuntime::Revm, + wit_system_api::VmRuntime::Wasm => VmRuntime::Wasm, + wit_system_api::VmRuntime::Evm => VmRuntime::Evm, } } } diff --git a/linera-sdk/src/service/conversions_to_wit.rs b/linera-sdk/src/service/conversions_to_wit.rs index fc7f6086ff5b..11c5b52c46a5 100644 --- a/linera-sdk/src/service/conversions_to_wit.rs +++ b/linera-sdk/src/service/conversions_to_wit.rs @@ -8,7 +8,7 @@ use linera_base::{ data_types::BlockHeight, http, identifiers::{AccountOwner, ApplicationId, BytecodeId, ChainId, MessageId, Owner}, - vm::{EvmRuntime, VmRuntime, WasmRuntime}, + vm::VmRuntime, }; use super::wit::service_system_api as wit_system_api; @@ -95,29 +95,8 @@ impl From for wit_system_api::BytecodeId { impl From for wit_system_api::VmRuntime { fn from(vm_runtime: VmRuntime) -> Self { match vm_runtime { - VmRuntime::Wasm(wasm_runtime) => wit_system_api::VmRuntime::Wasm(wasm_runtime.into()), - VmRuntime::Evm(evm_runtime) => wit_system_api::VmRuntime::Evm(evm_runtime.into()), - } - } -} - -impl From for wit_system_api::WasmRuntime { - fn from(wasm_runtime: WasmRuntime) -> Self { - match wasm_runtime { - WasmRuntime::Wasmer => wit_system_api::WasmRuntime::Wasmer, - WasmRuntime::Wasmtime => wit_system_api::WasmRuntime::Wasmtime, - WasmRuntime::WasmerWithSanitizer => wit_system_api::WasmRuntime::WasmerWithSanitizer, - WasmRuntime::WasmtimeWithSanitizer => { - wit_system_api::WasmRuntime::WasmtimeWithSanitizer - } - } - } -} - -impl From for wit_system_api::EvmRuntime { - fn from(evm_runtime: EvmRuntime) -> Self { - match evm_runtime { - EvmRuntime::Revm => wit_system_api::EvmRuntime::Revm, + VmRuntime::Wasm => wit_system_api::VmRuntime::Wasm, + VmRuntime::Evm => wit_system_api::VmRuntime::Evm, } } } diff --git a/linera-sdk/src/test/validator.rs b/linera-sdk/src/test/validator.rs index b067462b4b27..c1c4440e9548 100644 --- a/linera-sdk/src/test/validator.rs +++ b/linera-sdk/src/test/validator.rs @@ -20,6 +20,7 @@ use linera_core::worker::WorkerState; use linera_execution::{ committee::{Committee, Epoch}, system::{OpenChainConfig, SystemOperation, OPEN_CHAIN_MESSAGE_INDEX}, + WasmRuntime, }; use linera_storage::{DbStorage, Storage, TestClock}; use linera_views::memory::MemoryStore; @@ -68,7 +69,8 @@ impl TestValidator { pub async fn new() -> Self { let key_pair = ValidatorSecretKey::generate(); let committee = Committee::make_simple(vec![key_pair.public()]); - let storage = DbStorage::::make_test_storage() + let wasm_runtime = Some(WasmRuntime::default()); + let storage = DbStorage::::make_test_storage(wasm_runtime) .now_or_never() .expect("execution of DbStorage::new should not await anything"); let clock = storage.clock().clone(); diff --git a/linera-sdk/wit/contract-system-api.wit b/linera-sdk/wit/contract-system-api.wit index 2ea0c822dd4b..16efdd6465b8 100644 --- a/linera-sdk/wit/contract-system-api.wit +++ b/linera-sdk/wit/contract-system-api.wit @@ -106,10 +106,6 @@ interface contract-system-api { subscribers(channel-name), } - enum evm-runtime { - revm, - } - record http-header { name: string, value: list, @@ -198,15 +194,8 @@ interface contract-system-api { type u128 = tuple; - variant vm-runtime { - wasm(wasm-runtime), - evm(evm-runtime), - } - - enum wasm-runtime { - wasmer, - wasmtime, - wasmer-with-sanitizer, - wasmtime-with-sanitizer, + enum vm-runtime { + wasm, + evm, } } diff --git a/linera-sdk/wit/service-system-api.wit b/linera-sdk/wit/service-system-api.wit index 3e853b1a3c67..4b0377738888 100644 --- a/linera-sdk/wit/service-system-api.wit +++ b/linera-sdk/wit/service-system-api.wit @@ -55,10 +55,6 @@ interface service-system-api { part4: u64, } - enum evm-runtime { - revm, - } - record http-header { name: string, value: list, @@ -113,15 +109,8 @@ interface service-system-api { type u128 = tuple; - variant vm-runtime { - wasm(wasm-runtime), - evm(evm-runtime), - } - - enum wasm-runtime { - wasmer, - wasmtime, - wasmer-with-sanitizer, - wasmtime-with-sanitizer, + enum vm-runtime { + wasm, + evm, } } diff --git a/linera-service/src/linera/main.rs b/linera-service/src/linera/main.rs index b390cffc21c6..40d612188dba 100644 --- a/linera-service/src/linera/main.rs +++ b/linera-service/src/linera/main.rs @@ -41,7 +41,7 @@ use linera_core::{ }; use linera_execution::{ committee::{Committee, ValidatorState}, - Message, ResourceControlPolicy, SystemMessage, WithVmDefault as _, + Message, ResourceControlPolicy, SystemMessage, }; use linera_faucet_server::FaucetService; use linera_sdk::base::ValidatorPublicKey; @@ -897,9 +897,7 @@ impl Runnable for Job { let publisher = publisher.unwrap_or_else(|| context.default_chain()); info!("Publishing bytecode on chain {}", publisher); let chain_client = context.make_chain_client(publisher)?; - let vm_runtime = vm_runtime - .with_vm_default() - .expect("A virtual machine to be available"); + let vm_runtime = vm_runtime.unwrap_or_default(); let bytecode_id = context .publish_bytecode(&chain_client, contract, service, vm_runtime) .await?; @@ -1000,10 +998,7 @@ impl Runnable for Job { let chain_client = context.make_chain_client(publisher)?; let parameters = read_json(json_parameters, json_parameters_path)?; let argument = read_json(json_argument, json_argument_path)?; - let vm_runtime = vm_runtime - .with_vm_default() - .expect("A virtual machine should be available"); - + let vm_runtime = vm_runtime.unwrap_or_default(); let bytecode_id = context .publish_bytecode(&chain_client, contract, service, vm_runtime) .await?; @@ -1097,9 +1092,7 @@ impl Runnable for Job { info!("Creating application on chain {}", publisher); let chain_client = context.make_chain_client(publisher)?; - let vm_runtime = vm_runtime - .with_vm_default() - .expect("A virtual machine should be available"); + let vm_runtime = vm_runtime.unwrap_or_default(); let parameters = read_json(json_parameters, json_parameters_path)?; let argument = read_json(json_argument, json_argument_path)?; let project_path = path.unwrap_or_else(|| env::current_dir().unwrap()); diff --git a/linera-service/src/proxy/main.rs b/linera-service/src/proxy/main.rs index 26eb16f77284..7a54b01e7519 100644 --- a/linera-service/src/proxy/main.rs +++ b/linera-service/src/proxy/main.rs @@ -392,6 +392,7 @@ impl ProxyOptions { run_with_storage( full_storage_config, &genesis_config, + None, ProxyContext::from_options(self)?, ) .boxed() diff --git a/linera-service/src/schema_export.rs b/linera-service/src/schema_export.rs index 777ac4138975..6a7228782085 100644 --- a/linera-service/src/schema_export.rs +++ b/linera-service/src/schema_export.rs @@ -210,7 +210,7 @@ async fn main() -> std::io::Result<()> { let store_config = MemoryStoreConfig::new(TEST_MEMORY_MAX_STREAM_QUERIES); let namespace = "schema_export"; let root_key = &[]; - let storage = DbStorage::::initialize(store_config, namespace, root_key) + let storage = DbStorage::::initialize(store_config, namespace, root_key, None) .await .expect("storage"); let config = ChainListenerConfig::default(); diff --git a/linera-service/src/server.rs b/linera-service/src/server.rs index 579332db6346..8618b4a5ce20 100644 --- a/linera-service/src/server.rs +++ b/linera-service/src/server.rs @@ -24,6 +24,7 @@ use linera_client::{ storage::{full_initialize_storage, run_with_storage, Runnable, StorageConfigNamespace}, }; use linera_core::{worker::WorkerState, JoinSetExt as _}; +use linera_execution::{WasmRuntime, WithWasmDefault}; use linera_rpc::{ config::{ CrossChainConfig, NetworkProtocol, NotificationConfig, ShardConfig, ShardId, TlsConfig, @@ -346,6 +347,10 @@ enum ServerCommand { #[arg(long = "grace-period-ms", default_value = "500", value_parser = util::parse_millis)] grace_period: Duration, + /// The WebAssembly runtime to use. + #[arg(long)] + wasm_runtime: Option, + /// The maximal number of chains loaded in memory at a given time. #[arg(long, default_value = "400")] max_loaded_chains: NonZeroUsize, @@ -498,6 +503,7 @@ async fn run(options: ServerOptions) { genesis_config_path, shard, grace_period, + wasm_runtime, max_loaded_chains, max_concurrent_queries, max_stream_queries, @@ -525,6 +531,7 @@ async fn run(options: ServerOptions) { grace_period, max_loaded_chains, }; + let wasm_runtime = wasm_runtime.with_wasm_default(); let common_config = CommonStoreConfig { max_concurrent_queries, max_stream_queries, @@ -534,7 +541,7 @@ async fn run(options: ServerOptions) { .add_common_config(common_config) .await .unwrap(); - run_with_storage(full_storage_config, &genesis_config, job) + run_with_storage(full_storage_config, &genesis_config, wasm_runtime, job) .boxed() .await .unwrap() diff --git a/linera-storage/src/db_storage.rs b/linera-storage/src/db_storage.rs index 8021e54c9845..1fdaa4cde70d 100644 --- a/linera-storage/src/db_storage.rs +++ b/linera-storage/src/db_storage.rs @@ -19,6 +19,7 @@ use linera_chain::{ }; use linera_execution::{ committee::Epoch, BlobState, ExecutionRuntimeConfig, UserContractCode, UserServiceCode, + WasmRuntime, }; use linera_views::{ backends::dual::{DualStoreRootKeyAssignment, StoreInUse}, @@ -260,6 +261,7 @@ impl BatchExt for Batch { pub struct DbStorage { store: Arc, clock: Clock, + wasm_runtime: Option, user_contracts: Arc>, user_services: Arc>, execution_runtime_config: ExecutionRuntimeConfig, @@ -822,6 +824,10 @@ where } self.write_batch(batch).await } + + fn wasm_runtime(&self) -> Option { + self.wasm_runtime + } } impl DbStorage @@ -864,10 +870,11 @@ where Ok(()) } - fn create(store: Store, clock: C) -> Self { + fn create(store: Store, wasm_runtime: Option, clock: C) -> Self { Self { store: Arc::new(store), clock, + wasm_runtime, user_contracts: Arc::new(DashMap::new()), user_services: Arc::new(DashMap::new()), execution_runtime_config: ExecutionRuntimeConfig::default(), @@ -884,18 +891,20 @@ where config: Store::Config, namespace: &str, root_key: &[u8], + wasm_runtime: Option, ) -> Result { let store = Store::maybe_create_and_connect(&config, namespace, root_key).await?; - Ok(Self::create(store, WallClock)) + Ok(Self::create(store, wasm_runtime, WallClock)) } pub async fn new( config: Store::Config, namespace: &str, root_key: &[u8], + wasm_runtime: Option, ) -> Result { let store = Store::connect(&config, namespace, root_key).await?; - Ok(Self::create(store, WallClock)) + Ok(Self::create(store, wasm_runtime, WallClock)) } } @@ -905,7 +914,7 @@ where Store: TestKeyValueStore + Clone + Send + Sync + 'static, Store::Error: Send + Sync, { - pub async fn make_test_storage() -> Self { + pub async fn make_test_storage(wasm_runtime: Option) -> Self { let config = Store::new_test_config().await.unwrap(); let namespace = generate_test_namespace(); let root_key = &[]; @@ -913,6 +922,7 @@ where config, &namespace, root_key, + wasm_runtime, TestClock::new(), ) .await @@ -923,9 +933,10 @@ where config: Store::Config, namespace: &str, root_key: &[u8], + wasm_runtime: Option, clock: TestClock, ) -> Result { let store = Store::recreate_and_connect(&config, namespace, root_key).await?; - Ok(Self::create(store, clock)) + Ok(Self::create(store, wasm_runtime, clock)) } } diff --git a/linera-storage/src/lib.rs b/linera-storage/src/lib.rs index 3474a387bce0..46eb8383806a 100644 --- a/linera-storage/src/lib.rs +++ b/linera-storage/src/lib.rs @@ -26,13 +26,16 @@ use linera_chain::{ types::{ConfirmedBlock, ConfirmedBlockCertificate}, ChainError, ChainStateView, }; -#[cfg(with_revm)] -use linera_execution::revm::{EvmContractModule, EvmServiceModule}; use linera_execution::{ committee::{Committee, Epoch}, system::SystemChannel, BlobState, ChannelSubscription, ExecutionError, ExecutionRuntimeConfig, - ExecutionRuntimeContext, UserContractCode, UserServiceCode, + ExecutionRuntimeContext, UserContractCode, UserServiceCode, WasmRuntime, +}; +#[cfg(with_revm)] +use linera_execution::{ + revm::{EvmContractModule, EvmServiceModule}, + EvmRuntime, }; #[cfg(with_wasm_runtime)] use linera_execution::{WasmContractModule, WasmServiceModule}; @@ -260,6 +263,9 @@ pub trait Storage: Sized { Ok(()) } + /// Selects the WebAssembly runtime to use for applications (if any). + fn wasm_runtime(&self) -> Option; + /// Creates a [`UserContractCode`] instance using the bytecode in storage referenced /// by the `application_description`. async fn load_contract( @@ -282,10 +288,13 @@ pub trait Storage: Sized { .join() .await?; match application_description.bytecode_id.vm_runtime { - VmRuntime::Wasm(_wasm_runtime) => { + VmRuntime::Wasm => { cfg_if::cfg_if! { if #[cfg(with_wasm_runtime)] { - Ok(WasmContractModule::new(_contract_bytecode, _wasm_runtime) + let Some(wasm_runtime) = self.wasm_runtime() else { + panic!("A Wasm runtime is required to load user applications."); + }; + Ok(WasmContractModule::new(_contract_bytecode, wasm_runtime) .await? .into()) } else { @@ -297,10 +306,11 @@ pub trait Storage: Sized { } } } - VmRuntime::Evm(_evm_runtime) => { + VmRuntime::Evm => { cfg_if::cfg_if! { if #[cfg(with_revm)] { - Ok(EvmContractModule::new(_contract_bytecode, _evm_runtime) + let evm_runtime = EvmRuntime::Revm; + Ok(EvmContractModule::new(_contract_bytecode, evm_runtime) .await? .into()) } else { @@ -337,10 +347,13 @@ pub trait Storage: Sized { .join() .await?; match application_description.bytecode_id.vm_runtime { - VmRuntime::Wasm(_wasm_runtime) => { + VmRuntime::Wasm => { cfg_if::cfg_if! { if #[cfg(with_wasm_runtime)] { - Ok(WasmServiceModule::new(_service_bytecode, _wasm_runtime) + let Some(wasm_runtime) = self.wasm_runtime() else { + panic!("A Wasm runtime is required to load user applications."); + }; + Ok(WasmServiceModule::new(_service_bytecode, wasm_runtime) .await? .into()) } else { @@ -352,10 +365,11 @@ pub trait Storage: Sized { } } } - VmRuntime::Evm(_evm_runtime) => { + VmRuntime::Evm => { cfg_if::cfg_if! { if #[cfg(with_revm)] { - Ok(EvmServiceModule::new(_service_bytecode, _evm_runtime) + let evm_runtime = EvmRuntime::Revm; + Ok(EvmServiceModule::new(_service_bytecode, evm_runtime) .await? .into()) } else { From 945287acbba73d4c73437d08fba6539a84660239 Mon Sep 17 00:00:00 2001 From: Mathieu Dutour Sikiric Date: Sun, 23 Feb 2025 12:22:11 +0100 Subject: [PATCH 14/16] Correction after commit. --- linera-core/Cargo.toml | 5 +---- linera-execution/src/wasm/mod.rs | 13 +------------ linera-service/src/node_service.rs | 1 - 3 files changed, 2 insertions(+), 17 deletions(-) diff --git a/linera-core/Cargo.toml b/linera-core/Cargo.toml index 593b5bdf554d..79495233c0c8 100644 --- a/linera-core/Cargo.toml +++ b/linera-core/Cargo.toml @@ -13,10 +13,7 @@ version.workspace = true [features] wasmer = ["linera-execution/wasmer", "linera-storage/wasmer"] -wasmtime = [ - "linera-execution/wasmtime", - "linera-storage/wasmtime", -] +wasmtime = ["linera-execution/wasmtime", "linera-storage/wasmtime"] test = [ "anyhow", "linera-base/test", diff --git a/linera-execution/src/wasm/mod.rs b/linera-execution/src/wasm/mod.rs index 22119bc449ff..896b32c33cd7 100644 --- a/linera-execution/src/wasm/mod.rs +++ b/linera-execution/src/wasm/mod.rs @@ -346,18 +346,7 @@ pub mod test { wasm_runtime: impl Into>, ) -> Result<(WasmContractModule, WasmServiceModule), anyhow::Error> { let (contract_path, service_path) = get_example_bytecode_paths(name)?; - let wasm_runtime = match wasm_runtime.into() { - Some(wasm_runtime) => wasm_runtime, - None => { - cfg_if::cfg_if! { - if #[cfg(with_wasmer)] { - WasmRuntime::Wasmer - } else { - WasmRuntime::Wasmtime - } - } - } - }; + let wasm_runtime = wasm_runtime.into().unwrap_or_default(); let contract = WasmContractModule::from_file(&contract_path, wasm_runtime).await?; let service = WasmServiceModule::from_file(&service_path, wasm_runtime).await?; Ok((contract, service)) diff --git a/linera-service/src/node_service.rs b/linera-service/src/node_service.rs index db04d82ff375..ea10a84180bc 100644 --- a/linera-service/src/node_service.rs +++ b/linera-service/src/node_service.rs @@ -599,7 +599,6 @@ where } /// Creates a new application. - #[allow(clippy::too_many_arguments)] async fn create_application( &self, chain_id: ChainId, From 30c363b3365f8da48272f36ab9119e47edd8d525 Mon Sep 17 00:00:00 2001 From: Mathieu Dutour Sikiric Date: Sun, 23 Feb 2025 19:32:05 +0100 Subject: [PATCH 15/16] Changes from the Reviewing process. --- linera-base/src/unit_tests.rs | 4 ++-- linera-chain/src/unit_tests/chain_tests.rs | 2 +- linera-client/src/client_options.rs | 12 ++++++------ linera-execution/src/test_utils/mod.rs | 2 +- .../src/unit_tests/applications_tests.rs | 2 +- linera-execution/src/unit_tests/runtime_tests.rs | 2 +- linera-execution/src/unit_tests/system_tests.rs | 2 +- linera-execution/tests/contract_runtime_apis.rs | 4 ++-- linera-sdk/src/test/chain.rs | 2 +- linera-service/src/linera/main.rs | 3 --- linera-service/tests/linera_net_tests.rs | 4 ++-- 11 files changed, 18 insertions(+), 21 deletions(-) diff --git a/linera-base/src/unit_tests.rs b/linera-base/src/unit_tests.rs index 8f60fc3be327..e9e5d9371147 100644 --- a/linera-base/src/unit_tests.rs +++ b/linera-base/src/unit_tests.rs @@ -104,7 +104,7 @@ fn application_id_test_case() -> ApplicationId { bytecode_id: BytecodeId::new( CryptoHash::test_hash("contract bytecode"), CryptoHash::test_hash("service bytecode"), - VmRuntime::default(), + VmRuntime::Wasm, ), creation: MessageId { chain_id: ChainId::root(0), @@ -119,7 +119,7 @@ fn bytecode_id_test_case() -> BytecodeId { BytecodeId::new( CryptoHash::test_hash("another contract bytecode"), CryptoHash::test_hash("another service bytecode"), - VmRuntime::default(), + VmRuntime::Wasm, ) } diff --git a/linera-chain/src/unit_tests/chain_tests.rs b/linera-chain/src/unit_tests/chain_tests.rs index 1ba983d7c3d2..9dd6beaabfd4 100644 --- a/linera-chain/src/unit_tests/chain_tests.rs +++ b/linera-chain/src/unit_tests/chain_tests.rs @@ -67,7 +67,7 @@ fn make_app_description() -> (UserApplicationDescription, Blob, Blob) { let service = Bytecode::new(b"service".into()); let contract_blob = Blob::new_contract_bytecode(contract.compress()); let service_blob = Blob::new_service_bytecode(service.compress()); - let vm_runtime = VmRuntime::default(); + let vm_runtime = VmRuntime::Wasm; let bytecode_id = BytecodeId::new(contract_blob.id().hash, service_blob.id().hash, vm_runtime); ( diff --git a/linera-client/src/client_options.rs b/linera-client/src/client_options.rs index 3fd7d0ec3c80..425a4e90371f 100644 --- a/linera-client/src/client_options.rs +++ b/linera-client/src/client_options.rs @@ -775,8 +775,8 @@ pub enum ClientCommand { service: PathBuf, /// The virtual machine runtime to use. - #[arg(long)] - vm_runtime: Option, + #[arg(long, default_value = "wasm")] + vm_runtime: VmRuntime, /// An optional chain ID to publish the bytecode. The default chain of the wallet /// is used otherwise. @@ -841,8 +841,8 @@ pub enum ClientCommand { service: PathBuf, /// The virtual machine runtime to use. - #[arg(long)] - vm_runtime: Option, + #[arg(long, default_value = "wasm")] + vm_runtime: VmRuntime, /// An optional chain ID to publish the bytecode. The default chain of the wallet /// is used otherwise. @@ -1251,8 +1251,8 @@ pub enum ProjectCommand { publisher: Option, /// The virtual machine runtime to use. - #[arg(long)] - vm_runtime: Option, + #[arg(long, default_value = "wasm")] + vm_runtime: VmRuntime, /// The shared parameters as JSON string. #[arg(long)] diff --git a/linera-execution/src/test_utils/mod.rs b/linera-execution/src/test_utils/mod.rs index 72b2e133d2e8..59011ff65768 100644 --- a/linera-execution/src/test_utils/mod.rs +++ b/linera-execution/src/test_utils/mod.rs @@ -48,7 +48,7 @@ pub fn create_dummy_user_application_description( compressed_bytes: b"service".to_vec(), }); - let vm_runtime = VmRuntime::default(); + let vm_runtime = VmRuntime::Wasm; ( UserApplicationDescription { bytecode_id: BytecodeId::new( diff --git a/linera-execution/src/unit_tests/applications_tests.rs b/linera-execution/src/unit_tests/applications_tests.rs index 8e05d1319e04..ce4c4c3b3737 100644 --- a/linera-execution/src/unit_tests/applications_tests.rs +++ b/linera-execution/src/unit_tests/applications_tests.rs @@ -24,7 +24,7 @@ fn bytecode_id() -> BytecodeId { BytecodeId::new( CryptoHash::test_hash("contract"), CryptoHash::test_hash("service"), - VmRuntime::default(), + VmRuntime::Wasm, ) } diff --git a/linera-execution/src/unit_tests/runtime_tests.rs b/linera-execution/src/unit_tests/runtime_tests.rs index aded8fe5a257..38a7241b3bd5 100644 --- a/linera-execution/src/unit_tests/runtime_tests.rs +++ b/linera-execution/src/unit_tests/runtime_tests.rs @@ -211,7 +211,7 @@ fn create_dummy_application_id() -> ApplicationId { bytecode_id: BytecodeId::new( CryptoHash::test_hash("contract"), CryptoHash::test_hash("service"), - VmRuntime::default(), + VmRuntime::Wasm, ), creation: MessageId { chain_id, diff --git a/linera-execution/src/unit_tests/system_tests.rs b/linera-execution/src/unit_tests/system_tests.rs index ef2585293a4f..381e20448831 100644 --- a/linera-execution/src/unit_tests/system_tests.rs +++ b/linera-execution/src/unit_tests/system_tests.rs @@ -45,7 +45,7 @@ async fn application_message_index() -> anyhow::Result<()> { let service = Bytecode::new(b"service".into()); let contract_blob = Blob::new_contract_bytecode(contract.compress()); let service_blob = Blob::new_service_bytecode(service.compress()); - let vm_runtime = VmRuntime::default(); + let vm_runtime = VmRuntime::Wasm; let bytecode_id = BytecodeId::new(contract_blob.id().hash, service_blob.id().hash, vm_runtime); let operation = SystemOperation::CreateApplication { diff --git a/linera-execution/tests/contract_runtime_apis.rs b/linera-execution/tests/contract_runtime_apis.rs index 78d273398560..1c16df5b32a1 100644 --- a/linera-execution/tests/contract_runtime_apis.rs +++ b/linera-execution/tests/contract_runtime_apis.rs @@ -659,7 +659,7 @@ impl TransferTestEndpoint { fn sender_application_description() -> UserApplicationDescription { let contract_id = Self::sender_application_contract_blob().id().hash; let service_id = Self::sender_application_service_blob().id().hash; - let vm_runtime = VmRuntime::default(); + let vm_runtime = VmRuntime::Wasm; UserApplicationDescription { bytecode_id: BytecodeId::new(contract_id, service_id, vm_runtime), @@ -700,7 +700,7 @@ impl TransferTestEndpoint { bytecode_id: BytecodeId::new( CryptoHash::test_hash("recipient contract bytecode"), CryptoHash::test_hash("recipient service bytecode"), - VmRuntime::default(), + VmRuntime::Wasm, ), creation: MessageId { chain_id: ChainId::root(2000), diff --git a/linera-sdk/src/test/chain.rs b/linera-sdk/src/test/chain.rs index fdf4e8312f77..f7f0c6afdbba 100644 --- a/linera-sdk/src/test/chain.rs +++ b/linera-sdk/src/test/chain.rs @@ -215,7 +215,7 @@ impl ActiveChain { let service_blob = Blob::new_service_bytecode(service); let contract_blob_hash = contract_blob.id().hash; let service_blob_hash = service_blob.id().hash; - let vm_runtime = VmRuntime::default(); + let vm_runtime = VmRuntime::Wasm; let bytecode_id = BytecodeId::new(contract_blob_hash, service_blob_hash, vm_runtime); diff --git a/linera-service/src/linera/main.rs b/linera-service/src/linera/main.rs index 40d612188dba..3cb37ef6a8e5 100644 --- a/linera-service/src/linera/main.rs +++ b/linera-service/src/linera/main.rs @@ -897,7 +897,6 @@ impl Runnable for Job { let publisher = publisher.unwrap_or_else(|| context.default_chain()); info!("Publishing bytecode on chain {}", publisher); let chain_client = context.make_chain_client(publisher)?; - let vm_runtime = vm_runtime.unwrap_or_default(); let bytecode_id = context .publish_bytecode(&chain_client, contract, service, vm_runtime) .await?; @@ -998,7 +997,6 @@ impl Runnable for Job { let chain_client = context.make_chain_client(publisher)?; let parameters = read_json(json_parameters, json_parameters_path)?; let argument = read_json(json_argument, json_argument_path)?; - let vm_runtime = vm_runtime.unwrap_or_default(); let bytecode_id = context .publish_bytecode(&chain_client, contract, service, vm_runtime) .await?; @@ -1092,7 +1090,6 @@ impl Runnable for Job { info!("Creating application on chain {}", publisher); let chain_client = context.make_chain_client(publisher)?; - let vm_runtime = vm_runtime.unwrap_or_default(); let parameters = read_json(json_parameters, json_parameters_path)?; let argument = read_json(json_argument, json_argument_path)?; let project_path = path.unwrap_or_else(|| env::current_dir().unwrap()); diff --git a/linera-service/tests/linera_net_tests.rs b/linera-service/tests/linera_net_tests.rs index 7f3b52101c0a..2d8353558868 100644 --- a/linera-service/tests/linera_net_tests.rs +++ b/linera-service/tests/linera_net_tests.rs @@ -1401,7 +1401,7 @@ async fn test_wasm_end_to_end_matching_engine(config: impl LineraNetConfig) -> R let _guard = INTEGRATION_TEST_GUARD.lock().await; tracing::info!("Starting test {}", test_name!()); - let vm_runtime = VmRuntime::default(); + let vm_runtime = VmRuntime::Wasm; let (mut net, client_admin) = config.instantiate().await?; let client_a = net.make_client().await; @@ -1694,7 +1694,7 @@ async fn test_wasm_end_to_end_amm(config: impl LineraNetConfig) -> Result<()> { let _guard = INTEGRATION_TEST_GUARD.lock().await; tracing::info!("Starting test {}", test_name!()); - let vm_runtime = VmRuntime::default(); + let vm_runtime = VmRuntime::Wasm; let (mut net, client_amm) = config.instantiate().await?; let client0 = net.make_client().await; From f51454bfe7c49229d1b7427af78d308bc8788ed6 Mon Sep 17 00:00:00 2001 From: Mathieu Dutour Sikiric Date: Sun, 23 Feb 2025 19:51:29 +0100 Subject: [PATCH 16/16] Update to the CLI.md --- CLI.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CLI.md b/CLI.md index 98e837695ff8..d671403e68ca 100644 --- a/CLI.md +++ b/CLI.md @@ -614,6 +614,8 @@ Publish bytecode * `--vm-runtime ` — The virtual machine runtime to use + Default value: `wasm` + ## `linera publish-data-blob` @@ -678,6 +680,8 @@ Create an application, and publish the required bytecode ###### **Options:** * `--vm-runtime ` — The virtual machine runtime to use + + Default value: `wasm` * `--json-parameters ` — The shared parameters as JSON string * `--json-parameters-path ` — Path to a JSON file containing the shared parameters * `--json-argument ` — The instantiation argument as a JSON string @@ -884,6 +888,8 @@ Build and publish a Linera project ###### **Options:** * `--vm-runtime ` — The virtual machine runtime to use + + Default value: `wasm` * `--json-parameters ` — The shared parameters as JSON string * `--json-parameters-path ` — Path to a JSON file containing the shared parameters * `--json-argument ` — The instantiation argument as a JSON string