Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(wasm-instrument, wasm-gen): Make syscalls errors config and syscalls results processing more consistent #3554

Merged
merged 23 commits into from
Dec 12, 2023
Merged
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
2 changes: 1 addition & 1 deletion gsys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ extern "C" {
err_mid_pid: *mut ErrorWithTwoHashes,
);

/// Fallible `gr_reply_deposit` syscall.
/// Fallible `gr_reply_deposit` control syscall.
///
/// Arguments type:
/// - `message_id`: `const ptr` for message id.
Expand Down
11 changes: 7 additions & 4 deletions pallets/gear/src/benchmarking/code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,10 +236,13 @@ where
// Import supervisor functions. They start with idx 0.
for name in def.imported_functions {
let sign = name.signature();
let sig = builder::signature()
.with_params(sign.params.into_iter().map(Into::into))
.with_results(sign.results.into_iter())
.build_sig();
let sig_builder =
builder::signature().with_params(sign.params().iter().copied().map(Into::into));
let results = sign
.results()
.map(|results| results.to_vec())
.unwrap_or_default();
let sig = sig_builder.with_results(results.into_iter()).build_sig();
let sig = program.push_signature(sig);
program = program
.import()
Expand Down
4 changes: 2 additions & 2 deletions pallets/gear/src/benchmarking/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1385,10 +1385,10 @@ where
assert!(repetitions <= 1);

let params = if let Some(c) = param {
assert!(name.signature().params.len() == 1);
assert!(name.signature().params().len() == 1);
vec![InstrI32Const(c)]
} else {
assert!(name.signature().params.is_empty());
assert!(name.signature().params().is_empty());
vec![]
};

Expand Down
11 changes: 7 additions & 4 deletions utils/node-loader/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use gear_core::ids::{MessageId, ProgramId};
use gear_core_errors::ReplyCode;
use gear_utils::NonEmpty;
use gear_wasm_gen::{
EntryPointsSet, InvocableSyscall, ParamType, StandardGearWasmConfigsBundle, SyscallName,
SyscallsInjectionTypes, SyscallsParamsConfig,
EntryPointsSet, InvocableSyscall, ParamType, RegularParamType, StandardGearWasmConfigsBundle,
SyscallName, SyscallsInjectionTypes, SyscallsParamsConfig,
};
use gsdk::metadata::runtime_types::{
gear_common::event::DispatchStatus as GenDispatchStatus,
Expand Down Expand Up @@ -230,8 +230,11 @@ pub fn get_wasm_gen_config(
);

let mut params_config = SyscallsParamsConfig::default();
params_config.add_rule(ParamType::Alloc, (1..=10).into());
params_config.add_rule(ParamType::Free, (initial_pages..=initial_pages + 50).into());
params_config.add_rule(ParamType::Regular(RegularParamType::Alloc), (1..=10).into());
params_config.add_rule(
ParamType::Regular(RegularParamType::Free),
(initial_pages..=initial_pages + 50).into(),
);

StandardGearWasmConfigsBundle {
log_info: Some(format!("Gear program seed = '{seed}'")),
Expand Down
14 changes: 10 additions & 4 deletions utils/runtime-fuzzer/src/gear_calls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ use gear_call_gen::{ClaimValueArgs, SendReplyArgs};
use gear_core::ids::{CodeId, MessageId, ProgramId};
use gear_utils::NonEmpty;
use gear_wasm_gen::{
EntryPointsSet, InvocableSyscall, ParamType, StandardGearWasmConfigsBundle, SyscallName,
SyscallsInjectionTypes, SyscallsParamsConfig,
EntryPointsSet, InvocableSyscall, ParamType, RegularParamType, StandardGearWasmConfigsBundle,
SyscallName, SyscallsInjectionTypes, SyscallsParamsConfig,
};
use std::mem;

Expand Down Expand Up @@ -425,8 +425,14 @@ fn config(
);

let mut params_config = SyscallsParamsConfig::default();
params_config.add_rule(ParamType::Alloc, (10..=20).into());
params_config.add_rule(ParamType::Free, (initial_pages..=initial_pages + 35).into());
params_config.add_rule(
ParamType::Regular(RegularParamType::Alloc),
(10..=20).into(),
);
params_config.add_rule(
ParamType::Regular(RegularParamType::Free),
(initial_pages..=initial_pages + 35).into(),
);

let existing_addresses = NonEmpty::collect(
programs
Expand Down
27 changes: 2 additions & 25 deletions utils/wasm-gen/src/config/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,16 @@
mod injection;
mod param;
mod precise;
mod process_errors;

use gear_utils::NonEmpty;
use gear_wasm_instrument::syscalls::SyscallName;
use gsys::{Hash, HashWithValue};
use std::collections::HashSet;

pub use injection::*;
pub use param::*;
pub use precise::*;
pub use process_errors::*;

use crate::InvocableSyscall;

Expand Down Expand Up @@ -117,30 +118,6 @@ impl SyscallsConfigBuilder {
}
}

#[derive(Debug, Clone, Default)]
pub enum ErrorProcessingConfig {
/// Process errors on all the fallible syscalls.
All,
/// Process only errors on provided syscalls.
Whitelist(HashSet<InvocableSyscall>),
/// Process errors on all the syscalls excluding provided.
Blacklist(HashSet<InvocableSyscall>),
/// Don't process syscall errors at all.
#[default]
None,
}

impl ErrorProcessingConfig {
pub fn error_should_be_processed(&self, syscall: &InvocableSyscall) -> bool {
match self {
Self::All => true,
Self::Whitelist(wl) => wl.contains(syscall),
Self::Blacklist(bl) => !bl.contains(syscall),
Self::None => false,
}
}
}

/// United config for all entities in syscalls generator module.
#[derive(Debug, Clone, Default)]
pub struct SyscallsConfig {
Expand Down
2 changes: 1 addition & 1 deletion utils/wasm-gen/src/config/syscalls/injection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ impl SyscallsInjectionTypes {
}
}

/// Imports the given syscall, if necessary.
/// Imports the given syscall, if possible.
pub(crate) fn enable_syscall_import(&mut self, name: InvocableSyscall) {
if let Some(injection_type @ SyscallInjectionType::None) = self.0.get_mut(&name) {
*injection_type = SyscallInjectionType::Import;
Expand Down
45 changes: 26 additions & 19 deletions utils/wasm-gen/src/config/syscalls/param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use crate::DEFAULT_INITIAL_SIZE;
use arbitrary::{Result, Unstructured};
use std::{collections::HashMap, ops::RangeInclusive};

pub use gear_wasm_instrument::syscalls::ParamType;
pub use gear_wasm_instrument::syscalls::{ParamType, RegularParamType};

/// Syscalls params config.
///
Expand All @@ -50,17 +50,21 @@ impl SyscallsParamsConfig {

/// New [`SyscallsParamsConfig`] with all rules set to produce one constant value.
pub fn all_constant_value(value: i64) -> Self {
use ParamType::*;
use RegularParamType::*;

let allowed_values: SyscallParamAllowedValues = (value..=value).into();
Self(
[
ParamType::Length,
ParamType::Gas,
ParamType::Offset,
ParamType::DurationBlockNumber,
ParamType::DelayBlockNumber,
ParamType::Handler,
ParamType::Free,
ParamType::Version,
Regular(Length),
Regular(Gas),
Regular(Offset),
Regular(DurationBlockNumber),
Regular(DelayBlockNumber),
Regular(Handler),
Regular(Free),
Regular(FreeUpperBound),
Regular(Version),
]
.into_iter()
.map(|param_type| (param_type, allowed_values.clone()))
Expand All @@ -75,7 +79,7 @@ impl SyscallsParamsConfig {

/// Set allowed values for the `param`.
pub fn add_rule(&mut self, param: ParamType, allowed_values: SyscallParamAllowedValues) {
matches!(param, ParamType::Ptr(..))
matches!(param, ParamType::Regular(RegularParamType::Pointer(_)))
.then(|| panic!("ParamType::Ptr(..) isn't supported in SyscallsParamsConfig"));

self.0.insert(param, allowed_values);
Expand All @@ -84,21 +88,24 @@ impl SyscallsParamsConfig {

impl Default for SyscallsParamsConfig {
fn default() -> Self {
use ParamType::*;
use RegularParamType::*;

let free_start = DEFAULT_INITIAL_SIZE as i64;
let free_end = free_start + 5;
Self(
[
(ParamType::Length, (0..=0x10000).into()),
(Regular(Length), (0..=0x10000).into()),
// There are no rules for memory arrays and pointers as they are chosen
// in accordance to memory pages config.
(ParamType::Gas, (0..=250_000_000_000).into()),
(ParamType::Offset, (0..=10).into()),
(ParamType::DurationBlockNumber, (1..=8).into()),
(ParamType::DelayBlockNumber, (0..=4).into()),
(ParamType::Handler, (0..=100).into()),
(ParamType::Free, (free_start..=free_end).into()),
(ParamType::FreeUpperBound, (0..=10).into()),
(ParamType::Version, (1..=1).into()),
(Regular(Gas), (0..=250_000_000_000).into()),
(Regular(Offset), (0..=10).into()),
(Regular(DurationBlockNumber), (1..=8).into()),
(Regular(DelayBlockNumber), (0..=4).into()),
(Regular(Handler), (0..=100).into()),
(Regular(Free), (free_start..=free_end).into()),
(Regular(Version), (1..=1).into()),
(Regular(FreeUpperBound), (0..=10).into()),
]
.into_iter()
.collect(),
Expand Down
84 changes: 84 additions & 0 deletions utils/wasm-gen/src/config/syscalls/process_errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// This file is part of Gear.

// Copyright (C) 2021-2023 Gear Technologies Inc.
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

//! Processing syscalls errors config.

use std::collections::HashSet;

use crate::InvocableSyscall;

#[derive(Debug, Clone, Default)]
pub enum ErrorProcessingConfig {
/// Process errors on all the fallible syscalls.
All,
/// Process only errors on provided syscalls.
Whitelist(ErrorProneSyscalls),
/// Process errors on all the syscalls excluding provided.
Blacklist(ErrorProneSyscalls),
/// Don't process syscall errors at all.
#[default]
None,
}

impl ErrorProcessingConfig {
pub fn error_should_be_processed(&self, syscall: InvocableSyscall) -> bool {
match self {
Self::All => true,
Self::Whitelist(wl) => wl.contains(syscall),
Self::Blacklist(bl) => {
if syscall.returns_error() {
!bl.contains(syscall)
} else {
false
}
}
Self::None => false,
}
}
}

/// Set of syscalls that return an error.
///
/// Basically, it's a wrapper over a hash set of [`InvocableSysCall`],
/// that controls types of inserted syscalls.
#[derive(Debug, Clone, Default)]
pub struct ErrorProneSyscalls(HashSet<InvocableSyscall>);

impl ErrorProneSyscalls {
/// Create an empty set of returning error syscalls.
pub fn new() -> Self {
Self(HashSet::new())
}

/// Insert an error-prone syscall into the set.
pub fn insert(&mut self, syscall: InvocableSyscall) {
if syscall.returns_error() {
self.0.insert(syscall);
} else {
panic!(
"{syscall_str} is neither fallible, nor returns error value.",
syscall_str = syscall.to_str()
);
}
}

/// Check if the `syscall` is in the set.
pub fn contains(&self, syscall: InvocableSyscall) -> bool {
techraed marked this conversation as resolved.
Show resolved Hide resolved
self.0.contains(&syscall)
}
}
Loading