Fix tetraplets json path (#220)

This commit is contained in:
Mike Voronov 2022-02-18 18:00:42 +03:00 committed by GitHub
parent f994ce73c8
commit 78a2bc9d58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 174 additions and 119 deletions

View File

@ -33,7 +33,6 @@ use air_parser::ast;
use air_parser::ast::Ap;
use air_trace_handler::MergerApResult;
use std::cell::RefCell;
use std::rc::Rc;
impl<'i> super::ExecutableInstruction<'i> for Ap<'i> {

View File

@ -42,7 +42,7 @@ pub(super) fn apply_to_arg(
fn apply_const(value: impl Into<JValue>, exec_ctx: &ExecutionCtx<'_>, trace_ctx: &TraceHandler) -> ValueAggregate {
let value = Rc::new(value.into());
let tetraplet = SecurityTetraplet::literal_tetraplet(exec_ctx.init_peer_id.as_ref());
let tetraplet = Rc::new(RefCell::new(tetraplet));
let tetraplet = Rc::new(tetraplet);
ValueAggregate::new(value, tetraplet, trace_ctx.trace_pos())
}
@ -111,6 +111,7 @@ fn apply_scalar_wl_impl(
) -> ExecutionResult<ValueAggregate> {
let variable = Variable::scalar(scalar_name, position);
let (jvalue, tetraplet) = apply_lambda(variable, lambda, exec_ctx)?;
let tetraplet = Rc::new(tetraplet);
let result = ValueAggregate::new(Rc::new(jvalue), tetraplet, trace_ctx.trace_pos());
Ok(result)

View File

@ -26,7 +26,7 @@ use super::ExecutionError;
use super::ExecutionResult;
use super::TraceHandler;
use crate::execution_step::Joinable;
use crate::execution_step::RSecurityTetraplet;
use crate::execution_step::RcSecurityTetraplet;
use crate::joinable;
use crate::log_instruction;
@ -52,7 +52,7 @@ fn set_last_error<'i>(
call: &Call<'i>,
exec_ctx: &mut ExecutionCtx<'i>,
execution_error: ExecutionError,
tetraplet: Option<RSecurityTetraplet>,
tetraplet: Option<RcSecurityTetraplet>,
) -> ExecutionError {
let catchable_error = match execution_error {
ExecutionError::Catchable(catchable) => catchable,
@ -63,7 +63,7 @@ fn set_last_error<'i>(
// use tetraplet if they set, because an error could be propagated from data
// (from CallServiceFailed state) and exec_ctx.current_peer_id won't mean
// a peer where the error was occurred
Some(tetraplet) => tetraplet.borrow().peer_pk.clone(),
Some(tetraplet) => tetraplet.peer_pk.clone(),
None => exec_ctx.current_peer_id.to_string(),
};

View File

@ -63,7 +63,7 @@ pub(crate) fn set_local_result<'i>(
pub(crate) fn set_result_from_value<'i>(
value: Value,
tetraplet: RSecurityTetraplet,
tetraplet: RcSecurityTetraplet,
trace_pos: usize,
output: &CallOutputValue<'i>,
exec_ctx: &mut ExecutionCtx<'i>,

View File

@ -17,7 +17,7 @@
use super::*;
use crate::execution_step::air::call::call_result_setter::set_result_from_value;
use crate::execution_step::CatchableError;
use crate::execution_step::RSecurityTetraplet;
use crate::execution_step::RcSecurityTetraplet;
use air_interpreter_data::CallResult;
use air_interpreter_data::Sender;
@ -34,7 +34,7 @@ pub(crate) struct StateDescriptor {
/// This function looks at the existing call state, validates it,
/// and returns Ok(true) if the call should be executed further.
pub(super) fn handle_prev_state<'i>(
tetraplet: &RSecurityTetraplet,
tetraplet: &RcSecurityTetraplet,
output: &CallOutputValue<'i>,
prev_result: CallResult,
trace_pos: usize,
@ -59,7 +59,7 @@ 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, output, call_result, exec_ctx, trace_ctx)?;
update_state_with_service_result(tetraplet.clone(), output, call_result, exec_ctx, trace_ctx)?;
Ok(StateDescriptor::executed())
}
// result hasn't been prepared yet
@ -71,7 +71,7 @@ pub(super) fn handle_prev_state<'i>(
}
RequestSentBy(..) => {
// check whether current node can execute this call
let is_current_peer = tetraplet.borrow().peer_pk.as_str() == exec_ctx.current_peer_id.as_str();
let is_current_peer = tetraplet.peer_pk.as_str() == exec_ctx.current_peer_id.as_str();
if is_current_peer {
return Ok(StateDescriptor::can_execute_now(prev_result));
}
@ -94,7 +94,7 @@ use crate::execution_step::ValueAggregate;
use crate::JValue;
fn update_state_with_service_result<'i>(
tetraplet: &RSecurityTetraplet,
tetraplet: RcSecurityTetraplet,
output: &CallOutputValue<'i>,
service_result: CallServiceResult,
exec_ctx: &mut ExecutionCtx<'i>,
@ -107,7 +107,7 @@ fn update_state_with_service_result<'i>(
let trace_pos = trace_ctx.trace_pos();
let executed_result = ValueAggregate::new(result, tetraplet.clone(), trace_pos);
let executed_result = ValueAggregate::new(result, tetraplet, trace_pos);
let new_call_result = set_local_result(executed_result, output, exec_ctx)?;
trace_ctx.meet_call_end(new_call_result);

View File

@ -20,8 +20,8 @@ use super::call_result_setter::*;
use super::prev_result_handler::*;
use super::triplet::resolve;
use super::*;
use crate::execution_step::RSecurityTetraplet;
use crate::execution_step::SecurityTetraplets;
use crate::execution_step::RcSecurityTetraplet;
use crate::execution_step::RcSecurityTetraplets;
use crate::execution_step::UncatchableError;
use crate::trace_to_exec_err;
use crate::JValue;
@ -33,13 +33,12 @@ use air_parser::ast;
use air_trace_handler::MergerCallResult;
use air_trace_handler::TraceHandler;
use std::cell::RefCell;
use std::rc::Rc;
/// Represents Call instruction with resolved internal parts.
#[derive(Debug, Clone, PartialEq)]
pub(super) struct ResolvedCall<'i> {
tetraplet: RSecurityTetraplet,
tetraplet: RcSecurityTetraplet,
function_arg_paths: Rc<Vec<ast::Value<'i>>>,
output: ast::CallOutputValue<'i>,
}
@ -47,7 +46,7 @@ pub(super) struct ResolvedCall<'i> {
#[derive(Debug, Clone, PartialEq)]
struct ResolvedArguments {
call_arguments: String,
tetraplets: Vec<SecurityTetraplets>,
tetraplets: Vec<RcSecurityTetraplets>,
}
impl<'i> ResolvedCall<'i> {
@ -55,7 +54,7 @@ impl<'i> ResolvedCall<'i> {
pub(super) fn new(raw_call: &Call<'i>, exec_ctx: &ExecutionCtx<'i>) -> ExecutionResult<Self> {
let triplet = resolve(&raw_call.triplet, exec_ctx)?;
let tetraplet = SecurityTetraplet::from_triplet(triplet);
let tetraplet = Rc::new(RefCell::new(tetraplet));
let tetraplet = Rc::new(tetraplet);
check_output_name(&raw_call.output, exec_ctx)?;
@ -87,7 +86,7 @@ impl<'i> ResolvedCall<'i> {
}
// call can be executed only on peers with such peer_id
let tetraplet = &self.tetraplet.borrow();
let tetraplet = &self.tetraplet;
if tetraplet.peer_pk.as_str() != exec_ctx.current_peer_id.as_str() {
set_remote_call_result(tetraplet.peer_pk.clone(), exec_ctx, trace_ctx);
return Ok(());
@ -116,7 +115,7 @@ impl<'i> ResolvedCall<'i> {
Ok(())
}
pub(super) fn as_tetraplet(&self) -> RSecurityTetraplet {
pub(super) fn as_tetraplet(&self) -> RcSecurityTetraplet {
self.tetraplet.clone()
}

View File

@ -21,7 +21,7 @@ use crate::execution_step::execution_context::check_error_object;
use crate::execution_step::resolver::resolve_ast_scalar_wl;
use crate::execution_step::CatchableError;
use crate::execution_step::LastError;
use crate::execution_step::RSecurityTetraplet;
use crate::execution_step::RcSecurityTetraplet;
use crate::log_instruction;
use crate::ExecutionError;
use crate::JValue;
@ -30,7 +30,6 @@ use air_parser::ast;
use air_parser::ast::Fail;
use polyplets::SecurityTetraplet;
use std::cell::RefCell;
use std::rc::Rc;
impl<'i> super::ExecutableInstruction<'i> for Fail<'i> {
@ -72,7 +71,7 @@ fn fail_with_literals<'i>(
);
let literal_tetraplet = SecurityTetraplet::literal_tetraplet(exec_ctx.init_peer_id.as_ref());
let literal_tetraplet = Rc::new(RefCell::new(literal_tetraplet));
let literal_tetraplet = Rc::new(literal_tetraplet);
fail_with_error_object(exec_ctx, Rc::new(error_object), Some(literal_tetraplet))
}
@ -90,7 +89,7 @@ fn fail_with_last_error(exec_ctx: &mut ExecutionCtx<'_>) -> ExecutionResult<()>
fn fail_with_error_object(
exec_ctx: &mut ExecutionCtx<'_>,
error: Rc<JValue>,
tetraplet: Option<RSecurityTetraplet>,
tetraplet: Option<RcSecurityTetraplet>,
) -> ExecutionResult<()> {
exec_ctx
.last_error_descriptor

View File

@ -16,13 +16,14 @@
use super::*;
use crate::execution_step::CatchableError;
use crate::execution_step::RSecurityTetraplet;
use crate::JValue;
use crate::LambdaAST;
use crate::SecurityTetraplet;
use air_parser::ast;
use std::ops::Deref;
use std::rc::Rc;
// TODO: refactor this file after switching to boxed value
@ -133,12 +134,13 @@ fn create_scalar_lambda_iterable<'ctx>(
match exec_ctx.scalars.get(scalar_name)? {
ScalarRef::Value(variable) => {
let jvalues = select_from_scalar(&variable.result, lambda.iter(), exec_ctx)?;
from_jvalue(jvalues, variable.tetraplet.clone(), lambda)
let tetraplet = variable.tetraplet.deref().clone();
from_jvalue(jvalues, tetraplet, lambda)
}
ScalarRef::IterableValue(fold_state) => {
let iterable_value = fold_state.iterable.peek().unwrap();
let jvalue = iterable_value.apply_lambda(lambda, exec_ctx)?;
let tetraplet = as_tetraplet(&iterable_value);
let tetraplet = to_tetraplet(&iterable_value);
from_jvalue(jvalue, tetraplet, lambda)
}
@ -148,11 +150,12 @@ fn create_scalar_lambda_iterable<'ctx>(
/// Construct IterableValue from the result and given triplet.
fn from_jvalue(
jvalue: &JValue,
tetraplet: RSecurityTetraplet,
mut tetraplet: SecurityTetraplet,
lambda: &LambdaAST<'_>,
) -> ExecutionResult<FoldIterableScalar> {
let formatted_lambda_ast = air_lambda_ast::format_ast(lambda);
tetraplet.borrow_mut().add_lambda(&formatted_lambda_ast);
tetraplet.add_lambda(&formatted_lambda_ast);
let tetraplet = Rc::new(tetraplet);
let iterable = match jvalue {
JValue::Array(array) => array,
@ -171,7 +174,7 @@ fn from_jvalue(
Ok(iterable)
}
fn as_tetraplet(iterable: &IterableItem<'_>) -> RSecurityTetraplet {
fn to_tetraplet(iterable: &IterableItem<'_>) -> SecurityTetraplet {
use IterableItem::*;
let tetraplet = match iterable {
@ -180,5 +183,5 @@ fn as_tetraplet(iterable: &IterableItem<'_>) -> RSecurityTetraplet {
RcValue((_, tetraplet, _)) => tetraplet,
};
(*tetraplet).clone()
(*tetraplet).deref().clone()
}

View File

@ -24,7 +24,7 @@ pub(crate) use resolved_call::IterableResolvedCall;
pub(crate) use vec_resolved_call::IterableVecResolvedCall;
use super::ValueAggregate;
use crate::execution_step::RSecurityTetraplet;
use crate::execution_step::RcSecurityTetraplet;
use crate::JValue;
use std::rc::Rc;
@ -56,9 +56,9 @@ pub(crate) trait Iterable<'ctx> {
/// through, i.e., it is the `iterable` in the `(fold collection iterable instruction)` statement.
#[derive(Clone, Debug, Eq, PartialEq)]
pub(crate) enum IterableItem<'ctx> {
RefRef((&'ctx JValue, &'ctx RSecurityTetraplet, usize)),
RefValue((&'ctx JValue, RSecurityTetraplet, usize)),
RcValue((Rc<JValue>, RSecurityTetraplet, usize)),
RefRef((&'ctx JValue, &'ctx RcSecurityTetraplet, usize)),
RefValue((&'ctx JValue, RcSecurityTetraplet, usize)),
RcValue((Rc<JValue>, RcSecurityTetraplet, usize)),
}
impl IterableItem<'_> {

View File

@ -16,7 +16,7 @@
use super::Iterable;
use super::IterableItem;
use crate::execution_step::RSecurityTetraplet;
use crate::execution_step::RcSecurityTetraplet;
use crate::foldable_next;
use crate::foldable_prev;
use crate::JValue;
@ -26,12 +26,12 @@ use crate::JValue;
pub(crate) struct IterableLambdaResult {
pub(crate) jvalues: Vec<JValue>,
// consider adding index for each tetraplet
pub(crate) tetraplet: RSecurityTetraplet,
pub(crate) tetraplet: RcSecurityTetraplet,
pub(crate) cursor: usize,
}
impl IterableLambdaResult {
pub(crate) fn init(jvalues: Vec<JValue>, tetraplet: RSecurityTetraplet) -> Self {
pub(crate) fn init(jvalues: Vec<JValue>, tetraplet: RcSecurityTetraplet) -> Self {
Self {
jvalues,
tetraplet,

View File

@ -16,7 +16,7 @@
use super::Iterable;
use super::IterableItem;
use crate::execution_step::SecurityTetraplets;
use crate::execution_step::RcSecurityTetraplets;
use crate::foldable_next;
use crate::foldable_prev;
use crate::JValue;
@ -25,13 +25,13 @@ use crate::JValue;
#[derive(Clone, Debug, Eq, PartialEq)]
pub(crate) struct IterableVecJsonPathResult {
pub(crate) jvalues: Vec<JValue>,
pub(crate) tetraplets: SecurityTetraplets,
pub(crate) tetraplets: RcSecurityTetraplets,
pub(crate) cursor: usize,
}
impl IterableVecJsonPathResult {
#[allow(dead_code)]
pub(crate) fn init(jvalues: Vec<JValue>, tetraplets: SecurityTetraplets) -> Self {
pub(crate) fn init(jvalues: Vec<JValue>, tetraplets: RcSecurityTetraplets) -> Self {
// TODO: add assert on length
Self {
jvalues,

View File

@ -25,10 +25,10 @@ use super::ExecutionResult;
use super::ValueAggregate;
use crate::execution_step::lambda_applier::*;
use crate::execution_step::ExecutionCtx;
use crate::execution_step::RSecurityTetraplet;
use crate::execution_step::SecurityTetraplets;
use crate::execution_step::RcSecurityTetraplets;
use crate::JValue;
use crate::LambdaAST;
use crate::SecurityTetraplet;
pub(crate) use stream::StreamJvaluableIngredients;
@ -44,7 +44,7 @@ pub(crate) trait JValuable {
&self,
lambda: &LambdaAST<'_>,
exec_ctx: &ExecutionCtx<'i>,
) -> ExecutionResult<(&JValue, RSecurityTetraplet)>;
) -> ExecutionResult<(&JValue, SecurityTetraplet)>;
/// Return internal value as borrowed if it's possible, owned otherwise.
fn as_jvalue(&self) -> Cow<'_, JValue>;
@ -53,5 +53,5 @@ pub(crate) trait JValuable {
fn into_jvalue(self: Box<Self>) -> JValue;
/// Return tetraplets associating with internal value.
fn as_tetraplets(&self) -> SecurityTetraplets;
fn as_tetraplets(&self) -> RcSecurityTetraplets;
}

View File

@ -19,10 +19,10 @@ use super::ExecutionResult;
use super::JValuable;
use super::ValueAggregate;
use crate::execution_step::ExecutionCtx;
use crate::execution_step::RSecurityTetraplet;
use crate::execution_step::SecurityTetraplets;
use crate::execution_step::RcSecurityTetraplets;
use crate::JValue;
use crate::LambdaAST;
use crate::SecurityTetraplet;
use air_lambda_ast::format_ast;
@ -40,12 +40,13 @@ impl JValuable for std::cell::Ref<'_, Vec<ValueAggregate>> {
&self,
lambda: &LambdaAST<'_>,
exec_ctx: &ExecutionCtx<'i>,
) -> ExecutionResult<(&JValue, RSecurityTetraplet)> {
) -> ExecutionResult<(&JValue, SecurityTetraplet)> {
let stream_iter = self.iter().map(|r| r.result.deref());
let select_result = select_from_stream(stream_iter, lambda, exec_ctx)?;
let tetraplet = self[select_result.tetraplet_idx].tetraplet.clone();
tetraplet.borrow_mut().add_lambda(&format_ast(lambda));
let tetraplet = &self[select_result.tetraplet_idx].tetraplet;
let mut tetraplet = tetraplet.as_ref().clone();
tetraplet.add_lambda(&format_ast(lambda));
Ok((select_result.result, tetraplet))
}
@ -60,7 +61,7 @@ impl JValuable for std::cell::Ref<'_, Vec<ValueAggregate>> {
JValue::Array(jvalue_array)
}
fn as_tetraplets(&self) -> SecurityTetraplets {
fn as_tetraplets(&self) -> RcSecurityTetraplets {
self.iter().map(|r| r.tetraplet.clone()).collect::<Vec<_>>()
}
}

View File

@ -20,9 +20,9 @@ use super::LambdaAST;
use super::LambdaError::EmptyStream;
use crate::execution_step::CatchableError::LambdaApplierError;
use crate::execution_step::ExecutionCtx;
use crate::execution_step::RSecurityTetraplet;
use crate::execution_step::SecurityTetraplets;
use crate::execution_step::RcSecurityTetraplets;
use crate::JValue;
use crate::SecurityTetraplet;
use std::borrow::Cow;
@ -36,7 +36,7 @@ impl JValuable for () {
&self,
_lambda: &LambdaAST<'_>,
_exec_ctx: &ExecutionCtx<'i>,
) -> ExecutionResult<(&JValue, RSecurityTetraplet)> {
) -> ExecutionResult<(&JValue, SecurityTetraplet)> {
// applying lambda to an empty stream will produce a join behaviour
Err(LambdaApplierError(EmptyStream).into())
}
@ -49,7 +49,7 @@ impl JValuable for () {
JValue::Array(vec![])
}
fn as_tetraplets(&self) -> SecurityTetraplets {
fn as_tetraplets(&self) -> RcSecurityTetraplets {
vec![]
}
}

View File

@ -20,10 +20,11 @@ use super::IterableItem;
use super::JValuable;
use super::LambdaAST;
use crate::execution_step::ExecutionCtx;
use crate::execution_step::RSecurityTetraplet;
use crate::execution_step::SecurityTetraplets;
use crate::execution_step::RcSecurityTetraplets;
use crate::JValue;
use crate::SecurityTetraplet;
use air_lambda_ast::format_ast;
use std::borrow::Cow;
use std::ops::Deref;
@ -45,7 +46,7 @@ impl<'ctx> JValuable for IterableItem<'ctx> {
&self,
lambda: &LambdaAST<'_>,
exec_ctx: &ExecutionCtx<'i>,
) -> ExecutionResult<(&JValue, RSecurityTetraplet)> {
) -> ExecutionResult<(&JValue, SecurityTetraplet)> {
use super::IterableItem::*;
let (jvalue, tetraplet) = match self {
@ -55,7 +56,10 @@ impl<'ctx> JValuable for IterableItem<'ctx> {
};
let selected_value = select_from_scalar(jvalue, lambda.iter(), exec_ctx)?;
Ok((selected_value, tetraplet.clone()))
let mut tetraplet = tetraplet.as_ref().clone();
tetraplet.add_lambda(&format_ast(lambda));
Ok((selected_value, tetraplet))
}
fn as_jvalue(&self) -> Cow<'_, JValue> {
@ -78,7 +82,7 @@ impl<'ctx> JValuable for IterableItem<'ctx> {
}
}
fn as_tetraplets(&self) -> SecurityTetraplets {
fn as_tetraplets(&self) -> RcSecurityTetraplets {
use super::IterableItem::*;
// these clones are needed because rust-sdk allows passing arguments only by value

View File

@ -20,9 +20,9 @@ use super::JValuable;
use super::LambdaAST;
use super::ValueAggregate;
use crate::execution_step::ExecutionCtx;
use crate::execution_step::RSecurityTetraplet;
use crate::execution_step::SecurityTetraplets;
use crate::execution_step::RcSecurityTetraplets;
use crate::JValue;
use crate::SecurityTetraplet;
use air_lambda_ast::format_ast;
@ -39,10 +39,10 @@ impl JValuable for ValueAggregate {
&self,
lambda: &LambdaAST<'_>,
exec_ctx: &ExecutionCtx<'i>,
) -> ExecutionResult<(&JValue, RSecurityTetraplet)> {
) -> ExecutionResult<(&JValue, SecurityTetraplet)> {
let selected_value = select_from_scalar(&self.result, lambda.iter(), exec_ctx)?;
let tetraplet = self.tetraplet.clone();
tetraplet.borrow_mut().add_lambda(&format_ast(lambda));
let mut tetraplet = self.tetraplet.as_ref().clone();
tetraplet.add_lambda(&format_ast(lambda));
Ok((selected_value, tetraplet))
}
@ -55,7 +55,7 @@ impl JValuable for ValueAggregate {
self.result.deref().clone()
}
fn as_tetraplets(&self) -> SecurityTetraplets {
fn as_tetraplets(&self) -> RcSecurityTetraplets {
vec![self.tetraplet.clone()]
}
}

View File

@ -20,10 +20,10 @@ use super::JValuable;
use crate::execution_step::boxed_value::Generation;
use crate::execution_step::boxed_value::Stream;
use crate::execution_step::ExecutionCtx;
use crate::execution_step::RSecurityTetraplet;
use crate::execution_step::SecurityTetraplets;
use crate::execution_step::RcSecurityTetraplets;
use crate::JValue;
use crate::LambdaAST;
use crate::SecurityTetraplet;
use air_lambda_ast::format_ast;
@ -50,14 +50,14 @@ impl JValuable for StreamJvaluableIngredients<'_> {
&self,
lambda: &LambdaAST<'_>,
exec_ctx: &ExecutionCtx<'i>,
) -> ExecutionResult<(&JValue, RSecurityTetraplet)> {
) -> ExecutionResult<(&JValue, SecurityTetraplet)> {
let iter = self.iter()?.map(|v| v.result.deref());
let select_result = select_from_stream(iter, lambda, exec_ctx)?;
// unwrap is safe here because each value has a tetraplet and a lambda always returns a valid index
let resolved_call = self.iter()?.nth(select_result.tetraplet_idx).unwrap();
let tetraplet = resolved_call.tetraplet.clone();
tetraplet.borrow_mut().add_lambda(&format_ast(lambda));
let mut tetraplet = resolved_call.tetraplet.as_ref().clone();
tetraplet.add_lambda(&format_ast(lambda));
Ok((select_result.result, tetraplet))
}
@ -71,7 +71,7 @@ impl JValuable for StreamJvaluableIngredients<'_> {
self.stream.as_jvalue(self.generation).unwrap()
}
fn as_tetraplets(&self) -> SecurityTetraplets {
fn as_tetraplets(&self) -> RcSecurityTetraplets {
self.stream
.iter(self.generation)
.unwrap()

View File

@ -16,7 +16,7 @@
use super::JValuable;
use crate::execution_step::FoldState;
use crate::execution_step::RSecurityTetraplet;
use crate::execution_step::RcSecurityTetraplet;
use crate::JValue;
use serde::Deserialize;
@ -29,7 +29,7 @@ use std::rc::Rc;
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct ValueAggregate {
pub result: Rc<JValue>,
pub tetraplet: RSecurityTetraplet,
pub tetraplet: RcSecurityTetraplet,
pub trace_pos: usize,
}
@ -51,7 +51,7 @@ impl<'i> ScalarRef<'i> {
}
impl ValueAggregate {
pub(crate) fn new(result: Rc<JValue>, tetraplet: RSecurityTetraplet, trace_pos: usize) -> Self {
pub(crate) fn new(result: Rc<JValue>, tetraplet: RcSecurityTetraplet, trace_pos: usize) -> Self {
Self {
result,
tetraplet,

View File

@ -15,7 +15,7 @@
*/
use super::LastErrorObjectError;
use crate::execution_step::RSecurityTetraplet;
use crate::execution_step::RcSecurityTetraplet;
use crate::JValue;
use serde::Deserialize;
@ -40,7 +40,7 @@ pub struct LastError {
pub error: Rc<JValue>,
/// Tetraplet that identify host where the error occurred.
pub tetraplet: Option<RSecurityTetraplet>,
pub tetraplet: Option<RcSecurityTetraplet>,
}
pub(crate) fn error_from_raw_fields(error_code: i64, error_message: &str, instruction: &str, peer_id: &str) -> JValue {

View File

@ -17,7 +17,7 @@
use super::last_error_definition::error_from_raw_fields;
use super::LastError;
use crate::execution_step::LastErrorAffectable;
use crate::execution_step::RSecurityTetraplet;
use crate::execution_step::RcSecurityTetraplet;
use crate::JValue;
use crate::ToErrorCode;
@ -38,7 +38,7 @@ impl<'s> LastErrorDescriptor {
error: &(impl LastErrorAffectable + ToErrorCode + ToString),
instruction: &str,
peer_id: &str,
tetraplet: Option<RSecurityTetraplet>,
tetraplet: Option<RcSecurityTetraplet>,
) -> bool {
// this check is optimization to prevent creation of an error object in case if error
// couldn't be set
@ -61,14 +61,14 @@ impl<'s> LastErrorDescriptor {
error_message: &str,
instruction: &str,
peer_id: &str,
tetraplet: Option<RSecurityTetraplet>,
tetraplet: Option<RcSecurityTetraplet>,
) -> bool {
let error_object = error_from_raw_fields(error_code, error_message, instruction, peer_id);
self.set_from_error_object(Rc::new(error_object), tetraplet);
true
}
pub(crate) fn set_from_error_object(&mut self, error: Rc<JValue>, tetraplet: Option<RSecurityTetraplet>) {
pub(crate) fn set_from_error_object(&mut self, error: Rc<JValue>, tetraplet: Option<RcSecurityTetraplet>) {
self.last_error = LastError { error, tetraplet };
self.error_can_be_set = false;
}

View File

@ -46,9 +46,8 @@ pub(crate) use execution_context::LastError;
pub(crate) use air_trace_handler::TraceHandler;
use std::cell::RefCell;
use std::rc::Rc;
type ExecutionResult<T> = std::result::Result<T, ExecutionError>;
type RSecurityTetraplet = Rc<RefCell<crate::SecurityTetraplet>>;
type SecurityTetraplets = Vec<RSecurityTetraplet>;
type RcSecurityTetraplet = Rc<crate::SecurityTetraplet>;
type RcSecurityTetraplets = Vec<RcSecurityTetraplet>;

View File

@ -18,4 +18,4 @@ mod resolve;
pub(crate) use resolve::*;
use super::SecurityTetraplets;
use super::RcSecurityTetraplets;

View File

@ -14,28 +14,26 @@
* limitations under the License.
*/
use super::SecurityTetraplets;
use super::RcSecurityTetraplets;
use crate::execution_step::boxed_value::JValuable;
use crate::execution_step::boxed_value::Variable;
use crate::execution_step::execution_context::ExecutionCtx;
use crate::execution_step::lambda_applier::select_from_scalar;
use crate::execution_step::ExecutionResult;
use crate::execution_step::RSecurityTetraplet;
use crate::JValue;
use crate::LambdaAST;
use crate::SecurityTetraplet;
use air_parser::ast;
use crate::execution_step::lambda_applier::select_from_scalar;
use serde_json::json;
use std::cell::RefCell;
use std::rc::Rc;
/// Resolve value to called function arguments.
pub(crate) fn resolve_to_args<'i>(
value: &ast::Value<'i>,
ctx: &ExecutionCtx<'i>,
) -> ExecutionResult<(JValue, SecurityTetraplets)> {
) -> ExecutionResult<(JValue, RcSecurityTetraplets)> {
use ast::Value::*;
match value {
@ -53,10 +51,10 @@ pub(crate) fn resolve_to_args<'i>(
pub(crate) fn prepare_const(
arg: impl Into<JValue>,
ctx: &ExecutionCtx<'_>,
) -> ExecutionResult<(JValue, SecurityTetraplets)> {
) -> ExecutionResult<(JValue, RcSecurityTetraplets)> {
let jvalue = arg.into();
let tetraplet = SecurityTetraplet::literal_tetraplet(ctx.init_peer_id.as_ref());
let tetraplet = Rc::new(RefCell::new(tetraplet));
let tetraplet = Rc::new(tetraplet);
Ok((jvalue, vec![tetraplet]))
}
@ -65,7 +63,7 @@ pub(crate) fn prepare_const(
pub(crate) fn prepare_last_error<'i>(
error_accessor: &Option<LambdaAST<'i>>,
ctx: &ExecutionCtx<'i>,
) -> ExecutionResult<(JValue, SecurityTetraplets)> {
) -> ExecutionResult<(JValue, RcSecurityTetraplets)> {
use crate::LastError;
let LastError { error, tetraplet } = ctx.last_error();
@ -79,7 +77,7 @@ pub(crate) fn prepare_last_error<'i>(
Some(tetraplet) => vec![tetraplet.clone()],
None => {
let tetraplet = SecurityTetraplet::literal_tetraplet(ctx.init_peer_id.as_ref());
let tetraplet = Rc::new(RefCell::new(tetraplet));
let tetraplet = Rc::new(tetraplet);
vec![tetraplet]
}
};
@ -116,10 +114,13 @@ pub(crate) fn resolve_variable<'ctx, 'i>(
pub(crate) fn resolve_ast_variable_wl<'ctx, 'i>(
ast_variable: &ast::VariableWithLambda<'_>,
exec_ctx: &'ctx ExecutionCtx<'i>,
) -> ExecutionResult<(JValue, SecurityTetraplets)> {
) -> ExecutionResult<(JValue, RcSecurityTetraplets)> {
let variable: Variable<'_> = ast_variable.into();
match ast_variable.lambda() {
Some(lambda) => apply_lambda(variable, lambda, exec_ctx).map(|(value, tetraplet)| (value, vec![tetraplet])),
Some(lambda) => apply_lambda(variable, lambda, exec_ctx).map(|(value, tetraplet)| {
let tetraplet = Rc::new(tetraplet);
(value, vec![tetraplet])
}),
None => {
let value = resolve_variable(variable, exec_ctx)?;
let tetraplets = value.as_tetraplets();
@ -131,7 +132,7 @@ pub(crate) fn resolve_ast_variable_wl<'ctx, 'i>(
pub(crate) fn resolve_ast_scalar_wl<'ctx, 'i>(
ast_scalar: &ast::ScalarWithLambda<'_>,
exec_ctx: &'ctx ExecutionCtx<'i>,
) -> ExecutionResult<(JValue, SecurityTetraplets)> {
) -> ExecutionResult<(JValue, RcSecurityTetraplets)> {
// TODO: wrap lambda path with Rc to make this clone cheaper
let variable = ast::VariableWithLambda::Scalar(ast_scalar.clone());
resolve_ast_variable_wl(&variable, exec_ctx)
@ -141,7 +142,7 @@ pub(crate) fn apply_lambda<'i>(
variable: Variable<'_>,
lambda: &LambdaAST<'i>,
exec_ctx: &ExecutionCtx<'i>,
) -> ExecutionResult<(JValue, RSecurityTetraplet)> {
) -> ExecutionResult<(JValue, SecurityTetraplet)> {
let resolved = resolve_variable(variable, exec_ctx)?;
let (jvalue, tetraplet) = resolved.apply_lambda_with_tetraplets(lambda, exec_ctx)?;

View File

@ -17,6 +17,9 @@
use air::SecurityTetraplet;
use air_test_utils::prelude::*;
use fstrings::f;
use fstrings::format_args_f;
use std::cell::RefCell;
use std::rc::Rc;
@ -37,7 +40,7 @@ fn arg_host_function() -> (CallServiceClosure, Rc<RefCell<ArgTetraplets>>) {
}
#[test]
fn simple_fold() {
fn fold_with_inner_call() {
let return_numbers_call_service: CallServiceClosure = Box::new(|_| -> CallServiceResult {
CallServiceResult::ok(json!(["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]))
});
@ -54,10 +57,9 @@ fn simple_fold() {
let service_id = String::from("some_service_id");
let function_name = String::from("some_function_name");
let script = format!(
r#"
let script = f!(r#"
(seq
(call "{}" ("{}" "{}") [] IterableResultPeer1)
(call "{set_variable_vm_peer_id}" ("{service_id}" "{function_name}") [] IterableResultPeer1)
(fold IterableResultPeer1 i
(par
(call i ("local_service_id" "local_fn_name") [i "some_text_literal"] $acc)
@ -65,9 +67,7 @@ fn simple_fold() {
)
)
)
"#,
set_variable_vm_peer_id, service_id, function_name
);
"#);
let init_peer_id = String::from("some_init_peer_id");
let result = checked_call_vm!(set_variable_vm, init_peer_id.clone(), script.clone(), "", "");
@ -99,12 +99,13 @@ fn simple_fold() {
#[test]
fn fold_json_path() {
let return_numbers_call_service: CallServiceClosure = Box::new(|_| -> CallServiceResult {
CallServiceResult::ok(json!({"args": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]}))
});
let variable_numbers = json!({"args": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]});
let set_variable_vm_peer_id = String::from("some_peer_id_1");
let mut set_variable_vm = create_avm(return_numbers_call_service, set_variable_vm_peer_id.clone());
let mut set_variable_vm = create_avm(
set_variable_call_service(variable_numbers),
set_variable_vm_peer_id.clone(),
);
let (arg_host_func, arg_tetraplets) = arg_host_function();
let client_peer_id = String::from("client_id");
@ -112,20 +113,22 @@ fn fold_json_path() {
let service_id = String::from("some_service_id");
let function_name = String::from("some_function_name");
let script = format!(
r#"
let script = f!(r#"
(seq
(call "{}" ("{}" "{}") [] IterableResultPeer1)
(call "{set_variable_vm_peer_id}" ("{service_id}" "{function_name}") [] IterableResultPeer1)
(fold IterableResultPeer1.$.args i
(par
(call "{}" ("local_service_id" "local_fn_name") [i "some_text_literal"] $acc)
(seq
(fold IterableResultPeer1.$.args j
(seq
(call "{client_peer_id}" ("local_service_id" "local_fn_name") [i "some_text_literal"] $acc)
(next j)
)
)
(next i)
)
)
)
"#,
set_variable_vm_peer_id, service_id, function_name, client_peer_id
);
"#);
let init_peer_id = String::from("some_init_peer_id");
let result = checked_call_vm!(set_variable_vm, init_peer_id.clone(), script.clone(), "", "");
@ -146,7 +149,53 @@ fn fold_json_path() {
let expected_tetraplets = vec![vec![first_arg_tetraplet], vec![second_arg_tetraplet]];
let expected_tetraplets = Rc::new(RefCell::new(expected_tetraplets));
checked_call_vm!(client_vm, init_peer_id.clone(), script.clone(), "", result.data);
checked_call_vm!(client_vm, init_peer_id, script, "", result.data);
assert_eq!(arg_tetraplets, expected_tetraplets);
}
#[test]
fn check_tetraplet_works_correctly() {
let return_numbers_call_service: CallServiceClosure = Box::new(|_| -> CallServiceResult {
CallServiceResult::ok(json!({"args": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]}))
});
let set_variable_vm_peer_id = String::from("some_peer_id_1");
let mut set_variable_vm = create_avm(return_numbers_call_service, set_variable_vm_peer_id.clone());
let (arg_host_func, arg_tetraplets) = arg_host_function();
let client_peer_id = String::from("client_id");
let mut client_vm = create_avm(arg_host_func, client_peer_id.clone());
let service_id = String::from("some_service_id");
let function_name = String::from("some_function_name");
let script = f!(r#"
(seq
(call "{set_variable_vm_peer_id}" ("{service_id}" "{function_name}") [] value)
(seq
(call "{client_peer_id}" ("local_service_id" "local_fn_name") [value.$.args value.$.args.[0]])
(call "{client_peer_id}" ("local_service_id" "local_fn_name") [value.$.args value.$.args.[0]])
)
)"#);
let result = checked_call_vm!(set_variable_vm, "", script.clone(), "", "");
let first_arg_tetraplet = SecurityTetraplet {
peer_pk: set_variable_vm_peer_id.clone(),
service_id: service_id.clone(),
function_name: function_name.clone(),
json_path: String::from(".args"),
};
let second_arg_tetraplet = SecurityTetraplet {
peer_pk: set_variable_vm_peer_id.clone(),
service_id,
function_name,
json_path: String::from(".args.[0]"),
};
let expected_tetraplets = vec![vec![first_arg_tetraplet], vec![second_arg_tetraplet]];
let expected_tetraplets = Rc::new(RefCell::new(expected_tetraplets));
checked_call_vm!(client_vm, "", script, "", result.data);
assert_eq!(arg_tetraplets, expected_tetraplets);
}