Skip to main content

linera_rpc/
node_provider.rs

1// Copyright (c) Zefchain Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use linera_base::time::Duration;
5use linera_core::node::{NodeError, ValidatorNodeProvider};
6
7#[cfg(with_simple_network)]
8use crate::simple::SimpleNodeProvider;
9use crate::{client::Client, grpc::GrpcNodeProvider};
10
11/// A general node provider which delegates node provision to the underlying
12/// node provider according to the `ValidatorPublicNetworkConfig`.
13#[derive(Clone)]
14pub struct NodeProvider {
15    grpc: GrpcNodeProvider,
16    #[cfg(with_simple_network)]
17    simple: SimpleNodeProvider,
18}
19
20impl NodeProvider {
21    /// Creates a new [`NodeProvider`] with the given node options.
22    pub fn new(options: NodeOptions) -> Self {
23        Self {
24            grpc: GrpcNodeProvider::new(options),
25            #[cfg(with_simple_network)]
26            simple: SimpleNodeProvider::new(options),
27        }
28    }
29}
30
31impl ValidatorNodeProvider for NodeProvider {
32    type Node = Client;
33
34    fn make_node(&self, address: &str) -> anyhow::Result<Self::Node, NodeError> {
35        let address = address.to_lowercase();
36
37        #[cfg(with_simple_network)]
38        if address.starts_with("tcp") || address.starts_with("udp") {
39            return Ok(Client::Simple(self.simple.make_node(&address)?));
40        }
41
42        if address.starts_with("grpc") {
43            return Ok(Client::Grpc(Box::new(self.grpc.make_node(&address)?)));
44        }
45
46        Err(NodeError::CannotResolveValidatorAddress { address })
47    }
48}
49
50/// Default maximum backoff delay (30 seconds), following Google Cloud's recommendation.
51/// References:
52/// - <https://cloud.google.com/storage/docs/retry-strategy>
53/// - <https://docs.aws.amazon.com/sdkref/latest/guide/feature-retry-behavior.html>
54/// - <https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md>
55pub const DEFAULT_MAX_BACKOFF: Duration = Duration::from_secs(30);
56
57/// Options for configuring the clients created by a node provider.
58#[derive(Copy, Clone)]
59pub struct NodeOptions {
60    /// The maximum time to wait when sending a request.
61    pub send_timeout: Duration,
62    /// The maximum time to wait when receiving a response.
63    pub recv_timeout: Duration,
64    /// The delay between retries.
65    pub retry_delay: Duration,
66    /// The maximum number of retries for a request.
67    pub max_retries: u32,
68    /// The maximum backoff delay between retries.
69    pub max_backoff: Duration,
70}
71
72impl Default for NodeOptions {
73    fn default() -> Self {
74        Self {
75            send_timeout: Duration::ZERO,
76            recv_timeout: Duration::ZERO,
77            retry_delay: Duration::ZERO,
78            max_retries: 0,
79            max_backoff: DEFAULT_MAX_BACKOFF,
80        }
81    }
82}