-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
docs: documented network config #35
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,19 +3,26 @@ use near_jsonrpc_client::JsonRpcClient; | |
use crate::errors::RetryError; | ||
|
||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] | ||
/// Using this struct to configure RPC endpoints. | ||
/// This is primary way to configure retry logic. | ||
/// Configuration for a [NEAR RPC](https://docs.near.org/api/rpc/providers) endpoint with retry and backoff settings. | ||
pub struct RPCEndpoint { | ||
/// The URL of the RPC endpoint | ||
pub url: url::Url, | ||
/// Optional API key for authenticated requests | ||
pub api_key: Option<crate::types::ApiKey>, | ||
/// Number of consecutive failures to move on to the next endpoint. | ||
pub retries: u8, | ||
/// Whether to use exponential backoff between retries | ||
/// | ||
/// The formula is `d = initial_sleep * factor^retry` | ||
pub exponential_backoff: bool, | ||
/// Multiplier for exponential backoff calculation | ||
pub factor: u8, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the backoff multiplier is somewhat simplejack instead of e.g. an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't love floats, to be honest |
||
/// Base delay duration between retries | ||
pub initial_sleep: std::time::Duration, | ||
} | ||
|
||
impl RPCEndpoint { | ||
/// Constructs a new RPC endpoint configuration with default settings. | ||
pub const fn new(url: url::Url) -> Self { | ||
Self { | ||
url, | ||
|
@@ -28,10 +35,12 @@ impl RPCEndpoint { | |
} | ||
} | ||
|
||
/// Constructs default mainnet configuration. | ||
pub fn mainnet() -> Self { | ||
Self::new("https://archival-rpc.mainnet.near.org".parse().unwrap()) | ||
} | ||
|
||
/// Constructs default testnet configuration. | ||
pub fn testnet() -> Self { | ||
Self::new("https://archival-rpc.testnet.near.org".parse().unwrap()) | ||
} | ||
|
@@ -71,20 +80,49 @@ impl RPCEndpoint { | |
} | ||
|
||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] | ||
/// Configuration for a NEAR network including RPC endpoints and network-specific settings. | ||
/// | ||
/// # Multiple RPC endpoints | ||
/// | ||
/// This struct is used to configure multiple RPC endpoints for a NEAR network. | ||
/// It allows for failover between endpoints in case of a failure. | ||
/// | ||
/// | ||
/// ## Example | ||
/// ```rust,no_run | ||
/// use near_api::*; | ||
/// | ||
/// # async fn example() -> Result<(), Box<dyn std::error::Error>> { | ||
/// let config = NetworkConfig { | ||
/// rpc_endpoints: vec![RPCEndpoint::mainnet(), RPCEndpoint::new("https://near.lava.build".parse()?)], | ||
/// ..NetworkConfig::mainnet() | ||
/// }; | ||
/// # Ok(()) | ||
/// # } | ||
/// ``` | ||
pub struct NetworkConfig { | ||
/// Human readable name of the network (e.g. "mainnet", "testnet") | ||
pub network_name: String, | ||
/// List of [RPC endpoints](https://docs.near.org/api/rpc/providers) to use with failover | ||
pub rpc_endpoints: Vec<RPCEndpoint>, | ||
// https://github.com/near/near-cli-rs/issues/116 | ||
/// Account ID used for [linkdrop functionality](https://docs.near.org/build/primitives/linkdrop) | ||
pub linkdrop_account_id: Option<near_primitives::types::AccountId>, | ||
// https://docs.near.org/social/contract | ||
/// Account ID of the [NEAR Social contract](https://docs.near.org/social/contract) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. link for NEAR Social contract appears to be broken |
||
pub near_social_db_contract_account_id: Option<near_primitives::types::AccountId>, | ||
/// URL of the network's faucet service | ||
pub faucet_url: Option<url::Url>, | ||
/// URL for the [meta transaction relayer](https://docs.near.org/concepts/abstraction/relayers) service | ||
pub meta_transaction_relayer_url: Option<url::Url>, | ||
/// URL for the [fastnear](https://docs.near.org/tools/ecosystem-apis/fastnear-api) service. | ||
/// | ||
/// Currently, unused. See [#30](https://github.com/near/near-api-rs/issues/30) | ||
pub fastnear_url: Option<url::Url>, | ||
/// Account ID of the [staking pools factory](https://github.com/near/core-contracts/tree/master/staking-pool-factory) | ||
pub staking_pools_factory_account_id: Option<near_primitives::types::AccountId>, | ||
} | ||
|
||
impl NetworkConfig { | ||
/// Constructs default mainnet configuration. | ||
pub fn mainnet() -> Self { | ||
Self { | ||
network_name: "mainnet".to_string(), | ||
|
@@ -94,18 +132,19 @@ impl NetworkConfig { | |
faucet_url: None, | ||
meta_transaction_relayer_url: None, | ||
fastnear_url: Some("https://api.fastnear.com/".parse().unwrap()), | ||
staking_pools_factory_account_id: Some("pool.near".parse().unwrap()), | ||
staking_pools_factory_account_id: Some("poolv1.near".parse().unwrap()), | ||
} | ||
} | ||
|
||
/// Constructs default testnet configuration. | ||
pub fn testnet() -> Self { | ||
Self { | ||
network_name: "testnet".to_string(), | ||
rpc_endpoints: vec![RPCEndpoint::testnet()], | ||
linkdrop_account_id: Some("testnet".parse().unwrap()), | ||
near_social_db_contract_account_id: Some("v1.social08.testnet".parse().unwrap()), | ||
faucet_url: Some("https://helper.nearprotocol.com/account".parse().unwrap()), | ||
meta_transaction_relayer_url: Some("http://localhost:3030/relay".parse().unwrap()), | ||
meta_transaction_relayer_url: None, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. somewhat unrelated, but bon can be used here instead of // $ cargo add bon
// bon = { version= "3.3.1", features = ["experimental-overwritable"]}
use bon::Builder;
use network_builder::{SetName, SetRpcStuff};
#[derive(Builder)]
struct Network {
name: String,
#[builder(overwritable)]
rpc_stuff: String,
}
impl Network {
pub fn testnet() -> NetworkBuilder<SetRpcStuff<SetName>> {
Self::builder()
.name("testnet".into())
.rpc_stuff("my_fast_near_rpc".to_string())
}
}
fn main() {
{
let network = Network::testnet().build();
assert_eq!(network.name, "testnet");
assert_eq!(network.rpc_stuff, "my_fast_near_rpc");
}
{
let network = Network::testnet()
.rpc_stuff("very_slow_another_rpc".to_owned())
.build();
assert_eq!(network.name, "testnet");
assert_eq!(network.rpc_stuff, "very_slow_another_rpc");
}
} referencing elastio/bon#149 , as it links to experimental feature needed. without There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. but this crate being a lib, it won't be too great to use a dependency with experimental feature, which can break on minor releases, though pinning it with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To be honest, I don't really want ro pull some extra dep for that Ideally is to remove as much deps as possible, and keep it as slim as possible There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you were to use // A `#[derive(bon::Builder)]` here isn't required, but it's not prohibited!
// If you want to have both `Network::builder()` for regular code and
// `Network::testnet()` for test code, then both can coexist just fine
struct Network {
name: String,
rpc_stuff: String,
}
// Define a builder using the method syntax.
// There can be as many builders with as many different defaults as you need
// for different use cases.
#[bon::bon]
impl Network {
#[builder]
pub fn testnet(
#[builder(default = "testnet".into())]
name: String,
#[builder(default = "my_fast_near_rpc".into())]
rpc_stuff: String,
) -> Self {
Self { name, rpc_stuff }
}
}
// Both of these work as expected
Network::testnet().build();
Network::testnet().rpc_stuff("very_slow_another_rpc".to_owned()).build();
// If you were to add `#[derive(bon::Builder)]`, you'd also have this one.
// Here you'd probably make both `name` and `rpc_stuff` required:
// Network::builder().name("foo".into()).rpc_stuff("bar".into()).build(); cc @dj8yfo There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @akorchyn well, this dependency has a useful function, it will be pulled in exactly for that and nothing more, it's really convenient to configure options with this stuff, i've tried. Besides Veetaha just showed how to do this with stable features of bon. Anyway, this was just a suggestion how stuff could be improved, not how it must be improved imo. |
||
fastnear_url: None, | ||
staking_pools_factory_account_id: Some("pool.f863973.m0".parse().unwrap()), | ||
} | ||
|
@@ -135,17 +174,21 @@ impl<T: near_workspaces::Network> From<near_workspaces::Worker<T>> for NetworkCo | |
linkdrop_account_id: None, | ||
near_social_db_contract_account_id: None, | ||
faucet_url: None, | ||
meta_transaction_relayer_url: None, | ||
fastnear_url: None, | ||
meta_transaction_relayer_url: None, | ||
staking_pools_factory_account_id: None, | ||
} | ||
} | ||
} | ||
|
||
#[derive(Debug)] | ||
/// Represents the possible outcomes of a retryable operation. | ||
pub enum RetryResponse<R, E> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this type doesn't really bubble up to be eventually visible in documentation, does it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For now, I just not really sure if it's needed to be public. But I kept documentation just in case I will decide to make it public There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. actually , you could try adding # checked to work on `bubbly_bub_test` crate
[package.metadata.docs.rs]
# Additional `RUSTDOCFLAGS` to set (default: [])
rustdoc-args = ["--document-private-items"] in order to still have it published to documentation , while not bothering with reexports or otherwise organizing module structure. |
||
/// Operation succeeded with result R | ||
Ok(R), | ||
/// Operation failed with error E, should be retried | ||
Retry(E), | ||
/// Operation failed with critical error E, should not be retried | ||
Critical(E), | ||
} | ||
|
||
|
@@ -158,6 +201,11 @@ impl<R, E> From<Result<R, E>> for RetryResponse<R, E> { | |
} | ||
} | ||
|
||
/// Retry a task with exponential backoff and failover. | ||
/// | ||
/// # Arguments | ||
/// * `network` - The network configuration to use for the retryable operation. | ||
/// * `task` - The task to retry. | ||
pub async fn retry<R, E, T, F>(network: NetworkConfig, mut task: F) -> Result<R, RetryError<E>> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here, it doesn't really show up in documentation |
||
where | ||
F: FnMut(JsonRpcClient) -> T + Send, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's left unspecified what backoff behaviour will look like if
exponential_backoff
is false.it can be defined more accurately with a doc comment or
by using an enum like the following instead of
exponential_backoff: bool
: