LiteBalancer
LiteBalancer is the current multi-peer wrapper around connected
LiteClient instances. It is available with the liteclient feature and is
intended for callers that want the same LiteAPI helper surface with basic peer
selection and retry behavior.
Audience: applications that can connect to several liteservers and want basic
failover. Prerequisites: liteclient feature, live network access, and explicit
peer construction from config or socket/public-key pairs. This is not a
consensus or proof-verification layer.
Peer Setup
The balancer owns already constructed clients. When using public global config,
create one LiteClient per selected liteserver, then call start_up before
sending requests.
#![allow(unused)]
fn main() {
use std::str::FromStr;
use std::time::Duration;
use tonutils::liteclient::{
balancer::LiteBalancer,
client::LiteClient,
rate_limit::RequestRateLimit,
};
use tonutils::network_config::{ConfigGlobal, LiteServerBlacklist};
async fn example(config_json: &str) -> anyhow::Result<()> {
let config = ConfigGlobal::from_str(config_json)?;
let blacklist = LiteServerBlacklist::parse_tokens([
"index:0",
"id:AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE=",
])?;
let mut peers = Vec::new();
for (_index, liteserver) in config.select_liteservers(3, &blacklist) {
peers.push(LiteClient::connect_liteserver(liteserver).await?);
}
let mut balancer = LiteBalancer::new(peers, Duration::from_secs(10))
.with_rate_limit_per_peer(RequestRateLimit::per_second(5)?)
.with_global_rate_limit(RequestRateLimit::per_second(12)?);
balancer.start_up().await?;
let info = balancer.get_masterchain_info().await?;
println!("{}", info.last.seqno);
balancer.close_all().await?;
Ok(())
}
}
start_up marks connected peers as alive, performs a best-effort archival
probe, starts the current health-check task, and records the balancer as
initialized. close_all aborts the health-check task and closes all owned
clients.
Request Routing
The balancer exposes typed helpers for common LiteAPI calls, including
masterchain info, version, time, block and state loading, block headers,
account state, get-methods, transactions, shard info, config, libraries, and
message sending. Typed methods such as raw_get_block,
get_account_state_simple, run_get_method_typed, and
get_config_params_typed delegate to the underlying LiteClient through the
same peer selection and retry path. Request routing builds a priority list from
alive peers, observed masterchain seqno, average response time, and current
in-flight request count.
For non-archival calls, no peer quorum is established. The first successful peer response is returned, and failed peers are marked dead for later requests. For calls that need archival data, the balancer uses peers detected by its archival probe.
Request Rate Limits
Per-peer limits throttle each owned LiteClient. Global limits throttle total
balancer attempts, including retries and each send_message peer attempt.
Neither limit is enabled by default.
Use per-peer limits for rented liteserver quotas that apply separately to every server. Use a global limit when an upstream account or proxy enforces an aggregate request budget.
Current Limits
This is a prototype balancer, not a production peer manager yet:
- peer transitions are represented, but timeout and reconnect state machines are still incomplete;
- reconnection uses no stored peer descriptors, exponential backoff, or jitter;
- latency scoring uses an arithmetic average rather than EWMA;
- stale seqno and in-flight penalties are basic;
send_messagefailover does not yet preserve every peer error for detailed diagnostics;- proof fields returned by LiteAPI calls are not verified.
Use it as a convenience layer over trusted liteserver connections. Do not treat multi-peer routing as proof verification or consensus validation.