iota_light_client/
package_store.rs1use std::{collections::HashMap, sync::Arc};
6
7use anyhow::Result;
8use async_trait::async_trait;
9use iota_package_resolver::{Package, PackageStore, error::Error as PackageResolverError};
10use move_core_types::account_address::AccountAddress;
11use tokio::sync::Mutex;
12use tracing::{error, info};
13
14use crate::{config::Config, verifier::get_verified_object};
15
16pub struct RemotePackageStore {
17 config: Config,
18 cache: Mutex<HashMap<AccountAddress, Arc<Package>>>,
19}
20
21impl RemotePackageStore {
22 pub fn new(config: Config) -> Self {
23 Self {
24 config,
25 cache: Mutex::new(HashMap::new()),
26 }
27 }
28}
29
30#[async_trait]
31impl PackageStore for RemotePackageStore {
32 async fn fetch(&self, id: AccountAddress) -> iota_package_resolver::Result<Arc<Package>> {
35 let res: Result<Arc<Package>> = async move {
37 if let Some(package) = self.cache.lock().await.get(&id) {
38 info!("Fetch Package: {id} cache hit");
39 return Ok(package.clone());
40 }
41
42 info!("Fetch Package: {id}");
43
44 let object = get_verified_object(&self.config, id.into()).await?;
45 let package = Arc::new(Package::read_from_object(&object)?);
46
47 self.cache.lock().await.insert(id, package.clone());
49
50 Ok(package)
51 }
52 .await;
53 res.map_err(|e| {
54 error!("Fetch Package: {id} error: {e:?}");
55 PackageResolverError::PackageNotFound(id)
56 })
57 }
58}