penumbra_shielded_pool/component/
rpc.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use std::pin::Pin;

use cnidarium::Storage;
use penumbra_asset::asset::{self};
use penumbra_proto::core::component::shielded_pool::v1::{
    query_service_server::QueryService, AssetMetadataByIdRequest, AssetMetadataByIdResponse,
    AssetMetadataByIdsRequest, AssetMetadataByIdsResponse,
};

use tonic::Status;
use tracing::instrument;

use super::AssetRegistryRead;

mod bank_query;
mod transfer_query;

// TODO: Hide this and only expose a Router?
pub struct Server {
    storage: Storage,
}

impl Server {
    pub fn new(storage: Storage) -> Self {
        Self { storage }
    }
}

#[tonic::async_trait]
impl QueryService for Server {
    type AssetMetadataByIdsStream = Pin<
        Box<dyn futures::Stream<Item = Result<AssetMetadataByIdsResponse, tonic::Status>> + Send>,
    >;

    #[instrument(skip(self, request))]
    async fn asset_metadata_by_id(
        &self,
        request: tonic::Request<AssetMetadataByIdRequest>,
    ) -> Result<tonic::Response<AssetMetadataByIdResponse>, Status> {
        let state = self.storage.latest_snapshot();

        let request = request.into_inner();
        let id: asset::Id = request
            .asset_id
            .ok_or_else(|| Status::invalid_argument("missing asset_id"))?
            .try_into()
            .map_err(|e| Status::invalid_argument(format!("could not parse asset_id: {e}")))?;

        let denom_metadata = state.denom_metadata_by_asset(&id).await;

        let rsp = match denom_metadata {
            Some(denom_metadata) => {
                tracing::debug!(?id, ?denom_metadata, "found denom metadata");
                AssetMetadataByIdResponse {
                    denom_metadata: Some(denom_metadata.into()),
                }
            }
            None => {
                tracing::debug!(?id, "unknown asset id");
                Default::default()
            }
        };

        Ok(tonic::Response::new(rsp))
    }

    async fn asset_metadata_by_ids(
        &self,
        _request: tonic::Request<AssetMetadataByIdsRequest>,
    ) -> Result<tonic::Response<Self::AssetMetadataByIdsStream>, tonic::Status> {
        unimplemented!("asset_metadata_by_ids not yet implemented")
    }
}