Skip to content

Commit

Permalink
Holder: add function build_credential_request to avoid enforcing IO
Browse files Browse the repository at this point in the history
Signed-off-by: Patrik Stas <[email protected]>
  • Loading branch information
Patrik-Stas committed Aug 20, 2023
1 parent d78353d commit 4fb71e5
Show file tree
Hide file tree
Showing 11 changed files with 102 additions and 81 deletions.
5 changes: 2 additions & 3 deletions agents/rust/aries-vcx-agent/src/services/holder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,14 @@ impl ServiceCredentialsHolder {
let send_closure: SendClosure = Box::new(|msg: AriesMessage| {
Box::pin(async move { connection.send_message(&wallet, &msg, &HttpClient).await })
});

holder
.send_request(
.build_credential_request(
&self.profile.inject_anoncreds_ledger_read(),
&self.profile.inject_anoncreds(),
pw_did,
send_closure,
)
.await?;
holder.send_credential_request(send_closure).await?;
self.creds_holder
.insert(&holder.get_thread_id()?, HolderWrapper::new(holder, &connection_id))
}
Expand Down
10 changes: 7 additions & 3 deletions aries_vcx/src/handlers/issuance/holder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,21 +52,25 @@ impl Holder {
Ok(())
}

pub async fn send_request(
// todo: is the my_pw_did really necessary? is it used under the hood?
pub async fn build_credential_request(
&mut self,
ledger: &Arc<dyn AnoncredsLedgerRead>,
anoncreds: &Arc<dyn BaseAnonCreds>,
my_pw_did: String,
send_message: SendClosure,
) -> VcxResult<()> {
self.holder_sm = self
.holder_sm
.clone()
.send_request(ledger, anoncreds, my_pw_did, send_message)
.build_credential_request(ledger, anoncreds, my_pw_did)
.await?;
Ok(())
}

pub async fn send_credential_request(&mut self, send_message: SendClosure) -> VcxResult<()> {
self.holder_sm.send_credential_request(send_message).await
}

pub async fn decline_offer<'a>(&'a mut self, comment: Option<&'a str>, send_message: SendClosure) -> VcxResult<()> {
self.holder_sm = self
.holder_sm
Expand Down
2 changes: 1 addition & 1 deletion aries_vcx/src/handlers/issuance/mediated_holder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ pub fn holder_find_message_to_handle(
}
}
}
HolderState::RequestSent => match &message {
HolderState::RequestSet => match &message {
AriesMessage::CredentialIssuance(CredentialIssuance::IssueCredential(credential)) => {
if matches_thread_id!(credential, sm.get_thread_id().unwrap().as_str()) {
return Some((uid, message));
Expand Down
2 changes: 1 addition & 1 deletion aries_vcx/src/handlers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ impl From<HolderState> for u32 {
HolderState::Initial => 0,
HolderState::ProposalSent => 1,
HolderState::OfferReceived => 2,
HolderState::RequestSent => 3,
HolderState::RequestSet => 3,
HolderState::Finished => 4,
HolderState::Failed => 5,
}
Expand Down
62 changes: 43 additions & 19 deletions aries_vcx/src/protocols/issuance/holder/state_machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ use crate::protocols::issuance::holder::states::finished::FinishedHolderState;
use crate::protocols::issuance::holder::states::initial::InitialHolderState;
use crate::protocols::issuance::holder::states::offer_received::OfferReceivedState;
use crate::protocols::issuance::holder::states::proposal_sent::ProposalSentState;
use crate::protocols::issuance::holder::states::request_sent::RequestSentState;
use crate::protocols::issuance::holder::states::request_sent::RequestSetState;
use crate::protocols::SendClosure;

#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum HolderFullState {
Initial(InitialHolderState),
ProposalSent(ProposalSentState),
OfferReceived(OfferReceivedState),
RequestSent(RequestSentState),
RequestSet(RequestSetState),
Finished(FinishedHolderState),
}

Expand All @@ -46,7 +46,7 @@ pub enum HolderState {
Initial,
ProposalSent,
OfferReceived,
RequestSent,
RequestSet,
Finished,
Failed,
}
Expand All @@ -64,13 +64,13 @@ impl fmt::Display for HolderFullState {
HolderFullState::Initial(_) => f.write_str("Initial"),
HolderFullState::ProposalSent(_) => f.write_str("ProposalSent"),
HolderFullState::OfferReceived(_) => f.write_str("OfferReceived"),
HolderFullState::RequestSent(_) => f.write_str("RequestSent"),
HolderFullState::RequestSet(_) => f.write_str("RequestSent"),
HolderFullState::Finished(_) => f.write_str("Finished"),
}
}
}

fn build_credential_request_msg(credential_request_attach: String, thread_id: &str) -> RequestCredential {
fn _build_credential_request_msg(credential_request_attach: String, thread_id: &str) -> RequestCredential {
let content = RequestCredentialContent::new(vec![make_attach_from_str!(
&credential_request_attach,
AttachmentId::CredentialRequest.as_ref().to_string()
Expand Down Expand Up @@ -124,7 +124,7 @@ impl HolderSM {
HolderFullState::Initial(_) => HolderState::Initial,
HolderFullState::ProposalSent(_) => HolderState::ProposalSent,
HolderFullState::OfferReceived(_) => HolderState::OfferReceived,
HolderFullState::RequestSent(_) => HolderState::RequestSent,
HolderFullState::RequestSet(_) => HolderState::RequestSet,
HolderFullState::Finished(ref status) => match status.status {
Status::Success => HolderState::Finished,
_ => HolderState::Failed,
Expand Down Expand Up @@ -184,29 +184,36 @@ impl HolderSM {
Ok(Self { state, ..self })
}

pub async fn send_request<'a>(
pub async fn build_credential_request<'a>(
self,
ledger: &'a Arc<dyn AnoncredsLedgerRead>,
anoncreds: &'a Arc<dyn BaseAnonCreds>,
my_pw_did: String,
send_message: SendClosure,
) -> VcxResult<Self> {
let state = match self.state {
HolderFullState::OfferReceived(state_data) => {
match process_credential_offer(ledger, anoncreds, self.thread_id.clone(), my_pw_did, &state_data.offer)
.await
match build_credential_request_msg(
ledger,
anoncreds,
self.thread_id.clone(),
my_pw_did,
&state_data.offer,
)
.await
{
Ok((cred_request, req_meta, cred_def_json)) => {
send_message(cred_request.into()).await?;
HolderFullState::RequestSent((state_data, req_meta, cred_def_json).into())
Ok((msg_credential_request, req_meta, cred_def_json)) => {
HolderFullState::RequestSet(RequestSetState {
msg_credential_request,
req_meta,
cred_def_json,
})
}
Err(err) => {
let problem_report = build_problem_report_msg(Some(err.to_string()), &self.thread_id);
error!(
"Failed to create credential request, sending problem report: {:?}",
problem_report
);
send_message(problem_report.clone().into()).await?;
HolderFullState::Finished(problem_report.into())
}
}
Expand All @@ -219,6 +226,23 @@ impl HolderSM {
Ok(Self { state, ..self })
}

#[deprecated]
pub async fn send_credential_request(&self, send_message: SendClosure) -> VcxResult<()> {
match self.state {
HolderFullState::RequestSet(ref state) => {
let mut msg: RequestCredential = state.msg_credential_request.clone().into();
let mut timing = Timing::default();
timing.out_time = Some(Utc::now());
msg.decorators.timing = Some(timing);
send_message(msg.into()).await?;
}
_ => {
return Err(AriesVcxError::from_msg(AriesVcxErrorKind::NotReady, "Invalid action"));
}
};
Ok(())
}

pub async fn decline_offer(self, comment: Option<String>, send_message: SendClosure) -> VcxResult<Self> {
let state = match self.state {
HolderFullState::OfferReceived(_) => {
Expand All @@ -242,7 +266,7 @@ impl HolderSM {
send_message: SendClosure,
) -> VcxResult<Self> {
let state = match self.state {
HolderFullState::RequestSent(state_data) => {
HolderFullState::RequestSet(state_data) => {
match _store_credential(
ledger,
anoncreds,
Expand Down Expand Up @@ -280,7 +304,7 @@ impl HolderSM {

pub fn receive_problem_report(self, problem_report: ProblemReport) -> VcxResult<Self> {
let state = match self.state {
HolderFullState::ProposalSent(_) | HolderFullState::RequestSent(_) => {
HolderFullState::ProposalSent(_) | HolderFullState::RequestSet(_) => {
HolderFullState::Finished(problem_report.into())
}
s => {
Expand Down Expand Up @@ -403,7 +427,7 @@ impl HolderSM {
HolderFullState::Initial(ref state) => state.is_revokable(),
HolderFullState::ProposalSent(ref state) => state.is_revokable(ledger).await,
HolderFullState::OfferReceived(ref state) => state.is_revokable(ledger).await,
HolderFullState::RequestSent(ref state) => state.is_revokable(),
HolderFullState::RequestSet(ref state) => state.is_revokable(),
HolderFullState::Finished(ref state) => state.is_revokable(),
}
}
Expand Down Expand Up @@ -541,7 +565,7 @@ pub async fn create_anoncreds_credential_request(
.map_err(|err| err.into())
}

async fn process_credential_offer(
async fn build_credential_request_msg(
ledger: &Arc<dyn AnoncredsLedgerRead>,
anoncreds: &Arc<dyn BaseAnonCreds>,
thread_id: String,
Expand All @@ -561,6 +585,6 @@ async fn process_credential_offer(
let (req, req_meta, _cred_def_id, cred_def_json) =
create_anoncreds_credential_request(ledger, anoncreds, &cred_def_id, &my_pw_did, &cred_offer).await?;
trace!("Created cred def json: {}", cred_def_json);
let credential_request_msg = build_credential_request_msg(req, &thread_id);
let credential_request_msg = _build_credential_request_msg(req, &thread_id);
Ok((credential_request_msg, req_meta, cred_def_json))
}
13 changes: 1 addition & 12 deletions aries_vcx/src/protocols/issuance/holder/states/offer_received.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::sync::Arc;
use crate::errors::error::prelude::*;
use crate::handlers::util::get_attach_as_string;
use crate::protocols::issuance::holder::state_machine::parse_cred_def_id_from_cred_offer;
use crate::protocols::issuance::holder::states::request_sent::RequestSentState;
use crate::protocols::issuance::holder::states::request_sent::RequestSetState;
use crate::protocols::issuance::is_cred_def_revokable;
use messages::msg_fields::protocols::cred_issuance::offer_credential::OfferCredential;

Expand All @@ -13,17 +13,6 @@ pub struct OfferReceivedState {
pub offer: OfferCredential,
}

impl From<(OfferReceivedState, String, String)> for RequestSentState {
fn from((_state, req_meta, cred_def_json): (OfferReceivedState, String, String)) -> Self {
trace!("SM is now in RequestSent state");
trace!("cred_def_json={:?}", cred_def_json);
RequestSentState {
req_meta,
cred_def_json,
}
}
}

impl OfferReceivedState {
pub fn new(offer: OfferCredential) -> Self {
OfferReceivedState { offer }
Expand Down
10 changes: 6 additions & 4 deletions aries_vcx/src/protocols/issuance/holder/states/request_sent.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
use messages::msg_fields::protocols::cred_issuance::issue_credential::IssueCredential;
use messages::msg_fields::protocols::cred_issuance::request_credential::RequestCredential;

use crate::errors::error::prelude::*;
use crate::handlers::util::Status;
use crate::protocols::issuance::holder::states::finished::FinishedHolderState;

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct RequestSentState {
pub struct RequestSetState {
pub req_meta: String,
pub cred_def_json: String,
pub msg_credential_request: RequestCredential,
}

impl From<(RequestSentState, String, IssueCredential, Option<String>)> for FinishedHolderState {
impl From<(RequestSetState, String, IssueCredential, Option<String>)> for FinishedHolderState {
fn from(
(_, cred_id, credential, rev_reg_def_json): (RequestSentState, String, IssueCredential, Option<String>),
(_, cred_id, credential, rev_reg_def_json): (RequestSetState, String, IssueCredential, Option<String>),
) -> Self {
trace!("SM is now in Finished state");
FinishedHolderState {
Expand All @@ -24,7 +26,7 @@ impl From<(RequestSentState, String, IssueCredential, Option<String>)> for Finis
}
}

impl RequestSentState {
impl RequestSetState {
pub fn is_revokable(&self) -> VcxResult<bool> {
let parsed_cred_def: serde_json::Value = serde_json::from_str(&self.cred_def_json).map_err(|err| {
AriesVcxError::from_msg(
Expand Down
30 changes: 16 additions & 14 deletions aries_vcx/tests/test_creds_proofs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1666,21 +1666,22 @@ mod tests {
alice.credential = Holder::create_from_offer("test", cred_offer).unwrap();

let pw_did = alice.connection.pairwise_info().pw_did.to_string();
let send_closure = alice
.connection
.send_message_closure(alice.profile.inject_wallet())
.await
.unwrap();
alice
.credential
.send_request(
.build_credential_request(
&alice.profile.inject_anoncreds_ledger_read(),
&alice.profile.inject_anoncreds(),
pw_did,
alice
.connection
.send_message_closure(alice.profile.inject_wallet())
.await
.unwrap(),
)
.await
.unwrap();
assert_eq!(HolderState::RequestSent, alice.credential.get_state());
alice.credential.send_credential_request(send_closure).await.unwrap();
assert_eq!(HolderState::RequestSet, alice.credential.get_state());
}

#[cfg(feature = "migration")]
Expand Down Expand Up @@ -1777,22 +1778,23 @@ mod tests {
.await
.unwrap();

let send_closure = alice
.connection
.send_message_closure(alice.profile.inject_wallet())
.await
.unwrap();
let pw_did = alice.connection.pairwise_info().pw_did.to_string();
alice
.credential
.send_request(
.build_credential_request(
&alice.profile.inject_anoncreds_ledger_read(),
&alice.profile.inject_anoncreds(),
pw_did,
alice
.connection
.send_message_closure(alice.profile.inject_wallet())
.await
.unwrap(),
)
.await
.unwrap();
assert_eq!(HolderState::RequestSent, alice.credential.get_state());
alice.credential.send_credential_request(send_closure).await.unwrap();
assert_eq!(HolderState::RequestSet, alice.credential.get_state());
}

faber.send_credential().await;
Expand Down
15 changes: 9 additions & 6 deletions aries_vcx/tests/utils/devsetup_alice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,20 +177,23 @@ impl Alice {
self.credential = Holder::create_from_offer("degree", cred_offer).unwrap();
assert_eq!(HolderState::OfferReceived, self.credential.get_state());

let send_closure = self
.connection
.send_message_closure(self.profile.inject_wallet())
.await
.unwrap();

let pw_did = self.connection.pairwise_info().pw_did.to_string();
self.credential
.send_request(
.build_credential_request(
&self.profile.inject_anoncreds_ledger_read(),
&self.profile.inject_anoncreds(),
pw_did,
self.connection
.send_message_closure(self.profile.inject_wallet())
.await
.unwrap(),
)
.await
.unwrap();
assert_eq!(HolderState::RequestSent, self.credential.get_state());
self.credential.send_credential_request(send_closure).await.unwrap();
assert_eq!(HolderState::RequestSet, self.credential.get_state());
}

pub async fn accept_credential(&mut self) {
Expand Down
Loading

0 comments on commit 4fb71e5

Please sign in to comment.