Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions core/backend/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ use gear_sandbox::{
default_executor::{EnvironmentDefinitionBuilder, Instance, Store},
};
use gear_wasm_instrument::{
GLOBAL_NAME_GAS,
syscalls::SyscallName::{self, *},
GLOBAL_NAME_GAS, SyscallKind,
SyscallName::{self, *},
};
#[cfg(feature = "std")]
use {
Expand Down Expand Up @@ -162,10 +162,14 @@ where
EntryPoint: WasmEntryPoint,
{
#[rustfmt::skip]
fn bind_funcs(builder: &mut EnvBuilder<Ext>) {
fn bind_funcs(builder: &mut EnvBuilder<Ext>, syscall_kind: SyscallKind) {
macro_rules! add_function {
($syscall:ident, $func:ident) => {
builder.add_func($syscall, wrap_syscall!($func, $syscall));
match syscall_kind {
SyscallKind::Vara if !$syscall.is_vara_including_system_break() => {},
SyscallKind::Eth if !$syscall.is_eth() => {},
_ => builder.add_func($syscall, wrap_syscall!($func, $syscall)),
}
};
}

Expand Down Expand Up @@ -271,6 +275,7 @@ where
entry_point: EntryPoint,
entries: BTreeSet<DispatchKind>,
mem_size: WasmPagesAmount,
syscall_kind: SyscallKind,
) -> Result<Self, EnvironmentError> {
use EnvironmentError::*;
use SystemEnvironmentError::*;
Expand All @@ -290,14 +295,19 @@ where

builder.add_memory(memory.clone());

Self::bind_funcs(&mut builder);
Self::bind_funcs(&mut builder, syscall_kind);

// Check that we have implementations for all the syscalls.
// This is intended to panic during any testing, when the
// condition is not met.
let expected_count = match syscall_kind {
SyscallKind::Vara => SyscallName::all().count(),
SyscallKind::Eth => SyscallName::all()
.filter(|syscall| syscall.is_eth())
.count(),
};
assert_eq!(
builder.funcs_count,
SyscallName::all().count(),
builder.funcs_count, expected_count,
"Not all existing syscalls were added to the module's env."
);

Expand Down
61 changes: 35 additions & 26 deletions core/backend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,34 +74,43 @@ mod tests {
.with_test_writer()
.init();

// Make module with one empty function.
let mut module = ModuleBuilder::default();
module.add_func(FuncType::new([], []), Function::default());

// Insert syscalls imports.
for name in SyscallName::instrumentable(SyscallKind::Vara) {
let sign = name.signature();
let type_no = module.push_type(sign.func_type());

module.push_import(Import::func("env", name.to_str(), type_no));
}

let module = InstrumentationBuilder::new("env")
.with_gas_limiter(|_| CustomConstantCostRules::default())
.instrument(module.build())
for syscall_kind in [SyscallKind::Vara, SyscallKind::Eth] {
// Make module with one empty function.
let mut module = ModuleBuilder::default();
module.add_func(FuncType::new([], []), Function::default());

// Insert syscalls imports.
for name in SyscallName::instrumentable(syscall_kind) {
let sign = name.signature();
let type_no = module.push_type(sign.func_type());

module.push_import(Import::func("env", name.to_str(), type_no));
}

let module = InstrumentationBuilder::new("env")
.with_gas_limiter(|_| CustomConstantCostRules::default())
.instrument(module.build())
.unwrap();
let code = module.serialize().unwrap();

// Execute wasm and check success.
let ext = MockExt::default();
let env = Environment::new(
ext,
&code,
DispatchKind::Init,
Default::default(),
0.into(),
syscall_kind,
)
.unwrap();
let code = module.serialize().unwrap();

// Execute wasm and check success.
let ext = MockExt::default();
let env =
Environment::new(ext, &code, DispatchKind::Init, Default::default(), 0.into()).unwrap();
let report = env.execute(|_, _, _| {}).unwrap();
let report = env.execute(|_, _, _| {}).unwrap();

let BackendReport {
termination_reason, ..
} = report;
let BackendReport {
termination_reason, ..
} = report;

assert_eq!(termination_reason, ActorTerminationReason::Success.into());
assert_eq!(termination_reason, ActorTerminationReason::Success.into());
}
}
}
4 changes: 3 additions & 1 deletion core/processor/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::{context::SystemReservationContext, precharge::PreChargeGasOperation}
use actor_system_error::actor_system_error;
use alloc::{collections::BTreeMap, string::String, vec::Vec};
use gear_core::{
code::{CodeMetadata, InstrumentedCode},
code::{CodeMetadata, InstrumentedCode, SyscallKind},
env::MessageWaitedType,
gas::{GasAllowanceCounter, GasAmount, GasCounter},
ids::{ActorId, CodeId, MessageId, ReservationId},
Expand Down Expand Up @@ -542,4 +542,6 @@ pub(crate) struct WasmExecutionContext {
pub program: Program,
/// Size of the memory block.
pub memory_size: WasmPagesAmount,
/// What kind of syscall is being executed (Vara or Vara.ETH).
pub syscall_kind: SyscallKind,
}
5 changes: 4 additions & 1 deletion core/processor/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use crate::{
precharge::{ContextCharged, ForModuleInstantiation},
};
use gear_core::{
code::InstrumentedCodeAndMetadata,
code::{InstrumentedCodeAndMetadata, SyscallKind},
gas::{GasAllowanceCounter, GasCounter},
ids::ActorId,
message::IncomingDispatch,
Expand All @@ -41,6 +41,7 @@ pub struct ProcessExecutionContext {
pub(crate) balance: u128,
pub(crate) program: Program,
pub(crate) memory_size: WasmPagesAmount,
pub(crate) syscall_kind: SyscallKind,
}

impl ProcessExecutionContext {
Expand All @@ -49,6 +50,7 @@ impl ProcessExecutionContext {
context: ContextCharged<ForModuleInstantiation>,
instrumented_code_and_metadata: InstrumentedCodeAndMetadata,
balance: u128,
syscall_kind: SyscallKind,
) -> Self {
let (
destination_id,
Expand Down Expand Up @@ -82,6 +84,7 @@ impl ProcessExecutionContext {
balance,
program,
memory_size: allocations_data.memory_size,
syscall_kind,
}
}

Expand Down
6 changes: 5 additions & 1 deletion core/processor/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use crate::{
};
use alloc::{format, string::String, vec::Vec};
use gear_core::{
code::{CodeMetadata, InstrumentedCode},
code::{CodeMetadata, InstrumentedCode, SyscallKind},
env::{Externalities, WasmEntryPoint},
gas::{GasAllowanceCounter, GasCounter, ValueCounter},
ids::ActorId,
Expand Down Expand Up @@ -66,6 +66,7 @@ where
gas_reserver,
program,
memory_size,
syscall_kind,
} = context;

// TODO: consider avoiding cloning here.
Expand Down Expand Up @@ -135,6 +136,7 @@ where
kind,
program.code_metadata.exports().clone(),
memory_size,
syscall_kind,
)?;
env.execute(|ctx, memory, globals_config| {
Ext::lazy_pages_init_for_program(
Expand Down Expand Up @@ -252,6 +254,7 @@ pub fn execute_for_reply<Ext, EP>(
payload: Vec<u8>,
gas_limit: u64,
block_info: BlockInfo,
syscall_kind: SyscallKind,
) -> Result<Vec<u8>, String>
where
Ext: ProcessorExternalities + BackendExternalities + Send + 'static,
Expand Down Expand Up @@ -334,6 +337,7 @@ where
function,
program.code_metadata.exports().clone(),
memory_size,
syscall_kind,
)?;
env.execute(|ctx, memory, globals_config| {
Ext::lazy_pages_init_for_program(
Expand Down
1 change: 1 addition & 0 deletions core/processor/src/processing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ where
gas_reserver: execution_context.gas_reserver,
program: execution_context.program,
memory_size: execution_context.memory_size,
syscall_kind: execution_context.syscall_kind,
};

// Sending fee: double write cost for addition and removal some time soon
Expand Down
12 changes: 10 additions & 2 deletions core/src/code/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ mod metadata;
mod utils;

pub use errors::*;
pub use gear_wasm_instrument::SyscallKind;
pub use instrumented::*;
pub use metadata::*;
pub use utils::{ALLOWED_EXPORTS, MAX_WASM_PAGES_AMOUNT, REQUIRED_EXPORTS};
Expand Down Expand Up @@ -73,6 +74,8 @@ pub struct TryNewCodeConfig {
pub check_table_section: bool,
/// Make wasmparser validation
pub make_validation: bool,
/// Syscall kind for imports check
pub syscall_kind: SyscallKind,
}

impl TryNewCodeConfig {
Expand Down Expand Up @@ -103,6 +106,7 @@ impl Default for TryNewCodeConfig {
check_data_section: true,
check_table_section: true,
make_validation: true,
syscall_kind: SyscallKind::default(),
}
}
}
Expand Down Expand Up @@ -161,7 +165,7 @@ impl Code {
utils::check_exports(&module)?;
}
if config.check_imports {
utils::check_imports(&module)?;
utils::check_imports(&module, config.syscall_kind)?;
}
if let Some(limit) = config.type_section_params_per_type_limit {
utils::check_type_section(&module, limit)?;
Expand Down Expand Up @@ -299,6 +303,7 @@ impl Code {
/// )
/// )
/// ```
#[allow(clippy::too_many_arguments)]
pub fn try_new<R, GetRulesFn>(
original_code: Vec<u8>,
version: u32,
Expand All @@ -307,6 +312,7 @@ impl Code {
data_segments_amount_limit: Option<u32>,
type_section_len_limit: Option<u32>,
type_section_params_per_type_limit: Option<u32>,
syscall_kind: SyscallKind,
) -> Result<Self, CodeError>
where
R: Rules,
Expand All @@ -321,6 +327,7 @@ impl Code {
data_segments_amount_limit,
type_section_len_limit,
type_section_params_per_type_limit,
syscall_kind,
..Default::default()
},
)
Expand Down Expand Up @@ -454,7 +461,7 @@ mod tests {
use crate::{
code::{
Code, CodeError, DataSectionError, ExportError, GENERIC_OS_PAGE_SIZE, ImportError,
StackEndError, TryNewCodeConfig, TypeSectionError, utils::REF_TYPE_SIZE,
StackEndError, SyscallKind, TryNewCodeConfig, TypeSectionError, utils::REF_TYPE_SIZE,
},
gas_metering::CustomConstantCostRules,
};
Expand Down Expand Up @@ -793,6 +800,7 @@ mod tests {
None,
None,
None,
SyscallKind::Vara,
);

assert_code_err!(res, CodeError::Validation(_));
Expand Down
4 changes: 2 additions & 2 deletions core/src/code/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ pub fn check_exports(module: &Module) -> Result<(), CodeError> {
.map_err(CodeError::Export)
}

pub fn check_imports(module: &Module) -> Result<(), CodeError> {
pub fn check_imports(module: &Module, kind: SyscallKind) -> Result<(), CodeError> {
let types = module
.type_section
.as_ref()
Expand All @@ -159,7 +159,7 @@ pub fn check_imports(module: &Module) -> Result<(), CodeError> {
.as_ref()
.ok_or(SectionError::NotFound(SectionName::Import))?;

let syscalls = SyscallName::instrumentable_map(SyscallKind::Vara);
let syscalls = SyscallName::instrumentable_map(kind);

let mut visited_imports = BTreeSet::new();

Expand Down
28 changes: 0 additions & 28 deletions ethexe/processor/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1436,34 +1436,6 @@ async fn insufficient_executable_balance_still_charged() {
assert!(exec_balance_after < INSUFFICIENT_EXECUTABLE_BALANCE);
}

#[tokio::test]
async fn call_gr_wait_is_forbidden() {
init_logger();

let wat = r#"
(module
(import "env" "memory" (memory 0))
(import "env" "gr_wait" (func $wait))
(export "init" (func $init))
(func $init call $wait)
)
"#;

let transitions = simple_init_test(wat_to_wasm(wat).1).await;
let reply_code = transitions.current_messages()[0]
.1
.reply_details
.expect("must be reply")
.to_reply_code();
assert_eq!(
reply_code,
ReplyCode::Error(ErrorReplyReason::Execution(
SimpleExecutionError::BackendError
)),
"Forbidden syscall should return backend error"
);
}

#[tokio::test]
async fn call_wake_with_delay_is_unsupported() {
init_logger();
Expand Down
Loading
Loading