diff --git a/aries_vcx/TUTORIAL.md b/aries_vcx/TUTORIAL.md index 6a5a743248..d91f767db0 100644 --- a/aries_vcx/TUTORIAL.md +++ b/aries_vcx/TUTORIAL.md @@ -1,4 +1,3 @@ - # Run ### Stage 1 - unit tests - First we need to get unit tests passing on your machine. These don't require any external services to run. diff --git a/aries_vcx/src/common/anoncreds.rs b/aries_vcx/src/common/anoncreds.rs index 7fff8f5028..7648a5af6c 100644 --- a/aries_vcx/src/common/anoncreds.rs +++ b/aries_vcx/src/common/anoncreds.rs @@ -63,7 +63,7 @@ pub mod integration_tests { SetupProfile::run_indy(|setup| async move { let holder_setup = init_holder_setup_in_indy_context(&setup).await; - let (_, _, _, _, _, _, _, _, rev_reg_id, cred_rev_id, _) = create_and_store_credential( + let (_, _, _, _, _, _, _, _, rev_reg_id, cred_rev_id, _, rev_reg) = create_and_store_credential( &setup.profile, &holder_setup.profile, &setup.institution_did, @@ -93,8 +93,8 @@ pub mod integration_tests { .await .unwrap(); - anoncreds - .publish_local_revocations(&setup.institution_did, &rev_reg_id) + rev_reg + .publish_local_revocations(&setup.profile, &setup.institution_did) .await .unwrap(); diff --git a/aries_vcx/src/common/credentials/mod.rs b/aries_vcx/src/common/credentials/mod.rs index 6a922981bb..c61bd5a8c3 100644 --- a/aries_vcx/src/common/credentials/mod.rs +++ b/aries_vcx/src/common/credentials/mod.rs @@ -121,6 +121,7 @@ mod integration_tests { let rev_reg_id = res.8; let cred_rev_id = res.9; let tails_file = res.10; + let rev_reg = res.11; assert!(!is_cred_revoked(&holder_setup.profile, &rev_reg_id, &cred_rev_id) .await @@ -132,8 +133,8 @@ mod integration_tests { .revoke_credential_local(&tails_file, &rev_reg_id, &cred_rev_id) .await .unwrap(); - anoncreds - .publish_local_revocations(&setup.institution_did, &rev_reg_id) + rev_reg + .publish_local_revocations(&setup.profile, &setup.institution_did) .await .unwrap(); diff --git a/aries_vcx/src/common/primitives/revocation_registry.rs b/aries_vcx/src/common/primitives/revocation_registry.rs index adfb35b14a..107d2769bd 100644 --- a/aries_vcx/src/common/primitives/revocation_registry.rs +++ b/aries_vcx/src/common/primitives/revocation_registry.rs @@ -196,11 +196,38 @@ impl RevocationRegistry { pub async fn publish_local_revocations(&self, profile: &Arc, submitter_did: &str) -> VcxResult<()> { let anoncreds = Arc::clone(profile).inject_anoncreds(); + let ledger = Arc::clone(profile).inject_ledger(); - anoncreds - .publish_local_revocations(submitter_did, &self.rev_reg_id) - .await - .map_err(|err| err.into()) + if let Some(delta) = anoncreds.get_rev_reg_delta(&self.rev_reg_id).await? { + ledger + .publish_rev_reg_delta(&self.rev_reg_id, &delta, submitter_did) + .await?; + + info!( + "publish_local_revocations >>> rev_reg_delta published for rev_reg_id {}", + self.rev_reg_id + ); + + match anoncreds.clear_rev_reg_delta(&self.rev_reg_id).await { + Ok(_) => { + info!( + "publish_local_revocations >>> rev_reg_delta storage cleared for rev_reg_id {}", + self.rev_reg_id + ); + Ok(()) + } + Err(err) => Err(AriesVcxError::from_msg( + AriesVcxErrorKind::RevDeltaFailedToClear, + format!( + "Failed to clear revocation delta storage for rev_reg_id: {}, error: {err}", + self.rev_reg_id + ), + )), + } + } else { + Err(AriesVcxError::from_msg(AriesVcxErrorKind::RevDeltaNotFound, + format!("Failed to publish revocation delta for revocation registry {}, no delta found. Possibly already published?", self.rev_reg_id))) + } } } diff --git a/aries_vcx/src/common/test_utils.rs b/aries_vcx/src/common/test_utils.rs index b2139779dd..ced9a42187 100644 --- a/aries_vcx/src/common/test_utils.rs +++ b/aries_vcx/src/common/test_utils.rs @@ -167,8 +167,9 @@ pub async fn create_and_store_credential( String, String, String, + RevocationRegistry, ) { - let (schema_id, schema_json, cred_def_id, cred_def_json, rev_reg_id, _, _) = + let (schema_id, schema_json, cred_def_id, cred_def_json, rev_reg_id, _, rev_reg) = create_and_store_credential_def(issuer, institution_did, attr_list).await; let (offer, req, req_meta) = @@ -210,6 +211,7 @@ pub async fn create_and_store_credential( rev_reg_id, cred_rev_id.unwrap(), tails_file, + rev_reg, ) } diff --git a/aries_vcx/src/core/profile/vdrtools_profile.rs b/aries_vcx/src/core/profile/vdrtools_profile.rs index 3b2d823b27..5c0bddc415 100644 --- a/aries_vcx/src/core/profile/vdrtools_profile.rs +++ b/aries_vcx/src/core/profile/vdrtools_profile.rs @@ -20,7 +20,7 @@ impl VdrtoolsProfile { pub fn new(indy_wallet_handle: WalletHandle, indy_pool_handle: PoolHandle) -> Self { let wallet = Arc::new(IndySdkWallet::new(indy_wallet_handle)); let ledger = Arc::new(IndySdkLedger::new(indy_wallet_handle, indy_pool_handle)); - let anoncreds = Arc::new(IndySdkAnonCreds::new(indy_wallet_handle, indy_pool_handle)); + let anoncreds = Arc::new(IndySdkAnonCreds::new(indy_wallet_handle)); VdrtoolsProfile { wallet, ledger, diff --git a/aries_vcx/src/utils/mockdata/profile/mock_anoncreds.rs b/aries_vcx/src/utils/mockdata/profile/mock_anoncreds.rs index fcb20154cb..9c441fe651 100644 --- a/aries_vcx/src/utils/mockdata/profile/mock_anoncreds.rs +++ b/aries_vcx/src/utils/mockdata/profile/mock_anoncreds.rs @@ -5,7 +5,7 @@ use crate::{ global::settings, utils::{ self, - constants::{LARGE_NONCE, LIBINDY_CRED_OFFER, REV_STATE_JSON}, + constants::{LARGE_NONCE, LIBINDY_CRED_OFFER, REV_REG_DELTA_JSON, REV_STATE_JSON}, mockdata::mock_settings::get_mock_creds_retrieved_for_proof_request, }, }; @@ -186,7 +186,11 @@ impl BaseAnonCreds for MockAnoncreds { Ok(()) } - async fn publish_local_revocations(&self, _submitter_did: &str, _rev_reg_id: &str) -> VcxCoreResult<()> { + async fn get_rev_reg_delta(&self, _rev_reg_id: &str) -> VcxCoreResult> { + Ok(Some(REV_REG_DELTA_JSON.to_string())) + } + + async fn clear_rev_reg_delta(&self, _rev_reg_id: &str) -> VcxCoreResult<()> { Ok(()) } diff --git a/aries_vcx/tests/test_creds_proofs_revocations.rs b/aries_vcx/tests/test_creds_proofs_revocations.rs index f1a18c3ef4..5bdd4719c6 100644 --- a/aries_vcx/tests/test_creds_proofs_revocations.rs +++ b/aries_vcx/tests/test_creds_proofs_revocations.rs @@ -48,7 +48,7 @@ mod integration_tests { let time_before_revocation = time::OffsetDateTime::now_utc().unix_timestamp() as u64; info!("test_basic_revocation :: verifier :: Going to revoke credential"); - revoke_credential_and_publish_accumulator(&mut institution, &issuer_credential, &rev_reg.rev_reg_id).await; + revoke_credential_and_publish_accumulator(&mut institution, &issuer_credential, &rev_reg).await; tokio::time::sleep(Duration::from_millis(1000)).await; let time_after_revocation = time::OffsetDateTime::now_utc().unix_timestamp() as u64; @@ -121,7 +121,7 @@ mod integration_tests { assert!(!issuer_credential.is_revoked(&institution.profile).await.unwrap()); info!("test_revocation_notification :: verifier :: Going to revoke credential"); - revoke_credential_and_publish_accumulator(&mut institution, &issuer_credential, &rev_reg.rev_reg_id).await; + revoke_credential_and_publish_accumulator(&mut institution, &issuer_credential, &rev_reg).await; tokio::time::sleep(Duration::from_millis(1000)).await; assert!(issuer_credential.is_revoked(&institution.profile).await.unwrap()); @@ -206,7 +206,7 @@ mod integration_tests { assert!(!issuer_credential.is_revoked(&institution.profile).await.unwrap()); - publish_revocation(&mut institution, rev_reg.rev_reg_id.clone()).await; + publish_revocation(&mut institution, &rev_reg).await; let request_name2 = Some("request2"); let mut verifier = verifier_create_proof_and_send_request( &mut institution, @@ -255,7 +255,7 @@ mod integration_tests { create_connected_connections(&mut consumer3, &mut institution).await; // Issue and send three credentials of the same schema - let (schema_id, _schema_json, cred_def_id, _cred_def_json, cred_def, rev_reg, rev_reg_id) = + let (schema_id, _schema_json, cred_def_id, _cred_def_json, cred_def, rev_reg, _rev_reg_id) = _create_address_schema(&institution.profile, &institution.config_issuer.institution_did).await; let (address1, address2, city, state, zip) = attr_names(); let credential_data1 = json!({address1.clone(): "123 Main St", address2.clone(): "Suite 3", city.clone(): "Draper", state.clone(): "UT", zip.clone(): "84000"}).to_string(); @@ -369,7 +369,7 @@ mod integration_tests { ); // Publish revocations and verify the two are invalid, third still valid - publish_revocation(&mut institution, rev_reg_id.clone().unwrap()).await; + publish_revocation(&mut institution, &rev_reg).await; tokio::time::sleep(Duration::from_millis(1000)).await; assert!(issuer_credential1.is_revoked(&institution.profile).await.unwrap()); @@ -472,7 +472,7 @@ mod integration_tests { let time_before_revocation = time::OffsetDateTime::now_utc().unix_timestamp() as u64; tokio::time::sleep(Duration::from_millis(1000)).await; info!("test_revoked_credential_might_still_work :: verifier :: Going to revoke credential"); - revoke_credential_and_publish_accumulator(&mut institution, &issuer_credential, &rev_reg.rev_reg_id).await; + revoke_credential_and_publish_accumulator(&mut institution, &issuer_credential, &rev_reg).await; tokio::time::sleep(Duration::from_millis(1000)).await; let from = time_before_revocation - 100; @@ -556,7 +556,7 @@ mod integration_tests { create_connected_connections(&mut consumer, &mut verifier).await; let (consumer_to_issuer, issuer_to_consumer) = create_connected_connections(&mut consumer, &mut issuer).await; - let (schema_id, _schema_json, cred_def_id, _cred_def_json, cred_def, rev_reg, rev_reg_id) = + let (schema_id, _schema_json, cred_def_id, _cred_def_json, cred_def, rev_reg, _rev_reg_id) = _create_address_schema(&issuer.profile, &issuer.config_issuer.institution_did).await; let (address1, address2, city, state, zip) = attr_names(); let (req1, req2) = (Some("request1"), Some("request2")); @@ -588,7 +588,7 @@ mod integration_tests { assert!(!issuer_credential1.is_revoked(&issuer.profile).await.unwrap()); assert!(!issuer_credential2.is_revoked(&issuer.profile).await.unwrap()); - revoke_credential_and_publish_accumulator(&mut issuer, &issuer_credential1, &rev_reg_id.unwrap()).await; + revoke_credential_and_publish_accumulator(&mut issuer, &issuer_credential1, &rev_reg).await; let mut proof_verifier = verifier_create_proof_and_send_request( &mut verifier, @@ -649,7 +649,7 @@ mod integration_tests { create_connected_connections(&mut consumer, &mut verifier).await; let (consumer_to_issuer, issuer_to_consumer) = create_connected_connections(&mut consumer, &mut issuer).await; - let (schema_id, _schema_json, cred_def_id, _cred_def_json, cred_def, rev_reg, rev_reg_id) = + let (schema_id, _schema_json, cred_def_id, _cred_def_json, cred_def, rev_reg, _rev_reg_id) = _create_address_schema(&issuer.profile, &issuer.config_issuer.institution_did).await; let (address1, address2, city, state, zip) = attr_names(); let (req1, req2) = (Some("request1"), Some("request2")); @@ -681,7 +681,7 @@ mod integration_tests { assert!(!issuer_credential1.is_revoked(&issuer.profile).await.unwrap()); assert!(!issuer_credential2.is_revoked(&issuer.profile).await.unwrap()); - revoke_credential_and_publish_accumulator(&mut issuer, &issuer_credential2, &rev_reg_id.unwrap()).await; + revoke_credential_and_publish_accumulator(&mut issuer, &issuer_credential2, &rev_reg).await; let mut proof_verifier = verifier_create_proof_and_send_request( &mut verifier, @@ -857,7 +857,7 @@ mod integration_tests { assert!(!issuer_credential1.is_revoked(&issuer.profile).await.unwrap()); assert!(!issuer_credential2.is_revoked(&issuer.profile).await.unwrap()); - revoke_credential_and_publish_accumulator(&mut issuer, &issuer_credential1, &rev_reg.rev_reg_id).await; + revoke_credential_and_publish_accumulator(&mut issuer, &issuer_credential1, &rev_reg).await; let mut proof_verifier = verifier_create_proof_and_send_request( &mut verifier, @@ -947,7 +947,7 @@ mod integration_tests { assert!(!issuer_credential1.is_revoked(&issuer.profile).await.unwrap()); assert!(!issuer_credential2.is_revoked(&issuer.profile).await.unwrap()); - revoke_credential_and_publish_accumulator(&mut issuer, &issuer_credential2, &rev_reg_2.rev_reg_id).await; + revoke_credential_and_publish_accumulator(&mut issuer, &issuer_credential2, &rev_reg_2).await; let mut proof_verifier = verifier_create_proof_and_send_request( &mut verifier, diff --git a/aries_vcx/tests/utils/scenarios.rs b/aries_vcx/tests/utils/scenarios.rs index 759f1235c8..fe729d8573 100644 --- a/aries_vcx/tests/utils/scenarios.rs +++ b/aries_vcx/tests/utils/scenarios.rs @@ -759,12 +759,11 @@ pub mod test_utils { pub async fn revoke_credential_and_publish_accumulator( faber: &mut Faber, issuer_credential: &Issuer, - rev_reg_id: &str, + rev_reg: &RevocationRegistry, ) { - revoke_credential_local(faber, issuer_credential, &rev_reg_id).await; - let anoncreds = Arc::clone(&faber.profile).inject_anoncreds(); - anoncreds - .publish_local_revocations(&faber.config_issuer.institution_did, &rev_reg_id) + revoke_credential_local(faber, issuer_credential, &rev_reg.rev_reg_id).await; + rev_reg + .publish_local_revocations(&faber.profile, &faber.config_issuer.institution_did) .await .unwrap(); } @@ -803,10 +802,9 @@ pub mod test_utils { rev_reg_new } - pub async fn publish_revocation(institution: &mut Faber, rev_reg_id: String) { - let anoncreds = Arc::clone(&institution.profile).inject_anoncreds(); - anoncreds - .publish_local_revocations(&institution.config_issuer.institution_did, rev_reg_id.as_str()) + pub async fn publish_revocation(institution: &mut Faber, rev_reg: &RevocationRegistry) { + rev_reg + .publish_local_revocations(&institution.profile, &institution.config_issuer.institution_did) .await .unwrap(); } diff --git a/aries_vcx_core/src/anoncreds/base_anoncreds.rs b/aries_vcx_core/src/anoncreds/base_anoncreds.rs index 6d2dbc2731..e7d979175f 100644 --- a/aries_vcx_core/src/anoncreds/base_anoncreds.rs +++ b/aries_vcx_core/src/anoncreds/base_anoncreds.rs @@ -103,8 +103,9 @@ pub trait BaseAnonCreds: std::fmt::Debug + Send + Sync { // TODO - FUTURE - think about moving this to somewhere else, as it aggregates other calls (not PURE Anoncreds) async fn revoke_credential_local(&self, tails_dir: &str, rev_reg_id: &str, cred_rev_id: &str) -> VcxCoreResult<()>; - // TODO - FUTURE - think about moving this to somewhere else, as it aggregates other calls (not PURE Anoncreds) - async fn publish_local_revocations(&self, submitter_did: &str, rev_reg_id: &str) -> VcxCoreResult<()>; + async fn get_rev_reg_delta(&self, rev_reg_id: &str) -> VcxCoreResult>; + + async fn clear_rev_reg_delta(&self, rev_reg_id: &str) -> VcxCoreResult<()>; async fn generate_nonce(&self) -> VcxCoreResult; } diff --git a/aries_vcx_core/src/anoncreds/credx_anoncreds.rs b/aries_vcx_core/src/anoncreds/credx_anoncreds.rs index 30208d1d3f..e59d279757 100644 --- a/aries_vcx_core/src/anoncreds/credx_anoncreds.rs +++ b/aries_vcx_core/src/anoncreds/credx_anoncreds.rs @@ -688,9 +688,12 @@ impl BaseAnonCreds for IndyCredxAnonCreds { Err(unimplemented_method_err("credx revoke_credential_local")) } - async fn publish_local_revocations(&self, submitter_did: &str, rev_reg_id: &str) -> VcxCoreResult<()> { - let _ = (submitter_did, rev_reg_id); - Err(unimplemented_method_err("credx publish_local_revocations")) + async fn get_rev_reg_delta(&self, rev_reg_id: &str) -> VcxCoreResult> { + Err(unimplemented_method_err("credx get_rev_reg_delta")) + } + + async fn clear_rev_reg_delta(&self, rev_reg_id: &str) -> VcxCoreResult<()> { + Err(unimplemented_method_err("credx clear_rev_reg_delta")) } async fn generate_nonce(&self) -> VcxCoreResult { diff --git a/aries_vcx_core/src/anoncreds/indy_anoncreds.rs b/aries_vcx_core/src/anoncreds/indy_anoncreds.rs index 7215690555..505f3c91d7 100644 --- a/aries_vcx_core/src/anoncreds/indy_anoncreds.rs +++ b/aries_vcx_core/src/anoncreds/indy_anoncreds.rs @@ -1,6 +1,7 @@ use async_trait::async_trait; use crate::errors::error::VcxCoreResult; +use crate::indy::wallet_non_secrets::{clear_rev_reg_delta, get_rev_reg_delta}; use crate::{indy, PoolHandle, WalletHandle}; use super::base_anoncreds::BaseAnonCreds; @@ -8,15 +9,11 @@ use super::base_anoncreds::BaseAnonCreds; #[derive(Debug)] pub struct IndySdkAnonCreds { indy_wallet_handle: WalletHandle, - indy_pool_handle: PoolHandle, } impl IndySdkAnonCreds { - pub fn new(indy_wallet_handle: WalletHandle, indy_pool_handle: PoolHandle) -> Self { - IndySdkAnonCreds { - indy_wallet_handle, - indy_pool_handle, - } + pub fn new(indy_wallet_handle: WalletHandle) -> Self { + IndySdkAnonCreds { indy_wallet_handle } } } @@ -219,14 +216,13 @@ impl BaseAnonCreds for IndySdkAnonCreds { .await } - async fn publish_local_revocations(&self, submitter_did: &str, rev_reg_id: &str) -> VcxCoreResult<()> { - indy::primitives::revocation_registry::publish_local_revocations( - self.indy_wallet_handle, - self.indy_pool_handle, - submitter_did, - rev_reg_id, - ) - .await + async fn get_rev_reg_delta(&self, rev_reg_id: &str) -> VcxCoreResult> { + Ok(get_rev_reg_delta(self.indy_wallet_handle, rev_reg_id).await) + } + + async fn clear_rev_reg_delta(&self, rev_reg_id: &str) -> VcxCoreResult<()> { + clear_rev_reg_delta(self.indy_wallet_handle, rev_reg_id).await?; + Ok(()) } async fn generate_nonce(&self) -> VcxCoreResult { diff --git a/aries_vcx_core/src/indy/primitives/revocation_registry.rs b/aries_vcx_core/src/indy/primitives/revocation_registry.rs index 60dc2ba1ad..2dd6e47840 100644 --- a/aries_vcx_core/src/indy/primitives/revocation_registry.rs +++ b/aries_vcx_core/src/indy/primitives/revocation_registry.rs @@ -1,5 +1,8 @@ +use std::sync::Arc; + use vdrtools::{DidValue, Locator}; +use crate::anoncreds::base_anoncreds::BaseAnonCreds; use crate::errors::error::{AriesVcxCoreError, AriesVcxCoreErrorKind, VcxCoreResult}; use crate::global::settings; use crate::indy::anoncreds; @@ -8,6 +11,7 @@ use crate::indy::ledger::transactions::{ }; use crate::indy::utils::parse_and_validate; use crate::indy::wallet_non_secrets::{clear_rev_reg_delta, get_rev_reg_delta, set_rev_reg_delta}; +use crate::ledger::base_ledger::BaseLedger; use crate::{PoolHandle, WalletHandle}; pub const BLOB_STORAGE_TYPE: &str = "default"; @@ -150,37 +154,3 @@ pub async fn revoke_credential_local( set_rev_reg_delta(wallet_handle, rev_reg_id, &new_delta_json).await } - -// consider moving out of indy dir as this aggregates multiple calls -pub async fn publish_local_revocations( - wallet_handle: WalletHandle, - pool_handle: PoolHandle, - submitter_did: &str, - rev_reg_id: &str, -) -> VcxCoreResult<()> { - if let Some(delta) = get_rev_reg_delta(wallet_handle, rev_reg_id).await { - publish_rev_reg_delta(wallet_handle, pool_handle, submitter_did, rev_reg_id, &delta).await?; - - info!( - "publish_local_revocations >>> rev_reg_delta published for rev_reg_id {}", - rev_reg_id - ); - - match clear_rev_reg_delta(wallet_handle, rev_reg_id).await { - Ok(_) => { - info!( - "publish_local_revocations >>> rev_reg_delta storage cleared for rev_reg_id {}", - rev_reg_id - ); - Ok(()) - } - Err(err) => Err(AriesVcxCoreError::from_msg( - AriesVcxCoreErrorKind::RevDeltaFailedToClear, - format!("Failed to clear revocation delta storage for rev_reg_id: {rev_reg_id}, error: {err}"), - )), - } - } else { - Err(AriesVcxCoreError::from_msg(AriesVcxCoreErrorKind::RevDeltaNotFound, - format!("Failed to publish revocation delta for revocation registry {rev_reg_id}, no delta found. Possibly already published?"))) - } -} diff --git a/ci/libvcx.dockerfile b/ci/libvcx.dockerfile index f8c41ad3ed..c3239db32b 100644 --- a/ci/libvcx.dockerfile +++ b/ci/libvcx.dockerfile @@ -30,6 +30,6 @@ RUN cp /usr/share/zoneinfo/UTC /etc/localtime && echo UTC > /etc/timezone ENV TZ=UTC RUN echo 'https://dl-cdn.alpinelinux.org/alpine/v3.17/main' >> /etc/apk/repositories -RUN apk add --no-cache nodejs=18.14.2-r0 +RUN apk add --no-cache nodejs~=18 USER node diff --git a/libvcx_core/src/api_vcx/api_handle/revocation_registry.rs b/libvcx_core/src/api_vcx/api_handle/revocation_registry.rs index a41886dc14..499a3ab084 100644 --- a/libvcx_core/src/api_vcx/api_handle/revocation_registry.rs +++ b/libvcx_core/src/api_vcx/api_handle/revocation_registry.rs @@ -46,12 +46,11 @@ pub async fn publish_revocations(handle: u32) -> LibvcxResult<()> { let submitter_did = get_config_value(CONFIG_INSTITUTION_DID)?; let rev_reg = REV_REG_MAP.get_cloned(handle)?; - let rev_reg_id = rev_reg.get_rev_reg_id(); - // TODO: Check result - let profile = get_main_profile()?; - let anoncreds = profile.inject_anoncreds(); - anoncreds.publish_local_revocations(&submitter_did, &rev_reg_id).await?; + rev_reg + .publish_local_revocations(&get_main_profile()?, &submitter_did) + .await?; + Ok(()) }