linera_rpc/grpc/
node_provider.rs1use std::{str::FromStr as _, sync::Arc};
5
6use linera_base::time::{Duration, Instant};
7use linera_core::node::{NodeError, ValidatorNodeProvider};
8
9use super::GrpcClient;
10use crate::{
11 config::ValidatorPublicNetworkConfig,
12 grpc::{pool::GrpcConnectionPool, transport},
13 node_provider::NodeOptions,
14};
15
16#[derive(Clone)]
18pub struct GrpcNodeProvider {
19 pool: GrpcConnectionPool,
20 retry_delay: Duration,
21 max_retries: u32,
22 max_backoff: Duration,
23 subscription_cooldowns: Arc<papaya::HashMap<String, Instant>>,
27}
28
29impl GrpcNodeProvider {
30 pub fn new(options: NodeOptions) -> Self {
32 let transport_options = transport::Options::from(&options);
33 let retry_delay = options.retry_delay;
34 let max_retries = options.max_retries;
35 let max_backoff = options.max_backoff;
36 let pool = GrpcConnectionPool::new(transport_options);
37 Self {
38 pool,
39 retry_delay,
40 max_retries,
41 max_backoff,
42 subscription_cooldowns: Arc::new(papaya::HashMap::new()),
43 }
44 }
45}
46
47impl ValidatorNodeProvider for GrpcNodeProvider {
48 type Node = GrpcClient;
49
50 fn make_node(&self, address: &str) -> Result<Self::Node, NodeError> {
51 let network = ValidatorPublicNetworkConfig::from_str(address).map_err(|_| {
52 NodeError::CannotResolveValidatorAddress {
53 address: address.to_string(),
54 }
55 })?;
56 let http_address = network.http_address();
57 let channel =
58 self.pool
59 .channel(http_address.clone())
60 .map_err(|error| NodeError::GrpcError {
61 error: format!("error creating channel: {error}"),
62 })?;
63
64 Ok(GrpcClient::new(
65 http_address,
66 channel,
67 self.retry_delay,
68 self.max_retries,
69 self.max_backoff,
70 self.subscription_cooldowns.clone(),
71 ))
72 }
73}