linera_rpc/grpc/
node_provider.rs

1// Copyright (c) Zefchain Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use std::str::FromStr as _;
5
6use linera_base::time::Duration;
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)]
17pub struct GrpcNodeProvider {
18    pool: GrpcConnectionPool,
19    retry_delay: Duration,
20    max_retries: u32,
21    max_backoff: Duration,
22}
23
24impl GrpcNodeProvider {
25    pub fn new(options: NodeOptions) -> Self {
26        let transport_options = transport::Options::from(&options);
27        let retry_delay = options.retry_delay;
28        let max_retries = options.max_retries;
29        let max_backoff = options.max_backoff;
30        let pool = GrpcConnectionPool::new(transport_options);
31        Self {
32            pool,
33            retry_delay,
34            max_retries,
35            max_backoff,
36        }
37    }
38}
39
40impl ValidatorNodeProvider for GrpcNodeProvider {
41    type Node = GrpcClient;
42
43    fn make_node(&self, address: &str) -> Result<Self::Node, NodeError> {
44        let network = ValidatorPublicNetworkConfig::from_str(address).map_err(|_| {
45            NodeError::CannotResolveValidatorAddress {
46                address: address.to_string(),
47            }
48        })?;
49        let http_address = network.http_address();
50        let channel =
51            self.pool
52                .channel(http_address.clone())
53                .map_err(|error| NodeError::GrpcError {
54                    error: format!("error creating channel: {}", error),
55                })?;
56
57        Ok(GrpcClient::new(
58            http_address,
59            channel,
60            self.retry_delay,
61            self.max_retries,
62            self.max_backoff,
63        ))
64    }
65}