HedgedRpcClient

Struct HedgedRpcClient 

Source
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

Source

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?
examples/basic_get_account.rs (line 59)
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
Hide additional examples
examples/dual_race.rs (line 82)
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}
examples/rpc_race.rs (line 75)
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}
Source

pub fn providers(&self) -> &[(ProviderId, Arc<RpcClient>)]

Returns a reference to the configured providers.

Source

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.

Source

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?
examples/basic_get_account.rs (line 65)
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}
Source

pub async fn get_latest_blockhash_any(&self) -> Result<Hash, HedgedError>

Gets the latest blockhash, returning only the hash without provider information.

Source

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 key
  • commitment - The commitment level for the query
Examples found in repository?
examples/basic_get_account.rs (line 74)
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
Hide additional examples
examples/dual_race.rs (line 208)
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}
examples/rpc_race.rs (line 118)
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}
Source

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.

Source

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 key
  • commitment - The commitment level for the query
  • min_slot - Minimum acceptable slot number

Trait Implementations§

Source§

impl Clone for HedgedRpcClient

Source§

fn clone(&self) -> HedgedRpcClient

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more