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(()) } }