Skip to content

Commit

Permalink
feat(air)!: change fold over canon map iterator contents [fixes VM-62…
Browse files Browse the repository at this point in the history
…0] (#843)
  • Loading branch information
raftedproc authored Jun 25, 2024
1 parent 7eb9957 commit 325cce2
Show file tree
Hide file tree
Showing 5 changed files with 2,643 additions and 245 deletions.
17 changes: 15 additions & 2 deletions air/src/execution_step/instructions/fold/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

use super::*;
use crate::execution_step::execution_context::stream_map_key::StreamMapKey;
use crate::execution_step::value_types::populate_tetraplet_with_lambda;
use crate::execution_step::value_types::IterableValue;
use crate::execution_step::CatchableError;
Expand All @@ -26,6 +27,7 @@ use crate::SecurityTetraplet;
use air_interpreter_data::Provenance;
use air_parser::ast;

use std::collections::HashSet;
use std::ops::Deref;
use std::rc::Rc;

Expand Down Expand Up @@ -104,10 +106,21 @@ pub(crate) fn create_canon_stream_map_iterable_value(
return Ok(FoldIterableScalar::Empty);
}

// TODO: this one is a relatively long operation and will be refactored in Boxed Value
// TODO: this one is a relatively heavy operation and will be refactored in Boxed Value
// Can not create iterable from existing CanonStreamMap b/c CSM contains a map with
// a limited lifetime but the boxed value needs static lifetime.
let values = canon_stream_map.iter().cloned().collect::<Vec<_>>();
let mut met_keys = HashSet::new();
let mut values = vec![];

for val in canon_stream_map.canon_stream_map.iter().rev() {
if let Some(map_key) = StreamMapKey::from_kvpair_owned(val) {
if !met_keys.contains(&map_key) {
met_keys.insert(map_key);
values.push(val.clone());
}
}
}

let iterable_ingredients = CanonStreamMapIterableIngredients::init(values);
let iterable = Box::new(iterable_ingredients);
Ok(FoldIterableScalar::ScalarBased(iterable))
Expand Down
4 changes: 3 additions & 1 deletion air/src/execution_step/value_types/canon_stream_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ impl CanonStreamMap {
json_map.into()
}

pub(crate) fn iter(&self) -> impl ExactSizeIterator<Item = &ValueAggregate> {
pub(crate) fn iter(
&self,
) -> impl ExactSizeIterator<Item = &ValueAggregate> + DoubleEndedIterator<Item = &ValueAggregate> {
self.values.iter()
}

Expand Down
180 changes: 18 additions & 162 deletions air/tests/test_module/instructions/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -947,114 +947,24 @@ async fn fold_canon_stream_map() {
let vm_1_peer_name = "vm_1_peer_id";
let vm_1_peer_id = at(vm_1_peer_name);

let script = format!(
r#"
(seq
(seq
(ap ("key" "value1") %map)
(ap (-42 "value2") %map)
)
(seq
(canon "{vm_1_peer_name}" %map #%canon_map)
(fold #%canon_map iter
(seq
(call "{vm_1_peer_name}" ("m" "f") [iter] scalar) ; behaviour = echo
(next iter)
)
)
)
)
"#
);

let executor = AirScriptExecutor::from_annotated(TestRunParameters::from_init_peer_id(vm_1_peer_name), &script)
.await
.expect("invalid test AIR script");
let result = executor.execute_all(vm_1_peer_name).await.unwrap();

let actual_trace = trace_from_result(&result.last().unwrap());

let mut cid_tracker: ExecutionCidState = ExecutionCidState::new();
let tetraplet = json!({"function_name": "", "lens": "", "peer_pk": vm_1_peer_id, "service_id": ""});

let map_value_1 = json!({"key": "key", "value": "value1"});
let map_value_2 = json!({"key": -42, "value": "value2"});

let expected_trace: Vec<ExecutedState> = vec![
executed_state::ap(0),
executed_state::ap(0),
canon_tracked(
json!({"tetraplet": tetraplet,
"values": [
{
"result": map_value_1,
"tetraplet": tetraplet,
"provenance": Provenance::Literal,
},
{
"result": map_value_2,
"tetraplet": tetraplet,
"provenance": Provenance::Literal,
},
]}),
&mut cid_tracker,
),
scalar_tracked!(
map_value_1.clone(),
cid_tracker,
peer = &vm_1_peer_id,
service = "m..0",
function = "f",
args = [map_value_1]
),
scalar_tracked!(
map_value_2.clone(),
cid_tracker,
peer = vm_1_peer_id,
service = "m..0",
function = "f",
args = [map_value_2]
),
];

assert_eq!(&*actual_trace, expected_trace,);
}

/// This test checks that fold over map and fold over canon map both produce
/// the same kvpairs sequences. Please note that call results produced by
/// the folds mentioned differ in their tetraplets b/c testing framework
/// increments service name index for each call used.
#[tokio::test]
async fn fold_map_and_canon_map_orders_are_same() {
let vm_1_peer_name = "vm_1_peer_id";
let vm_1_peer_id = at(vm_1_peer_name);

let script = format!(
r#"
(seq
(seq
(seq
(ap ("key" "value1") %map)
(ap (-42 "value2") %map)
(ap ("key" "value4") %map)
(ap (-42 "value3") %map)
)
(seq
(ap (42 "value3") %map)
(ap ("other" "value4") %map)
(ap (-42 "value2") %map)
(ap ("key" "value1") %map)
)
)
(seq
(seq
(canon "{vm_1_peer_name}" %map #%canon_map)
(fold #%canon_map iter
(seq
(call "{vm_1_peer_name}" ("m" "f") [iter] scalar) ; behaviour = echo
(next iter)
)
)
)
(fold %map iter
(canon "{vm_1_peer_name}" %map #%canon_map)
(fold #%canon_map iter
(seq
(call "{vm_1_peer_name}" ("m" "f") [iter] scalar1) ; behaviour = echo
(call "{vm_1_peer_name}" ("m" "f") [iter] scalar) ; behaviour = echo
(next iter)
)
)
Expand All @@ -1073,10 +983,10 @@ async fn fold_map_and_canon_map_orders_are_same() {
let mut cid_tracker: ExecutionCidState = ExecutionCidState::new();
let tetraplet = json!({"function_name": "", "lens": "", "peer_pk": vm_1_peer_id, "service_id": ""});

let map_value_1 = json!({"key": "key", "value": "value1"});
let map_value_2 = json!({"key": -42, "value": "value2"});
let map_value_3 = json!({"key": 42, "value": "value3"});
let map_value_4 = json!({"key": "other", "value": "value4"});
let map_value_1 = json!({"key": "key", "value": "value1"});
let map_value_3 = json!({"key": -42, "value": "value3"});
let map_value_4 = json!({"key": "key", "value": "value4"});

let expected_trace: Vec<ExecutedState> = vec![
executed_state::ap(0),
Expand All @@ -1086,23 +996,23 @@ async fn fold_map_and_canon_map_orders_are_same() {
canon_tracked(
json!({"tetraplet": tetraplet,
"values": [
{
"result": map_value_1,
{
"result": map_value_4,
"tetraplet": tetraplet,
"provenance": Provenance::Literal,
},
{
"result": map_value_2,
"result": map_value_3,
"tetraplet": tetraplet,
"provenance": Provenance::Literal,
},
{
"result": map_value_3,
"result": map_value_2,
"tetraplet": tetraplet,
"provenance": Provenance::Literal,
},
{
"result": map_value_4,
"result": map_value_1,
"tetraplet": tetraplet,
"provenance": Provenance::Literal,
},
Expand All @@ -1115,71 +1025,17 @@ async fn fold_map_and_canon_map_orders_are_same() {
peer = &vm_1_peer_id,
service = "m..0",
function = "f",
args = [map_value_1.clone()]
),
scalar_tracked!(
map_value_2.clone(),
cid_tracker,
peer = &vm_1_peer_id,
service = "m..0",
function = "f",
args = [map_value_2.clone()]
),
scalar_tracked!(
map_value_3.clone(),
cid_tracker,
peer = &vm_1_peer_id,
service = "m..0",
function = "f",
args = [map_value_3.clone()]
),
scalar_tracked!(
map_value_4.clone(),
cid_tracker,
peer = &vm_1_peer_id,
service = "m..0",
function = "f",
args = [map_value_4.clone()]
),
fold(vec![
subtrace_lore(0, subtrace_desc(10, 1), subtrace_desc(14, 0)),
subtrace_lore(1, subtrace_desc(11, 1), subtrace_desc(14, 0)),
subtrace_lore(2, subtrace_desc(12, 1), subtrace_desc(14, 0)),
subtrace_lore(3, subtrace_desc(13, 1), subtrace_desc(14, 0)),
]),
scalar_tracked!(
map_value_1.clone(),
cid_tracker,
peer = &vm_1_peer_id,
service = "m..1",
function = "f",
args = [map_value_1]
),
scalar_tracked!(
map_value_2.clone(),
cid_tracker,
peer = &vm_1_peer_id,
service = "m..1",
peer = vm_1_peer_id,
service = "m..0",
function = "f",
args = [map_value_2]
),
scalar_tracked!(
map_value_3.clone(),
cid_tracker,
peer = &vm_1_peer_id,
service = "m..1",
function = "f",
args = [map_value_3]
),
scalar_tracked!(
map_value_4.clone(),
cid_tracker,
peer = &vm_1_peer_id,
service = "m..1",
function = "f",
args = [map_value_4]
),
];

assert_eq!(&*actual_trace, expected_trace);
assert_eq!(&*actual_trace, expected_trace,);
}
Loading

0 comments on commit 325cce2

Please sign in to comment.