feat(interpreter-data)!: New data format for calls (#501)

BREAKING CHANGE:
1. Call values in the trace have CID references to structures that have call arguments' hash and CID references to values and tetraplets.
2. If call value is unused, it is serialized with `Unused` variant, and CID references are not stored.

Previous data scheme was (Scalar as an example, other cases are similar):

```
Scalar(CID<JValue>) ---<value_store>----> JValue
```

New data scheme is much more sophisticated:

```
Scalar(CID<ServiceResultAggregate>) ---+
                                       |
  +----<service_result_store>----------+
  |
  +-------> ServiceResultAggregate:
               value_cid ------------<value_store>----> JValue
               tetraplet_cid --------<tetraplet_store>----> SecurityTetraplet
               argument_hash: String
```
`Stream` variant is similar, however, `Unused` is different: it has value CID only, but the value is not stored into the `value_store`:

```
Unused(Rc<CID<JValue>>) ---> X
```

Co-authored-by: Mike Voronov <michail.vms@gmail.com>
This commit is contained in:
Ivan Boldyrev
2023-03-21 19:12:04 +07:00
committed by GitHub
parent 631abd4ec4
commit d5028942e4
56 changed files with 2965 additions and 1302 deletions

View File

@ -89,6 +89,9 @@ pub enum UncatchableError {
stream is {stream:?}"
)]
StreamDontHaveSuchGeneration { stream: Stream, generation: Generation },
#[error("failed to deserialize to CallServiceFailed: {0}")]
MalformedCallServiceFailed(serde_json::Error),
}
impl ToErrorCode for UncatchableError {

View File

@ -0,0 +1,143 @@
/*
* Copyright 2023 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.
*/
use crate::execution_step::RcSecurityTetraplet;
use crate::execution_step::ValueAggregate;
use crate::JValue;
use crate::UncatchableError;
use air_interpreter_cid::CidCalculationError;
use air_interpreter_cid::CID;
use air_interpreter_data::CanonCidAggregate;
use air_interpreter_data::CidInfo;
use air_interpreter_data::CidTracker;
use air_interpreter_data::ServiceResultAggregate;
use air_interpreter_data::TracePos;
use polyplets::SecurityTetraplet;
use std::rc::Rc;
#[derive(Debug, Default, Clone)]
pub struct ExecutionCidState {
pub value_tracker: CidTracker<JValue>,
pub tetraplet_tracker: CidTracker<SecurityTetraplet>,
pub canon_tracker: CidTracker<CanonCidAggregate>,
pub service_result_agg_tracker: CidTracker<ServiceResultAggregate>,
}
impl ExecutionCidState {
pub fn new() -> Self {
Self::default()
}
pub fn insert_value(
&mut self,
value: Rc<JValue>,
tetraplet: RcSecurityTetraplet,
argument_hash: Rc<str>,
) -> Result<Rc<CID<ServiceResultAggregate>>, CidCalculationError> {
let value_cid = self.value_tracker.record_value(value)?;
let tetraplet_cid = self.tetraplet_tracker.record_value(tetraplet)?;
let service_result_agg = ServiceResultAggregate {
value_cid,
argument_hash,
tetraplet_cid,
};
self.service_result_agg_tracker.record_value(service_result_agg)
}
pub(crate) fn from_cid_info(prev_cid_info: CidInfo, current_cid_info: CidInfo) -> Self {
let value_tracker = CidTracker::from_cid_stores(prev_cid_info.value_store, current_cid_info.value_store);
let tetraplet_tracker =
CidTracker::from_cid_stores(prev_cid_info.tetraplet_store, current_cid_info.tetraplet_store);
let canon_tracker = CidTracker::from_cid_stores(prev_cid_info.canon_store, current_cid_info.canon_store);
let service_result_agg_tracker = CidTracker::from_cid_stores(
prev_cid_info.service_result_store,
current_cid_info.service_result_store,
);
Self {
value_tracker,
tetraplet_tracker,
canon_tracker,
service_result_agg_tracker,
}
}
pub(crate) fn get_value_by_cid(&self, cid: &CID<JValue>) -> Result<Rc<JValue>, UncatchableError> {
self.value_tracker
.get(cid)
.ok_or_else(|| UncatchableError::ValueForCidNotFound("value", cid.clone().into()))
}
pub(crate) fn get_tetraplet_by_cid(
&self,
cid: &CID<SecurityTetraplet>,
) -> Result<RcSecurityTetraplet, UncatchableError> {
self.tetraplet_tracker
.get(cid)
.ok_or_else(|| UncatchableError::ValueForCidNotFound("tetraplet", cid.clone().into()))
}
pub(crate) fn get_canon_value_by_cid(
&self,
cid: &CID<CanonCidAggregate>,
) -> Result<ValueAggregate, UncatchableError> {
let canon_aggregate = self
.canon_tracker
.get(cid)
.ok_or_else(|| UncatchableError::ValueForCidNotFound("canon aggregate", cid.clone().into()))?;
let result = self.get_value_by_cid(&canon_aggregate.value)?;
let tetraplet = self.get_tetraplet_by_cid(&canon_aggregate.tetraplet)?;
let fake_trace_pos = TracePos::default();
Ok(ValueAggregate {
result,
tetraplet,
trace_pos: fake_trace_pos,
})
}
pub(crate) fn get_service_result_agg_by_cid(
&self,
cid: &CID<ServiceResultAggregate>,
) -> Result<Rc<ServiceResultAggregate>, UncatchableError> {
self.service_result_agg_tracker
.get(cid)
.ok_or_else(|| UncatchableError::ValueForCidNotFound("service result aggregate", cid.clone().into()))
}
pub(crate) fn resolve_service_value(
&self,
service_result_agg_cid: &CID<ServiceResultAggregate>,
) -> Result<Rc<JValue>, UncatchableError> {
let service_result_aggregate = self.get_service_result_agg_by_cid(service_result_agg_cid)?;
self.get_value_by_cid(&service_result_aggregate.value_cid)
}
}
impl From<ExecutionCidState> for CidInfo {
fn from(value: ExecutionCidState) -> Self {
Self {
value_store: value.value_tracker.into(),
tetraplet_store: value.tetraplet_tracker.into(),
canon_store: value.canon_tracker.into(),
service_result_store: value.service_result_agg_tracker.into(),
}
}
}

View File

@ -14,25 +14,17 @@
* limitations under the License.
*/
use super::ExecutionCidState;
use super::LastError;
use super::LastErrorDescriptor;
use super::Scalars;
use super::Streams;
use crate::execution_step::RcSecurityTetraplet;
use crate::execution_step::ValueAggregate;
use crate::JValue;
use crate::UncatchableError;
use air_execution_info_collector::InstructionTracker;
use air_interpreter_cid::CID;
use air_interpreter_data::CanonCidAggregate;
use air_interpreter_data::CidInfo;
use air_interpreter_data::CidTracker;
use air_interpreter_data::GlobalStreamGens;
use air_interpreter_data::RestrictedStreamGens;
use air_interpreter_data::TracePos;
use air_interpreter_interface::*;
use polyplets::SecurityTetraplet;
use std::rc::Rc;
@ -144,70 +136,6 @@ pub(crate) struct ExecCtxIngredients {
pub(crate) cid_info: CidInfo,
}
#[derive(Debug, Default, Clone)]
pub struct ExecutionCidState {
pub(crate) value_tracker: CidTracker<JValue>,
pub(crate) tetraplet_tracker: CidTracker<SecurityTetraplet>,
pub(crate) canon_tracker: CidTracker<CanonCidAggregate>,
}
impl ExecutionCidState {
fn from_cid_info(prev_cid_info: CidInfo, current_cid_info: CidInfo) -> Self {
Self {
value_tracker: CidTracker::from_cid_stores(prev_cid_info.value_store, current_cid_info.value_store),
tetraplet_tracker: CidTracker::from_cid_stores(
prev_cid_info.tetraplet_store,
current_cid_info.tetraplet_store,
),
canon_tracker: CidTracker::from_cid_stores(prev_cid_info.canon_store, current_cid_info.canon_store),
}
}
pub(crate) fn get_value_by_cid(&self, cid: &CID<JValue>) -> Result<Rc<JValue>, UncatchableError> {
self.value_tracker
.get(cid)
.ok_or_else(|| UncatchableError::ValueForCidNotFound("value", cid.clone().into()))
}
pub(crate) fn get_tetraplet_by_cid(
&self,
cid: &CID<SecurityTetraplet>,
) -> Result<RcSecurityTetraplet, UncatchableError> {
self.tetraplet_tracker
.get(cid)
.ok_or_else(|| UncatchableError::ValueForCidNotFound("tetraplet", cid.clone().into()))
}
pub(crate) fn get_canon_value_by_cid(
&self,
cid: &CID<CanonCidAggregate>,
) -> Result<ValueAggregate, UncatchableError> {
let canon_aggregate = self
.canon_tracker
.get(cid)
.ok_or_else(|| UncatchableError::ValueForCidNotFound("canon aggregate", cid.clone().into()))?;
let result = self.get_value_by_cid(&canon_aggregate.value)?;
let tetraplet = self.get_tetraplet_by_cid(&canon_aggregate.tetraplet)?;
let fake_trace_pos = TracePos::default();
Ok(ValueAggregate {
result,
tetraplet,
trace_pos: fake_trace_pos,
})
}
}
impl From<ExecutionCidState> for CidInfo {
fn from(value: ExecutionCidState) -> Self {
Self {
value_store: value.value_tracker.into(),
tetraplet_store: value.tetraplet_tracker.into(),
canon_store: value.canon_tracker.into(),
}
}
}
use serde::Deserialize;
use serde::Serialize;
use std::fmt::Display;

View File

@ -14,6 +14,7 @@
* limitations under the License.
*/
mod cid_state;
mod context;
mod last_error;
mod scalar_variables;
@ -21,6 +22,7 @@ mod streams_variables;
pub use last_error::*;
pub use cid_state::ExecutionCidState;
pub(crate) use context::*;
pub(crate) use scalar_variables::*;
pub(crate) use streams_variables::*;

View File

@ -20,6 +20,7 @@ use crate::execution_step::Generation;
use crate::execution_step::ValueAggregate;
use crate::UncatchableError;
use air_interpreter_cid::value_to_json_cid;
use air_interpreter_data::CallResult;
use air_interpreter_data::TracePos;
use air_interpreter_data::ValueRef;
@ -30,20 +31,26 @@ use air_trace_handler::TraceHandler;
pub(crate) fn populate_context_from_peer_service_result<'i>(
executed_result: ValueAggregate,
output: &CallOutputValue<'i>,
tetraplet: RcSecurityTetraplet,
argument_hash: Rc<str>,
exec_ctx: &mut ExecutionCtx<'i>,
) -> ExecutionResult<CallResult> {
let cid = exec_ctx
.cid_state
.value_tracker
.record_value(executed_result.result.clone())
.map_err(UncatchableError::from)?;
match output {
CallOutputValue::Scalar(scalar) => {
let service_result_agg_cid = exec_ctx
.cid_state
.insert_value(executed_result.result.clone(), tetraplet, argument_hash)
.map_err(UncatchableError::from)?;
exec_ctx.scalars.set_scalar_value(scalar.name, executed_result)?;
Ok(CallResult::executed_scalar(cid))
Ok(CallResult::executed_scalar(service_result_agg_cid))
}
CallOutputValue::Stream(stream) => {
let service_result_agg_cid = exec_ctx
.cid_state
.insert_value(executed_result.result.clone(), tetraplet, argument_hash)
.map_err(UncatchableError::from)?;
let value_descriptor = StreamValueDescriptor::new(
executed_result,
stream.name,
@ -52,11 +59,15 @@ pub(crate) fn populate_context_from_peer_service_result<'i>(
stream.position,
);
let generation = exec_ctx.streams.add_stream_value(value_descriptor)?;
Ok(CallResult::executed_stream(cid, generation))
Ok(CallResult::executed_stream(service_result_agg_cid, generation))
}
CallOutputValue::None => {
let value_cid = value_to_json_cid(&*executed_result.result)
.map_err(UncatchableError::from)?
.into();
Ok(CallResult::executed_unused(value_cid))
}
// by the internal conventions if call has no output value,
// corresponding data should have scalar type
CallOutputValue::None => Ok(CallResult::executed_scalar(cid)),
}
}
@ -70,13 +81,13 @@ pub(crate) fn populate_context_from_data<'i>(
) -> ExecutionResult<ValueRef> {
match (output, value) {
(CallOutputValue::Scalar(scalar), ValueRef::Scalar(cid)) => {
let value = exec_ctx.cid_state.get_value_by_cid(&cid)?;
let value = exec_ctx.cid_state.resolve_service_value(&cid)?;
let result = ValueAggregate::new(value, tetraplet, trace_pos);
exec_ctx.scalars.set_scalar_value(scalar.name, result)?;
Ok(ValueRef::Scalar(cid))
}
(CallOutputValue::Stream(stream), ValueRef::Stream { cid, generation }) => {
let value = exec_ctx.cid_state.get_value_by_cid(&cid)?;
let value = exec_ctx.cid_state.resolve_service_value(&cid)?;
let result = ValueAggregate::new(value, tetraplet, trace_pos);
let value_descriptor = StreamValueDescriptor::new(
result,
@ -93,9 +104,7 @@ pub(crate) fn populate_context_from_data<'i>(
};
Ok(result)
}
// by the internal conventions if call has no output value,
// corresponding data should have scalar type
(CallOutputValue::None, value @ ValueRef::Scalar(_)) => Ok(value),
(CallOutputValue::None, value @ ValueRef::Unused(_)) => Ok(value),
(_, value) => Err(ExecutionError::Uncatchable(
UncatchableError::CallResultNotCorrespondToInstr(value),
)),

View File

@ -18,8 +18,10 @@ use super::*;
use crate::execution_step::instructions::call::call_result_setter::populate_context_from_data;
use crate::execution_step::CatchableError;
use crate::execution_step::RcSecurityTetraplet;
use crate::UncatchableError;
use air_interpreter_data::CallResult;
use air_interpreter_data::CallServiceFailed;
use air_interpreter_data::Sender;
use air_interpreter_interface::CallServiceResult;
use air_parser::ast::CallOutputValue;
@ -40,6 +42,7 @@ pub(crate) struct StateDescriptor {
pub(super) fn handle_prev_state<'i>(
met_result: MetCallResult,
tetraplet: &RcSecurityTetraplet,
argument_hash: Option<&Rc<str>>,
output: &CallOutputValue<'i>,
exec_ctx: &mut ExecutionCtx<'i>,
trace_ctx: &mut TraceHandler,
@ -49,11 +52,19 @@ pub(super) fn handle_prev_state<'i>(
match met_result.result {
// this call was failed on one of the previous executions,
// here it's needed to bubble this special error up
CallServiceFailed(ret_code, ref err_msg) => {
Failed(ref failed_cid) => {
let err_value = exec_ctx
.cid_state
.resolve_service_value(failed_cid)
.map_err(UncatchableError::from)?;
let call_service_failed: CallServiceFailed =
serde_json::from_value((*err_value).clone()).map_err(UncatchableError::MalformedCallServiceFailed)?;
exec_ctx.make_subgraph_incomplete();
let err_msg = err_msg.clone();
trace_ctx.meet_call_end(met_result.result);
Err(CatchableError::LocalServiceError(ret_code, err_msg).into())
let err_msg = call_service_failed.message;
Err(CatchableError::LocalServiceError(call_service_failed.ret_code, err_msg).into())
}
RequestSentBy(Sender::PeerIdWithCallId { ref peer_id, call_id })
if peer_id.as_str() == exec_ctx.run_parameters.current_peer_id.as_str() =>
@ -61,7 +72,14 @@ pub(super) fn handle_prev_state<'i>(
// call results are identified by call_id that is saved in data
match exec_ctx.call_results.remove(&call_id) {
Some(call_result) => {
update_state_with_service_result(tetraplet.clone(), output, call_result, exec_ctx, trace_ctx)?;
update_state_with_service_result(
tetraplet.clone(),
argument_hash.expect("Result for joinable error").clone(),
output,
call_result,
exec_ctx,
trace_ctx,
)?;
Ok(StateDescriptor::executed())
}
// result hasn't been prepared yet
@ -105,50 +123,70 @@ use crate::JValue;
fn update_state_with_service_result<'i>(
tetraplet: RcSecurityTetraplet,
argument_hash: Rc<str>,
output: &CallOutputValue<'i>,
service_result: CallServiceResult,
exec_ctx: &mut ExecutionCtx<'i>,
trace_ctx: &mut TraceHandler,
) -> ExecutionResult<()> {
// check that service call succeeded
let service_result = handle_service_error(service_result, trace_ctx)?;
let service_result = handle_service_error(
service_result,
argument_hash.clone(),
tetraplet.clone(),
exec_ctx,
trace_ctx,
)?;
// try to get service result from call service result
let result = try_to_service_result(service_result, trace_ctx)?;
let result = try_to_service_result(service_result, &argument_hash, &tetraplet, exec_ctx, trace_ctx)?;
let trace_pos = trace_ctx.trace_pos();
let executed_result = ValueAggregate::new(result, tetraplet, trace_pos);
let new_call_result = populate_context_from_peer_service_result(executed_result, output, exec_ctx)?;
let executed_result = ValueAggregate::new(result, tetraplet.clone(), trace_pos);
let new_call_result =
populate_context_from_peer_service_result(executed_result, output, tetraplet, argument_hash, exec_ctx)?;
trace_ctx.meet_call_end(new_call_result);
Ok(())
}
fn handle_service_error(
fn handle_service_error<'i>(
service_result: CallServiceResult,
argument_hash: Rc<str>,
tetraplet: RcSecurityTetraplet,
exec_ctx: &mut ExecutionCtx<'i>,
trace_ctx: &mut TraceHandler,
) -> ExecutionResult<CallServiceResult> {
use air_interpreter_interface::CALL_SERVICE_SUCCESS;
use CallResult::CallServiceFailed;
use CallResult::Failed;
if service_result.ret_code == CALL_SERVICE_SUCCESS {
return Ok(service_result);
}
let error_message = Rc::new(service_result.result);
let error_message = Rc::new(service_result.result.clone());
let error = CatchableError::LocalServiceError(service_result.ret_code, error_message.clone());
trace_ctx.meet_call_end(CallServiceFailed(service_result.ret_code, error_message));
let failed_value = CallServiceFailed::new(service_result.ret_code, error_message).to_value();
let service_result_agg_cid = exec_ctx
.cid_state
.insert_value(failed_value.into(), tetraplet, argument_hash)
.map_err(UncatchableError::from)?;
trace_ctx.meet_call_end(Failed(service_result_agg_cid));
Err(error.into())
}
fn try_to_service_result(
service_result: CallServiceResult,
argument_hash: &Rc<str>,
tetraplet: &RcSecurityTetraplet,
exec_ctx: &mut ExecutionCtx<'_>,
trace_ctx: &mut TraceHandler,
) -> ExecutionResult<Rc<JValue>> {
use CallResult::CallServiceFailed;
match serde_json::from_str(&service_result.result) {
Ok(result) => Ok(Rc::new(result)),
Err(e) => {
@ -156,7 +194,14 @@ fn try_to_service_result(
f!("call_service result '{service_result}' can't be serialized or deserialized with an error: {e}");
let error_msg = Rc::new(error_msg);
let error = CallServiceFailed(i32::MAX, error_msg.clone());
let failed_value = CallServiceFailed::new(i32::MAX, error_msg.clone()).to_value();
let service_result_agg_cid = exec_ctx
.cid_state
.insert_value(failed_value.into(), tetraplet.clone(), argument_hash.clone())
.map_err(UncatchableError::from)?;
let error = CallResult::failed(service_result_agg_cid);
trace_ctx.meet_call_end(error);
Err(CatchableError::LocalServiceError(i32::MAX, error_msg).into())

View File

@ -27,6 +27,7 @@ use crate::trace_to_exec_err;
use crate::JValue;
use crate::SecurityTetraplet;
use air_interpreter_cid::value_to_json_cid;
use air_interpreter_data::CallResult;
use air_interpreter_interface::CallRequestParams;
use air_parser::ast;
@ -50,6 +51,22 @@ struct ResolvedArguments {
tetraplets: Vec<RcSecurityTetraplets>,
}
#[derive(Debug)]
enum CheckArgsResult<T> {
Ok(T),
Joinable(ExecutionError),
}
impl<T> CheckArgsResult<T> {
fn new(result: ExecutionResult<T>) -> ExecutionResult<Self> {
match result {
Ok(nested) => Ok(CheckArgsResult::Ok(nested)),
Err(err) if err.is_joinable() => Ok(CheckArgsResult::Joinable(err)),
Err(err) => Err(err),
}
}
}
impl<'i> ResolvedCall<'i> {
/// Build `ResolvedCall` from `Call` by transforming `PeerPart` & `FunctionPart` into `ResolvedTriplet`.
#[tracing::instrument(level = "trace", skip_all)]
@ -80,9 +97,19 @@ impl<'i> ResolvedCall<'i> {
// https://github.com/fluencelabs/aquavm/issues/214
// also note that if there is a non-join error then the corresponding state
// won't be saved to data
self.check_args(exec_ctx)?;
let checked_args = match self.check_args(exec_ctx)? {
CheckArgsResult::Ok(args) => Some(args),
CheckArgsResult::Joinable(_) => None,
};
let argument_hash: Option<Rc<str>> = checked_args.map(|args| {
value_to_json_cid(&args)
.expect("JSON serializer shouldn't fail")
.into_inner()
.into()
});
let state = self.prepare_current_executed_state(raw_call, argument_hash.as_ref(), exec_ctx, trace_ctx)?;
let state = self.prepare_current_executed_state(raw_call, exec_ctx, trace_ctx)?;
if !state.should_execute() {
state.maybe_set_prev_state(trace_ctx);
return Ok(());
@ -95,6 +122,8 @@ impl<'i> ResolvedCall<'i> {
return Ok(());
}
// TODO we are recalculating params here for the second time.
// we might extend the `checked_args`, but we have to proove that the value is same.
let request_params = match self.prepare_request_params(exec_ctx, tetraplet) {
Ok(params) => params,
Err(e) if e.is_joinable() => {
@ -106,7 +135,9 @@ impl<'i> ResolvedCall<'i> {
return Err(e);
}
};
let call_id = exec_ctx.next_call_request_id();
exec_ctx.call_requests.insert(call_id, request_params);
exec_ctx.make_subgraph_incomplete();
@ -153,30 +184,27 @@ impl<'i> ResolvedCall<'i> {
fn prepare_current_executed_state(
&self,
raw_call: &Call<'i>,
argument_hash: Option<&Rc<str>>,
exec_ctx: &mut ExecutionCtx<'i>,
trace_ctx: &mut TraceHandler,
) -> ExecutionResult<StateDescriptor> {
let prev_result = trace_ctx.meet_call_start();
match trace_to_exec_err!(prev_result, raw_call)? {
MergerCallResult::Met(call_result) => {
handle_prev_state(call_result, &self.tetraplet, &self.output, exec_ctx, trace_ctx)
}
MergerCallResult::Met(call_result) => handle_prev_state(
call_result,
&self.tetraplet,
argument_hash,
&self.output,
exec_ctx,
trace_ctx,
),
MergerCallResult::NotMet => Ok(StateDescriptor::no_previous_state()),
}
}
/// Prepare arguments of this call instruction by resolving and preparing their security tetraplets.
fn resolve_args(&self, exec_ctx: &ExecutionCtx<'i>) -> ExecutionResult<ResolvedArguments> {
use crate::execution_step::resolver::resolve_to_args;
let function_args = self.function_arg_paths.iter();
let mut call_arguments = Vec::with_capacity(function_args.len());
let mut tetraplets = Vec::with_capacity(function_args.len());
for instruction_value in function_args {
let (arg, tetraplet) = resolve_to_args(instruction_value, exec_ctx)?;
call_arguments.push(arg);
tetraplets.push(tetraplet);
}
let (call_arguments, tetraplets) = self.collect_args(exec_ctx)?;
let call_arguments = JValue::Array(call_arguments);
let call_arguments = call_arguments.to_string();
@ -189,19 +217,29 @@ impl<'i> ResolvedCall<'i> {
Ok(resolved_arguments)
}
/// Lightweight version of resolve_args function that intended to check arguments of
/// a call instruction. It suppresses joinable errors.
fn check_args(&self, exec_ctx: &ExecutionCtx<'i>) -> ExecutionResult<()> {
// TODO: make this function more lightweight
/// A version of `resolve_args` that supresses joinable errors.
fn check_args(&self, exec_ctx: &ExecutionCtx<'i>) -> ExecutionResult<CheckArgsResult<Vec<serde_json::Value>>> {
let fun_result = self.collect_args(exec_ctx);
CheckArgsResult::new(fun_result.map(|values| values.0))
}
fn collect_args(
&self,
exec_ctx: &ExecutionCtx<'i>,
) -> ExecutionResult<(Vec<serde_json::Value>, Vec<RcSecurityTetraplets>)> {
use crate::execution_step::resolver::resolve_to_args;
self.function_arg_paths
.iter()
.try_for_each(|arg_path| match resolve_to_args(arg_path, exec_ctx) {
Ok(_) => Ok(()),
Err(e) if e.is_joinable() => Ok(()),
Err(e) => Err(e),
})
let function_args = self.function_arg_paths.iter();
let mut call_arguments = Vec::with_capacity(function_args.len());
let mut tetraplets = Vec::with_capacity(function_args.len());
for instruction_value in function_args {
let (arg, tetraplet) = resolve_to_args(instruction_value, exec_ctx)?;
call_arguments.push(arg);
tetraplets.push(tetraplet);
}
Ok((call_arguments, tetraplets))
}
}

View File

@ -35,6 +35,7 @@ mod utils;
pub use air_interpreter_interface::InterpreterOutcome;
pub use air_interpreter_interface::RunParameters;
pub use air_interpreter_interface::INTERPRETER_SUCCESS;
pub use execution_step::execution_context::ExecutionCidState;
pub use execution_step::execution_context::LastError;
pub use execution_step::CatchableError;
pub use execution_step::ExecutionError;

View File

@ -14,6 +14,7 @@
* limitations under the License.
*/
use air::ExecutionCidState;
use air::UncatchableError::ValueForCidNotFound;
use air_interpreter_cid::CID;
use air_interpreter_data::{CidStore, CidTracker};
@ -38,13 +39,18 @@ fn test_canon_ok() {
let result = executor.execute_one(init_peer_id).unwrap();
let data = data_from_result(&result);
let mut value_tracker = CidTracker::<JValue>::new();
let mut tetraplet_tracker = CidTracker::<SecurityTetraplet>::new();
let mut canon_tracker = CidTracker::<CanonCidAggregate>::new();
let mut cid_state = ExecutionCidState::new();
let expected_trace = vec![
ap(0),
stream_tracked("to canon", 1, &mut value_tracker),
stream_tracked!(
"to canon",
1,
cid_state,
peer = init_peer_id,
service = "serv..0",
function = "func"
),
canon_tracked(
json!({
"tetraplet": {"function_name": "", "json_path": "", "peer_pk": init_peer_id, "service_id": ""},
@ -66,16 +72,18 @@ fn test_canon_ok() {
},
}]
}),
&mut value_tracker,
&mut tetraplet_tracker,
&mut canon_tracker,
&mut cid_state,
),
];
assert_eq!(&*data.trace, expected_trace);
assert_eq!(data.cid_info.value_store, value_tracker.into());
assert_eq!(data.cid_info.tetraplet_store, tetraplet_tracker.into());
assert_eq!(data.cid_info.canon_store, canon_tracker.into());
assert_eq!(data.cid_info.value_store, cid_state.value_tracker.into());
assert_eq!(data.cid_info.tetraplet_store, cid_state.tetraplet_tracker.into());
assert_eq!(data.cid_info.canon_store, cid_state.canon_tracker.into());
assert_eq!(
data.cid_info.service_result_store,
cid_state.service_result_agg_tracker.into()
);
}
#[test]
@ -99,13 +107,25 @@ fn test_canon_ok_multi() {
let result3 = executor.execute_one(init_peer_id).unwrap();
let data = data_from_result(&result3);
let mut value_tracker = CidTracker::<JValue>::new();
let mut tetraplet_tracker = CidTracker::<SecurityTetraplet>::new();
let mut canon_tracker = CidTracker::<CanonCidAggregate>::new();
let mut cid_state = ExecutionCidState::new();
let expected_trace = vec![
stream_tracked("to canon", 0, &mut value_tracker),
stream_tracked("other", 1, &mut value_tracker),
stream_tracked!(
"to canon",
0,
cid_state,
peer = init_peer_id,
service = "serv..0",
function = "func"
),
stream_tracked!(
"other",
1,
cid_state,
peer = other_peer_id,
service = "other_serv..1",
function = "other_func"
),
canon_tracked(
json!({
"tetraplet": {"function_name": "", "json_path": "", "peer_pk": init_peer_id, "service_id": ""},
@ -127,17 +147,19 @@ fn test_canon_ok_multi() {
},
}]
}),
&mut value_tracker,
&mut tetraplet_tracker,
&mut canon_tracker,
&mut cid_state,
),
];
assert_eq!(&*data.trace, expected_trace);
assert_eq!(data.cid_info.value_store.len(), 2);
assert_eq!(data.cid_info.value_store, value_tracker.into());
assert_eq!(data.cid_info.tetraplet_store, tetraplet_tracker.into());
assert_eq!(data.cid_info.canon_store, canon_tracker.into());
assert_eq!(data.cid_info.value_store, cid_state.value_tracker.into());
assert_eq!(data.cid_info.tetraplet_store, cid_state.tetraplet_tracker.into());
assert_eq!(data.cid_info.canon_store, cid_state.canon_tracker.into());
assert_eq!(
data.cid_info.service_result_store,
cid_state.service_result_agg_tracker.into()
);
}
#[test]
@ -145,9 +167,7 @@ fn test_canon_value_not_found() {
let init_peer_id = "vm_peer_id";
let mut vm = create_avm(echo_call_service(), init_peer_id);
let mut value_tracker = CidTracker::<JValue>::new();
let mut tetraplet_tracker = CidTracker::<SecurityTetraplet>::new();
let mut canon_tracker = CidTracker::<CanonCidAggregate>::new();
let mut cid_state = ExecutionCidState::new();
let air_script = format!(
r#"
@ -170,17 +190,17 @@ fn test_canon_value_not_found() {
},
}]
}),
&mut value_tracker,
&mut tetraplet_tracker,
&mut canon_tracker,
&mut cid_state,
),
];
let missing_cid = "bagaaieraondvznakk2hi3kfaixhnceatpykz7cikytniqo3lc7ogkgz2qbeq";
let value_store: CidStore<_> = value_tracker.into();
let value_store: CidStore<_> = cid_state.value_tracker.into();
assert!(value_store.get(&CID::<_>::new(missing_cid)).is_some());
let cur_data = raw_data_from_trace_with_canon(trace, CidTracker::<_>::new(), tetraplet_tracker, canon_tracker);
// Override with fake data.
cid_state.value_tracker = CidTracker::<_>::new();
let cur_data = raw_data_from_trace_with_canon(trace, cid_state);
let result = call_vm!(vm, <_>::default(), air_script, vec![], cur_data);
let expected_error = ValueForCidNotFound("value", String::from(missing_cid));
assert!(check_error(&result, expected_error));
@ -192,9 +212,7 @@ fn test_canon_root_tetraplet_not_found() {
let other_peer_id = "other_peer_id";
let mut vm = create_avm(echo_call_service(), init_peer_id);
let mut value_tracker = CidTracker::<JValue>::new();
let mut tetraplet_tracker = CidTracker::<SecurityTetraplet>::new();
let mut canon_tracker = CidTracker::<CanonCidAggregate>::new();
let mut cid_state = ExecutionCidState::new();
let air_script = format!(
r#"
@ -217,14 +235,12 @@ fn test_canon_root_tetraplet_not_found() {
},
}]
}),
&mut value_tracker,
&mut tetraplet_tracker,
&mut canon_tracker,
&mut cid_state,
),
];
let missing_cid = "bagaaiera2bwoxisr5k7qlbzhxi2jmdqlgqybqgxcfwt3v652nqdo5fyc665q";
let tetraplet_store: CidStore<_> = tetraplet_tracker.into();
let tetraplet_store: CidStore<_> = cid_state.tetraplet_tracker.into();
assert!(tetraplet_store.get(&CID::<_>::new(missing_cid)).is_some());
let mut fake_tetraplet_tracker = CidTracker::<_>::new();
@ -232,7 +248,9 @@ fn test_canon_root_tetraplet_not_found() {
.record_value(SecurityTetraplet::literal_tetraplet(other_peer_id))
.unwrap();
let cur_data = raw_data_from_trace_with_canon(trace, value_tracker, fake_tetraplet_tracker, canon_tracker);
cid_state.tetraplet_tracker = fake_tetraplet_tracker;
let cur_data = raw_data_from_trace_with_canon(trace, cid_state);
let result = call_vm!(vm, <_>::default(), air_script, vec![], cur_data);
let expected_error = ValueForCidNotFound("tetraplet", String::from(missing_cid));
@ -244,9 +262,7 @@ fn test_canon_tetraplet_not_found() {
let init_peer_id = "vm_peer_id";
let mut vm = create_avm(echo_call_service(), init_peer_id);
let mut value_tracker = CidTracker::<JValue>::new();
let mut tetraplet_tracker = CidTracker::<SecurityTetraplet>::new();
let mut canon_tracker = CidTracker::<CanonCidAggregate>::new();
let mut cid_state = ExecutionCidState::new();
let air_script = format!(
r#"
@ -255,7 +271,14 @@ fn test_canon_tetraplet_not_found() {
(canon "{init_peer_id}" $stream #canon))"#
);
let trace = vec![
stream_tracked(42, 0, &mut value_tracker),
stream_tracked!(
42,
0,
cid_state,
peer = "peer_1",
service = "serv..0",
function = "func"
),
canon_tracked(
json!({
"tetraplet": {"function_name": "", "json_path": "", "peer_pk": init_peer_id, "service_id": ""},
@ -269,14 +292,12 @@ fn test_canon_tetraplet_not_found() {
},
}]
}),
&mut value_tracker,
&mut tetraplet_tracker,
&mut canon_tracker,
&mut cid_state,
),
];
let missing_cid = "bagaaieracu6twiik6az3cosyzlplrscon3ek6rnu3lkjnflibphqkw6kcdiq";
let tetraplet_store: CidStore<_> = tetraplet_tracker.into();
let tetraplet_store: CidStore<_> = cid_state.tetraplet_tracker.into();
assert!(tetraplet_store.get(&CID::<_>::new(missing_cid)).is_some());
let mut fake_tetraplet_tracker = CidTracker::<_>::new();
@ -284,7 +305,8 @@ fn test_canon_tetraplet_not_found() {
.record_value(SecurityTetraplet::literal_tetraplet(init_peer_id))
.unwrap();
let cur_data = raw_data_from_trace_with_canon(trace, value_tracker, fake_tetraplet_tracker, canon_tracker);
cid_state.tetraplet_tracker = fake_tetraplet_tracker;
let cur_data = raw_data_from_trace_with_canon(trace, cid_state);
let result = call_vm!(vm, <_>::default(), air_script, vec![], cur_data);
let expected_error = ValueForCidNotFound("tetraplet", String::from(missing_cid));
@ -296,9 +318,7 @@ fn test_canon_agg_not_found() {
let init_peer_id = "vm_peer_id";
let mut vm = create_avm(echo_call_service(), init_peer_id);
let mut value_tracker = CidTracker::<JValue>::new();
let mut tetraplet_tracker = CidTracker::<SecurityTetraplet>::new();
let mut canon_tracker = CidTracker::<CanonCidAggregate>::new();
let mut cid_state = ExecutionCidState::new();
let air_script = format!(
r#"
@ -321,17 +341,17 @@ fn test_canon_agg_not_found() {
},
}]
}),
&mut value_tracker,
&mut tetraplet_tracker,
&mut canon_tracker,
&mut cid_state,
),
];
let missing_cid = "bagaaierapp2oi35ib4iveexfswax6jcf2zhj3e2ergzjyavm6m7stlzh23ta";
let canon_store: CidStore<_> = canon_tracker.into();
let canon_store: CidStore<_> = cid_state.canon_tracker.into();
assert!(canon_store.get(&CID::<_>::new(missing_cid)).is_some());
let cur_data = raw_data_from_trace_with_canon(trace, value_tracker, tetraplet_tracker, <_>::default());
// Fake data
cid_state.canon_tracker = <_>::default();
let cur_data = raw_data_from_trace_with_canon(trace, cid_state);
let result = call_vm!(vm, <_>::default(), air_script, vec![], cur_data);
let expected_error = ValueForCidNotFound("canon aggregate", String::from(missing_cid));

View File

@ -16,48 +16,55 @@
mod canon;
use air::ExecutionCidState;
use air::UncatchableError::ValueForCidNotFound;
use air_interpreter_data::CidTracker;
use air_interpreter_data::ExecutionTrace;
use air_test_framework::AirScriptExecutor;
use air_test_utils::prelude::*;
use pretty_assertions::assert_eq;
#[test]
fn test_missing_cid() {
let vm_peer_id = "vm_peer_id";
let mut vm = create_avm(echo_call_service(), vm_peer_id);
let peer_id = "peer_id";
let mut vm = create_avm(echo_call_service(), peer_id);
let air_script = r#"
(seq
(call "peer_id" ("service" "call1") [] x)
(call "peer_id" ("service" "call2") []))"#;
let trace = vec![scalar_number(42), scalar_number(43)];
let mut tracker = CidTracker::<JValue>::new();
tracker.record_value(json!(43)).unwrap();
let mut cid_state = ExecutionCidState::new();
let trace = vec![
scalar_tracked!(42, cid_state, peer = peer_id, service = "service", function = "call1"),
unused!(43, peer = peer_id, service = "service", function = "call2"),
];
cid_state.service_result_agg_tracker = <_>::default();
let cur_data = raw_data_from_trace(trace, tracker);
let cur_data = raw_data_from_trace(trace, cid_state);
let result = call_vm!(vm, <_>::default(), air_script, vec![], cur_data);
let missing_cid = String::from("bagaaieraondvznakk2hi3kfaixhnceatpykz7cikytniqo3lc7ogkgz2qbeq");
let expected_error = ValueForCidNotFound("value", missing_cid);
assert!(check_error(&result, expected_error));
let missing_cid = String::from("bagaaierajmqwu6mhm7iw5mxxy647ri6yznuwjxfm72u4u5a5zdasfid4xwiq");
let expected_error = ValueForCidNotFound("service result aggregate", missing_cid);
assert!(check_error(&result, expected_error), "{:?}", result);
}
#[test]
fn test_correct_cid() {
let vm_peer_id = "vm_peer_id";
let mut vm = create_avm(echo_call_service(), vm_peer_id);
let peer_id = "peer_id";
let mut vm = create_avm(echo_call_service(), peer_id);
let air_script = r#"
(seq
(call "peer_id" ("service" "call1") [] x)
(call "peer_id" ("service" "call2") [] y))"#;
let trace = vec![scalar_number(42), scalar_number(43)];
let mut tracker = CidTracker::<JValue>::new();
tracker.record_value(json!(43)).unwrap();
tracker.record_value(json!(42)).unwrap();
let mut tracker = ExecutionCidState::new();
let trace = vec![
scalar_tracked!(42, tracker, peer = peer_id, service = "service", function = "call1"),
scalar_tracked!(43, tracker, peer = peer_id, service = "service", function = "call2"),
];
let cur_data = raw_data_from_trace(trace, tracker);
let result = call_vm!(vm, <_>::default(), air_script, vec![], cur_data);
assert_eq!(result.ret_code, 0);
assert_eq!(result.ret_code, 0, "{:?}", result);
}
#[test]
@ -81,12 +88,32 @@ fn test_scalar_cid() {
let result = executor.execute_one(vm_peer_id).unwrap();
let data = data_from_result(&result);
let mut tracker = CidTracker::<JValue>::new();
let expected_trace = vec![scalar_tracked("hi", &mut tracker), scalar_tracked("ipld", &mut tracker)];
let mut cid_state = ExecutionCidState::new();
let expected_trace = vec![
scalar_tracked!(
"hi",
cid_state,
peer = vm_peer_id,
service = "service..0",
function = "call1"
),
scalar_tracked!(
"ipld",
cid_state,
peer = vm_peer_id,
service = "service..1",
function = "call2"
),
];
assert_eq!(result.ret_code, 0);
assert_eq!(data.trace, expected_trace);
assert_eq!(data.cid_info.value_store, tracker.into());
assert_eq!(data.trace, ExecutionTrace::from(expected_trace));
assert_eq!(data.cid_info.value_store, cid_state.value_tracker.into());
assert_eq!(data.cid_info.tetraplet_store, cid_state.tetraplet_tracker.into());
assert_eq!(
data.cid_info.service_result_store,
cid_state.service_result_agg_tracker.into(),
);
}
#[test]
@ -110,13 +137,66 @@ fn test_stream_cid() {
let result = executor.execute_one(vm_peer_id).unwrap();
let data = data_from_result(&result);
let mut tracker = CidTracker::<JValue>::new();
let mut cid_state = ExecutionCidState::new();
let expected_trace = vec![
stream_tracked("hi", 0, &mut tracker),
stream_tracked("ipld", 1, &mut tracker),
stream_tracked!(
"hi",
0,
cid_state,
peer = vm_peer_id,
service = "service..0",
function = "call1"
),
stream_tracked!(
"ipld",
1,
cid_state,
peer = vm_peer_id,
service = "service..1",
function = "call2"
),
];
assert_eq!(result.ret_code, 0);
assert_eq!(data.trace, expected_trace);
assert_eq!(data.cid_info.value_store, tracker.into());
assert_eq!(data.cid_info.value_store, cid_state.value_tracker.into());
assert_eq!(data.cid_info.tetraplet_store, cid_state.tetraplet_tracker.into());
assert_eq!(
data.cid_info.service_result_store,
cid_state.service_result_agg_tracker.into()
);
}
#[test]
fn test_unused_cid() {
let vm_peer_id = "vm_peer_id";
let annotated_air_script = format!(
r#"
(seq
(call "{vm_peer_id}" ("service" "call1") []) ; ok="hi"
(call "{vm_peer_id}" ("service" "call2") []) ; ok="ipld"
)"#
);
let executor = AirScriptExecutor::new(
TestRunParameters::from_init_peer_id(vm_peer_id),
vec![],
std::iter::empty(),
&annotated_air_script,
)
.unwrap();
let result = executor.execute_one(vm_peer_id).unwrap();
let data = data_from_result(&result);
let expected_trace = vec![
unused!("hi", peer = vm_peer_id, service = "service..0", function = "call1"),
unused!("ipld", peer = vm_peer_id, service = "service..1", function = "call2"),
];
assert_eq!(result.ret_code, 0);
assert_eq!(data.trace, expected_trace);
assert!(data.cid_info.value_store.is_empty());
assert!(data.cid_info.tetraplet_store.is_empty());
assert!(data.cid_info.service_result_store.is_empty());
}

View File

@ -14,8 +14,12 @@
* limitations under the License.
*/
use air::ExecutionCidState;
use air_interpreter_data::ExecutionTrace;
use air_test_utils::prelude::*;
use pretty_assertions::assert_eq;
#[test]
fn seq_par_call() {
let vm_peer_id = "some_peer_id";
@ -36,25 +40,36 @@ fn seq_par_call() {
let unit_call_service_result = "result from unit_call_service";
let expected_trace = vec![
executed_state::par(1, 1),
executed_state::scalar_string(unit_call_service_result),
scalar!(
unit_call_service_result,
peer = vm_peer_id,
service = "local_service_id",
function = "local_fn_name"
),
executed_state::request_sent_by(vm_peer_id),
executed_state::scalar_string(unit_call_service_result),
scalar!(
unit_call_service_result,
peer = vm_peer_id,
service = "local_service_id",
function = "local_fn_name"
),
];
assert_eq!(actual_trace, expected_trace);
assert_eq!(actual_trace, ExecutionTrace::from(expected_trace));
assert_eq!(result.next_peer_pks, vec![String::from("remote_peer_id")]);
}
#[test]
fn par_par_call() {
let vm_peer_id = "some_peer_id";
let remote_peer_id = "remote_peer_id";
let mut vm = create_avm(unit_call_service(), vm_peer_id);
let script = f!(r#"
(par
(par
(call "{vm_peer_id}" ("local_service_id" "local_fn_name") [] result_1)
(call "remote_peer_id" ("service_id" "fn_name") [] g)
(call "{remote_peer_id}" ("service_id" "fn_name") [] g)
)
(call "{vm_peer_id}" ("local_service_id" "local_fn_name") [] result_2)
)"#);
@ -63,14 +78,27 @@ fn par_par_call() {
let actual_trace = trace_from_result(&result);
let unit_call_service_result = "result from unit_call_service";
let mut cid_state = ExecutionCidState::new();
let expected_trace = vec![
executed_state::par(3, 1),
executed_state::par(1, 1),
executed_state::scalar_string(unit_call_service_result),
scalar_tracked!(
unit_call_service_result,
cid_state,
peer = vm_peer_id,
service = "local_service_id",
function = "local_fn_name"
),
executed_state::request_sent_by(vm_peer_id),
executed_state::scalar_string(unit_call_service_result),
scalar_tracked!(
unit_call_service_result,
cid_state,
peer = vm_peer_id,
service = "local_service_id",
function = "local_fn_name"
),
];
assert_eq!(actual_trace, expected_trace);
assert_eq!(actual_trace, ExecutionTrace::from(expected_trace));
assert_eq!(result.next_peer_pks, vec![String::from("remote_peer_id")]);
}

View File

@ -14,6 +14,8 @@
* limitations under the License.
*/
use air::ExecutionCidState;
use air_interpreter_data::{ExecutionTrace, InterpreterData};
use air_test_utils::prelude::*;
use pretty_assertions::assert_eq;
@ -82,37 +84,45 @@ fn merge_streams_in_two_fold() {
let actual_trace_1 = trace_from_result(&result_1);
let expected_trace_1 = vec![
scalar_string_array(vec![vm_1_peer_id, vm_2_peer_id]),
let expected_trace_1 = ExecutionTrace::from(vec![
scalar!(
json!([vm_1_peer_id, vm_2_peer_id]),
peer = set_variable_peer_id,
service = "neighborhood"
),
par(1, 2),
stream_string(vm_1_peer_id, 0),
stream!(vm_1_peer_id, 0, peer = vm_1_peer_id, service = "add_provider"),
par(1, 0),
request_sent_by(set_variable_peer_id),
par(1, 2),
stream_string(vm_1_peer_id, 0),
stream!(vm_1_peer_id, 0, peer = vm_1_peer_id, service = "get_providers"),
par(1, 0),
request_sent_by(vm_1_peer_id),
stream_string(vm_1_peer_id, 1),
stream!(vm_1_peer_id, 1, peer = vm_1_peer_id, service = "identity"),
request_sent_by(vm_1_peer_id),
];
]);
assert_eq!(actual_trace_1, expected_trace_1);
assert_eq!(result_1.next_peer_pks, vec![vm_2_peer_id.to_string()]);
let actual_trace_2 = trace_from_result(&result_2);
let expected_trace_2 = vec![
scalar_string_array(vec![vm_1_peer_id, vm_2_peer_id]),
let expected_trace_2 = ExecutionTrace::from(vec![
scalar!(
json!([vm_1_peer_id, vm_2_peer_id]),
peer = set_variable_peer_id,
service = "neighborhood"
),
par(1, 2),
request_sent_by(set_variable_peer_id),
par(1, 0),
stream_string(vm_2_peer_id, 0),
stream!(vm_2_peer_id, 0, peer = vm_2_peer_id, service = "add_provider"),
par(1, 2),
request_sent_by(vm_2_peer_id),
par(1, 0),
stream_string(vm_2_peer_id, 0),
stream!(vm_2_peer_id, 0, peer = vm_2_peer_id, service = "get_providers"),
request_sent_by(vm_2_peer_id),
];
]);
assert_eq!(actual_trace_2, expected_trace_2);
assert_eq!(result_2.next_peer_pks, vec![vm_1_peer_id.to_string()]);
@ -120,16 +130,20 @@ fn merge_streams_in_two_fold() {
let actual_trace_3 = trace_from_result(&result_3);
let expected_trace_3 = vec![
scalar_string_array(vec![vm_1_peer_id, vm_2_peer_id]),
scalar!(
json!([vm_1_peer_id, vm_2_peer_id]),
peer = set_variable_peer_id,
service = "neighborhood"
),
par(1, 2),
stream_string(vm_1_peer_id, 0),
stream!(vm_1_peer_id, 0, peer = vm_1_peer_id, service = "add_provider"),
par(1, 0),
stream_string(vm_2_peer_id, 2),
stream!(vm_2_peer_id, 2, peer = vm_2_peer_id, service = "add_provider"),
par(1, 2),
stream_string(vm_1_peer_id, 0),
stream!(vm_1_peer_id, 0, peer = vm_1_peer_id, service = "get_providers"),
par(1, 0),
stream_string(vm_2_peer_id, 1),
stream_string(vm_1_peer_id, 1),
stream!(vm_2_peer_id, 1, peer = vm_2_peer_id, service = "get_providers"),
stream!(vm_1_peer_id, 1, peer = vm_1_peer_id, service = "identity"),
request_sent_by(vm_1_peer_id),
];
@ -138,19 +152,23 @@ fn merge_streams_in_two_fold() {
let actual_trace_4 = trace_from_result(&result_4);
let expected_trace_4 = vec![
scalar_string_array(vec![vm_1_peer_id, vm_2_peer_id]),
let expected_trace_4 = ExecutionTrace::from(vec![
scalar!(
json!([vm_1_peer_id, vm_2_peer_id]),
peer = set_variable_peer_id,
service = "neighborhood"
),
par(1, 2),
stream_string(vm_1_peer_id, 0),
stream!(vm_1_peer_id, 0, peer = vm_1_peer_id, service = "add_provider"),
par(1, 0),
stream_string(vm_2_peer_id, 2),
stream!(vm_2_peer_id, 2, peer = vm_2_peer_id, service = "add_provider"),
par(1, 2),
stream_string(vm_1_peer_id, 0),
stream!(vm_1_peer_id, 0, peer = vm_1_peer_id, service = "get_providers"),
par(1, 0),
stream_string(vm_2_peer_id, 1),
stream_string(vm_1_peer_id, 1),
scalar_string(vm_2_peer_id),
];
stream!(vm_2_peer_id, 1, peer = vm_2_peer_id, service = "get_providers"),
stream!(vm_1_peer_id, 1, peer = vm_1_peer_id, service = "identity"),
scalar!(vm_2_peer_id, peer = vm_2_peer_id),
]);
assert_eq!(actual_trace_4, expected_trace_4);
assert!(result_4.next_peer_pks.is_empty());
@ -310,11 +328,18 @@ fn fold_merge() {
let value_pos = subtrace_lore.value_pos;
if let ExecutedState::Call(CallResult::Executed(value)) = &data.trace[value_pos] {
let cid = match value {
ValueRef::Scalar(cid) => cid,
ValueRef::Stream { cid, .. } => cid,
ValueRef::Scalar(service_result_cid) => service_result_cid,
ValueRef::Stream {
cid: service_result_cid,
..
} => service_result_cid,
// Cannot resolve
ValueRef::Unused(_value_cid) => continue,
};
let value = data.cid_info.value_store.get(cid).unwrap().clone();
let service_result_agg = data.cid_info.service_result_store.get(cid).unwrap();
let value = data.cid_info.value_store.get(&service_result_agg.value_cid).unwrap();
if let JValue::String(ref var_name) = &*value {
let current_count: usize = calls_count.get(var_name).copied().unwrap_or_default();
calls_count.insert(var_name.to_owned(), current_count + 1);
@ -336,3 +361,126 @@ fn fold_merge() {
}
}
}
#[test]
fn test_merge_scalar_match() {
let air = r#"(call "peer" ("" "") [] var)"#;
let mut avm = create_avm(echo_call_service(), "peer");
let mut cid_store = ExecutionCidState::new();
let trace = ExecutionTrace::from(vec![scalar_tracked!(42, cid_store, peer = "peer")]);
let data = raw_data_from_trace(trace, cid_store);
checked_call_vm!(avm, <_>::default(), air, data.clone(), data);
}
#[test]
fn test_merge_scalar_mismatch() {
let air = r#"(call "peer" ("" "") [] var)"#;
let mut avm = create_avm(echo_call_service(), "peer");
let mut cid_state1 = ExecutionCidState::default();
let mut cid_state2 = ExecutionCidState::default();
let trace1 = ExecutionTrace::from(vec![scalar_tracked!(42, cid_state1, peer = "peer")]);
let trace2 = ExecutionTrace::from(vec![scalar_tracked!(43, cid_state2, peer = "peer")]);
let data1 = raw_data_from_trace(trace1, cid_state1);
let data2 = raw_data_from_trace(trace2, cid_state2);
let result = avm.call(air, data1, data2, <_>::default()).unwrap();
assert_eq!(result.ret_code, 20000);
assert_eq!(
result.error_message,
concat!(
r#"on instruction 'call "peer" ("" "") [] var' trace handler encountered an error:"#,
r#" values in call results are not equal:"#,
r#" Scalar(CID("bagaaierautomsqybwfcilogqikd6sxzhaqkrout64cosdlpo7p6wvod4miza"))"#,
r#" != Scalar(CID("bagaaieraywolxobx5koykfm7lnjtpci6wt4ccqqehbbhpebomznlzaszhgya"))"#
)
);
}
#[test]
fn test_merge_stream_match() {
let air = r#"(call "peer" ("" "") [] $var)"#;
let mut avm = create_avm(echo_call_service(), "peer");
let mut cid_store = ExecutionCidState::new();
let trace = ExecutionTrace::from(vec![stream_tracked!(42, 0, cid_store, peer = "peer")]);
let data = raw_data_from_trace(trace, cid_store);
checked_call_vm!(avm, <_>::default(), air, data.clone(), data);
}
#[test]
fn test_merge_stream_match_gen() {
let air = r#"(call "peer" ("" "") [] $var)"#;
let mut avm = create_avm(echo_call_service(), "peer");
let mut cid_state1 = ExecutionCidState::default();
let mut cid_state2 = ExecutionCidState::default();
let trace1 = ExecutionTrace::from(vec![stream_tracked!(42, 0, cid_state1, peer = "peer")]);
let trace2 = ExecutionTrace::from(vec![stream_tracked!(42, 1, cid_state2, peer = "peer")]);
let data1 = raw_data_from_trace(trace1, cid_state1);
let data2 = raw_data_from_trace(trace2, cid_state2);
checked_call_vm!(avm, <_>::default(), air, data1, data2);
}
#[test]
fn test_merge_stream_mismatch() {
let air = r#"(call "peer" ("" "") [] $var)"#;
let mut avm = create_avm(echo_call_service(), "peer");
let mut cid_state1 = ExecutionCidState::default();
let mut cid_state2 = ExecutionCidState::default();
let trace1 = ExecutionTrace::from(vec![stream_tracked!(42, 0, cid_state1, peer = "peer")]);
let trace2 = ExecutionTrace::from(vec![stream_tracked!(43, 0, cid_state2, peer = "peer")]);
let data1 = raw_data_from_trace(trace1, cid_state1);
let data2 = raw_data_from_trace(trace2, cid_state2);
let result = avm.call(air, data1, data2, <_>::default()).unwrap();
assert_eq!(result.ret_code, 20000);
assert_eq!(
result.error_message,
concat!(
r#"on instruction 'call "peer" ("" "") [] $var' trace handler encountered an error:"#,
r#" values in call results are not equal:"#,
r#" Stream { cid: CID("bagaaierautomsqybwfcilogqikd6sxzhaqkrout64cosdlpo7p6wvod4miza"), generation: 0 }"#,
r#" != Stream { cid: CID("bagaaieraywolxobx5koykfm7lnjtpci6wt4ccqqehbbhpebomznlzaszhgya"), generation: 0 }"#
)
);
}
#[test]
fn test_merge_unused_match() {
let air = r#"(call "peer" ("" "") [])"#;
let mut avm = create_avm(echo_call_service(), "peer");
let trace = ExecutionTrace::from(vec![unused!(42, peer = "peer")]);
let data = raw_data_from_trace(trace, <_>::default());
checked_call_vm!(avm, <_>::default(), air, data.clone(), data);
}
#[test]
fn test_merge_unused_mismatch() {
let air = r#"(call "peer" ("" "") [])"#;
let mut avm = create_avm(echo_call_service(), "peer");
let trace1 = ExecutionTrace::from(vec![unused!(42, peer = "peer")]);
let trace2 = ExecutionTrace::from(vec![unused!(43, peer = "peer")]);
let data1 = raw_data_from_trace(trace1, <_>::default());
let data2 = raw_data_from_trace(trace2, <_>::default());
let result = avm.call(air, data1, data2, <_>::default()).unwrap();
assert_eq!(result.ret_code, 20000);
assert_eq!(
result.error_message,
concat!(
r#"on instruction 'call "peer" ("" "") [] ' trace handler encountered an error:"#,
r#" values in call results are not equal:"#,
r#" Unused(CID("bagaaieraondvznakk2hi3kfaixhnceatpykz7cikytniqo3lc7ogkgz2qbeq"))"#,
r#" != Unused(CID("bagaaieraitfxgdccasakar33kbnoncxvbd5zb6lm6dwfjrvnc2kj3vbh6e5a"))"#
)
);
}

View File

@ -14,40 +14,71 @@
* limitations under the License.
*/
use air_interpreter_data::CidTracker;
use air::ExecutionCidState;
use air_interpreter_data::ExecutionTrace;
use air_test_utils::prelude::*;
use pretty_assertions::assert_eq;
#[test]
fn executed_trace_seq_par_call() {
let local_peer_id = "local_peer_id";
let remote_peer_id = "remote_peer_id";
let mut vm = create_avm(unit_call_service(), local_peer_id);
let script = f!(r#"
(seq
(par
(call "{local_peer_id}" ("local_service_id" "local_fn_name") [] result_1)
(call "remote_peer_id" ("service_id" "fn_name") [] g)
(call "{remote_peer_id}" ("service_id" "fn_name") [] g)
)
(call "{local_peer_id}" ("local_service_id" "local_fn_name") [] result_2)
)"#);
let mut tracker = CidTracker::new();
let mut cid_state = ExecutionCidState::new();
let unit_call_service_result = "result from unit_call_service";
let initial_trace = vec![
par(1, 1),
scalar_tracked(unit_call_service_result, &mut tracker),
scalar_tracked(unit_call_service_result, &mut tracker),
scalar_tracked!(
unit_call_service_result,
cid_state,
peer = local_peer_id,
service = "local_service_id",
function = "local_fn_name"
),
scalar_tracked!(
unit_call_service_result,
cid_state,
peer = remote_peer_id,
service = "service_id",
function = "fn_name"
),
];
let initial_data = raw_data_from_trace(initial_trace, tracker);
let initial_data = raw_data_from_trace(initial_trace, cid_state);
let result = checked_call_vm!(vm, <_>::default(), script, "", initial_data);
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
par(1, 1),
scalar_string(unit_call_service_result),
scalar_string(unit_call_service_result),
scalar_string(unit_call_service_result),
scalar!(
unit_call_service_result,
peer = local_peer_id,
service = "local_service_id",
function = "local_fn_name"
),
scalar!(
unit_call_service_result,
peer = remote_peer_id,
service = "service_id",
function = "fn_name"
),
scalar!(
unit_call_service_result,
peer = local_peer_id,
service = "local_service_id",
function = "local_fn_name"
),
];
assert_eq!(actual_trace, expected_trace);
@ -57,38 +88,55 @@ fn executed_trace_seq_par_call() {
#[test]
fn executed_trace_par_par_call() {
let local_peer_id = "local_peer_id";
let remote_peer_id = "remote_peer_id";
let mut vm = create_avm(unit_call_service(), local_peer_id);
let script = f!(r#"
(par
(par
(call "{local_peer_id}" ("local_service_id" "local_fn_name") [] result_1)
(call "remote_peer_id" ("service_id" "fn_name") [] g)
(call "{remote_peer_id}" ("service_id" "fn_name") [] g)
)
(call "{local_peer_id}" ("local_service_id" "local_fn_name") [] result_2)
)"#);
let unit_call_service_result = "result from unit_call_service";
let mut tracker = CidTracker::new();
let mut cid_state = ExecutionCidState::new();
let initial_state = vec![
par(2, 1),
par(1, 0),
request_sent_by("peer_id_1"),
scalar_tracked(unit_call_service_result, &mut tracker),
scalar_tracked!(
unit_call_service_result,
cid_state,
peer = local_peer_id,
service = "local_service_id",
function = "local_fn_name"
),
];
let initial_data = raw_data_from_trace(initial_state, tracker);
let initial_data = raw_data_from_trace(initial_state, cid_state);
let result = checked_call_vm!(vm, <_>::default(), &script, "", initial_data);
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
let expected_trace = ExecutionTrace::from(vec![
par(3, 1),
par(1, 1),
scalar_string(unit_call_service_result),
scalar!(
unit_call_service_result,
peer = local_peer_id,
service = "local_service_id",
function = "local_fn_name"
),
request_sent_by(local_peer_id),
scalar_string(unit_call_service_result),
];
scalar!(
unit_call_service_result,
peer = local_peer_id,
service = "local_service_id",
function = "local_fn_name"
),
]);
assert_eq!(actual_trace, expected_trace);
assert_eq!(result.next_peer_pks, vec![String::from("remote_peer_id")]);
@ -110,8 +158,8 @@ fn executed_trace_par_par_call() {
#[test]
fn executed_trace_seq_seq() {
let peer_id_1 = String::from("12D3KooWHk9BjDQBUqnavciRPhAYFvqKBe4ZiPPvde7vDaqgn5er");
let peer_id_2 = String::from("12D3KooWAzJcYitiZrerycVB4Wryrx22CFKdDGx7c4u31PFdfTbR");
let peer_id_1 = "12D3KooWHk9BjDQBUqnavciRPhAYFvqKBe4ZiPPvde7vDaqgn5er";
let peer_id_2 = "12D3KooWAzJcYitiZrerycVB4Wryrx22CFKdDGx7c4u31PFdfTbR";
let mut vm1 = create_avm(unit_call_service(), peer_id_1.clone());
let mut vm2 = create_avm(unit_call_service(), peer_id_2.clone());
@ -137,9 +185,13 @@ fn executed_trace_seq_seq() {
let call_service_result = "result from unit_call_service";
let expected_trace = vec![
scalar_string(call_service_result),
scalar_string(call_service_result),
scalar_string(call_service_result),
scalar!(call_service_result, peer = peer_id_1, service = "identity"),
scalar!(call_service_result, peer = peer_id_1, service = "add_blueprint"),
scalar!(
call_service_result,
peer = peer_id_2,
service = "addBlueprint-14d8488e-d10d-474d-96b2-878f6a7d74c8"
),
];
assert_eq!(actual_trace, expected_trace);
@ -162,7 +214,7 @@ fn executed_trace_create_service() {
);
let module_bytes = json!([1, 2]);
let blueprint = json!({ "name": "blueprint", "dependencies": [module]});
let blueprint = json!({"name": "blueprint", "dependencies": [module]});
let add_module_response = "add_module response";
let add_blueprint_response = "add_blueprint response";
@ -178,25 +230,63 @@ fn executed_trace_create_service() {
CallServiceResult::ok(json!(response))
});
let mut vm = create_avm(call_service, "A");
let init_peer_id = "A";
let set_variables_id = "set_variables";
let mut vm = create_avm(call_service, init_peer_id);
let script = include_str!("./scripts/create_service.air");
let mut cid_tracker = CidTracker::new();
let mut cid_state = ExecutionCidState::new();
let add_module_response = "add_module response";
let add_blueprint_response = "add_blueprint response";
let create_response = "create response";
let expected_trace = vec![
scalar_tracked(module_bytes.clone(), &mut cid_tracker),
scalar_tracked(module_config.clone(), &mut cid_tracker),
scalar_tracked(blueprint.clone(), &mut cid_tracker),
scalar_tracked(add_module_response, &mut cid_tracker),
scalar_tracked(add_blueprint_response, &mut cid_tracker),
scalar_tracked(create_response, &mut cid_tracker),
scalar_tracked("test", &mut cid_tracker),
scalar_tracked!(
(module_bytes.clone()),
cid_state,
peer = set_variables_id,
service = "add_module",
args = vec!["module_bytes"]
),
scalar_tracked!(
(module_config.clone()),
cid_state,
peer = set_variables_id,
service = "add_module",
args = vec!["module_config"]
),
scalar_tracked!(
(blueprint.clone()),
cid_state,
peer = set_variables_id,
service = "add_module",
args = vec!["blueprint"]
),
scalar_tracked!(
add_module_response,
cid_state,
peer = init_peer_id,
service = "add_module",
args = vec![module_bytes, module_config]
),
scalar_tracked!(
add_blueprint_response,
cid_state,
peer = init_peer_id,
service = "add_blueprint",
args = vec![blueprint]
),
scalar_tracked!(
create_response,
cid_state,
peer = init_peer_id,
service = "create",
args = vec![add_blueprint_response]
),
scalar_tracked!("test", cid_state, peer = "remote_peer_id", args = vec![create_response]),
];
let initial_data = raw_data_from_trace(expected_trace.clone(), cid_tracker);
let initial_data = raw_data_from_trace(expected_trace.clone(), cid_state);
let result = checked_call_vm!(vm, <_>::default(), script, "", initial_data);
@ -243,31 +333,111 @@ fn executed_trace_par_seq_fold_call() {
let actual_trace = trace_from_result(&result);
let generation = 0;
let expected_trace = vec![
let expected_trace = ExecutionTrace::from(vec![
par(21, 1),
scalar_string_array(vec!["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]),
scalar!(
json!(["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]),
peer = "some_peer_id_1",
service = "local_service_id",
function = "local_fn_name"
),
par(1, 18),
stream_string(1.to_string(), generation),
stream!(
1.to_string(),
generation,
peer = "some_peer_id_2",
service = "local_service_id",
function = "local_fn_name",
args = vec!["1"]
),
par(1, 16),
stream_string(2.to_string(), generation),
stream!(
2.to_string(),
generation,
peer = "some_peer_id_2",
service = "local_service_id",
function = "local_fn_name",
args = vec!["2"]
),
par(1, 14),
stream_string(3.to_string(), generation),
stream!(
3.to_string(),
generation,
peer = "some_peer_id_2",
service = "local_service_id",
function = "local_fn_name",
args = vec!["3"]
),
par(1, 12),
stream_string(4.to_string(), generation),
stream!(
4.to_string(),
generation,
peer = "some_peer_id_2",
service = "local_service_id",
function = "local_fn_name",
args = vec!["4"]
),
par(1, 10),
stream_string(5.to_string(), generation),
stream!(
5.to_string(),
generation,
peer = "some_peer_id_2",
service = "local_service_id",
function = "local_fn_name",
args = vec!["5"]
),
par(1, 8),
stream_string(6.to_string(), generation),
stream!(
6.to_string(),
generation,
peer = "some_peer_id_2",
service = "local_service_id",
function = "local_fn_name",
args = vec!["6"]
),
par(1, 6),
stream_string(7.to_string(), generation),
stream!(
7.to_string(),
generation,
peer = "some_peer_id_2",
service = "local_service_id",
function = "local_fn_name",
args = vec!["7"]
),
par(1, 4),
stream_string(8.to_string(), generation),
stream!(
8.to_string(),
generation,
peer = "some_peer_id_2",
service = "local_service_id",
function = "local_fn_name",
args = vec!["8"]
),
par(1, 2),
stream_string(9.to_string(), generation),
stream!(
9.to_string(),
generation,
peer = "some_peer_id_2",
service = "local_service_id",
function = "local_fn_name",
args = vec!["9"]
),
par(1, 0),
stream_string(10.to_string(), generation),
scalar_string("result from unit_call_service"),
];
stream!(
10.to_string(),
generation,
peer = "some_peer_id_2",
service = "local_service_id",
function = "local_fn_name",
args = vec!["10"]
),
scalar!(
"result from unit_call_service",
peer = "some_peer_id_3",
service = "local_service_id",
function = "local_fn_name"
),
]);
assert_eq!(actual_trace, expected_trace);
assert!(result.next_peer_pks.is_empty());
@ -309,28 +479,108 @@ fn executed_trace_par_seq_fold_in_cycle_call() {
let generation = 0;
let expected_trace = vec![
par(21, 1),
scalar_string_array(vec!["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]),
scalar!(
json!(["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]),
peer = "some_peer_id_1",
service = "local_service_id",
function = "local_fn_name"
),
par(1, 18),
stream_string(1.to_string(), generation),
stream!(
1.to_string(),
generation,
peer = "some_peer_id_2",
service = "local_service_id",
function = "local_fn_name",
args = vec!["1"]
),
par(1, 16),
stream_string(2.to_string(), generation),
stream!(
2.to_string(),
generation,
peer = "some_peer_id_2",
service = "local_service_id",
function = "local_fn_name",
args = vec!["2"]
),
par(1, 14),
stream_string(3.to_string(), generation),
stream!(
3.to_string(),
generation,
peer = "some_peer_id_2",
service = "local_service_id",
function = "local_fn_name",
args = vec!["3"]
),
par(1, 12),
stream_string(4.to_string(), generation),
stream!(
4.to_string(),
generation,
peer = "some_peer_id_2",
service = "local_service_id",
function = "local_fn_name",
args = vec!["4"]
),
par(1, 10),
stream_string(5.to_string(), generation),
stream!(
5.to_string(),
generation,
peer = "some_peer_id_2",
service = "local_service_id",
function = "local_fn_name",
args = vec!["5"]
),
par(1, 8),
stream_string(6.to_string(), generation),
stream!(
6.to_string(),
generation,
peer = "some_peer_id_2",
service = "local_service_id",
function = "local_fn_name",
args = vec!["6"]
),
par(1, 6),
stream_string(7.to_string(), generation),
stream!(
7.to_string(),
generation,
peer = "some_peer_id_2",
service = "local_service_id",
function = "local_fn_name",
args = vec!["7"]
),
par(1, 4),
stream_string(8.to_string(), generation),
stream!(
8.to_string(),
generation,
peer = "some_peer_id_2",
service = "local_service_id",
function = "local_fn_name",
args = vec!["8"]
),
par(1, 2),
stream_string(9.to_string(), generation),
stream!(
9.to_string(),
generation,
peer = "some_peer_id_2",
service = "local_service_id",
function = "local_fn_name",
args = vec!["9"]
),
par(1, 0),
stream_string(10.to_string(), generation),
scalar_string("result from unit_call_service"),
stream!(
10.to_string(),
generation,
peer = "some_peer_id_2",
service = "local_service_id",
function = "local_fn_name",
args = vec!["10"]
),
scalar!(
"result from unit_call_service",
peer = "some_peer_id_3",
service = "local_service_id",
function = "local_fn_name"
),
];
assert_eq!(actual_trace, expected_trace);
@ -374,11 +624,11 @@ fn executed_trace_seq_par_seq_seq() {
let unit_call_service_result = "result from unit_call_service";
let executed_trace = vec![
par(2, 2),
scalar_string(unit_call_service_result),
scalar_string(unit_call_service_result),
scalar_string(unit_call_service_result),
scalar_string(unit_call_service_result),
scalar_string(unit_call_service_result),
scalar!(unit_call_service_result, peer = peer_id_1),
scalar!(unit_call_service_result, peer = peer_id_2),
scalar!(unit_call_service_result, peer = peer_id_2),
scalar!(unit_call_service_result, peer = peer_id_1),
scalar!(unit_call_service_result, peer = peer_id_2),
];
assert_eq!(actual_trace, executed_trace);

View File

@ -201,12 +201,8 @@ fn variable_names_shown_in_error() {
let result = checked_call_vm!(echo_vm, <_>::default(), script, "", result.data);
let trace = trace_from_result(&result);
assert_eq!(
trace[1.into()],
executed_state::scalar(json!(
"call cannot resolve non-String triplet variable part `-relay-` with value '1'"
))
);
let msg = "call cannot resolve non-String triplet variable part `-relay-` with value '1'";
assert_eq!(trace[1.into()], unused!(msg, peer = echo_vm_peer_id, args = vec![msg]));
}
#[test]

View File

@ -18,6 +18,8 @@ use air::CatchableError;
use air_test_framework::AirScriptExecutor;
use air_test_utils::prelude::*;
use pretty_assertions::assert_eq;
use std::cell::RefCell;
#[test]
@ -37,8 +39,8 @@ fn length_functor_for_array_scalar() {
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
executed_state::scalar(json!([1, 1, 1])),
executed_state::scalar_number(3),
scalar!(json!([1, 1, 1]), peer = init_peer_id, service = "..0"),
unused!(3, peer = init_peer_id, args = vec![3], service = "..1"),
];
assert_eq!(actual_trace, expected_trace);
}
@ -103,7 +105,7 @@ fn length_functor_for_stream() {
},
]
})),
executed_state::scalar_number(2),
unused!(2, peer = init_peer_id, service = "..0", args = vec![2]),
];
assert_eq!(actual_trace, expected_trace);
}
@ -131,7 +133,7 @@ fn length_functor_for_empty_stream() {
json!({"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "init_peer_id", "service_id": ""},
"values": []} ),
),
executed_state::scalar_number(0),
unused!(0, peer = init_peer_id, service = "..0", args = vec![0]),
];
assert_eq!(actual_trace, expected_trace);
}
@ -166,7 +168,7 @@ fn length_functor_for_canon_stream() {
{"result": 1, "tetraplet": {"function_name": "", "json_path": "", "peer_pk": "init_peer_id", "service_id": ""}, "trace_pos": 1}
]} ),
),
executed_state::scalar_number(2),
unused!(2, peer = init_peer_id, service = "..0", args = vec![2]),
];
assert_eq!(actual_trace, expected_trace);
}
@ -193,7 +195,7 @@ fn length_functor_for_empty_canon_stream() {
executed_state::canon(
json!({"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "init_peer_id", "service_id": ""}, "values": []} ),
),
executed_state::scalar_number(0),
unused!(0, peer = init_peer_id, service = "..0", args = vec![0]),
];
assert_eq!(actual_trace, expected_trace);
}
@ -232,8 +234,8 @@ fn functor_dont_influence_tetraplet() {
assert_eq!(actual_tetraplet.as_ref(), &expected_tetraplet);
let expected_trace = vec![
executed_state::scalar(set_variable_peer_result),
executed_state::scalar_number(3),
scalar!(set_variable_peer_result, peer = set_variable_peer_id),
unused!(3, peer = tetraplet_catcher_peer_id, args = vec![3]),
];
assert_eq!(actual_trace, expected_trace);
}

View File

@ -71,7 +71,7 @@ fn lambda_with_string_scalar() {
let result = checked_call_vm!(local_vm, <_>::default(), script, "", result.data);
let trace = trace_from_result(&result);
assert_eq!(&trace[2.into()], &executed_state::scalar_number(1u32));
assert_eq!(&trace[2.into()], &unused!(1u32, peer = local_peer_id, args = vec![1]));
}
#[test]
@ -103,7 +103,7 @@ fn lambda_with_number_scalar() {
let result = checked_call_vm!(local_vm, <_>::default(), script, "", result.data);
let trace = trace_from_result(&result);
assert_eq!(&trace[2.into()], &executed_state::scalar_number(1u32));
assert_eq!(&trace[2.into()], &unused!(1u32, peer = local_peer_id, args = vec![1]));
}
#[test]
@ -146,7 +146,10 @@ fn lambda_with_number_stream() {
let result = checked_call_vm!(local_vm, <_>::default(), script, "", result.data);
let actual_trace = trace_from_result(&result);
assert_eq!(&actual_trace[6.into()], &executed_state::scalar_number(2));
assert_eq!(
&actual_trace[6.into()],
&unused!(2, peer = local_peer_id, args = vec![2])
);
}
#[test]
@ -194,7 +197,10 @@ fn lambda_with_number_stream_and_followed_scalar() {
let result = checked_call_vm!(local_vm, <_>::default(), script, "", result.data);
let actual_trace = trace_from_result(&result);
assert_eq!(&actual_trace[7.into()], &executed_state::scalar_number(checkable_value));
assert_eq!(
&actual_trace[7.into()],
&unused!(checkable_value, peer = local_peer_id, args = vec![checkable_value])
);
}
#[test]

View File

@ -30,7 +30,10 @@ fn empty_array() {
let result = checked_call_vm!(vm, <_>::default(), script, "", "");
let actual_trace = trace_from_result(&result);
let expected_trace = vec![executed_state::scalar(json!([])), executed_state::scalar(json!([]))];
let expected_trace = vec![
scalar!(json!([]), peer = vm_peer_id, args = vec![json!([])]),
unused!(json!([]), peer = vm_peer_id, args = vec![json!([])]),
];
assert_eq!(actual_trace, expected_trace);
assert!(result.next_peer_pks.is_empty());

View File

@ -18,9 +18,6 @@ use air::CatchableError;
use air::ExecutionError;
use air_test_utils::prelude::*;
use fstrings::f;
use fstrings::format_args_f;
#[test]
fn scalars_scope() {
let peer_1_id = "peer_1_id";
@ -35,7 +32,8 @@ fn scalars_scope() {
let peers = json!([peer_1_id, peer_2_id]);
let mut set_array_0_vm = create_avm(set_variable_call_service(peers.clone()), set_array_0_peer_id);
let script = f!(r#"
let script = format!(
r#"
(seq
(call "{set_array_0_peer_id}" ("" "") [] array-0)
(fold array-0 array-0-iterator
@ -55,7 +53,8 @@ fn scalars_scope() {
)
)
)
)"#);
)"#
);
let result = checked_call_vm!(set_array_0_vm, <_>::default(), &script, "", "");
let result = checked_call_vm!(peer_1_vm, <_>::default(), &script, "", result.data);
@ -63,11 +62,11 @@ fn scalars_scope() {
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
executed_state::scalar(peers),
scalar!(peers, peer = set_array_0_peer_id),
executed_state::par(1, 0),
executed_state::scalar(array_1_content),
executed_state::scalar_string("result from unit_call_service"),
executed_state::scalar_string("result from unit_call_service"),
scalar!(array_1_content, peer = peer_1_id),
unused!("result from unit_call_service", peer = some_peer_id),
unused!("result from unit_call_service", peer = some_peer_id),
executed_state::par(1, 0),
executed_state::request_sent_by(some_peer_id),
];
@ -92,7 +91,8 @@ fn before_after_of_next() {
let vm_peer_1_id = "vm_peer_1_id";
let mut peer_1_vm = create_avm(echo_call_service(), vm_peer_1_id);
let script = f!(r#"
let script = format!(
r#"
(seq
(call "{set_array_0_peer_id}" ("" "") [] array-0)
(fold array-0 array-0-iterator
@ -104,7 +104,8 @@ fn before_after_of_next() {
)
)
)
)"#);
)"#
);
let result = checked_call_vm!(set_array_0_vm, <_>::default(), &script, "", "");
let result = checked_call_vm!(peer_0_vm, <_>::default(), &script, "", result.data);
@ -112,13 +113,13 @@ fn before_after_of_next() {
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
executed_state::scalar(array_0_content),
executed_state::scalar_number(0),
executed_state::scalar_number(1),
executed_state::scalar_number(2),
executed_state::scalar_number(2),
executed_state::scalar_number(1),
executed_state::scalar_number(0),
scalar!(array_0_content, peer = set_array_0_peer_id),
scalar!(0, peer = vm_peer_0_id),
scalar!(1, peer = vm_peer_0_id),
scalar!(2, peer = vm_peer_0_id),
unused!(2, peer = vm_peer_1_id, args = vec![2]),
unused!(1, peer = vm_peer_1_id, args = vec![1]),
unused!(0, peer = vm_peer_1_id, args = vec![0]),
];
assert_eq!(actual_trace, expected_trace);
}
@ -144,7 +145,8 @@ fn local_and_global_scalars() {
let local_consumer_peer_id = "local_consumer_peer_id";
let mut local_consumer_vm = create_avm(echo_call_service(), local_consumer_peer_id);
let script = f!(r#"
let script = format!(
r#"
(seq
(seq
(seq
@ -176,7 +178,8 @@ fn local_and_global_scalars() {
)
)
(call "{local_consumer_peer_id}" ("" "") [local]) ;; local set by (1) will be used
)"#);
)"#
);
let result = checked_call_vm!(set_variable_vm, <_>::default(), &script, "", "");
let result = checked_call_vm!(local_setter_vm, <_>::default(), &script, "", result.data);
@ -190,22 +193,22 @@ fn local_and_global_scalars() {
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
executed_state::scalar(iterable_content.clone()),
executed_state::scalar(iterable_content),
executed_state::scalar_number(0),
executed_state::scalar_number(1),
executed_state::scalar_number(2),
executed_state::scalar_number(2),
executed_state::scalar_number(3),
executed_state::scalar_number(3),
executed_state::scalar_number(1),
executed_state::scalar_number(4),
executed_state::scalar_number(5),
executed_state::scalar_number(5),
executed_state::scalar_number(6),
executed_state::scalar_number(6),
executed_state::scalar_number(4),
executed_state::scalar_number(0),
scalar!(iterable_content.clone(), peer = set_variable_peer_id),
scalar!(iterable_content, peer = set_variable_peer_id),
scalar!(0, peer = local_setter_peer_id),
scalar!(1, peer = local_setter_peer_id),
scalar!(2, peer = local_setter_peer_id),
unused!(2, peer = local_consumer_peer_id, args = vec![2]),
scalar!(3, peer = local_setter_peer_id),
unused!(3, peer = local_consumer_peer_id, args = vec![3]),
unused!(1, peer = local_consumer_peer_id, args = vec![1]),
scalar!(4, peer = local_setter_peer_id),
scalar!(5, peer = local_setter_peer_id),
unused!(5, peer = local_consumer_peer_id, args = vec![5]),
scalar!(6, peer = local_setter_peer_id),
unused!(6, peer = local_consumer_peer_id, args = vec![6]),
unused!(4, peer = local_consumer_peer_id, args = vec![4]),
unused!(0, peer = local_consumer_peer_id, args = vec![0]),
];
assert_eq!(actual_trace, expected_trace);
}
@ -216,7 +219,8 @@ fn new_with_randomly_set_scalars_in_fold_1() {
let mut test_vm_1 = create_avm(set_variable_call_service(json!([1, 2, 3])), test_peer_id_1);
let test_peer_id_2 = "test_peer_id_2";
let script = f!(r#"
let script = format!(
r#"
(seq
(call "{test_peer_id_1}" ("" "") [] iterable)
(fold iterable iterator
@ -242,7 +246,8 @@ fn new_with_randomly_set_scalars_in_fold_1() {
(call "{test_peer_id_1}" ("" "") [scalar])
)
)
)"#);
)"#
);
let result = call_vm!(test_vm_1, <_>::default(), &script, "", "");
assert_eq!(result.ret_code, 0)
@ -255,7 +260,8 @@ fn new_with_randomly_set_scalars_in_fold_2() {
let test_peer_id_2 = "test_peer_id_2";
let variable_name = "scalar";
let script = f!(r#"
let script = format!(
r#"
(seq
(call "{test_peer_id_1}" ("" "") [] iterable)
(fold iterable iterator
@ -278,7 +284,8 @@ fn new_with_randomly_set_scalars_in_fold_2() {
(call "{test_peer_id_1}" ("" "") [{variable_name}])
)
)
)"#);
)"#
);
let result = call_vm!(test_vm_1, <_>::default(), &script, "", "");
let expected_error = ExecutionError::Catchable(rc!(CatchableError::VariableWasNotInitializedAfterNew(

View File

@ -14,10 +14,10 @@
* limitations under the License.
*/
use air_interpreter_data::ExecutionTrace;
use air_test_utils::prelude::*;
use fstrings::f;
use fstrings::format_args_f;
use pretty_assertions::assert_eq;
#[test]
fn check_that_scalar_is_visible_only_inside_fold_block() {
@ -30,7 +30,8 @@ fn check_that_scalar_is_visible_only_inside_fold_block() {
let variable_receiver_peer_id = "variable_receiver_peer_id";
let mut variable_receiver_peer_vm = create_avm(echo_call_service(), variable_receiver_peer_id);
let script = f!(r#"
let script = format!(
r#"
(seq
(call "{variable_setter_peer_id}" ("" "") ["iterable_1"] iterable_1)
(xor
@ -46,21 +47,31 @@ fn check_that_scalar_is_visible_only_inside_fold_block() {
(call "{variable_receiver_peer_id}" ("" "") [scalar])
)
)
"#);
"#
);
let result = checked_call_vm!(variable_setter_vm, <_>::default(), &script, "", "");
let result = checked_call_vm!(fallible_peer_vm, <_>::default(), &script, "", result.data);
let result = checked_call_vm!(variable_receiver_peer_vm, <_>::default(), &script, "", result.data);
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
executed_state::scalar(json!([1, 2, 3])),
executed_state::scalar(json!([1, 2, 3])),
executed_state::scalar(json!([1, 2, 3])),
executed_state::scalar(json!([1, 2, 3])),
executed_state::service_failed(1, "failed result from fallible_call_service"),
let expected_trace = ExecutionTrace::from(vec![
scalar!(
json!([1, 2, 3]),
peer = variable_setter_peer_id,
args = vec!["iterable_1"]
),
scalar!(json!([1, 2, 3]), peer = variable_setter_peer_id),
scalar!(json!([1, 2, 3]), peer = variable_setter_peer_id),
scalar!(json!([1, 2, 3]), peer = variable_setter_peer_id),
failed!(
1,
"failed result from fallible_call_service",
peer = fallible_peer_id,
service = "fail"
),
executed_state::request_sent_by(fallible_peer_id),
];
]);
assert_eq!(actual_trace, expected_trace);
}
@ -76,7 +87,8 @@ fn scopes_check_that_scalar_not_overwritten_by_fold_end() {
let variable_receiver_peer_id = "variable_receiver_peer_id";
let mut variable_receiver_peer_vm = create_avm(echo_call_service(), variable_receiver_peer_id);
let script = f!(r#"
let script = format!(
r#"
(seq
(seq
(call "{variable_setter_peer_id}" ("" "") ["iterable_1"] iterable_1)
@ -95,22 +107,36 @@ fn scopes_check_that_scalar_not_overwritten_by_fold_end() {
(call "{variable_receiver_peer_id}" ("" "") [scalar])
)
)
"#);
"#
);
let result = checked_call_vm!(variable_setter_vm, <_>::default(), &script, "", "");
let result = checked_call_vm!(fallible_peer_vm, <_>::default(), &script, "", result.data);
let result = checked_call_vm!(variable_receiver_peer_vm, <_>::default(), &script, "", result.data);
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
executed_state::scalar(json!([1, 2, 3])),
executed_state::scalar(json!([1, 2, 3])),
executed_state::scalar(json!([1, 2, 3])),
executed_state::scalar(json!([1, 2, 3])),
executed_state::scalar(json!([1, 2, 3])),
executed_state::service_failed(1, "failed result from fallible_call_service"),
executed_state::scalar(json!([1, 2, 3])),
];
let expected_trace = ExecutionTrace::from(vec![
scalar!(
json!([1, 2, 3]),
peer = variable_setter_peer_id,
args = vec!["iterable_1"]
),
scalar!(json!([1, 2, 3]), peer = variable_setter_peer_id, args = vec!["scalar"]),
scalar!(json!([1, 2, 3]), peer = variable_setter_peer_id),
scalar!(json!([1, 2, 3]), peer = variable_setter_peer_id),
scalar!(json!([1, 2, 3]), peer = variable_setter_peer_id),
failed!(
1,
"failed result from fallible_call_service",
peer = fallible_peer_id,
service = "fail"
),
unused!(
json!([1, 2, 3]),
peer = variable_receiver_peer_id,
args = vec![json!([1, 2, 3])]
),
]);
assert_eq!(actual_trace, expected_trace);
}

View File

@ -14,6 +14,7 @@
* limitations under the License.
*/
use air_interpreter_data::ExecutionTrace;
use air_test_utils::prelude::*;
use pretty_assertions::assert_eq;
@ -55,14 +56,14 @@ fn recursive_stream_with_early_exit() {
let result = checked_call_vm!(vm, <_>::default(), script, "", "");
let actual_trace = trace_from_result(&result);
let expected_state = vec![
executed_state::stream_number(1, 0),
executed_state::stream_number(1, 1),
stream!(1, 0, peer = vm_peer_id, function = "stream_value"),
stream!(1, 1, peer = vm_peer_id, function = "stream_value"),
executed_state::fold(vec![
executed_state::subtrace_lore(0, subtrace_desc(3, 1), subtrace_desc(4, 0)),
executed_state::subtrace_lore(1, subtrace_desc(4, 1), subtrace_desc(5, 0)),
]),
executed_state::scalar_string("stop"),
executed_state::scalar_string("stop"),
scalar!("stop", peer = vm_peer_id, function = "stop"),
scalar!("stop", peer = vm_peer_id, function = "stop"),
];
assert_eq!(actual_trace, expected_state);
@ -156,7 +157,7 @@ fn recursive_stream_many_iterations() {
let result = checked_call_vm!(vm_2, <_>::default(), script, "", result.data);
let actual_trace = trace_from_result(&result);
let actual_last_state = actual_trace.last().unwrap();
let expected_last_state = executed_state::scalar_string(result_value);
let expected_last_state = unused!(result_value, peer = vm_peer_id_2, args = [result_value]);
assert_eq!(actual_last_state, &expected_last_state);
}
@ -216,10 +217,10 @@ fn recursive_stream_join() {
let result = checked_call_vm!(vm_3, <_>::default(), &script, "", result.data);
let result = checked_call_vm!(vm_2, <_>::default(), &script, "", result.data);
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
let expected_trace = ExecutionTrace::from(vec![
executed_state::par(1, 1),
executed_state::stream_string("non_join", 0),
executed_state::scalar_string(""),
stream!("non_join", 0, peer = vm_peer_id_1, function = "stream_value"),
scalar!("", peer = vm_peer_id_3, function = "stream_value", args = [""]),
executed_state::fold(vec![
executed_state::subtrace_lore(1, subtrace_desc(4, 2), subtrace_desc(6, 0)),
executed_state::subtrace_lore(5, subtrace_desc(6, 2), subtrace_desc(8, 0)),
@ -227,18 +228,18 @@ fn recursive_stream_join() {
executed_state::subtrace_lore(9, subtrace_desc(10, 2), subtrace_desc(12, 0)),
executed_state::subtrace_lore(11, subtrace_desc(12, 2), subtrace_desc(14, 0)),
]),
executed_state::scalar_string("non_join"),
scalar!("non_join", peer = vm_peer_id_1, args = [""]),
executed_state::ap(1),
executed_state::scalar_string("non_join"),
scalar!("non_join", peer = vm_peer_id_1, args = [""]),
executed_state::ap(2),
executed_state::scalar_string("non_join"),
scalar!("non_join", peer = vm_peer_id_1, args = [""]),
executed_state::ap(3),
executed_state::scalar_string("non_join"),
scalar!("non_join", peer = vm_peer_id_1, args = [""]),
executed_state::ap(4),
executed_state::scalar_string("join"),
executed_state::scalar_string(""),
executed_state::scalar_string(result_value),
];
scalar!("join", peer = vm_peer_id_1, args = [""]),
unused!("", peer = vm_peer_id_2, args = [""]),
unused!(result_value, peer = vm_peer_id_2, args = [result_value]),
]);
assert_eq!(actual_trace, expected_trace);
}
@ -290,9 +291,10 @@ fn recursive_stream_error_handling() {
let result = checked_call_vm!(vm_1, <_>::default(), &script, "", "");
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
executed_state::stream_string("non_stop", 0),
executed_state::stream_string("non_stop", 1),
stream!("non_stop", 0, peer = vm_peer_id_1, function = "stream_value"),
stream!("non_stop", 1, peer = vm_peer_id_1, function = "stream_value"),
executed_state::fold(vec![
subtrace_lore(0, SubTraceDesc::new(3.into(), 2), SubTraceDesc::new(5.into(), 0)),
subtrace_lore(1, SubTraceDesc::new(5.into(), 2), SubTraceDesc::new(7.into(), 0)),
@ -300,14 +302,14 @@ fn recursive_stream_error_handling() {
subtrace_lore(6, SubTraceDesc::new(9.into(), 1), SubTraceDesc::new(10.into(), 0)),
subtrace_lore(8, SubTraceDesc::new(10.into(), 1), SubTraceDesc::new(11.into(), 0)),
]),
executed_state::scalar_string("non_stop"),
scalar!("non_stop", peer = vm_peer_id_1, function = "stop"),
executed_state::ap(2),
executed_state::scalar_string("non_stop"),
scalar!("non_stop", peer = vm_peer_id_1, function = "stop"),
executed_state::ap(2),
executed_state::scalar_string("non_stop"),
scalar!("non_stop", peer = vm_peer_id_1, function = "stop"),
executed_state::ap(3),
executed_state::service_failed(1, "error"),
executed_state::service_failed(1, "error"),
failed!(1, "error", peer = vm_peer_id_1, function = "stop"),
failed!(1, "error", peer = vm_peer_id_1, function = "stop"),
];
assert_eq!(actual_trace, expected_trace);
@ -371,7 +373,7 @@ fn recursive_stream_inner_fold() {
let actual_trace = trace_from_result(&result);
let actual_last_state = actual_trace.last().unwrap();
let expected_last_state = executed_state::scalar_string(result_value);
let expected_last_state = unused!(result_value, peer = vm_peer_id_2, args = [result_value]);
assert_eq!(actual_last_state, &expected_last_state);
}

View File

@ -14,6 +14,7 @@
* limitations under the License.
*/
use air_interpreter_data::ExecutionTrace;
use air_test_utils::prelude::*;
use pretty_assertions::assert_eq;
@ -80,33 +81,33 @@ fn stream_merging_v0() {
let actual_trace_1 = trace_from_result(&executor_result_1);
let unit_call_service_result = "result from unit_call_service";
let expected_trace_1 = vec![
executed_state::scalar_string(unit_call_service_result),
let expected_trace_1 = ExecutionTrace::from(vec![
unused!(unit_call_service_result, peer = initiator_id),
executed_state::par(11, 1),
executed_state::par(9, 1),
executed_state::par(7, 1),
executed_state::par(5, 1),
executed_state::par(3, 1),
executed_state::par(1, 1),
executed_state::stream_string("1", 0),
stream!("1", 0, peer = setter_1_id),
executed_state::request_sent_by(initiator_id),
executed_state::stream_string("1", 0),
stream!("1", 0, peer = setter_1_id),
executed_state::request_sent_by(initiator_id),
executed_state::request_sent_by(initiator_id),
executed_state::stream_string("1", 0),
stream!("1", 0, peer = setter_1_id),
executed_state::request_sent_by(initiator_id),
executed_state::fold(vec![
executed_state::subtrace_lore(7, subtrace_desc(15, 2), subtrace_desc(21, 0)),
executed_state::subtrace_lore(9, subtrace_desc(17, 2), subtrace_desc(21, 0)),
executed_state::subtrace_lore(12, subtrace_desc(19, 2), subtrace_desc(21, 0)),
]),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
];
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
]);
assert_eq!(actual_trace_1, expected_trace_1);
let executor_result_2 = checked_call_vm!(
@ -119,20 +120,20 @@ fn stream_merging_v0() {
let actual_trace_2 = trace_from_result(&executor_result_2);
let expected_trace_2 = vec![
executed_state::scalar_string(unit_call_service_result),
unused!(unit_call_service_result, peer = initiator_id),
executed_state::par(11, 1),
executed_state::par(9, 1),
executed_state::par(7, 1),
executed_state::par(5, 1),
executed_state::par(3, 1),
executed_state::par(1, 1),
executed_state::stream_string("1", 0),
executed_state::stream_string("2", 1),
executed_state::stream_string("1", 0),
stream!("1", 0, peer = setter_1_id),
stream!("2", 1, peer = setter_2_id),
stream!("1", 0, peer = setter_1_id),
executed_state::request_sent_by(initiator_id),
executed_state::request_sent_by(initiator_id),
executed_state::stream_string("1", 0),
executed_state::stream_string("2", 1),
stream!("1", 0, peer = setter_1_id),
stream!("2", 1, peer = setter_2_id),
executed_state::fold(vec![
executed_state::subtrace_lore(7, subtrace_desc(15, 2), subtrace_desc(21, 0)),
executed_state::subtrace_lore(9, subtrace_desc(17, 2), subtrace_desc(21, 0)),
@ -140,16 +141,16 @@ fn stream_merging_v0() {
executed_state::subtrace_lore(8, subtrace_desc(21, 2), subtrace_desc(25, 0)),
executed_state::subtrace_lore(13, subtrace_desc(23, 2), subtrace_desc(25, 0)),
]),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
];
assert_eq!(actual_trace_2.deref(), expected_trace_2);
@ -162,21 +163,21 @@ fn stream_merging_v0() {
);
let actual_trace_3 = trace_from_result(&executor_result_3);
let expected_trace_3 = vec![
executed_state::scalar_string(unit_call_service_result),
let expected_trace_3 = ExecutionTrace::from(vec![
unused!(unit_call_service_result, peer = initiator_id),
executed_state::par(11, 1),
executed_state::par(9, 1),
executed_state::par(7, 1),
executed_state::par(5, 1),
executed_state::par(3, 1),
executed_state::par(1, 1),
executed_state::stream_string("1", 0),
executed_state::stream_string("2", 1),
executed_state::stream_string("1", 0),
executed_state::stream_string("3", 2),
executed_state::stream_string("3", 2),
executed_state::stream_string("1", 0),
executed_state::stream_string("2", 1),
stream!("1", 0, peer = setter_1_id),
stream!("2", 1, peer = setter_2_id),
stream!("1", 0, peer = setter_1_id),
stream!("3", 2, peer = setter_3_id),
stream!("3", 2, peer = setter_3_id),
stream!("1", 0, peer = setter_1_id),
stream!("2", 1, peer = setter_2_id),
executed_state::fold(vec![
executed_state::subtrace_lore(7, subtrace_desc(15, 2), subtrace_desc(21, 0)),
executed_state::subtrace_lore(9, subtrace_desc(17, 2), subtrace_desc(21, 0)),
@ -186,21 +187,21 @@ fn stream_merging_v0() {
executed_state::subtrace_lore(10, subtrace_desc(25, 2), subtrace_desc(29, 0)),
executed_state::subtrace_lore(11, subtrace_desc(27, 2), subtrace_desc(29, 0)),
]),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
];
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
unused!(unit_call_service_result, peer = executor_id, args = ["3"]),
unused!(unit_call_service_result, peer = executor_id, args = ["3"]),
unused!(unit_call_service_result, peer = executor_id, args = ["3"]),
unused!(unit_call_service_result, peer = executor_id, args = ["3"]),
]);
assert_eq!(actual_trace_3, expected_trace_3);
}
@ -232,20 +233,20 @@ fn stream_merging_v1() {
let actual_trace_1 = trace_from_result(&executor_result_1);
let unit_call_service_result = "result from unit_call_service";
let expected_trace_1 = vec![
executed_state::scalar_string(unit_call_service_result),
let expected_trace_1 = ExecutionTrace::from(vec![
unused!(unit_call_service_result, peer = initiator_id),
executed_state::par(11, 1),
executed_state::par(9, 1),
executed_state::par(7, 1),
executed_state::par(5, 1),
executed_state::par(3, 1),
executed_state::par(1, 1),
executed_state::stream_string("1", 0),
stream!("1", 0, peer = setter_1_id),
executed_state::request_sent_by(initiator_id),
executed_state::stream_string("1", 0),
stream!("1", 0, peer = setter_1_id),
executed_state::request_sent_by(initiator_id),
executed_state::request_sent_by(initiator_id),
executed_state::stream_string("1", 0),
stream!("1", 0, peer = setter_1_id),
executed_state::request_sent_by(initiator_id),
executed_state::fold(vec![
executed_state::subtrace_lore(7, subtrace_desc(15, 2), subtrace_desc(23, 1)),
@ -253,15 +254,15 @@ fn stream_merging_v1() {
executed_state::subtrace_lore(12, subtrace_desc(19, 2), subtrace_desc(21, 1)),
]),
executed_state::par(7, 1),
executed_state::scalar_string(unit_call_service_result),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
executed_state::par(4, 1),
executed_state::scalar_string(unit_call_service_result),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
executed_state::par(1, 1),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
];
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
]);
assert_eq!(actual_trace_1, expected_trace_1);
let executor_result_2 = checked_call_vm!(
@ -273,21 +274,21 @@ fn stream_merging_v1() {
);
let actual_trace_2 = trace_from_result(&executor_result_2);
let expected_trace_2 = vec![
executed_state::scalar_string(unit_call_service_result),
let expected_trace_2 = ExecutionTrace::from(vec![
unused!(unit_call_service_result, peer = initiator_id),
executed_state::par(11, 1),
executed_state::par(9, 1),
executed_state::par(7, 1),
executed_state::par(5, 1),
executed_state::par(3, 1),
executed_state::par(1, 1),
executed_state::stream_string("1", 0),
executed_state::stream_string("2", 1),
executed_state::stream_string("1", 0),
stream!("1", 0, peer = setter_1_id),
stream!("2", 1, peer = setter_2_id),
stream!("1", 0, peer = setter_1_id),
executed_state::request_sent_by(initiator_id),
executed_state::request_sent_by(initiator_id),
executed_state::stream_string("1", 0),
executed_state::stream_string("2", 1),
stream!("1", 0, peer = setter_1_id),
stream!("2", 1, peer = setter_2_id),
executed_state::fold(vec![
executed_state::subtrace_lore(7, subtrace_desc(15, 2), subtrace_desc(23, 1)),
executed_state::subtrace_lore(9, subtrace_desc(17, 2), subtrace_desc(22, 1)),
@ -296,21 +297,21 @@ fn stream_merging_v1() {
executed_state::subtrace_lore(13, subtrace_desc(26, 2), subtrace_desc(28, 1)),
]),
executed_state::par(7, 1),
executed_state::scalar_string(unit_call_service_result),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
executed_state::par(4, 1),
executed_state::scalar_string(unit_call_service_result),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
executed_state::par(1, 1),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
executed_state::par(4, 1),
executed_state::scalar_string(unit_call_service_result),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
executed_state::par(1, 1),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
];
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
]);
assert_eq!(actual_trace_2, expected_trace_2);
let executor_result_3 = checked_call_vm!(
@ -322,21 +323,21 @@ fn stream_merging_v1() {
);
let actual_trace_3 = trace_from_result(&executor_result_3);
let expected_trace_3 = vec![
executed_state::scalar_string(unit_call_service_result),
let expected_trace_3 = ExecutionTrace::from(vec![
unused!(unit_call_service_result, peer = initiator_id),
executed_state::par(11, 1),
executed_state::par(9, 1),
executed_state::par(7, 1),
executed_state::par(5, 1),
executed_state::par(3, 1),
executed_state::par(1, 1),
executed_state::stream_string("1", 0),
executed_state::stream_string("2", 1),
executed_state::stream_string("1", 0),
executed_state::stream_string("3", 2),
executed_state::stream_string("3", 2),
executed_state::stream_string("1", 0),
executed_state::stream_string("2", 1),
stream!("1", 0, peer = setter_1_id),
stream!("2", 1, peer = setter_2_id),
stream!("1", 0, peer = setter_1_id),
stream!("3", 2, peer = setter_3_id),
stream!("3", 2, peer = setter_3_id),
stream!("1", 0, peer = setter_1_id),
stream!("2", 1, peer = setter_2_id),
executed_state::fold(vec![
executed_state::subtrace_lore(7, subtrace_desc(15, 2), subtrace_desc(23, 1)),
executed_state::subtrace_lore(9, subtrace_desc(17, 2), subtrace_desc(22, 1)),
@ -347,27 +348,27 @@ fn stream_merging_v1() {
executed_state::subtrace_lore(11, subtrace_desc(32, 2), subtrace_desc(34, 1)),
]),
executed_state::par(7, 1),
executed_state::scalar_string(unit_call_service_result),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
executed_state::par(4, 1),
executed_state::scalar_string(unit_call_service_result),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
executed_state::par(1, 1),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
executed_state::par(4, 1),
executed_state::scalar_string(unit_call_service_result),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
executed_state::par(1, 1),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
executed_state::par(4, 1),
executed_state::scalar_string(unit_call_service_result),
unused!(unit_call_service_result, peer = executor_id, args = ["3"]),
executed_state::par(1, 1),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
];
unused!(unit_call_service_result, peer = executor_id, args = ["3"]),
unused!(unit_call_service_result, peer = executor_id, args = ["3"]),
unused!(unit_call_service_result, peer = executor_id, args = ["3"]),
]);
assert_eq!(actual_trace_3, expected_trace_3);
}
@ -400,33 +401,33 @@ fn stream_merging_v2() {
let actual_trace_1 = trace_from_result(&executor_result_1);
let unit_call_service_result = "result from unit_call_service";
let expected_trace_1 = vec![
executed_state::scalar_string(unit_call_service_result),
let expected_trace_1 = ExecutionTrace::from(vec![
unused!(unit_call_service_result, peer = initiator_id),
executed_state::par(11, 1),
executed_state::par(9, 1),
executed_state::par(7, 1),
executed_state::par(5, 1),
executed_state::par(3, 1),
executed_state::par(1, 1),
executed_state::stream_string("1", 0),
stream!("1", 0, peer = setter_1_id),
executed_state::request_sent_by(initiator_id),
executed_state::stream_string("1", 0),
stream!("1", 0, peer = setter_1_id),
executed_state::request_sent_by(initiator_id),
executed_state::request_sent_by(initiator_id),
executed_state::stream_string("1", 0),
stream!("1", 0, peer = setter_1_id),
executed_state::request_sent_by(initiator_id),
executed_state::fold(vec![
executed_state::subtrace_lore(7, subtrace_desc(15, 1), subtrace_desc(21, 2)),
executed_state::subtrace_lore(9, subtrace_desc(16, 1), subtrace_desc(19, 2)),
executed_state::subtrace_lore(12, subtrace_desc(17, 1), subtrace_desc(18, 2)),
]),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
];
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
]);
assert_eq!(actual_trace_1, expected_trace_1);
let executor_result_2 = checked_call_vm!(
@ -438,21 +439,21 @@ fn stream_merging_v2() {
);
let actual_trace_2 = trace_from_result(&executor_result_2);
let expected_trace_2 = vec![
executed_state::scalar_string(unit_call_service_result),
let expected_trace_2 = ExecutionTrace::from(vec![
unused!(unit_call_service_result, peer = initiator_id),
executed_state::par(11, 1),
executed_state::par(9, 1),
executed_state::par(7, 1),
executed_state::par(5, 1),
executed_state::par(3, 1),
executed_state::par(1, 1),
executed_state::stream_string("1", 0),
executed_state::stream_string("2", 1),
executed_state::stream_string("1", 0),
stream!("1", 0, peer = setter_1_id),
stream!("2", 1, peer = setter_2_id),
stream!("1", 0, peer = setter_1_id),
executed_state::request_sent_by(initiator_id),
executed_state::request_sent_by(initiator_id),
executed_state::stream_string("1", 0),
executed_state::stream_string("2", 1),
stream!("1", 0, peer = setter_1_id),
stream!("2", 1, peer = setter_2_id),
executed_state::fold(vec![
executed_state::subtrace_lore(7, subtrace_desc(15, 0), subtrace_desc(19, 2)),
executed_state::subtrace_lore(9, subtrace_desc(15, 0), subtrace_desc(17, 2)),
@ -460,17 +461,17 @@ fn stream_merging_v2() {
executed_state::subtrace_lore(8, subtrace_desc(21, 0), subtrace_desc(23, 2)),
executed_state::subtrace_lore(13, subtrace_desc(21, 0), subtrace_desc(21, 2)),
]),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
];
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
]);
assert_eq!(actual_trace_2, expected_trace_2);
let executor_result_3 = checked_call_vm!(
@ -482,21 +483,21 @@ fn stream_merging_v2() {
);
let actual_trace_3 = trace_from_result(&executor_result_3);
let expected_trace_3 = vec![
executed_state::scalar_string(unit_call_service_result),
let expected_trace_3 = ExecutionTrace::from(vec![
unused!(unit_call_service_result, peer = initiator_id),
executed_state::par(11, 1),
executed_state::par(9, 1),
executed_state::par(7, 1),
executed_state::par(5, 1),
executed_state::par(3, 1),
executed_state::par(1, 1),
executed_state::stream_string("1", 0),
executed_state::stream_string("2", 1),
executed_state::stream_string("1", 0),
executed_state::stream_string("3", 2),
executed_state::stream_string("3", 2),
executed_state::stream_string("1", 0),
executed_state::stream_string("2", 1),
stream!("1", 0, peer = setter_1_id),
stream!("2", 1, peer = setter_2_id),
stream!("1", 0, peer = setter_1_id),
stream!("3", 2, peer = setter_3_id),
stream!("3", 2, peer = setter_3_id),
stream!("1", 0, peer = setter_1_id),
stream!("2", 1, peer = setter_2_id),
executed_state::fold(vec![
executed_state::subtrace_lore(7, subtrace_desc(15, 0), subtrace_desc(19, 2)),
executed_state::subtrace_lore(9, subtrace_desc(15, 0), subtrace_desc(17, 2)),
@ -506,20 +507,20 @@ fn stream_merging_v2() {
executed_state::subtrace_lore(10, subtrace_desc(25, 0), subtrace_desc(27, 2)),
executed_state::subtrace_lore(11, subtrace_desc(25, 0), subtrace_desc(25, 2)),
]),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
executed_state::scalar_string(unit_call_service_result),
];
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
unused!(unit_call_service_result, peer = executor_id, args = ["3"]),
unused!(unit_call_service_result, peer = executor_id, args = ["3"]),
unused!(unit_call_service_result, peer = executor_id, args = ["3"]),
unused!(unit_call_service_result, peer = executor_id, args = ["3"]),
unused!(unit_call_service_result, peer = executor_id, args = ["3"]),
]);
assert_eq!(actual_trace_3, expected_trace_3);
}

View File

@ -14,15 +14,17 @@
* limitations under the License.
*/
use air::ExecutionCidState;
use air::UncatchableError;
use air_interpreter_cid::value_to_json_cid;
use air_interpreter_data::CidTracker;
use air_interpreter_data::ExecutionTrace;
use air_interpreter_data::ValueRef;
use air_test_utils::prelude::*;
use air_trace_handler::merger::CallResultError;
use air_trace_handler::merger::MergeError;
use air_trace_handler::TraceHandlerError;
use pretty_assertions::assert_eq;
#[test]
fn par_early_exit() {
let init_peer_id = "init_peer_id";
@ -46,8 +48,8 @@ fn par_early_exit() {
let setter_3_res_1 = checked_call_vm!(setter_3, <_>::default(), &script, "", init_result_1.data.clone());
let actual_trace_1 = trace_from_result(&setter_3_res_1);
let expected_trace = vec![
executed_state::scalar_string("result from unit_call_service"),
let expected_trace = ExecutionTrace::from(vec![
unused!("result from unit_call_service", peer = init_peer_id),
executed_state::par(12, 1),
executed_state::par(9, 1),
executed_state::par(7, 1),
@ -57,13 +59,28 @@ fn par_early_exit() {
executed_state::request_sent_by(init_peer_id),
executed_state::request_sent_by(init_peer_id),
executed_state::request_sent_by(init_peer_id),
executed_state::stream_string("success result from fallible_call_service", 0),
executed_state::service_failed(1, "failed result from fallible_call_service"),
executed_state::stream_string("success result from fallible_call_service", 0),
executed_state::service_failed(1, "failed result from fallible_call_service"),
executed_state::service_failed(1, "failed result from fallible_call_service"),
stream!("success result from fallible_call_service", 0, peer = setter_3_id),
failed!(
1,
"failed result from fallible_call_service",
peer = setter_3_id,
service = "error"
),
stream!("success result from fallible_call_service", 0, peer = setter_3_id),
failed!(
1,
"failed result from fallible_call_service",
peer = setter_3_id,
service = "error"
),
failed!(
1,
"failed result from fallible_call_service",
peer = setter_3_id,
service = "error"
),
executed_state::request_sent_by(setter_3_id),
];
]);
assert_eq!(actual_trace_1, expected_trace);
let setter_3_res_2 = checked_call_vm!(
@ -90,49 +107,79 @@ fn par_early_exit() {
let actual_trace_2 = trace_from_result(&setter_3_res_3);
let actual_trace_3 = trace_from_result(&init_result_2);
let expected_trace = vec![
executed_state::scalar_string("result from unit_call_service"),
let expected_trace = ExecutionTrace::from(vec![
unused!("result from unit_call_service", peer = init_peer_id),
executed_state::par(12, 1),
executed_state::par(9, 1),
executed_state::par(7, 1),
executed_state::par(5, 1),
executed_state::par(3, 1),
executed_state::par(1, 1),
executed_state::stream_string("1", 1),
executed_state::stream_string("2", 2),
executed_state::stream_string("1", 1),
executed_state::stream_string("success result from fallible_call_service", 0),
executed_state::service_failed(1, "failed result from fallible_call_service"),
executed_state::stream_string("success result from fallible_call_service", 0),
executed_state::service_failed(1, "failed result from fallible_call_service"),
executed_state::service_failed(1, "failed result from fallible_call_service"),
stream!("1", 1, peer = setter_1_id),
stream!("2", 2, peer = setter_2_id),
stream!("1", 1, peer = setter_1_id),
stream!("success result from fallible_call_service", 0, peer = setter_3_id),
failed!(
1,
"failed result from fallible_call_service",
peer = setter_3_id,
service = "error"
),
stream!("success result from fallible_call_service", 0, peer = setter_3_id),
failed!(
1,
"failed result from fallible_call_service",
peer = setter_3_id,
service = "error"
),
failed!(
1,
"failed result from fallible_call_service",
peer = setter_3_id,
service = "error"
),
executed_state::request_sent_by("setter_3"),
];
]);
assert_eq!(actual_trace_2, expected_trace);
let expected_trace = vec![
executed_state::scalar_string("result from unit_call_service"),
let expected_trace = ExecutionTrace::from(vec![
unused!("result from unit_call_service", peer = init_peer_id),
executed_state::par(12, 1),
executed_state::par(9, 1),
executed_state::par(7, 1),
executed_state::par(5, 1),
executed_state::par(3, 1),
executed_state::par(1, 1),
executed_state::stream_string("1", 1),
executed_state::stream_string("2", 2),
executed_state::stream_string("1", 1),
executed_state::stream_string("success result from fallible_call_service", 0),
executed_state::service_failed(1, "failed result from fallible_call_service"),
executed_state::stream_string("success result from fallible_call_service", 0),
executed_state::service_failed(1, "failed result from fallible_call_service"),
executed_state::service_failed(1, "failed result from fallible_call_service"),
executed_state::scalar_string("result from unit_call_service"),
];
stream!("1", 1, peer = setter_1_id),
stream!("2", 2, peer = setter_2_id),
stream!("1", 1, peer = setter_1_id),
stream!("success result from fallible_call_service", 0, peer = setter_3_id),
failed!(
1,
"failed result from fallible_call_service",
peer = setter_3_id,
service = "error"
),
stream!("success result from fallible_call_service", 0, peer = setter_3_id),
failed!(
1,
"failed result from fallible_call_service",
peer = setter_3_id,
service = "error"
),
failed!(
1,
"failed result from fallible_call_service",
peer = setter_3_id,
service = "error"
),
unused!("result from unit_call_service", peer = init_peer_id),
]);
assert_eq!(actual_trace_3, expected_trace);
let mut setter_3_tracker = CidTracker::new();
let setter_3_malicious_trace = vec![
executed_state::scalar_tracked("result from unit_call_service", &mut setter_3_tracker),
let mut setter_3_cid_state = ExecutionCidState::new();
let setter_3_malicious_trace = ExecutionTrace::from(vec![
unused!("result from unit_call_service", peer = init_peer_id),
executed_state::par(10, 0),
executed_state::par(9, 0),
executed_state::par(7, 1),
@ -141,12 +188,22 @@ fn par_early_exit() {
executed_state::par(1, 1),
executed_state::request_sent_by(init_peer_id),
executed_state::request_sent_by(init_peer_id),
executed_state::stream_tracked("non_exist_value", 0, &mut setter_3_tracker),
executed_state::stream_tracked("success result from fallible_call_service", 0, &mut setter_3_tracker),
executed_state::service_failed(1, "failed result from fallible_call_service"),
stream_tracked!("non_exist_value", 0, setter_3_cid_state, peer = setter_1_id),
stream_tracked!(
"success result from fallible_call_service",
0,
setter_3_cid_state,
peer = setter_1_id
),
failed!(
1,
"failed result from fallible_call_service",
peer = setter_3_id,
service = "error"
),
executed_state::request_sent_by(setter_3_id),
];
let setter_3_malicious_data = raw_data_from_trace(setter_3_malicious_trace, setter_3_tracker);
]);
let setter_3_malicious_data = raw_data_from_trace(setter_3_malicious_trace, setter_3_cid_state);
let init_result_3 = call_vm!(
init,
<_>::default(),
@ -155,12 +212,24 @@ fn par_early_exit() {
setter_3_malicious_data
);
let mut cid_state = ExecutionCidState::new();
let prev_value = ValueRef::Stream {
cid: value_to_json_cid(&json!("1")).unwrap().into(),
cid: value_aggregate_cid(
json!("1"),
SecurityTetraplet::new(setter_1_id, "", "", ""),
vec![],
&mut cid_state,
),
generation: 1,
};
let current_value = ValueRef::Stream {
cid: value_to_json_cid(&json!("non_exist_value")).unwrap().into(),
cid: value_aggregate_cid(
json!("non_exist_value"),
SecurityTetraplet::new(setter_1_id, "", "", ""),
vec![],
&mut cid_state,
),
generation: 0,
};
let expected_error = UncatchableError::TraceError {
@ -209,11 +278,13 @@ fn fold_early_exit() {
);
let actual_trace = trace_from_result(&last_peer_checker_result);
let expected_state = executed_state::scalar(json!({
let error_value = json!({
"error_code": 10000i64,
"instruction" : r#"call "error_trigger_id" ("error" "") [] "#,
"message": r#"Local service error, ret_code is 1, error message is '"failed result from fallible_call_service"'"#,
"peer_id": "error_trigger_id"}));
"peer_id": "error_trigger_id"
});
let expected_state = unused!(error_value.clone(), peer = last_peer_checker_id, args = [error_value]);
let bubbled_error_from_stream_1 = actual_trace.len() - 3;
assert_eq!(&actual_trace[bubbled_error_from_stream_1.into()], &expected_state);
@ -281,18 +352,18 @@ fn fold_par_early_exit() {
let unit_call_service_result = "result from unit_call_service";
let expected_trace = vec![
executed_state::scalar_string_array(vec!["a1", "a2"]),
executed_state::scalar_string_array(vec!["b1", "b2"]),
executed_state::scalar_string_array(vec!["c1", "c2"]),
executed_state::scalar_string_array(vec!["d1", "d2"]),
executed_state::stream_string("a1", 0),
executed_state::stream_string("a2", 1),
executed_state::stream_string("b1", 0),
executed_state::stream_string("b2", 1),
executed_state::stream_string("c1", 0),
executed_state::stream_string("c2", 1),
executed_state::stream_string("d1", 0),
executed_state::stream_string("d2", 1),
scalar!(json!(["a1", "a2"]), peer = variables_setter_id, args = ["stream_1"]),
scalar!(json!(["b1", "b2"]), peer = variables_setter_id, args = ["stream_2"]),
scalar!(json!(["c1", "c2"]), peer = variables_setter_id, args = ["stream_3"]),
scalar!(json!(["d1", "d2"]), peer = variables_setter_id, args = ["stream_4"]),
stream!("a1", 0, peer = stream_setter_id, args = ["a1"]),
stream!("a2", 1, peer = stream_setter_id, args = ["a2"]),
stream!("b1", 0, peer = stream_setter_id, args = ["b1"]),
stream!("b2", 1, peer = stream_setter_id, args = ["b2"]),
stream!("c1", 0, peer = stream_setter_id, args = ["c1"]),
stream!("c2", 1, peer = stream_setter_id, args = ["c2"]),
stream!("d1", 0, peer = stream_setter_id, args = ["d1"]),
stream!("d2", 1, peer = stream_setter_id, args = ["d2"]),
executed_state::par(69, 1),
executed_state::fold(vec![
executed_state::subtrace_lore(4, subtrace_desc(14, 34), subtrace_desc(48, 0)),
@ -315,19 +386,24 @@ fn fold_par_early_exit() {
executed_state::subtrace_lore(11, subtrace_desc(23, 2), subtrace_desc(25, 0)),
]),
executed_state::par(1, 0),
executed_state::scalar_string(unit_call_service_result),
executed_state::par(1, 0),
executed_state::scalar_string(unit_call_service_result),
unused!(unit_call_service_result, peer = fold_executor_id),
par(1, 0),
unused!(unit_call_service_result, peer = fold_executor_id),
executed_state::par(5, 0),
executed_state::fold(vec![
executed_state::subtrace_lore(10, subtrace_desc(27, 2), subtrace_desc(29, 0)),
executed_state::subtrace_lore(11, subtrace_desc(29, 2), subtrace_desc(31, 0)),
]),
executed_state::par(1, 0),
executed_state::scalar_string(unit_call_service_result),
executed_state::par(1, 0),
executed_state::scalar_string(unit_call_service_result),
executed_state::service_failed(1, "failed result from fallible_call_service"),
unused!(unit_call_service_result, peer = fold_executor_id),
par(1, 0),
unused!(unit_call_service_result, peer = fold_executor_id),
failed!(
1,
"failed result from fallible_call_service",
peer = error_trigger_id,
service = "error"
),
executed_state::par(15, 0),
executed_state::par(13, 1),
executed_state::fold(vec![
@ -337,5 +413,5 @@ fn fold_par_early_exit() {
];
let trace_len = expected_trace.len();
assert_eq!((*actual_trace)[0..trace_len], expected_trace);
assert_eq!(&(*actual_trace)[0..trace_len], expected_trace);
}

View File

@ -283,7 +283,7 @@ fn tetraplet_with_wasm_modules() {
let test_params = TestRunParameters::from_init_peer_id(ADMIN_PEER_PK);
let result = checked_call_vm!(vm, test_params, script, "", "");
let actual_trace = trace_from_result(&result);
let expected_state = executed_state::scalar_string("Ok");
let expected_state = scalar!("Ok");
assert_eq!(actual_trace[1.into()], expected_state)
}

View File

@ -42,8 +42,12 @@ fn ap_with_scalars() {
let actual_trace = trace_from_result(&result);
let expected_state = vec![
executed_state::scalar(json!({ "field": test_value })),
executed_state::scalar_string(test_value),
scalar!(
json!({ "field": test_value }),
peer = vm_1_peer_id,
args = ["scalar_1_result"]
),
unused!(test_value, peer = vm_2_peer_id, args = [test_value]),
];
assert_eq!(actual_trace, expected_state);
@ -81,7 +85,7 @@ fn ap_with_string_literal() {
]
}
)),
executed_state::scalar(json!([some_string])),
unused!(json!([some_string]), peer = vm_1_peer_id, args = [json!([some_string])]),
];
assert_eq!(actual_trace, expected_state);
@ -116,7 +120,7 @@ fn ap_with_bool_literal() {
}
]
})),
executed_state::scalar(json!([true])),
unused!(json!([true]), peer = vm_1_peer_id, args = [json!([true])]),
];
assert_eq!(actual_trace, expected_state);
@ -151,7 +155,7 @@ fn ap_with_number_literal() {
}
]
})),
executed_state::scalar(json!([100])),
unused!(json!([100]), peer = vm_1_peer_id, args = [json!([100])]),
];
assert_eq!(actual_trace, expected_state);
@ -186,7 +190,7 @@ fn ap_with_last_error() {
}
]
})),
executed_state::scalar(json!([null])),
unused!(json!([null]), peer = vm_1_peer_id, args = [json!([null])]),
];
assert_eq!(actual_trace, expected_state);
@ -209,7 +213,11 @@ fn ap_with_timestamp() {
let result = checked_call_vm!(vm_1, test_params.clone(), script, "", "");
let actual_trace = trace_from_result(&result);
let expected_state = vec![executed_state::scalar_number(test_params.timestamp)];
let expected_state = vec![unused!(
test_params.timestamp,
peer = vm_1_peer_id,
args = [test_params.timestamp]
)];
assert_eq!(actual_trace, expected_state);
}
@ -230,7 +238,7 @@ fn ap_with_ttl() {
let result = checked_call_vm!(vm_1, test_params.clone(), script, "", "");
let actual_trace = trace_from_result(&result);
let expected_state = vec![executed_state::scalar_number(test_params.ttl)];
let expected_state = vec![unused!(test_params.ttl, peer = vm_1_peer_id, args = [test_params.ttl])];
assert_eq!(actual_trace, expected_state);
}
@ -259,7 +267,11 @@ fn ap_with_dst_stream() {
let actual_trace = trace_from_result(&result);
let expected_state = vec![
executed_state::scalar(json!({ "field": test_value })),
scalar!(
json!({ "field": test_value }),
peer = vm_1_peer_id,
args = ["scalar_1_result"]
),
executed_state::ap(0),
executed_state::canon(json!({
"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "vm_2_peer_id", "service_id": ""},
@ -271,7 +283,11 @@ fn ap_with_dst_stream() {
}
]
})),
executed_state::scalar(json!([{ "field": test_value }])),
unused!(
json!([{ "field": test_value }]),
peer = vm_2_peer_id,
args = [json!([{ "field": test_value }])]
),
];
assert_eq!(actual_trace, expected_state);
@ -304,8 +320,15 @@ fn ap_canon_stream_with_lambda() {
let actual_trace = trace_from_result(&result);
let expected_state = vec![
executed_state::stream_number(0, 0),
executed_state::stream_number(1, 1),
stream!(0, 0, peer = vm_1_peer_id, args = [0]),
stream!(
1,
1,
peer = vm_1_peer_id,
service = service_name,
function = function_name,
args = [1]
),
executed_state::canon(
json!({"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "vm_1_peer_id", "service_id": ""},
"values": [{"result": 0, "tetraplet": {"function_name": "", "json_path": "", "peer_pk": "vm_1_peer_id", "service_id": ""}, "trace_pos": 0},
@ -324,7 +347,7 @@ fn ap_canon_stream_with_lambda() {
]
}
)),
executed_state::scalar(json!([1])),
unused!(json!([1]), peer = vm_1_peer_id, args = [json!([1])]),
];
assert_eq!(actual_trace, expected_state);
@ -364,8 +387,15 @@ fn ap_canon_stream() {
let actual_trace = trace_from_result(&result);
let expected_state = vec![
executed_state::stream_number(0, 0),
executed_state::stream_number(1, 1),
stream!(0, 0, peer = vm_1_peer_id, args = [0]),
stream!(
1,
1,
peer = vm_1_peer_id,
service = service_name,
function = function_name,
args = [1]
),
executed_state::canon(
json!({"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "vm_1_peer_id", "service_id": ""},
"values": [{"result": 0, "tetraplet": {"function_name": "", "json_path": "", "peer_pk": "vm_1_peer_id", "service_id": ""}, "trace_pos": 0},
@ -384,7 +414,7 @@ fn ap_canon_stream() {
]
}
)),
executed_state::scalar(json!([[0, 1]])),
unused!(json!([[0, 1]]), peer = vm_1_peer_id, args = [json!([[0, 1]])]),
];
assert_eq!(actual_trace, expected_state);

View File

@ -14,7 +14,8 @@
* limitations under the License.
*/
use air::UncatchableError;
use air::{ExecutionCidState, UncatchableError};
use air_interpreter_data::{ExecutionTrace, ServiceResultAggregate};
use air_test_utils::prelude::*;
// Check that %init_peer_id% alias works correctly (by comparing result with it and explicit peer id).
@ -34,7 +35,12 @@ fn current_peer_id_call() {
let result = checked_call_vm!(vm, test_params, script, "", "");
let actual_trace = trace_from_result(&result);
let expected_trace = vec![executed_state::scalar_string("result from unit_call_service")];
let expected_trace = vec![scalar!(
"result from unit_call_service",
peer = vm_peer_id,
service = service_id,
function = function_name
)];
assert_eq!(actual_trace, expected_trace);
assert!(result.next_peer_pks.is_empty());
@ -61,7 +67,11 @@ fn call_with_timestamp() {
let result = checked_call_vm!(vm, test_params.clone(), script, "", "");
let actual_trace = trace_from_result(&result);
let expected_trace = vec![executed_state::scalar_number(test_params.timestamp)];
let expected_trace = vec![scalar!(
test_params.timestamp,
peer = vm_peer_id,
args = [test_params.timestamp]
)];
assert_eq!(actual_trace, expected_trace);
}
@ -77,7 +87,7 @@ fn call_with_ttl() {
let result = checked_call_vm!(vm, test_params.clone(), script, "", "");
let actual_trace = trace_from_result(&result);
let expected_trace = vec![executed_state::scalar_number(test_params.ttl)];
let expected_trace = vec![scalar!(test_params.ttl, peer = vm_peer_id, args = [test_params.ttl])];
assert_eq!(actual_trace, expected_trace);
}
@ -166,8 +176,48 @@ fn string_parameters() {
let result = checked_call_vm!(vm, <_>::default(), script, "", result.data);
let actual_trace = trace_from_result(&result);
let expected_state = executed_state::scalar_string("arg1");
let expected_state = scalar!(
"arg1",
peer = vm_peer_id,
service = service_id,
function = function_name,
args = ["arg1", "arg2", "arg3_value"]
);
assert_eq!(actual_trace.len(), 2);
assert_eq!(actual_trace[1.into()], expected_state);
}
#[test]
fn test_invalid_call_service_failed() {
let peer_id = "init_peer_id";
let mut cid_state = ExecutionCidState::new();
// Craft an artificial incorrect error result
let value = json!("error");
let value_cid = cid_state.value_tracker.record_value(value).unwrap();
let tetraplet = SecurityTetraplet::literal_tetraplet(peer_id);
let tetraplet_cid = cid_state.tetraplet_tracker.record_value(tetraplet).unwrap();
let service_result_agg = ServiceResultAggregate {
value_cid,
argument_hash: "0000000000000".into(),
tetraplet_cid,
};
let service_result_agg_cid = cid_state
.service_result_agg_tracker
.record_value(service_result_agg)
.unwrap();
let trace = ExecutionTrace::from(vec![ExecutedState::Call(CallResult::Failed(service_result_agg_cid))]);
let data = raw_data_from_trace(trace, cid_state);
let mut vm = create_avm(unit_call_service(), peer_id);
let air = format!(r#"(call "{peer_id}" ("" "") [] var)"#);
let res = vm.call(&air, vec![], data, TestRunParameters::default()).unwrap();
assert_eq!(res.ret_code, 20011);
assert_eq!(
res.error_message,
"failed to deserialize to CallServiceFailed: invalid type: string \"error\", expected struct CallServiceFailed",
);
}

View File

@ -109,16 +109,16 @@ fn canon_fixes_stream_correct() {
executed_state::par(1, 3),
executed_state::request_sent_by(peer_id_2),
executed_state::par(1, 1),
executed_state::stream_number(2, 0),
executed_state::stream_number(3, 1),
executed_state::scalar_number(4),
stream!(2, 0, peer = peer_id_2, args = [2]),
stream!(3, 1, peer = peer_id_3, args = [3]),
unused!(4, peer = peer_id_4, args = [4]),
executed_state::canon(
json!({"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "peer_id_3", "service_id": ""},
"values": [{"result": 2, "tetraplet": {"function_name": "", "json_path": "", "peer_pk": "peer_id_2", "service_id": ""}, "trace_pos": 3},
{"result": 3, "tetraplet": {"function_name": "", "json_path": "", "peer_pk": "peer_id_3", "service_id": ""}, "trace_pos": 4}]}),
),
executed_state::par(1, 1),
executed_state::scalar(json!([2, 3])),
unused!(json!([2, 3]), peer = peer_id_3, args = [json!([2, 3])]),
executed_state::request_sent_by(peer_id_3),
];
assert_eq!(actual_vm_3_result_2_trace, expected_vm_3_result_2_trace);
@ -127,19 +127,19 @@ fn canon_fixes_stream_correct() {
let vm_1_result_2_trace = trace_from_result(&vm_1_result_2);
let expected_vm_1_result_2_trace = vec![
executed_state::par(1, 3),
executed_state::stream_number(1, 0),
stream!(1, 0, peer = peer_id_1, args = [1]),
executed_state::par(1, 1),
executed_state::stream_number(2, 1),
executed_state::stream_number(3, 2),
executed_state::scalar_number(4),
stream!(2, 1, peer = peer_id_2, args = [2]),
stream!(3, 2, peer = peer_id_3, args = [3]),
unused!(4, peer = peer_id_4, args = [4]),
executed_state::canon(
json!({"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "peer_id_3", "service_id": ""},
"values": [{"result": 2, "tetraplet": {"function_name": "", "json_path": "", "peer_pk": "peer_id_2", "service_id": ""}, "trace_pos": 3},
{"result": 3, "tetraplet": {"function_name": "", "json_path": "", "peer_pk": "peer_id_3", "service_id": ""}, "trace_pos": 4}]}),
),
executed_state::par(1, 1),
executed_state::scalar(json!([2, 3])),
executed_state::scalar(json!([2, 3])),
unused!(json!([2, 3]), peer = peer_id_3, args = [json!([2, 3])]),
unused!(json!([2, 3]), peer = peer_id_1, args = [json!([2, 3])]),
];
assert_eq!(vm_1_result_2_trace.deref(), expected_vm_1_result_2_trace);
}
@ -248,7 +248,7 @@ fn canon_empty_stream() {
executed_state::canon(
json!({"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "peer_id_1", "service_id": ""}, "values": []}),
),
executed_state::scalar(json!([])),
unused!(json!([]), peer = peer_id_1, args = [json!([])]),
];
assert_eq!(actual_trace, expected_trace);
@ -258,7 +258,7 @@ fn canon_empty_stream() {
executed_state::canon(
json!({"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "peer_id_1", "service_id": ""}, "values": []} ),
),
executed_state::scalar(json!([])),
unused!(json!([]), peer = peer_id_1, args = [json!([])]),
];
assert_eq!(actual_trace, expected_trace);
}
@ -315,11 +315,11 @@ fn canon_over_later_defined_stream() {
let expected_trace = vec![
executed_state::par(1, 2),
executed_state::stream_number(1, 0),
stream!(1, 0, peer = vm_peer_id_2, args = [1]),
executed_state::canon(
json!({"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "vm_peer_id_1", "service_id": ""},"values": []}),
),
executed_state::scalar(json!([])),
unused!(json!([]), peer = vm_peer_id_3, args = [json!([])]),
];
assert_eq!(actual_trace, expected_trace);
}

View File

@ -16,8 +16,11 @@
use air::PreparationError;
use air::ToErrorCode;
use air_interpreter_data::ExecutionTrace;
use air_test_utils::prelude::*;
use pretty_assertions::assert_eq;
#[test]
fn lfold() {
let mut vm = create_avm(echo_call_service(), "A");
@ -41,13 +44,14 @@ fn lfold() {
let result = checked_call_vm!(vm, <_>::default(), lfold, "", result.data);
let actual_trace = trace_from_result(&result);
let expected_state = executed_state::scalar_string_array(vec!["1", "2", "3", "4", "5"]);
let expected_state = scalar!(json!(["1", "2", "3", "4", "5"]), peer = "set_variable");
assert_eq!(actual_trace.len(), 6);
assert_eq!(actual_trace[0.into()], expected_state);
for i in 1..=5 {
let expected_state = executed_state::stream_string(format!("{i}"), i as u32 - 1);
let val = format!("{i}");
let expected_state = stream!(val.as_str(), i as u32 - 1, peer = "A", args = [val.as_str()]);
assert_eq!(actual_trace[i.into()], expected_state);
}
}
@ -77,11 +81,12 @@ fn rfold() {
let actual_trace = trace_from_result(&result);
assert_eq!(actual_trace.len(), 6);
let expected_state = executed_state::scalar_string_array(vec!["1", "2", "3", "4", "5"]);
let expected_state = scalar!(json!(["1", "2", "3", "4", "5"]), peer = "set_variable");
assert_eq!(actual_trace[0.into()], expected_state);
for i in 1..=5 {
let expected_state = executed_state::stream_string(format!("{}", 6 - i), i as u32 - 1);
let val = format!("{}", 6 - i);
let expected_state = stream!(val.as_str(), i as u32 - 1, peer = "A", args = [val.as_str()]);
assert_eq!(actual_trace[i.into()], expected_state);
}
}
@ -119,14 +124,15 @@ fn inner_fold() {
let actual_trace = trace_from_result(&result);
assert_eq!(actual_trace.len(), 27);
let expected_state = executed_state::scalar_string_array(vec!["1", "2", "3", "4", "5"]);
let expected_state = scalar!(json!(["1", "2", "3", "4", "5"]), peer = "set_variable");
assert_eq!(actual_trace[0.into()], expected_state);
assert_eq!(actual_trace[1.into()], expected_state);
for i in 1..=5 {
for j in 1..=5 {
let state_id = 1 + 5 * (i - 1) + j;
let expected_state = executed_state::stream_string(i.to_string(), state_id as u32 - 2);
let val = i.to_string();
let expected_state = stream!(val.as_str(), state_id as u32 - 2, peer = "A", args = [val]);
assert_eq!(actual_trace[state_id.into()], expected_state);
}
}
@ -184,7 +190,7 @@ fn empty_iterable_fold() {
let result = checked_call_vm!(vm, <_>::default(), empty_fold, "", result.data);
let actual_trace = trace_from_result(&result);
let expected_state = executed_state::scalar(json!([]));
let expected_state = scalar!(json!([]), peer = "set_variable");
assert_eq!(actual_trace.len(), 1);
assert_eq!(actual_trace[0.into()], expected_state);
@ -228,7 +234,7 @@ fn empty_fold_json_path() {
let result = checked_call_vm!(vm, <_>::default(), empty_fold, "", result.data);
let actual_trace = trace_from_result(&result);
let expected_trace = vec![executed_state::scalar(json!({ "messages": [] }))];
let expected_trace = vec![scalar!(json!({ "messages": [] }), peer = "set_variable")];
assert_eq!(actual_trace, expected_trace);
}
@ -283,13 +289,14 @@ fn lambda() {
let result = checked_call_vm!(vm, <_>::default(), script, "", result.data);
let actual_trace = trace_from_result(&result);
let expected_state = executed_state::scalar(json!({ "array": ["1", "2", "3", "4", "5"] }));
let expected_state = scalar!(json!({ "array": ["1", "2", "3", "4", "5"] }), peer = "set_variable");
assert_eq!(actual_trace.len(), 6);
assert_eq!(actual_trace[0.into()], expected_state);
for i in 1..=5 {
let expected_state = executed_state::stream_string(format!("{i}"), i as u32 - 1);
let val = format!("{i}");
let expected_state = stream!(val.as_str(), i as u32 - 1, peer = "A", args = [val]);
assert_eq!(actual_trace[i.into()], expected_state);
}
}
@ -339,20 +346,20 @@ fn shadowing() {
let result = checked_call_vm!(vm_b, <_>::default(), script, "", result.data);
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
scalar_string_array(vec!["1", "2"]),
scalar_string_array(vec!["1", "2"]),
scalar_string("1"),
scalar_string("1"),
scalar_string("1"),
scalar_string("1"),
let expected_trace = ExecutionTrace::from(vec![
scalar!(json!(["1", "2"]), peer = "set_variable"),
scalar!(json!(["1", "2"]), peer = "set_variable"),
scalar!("1", peer = "A", args = ["1"]),
unused!("1", peer = "B", args = ["1"]),
scalar!("1", peer = "A", args = ["1"]),
unused!("1", peer = "B", args = ["1"]),
par(1, 1),
scalar_string("1"),
scalar_string("1"),
scalar_string("2"),
scalar_string("2"),
scalar!("1", peer = "A", args = ["1"]),
unused!("1", peer = "B", args = ["1"]),
scalar!("2", peer = "A", args = ["2"]),
unused!("2", peer = "B", args = ["2"]),
request_sent_by("B"),
];
]);
assert_eq!(actual_trace, expected_trace);
}
@ -406,19 +413,19 @@ fn shadowing_scope() {
let result = execute_script(String::from(variable_shadowing_script)).unwrap();
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
scalar_string_array(vec!["1", "2"]),
scalar_string_array(vec!["1", "2"]),
scalar_string("value"),
scalar_string("1"),
scalar_string("1"),
scalar_string("1"),
scalar_string("1"),
scalar_string("value"),
scalar_string("value"),
scalar_string("2"),
let expected_trace = ExecutionTrace::from(vec![
scalar!(vec!["1", "2"], peer = "set_variable"),
scalar!(vec!["1", "2"], peer = "set_variable"),
scalar!("value", peer = "A", args = ["value"]),
scalar!("1", peer = "A", args = ["1"]),
unused!("1", peer = "B", args = ["1"]),
scalar!("1", peer = "A", args = ["1"]),
unused!("1", peer = "B", args = ["1"]),
unused!("value", peer = "A", args = ["value"]),
scalar!("value", peer = "A", args = ["value"]),
scalar!("2", peer = "A", args = ["2"]),
request_sent_by("A"),
];
]);
assert_eq!(actual_trace, expected_trace);
}
@ -464,13 +471,13 @@ fn fold_stream_seq_next_never_completes() {
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
executed_state::stream_number(1, 0),
stream!(1, 0, peer = vm_peer_id),
executed_state::fold(vec![subtrace_lore(
0,
SubTraceDesc::new(2.into(), 1),
SubTraceDesc::new(3.into(), 0),
)]),
executed_state::stream_number(1, 0),
stream!(1, 0, peer = vm_peer_id, args = [1]),
];
assert_eq!(actual_trace, expected_trace);
}
@ -500,13 +507,13 @@ fn fold_stream_seq_next_never_completes_with_never() {
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
executed_state::stream_number(1, 0),
stream!(1, 0, peer = vm_peer_id),
executed_state::fold(vec![subtrace_lore(
0,
SubTraceDesc::new(2.into(), 1),
SubTraceDesc::new(3.into(), 0),
)]),
executed_state::stream_number(1, 0),
stream!(1, 0, peer = vm_peer_id, args = [1]),
];
assert_eq!(actual_trace, expected_trace);
}
@ -536,14 +543,14 @@ fn fold_stream_seq_next_completes_with_null() {
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
executed_state::stream_number(1, 0),
stream!(1, 0, peer = vm_peer_id),
executed_state::fold(vec![subtrace_lore(
0,
SubTraceDesc::new(2.into(), 1),
SubTraceDesc::new(3.into(), 0),
)]),
executed_state::stream_number(1, 0),
executed_state::scalar_number(1),
stream!(1, 0, peer = vm_peer_id, args = [1]),
unused!(1, peer = vm_peer_id),
];
assert_eq!(actual_trace, expected_trace);
}
@ -576,17 +583,17 @@ fn fold_scalar_seq_next_completes_with_null() {
let result = checked_call_vm!(vm, <_>::default(), &script, "", "");
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
executed_state::scalar(service_result.clone()),
let expected_trace = ExecutionTrace::from(vec![
scalar!(service_result.clone(), peer = vm_peer_id),
executed_state::par(1, 2),
executed_state::stream(service_result.clone(), 0),
stream!(service_result.clone(), 0, peer = vm_peer_id, args = [1]),
executed_state::par(1, 0),
executed_state::stream(service_result.clone(), 0),
stream!(service_result.clone(), 0, peer = vm_peer_id, args = [2]),
executed_state::canon(
json!({"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "vm_peer_id", "service_id": ""}, "values": []}),
),
executed_state::scalar(service_result),
];
unused!(service_result, peer = vm_peer_id, args = [json!([])]),
]);
assert_eq!(actual_trace, expected_trace);
}
@ -619,7 +626,7 @@ fn fold_scalar_seq_next_not_completes_with_never() {
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
executed_state::scalar(service_result),
scalar!(service_result, peer = vm_peer_id),
executed_state::par(1, 2),
executed_state::request_sent_by(vm_peer_id),
executed_state::par(1, 0),
@ -662,10 +669,10 @@ fn fold_stream_seq_next_saves_call_result() {
subtrace_lore(0, SubTraceDesc::new(3.into(), 1), SubTraceDesc::new(6.into(), 0)),
subtrace_lore(1, SubTraceDesc::new(4.into(), 1), SubTraceDesc::new(5.into(), 1)),
]),
executed_state::stream_number(1, 0),
executed_state::stream_number(2, 1),
executed_state::stream_number(2, 2),
executed_state::scalar_number(0),
stream!(1, 0, peer = vm_peer_id, args = [1]),
stream!(2, 1, peer = vm_peer_id, args = [2]),
stream!(2, 2, peer = vm_peer_id, args = [2]),
unused!(0, peer = vm_peer_id, args = [0]),
];
assert_eq!(actual_trace, expected_trace);
}
@ -715,7 +722,7 @@ fn fold_par_next_completes() {
subtrace_lore(2, SubTraceDesc::new(8.into(), 2), SubTraceDesc::new(10.into(), 0)),
]),
executed_state::par(1, 4),
executed_state::stream_number(1, 0),
stream!(1, 0, peer = vm_2_peer_id),
executed_state::par(1, 2),
executed_state::request_sent_by(vm_1_peer_id),
executed_state::par(1, 0),
@ -738,7 +745,7 @@ fn fold_par_next_completes() {
executed_state::par(1, 4),
executed_state::request_sent_by(vm_1_peer_id),
executed_state::par(1, 2),
executed_state::stream_number(1, 0),
stream!(1, 0, peer = vm_3_peer_id),
executed_state::par(1, 0),
executed_state::request_sent_by(vm_1_peer_id),
executed_state::request_sent_by(vm_3_peer_id),
@ -761,7 +768,7 @@ fn fold_par_next_completes() {
executed_state::par(1, 2),
executed_state::request_sent_by(vm_1_peer_id),
executed_state::par(1, 0),
executed_state::stream_number(1, 0),
stream!(1, 0, peer = vm_4_peer_id),
executed_state::request_sent_by(vm_4_peer_id),
];
assert_eq!(actual_trace, expected_trace);

View File

@ -43,7 +43,13 @@ fn match_equal() {
let result = checked_call_vm!(vm, <_>::default(), script, "", result.data);
let actual_trace = trace_from_result(&result);
let expected_state = executed_state::scalar_string("result_1");
let expected_state = scalar!(
"result_1",
peer = local_peer_id,
service = "service_id_2",
function = "local_fn_name",
args = ["result_1"]
);
assert_eq!(actual_trace.len(), 3);
assert_eq!(actual_trace[2.into()], expected_state);
@ -75,7 +81,13 @@ fn match_not_equal() {
let result = checked_call_vm!(vm, <_>::default(), script, "", result.data);
let actual_trace = trace_from_result(&result);
let expected_state = executed_state::scalar_string("result_2");
let expected_state = scalar!(
"result_2",
peer = local_peer_id,
service = "service_id_2",
function = "local_fn_name",
args = ["result_2"]
);
assert_eq!(actual_trace.len(), 3);
assert_eq!(actual_trace[2.into()], expected_state);
@ -104,7 +116,13 @@ fn match_with_string() {
let result = checked_call_vm!(vm, <_>::default(), script, "", result.data);
let actual_trace = trace_from_result(&result);
let expected_state = executed_state::scalar_string("result_1");
let expected_state = scalar!(
"result_1",
peer = local_peer_id,
service = "service_id_2",
function = "local_fn_name",
args = ["result_1"]
);
assert_eq!(actual_trace.len(), 2);
assert_eq!(actual_trace[1.into()], expected_state);
@ -134,7 +152,13 @@ fn match_with_init_peer_id() {
let result = checked_call_vm!(vm, test_params, script, "", result.data);
let actual_trace = trace_from_result(&result);
let expected_executed_call_result = executed_state::scalar_string("result_1");
let expected_executed_call_result = scalar!(
"result_1",
peer = local_peer_id,
service = "service_id_2",
function = "local_fn_name",
args = ["result_1"]
);
assert_eq!(actual_trace.len(), 2);
assert_eq!(actual_trace[1.into()], expected_executed_call_result);
@ -165,7 +189,13 @@ fn match_with_timestamp() {
let result = checked_call_vm!(vm, test_params, script, "", result.data);
let actual_trace = trace_from_result(&result);
let expected_executed_call_result = executed_state::scalar_string("result_1");
let expected_executed_call_result = scalar!(
"result_1",
peer = local_peer_id,
service = "service_id_2",
function = "local_fn_name",
args = ["result_1"]
);
assert_eq!(actual_trace.len(), 2);
assert_eq!(actual_trace[1.into()], expected_executed_call_result);
@ -196,7 +226,13 @@ fn match_with_ttl() {
let result = checked_call_vm!(vm, test_params, script, "", result.data);
let actual_trace = trace_from_result(&result);
let expected_executed_call_result = executed_state::scalar_string("result_1");
let expected_executed_call_result = scalar!(
"result_1",
peer = local_peer_id,
service = "service_id_2",
function = "local_fn_name",
args = ["result_1"]
);
assert_eq!(actual_trace.len(), 2);
assert_eq!(actual_trace[1.into()], expected_executed_call_result);
@ -318,5 +354,14 @@ fn issue_165() {
let echo_result = checked_call_vm!(echo_peer, <_>::default(), &script, "", setter_result.data);
let trace = trace_from_result(&echo_result);
assert_eq!(trace.last().unwrap(), &executed_state::scalar(json!(1)));
assert_eq!(
trace.last().unwrap(),
&unused!(
1,
peer = echo_peer_id,
service = "callbackSrv",
function = "response",
args = [1]
)
);
}

View File

@ -43,7 +43,13 @@ fn mismatch_equal() {
let result = checked_call_vm!(vm, <_>::default(), script, "", result.data);
let actual_trace = trace_from_result(&result);
let expected_state = executed_state::scalar_string("result_2");
let expected_state = scalar!(
"result_2",
peer = local_peer_id,
service = "service_id_2",
function = "local_fn_name",
args = ["result_2"]
);
assert_eq!(actual_trace.len(), 3);
assert_eq!(actual_trace[2.into()], expected_state);
@ -75,7 +81,13 @@ fn mismatch_not_equal() {
let result = checked_call_vm!(vm, <_>::default(), script, "", result.data);
let actual_trace = trace_from_result(&result);
let expected_state = executed_state::scalar_string("result_1");
let expected_state = scalar!(
"result_1",
peer = local_peer_id,
service = "service_id_2",
function = "local_fn_name",
args = ["result_1"]
);
assert_eq!(actual_trace.len(), 3);
assert_eq!(actual_trace[2.into()], expected_state);
@ -104,7 +116,13 @@ fn mismatch_with_string() {
let result = checked_call_vm!(vm, <_>::default(), script, "", result.data);
let actual_trace = trace_from_result(&result);
let expected_state = executed_state::scalar_string("result_2");
let expected_state = scalar!(
"result_2",
peer = local_peer_id,
service = "service_id_2",
function = "local_fn_name",
args = ["result_2"]
);
assert_eq!(actual_trace.len(), 2);
assert_eq!(actual_trace[1.into()], expected_state);

View File

@ -14,9 +14,12 @@
* limitations under the License.
*/
use air_interpreter_data::ExecutionTrace;
use air_parser::AirPos;
use air_test_utils::prelude::*;
use pretty_assertions::assert_eq;
#[test]
#[ignore]
fn new_with_global_streams_seq() {
@ -73,18 +76,18 @@ fn new_with_global_streams_seq() {
let actual_trace = trace_from_result(&vm_2_result);
let expected_trace = vec![
executed_state::stream_number(1, 0),
executed_state::stream_number(2, 0),
stream!(1, 0, peer = set_variable_peer_id, args = ["1"]),
stream!(2, 0, peer = set_variable_peer_id, args = ["2"]),
executed_state::fold(vec![
executed_state::subtrace_lore(0, SubTraceDesc::new(3.into(), 1), SubTraceDesc::new(7.into(), 2)),
executed_state::subtrace_lore(1, SubTraceDesc::new(4.into(), 1), SubTraceDesc::new(5.into(), 2)),
]),
executed_state::stream_number(1, 0),
executed_state::stream_number(2, 0),
executed_state::scalar(json!([2])),
executed_state::scalar(json!([1, 2])),
executed_state::scalar(json!([1])),
executed_state::scalar(json!([1, 2])),
stream!(1, 0, peer = local_vm_peer_id_1, args = [1]),
stream!(2, 0, peer = local_vm_peer_id_1, args = [1]),
scalar!(json!([2]), peer = local_vm_peer_id_1, args = [json!([2])]),
scalar!(json!([1, 2]), peer = local_vm_peer_id_1, args = [json!([1, 2])]),
scalar!(json!([1]), peer = local_vm_peer_id_1, args = [json!([1])]),
scalar!(json!([1, 2]), peer = local_vm_peer_id_1, args = [json!([1, 2])]),
];
assert_eq!(actual_trace, expected_trace);
@ -119,16 +122,16 @@ fn several_restrictions() {
let result = checked_call_vm!(vm, <_>::default(), script, "", "");
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
executed_state::stream_string("test", 0),
let expected_trace = ExecutionTrace::from(vec![
stream!("test", 0, peer = vm_peer_id, args = ["test"]),
executed_state::canon(json!({
"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "vm_peer_id", "service_id": ""},
"values": [
]
})),
executed_state::scalar(json!([])),
];
unused!(json!([]), peer = vm_peer_id, args = [json!([])]),
]);
assert_eq!(actual_trace, expected_trace);
}
@ -179,7 +182,7 @@ fn check_influence_to_not_restricted() {
let result = checked_call_vm!(vm, <_>::default(), script, "", "");
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
let expected_trace = ExecutionTrace::from(vec![
executed_state::ap(0),
executed_state::ap(0),
executed_state::ap(0),
@ -195,7 +198,13 @@ fn check_influence_to_not_restricted() {
]
}
)),
executed_state::scalar(json!(["more"])),
scalar!(
json!(["more"]),
peer = vm_peer_id,
service = "op",
function = "identity",
args = [json!(["more"])]
),
executed_state::canon(json!(
{
"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "vm_peer_id", "service_id": ""},
@ -208,7 +217,13 @@ fn check_influence_to_not_restricted() {
]
}
)),
executed_state::scalar(json!(["push more"])),
unused!(
json!(["push more"]),
peer = vm_peer_id,
service = "callbackSrv",
function = "response",
args = [json!(["push more"])]
),
executed_state::canon(json!({
"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "vm_peer_id", "service_id": ""},
"values": [
@ -219,15 +234,33 @@ fn check_influence_to_not_restricted() {
}
]
})),
executed_state::scalar(json!(["push more"])),
unused!(
json!(["push more"]),
peer = vm_peer_id,
service = "callbackSrv",
function = "response",
args = [json!(["push more"])]
),
executed_state::canon(json!({
"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "vm_peer_id", "service_id": ""},
"values": [
]
})),
executed_state::scalar(json!([])),
executed_state::scalar(json!(["more"])),
];
unused!(
json!([]),
peer = vm_peer_id,
service = "callbackSrv",
function = "response",
args = [json!([])]
),
unused!(
json!(["more"]),
peer = vm_peer_id,
service = "callbackSrv",
function = "response",
args = [json!(["more"])]
),
]);
assert_eq!(actual_trace, expected_trace);
}
@ -264,7 +297,7 @@ fn new_in_fold_with_ap() {
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
executed_state::scalar(json!([1, 2, 3, 4, 5])),
scalar!(json!([1, 2, 3, 4, 5]), peer = set_variable_peer_id),
executed_state::ap(0),
executed_state::canon(json!({
"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "vm_peer_id", "service_id": ""},
@ -276,7 +309,7 @@ fn new_in_fold_with_ap() {
}
]
})),
executed_state::scalar_string_array(vec!["none"]),
scalar!(json!(["none"]), peer = vm_peer_id, args = [json!(["none"])]),
executed_state::ap(0),
executed_state::canon(json!({
"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "vm_peer_id", "service_id": ""},
@ -288,7 +321,7 @@ fn new_in_fold_with_ap() {
}
]
})),
executed_state::scalar_string_array(vec!["none"]),
scalar!(json!(["none"]), peer = vm_peer_id, args = [json!(["none"])]),
executed_state::ap(0),
executed_state::canon(json!({
"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "vm_peer_id", "service_id": ""},
@ -300,7 +333,7 @@ fn new_in_fold_with_ap() {
}
]
})),
executed_state::scalar_string_array(vec!["none"]),
scalar!(json!(["none"]), peer = vm_peer_id, args = [json!(["none"])]),
executed_state::ap(0),
executed_state::canon(json!({
"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "vm_peer_id", "service_id": ""},
@ -312,7 +345,7 @@ fn new_in_fold_with_ap() {
}
]
})),
executed_state::scalar_string_array(vec!["none"]),
scalar!(json!(["none"]), peer = vm_peer_id, args = [json!(["none"])]),
executed_state::ap(0),
executed_state::canon(json!({
"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "vm_peer_id", "service_id": ""},
@ -324,7 +357,7 @@ fn new_in_fold_with_ap() {
}
]
})),
executed_state::scalar_string_array(vec!["none"]),
scalar!(json!(["none"]), peer = vm_peer_id, args = [json!(["none"])]),
];
assert_eq!(actual_trace, expected_trace);
@ -367,9 +400,15 @@ fn new_with_streams_with_errors() {
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
executed_state::stream_number(1, 0),
executed_state::stream_number(2, 0),
executed_state::service_failed(1, "failed result from fallible_call_service"),
stream!(1, 0, peer = local_peer_id, args = [1]),
stream!(2, 0, peer = local_peer_id, args = [2]),
failed!(
1,
"failed result from fallible_call_service",
peer = fallible_peer_id,
service = "service_id_1",
function = "local_fn_name"
),
];
assert_eq!(actual_trace, expected_trace);
@ -438,14 +477,15 @@ fn new_with_scalars_with_errors() {
let result = checked_call_vm!(variable_receiver_vm, <_>::default(), &script, "", result.data);
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
executed_state::scalar_number(1),
executed_state::scalar_number(2),
executed_state::scalar_number(2),
executed_state::service_failed(1, r#"failed result from fallible_call_service"#),
executed_state::scalar_number(1),
executed_state::scalar_number(1),
];
let msg = r#"failed result from fallible_call_service"#;
let expected_trace = ExecutionTrace::from(vec![
scalar!(1, peer = set_variable_peer_id, args = ["global"]),
scalar!(2, peer = set_variable_peer_id, args = ["scoped"]),
unused!(2, peer = variable_receiver_peer_id, args = [2]),
failed!(1, msg, peer = fallible_peer_id, service = fallible_service_id),
unused!(1, peer = variable_receiver_peer_id, args = [1]),
unused!(1, peer = variable_receiver_peer_id, args = [1]),
]);
assert_eq!(actual_trace, expected_trace);
}
@ -483,10 +523,10 @@ fn new_with_global_scalars() {
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
executed_state::scalar_number(1),
executed_state::scalar_number(2),
executed_state::scalar_number(2),
executed_state::scalar_number(1),
scalar!(1, peer = set_variable_peer_id, args = ["global"]),
scalar!(2, peer = set_variable_peer_id, args = ["scoped"]),
unused!(2, peer = variable_receiver_peer_id, args = [2]),
unused!(1, peer = variable_receiver_peer_id, args = [1]),
];
assert_eq!(actual_trace, expected_trace);
}
@ -563,24 +603,24 @@ fn new_with_scalars_in_lfold_with_outside_next() {
let result = checked_call_vm!(test_vm, <_>::default(), &script, "", "");
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
executed_state::scalar(json!([1, 2, 3])),
executed_state::scalar_number(0),
executed_state::scalar_number(0),
executed_state::scalar_number(10),
executed_state::scalar_number(10),
executed_state::scalar_number(1),
executed_state::scalar_number(1),
executed_state::scalar_number(11),
executed_state::scalar_number(11),
executed_state::scalar_number(2),
executed_state::scalar_number(2),
executed_state::scalar_number(12),
executed_state::scalar_number(12),
executed_state::scalar_number(2),
executed_state::scalar_number(1),
executed_state::scalar_number(0),
];
let expected_trace = ExecutionTrace::from(vec![
scalar!(json!([1, 2, 3]), peer = test_peer_id, args = [GET_ITERABLE_ACTION_NAME]),
scalar!(0, peer = test_peer_id, args = [json!(OUTSIDE_ACTION_NAME)]),
unused!(0, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(0)]),
scalar!(10, peer = test_peer_id, args = [INSIDE_ACTION_NAME]),
unused!(10, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(10)]),
scalar!(1, peer = test_peer_id, args = [json!(OUTSIDE_ACTION_NAME)]),
unused!(1, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(1)]),
scalar!(11, peer = test_peer_id, args = [INSIDE_ACTION_NAME]),
unused!(11, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(11)]),
scalar!(2, peer = test_peer_id, args = [json!(OUTSIDE_ACTION_NAME)]),
unused!(2, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(2)]),
scalar!(12, peer = test_peer_id, args = [INSIDE_ACTION_NAME]),
unused!(12, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(12)]),
unused!(2, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(2)]),
unused!(1, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(1)]),
unused!(0, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(0)]),
]);
assert_eq!(actual_trace, expected_trace);
}
@ -620,24 +660,24 @@ fn new_with_scalars_in_rfold_with_outside_next() {
let result = checked_call_vm!(test_vm, <_>::default(), &script, "", "");
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
executed_state::scalar(json!([1, 2, 3])),
executed_state::scalar_number(0),
executed_state::scalar_number(0),
executed_state::scalar_number(10),
executed_state::scalar_number(10),
executed_state::scalar_number(0),
executed_state::scalar_number(1),
executed_state::scalar_number(1),
executed_state::scalar_number(11),
executed_state::scalar_number(11),
executed_state::scalar_number(1),
executed_state::scalar_number(2),
executed_state::scalar_number(2),
executed_state::scalar_number(12),
executed_state::scalar_number(12),
executed_state::scalar_number(2),
];
let expected_trace = ExecutionTrace::from(vec![
scalar!(json!([1, 2, 3]), peer = test_peer_id, args = [GET_ITERABLE_ACTION_NAME]),
scalar!(0, peer = test_peer_id, args = [OUTSIDE_ACTION_NAME]),
unused!(0, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(0)]),
scalar!(10, peer = test_peer_id, args = [json!(INSIDE_ACTION_NAME)]),
unused!(10, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(10)]),
unused!(0, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(0)]),
scalar!(1, peer = test_peer_id, args = [OUTSIDE_ACTION_NAME]),
unused!(1, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(1)]),
scalar!(11, peer = test_peer_id, args = [json!(INSIDE_ACTION_NAME)]),
unused!(11, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(11)]),
unused!(1, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(1)]),
scalar!(2, peer = test_peer_id, args = [OUTSIDE_ACTION_NAME]),
unused!(2, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(2)]),
scalar!(12, peer = test_peer_id, args = [json!(INSIDE_ACTION_NAME)]),
unused!(12, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(12)]),
unused!(2, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(2)]),
]);
assert_eq!(actual_trace, expected_trace);
}
@ -680,26 +720,26 @@ fn new_with_scalars_in_fold_with_inside_next() {
let result = checked_call_vm!(test_vm, <_>::default(), &script, "", "");
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
executed_state::scalar(json!([1, 2, 3])),
executed_state::scalar_number(0),
executed_state::scalar_number(0),
executed_state::scalar_number(10),
executed_state::scalar_number(10),
executed_state::scalar_number(1),
executed_state::scalar_number(1),
executed_state::scalar_number(11),
executed_state::scalar_number(11),
executed_state::scalar_number(2),
executed_state::scalar_number(2),
executed_state::scalar_number(12),
executed_state::scalar_number(12),
executed_state::scalar_number(12),
executed_state::scalar_number(2),
executed_state::scalar_number(11),
executed_state::scalar_number(1),
executed_state::scalar_number(10),
executed_state::scalar_number(0),
];
let expected_trace = ExecutionTrace::from(vec![
scalar!(json!([1, 2, 3]), peer = test_peer_id, args = [GET_ITERABLE_ACTION_NAME]),
scalar!(0, peer = test_peer_id, args = [OUTSIDE_ACTION_NAME]),
unused!(0, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(0)]),
scalar!(10, peer = test_peer_id, args = [json!(INSIDE_ACTION_NAME)]),
unused!(10, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(10)]),
scalar!(1, peer = test_peer_id, args = [OUTSIDE_ACTION_NAME]),
unused!(1, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(1)]),
scalar!(11, peer = test_peer_id, args = [json!(INSIDE_ACTION_NAME)]),
unused!(11, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(11)]),
scalar!(2, peer = test_peer_id, args = [OUTSIDE_ACTION_NAME]),
unused!(2, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(2)]),
scalar!(12, peer = test_peer_id, args = [json!(INSIDE_ACTION_NAME)]),
unused!(12, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(12)]),
unused!(12, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(12)]),
unused!(2, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(2)]),
unused!(11, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(11)]),
unused!(1, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(1)]),
unused!(10, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(10)]),
unused!(0, peer = test_peer_id, args = [json!(OUTPUT_ACTION_NAME), json!(0)]),
]);
assert_eq!(actual_trace, expected_trace);
}

View File

@ -14,16 +14,13 @@
* limitations under the License.
*/
use air_interpreter_data::CidTracker;
use air::ExecutionCidState;
use air_test_utils::prelude::*;
use std::rc::Rc;
#[test]
fn seq_remote_remote() {
let mut vm = create_avm(unit_call_service(), "");
let mut cid_tracker = CidTracker::new();
cid_tracker.record_value(Rc::new("".into())).unwrap();
let mut cid_state = ExecutionCidState::new();
let script = r#"
(seq
@ -34,8 +31,14 @@ fn seq_remote_remote() {
let result = checked_call_vm!(vm, <_>::default(), script, "", "");
assert_eq!(result.next_peer_pks, vec![String::from("remote_peer_id_1")]);
let initial_trace = vec![executed_state::scalar_string("")];
let initial_data = raw_data_from_trace(initial_trace, cid_tracker.into());
let initial_trace = vec![scalar_tracked!(
"",
cid_state,
peer = "remote_peer_id_1",
service = "local_service_id",
function = "local_fn_name"
)];
let initial_data = raw_data_from_trace(initial_trace, cid_state.into());
let result = checked_call_vm!(vm, <_>::default(), script, "", initial_data);

View File

@ -32,12 +32,23 @@ fn xor() {
let result = checked_call_vm!(vm, <_>::default(), script, "", "");
let actual_trace = trace_from_result(&result);
let expected_call_result = executed_state::scalar_string("success result from fallible_call_service");
let expected_call_result = scalar!(
"success result from fallible_call_service",
peer = local_peer_id,
service = "service_id_2",
function = "local_fn_name"
);
assert_eq!(actual_trace.len(), 2);
assert_eq!(
actual_trace[0.into()],
executed_state::service_failed(1, "failed result from fallible_call_service")
failed!(
1,
"failed result from fallible_call_service",
peer = local_peer_id,
service = "service_id_1",
function = "local_fn_name"
)
);
assert_eq!(actual_trace[1.into()], expected_call_result);
@ -133,13 +144,47 @@ fn xor_par() {
let expected_trace = vec![
par(3, 3),
par(1, 1),
service_failed(1, failed_result),
service_failed(1, failed_result),
failed!(
1,
failed_result,
peer = local_peer_id,
service = "service_id_1",
function = "local_fn_name"
),
failed!(
1,
failed_result,
peer = local_peer_id,
service = "service_id_1",
function = "local_fn_name"
),
par(1, 1),
service_failed(1, failed_result),
service_failed(1, failed_result),
scalar_string(success_result),
scalar_string(success_result),
failed!(
1,
failed_result,
peer = local_peer_id,
service = "service_id_1",
function = "local_fn_name"
),
failed!(
1,
failed_result,
peer = local_peer_id,
service = "service_id_1",
function = "local_fn_name"
),
scalar!(
success_result,
peer = local_peer_id,
service = "service_id_2",
function = "local_fn_name"
),
scalar!(
success_result,
peer = local_peer_id,
service = "service_id_2",
function = "local_fn_name"
),
];
assert_eq!(actual_trace, expected_trace);
@ -167,8 +212,13 @@ fn last_error_with_xor() {
let result = checked_call_vm!(vm, <_>::default(), script, "", result.data);
let actual_trace = trace_from_result(&result);
let expected_state = executed_state::scalar_string(
r#"Local service error, ret_code is 1, error message is '"failed result from fallible_call_service"'"#,
let msg = r#"Local service error, ret_code is 1, error message is '"failed result from fallible_call_service"'"#;
let expected_state = scalar!(
msg,
peer = local_peer_id,
service = "service_id_2",
function = "local_fn_name",
args = [msg]
);
assert_eq!(actual_trace[1.into()], expected_state);

View File

@ -14,8 +14,11 @@
* limitations under the License.
*/
use air_interpreter_data::ExecutionTrace;
use air_test_utils::prelude::*;
use pretty_assertions::assert_eq;
#[test]
fn join_chat_1() {
use std::collections::HashSet;
@ -71,7 +74,12 @@ fn join_chat_1() {
let relay_1_actual_trace = trace_from_result(&relay_1_result);
let relay_1_expected_trace = vec![
executed_state::stream_string("result from unit_call_service", 0),
stream!(
"result from unit_call_service",
0,
peer = relay_1_peer_id,
service = "identity"
),
executed_state::request_sent_by(relay_1_peer_id),
];
@ -82,15 +90,25 @@ fn join_chat_1() {
let remote_actual_trace = trace_from_result(&remote_result);
let remote_expected_trace = vec![
executed_state::stream_string("result from unit_call_service", 0),
executed_state::stream(
stream!(
"result from unit_call_service",
0,
peer = relay_1_peer_id,
service = "identity"
),
stream!(
json!([[client_1_peer_id, relay_1_peer_id], [client_2_peer_id, relay_2_peer_id]]),
0,
peer = remote_peer_id,
service = "552196ea-b9b2-4761-98d4-8e7dba77fac4",
function = "add"
),
scalar!(
json!([[client_1_peer_id, relay_1_peer_id], [client_2_peer_id, relay_2_peer_id]]),
peer = remote_peer_id,
service = "920e3ba3-cbdf-4ae3-8972-0fa2f31fffd9",
function = "get_users"
),
executed_state::scalar(json!([
[client_1_peer_id, relay_1_peer_id],
[client_2_peer_id, relay_2_peer_id]
])),
executed_state::par(1, 2),
executed_state::request_sent_by(remote_peer_id),
executed_state::par(1, 0),
@ -110,22 +128,37 @@ fn join_chat_1() {
let relay_1_actual_trace = trace_from_result(&relay_1_result);
let relay_1_expected_trace = vec![
executed_state::stream_string("result from unit_call_service", 0),
executed_state::stream(
let relay_1_expected_trace = ExecutionTrace::from(vec![
stream!(
"result from unit_call_service",
0,
peer = relay_1_peer_id,
service = "identity"
),
stream!(
json!([[client_1_peer_id, relay_1_peer_id], [client_2_peer_id, relay_2_peer_id]]),
0,
peer = remote_peer_id,
service = "552196ea-b9b2-4761-98d4-8e7dba77fac4",
function = "add"
),
scalar!(
json!([[client_1_peer_id, relay_1_peer_id], [client_2_peer_id, relay_2_peer_id]]),
peer = remote_peer_id,
service = "920e3ba3-cbdf-4ae3-8972-0fa2f31fffd9",
function = "get_users"
),
executed_state::scalar(json!([
[client_1_peer_id, relay_1_peer_id],
[client_2_peer_id, relay_2_peer_id]
])),
executed_state::par(2, 2),
executed_state::stream_string("result from unit_call_service", 0),
stream!(
"result from unit_call_service",
0,
peer = relay_1_peer_id,
service = "identity"
),
executed_state::request_sent_by(relay_1_peer_id),
executed_state::par(1, 0),
executed_state::request_sent_by(remote_peer_id),
];
]);
assert_eq!(relay_1_actual_trace, relay_1_expected_trace);
assert_eq!(relay_1_result.next_peer_pks, vec![String::from(client_1_peer_id)]);
@ -134,22 +167,43 @@ fn join_chat_1() {
let client_1_actual_trace = trace_from_result(&client_1_result);
let client_1_expected_trace = vec![
executed_state::stream_string("result from unit_call_service", 0),
executed_state::stream(
let client_1_expected_trace = ExecutionTrace::from(vec![
stream!(
"result from unit_call_service",
0,
peer = relay_1_peer_id,
service = "identity"
),
stream!(
json!([[client_1_peer_id, relay_1_peer_id], [client_2_peer_id, relay_2_peer_id]]),
0,
peer = remote_peer_id,
service = "552196ea-b9b2-4761-98d4-8e7dba77fac4",
function = "add"
),
scalar!(
json!([[client_1_peer_id, relay_1_peer_id], [client_2_peer_id, relay_2_peer_id]]),
peer = remote_peer_id,
service = "920e3ba3-cbdf-4ae3-8972-0fa2f31fffd9",
function = "get_users"
),
executed_state::scalar(json!([
[client_1_peer_id, relay_1_peer_id],
[client_2_peer_id, relay_2_peer_id]
])),
executed_state::par(2, 2),
executed_state::stream_string("result from unit_call_service", 0),
executed_state::stream_string("result from unit_call_service", 0),
stream!(
"result from unit_call_service",
0,
peer = relay_1_peer_id,
service = "identity"
),
stream!(
"result from unit_call_service",
0,
peer = client_1_peer_id,
service = "fgemb3",
function = "add"
),
executed_state::par(1, 0),
executed_state::request_sent_by(remote_peer_id),
];
]);
assert_eq!(client_1_actual_trace, client_1_expected_trace);
assert!(client_1_result.next_peer_pks.is_empty());
@ -158,22 +212,37 @@ fn join_chat_1() {
let relay_2_actual_trace = trace_from_result(&relay_2_result);
let relay_2_expected_trace = vec![
executed_state::stream_string("result from unit_call_service", 0),
executed_state::stream(
let relay_2_expected_trace = ExecutionTrace::from(vec![
stream!(
"result from unit_call_service",
0,
peer = relay_1_peer_id,
service = "identity"
),
stream!(
json!([[client_1_peer_id, relay_1_peer_id], [client_2_peer_id, relay_2_peer_id]]),
0,
peer = remote_peer_id,
service = "552196ea-b9b2-4761-98d4-8e7dba77fac4",
function = "add"
),
scalar!(
json!([[client_1_peer_id, relay_1_peer_id], [client_2_peer_id, relay_2_peer_id]]),
peer = remote_peer_id,
service = "920e3ba3-cbdf-4ae3-8972-0fa2f31fffd9",
function = "get_users"
),
executed_state::scalar(json!([
[client_1_peer_id, relay_1_peer_id],
[client_2_peer_id, relay_2_peer_id]
])),
executed_state::par(1, 3),
executed_state::request_sent_by(remote_peer_id),
executed_state::par(2, 0),
executed_state::stream_string("result from unit_call_service", 0),
stream!(
"result from unit_call_service",
0,
peer = relay_2_peer_id,
service = "identity"
),
executed_state::request_sent_by(relay_2_peer_id),
];
]);
assert_eq!(relay_2_actual_trace, relay_2_expected_trace);
assert_eq!(relay_2_result.next_peer_pks, vec![String::from(client_2_peer_id)]);
@ -182,22 +251,43 @@ fn join_chat_1() {
let client_2_actual_trace = trace_from_result(&client_2_result);
let client_2_expected_trace = vec![
executed_state::stream_string("result from unit_call_service", 0),
executed_state::stream(
let client_2_expected_trace = ExecutionTrace::from(vec![
stream!(
"result from unit_call_service",
0,
peer = relay_1_peer_id,
service = "identity"
),
stream!(
json!([[client_1_peer_id, relay_1_peer_id], [client_2_peer_id, relay_2_peer_id]]),
0,
peer = remote_peer_id,
service = "552196ea-b9b2-4761-98d4-8e7dba77fac4",
function = "add"
),
scalar!(
json!([[client_1_peer_id, relay_1_peer_id], [client_2_peer_id, relay_2_peer_id]]),
peer = remote_peer_id,
service = "920e3ba3-cbdf-4ae3-8972-0fa2f31fffd9",
function = "get_users"
),
executed_state::scalar(json!([
[client_1_peer_id, relay_1_peer_id],
[client_2_peer_id, relay_2_peer_id]
])),
executed_state::par(1, 3),
executed_state::request_sent_by(remote_peer_id),
executed_state::par(2, 0),
executed_state::stream_string("result from unit_call_service", 0),
executed_state::stream_string("result from unit_call_service", 0),
];
stream!(
"result from unit_call_service",
0,
peer = relay_2_peer_id,
service = "identity"
),
stream!(
"result from unit_call_service",
0,
peer = client_2_peer_id,
service = "fgemb3",
function = "add"
),
]);
assert_eq!(client_2_actual_trace, client_2_expected_trace);
assert!(client_2_result.next_peer_pks.is_empty());
@ -243,16 +333,50 @@ fn join_chat_2() {
let client_1_actual_trace = trace_from_result(&client_1_result);
let client_1_expected_trace = vec![
executed_state::stream_string("result from unit_call_service", 0),
executed_state::scalar(json!([["A"], ["B"]])),
let client_1_expected_trace = ExecutionTrace::from(vec![
stream!(
"result from unit_call_service",
0,
peer = relay_1_peer_id,
service = "identity"
),
scalar!(
json!([["A"], ["B"]]),
peer = remote_peer_id,
service = "920e3ba3-cbdf-4ae3-8972-0fa2f31fffd9",
function = "get_users"
),
executed_state::par(2, 3),
executed_state::stream_string("result from unit_call_service", 0),
executed_state::stream_string("result from unit_call_service", 0),
stream!(
"result from unit_call_service",
0,
peer = relay_1_peer_id,
service = "identity"
),
stream!(
"result from unit_call_service",
0,
peer = client_peer_id,
service = "fgemb3",
function = "add",
args = [json!(["A"])]
),
executed_state::par(2, 0),
executed_state::stream_string("result from unit_call_service", 0),
executed_state::stream_string("result from unit_call_service", 0),
];
stream!(
"result from unit_call_service",
0,
peer = relay_1_peer_id,
service = "identity"
),
stream!(
"result from unit_call_service",
0,
peer = client_peer_id,
service = "fgemb3",
function = "add",
args = [json!(["B"])]
),
]);
assert_eq!(client_1_actual_trace, client_1_expected_trace);
assert!(client_1_result.next_peer_pks.is_empty());
@ -305,17 +429,46 @@ fn init_peer_id() {
let client_1_actual_trace = trace_from_result(&client_1_result);
let client_1_expected_trace = vec![
executed_state::scalar_string("result from unit_call_service"),
executed_state::scalar(json!([[client_1_peer_id], ["B"]])),
let client_1_expected_trace = ExecutionTrace::from(vec![
unused!(
"result from unit_call_service",
peer = relay_1_peer_id,
service = "identity"
),
scalar!(
json!([[client_1_peer_id], ["B"]]),
peer = remote_peer_id,
service = "920e3ba3-cbdf-4ae3-8972-0fa2f31fffd9",
function = "get_users"
),
executed_state::par(2, 3),
executed_state::scalar_string("result from unit_call_service"),
executed_state::scalar_string("result from unit_call_service"),
unused!(
"result from unit_call_service",
peer = relay_1_peer_id,
service = "identity"
),
unused!(
"result from unit_call_service",
peer = client_1_peer_id,
service = "fgemb3",
function = "add",
args = [json!([client_1_peer_id])]
),
executed_state::par(2, 0),
executed_state::scalar_string("result from unit_call_service"),
executed_state::scalar_string("result from unit_call_service"),
unused!(
"result from unit_call_service",
peer = relay_1_peer_id,
service = "identity"
),
unused!(
"result from unit_call_service",
peer = client_1_peer_id,
service = "fgemb3",
function = "add",
args = [json!(["B"])]
),
executed_state::request_sent_by(client_1_peer_id),
];
]);
assert_eq!(client_1_actual_trace, client_1_expected_trace);
assert_eq!(client_1_result.next_peer_pks, vec![initiator_peer_id.to_string()]);
@ -324,17 +477,50 @@ fn init_peer_id() {
let initiator_1_actual_trace = trace_from_result(&initiator_1_result);
let initiator_1_expected_trace = vec![
executed_state::scalar_string("result from unit_call_service"),
executed_state::scalar(json!([[client_1_peer_id], ["B"]])),
let initiator_1_expected_trace = ExecutionTrace::from(vec![
unused!(
"result from unit_call_service",
peer = relay_1_peer_id,
service = "identity"
),
scalar!(
json!([[client_1_peer_id], ["B"]]),
peer = remote_peer_id,
service = "920e3ba3-cbdf-4ae3-8972-0fa2f31fffd9",
function = "get_users"
),
executed_state::par(2, 3),
executed_state::scalar_string("result from unit_call_service"),
executed_state::scalar_string("result from unit_call_service"),
unused!(
"result from unit_call_service",
peer = relay_1_peer_id,
service = "identity"
),
unused!(
"result from unit_call_service",
peer = client_1_peer_id,
service = "fgemb3",
function = "add",
args = [json!([client_1_peer_id])]
),
executed_state::par(2, 0),
executed_state::scalar_string("result from unit_call_service"),
executed_state::scalar_string("result from unit_call_service"),
executed_state::scalar_string("result from unit_call_service"),
];
unused!(
"result from unit_call_service",
peer = relay_1_peer_id,
service = "identity"
),
unused!(
"result from unit_call_service",
peer = client_1_peer_id,
service = "fgemb3",
function = "add",
args = [json!(["B"])]
),
unused!(
"result from unit_call_service",
peer = initiator_peer_id,
service = "identity"
),
]);
assert_eq!(initiator_1_actual_trace, initiator_1_expected_trace);
assert!(initiator_1_result.next_peer_pks.is_empty());

View File

@ -75,12 +75,42 @@ fn create_service() {
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
executed_state::scalar(module_bytes),
executed_state::scalar(module_config),
executed_state::scalar(blueprint),
executed_state::scalar_string(add_module_response),
executed_state::scalar_string(add_blueprint_response),
executed_state::scalar_string(create_response),
scalar!(
module_bytes.clone(),
peer = "set_variables",
service = "add_module",
args = ["module_bytes"]
),
scalar!(
module_config.clone(),
peer = "set_variables",
service = "add_module",
args = ["module_config"]
),
scalar!(
blueprint.clone(),
peer = "set_variables",
service = "add_module",
args = ["blueprint"]
),
scalar!(
add_module_response,
peer = "A",
service = "add_module",
args = [module_bytes, module_config]
),
scalar!(
add_blueprint_response,
peer = "A",
service = "add_blueprint",
args = [blueprint]
),
scalar!(
create_response,
peer = "A",
service = "create",
args = [add_blueprint_response]
),
executed_state::request_sent_by("A"),
];

View File

@ -74,20 +74,20 @@ fn issue_173() {
let actual_trace = trace_from_result(&vm_2_result);
let expected_trace = vec![
executed_state::stream_number(1, 0),
executed_state::stream_number(2, 0),
stream!(1, 0),
stream!(2, 0),
executed_state::fold(vec![
executed_state::subtrace_lore(0, SubTraceDesc::new(3.into(), 2), SubTraceDesc::new(9.into(), 2)),
executed_state::subtrace_lore(1, SubTraceDesc::new(5.into(), 2), SubTraceDesc::new(7.into(), 2)),
]),
executed_state::par(6, 1),
executed_state::stream_number(1, 0),
stream!(1, 0),
executed_state::par(2, 1),
executed_state::stream_number(2, 0),
executed_state::scalar(json!([2])),
executed_state::scalar(json!([1, 2])),
executed_state::scalar(json!([1])),
executed_state::scalar(json!([1, 2])),
stream!(2, 0),
scalar!(json!([2])),
scalar!(json!([1, 2])),
scalar!(json!([1])),
scalar!(json!([1, 2])),
];
assert_eq!(actual_trace, expected_trace);

View File

@ -44,6 +44,6 @@ fn issue_206() {
let result = checked_call_vm!(peer_1, test_params, &script, "", "");
let actual_trace = trace_from_result(&result);
let expected_trace = vec![executed_state::ap(0), executed_state::scalar(json!(["is nil"]))];
let expected_trace = vec![executed_state::ap(0), scalar!(json!(["is nil"]))];
assert_eq!(actual_trace, expected_trace);
}

View File

@ -14,8 +14,11 @@
* limitations under the License.
*/
use air_interpreter_data::ExecutionTrace;
use air_test_utils::prelude::*;
use pretty_assertions::assert_eq;
#[test]
// test for github.com/fluencelabs/aquavm/issues/211
// On the versions < 0.20.1 it just crashes
@ -70,9 +73,14 @@ fn issue_211() {
let result = engine.execute_one(peer_1_id).unwrap();
let expected_trace = vec![
executed_state::scalar_number(2),
executed_state::scalar(json!([1, 2, 3])),
let expected_trace = ExecutionTrace::from(vec![
scalar!(2, peer = peer_1_id, service = "getdatasrv..0", function = "idx"),
scalar!(
json!([1, 2, 3]),
peer = peer_1_id,
service = "getdatasrv..1",
function = "nodes"
),
executed_state::par(6, 0),
executed_state::par(1, 4),
executed_state::ap(0),
@ -100,7 +108,13 @@ fn issue_211() {
},
]
})),
executed_state::scalar_string("expected result"),
unused!(
"expected result",
peer = peer_1_id,
service = "op..2",
function = "noop",
args = vec![json!(3), json!([1, 2, 3])]
),
executed_state::canon(json!({
"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "peer_1_id", "service_id": ""},
"values": [
@ -121,8 +135,14 @@ fn issue_211() {
},
]
})),
executed_state::scalar_string("expected result"),
];
scalar!(
"expected result",
peer = peer_1_id,
service = "op..3",
function = "identity",
args = vec![json!([1, 2, 3])]
),
]);
let actual_trace = trace_from_result(&result);
assert_eq!(actual_trace, expected_trace);

View File

@ -14,8 +14,11 @@
* limitations under the License.
*/
use air_interpreter_data::ExecutionTrace;
use air_test_utils::prelude::*;
use pretty_assertions::assert_eq;
#[test]
// test for github.com/fluencelabs/aquavm/issues/214
fn issue_214() {
@ -44,7 +47,7 @@ fn issue_214() {
)
(xor
(call -relay- ("op" "identity") [s.$.field!] res) ;; (1) should not produce data after calling on relay
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1]) ;; (2) should be called
(call %init_peer_id% ("errorHandlingSrv" "error") ["%last_error%" 1]) ;; (2) should be called
)
)
(xor
@ -58,11 +61,17 @@ fn issue_214() {
let test_params = TestRunParameters::from_init_peer_id(client_id);
let result = checked_call_vm!(client, test_params, &script, "", "");
let expected_trace = vec![
executed_state::scalar_string(relay_id),
executed_state::scalar(scalar),
executed_state::scalar_string(error_handler),
];
let expected_trace = ExecutionTrace::from(vec![
scalar!(relay_id, peer = client_id, service = "getDataSrv", function = "-relay-"),
scalar!(scalar, peer = client_id, service = "getDataSrv", function = "s"),
unused!(
error_handler,
peer = client_id,
service = "errorHandlingSrv",
function = "error",
args = vec![json!("%last_error%"), json!(1)]
),
]);
let actual_trace = trace_from_result(&result);
assert_eq!(actual_trace, expected_trace);

View File

@ -49,8 +49,8 @@ fn issue_216() {
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
executed_state::scalar(json!([])),
executed_state::scalar_string(error_message),
scalar!(json!([]), peer = some_peer_id, function = "value"),
unused!(error_message, peer = client_id, args = vec![error_message]),
];
assert_eq!(actual_trace, expected_trace);
}

View File

@ -14,8 +14,10 @@
* limitations under the License.
*/
use air_interpreter_data::ExecutionTrace;
use air_test_framework::AirScriptExecutor;
use air_test_utils::prelude::*;
use pretty_assertions::assert_eq;
#[test]
// test for github.com/fluencelabs/aquavm/issues/221
@ -81,13 +83,13 @@ fn issue_221() {
let _join_1_result = executor.execute_one(join_1_id).unwrap();
let join_1_result = executor.execute_one(join_1_id).unwrap(); // before 0.20.9 it fails here
let actual_trace = trace_from_result(&join_1_result);
let expected_trace = vec![
executed_state::scalar(json!([peer_1_id, peer_2_id])),
let expected_trace = ExecutionTrace::from(vec![
scalar!(json!([peer_1_id, peer_2_id]), peer = set_variable_id, service = "..0"),
executed_state::par(2, 3),
executed_state::scalar_string(peer_1_value),
scalar!(peer_1_value, peer = peer_1_id, service = "..1", args = vec![peer_1_id]),
executed_state::ap(0),
executed_state::par(2, 0),
executed_state::scalar_string(peer_2_value),
scalar!(peer_2_value, peer = peer_2_id, service = "..1", args = vec![peer_2_id]),
executed_state::ap(1),
executed_state::fold(vec![
executed_state::subtrace_lore(3, SubTraceDesc::new(8.into(), 4), SubTraceDesc::new(12.into(), 0)),
@ -95,14 +97,24 @@ fn issue_221() {
]),
executed_state::par(3, 0),
executed_state::par(1, 1),
executed_state::scalar_string(peer_1_value),
unused!(
peer_1_value,
peer = join_1_id,
service = "..2",
args = vec![peer_1_value]
),
executed_state::request_sent_by(peer_1_id),
executed_state::par(3, 0),
executed_state::par(1, 1),
executed_state::scalar_string(peer_2_value),
unused!(
peer_2_value,
peer = join_1_id,
service = "..2",
args = vec![peer_2_value]
),
executed_state::request_sent_by(peer_2_id),
executed_state::request_sent_by(join_1_id),
];
]);
assert_eq!(actual_trace, expected_trace);
}

View File

@ -17,8 +17,6 @@
use air_test_utils::prelude::*;
use pretty_assertions::assert_eq;
use std::ops::Deref;
#[test]
// test for github.com/fluencelabs/aquavm/issues/222
fn issue_222() {
@ -68,15 +66,15 @@ fn issue_222() {
let expected_trace = vec![
executed_state::par(3, 3),
executed_state::par(1, 1),
executed_state::stream(json!([1]), 1),
executed_state::stream(json!([2]), 0),
stream!(json!([1]), 1, peer = other_1_id),
stream!(json!([2]), 0, peer = other_2_id),
executed_state::fold(vec![
executed_state::subtrace_lore(3, SubTraceDesc::new(5.into(), 1), SubTraceDesc::new(6.into(), 0)),
executed_state::subtrace_lore(2, SubTraceDesc::new(6.into(), 1), SubTraceDesc::new(7.into(), 0)),
]),
executed_state::scalar(json!([2])),
executed_state::scalar(json!([1])),
unused!(json!([2]), peer = other_id, args = vec![vec![2]]),
unused!(json!([1]), peer = other_id, args = vec![vec![1]]),
];
assert_eq!(actual_trace.deref(), expected_trace);
assert_eq!(&*actual_trace, expected_trace);
}

View File

@ -14,8 +14,11 @@
* limitations under the License.
*/
use air_interpreter_data::ExecutionTrace;
use air_test_utils::prelude::*;
use pretty_assertions::assert_eq;
#[test]
// test for github.com/fluencelabs/aquavm/issues/241
fn issue_241() {
@ -56,16 +59,16 @@ fn issue_241() {
let result = checked_call_vm!(some_peer_vm, <_>::default(), &script, "", result.data);
let actual_trace = trace_from_result(&result);
let expected_trace = vec![
executed_state::scalar(peers),
let expected_trace = ExecutionTrace::from(vec![
scalar!(peers, peer = set_array_0_peer_id),
executed_state::par(1, 4),
executed_state::scalar(array_1_content),
executed_state::scalar_string("result from unit_call_service"),
executed_state::scalar_string("result from unit_call_service"),
scalar!(array_1_content, peer = peer_1_id),
unused!("result from unit_call_service", peer = some_peer_id),
unused!("result from unit_call_service", peer = some_peer_id),
executed_state::par(1, 0),
// before 0.22.0 scalars wasn't clear after end of a fold block and here was more states
// before 0.22.0 scalar!s wasn't clear after end of a fold block and here was more states
// from the second iteration of fold over array-1
executed_state::request_sent_by(some_peer_id),
];
]);
assert_eq!(actual_trace, expected_trace);
}

View File

@ -14,15 +14,11 @@
* limitations under the License.
*/
use air::UncatchableError;
use air_interpreter_cid::value_to_json_cid;
use air_interpreter_data::CidTracker;
use air::{ExecutionCidState, UncatchableError};
use air_test_utils::prelude::*;
use air_trace_handler::merger::MergeError;
use air_trace_handler::TraceHandlerError;
use std::rc::Rc;
#[test]
// test for github.com/fluencelabs/aquavm/issues/295
fn issue_295() {
@ -36,15 +32,21 @@ fn issue_295() {
)
"#);
let mut cid_tracker = CidTracker::new();
cid_tracker.record_value(Rc::new("".into())).unwrap();
let prev_trace = vec![executed_state::scalar_string(""), executed_state::ap(1)];
let current_trace = vec![executed_state::scalar_string(""), executed_state::scalar_string("")];
let prev_data = raw_data_from_trace(prev_trace, cid_tracker.clone().into());
let current_data = raw_data_from_trace(current_trace, cid_tracker.into());
let mut cid_state = ExecutionCidState::new();
let scalar = scalar_tracked!("", cid_state, peer = vm_peer_id);
let prev_trace = vec![scalar.clone(), executed_state::ap(1)];
let current_trace = vec![scalar.clone(), scalar];
let prev_data = raw_data_from_trace(prev_trace, cid_state.clone().into());
let current_data = raw_data_from_trace(current_trace, cid_state.clone().into());
let result = call_vm!(vm, <_>::default(), &script, prev_data, current_data);
let cid = value_to_json_cid(&json!("")).unwrap().into();
let cid = value_aggregate_cid(
json!(""),
SecurityTetraplet::new(vm_peer_id, "", "", ""),
vec![],
&mut cid_state,
);
let expected_error = UncatchableError::TraceError {
trace_error: TraceHandlerError::MergeError(MergeError::IncompatibleExecutedStates(
ExecutedState::Ap(ApResult::new(1)),

View File

@ -39,8 +39,8 @@ fn issue_300() {
let expected_trace = vec![
executed_state::par(1, 1),
executed_state::stream_number(2, 1),
executed_state::stream_number(1, 0),
stream!(2, 1, peer = peer_id_1, args = vec![2]),
stream!(1, 0, peer = peer_id_2, args = vec![1]),
];
assert_eq!(actual_trace, expected_trace);
}

View File

@ -56,9 +56,9 @@ fn issue_302() {
let expected_trace = vec![
executed_state::par(1, 4),
executed_state::stream_number(2, 1),
executed_state::stream_number(1, 0),
executed_state::stream_number(0, 2),
stream!(2, 1, peer = peer_id_1, args = vec![2]),
stream!(1, 0, peer = peer_id_2, args = vec![1]),
stream!(0, 2, peer = peer_id_3, args = vec![0]),
executed_state::canon(json!({
"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "peer_id_2", "service_id": ""},
"values": [
@ -79,7 +79,7 @@ fn issue_302() {
},
]
})),
executed_state::scalar(json!([1, 2, 0])),
unused!(json!([1, 2, 0]), peer = peer_id_2, args = vec![vec![1, 2, 0]]),
];
assert_eq!(actual_trace.deref(), expected_trace);
}

View File

@ -14,8 +14,8 @@
* limitations under the License.
*/
use air::ExecutionCidState;
use air::UncatchableError;
use air_interpreter_cid::value_to_json_cid;
use air_interpreter_cid::CID;
use air_interpreter_data::FoldSubTraceLore;
use air_interpreter_data::ParResult;
@ -38,12 +38,14 @@ fn par_len_underflow() {
let vm_peer_id_1 = "vm_peer_id_1";
let mut peer_vm_1 = create_avm(unit_call_service(), vm_peer_id_1);
let script = f!(r#"
let script = format!(
r#"
(par
(ap 42 some)
(call "other" ("" "") [some] other)
)
"#);
"#
);
let trace = vec![
executed_state::par(42, 1),
@ -63,7 +65,8 @@ fn set_subtrace_len_and_pos_failed() {
let vm_peer_id_1 = "vm_peer_id_1";
let arg = json!([42, 43]);
let mut peer_vm_1 = create_avm(set_variable_call_service(arg), vm_peer_id_1);
let script = f!(r#"
let script = format!(
r#"
(par
(call "vm_peer_id_1" ("" "") [] $s)
(fold $s i
@ -71,11 +74,12 @@ fn set_subtrace_len_and_pos_failed() {
(next i)
)
)
"#);
let mut tracker = CidTracker::<JValue>::new();
"#
);
let mut cid_state = ExecutionCidState::new();
let trace = vec![
executed_state::par(1, 2),
stream_tracked(json!([42, 43]), 0, &mut tracker),
stream_tracked!(json!([42, 43]), 0, cid_state),
executed_state::fold(vec![executed_state::subtrace_lore(
1,
subtrace_desc(5, 1),
@ -83,7 +87,7 @@ fn set_subtrace_len_and_pos_failed() {
)]),
request_sent_by("vm_peer_id_1"),
];
let wrong_data = raw_data_from_trace(trace, tracker);
let wrong_data = raw_data_from_trace(trace, cid_state);
let result = call_vm!(peer_vm_1, <_>::default(), script, wrong_data, "");
let expected_error = UncatchableError::TraceError {
trace_error: KeeperError(SetSubtraceLenAndPosFailed {
@ -100,7 +104,8 @@ fn set_subtrace_len_and_pos_failed() {
fn no_element_at_position() {
let vm_peer_id_1 = "vm_peer_id_1";
let mut peer_vm_1 = create_avm(unit_call_service(), vm_peer_id_1);
let script = f!(r#"
let script = format!(
r#"
(par
(call "vm_peer_id_1" ("" "") [] $s)
(fold $s i
@ -108,11 +113,12 @@ fn no_element_at_position() {
(next i)
)
)
"#);
let mut tracker = CidTracker::<JValue>::new();
"#
);
let mut cid_state = ExecutionCidState::new();
let trace = vec![
executed_state::par(1, 2),
stream_tracked(json!([42, 43]), 0, &mut tracker),
stream_tracked!(json!([42, 43]), 0, cid_state),
executed_state::fold(vec![executed_state::subtrace_lore(
42,
subtrace_desc(3, 1),
@ -120,7 +126,7 @@ fn no_element_at_position() {
)]),
request_sent_by("vm_peer_id_1"),
];
let wrong_data = raw_data_from_trace(trace, tracker);
let wrong_data = raw_data_from_trace(trace, cid_state);
let result = call_vm!(peer_vm_1, <_>::default(), script, wrong_data, "");
let expected_error = UncatchableError::TraceError {
trace_error: air_trace_handler::TraceHandlerError::KeeperError(NoElementAtPosition {
@ -137,7 +143,8 @@ fn no_stream_state() {
let vm_peer_id_1 = "vm_peer_id_1";
let arg = json!([42, 43]);
let mut peer_vm_1 = create_avm(set_variable_call_service(arg), vm_peer_id_1);
let script = f!(r#"
let script = format!(
r#"
(par
(call "vm_peer_id_1" ("" "") [] $s)
(fold $s i
@ -145,12 +152,13 @@ fn no_stream_state() {
(next i)
)
)
"#);
let mut tracker = CidTracker::<JValue>::new();
"#
);
let mut tracker = ExecutionCidState::new();
let wrong_state = request_sent_by("vm_peer_id_1");
let trace = vec![
executed_state::par(1, 2),
stream_tracked(json!([42, 43]), 0, &mut tracker),
stream_tracked!(json!([42, 43]), 0, &mut tracker),
executed_state::fold(vec![executed_state::subtrace_lore(
3,
subtrace_desc(3, 1), // try to change the number of elems to 3
@ -171,26 +179,28 @@ fn no_stream_state() {
fn incompatible_executed_states() {
let vm_peer_id = "vm_peer_id";
let mut peer_vm_1 = create_avm(echo_call_service(), vm_peer_id);
let script = f!(r#"
let script = format!(
r#"
(seq
(call "{vm_peer_id}" ("" "") [] scalar)
(ap scalar $stream)
)
"#);
let mut cid_tracker = CidTracker::new();
"#
);
let mut cid_tracker = ExecutionCidState::new();
let prev_trace = vec![
executed_state::scalar_tracked("", &mut cid_tracker),
scalar_tracked!("", cid_tracker, peer = vm_peer_id),
executed_state::ap(1),
];
let current_trace = vec![executed_state::scalar_string(""), executed_state::scalar_string("")];
let current_trace = vec![scalar!("", peer = vm_peer_id), scalar!("", peer = vm_peer_id)];
let prev_data = raw_data_from_trace(prev_trace, cid_tracker.clone().into());
let current_data = raw_data_from_trace(current_trace, cid_tracker.into());
let result = call_vm!(peer_vm_1, <_>::default(), &script, prev_data, current_data);
let cid = value_to_json_cid(&json!("")).unwrap().into();
let expected_error = UncatchableError::TraceError {
trace_error: MergeError(air_trace_handler::merger::MergeError::IncompatibleExecutedStates(
ExecutedState::Ap(ApResult::new(1)),
ExecutedState::Call(CallResult::Executed(ValueRef::Scalar(cid))),
scalar!("", peer = vm_peer_id),
)),
instruction: "ap scalar $stream".to_string(),
};
@ -202,12 +212,14 @@ fn different_executed_state_expected() {
let vm_peer_id_1 = "vm_peer_id_1";
let arg = json!([42, 43]);
let mut peer_vm_1 = create_avm(set_variable_call_service(arg), vm_peer_id_1);
let script = f!(r#"
let script = format!(
r#"
(seq
(ap 42 some)
(call "vm_peer_id_2" ("" "") [] $s)
)
"#);
"#
);
let wrong_state = executed_state::ap(42);
let prev_trace = vec![wrong_state.clone()];
let prev_data = raw_data_from_trace(prev_trace, <_>::default());
@ -227,9 +239,11 @@ fn different_executed_state_expected() {
fn invalid_dst_generations() {
let vm_peer_id_1 = "vm_peer_id_1";
let mut peer_vm_1 = create_avm(unit_call_service(), vm_peer_id_1);
let script = f!(r#"
let script = format!(
r#"
(ap "a" $s)
"#);
"#
);
let data = json!(
{
"version": "0.6.3",
@ -245,7 +259,8 @@ fn invalid_dst_generations() {
"cid_info": {
"value_store": {},
"tetraplet_store": {},
"canon_store": {}
"canon_store": {},
"service_result_store": {}
}
});
let data: Vec<u8> = serde_json::to_vec(&data).unwrap();
@ -266,21 +281,35 @@ fn invalid_dst_generations() {
fn incorrect_call_result() {
let vm_peer_id_1 = "vm_peer_id_1";
let mut peer_vm_1 = create_avm(unit_call_service(), vm_peer_id_1);
let script = f!(r#"
let script = format!(
r#"
(call "vm_peer_id_1" ("" "") [] v)
"#);
let prev_call_result = service_failed(42, "some");
"#
);
let prev_call_result = failed!(42, "some", peer = vm_peer_id_1);
let prev_trace = vec![prev_call_result.clone()];
let prev_data = raw_data_from_trace(prev_trace, <_>::default());
let curr_call_result = scalar_string("some");
let curr_call_result = scalar!("some", peer = vm_peer_id_1);
let curr_trace = vec![curr_call_result.clone()];
let curr_data = raw_data_from_trace(curr_trace, <_>::default());
let result = call_vm!(peer_vm_1, <_>::default(), &script, prev_data, curr_data);
let curr_call_value_ref = ValueRef::Scalar(value_to_json_cid(&json!("some")).unwrap().into());
let mut cid_store = ExecutionCidState::new();
let curr_call_value_ref = ValueRef::Scalar(value_aggregate_cid(
json!("some"),
SecurityTetraplet::literal_tetraplet(vm_peer_id_1),
vec![],
&mut cid_store,
));
let expected_error = UncatchableError::TraceError {
trace_error: MergeError(air_trace_handler::MergeError::IncorrectCallResult(
CallResultError::IncompatibleCallResults {
prev_call: air_interpreter_data::CallResult::CallServiceFailed(42, String::from(r#""some""#).into()),
prev_call: air_interpreter_data::CallResult::Failed(value_aggregate_cid(
serde_json::to_value(CallServiceFailed::new(42, r#""some""#.to_owned().into())).unwrap(),
SecurityTetraplet::literal_tetraplet(vm_peer_id_1),
vec![],
&mut cid_store,
)),
current_call: air_interpreter_data::CallResult::Executed(curr_call_value_ref),
},
)),
@ -294,9 +323,11 @@ fn canon_result_error() {
let vm_peer_id_1 = "vm_peer_id_1";
let arg = json!([42, 43]);
let mut peer_vm_1 = create_avm(set_variable_call_service(arg.clone()), vm_peer_id_1);
let script = f!(r#"
let script = format!(
r#"
(canon "vm_peer_id_1" $stream #canon)
"#);
"#
);
let prev_tetraplet = json!({
"tetraplet": {"function_name": "s", "json_path": "", "peer_pk": "vm_peer_id_1", "service_id": ""},
"values": [
@ -344,7 +375,8 @@ fn canon_result_error() {
fn several_records_with_same_pos() {
let vm_peer_id_1 = "vm_peer_id_1";
let mut peer_vm_1 = create_avm(unit_call_service(), vm_peer_id_1);
let script = f!(r#"
let script = format!(
r#"
(par
(call "vm_peer_id_1" ("" "") [] $s)
(fold $s i
@ -352,19 +384,20 @@ fn several_records_with_same_pos() {
(next i)
)
)
"#);
let mut tracker = CidTracker::<JValue>::new();
"#
);
let mut cid_state = ExecutionCidState::new();
let value_pos = 1;
let trace = vec![
executed_state::par(1, 2),
stream_tracked(json!([42, 43]), 0, &mut tracker),
stream_tracked!(json!([42, 43]), 0, cid_state),
fold(vec![
subtrace_lore(value_pos, subtrace_desc(3, 1), subtrace_desc(4, 0)),
subtrace_lore(value_pos, subtrace_desc(3, 1), subtrace_desc(4, 0)),
]),
request_sent_by("vm_peer_id_1"),
];
let wrong_data = raw_data_from_trace(trace, tracker);
let wrong_data = raw_data_from_trace(trace, cid_state);
let result = call_vm!(peer_vm_1, <_>::default(), &script, wrong_data, "");
// let result = peer_vm_1.call(script, wrong_data, "", <_>::default()).unwrap();
let fold_lore = FoldSubTraceLore {
@ -397,18 +430,32 @@ fn values_not_equal() {
let vm_peer_id_1 = "vm_peer_id_1";
let arg = json!([42, 43]);
let mut peer_vm_1 = create_avm(set_variable_call_service(arg), vm_peer_id_1);
let script = f!(r#"
let script = format!(
r#"
(call "vm_peer_id_1" ("" "") [] $s)
"#);
"#
);
let prev_value = json!(42);
let prev_trace = vec![scalar(prev_value.clone())];
let prev_trace = vec![scalar!(prev_value.clone(), peer = vm_peer_id_1)];
let prev_data = raw_data_from_trace(prev_trace, <_>::default());
let curr_value = json!(43);
let curr_trace = vec![scalar(curr_value.clone())];
let curr_trace = vec![scalar!(curr_value.clone(), peer = vm_peer_id_1)];
let curr_data = raw_data_from_trace(curr_trace, <_>::default());
let result = call_vm!(peer_vm_1, <_>::default(), &script, prev_data, curr_data);
let prev_value = ValueRef::Scalar(value_to_json_cid(&prev_value).unwrap().into());
let current_value = ValueRef::Scalar(value_to_json_cid(&curr_value).unwrap().into());
let mut cid_state = ExecutionCidState::new();
let prev_value = ValueRef::Scalar(value_aggregate_cid(
prev_value,
SecurityTetraplet::literal_tetraplet(vm_peer_id_1),
vec![],
&mut cid_state,
));
let current_value = ValueRef::Scalar(value_aggregate_cid(
curr_value,
SecurityTetraplet::literal_tetraplet(vm_peer_id_1),
vec![],
&mut cid_state,
));
let expected_error = UncatchableError::TraceError {
trace_error: MergeError(air_trace_handler::merger::MergeError::IncorrectCallResult(
CallResultError::ValuesNotEqual {
@ -416,7 +463,7 @@ fn values_not_equal() {
current_value,
},
)),
instruction: String::from(f!(r#"call "{vm_peer_id_1}" ("" "") [] $s"#)),
instruction: String::from(format!(r#"call "{vm_peer_id_1}" ("" "") [] $s"#)),
};
assert!(check_error(&result, expected_error));
}

View File

@ -15,7 +15,7 @@
*/
use air::UncatchableError::*;
use air_interpreter_cid::value_to_json_cid;
use air_interpreter_cid::CID;
use air_interpreter_data::ValueRef;
use air_test_utils::prelude::*;
@ -73,13 +73,13 @@ fn call_result_not_correspond_to_instr() {
"#);
let scalar_value = 42;
let wrong_trace = vec![scalar_number(scalar_value)];
let wrong_trace = vec![scalar!(scalar_value)];
let data = raw_data_from_trace(wrong_trace, <_>::default());
let result = peer_vm_1.call(script, "", data, <_>::default()).unwrap();
let value_ref = ValueRef::Scalar(value_to_json_cid(&json!(scalar_value)).unwrap().into());
let value_ref = ValueRef::Scalar(CID::new("bagaaierax2kxw256denmh2rmtot4cnuvz7wrf6e2l7jnxhtv3qb6xvqj2vhq").into());
let expected_error = CallResultNotCorrespondToInstr(value_ref);
assert!(check_error(&result, expected_error));
assert!(check_error(&result, expected_error), "{:?}", result);
}
#[test]
@ -109,11 +109,11 @@ fn value_for_cid_not_found() {
(call "vm_peer_id_1" ("" "") [] some)
"#);
let wrong_trace = vec![scalar_number(42)];
let wrong_trace = vec![scalar!(42)];
let data = raw_data_from_trace(wrong_trace, <_>::default());
let result = peer_vm_1.call(script, "", data, <_>::default()).unwrap();
println!("{:?}", result);
let missing_cid = String::from("bagaaieraondvznakk2hi3kfaixhnceatpykz7cikytniqo3lc7ogkgz2qbeq");
let expected_error = ValueForCidNotFound("value", missing_cid);
let missing_cid = String::from("bagaaierax2kxw256denmh2rmtot4cnuvz7wrf6e2l7jnxhtv3qb6xvqj2vhq");
let expected_error = ValueForCidNotFound("service result aggregate", missing_cid);
assert!(check_error(&result, expected_error));
}

View File

@ -23,7 +23,6 @@ use crate::TracePos;
use air_interpreter_cid::CID;
use polyplets::SecurityTetraplet;
use se_de::par_serializer;
use se_de::sender_serializer;
use serde::Deserialize;
use serde::Serialize;
@ -36,7 +35,7 @@ pub struct ParResult {
pub right_size: u32,
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum Sender {
PeerId(Rc<String>),
PeerIdWithCallId { peer_id: Rc<String>, call_id: u32 },
@ -46,26 +45,79 @@ pub enum Sender {
#[serde(rename_all = "snake_case")]
pub enum CallResult {
/// Request was sent to a target node by node with such public key and it shouldn't be called again.
#[serde(with = "sender_serializer")]
#[serde(rename = "sent_by")]
RequestSentBy(Sender),
/// A corresponding call's been already executed with such value as a result.
Executed(ValueRef),
/// call_service ended with a service error.
#[serde(rename = "failed")]
CallServiceFailed(i32, Rc<String>),
/// The call returned a service error.
///
/// The `JValue` has to be a two element array `[i32, String]`.
Failed(Rc<CID<ServiceResultAggregate>>),
}
/*
* The current value structure is:
*
* ```
* Scalar(CID<ServiceResultAggregate>) ---+
* |
* +----<service_result_store>------+
* |
* +-------> ServiceResultAggregate:
* value_cid ------------<value_store>----> JValue
* tetraplet_cid --------<tetraplet_store>----> SecurityTetraplet
* argument_hash: String
* ```
*
* `Stream` variant is similar, however, `Unused` is different: it has value CID only, but the value
* is not stored into the `value_store`:
*
* ```
* Unused(Rc<CID<JValue>>) ---> X
* ```
*/
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ValueRef {
/// The call value is stored to a scalar variable.
Scalar(Rc<CID<ServiceResultAggregate>>),
/// The call value is stored to a stream variable.
Stream {
cid: Rc<CID<ServiceResultAggregate>>,
generation: u32,
},
/// The call value is not stored.
Unused(Rc<CID<JValue>>),
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CallServiceFailed {
pub ret_code: i32,
/// This field contains a JSON-serialized value, not a plain error message.
pub message: Rc<String>,
}
impl CallServiceFailed {
pub fn new(ret_code: i32, message: Rc<String>) -> Self {
Self { ret_code, message }
}
pub fn to_value(&self) -> JValue {
serde_json::to_value(self).expect("default serializer shouldn't fail")
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ValueRef {
Scalar(Rc<CID<JValue>>),
Stream {
cid: Rc<CID<JValue>>,
generation: u32,
},
/// A proof of service result execution result.
pub struct ServiceResultAggregate {
pub value_cid: Rc<CID<JValue>>,
/// Hash of the call arguments.
pub argument_hash: Rc<str>,
/// The tetraplet of the call result.
pub tetraplet_cid: Rc<CID<SecurityTetraplet>>,
}
/// Let's consider an example of trace that could be produces by the following fold:

View File

@ -15,7 +15,6 @@
*/
use super::*;
use crate::JValue;
impl ParResult {
pub fn new(left_size: u32, right_size: u32) -> Self {
@ -42,20 +41,30 @@ impl CallResult {
CallResult::RequestSentBy(Sender::PeerIdWithCallId { peer_id, call_id })
}
pub fn executed_scalar(cid: Rc<CID<JValue>>) -> CallResult {
let value = ValueRef::Scalar(cid);
CallResult::Executed(value)
pub fn executed_service_result(value_ref: ValueRef) -> Self {
Self::Executed(value_ref)
}
pub fn executed_stream(cid: Rc<CID<JValue>>, generation: u32) -> CallResult {
let value = ValueRef::Stream { cid, generation };
CallResult::Executed(value)
pub fn executed_scalar(service_result_agg_cid: Rc<CID<ServiceResultAggregate>>) -> Self {
Self::executed_service_result(ValueRef::Scalar(service_result_agg_cid))
}
pub fn failed(ret_code: i32, error_msg: impl Into<String>) -> CallResult {
CallResult::CallServiceFailed(ret_code, Rc::new(error_msg.into()))
pub fn executed_stream(
service_result_agg_cid: Rc<CID<ServiceResultAggregate>>,
generation: u32,
) -> CallResult {
Self::executed_service_result(ValueRef::Stream {
cid: service_result_agg_cid,
generation,
})
}
pub fn executed_unused(value_cid: Rc<CID<JValue>>) -> CallResult {
Self::executed_service_result(ValueRef::Unused(value_cid))
}
pub fn failed(service_result_agg_cid: Rc<CID<ServiceResultAggregate>>) -> CallResult {
CallResult::Failed(service_result_agg_cid)
}
}
@ -107,11 +116,11 @@ impl std::fmt::Display for ExecutedState {
right_size: right_subgraph_size,
}) => write!(f, "par({left_subgraph_size}, {right_subgraph_size})"),
Call(RequestSentBy(sender)) => write!(f, r"{sender}"),
Call(Executed(value)) => {
write!(f, "executed({value})")
Call(Executed(value_ref)) => {
write!(f, "executed({value_ref:?})")
}
Call(CallServiceFailed(ret_code, err_msg)) => {
write!(f, r#"call_service_failed({ret_code}, "{err_msg}")"#)
Call(Failed(failed_cid)) => {
write!(f, "failed({failed_cid:?})")
}
Fold(FoldResult { lore }) => {
writeln!(f, "fold(",)?;
@ -145,6 +154,7 @@ impl std::fmt::Display for ValueRef {
ValueRef::Stream { cid, generation } => {
write!(f, "stream: {cid:?} generation: {generation}")
}
ValueRef::Unused(cid) => write!(f, "unused: {cid:?}"),
}
}
}

View File

@ -66,57 +66,3 @@ pub mod par_serializer {
deserializer.deserialize_seq(ParVisitor {})
}
}
pub mod sender_serializer {
use super::*;
pub fn serialize<S>(value: &Sender, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match value {
Sender::PeerId(peer_id) => serializer.serialize_str(peer_id.as_str()),
Sender::PeerIdWithCallId { peer_id, call_id } => {
let result = format!("{peer_id}: {call_id}");
serializer.serialize_str(&result)
}
}
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<Sender, D::Error>
where
D: Deserializer<'de>,
{
struct SenderVisitor;
impl<'de> Visitor<'de> for SenderVisitor {
type Value = Sender;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("call sender")
}
fn visit_str<E: serde::de::Error>(self, raw_sender: &str) -> Result<Self::Value, E> {
let sender = match raw_sender.find(": ") {
None => Sender::PeerId(Rc::new(raw_sender.to_string())),
Some(pos) => {
let peer_id = raw_sender[..pos].to_string();
let call_id = &raw_sender[pos + 2..];
let call_id = call_id.parse::<u32>().map_err(|e| {
serde::de::Error::custom(format!(
"failed to parse call_id of a sender {call_id}: {e}"
))
})?;
Sender::PeerIdWithCallId {
peer_id: Rc::new(peer_id),
call_id,
}
}
};
Ok(sender)
}
}
deserializer.deserialize_str(SenderVisitor {})
}
}

View File

@ -20,6 +20,7 @@ use crate::cid_store::CidStore;
use crate::CanonCidAggregate;
use crate::ExecutionTrace;
use crate::JValue;
use crate::ServiceResultAggregate;
use air_utils::measure;
use polyplets::SecurityTetraplet;
@ -130,16 +131,19 @@ impl Versions {
}
}
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct CidInfo {
/// Map CID to value
/// Map CID to value.
pub value_store: CidStore<JValue>,
/// Map CID to a tetraplet
/// Map CID to a tetraplet.
pub tetraplet_store: CidStore<SecurityTetraplet>,
/// Map CID to a canon value
/// Map CID to a canon value.
pub canon_store: CidStore<CanonCidAggregate>,
/// Map CID to a service result aggregate.
pub service_result_store: CidStore<ServiceResultAggregate>,
}
#[cfg(test)]

View File

@ -28,88 +28,69 @@ use crate::FoldResult;
use crate::FoldSubTraceLore;
use crate::SubTraceDesc;
use air::ExecutionCidState;
use air_interpreter_cid::value_to_json_cid;
use air_interpreter_cid::CID;
use air_interpreter_data::CanonCidAggregate;
use air_interpreter_data::CidTracker;
use air_interpreter_data::ServiceResultAggregate;
use avm_server::SecurityTetraplet;
use serde::Deserialize;
use serde::Serialize;
use std::rc::Rc;
pub fn scalar(result: JValue) -> ExecutedState {
let cid = value_to_json_cid(&result)
.unwrap_or_else(|e| panic!("{:?}: failed to compute CID of {:?}", e, result));
let value = ValueRef::Scalar(Rc::new(cid));
ExecutedState::Call(CallResult::Executed(value))
pub fn simple_value_aggregate_cid(
result: impl Into<serde_json::Value>,
cid_state: &mut ExecutionCidState,
) -> Rc<CID<ServiceResultAggregate>> {
let value_cid = cid_state
.value_tracker
.record_value(Rc::new(result.into()))
.unwrap();
let tetraplet = SecurityTetraplet::default();
let tetraplet_cid = cid_state
.tetraplet_tracker
.record_value(Rc::new(tetraplet))
.unwrap();
let service_result_agg = ServiceResultAggregate {
value_cid,
argument_hash: "".into(),
tetraplet_cid,
};
cid_state
.service_result_agg_tracker
.record_value(Rc::new(service_result_agg))
.unwrap()
}
pub fn scalar_tracked(result: impl Into<JValue>, tracker: &mut CidTracker) -> ExecutedState {
let cid = tracker.record_value(Rc::new(result.into())).unwrap();
let value = ValueRef::Scalar(cid);
ExecutedState::Call(CallResult::Executed(value))
}
pub fn value_aggregate_cid(
result: impl Into<serde_json::Value>,
tetraplet: SecurityTetraplet,
args: Vec<serde_json::Value>,
cid_state: &mut ExecutionCidState,
) -> Rc<CID<ServiceResultAggregate>> {
let value_cid = cid_state
.value_tracker
.record_value(Rc::new(result.into()))
.unwrap();
let tetraplet_cid = cid_state
.tetraplet_tracker
.record_value(Rc::new(tetraplet))
.unwrap();
pub fn scalar_number(result: impl Into<serde_json::Number>) -> ExecutedState {
let result = JValue::Number(result.into());
let arguments = serde_json::Value::Array(args);
let argument_hash = value_to_json_cid(&arguments).unwrap().into_inner().into();
scalar(result)
}
let service_result_agg = ServiceResultAggregate {
value_cid,
argument_hash,
tetraplet_cid,
};
pub fn stream_call_result(result: JValue, generation: u32) -> CallResult {
let cid = value_to_json_cid(&result)
.unwrap_or_else(|e| panic!("{:?}: failed to compute CID of {:?}", e, result));
CallResult::executed_stream(Rc::new(cid), generation)
}
pub fn stream(result: JValue, generation: u32) -> ExecutedState {
ExecutedState::Call(stream_call_result(result, generation))
}
pub fn stream_tracked(
value: impl Into<JValue>,
generation: u32,
tracker: &mut CidTracker,
) -> ExecutedState {
let cid = tracker.record_value(Rc::new(value.into())).unwrap();
ExecutedState::Call(CallResult::executed_stream(cid, generation))
}
pub fn scalar_string(result: impl Into<String>) -> ExecutedState {
let result = JValue::String(result.into());
scalar(result)
}
pub fn scalar_string_array(result: Vec<impl Into<String>>) -> ExecutedState {
let result = result
.into_iter()
.map(|s| JValue::String(s.into()))
.collect::<Vec<_>>();
let value = JValue::Array(result);
scalar(value)
}
pub fn stream_string(result: impl Into<String>, generation: u32) -> ExecutedState {
let result = JValue::String(result.into());
stream(result, generation)
}
pub fn stream_number(result: impl Into<serde_json::Number>, generation: u32) -> ExecutedState {
let result = JValue::Number(result.into());
stream(result, generation)
}
pub fn stream_string_array(result: Vec<impl Into<String>>, generation: u32) -> ExecutedState {
let result = result
.into_iter()
.map(|s| JValue::String(s.into()))
.collect::<Vec<_>>();
let value = JValue::Array(result);
stream(value, generation)
cid_state
.service_result_agg_tracker
.record_value(Rc::new(service_result_agg))
.unwrap()
}
pub fn request_sent_by(sender: impl Into<String>) -> ExecutedState {
@ -127,13 +108,6 @@ pub fn par(left: usize, right: usize) -> ExecutedState {
ExecutedState::Par(par_result)
}
pub fn service_failed(ret_code: i32, error_message: &str) -> ExecutedState {
ExecutedState::Call(CallResult::CallServiceFailed(
ret_code,
Rc::new(format!(r#""{error_message}""#)),
))
}
pub fn fold(lore: FoldLore) -> ExecutedState {
let result = FoldResult { lore };
ExecutedState::Fold(result)
@ -177,27 +151,19 @@ pub struct CanonResultAlike {
/// This function takes a JSON DSL-like struct for compatibility and test writer
/// convenience.
pub fn canon(canonicalized_element: JValue) -> ExecutedState {
let mut value_tracker = CidTracker::<JValue>::new();
let mut tetraplet_tracker = CidTracker::<SecurityTetraplet>::new();
let mut canon_tracker = CidTracker::<CanonCidAggregate>::new();
let mut cid_state = ExecutionCidState::new();
canon_tracked(
canonicalized_element,
&mut value_tracker,
&mut tetraplet_tracker,
&mut canon_tracker,
)
canon_tracked(canonicalized_element, &mut cid_state)
}
pub fn canon_tracked(
canonicalized_element: JValue,
value_tracker: &mut CidTracker<JValue>,
tetraplet_tracker: &mut CidTracker<SecurityTetraplet>,
canon_tracker: &mut CidTracker<CanonCidAggregate>,
cid_state: &mut ExecutionCidState,
) -> ExecutedState {
let canon_input = serde_json::from_value::<CanonResultAlike>(canonicalized_element)
.expect("Malformed canon input");
let tetraplet_cid = tetraplet_tracker
let tetraplet_cid = cid_state
.tetraplet_tracker
.record_value(canon_input.tetraplet.clone())
.unwrap_or_else(|e| {
panic!(
@ -209,9 +175,11 @@ pub fn canon_tracked(
.values
.iter()
.map(|value| {
let value_cid = value_tracker.record_value(value.result.clone())?;
let tetraplet_cid = tetraplet_tracker.record_value(value.tetraplet.clone())?;
canon_tracker.record_value(CanonCidAggregate {
let value_cid = cid_state.value_tracker.record_value(value.result.clone())?;
let tetraplet_cid = cid_state
.tetraplet_tracker
.record_value(value.tetraplet.clone())?;
cid_state.canon_tracker.record_value(CanonCidAggregate {
value: value_cid,
tetraplet: tetraplet_cid,
})
@ -221,3 +189,216 @@ pub fn canon_tracked(
let canon_result = CanonResult::new(tetraplet_cid, value_cids);
ExecutedState::Canon(canon_result)
}
#[macro_export]
macro_rules! _trace_value_body {
($value:expr) => {
$crate::executed_state::ExecutedCallBuilder::new($value)
};
($value:expr, $func1:ident = $v1:expr $(, $func:ident = $v:expr)*) => {
$crate::executed_state::ExecutedCallBuilder::new($value) .$func1($v1) $(. $func($v))*
};
}
#[macro_export]
macro_rules! scalar {
($value:expr) => {
_trace_value_body!($value).scalar()
};
($value:expr, $func1:ident = $v1:expr $(, $func:ident = $v:expr)*) => {
_trace_value_body!($value, $func1 = $v1 $(, $func = $v)*).scalar()
};
}
#[macro_export]
macro_rules! scalar_tracked {
($value:expr, $state:expr) => {
_trace_value_body!($value).scalar_tracked(&mut $state)
};
($value:expr, $state:expr, $func1:ident = $v1:expr $(, $func:ident = $v:expr)*) => {
_trace_value_body!($value, $func1 = $v1 $(, $func = $v)*).scalar_tracked(&mut $state)
};
}
#[macro_export]
macro_rules! failed {
($ret_code:expr, $error_message:expr) => {{
let failed_value = $crate::executed_state::_failure_to_value($ret_code, $error_message);
_trace_value_body!(failed_value).failed()
}};
($ret_code:expr, $error_message:expr, $func1:ident = $v1:expr $(, $func:ident = $v:expr)*) => {{
let failed_value = $crate::executed_state::_failure_to_value($ret_code, $error_message);
_trace_value_body!(failed_value, $func1 = $v1 $(, $func = $v)*).failed()
}}
}
#[macro_export]
macro_rules! stream {
($value:expr, $generation:expr) => {
_trace_value_body!($value).stream($generation)
};
($value:expr, $generation:expr, $func1:ident = $v1:expr $(, $func:ident = $v:expr)*) => {
_trace_value_body!($value, $func1 = $v1 $(, $func = $v)*).stream($generation)
};
}
#[macro_export]
macro_rules! stream_tracked {
($value:expr, $generation:expr, $state:expr) => {
_trace_value_body!($value).stream_tracked($generation, &mut $state)
};
($value:expr, $generation:expr, $state:expr, $func1:ident = $v1:expr $(, $func:ident = $v:expr)*) => {
_trace_value_body!($value, $func1 = $v1 $(, $func = $v)*).stream_tracked($generation, &mut $state)
};
}
/// Please note that `unused_tracked` does not exist as unused is never tracked.
#[macro_export]
macro_rules! unused {
($value:expr) => {
_trace_value_body!($value).unused()
};
($value:expr, $func1:ident = $v1:expr $(, $func:ident = $v:expr)*) => {
_trace_value_body!($value, $func1 = $v1 $(, $func = $v)*).unused()
};
}
pub fn _failure_to_value(ret_code: i32, error_message: &str) -> JValue {
let message_serialized = serde_json::to_string(error_message).unwrap();
crate::CallServiceFailed::new(ret_code, message_serialized.into()).to_value()
}
pub struct ExecutedCallBuilder {
result: JValue,
tetraplet: SecurityTetraplet,
args: Vec<JValue>,
}
impl ExecutedCallBuilder {
pub fn new(result: impl Into<JValue>) -> Self {
Self {
result: result.into(),
tetraplet: Default::default(),
args: Default::default(),
}
}
pub fn peer(mut self, peer_pk: impl Into<String>) -> Self {
self.tetraplet.peer_pk = peer_pk.into();
self
}
pub fn service(mut self, service_id: impl Into<String>) -> Self {
self.tetraplet.service_id = service_id.into();
self
}
pub fn function(mut self, function_name: impl Into<String>) -> Self {
self.tetraplet.function_name = function_name.into();
self
}
pub fn json_path(mut self, json_path: impl Into<String>) -> Self {
self.tetraplet.json_path = json_path.into();
self
}
pub fn args(mut self, args: impl IntoIterator<Item = impl Into<JValue>>) -> Self {
self.args = args.into_iter().map(Into::into).collect();
self
}
pub fn scalar(self) -> ExecutedState {
let mut cid_state = ExecutionCidState::new();
self.scalar_tracked(&mut cid_state)
}
pub fn unused(self) -> ExecutedState {
let value_cid = value_to_json_cid(&self.result).unwrap();
let value = ValueRef::Unused(value_cid.into());
ExecutedState::Call(CallResult::Executed(value))
}
pub fn scalar_tracked(self, cid_state: &mut ExecutionCidState) -> ExecutedState {
let service_result_agg_cid =
value_aggregate_cid(self.result, self.tetraplet, self.args, cid_state);
let value = ValueRef::Scalar(service_result_agg_cid);
ExecutedState::Call(CallResult::Executed(value))
}
pub fn failed(self) -> ExecutedState {
let mut cid_state = ExecutionCidState::new();
self.failed_tracked(&mut cid_state)
}
pub fn failed_tracked(self, cid_state: &mut ExecutionCidState) -> ExecutedState {
let service_result_agg_cid =
value_aggregate_cid(self.result, self.tetraplet, self.args, cid_state);
ExecutedState::Call(CallResult::Failed(service_result_agg_cid))
}
pub fn stream(self, generation: u32) -> ExecutedState {
let mut cid_state = ExecutionCidState::new();
self.stream_tracked(generation, &mut cid_state)
}
pub fn stream_tracked(
self,
generation: u32,
cid_state: &mut ExecutionCidState,
) -> ExecutedState {
let service_result_agg_cid =
value_aggregate_cid(self.result, self.tetraplet, self.args, cid_state);
let value = ValueRef::Stream {
cid: service_result_agg_cid,
generation,
};
ExecutedState::Call(CallResult::Executed(value))
}
}
#[cfg(test)]
mod tests {
use air::ExecutionCidState;
use serde_json::json;
#[test]
fn test_scalar() {
assert_eq!(scalar!(42), scalar!(42));
assert_eq!(scalar!("test"), scalar!("test"));
assert_ne!(scalar!(42), scalar!(42, peer = "test"));
assert_ne!(
scalar!(42, peer = "test"),
scalar!(42, peer = "test", args = vec![json!(1)]),
);
}
#[test]
fn test_scalar_tracked() {
let mut store = ExecutionCidState::new();
assert_eq!(scalar_tracked!(42, store), scalar_tracked!(42, store));
assert_eq!(scalar!(42), scalar_tracked!(42, store));
assert_eq!(
scalar_tracked!("test", store),
scalar_tracked!("test", store)
);
assert_ne!(
scalar_tracked!(42, store),
scalar_tracked!(42, store, peer = "test")
);
assert_ne!(
scalar_tracked!(42, store, peer = "test"),
scalar_tracked!(42, store, peer = "test", args = vec![json!(1)]),
);
assert_eq!(
scalar!(42, peer = "test", args = vec![json!(1)]),
scalar_tracked!(42, store, peer = "test", args = vec![json!(1)]),
);
}
}

View File

@ -36,9 +36,7 @@ mod native_test_runner;
mod wasm_test_runner;
pub use air::interpreter_data::*;
use air_interpreter_data::CanonCidAggregate;
use air_interpreter_data::CidStore;
use air_interpreter_data::CidTracker;
use air::ExecutionCidState;
pub use avm_interface::raw_outcome::*;
pub use avm_server::*;
@ -93,16 +91,15 @@ pub fn data_from_result(result: &RawAVMOutcome) -> InterpreterData {
serde_json::from_slice(&result.data).expect("default serializer shouldn't fail")
}
pub fn raw_data_from_trace(trace: impl Into<ExecutionTrace>, value_tracker: CidTracker) -> Vec<u8> {
pub fn raw_data_from_trace(
trace: impl Into<ExecutionTrace>,
cid_state: ExecutionCidState,
) -> Vec<u8> {
let data = InterpreterData::from_execution_result(
trace.into(),
<_>::default(),
<_>::default(),
CidInfo {
value_store: value_tracker.into(),
tetraplet_store: CidStore::<_>::default(),
canon_store: CidStore::<_>::default(),
},
cid_state.into(),
0,
semver::Version::new(1, 1, 1),
);
@ -111,18 +108,17 @@ pub fn raw_data_from_trace(trace: impl Into<ExecutionTrace>, value_tracker: CidT
pub fn raw_data_from_trace_with_canon(
trace: impl Into<ExecutionTrace>,
value_tracker: CidTracker,
tetraplet_tracker: CidTracker<SecurityTetraplet>,
canon_tracker: CidTracker<CanonCidAggregate>,
cid_state: ExecutionCidState,
) -> Vec<u8> {
let data = InterpreterData::from_execution_result(
trace.into(),
<_>::default(),
<_>::default(),
CidInfo {
value_store: value_tracker.into(),
tetraplet_store: tetraplet_tracker.into(),
canon_store: canon_tracker.into(),
value_store: cid_state.value_tracker.into(),
tetraplet_store: cid_state.tetraplet_tracker.into(),
canon_store: cid_state.canon_tracker.into(),
service_result_store: cid_state.service_result_agg_tracker.into(),
},
0,
semver::Version::new(1, 1, 1),

View File

@ -67,12 +67,12 @@ fn merge_call_results(prev_call: CallResult, current_call: CallResult) -> MergeR
use PreparationScheme::*;
let (merged_state, scheme) = match (prev_call, current_call) {
(prev @ CallServiceFailed(..), current @ CallServiceFailed(..)) => {
(prev @ Failed(..), current @ Failed(..)) => {
check_equal(&prev, &current)?;
(prev, Previous)
}
(RequestSentBy(_), current @ CallServiceFailed(..)) => (current, Current),
(prev @ CallServiceFailed(..), RequestSentBy(_)) => (prev, Previous),
(RequestSentBy(_), current @ Failed(..)) => (current, Current),
(prev @ Failed(..), RequestSentBy(_)) => (prev, Previous),
// senders shouldn't be checked for equality, for more info please look at
// github.com/fluencelabs/aquavm/issues/137
(previous @ RequestSentBy(_), RequestSentBy(_)) => (previous, Previous),

View File

@ -17,7 +17,6 @@
use super::*;
use air_interpreter_cid::CID;
use serde_json::Value as JValue;
pub(super) fn merge_executed(prev_value: ValueRef, current_value: ValueRef) -> MergeResult<CallResult> {
match (&prev_value, &current_value) {
@ -29,6 +28,10 @@ pub(super) fn merge_executed(prev_value: ValueRef, current_value: ValueRef) -> M
are_streams_equal(pr, cr, &prev_value, &current_value)?;
Ok(CallResult::Executed(prev_value))
}
(ValueRef::Unused(_), ValueRef::Unused(_)) => {
are_scalars_equal(&prev_value, &current_value)?;
Ok(CallResult::Executed(prev_value))
}
_ => Err(CallResultError::not_equal_values(prev_value, current_value)),
}
}
@ -45,8 +48,8 @@ fn are_scalars_equal(prev_value: &ValueRef, current_value: &ValueRef) -> MergeRe
}
fn are_streams_equal(
prev_result_value: &CID<JValue>,
current_result_value: &CID<JValue>,
prev_result_value: &CID<ServiceResultAggregate>,
current_result_value: &CID<ServiceResultAggregate>,
prev_value: &ValueRef,
current_value: &ValueRef,
) -> MergeResult<()> {

View File

@ -287,8 +287,19 @@ mod tests {
assert_eq!(
trace,
ExecutionTrace::from(vec![
scalar(json!([{"p":"peer2","v":2},{"p":"peer3","v":3},])),
scalar_number(12),
scalar!(
json!([{"p":"peer2","v":2},{"p":"peer3","v":3}]),
peer = "peer1",
service = "service..0",
function = "func"
),
scalar!(
12,
peer = "peer2",
service = "service..1",
function = "func",
args = vec![json!({"p":"peer2","v":2}), json!(1)]
),
request_sent_by("peer2"),
])
);
@ -305,8 +316,19 @@ mod tests {
assert_eq!(
trace,
ExecutionTrace::from(vec![
scalar(json!([{"p":"peer2","v":2},{"p":"peer3","v":3},])),
scalar_number(12),
scalar!(
json!([{"p":"peer2","v":2},{"p":"peer3","v":3}]),
peer = "peer1",
service = "service..0",
function = "func"
),
scalar!(
12,
peer = "peer2",
service = "service..1",
function = "func",
args = vec![json!({"p":"peer2","v":2}), json!(1)]
),
request_sent_by("peer2"),
])
);
@ -360,9 +382,19 @@ mod tests {
assert_eq!(
&*trace,
vec![
executed_state::scalar(json!(["peer2", "peer3"])),
executed_state::scalar(json!(42)),
executed_state::scalar(json!(43)),
scalar!(json!(["peer2", "peer3"]), peer = "peer1", service = "..0"),
unused!(
json!(42),
peer = "peer2",
service = "..1",
args = vec!["peer2"]
),
unused!(
json!(43),
peer = "peer3",
service = "..1",
args = vec!["peer3"]
),
]
);
}
@ -432,8 +464,19 @@ mod tests {
assert_eq!(
trace,
ExecutionTrace::from(vec![
scalar(json!([{"p":"peer2","v":2},{"p":"peer3","v":3},{"p":"peer4"}])),
scalar_number(12),
scalar!(
json!([{"p":"peer2","v":2},{"p":"peer3","v":3},{"p":"peer4"}]),
peer = "peer1",
service = "service..0",
function = "func"
),
scalar!(
12,
peer = "peer2",
service = "service..1",
function = "func",
args = vec![2, 1]
),
request_sent_by("peer2"),
])
);
@ -451,8 +494,19 @@ mod tests {
assert_eq!(
trace,
ExecutionTrace::from(vec![
scalar(json!([{"p":"peer2","v":2},{"p":"peer3","v":3},{"p":"peer4"}])),
scalar_number(12),
scalar!(
json!([{"p":"peer2","v":2},{"p":"peer3","v":3},{"p":"peer4"}]),
peer = "peer1",
service = "service..0",
function = "func"
),
scalar!(
12,
peer = "peer2",
service = "service..1",
function = "func",
args = vec![2, 1]
),
request_sent_by("peer2"),
])
);
@ -489,7 +543,16 @@ mod tests {
assert_eq!(
trace_from_result(outcome1),
ExecutionTrace::from(vec![scalar_number(1), request_sent_by("peer1"),]),
ExecutionTrace::from(vec![
scalar!(
1,
peer = "peer1",
service = "service..0",
function = "func",
args = vec![1, 22]
),
request_sent_by("peer1"),
]),
)
}
@ -525,11 +588,21 @@ mod tests {
assert_eq!(
trace_from_result(&trace1),
ExecutionTrace::from(vec![scalar_number(42)]),
ExecutionTrace::from(vec![unused!(
42,
peer = peer,
service = "service..0",
function = "function"
)]),
);
assert_eq!(
trace_from_result(&trace2),
ExecutionTrace::from(vec![scalar_number(24)]),
ExecutionTrace::from(vec![unused!(
24,
peer = peer,
service = "service..1",
function = "function"
)]),
);
}
@ -571,11 +644,21 @@ mod tests {
assert_eq!(
trace_from_result(&trace1),
ExecutionTrace::from(vec![scalar_number(42)]),
ExecutionTrace::from(vec![unused!(
42,
peer = peer,
service = "service",
function = "function"
),]),
);
assert_eq!(
trace_from_result(&trace2),
ExecutionTrace::from(vec![scalar_number(24)]),
ExecutionTrace::from(vec![unused!(
24,
peer = peer,
service = "service",
function = "function"
),]),
);
}
@ -624,7 +707,13 @@ mod tests {
assert_eq!(
trace_from_result(outcome),
ExecutionTrace::from(vec![scalar_string("service"),]),
ExecutionTrace::from(vec![scalar!(
"service",
peer = "peer1",
service = "service..0",
function = "func",
args = vec![1, 22]
),]),
)
}
@ -648,7 +737,13 @@ mod tests {
assert_eq!(
trace_from_result(outcome),
ExecutionTrace::from(vec![scalar_string("func"),]),
ExecutionTrace::from(vec![scalar!(
"func",
peer = "peer1",
service = "service..0",
function = "func",
args = vec![1, 22]
),]),
)
}
@ -672,7 +767,13 @@ mod tests {
assert_eq!(
trace_from_result(outcome),
ExecutionTrace::from(vec![scalar_number(22),]),
ExecutionTrace::from(vec![scalar!(
22,
peer = "peer1",
service = "service..0",
function = "func",
args = vec![1, 22]
),]),
)
}
@ -696,7 +797,8 @@ mod tests {
assert_eq!(
trace_from_result(outcome),
ExecutionTrace::from(vec![scalar(json!([[{
ExecutionTrace::from(vec![scalar!(
json!([[{
"function_name": "",
"json_path": "",
"peer_pk": "peer1",
@ -706,7 +808,12 @@ mod tests {
"json_path": "",
"peer_pk": "peer1",
"service_id": "",
}]]))]),
}]]),
peer = peer,
service = "service..0",
function = "func",
args = vec![1, 22]
)]),
)
}
}