sui_light_client/
package_store.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use anyhow::Result;
5use async_trait::async_trait;
6use move_core_types::account_address::AccountAddress;
7use std::collections::HashMap;
8use std::sync::Arc;
9use sui_package_resolver::{Package, PackageStore, error::Error as PackageResolverError};
10use tokio::sync::Mutex;
11use tracing::{error, info};
12
13use crate::config::Config;
14use crate::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) -> sui_package_resolver::Result<Arc<Package>> {
33        // Check if we have it in the cache
34        let res: Result<Arc<Package>> = async move {
35            if let Some(package) = self.cache.lock().await.get(&id) {
36                info!("Fetch Package: {} cache hit", id);
37                return Ok(package.clone());
38            }
39
40            info!("Fetch Package: {}", id);
41
42            let object = get_verified_object(&self.config, id.into()).await?;
43            let package = Arc::new(Package::read_from_object(&object)?);
44
45            // Add to the cache
46            self.cache.lock().await.insert(id, package.clone());
47
48            Ok(package)
49        }
50        .await;
51        res.map_err(|e| {
52            error!("Fetch Package: {} error: {:?}", id, e);
53            PackageResolverError::PackageNotFound(id)
54        })
55    }
56}