From d30adb21f27bb0f0d769829981c5744ce0b7e8f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Kr=C3=BCger?= Date: Wed, 20 Mar 2024 09:59:09 +0100 Subject: [PATCH 1/7] refactor: Make delegation::Store::get return Option --- src/delegation/agent.rs | 2 +- src/delegation/store/memory.rs | 16 ++++++++++------ src/delegation/store/traits.rs | 9 ++++++--- src/invocation/agent.rs | 8 ++++++-- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/delegation/agent.rs b/src/delegation/agent.rs index 89f86a8b..886b331b 100644 --- a/src/delegation/agent.rs +++ b/src/delegation/agent.rs @@ -14,7 +14,7 @@ use std::{collections::BTreeMap, marker::PhantomData}; use thiserror::Error; use web_time::SystemTime; -/// A stateful agent capable of delegatint to others, and being delegated to. +/// A stateful agent capable of delegating to others, and being delegated to. /// /// This is helpful for sessions where more than one delegation will be made. #[derive(Debug)] diff --git a/src/delegation/store/memory.rs b/src/delegation/store/memory.rs index 18d86103..297715e2 100644 --- a/src/delegation/store/memory.rs +++ b/src/delegation/store/memory.rs @@ -10,7 +10,10 @@ use libipld_core::codec::Encode; use libipld_core::ipld::Ipld; use libipld_core::{cid::Cid, codec::Codec}; use nonempty::NonEmpty; -use std::collections::{BTreeMap, BTreeSet}; +use std::{ + collections::{BTreeMap, BTreeSet}, + convert::Infallible, +}; use web_time::SystemTime; #[cfg_attr(doc, aquamarine::aquamarine)] @@ -117,12 +120,13 @@ where delegation::Payload: TryFrom>, Delegation: Encode, { - type DelegationStoreError = String; // FIXME misisng + type DelegationStoreError = Infallible; - fn get(&self, cid: &Cid) -> Result<&Delegation, Self::DelegationStoreError> { - self.ucans - .get(cid) - .ok_or(format!("not found in delegation memstore: {:?}", cid).into()) + fn get( + &self, + cid: &Cid, + ) -> Result>, Self::DelegationStoreError> { + Ok(self.ucans.get(cid)) // FIXME } diff --git a/src/delegation/store/traits.rs b/src/delegation/store/traits.rs index 3bd7b1fb..2f8f42d5 100644 --- a/src/delegation/store/traits.rs +++ b/src/delegation/store/traits.rs @@ -11,7 +11,10 @@ use web_time::SystemTime; pub trait Store, Enc: Codec + TryFrom + Into> { type DelegationStoreError: Debug; - fn get(&self, cid: &Cid) -> Result<&Delegation, Self::DelegationStoreError>; + fn get( + &self, + cid: &Cid, + ) -> Result>, Self::DelegationStoreError>; fn insert( &mut self, @@ -60,7 +63,7 @@ pub trait Store, Enc: Codec + TryFrom + In fn get_many( &self, cids: &[Cid], - ) -> Result>, Self::DelegationStoreError> { + ) -> Result>>, Self::DelegationStoreError> { cids.iter().try_fold(vec![], |mut acc, cid| { acc.push(self.get(cid)?); Ok(acc) @@ -73,7 +76,7 @@ impl, DID: Did, V: varsig::Header, C: Codec + TryFrom>::DelegationStoreError; - fn get(&self, cid: &Cid) -> Result<&Delegation, Self::DelegationStoreError> { + fn get(&self, cid: &Cid) -> Result>, Self::DelegationStoreError> { (**self).get(cid) } diff --git a/src/invocation/agent.rs b/src/invocation/agent.rs index a4e5f7fd..c93e8036 100644 --- a/src/invocation/agent.rs +++ b/src/invocation/agent.rs @@ -209,8 +209,9 @@ where .get_many(&invocation.proofs()) .map_err(ReceiveError::DelegationStoreError)? .iter() - .map(|d| &d.payload) - .collect(); + .zip(invocation.proofs().iter()) + .map(|(d, cid)| Ok(&d.ok_or(ReceiveError::MissingDelegation(*cid))?.payload)) + .collect::>>()?; let _ = &invocation .payload @@ -290,6 +291,9 @@ pub enum ReceiveError< > where >::InvocationStoreError: fmt::Debug, { + #[error("missing delegation: {0}")] + MissingDelegation(Cid), + #[error("encoding error: {0}")] EncodingError(#[from] libipld_core::error::Error), From 11c8c0508440d8cf0195ce1c70d21b63ea82a455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Kr=C3=BCger?= Date: Wed, 20 Mar 2024 11:57:01 +0100 Subject: [PATCH 2/7] refactor: Make delegation::Store::insert take &self instead of &mut self --- src/delegation/agent.rs | 8 ++-- src/delegation/store/memory.rs | 88 ++++++++++++++++++++++++++-------- src/delegation/store/traits.rs | 33 +++++++------ src/invocation/agent.rs | 21 +++++--- 4 files changed, 103 insertions(+), 47 deletions(-) diff --git a/src/delegation/agent.rs b/src/delegation/agent.rs index 886b331b..f7b973d6 100644 --- a/src/delegation/agent.rs +++ b/src/delegation/agent.rs @@ -93,14 +93,12 @@ where } } - let to_delegate = &self + let proofs = &self .store .get_chain(&self.did, &subject, "/".into(), vec![], now) .map_err(DelegateError::StoreError)? - .ok_or(DelegateError::ProofsNotFound)? - .first() - .1 - .payload(); + .ok_or(DelegateError::ProofsNotFound)?; + let to_delegate = proofs.first().1.payload(); let mut policy = to_delegate.policy.clone(); policy.append(&mut new_policy.clone()); diff --git a/src/delegation/store/memory.rs b/src/delegation/store/memory.rs index 297715e2..c36a6e2d 100644 --- a/src/delegation/store/memory.rs +++ b/src/delegation/store/memory.rs @@ -10,6 +10,7 @@ use libipld_core::codec::Encode; use libipld_core::ipld::Ipld; use libipld_core::{cid::Cid, codec::Codec}; use nonempty::NonEmpty; +use std::sync::{Arc, Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard}; use std::{ collections::{BTreeMap, BTreeSet}, convert::Infallible, @@ -72,36 +73,77 @@ use web_time::SystemTime; /// linkStyle 6 stroke:orange; /// linkStyle 1 stroke:orange; /// ``` -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone)] pub struct MemoryStore< DID: did::Did + Ord = did::preset::Verifier, V: varsig::Header = varsig::header::Preset, C: Codec + TryFrom + Into = varsig::encoding::Preset, > { - ucans: BTreeMap>, + inner: Arc>>, +} + +#[derive(Debug, Clone, PartialEq)] +struct MemoryStoreInner< + DID: did::Did + Ord = did::preset::Verifier, + V: varsig::Header = varsig::header::Preset, + C: Codec + TryFrom + Into = varsig::encoding::Preset, +> { + ucans: BTreeMap>>, index: BTreeMap, BTreeMap>>, revocations: BTreeSet, } -impl MemoryStore { +impl, C: Codec + TryFrom + Into> + MemoryStore +{ pub fn new() -> Self { Self::default() } pub fn len(&self) -> usize { - self.ucans.len() + self.read().ucans.len() } pub fn is_empty(&self) -> bool { - self.ucans.is_empty() // FIXME acocunt for revocations? + self.read().ucans.is_empty() // FIXME acocunt for revocations? + } + + fn read(&self) -> RwLockReadGuard<'_, MemoryStoreInner> { + match self.inner.read() { + Ok(guard) => guard, + Err(poison) => { + // We ignore lock poisoning for simplicity + poison.into_inner() + } + } + } + + fn write(&self) -> RwLockWriteGuard<'_, MemoryStoreInner> { + match self.inner.write() { + Ok(guard) => guard, + Err(poison) => { + // We ignore lock poisoning for simplicity + poison.into_inner() + } + } } } -impl, C: Codec + TryFrom + Into> Default +impl, C: Codec + TryFrom + Into> Default for MemoryStore { fn default() -> Self { - MemoryStore { + Self { + inner: Default::default(), + } + } +} + +impl, C: Codec + TryFrom + Into> Default + for MemoryStoreInner +{ + fn default() -> Self { + MemoryStoreInner { ucans: BTreeMap::new(), index: BTreeMap::new(), revocations: BTreeSet::new(), @@ -125,30 +167,34 @@ where fn get( &self, cid: &Cid, - ) -> Result>, Self::DelegationStoreError> { - Ok(self.ucans.get(cid)) + ) -> Result>>, Self::DelegationStoreError> { + // cheap Arc clone + Ok(self.read().ucans.get(cid).cloned()) // FIXME } fn insert( - &mut self, + &self, cid: Cid, delegation: Delegation, ) -> Result<(), Self::DelegationStoreError> { - self.index + let mut write_tx = self.write(); + + write_tx + .index .entry(delegation.subject().clone()) .or_default() .entry(delegation.audience().clone()) .or_default() .insert(cid); - self.ucans.insert(cid.clone(), delegation); + write_tx.ucans.insert(cid.clone(), Arc::new(delegation)); Ok(()) } - fn revoke(&mut self, cid: Cid) -> Result<(), Self::DelegationStoreError> { - self.revocations.insert(cid); + fn revoke(&self, cid: Cid) -> Result<(), Self::DelegationStoreError> { + self.write().revocations.insert(cid); Ok(()) } @@ -159,12 +205,14 @@ where command: String, policy: Vec, // FIXME now: SystemTime, - ) -> Result)>>, Self::DelegationStoreError> { + ) -> Result>)>>, Self::DelegationStoreError> + { let blank_set = BTreeSet::new(); let blank_map = BTreeMap::new(); + let read_tx = self.read(); - let all_powerlines = self.index.get(&None).unwrap_or(&blank_map); - let all_aud_for_subject = self.index.get(subject).unwrap_or(&blank_map); + let all_powerlines = read_tx.index.get(&None).unwrap_or(&blank_map); + let all_aud_for_subject = read_tx.index.get(subject).unwrap_or(&blank_map); let powerline_candidates = all_powerlines.get(aud).unwrap_or(&blank_set); let sub_candidates = all_aud_for_subject.get(aud).unwrap_or(&blank_set); @@ -189,11 +237,11 @@ where } 'inner: for cid in parent_cid_candidates { - if self.revocations.contains(cid) { + if read_tx.revocations.contains(cid) { continue; } - if let Some(delegation) = self.ucans.get(cid) { + if let Some(delegation) = read_tx.ucans.get(cid) { if delegation.check_time(now).is_err() { continue; } @@ -221,7 +269,7 @@ where } } - hypothesis_chain.push((cid.clone(), delegation)); + hypothesis_chain.push((cid.clone(), Arc::clone(delegation))); let issuer = delegation.issuer().clone(); diff --git a/src/delegation/store/traits.rs b/src/delegation/store/traits.rs index 2f8f42d5..7413e700 100644 --- a/src/delegation/store/traits.rs +++ b/src/delegation/store/traits.rs @@ -5,7 +5,7 @@ use crate::{ }; use libipld_core::{cid::Cid, codec::Codec}; use nonempty::NonEmpty; -use std::fmt::Debug; +use std::{fmt::Debug, sync::Arc}; use web_time::SystemTime; pub trait Store, Enc: Codec + TryFrom + Into> { @@ -14,10 +14,10 @@ pub trait Store, Enc: Codec + TryFrom + In fn get( &self, cid: &Cid, - ) -> Result>, Self::DelegationStoreError>; + ) -> Result>>, Self::DelegationStoreError>; fn insert( - &mut self, + &self, cid: Cid, delegation: Delegation, ) -> Result<(), Self::DelegationStoreError>; @@ -25,7 +25,7 @@ pub trait Store, Enc: Codec + TryFrom + In // FIXME validate invocation // store invocation // just... move to invocation - fn revoke(&mut self, cid: Cid) -> Result<(), Self::DelegationStoreError>; + fn revoke(&self, cid: Cid) -> Result<(), Self::DelegationStoreError>; fn get_chain( &self, @@ -34,7 +34,7 @@ pub trait Store, Enc: Codec + TryFrom + In command: String, policy: Vec, now: SystemTime, - ) -> Result)>>, Self::DelegationStoreError>; + ) -> Result>)>>, Self::DelegationStoreError>; fn get_chain_cids( &self, @@ -63,32 +63,34 @@ pub trait Store, Enc: Codec + TryFrom + In fn get_many( &self, cids: &[Cid], - ) -> Result>>, Self::DelegationStoreError> { - cids.iter().try_fold(vec![], |mut acc, cid| { - acc.push(self.get(cid)?); - Ok(acc) - }) + ) -> Result>>>, Self::DelegationStoreError> { + cids.iter() + .map(|cid| self.get(cid)) + .collect::>() } } impl, DID: Did, V: varsig::Header, C: Codec + TryFrom + Into> - Store for &mut T + Store for &T { type DelegationStoreError = >::DelegationStoreError; - fn get(&self, cid: &Cid) -> Result>, Self::DelegationStoreError> { + fn get( + &self, + cid: &Cid, + ) -> Result>>, Self::DelegationStoreError> { (**self).get(cid) } fn insert( - &mut self, + &self, cid: Cid, delegation: Delegation, ) -> Result<(), Self::DelegationStoreError> { (**self).insert(cid, delegation) } - fn revoke(&mut self, cid: Cid) -> Result<(), Self::DelegationStoreError> { + fn revoke(&self, cid: Cid) -> Result<(), Self::DelegationStoreError> { (**self).revoke(cid) } @@ -99,7 +101,8 @@ impl, DID: Did, V: varsig::Header, C: Codec + TryFrom, now: SystemTime, - ) -> Result)>>, Self::DelegationStoreError> { + ) -> Result>)>>, Self::DelegationStoreError> + { (**self).get_chain(audience, subject, command, policy, now) } } diff --git a/src/invocation/agent.rs b/src/invocation/agent.rs index c93e8036..fc5845c3 100644 --- a/src/invocation/agent.rs +++ b/src/invocation/agent.rs @@ -27,6 +27,7 @@ use std::{ collections::{BTreeMap, BTreeSet}, fmt, marker::PhantomData, + sync::Arc, }; use thiserror::Error; use web_time::SystemTime; @@ -204,13 +205,19 @@ where .put(cid.clone(), invocation.clone()) .map_err(ReceiveError::InvocationStoreError)?; - let proof_payloads: Vec<&delegation::Payload> = self + let proofs = &self .delegation_store .get_many(&invocation.proofs()) - .map_err(ReceiveError::DelegationStoreError)? + .map_err(ReceiveError::DelegationStoreError)?; + let proof_payloads: Vec<&delegation::Payload> = proofs .iter() .zip(invocation.proofs().iter()) - .map(|(d, cid)| Ok(&d.ok_or(ReceiveError::MissingDelegation(*cid))?.payload)) + .map(|(d, cid)| { + Ok(&d + .as_ref() + .ok_or(ReceiveError::MissingDelegation(*cid))? + .payload) + }) .collect::>>()?; let _ = &invocation @@ -748,13 +755,13 @@ mod tests { let mut agent: Agent< '_, &mut crate::invocation::store::MemoryStore, - &mut crate::delegation::store::MemoryStore, + &crate::delegation::store::MemoryStore, AccountManage, > = Agent::new( &ctx.server, &ctx.server_signer, &mut ctx.inv_store, - &mut ctx.del_store, + &ctx.del_store, ); let observed = agent.receive(ctx.account_invocation.clone()); @@ -769,13 +776,13 @@ mod tests { let mut agent: Agent< '_, &mut crate::invocation::store::MemoryStore, - &mut crate::delegation::store::MemoryStore, + &crate::delegation::store::MemoryStore, AccountManage, > = Agent::new( &ctx.server, &ctx.server_signer, &mut ctx.inv_store, - &mut ctx.del_store, + &ctx.del_store, ); let not_account_invocation = crate::Invocation::try_sign( From 32164a3e199c63fe8d4f04d7f6a1bc8abf84358e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Kr=C3=BCger?= Date: Wed, 20 Mar 2024 12:14:55 +0100 Subject: [PATCH 3/7] refactor: Make invocation::Store take &self instead of &mut self --- src/invocation/agent.rs | 14 ++++----- src/invocation/store.rs | 65 ++++++++++++++++++++++++++++++++--------- 2 files changed, 59 insertions(+), 20 deletions(-) diff --git a/src/invocation/agent.rs b/src/invocation/agent.rs index fc5845c3..23bd1360 100644 --- a/src/invocation/agent.rs +++ b/src/invocation/agent.rs @@ -635,7 +635,7 @@ mod tests { ); let inv_store = crate::invocation::store::MemoryStore::default(); - let mut del_store = crate::delegation::store::MemoryStore::default(); + let del_store = crate::delegation::store::MemoryStore::default(); // Scenario // ======== @@ -750,17 +750,17 @@ mod tests { #[test_log::test] fn test_chain_ok() -> TestResult { - let mut ctx = setup_test_chain()?; + let ctx = setup_test_chain()?; let mut agent: Agent< '_, - &mut crate::invocation::store::MemoryStore, + &crate::invocation::store::MemoryStore, &crate::delegation::store::MemoryStore, AccountManage, > = Agent::new( &ctx.server, &ctx.server_signer, - &mut ctx.inv_store, + &ctx.inv_store, &ctx.del_store, ); @@ -771,17 +771,17 @@ mod tests { #[test_log::test] fn test_chain_wrong_sub() -> TestResult { - let mut ctx = setup_test_chain()?; + let ctx = setup_test_chain()?; let mut agent: Agent< '_, - &mut crate::invocation::store::MemoryStore, + &crate::invocation::store::MemoryStore, &crate::delegation::store::MemoryStore, AccountManage, > = Agent::new( &ctx.server, &ctx.server_signer, - &mut ctx.inv_store, + &ctx.inv_store, &ctx.del_store, ); diff --git a/src/invocation/store.rs b/src/invocation/store.rs index 26618909..4c9279fa 100644 --- a/src/invocation/store.rs +++ b/src/invocation/store.rs @@ -4,6 +4,7 @@ use super::Invocation; use crate::ability; use crate::{crypto::varsig, did::Did}; use libipld_core::{cid::Cid, codec::Codec}; +use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard}; use std::{collections::BTreeMap, convert::Infallible}; pub trait Store, C: Codec + Into + TryFrom> { @@ -12,10 +13,10 @@ pub trait Store, C: Codec + Into + TryFro fn get( &self, cid: Cid, - ) -> Result>, Self::InvocationStoreError>; + ) -> Result>>, Self::InvocationStoreError>; fn put( - &mut self, + &self, cid: Cid, invocation: Invocation, ) -> Result<(), Self::InvocationStoreError>; @@ -31,20 +32,22 @@ impl< DID: Did, V: varsig::Header, C: Codec + Into + TryFrom, - > Store for &mut S + > Store for &S { type InvocationStoreError = >::InvocationStoreError; fn get( &self, cid: Cid, - ) -> Result>, >::InvocationStoreError> - { + ) -> Result< + Option>>, + >::InvocationStoreError, + > { (**self).get(cid) } fn put( - &mut self, + &self, cid: Cid, invocation: Invocation, ) -> Result<(), >::InvocationStoreError> { @@ -52,14 +55,48 @@ impl< } } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone)] pub struct MemoryStore< T = crate::ability::preset::Preset, DID: crate::did::Did = crate::did::preset::Verifier, V: varsig::Header = varsig::header::Preset, C: Codec + TryFrom + Into = varsig::encoding::Preset, > { - store: BTreeMap>, + inner: Arc>>, +} + +#[derive(Debug, Clone, PartialEq)] +pub struct MemoryStoreInner< + T = crate::ability::preset::Preset, + DID: crate::did::Did = crate::did::preset::Verifier, + V: varsig::Header = varsig::header::Preset, + C: Codec + TryFrom + Into = varsig::encoding::Preset, +> { + store: BTreeMap>>, +} + +impl, Enc: Codec + Into + TryFrom> + MemoryStore +{ + fn read(&self) -> RwLockReadGuard<'_, MemoryStoreInner> { + match self.inner.read() { + Ok(guard) => guard, + Err(poison) => { + // There's no logic errors through lock poisoning in our case + poison.into_inner() + } + } + } + + fn write(&self) -> RwLockWriteGuard<'_, MemoryStoreInner> { + match self.inner.write() { + Ok(guard) => guard, + Err(poison) => { + // There's no logic errors through lock poisoning in our case + poison.into_inner() + } + } + } } impl, Enc: Codec + Into + TryFrom> Default @@ -67,7 +104,9 @@ impl, Enc: Codec + Into + TryFrom> { fn default() -> Self { Self { - store: BTreeMap::new(), + inner: Arc::new(RwLock::new(MemoryStoreInner { + store: BTreeMap::new(), + })), } } } @@ -80,16 +119,16 @@ impl, Enc: Codec + Into + TryFrom> fn get( &self, cid: Cid, - ) -> Result>, Self::InvocationStoreError> { - Ok(self.store.get(&cid)) + ) -> Result>>, Self::InvocationStoreError> { + Ok(self.read().store.get(&cid).cloned()) } fn put( - &mut self, + &self, cid: Cid, invocation: Invocation, ) -> Result<(), Self::InvocationStoreError> { - self.store.insert(cid, invocation); + self.write().store.insert(cid, Arc::new(invocation)); Ok(()) } } From 7c50aba4ae8ea286da90dbe044d12c80ef388e88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Kr=C3=BCger?= Date: Wed, 20 Mar 2024 16:19:05 +0100 Subject: [PATCH 4/7] refactor: Make `delegation::Agent` not take `&mut self` in methods --- src/delegation/agent.rs | 6 +++--- src/invocation/agent.rs | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/delegation/agent.rs b/src/delegation/agent.rs index f7b973d6..3a0565a3 100644 --- a/src/delegation/agent.rs +++ b/src/delegation/agent.rs @@ -29,7 +29,7 @@ pub struct Agent< pub did: &'a DID, /// The attached [`deleagtion::Store`][super::store::Store]. - pub store: &'a mut S, + pub store: S, signer: &'a ::Signer, _marker: PhantomData<(V, Enc)>, @@ -47,7 +47,7 @@ where Payload: TryFrom>, Named: From>, { - pub fn new(did: &'a DID, signer: &'a ::Signer, store: &'a mut S) -> Self { + pub fn new(did: &'a DID, signer: &'a ::Signer, store: S) -> Self { Self { did, store, @@ -120,7 +120,7 @@ where } pub fn receive( - &mut self, + &self, cid: Cid, // FIXME remove and generate from the capsule header? delegation: Delegation, ) -> Result<(), ReceiveError> { diff --git a/src/invocation/agent.rs b/src/invocation/agent.rs index 23bd1360..6fdd306b 100644 --- a/src/invocation/agent.rs +++ b/src/invocation/agent.rs @@ -86,7 +86,7 @@ where } pub fn invoke( - &mut self, + &self, audience: Option, subject: DID, ability: T, @@ -172,7 +172,7 @@ where // } pub fn receive( - &mut self, + &self, invocation: Invocation, ) -> Result>, ReceiveError> where @@ -184,7 +184,7 @@ where } pub fn generic_receive( - &mut self, + &self, invocation: Invocation, now: SystemTime, ) -> Result>, ReceiveError> @@ -233,7 +233,7 @@ where } // pub fn revoke( - // &mut self, + // &self, // subject: DID, // cause: Option, // cid: Cid, From 1971a3d4bdd756175594f2f388537612c18de297 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Kr=C3=BCger?= Date: Wed, 20 Mar 2024 12:36:39 +0100 Subject: [PATCH 5/7] refactor: Make `Agent` take `DID` by value --- src/invocation/agent.rs | 59 +++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 38 deletions(-) diff --git a/src/invocation/agent.rs b/src/invocation/agent.rs index 6fdd306b..11838bde 100644 --- a/src/invocation/agent.rs +++ b/src/invocation/agent.rs @@ -34,7 +34,6 @@ use web_time::SystemTime; #[derive(Debug)] pub struct Agent< - 'a, S: Store, D: delegation::store::Store, T: ToCommand = ability::preset::Preset, @@ -43,7 +42,7 @@ pub struct Agent< C: Codec + Into + TryFrom = varsig::encoding::Preset, > { /// The agent's [`DID`]. - pub did: &'a DID, + pub did: DID, /// A [`delegation::Store`][delegation::store::Store]. pub delegation_store: D, @@ -51,11 +50,11 @@ pub struct Agent< /// A [`Store`][Store] for the agent's [`Invocation`]s. pub invocation_store: S, - signer: &'a ::Signer, + signer: ::Signer, marker: PhantomData<(T, V, C)>, } -impl<'a, T, DID, S, D, V, C> Agent<'a, S, D, T, DID, V, C> +impl Agent where Ipld: Encode, T: ToCommand + Clone + ParseAbility, @@ -71,8 +70,8 @@ where >::DelegationStoreError: fmt::Debug, { pub fn new( - did: &'a DID, - signer: &'a ::Signer, + did: DID, + signer: ::Signer, invocation_store: S, delegation_store: D, ) -> Self { @@ -225,7 +224,7 @@ where .check(proof_payloads, now) .map_err(ReceiveError::ValidationError)?; - Ok(if invocation.normalized_audience() != self.did { + Ok(if invocation.normalized_audience() != &self.did { Recipient::Other(invocation.payload) } else { Recipient::You(invocation.payload) @@ -408,11 +407,9 @@ mod tests { (verifier, signer) } - fn setup_agent<'a>( - did: &'a crate::did::preset::Verifier, - signer: &'a crate::did::preset::Signer, - ) -> Agent<'a, crate::invocation::store::MemoryStore, crate::delegation::store::MemoryStore> - { + fn setup_agent( + ) -> Agent { + let (did, signer) = gen_did(); let inv_store = crate::invocation::store::MemoryStore::default(); let del_store = crate::delegation::store::MemoryStore::default(); @@ -438,8 +435,7 @@ mod tests { #[test_log::test] fn test_invoker_is_sub_implicit_aud() -> TestResult { let (_nbf, now, exp) = setup_valid_time(); - let (server, server_signer) = gen_did(); - let mut agent = setup_agent(&server, &server_signer); + let mut agent = setup_agent(); let invocation = agent.invoke( None, @@ -467,8 +463,7 @@ mod tests { #[test_log::test] fn test_invoker_is_sub_and_aud() -> TestResult { let (_nbf, now, exp) = setup_valid_time(); - let (server, server_signer) = gen_did(); - let mut agent = setup_agent(&server, &server_signer); + let mut agent = setup_agent(); let invocation = agent.invoke( Some(agent.did.clone()), @@ -497,8 +492,7 @@ mod tests { #[test_log::test] fn test_other_recipient() -> TestResult { let (_nbf, now, exp) = setup_valid_time(); - let (server, server_signer) = gen_did(); - let mut agent = setup_agent(&server, &server_signer); + let mut agent = setup_agent(); let (not_server, _) = gen_did(); @@ -528,8 +522,7 @@ mod tests { #[test_log::test] fn test_expired() -> TestResult { let (past, now, _exp) = setup_valid_time(); - let (server, server_signer) = gen_did(); - let mut agent = setup_agent(&server, &server_signer); + let mut agent = setup_agent(); let invocation = agent.invoke( None, @@ -564,8 +557,8 @@ mod tests { #[test_log::test] fn test_invalid_sig() -> TestResult { let (_past, now, _exp) = setup_valid_time(); - let (server, server_signer) = gen_did(); - let mut agent = setup_agent(&server, &server_signer); + let mut agent = setup_agent(); + let server = &agent.did; let mut invocation = agent.invoke( None, @@ -752,14 +745,9 @@ mod tests { fn test_chain_ok() -> TestResult { let ctx = setup_test_chain()?; - let mut agent: Agent< - '_, - &crate::invocation::store::MemoryStore, - &crate::delegation::store::MemoryStore, - AccountManage, - > = Agent::new( - &ctx.server, - &ctx.server_signer, + let mut agent = Agent::new( + ctx.server.clone(), + ctx.server_signer.clone(), &ctx.inv_store, &ctx.del_store, ); @@ -773,14 +761,9 @@ mod tests { fn test_chain_wrong_sub() -> TestResult { let ctx = setup_test_chain()?; - let mut agent: Agent< - '_, - &crate::invocation::store::MemoryStore, - &crate::delegation::store::MemoryStore, - AccountManage, - > = Agent::new( - &ctx.server, - &ctx.server_signer, + let mut agent = Agent::new( + ctx.server.clone(), + ctx.server_signer.clone(), &ctx.inv_store, &ctx.del_store, ); From 254b7f40e4c2ae327127c7d31dd1965581d3f1ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Kr=C3=BCger?= Date: Wed, 20 Mar 2024 16:21:15 +0100 Subject: [PATCH 6/7] refactor: Take `DID` by value in `delegation::Agent::new` --- src/delegation/agent.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/delegation/agent.rs b/src/delegation/agent.rs index 3a0565a3..14d28e56 100644 --- a/src/delegation/agent.rs +++ b/src/delegation/agent.rs @@ -19,35 +19,33 @@ use web_time::SystemTime; /// This is helpful for sessions where more than one delegation will be made. #[derive(Debug)] pub struct Agent< - 'a, DID: Did, S: Store, V: varsig::Header, Enc: Codec + TryFrom + Into, > { /// The [`Did`][Did] of the agent. - pub did: &'a DID, + pub did: DID, /// The attached [`deleagtion::Store`][super::store::Store]. pub store: S, - signer: &'a ::Signer, + signer: ::Signer, _marker: PhantomData<(V, Enc)>, } impl< - 'a, DID: Did + Clone, S: Store + Clone, V: varsig::Header + Clone, Enc: Codec + TryFrom + Into, - > Agent<'a, DID, S, V, Enc> + > Agent where Ipld: Encode, Payload: TryFrom>, Named: From>, { - pub fn new(did: &'a DID, signer: &'a ::Signer, store: S) -> Self { + pub fn new(did: DID, signer: ::Signer, store: S) -> Self { Self { did, store, @@ -73,7 +71,7 @@ where let nonce = Nonce::generate_12(&mut salt); if let Some(ref sub) = subject { - if sub == self.did { + if sub == &self.did { let payload: Payload = Payload { issuer: self.did.clone(), audience, @@ -88,7 +86,7 @@ where }; return Ok( - Delegation::try_sign(self.signer, varsig_header, payload).expect("FIXME") + Delegation::try_sign(&self.signer, varsig_header, payload).expect("FIXME") ); } } @@ -116,7 +114,7 @@ where not_before: not_before.map(Into::into), }; - Ok(Delegation::try_sign(self.signer, varsig_header, payload).expect("FIXME")) + Ok(Delegation::try_sign(&self.signer, varsig_header, payload).expect("FIXME")) } pub fn receive( @@ -128,7 +126,7 @@ where return Ok(()); } - if delegation.audience() != self.did { + if delegation.audience() != &self.did { return Err(ReceiveError::WrongAudience(delegation.audience().clone())); } From 0c8a7180ed178bc260c30fc20d101556e2e68e0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Kr=C3=BCger?= Date: Wed, 20 Mar 2024 16:24:27 +0100 Subject: [PATCH 7/7] refactor: Change generic order in `delegation::Agent` and add defaults --- src/delegation/agent.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/delegation/agent.rs b/src/delegation/agent.rs index 14d28e56..bfee4119 100644 --- a/src/delegation/agent.rs +++ b/src/delegation/agent.rs @@ -1,5 +1,6 @@ use super::{payload::Payload, policy::Predicate, store::Store, Delegation}; use crate::ability::arguments::Named; +use crate::did; use crate::{ crypto::{signature::Envelope, varsig, Nonce}, did::Did, @@ -19,10 +20,10 @@ use web_time::SystemTime; /// This is helpful for sessions where more than one delegation will be made. #[derive(Debug)] pub struct Agent< - DID: Did, S: Store, - V: varsig::Header, - Enc: Codec + TryFrom + Into, + DID: Did = did::preset::Verifier, + V: varsig::Header + Clone = varsig::header::Preset, + Enc: Codec + Into + TryFrom = varsig::encoding::Preset, > { /// The [`Did`][Did] of the agent. pub did: DID, @@ -35,11 +36,11 @@ pub struct Agent< } impl< - DID: Did + Clone, S: Store + Clone, + DID: Did + Clone, V: varsig::Header + Clone, Enc: Codec + TryFrom + Into, - > Agent + > Agent where Ipld: Encode, Payload: TryFrom>,