mirror of
https://github.com/fluencelabs/aquavm
synced 2025-06-23 11:41:33 +00:00
WIP soft limits triggering is signalled via AVMOutcome
This commit is contained in:
@ -25,6 +25,7 @@ use crate::INTERPRETER_SUCCESS;
|
||||
use air_interpreter_data::InterpreterDataEnvelope;
|
||||
use air_interpreter_interface::CallRequests;
|
||||
use air_interpreter_interface::CallRequestsRepr;
|
||||
use air_interpreter_interface::SoftLimitsTriggering;
|
||||
use air_interpreter_sede::ToSerialized;
|
||||
use air_interpreter_signatures::KeyPair;
|
||||
use air_utils::measure;
|
||||
@ -41,6 +42,7 @@ pub(crate) fn from_success_result(
|
||||
exec_ctx: ExecutionCtx<'_>,
|
||||
trace_handler: TraceHandler,
|
||||
keypair: &KeyPair,
|
||||
soft_limits_triggering: SoftLimitsTriggering,
|
||||
) -> Result<InterpreterOutcome, InterpreterOutcome> {
|
||||
let (ret_code, error_message) = if exec_ctx.call_results.is_empty() {
|
||||
(INTERPRETER_SUCCESS, String::new())
|
||||
@ -49,7 +51,14 @@ pub(crate) fn from_success_result(
|
||||
(farewell_error.to_error_code(), farewell_error.to_string())
|
||||
};
|
||||
|
||||
let outcome = populate_outcome_from_contexts(exec_ctx, trace_handler, ret_code, error_message, keypair);
|
||||
let outcome = populate_outcome_from_contexts(
|
||||
exec_ctx,
|
||||
trace_handler,
|
||||
ret_code,
|
||||
error_message,
|
||||
keypair,
|
||||
soft_limits_triggering,
|
||||
);
|
||||
Ok(outcome)
|
||||
}
|
||||
|
||||
@ -59,6 +68,7 @@ pub(crate) fn from_success_result(
|
||||
pub(crate) fn from_uncatchable_error(
|
||||
data: impl Into<Vec<u8>> + Debug,
|
||||
error: impl ToErrorCode + ToString + Debug,
|
||||
soft_limits_triggering: SoftLimitsTriggering,
|
||||
) -> InterpreterOutcome {
|
||||
let ret_code = error.to_error_code();
|
||||
let data = data.into();
|
||||
@ -66,7 +76,14 @@ pub(crate) fn from_uncatchable_error(
|
||||
.serialize(&CallRequests::new())
|
||||
.expect("default serializer shouldn't fail");
|
||||
|
||||
InterpreterOutcome::new(ret_code, error.to_string(), data, vec![], call_requests)
|
||||
InterpreterOutcome::new(
|
||||
ret_code,
|
||||
error.to_string(),
|
||||
data,
|
||||
vec![],
|
||||
call_requests,
|
||||
soft_limits_triggering,
|
||||
)
|
||||
}
|
||||
|
||||
/// Create InterpreterOutcome from supplied execution context, trace handler, and error,
|
||||
@ -77,6 +94,7 @@ pub(crate) fn from_execution_error(
|
||||
trace_handler: TraceHandler,
|
||||
error: impl ToErrorCode + ToString + Debug,
|
||||
keypair: &KeyPair,
|
||||
soft_limits_triggering: SoftLimitsTriggering,
|
||||
) -> InterpreterOutcome {
|
||||
populate_outcome_from_contexts(
|
||||
exec_ctx,
|
||||
@ -84,6 +102,7 @@ pub(crate) fn from_execution_error(
|
||||
error.to_error_code(),
|
||||
error.to_string(),
|
||||
keypair,
|
||||
soft_limits_triggering,
|
||||
)
|
||||
}
|
||||
|
||||
@ -94,13 +113,14 @@ fn populate_outcome_from_contexts(
|
||||
ret_code: i64,
|
||||
error_message: String,
|
||||
keypair: &KeyPair,
|
||||
soft_limits_triggering: SoftLimitsTriggering,
|
||||
) -> InterpreterOutcome {
|
||||
match compactify_streams(&mut exec_ctx, &mut trace_handler) {
|
||||
match compactify_streams(&mut exec_ctx, &mut trace_handler, soft_limits_triggering) {
|
||||
Ok(()) => {}
|
||||
Err(outcome) => return outcome,
|
||||
};
|
||||
|
||||
match sign_result(&mut exec_ctx, keypair) {
|
||||
match sign_result(&mut exec_ctx, keypair, soft_limits_triggering) {
|
||||
Ok(()) => {}
|
||||
Err(outcome) => return outcome,
|
||||
};
|
||||
@ -126,22 +146,37 @@ fn populate_outcome_from_contexts(
|
||||
tracing::Level::INFO,
|
||||
"CallRequestsRepr.serialize",
|
||||
);
|
||||
InterpreterOutcome::new(ret_code, error_message, data, next_peer_pks, call_requests)
|
||||
InterpreterOutcome::new(
|
||||
ret_code,
|
||||
error_message,
|
||||
data,
|
||||
next_peer_pks,
|
||||
call_requests,
|
||||
soft_limits_triggering,
|
||||
)
|
||||
}
|
||||
|
||||
fn compactify_streams(exec_ctx: &mut ExecutionCtx<'_>, trace_ctx: &mut TraceHandler) -> Result<(), InterpreterOutcome> {
|
||||
fn compactify_streams(
|
||||
exec_ctx: &mut ExecutionCtx<'_>,
|
||||
trace_ctx: &mut TraceHandler,
|
||||
soft_limits_triggering: SoftLimitsTriggering,
|
||||
) -> Result<(), InterpreterOutcome> {
|
||||
exec_ctx
|
||||
.streams
|
||||
.compactify(trace_ctx)
|
||||
.and_then(|_| exec_ctx.stream_maps.compactify(trace_ctx))
|
||||
.map_err(execution_error_into_outcome)
|
||||
.map_err(|err| execution_error_into_outcome(err, soft_limits_triggering))
|
||||
}
|
||||
|
||||
fn sign_result(exec_ctx: &mut ExecutionCtx<'_>, keypair: &KeyPair) -> Result<(), InterpreterOutcome> {
|
||||
fn sign_result(
|
||||
exec_ctx: &mut ExecutionCtx<'_>,
|
||||
keypair: &KeyPair,
|
||||
soft_limits_triggering: SoftLimitsTriggering,
|
||||
) -> Result<(), InterpreterOutcome> {
|
||||
let current_signature = exec_ctx
|
||||
.peer_cid_tracker
|
||||
.gen_signature(&exec_ctx.run_parameters.salt, keypair)
|
||||
.map_err(signing_error_into_outcome)?;
|
||||
.map_err(|err| signing_error_into_outcome(err, soft_limits_triggering))?;
|
||||
|
||||
let current_pubkey = keypair.public();
|
||||
exec_ctx.signature_store.put(current_pubkey, current_signature);
|
||||
@ -151,12 +186,29 @@ fn sign_result(exec_ctx: &mut ExecutionCtx<'_>, keypair: &KeyPair) -> Result<(),
|
||||
|
||||
// these methods are called only if there is an internal error in the interpreter and
|
||||
// new execution trace was corrupted
|
||||
fn execution_error_into_outcome(error: ExecutionError) -> InterpreterOutcome {
|
||||
InterpreterOutcome::new(error.to_error_code(), error.to_string(), vec![], vec![], <_>::default())
|
||||
fn execution_error_into_outcome(
|
||||
error: ExecutionError,
|
||||
soft_limits_triggering: SoftLimitsTriggering,
|
||||
) -> InterpreterOutcome {
|
||||
InterpreterOutcome::new(
|
||||
error.to_error_code(),
|
||||
error.to_string(),
|
||||
vec![],
|
||||
vec![],
|
||||
<_>::default(),
|
||||
soft_limits_triggering,
|
||||
)
|
||||
}
|
||||
|
||||
fn signing_error_into_outcome(error: SigningError) -> InterpreterOutcome {
|
||||
InterpreterOutcome::new(error.to_error_code(), error.to_string(), vec![], vec![], <_>::default())
|
||||
fn signing_error_into_outcome(error: SigningError, soft_limits_triggering: SoftLimitsTriggering) -> InterpreterOutcome {
|
||||
InterpreterOutcome::new(
|
||||
error.to_error_code(),
|
||||
error.to_string(),
|
||||
vec![],
|
||||
vec![],
|
||||
<_>::default(),
|
||||
soft_limits_triggering,
|
||||
)
|
||||
}
|
||||
|
||||
/// Deduplicate values in a supplied vector.
|
||||
|
@ -128,7 +128,7 @@ impl PreparationError {
|
||||
}
|
||||
|
||||
pub fn air_size_limit(actual_size: usize, limit: u64) -> Self {
|
||||
Self::SizeLimitsExceded(SizeLimitsExceded::AIR(actual_size, limit))
|
||||
Self::SizeLimitsExceded(SizeLimitsExceded::Air(actual_size, limit))
|
||||
}
|
||||
|
||||
pub fn particle_size_limit(actual_size: usize, limit: u64) -> Self {
|
||||
@ -144,7 +144,7 @@ impl PreparationError {
|
||||
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),
|
||||
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")]
|
||||
|
@ -26,6 +26,7 @@ use air_interpreter_data::Versions;
|
||||
use air_interpreter_interface::CallResultsRepr;
|
||||
use air_interpreter_interface::RunParameters;
|
||||
use air_interpreter_interface::SerializedCallResults;
|
||||
use air_interpreter_interface::SoftLimitsTriggering;
|
||||
use air_interpreter_sede::FromSerialized;
|
||||
use air_interpreter_signatures::KeyError;
|
||||
use air_interpreter_signatures::KeyPair;
|
||||
@ -75,6 +76,7 @@ pub(crate) fn prepare<'i>(
|
||||
call_results: &SerializedCallResults,
|
||||
run_parameters: RunParameters,
|
||||
signature_store: SignatureStore,
|
||||
soft_limits_triggering: &mut SoftLimitsTriggering,
|
||||
) -> PreparationResult<PreparationDescriptor<'static, 'i>> {
|
||||
let air: Instruction<'i> = air_parser::parse(raw_air).map_err(PreparationError::AIRParseError)?;
|
||||
|
||||
@ -94,6 +96,7 @@ pub(crate) fn prepare<'i>(
|
||||
call_results,
|
||||
signature_store,
|
||||
&run_parameters,
|
||||
soft_limits_triggering,
|
||||
)?;
|
||||
let trace_handler = TraceHandler::from_trace(prev_data.trace, current_data.trace);
|
||||
|
||||
@ -143,6 +146,7 @@ fn make_exec_ctx(
|
||||
call_results: &SerializedCallResults,
|
||||
signature_store: SignatureStore,
|
||||
run_parameters: &RunParameters,
|
||||
soft_limits_triggering: &mut SoftLimitsTriggering,
|
||||
) -> PreparationResult<ExecutionCtx<'static>> {
|
||||
use crate::preparation_step::sizes_limits_check::limit_behavior;
|
||||
|
||||
@ -159,8 +163,12 @@ fn make_exec_ctx(
|
||||
.values()
|
||||
.any(|call_result| call_result.result.len() > run_parameters.call_result_size_limit as usize)
|
||||
{
|
||||
let error = PreparationError::call_result_size_limit(run_parameters.call_result_size_limit);
|
||||
limit_behavior(run_parameters, error)?;
|
||||
let error: PreparationError = PreparationError::call_result_size_limit(run_parameters.call_result_size_limit);
|
||||
limit_behavior(
|
||||
run_parameters,
|
||||
error,
|
||||
&mut soft_limits_triggering.particle_size_limit_exceeded,
|
||||
)?;
|
||||
}
|
||||
|
||||
let ctx = ExecutionCtx::new(
|
||||
|
@ -17,12 +17,17 @@
|
||||
use super::preparation::PreparationResult;
|
||||
use crate::PreparationError;
|
||||
|
||||
use air_interpreter_interface::RunParameters;
|
||||
use air_interpreter_interface::{RunParameters, SoftLimitsTriggering};
|
||||
|
||||
pub(crate) fn limit_behavior(run_parameters: &RunParameters, error: PreparationError) -> PreparationResult<()> {
|
||||
pub(crate) fn limit_behavior(
|
||||
run_parameters: &RunParameters,
|
||||
error: PreparationError,
|
||||
soft_limit_flag: &mut bool,
|
||||
) -> PreparationResult<()> {
|
||||
if run_parameters.hard_limit_enabled {
|
||||
Err(error)
|
||||
} else {
|
||||
*soft_limit_flag = true;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@ -31,16 +36,26 @@ pub(crate) fn check_against_size_limits(
|
||||
run_parameters: &RunParameters,
|
||||
air: &str,
|
||||
raw_current_data: &[u8],
|
||||
) -> PreparationResult<()> {
|
||||
) -> PreparationResult<SoftLimitsTriggering> {
|
||||
let mut soft_limits_triggering = SoftLimitsTriggering::default();
|
||||
|
||||
if air.len() as u64 > run_parameters.air_size_limit {
|
||||
let error = PreparationError::air_size_limit(air.len(), run_parameters.air_size_limit);
|
||||
limit_behavior(run_parameters, error)?;
|
||||
limit_behavior(
|
||||
run_parameters,
|
||||
error,
|
||||
&mut soft_limits_triggering.air_size_limit_exceeded,
|
||||
)?;
|
||||
}
|
||||
|
||||
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)?;
|
||||
limit_behavior(
|
||||
run_parameters,
|
||||
error,
|
||||
&mut soft_limits_triggering.particle_size_limit_exceeded,
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(soft_limits_triggering)
|
||||
}
|
||||
|
@ -63,20 +63,34 @@ fn execute_air_impl(
|
||||
) -> Result<InterpreterOutcome, InterpreterOutcome> {
|
||||
use crate::preparation_step::check_against_size_limits;
|
||||
|
||||
farewell_if_fail!(
|
||||
let mut soft_limits_triggering = farewell_if_fail!(
|
||||
check_against_size_limits(¶ms, &air, &raw_current_data),
|
||||
raw_prev_data
|
||||
);
|
||||
|
||||
farewell_if_fail!(
|
||||
check_against_size_limits(¶ms, &air, &raw_current_data),
|
||||
raw_prev_data,
|
||||
soft_limits_triggering
|
||||
);
|
||||
|
||||
let ParsedDataPair {
|
||||
prev_data,
|
||||
current_data,
|
||||
} = farewell_if_fail!(parse_data(&raw_prev_data, &raw_current_data), raw_prev_data);
|
||||
} = farewell_if_fail!(
|
||||
parse_data(&raw_prev_data, &raw_current_data),
|
||||
raw_prev_data,
|
||||
soft_limits_triggering
|
||||
);
|
||||
|
||||
// TODO currently we use particle ID, but it should be changed to signature,
|
||||
// as partical ID can be equally replayed
|
||||
let salt = params.particle_id.clone();
|
||||
let signature_store = farewell_if_fail!(verify(&prev_data, ¤t_data, &salt), raw_prev_data);
|
||||
let signature_store = farewell_if_fail!(
|
||||
verify(&prev_data, ¤t_data, &salt),
|
||||
raw_prev_data,
|
||||
soft_limits_triggering
|
||||
);
|
||||
|
||||
let PreparationDescriptor {
|
||||
mut exec_ctx,
|
||||
@ -84,8 +98,17 @@ fn execute_air_impl(
|
||||
air,
|
||||
keypair,
|
||||
} = farewell_if_fail!(
|
||||
prepare(prev_data, current_data, &air, &call_results, params, signature_store,),
|
||||
raw_prev_data
|
||||
prepare(
|
||||
prev_data,
|
||||
current_data,
|
||||
&air,
|
||||
&call_results,
|
||||
params,
|
||||
signature_store,
|
||||
&mut soft_limits_triggering
|
||||
),
|
||||
raw_prev_data,
|
||||
soft_limits_triggering
|
||||
);
|
||||
|
||||
// match here is used instead of map_err, because the compiler can't determine that
|
||||
@ -103,18 +126,29 @@ fn execute_air_impl(
|
||||
&salt,
|
||||
&keypair,
|
||||
),
|
||||
raw_prev_data
|
||||
raw_prev_data,
|
||||
soft_limits_triggering
|
||||
);
|
||||
|
||||
measure!(
|
||||
match exec_result {
|
||||
Ok(_) => farewell::from_success_result(exec_ctx, trace_handler, &keypair),
|
||||
Ok(_) => farewell::from_success_result(exec_ctx, trace_handler, &keypair, soft_limits_triggering),
|
||||
// return new collected trace in case of errors
|
||||
Err(error) if error.is_catchable() => {
|
||||
Err(farewell::from_execution_error(exec_ctx, trace_handler, error, &keypair))
|
||||
Err(farewell::from_execution_error(
|
||||
exec_ctx,
|
||||
trace_handler,
|
||||
error,
|
||||
&keypair,
|
||||
soft_limits_triggering,
|
||||
))
|
||||
}
|
||||
// return the prev data in case of any trace errors
|
||||
Err(error) => Err(farewell::from_uncatchable_error(raw_prev_data, error)),
|
||||
Err(error) => Err(farewell::from_uncatchable_error(
|
||||
raw_prev_data,
|
||||
error,
|
||||
soft_limits_triggering
|
||||
)),
|
||||
},
|
||||
tracing::Level::INFO,
|
||||
"farewell",
|
||||
|
@ -17,6 +17,7 @@
|
||||
use super::CallRequests;
|
||||
use crate::raw_outcome::RawAVMOutcome;
|
||||
|
||||
use air_interpreter_interface::SoftLimitsTriggering;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
||||
@ -40,6 +41,8 @@ pub struct AVMOutcome {
|
||||
/// Time of a particle execution
|
||||
/// (it counts only execution time without operations with DataStore and so on)
|
||||
pub execution_time: Duration,
|
||||
|
||||
soft_limits_triggering: SoftLimitsTriggering, // WIP
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
@ -56,6 +59,7 @@ impl AVMOutcome {
|
||||
next_peer_pks: Vec<String>,
|
||||
memory_delta: usize,
|
||||
execution_time: Duration,
|
||||
soft_limits_triggering: SoftLimitsTriggering,
|
||||
) -> Self {
|
||||
Self {
|
||||
data,
|
||||
@ -63,6 +67,7 @@ impl AVMOutcome {
|
||||
next_peer_pks,
|
||||
memory_delta,
|
||||
execution_time,
|
||||
soft_limits_triggering,
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,6 +85,7 @@ impl AVMOutcome {
|
||||
data,
|
||||
call_requests,
|
||||
next_peer_pks,
|
||||
soft_limits_triggering,
|
||||
} = raw_outcome;
|
||||
|
||||
let avm_outcome = AVMOutcome::new(
|
||||
@ -88,6 +94,7 @@ impl AVMOutcome {
|
||||
next_peer_pks,
|
||||
memory_delta,
|
||||
execution_time,
|
||||
soft_limits_triggering,
|
||||
);
|
||||
|
||||
if ret_code == INTERPRETER_SUCCESS {
|
||||
|
@ -20,6 +20,7 @@ use super::CallRequests;
|
||||
|
||||
use air_interpreter_interface::InterpreterOutcome;
|
||||
|
||||
use air_interpreter_interface::SoftLimitsTriggering;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
||||
@ -31,6 +32,7 @@ pub struct RawAVMOutcome {
|
||||
pub data: Vec<u8>,
|
||||
pub call_requests: CallRequests,
|
||||
pub next_peer_pks: Vec<String>,
|
||||
pub soft_limits_triggering: SoftLimitsTriggering,
|
||||
}
|
||||
|
||||
impl RawAVMOutcome {
|
||||
@ -41,9 +43,17 @@ impl RawAVMOutcome {
|
||||
data,
|
||||
call_requests,
|
||||
next_peer_pks,
|
||||
air_size_limit_exceeded,
|
||||
particle_size_limit_exceeded,
|
||||
call_result_size_limit_exceeded,
|
||||
} = outcome;
|
||||
|
||||
let call_requests = crate::from_raw_call_requests(call_requests.into())?;
|
||||
let soft_limits_triggering = SoftLimitsTriggering::new(
|
||||
air_size_limit_exceeded,
|
||||
particle_size_limit_exceeded,
|
||||
call_result_size_limit_exceeded,
|
||||
);
|
||||
|
||||
let raw_avm_outcome = Self {
|
||||
ret_code,
|
||||
@ -51,6 +61,7 @@ impl RawAVMOutcome {
|
||||
data,
|
||||
call_requests,
|
||||
next_peer_pks,
|
||||
soft_limits_triggering,
|
||||
};
|
||||
|
||||
Ok(raw_avm_outcome)
|
||||
|
@ -43,6 +43,7 @@ pub struct AVMRuntimeLimits {
|
||||
pub hard_limit_enabled: bool,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct RuntimeLimits {
|
||||
// The AIR script size limit.
|
||||
pub air_size_limit: Option<u64>,
|
||||
@ -392,17 +393,6 @@ impl RuntimeLimits {
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -25,6 +25,7 @@ pub struct AVMRuntimeLimits {
|
||||
pub hard_limit_enabled: bool,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct RuntimeLimits {
|
||||
pub air_size_limit: Option<u64>,
|
||||
pub particle_size_limit: Option<u64>,
|
||||
@ -48,17 +49,6 @@ impl AVMRuntimeLimits {
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -24,6 +24,13 @@ use serde::Serialize;
|
||||
|
||||
pub const INTERPRETER_SUCCESS: i64 = 0;
|
||||
|
||||
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct SoftLimitsTriggering {
|
||||
pub air_size_limit_exceeded: bool,
|
||||
pub particle_size_limit_exceeded: bool,
|
||||
pub call_result_size_limit_exceeded: bool,
|
||||
}
|
||||
|
||||
/// Describes a result returned at the end of the interpreter execution_step.
|
||||
#[cfg_attr(feature = "marine", marine)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
@ -43,6 +50,25 @@ pub struct InterpreterOutcome {
|
||||
|
||||
/// Collected parameters of all met call instructions that could be executed on a current peer.
|
||||
pub call_requests: Vec<u8>,
|
||||
|
||||
/// WIP
|
||||
pub air_size_limit_exceeded: bool,
|
||||
pub particle_size_limit_exceeded: bool,
|
||||
pub call_result_size_limit_exceeded: bool,
|
||||
}
|
||||
|
||||
impl SoftLimitsTriggering {
|
||||
pub fn new(
|
||||
air_size_limit_exceeded: bool,
|
||||
particle_size_limit_exceeded: bool,
|
||||
call_result_size_limit_exceeded: bool,
|
||||
) -> Self {
|
||||
Self {
|
||||
air_size_limit_exceeded,
|
||||
particle_size_limit_exceeded,
|
||||
call_result_size_limit_exceeded,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl InterpreterOutcome {
|
||||
@ -52,6 +78,7 @@ impl InterpreterOutcome {
|
||||
data: Vec<u8>,
|
||||
next_peer_pks: Vec<String>,
|
||||
call_requests: SerializedCallRequests,
|
||||
soft_limits_triggering: SoftLimitsTriggering,
|
||||
) -> Self {
|
||||
let call_requests = call_requests.into();
|
||||
Self {
|
||||
@ -60,6 +87,9 @@ impl InterpreterOutcome {
|
||||
data,
|
||||
next_peer_pks,
|
||||
call_requests,
|
||||
air_size_limit_exceeded: soft_limits_triggering.air_size_limit_exceeded,
|
||||
particle_size_limit_exceeded: soft_limits_triggering.particle_size_limit_exceeded,
|
||||
call_result_size_limit_exceeded: soft_limits_triggering.call_result_size_limit_exceeded,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -67,7 +97,7 @@ impl InterpreterOutcome {
|
||||
#[cfg(feature = "marine")]
|
||||
impl InterpreterOutcome {
|
||||
pub fn from_ivalue(ivalue: IValue) -> Result<Self, String> {
|
||||
const OUTCOME_FIELDS_COUNT: usize = 5;
|
||||
const OUTCOME_FIELDS_COUNT: usize = 8;
|
||||
|
||||
let mut record_values = try_as_record(ivalue)?.into_vec();
|
||||
if record_values.len() != OUTCOME_FIELDS_COUNT {
|
||||
@ -76,11 +106,24 @@ impl InterpreterOutcome {
|
||||
));
|
||||
}
|
||||
|
||||
let air_size_limit_exceeded =
|
||||
try_as_boolean(record_values.pop().unwrap(), "air_size_limit_exceeded")?;
|
||||
let particle_size_limit_exceeded =
|
||||
try_as_boolean(record_values.pop().unwrap(), "particle_size_limit_exceeded")?;
|
||||
let call_result_size_limit_exceeded = try_as_boolean(
|
||||
record_values.pop().unwrap(),
|
||||
"call_result_size_limit_exceeded",
|
||||
)?;
|
||||
let call_requests = try_as_byte_vec(record_values.pop().unwrap(), "call_requests")?;
|
||||
let next_peer_pks = try_as_string_vec(record_values.pop().unwrap(), "next_peer_pks")?;
|
||||
let data = try_as_byte_vec(record_values.pop().unwrap(), "data")?;
|
||||
let error_message = try_as_string(record_values.pop().unwrap(), "error_message")?;
|
||||
let ret_code = try_as_i64(record_values.pop().unwrap(), "ret_code")?;
|
||||
let soft_limits_triggering = SoftLimitsTriggering::new(
|
||||
air_size_limit_exceeded,
|
||||
particle_size_limit_exceeded,
|
||||
call_result_size_limit_exceeded,
|
||||
);
|
||||
|
||||
let outcome = Self::new(
|
||||
ret_code,
|
||||
@ -88,6 +131,7 @@ impl InterpreterOutcome {
|
||||
data,
|
||||
next_peer_pks,
|
||||
call_requests.into(),
|
||||
soft_limits_triggering,
|
||||
);
|
||||
|
||||
Ok(outcome)
|
||||
@ -160,3 +204,11 @@ fn try_as_string_vec(ivalue: IValue, field_name: &str) -> Result<Vec<String>, St
|
||||
v => Err(format!("expected an array for {field_name}, got {v:?}")),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "marine")]
|
||||
fn try_as_boolean(ivalue: IValue, field_name: &str) -> Result<bool, String> {
|
||||
match ivalue {
|
||||
IValue::Boolean(value) => Ok(value),
|
||||
v => Err(format!("expected a bool for {field_name}, got {v:?}")),
|
||||
}
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ impl AirRunner for WasmAirRunner {
|
||||
)
|
||||
});
|
||||
|
||||
let runner = pool.pull(|| make_pooled_avm_runner(test_init_parameters.clone()));
|
||||
let runner = pool.pull(|| make_pooled_avm_runner(test_init_parameters));
|
||||
|
||||
Self {
|
||||
current_peer_id: current_peer_id.into(),
|
||||
|
@ -51,11 +51,26 @@ macro_rules! auto_checked_add {
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! farewell_if_fail {
|
||||
($cmd:expr, $raw_prev_data:expr, $soft_limits_triggering:expr) => {
|
||||
match $cmd {
|
||||
Ok(result) => result,
|
||||
// return the prev data in case of errors
|
||||
Err(error) => {
|
||||
return Err(farewell::from_uncatchable_error(
|
||||
$raw_prev_data,
|
||||
error,
|
||||
$soft_limits_triggering,
|
||||
))
|
||||
}
|
||||
};
|
||||
};
|
||||
($cmd:expr, $raw_prev_data:expr) => {
|
||||
match $cmd {
|
||||
Ok(result) => result,
|
||||
// return the prev data in case of errors
|
||||
Err(error) => return Err(farewell::from_uncatchable_error($raw_prev_data, error)),
|
||||
Err(error) => {
|
||||
farewell_if_fail!($cmd, $raw_prev_data, <_>::default())
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ impl<R: AirRunner> Network<R> {
|
||||
resolver: Default::default(),
|
||||
});
|
||||
for peer_name in named_peers {
|
||||
network.ensure_named_peer(peer_name, test_init_params.clone());
|
||||
network.ensure_named_peer(peer_name, test_init_params);
|
||||
}
|
||||
network
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ impl<R: AirRunner> AirScriptExecutor<R> {
|
||||
annotated_air_script: &str,
|
||||
) -> Result<Self, String> {
|
||||
let transformed =
|
||||
TransformedAirScript::new(annotated_air_script, network, test_init_parameters.clone())?;
|
||||
TransformedAirScript::new(annotated_air_script, network, test_init_parameters)?;
|
||||
|
||||
Self::from_transformed_air_script(test_parameters, test_init_parameters, transformed)
|
||||
}
|
||||
@ -115,10 +115,10 @@ impl<R: AirRunner> AirScriptExecutor<R> {
|
||||
let network = Network::new(
|
||||
extra_peers.into_iter(),
|
||||
common_services,
|
||||
test_init_parameters.clone(),
|
||||
test_init_parameters,
|
||||
);
|
||||
let transformed =
|
||||
TransformedAirScript::new(annotated_air_script, network, test_init_parameters.clone())?;
|
||||
TransformedAirScript::new(annotated_air_script, network, test_init_parameters)?;
|
||||
|
||||
Self::from_transformed_air_script(test_parameters, test_init_parameters, transformed)
|
||||
}
|
||||
|
@ -83,11 +83,11 @@ struct Transformer<'net, R> {
|
||||
impl<R: AirRunner> Transformer<'_, R> {
|
||||
pub(crate) fn transform(&self, sexp: &mut Sexp, test_init_parameters: TestInitParameters) {
|
||||
match sexp {
|
||||
Sexp::Call(call) => self.handle_call(call, test_init_parameters.clone()),
|
||||
Sexp::Canon(canon) => self.handle_canon(canon, test_init_parameters.clone()),
|
||||
Sexp::Call(call) => self.handle_call(call, test_init_parameters),
|
||||
Sexp::Canon(canon) => self.handle_canon(canon, test_init_parameters),
|
||||
Sexp::List(children) => {
|
||||
for child in children.iter_mut().skip(1) {
|
||||
self.transform(child, test_init_parameters.clone());
|
||||
self.transform(child, test_init_parameters);
|
||||
}
|
||||
}
|
||||
Sexp::Symbol(_) | Sexp::String(_) => {}
|
||||
|
Reference in New Issue
Block a user