Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split connection state machines #120

Merged
merged 3 commits into from
Sep 30, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions libvcx/src/api/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@ pub extern fn vcx_connection_update_state(command_handle: CommandHandle,
}

spawn(move || {
let rc = match update_state(connection_handle, None) {
let rc = match update_state(connection_handle) {
Ok(x) => {
trace!("vcx_connection_update_state_cb(command_handle: {}, rc: {}, connection_handle: {}, state: {}), source_id: {:?}",
command_handle, error::SUCCESS.message, connection_handle, get_state(connection_handle), source_id);
Expand Down Expand Up @@ -1283,7 +1283,7 @@ mod tests {
use std::ptr;

use api::{return_types_u32, VcxStateType};
use connection::tests::{build_test_connection_inviter_requested, build_test_connection_inviter_invited};
use connection::tests::{build_test_connection_inviter_requested, build_test_connection_inviter_invited, build_test_connection_inviter_null};
use utils::constants::{DELETE_CONNECTION_DECRYPTED_RESPONSE, GET_MESSAGES_DECRYPTED_RESPONSE};
use utils::devsetup::*;
use utils::error;
Expand Down Expand Up @@ -1331,7 +1331,8 @@ mod tests {
let cb = return_types_u32::Return_U32_STR::new().unwrap();
let rc = vcx_connection_connect(cb.command_handle, 0, CString::new("{}").unwrap().into_raw(), Some(cb.get_callback()));
assert_eq!(rc, error::INVALID_CONNECTION_HANDLE.code_num);
let handle = build_test_connection_inviter_requested();

let handle = build_test_connection_inviter_null();
assert!(handle > 0);

let cb = return_types_u32::Return_U32_STR::new().unwrap();
Expand Down
91 changes: 67 additions & 24 deletions libvcx/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,17 @@ use serde_json;

use error::prelude::*;
use messages;
use messages::SerializableObjectWithState;
use messages::get_message::Message;
use messages::SerializableObjectWithState;
use object_cache::ObjectCache;
use settings;
use settings::ProtocolTypes;
use utils::error;
use v3::handlers::connection::connection::Connection as ConnectionV3;
use v3::handlers::connection::agent_info::AgentInfo;
use v3::handlers::connection::connection::{Connection as ConnectionV3, SmConnection, SmConnectionState};
use v3::messages::a2a::A2AMessage;
use v3::messages::connection::did_doc::DidDoc;
use v3::messages::connection::invite::Invitation as InvitationV3;
use v3::handlers::connection::state_machine::ActorDidExchangeState;

lazy_static! {
static ref CONNECTION_MAP: ObjectCache<ConnectionV3> = ObjectCache::<ConnectionV3>::new("connections-cache");
Expand Down Expand Up @@ -99,7 +98,7 @@ fn store_connection(connection: ConnectionV3) -> VcxResult<u32> {
pub fn create_connection(source_id: &str) -> VcxResult<u32> {
trace!("create_connection >>> source_id: {}", source_id);
let connection = ConnectionV3::create(source_id);
return store_connection(connection)
return store_connection(connection);
}

pub fn create_connection_with_invite(source_id: &str, details: &str) -> VcxResult<u32> {
Expand All @@ -120,14 +119,14 @@ pub fn send_generic_message(connection_handle: u32, msg: &str, msg_options: &str

pub fn update_state_with_message(handle: u32, message: A2AMessage) -> VcxResult<u32> {
CONNECTION_MAP.get_mut(handle, |connection| {
connection.update_state(Some(&message))?;
connection.update_state_with_message(&message)?;
Ok(error::SUCCESS.code_num)
})
}

pub fn update_state(handle: u32, message: Option<A2AMessage>) -> VcxResult<u32> {
pub fn update_state(handle: u32) -> VcxResult<u32> {
CONNECTION_MAP.get_mut(handle, |connection| {
connection.update_state(message.as_ref())?;
connection.update_state()?;
Ok(error::SUCCESS.code_num)
})
}
Expand Down Expand Up @@ -161,13 +160,13 @@ pub fn to_string(handle: u32) -> VcxResult<String> {
}

pub fn from_string(connection_data: &str) -> VcxResult<u32> {
let object: SerializableObjectWithState<AgentInfo, ActorDidExchangeState> = ::serde_json::from_str(connection_data)
let object: SerializableObjectWithState<AgentInfo, SmConnectionState> = ::serde_json::from_str(connection_data)
.map_err(|err| VcxError::from_msg(VcxErrorKind::InvalidJson, format!("Cannot deserialize Connection: {:?}", err)))?;

let handle = match object {
SerializableObjectWithState::V3 { data, state, source_id } => {
CONNECTION_MAP.add((state, data, source_id).into())?
},
}
_ => return Err(VcxError::from_msg(VcxErrorKind::InvalidJson, format!("Unexpected format of serialized connection: {:?}", object)))
};
Ok(handle)
Expand All @@ -188,14 +187,14 @@ pub fn get_invite_details(handle: u32, _abbreviated: bool) -> VcxResult<String>
}).or(Err(VcxError::from(VcxErrorKind::InvalidConnectionHandle)))
}

impl Into<(ActorDidExchangeState, AgentInfo, String)> for ConnectionV3 {
fn into(self) -> (ActorDidExchangeState, AgentInfo, String) {
(self.state_object().to_owned(), self.agent_info().to_owned(), self.source_id())
impl Into<(SmConnectionState, AgentInfo, String)> for ConnectionV3 {
fn into(self) -> (SmConnectionState, AgentInfo, String) {
(self.state_object(), self.agent_info().to_owned(), self.source_id())
}
}

impl From<(ActorDidExchangeState, AgentInfo, String)> for ConnectionV3 {
fn from((state, agent_info, source_id): (ActorDidExchangeState, AgentInfo, String)) -> ConnectionV3 {
impl From<(SmConnectionState, AgentInfo, String)> for ConnectionV3 {
fn from((state, agent_info, source_id): (SmConnectionState, AgentInfo, String)) -> ConnectionV3 {
ConnectionV3::from_parts(source_id, agent_info, state)
}
}
Expand Down Expand Up @@ -264,17 +263,25 @@ pub mod tests {
use std::thread;
use std::time::Duration;

use serde::Serialize;
use serde_json::Value;

use api::VcxStateType;
use messages::MessageStatusCode;
use messages::get_message::*;
use messages::MessageStatusCode;
use utils::constants::*;
use utils::constants;
use utils::devsetup::*;
use utils::httpclient::AgencyMockDecrypted;
use utils::mockdata::mockdata_connection::{ARIES_CONNECTION_ACK, ARIES_CONNECTION_INVITATION, ARIES_CONNECTION_REQUEST};
use utils::mockdata::mockdata_connection::{ARIES_CONNECTION_ACK, ARIES_CONNECTION_INVITATION, ARIES_CONNECTION_REQUEST, CONNECTION_SM_INVITEE_COMPLETED, CONNECTION_SM_INVITEE_INVITED, CONNECTION_SM_INVITEE_REQUESTED, CONNECTION_SM_INVITER_COMPLETED};

use super::*;

pub fn build_test_connection_inviter_null() -> u32 {
let handle = create_connection("faber_to_alice").unwrap();
handle
}

pub fn build_test_connection_inviter_invited() -> u32 {
let handle = create_connection("faber_to_alice").unwrap();
connect(handle, Some("{}".to_string())).unwrap();
Expand All @@ -283,7 +290,7 @@ pub mod tests {

pub fn build_test_connection_inviter_requested() -> u32 {
let handle = build_test_connection_inviter_invited();
let msg : A2AMessage = serde_json::from_str(ARIES_CONNECTION_REQUEST).unwrap();
let msg: A2AMessage = serde_json::from_str(ARIES_CONNECTION_REQUEST).unwrap();
update_state_with_message(handle, msg).unwrap();
handle
}
Expand All @@ -294,30 +301,30 @@ pub mod tests {
let faber_to_alice = create_connection("alice").unwrap();
let _my_public_did = settings::get_config_value(settings::CONFIG_INSTITUTION_DID).unwrap();
connect(faber_to_alice, None).unwrap();
update_state(faber_to_alice, None).unwrap();
update_state(faber_to_alice).unwrap();
let details = get_invite_details(faber_to_alice, false).unwrap();

::utils::devsetup::set_consumer();
debug!("Consumer is going to accept connection invitation.");
let alice_to_faber = create_connection_with_invite("faber", &details).unwrap();
connect(alice_to_faber, None).unwrap();
update_state(alice_to_faber, None).unwrap();
update_state(alice_to_faber).unwrap();
// assert_eq!(VcxStateType::VcxStateRequestReceived as u32, get_state(faber));

debug!("Institution is going to process connection request.");
::utils::devsetup::set_institution();
thread::sleep(Duration::from_millis(500));
update_state(faber_to_alice, None).unwrap();
update_state(faber_to_alice).unwrap();

debug!("Consumer is going to complete the connection protocol.");
::utils::devsetup::set_consumer();
update_state(alice_to_faber, None).unwrap();
update_state(alice_to_faber).unwrap();
assert_eq!(VcxStateType::VcxStateAccepted as u32, get_state(alice_to_faber));

debug!("Institution is going to complete the connection protocol.");
::utils::devsetup::set_institution();
thread::sleep(Duration::from_millis(500));
update_state(faber_to_alice, None).unwrap();
update_state(faber_to_alice).unwrap();
assert_eq!(VcxStateType::VcxStateAccepted as u32, get_state(faber_to_alice));

(alice_to_faber, faber_to_alice)
Expand All @@ -338,12 +345,12 @@ pub mod tests {

AgencyMockDecrypted::set_next_decrypted_response(constants::GET_MESSAGES_DECRYPTED_RESPONSE);
AgencyMockDecrypted::set_next_decrypted_message(ARIES_CONNECTION_REQUEST);
update_state(handle, None).unwrap();
update_state(handle).unwrap();
assert_eq!(get_state(handle), VcxStateType::VcxStateRequestReceived as u32);

AgencyMockDecrypted::set_next_decrypted_response(constants::GET_MESSAGES_DECRYPTED_RESPONSE);
AgencyMockDecrypted::set_next_decrypted_message(ARIES_CONNECTION_ACK);
update_state(handle, None).unwrap();
update_state(handle).unwrap();
assert_eq!(get_state(handle), VcxStateType::VcxStateAccepted as u32);

AgencyMockDecrypted::set_next_decrypted_response(constants::DELETE_CONNECTION_DECRYPTED_RESPONSE);
Expand Down Expand Up @@ -418,6 +425,42 @@ pub mod tests {
assert_eq!(get_invite_details(0, true).unwrap_err().kind(), VcxErrorKind::InvalidConnectionHandle);
}

#[test]
#[cfg(feature = "general_test")]
fn test_deserialize_connection_inviter_completed() {
let _setup = SetupAriesMocks::init();

let handle = from_string(CONNECTION_SM_INVITER_COMPLETED).unwrap();
let second_string = to_string(handle).unwrap();

assert_eq!(get_pw_did(handle).unwrap(), "2ZHFFhzA2XtTD6hJqzL7ux");
assert_eq!(get_pw_verkey(handle).unwrap(), "rCw3x5h1jS6gPo7rRrt3EYbXXe5nNjnGbdf1jAwUxuj");
assert_eq!(get_agent_did(handle).unwrap(), "EZrZyu4bfydm4ByNm56kPP");
assert_eq!(get_agent_verkey(handle).unwrap(), "8Ps2WosJ9AV1eXPoJKsEJdM3NchPhSyS8qFt6LQUTKv2");
assert_eq!(get_state(handle), VcxStateType::VcxStateAccepted as u32);
assert!(release(handle).is_ok());
}

fn test_deserialize_and_serialize(sm_serialized: &str) {
let mut original_object: Value = serde_json::from_str(sm_serialized).unwrap();
let handle_conn = from_string(sm_serialized).unwrap();
let reserialized = to_string(handle_conn).unwrap();
let reserialized_object: Value = serde_json::from_str(&reserialized).unwrap();

assert_eq!(original_object, reserialized_object);
}

#[test]
#[cfg(feature = "general_test")]
fn test_deserialize_and_serialize_should_produce_the_same_object() {
let _setup = SetupAriesMocks::init();

test_deserialize_and_serialize(CONNECTION_SM_INVITEE_INVITED);
test_deserialize_and_serialize(CONNECTION_SM_INVITEE_REQUESTED);
test_deserialize_and_serialize(CONNECTION_SM_INVITEE_COMPLETED);
test_deserialize_and_serialize(CONNECTION_SM_INVITER_COMPLETED);
}

#[test]
#[cfg(feature = "general_test")]
fn test_serialize_deserialize() {
Expand Down
2 changes: 1 addition & 1 deletion libvcx/src/utils/libindy/anoncreds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ use utils::libindy::cache::{clear_rev_reg_delta_cache, get_rev_reg_delta_cache,
use utils::libindy::ledger::*;
use utils::libindy::payments::{pay_for_txn, PaymentTxn};
use utils::mockdata::mock_settings::get_mock_creds_retrieved_for_proof_request;
use v3::handlers::issuance::utils::encode_attributes;
use v3::messages::proof_presentation::presentation_request::{PresentationRequestData, PresentationRequest};
use utils::mockdata::mockdata_proof;


const BLOB_STORAGE_TYPE: &str = "default";
const REVOCATION_REGISTRY_TYPE: &str = "ISSUANCE_BY_DEFAULT";

Expand Down
80 changes: 18 additions & 62 deletions libvcx/src/utils/mockdata/mockdata_connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,13 @@ pub const ARIES_CONNECTION_INVITATION: &str = r#"
// Alice created and serialized connection created from received invitation
pub const CONNECTION_SM_INVITEE_INVITED: &str = r#"
{
"version": "2.0",
"version": "3.0",
"source_id": "alice-670c6360-5c0e-4495-bd25-2ee58c39fc7e",
"data": {
"source_id": "alice-670c6360-5c0e-4495-bd25-2ee58c39fc7e",
"pw_did": "",
"pw_verkey": "",
"state": 2,
"uuid": "",
"endpoint": "",
"invite_detail": null,
"redirect_detail": null,
"invite_url": null,
"pw_vk": "",
"agent_did": "",
"agent_vk": "",
"their_pw_did": "18ac5f5d-c81d-451a-be20-a0df4933513a",
"their_pw_verkey": "HoNSv4aPCRQ8BsJrVXS26Za4rdEFvtCyyoQEtCS175dw",
"public_did": null,
"their_public_did": null,
"version": "2.0"
"agent_vk": ""
},
"state": {
"Invitee": {
Expand Down Expand Up @@ -104,24 +93,13 @@ pub const ARIES_CONNECTION_REQUEST: &str = r#"
// Alice sends connection request to Faber
pub const CONNECTION_SM_INVITEE_REQUESTED: &str = r#"
{
"version": "2.0",
"version": "3.0",
"source_id": "alice-670c6360-5c0e-4495-bd25-2ee58c39fc7e",
"data": {
"source_id": "alice-670c6360-5c0e-4495-bd25-2ee58c39fc7e",
"pw_did": "KC6NKcpXcpVnpjL8uKH3tV",
"pw_verkey": "Av4ZDAKgpniTnxLukLQFZ2DbdNqPub8MBxxynCZ5VuFi",
"state": 3,
"uuid": "",
"endpoint": "",
"invite_detail": null,
"redirect_detail": null,
"invite_url": null,
"pw_vk": "Av4ZDAKgpniTnxLukLQFZ2DbdNqPub8MBxxynCZ5VuFi",
"agent_did": "Gqw6t57yDgzaG79h4HUVCf",
"agent_vk": "9drH4FZk79Y4bx5jzPBaJEmB4woEGG1XQSfgF7NkyKvV",
"their_pw_did": "18ac5f5d-c81d-451a-be20-a0df4933513a",
"their_pw_verkey": "HoNSv4aPCRQ8BsJrVXS26Za4rdEFvtCyyoQEtCS175dw",
"public_did": null,
"their_public_did": null,
"version": "2.0"
"agent_vk": "9drH4FZk79Y4bx5jzPBaJEmB4woEGG1XQSfgF7NkyKvV"
},
"state": {
"Invitee": {
Expand Down Expand Up @@ -226,24 +204,13 @@ pub const ARIES_CONNECTION_RESPONSE: &str = r#"
// Alice (invitee) connection SM after Faber accepted connection by sending connection response
pub const CONNECTION_SM_INVITEE_COMPLETED: &str = r#"
{
"version": "2.0",
"version": "3.0",
"source_id": "alice-670c6360-5c0e-4495-bd25-2ee58c39fc7e",
"data": {
"source_id": "alice-670c6360-5c0e-4495-bd25-2ee58c39fc7e",
"pw_did": "KC6NKcpXcpVnpjL8uKH3tV",
"pw_verkey": "Av4ZDAKgpniTnxLukLQFZ2DbdNqPub8MBxxynCZ5VuFi",
"state": 4,
"uuid": "",
"endpoint": "",
"invite_detail": null,
"redirect_detail": null,
"invite_url": null,
"pw_vk": "Av4ZDAKgpniTnxLukLQFZ2DbdNqPub8MBxxynCZ5VuFi",
"agent_did": "Gqw6t57yDgzaG79h4HUVCf",
"agent_vk": "9drH4FZk79Y4bx5jzPBaJEmB4woEGG1XQSfgF7NkyKvV",
"their_pw_did": "2ZHFFhzA2XtTD6hJqzL7ux",
"their_pw_verkey": "rCw3x5h1jS6gPo7rRrt3EYbXXe5nNjnGbdf1jAwUxuj",
"public_did": null,
"their_public_did": null,
"version": "2.0"
"agent_vk": "9drH4FZk79Y4bx5jzPBaJEmB4woEGG1XQSfgF7NkyKvV"
},
"state": {
"Invitee": {
Expand Down Expand Up @@ -303,24 +270,13 @@ pub const ARIES_CONNECTION_ACK: &str = r#"
// Inviter (Faber) after finished connection protocol by sending connection ack
pub const CONNECTION_SM_INVITER_COMPLETED: &str = r#"
{
"version": "2.0",
"version": "3.0",
"source_id": "alice-131bc1e2-fa29-404c-a87c-69983e02084d",
"data": {
"source_id": "alice-131bc1e2-fa29-404c-a87c-69983e02084d",
"pw_did": "2ZHFFhzA2XtTD6hJqzL7ux",
"pw_verkey": "rCw3x5h1jS6gPo7rRrt3EYbXXe5nNjnGbdf1jAwUxuj",
"state": 4,
"uuid": "",
"endpoint": "",
"invite_detail": null,
"redirect_detail": null,
"invite_url": null,
"pw_vk": "rCw3x5h1jS6gPo7rRrt3EYbXXe5nNjnGbdf1jAwUxuj",
"agent_did": "EZrZyu4bfydm4ByNm56kPP",
"agent_vk": "8Ps2WosJ9AV1eXPoJKsEJdM3NchPhSyS8qFt6LQUTKv2",
"their_pw_did": "KC6NKcpXcpVnpjL8uKH3tV",
"their_pw_verkey": "Av4ZDAKgpniTnxLukLQFZ2DbdNqPub8MBxxynCZ5VuFi",
"public_did": null,
"their_public_did": null,
"version": "2.0"
"agent_vk": "8Ps2WosJ9AV1eXPoJKsEJdM3NchPhSyS8qFt6LQUTKv2"
},
"state": {
"Inviter": {
Expand Down Expand Up @@ -367,6 +323,7 @@ pub const CONNECTION_SM_INVITER_COMPLETED: &str = r#"
pub const DEFAULT_SERIALIZED_CONNECTION: &str = r#"
{
"version": "3.0",
"source_id": "test_serialize_deserialize",
"data": {
"pw_did": "",
"pw_vk": "",
Expand All @@ -377,7 +334,6 @@ pub const DEFAULT_SERIALIZED_CONNECTION: &str = r#"
"Inviter": {
"Null": {}
}
},
"source_id": "test_serialize_deserialize"
}
}"#;

Loading