pub struct HedgedRpcClient { /* private fields */ }Expand description
A Solana RPC client that hedges requests across multiple providers.
The client races requests to multiple RPC endpoints and returns the first successful response, implementing the “hedged requests” pattern to reduce tail latency.
Implementations§
Source§impl HedgedRpcClient
impl HedgedRpcClient
Sourcepub fn new(provider_cfgs: Vec<ProviderConfig>, cfg: HedgeConfig) -> Self
pub fn new(provider_cfgs: Vec<ProviderConfig>, cfg: HedgeConfig) -> Self
Creates a new hedged RPC client with the specified providers and configuration.
§Arguments
provider_cfgs- List of RPC provider configurations (URLs and IDs)cfg- Hedging strategy configuration
§Example
use hedged_rpc_client::{HedgedRpcClient, HedgeConfig, ProviderConfig, ProviderId};
use std::time::Duration;
let providers = vec![
ProviderConfig {
id: ProviderId("helius"),
url: "https://mainnet.helius-rpc.com".to_string(),
},
];
let config = HedgeConfig {
initial_providers: 1,
hedge_after: Duration::from_millis(50),
max_providers: 3,
min_slot: None,
overall_timeout: Duration::from_secs(2),
};
let client = HedgedRpcClient::new(providers, config);Examples found in repository?
23async fn main() -> Result<(), Box<dyn std::error::Error>> {
24 let mut providers = Vec::new();
25
26 if let Some(p) = provider_from_env("HELIUS_RPC_URL", "helius") {
27 providers.push(p);
28 }
29 if let Some(p) = provider_from_env("TRITON_RPC_URL", "triton") {
30 providers.push(p);
31 }
32 if let Some(p) = provider_from_env("QUICKNODE_RPC_URL", "quicknode") {
33 providers.push(p);
34 }
35
36 if providers.is_empty() {
37 eprintln!("No providers configured.");
38 eprintln!("Set at least one of: HELIUS_RPC_URL, TRITON_RPC_URL, QUICKNODE_RPC_URL");
39 return Ok(());
40 }
41
42 eprintln!(
43 "Using providers:\n{}",
44 providers
45 .iter()
46 .map(|p| format!("- {}: {}", (p.id).0, p.url))
47 .collect::<Vec<_>>()
48 .join("\n")
49 );
50
51 let cfg = HedgeConfig {
52 initial_providers: 1,
53 hedge_after: Duration::from_millis(80),
54 max_providers: providers.len(),
55 min_slot: None,
56 overall_timeout: Duration::from_secs(2),
57 };
58
59 let client = HedgedRpcClient::new(providers, cfg);
60
61 let addr: Pubkey = "So11111111111111111111111111111111111111112".parse()?;
62 let commitment = CommitmentConfig::processed();
63
64 let t0 = Instant::now();
65 let (bh_provider, blockhash) = client.get_latest_blockhash().await?;
66 let dt_bh = t0.elapsed();
67
68 println!(
69 "[blockhash] provider={} latency={:?} hash={}",
70 bh_provider.0, dt_bh, blockhash,
71 );
72
73 let t1 = Instant::now();
74 let (acc_provider, resp) = client.get_account(&addr, commitment).await?;
75 let dt_acc = t1.elapsed();
76
77 println!(
78 "[account] provider={} latency={:?} slot={}",
79 acc_provider.0, dt_acc, resp.context.slot,
80 );
81
82 match resp.value {
83 Some(account) => {
84 println!("lamports={}", account.lamports);
85 println!("data_len={}", account.data.len());
86 println!("owner={}", account.owner);
87 }
88 None => println!("account not found"),
89 }
90
91 Ok(())
92}More examples
55async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
56 let mut providers = Vec::new();
57
58 if let Some(p) = provider_from_env("HELIUS_RPC_URL", "helius") {
59 providers.push(p);
60 }
61 if let Some(p) = provider_from_env("TRITON_RPC_URL", "triton") {
62 providers.push(p);
63 }
64 if let Some(p) = provider_from_env("QUICKNODE_RPC_URL", "quicknode") {
65 providers.push(p);
66 }
67
68 if providers.is_empty() {
69 eprintln!("No providers configured.");
70 eprintln!("Set at least one of: HELIUS_RPC_URL, TRITON_RPC_URL, QUICKNODE_RPC_URL");
71 return Ok(());
72 }
73
74 let cfg = HedgeConfig {
75 initial_providers: 2,
76 hedge_after: Duration::from_millis(20),
77 max_providers: providers.len(),
78 min_slot: None,
79 overall_timeout: Duration::from_secs(2),
80 };
81
82 let client_a = HedgedRpcClient::new(providers.clone(), cfg.clone());
83 let client_b = HedgedRpcClient::new(providers, cfg);
84
85 let addr: Pubkey = "So11111111111111111111111111111111111111112".parse()?;
86 let commitment = CommitmentConfig::processed();
87 let num_calls_per_runner: usize = 10_000;
88 let max_in_flight_per_runner: usize = 256;
89
90 let runner_a = tokio::spawn(run_runner(
91 "A",
92 client_a,
93 addr,
94 commitment,
95 num_calls_per_runner,
96 max_in_flight_per_runner,
97 ));
98
99 let runner_b = tokio::spawn(run_runner(
100 "B",
101 client_b,
102 addr,
103 commitment,
104 num_calls_per_runner,
105 max_in_flight_per_runner,
106 ));
107
108 let stats_a = runner_a.await??;
109 let stats_b = runner_b.await??;
110
111 println!("\n=== comparison ===");
112 println!(
113 "Runner {}: total={}, successes={}, errors={}, avg_latency={:.3} ms",
114 stats_a.label,
115 stats_a.total_calls,
116 stats_a.successes,
117 stats_a.errors,
118 stats_a.avg_latency_ms
119 );
120 for (provider, wins) in &stats_a.per_provider_wins {
121 println!(
122 " [{}] wins from provider {} = {}",
123 stats_a.label, provider, wins
124 );
125 }
126
127 println!(
128 "Runner {}: total={}, successes={}, errors={}, avg_latency={:.3} ms",
129 stats_b.label,
130 stats_b.total_calls,
131 stats_b.successes,
132 stats_b.errors,
133 stats_b.avg_latency_ms
134 );
135 for (provider, wins) in &stats_b.per_provider_wins {
136 println!(
137 " [{}] wins from provider {} = {}",
138 stats_b.label, provider, wins
139 );
140 }
141
142 if stats_a.avg_latency_ms < stats_b.avg_latency_ms {
143 println!(
144 "\n=> Runner {} was faster on average by {:.3} ms",
145 stats_a.label,
146 stats_b.avg_latency_ms - stats_a.avg_latency_ms
147 );
148 } else if stats_b.avg_latency_ms < stats_a.avg_latency_ms {
149 println!(
150 "\n=> Runner {} was faster on average by {:.3} ms",
151 stats_b.label,
152 stats_a.avg_latency_ms - stats_b.avg_latency_ms
153 );
154 } else {
155 println!("\n=> Both runners had the same average latency.");
156 }
157
158 Ok(())
159}48async fn main() -> Result<(), Box<dyn std::error::Error>> {
49 let mut providers = Vec::new();
50
51 if let Some(p) = provider_from_env("HELIUS_RPC_URL", "helius") {
52 providers.push(p);
53 }
54 if let Some(p) = provider_from_env("TRITON_RPC_URL", "triton") {
55 providers.push(p);
56 }
57 if let Some(p) = provider_from_env("QUICKNODE_RPC_URL", "quicknode") {
58 providers.push(p);
59 }
60
61 if providers.is_empty() {
62 eprintln!("No providers configured.");
63 eprintln!("Set at least one of: HELIUS_RPC_URL, TRITON_RPC_URL, QUICKNODE_RPC_URL");
64 return Ok(());
65 }
66
67 let cfg = HedgeConfig {
68 initial_providers: providers.len(),
69 hedge_after: Duration::from_millis(20),
70 max_providers: providers.len(),
71 min_slot: None,
72 overall_timeout: Duration::from_secs(1),
73 };
74
75 let client = HedgedRpcClient::new(providers, cfg);
76
77 let addr: Pubkey = "So11111111111111111111111111111111111111112".parse()?;
78 let commitment = CommitmentConfig::processed();
79
80 let (tx, mut rx) = mpsc::channel::<CallResult>(MAX_IN_FLIGHT * 2);
81 let semaphore = Arc::new(Semaphore::new(MAX_IN_FLIGHT));
82 let consumer = tokio::spawn(async move {
83 let mut results: Vec<CallResult> = Vec::with_capacity(NUM_CALLS);
84
85 while let Some(res) = rx.recv().await {
86 match &res.outcome {
87 CallOutcome::Ok { provider, latency } => {
88 println!(
89 "[call {:05}] OK provider={} latency={:?}",
90 res.call_idx, provider.0, latency
91 );
92 }
93 CallOutcome::Err { error, latency } => {
94 println!(
95 "[call {:05}] ERR latency={:?} error={}",
96 res.call_idx, latency, error
97 );
98 }
99 }
100
101 results.push(res);
102 }
103
104 results
105 });
106
107 for i in 0..NUM_CALLS {
108 let client_clone = client.clone();
109 let tx_clone = tx.clone();
110 let addr_copy = addr;
111 let commitment_clone = commitment;
112 let sem = semaphore.clone();
113
114 tokio::spawn(async move {
115 let _permit = sem.acquire_owned().await.expect("semaphore closed");
116
117 let start = Instant::now();
118 let res = client_clone.get_account(&addr_copy, commitment_clone).await;
119 let elapsed = start.elapsed();
120
121 let outcome = match res {
122 Ok((provider, _resp)) => CallOutcome::Ok {
123 provider,
124 latency: elapsed,
125 },
126 Err(e) => CallOutcome::Err {
127 error: e.to_string(),
128 latency: elapsed,
129 },
130 };
131
132 let _ = tx_clone
133 .send(CallResult {
134 call_idx: i,
135 outcome,
136 })
137 .await;
138 });
139 }
140
141 drop(tx);
142 let mut results = consumer.await?;
143
144 results.sort_by_key(|r| r.call_idx);
145
146 let mut wins: HashMap<&'static str, usize> = HashMap::new();
147 let mut total_latency: HashMap<&'static str, Duration> = HashMap::new();
148 let mut error_count = 0usize;
149
150 for r in &results {
151 match &r.outcome {
152 CallOutcome::Ok { provider, latency } => {
153 let name = provider.0;
154 *wins.entry(name).or_insert(0) += 1;
155 *total_latency.entry(name).or_insert(Duration::ZERO) += *latency;
156 }
157 CallOutcome::Err { .. } => {
158 error_count += 1;
159 }
160 }
161 }
162
163 println!("\n=== summary ===");
164 println!("total calls : {}", NUM_CALLS);
165 println!("successes : {}", NUM_CALLS - error_count);
166 println!("errors (any kind) : {}", error_count);
167
168 for (provider, count) in wins.iter() {
169 let total = total_latency[provider];
170 let avg_ms = total.as_secs_f64() * 1000.0 / (*count as f64);
171 println!(
172 "provider {:>10}: wins = {:6}, avg_latency = {:8.3} ms",
173 provider, count, avg_ms,
174 );
175 }
176
177 Ok(())
178}Sourcepub fn providers(&self) -> &[(ProviderId, Arc<RpcClient>)]
pub fn providers(&self) -> &[(ProviderId, Arc<RpcClient>)]
Returns a reference to the configured providers.
Sourcepub fn provider_stats(&self) -> HashMap<ProviderId, ProviderStatsSnapshot>
pub fn provider_stats(&self) -> HashMap<ProviderId, ProviderStatsSnapshot>
Returns a snapshot of accumulated performance statistics for each provider.
Statistics include wins (successful responses), average latency, and error counts.
Sourcepub async fn get_latest_blockhash(
&self,
) -> Result<(ProviderId, Hash), HedgedError>
pub async fn get_latest_blockhash( &self, ) -> Result<(ProviderId, Hash), HedgedError>
Gets the latest blockhash from the fastest responding provider.
Returns the blockhash along with the ID of the provider that responded first.
Examples found in repository?
23async fn main() -> Result<(), Box<dyn std::error::Error>> {
24 let mut providers = Vec::new();
25
26 if let Some(p) = provider_from_env("HELIUS_RPC_URL", "helius") {
27 providers.push(p);
28 }
29 if let Some(p) = provider_from_env("TRITON_RPC_URL", "triton") {
30 providers.push(p);
31 }
32 if let Some(p) = provider_from_env("QUICKNODE_RPC_URL", "quicknode") {
33 providers.push(p);
34 }
35
36 if providers.is_empty() {
37 eprintln!("No providers configured.");
38 eprintln!("Set at least one of: HELIUS_RPC_URL, TRITON_RPC_URL, QUICKNODE_RPC_URL");
39 return Ok(());
40 }
41
42 eprintln!(
43 "Using providers:\n{}",
44 providers
45 .iter()
46 .map(|p| format!("- {}: {}", (p.id).0, p.url))
47 .collect::<Vec<_>>()
48 .join("\n")
49 );
50
51 let cfg = HedgeConfig {
52 initial_providers: 1,
53 hedge_after: Duration::from_millis(80),
54 max_providers: providers.len(),
55 min_slot: None,
56 overall_timeout: Duration::from_secs(2),
57 };
58
59 let client = HedgedRpcClient::new(providers, cfg);
60
61 let addr: Pubkey = "So11111111111111111111111111111111111111112".parse()?;
62 let commitment = CommitmentConfig::processed();
63
64 let t0 = Instant::now();
65 let (bh_provider, blockhash) = client.get_latest_blockhash().await?;
66 let dt_bh = t0.elapsed();
67
68 println!(
69 "[blockhash] provider={} latency={:?} hash={}",
70 bh_provider.0, dt_bh, blockhash,
71 );
72
73 let t1 = Instant::now();
74 let (acc_provider, resp) = client.get_account(&addr, commitment).await?;
75 let dt_acc = t1.elapsed();
76
77 println!(
78 "[account] provider={} latency={:?} slot={}",
79 acc_provider.0, dt_acc, resp.context.slot,
80 );
81
82 match resp.value {
83 Some(account) => {
84 println!("lamports={}", account.lamports);
85 println!("data_len={}", account.data.len());
86 println!("owner={}", account.owner);
87 }
88 None => println!("account not found"),
89 }
90
91 Ok(())
92}Sourcepub async fn get_latest_blockhash_any(&self) -> Result<Hash, HedgedError>
pub async fn get_latest_blockhash_any(&self) -> Result<Hash, HedgedError>
Gets the latest blockhash, returning only the hash without provider information.
Sourcepub async fn get_account(
&self,
pubkey: &Pubkey,
commitment: CommitmentConfig,
) -> Result<(ProviderId, RpcResponse<Option<Account>>), HedgedError>
pub async fn get_account( &self, pubkey: &Pubkey, commitment: CommitmentConfig, ) -> Result<(ProviderId, RpcResponse<Option<Account>>), HedgedError>
Gets account data from the fastest responding provider.
Returns the account response along with the ID of the provider that responded first.
§Arguments
pubkey- The account’s public keycommitment- The commitment level for the query
Examples found in repository?
23async fn main() -> Result<(), Box<dyn std::error::Error>> {
24 let mut providers = Vec::new();
25
26 if let Some(p) = provider_from_env("HELIUS_RPC_URL", "helius") {
27 providers.push(p);
28 }
29 if let Some(p) = provider_from_env("TRITON_RPC_URL", "triton") {
30 providers.push(p);
31 }
32 if let Some(p) = provider_from_env("QUICKNODE_RPC_URL", "quicknode") {
33 providers.push(p);
34 }
35
36 if providers.is_empty() {
37 eprintln!("No providers configured.");
38 eprintln!("Set at least one of: HELIUS_RPC_URL, TRITON_RPC_URL, QUICKNODE_RPC_URL");
39 return Ok(());
40 }
41
42 eprintln!(
43 "Using providers:\n{}",
44 providers
45 .iter()
46 .map(|p| format!("- {}: {}", (p.id).0, p.url))
47 .collect::<Vec<_>>()
48 .join("\n")
49 );
50
51 let cfg = HedgeConfig {
52 initial_providers: 1,
53 hedge_after: Duration::from_millis(80),
54 max_providers: providers.len(),
55 min_slot: None,
56 overall_timeout: Duration::from_secs(2),
57 };
58
59 let client = HedgedRpcClient::new(providers, cfg);
60
61 let addr: Pubkey = "So11111111111111111111111111111111111111112".parse()?;
62 let commitment = CommitmentConfig::processed();
63
64 let t0 = Instant::now();
65 let (bh_provider, blockhash) = client.get_latest_blockhash().await?;
66 let dt_bh = t0.elapsed();
67
68 println!(
69 "[blockhash] provider={} latency={:?} hash={}",
70 bh_provider.0, dt_bh, blockhash,
71 );
72
73 let t1 = Instant::now();
74 let (acc_provider, resp) = client.get_account(&addr, commitment).await?;
75 let dt_acc = t1.elapsed();
76
77 println!(
78 "[account] provider={} latency={:?} slot={}",
79 acc_provider.0, dt_acc, resp.context.slot,
80 );
81
82 match resp.value {
83 Some(account) => {
84 println!("lamports={}", account.lamports);
85 println!("data_len={}", account.data.len());
86 println!("owner={}", account.owner);
87 }
88 None => println!("account not found"),
89 }
90
91 Ok(())
92}More examples
161async fn run_runner(
162 label: &'static str,
163 client: HedgedRpcClient,
164 addr: Pubkey,
165 commitment: CommitmentConfig,
166 num_calls: usize,
167 max_in_flight: usize,
168) -> Result<RunnerStats, Box<dyn std::error::Error + Send + Sync>> {
169 let (tx, mut rx) = mpsc::channel::<CallResult>(max_in_flight * 2);
170 let semaphore = Arc::new(Semaphore::new(max_in_flight));
171
172 let consumer = tokio::spawn(async move {
173 let mut results: Vec<CallResult> = Vec::with_capacity(num_calls);
174
175 while let Some(res) = rx.recv().await {
176 match &res.outcome {
177 CallOutcome::Ok { provider, latency } => {
178 println!(
179 "[{} call {:05}] OK provider={} latency={:?}",
180 label, res.call_idx, provider.0, latency
181 );
182 }
183 CallOutcome::Err { error, latency } => {
184 println!(
185 "[{} call {:05}] ERR latency={:?} error={}",
186 label, res.call_idx, latency, error
187 );
188 }
189 }
190
191 results.push(res);
192 }
193
194 results
195 });
196
197 for i in 0..num_calls {
198 let client_clone = client.clone();
199 let tx_clone = tx.clone();
200 let addr_copy = addr;
201 let commitment_clone = commitment;
202 let sem = semaphore.clone();
203
204 tokio::spawn(async move {
205 let _permit = sem.acquire_owned().await.expect("semaphore closed");
206
207 let start = Instant::now();
208 let res = client_clone.get_account(&addr_copy, commitment_clone).await;
209 let elapsed = start.elapsed();
210
211 let outcome = match res {
212 Ok((provider, _resp)) => CallOutcome::Ok {
213 provider,
214 latency: elapsed,
215 },
216 Err(e) => CallOutcome::Err {
217 error: e.to_string(),
218 latency: elapsed,
219 },
220 };
221
222 let _ = tx_clone
223 .send(CallResult {
224 call_idx: i,
225 outcome,
226 })
227 .await;
228 });
229 }
230
231 drop(tx);
232 let results = consumer.await?;
233
234 let mut successes = 0usize;
235 let mut errors = 0usize;
236 let mut sum_latency = Duration::ZERO;
237 let mut per_provider_wins: HashMap<&'static str, usize> = HashMap::new();
238
239 for r in &results {
240 match &r.outcome {
241 CallOutcome::Ok { provider, latency } => {
242 successes += 1;
243 sum_latency += *latency;
244 *per_provider_wins.entry(provider.0).or_insert(0) += 1;
245 }
246 CallOutcome::Err { .. } => {
247 errors += 1;
248 }
249 }
250 }
251
252 let avg_latency_ms = if successes > 0 {
253 (sum_latency.as_secs_f64() * 1000.0) / (successes as f64)
254 } else {
255 0.0
256 };
257
258 Ok(RunnerStats {
259 label,
260 total_calls: num_calls,
261 successes,
262 errors,
263 avg_latency_ms,
264 per_provider_wins,
265 })
266}48async fn main() -> Result<(), Box<dyn std::error::Error>> {
49 let mut providers = Vec::new();
50
51 if let Some(p) = provider_from_env("HELIUS_RPC_URL", "helius") {
52 providers.push(p);
53 }
54 if let Some(p) = provider_from_env("TRITON_RPC_URL", "triton") {
55 providers.push(p);
56 }
57 if let Some(p) = provider_from_env("QUICKNODE_RPC_URL", "quicknode") {
58 providers.push(p);
59 }
60
61 if providers.is_empty() {
62 eprintln!("No providers configured.");
63 eprintln!("Set at least one of: HELIUS_RPC_URL, TRITON_RPC_URL, QUICKNODE_RPC_URL");
64 return Ok(());
65 }
66
67 let cfg = HedgeConfig {
68 initial_providers: providers.len(),
69 hedge_after: Duration::from_millis(20),
70 max_providers: providers.len(),
71 min_slot: None,
72 overall_timeout: Duration::from_secs(1),
73 };
74
75 let client = HedgedRpcClient::new(providers, cfg);
76
77 let addr: Pubkey = "So11111111111111111111111111111111111111112".parse()?;
78 let commitment = CommitmentConfig::processed();
79
80 let (tx, mut rx) = mpsc::channel::<CallResult>(MAX_IN_FLIGHT * 2);
81 let semaphore = Arc::new(Semaphore::new(MAX_IN_FLIGHT));
82 let consumer = tokio::spawn(async move {
83 let mut results: Vec<CallResult> = Vec::with_capacity(NUM_CALLS);
84
85 while let Some(res) = rx.recv().await {
86 match &res.outcome {
87 CallOutcome::Ok { provider, latency } => {
88 println!(
89 "[call {:05}] OK provider={} latency={:?}",
90 res.call_idx, provider.0, latency
91 );
92 }
93 CallOutcome::Err { error, latency } => {
94 println!(
95 "[call {:05}] ERR latency={:?} error={}",
96 res.call_idx, latency, error
97 );
98 }
99 }
100
101 results.push(res);
102 }
103
104 results
105 });
106
107 for i in 0..NUM_CALLS {
108 let client_clone = client.clone();
109 let tx_clone = tx.clone();
110 let addr_copy = addr;
111 let commitment_clone = commitment;
112 let sem = semaphore.clone();
113
114 tokio::spawn(async move {
115 let _permit = sem.acquire_owned().await.expect("semaphore closed");
116
117 let start = Instant::now();
118 let res = client_clone.get_account(&addr_copy, commitment_clone).await;
119 let elapsed = start.elapsed();
120
121 let outcome = match res {
122 Ok((provider, _resp)) => CallOutcome::Ok {
123 provider,
124 latency: elapsed,
125 },
126 Err(e) => CallOutcome::Err {
127 error: e.to_string(),
128 latency: elapsed,
129 },
130 };
131
132 let _ = tx_clone
133 .send(CallResult {
134 call_idx: i,
135 outcome,
136 })
137 .await;
138 });
139 }
140
141 drop(tx);
142 let mut results = consumer.await?;
143
144 results.sort_by_key(|r| r.call_idx);
145
146 let mut wins: HashMap<&'static str, usize> = HashMap::new();
147 let mut total_latency: HashMap<&'static str, Duration> = HashMap::new();
148 let mut error_count = 0usize;
149
150 for r in &results {
151 match &r.outcome {
152 CallOutcome::Ok { provider, latency } => {
153 let name = provider.0;
154 *wins.entry(name).or_insert(0) += 1;
155 *total_latency.entry(name).or_insert(Duration::ZERO) += *latency;
156 }
157 CallOutcome::Err { .. } => {
158 error_count += 1;
159 }
160 }
161 }
162
163 println!("\n=== summary ===");
164 println!("total calls : {}", NUM_CALLS);
165 println!("successes : {}", NUM_CALLS - error_count);
166 println!("errors (any kind) : {}", error_count);
167
168 for (provider, count) in wins.iter() {
169 let total = total_latency[provider];
170 let avg_ms = total.as_secs_f64() * 1000.0 / (*count as f64);
171 println!(
172 "provider {:>10}: wins = {:6}, avg_latency = {:8.3} ms",
173 provider, count, avg_ms,
174 );
175 }
176
177 Ok(())
178}Sourcepub async fn get_account_any(
&self,
pubkey: &Pubkey,
commitment: CommitmentConfig,
) -> Result<RpcResponse<Option<Account>>, HedgedError>
pub async fn get_account_any( &self, pubkey: &Pubkey, commitment: CommitmentConfig, ) -> Result<RpcResponse<Option<Account>>, HedgedError>
Gets account data, returning only the response without provider information.
Sourcepub async fn get_account_fresh(
&self,
pubkey: &Pubkey,
commitment: CommitmentConfig,
min_slot: u64,
) -> Result<(ProviderId, RpcResponse<Option<Account>>), HedgedError>
pub async fn get_account_fresh( &self, pubkey: &Pubkey, commitment: CommitmentConfig, min_slot: u64, ) -> Result<(ProviderId, RpcResponse<Option<Account>>), HedgedError>
Gets account data with slot freshness validation.
Returns an error if the response slot is older than the specified minimum slot. Useful for ensuring data recency in time-sensitive operations.
§Arguments
pubkey- The account’s public keycommitment- The commitment level for the querymin_slot- Minimum acceptable slot number
Trait Implementations§
Source§impl Clone for HedgedRpcClient
impl Clone for HedgedRpcClient
Source§fn clone(&self) -> HedgedRpcClient
fn clone(&self) -> HedgedRpcClient
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for HedgedRpcClient
impl !RefUnwindSafe for HedgedRpcClient
impl Send for HedgedRpcClient
impl Sync for HedgedRpcClient
impl Unpin for HedgedRpcClient
impl !UnwindSafe for HedgedRpcClient
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more