diff --git a/air/src/execution_step/errors/uncatchable_errors.rs b/air/src/execution_step/errors/uncatchable_errors.rs index 511d993e..2c0d35bb 100644 --- a/air/src/execution_step/errors/uncatchable_errors.rs +++ b/air/src/execution_step/errors/uncatchable_errors.rs @@ -23,6 +23,7 @@ use crate::StreamMapKeyError; use crate::ToErrorCode; use air_interpreter_cid::CidCalculationError; +use air_interpreter_cid::CidRef; use air_interpreter_data::ValueRef; use air_trace_handler::GenerationCompactificationError; use air_trace_handler::IntConversionError; @@ -33,6 +34,8 @@ use strum_macros::EnumDiscriminants; use strum_macros::EnumIter; use thiserror::Error as ThisError; +use std::rc::Rc; + /// Uncatchable errors arisen during AIR script execution. Uncatchable here means that these errors /// couldn't be handled by a xor instruction and their error_code couldn't be used in a match /// instruction. They are similar to JVM runtime errors and some of them could be caught only @@ -90,7 +93,7 @@ pub enum UncatchableError { /// We consider now that every CID should present in the data; /// and not having any CID is considered a non-catching error. #[error("{0} for CID {1:?} not found")] - ValueForCidNotFound(&'static str, String), + ValueForCidNotFound(&'static str, Rc), /// Errors occurred while insertion of a value inside stream that doesn't have corresponding generation. #[error( diff --git a/air/src/execution_step/execution_context/cid_state.rs b/air/src/execution_step/execution_context/cid_state.rs index 0dd5c91e..21ccc623 100644 --- a/air/src/execution_step/execution_context/cid_state.rs +++ b/air/src/execution_step/execution_context/cid_state.rs @@ -71,7 +71,7 @@ impl ExecutionCidState { value: Rc, tetraplet: RcSecurityTetraplet, argument_hash: Rc, - ) -> Result>, UncatchableError> { + ) -> Result, UncatchableError> { let value_cid = self.value_tracker.track_value(value)?; let tetraplet_cid = self.tetraplet_tracker.track_value(tetraplet)?; let service_result_agg = ServiceResultCidAggregate::new(value_cid, argument_hash, tetraplet_cid); @@ -84,7 +84,7 @@ impl ExecutionCidState { pub(crate) fn track_canon_value( &mut self, canon_value: &ValueAggregate, - ) -> Result>, UncatchableError> { + ) -> Result, UncatchableError> { let value_cid = self.value_tracker.track_value(canon_value.get_result().clone())?; let tetraplet = self.tetraplet_tracker.track_value(canon_value.get_tetraplet())?; @@ -97,7 +97,7 @@ impl ExecutionCidState { pub(crate) fn get_value_by_cid(&self, cid: &CID) -> Result, UncatchableError> { self.value_tracker .get(cid) - .ok_or_else(|| UncatchableError::ValueForCidNotFound("value", cid.clone().into())) + .ok_or_else(|| UncatchableError::ValueForCidNotFound("value", cid.get_inner())) } pub(crate) fn get_tetraplet_by_cid( @@ -106,7 +106,7 @@ impl ExecutionCidState { ) -> Result { self.tetraplet_tracker .get(cid) - .ok_or_else(|| UncatchableError::ValueForCidNotFound("tetraplet", cid.clone().into())) + .ok_or_else(|| UncatchableError::ValueForCidNotFound("tetraplet", cid.get_inner())) } pub(crate) fn get_canon_value_by_cid( @@ -116,7 +116,7 @@ impl ExecutionCidState { let canon_aggregate = self .canon_element_tracker .get(cid) - .ok_or_else(|| UncatchableError::ValueForCidNotFound("canon aggregate", cid.clone().into()))?; + .ok_or_else(|| UncatchableError::ValueForCidNotFound("canon aggregate", cid.get_inner()))?; let result = self.get_value_by_cid(&canon_aggregate.value)?; let tetraplet = self.get_tetraplet_by_cid(&canon_aggregate.tetraplet)?; @@ -135,7 +135,7 @@ impl ExecutionCidState { ) -> Result, UncatchableError> { self.canon_result_tracker .get(cid) - .ok_or_else(|| UncatchableError::ValueForCidNotFound("canon result aggregate", cid.clone().into())) + .ok_or_else(|| UncatchableError::ValueForCidNotFound("canon result aggregate", cid.get_inner())) } pub(crate) fn get_service_result_agg_by_cid( @@ -144,7 +144,7 @@ impl ExecutionCidState { ) -> Result, UncatchableError> { self.service_result_agg_tracker .get(cid) - .ok_or_else(|| UncatchableError::ValueForCidNotFound("service result aggregate", cid.clone().into())) + .ok_or_else(|| UncatchableError::ValueForCidNotFound("service result aggregate", cid.get_inner())) } pub(crate) fn resolve_service_info( diff --git a/air/src/execution_step/instructions/call/call_result_setter.rs b/air/src/execution_step/instructions/call/call_result_setter.rs index f95d6d5e..d0c26d43 100644 --- a/air/src/execution_step/instructions/call/call_result_setter.rs +++ b/air/src/execution_step/instructions/call/call_result_setter.rs @@ -65,9 +65,7 @@ pub(crate) fn populate_context_from_peer_service_result<'i>( Ok(CallResult::executed_stream_stub(service_result_agg_cid)) } CallOutputValue::None => { - let value_cid = value_to_json_cid(&*executed_result.result) - .map_err(UncatchableError::from)? - .into(); + let value_cid = value_to_json_cid(&*executed_result.result).map_err(UncatchableError::from)?; Ok(CallResult::executed_unused(value_cid)) } diff --git a/air/src/execution_step/instructions/call/resolved_call.rs b/air/src/execution_step/instructions/call/resolved_call.rs index 4f257da9..4fa2bc05 100644 --- a/air/src/execution_step/instructions/call/resolved_call.rs +++ b/air/src/execution_step/instructions/call/resolved_call.rs @@ -29,6 +29,7 @@ use crate::JValue; use crate::SecurityTetraplet; use air_interpreter_cid::value_to_json_cid; +use air_interpreter_cid::CidRef; use air_interpreter_data::CallResult; use air_interpreter_interface::CallRequestParams; use air_parser::ast; @@ -102,12 +103,8 @@ impl<'i> ResolvedCall<'i> { CheckArgsResult::Ok(args) => Some(args), CheckArgsResult::Joinable(_) => None, }; - let argument_hash: Option> = checked_args.map(|args| { - value_to_json_cid(&args) - .expect("JSON serializer shouldn't fail") - .into_inner() - .into() - }); + let argument_hash: Option> = + checked_args.map(|args| value_to_json_cid(&args).expect("serializer shouldn't fail").get_inner()); let state = self.prepare_current_executed_state(raw_call, argument_hash.as_ref(), exec_ctx, trace_ctx)?; diff --git a/air/src/execution_step/instructions/canon.rs b/air/src/execution_step/instructions/canon.rs index 28d23831..bc53f62b 100644 --- a/air/src/execution_step/instructions/canon.rs +++ b/air/src/execution_step/instructions/canon.rs @@ -34,7 +34,6 @@ use air_parser::AirPos; use air_trace_handler::merger::MergerCanonResult; use std::borrow::Cow; -use std::rc::Rc; impl<'i> super::ExecutableInstruction<'i> for ast::Canon<'i> { #[tracing::instrument(level = "debug", skip(exec_ctx, trace_ctx))] @@ -65,7 +64,7 @@ impl<'i> super::ExecutableInstruction<'i> for ast::Canon<'i> { fn epilog_closure(canon_stream_name: &str) -> Box> { Box::new( move |canon_stream: CanonStream, - canon_result_cid: Rc>, + canon_result_cid: CID, exec_ctx: &mut ExecutionCtx<'_>, trace_ctx: &mut TraceHandler| -> ExecutionResult<()> { diff --git a/air/src/execution_step/instructions/canon_map.rs b/air/src/execution_step/instructions/canon_map.rs index ab129320..ec19a577 100644 --- a/air/src/execution_step/instructions/canon_map.rs +++ b/air/src/execution_step/instructions/canon_map.rs @@ -35,7 +35,6 @@ use air_parser::AirPos; use air_trace_handler::merger::MergerCanonResult; use std::borrow::Cow; -use std::rc::Rc; impl<'i> super::ExecutableInstruction<'i> for ast::CanonMap<'i> { #[tracing::instrument(level = "debug", skip(exec_ctx, trace_ctx))] @@ -65,7 +64,7 @@ impl<'i> super::ExecutableInstruction<'i> for ast::CanonMap<'i> { fn epilog_closure<'closure, 'name: 'closure>(canon_stream_map_name: &'name str) -> Box> { Box::new( move |canon_stream: CanonStream, - canon_result_cid: Rc>, + canon_result_cid: CID, exec_ctx: &mut ExecutionCtx<'_>, trace_ctx: &mut TraceHandler| -> ExecutionResult<()> { diff --git a/air/src/execution_step/instructions/canon_stream_map_scalar.rs b/air/src/execution_step/instructions/canon_stream_map_scalar.rs index 59631cae..d203ad4c 100644 --- a/air/src/execution_step/instructions/canon_stream_map_scalar.rs +++ b/air/src/execution_step/instructions/canon_stream_map_scalar.rs @@ -68,7 +68,7 @@ impl<'i> super::ExecutableInstruction<'i> for ast::CanonStreamMapScalar<'i> { fn epilog_closure<'closure, 'name: 'closure>(scalar_name: &'name str) -> Box> { Box::new( move |canon_stream: CanonStream, - canon_result_cid: Rc>, + canon_result_cid: CID, exec_ctx: &mut ExecutionCtx<'_>, trace_ctx: &mut TraceHandler| -> ExecutionResult<()> { diff --git a/air/src/execution_step/instructions/canon_utils/mod.rs b/air/src/execution_step/instructions/canon_utils/mod.rs index 434f4d37..8ec64291 100644 --- a/air/src/execution_step/instructions/canon_utils/mod.rs +++ b/air/src/execution_step/instructions/canon_utils/mod.rs @@ -27,9 +27,7 @@ use air_interpreter_data::CanonResultCidAggregate; use air_parser::ast::ResolvableToPeerIdVariable; use polyplets::SecurityTetraplet; -use std::rc::Rc; - -pub(crate) type CanonEpilogClosure<'closure> = dyn Fn(CanonStream, Rc>, &mut ExecutionCtx<'_>, &mut TraceHandler) -> ExecutionResult<()> +pub(crate) type CanonEpilogClosure<'closure> = dyn Fn(CanonStream, CID, &mut ExecutionCtx<'_>, &mut TraceHandler) -> ExecutionResult<()> + 'closure; pub(crate) type CreateCanonStreamClosure<'closure> = dyn Fn(&mut ExecutionCtx<'_>, String) -> CanonStream + 'closure; @@ -78,7 +76,7 @@ pub(crate) fn handle_canon_request_sent_by( pub(crate) fn handle_canon_executed( peer_id_var: &ResolvableToPeerIdVariable<'_>, epilog: &CanonEpilogClosure<'_>, - canon_result_cid: Rc>, + canon_result_cid: CID, exec_ctx: &mut ExecutionCtx<'_>, trace_ctx: &mut TraceHandler, ) -> ExecutionResult<()> { @@ -143,7 +141,7 @@ fn create_canon_stream_for_first_time( fn populate_seen_cid_context( exec_ctx: &mut ExecutionCtx<'_>, peer_id: &str, - canon_result_cid: &Rc>, + canon_result_cid: &CID, ) { exec_ctx.record_canon_cid(peer_id, canon_result_cid) } @@ -151,7 +149,7 @@ fn populate_seen_cid_context( fn populate_unseen_cid_context( exec_ctx: &mut ExecutionCtx<'_>, canon_stream: &CanonStream, -) -> ExecutionResult>> { +) -> ExecutionResult> { let value_cids = canon_stream .iter() .map(|canon_value| exec_ctx.cid_state.track_canon_value(canon_value)) diff --git a/air/src/execution_step/value_types/canon_stream.rs b/air/src/execution_step/value_types/canon_stream.rs index 6640fee5..58e83458 100644 --- a/air/src/execution_step/value_types/canon_stream.rs +++ b/air/src/execution_step/value_types/canon_stream.rs @@ -103,11 +103,11 @@ impl fmt::Display for CanonStream { #[derive(Debug, Clone, Deserialize, Serialize)] pub struct CanonStreamWithProvenance { pub(crate) canon_stream: CanonStream, - pub(crate) cid: Rc>, + pub(crate) cid: CID, } impl CanonStreamWithProvenance { - pub(crate) fn new(canon_stream: CanonStream, cid: Rc>) -> Self { + pub(crate) fn new(canon_stream: CanonStream, cid: CID) -> Self { Self { canon_stream, cid } } } diff --git a/air/src/execution_step/value_types/canon_stream_map.rs b/air/src/execution_step/value_types/canon_stream_map.rs index 9302120e..fcefcfed 100644 --- a/air/src/execution_step/value_types/canon_stream_map.rs +++ b/air/src/execution_step/value_types/canon_stream_map.rs @@ -112,11 +112,11 @@ impl fmt::Display for CanonStreamMap<'_> { #[derive(Debug, Clone)] pub struct CanonStreamMapWithProvenance<'a> { pub(crate) canon_stream_map: CanonStreamMap<'a>, - pub(crate) cid: Rc>, + pub(crate) cid: CID, } impl<'a> CanonStreamMapWithProvenance<'a> { - pub(crate) fn new(canon_stream_map: CanonStreamMap<'a>, cid: Rc>) -> Self { + pub(crate) fn new(canon_stream_map: CanonStreamMap<'a>, cid: CID) -> Self { Self { canon_stream_map, cid } } } diff --git a/air/src/execution_step/value_types/scalar.rs b/air/src/execution_step/value_types/scalar.rs index 4915d95e..b615f39f 100644 --- a/air/src/execution_step/value_types/scalar.rs +++ b/air/src/execution_step/value_types/scalar.rs @@ -45,14 +45,14 @@ pub enum ValueAggregate { result: ServiceResultAggregate, // the original call result CID; not changed on lambda application #[serde(rename = "cid")] - provenance_cid: Rc>, + provenance_cid: CID, }, Canon { #[serde(flatten)] result: CanonResultAggregate, // the original canon CID; not changed on lambda application #[serde(rename = "cid")] - provenance_cid: Rc>, + provenance_cid: CID, }, } @@ -109,7 +109,7 @@ impl ValueAggregate { pub(crate) fn from_service_result( service_result: ServiceResultAggregate, - service_result_agg_cid: Rc>, + service_result_agg_cid: CID, ) -> Self { Self::ServiceResult { result: service_result, @@ -119,7 +119,7 @@ impl ValueAggregate { pub(crate) fn from_canon_result( canon_result: CanonResultAggregate, - canon_result_agg_cid: Rc>, + canon_result_agg_cid: CID, ) -> Self { Self::Canon { result: canon_result, diff --git a/air/src/execution_step/value_types/stream/stream_definition.rs b/air/src/execution_step/value_types/stream/stream_definition.rs index 10dee219..b0d99613 100644 --- a/air/src/execution_step/value_types/stream/stream_definition.rs +++ b/air/src/execution_step/value_types/stream/stream_definition.rs @@ -538,7 +538,7 @@ mod test { let trace = ExecutionTrace::from(vec![]); let mut trace_ctx = TraceHandler::from_trace(trace.clone(), trace); - let canon_result = CanonResult::executed(Rc::new(CID::new("fake canon CID"))); + let canon_result = CanonResult::executed(CID::new("fake canon CID")); trace_ctx.meet_canon_end(canon_result.clone()); trace_ctx.meet_canon_end(canon_result.clone()); trace_ctx.meet_canon_end(canon_result); diff --git a/air/src/execution_step/value_types/stream_map.rs b/air/src/execution_step/value_types/stream_map.rs index 0b3c7203..f3ca1312 100644 --- a/air/src/execution_step/value_types/stream_map.rs +++ b/air/src/execution_step/value_types/stream_map.rs @@ -239,7 +239,7 @@ mod test { let trace = ExecutionTrace::from(vec![]); let mut trace_ctx = TraceHandler::from_trace(trace.clone(), trace); - let canon_result = CanonResult::executed(Rc::new(CID::new("fake canon CID"))); + let canon_result = CanonResult::executed(CID::new("fake canon CID")); trace_ctx.meet_canon_end(canon_result.clone()); trace_ctx.meet_canon_end(canon_result.clone()); trace_ctx.meet_canon_end(canon_result); diff --git a/air/tests/test_module/features/cid/canon.rs b/air/tests/test_module/features/cid/canon.rs index 74d56c55..2ce726f5 100644 --- a/air/tests/test_module/features/cid/canon.rs +++ b/air/tests/test_module/features/cid/canon.rs @@ -230,7 +230,7 @@ fn test_canon_value_not_found() { 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)); + let expected_error = ValueForCidNotFound("value", missing_cid.into()); assert!(check_error(&result, expected_error)); } @@ -281,7 +281,7 @@ fn test_canon_root_tetraplet_not_found() { 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)); + let expected_error = ValueForCidNotFound("tetraplet", missing_cid.into()); assert!(check_error(&result, expected_error)); } @@ -337,7 +337,7 @@ fn test_canon_tetraplet_not_found() { 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)); + let expected_error = ValueForCidNotFound("tetraplet", missing_cid.into()); assert!(check_error(&result, expected_error), "{}", result.error_message); } @@ -383,6 +383,6 @@ fn test_canon_agg_not_found() { 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)); + let expected_error = ValueForCidNotFound("canon aggregate", missing_cid.into()); assert!(check_error(&result, expected_error)); } diff --git a/air/tests/test_module/features/cid/mod.rs b/air/tests/test_module/features/cid/mod.rs index 02285b43..6e738668 100644 --- a/air/tests/test_module/features/cid/mod.rs +++ b/air/tests/test_module/features/cid/mod.rs @@ -42,7 +42,7 @@ fn test_missing_cid() { 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("bagaaierajmqwu6mhm7iw5mxxy647ri6yznuwjxfm72u4u5a5zdasfid4xwiq"); + let missing_cid = "bagaaierajmqwu6mhm7iw5mxxy647ri6yznuwjxfm72u4u5a5zdasfid4xwiq".into(); let expected_error = ValueForCidNotFound("service result aggregate", missing_cid); assert!(check_error(&result, expected_error), "{:?}", result); } diff --git a/air/tests/test_module/features/signatures/attacks.rs b/air/tests/test_module/features/signatures/attacks.rs index ca9822ef..2769c215 100644 --- a/air/tests/test_module/features/signatures/attacks.rs +++ b/air/tests/test_module/features/signatures/attacks.rs @@ -15,11 +15,14 @@ */ use air::{ExecutionCidState, PreparationError}; +use air_interpreter_cid::CidRef; use air_interpreter_signatures::{PeerCidTracker, PublicKey, SignatureStore}; use air_test_utils::key_utils::derive_dummy_keypair; use air_test_utils::prelude::*; use semver::Version; +use std::rc::Rc; + /// This testing modules assert AquaVM resistance to various attacks. /// /// CID store manipulations are checked in the `corruption` module. @@ -447,7 +450,7 @@ fn test_attack_replay() { "3eSuF5uvjQvmvSC6vu5Kmb8bJcswXhNUcqsSG9USEad1oNgnpAcBNm2maM4Tyk3BsLYnwdwNEj4KiJ4pqence7XF".to_owned(), "6m3zmtymxDL56KBpNgKqc7QiGRuWuxr82bG2q7dF5xCD".to_owned(), ); - let cids: Vec> = vec!["bagaaieraazcwm4lxybe4pwlisvcgpv4mii63nxouogvf4ihkmz762mnhea7a".into()]; + let cids: Vec> = vec!["bagaaieraazcwm4lxybe4pwlisvcgpv4mii63nxouogvf4ihkmz762mnhea7a".into()]; let expected = PreparationError::DataSignatureCheckError(verification::DataVerifierError::SignatureMismatch { error: nested_error.into(), cids, diff --git a/air/tests/test_module/features/signatures/corruption.rs b/air/tests/test_module/features/signatures/corruption.rs index 21940832..f7db6a5c 100644 --- a/air/tests/test_module/features/signatures/corruption.rs +++ b/air/tests/test_module/features/signatures/corruption.rs @@ -94,7 +94,7 @@ fn test_attack_replace_value() { &res, PreparationError::CidStoreVerificationError(CidStoreVerificationError::MismatchError { type_name: "serde_json::value::Value", - cid_repr: "bagaaierabjifaczkgq2745dsq57lelki2r5cfduunmfzsgvxiavi2ahwwmwq".to_owned(), + cid_repr: "bagaaierabjifaczkgq2745dsq57lelki2r5cfduunmfzsgvxiavi2ahwwmwq".into(), }) ); } @@ -167,7 +167,7 @@ fn test_attack_replace_tetraplet() { &res, PreparationError::CidStoreVerificationError(CidStoreVerificationError::MismatchError { type_name: "marine_call_parameters::SecurityTetraplet", - cid_repr: "bagaaierapisclqfeq36psuo6uxiazvcash32pndayqlwxrqchii2ykxerfba".to_owned(), + cid_repr: "bagaaierapisclqfeq36psuo6uxiazvcash32pndayqlwxrqchii2ykxerfba".into(), }) ); } @@ -196,7 +196,7 @@ fn test_attack_replace_call_result() { let mut mallory_cid_state = ExecutionCidState::new(); let alice_trace_1 = scalar_tracked!("alice", &mut mallory_cid_state, peer = &alice_peer_id); - let alice_trace_1_cid = (*extract_service_result_cid(&alice_trace_1)).clone().into_inner(); + let alice_trace_1_cid = extract_service_result_cid(&alice_trace_1).get_inner(); let mallory_trace = vec![ alice_trace_1, @@ -210,7 +210,7 @@ fn test_attack_replace_call_result() { .unwrap() .iter_mut() { - if *cid == alice_trace_1_cid { + if &*cid == &*alice_trace_1_cid { service_cid_val["argument_hash"] = "42".into(); cnt += 1; } @@ -247,7 +247,7 @@ fn test_attack_replace_call_result() { &res, PreparationError::CidStoreVerificationError(CidStoreVerificationError::MismatchError { type_name: "air_interpreter_data::executed_state::ServiceResultCidAggregate", - cid_repr: "bagaaierarbji6ebokx3pantdp6xg2l57bhdj7pmlydwe2wnbd6fdkatg7xka".to_owned(), + cid_repr: "bagaaierarbji6ebokx3pantdp6xg2l57bhdj7pmlydwe2wnbd6fdkatg7xka".into(), }) ); } @@ -334,7 +334,7 @@ fn test_attack_replace_canon_value() { &res, PreparationError::CidStoreVerificationError(CidStoreVerificationError::MismatchError { type_name: "air_interpreter_data::executed_state::CanonCidAggregate", - cid_repr: "bagaaierayrb7yu6tvdofr3d7tvuzx7fb3uve27rqty4ckzy7ox66oicuhjjq".to_owned(), + cid_repr: "bagaaierayrb7yu6tvdofr3d7tvuzx7fb3uve27rqty4ckzy7ox66oicuhjjq".into(), }) ); } @@ -430,7 +430,7 @@ fn test_attack_replace_canon_result_values() { &res, PreparationError::CidStoreVerificationError(CidStoreVerificationError::MismatchError { type_name: "air_interpreter_data::executed_state::CanonResultCidAggregate", - cid_repr: "bagaaieratezrhuyz2eprlmiidxywv6ir2tmswlxycad37noykg3p5oxhs5tq".to_owned(), + cid_repr: "bagaaieratezrhuyz2eprlmiidxywv6ir2tmswlxycad37noykg3p5oxhs5tq".into(), }) ); } @@ -530,7 +530,7 @@ fn test_attack_replace_canon_result_tetraplet() { &res, PreparationError::CidStoreVerificationError(CidStoreVerificationError::MismatchError { type_name: "air_interpreter_data::executed_state::CanonResultCidAggregate", - cid_repr: "bagaaieratezrhuyz2eprlmiidxywv6ir2tmswlxycad37noykg3p5oxhs5tq".to_owned(), + cid_repr: "bagaaieratezrhuyz2eprlmiidxywv6ir2tmswlxycad37noykg3p5oxhs5tq".into(), }) ); } diff --git a/air/tests/test_module/negative_tests/uncatchable_trace_unrelated.rs b/air/tests/test_module/negative_tests/uncatchable_trace_unrelated.rs index 893d772a..bf9d9ab1 100644 --- a/air/tests/test_module/negative_tests/uncatchable_trace_unrelated.rs +++ b/air/tests/test_module/negative_tests/uncatchable_trace_unrelated.rs @@ -126,7 +126,7 @@ fn value_for_cid_not_found() { let data = raw_data_from_trace(wrong_trace, <_>::default()); let result = peer_vm_1.call(script, "", data, <_>::default()).unwrap(); - let missing_cid = String::from("bagaaierax2kxw256denmh2rmtot4cnuvz7wrf6e2l7jnxhtv3qb6xvqj2vhq"); + let missing_cid = "bagaaierax2kxw256denmh2rmtot4cnuvz7wrf6e2l7jnxhtv3qb6xvqj2vhq".into(); let expected_error = ValueForCidNotFound("service result aggregate", missing_cid); assert!(check_error(&result, expected_error)); } diff --git a/crates/air-lib/interpreter-cid/src/lib.rs b/crates/air-lib/interpreter-cid/src/lib.rs index 29d32bca..c2393c75 100644 --- a/crates/air-lib/interpreter-cid/src/lib.rs +++ b/crates/air-lib/interpreter-cid/src/lib.rs @@ -32,18 +32,37 @@ use serde::Serialize; use std::fmt; use std::io::BufWriter; use std::marker::PhantomData; +use std::rc::Rc; + +/// Should-be-opaque type for the inner representation of CID. +/// It has to be serializable and Borsh-serializable, as well as implement `Debug`, `Eq`, `Ord`, `Hash` and similar +/// basic traits. It is also can be unsized. +// You should be able to replace it with [u8], and most of the code will just work. +pub type CidRef = str; #[derive(Serialize, Deserialize)] #[serde(transparent)] -pub struct CID(String, #[serde(skip)] PhantomData<*const T>); +pub struct CID(Rc, #[serde(skip)] PhantomData<*const T>); impl CID { - pub fn new(cid: impl Into) -> Self { + pub fn new(cid: impl Into>) -> Self { Self(cid.into(), PhantomData) } - pub fn into_inner(self) -> String { - self.0 + pub fn get_inner(&self) -> Rc { + self.0.clone() + } +} + +impl std::convert::AsRef for CID { + fn as_ref(&self) -> &CidRef { + &self.0 + } +} + +impl std::borrow::Borrow for CID { + fn borrow(&self) -> &CidRef { + &self.0 } } @@ -74,12 +93,6 @@ impl std::hash::Hash for CID { } } -impl From> for String { - fn from(value: CID) -> Self { - value.0 - } -} - // TODO we might refactor this to `SerializationFormat` trait // that both transform data to binary/text form (be it JSON, CBOR or something else) // and produces CID too diff --git a/crates/air-lib/interpreter-data/src/cid_store.rs b/crates/air-lib/interpreter-data/src/cid_store.rs index 175cc33b..e1f9d9fa 100644 --- a/crates/air-lib/interpreter-data/src/cid_store.rs +++ b/crates/air-lib/interpreter-data/src/cid_store.rs @@ -18,6 +18,7 @@ use crate::JValue; use air_interpreter_cid::value_to_json_cid; use air_interpreter_cid::CidCalculationError; +use air_interpreter_cid::CidRef; use air_interpreter_cid::CID; use serde::Deserialize; use serde::Serialize; @@ -28,7 +29,7 @@ use std::{collections::HashMap, rc::Rc}; /// Stores CID to Value corresponance. #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[serde(transparent)] -pub struct CidStore(HashMap>, Rc>); +pub struct CidStore(HashMap, Rc>); impl CidStore { pub fn new() -> Self { @@ -47,21 +48,21 @@ impl CidStore { self.0.len() } - pub fn iter(&self) -> impl Iterator>, &Rc)> { + pub fn iter(&self) -> impl Iterator, &Rc)> { self.0.iter() } pub fn check_reference( &self, _source_cid: &CID, - target_cid: &Rc>, + target_cid: &CID, ) -> Result<(), CidStoreVerificationError> { self.0 .get(target_cid) .ok_or_else(|| CidStoreVerificationError::MissingReference { source_type_name: std::any::type_name::(), target_type_name: std::any::type_name::(), - target_cid_repr: (**target_cid).clone().into_inner(), + target_cid_repr: target_cid.get_inner(), })?; Ok(()) } @@ -71,10 +72,10 @@ impl CidStore { pub fn verify(&self) -> Result<(), CidStoreVerificationError> { for (cid, value) in &self.0 { let expected_cid = value_to_json_cid::(value)?; - if expected_cid != **cid { + if expected_cid != *cid { return Err(CidStoreVerificationError::MismatchError { type_name: std::any::type_name::(), - cid_repr: (**cid).clone().into_inner(), + cid_repr: (*cid).get_inner(), }); } } @@ -91,14 +92,14 @@ pub enum CidStoreVerificationError { MismatchError { // nb: type_name is std::any::type_name() result that may be inconsistent between the Rust compiler versions type_name: &'static str, - cid_repr: String, + cid_repr: Rc, }, #[error("Reference CID {target_cid_repr:?} from type {source_type_name:?} to {target_type_name:?} was not found")] MissingReference { source_type_name: &'static str, target_type_name: &'static str, - target_cid_repr: String, + target_cid_repr: Rc, }, } @@ -110,7 +111,7 @@ impl Default for CidStore { #[derive(Clone, Debug)] pub struct CidTracker { - cids: HashMap>, Rc>, + cids: HashMap, Rc>, } impl CidTracker { @@ -136,9 +137,9 @@ impl CidTracker { pub fn track_value( &mut self, value: impl Into>, - ) -> Result>, CidCalculationError> { + ) -> Result, CidCalculationError> { let value = value.into(); - let cid = Rc::new(value_to_json_cid(&*value)?); + let cid = value_to_json_cid(&*value)?; self.cids.insert(cid.clone(), value); Ok(cid) } @@ -159,9 +160,9 @@ impl From> for CidStore { } impl IntoIterator for CidStore { - type Item = (Rc>, Rc); + type Item = (CID, Rc); - type IntoIter = std::collections::hash_map::IntoIter>, Rc>; + type IntoIter = std::collections::hash_map::IntoIter, Rc>; fn into_iter(self) -> Self::IntoIter { self.0.into_iter() diff --git a/crates/air-lib/interpreter-data/src/executed_state.rs b/crates/air-lib/interpreter-data/src/executed_state.rs index d86e56ed..69ff4ecb 100644 --- a/crates/air-lib/interpreter-data/src/executed_state.rs +++ b/crates/air-lib/interpreter-data/src/executed_state.rs @@ -55,7 +55,7 @@ pub enum CallResult { /// The call returned a service error. /// /// The `JValue` has to be a two element array `[i32, String]`. - Failed(Rc>), + Failed(CID), } /* @@ -76,21 +76,21 @@ pub enum CallResult { * is not stored into the `value_store`: * * ``` - * Unused(Rc>) ---> X + * Unused(CID) ---> 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>), + Scalar(CID), /// The call value is stored to a stream variable. Stream { - cid: Rc>, + cid: CID, generation: GenerationIdx, }, /// The call value is not stored. - Unused(Rc>), + Unused(CID), } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] @@ -114,11 +114,11 @@ impl CallServiceFailed { #[serde(rename_all = "snake_case")] /// A proof of service result execution result. pub struct ServiceResultCidAggregate { - pub value_cid: Rc>, + pub value_cid: CID, /// Hash of the call arguments. pub argument_hash: Rc, /// The tetraplet of the call result. - pub tetraplet_cid: Rc>, + pub tetraplet_cid: CID, } /// Let's consider an example of trace that could be produces by the following fold: @@ -190,21 +190,21 @@ pub enum CanonResult { /// Request was sent to a target node by node with such public key and it shouldn't be called again. #[serde(rename = "sent_by")] RequestSentBy(Rc), - Executed(Rc>), + Executed(CID), } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] pub struct CanonResultCidAggregate { - pub tetraplet: Rc>, - pub values: Vec>>, + pub tetraplet: CID, + pub values: Vec>, } /// The type Canon trace CID refers to. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct CanonCidAggregate { - pub value: Rc>, - pub tetraplet: Rc>, + pub value: CID, + pub tetraplet: CID, pub provenance: Provenance, } @@ -214,11 +214,11 @@ pub enum Provenance { Literal, ServiceResult { // the original call result CID; not changed on lambda application - cid: Rc>, + cid: CID, }, Canon { // the original canon CID; not changed on lambda application - cid: Rc>, + cid: CID, }, } diff --git a/crates/air-lib/interpreter-data/src/executed_state/impls.rs b/crates/air-lib/interpreter-data/src/executed_state/impls.rs index 032f7fd8..7fafbb49 100644 --- a/crates/air-lib/interpreter-data/src/executed_state/impls.rs +++ b/crates/air-lib/interpreter-data/src/executed_state/impls.rs @@ -43,25 +43,25 @@ impl CallResult { Self::Executed(value_ref) } - pub fn executed_scalar(service_result_agg_cid: Rc>) -> Self { + pub fn executed_scalar(service_result_agg_cid: CID) -> Self { Self::executed_service_result(ValueRef::Scalar(service_result_agg_cid)) } - pub fn executed_stream_stub(cid: Rc>) -> CallResult { + pub fn executed_stream_stub(cid: CID) -> CallResult { let generation = GenerationIdx::stub(); let value = ValueRef::Stream { cid, generation }; CallResult::Executed(value) } - pub fn executed_unused(value_cid: Rc>) -> CallResult { + pub fn executed_unused(value_cid: CID) -> CallResult { Self::executed_service_result(ValueRef::Unused(value_cid)) } - pub fn failed(service_result_agg_cid: Rc>) -> CallResult { + pub fn failed(service_result_agg_cid: CID) -> CallResult { CallResult::Failed(service_result_agg_cid) } - pub fn get_cid(&self) -> Option<&Rc>> { + pub fn get_cid(&self) -> Option<&CID> { match self { CallResult::RequestSentBy(_) => None, CallResult::Executed(executed) => executed.get_cid(), @@ -105,7 +105,7 @@ impl ApResult { } impl CanonResult { - pub fn executed(cid: Rc>) -> Self { + pub fn executed(cid: CID) -> Self { CanonResult::Executed(cid) } @@ -115,18 +115,15 @@ impl CanonResult { } impl CanonResultCidAggregate { - pub fn new( - tetraplet: Rc>, - values: Vec>>, - ) -> Self { + pub fn new(tetraplet: CID, values: Vec>) -> Self { Self { tetraplet, values } } } impl CanonCidAggregate { pub fn new( - value: Rc>, - tetraplet: Rc>, + value: CID, + tetraplet: CID, provenance: Provenance, ) -> Self { Self { @@ -139,9 +136,9 @@ impl CanonCidAggregate { impl ServiceResultCidAggregate { pub fn new( - value_cid: Rc>, + value_cid: CID, argument_hash: Rc, - tetraplet_cid: Rc>, + tetraplet_cid: CID, ) -> Self { Self { value_cid, @@ -158,12 +155,12 @@ impl Provenance { } #[inline] - pub fn service_result(cid: Rc>) -> Self { + pub fn service_result(cid: CID) -> Self { Self::ServiceResult { cid } } #[inline] - pub fn canon(cid: Rc>) -> Self { + pub fn canon(cid: CID) -> Self { Self::Canon { cid } } } @@ -211,7 +208,7 @@ impl std::fmt::Display for ExecutedState { } impl ValueRef { - pub(crate) fn get_cid(&self) -> Option<&Rc>> { + pub(crate) fn get_cid(&self) -> Option<&CID> { match self { ValueRef::Scalar(cid) => Some(cid), ValueRef::Stream { cid, .. } => Some(cid), diff --git a/crates/air-lib/interpreter-data/src/interpreter_data/errors.rs b/crates/air-lib/interpreter-data/src/interpreter_data/errors.rs index a1295588..78335fff 100644 --- a/crates/air-lib/interpreter-data/src/interpreter_data/errors.rs +++ b/crates/air-lib/interpreter-data/src/interpreter_data/errors.rs @@ -14,6 +14,9 @@ * limitations under the License. */ +use std::rc::Rc; + +use air_interpreter_cid::CidRef; use thiserror::Error as ThisError; #[derive(Debug, ThisError)] pub enum DataVerifierError { @@ -29,7 +32,7 @@ pub enum DataVerifierError { #[error("signature mismatch for {peer_id:?}: {error:?}, values: CIDS: {cids:?}")] SignatureMismatch { error: Box, - cids: Vec>, + cids: Vec>, peer_id: String, }, @@ -38,7 +41,7 @@ pub enum DataVerifierError { )] MergeMismatch { peer_id: String, - larger_cids: Vec>, - smaller_cids: Vec>, + larger_cids: Vec>, + smaller_cids: Vec>, }, } diff --git a/crates/air-lib/interpreter-data/src/interpreter_data/verification.rs b/crates/air-lib/interpreter-data/src/interpreter_data/verification.rs index 6a2e3473..4d3e9c06 100644 --- a/crates/air-lib/interpreter-data/src/interpreter_data/verification.rs +++ b/crates/air-lib/interpreter-data/src/interpreter_data/verification.rs @@ -21,7 +21,7 @@ use crate::ExecutedState; use crate::ExecutionTrace; use crate::InterpreterData; -use air_interpreter_cid::CID; +use air_interpreter_cid::{CidRef, CID}; use air_interpreter_signatures::PublicKey; use air_interpreter_signatures::Signature; use air_interpreter_signatures::SignatureStore; @@ -179,11 +179,11 @@ fn collect_peers_cids_from_trace<'data>( fn try_push_cid( grouped_cids: &mut HashMap, PeerInfo<'_>>, peer_pk: &str, - cid: &Rc>, + cid: &CID, ) -> Result<(), DataVerifierError> { match grouped_cids.get_mut(peer_pk) { Some(peer_info) => { - peer_info.cids.push((**cid).clone().into_inner().into()); + peer_info.cids.push(cid.get_inner()); Ok(()) } None => Err(DataVerifierError::PeerIdNotFound(peer_pk.into())), @@ -214,7 +214,7 @@ fn check_cid_multiset_invariant( } } -fn to_count_map(cids: &Vec>) -> HashMap<&str, usize> { +fn to_count_map(cids: &Vec>) -> HashMap<&str, usize> { let mut count_map = HashMap::<_, usize>::new(); for cid in cids { // the counter can't overflow, the memory will overflow first @@ -244,7 +244,7 @@ struct PeerInfo<'data> { /// A peer's signature. signature: &'data Signature, /// Sorted vector of CIDs that belong to the peer. - cids: Vec>, + cids: Vec>, } impl<'data> PeerInfo<'data> { diff --git a/crates/air-lib/interpreter-signatures/Cargo.toml b/crates/air-lib/interpreter-signatures/Cargo.toml index 4458aa03..0c10672f 100644 --- a/crates/air-lib/interpreter-signatures/Cargo.toml +++ b/crates/air-lib/interpreter-signatures/Cargo.toml @@ -15,6 +15,6 @@ air-interpreter-cid = { version = "0.4.0", path = "../interpreter-cid" } fluence-keypair = { version = "0.10.1", default-features = false } bs58 = "0.5.0" -borsh = "0.10.3" +borsh = { version = "0.10.3", features = ["rc"]} borsh-derive = "0.10.3" serde = { version = "1.0.164", features = ["derive"] } diff --git a/crates/air-lib/interpreter-signatures/src/trackers.rs b/crates/air-lib/interpreter-signatures/src/trackers.rs index 6e49a925..d9c62093 100644 --- a/crates/air-lib/interpreter-signatures/src/trackers.rs +++ b/crates/air-lib/interpreter-signatures/src/trackers.rs @@ -16,7 +16,7 @@ use crate::SaltedData; -use air_interpreter_cid::CID; +use air_interpreter_cid::{CidRef, CID}; use fluence_keypair::error::SigningError; use fluence_keypair::KeyPair; @@ -26,7 +26,7 @@ use std::rc::Rc; #[derive(Debug)] pub struct PeerCidTracker { current_peer_id: Rc, - cids: Vec>, + cids: Vec>, } impl PeerCidTracker { @@ -39,7 +39,7 @@ impl PeerCidTracker { pub fn register(&mut self, peer: &str, cid: &CID) { if peer == *self.current_peer_id { - self.cids.push(cid.clone().into_inner().into()) + self.cids.push(cid.get_inner()) } } @@ -53,7 +53,7 @@ impl PeerCidTracker { } fn sign_cids( - mut cids: Vec>, + mut cids: Vec>, salt: &str, keypair: &KeyPair, ) -> Result { diff --git a/crates/air-lib/test-utils/src/executed_state.rs b/crates/air-lib/test-utils/src/executed_state.rs index 938dbb50..61c3f560 100644 --- a/crates/air-lib/test-utils/src/executed_state.rs +++ b/crates/air-lib/test-utils/src/executed_state.rs @@ -46,7 +46,7 @@ use std::rc::Rc; pub fn simple_value_aggregate_cid( result: impl Into, cid_state: &mut ExecutionCidState, -) -> Rc> { +) -> CID { let value_cid = cid_state .value_tracker .track_value(Rc::new(result.into())) @@ -72,7 +72,7 @@ pub fn value_aggregate_cid( tetraplet: SecurityTetraplet, args: Vec, cid_state: &mut ExecutionCidState, -) -> Rc> { +) -> CID { let value_cid = cid_state .value_tracker .track_value(Rc::new(result.into())) @@ -83,7 +83,7 @@ pub fn value_aggregate_cid( .unwrap(); let arguments = serde_json::Value::Array(args); - let argument_hash = value_to_json_cid(&arguments).unwrap().into_inner().into(); + let argument_hash = value_to_json_cid(&arguments).unwrap().get_inner(); let service_result_agg = ServiceResultCidAggregate { value_cid, @@ -344,7 +344,7 @@ impl ExecutedCallBuilder { pub fn unused(self) -> ExecutedState { let value_cid = value_to_json_cid(&self.result).unwrap(); - let value = ValueRef::Unused(value_cid.into()); + let value = ValueRef::Unused(value_cid); ExecutedState::Call(CallResult::Executed(value)) } @@ -389,7 +389,7 @@ impl ExecutedCallBuilder { pub fn extract_service_result_cid( stream_exec_state: &ExecutedState, -) -> Rc> { +) -> CID { match stream_exec_state { ExecutedState::Call(CallResult::Executed(ValueRef::Stream { cid, .. })) => cid.clone(), ExecutedState::Call(CallResult::Executed(ValueRef::Scalar(cid))) => cid.clone(), @@ -397,7 +397,7 @@ pub fn extract_service_result_cid( } } -pub fn extract_canon_result_cid(canon_state: &ExecutedState) -> Rc> { +pub fn extract_canon_result_cid(canon_state: &ExecutedState) -> CID { match canon_state { ExecutedState::Canon(CanonResult::Executed(cid)) => cid.clone(), _ => panic!("the function is intended for executed canon only"),