linera_core/environment/wallet/
memory.rs1use futures::{Stream, StreamExt as _};
5use linera_base::identifiers::ChainId;
6
7use super::{Chain, Wallet};
8
9#[derive(Default, Clone, serde::Serialize, serde::Deserialize)]
15pub struct Memory(papaya::HashMap<ChainId, Chain>);
16
17impl Memory {
18 pub fn get(&self, id: ChainId) -> Option<Chain> {
19 self.0.pin().get(&id).cloned()
20 }
21
22 pub fn insert(&self, id: ChainId, chain: Chain) -> Option<Chain> {
23 self.0.pin().insert(id, chain).cloned()
24 }
25
26 pub fn try_insert(&self, id: ChainId, chain: Chain) -> Option<Chain> {
27 match self.0.pin().try_insert(id, chain) {
28 Ok(_inserted) => None,
29 Err(error) => Some(error.not_inserted),
30 }
31 }
32
33 pub fn remove(&self, id: ChainId) -> Option<Chain> {
34 self.0.pin().remove(&id).cloned()
35 }
36
37 pub fn items(&self) -> Vec<(ChainId, Chain)> {
38 self.0
39 .pin()
40 .iter()
41 .map(|(id, chain)| (*id, chain.clone()))
42 .collect::<Vec<_>>()
43 }
44
45 pub fn chain_ids(&self) -> Vec<ChainId> {
46 self.0.pin().keys().copied().collect::<Vec<_>>()
47 }
48
49 pub fn owned_chain_ids(&self) -> Vec<ChainId> {
50 self.0
51 .pin()
52 .iter()
53 .filter_map(|(id, chain)| chain.owner.as_ref().map(|_| *id))
54 .collect::<Vec<_>>()
55 }
56
57 pub fn mutate<R>(
58 &self,
59 chain_id: ChainId,
60 mut mutate: impl FnMut(&mut Chain) -> R,
61 ) -> Option<R> {
62 use papaya::Operation::*;
63
64 let mut outcome = None;
65 self.0.pin().compute(chain_id, |chain| {
66 if let Some((_, chain)) = chain {
67 let mut chain = chain.clone();
68 outcome = Some(mutate(&mut chain));
69 Insert(chain)
70 } else {
71 Abort(())
72 }
73 });
74
75 outcome
76 }
77}
78
79impl Extend<(ChainId, Chain)> for Memory {
80 fn extend<It: IntoIterator<Item = (ChainId, Chain)>>(&mut self, chains: It) {
81 let map = self.0.pin();
82 for (id, chain) in chains {
83 let _ = map.insert(id, chain);
84 }
85 }
86}
87
88impl Wallet for Memory {
89 type Error = std::convert::Infallible;
90
91 async fn get(&self, id: ChainId) -> Result<Option<Chain>, Self::Error> {
92 Ok(self.get(id))
93 }
94
95 async fn insert(&self, id: ChainId, chain: Chain) -> Result<Option<Chain>, Self::Error> {
96 Ok(self.insert(id, chain))
97 }
98
99 async fn try_insert(&self, id: ChainId, chain: Chain) -> Result<Option<Chain>, Self::Error> {
100 Ok(self.try_insert(id, chain))
101 }
102
103 async fn remove(&self, id: ChainId) -> Result<Option<Chain>, Self::Error> {
104 Ok(self.remove(id))
105 }
106
107 fn items(&self) -> impl Stream<Item = Result<(ChainId, Chain), Self::Error>> {
108 futures::stream::iter(self.items()).map(Ok)
109 }
110
111 async fn modify(
112 &self,
113 id: ChainId,
114 f: impl FnMut(&mut Chain) + Send,
115 ) -> Result<Option<()>, Self::Error> {
116 Ok(self.mutate(id, f))
117 }
118}