Split up solana-client (#27246)
* Move thin-client to new crate * Move tpu client and varieties to new crate * Move pubsub-client to new crate * Move rpc-client to new crate * Add client-common crate to avoid circular dependencies * Move rpc_cache and make less pub * Remove unused unpub modules * Add nonce-client * Remove unused dependencies * Fix rpc_client docs * Move spinner to calling clients * Rename client-common to rpc-client-api * Remove unnecessary rpc_ prefix * Remove unused ClientErrorKind variant * Remove unnecessary Client prefix * Move mod declarations into lib.rs and remove unnecessary files * Rename nonce-client and remove redundant module name * Restore mock_sender_for_cli in solana-client
This commit is contained in:
parent
efa6201eda
commit
c24eaa36f8
|
@ -4884,6 +4884,7 @@ dependencies = [
|
|||
"solana-logger 1.12.0",
|
||||
"solana-program-runtime",
|
||||
"solana-remote-wallet",
|
||||
"solana-rpc-client",
|
||||
"solana-sdk 1.12.0",
|
||||
"solana-streamer",
|
||||
"solana-test-validator",
|
||||
|
@ -4942,58 +4943,15 @@ dependencies = [
|
|||
name = "solana-client"
|
||||
version = "1.12.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"assert_matches",
|
||||
"async-mutex",
|
||||
"async-trait",
|
||||
"base64 0.13.0",
|
||||
"bincode",
|
||||
"bs58",
|
||||
"bytes",
|
||||
"clap 2.33.3",
|
||||
"crossbeam-channel",
|
||||
"enum_dispatch",
|
||||
"futures 0.3.23",
|
||||
"futures-util",
|
||||
"indexmap",
|
||||
"indicatif",
|
||||
"itertools",
|
||||
"jsonrpc-core",
|
||||
"jsonrpc-http-server",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"quinn",
|
||||
"quinn-proto",
|
||||
"quinn-udp",
|
||||
"rand 0.7.3",
|
||||
"rand_chacha 0.2.2",
|
||||
"rayon",
|
||||
"reqwest",
|
||||
"rustls 0.20.6",
|
||||
"semver 1.0.13",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"solana-account-decoder",
|
||||
"solana-clap-utils",
|
||||
"solana-faucet",
|
||||
"solana-logger 1.12.0",
|
||||
"solana-measure",
|
||||
"solana-metrics",
|
||||
"solana-net-utils",
|
||||
"solana-perf",
|
||||
"solana-pubsub-client",
|
||||
"solana-rpc-client",
|
||||
"solana-rpc-client-api",
|
||||
"solana-rpc-client-nonce-utils",
|
||||
"solana-sdk 1.12.0",
|
||||
"solana-streamer",
|
||||
"solana-transaction-status",
|
||||
"solana-version",
|
||||
"solana-vote-program",
|
||||
"spl-token-2022",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tokio-tungstenite",
|
||||
"tungstenite",
|
||||
"url 2.2.2",
|
||||
"solana-thin-client",
|
||||
"solana-tpu-client",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -5911,6 +5869,29 @@ dependencies = [
|
|||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-pubsub-client"
|
||||
version = "1.12.0"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"futures-util",
|
||||
"log",
|
||||
"reqwest",
|
||||
"semver 1.0.13",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"solana-account-decoder",
|
||||
"solana-rpc-client-api",
|
||||
"solana-sdk 1.12.0",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tokio-tungstenite",
|
||||
"tungstenite",
|
||||
"url 2.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-rayon-threadlimit"
|
||||
version = "1.12.0"
|
||||
|
@ -5992,6 +5973,72 @@ dependencies = [
|
|||
"tokio-util 0.6.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-rpc-client"
|
||||
version = "1.12.0"
|
||||
dependencies = [
|
||||
"assert_matches",
|
||||
"async-trait",
|
||||
"base64 0.13.0",
|
||||
"bincode",
|
||||
"bs58",
|
||||
"crossbeam-channel",
|
||||
"futures 0.3.23",
|
||||
"indicatif",
|
||||
"jsonrpc-core",
|
||||
"jsonrpc-http-server",
|
||||
"log",
|
||||
"reqwest",
|
||||
"semver 1.0.13",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"solana-account-decoder",
|
||||
"solana-rpc-client-api",
|
||||
"solana-sdk 1.12.0",
|
||||
"solana-transaction-status",
|
||||
"solana-version",
|
||||
"solana-vote-program",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-rpc-client-api"
|
||||
version = "1.12.0"
|
||||
dependencies = [
|
||||
"base64 0.13.0",
|
||||
"bs58",
|
||||
"jsonrpc-core",
|
||||
"reqwest",
|
||||
"semver 1.0.13",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"solana-account-decoder",
|
||||
"solana-sdk 1.12.0",
|
||||
"solana-transaction-status",
|
||||
"solana-version",
|
||||
"spl-token-2022",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-rpc-client-nonce-utils"
|
||||
version = "1.12.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap 2.33.3",
|
||||
"futures 0.3.23",
|
||||
"serde_json",
|
||||
"solana-account-decoder",
|
||||
"solana-clap-utils",
|
||||
"solana-rpc-client",
|
||||
"solana-rpc-client-api",
|
||||
"solana-sdk 1.12.0",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-rpc-test"
|
||||
version = "1.12.0"
|
||||
|
@ -6389,6 +6436,20 @@ dependencies = [
|
|||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-thin-client"
|
||||
version = "1.12.0"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"log",
|
||||
"rayon",
|
||||
"solana-logger 1.12.0",
|
||||
"solana-rpc-client",
|
||||
"solana-rpc-client-api",
|
||||
"solana-sdk 1.12.0",
|
||||
"solana-tpu-client",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-tokens"
|
||||
version = "1.12.0"
|
||||
|
@ -6420,6 +6481,43 @@ dependencies = [
|
|||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-tpu-client"
|
||||
version = "1.12.0"
|
||||
dependencies = [
|
||||
"async-mutex",
|
||||
"async-trait",
|
||||
"bincode",
|
||||
"crossbeam-channel",
|
||||
"enum_dispatch",
|
||||
"futures 0.3.23",
|
||||
"futures-util",
|
||||
"indexmap",
|
||||
"indicatif",
|
||||
"itertools",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"quinn",
|
||||
"quinn-proto",
|
||||
"quinn-udp",
|
||||
"rand 0.7.3",
|
||||
"rand_chacha 0.2.2",
|
||||
"rayon",
|
||||
"rustls 0.20.6",
|
||||
"solana-logger 1.12.0",
|
||||
"solana-measure",
|
||||
"solana-metrics",
|
||||
"solana-net-utils",
|
||||
"solana-perf",
|
||||
"solana-pubsub-client",
|
||||
"solana-rpc-client",
|
||||
"solana-rpc-client-api",
|
||||
"solana-sdk 1.12.0",
|
||||
"solana-streamer",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-transaction-dos"
|
||||
version = "1.12.0"
|
||||
|
|
|
@ -58,10 +58,14 @@ members = [
|
|||
"programs/stake",
|
||||
"programs/vote",
|
||||
"programs/zk-token-proof",
|
||||
"pubsub-client",
|
||||
"rayon-threadlimit",
|
||||
"rbpf-cli",
|
||||
"remote-wallet",
|
||||
"rpc",
|
||||
"rpc-client",
|
||||
"rpc-client-api",
|
||||
"rpc-client-nonce-utils",
|
||||
"rpc-test",
|
||||
"runtime",
|
||||
"runtime/store-tool",
|
||||
|
@ -78,7 +82,9 @@ members = [
|
|||
"streamer",
|
||||
"sys-tuner",
|
||||
"test-validator",
|
||||
"thin-client",
|
||||
"tokens",
|
||||
"tpu-client",
|
||||
"transaction-dos",
|
||||
"transaction-status",
|
||||
"upload-perf",
|
||||
|
|
|
@ -39,6 +39,7 @@ solana-faucet = { path = "../faucet", version = "=1.12.0" }
|
|||
solana-logger = { path = "../logger", version = "=1.12.0" }
|
||||
solana-program-runtime = { path = "../program-runtime", version = "=1.12.0" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "=1.12.0" }
|
||||
solana-rpc-client = { path = "../rpc-client", version = "=1.12.0" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.12.0" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.12.0" }
|
||||
solana-version = { path = "../version", version = "=1.12.0" }
|
||||
|
|
|
@ -1713,10 +1713,10 @@ mod tests {
|
|||
serde_json::{json, Value},
|
||||
solana_client::{
|
||||
blockhash_query,
|
||||
mock_sender_for_cli::SIGNATURE,
|
||||
rpc_request::RpcRequest,
|
||||
rpc_response::{Response, RpcResponseContext},
|
||||
},
|
||||
solana_rpc_client::mock_sender_for_cli::SIGNATURE,
|
||||
solana_sdk::{
|
||||
pubkey::Pubkey,
|
||||
signature::{
|
||||
|
|
|
@ -10,60 +10,17 @@ license = "Apache-2.0"
|
|||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
async-mutex = "1.4.0"
|
||||
async-trait = "0.1.57"
|
||||
base64 = "0.13.0"
|
||||
bincode = "1.3.3"
|
||||
bs58 = "0.4.0"
|
||||
bytes = "1.2.1"
|
||||
clap = "2.33.0"
|
||||
crossbeam-channel = "0.5"
|
||||
enum_dispatch = "0.3.8"
|
||||
futures = "0.3"
|
||||
futures-util = "0.3.21"
|
||||
indexmap = "1.9.1"
|
||||
indicatif = "0.17.0"
|
||||
itertools = "0.10.2"
|
||||
jsonrpc-core = "18.0.0"
|
||||
lazy_static = "1.4.0"
|
||||
log = "0.4.17"
|
||||
quinn = "0.8.4"
|
||||
quinn-proto = "0.8.4"
|
||||
quinn-udp = "0.1.3"
|
||||
rand = "0.7.0"
|
||||
rand_chacha = "0.2.2"
|
||||
rayon = "1.5.3"
|
||||
reqwest = { version = "0.11.11", default-features = false, features = ["blocking", "brotli", "deflate", "gzip", "rustls-tls", "json"] }
|
||||
rustls = { version = "0.20.6", features = ["dangerous_configuration"] }
|
||||
semver = "1.0.13"
|
||||
serde = "1.0.143"
|
||||
serde_derive = "1.0.103"
|
||||
serde_json = "1.0.83"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.12.0" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.12.0" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.12.0" }
|
||||
solana-measure = { path = "../measure", version = "=1.12.0" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.12.0" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.12.0" }
|
||||
solana-pubsub-client = { path = "../pubsub-client", version = "=1.12.0" }
|
||||
solana-rpc-client = { path = "../rpc-client", version = "=1.12.0" }
|
||||
solana-rpc-client-api = { path = "../rpc-client-api", version = "=1.12.0" }
|
||||
solana-rpc-client-nonce-utils = { path = "../rpc-client-nonce-utils", version = "=1.12.0" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.12.0" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.12.0" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.12.0" }
|
||||
solana-version = { path = "../version", version = "=1.12.0" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.12.0" }
|
||||
spl-token-2022 = { version = "=0.4.3", features = ["no-entrypoint"] }
|
||||
thiserror = "1.0"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
tokio-stream = "0.1.9"
|
||||
tokio-tungstenite = { version = "0.17.2", features = ["rustls-tls-webpki-roots"] }
|
||||
tungstenite = { version = "0.17.2", features = ["rustls-tls-webpki-roots"] }
|
||||
url = "2.2.2"
|
||||
solana-thin-client = { path = "../thin-client", version = "=1.12.0" }
|
||||
solana-tpu-client = { path = "../tpu-client", version = "=1.12.0" }
|
||||
|
||||
[dev-dependencies]
|
||||
anyhow = "1.0.58"
|
||||
assert_matches = "1.5.0"
|
||||
jsonrpc-http-server = "18.0.0"
|
||||
solana-logger = { path = "../logger", version = "=1.12.0" }
|
||||
solana-perf = { path = "../perf", version = "=1.12.0" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
|
|
@ -1,212 +0,0 @@
|
|||
pub use reqwest;
|
||||
use {
|
||||
crate::{nonblocking::quic_client::QuicError, rpc_request, rpc_response},
|
||||
quinn::ConnectError,
|
||||
solana_faucet::faucet::FaucetError,
|
||||
solana_sdk::{
|
||||
signature::SignerError, transaction::TransactionError, transport::TransportError,
|
||||
},
|
||||
std::io,
|
||||
thiserror::Error,
|
||||
}; // export `reqwest` for clients
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum ClientErrorKind {
|
||||
#[error(transparent)]
|
||||
Io(#[from] io::Error),
|
||||
#[error(transparent)]
|
||||
Reqwest(#[from] reqwest::Error),
|
||||
#[error(transparent)]
|
||||
RpcError(#[from] rpc_request::RpcError),
|
||||
#[error(transparent)]
|
||||
SerdeJson(#[from] serde_json::error::Error),
|
||||
#[error(transparent)]
|
||||
SigningError(#[from] SignerError),
|
||||
#[error(transparent)]
|
||||
TransactionError(#[from] TransactionError),
|
||||
#[error(transparent)]
|
||||
FaucetError(#[from] FaucetError),
|
||||
#[error("Custom: {0}")]
|
||||
Custom(String),
|
||||
}
|
||||
|
||||
impl ClientErrorKind {
|
||||
pub fn get_transaction_error(&self) -> Option<TransactionError> {
|
||||
match self {
|
||||
Self::RpcError(rpc_request::RpcError::RpcResponseError {
|
||||
data:
|
||||
rpc_request::RpcResponseErrorData::SendTransactionPreflightFailure(
|
||||
rpc_response::RpcSimulateTransactionResult {
|
||||
err: Some(tx_err), ..
|
||||
},
|
||||
),
|
||||
..
|
||||
}) => Some(tx_err.clone()),
|
||||
Self::TransactionError(tx_err) => Some(tx_err.clone()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TransportError> for ClientErrorKind {
|
||||
fn from(err: TransportError) -> Self {
|
||||
match err {
|
||||
TransportError::IoError(err) => Self::Io(err),
|
||||
TransportError::TransactionError(err) => Self::TransactionError(err),
|
||||
TransportError::Custom(err) => Self::Custom(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ClientErrorKind> for TransportError {
|
||||
fn from(client_error_kind: ClientErrorKind) -> Self {
|
||||
match client_error_kind {
|
||||
ClientErrorKind::Io(err) => Self::IoError(err),
|
||||
ClientErrorKind::TransactionError(err) => Self::TransactionError(err),
|
||||
ClientErrorKind::Reqwest(err) => Self::Custom(format!("{:?}", err)),
|
||||
ClientErrorKind::RpcError(err) => Self::Custom(format!("{:?}", err)),
|
||||
ClientErrorKind::SerdeJson(err) => Self::Custom(format!("{:?}", err)),
|
||||
ClientErrorKind::SigningError(err) => Self::Custom(format!("{:?}", err)),
|
||||
ClientErrorKind::FaucetError(err) => Self::Custom(format!("{:?}", err)),
|
||||
ClientErrorKind::Custom(err) => Self::Custom(format!("{:?}", err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<QuicError> for ClientErrorKind {
|
||||
fn from(quic_error: QuicError) -> Self {
|
||||
Self::Custom(format!("{:?}", quic_error))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ConnectError> for ClientErrorKind {
|
||||
fn from(connect_error: ConnectError) -> Self {
|
||||
Self::Custom(format!("{:?}", connect_error))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
#[error("{kind}")]
|
||||
pub struct ClientError {
|
||||
pub request: Option<rpc_request::RpcRequest>,
|
||||
|
||||
#[source]
|
||||
pub kind: ClientErrorKind,
|
||||
}
|
||||
|
||||
impl ClientError {
|
||||
pub fn new_with_request(kind: ClientErrorKind, request: rpc_request::RpcRequest) -> Self {
|
||||
Self {
|
||||
request: Some(request),
|
||||
kind,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_with_request(self, request: rpc_request::RpcRequest) -> Self {
|
||||
Self {
|
||||
request: Some(request),
|
||||
..self
|
||||
}
|
||||
}
|
||||
|
||||
pub fn request(&self) -> Option<&rpc_request::RpcRequest> {
|
||||
self.request.as_ref()
|
||||
}
|
||||
|
||||
pub fn kind(&self) -> &ClientErrorKind {
|
||||
&self.kind
|
||||
}
|
||||
|
||||
pub fn get_transaction_error(&self) -> Option<TransactionError> {
|
||||
self.kind.get_transaction_error()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ClientErrorKind> for ClientError {
|
||||
fn from(kind: ClientErrorKind) -> Self {
|
||||
Self {
|
||||
request: None,
|
||||
kind,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TransportError> for ClientError {
|
||||
fn from(err: TransportError) -> Self {
|
||||
Self {
|
||||
request: None,
|
||||
kind: err.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ClientError> for TransportError {
|
||||
fn from(client_error: ClientError) -> Self {
|
||||
client_error.kind.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for ClientError {
|
||||
fn from(err: std::io::Error) -> Self {
|
||||
Self {
|
||||
request: None,
|
||||
kind: err.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<reqwest::Error> for ClientError {
|
||||
fn from(err: reqwest::Error) -> Self {
|
||||
Self {
|
||||
request: None,
|
||||
kind: err.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<rpc_request::RpcError> for ClientError {
|
||||
fn from(err: rpc_request::RpcError) -> Self {
|
||||
Self {
|
||||
request: None,
|
||||
kind: err.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<serde_json::error::Error> for ClientError {
|
||||
fn from(err: serde_json::error::Error) -> Self {
|
||||
Self {
|
||||
request: None,
|
||||
kind: err.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SignerError> for ClientError {
|
||||
fn from(err: SignerError) -> Self {
|
||||
Self {
|
||||
request: None,
|
||||
kind: err.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TransactionError> for ClientError {
|
||||
fn from(err: TransactionError) -> Self {
|
||||
Self {
|
||||
request: None,
|
||||
kind: err.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FaucetError> for ClientError {
|
||||
fn from(err: FaucetError) -> Self {
|
||||
Self {
|
||||
request: None,
|
||||
kind: err.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, ClientError>;
|
|
@ -1,38 +1,120 @@
|
|||
#![allow(clippy::integer_arithmetic)]
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
#[macro_use]
|
||||
extern crate solana_metrics;
|
||||
|
||||
pub mod blockhash_query;
|
||||
pub mod client_error;
|
||||
pub mod connection_cache;
|
||||
pub(crate) mod http_sender;
|
||||
pub(crate) mod mock_sender;
|
||||
pub mod nonblocking;
|
||||
pub mod nonce_utils;
|
||||
pub mod pubsub_client;
|
||||
pub mod quic_client;
|
||||
pub mod rpc_cache;
|
||||
pub mod rpc_client;
|
||||
pub mod rpc_config;
|
||||
pub mod rpc_custom_error;
|
||||
pub mod rpc_deprecated_config;
|
||||
pub mod rpc_filter;
|
||||
pub mod rpc_request;
|
||||
pub mod rpc_response;
|
||||
pub mod rpc_sender;
|
||||
pub mod spinner;
|
||||
pub mod thin_client;
|
||||
pub mod tpu_client;
|
||||
pub mod tpu_connection;
|
||||
pub mod transaction_executor;
|
||||
pub mod udp_client;
|
||||
|
||||
pub mod mock_sender_for_cli {
|
||||
/// Magic `SIGNATURE` value used by `solana-cli` unit tests.
|
||||
/// Please don't use this constant.
|
||||
pub const SIGNATURE: &str =
|
||||
"43yNSFC6fYTuPgTNFFhF4axw7AfWxB2BPdurme8yrsWEYwm8299xh8n6TAHjGymiSub1XtyxTNyd9GBfY2hxoBw8";
|
||||
pub use solana_rpc_client::mock_sender_for_cli;
|
||||
|
||||
pub mod blockhash_query {
|
||||
pub use solana_rpc_client_nonce_utils::blockhash_query::*;
|
||||
}
|
||||
pub mod client_error {
|
||||
pub use solana_rpc_client_api::client_error::{
|
||||
reqwest, Error as ClientError, ErrorKind as ClientErrorKind, Result,
|
||||
};
|
||||
}
|
||||
pub mod connection_cache {
|
||||
pub use solana_tpu_client::connection_cache::*;
|
||||
}
|
||||
pub mod nonblocking {
|
||||
pub mod blockhash_query {
|
||||
pub use solana_rpc_client_nonce_utils::nonblocking::blockhash_query::*;
|
||||
}
|
||||
/// Durable transaction nonce helpers.
|
||||
pub mod nonce_utils {
|
||||
pub use solana_rpc_client_nonce_utils::nonblocking::*;
|
||||
}
|
||||
pub mod pubsub_client {
|
||||
pub use solana_pubsub_client::nonblocking::pubsub_client::*;
|
||||
}
|
||||
/// Simple nonblocking client that connects to a given UDP port with the QUIC protocol
|
||||
/// and provides an interface for sending transactions which is restricted by the
|
||||
/// server's flow control.
|
||||
pub mod quic_client {
|
||||
pub use solana_tpu_client::nonblocking::quic_client::*;
|
||||
}
|
||||
/// Communication with a Solana node over RPC asynchronously .
|
||||
///
|
||||
/// Software that interacts with the Solana blockchain, whether querying its
|
||||
/// state or submitting transactions, communicates with a Solana node over
|
||||
/// [JSON-RPC], using the [`RpcClient`] type.
|
||||
///
|
||||
/// [JSON-RPC]: https://www.jsonrpc.org/specification
|
||||
pub mod rpc_client {
|
||||
pub use solana_rpc_client::nonblocking::rpc_client::*;
|
||||
}
|
||||
pub mod tpu_client {
|
||||
pub use solana_tpu_client::nonblocking::tpu_client::*;
|
||||
}
|
||||
/// Trait defining async send functions, to be used for UDP or QUIC sending
|
||||
pub mod tpu_connection {
|
||||
pub use solana_tpu_client::nonblocking::tpu_connection::*;
|
||||
}
|
||||
/// Simple UDP client that communicates with the given UDP port with UDP and provides
|
||||
/// an interface for sending transactions
|
||||
pub mod udp_client {
|
||||
pub use solana_tpu_client::nonblocking::udp_client::*;
|
||||
}
|
||||
}
|
||||
/// Durable transaction nonce helpers.
|
||||
pub mod nonce_utils {
|
||||
pub use solana_rpc_client_nonce_utils::*;
|
||||
}
|
||||
pub mod pubsub_client {
|
||||
pub use solana_pubsub_client::pubsub_client::*;
|
||||
}
|
||||
/// Simple client that connects to a given UDP port with the QUIC protocol and provides
|
||||
/// an interface for sending transactions which is restricted by the server's flow control.
|
||||
pub mod quic_client {
|
||||
pub use solana_tpu_client::quic_client::*;
|
||||
}
|
||||
/// Communication with a Solana node over RPC.
|
||||
///
|
||||
/// Software that interacts with the Solana blockchain, whether querying its
|
||||
/// state or submitting transactions, communicates with a Solana node over
|
||||
/// [JSON-RPC], using the [`RpcClient`] type.
|
||||
///
|
||||
/// [JSON-RPC]: https://www.jsonrpc.org/specification
|
||||
pub mod rpc_client {
|
||||
pub use solana_rpc_client::rpc_client::*;
|
||||
}
|
||||
pub mod rpc_config {
|
||||
pub use solana_rpc_client_api::config::*;
|
||||
}
|
||||
/// Implementation defined RPC server errors
|
||||
pub mod rpc_custom_error {
|
||||
pub use solana_rpc_client_api::custom_error::*;
|
||||
}
|
||||
pub mod rpc_deprecated_config {
|
||||
pub use solana_rpc_client_api::deprecated_config::*;
|
||||
}
|
||||
pub mod rpc_filter {
|
||||
pub use solana_rpc_client_api::filter::*;
|
||||
}
|
||||
pub mod rpc_request {
|
||||
pub use solana_rpc_client_api::request::*;
|
||||
}
|
||||
pub mod rpc_response {
|
||||
pub use solana_rpc_client_api::response::*;
|
||||
}
|
||||
/// A transport for RPC calls.
|
||||
pub mod rpc_sender {
|
||||
pub use solana_rpc_client::rpc_sender::*;
|
||||
}
|
||||
/// The `thin_client` module is a client-side object that interfaces with
|
||||
/// a server-side TPU. Client code should use this object instead of writing
|
||||
/// messages to the network directly. The binary encoding of its messages are
|
||||
/// unstable and may change in future releases.
|
||||
pub mod thin_client {
|
||||
pub use solana_thin_client::thin_client::*;
|
||||
}
|
||||
pub mod tpu_client {
|
||||
pub use solana_tpu_client::tpu_client::*;
|
||||
}
|
||||
pub mod tpu_connection {
|
||||
pub use solana_tpu_client::tpu_connection::*;
|
||||
}
|
||||
/// Simple TPU client that communicates with the given UDP port with UDP and provides
|
||||
/// an interface for sending transactions
|
||||
pub mod udp_client {
|
||||
pub use solana_tpu_client::udp_client::*;
|
||||
}
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
pub mod blockhash_query;
|
||||
pub mod nonce_utils;
|
||||
pub mod pubsub_client;
|
||||
pub mod quic_client;
|
||||
pub mod rpc_client;
|
||||
pub mod tpu_client;
|
||||
pub mod tpu_connection;
|
||||
pub mod udp_client;
|
|
@ -1,40 +0,0 @@
|
|||
//! Spinner creator
|
||||
|
||||
use {
|
||||
indicatif::{ProgressBar, ProgressStyle},
|
||||
std::time::Duration,
|
||||
};
|
||||
|
||||
pub(crate) fn new_progress_bar() -> ProgressBar {
|
||||
let progress_bar = ProgressBar::new(42);
|
||||
progress_bar.set_style(
|
||||
ProgressStyle::default_spinner()
|
||||
.template("{spinner:.green} {wide_msg}")
|
||||
.expect("ProgresStyle::template direct input to be correct"),
|
||||
);
|
||||
progress_bar.enable_steady_tick(Duration::from_millis(100));
|
||||
progress_bar
|
||||
}
|
||||
|
||||
pub(crate) fn set_message_for_confirmed_transactions(
|
||||
progress_bar: &ProgressBar,
|
||||
confirmed_transactions: u32,
|
||||
total_transactions: usize,
|
||||
block_height: Option<u64>,
|
||||
last_valid_block_height: u64,
|
||||
status: &str,
|
||||
) {
|
||||
progress_bar.set_message(format!(
|
||||
"{:>5.1}% | {:<40}{}",
|
||||
confirmed_transactions as f64 * 100. / total_transactions as f64,
|
||||
status,
|
||||
match block_height {
|
||||
Some(block_height) => format!(
|
||||
" [block height {}; re-sign in {} blocks]",
|
||||
block_height,
|
||||
last_valid_block_height.saturating_sub(block_height),
|
||||
),
|
||||
None => String::new(),
|
||||
},
|
||||
));
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
#![allow(clippy::integer_arithmetic)]
|
||||
use {
|
||||
crate::rpc_client::RpcClient,
|
||||
log::*,
|
||||
solana_measure::measure::Measure,
|
||||
solana_rpc_client::rpc_client::RpcClient,
|
||||
solana_sdk::{
|
||||
commitment_config::CommitmentConfig, signature::Signature, timing::timestamp,
|
||||
transaction::Transaction,
|
||||
|
|
|
@ -4649,53 +4649,15 @@ dependencies = [
|
|||
name = "solana-client"
|
||||
version = "1.12.0"
|
||||
dependencies = [
|
||||
"async-mutex",
|
||||
"async-trait",
|
||||
"base64 0.13.0",
|
||||
"bincode",
|
||||
"bs58",
|
||||
"bytes",
|
||||
"clap 2.33.3",
|
||||
"crossbeam-channel",
|
||||
"enum_dispatch",
|
||||
"futures 0.3.23",
|
||||
"futures-util",
|
||||
"indexmap",
|
||||
"indicatif",
|
||||
"itertools",
|
||||
"jsonrpc-core",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"quinn",
|
||||
"quinn-proto",
|
||||
"quinn-udp",
|
||||
"rand 0.7.3",
|
||||
"rand_chacha 0.2.2",
|
||||
"rayon",
|
||||
"reqwest",
|
||||
"rustls 0.20.6",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"solana-account-decoder",
|
||||
"solana-clap-utils",
|
||||
"solana-faucet",
|
||||
"solana-measure",
|
||||
"solana-metrics",
|
||||
"solana-net-utils",
|
||||
"solana-pubsub-client",
|
||||
"solana-rpc-client",
|
||||
"solana-rpc-client-api",
|
||||
"solana-rpc-client-nonce-utils",
|
||||
"solana-sdk 1.12.0",
|
||||
"solana-streamer",
|
||||
"solana-transaction-status",
|
||||
"solana-version",
|
||||
"solana-vote-program",
|
||||
"spl-token-2022",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tokio-tungstenite",
|
||||
"tungstenite",
|
||||
"url 2.2.2",
|
||||
"solana-thin-client",
|
||||
"solana-tpu-client",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -5312,6 +5274,29 @@ dependencies = [
|
|||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-pubsub-client"
|
||||
version = "1.12.0"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"futures-util",
|
||||
"log",
|
||||
"reqwest",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"solana-account-decoder",
|
||||
"solana-rpc-client-api",
|
||||
"solana-sdk 1.12.0",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tokio-tungstenite",
|
||||
"tungstenite",
|
||||
"url 2.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-rayon-threadlimit"
|
||||
version = "1.12.0"
|
||||
|
@ -5388,6 +5373,61 @@ dependencies = [
|
|||
"tokio-util 0.6.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-rpc-client"
|
||||
version = "1.12.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base64 0.13.0",
|
||||
"bincode",
|
||||
"bs58",
|
||||
"indicatif",
|
||||
"log",
|
||||
"reqwest",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"solana-account-decoder",
|
||||
"solana-rpc-client-api",
|
||||
"solana-sdk 1.12.0",
|
||||
"solana-transaction-status",
|
||||
"solana-version",
|
||||
"solana-vote-program",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-rpc-client-api"
|
||||
version = "1.12.0"
|
||||
dependencies = [
|
||||
"base64 0.13.0",
|
||||
"bs58",
|
||||
"jsonrpc-core",
|
||||
"reqwest",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"solana-account-decoder",
|
||||
"solana-sdk 1.12.0",
|
||||
"solana-transaction-status",
|
||||
"solana-version",
|
||||
"spl-token-2022",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-rpc-client-nonce-utils"
|
||||
version = "1.12.0"
|
||||
dependencies = [
|
||||
"clap 2.33.3",
|
||||
"solana-clap-utils",
|
||||
"solana-rpc-client",
|
||||
"solana-sdk 1.12.0",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-runtime"
|
||||
version = "1.12.0"
|
||||
|
@ -5719,6 +5759,51 @@ dependencies = [
|
|||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-thin-client"
|
||||
version = "1.12.0"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"log",
|
||||
"solana-rpc-client",
|
||||
"solana-rpc-client-api",
|
||||
"solana-sdk 1.12.0",
|
||||
"solana-tpu-client",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-tpu-client"
|
||||
version = "1.12.0"
|
||||
dependencies = [
|
||||
"async-mutex",
|
||||
"async-trait",
|
||||
"bincode",
|
||||
"enum_dispatch",
|
||||
"futures 0.3.23",
|
||||
"futures-util",
|
||||
"indexmap",
|
||||
"indicatif",
|
||||
"itertools",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"quinn",
|
||||
"quinn-proto",
|
||||
"quinn-udp",
|
||||
"rand 0.7.3",
|
||||
"rayon",
|
||||
"rustls 0.20.6",
|
||||
"solana-measure",
|
||||
"solana-metrics",
|
||||
"solana-net-utils",
|
||||
"solana-pubsub-client",
|
||||
"solana-rpc-client",
|
||||
"solana-rpc-client-api",
|
||||
"solana-sdk 1.12.0",
|
||||
"solana-streamer",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-transaction-status"
|
||||
version = "1.12.0"
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
[package]
|
||||
name = "solana-pubsub-client"
|
||||
version = "1.12.0"
|
||||
description = "Solana Pubsub Client"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
documentation = "https://docs.rs/solana-pubsub-client"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
crossbeam-channel = "0.5"
|
||||
futures-util = "0.3.21"
|
||||
log = "0.4.17"
|
||||
reqwest = { version = "0.11.11", default-features = false, features = ["blocking", "brotli", "deflate", "gzip", "rustls-tls", "json"] }
|
||||
semver = "1.0.13"
|
||||
serde = "1.0.143"
|
||||
serde_derive = "1.0.103"
|
||||
serde_json = "1.0.83"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.12.0" }
|
||||
solana-rpc-client-api = { path = "../rpc-client-api", version = "=1.12.0" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.12.0" }
|
||||
thiserror = "1.0"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
tokio-stream = "0.1.9"
|
||||
tokio-tungstenite = { version = "0.17.2", features = ["rustls-tls-webpki-roots"] }
|
||||
tungstenite = { version = "0.17.2", features = ["rustls-tls-webpki-roots"] }
|
||||
url = "2.2.2"
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
|
@ -0,0 +1,4 @@
|
|||
#![allow(clippy::integer_arithmetic)]
|
||||
|
||||
pub mod nonblocking;
|
||||
pub mod pubsub_client;
|
|
@ -0,0 +1 @@
|
|||
pub mod pubsub_client;
|
|
@ -1,17 +1,4 @@
|
|||
use {
|
||||
crate::{
|
||||
http_sender::RpcErrorObject,
|
||||
rpc_config::{
|
||||
RpcAccountInfoConfig, RpcBlockSubscribeConfig, RpcBlockSubscribeFilter,
|
||||
RpcProgramAccountsConfig, RpcSignatureSubscribeConfig, RpcTransactionLogsConfig,
|
||||
RpcTransactionLogsFilter,
|
||||
},
|
||||
rpc_filter::maybe_map_filters,
|
||||
rpc_response::{
|
||||
Response as RpcResponse, RpcBlockUpdate, RpcKeyedAccount, RpcLogsResponse,
|
||||
RpcSignatureResult, RpcVersionInfo, RpcVote, SlotInfo, SlotUpdate,
|
||||
},
|
||||
},
|
||||
futures_util::{
|
||||
future::{ready, BoxFuture, FutureExt},
|
||||
sink::SinkExt,
|
||||
|
@ -21,6 +8,19 @@ use {
|
|||
serde::de::DeserializeOwned,
|
||||
serde_json::{json, Map, Value},
|
||||
solana_account_decoder::UiAccount,
|
||||
solana_rpc_client_api::{
|
||||
config::{
|
||||
RpcAccountInfoConfig, RpcBlockSubscribeConfig, RpcBlockSubscribeFilter,
|
||||
RpcProgramAccountsConfig, RpcSignatureSubscribeConfig, RpcTransactionLogsConfig,
|
||||
RpcTransactionLogsFilter,
|
||||
},
|
||||
error_object::RpcErrorObject,
|
||||
filter::maybe_map_filters,
|
||||
response::{
|
||||
Response as RpcResponse, RpcBlockUpdate, RpcKeyedAccount, RpcLogsResponse,
|
||||
RpcSignatureResult, RpcVersionInfo, RpcVote, SlotInfo, SlotUpdate,
|
||||
},
|
||||
},
|
||||
solana_sdk::{clock::Slot, pubkey::Pubkey, signature::Signature},
|
||||
std::collections::BTreeMap,
|
||||
thiserror::Error,
|
|
@ -1,17 +1,5 @@
|
|||
pub use crate::nonblocking::pubsub_client::PubsubClientError;
|
||||
use {
|
||||
crate::{
|
||||
rpc_config::{
|
||||
RpcAccountInfoConfig, RpcBlockSubscribeConfig, RpcBlockSubscribeFilter,
|
||||
RpcProgramAccountsConfig, RpcSignatureSubscribeConfig, RpcTransactionLogsConfig,
|
||||
RpcTransactionLogsFilter,
|
||||
},
|
||||
rpc_filter,
|
||||
rpc_response::{
|
||||
Response as RpcResponse, RpcBlockUpdate, RpcKeyedAccount, RpcLogsResponse,
|
||||
RpcSignatureResult, RpcVote, SlotInfo, SlotUpdate,
|
||||
},
|
||||
},
|
||||
crossbeam_channel::{unbounded, Receiver, Sender},
|
||||
log::*,
|
||||
serde::de::DeserializeOwned,
|
||||
|
@ -21,6 +9,18 @@ use {
|
|||
Map, Value,
|
||||
},
|
||||
solana_account_decoder::UiAccount,
|
||||
solana_rpc_client_api::{
|
||||
config::{
|
||||
RpcAccountInfoConfig, RpcBlockSubscribeConfig, RpcBlockSubscribeFilter,
|
||||
RpcProgramAccountsConfig, RpcSignatureSubscribeConfig, RpcTransactionLogsConfig,
|
||||
RpcTransactionLogsFilter,
|
||||
},
|
||||
filter,
|
||||
response::{
|
||||
Response as RpcResponse, RpcBlockUpdate, RpcKeyedAccount, RpcLogsResponse,
|
||||
RpcSignatureResult, RpcVote, SlotInfo, SlotUpdate,
|
||||
},
|
||||
},
|
||||
solana_sdk::{clock::Slot, pubkey::Pubkey, signature::Signature},
|
||||
std::{
|
||||
marker::PhantomData,
|
||||
|
@ -396,7 +396,7 @@ impl PubsubClient {
|
|||
let node_version = PubsubProgramClientSubscription::get_version(&socket_clone).ok();
|
||||
// If node does not support the pubsub `getVersion` method, assume version is old
|
||||
// and filters should be mapped (node_version.is_none()).
|
||||
rpc_filter::maybe_map_filters(node_version, filters)
|
||||
filter::maybe_map_filters(node_version, filters)
|
||||
.map_err(PubsubClientError::RequestError)?;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
[package]
|
||||
name = "solana-rpc-client-api"
|
||||
version = "1.12.0"
|
||||
description = "Solana Client Common Utilities"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
documentation = "https://docs.rs/solana-rpc-client-api"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
base64 = "0.13.0"
|
||||
bs58 = "0.4.0"
|
||||
jsonrpc-core = "18.0.0"
|
||||
reqwest = { version = "0.11.11", default-features = false, features = ["blocking", "brotli", "deflate", "gzip", "rustls-tls", "json"] }
|
||||
semver = "1.0.13"
|
||||
serde = "1.0.143"
|
||||
serde_derive = "1.0.103"
|
||||
serde_json = "1.0.83"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.12.0" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.12.0" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.12.0" }
|
||||
solana-version = { path = "../version", version = "=1.12.0" }
|
||||
spl-token-2022 = { version = "=0.4.3", features = ["no-entrypoint"] }
|
||||
thiserror = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
|
@ -0,0 +1,186 @@
|
|||
pub use reqwest;
|
||||
use {
|
||||
crate::{request, response},
|
||||
solana_sdk::{
|
||||
signature::SignerError, transaction::TransactionError, transport::TransportError,
|
||||
},
|
||||
std::io,
|
||||
thiserror::Error as ThisError,
|
||||
};
|
||||
|
||||
#[derive(ThisError, Debug)]
|
||||
pub enum ErrorKind {
|
||||
#[error(transparent)]
|
||||
Io(#[from] io::Error),
|
||||
#[error(transparent)]
|
||||
Reqwest(#[from] reqwest::Error),
|
||||
#[error(transparent)]
|
||||
RpcError(#[from] request::RpcError),
|
||||
#[error(transparent)]
|
||||
SerdeJson(#[from] serde_json::error::Error),
|
||||
#[error(transparent)]
|
||||
SigningError(#[from] SignerError),
|
||||
#[error(transparent)]
|
||||
TransactionError(#[from] TransactionError),
|
||||
#[error("Custom: {0}")]
|
||||
Custom(String),
|
||||
}
|
||||
|
||||
impl ErrorKind {
|
||||
pub fn get_transaction_error(&self) -> Option<TransactionError> {
|
||||
match self {
|
||||
Self::RpcError(request::RpcError::RpcResponseError {
|
||||
data:
|
||||
request::RpcResponseErrorData::SendTransactionPreflightFailure(
|
||||
response::RpcSimulateTransactionResult {
|
||||
err: Some(tx_err), ..
|
||||
},
|
||||
),
|
||||
..
|
||||
}) => Some(tx_err.clone()),
|
||||
Self::TransactionError(tx_err) => Some(tx_err.clone()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TransportError> for ErrorKind {
|
||||
fn from(err: TransportError) -> Self {
|
||||
match err {
|
||||
TransportError::IoError(err) => Self::Io(err),
|
||||
TransportError::TransactionError(err) => Self::TransactionError(err),
|
||||
TransportError::Custom(err) => Self::Custom(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ErrorKind> for TransportError {
|
||||
fn from(client_error_kind: ErrorKind) -> Self {
|
||||
match client_error_kind {
|
||||
ErrorKind::Io(err) => Self::IoError(err),
|
||||
ErrorKind::TransactionError(err) => Self::TransactionError(err),
|
||||
ErrorKind::Reqwest(err) => Self::Custom(format!("{:?}", err)),
|
||||
ErrorKind::RpcError(err) => Self::Custom(format!("{:?}", err)),
|
||||
ErrorKind::SerdeJson(err) => Self::Custom(format!("{:?}", err)),
|
||||
ErrorKind::SigningError(err) => Self::Custom(format!("{:?}", err)),
|
||||
ErrorKind::Custom(err) => Self::Custom(format!("{:?}", err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(ThisError, Debug)]
|
||||
#[error("{kind}")]
|
||||
pub struct Error {
|
||||
pub request: Option<request::RpcRequest>,
|
||||
|
||||
#[source]
|
||||
pub kind: ErrorKind,
|
||||
}
|
||||
|
||||
impl Error {
|
||||
pub fn new_with_request(kind: ErrorKind, request: request::RpcRequest) -> Self {
|
||||
Self {
|
||||
request: Some(request),
|
||||
kind,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_with_request(self, request: request::RpcRequest) -> Self {
|
||||
Self {
|
||||
request: Some(request),
|
||||
..self
|
||||
}
|
||||
}
|
||||
|
||||
pub fn request(&self) -> Option<&request::RpcRequest> {
|
||||
self.request.as_ref()
|
||||
}
|
||||
|
||||
pub fn kind(&self) -> &ErrorKind {
|
||||
&self.kind
|
||||
}
|
||||
|
||||
pub fn get_transaction_error(&self) -> Option<TransactionError> {
|
||||
self.kind.get_transaction_error()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ErrorKind> for Error {
|
||||
fn from(kind: ErrorKind) -> Self {
|
||||
Self {
|
||||
request: None,
|
||||
kind,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TransportError> for Error {
|
||||
fn from(err: TransportError) -> Self {
|
||||
Self {
|
||||
request: None,
|
||||
kind: err.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Error> for TransportError {
|
||||
fn from(client_error: Error) -> Self {
|
||||
client_error.kind.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for Error {
|
||||
fn from(err: std::io::Error) -> Self {
|
||||
Self {
|
||||
request: None,
|
||||
kind: err.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<reqwest::Error> for Error {
|
||||
fn from(err: reqwest::Error) -> Self {
|
||||
Self {
|
||||
request: None,
|
||||
kind: err.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<request::RpcError> for Error {
|
||||
fn from(err: request::RpcError) -> Self {
|
||||
Self {
|
||||
request: None,
|
||||
kind: err.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<serde_json::error::Error> for Error {
|
||||
fn from(err: serde_json::error::Error) -> Self {
|
||||
Self {
|
||||
request: None,
|
||||
kind: err.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SignerError> for Error {
|
||||
fn from(err: SignerError) -> Self {
|
||||
Self {
|
||||
request: None,
|
||||
kind: err.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TransactionError> for Error {
|
||||
fn from(err: TransactionError) -> Self {
|
||||
Self {
|
||||
request: None,
|
||||
kind: err.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
|
@ -1,5 +1,5 @@
|
|||
use {
|
||||
crate::rpc_filter::RpcFilterType,
|
||||
crate::filter::RpcFilterType,
|
||||
solana_account_decoder::{UiAccountEncoding, UiDataSliceConfig},
|
||||
solana_sdk::{
|
||||
clock::{Epoch, Slot},
|
|
@ -1,6 +1,6 @@
|
|||
//! Implementation defined RPC server errors
|
||||
use {
|
||||
crate::rpc_response::RpcSimulateTransactionResult,
|
||||
crate::response::RpcSimulateTransactionResult,
|
||||
jsonrpc_core::{Error, ErrorCode},
|
||||
solana_sdk::clock::Slot,
|
||||
solana_transaction_status::EncodeError,
|
|
@ -1,6 +1,6 @@
|
|||
#![allow(deprecated)]
|
||||
use {
|
||||
crate::rpc_config::{
|
||||
crate::config::{
|
||||
EncodingConfig, RpcBlockConfig, RpcEncodingConfigWrapper, RpcTransactionConfig,
|
||||
},
|
||||
solana_sdk::{clock::Slot, commitment_config::CommitmentConfig},
|
|
@ -0,0 +1,5 @@
|
|||
#[derive(Deserialize, Debug)]
|
||||
pub struct RpcErrorObject {
|
||||
pub code: i64,
|
||||
pub message: String,
|
||||
}
|
|
@ -259,7 +259,7 @@ impl From<RpcMemcmp> for Memcmp {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn maybe_map_filters(
|
||||
pub fn maybe_map_filters(
|
||||
node_version: Option<semver::Version>,
|
||||
filters: &mut [RpcFilterType],
|
||||
) -> Result<(), String> {
|
|
@ -0,0 +1,13 @@
|
|||
#![allow(clippy::integer_arithmetic)]
|
||||
|
||||
pub mod client_error;
|
||||
pub mod config;
|
||||
pub mod custom_error;
|
||||
pub mod deprecated_config;
|
||||
pub mod error_object;
|
||||
pub mod filter;
|
||||
pub mod request;
|
||||
pub mod response;
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
|
@ -1,5 +1,5 @@
|
|||
use {
|
||||
crate::rpc_response::RpcSimulateTransactionResult,
|
||||
crate::response::RpcSimulateTransactionResult,
|
||||
serde_json::{json, Value},
|
||||
solana_sdk::{clock::Slot, pubkey::Pubkey},
|
||||
std::fmt,
|
||||
|
@ -208,7 +208,7 @@ pub const MAX_GET_SLOT_LEADERS: usize = 5000;
|
|||
pub const DELINQUENT_VALIDATOR_SLOT_DISTANCE: u64 = 128;
|
||||
|
||||
impl RpcRequest {
|
||||
pub(crate) fn build_request_json(self, id: u64, params: Value) -> Value {
|
||||
pub fn build_request_json(self, id: u64, params: Value) -> Value {
|
||||
let jsonrpc = "2.0";
|
||||
json!({
|
||||
"jsonrpc": jsonrpc,
|
||||
|
@ -274,7 +274,7 @@ pub enum TokenAccountsFilter {
|
|||
mod tests {
|
||||
use {
|
||||
super::*,
|
||||
crate::rpc_config::RpcTokenAccountsFilter,
|
||||
crate::config::RpcTokenAccountsFilter,
|
||||
solana_sdk::commitment_config::{CommitmentConfig, CommitmentLevel},
|
||||
};
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
[package]
|
||||
name = "solana-rpc-client-nonce-utils"
|
||||
version = "1.12.0"
|
||||
description = "Solana RPC Client Nonce Utilities"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
documentation = "https://docs.rs/solana-nonce-client"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
clap = "2.33.0"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.12.0" }
|
||||
solana-rpc-client = { path = "../rpc-client", version = "=1.12.0" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.12.0" }
|
||||
thiserror = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
anyhow = "1.0.58"
|
||||
futures = "0.3"
|
||||
serde_json = "1.0.83"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.12.0" }
|
||||
solana-rpc-client-api = { path = "../rpc-client-api", version = "=1.12.0" }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
|
@ -1,11 +1,11 @@
|
|||
use {
|
||||
crate::{nonce_utils, rpc_client::RpcClient},
|
||||
clap::ArgMatches,
|
||||
solana_clap_utils::{
|
||||
input_parsers::{pubkey_of, value_of},
|
||||
nonce::*,
|
||||
offline::*,
|
||||
},
|
||||
solana_rpc_client::rpc_client::RpcClient,
|
||||
solana_sdk::{
|
||||
commitment_config::CommitmentConfig, fee_calculator::FeeCalculator, hash::Hash,
|
||||
pubkey::Pubkey,
|
||||
|
@ -35,8 +35,8 @@ impl Source {
|
|||
}
|
||||
Self::NonceAccount(ref pubkey) => {
|
||||
#[allow(clippy::redundant_closure)]
|
||||
let data = nonce_utils::get_account_with_commitment(rpc_client, pubkey, commitment)
|
||||
.and_then(|ref a| nonce_utils::data_from_account(a))?;
|
||||
let data = crate::get_account_with_commitment(rpc_client, pubkey, commitment)
|
||||
.and_then(|ref a| crate::data_from_account(a))?;
|
||||
Ok((data.blockhash(), data.fee_calculator))
|
||||
}
|
||||
}
|
||||
|
@ -61,8 +61,8 @@ impl Source {
|
|||
Ok(res)
|
||||
}
|
||||
Self::NonceAccount(ref pubkey) => {
|
||||
let res = nonce_utils::get_account_with_commitment(rpc_client, pubkey, commitment)?;
|
||||
let res = nonce_utils::data_from_account(&res)?;
|
||||
let res = crate::get_account_with_commitment(rpc_client, pubkey, commitment)?;
|
||||
let res = crate::data_from_account(&res)?;
|
||||
Ok(Some(res)
|
||||
.filter(|d| d.blockhash() == *blockhash)
|
||||
.map(|d| d.fee_calculator))
|
||||
|
@ -82,8 +82,8 @@ impl Source {
|
|||
}
|
||||
Self::NonceAccount(ref pubkey) => {
|
||||
#[allow(clippy::redundant_closure)]
|
||||
let data = nonce_utils::get_account_with_commitment(rpc_client, pubkey, commitment)
|
||||
.and_then(|ref a| nonce_utils::data_from_account(a))?;
|
||||
let data = crate::get_account_with_commitment(rpc_client, pubkey, commitment)
|
||||
.and_then(|ref a| crate::data_from_account(a))?;
|
||||
Ok(data.blockhash())
|
||||
}
|
||||
}
|
||||
|
@ -99,8 +99,8 @@ impl Source {
|
|||
Self::Cluster => rpc_client.is_blockhash_valid(blockhash, commitment)?,
|
||||
Self::NonceAccount(ref pubkey) => {
|
||||
#[allow(clippy::redundant_closure)]
|
||||
let _ = nonce_utils::get_account_with_commitment(rpc_client, pubkey, commitment)
|
||||
.and_then(|ref a| nonce_utils::data_from_account(a))?;
|
||||
let _ = crate::get_account_with_commitment(rpc_client, pubkey, commitment)
|
||||
.and_then(|ref a| crate::data_from_account(a))?;
|
||||
true
|
||||
}
|
||||
})
|
||||
|
@ -185,14 +185,14 @@ impl Default for BlockhashQuery {
|
|||
mod tests {
|
||||
use {
|
||||
super::*,
|
||||
crate::{
|
||||
blockhash_query,
|
||||
rpc_request::RpcRequest,
|
||||
rpc_response::{Response, RpcFeeCalculator, RpcFees, RpcResponseContext},
|
||||
},
|
||||
crate::blockhash_query,
|
||||
clap::App,
|
||||
serde_json::{self, json},
|
||||
solana_account_decoder::{UiAccount, UiAccountEncoding},
|
||||
solana_rpc_client_api::{
|
||||
request::RpcRequest,
|
||||
response::{Response, RpcFeeCalculator, RpcFees, RpcResponseContext},
|
||||
},
|
||||
solana_sdk::{
|
||||
account::Account,
|
||||
hash::hash,
|
|
@ -1,10 +1,13 @@
|
|||
//! Durable transaction nonce helpers.
|
||||
|
||||
pub use crate::nonblocking::nonce_utils::{
|
||||
pub mod blockhash_query;
|
||||
pub mod nonblocking;
|
||||
|
||||
pub use crate::nonblocking::{
|
||||
account_identity_ok, data_from_account, data_from_state, state_from_account, Error,
|
||||
};
|
||||
use {
|
||||
crate::rpc_client::RpcClient,
|
||||
solana_rpc_client::rpc_client::RpcClient,
|
||||
solana_sdk::{account::Account, commitment_config::CommitmentConfig, pubkey::Pubkey},
|
||||
};
|
||||
|
|
@ -1,11 +1,12 @@
|
|||
use {
|
||||
crate::nonblocking::{nonce_utils, rpc_client::RpcClient},
|
||||
crate::nonblocking,
|
||||
clap::ArgMatches,
|
||||
solana_clap_utils::{
|
||||
input_parsers::{pubkey_of, value_of},
|
||||
nonce::*,
|
||||
offline::*,
|
||||
},
|
||||
solana_rpc_client::nonblocking::rpc_client::RpcClient,
|
||||
solana_sdk::{commitment_config::CommitmentConfig, hash::Hash, pubkey::Pubkey},
|
||||
};
|
||||
|
||||
|
@ -30,9 +31,9 @@ impl Source {
|
|||
}
|
||||
Self::NonceAccount(ref pubkey) => {
|
||||
#[allow(clippy::redundant_closure)]
|
||||
let data = nonce_utils::get_account_with_commitment(rpc_client, pubkey, commitment)
|
||||
let data = nonblocking::get_account_with_commitment(rpc_client, pubkey, commitment)
|
||||
.await
|
||||
.and_then(|ref a| nonce_utils::data_from_account(a))?;
|
||||
.and_then(|ref a| nonblocking::data_from_account(a))?;
|
||||
Ok(data.blockhash())
|
||||
}
|
||||
}
|
||||
|
@ -48,9 +49,9 @@ impl Source {
|
|||
Self::Cluster => rpc_client.is_blockhash_valid(blockhash, commitment).await?,
|
||||
Self::NonceAccount(ref pubkey) => {
|
||||
#[allow(clippy::redundant_closure)]
|
||||
let _ = nonce_utils::get_account_with_commitment(rpc_client, pubkey, commitment)
|
||||
let _ = nonblocking::get_account_with_commitment(rpc_client, pubkey, commitment)
|
||||
.await
|
||||
.and_then(|ref a| nonce_utils::data_from_account(a))?;
|
||||
.and_then(|ref a| nonblocking::data_from_account(a))?;
|
||||
true
|
||||
}
|
||||
})
|
||||
|
@ -115,14 +116,14 @@ impl Default for BlockhashQuery {
|
|||
mod tests {
|
||||
use {
|
||||
super::*,
|
||||
crate::{
|
||||
nonblocking::blockhash_query,
|
||||
rpc_request::RpcRequest,
|
||||
rpc_response::{Response, RpcBlockhash, RpcResponseContext},
|
||||
},
|
||||
crate::nonblocking::blockhash_query,
|
||||
clap::App,
|
||||
serde_json::{self, json},
|
||||
solana_account_decoder::{UiAccount, UiAccountEncoding},
|
||||
solana_rpc_client_api::{
|
||||
request::RpcRequest,
|
||||
response::{Response, RpcBlockhash, RpcResponseContext},
|
||||
},
|
||||
solana_sdk::{
|
||||
account::Account,
|
||||
fee_calculator::FeeCalculator,
|
|
@ -1,7 +1,9 @@
|
|||
//! Durable transaction nonce helpers.
|
||||
|
||||
pub mod blockhash_query;
|
||||
|
||||
use {
|
||||
crate::nonblocking::rpc_client::RpcClient,
|
||||
solana_rpc_client::nonblocking::rpc_client::RpcClient,
|
||||
solana_sdk::{
|
||||
account::{Account, ReadableAccount},
|
||||
account_utils::StateMut,
|
||||
|
@ -97,10 +99,8 @@ pub fn account_identity_ok<T: ReadableAccount>(account: &T) -> Result<(), Error>
|
|||
/// Determine if a nonce account is initialized:
|
||||
///
|
||||
/// ```no_run
|
||||
/// use solana_client::nonblocking::{
|
||||
/// rpc_client::RpcClient,
|
||||
/// nonce_utils,
|
||||
/// };
|
||||
/// use solana_rpc_client_nonce_utils::nonblocking;
|
||||
/// use solana_rpc_client::nonblocking::rpc_client::RpcClient;
|
||||
/// use solana_sdk::{
|
||||
/// nonce::State,
|
||||
/// pubkey::Pubkey,
|
||||
|
@ -116,7 +116,7 @@ pub fn account_identity_ok<T: ReadableAccount>(account: &T) -> Result<(), Error>
|
|||
/// // Sign the tx with nonce_account's `blockhash` instead of the
|
||||
/// // network's latest blockhash.
|
||||
/// let nonce_account = client.get_account(nonce_account_pubkey).await?;
|
||||
/// let nonce_state = nonce_utils::state_from_account(&nonce_account)?;
|
||||
/// let nonce_state = nonblocking::state_from_account(&nonce_account)?;
|
||||
///
|
||||
/// Ok(!matches!(nonce_state, State::Uninitialized))
|
||||
/// }
|
||||
|
@ -149,10 +149,8 @@ pub fn state_from_account<T: ReadableAccount + StateMut<Versions>>(
|
|||
/// Create and sign a transaction with a durable nonce:
|
||||
///
|
||||
/// ```no_run
|
||||
/// use solana_client::nonblocking::{
|
||||
/// rpc_client::RpcClient,
|
||||
/// nonce_utils,
|
||||
/// };
|
||||
/// use solana_rpc_client_nonce_utils::nonblocking;
|
||||
/// use solana_rpc_client::nonblocking::rpc_client::RpcClient;
|
||||
/// use solana_sdk::{
|
||||
/// message::Message,
|
||||
/// pubkey::Pubkey,
|
||||
|
@ -201,7 +199,7 @@ pub fn state_from_account<T: ReadableAccount + StateMut<Versions>>(
|
|||
/// // Sign the tx with nonce_account's `blockhash` instead of the
|
||||
/// // network's latest blockhash.
|
||||
/// let nonce_account = client.get_account(nonce_account_pubkey).await?;
|
||||
/// let nonce_data = nonce_utils::data_from_account(&nonce_account)?;
|
||||
/// let nonce_data = nonblocking::data_from_account(&nonce_account)?;
|
||||
/// let blockhash = nonce_data.blockhash();
|
||||
///
|
||||
/// tx.try_sign(&[payer], blockhash)?;
|
|
@ -0,0 +1,40 @@
|
|||
[package]
|
||||
name = "solana-rpc-client"
|
||||
version = "1.12.0"
|
||||
description = "Solana RPC Client"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
documentation = "https://docs.rs/solana-rpc-client"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
async-trait = "0.1.57"
|
||||
base64 = "0.13.0"
|
||||
bincode = "1.3.3"
|
||||
bs58 = "0.4.0"
|
||||
indicatif = "0.17.0"
|
||||
log = "0.4.17"
|
||||
reqwest = { version = "0.11.11", default-features = false, features = ["blocking", "brotli", "deflate", "gzip", "rustls-tls", "json"] }
|
||||
semver = "1.0.13"
|
||||
serde = "1.0.143"
|
||||
serde_derive = "1.0.103"
|
||||
serde_json = "1.0.83"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.12.0" }
|
||||
solana-rpc-client-api = { path = "../rpc-client-api", version = "=1.12.0" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.12.0" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.12.0" }
|
||||
solana-version = { path = "../version", version = "=1.12.0" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.12.0" }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
|
||||
[dev-dependencies]
|
||||
assert_matches = "1.5.0"
|
||||
crossbeam-channel = "0.5"
|
||||
futures = "0.3"
|
||||
jsonrpc-core = "18.0.0"
|
||||
jsonrpc-http-server = "18.0.0"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
|
@ -1,13 +1,7 @@
|
|||
//! Nonblocking [`RpcSender`] over HTTP.
|
||||
|
||||
use {
|
||||
crate::{
|
||||
client_error::Result,
|
||||
rpc_custom_error,
|
||||
rpc_request::{RpcError, RpcRequest, RpcResponseErrorData},
|
||||
rpc_response::RpcSimulateTransactionResult,
|
||||
rpc_sender::*,
|
||||
},
|
||||
crate::rpc_sender::*,
|
||||
async_trait::async_trait,
|
||||
log::*,
|
||||
reqwest::{
|
||||
|
@ -15,6 +9,13 @@ use {
|
|||
header::{self, CONTENT_TYPE, RETRY_AFTER},
|
||||
StatusCode,
|
||||
},
|
||||
solana_rpc_client_api::{
|
||||
client_error::Result,
|
||||
custom_error,
|
||||
error_object::RpcErrorObject,
|
||||
request::{RpcError, RpcRequest, RpcResponseErrorData},
|
||||
response::RpcSimulateTransactionResult,
|
||||
},
|
||||
std::{
|
||||
sync::{
|
||||
atomic::{AtomicU64, Ordering},
|
||||
|
@ -72,12 +73,6 @@ impl HttpSender {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub(crate) struct RpcErrorObject {
|
||||
pub code: i64,
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
struct StatsUpdater<'a> {
|
||||
stats: &'a RwLock<RpcTransportStats>,
|
||||
request_start_time: Instant,
|
||||
|
@ -169,7 +164,7 @@ impl RpcSender for HttpSender {
|
|||
return match serde_json::from_value::<RpcErrorObject>(json["error"].clone()) {
|
||||
Ok(rpc_error_object) => {
|
||||
let data = match rpc_error_object.code {
|
||||
rpc_custom_error::JSON_RPC_SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE => {
|
||||
custom_error::JSON_RPC_SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE => {
|
||||
match serde_json::from_value::<RpcSimulateTransactionResult>(json["error"]["data"].clone()) {
|
||||
Ok(data) => RpcResponseErrorData::SendTransactionPreflightFailure(data),
|
||||
Err(err) => {
|
||||
|
@ -178,9 +173,9 @@ impl RpcSender for HttpSender {
|
|||
}
|
||||
}
|
||||
},
|
||||
rpc_custom_error::JSON_RPC_SERVER_ERROR_NODE_UNHEALTHY => {
|
||||
match serde_json::from_value::<rpc_custom_error::NodeUnhealthyErrorData>(json["error"]["data"].clone()) {
|
||||
Ok(rpc_custom_error::NodeUnhealthyErrorData {num_slots_behind}) => RpcResponseErrorData::NodeUnhealthy {num_slots_behind},
|
||||
custom_error::JSON_RPC_SERVER_ERROR_NODE_UNHEALTHY => {
|
||||
match serde_json::from_value::<custom_error::NodeUnhealthyErrorData>(json["error"]["data"].clone()) {
|
||||
Ok(custom_error::NodeUnhealthyErrorData {num_slots_behind}) => RpcResponseErrorData::NodeUnhealthy {num_slots_behind},
|
||||
Err(_err) => {
|
||||
RpcResponseErrorData::Empty
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
#![allow(clippy::integer_arithmetic)]
|
||||
|
||||
pub mod http_sender;
|
||||
pub mod mock_sender;
|
||||
pub mod nonblocking;
|
||||
pub mod rpc_client;
|
||||
pub mod rpc_sender;
|
||||
pub mod spinner;
|
||||
|
||||
pub mod mock_sender_for_cli {
|
||||
/// Magic `SIGNATURE` value used by `solana-cli` unit tests.
|
||||
/// Please don't use this constant.
|
||||
pub const SIGNATURE: &str =
|
||||
"43yNSFC6fYTuPgTNFFhF4axw7AfWxB2BPdurme8yrsWEYwm8299xh8n6TAHjGymiSub1XtyxTNyd9GBfY2hxoBw8";
|
||||
}
|
|
@ -1,11 +1,15 @@
|
|||
//! A nonblocking [`RpcSender`] used for unit testing [`RpcClient`](crate::rpc_client::RpcClient).
|
||||
|
||||
use {
|
||||
crate::{
|
||||
crate::rpc_sender::*,
|
||||
async_trait::async_trait,
|
||||
serde_json::{json, Number, Value},
|
||||
solana_account_decoder::{UiAccount, UiAccountEncoding},
|
||||
solana_rpc_client_api::{
|
||||
client_error::Result,
|
||||
rpc_config::RpcBlockProductionConfig,
|
||||
rpc_request::RpcRequest,
|
||||
rpc_response::{
|
||||
config::RpcBlockProductionConfig,
|
||||
request::RpcRequest,
|
||||
response::{
|
||||
Response, RpcAccountBalance, RpcBlockProduction, RpcBlockProductionRange, RpcBlockhash,
|
||||
RpcConfirmedTransactionStatusWithSignature, RpcContactInfo, RpcFees, RpcIdentity,
|
||||
RpcInflationGovernor, RpcInflationRate, RpcInflationReward, RpcKeyedAccount,
|
||||
|
@ -13,11 +17,7 @@ use {
|
|||
RpcStakeActivation, RpcSupply, RpcVersionInfo, RpcVoteAccountInfo,
|
||||
RpcVoteAccountStatus, StakeActivationState,
|
||||
},
|
||||
rpc_sender::*,
|
||||
},
|
||||
async_trait::async_trait,
|
||||
serde_json::{json, Number, Value},
|
||||
solana_account_decoder::{UiAccount, UiAccountEncoding},
|
||||
solana_sdk::{
|
||||
account::Account,
|
||||
clock::{Slot, UnixTimestamp},
|
|
@ -0,0 +1 @@
|
|||
pub mod rpc_client;
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
|||
//! A transport for RPC calls.
|
||||
use {
|
||||
crate::{client_error::Result, rpc_request::RpcRequest},
|
||||
async_trait::async_trait,
|
||||
solana_rpc_client_api::{client_error::Result, request::RpcRequest},
|
||||
std::time::Duration,
|
||||
};
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
//! Spinner creator
|
||||
|
||||
use {
|
||||
indicatif::{ProgressBar, ProgressStyle},
|
||||
std::time::Duration,
|
||||
};
|
||||
|
||||
pub fn new_progress_bar() -> ProgressBar {
|
||||
let progress_bar = ProgressBar::new(42);
|
||||
progress_bar.set_style(
|
||||
ProgressStyle::default_spinner()
|
||||
.template("{spinner:.green} {wide_msg}")
|
||||
.expect("ProgresStyle::template direct input to be correct"),
|
||||
);
|
||||
progress_bar.enable_steady_tick(Duration::from_millis(100));
|
||||
progress_bar
|
||||
}
|
|
@ -4,6 +4,7 @@ pub mod max_slots;
|
|||
pub mod optimistically_confirmed_bank_tracker;
|
||||
pub mod parsed_token_accounts;
|
||||
pub mod rpc;
|
||||
mod rpc_cache;
|
||||
pub mod rpc_completed_slots_service;
|
||||
pub mod rpc_health;
|
||||
pub mod rpc_pubsub;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
use {
|
||||
crate::{
|
||||
max_slots::MaxSlots, optimistically_confirmed_bank_tracker::OptimisticallyConfirmedBank,
|
||||
parsed_token_accounts::*, rpc_health::*,
|
||||
parsed_token_accounts::*, rpc_cache::LargestAccountsCache, rpc_health::*,
|
||||
},
|
||||
bincode::{config::Options, serialize},
|
||||
crossbeam_channel::{unbounded, Receiver, Sender},
|
||||
|
@ -16,7 +16,6 @@ use {
|
|||
},
|
||||
solana_client::{
|
||||
connection_cache::ConnectionCache,
|
||||
rpc_cache::LargestAccountsCache,
|
||||
rpc_config::*,
|
||||
rpc_custom_error::RpcCustomError,
|
||||
rpc_deprecated_config::*,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use {
|
||||
crate::{rpc_config::RpcLargestAccountsFilter, rpc_response::RpcAccountBalance},
|
||||
solana_client::{rpc_config::RpcLargestAccountsFilter, rpc_response::RpcAccountBalance},
|
||||
std::{
|
||||
collections::HashMap,
|
||||
time::{Duration, SystemTime},
|
||||
|
@ -20,14 +20,14 @@ struct LargestAccountsCacheValue {
|
|||
}
|
||||
|
||||
impl LargestAccountsCache {
|
||||
pub fn new(duration: u64) -> Self {
|
||||
pub(crate) fn new(duration: u64) -> Self {
|
||||
Self {
|
||||
duration,
|
||||
cache: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_largest_accounts(
|
||||
pub(crate) fn get_largest_accounts(
|
||||
&self,
|
||||
filter: &Option<RpcLargestAccountsFilter>,
|
||||
) -> Option<(u64, Vec<RpcAccountBalance>)> {
|
||||
|
@ -41,7 +41,7 @@ impl LargestAccountsCache {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn set_largest_accounts(
|
||||
pub(crate) fn set_largest_accounts(
|
||||
&mut self,
|
||||
filter: &Option<RpcLargestAccountsFilter>,
|
||||
slot: u64,
|
|
@ -9,6 +9,7 @@ use {
|
|||
rpc_accounts::*, rpc_bank::*, rpc_deprecated_v1_7::*, rpc_deprecated_v1_9::*,
|
||||
rpc_full::*, rpc_minimal::*, rpc_obsolete_v1_7::*, *,
|
||||
},
|
||||
rpc_cache::LargestAccountsCache,
|
||||
rpc_health::*,
|
||||
},
|
||||
crossbeam_channel::unbounded,
|
||||
|
@ -18,7 +19,7 @@ use {
|
|||
RequestMiddlewareAction, ServerBuilder,
|
||||
},
|
||||
regex::Regex,
|
||||
solana_client::{connection_cache::ConnectionCache, rpc_cache::LargestAccountsCache},
|
||||
solana_client::connection_cache::ConnectionCache,
|
||||
solana_gossip::cluster_info::ClusterInfo,
|
||||
solana_ledger::{
|
||||
bigtable_upload::ConfirmedBlockUploadConfig,
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
[package]
|
||||
name = "solana-thin-client"
|
||||
version = "1.12.0"
|
||||
description = "Solana Thin Client"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
documentation = "https://docs.rs/solana-thin-client"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
bincode = "1.3.3"
|
||||
log = "0.4.17"
|
||||
solana-rpc-client = { path = "../rpc-client", version = "=1.12.0" }
|
||||
solana-rpc-client-api = { path = "../rpc-client-api", version = "=1.12.0" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.12.0" }
|
||||
solana-tpu-client = { path = "../tpu-client", version = "=1.12.0" }
|
||||
|
||||
[dev-dependencies]
|
||||
rayon = "1.5.3"
|
||||
solana-logger = { path = "../logger", version = "=1.12.0" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
|
@ -0,0 +1,3 @@
|
|||
#![allow(clippy::integer_arithmetic)]
|
||||
|
||||
pub mod thin_client;
|
|
@ -4,12 +4,9 @@
|
|||
//! unstable and may change in future releases.
|
||||
|
||||
use {
|
||||
crate::{
|
||||
connection_cache::ConnectionCache, rpc_client::RpcClient,
|
||||
rpc_config::RpcProgramAccountsConfig, rpc_response::Response,
|
||||
tpu_connection::TpuConnection,
|
||||
},
|
||||
log::*,
|
||||
solana_rpc_client::rpc_client::RpcClient,
|
||||
solana_rpc_client_api::{config::RpcProgramAccountsConfig, response::Response},
|
||||
solana_sdk::{
|
||||
account::Account,
|
||||
client::{AsyncClient, Client, SyncClient},
|
||||
|
@ -28,6 +25,7 @@ use {
|
|||
transaction::{self, Transaction, VersionedTransaction},
|
||||
transport::Result as TransportResult,
|
||||
},
|
||||
solana_tpu_client::{connection_cache::ConnectionCache, tpu_connection::TpuConnection},
|
||||
std::{
|
||||
io,
|
||||
net::SocketAddr,
|
|
@ -0,0 +1,2 @@
|
|||
/target/
|
||||
/farf/
|
|
@ -0,0 +1,48 @@
|
|||
[package]
|
||||
name = "solana-tpu-client"
|
||||
version = "1.12.0"
|
||||
description = "Solana TPU Client"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
documentation = "https://docs.rs/solana-tpu-client"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
async-mutex = "1.4.0"
|
||||
async-trait = "0.1.57"
|
||||
bincode = "1.3.3"
|
||||
enum_dispatch = "0.3.8"
|
||||
futures = "0.3"
|
||||
futures-util = "0.3.21"
|
||||
indexmap = "1.9.1"
|
||||
indicatif = "0.17.0"
|
||||
itertools = "0.10.2"
|
||||
lazy_static = "1.4.0"
|
||||
log = "0.4.17"
|
||||
quinn = "0.8.4"
|
||||
quinn-proto = "0.8.4"
|
||||
quinn-udp = "0.1.3"
|
||||
rand = "0.7.0"
|
||||
rayon = "1.5.3"
|
||||
rustls = { version = "0.20.6", features = ["dangerous_configuration"] }
|
||||
solana-measure = { path = "../measure", version = "=1.12.0" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.12.0" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.12.0" }
|
||||
solana-pubsub-client = { path = "../pubsub-client", version = "=1.12.0" }
|
||||
solana-rpc-client = { path = "../rpc-client", version = "=1.12.0" }
|
||||
solana-rpc-client-api = { path = "../rpc-client-api", version = "=1.12.0" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.12.0" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.12.0" }
|
||||
thiserror = "1.0"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
|
||||
[dev-dependencies]
|
||||
crossbeam-channel = "0.5"
|
||||
rand_chacha = "0.2.2"
|
||||
solana-logger = { path = "../logger", version = "=1.12.0" }
|
||||
solana-perf = { path = "../perf", version = "=1.12.0" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
|
@ -0,0 +1,11 @@
|
|||
#![allow(clippy::integer_arithmetic)]
|
||||
|
||||
pub mod connection_cache;
|
||||
pub mod nonblocking;
|
||||
pub mod quic_client;
|
||||
pub mod tpu_client;
|
||||
pub mod tpu_connection;
|
||||
pub mod udp_client;
|
||||
|
||||
#[macro_use]
|
||||
extern crate solana_metrics;
|
|
@ -0,0 +1,4 @@
|
|||
pub mod quic_client;
|
||||
pub mod tpu_client;
|
||||
pub mod tpu_connection;
|
||||
pub mod udp_client;
|
|
@ -3,8 +3,8 @@
|
|||
//! server's flow control.
|
||||
use {
|
||||
crate::{
|
||||
client_error::ClientErrorKind, connection_cache::ConnectionCacheStats,
|
||||
nonblocking::tpu_connection::TpuConnection, tpu_connection::ClientStats,
|
||||
connection_cache::ConnectionCacheStats, nonblocking::tpu_connection::TpuConnection,
|
||||
tpu_connection::ClientStats,
|
||||
},
|
||||
async_mutex::Mutex,
|
||||
async_trait::async_trait,
|
||||
|
@ -17,6 +17,7 @@ use {
|
|||
},
|
||||
solana_measure::measure::Measure,
|
||||
solana_net_utils::VALIDATOR_PORT_RANGE,
|
||||
solana_rpc_client_api::client_error::ErrorKind as ClientErrorKind,
|
||||
solana_sdk::{
|
||||
quic::{
|
||||
QUIC_CONNECTION_HANDSHAKE_TIMEOUT_MS, QUIC_KEEP_ALIVE_MS, QUIC_MAX_TIMEOUT_MS,
|
||||
|
@ -82,6 +83,12 @@ pub enum QuicError {
|
|||
ConnectError(#[from] ConnectError),
|
||||
}
|
||||
|
||||
impl From<QuicError> for ClientErrorKind {
|
||||
fn from(quic_error: QuicError) -> Self {
|
||||
Self::Custom(format!("{:?}", quic_error))
|
||||
}
|
||||
}
|
||||
|
||||
impl QuicLazyInitializedEndpoint {
|
||||
pub fn new(client_certificate: Arc<QuicClientCertificate>) -> Self {
|
||||
Self {
|
||||
|
@ -439,7 +446,8 @@ impl QuicClient {
|
|||
T: AsRef<[u8]>,
|
||||
{
|
||||
self._send_buffer(data.as_ref(), stats, connection_stats)
|
||||
.await?;
|
||||
.await
|
||||
.map_err(Into::<ClientErrorKind>::into)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -483,7 +491,8 @@ impl QuicClient {
|
|||
}
|
||||
let connection = self
|
||||
._send_buffer(buffers[0].as_ref(), stats, connection_stats)
|
||||
.await?;
|
||||
.await
|
||||
.map_err(Into::<ClientErrorKind>::into)?;
|
||||
|
||||
// Used to avoid dereferencing the Arc multiple times below
|
||||
// by just getting a reference to the NewConnection once
|
||||
|
@ -504,7 +513,10 @@ impl QuicClient {
|
|||
.collect();
|
||||
|
||||
for f in futures {
|
||||
f.await.into_iter().try_for_each(|res| res)?;
|
||||
f.await
|
||||
.into_iter()
|
||||
.try_for_each(|res| res)
|
||||
.map_err(Into::<ClientErrorKind>::into)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
|
@ -1,15 +1,7 @@
|
|||
use {
|
||||
crate::{
|
||||
client_error::{ClientError, Result as ClientResult},
|
||||
connection_cache::ConnectionCache,
|
||||
nonblocking::{
|
||||
pubsub_client::{PubsubClient, PubsubClientError},
|
||||
rpc_client::RpcClient,
|
||||
tpu_connection::TpuConnection,
|
||||
},
|
||||
rpc_request::MAX_GET_SIGNATURE_STATUSES_QUERY_ITEMS,
|
||||
rpc_response::{RpcContactInfo, SlotUpdate},
|
||||
spinner,
|
||||
nonblocking::tpu_connection::TpuConnection,
|
||||
tpu_client::{
|
||||
RecentLeaderSlots, TpuClientConfig, MAX_FANOUT_SLOTS, SEND_TRANSACTION_INTERVAL,
|
||||
TRANSACTION_RESEND_INTERVAL,
|
||||
|
@ -17,7 +9,15 @@ use {
|
|||
},
|
||||
bincode::serialize,
|
||||
futures_util::{future::join_all, stream::StreamExt},
|
||||
indicatif::ProgressBar,
|
||||
log::*,
|
||||
solana_pubsub_client::nonblocking::pubsub_client::{PubsubClient, PubsubClientError},
|
||||
solana_rpc_client::{nonblocking::rpc_client::RpcClient, spinner},
|
||||
solana_rpc_client_api::{
|
||||
client_error::{Error as ClientError, Result as ClientResult},
|
||||
request::MAX_GET_SIGNATURE_STATUSES_QUERY_ITEMS,
|
||||
response::{RpcContactInfo, SlotUpdate},
|
||||
},
|
||||
solana_sdk::{
|
||||
clock::Slot,
|
||||
commitment_config::CommitmentConfig,
|
||||
|
@ -366,7 +366,7 @@ impl TpuClient {
|
|||
if !self.send_transaction(transaction).await {
|
||||
let _result = self.rpc_client.send_transaction(transaction).await.ok();
|
||||
}
|
||||
spinner::set_message_for_confirmed_transactions(
|
||||
set_message_for_confirmed_transactions(
|
||||
&progress_bar,
|
||||
confirmed_transactions,
|
||||
total_transactions,
|
||||
|
@ -381,7 +381,7 @@ impl TpuClient {
|
|||
|
||||
// Wait for the next block before checking for transaction statuses
|
||||
let mut block_height_refreshes = 10;
|
||||
spinner::set_message_for_confirmed_transactions(
|
||||
set_message_for_confirmed_transactions(
|
||||
&progress_bar,
|
||||
confirmed_transactions,
|
||||
total_transactions,
|
||||
|
@ -430,7 +430,7 @@ impl TpuClient {
|
|||
}
|
||||
}
|
||||
}
|
||||
spinner::set_message_for_confirmed_transactions(
|
||||
set_message_for_confirmed_transactions(
|
||||
&progress_bar,
|
||||
confirmed_transactions,
|
||||
total_transactions,
|
||||
|
@ -666,3 +666,26 @@ async fn maybe_fetch_cache_info(
|
|||
maybe_slot_leaders,
|
||||
}
|
||||
}
|
||||
|
||||
fn set_message_for_confirmed_transactions(
|
||||
progress_bar: &ProgressBar,
|
||||
confirmed_transactions: u32,
|
||||
total_transactions: usize,
|
||||
block_height: Option<u64>,
|
||||
last_valid_block_height: u64,
|
||||
status: &str,
|
||||
) {
|
||||
progress_bar.set_message(format!(
|
||||
"{:>5.1}% | {:<40}{}",
|
||||
confirmed_transactions as f64 * 100. / total_transactions as f64,
|
||||
status,
|
||||
match block_height {
|
||||
Some(block_height) => format!(
|
||||
" [block height {}; re-sign in {} blocks]",
|
||||
block_height,
|
||||
last_valid_block_height.saturating_sub(block_height),
|
||||
),
|
||||
None => String::new(),
|
||||
},
|
||||
));
|
||||
}
|
|
@ -2,8 +2,9 @@ pub use crate::nonblocking::tpu_client::TpuSenderError;
|
|||
use {
|
||||
crate::{
|
||||
connection_cache::ConnectionCache,
|
||||
nonblocking::tpu_client::TpuClient as NonblockingTpuClient, rpc_client::RpcClient,
|
||||
nonblocking::tpu_client::TpuClient as NonblockingTpuClient,
|
||||
},
|
||||
solana_rpc_client::rpc_client::RpcClient,
|
||||
solana_sdk::{
|
||||
clock::Slot,
|
||||
message::Message,
|
|
@ -2,13 +2,13 @@
|
|||
mod tests {
|
||||
use {
|
||||
crossbeam_channel::{unbounded, Receiver},
|
||||
solana_client::{
|
||||
connection_cache::ConnectionCacheStats,
|
||||
nonblocking::quic_client::QuicLazyInitializedEndpoint,
|
||||
},
|
||||
solana_perf::packet::PacketBatch,
|
||||
solana_sdk::{packet::PACKET_DATA_SIZE, signature::Keypair},
|
||||
solana_streamer::{quic::StreamStats, streamer::StakedNodes},
|
||||
solana_tpu_client::{
|
||||
connection_cache::ConnectionCacheStats,
|
||||
nonblocking::quic_client::QuicLazyInitializedEndpoint,
|
||||
},
|
||||
std::{
|
||||
net::{IpAddr, SocketAddr, UdpSocket},
|
||||
sync::{
|
||||
|
@ -62,7 +62,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_quic_client_multiple_writes() {
|
||||
use solana_client::{quic_client::QuicTpuConnection, tpu_connection::TpuConnection};
|
||||
use solana_tpu_client::{quic_client::QuicTpuConnection, tpu_connection::TpuConnection};
|
||||
solana_logger::setup();
|
||||
let (sender, receiver) = unbounded();
|
||||
let staked_nodes = Arc::new(RwLock::new(StakedNodes::default()));
|
||||
|
@ -105,7 +105,7 @@ mod tests {
|
|||
|
||||
#[tokio::test]
|
||||
async fn test_nonblocking_quic_client_multiple_writes() {
|
||||
use solana_client::nonblocking::{
|
||||
use solana_tpu_client::nonblocking::{
|
||||
quic_client::QuicTpuConnection, tpu_connection::TpuConnection,
|
||||
};
|
||||
solana_logger::setup();
|
Loading…
Reference in New Issue