penumbra_app/
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
mod query;

// TODO: Once we migrate to Tonic 0.10.0, we'll be able to use the `Routes` structure to have each
// component define a method that returns a `Routes` with all of its query services bundled inside.
//
// This means we won't have to import all this shit and recite every single service -- we can e.g.,
// have the app crate assemble all of its components' query services into a single `Routes` and
// then just add that to the gRPC server.
use {
    self::query::AppQueryServer,
    crate::PenumbraHost,
    anyhow::Context,
    cnidarium::rpc::{
        proto::v1::query_service_server::QueryServiceServer as StorageQueryServiceServer,
        Server as StorageServer,
    },
    ibc_proto::cosmos::bank::v1beta1::query_server::QueryServer as TransferQueryServer,
    ibc_proto::ibc::applications::transfer::v1::query_server::QueryServer as BankQueryServer,
    ibc_proto::ibc::core::{
        channel::v1::query_server::QueryServer as ChannelQueryServer,
        client::v1::query_server::QueryServer as ClientQueryServer,
        connection::v1::query_server::QueryServer as ConnectionQueryServer,
    },
    penumbra_auction::component::rpc::Server as AuctionServer,
    penumbra_compact_block::component::rpc::Server as CompactBlockServer,
    penumbra_dex::component::rpc::Server as DexServer,
    penumbra_fee::component::rpc::Server as FeeServer,
    penumbra_governance::component::rpc::Server as GovernanceServer,
    penumbra_proto::{
        core::{
            app::v1::query_service_server::QueryServiceServer as AppQueryServiceServer,
            component::{
                auction::v1::query_service_server::QueryServiceServer as AuctionQueryServiceServer,
                compact_block::v1::query_service_server::QueryServiceServer as CompactBlockQueryServiceServer,
                dex::v1::{
                    query_service_server::QueryServiceServer as DexQueryServiceServer,
                    simulation_service_server::SimulationServiceServer,
                },
                fee::v1::query_service_server::QueryServiceServer as FeeQueryServiceServer,
                governance::v1::query_service_server::QueryServiceServer as GovernanceQueryServiceServer,
                sct::v1::query_service_server::QueryServiceServer as SctQueryServiceServer,
                shielded_pool::v1::query_service_server::QueryServiceServer as ShieldedPoolQueryServiceServer,
                stake::v1::query_service_server::QueryServiceServer as StakeQueryServiceServer,
            },
        },
        util::tendermint_proxy::v1::tendermint_proxy_service_server::{
            TendermintProxyService, TendermintProxyServiceServer,
        },
    },
    penumbra_sct::component::rpc::Server as SctServer,
    penumbra_shielded_pool::component::rpc::Server as ShieldedPoolServer,
    penumbra_stake::component::rpc::Server as StakeServer,
    penumbra_tower_trace::remote_addr,
    tonic_web::enable as we,
};

pub fn router(
    storage: &cnidarium::Storage,
    tm_proxy: impl TendermintProxyService,
    _enable_expensive_rpc: bool,
) -> anyhow::Result<tonic::transport::server::Router> {
    let ibc = penumbra_ibc::component::rpc::IbcQuery::<PenumbraHost>::new(storage.clone());
    let grpc_server = tonic::transport::server::Server::builder()
        .trace_fn(|req| match remote_addr(req) {
            Some(remote_addr) => {
                tracing::error_span!("grpc", ?remote_addr)
            }
            None => tracing::error_span!("grpc"),
        })
        // Allow HTTP/1, which will be used by grpc-web connections.
        // This is particularly important when running locally, as gRPC
        // typically uses HTTP/2, which requires HTTPS. Accepting HTTP/2
        // allows local applications such as web browsers to talk to pd.
        .accept_http1(true)
        // As part of #2932, we are disabling all timeouts until we circle back to our
        // performance story.
        // Sets a timeout for all gRPC requests, but note that in the case of streaming
        // requests, the timeout is only applied to the initial request. This means that
        // this does not prevent long lived streams, for example to allow clients to obtain
        // new blocks.
        // .timeout(std::time::Duration::from_secs(7))
        // Wrap each of the gRPC services in a tonic-web proxy:
        .add_service(we(StorageQueryServiceServer::new(StorageServer::new(
            storage.clone(),
        ))))
        .add_service(we(AuctionQueryServiceServer::new(AuctionServer::new(
            storage.clone(),
        ))))
        .add_service(we(AppQueryServiceServer::new(AppQueryServer::new(
            storage.clone(),
        ))))
        .add_service(we(CompactBlockQueryServiceServer::new(
            CompactBlockServer::new(storage.clone()),
        )))
        .add_service(we(DexQueryServiceServer::new(DexServer::new(
            storage.clone(),
        ))))
        .add_service(we(FeeQueryServiceServer::new(FeeServer::new(
            storage.clone(),
        ))))
        .add_service(we(GovernanceQueryServiceServer::new(
            GovernanceServer::new(storage.clone()),
        )))
        .add_service(we(SctQueryServiceServer::new(SctServer::new(
            storage.clone(),
        ))))
        .add_service(we(ShieldedPoolQueryServiceServer::new(
            ShieldedPoolServer::new(storage.clone()),
        )))
        .add_service(we(TransferQueryServer::new(ShieldedPoolServer::new(
            storage.clone(),
        ))))
        .add_service(we(BankQueryServer::new(ShieldedPoolServer::new(
            storage.clone(),
        ))))
        .add_service(we(StakeQueryServiceServer::new(StakeServer::new(
            storage.clone(),
        ))))
        .add_service(we(ClientQueryServer::new(ibc.clone())))
        .add_service(we(ChannelQueryServer::new(ibc.clone())))
        .add_service(we(ConnectionQueryServer::new(ibc.clone())))
        .add_service(we(TendermintProxyServiceServer::new(tm_proxy)))
        .add_service(we(SimulationServiceServer::new(DexServer::new(
            storage.clone(),
        ))))
        .add_service(we(tonic_reflection::server::Builder::configure()
            .register_encoded_file_descriptor_set(penumbra_proto::FILE_DESCRIPTOR_SET)
            .build()
            .with_context(|| "could not configure grpc reflection service")?));

    Ok(grpc_server)
}