WIP new structs to hand limits over in runtime

This commit is contained in:
Roman Nozdrin 2024-02-07 10:01:34 +00:00
parent 1da02d197d
commit 81019e6633
17 changed files with 413 additions and 129 deletions

View File

@ -91,17 +91,9 @@ pub enum PreparationError {
#[error(transparent)]
DataSignatureCheckError(#[from] DataVerifierError),
/// AIR script size is bigger than the allowed limit.
#[error("air size: {0} bytes is bigger than the limit allowed: {1} bytes")]
AIRSizeLimitReached(usize, u64),
/// Current_data particle size is bigger than the allowed limit.
#[error("Current_data particle size: {0} bytes is bigger than the limit allowed: {1} bytes")]
ParticleSizeLimitReached(usize, u64),
/// CallResult size is bigger than the allowed limit.
#[error("Call result size is bigger than the limit allowed: {0} bytes")]
CallResultSizeLimitReached(u64),
/// RAM limits are excedeed.
#[error(transparent)]
SizeLimitsExceded(#[from] SizeLimitsExceded),
}
impl ToErrorCode for PreparationError {
@ -136,14 +128,29 @@ impl PreparationError {
}
pub fn air_size_limit(actual_size: usize, limit: u64) -> Self {
Self::AIRSizeLimitReached(actual_size, limit)
Self::SizeLimitsExceded(SizeLimitsExceded::AIR(actual_size, limit))
}
pub fn particle_size_limit(actual_size: usize, limit: u64) -> Self {
Self::ParticleSizeLimitReached(actual_size, limit)
Self::SizeLimitsExceded(SizeLimitsExceded::Particle(actual_size, limit))
}
pub fn call_result_size_limit(limit: u64) -> Self {
Self::CallResultSizeLimitReached(limit)
Self::SizeLimitsExceded(SizeLimitsExceded::CallResult(limit))
}
}
#[derive(Debug, ThisError)]
pub enum SizeLimitsExceded {
/// AIR script size is bigger than the allowed limit.
#[error("air size: {0} bytes is bigger than the limit allowed: {1} bytes")]
AIR(usize, u64),
/// Current_data particle size is bigger than the allowed limit.
#[error("Current_data particle size: {0} bytes is bigger than the limit allowed: {1} bytes")]
Particle(usize, u64),
/// CallResult size is bigger than the allowed limit.
#[error("Call result size is bigger than the limit allowed: {0} bytes")]
CallResult(u64),
}

View File

@ -144,6 +144,8 @@ fn make_exec_ctx(
signature_store: SignatureStore,
run_parameters: &RunParameters,
) -> PreparationResult<ExecutionCtx<'static>> {
use crate::preparation_step::sizes_limits_check::limit_behavior;
let call_results = measure!(
CallResultsRepr
.deserialize(call_results)
@ -157,9 +159,8 @@ fn make_exec_ctx(
.values()
.any(|call_result| call_result.result.len() > run_parameters.call_result_size_limit as usize)
{
return Err(PreparationError::call_result_size_limit(
run_parameters.call_result_size_limit,
));
let error = PreparationError::call_result_size_limit(run_parameters.call_result_size_limit);
limit_behavior(run_parameters, error)?;
}
let ctx = ExecutionCtx::new(

View File

@ -19,23 +19,27 @@ use crate::PreparationError;
use air_interpreter_interface::RunParameters;
pub(crate) fn limit_behavior(run_parameters: &RunParameters, error: PreparationError) -> PreparationResult<()> {
if run_parameters.hard_limit_enabled {
Err(error)
} else {
Ok(())
}
}
pub(crate) fn check_against_size_limits(
run_parameters: &RunParameters,
air: &str,
raw_current_data: &[u8],
) -> PreparationResult<()> {
if air.len() as u64 > run_parameters.air_size_limit {
return Err(PreparationError::air_size_limit(
air.len(),
run_parameters.air_size_limit,
));
let error = PreparationError::air_size_limit(air.len(), run_parameters.air_size_limit);
limit_behavior(run_parameters, error)?;
}
if raw_current_data.len() > run_parameters.particle_size_limit as usize {
return Err(PreparationError::particle_size_limit(
raw_current_data.len(),
run_parameters.particle_size_limit,
));
if raw_current_data.len() as u64 > run_parameters.particle_size_limit {
let error = PreparationError::particle_size_limit(raw_current_data.len(), run_parameters.particle_size_limit);
limit_behavior(run_parameters, error)?;
}
Ok(())

View File

@ -102,6 +102,7 @@ fn invalid_callresults() {
let air_size_limit = MAX_AIR_SIZE;
let particle_size_limit = MAX_PARTICLE_SIZE;
let call_result_size_limit = MAX_CALL_RESULT_SIZE;
let hard_limit_enable = false;
let run_parameters = RunParameters::new(
client_peer_id.clone(),
@ -114,6 +115,7 @@ fn invalid_callresults() {
air_size_limit,
particle_size_limit,
call_result_size_limit,
hard_limit_enable,
);
let result = air::execute_air(air, prev_data, data, run_parameters, wrong_call_results.clone().into());
@ -128,50 +130,111 @@ fn invalid_callresults() {
}
#[test]
fn air_size_limit() {
fn air_size_hard_limit() {
let script = "a".repeat((MAX_AIR_SIZE + 1) as usize);
let mut vm = create_avm(unit_call_service(), "some_peer_id");
let result = vm.call(script, "", "", <_>::default()).unwrap();
let expected_error = PreparationError::AIRSizeLimitReached((MAX_AIR_SIZE + 1) as usize, MAX_AIR_SIZE);
let peer_id = "some_peer_id".to_owned();
let air_size_limit = MAX_AIR_SIZE;
let particle_size_limit = MAX_PARTICLE_SIZE;
let call_result_size_limit = MAX_CALL_RESULT_SIZE;
let hard_limit_enable = true;
let run_parameters = RunParameters::new(
peer_id.clone(),
peer_id,
0,
0,
<_>::default(),
<_>::default(),
"".to_owned(),
air_size_limit,
particle_size_limit,
call_result_size_limit,
hard_limit_enable,
);
let result = air::execute_air(script, vec![], vec![], run_parameters, <_>::default());
let result = RawAVMOutcome::from_interpreter_outcome(result).unwrap();
let expected_error = PreparationError::air_size_limit((MAX_AIR_SIZE + 1) as usize, MAX_AIR_SIZE);
assert!(check_error(&result, expected_error));
}
#[test]
fn particle_size_limit() {
let script = "(null)";
let mut vm = create_avm(unit_call_service(), "some_peer_id");
fn particle_size_hard_limit() {
let script = "(null)".to_owned();
let cur_data = vec![0; (MAX_PARTICLE_SIZE + 1) as usize];
let result = vm.call(script, "", cur_data, <_>::default()).unwrap();
let expected_error =
PreparationError::ParticleSizeLimitReached((MAX_PARTICLE_SIZE + 1) as usize, MAX_PARTICLE_SIZE);
let peer_id = "some_peer_id".to_owned();
let air_size_limit = MAX_AIR_SIZE;
let particle_size_limit = MAX_PARTICLE_SIZE;
let call_result_size_limit = MAX_CALL_RESULT_SIZE;
let hard_limit_enable = true;
let run_parameters = RunParameters::new(
peer_id.clone(),
peer_id,
0,
0,
<_>::default(),
<_>::default(),
"".to_owned(),
air_size_limit,
particle_size_limit,
call_result_size_limit,
hard_limit_enable,
);
let result = air::execute_air(script, vec![], cur_data, run_parameters, <_>::default());
let result = RawAVMOutcome::from_interpreter_outcome(result).unwrap();
let expected_error = PreparationError::particle_size_limit((MAX_PARTICLE_SIZE + 1) as usize, MAX_PARTICLE_SIZE);
assert!(check_error(&result, expected_error));
}
#[test]
fn call_result_size_limit() {
fn call_result_size_hard_limit() {
use maplit::hashmap;
use air::ToErrorCode;
use air_interpreter_interface::MAX_CALL_RESULT_SIZE;
use air_interpreter_sede::ToSerialized;
let peer_id = "some_peer_id";
let mut vm = create_avm(unit_call_service(), "some_peer_id");
let script = "(null)";
let script = "(null)".to_owned();
let result_1 = "a".repeat((MAX_CALL_RESULT_SIZE / 2 + 1) as usize);
let result_2 = "b".repeat((MAX_CALL_RESULT_SIZE + 1) as usize);
let call_results: CallResults =
hashmap! {0 => CallServiceResult::ok(result_1.into()), 1 => CallServiceResult::ok(result_2.into())};
let result = vm
.call_single(script, "", "", peer_id, 0, 64, None, call_results, "particle_id")
.unwrap();
let raw_call_results = into_raw_result(call_results);
let raw_call_results = CallResultsRepr.serialize(&raw_call_results).unwrap();
let expected_error = PreparationError::CallResultSizeLimitReached(MAX_CALL_RESULT_SIZE);
let peer_id = "some_peer_id".to_owned();
let air_size_limit = MAX_AIR_SIZE;
let particle_size_limit = MAX_PARTICLE_SIZE;
let call_result_size_limit = MAX_CALL_RESULT_SIZE;
let hard_limit_enable = true;
let run_parameters = RunParameters::new(
peer_id.clone(),
peer_id,
0,
0,
<_>::default(),
<_>::default(),
"".to_owned(),
air_size_limit,
particle_size_limit,
call_result_size_limit,
hard_limit_enable,
);
let result = air::execute_air(script, vec![], vec![], run_parameters, raw_call_results);
let result = RawAVMOutcome::from_interpreter_outcome(result).unwrap();
let expected_error = PreparationError::call_result_size_limit(MAX_CALL_RESULT_SIZE);
assert_eq!(result.ret_code, expected_error.to_error_code());
}

View File

@ -70,7 +70,7 @@ impl<E> AVM<E> {
data_store.initialize()?;
let runner = AVMRunner::new(air_wasm_path, max_heap_size, None, None, None, logging_mask)
let runner = AVMRunner::new(air_wasm_path, max_heap_size, <_>::default(), logging_mask)
.map_err(AVMError::RunnerError)?;
let runner = SendSafeRunner(runner);
let avm = Self { runner, data_store };

View File

@ -28,11 +28,14 @@ mod avm;
mod config;
mod errors;
mod runner;
mod runtime_limits;
pub use avm::AVM;
pub use config::AVMConfig;
pub use errors::AVMError;
pub use runner::AVMMemoryStats;
pub use runner::AVMRuntimeLimits;
pub use runner::RuntimeLimits;
pub use avm_interface::*;

View File

@ -32,18 +32,36 @@ use marine::ModuleDescriptor;
use std::path::PathBuf;
#[derive(Clone, Copy, Debug)]
pub struct AVMRuntimeLimits {
pub air_size_limit: u64, // WIP remove pub?
/// The particle data size limit.
pub particle_size_limit: u64,
/// This is the limit for the size of service call result.
pub call_result_size_limit: u64,
/// This knob controls hard RAM limits behavior for AVMRunner.
pub hard_limit_enabled: bool,
}
pub struct RuntimeLimits {
// The AIR script size limit.
pub air_size_limit: Option<u64>,
/// The particle data size limit.
pub particle_size_limit: Option<u64>,
/// This is the limit for the size of service call result.
pub call_result_size_limit: Option<u64>,
/// This knob controls hard RAM limits behavior for AVMRunner.
pub hard_limit_enabled: bool,
}
pub struct AVMRunner {
marine: Marine,
/// file name of the AIR interpreter .wasm
wasm_filename: String,
/// The memory limit provided by constructor
total_memory_limit: Option<u64>,
/// The AIR script size limit.
pub air_size_limit: u64,
/// The particle data size limit.
pub particle_size_limit: u64,
// This is the limit for the size of service call result.
pub call_result_size_limit: u64,
/// This struct contains runtime RAM allowance.
avm_runtime_limits: AVMRuntimeLimits,
}
/// Return statistic of AVM server Wasm module heap footprint.
@ -63,32 +81,21 @@ impl AVMRunner {
pub fn new(
air_wasm_path: PathBuf,
total_memory_limit: Option<u64>,
air_size_limit: Option<u64>,
particle_size_limit: Option<u64>,
call_result_size_limit: Option<u64>,
runtime_limits: RuntimeLimits,
logging_mask: i32,
) -> RunnerResult<Self> {
use air_interpreter_interface::MAX_AIR_SIZE;
use air_interpreter_interface::MAX_CALL_RESULT_SIZE;
use air_interpreter_interface::MAX_PARTICLE_SIZE;
let (wasm_dir, wasm_filename) = split_dirname(air_wasm_path)?;
let marine_config =
make_marine_config(wasm_dir, &wasm_filename, total_memory_limit, logging_mask);
let marine = Marine::with_raw_config(marine_config)?;
let air_size_limit = air_size_limit.unwrap_or(MAX_AIR_SIZE);
let particle_size_limit = particle_size_limit.unwrap_or(MAX_PARTICLE_SIZE);
let call_result_size_limit = call_result_size_limit.unwrap_or(MAX_CALL_RESULT_SIZE);
let avm_runtime_limits = runtime_limits.into();
let avm = Self {
marine,
wasm_filename,
total_memory_limit,
air_size_limit,
particle_size_limit,
call_result_size_limit,
avm_runtime_limits,
};
Ok(avm)
@ -122,9 +129,7 @@ impl AVMRunner {
init_peer_id.into(),
timestamp,
ttl,
self.air_size_limit,
self.particle_size_limit,
self.call_result_size_limit,
self.avm_runtime_limits,
call_results,
key_format.into(),
secret_key_bytes,
@ -173,9 +178,7 @@ impl AVMRunner {
init_peer_id.into(),
timestamp,
ttl,
self.air_size_limit,
self.particle_size_limit,
self.call_result_size_limit,
self.avm_runtime_limits,
call_results,
key_format,
secret_key_bytes,
@ -242,14 +245,19 @@ fn prepare_args(
init_peer_id: String,
timestamp: u64,
ttl: u32,
air_size_limit: u64,
particle_size_limit: u64,
call_result_size_limit: u64,
avm_runtime_limits: AVMRuntimeLimits,
call_results: CallResults,
key_format: u8,
secret_key_bytes: Vec<u8>,
particle_id: String,
) -> Vec<IValue> {
let AVMRuntimeLimits {
air_size_limit,
particle_size_limit,
call_result_size_limit,
hard_limit_enabled,
} = avm_runtime_limits;
let run_parameters = air_interpreter_interface::RunParameters::new(
init_peer_id,
current_peer_id,
@ -261,6 +269,7 @@ fn prepare_args(
air_size_limit,
particle_size_limit,
call_result_size_limit,
hard_limit_enabled,
)
.into_ivalue();
@ -350,3 +359,61 @@ fn try_as_one_value_vec(mut ivalues: Vec<IValue>) -> RunnerResult<IValue> {
Ok(ivalues.remove(0))
}
impl AVMRuntimeLimits {
pub fn new(
air_size_limit: u64,
particle_size_limit: u64,
call_result_size_limit: u64,
hard_limit_enabled: bool,
) -> Self {
Self {
air_size_limit,
particle_size_limit,
call_result_size_limit,
hard_limit_enabled,
}
}
}
impl RuntimeLimits {
pub fn new(
air_size_limit: Option<u64>,
particle_size_limit: Option<u64>,
call_result_size_limit: Option<u64>,
hard_limit_enabled: bool,
) -> Self {
Self {
air_size_limit,
particle_size_limit,
call_result_size_limit,
hard_limit_enabled,
}
}
}
impl Default for RuntimeLimits {
fn default() -> Self {
Self {
air_size_limit: None,
particle_size_limit: None,
call_result_size_limit: None,
hard_limit_enabled: false,
}
}
}
impl From<RuntimeLimits> for AVMRuntimeLimits {
fn from(value: RuntimeLimits) -> Self {
use air_interpreter_interface::MAX_AIR_SIZE;
use air_interpreter_interface::MAX_CALL_RESULT_SIZE;
use air_interpreter_interface::MAX_PARTICLE_SIZE;
AVMRuntimeLimits::new(
value.air_size_limit.unwrap_or(MAX_AIR_SIZE),
value.particle_size_limit.unwrap_or(MAX_PARTICLE_SIZE),
value.call_result_size_limit.unwrap_or(MAX_CALL_RESULT_SIZE),
value.hard_limit_enabled,
)
}
}

View File

@ -0,0 +1,75 @@
/*
* Copyright 2024 Fluence Labs Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
pub struct AVMRuntimeLimits {
/// AIR script size limit.
pub air_size_limit: u64,
/// Particle data size limit.
pub particle_size_limit: u64,
/// Service call result size limit.
pub call_result_size_limit: u64,
/// Knob to enable/disable RAM consumption hard limits in AquaVM.
pub hard_limit_enabled: bool,
}
pub struct RuntimeLimits {
pub air_size_limit: Option<u64>,
pub particle_size_limit: Option<u64>,
pub call_result_size_limit: Option<u64>,
pub hard_limit_enabled: bool,
}
impl AVMRuntimeLimits {
pub fn new(
air_size_limit: u64,
particle_size_limit: u64,
call_result_size_limit: u64,
hard_limit_enabled: bool,
) -> Self {
Self {
air_size_limit,
particle_size_limit,
call_result_size_limit,
hard_limit_enabled,
}
}
}
impl Default for RuntimeLimits {
fn default() -> Self {
Self {
air_size_limit: None,
particle_size_limit: None,
call_result_size_limit: None,
hard_limit_enabled: false,
}
}
}
impl From<RuntimeLimits> for AVMRuntimeLimits {
fn from(value: RuntimeLimits) -> Self {
use air_interpreter_interface::MAX_AIR_SIZE;
use air_interpreter_interface::MAX_CALL_RESULT_SIZE;
use air_interpreter_interface::MAX_PARTICLE_SIZE;
AVMRuntimeLimits::new(
value.air_size_limit.unwrap_or(MAX_AIR_SIZE),
value.particle_size_limit.unwrap_or(MAX_PARTICLE_SIZE),
value.call_result_size_limit.unwrap_or(MAX_CALL_RESULT_SIZE),
value.hard_limit_enabled,
)
}
}

View File

@ -62,6 +62,9 @@ pub struct RunParameters {
/// This is the limit for the size of service call result.
pub call_result_size_limit: u64,
/// This knob controls hard RAM limits behavior for AVMRunner.
pub hard_limit_enabled: bool,
}
impl RunParameters {
@ -77,6 +80,7 @@ impl RunParameters {
air_size_limit: u64,
particle_size_limit: u64,
call_result_size_limit: u64,
hard_limit_enabled: bool,
) -> Self {
Self {
init_peer_id,
@ -89,6 +93,7 @@ impl RunParameters {
air_size_limit,
particle_size_limit,
call_result_size_limit,
hard_limit_enabled,
}
}
@ -105,6 +110,7 @@ impl RunParameters {
IValue::U64(self.air_size_limit),
IValue::U64(self.particle_size_limit),
IValue::U64(self.call_result_size_limit),
IValue::Boolean(self.hard_limit_enabled),
];
// unwrap is safe here because run_parameters is non-empty array
let run_parameters = NEVec::new(run_parameters).unwrap();

View File

@ -21,6 +21,7 @@ use air_interpreter_interface::RunParameters;
use air_interpreter_sede::ToSerialized;
use avm_server::avm_runner::*;
use avm_server::into_raw_result;
use avm_server::AVMRuntimeLimits;
use fluence_keypair::KeyPair;
pub struct NativeAirRunner {
@ -59,8 +60,12 @@ impl AirRunner for NativeAirRunner {
let key_format = keypair.key_format().into();
let secret_key_bytes = keypair.secret().unwrap();
let (air_size_limit, particle_size_limit, call_result_size_limit) =
self.test_init_parameters.to_attributes_w_default();
let AVMRuntimeLimits {
air_size_limit,
particle_size_limit,
call_result_size_limit,
hard_limit_enabled,
} = self.test_init_parameters.into();
let outcome = air::execute_air(
air.into(),
@ -77,6 +82,7 @@ impl AirRunner for NativeAirRunner {
air_size_limit,
particle_size_limit,
call_result_size_limit,
hard_limit_enabled,
},
raw_call_results,
);

View File

@ -27,6 +27,8 @@ pub use crate::wasm_test_runner::WasmAirRunner;
use super::CallServiceClosure;
use avm_server::avm_runner::*;
use avm_server::AVMRuntimeLimits;
use avm_server::RuntimeLimits;
use fluence_keypair::KeyPair;
use std::collections::HashMap;
@ -69,11 +71,12 @@ pub struct TestRunParameters {
}
/// This struct is used to set limits for the test runner creating AVMRunner.
#[derive(Debug, Default, Clone)]
#[derive(Debug, Default, Clone, Copy)]
pub struct TestInitParameters {
pub air_size_limit: Option<u64>,
pub particle_size_limit: Option<u64>,
pub call_result_size_limit: Option<u64>,
pub hard_limit_enabled: bool,
}
impl<R: AirRunner> TestRunner<R> {
@ -247,11 +250,17 @@ impl TestRunParameters {
}
impl TestInitParameters {
pub fn new(air_size_limit: u64, particle_size_limit: u64, call_result_size_limit: u64) -> Self {
pub fn new(
air_size_limit: u64,
particle_size_limit: u64,
call_result_size_limit: u64,
hard_limit_enabled: bool,
) -> Self {
Self {
air_size_limit: Some(air_size_limit),
particle_size_limit: Some(particle_size_limit),
call_result_size_limit: Some(call_result_size_limit),
hard_limit_enabled,
}
}
@ -260,18 +269,37 @@ impl TestInitParameters {
air_size_limit: Some(u64::MAX),
particle_size_limit: Some(u64::MAX),
call_result_size_limit: Some(u64::MAX),
hard_limit_enabled: false,
}
}
}
pub fn to_attributes_w_default(&self) -> (u64, u64, u64) {
impl From<TestInitParameters> for RuntimeLimits {
fn from(value: TestInitParameters) -> Self {
RuntimeLimits::new(
value.air_size_limit,
value.particle_size_limit,
value.call_result_size_limit,
value.hard_limit_enabled,
)
}
}
impl From<TestInitParameters> for AVMRuntimeLimits {
fn from(value: TestInitParameters) -> Self {
use air_interpreter_interface::MAX_AIR_SIZE;
use air_interpreter_interface::MAX_CALL_RESULT_SIZE;
use air_interpreter_interface::MAX_PARTICLE_SIZE;
let air_size_limit = value.air_size_limit.unwrap_or(MAX_AIR_SIZE);
let particle_size_limit: u64 = value.particle_size_limit.unwrap_or(MAX_PARTICLE_SIZE);
let call_result_size_limit = value.call_result_size_limit.unwrap_or(MAX_CALL_RESULT_SIZE);
let air_size_limit = self.air_size_limit.unwrap_or(MAX_AIR_SIZE);
let particle_size_limit: u64 = self.particle_size_limit.unwrap_or(MAX_PARTICLE_SIZE);
let call_result_size_limit = self.call_result_size_limit.unwrap_or(MAX_CALL_RESULT_SIZE);
(air_size_limit, particle_size_limit, call_result_size_limit)
AVMRuntimeLimits::new(
air_size_limit,
particle_size_limit,
call_result_size_limit,
value.hard_limit_enabled,
)
}
}

View File

@ -35,15 +35,11 @@ pub struct WasmAirRunner {
fn make_pooled_avm_runner(test_init_parameters: TestInitParameters) -> AVMRunner {
let logging_mask = i32::MAX;
let (air_size_limit, particle_size_limit, call_result_size_limit) =
test_init_parameters.to_attributes_w_default();
AVMRunner::new(
PathBuf::from(AIR_WASM_PATH),
Some(AVM_MAX_HEAP_SIZE),
Some(air_size_limit),
Some(particle_size_limit),
Some(call_result_size_limit),
test_init_parameters.into(),
logging_mask,
)
.expect("vm should be created")
@ -114,15 +110,11 @@ pub struct ReleaseWasmAirRunner {
impl AirRunner for ReleaseWasmAirRunner {
fn new(current_peer_id: impl Into<String>, test_init_parameters: TestInitParameters) -> Self {
let logging_mask = i32::MAX;
let (air_size_limit, particle_size_limit, call_result_size_limit) =
test_init_parameters.to_attributes_w_default();
let runner = AVMRunner::new(
PathBuf::from(RELEASE_AIR_WASM_PATH),
Some(AVM_MAX_HEAP_SIZE),
Some(air_size_limit),
Some(particle_size_limit),
Some(call_result_size_limit),
test_init_parameters.into(),
logging_mask,
)
.expect("vm should be created");

View File

@ -17,6 +17,7 @@ avm-interface = { version = "0.31.2", path = "../../../avm/interface" }
air-interpreter-interface = { version = "0.17.2", path = "../../../crates/air-lib/interpreter-interface", default-features = false }
air-interpreter-data = { version = "0.17.0", path = "../../../crates/air-lib/interpreter-data" }
air-interpreter-sede = { version = "0.1.0", path = "../../../crates/air-lib/interpreter-sede", default-features = false }
avm-server = { version = "0.35.0", path = "../../../avm/server" }
air-test-utils = { version = "0.15.1",path = "../../../crates/air-lib/test-utils", optional = true }
clap = { version = "4.4.7", features = ["derive", "env"] }

View File

@ -55,6 +55,9 @@ pub(crate) struct PlainDataArgs {
#[clap(long = "call-result-size-limit")]
call_result_size_limit: Option<u64>,
#[clap(long = "hard-limit-enabled", default_value = "false")]
hard_limit_enabled: bool,
}
pub(crate) fn load(args: &PlainDataArgs) -> eyre::Result<ExecutionData<'_>> {
@ -80,11 +83,12 @@ pub(crate) fn load(args: &PlainDataArgs) -> eyre::Result<ExecutionData<'_>> {
current_peer_id.into(),
);
let test_init_parameters = TestInitParameters {
air_size_limit: args.air_size_limit,
particle_size_limit: args.particle_size_limit,
call_result_size_limit: args.call_result_size_limit,
};
let test_init_parameters = TestInitParameters::new(
args.air_size_limit,
args.particle_size_limit,
args.call_result_size_limit,
args.hard_limit_enabled,
);
Ok(ExecutionData {
air_script,

View File

@ -21,14 +21,13 @@ use super::runner::TestInitParameters;
use air_interpreter_interface::CallResultsRepr;
use air_interpreter_interface::RunParameters;
use avm_interface::raw_outcome::RawAVMOutcome;
use avm_server::AVMRuntimeLimits;
use fluence_keypair::KeyPair;
use std::error::Error as StdError;
pub(crate) struct NativeAvmRunner {
pub air_size_limit: u64,
pub particle_size_limit: u64,
pub call_result_size_limit: u64,
pub avm_runtime_limits: AVMRuntimeLimits,
}
impl AirRunner for NativeAvmRunner {
@ -57,6 +56,12 @@ impl AirRunner for NativeAvmRunner {
let key_format = keypair.key_format().into();
let secret_key_bytes = keypair.secret().expect("Failed to get secret key");
let AVMRuntimeLimits {
air_size_limit,
particle_size_limit,
call_result_size_limit,
hard_limit_enabled,
} = self.avm_runtime_limits;
let outcome = air::execute_air(
air,
@ -67,12 +72,13 @@ impl AirRunner for NativeAvmRunner {
current_peer_id,
timestamp,
ttl,
air_size_limit: self.air_size_limit,
particle_size_limit: self.particle_size_limit,
call_result_size_limit: self.call_result_size_limit,
key_format,
secret_key_bytes,
particle_id,
air_size_limit,
particle_size_limit,
call_result_size_limit,
hard_limit_enabled,
},
raw_call_results,
);
@ -91,12 +97,7 @@ impl DataToHumanReadable for NativeAvmRunner {
pub(crate) fn create_native_avm_runner(
test_init_parameters: TestInitParameters,
) -> eyre::Result<Box<NativeAvmRunner>> {
let (air_size_limit, particle_size_limit, call_result_size_limit) =
test_init_parameters.to_attributes_w_default();
let avm_runtime_limits: AVMRuntimeLimits = test_init_parameters.into();
Ok(Box::new(NativeAvmRunner {
air_size_limit,
particle_size_limit,
call_result_size_limit,
}))
Ok(Box::new(NativeAvmRunner { avm_runtime_limits }))
}

View File

@ -16,6 +16,8 @@
use avm_interface::raw_outcome::RawAVMOutcome;
use avm_interface::CallResults;
use avm_server::AVMRuntimeLimits;
use avm_server::RuntimeLimits;
use fluence_keypair::KeyPair;
use std::error::Error as StdError;
@ -49,25 +51,54 @@ pub struct TestInitParameters {
pub air_size_limit: Option<u64>,
pub particle_size_limit: Option<u64>,
pub call_result_size_limit: Option<u64>,
pub hard_limit_enabled: bool,
}
impl TestInitParameters {
pub fn to_attributes_w_default(&self) -> (u64, u64, u64) {
use air_interpreter_interface::MAX_AIR_SIZE;
use air_interpreter_interface::MAX_CALL_RESULT_SIZE;
use air_interpreter_interface::MAX_PARTICLE_SIZE;
let air_size_limit = self.air_size_limit.unwrap_or(MAX_AIR_SIZE);
let particle_size_limit: u64 = self.particle_size_limit.unwrap_or(MAX_PARTICLE_SIZE);
let call_result_size_limit = self.call_result_size_limit.unwrap_or(MAX_CALL_RESULT_SIZE);
(air_size_limit, particle_size_limit, call_result_size_limit)
pub fn new(
air_size_limit: Option<u64>,
particle_size_limit: Option<u64>,
call_result_size_limit: Option<u64>,
hard_limit_enabled: bool,
) -> Self {
Self {
air_size_limit,
particle_size_limit,
call_result_size_limit,
hard_limit_enabled,
}
}
pub fn no_limits() -> Self {
Self {
air_size_limit: Some(u64::MAX),
particle_size_limit: Some(u64::MAX),
call_result_size_limit: Some(u64::MAX),
hard_limit_enabled: false,
}
}
}
impl From<TestInitParameters> for RuntimeLimits {
fn from(value: TestInitParameters) -> Self {
RuntimeLimits::new(
value.air_size_limit,
value.particle_size_limit,
value.call_result_size_limit,
value.hard_limit_enabled,
)
}
}
impl From<TestInitParameters> for AVMRuntimeLimits {
fn from(value: TestInitParameters) -> Self {
use air_interpreter_interface::MAX_AIR_SIZE;
use air_interpreter_interface::MAX_CALL_RESULT_SIZE;
use air_interpreter_interface::MAX_PARTICLE_SIZE;
AVMRuntimeLimits::new(
value.air_size_limit.unwrap_or(MAX_AIR_SIZE),
value.particle_size_limit.unwrap_or(MAX_PARTICLE_SIZE),
value.call_result_size_limit.unwrap_or(MAX_CALL_RESULT_SIZE),
value.hard_limit_enabled,
)
}
}

View File

@ -74,15 +74,10 @@ pub(crate) fn create_wasm_avm_runner(
max_heap_size: Option<u64>,
test_init_parameters: TestInitParameters,
) -> eyre::Result<Box<WasmAvmRunner>> {
let (air_size_limit, particle_size_limit, call_result_size_limit) =
test_init_parameters.to_attributes_w_default();
Ok(Box::new(WasmAvmRunner(AVMRunner::new(
air_interpreter_wasm_path.to_owned(),
max_heap_size,
Some(air_size_limit),
Some(particle_size_limit),
Some(call_result_size_limit),
test_init_parameters.into(),
0,
)?)))
}