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

Extract auto-update logic from aries #155

Merged
merged 7 commits into from
Oct 22, 2020
Merged
Show file tree
Hide file tree
Changes from 6 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
2 changes: 1 addition & 1 deletion libvcx/src/api/credential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,7 @@ pub extern fn vcx_credential_update_state_with_message(command_handle: CommandHa
command_handle, credential_handle, source_id);

spawn(move || {
match credential::update_state(credential_handle, Some(message), None) {
match credential::update_state(credential_handle, Some(&message), None) {
Ok(_) => (),
Err(e) => {
error!("vcx_credential_update_state_with_message_cb(command_handle: {}, rc: {}, state: {}), source_id: {:?}",
Expand Down
2 changes: 1 addition & 1 deletion libvcx/src/api/disclosed_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@ pub extern fn vcx_disclosed_proof_update_state_with_message(command_handle: Comm
command_handle, proof_handle, source_id);

spawn(move || {
match disclosed_proof::update_state(proof_handle, Some(message), None) {
match disclosed_proof::update_state(proof_handle, Some(&message), None) {
Ok(s) => {
trace!("vcx_disclosed_proof_update_state__with_message_cb(command_handle: {}, rc: {}, state: {}) source_id: {}",
command_handle, error::SUCCESS.message, s, source_id);
Expand Down
2 changes: 1 addition & 1 deletion libvcx/src/api/issuer_credential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ pub extern fn vcx_issuer_credential_update_state_with_message(command_handle: Co
}

spawn(move || {
match issuer_credential::update_state(credential_handle, Some(message), None) {
match issuer_credential::update_state(credential_handle, Some(&message), None) {
Ok(x) => {
trace!("vcx_issuer_credential_update_state_with_message_cb(command_handle: {}, credential_handle: {}, rc: {}, state: {}) source_id: {}",
command_handle, credential_handle, error::SUCCESS.message, x, source_id);
Expand Down
2 changes: 1 addition & 1 deletion libvcx/src/api/proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ pub extern fn vcx_proof_update_state_with_message(command_handle: CommandHandle,
}

spawn(move|| {
match proof::update_state(proof_handle, Some(message), None) {
match proof::update_state(proof_handle, Some(&message), None) {
Ok(x) => {
trace!("vcx_proof_update_state_with_message_cb(command_handle: {}, rc: {}, proof_handle: {}, state: {}) source_id: {}",
command_handle, error::SUCCESS.message, proof_handle, x, source_id);
Expand Down
48 changes: 10 additions & 38 deletions libvcx/src/aries/handlers/connection/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,15 @@ impl Connection {
}
}

pub fn bootstrap_agent_info(&self) -> Option<&AgentInfo> {
match &self.connection_sm {
SmConnection::Inviter(sm_inviter) => {
sm_inviter.prev_agent_info()
}
SmConnection::Invitee(sm_invitee) => None
}
}

pub fn remote_did(&self) -> VcxResult<String> {
match &self.connection_sm {
SmConnection::Inviter(sm_inviter) => {
Expand Down Expand Up @@ -237,7 +246,7 @@ impl Connection {
}
}

fn find_message_to_handle(&self, messages: HashMap<String, A2AMessage>) -> Option<(String, A2AMessage)> {
pub fn find_message_to_handle(&self, messages: HashMap<String, A2AMessage>) -> Option<(String, A2AMessage)> {
match &self.connection_sm {
SmConnection::Inviter(sm_inviter) => {
sm_inviter.find_message_to_handle(messages)
Expand All @@ -257,43 +266,6 @@ impl Connection {
self.step(DidExchangeMessages::Connect())
}

/**
Tries to update state of connection state machine in 3 steps:
1. find relevant message in agency,
2. use it to update connection state and possibly send response over network,
3. update state of used message in agency to "Reviewed".
*/
pub fn update_state(&mut self) -> VcxResult<()> {
trace!("Connection::update_state >>>");

if self.is_in_null_state() {
warn!("Connection::update_state :: update state on connection in null state is ignored");
return Ok(());
}

// connection protocol itself handles message authentication where it makes sense
let messages = self.get_messages_noauth()?;
trace!("Connection::update_state >>> retrieved messages {:?}", messages);

if let Some((uid, message)) = self.find_message_to_handle(messages) {
trace!("Connection::update_state >>> handling message uid: {:?}", uid);
self.update_state_with_message(&message)?;
self.agent_info().clone().update_message_status(uid)?;
} else if let SmConnection::Inviter(sm_inviter) = &self.connection_sm {
trace!("Connection::update_state >>> Inviter found no message to handle on main connection agent. Will check bootstrap agent.");
if let Some((messages, bootstrap_agent_info)) = sm_inviter.get_bootstrap_agent_messages()? {
if let Some((uid, message)) = self.find_message_to_handle(messages) {
trace!("Connection::update_state >>> handling message found on bootstrap agent uid: {:?}", uid);
self.update_state_with_message(&message)?;
bootstrap_agent_info.update_message_status(uid)?;
}
}
}

trace!("Connection::update_state >>> done");
Ok(())
}

/**
Perform state machine transition using supplied message.
*/
Expand Down
12 changes: 0 additions & 12 deletions libvcx/src/aries/handlers/connection/inviter/state_machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,18 +119,6 @@ impl SmConnectionInviter {
None
}

pub fn get_bootstrap_agent_messages(&self) -> VcxResult<Option<(HashMap<String, A2AMessage>, AgentInfo)>> {
let expected_sender_vk = match self.remote_vk() {
Ok(vk) => vk,
Err(_) => return Ok(None)
};
if let Some(prev_agent_info) = self.prev_agent_info() {
let messages = prev_agent_info.get_messages(&expected_sender_vk)?;
return Ok(Some((messages, prev_agent_info.clone())));
}
Ok(None)
}

pub fn get_protocols(&self) -> Vec<ProtocolDescriptor> {
ProtocolRegistry::init().protocols()
}
Expand Down
26 changes: 12 additions & 14 deletions libvcx/src/aries/handlers/issuance/holder/holder.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
// Holder
use std::collections::HashMap;

use connection;
use error::prelude::*;
use aries::handlers::issuance::holder::state_machine::HolderSM;
use aries::handlers::issuance::messages::CredentialIssuanceMessage;
use aries::messages::a2a::A2AMessage;
use aries::messages::issuance::credential::Credential;
use aries::messages::issuance::credential_offer::CredentialOffer;

#[derive(Serialize, Deserialize, Debug, Clone)]
Expand All @@ -26,19 +25,18 @@ impl Holder {
self.step(CredentialIssuanceMessage::CredentialRequestSend(connection_handle))
}

pub fn update_state(&mut self, msg: Option<String>, connection_handle: Option<u32>) -> VcxResult<()> {
match msg {
Some(msg) => {
let message: A2AMessage = ::serde_json::from_str(&msg)
.map_err(|err| VcxError::from_msg(VcxErrorKind::InvalidOption, format!("Cannot update state: Message deserialization failed: {:?}", err)))?;
pub fn maybe_update_connection_handle(&mut self, connection_handle: Option<u32>) -> u32 {
let conn_handle = connection_handle.unwrap_or(self.holder_sm.get_connection_handle());
self.holder_sm.set_connection_handle(conn_handle);
conn_handle
}

self.step(message.into())
}
None => {
self.holder_sm = self.holder_sm.clone().update_state(connection_handle)?;
Ok(())
}
}
pub fn is_terminal_state(&self) -> bool {
self.holder_sm.is_terminal_state()
}

pub fn find_message_to_handle(&self, messages: HashMap<String, A2AMessage>) -> Option<(String, A2AMessage)> {
self.holder_sm.find_message_to_handle(messages)
}

pub fn get_status(&self) -> u32 {
Expand Down
30 changes: 9 additions & 21 deletions libvcx/src/aries/handlers/issuance/holder/state_machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,27 +75,7 @@ impl HolderSM {
}
}

pub fn update_state(mut self, connection_handle: Option<u32>) -> VcxResult<Self> {
trace!("Holder::update_state >>> ");

if self.is_terminal_state() { return Ok(self); }

let conn_handle = connection_handle.unwrap_or(self.state.get_connection_handle());
self.state.set_connection_handle(conn_handle);

let messages = connection::get_messages(conn_handle)?;

match self.find_message_to_handle(messages) {
Some((uid, msg)) => {
let state = self.handle_message(msg.into())?;
connection::update_message_status(conn_handle, uid)?;
Ok(state)
}
None => Ok(self)
}
}

fn find_message_to_handle(&self, messages: HashMap<String, A2AMessage>) -> Option<(String, A2AMessage)> {
pub fn find_message_to_handle(&self, messages: HashMap<String, A2AMessage>) -> Option<(String, A2AMessage)> {
trace!("Holder::find_message_to_handle >>> messages: {:?}", messages);

for (uid, message) in messages {
Expand Down Expand Up @@ -212,6 +192,14 @@ impl HolderSM {
}
}

pub fn get_connection_handle(&self) -> u32 {
self.state.get_connection_handle()
}

pub fn set_connection_handle(&mut self, conn_handle: u32) {
self.state.set_connection_handle(conn_handle)
}

pub fn get_credential(&self) -> VcxResult<(String, A2AMessage)> {
match self.state {
HolderState::Finished(ref state) => {
Expand Down
27 changes: 14 additions & 13 deletions libvcx/src/aries/handlers/issuance/issuer/issuer.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::collections::HashMap;

use error::prelude::*;
use aries::handlers::issuance::issuer::state_machine::IssuerSM;
use aries::handlers::issuance::messages::CredentialIssuanceMessage;
Expand Down Expand Up @@ -35,23 +37,22 @@ impl Issuer {
Ok(self.issuer_sm.get_source_id())
}

pub fn is_terminal_state(&self) -> bool {
self.issuer_sm.is_terminal_state()
}

pub fn find_message_to_handle(&self, messages: HashMap<String, A2AMessage>) -> Option<(String, A2AMessage)> {
self.issuer_sm.find_message_to_handle(messages)
}

pub fn revoke_credential(&self, publish: bool) -> VcxResult<()> {
self.issuer_sm.revoke(publish)
}

pub fn update_status(&mut self, msg: Option<String>, connection_handle: Option<u32>) -> VcxResult<()> {
match msg {
Some(msg) => {
let message: A2AMessage = ::serde_json::from_str(&msg)
.map_err(|err| VcxError::from_msg(VcxErrorKind::InvalidOption, format!("Cannot deserialize Message: {:?}", err)))?;

self.step(message.into())
}
None => {
self.issuer_sm = self.issuer_sm.clone().update_state(connection_handle)?;
Ok(())
}
}
pub fn maybe_update_connection_handle(&mut self, connection_handle: Option<u32>) -> u32 {
let conn_handle = connection_handle.unwrap_or(self.issuer_sm.get_connection_handle());
self.issuer_sm.set_connection_handle(conn_handle);
conn_handle
}

pub fn get_credential_status(&self) -> VcxResult<u32> {
Expand Down
24 changes: 6 additions & 18 deletions libvcx/src/aries/handlers/issuance/issuer/state_machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,27 +123,15 @@ impl IssuerSM {
}
}

pub fn update_state(mut self, connection_handle: Option<u32>) -> VcxResult<Self> {
trace!("Issuer::update_state >>> ", );

if self.is_terminal_state() { return Ok(self); }

let conn_handle = connection_handle.unwrap_or(self.state.get_connection_handle());
self.state.set_connection_handle(conn_handle);

let messages = get_messages(conn_handle)?;
pub fn get_connection_handle(&self) -> u32 {
self.state.get_connection_handle()
}

match self.find_message_to_handle(messages) {
Some((uid, msg)) => {
let state = self.handle_message(msg.into())?;
connection::update_message_status(conn_handle, uid)?;
Ok(state)
}
None => Ok(self)
}
pub fn set_connection_handle(&mut self, conn_handle: u32) {
self.state.set_connection_handle(conn_handle)
}

fn find_message_to_handle(&self, messages: HashMap<String, A2AMessage>) -> Option<(String, A2AMessage)> {
pub fn find_message_to_handle(&self, messages: HashMap<String, A2AMessage>) -> Option<(String, A2AMessage)> {
trace!("Issuer::find_message_to_handle >>> messages: {:?}", messages);

for (uid, message) in messages {
Expand Down
33 changes: 11 additions & 22 deletions libvcx/src/aries/handlers/proof_presentation/prover/prover.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::convert::TryInto;
use std::collections::HashMap;

use ::{connection, settings};
use error::prelude::*;
Expand Down Expand Up @@ -59,41 +60,29 @@ impl Prover {
self.step(ProverMessages::SendPresentation(connection_handle))
}

pub fn update_state(&mut self, message: Option<&str>, connection_handle: Option<u32>) -> VcxResult<()> {
trace!("Prover::update_state >>> connection_handle: {:?}, message: {:?}", connection_handle, message);
pub fn has_transitions(&self) -> bool {
self.prover_sm.has_transitions()
}

if !self.prover_sm.has_transitions() {
trace!("Prover::update_state >> found no available transition");
return Ok(());
}
pub fn find_message_to_handle(&self, messages: HashMap<String, A2AMessage>) -> Option<(String, A2AMessage)> {
self.prover_sm.find_message_to_handle(messages)
}

pub fn maybe_update_connection_handle(&mut self, connection_handle: Option<u32>) -> VcxResult<u32> {
let connection_handle = connection_handle.unwrap_or(self.prover_sm.connection_handle()?);
self.prover_sm.set_connection_handle(connection_handle);

if let Some(message_) = message {
return self.update_state_with_message(message_);
}

let messages = connection::get_messages(connection_handle)?;
trace!("Prover::update_state >>> found messages: {:?}", messages);

if let Some((uid, message)) = self.prover_sm.find_message_to_handle(messages) {
self.handle_message(message.into())?;
connection::update_message_status(connection_handle, uid)?;
};

Ok(())
Ok(connection_handle)
}

pub fn update_state_with_message(&mut self, message: &str) -> VcxResult<()> {
pub fn update_state_with_message(&mut self, message: &str) -> VcxResult<u32> {
trace!("Prover::update_state_with_message >>> message: {:?}", message);

let a2a_message: A2AMessage = ::serde_json::from_str(&message)
.map_err(|err| VcxError::from_msg(VcxErrorKind::InvalidOption, format!("Cannot updated state with message: Message deserialization failed: {:?}", err)))?;

self.handle_message(a2a_message.into())?;

Ok(())
Ok(self.state())
}

pub fn handle_message(&mut self, message: ProverMessages) -> VcxResult<()> {
Expand Down
Loading