Compare commits
24 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
f2561ea547 | ||
|
b98e133f2d | ||
|
25274e8a33 | ||
|
3bf00e4af5 | ||
|
c289cd2a4b | ||
|
84ac4ff57f | ||
|
58ef6b31f9 | ||
|
304cd65ecb | ||
|
3bee921088 | ||
|
35d4f390ad | ||
|
785481ace4 | ||
|
0e6ba29859 | ||
|
ec1d06240c | ||
|
32dea4427b | ||
|
9aa95870fa | ||
|
d48e9b3a7b | ||
|
95a279f310 | ||
|
1700820583 | ||
|
0745738eb1 | ||
|
d02bf12976 | ||
|
587d45769d | ||
|
f495024591 | ||
|
28a681a7bf | ||
|
15acdcc19a |
343
Cargo.lock
generated
343
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -88,3 +88,6 @@ members = [
|
||||
exclude = [
|
||||
"programs/bpf",
|
||||
]
|
||||
|
||||
# This prevents a Travis CI error when building for Windows.
|
||||
resolver = "2"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-account-decoder"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana account decoder"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -19,9 +19,9 @@ lazy_static = "1.4.0"
|
||||
serde = "1.0.136"
|
||||
serde_derive = "1.0.103"
|
||||
serde_json = "1.0.79"
|
||||
solana-config-program = { path = "../programs/config", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.10.8" }
|
||||
solana-config-program = { path = "../programs/config", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.10.9" }
|
||||
spl-token = { version = "=3.2.0", features = ["no-entrypoint"] }
|
||||
thiserror = "1.0"
|
||||
zstd = "0.11.1"
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-accounts-bench"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -12,11 +12,11 @@ publish = false
|
||||
clap = "2.33.1"
|
||||
log = "0.4.14"
|
||||
rayon = "1.5.1"
|
||||
solana-logger = { path = "../logger", version = "=1.10.8" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.8" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-version = { path = "../version", version = "=1.10.8" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.9" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
solana-version = { path = "../version", version = "=1.10.9" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-accounts-cluster-bench"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -13,25 +13,25 @@ clap = "2.33.1"
|
||||
log = "0.4.14"
|
||||
rand = "0.7.0"
|
||||
rayon = "1.5.1"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.10.8" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.10.8" }
|
||||
solana-client = { path = "../client", version = "=1.10.8" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.10.8" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.10.8" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.8" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.8" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.10.8" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.10.8" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.10.8" }
|
||||
solana-version = { path = "../version", version = "=1.10.8" }
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.10.9" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.10.9" }
|
||||
solana-client = { path = "../client", version = "=1.10.9" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.10.9" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.10.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.9" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.9" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.10.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.10.9" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.10.9" }
|
||||
solana-version = { path = "../version", version = "=1.10.9" }
|
||||
spl-token = { version = "=3.2.0", features = ["no-entrypoint"] }
|
||||
|
||||
[dev-dependencies]
|
||||
solana-core = { path = "../core", version = "=1.10.8" }
|
||||
solana-local-cluster = { path = "../local-cluster", version = "=1.10.8" }
|
||||
solana-test-validator = { path = "../test-validator", version = "=1.10.8" }
|
||||
solana-core = { path = "../core", version = "=1.10.9" }
|
||||
solana-local-cluster = { path = "../local-cluster", version = "=1.10.9" }
|
||||
solana-test-validator = { path = "../test-validator", version = "=1.10.9" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-banking-bench"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -14,17 +14,17 @@ crossbeam-channel = "0.5"
|
||||
log = "0.4.14"
|
||||
rand = "0.7.0"
|
||||
rayon = "1.5.1"
|
||||
solana-core = { path = "../core", version = "=1.10.8" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.10.8" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.10.8" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.8" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.8" }
|
||||
solana-perf = { path = "../perf", version = "=1.10.8" }
|
||||
solana-poh = { path = "../poh", version = "=1.10.8" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.10.8" }
|
||||
solana-version = { path = "../version", version = "=1.10.8" }
|
||||
solana-core = { path = "../core", version = "=1.10.9" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.10.9" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.10.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.9" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.9" }
|
||||
solana-perf = { path = "../perf", version = "=1.10.9" }
|
||||
solana-poh = { path = "../poh", version = "=1.10.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.10.9" }
|
||||
solana-version = { path = "../version", version = "=1.10.9" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-banks-client"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana banks client"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,17 +12,17 @@ edition = "2021"
|
||||
[dependencies]
|
||||
borsh = "0.9.3"
|
||||
futures = "0.3"
|
||||
solana-banks-interface = { path = "../banks-interface", version = "=1.10.8" }
|
||||
solana-program = { path = "../sdk/program", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-banks-interface = { path = "../banks-interface", version = "=1.10.9" }
|
||||
solana-program = { path = "../sdk/program", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
tarpc = { version = "0.27.2", features = ["full"] }
|
||||
thiserror = "1.0"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
tokio-serde = { version = "0.8", features = ["bincode"] }
|
||||
|
||||
[dev-dependencies]
|
||||
solana-banks-server = { path = "../banks-server", version = "=1.10.8" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.8" }
|
||||
solana-banks-server = { path = "../banks-server", version = "=1.10.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.9" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-banks-interface"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana banks RPC interface"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -11,7 +11,7 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1.0.136", features = ["derive"] }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
tarpc = { version = "0.27.2", features = ["full"] }
|
||||
|
||||
[lib]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-banks-server"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana banks server"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -13,10 +13,10 @@ edition = "2021"
|
||||
bincode = "1.3.3"
|
||||
crossbeam-channel = "0.5"
|
||||
futures = "0.3"
|
||||
solana-banks-interface = { path = "../banks-interface", version = "=1.10.8" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-send-transaction-service = { path = "../send-transaction-service", version = "=1.10.8" }
|
||||
solana-banks-interface = { path = "../banks-interface", version = "=1.10.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
solana-send-transaction-service = { path = "../send-transaction-service", version = "=1.10.9" }
|
||||
tarpc = { version = "0.27.2", features = ["full"] }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
tokio-serde = { version = "0.8", features = ["bincode"] }
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-bench-streamer"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -11,9 +11,9 @@ publish = false
|
||||
[dependencies]
|
||||
clap = "2.33.1"
|
||||
crossbeam-channel = "0.5"
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.10.8" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.10.8" }
|
||||
solana-version = { path = "../version", version = "=1.10.8" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.10.9" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.10.9" }
|
||||
solana-version = { path = "../version", version = "=1.10.9" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-bench-tps"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -15,23 +15,28 @@ log = "0.4.14"
|
||||
rayon = "1.5.1"
|
||||
serde_json = "1.0.79"
|
||||
serde_yaml = "0.8.23"
|
||||
solana-client = { path = "../client", version = "=1.10.8" }
|
||||
solana-core = { path = "../core", version = "=1.10.8" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.10.8" }
|
||||
solana-genesis = { path = "../genesis", version = "=1.10.8" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.10.8" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.8" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.8" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.10.8" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.10.8" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.10.8" }
|
||||
solana-version = { path = "../version", version = "=1.10.8" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.10.9" }
|
||||
solana-cli-config = { path = "../cli-config", version = "=1.10.9" }
|
||||
solana-client = { path = "../client", version = "=1.10.9" }
|
||||
solana-core = { path = "../core", version = "=1.10.9" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.10.9" }
|
||||
solana-genesis = { path = "../genesis", version = "=1.10.9" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.10.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.9" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.9" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.10.9" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.10.9" }
|
||||
solana-rpc = { path = "../rpc", version = "=1.10.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.10.9" }
|
||||
solana-version = { path = "../version", version = "=1.10.9" }
|
||||
thiserror = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
serial_test = "0.6.0"
|
||||
solana-local-cluster = { path = "../local-cluster", version = "=1.10.8" }
|
||||
solana-local-cluster = { path = "../local-cluster", version = "=1.10.9" }
|
||||
solana-test-validator = { path = "../test-validator", version = "=1.10.9" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -1,19 +1,21 @@
|
||||
use {
|
||||
crate::cli::Config,
|
||||
crate::{
|
||||
bench_tps_client::*,
|
||||
cli::Config,
|
||||
perf_utils::{sample_txs, SampleStats},
|
||||
},
|
||||
log::*,
|
||||
rayon::prelude::*,
|
||||
solana_client::perf_utils::{sample_txs, SampleStats},
|
||||
solana_core::gen_keys::GenKeys,
|
||||
solana_faucet::faucet::request_airdrop_transaction,
|
||||
solana_measure::measure::Measure,
|
||||
solana_metrics::{self, datapoint_info},
|
||||
solana_sdk::{
|
||||
client::Client,
|
||||
clock::{DEFAULT_MS_PER_SLOT, DEFAULT_S_PER_SLOT, MAX_PROCESSING_AGE},
|
||||
commitment_config::CommitmentConfig,
|
||||
hash::Hash,
|
||||
instruction::{AccountMeta, Instruction},
|
||||
message::Message,
|
||||
native_token::Sol,
|
||||
pubkey::Pubkey,
|
||||
signature::{Keypair, Signer},
|
||||
system_instruction, system_transaction,
|
||||
@@ -22,7 +24,6 @@ use {
|
||||
},
|
||||
std::{
|
||||
collections::{HashSet, VecDeque},
|
||||
net::SocketAddr,
|
||||
process::exit,
|
||||
sync::{
|
||||
atomic::{AtomicBool, AtomicIsize, AtomicUsize, Ordering},
|
||||
@@ -38,16 +39,9 @@ const MAX_TX_QUEUE_AGE: u64 = (MAX_PROCESSING_AGE as f64 * DEFAULT_S_PER_SLOT) a
|
||||
|
||||
pub const MAX_SPENDS_PER_TX: u64 = 4;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum BenchTpsError {
|
||||
AirdropFailure,
|
||||
}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, BenchTpsError>;
|
||||
|
||||
pub type SharedTransactions = Arc<RwLock<VecDeque<Vec<(Transaction, u64)>>>>;
|
||||
|
||||
fn get_latest_blockhash<T: Client>(client: &T) -> Hash {
|
||||
fn get_latest_blockhash<T: BenchTpsClient>(client: &T) -> Hash {
|
||||
loop {
|
||||
match client.get_latest_blockhash_with_commitment(CommitmentConfig::processed()) {
|
||||
Ok((blockhash, _)) => return blockhash,
|
||||
@@ -61,7 +55,7 @@ fn get_latest_blockhash<T: Client>(client: &T) -> Hash {
|
||||
|
||||
fn wait_for_target_slots_per_epoch<T>(target_slots_per_epoch: u64, client: &Arc<T>)
|
||||
where
|
||||
T: 'static + Client + Send + Sync,
|
||||
T: 'static + BenchTpsClient + Send + Sync,
|
||||
{
|
||||
if target_slots_per_epoch != 0 {
|
||||
info!(
|
||||
@@ -91,7 +85,7 @@ fn create_sampler_thread<T>(
|
||||
maxes: &Arc<RwLock<Vec<(String, SampleStats)>>>,
|
||||
) -> JoinHandle<()>
|
||||
where
|
||||
T: 'static + Client + Send + Sync,
|
||||
T: 'static + BenchTpsClient + Send + Sync,
|
||||
{
|
||||
info!("Sampling TPS every {} second...", sample_period);
|
||||
let exit_signal = exit_signal.clone();
|
||||
@@ -169,7 +163,7 @@ fn create_sender_threads<T>(
|
||||
shared_tx_active_thread_count: &Arc<AtomicIsize>,
|
||||
) -> Vec<JoinHandle<()>>
|
||||
where
|
||||
T: 'static + Client + Send + Sync,
|
||||
T: 'static + BenchTpsClient + Send + Sync,
|
||||
{
|
||||
(0..threads)
|
||||
.map(|_| {
|
||||
@@ -197,7 +191,7 @@ where
|
||||
|
||||
pub fn do_bench_tps<T>(client: Arc<T>, config: Config, gen_keypairs: Vec<Keypair>) -> u64
|
||||
where
|
||||
T: 'static + Client + Send + Sync,
|
||||
T: 'static + BenchTpsClient + Send + Sync,
|
||||
{
|
||||
let Config {
|
||||
id,
|
||||
@@ -391,7 +385,7 @@ fn generate_txs(
|
||||
}
|
||||
}
|
||||
|
||||
fn get_new_latest_blockhash<T: Client>(client: &Arc<T>, blockhash: &Hash) -> Option<Hash> {
|
||||
fn get_new_latest_blockhash<T: BenchTpsClient>(client: &Arc<T>, blockhash: &Hash) -> Option<Hash> {
|
||||
let start = Instant::now();
|
||||
while start.elapsed().as_secs() < 5 {
|
||||
if let Ok(new_blockhash) = client.get_latest_blockhash() {
|
||||
@@ -407,7 +401,7 @@ fn get_new_latest_blockhash<T: Client>(client: &Arc<T>, blockhash: &Hash) -> Opt
|
||||
None
|
||||
}
|
||||
|
||||
fn poll_blockhash<T: Client>(
|
||||
fn poll_blockhash<T: BenchTpsClient>(
|
||||
exit_signal: &Arc<AtomicBool>,
|
||||
blockhash: &Arc<RwLock<Hash>>,
|
||||
client: &Arc<T>,
|
||||
@@ -449,7 +443,7 @@ fn poll_blockhash<T: Client>(
|
||||
}
|
||||
}
|
||||
|
||||
fn do_tx_transfers<T: Client>(
|
||||
fn do_tx_transfers<T: BenchTpsClient>(
|
||||
exit_signal: &Arc<AtomicBool>,
|
||||
shared_txs: &SharedTransactions,
|
||||
shared_tx_thread_count: &Arc<AtomicIsize>,
|
||||
@@ -467,11 +461,7 @@ fn do_tx_transfers<T: Client>(
|
||||
};
|
||||
if let Some(txs0) = txs {
|
||||
shared_tx_thread_count.fetch_add(1, Ordering::Relaxed);
|
||||
info!(
|
||||
"Transferring 1 unit {} times... to {}",
|
||||
txs0.len(),
|
||||
client.as_ref().tpu_addr(),
|
||||
);
|
||||
info!("Transferring 1 unit {} times...", txs0.len());
|
||||
let tx_len = txs0.len();
|
||||
let transfer_start = Instant::now();
|
||||
let mut old_transactions = false;
|
||||
@@ -487,7 +477,7 @@ fn do_tx_transfers<T: Client>(
|
||||
transactions.push(tx.0);
|
||||
}
|
||||
|
||||
if let Err(error) = client.async_send_batch(transactions) {
|
||||
if let Err(error) = client.send_batch(transactions) {
|
||||
warn!("send_batch_sync in do_tx_transfers failed: {}", error);
|
||||
}
|
||||
|
||||
@@ -514,7 +504,11 @@ fn do_tx_transfers<T: Client>(
|
||||
}
|
||||
}
|
||||
|
||||
fn verify_funding_transfer<T: Client>(client: &Arc<T>, tx: &Transaction, amount: u64) -> bool {
|
||||
fn verify_funding_transfer<T: BenchTpsClient>(
|
||||
client: &Arc<T>,
|
||||
tx: &Transaction,
|
||||
amount: u64,
|
||||
) -> bool {
|
||||
for a in &tx.message().account_keys[1..] {
|
||||
match client.get_balance_with_commitment(a, CommitmentConfig::processed()) {
|
||||
Ok(balance) => return balance >= amount,
|
||||
@@ -525,7 +519,7 @@ fn verify_funding_transfer<T: Client>(client: &Arc<T>, tx: &Transaction, amount:
|
||||
}
|
||||
|
||||
trait FundingTransactions<'a> {
|
||||
fn fund<T: 'static + Client + Send + Sync>(
|
||||
fn fund<T: 'static + BenchTpsClient + Send + Sync>(
|
||||
&mut self,
|
||||
client: &Arc<T>,
|
||||
to_fund: &[(&'a Keypair, Vec<(Pubkey, u64)>)],
|
||||
@@ -533,12 +527,16 @@ trait FundingTransactions<'a> {
|
||||
);
|
||||
fn make(&mut self, to_fund: &[(&'a Keypair, Vec<(Pubkey, u64)>)]);
|
||||
fn sign(&mut self, blockhash: Hash);
|
||||
fn send<T: Client>(&self, client: &Arc<T>);
|
||||
fn verify<T: 'static + Client + Send + Sync>(&mut self, client: &Arc<T>, to_lamports: u64);
|
||||
fn send<T: BenchTpsClient>(&self, client: &Arc<T>);
|
||||
fn verify<T: 'static + BenchTpsClient + Send + Sync>(
|
||||
&mut self,
|
||||
client: &Arc<T>,
|
||||
to_lamports: u64,
|
||||
);
|
||||
}
|
||||
|
||||
impl<'a> FundingTransactions<'a> for Vec<(&'a Keypair, Transaction)> {
|
||||
fn fund<T: 'static + Client + Send + Sync>(
|
||||
fn fund<T: 'static + BenchTpsClient + Send + Sync>(
|
||||
&mut self,
|
||||
client: &Arc<T>,
|
||||
to_fund: &[(&'a Keypair, Vec<(Pubkey, u64)>)],
|
||||
@@ -607,16 +605,20 @@ impl<'a> FundingTransactions<'a> for Vec<(&'a Keypair, Transaction)> {
|
||||
debug!("sign {} txs: {}us", self.len(), sign_txs.as_us());
|
||||
}
|
||||
|
||||
fn send<T: Client>(&self, client: &Arc<T>) {
|
||||
fn send<T: BenchTpsClient>(&self, client: &Arc<T>) {
|
||||
let mut send_txs = Measure::start("send_txs");
|
||||
self.iter().for_each(|(_, tx)| {
|
||||
client.async_send_transaction(tx.clone()).expect("transfer");
|
||||
client.send_transaction(tx.clone()).expect("transfer");
|
||||
});
|
||||
send_txs.stop();
|
||||
debug!("send {} txs: {}us", self.len(), send_txs.as_us());
|
||||
}
|
||||
|
||||
fn verify<T: 'static + Client + Send + Sync>(&mut self, client: &Arc<T>, to_lamports: u64) {
|
||||
fn verify<T: 'static + BenchTpsClient + Send + Sync>(
|
||||
&mut self,
|
||||
client: &Arc<T>,
|
||||
to_lamports: u64,
|
||||
) {
|
||||
let starting_txs = self.len();
|
||||
let verified_txs = Arc::new(AtomicUsize::new(0));
|
||||
let too_many_failures = Arc::new(AtomicBool::new(false));
|
||||
@@ -691,7 +693,7 @@ impl<'a> FundingTransactions<'a> for Vec<(&'a Keypair, Transaction)> {
|
||||
/// fund the dests keys by spending all of the source keys into MAX_SPENDS_PER_TX
|
||||
/// on every iteration. This allows us to replay the transfers because the source is either empty,
|
||||
/// or full
|
||||
pub fn fund_keys<T: 'static + Client + Send + Sync>(
|
||||
pub fn fund_keys<T: 'static + BenchTpsClient + Send + Sync>(
|
||||
client: Arc<T>,
|
||||
source: &Keypair,
|
||||
dests: &[Keypair],
|
||||
@@ -733,75 +735,6 @@ pub fn fund_keys<T: 'static + Client + Send + Sync>(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn airdrop_lamports<T: Client>(
|
||||
client: &T,
|
||||
faucet_addr: &SocketAddr,
|
||||
id: &Keypair,
|
||||
desired_balance: u64,
|
||||
) -> Result<()> {
|
||||
let starting_balance = client.get_balance(&id.pubkey()).unwrap_or(0);
|
||||
metrics_submit_lamport_balance(starting_balance);
|
||||
info!("starting balance {}", starting_balance);
|
||||
|
||||
if starting_balance < desired_balance {
|
||||
let airdrop_amount = desired_balance - starting_balance;
|
||||
info!(
|
||||
"Airdropping {:?} lamports from {} for {}",
|
||||
airdrop_amount,
|
||||
faucet_addr,
|
||||
id.pubkey(),
|
||||
);
|
||||
|
||||
let blockhash = get_latest_blockhash(client);
|
||||
match request_airdrop_transaction(faucet_addr, &id.pubkey(), airdrop_amount, blockhash) {
|
||||
Ok(transaction) => {
|
||||
let mut tries = 0;
|
||||
loop {
|
||||
tries += 1;
|
||||
let signature = client.async_send_transaction(transaction.clone()).unwrap();
|
||||
let result = client.poll_for_signature_confirmation(&signature, 1);
|
||||
|
||||
if result.is_ok() {
|
||||
break;
|
||||
}
|
||||
if tries >= 5 {
|
||||
panic!(
|
||||
"Error requesting airdrop: to addr: {:?} amount: {} {:?}",
|
||||
faucet_addr, airdrop_amount, result
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
panic!(
|
||||
"Error requesting airdrop: {:?} to addr: {:?} amount: {}",
|
||||
err, faucet_addr, airdrop_amount
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
let current_balance = client
|
||||
.get_balance_with_commitment(&id.pubkey(), CommitmentConfig::processed())
|
||||
.unwrap_or_else(|e| {
|
||||
info!("airdrop error {}", e);
|
||||
starting_balance
|
||||
});
|
||||
info!("current balance {}...", current_balance);
|
||||
|
||||
metrics_submit_lamport_balance(current_balance);
|
||||
if current_balance - starting_balance != airdrop_amount {
|
||||
info!(
|
||||
"Airdrop failed! {} {} {}",
|
||||
id.pubkey(),
|
||||
current_balance,
|
||||
starting_balance
|
||||
);
|
||||
return Err(BenchTpsError::AirdropFailure);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn compute_and_report_stats(
|
||||
maxes: &Arc<RwLock<Vec<(String, SampleStats)>>>,
|
||||
sample_period: u64,
|
||||
@@ -885,15 +818,33 @@ pub fn generate_keypairs(seed_keypair: &Keypair, count: u64) -> (Vec<Keypair>, u
|
||||
(rnd.gen_n_keypairs(total_keys), extra)
|
||||
}
|
||||
|
||||
pub fn generate_and_fund_keypairs<T: 'static + Client + Send + Sync>(
|
||||
pub fn generate_and_fund_keypairs<T: 'static + BenchTpsClient + Send + Sync>(
|
||||
client: Arc<T>,
|
||||
faucet_addr: Option<SocketAddr>,
|
||||
funding_key: &Keypair,
|
||||
keypair_count: usize,
|
||||
lamports_per_account: u64,
|
||||
) -> Result<Vec<Keypair>> {
|
||||
let rent = client.get_minimum_balance_for_rent_exemption(0)?;
|
||||
let lamports_per_account = lamports_per_account + rent;
|
||||
|
||||
info!("Creating {} keypairs...", keypair_count);
|
||||
let (mut keypairs, extra) = generate_keypairs(funding_key, keypair_count as u64);
|
||||
fund_keypairs(client, funding_key, &keypairs, extra, lamports_per_account)?;
|
||||
|
||||
// 'generate_keypairs' generates extra keys to be able to have size-aligned funding batches for fund_keys.
|
||||
keypairs.truncate(keypair_count);
|
||||
|
||||
Ok(keypairs)
|
||||
}
|
||||
|
||||
pub fn fund_keypairs<T: 'static + BenchTpsClient + Send + Sync>(
|
||||
client: Arc<T>,
|
||||
funding_key: &Keypair,
|
||||
keypairs: &[Keypair],
|
||||
extra: u64,
|
||||
lamports_per_account: u64,
|
||||
) -> Result<()> {
|
||||
let rent = client.get_minimum_balance_for_rent_exemption(0)?;
|
||||
info!("Get lamports...");
|
||||
|
||||
// Sample the first keypair, to prevent lamport loss on repeated solana-bench-tps executions
|
||||
@@ -901,7 +852,7 @@ pub fn generate_and_fund_keypairs<T: 'static + Client + Send + Sync>(
|
||||
let first_keypair_balance = client.get_balance(&first_key).unwrap_or(0);
|
||||
|
||||
// Sample the last keypair, to check if funding was already completed
|
||||
let last_key = keypairs[keypair_count - 1].pubkey();
|
||||
let last_key = keypairs[keypairs.len() - 1].pubkey();
|
||||
let last_keypair_balance = client.get_balance(&last_key).unwrap_or(0);
|
||||
|
||||
// Repeated runs will eat up keypair balances from transaction fees. In order to quickly
|
||||
@@ -930,24 +881,35 @@ pub fn generate_and_fund_keypairs<T: 'static + Client + Send + Sync>(
|
||||
funding_key_balance, max_fee, lamports_per_account, extra, total
|
||||
);
|
||||
|
||||
if client.get_balance(&funding_key.pubkey()).unwrap_or(0) < total {
|
||||
airdrop_lamports(client.as_ref(), &faucet_addr.unwrap(), funding_key, total)?;
|
||||
if funding_key_balance < total + rent {
|
||||
error!(
|
||||
"funder has {}, needed {}",
|
||||
Sol(funding_key_balance),
|
||||
Sol(total)
|
||||
);
|
||||
let latest_blockhash = get_latest_blockhash(client.as_ref());
|
||||
if client
|
||||
.request_airdrop_with_blockhash(
|
||||
&funding_key.pubkey(),
|
||||
total + rent - funding_key_balance,
|
||||
&latest_blockhash,
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
return Err(BenchTpsError::AirdropFailure);
|
||||
}
|
||||
}
|
||||
|
||||
fund_keys(
|
||||
client,
|
||||
funding_key,
|
||||
&keypairs,
|
||||
keypairs,
|
||||
total,
|
||||
max_fee,
|
||||
lamports_per_account,
|
||||
);
|
||||
}
|
||||
|
||||
// 'generate_keypairs' generates extra keys to be able to have size-aligned funding batches for fund_keys.
|
||||
keypairs.truncate(keypair_count);
|
||||
|
||||
Ok(keypairs)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -956,14 +918,14 @@ mod tests {
|
||||
super::*,
|
||||
solana_runtime::{bank::Bank, bank_client::BankClient},
|
||||
solana_sdk::{
|
||||
client::SyncClient, fee_calculator::FeeRateGovernor,
|
||||
genesis_config::create_genesis_config,
|
||||
fee_calculator::FeeRateGovernor, genesis_config::create_genesis_config,
|
||||
native_token::sol_to_lamports,
|
||||
},
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn test_bench_tps_bank_client() {
|
||||
let (genesis_config, id) = create_genesis_config(10_000);
|
||||
let (genesis_config, id) = create_genesis_config(sol_to_lamports(10_000.0));
|
||||
let bank = Bank::new_for_tests(&genesis_config);
|
||||
let client = Arc::new(BankClient::new(bank));
|
||||
|
||||
@@ -976,48 +938,49 @@ mod tests {
|
||||
|
||||
let keypair_count = config.tx_count * config.keypair_multiplier;
|
||||
let keypairs =
|
||||
generate_and_fund_keypairs(client.clone(), None, &config.id, keypair_count, 20)
|
||||
.unwrap();
|
||||
generate_and_fund_keypairs(client.clone(), &config.id, keypair_count, 20).unwrap();
|
||||
|
||||
do_bench_tps(client, config, keypairs);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bench_tps_fund_keys() {
|
||||
let (genesis_config, id) = create_genesis_config(10_000);
|
||||
let (genesis_config, id) = create_genesis_config(sol_to_lamports(10_000.0));
|
||||
let bank = Bank::new_for_tests(&genesis_config);
|
||||
let client = Arc::new(BankClient::new(bank));
|
||||
let keypair_count = 20;
|
||||
let lamports = 20;
|
||||
let rent = client.get_minimum_balance_for_rent_exemption(0).unwrap();
|
||||
|
||||
let keypairs =
|
||||
generate_and_fund_keypairs(client.clone(), None, &id, keypair_count, lamports).unwrap();
|
||||
generate_and_fund_keypairs(client.clone(), &id, keypair_count, lamports).unwrap();
|
||||
|
||||
for kp in &keypairs {
|
||||
assert_eq!(
|
||||
client
|
||||
.get_balance_with_commitment(&kp.pubkey(), CommitmentConfig::processed())
|
||||
.unwrap(),
|
||||
lamports
|
||||
lamports + rent
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bench_tps_fund_keys_with_fees() {
|
||||
let (mut genesis_config, id) = create_genesis_config(10_000);
|
||||
let (mut genesis_config, id) = create_genesis_config(sol_to_lamports(10_000.0));
|
||||
let fee_rate_governor = FeeRateGovernor::new(11, 0);
|
||||
genesis_config.fee_rate_governor = fee_rate_governor;
|
||||
let bank = Bank::new_for_tests(&genesis_config);
|
||||
let client = Arc::new(BankClient::new(bank));
|
||||
let keypair_count = 20;
|
||||
let lamports = 20;
|
||||
let rent = client.get_minimum_balance_for_rent_exemption(0).unwrap();
|
||||
|
||||
let keypairs =
|
||||
generate_and_fund_keypairs(client.clone(), None, &id, keypair_count, lamports).unwrap();
|
||||
generate_and_fund_keypairs(client.clone(), &id, keypair_count, lamports).unwrap();
|
||||
|
||||
for kp in &keypairs {
|
||||
assert_eq!(client.get_balance(&kp.pubkey()).unwrap(), lamports);
|
||||
assert_eq!(client.get_balance(&kp.pubkey()).unwrap(), lamports + rent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
87
bench-tps/src/bench_tps_client.rs
Normal file
87
bench-tps/src/bench_tps_client.rs
Normal file
@@ -0,0 +1,87 @@
|
||||
use {
|
||||
solana_client::{client_error::ClientError, tpu_client::TpuSenderError},
|
||||
solana_sdk::{
|
||||
commitment_config::CommitmentConfig, epoch_info::EpochInfo, hash::Hash, message::Message,
|
||||
pubkey::Pubkey, signature::Signature, transaction::Transaction, transport::TransportError,
|
||||
},
|
||||
thiserror::Error,
|
||||
};
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum BenchTpsError {
|
||||
#[error("Airdrop failure")]
|
||||
AirdropFailure,
|
||||
#[error("IO error: {0:?}")]
|
||||
IoError(#[from] std::io::Error),
|
||||
#[error("Client error: {0:?}")]
|
||||
ClientError(#[from] ClientError),
|
||||
#[error("TpuClient error: {0:?}")]
|
||||
TpuSenderError(#[from] TpuSenderError),
|
||||
#[error("Transport error: {0:?}")]
|
||||
TransportError(#[from] TransportError),
|
||||
#[error("Custom error: {0}")]
|
||||
Custom(String),
|
||||
}
|
||||
|
||||
pub(crate) type Result<T> = std::result::Result<T, BenchTpsError>;
|
||||
|
||||
pub trait BenchTpsClient {
|
||||
/// Send a signed transaction without confirmation
|
||||
fn send_transaction(&self, transaction: Transaction) -> Result<Signature>;
|
||||
|
||||
/// Send a batch of signed transactions without confirmation.
|
||||
fn send_batch(&self, transactions: Vec<Transaction>) -> Result<()>;
|
||||
|
||||
/// Get latest blockhash
|
||||
fn get_latest_blockhash(&self) -> Result<Hash>;
|
||||
|
||||
/// Get latest blockhash and its last valid block height, using explicit commitment
|
||||
fn get_latest_blockhash_with_commitment(
|
||||
&self,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> Result<(Hash, u64)>;
|
||||
|
||||
/// Get transaction count
|
||||
fn get_transaction_count(&self) -> Result<u64>;
|
||||
|
||||
/// Get transaction count, using explicit commitment
|
||||
fn get_transaction_count_with_commitment(
|
||||
&self,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> Result<u64>;
|
||||
|
||||
/// Get epoch info
|
||||
fn get_epoch_info(&self) -> Result<EpochInfo>;
|
||||
|
||||
/// Get account balance
|
||||
fn get_balance(&self, pubkey: &Pubkey) -> Result<u64>;
|
||||
|
||||
/// Get account balance, using explicit commitment
|
||||
fn get_balance_with_commitment(
|
||||
&self,
|
||||
pubkey: &Pubkey,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> Result<u64>;
|
||||
|
||||
/// Calculate the fee for a `Message`
|
||||
fn get_fee_for_message(&self, message: &Message) -> Result<u64>;
|
||||
|
||||
/// Get the rent-exempt minimum for an account
|
||||
fn get_minimum_balance_for_rent_exemption(&self, data_len: usize) -> Result<u64>;
|
||||
|
||||
/// Return the address of client
|
||||
fn addr(&self) -> String;
|
||||
|
||||
/// Request, submit, and confirm an airdrop transaction
|
||||
fn request_airdrop_with_blockhash(
|
||||
&self,
|
||||
pubkey: &Pubkey,
|
||||
lamports: u64,
|
||||
recent_blockhash: &Hash,
|
||||
) -> Result<Signature>;
|
||||
}
|
||||
|
||||
mod bank_client;
|
||||
mod rpc_client;
|
||||
mod thin_client;
|
||||
mod tpu_client;
|
85
bench-tps/src/bench_tps_client/bank_client.rs
Normal file
85
bench-tps/src/bench_tps_client/bank_client.rs
Normal file
@@ -0,0 +1,85 @@
|
||||
use {
|
||||
crate::bench_tps_client::{BenchTpsClient, BenchTpsError, Result},
|
||||
solana_runtime::bank_client::BankClient,
|
||||
solana_sdk::{
|
||||
client::{AsyncClient, SyncClient},
|
||||
commitment_config::CommitmentConfig,
|
||||
epoch_info::EpochInfo,
|
||||
hash::Hash,
|
||||
message::Message,
|
||||
pubkey::Pubkey,
|
||||
signature::Signature,
|
||||
transaction::Transaction,
|
||||
},
|
||||
};
|
||||
|
||||
impl BenchTpsClient for BankClient {
|
||||
fn send_transaction(&self, transaction: Transaction) -> Result<Signature> {
|
||||
AsyncClient::async_send_transaction(self, transaction).map_err(|err| err.into())
|
||||
}
|
||||
fn send_batch(&self, transactions: Vec<Transaction>) -> Result<()> {
|
||||
AsyncClient::async_send_batch(self, transactions).map_err(|err| err.into())
|
||||
}
|
||||
fn get_latest_blockhash(&self) -> Result<Hash> {
|
||||
SyncClient::get_latest_blockhash(self).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_latest_blockhash_with_commitment(
|
||||
&self,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> Result<(Hash, u64)> {
|
||||
SyncClient::get_latest_blockhash_with_commitment(self, commitment_config)
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_transaction_count(&self) -> Result<u64> {
|
||||
SyncClient::get_transaction_count(self).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_transaction_count_with_commitment(
|
||||
&self,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> Result<u64> {
|
||||
SyncClient::get_transaction_count_with_commitment(self, commitment_config)
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_epoch_info(&self) -> Result<EpochInfo> {
|
||||
SyncClient::get_epoch_info(self).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_balance(&self, pubkey: &Pubkey) -> Result<u64> {
|
||||
SyncClient::get_balance(self, pubkey).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_balance_with_commitment(
|
||||
&self,
|
||||
pubkey: &Pubkey,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> Result<u64> {
|
||||
SyncClient::get_balance_with_commitment(self, pubkey, commitment_config)
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_fee_for_message(&self, message: &Message) -> Result<u64> {
|
||||
SyncClient::get_fee_for_message(self, message).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_minimum_balance_for_rent_exemption(&self, data_len: usize) -> Result<u64> {
|
||||
SyncClient::get_minimum_balance_for_rent_exemption(self, data_len).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn addr(&self) -> String {
|
||||
"Local BankClient".to_string()
|
||||
}
|
||||
|
||||
fn request_airdrop_with_blockhash(
|
||||
&self,
|
||||
_pubkey: &Pubkey,
|
||||
_lamports: u64,
|
||||
_recent_blockhash: &Hash,
|
||||
) -> Result<Signature> {
|
||||
// BankClient doesn't support airdrops
|
||||
Err(BenchTpsError::AirdropFailure)
|
||||
}
|
||||
}
|
83
bench-tps/src/bench_tps_client/rpc_client.rs
Normal file
83
bench-tps/src/bench_tps_client/rpc_client.rs
Normal file
@@ -0,0 +1,83 @@
|
||||
use {
|
||||
crate::bench_tps_client::{BenchTpsClient, Result},
|
||||
solana_client::rpc_client::RpcClient,
|
||||
solana_sdk::{
|
||||
commitment_config::CommitmentConfig, epoch_info::EpochInfo, hash::Hash, message::Message,
|
||||
pubkey::Pubkey, signature::Signature, transaction::Transaction,
|
||||
},
|
||||
};
|
||||
|
||||
impl BenchTpsClient for RpcClient {
|
||||
fn send_transaction(&self, transaction: Transaction) -> Result<Signature> {
|
||||
RpcClient::send_transaction(self, &transaction).map_err(|err| err.into())
|
||||
}
|
||||
fn send_batch(&self, transactions: Vec<Transaction>) -> Result<()> {
|
||||
for transaction in transactions {
|
||||
BenchTpsClient::send_transaction(self, transaction)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
fn get_latest_blockhash(&self) -> Result<Hash> {
|
||||
RpcClient::get_latest_blockhash(self).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_latest_blockhash_with_commitment(
|
||||
&self,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> Result<(Hash, u64)> {
|
||||
RpcClient::get_latest_blockhash_with_commitment(self, commitment_config)
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_transaction_count(&self) -> Result<u64> {
|
||||
RpcClient::get_transaction_count(self).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_transaction_count_with_commitment(
|
||||
&self,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> Result<u64> {
|
||||
RpcClient::get_transaction_count_with_commitment(self, commitment_config)
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_epoch_info(&self) -> Result<EpochInfo> {
|
||||
RpcClient::get_epoch_info(self).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_balance(&self, pubkey: &Pubkey) -> Result<u64> {
|
||||
RpcClient::get_balance(self, pubkey).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_balance_with_commitment(
|
||||
&self,
|
||||
pubkey: &Pubkey,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> Result<u64> {
|
||||
RpcClient::get_balance_with_commitment(self, pubkey, commitment_config)
|
||||
.map(|res| res.value)
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_fee_for_message(&self, message: &Message) -> Result<u64> {
|
||||
RpcClient::get_fee_for_message(self, message).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_minimum_balance_for_rent_exemption(&self, data_len: usize) -> Result<u64> {
|
||||
RpcClient::get_minimum_balance_for_rent_exemption(self, data_len).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn addr(&self) -> String {
|
||||
self.url()
|
||||
}
|
||||
|
||||
fn request_airdrop_with_blockhash(
|
||||
&self,
|
||||
pubkey: &Pubkey,
|
||||
lamports: u64,
|
||||
recent_blockhash: &Hash,
|
||||
) -> Result<Signature> {
|
||||
RpcClient::request_airdrop_with_blockhash(self, pubkey, lamports, recent_blockhash)
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
}
|
86
bench-tps/src/bench_tps_client/thin_client.rs
Normal file
86
bench-tps/src/bench_tps_client/thin_client.rs
Normal file
@@ -0,0 +1,86 @@
|
||||
use {
|
||||
crate::bench_tps_client::{BenchTpsClient, Result},
|
||||
solana_client::thin_client::ThinClient,
|
||||
solana_sdk::{
|
||||
client::{AsyncClient, Client, SyncClient},
|
||||
commitment_config::CommitmentConfig,
|
||||
epoch_info::EpochInfo,
|
||||
hash::Hash,
|
||||
message::Message,
|
||||
pubkey::Pubkey,
|
||||
signature::Signature,
|
||||
transaction::Transaction,
|
||||
},
|
||||
};
|
||||
|
||||
impl BenchTpsClient for ThinClient {
|
||||
fn send_transaction(&self, transaction: Transaction) -> Result<Signature> {
|
||||
AsyncClient::async_send_transaction(self, transaction).map_err(|err| err.into())
|
||||
}
|
||||
fn send_batch(&self, transactions: Vec<Transaction>) -> Result<()> {
|
||||
AsyncClient::async_send_batch(self, transactions).map_err(|err| err.into())
|
||||
}
|
||||
fn get_latest_blockhash(&self) -> Result<Hash> {
|
||||
SyncClient::get_latest_blockhash(self).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_latest_blockhash_with_commitment(
|
||||
&self,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> Result<(Hash, u64)> {
|
||||
SyncClient::get_latest_blockhash_with_commitment(self, commitment_config)
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_transaction_count(&self) -> Result<u64> {
|
||||
SyncClient::get_transaction_count(self).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_transaction_count_with_commitment(
|
||||
&self,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> Result<u64> {
|
||||
SyncClient::get_transaction_count_with_commitment(self, commitment_config)
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_epoch_info(&self) -> Result<EpochInfo> {
|
||||
SyncClient::get_epoch_info(self).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_balance(&self, pubkey: &Pubkey) -> Result<u64> {
|
||||
SyncClient::get_balance(self, pubkey).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_balance_with_commitment(
|
||||
&self,
|
||||
pubkey: &Pubkey,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> Result<u64> {
|
||||
SyncClient::get_balance_with_commitment(self, pubkey, commitment_config)
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_fee_for_message(&self, message: &Message) -> Result<u64> {
|
||||
SyncClient::get_fee_for_message(self, message).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_minimum_balance_for_rent_exemption(&self, data_len: usize) -> Result<u64> {
|
||||
SyncClient::get_minimum_balance_for_rent_exemption(self, data_len).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn addr(&self) -> String {
|
||||
Client::tpu_addr(self)
|
||||
}
|
||||
|
||||
fn request_airdrop_with_blockhash(
|
||||
&self,
|
||||
pubkey: &Pubkey,
|
||||
lamports: u64,
|
||||
recent_blockhash: &Hash,
|
||||
) -> Result<Signature> {
|
||||
self.rpc_client()
|
||||
.request_airdrop_with_blockhash(pubkey, lamports, recent_blockhash)
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
}
|
99
bench-tps/src/bench_tps_client/tpu_client.rs
Normal file
99
bench-tps/src/bench_tps_client/tpu_client.rs
Normal file
@@ -0,0 +1,99 @@
|
||||
use {
|
||||
crate::bench_tps_client::{BenchTpsClient, Result},
|
||||
solana_client::tpu_client::TpuClient,
|
||||
solana_sdk::{
|
||||
commitment_config::CommitmentConfig, epoch_info::EpochInfo, hash::Hash, message::Message,
|
||||
pubkey::Pubkey, signature::Signature, transaction::Transaction,
|
||||
},
|
||||
};
|
||||
|
||||
impl BenchTpsClient for TpuClient {
|
||||
fn send_transaction(&self, transaction: Transaction) -> Result<Signature> {
|
||||
let signature = transaction.signatures[0];
|
||||
self.try_send_transaction(&transaction)?;
|
||||
Ok(signature)
|
||||
}
|
||||
fn send_batch(&self, transactions: Vec<Transaction>) -> Result<()> {
|
||||
for transaction in transactions {
|
||||
BenchTpsClient::send_transaction(self, transaction)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
fn get_latest_blockhash(&self) -> Result<Hash> {
|
||||
self.rpc_client()
|
||||
.get_latest_blockhash()
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_latest_blockhash_with_commitment(
|
||||
&self,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> Result<(Hash, u64)> {
|
||||
self.rpc_client()
|
||||
.get_latest_blockhash_with_commitment(commitment_config)
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_transaction_count(&self) -> Result<u64> {
|
||||
self.rpc_client()
|
||||
.get_transaction_count()
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_transaction_count_with_commitment(
|
||||
&self,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> Result<u64> {
|
||||
self.rpc_client()
|
||||
.get_transaction_count_with_commitment(commitment_config)
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_epoch_info(&self) -> Result<EpochInfo> {
|
||||
self.rpc_client().get_epoch_info().map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_balance(&self, pubkey: &Pubkey) -> Result<u64> {
|
||||
self.rpc_client()
|
||||
.get_balance(pubkey)
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_balance_with_commitment(
|
||||
&self,
|
||||
pubkey: &Pubkey,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> Result<u64> {
|
||||
self.rpc_client()
|
||||
.get_balance_with_commitment(pubkey, commitment_config)
|
||||
.map(|res| res.value)
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_fee_for_message(&self, message: &Message) -> Result<u64> {
|
||||
self.rpc_client()
|
||||
.get_fee_for_message(message)
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn get_minimum_balance_for_rent_exemption(&self, data_len: usize) -> Result<u64> {
|
||||
self.rpc_client()
|
||||
.get_minimum_balance_for_rent_exemption(data_len)
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn addr(&self) -> String {
|
||||
self.rpc_client().url()
|
||||
}
|
||||
|
||||
fn request_airdrop_with_blockhash(
|
||||
&self,
|
||||
pubkey: &Pubkey,
|
||||
lamports: u64,
|
||||
recent_blockhash: &Hash,
|
||||
) -> Result<Signature> {
|
||||
self.rpc_client()
|
||||
.request_airdrop_with_blockhash(pubkey, lamports, recent_blockhash)
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
}
|
@@ -1,6 +1,7 @@
|
||||
use {
|
||||
clap::{crate_description, crate_name, App, Arg, ArgMatches},
|
||||
solana_faucet::faucet::FAUCET_PORT,
|
||||
solana_clap_utils::input_validators::{is_url, is_url_or_moniker},
|
||||
solana_cli_config::{ConfigInput, CONFIG_FILE},
|
||||
solana_sdk::{
|
||||
fee_calculator::FeeRateGovernor,
|
||||
pubkey::Pubkey,
|
||||
@@ -11,10 +12,28 @@ use {
|
||||
|
||||
const NUM_LAMPORTS_PER_ACCOUNT_DEFAULT: u64 = solana_sdk::native_token::LAMPORTS_PER_SOL;
|
||||
|
||||
pub enum ExternalClientType {
|
||||
// Submits transactions to an Rpc node using an RpcClient
|
||||
RpcClient,
|
||||
// Submits transactions directly to leaders using a ThinClient, broadcasting to multiple
|
||||
// leaders when num_nodes > 1
|
||||
ThinClient,
|
||||
// Submits transactions directly to leaders using a TpuClient, broadcasting to upcoming leaders
|
||||
// via TpuClient default configuration
|
||||
TpuClient,
|
||||
}
|
||||
|
||||
impl Default for ExternalClientType {
|
||||
fn default() -> Self {
|
||||
Self::ThinClient
|
||||
}
|
||||
}
|
||||
|
||||
/// Holds the configuration for a single run of the benchmark
|
||||
pub struct Config {
|
||||
pub entrypoint_addr: SocketAddr,
|
||||
pub faucet_addr: SocketAddr,
|
||||
pub json_rpc_url: String,
|
||||
pub websocket_url: String,
|
||||
pub id: Keypair,
|
||||
pub threads: usize,
|
||||
pub num_nodes: usize,
|
||||
@@ -31,13 +50,16 @@ pub struct Config {
|
||||
pub num_lamports_per_account: u64,
|
||||
pub target_slots_per_epoch: u64,
|
||||
pub target_node: Option<Pubkey>,
|
||||
pub external_client_type: ExternalClientType,
|
||||
pub use_quic: bool,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Config {
|
||||
Config {
|
||||
entrypoint_addr: SocketAddr::from(([127, 0, 0, 1], 8001)),
|
||||
faucet_addr: SocketAddr::from(([127, 0, 0, 1], FAUCET_PORT)),
|
||||
json_rpc_url: ConfigInput::default().json_rpc_url,
|
||||
websocket_url: ConfigInput::default().websocket_url,
|
||||
id: Keypair::new(),
|
||||
threads: 4,
|
||||
num_nodes: 1,
|
||||
@@ -54,6 +76,8 @@ impl Default for Config {
|
||||
num_lamports_per_account: NUM_LAMPORTS_PER_ACCOUNT_DEFAULT,
|
||||
target_slots_per_epoch: 0,
|
||||
target_node: None,
|
||||
external_client_type: ExternalClientType::default(),
|
||||
use_quic: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,6 +86,42 @@ impl Default for Config {
|
||||
pub fn build_args<'a, 'b>(version: &'b str) -> App<'a, 'b> {
|
||||
App::new(crate_name!()).about(crate_description!())
|
||||
.version(version)
|
||||
.arg({
|
||||
let arg = Arg::with_name("config_file")
|
||||
.short("C")
|
||||
.long("config")
|
||||
.value_name("FILEPATH")
|
||||
.takes_value(true)
|
||||
.global(true)
|
||||
.help("Configuration file to use");
|
||||
if let Some(ref config_file) = *CONFIG_FILE {
|
||||
arg.default_value(config_file)
|
||||
} else {
|
||||
arg
|
||||
}
|
||||
})
|
||||
.arg(
|
||||
Arg::with_name("json_rpc_url")
|
||||
.short("u")
|
||||
.long("url")
|
||||
.value_name("URL_OR_MONIKER")
|
||||
.takes_value(true)
|
||||
.global(true)
|
||||
.validator(is_url_or_moniker)
|
||||
.help(
|
||||
"URL for Solana's JSON RPC or moniker (or their first letter): \
|
||||
[mainnet-beta, testnet, devnet, localhost]",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("websocket_url")
|
||||
.long("ws")
|
||||
.value_name("URL")
|
||||
.takes_value(true)
|
||||
.global(true)
|
||||
.validator(is_url)
|
||||
.help("WebSocket URL for the solana cluster"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("entrypoint")
|
||||
.short("n")
|
||||
@@ -76,7 +136,8 @@ pub fn build_args<'a, 'b>(version: &'b str) -> App<'a, 'b> {
|
||||
.long("faucet")
|
||||
.value_name("HOST:PORT")
|
||||
.takes_value(true)
|
||||
.help("Location of the faucet; defaults to entrypoint:FAUCET_PORT"),
|
||||
.hidden(true)
|
||||
.help("Deprecated. BenchTps no longer queries the faucet directly"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("identity")
|
||||
@@ -191,6 +252,27 @@ pub fn build_args<'a, 'b>(version: &'b str) -> App<'a, 'b> {
|
||||
"Wait until epochs are this many slots long.",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("rpc_client")
|
||||
.long("use-rpc-client")
|
||||
.conflicts_with("tpu_client")
|
||||
.takes_value(false)
|
||||
.help("Submit transactions with a RpcClient")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("tpu_client")
|
||||
.long("use-tpu-client")
|
||||
.conflicts_with("rpc_client")
|
||||
.takes_value(false)
|
||||
.help("Submit transactions with a TpuClient")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("tpu_use_quic")
|
||||
.long("tpu-use-quic")
|
||||
.takes_value(false)
|
||||
.help("Submit transactions via QUIC; only affects ThinClient (default) \
|
||||
or TpuClient sends"),
|
||||
)
|
||||
}
|
||||
|
||||
/// Parses a clap `ArgMatches` structure into a `Config`
|
||||
@@ -201,6 +283,45 @@ pub fn build_args<'a, 'b>(version: &'b str) -> App<'a, 'b> {
|
||||
pub fn extract_args(matches: &ArgMatches) -> Config {
|
||||
let mut args = Config::default();
|
||||
|
||||
let config = if let Some(config_file) = matches.value_of("config_file") {
|
||||
solana_cli_config::Config::load(config_file).unwrap_or_default()
|
||||
} else {
|
||||
solana_cli_config::Config::default()
|
||||
};
|
||||
let (_, json_rpc_url) = ConfigInput::compute_json_rpc_url_setting(
|
||||
matches.value_of("json_rpc_url").unwrap_or(""),
|
||||
&config.json_rpc_url,
|
||||
);
|
||||
args.json_rpc_url = json_rpc_url;
|
||||
|
||||
let (_, websocket_url) = ConfigInput::compute_websocket_url_setting(
|
||||
matches.value_of("websocket_url").unwrap_or(""),
|
||||
&config.websocket_url,
|
||||
matches.value_of("json_rpc_url").unwrap_or(""),
|
||||
&config.json_rpc_url,
|
||||
);
|
||||
args.websocket_url = websocket_url;
|
||||
|
||||
let (_, id_path) = ConfigInput::compute_keypair_path_setting(
|
||||
matches.value_of("identity").unwrap_or(""),
|
||||
&config.keypair_path,
|
||||
);
|
||||
if let Ok(id) = read_keypair_file(id_path) {
|
||||
args.id = id;
|
||||
} else if matches.is_present("identity") {
|
||||
panic!("could not parse identity path");
|
||||
}
|
||||
|
||||
if matches.is_present("tpu_client") {
|
||||
args.external_client_type = ExternalClientType::TpuClient;
|
||||
} else if matches.is_present("rpc_client") {
|
||||
args.external_client_type = ExternalClientType::RpcClient;
|
||||
}
|
||||
|
||||
if matches.is_present("tpu_use_quic") {
|
||||
args.use_quic = true;
|
||||
}
|
||||
|
||||
if let Some(addr) = matches.value_of("entrypoint") {
|
||||
args.entrypoint_addr = solana_net_utils::parse_host_port(addr).unwrap_or_else(|e| {
|
||||
eprintln!("failed to parse entrypoint address: {}", e);
|
||||
@@ -208,18 +329,6 @@ pub fn extract_args(matches: &ArgMatches) -> Config {
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(addr) = matches.value_of("faucet") {
|
||||
args.faucet_addr = solana_net_utils::parse_host_port(addr).unwrap_or_else(|e| {
|
||||
eprintln!("failed to parse faucet address: {}", e);
|
||||
exit(1)
|
||||
});
|
||||
}
|
||||
|
||||
if matches.is_present("identity") {
|
||||
args.id = read_keypair_file(matches.value_of("identity").unwrap())
|
||||
.expect("can't read client identity");
|
||||
}
|
||||
|
||||
if let Some(t) = matches.value_of("threads") {
|
||||
args.threads = t.to_string().parse().expect("can't parse threads");
|
||||
}
|
||||
|
72
bench-tps/src/keypairs.rs
Normal file
72
bench-tps/src/keypairs.rs
Normal file
@@ -0,0 +1,72 @@
|
||||
use {
|
||||
crate::{
|
||||
bench::{fund_keypairs, generate_and_fund_keypairs},
|
||||
bench_tps_client::BenchTpsClient,
|
||||
},
|
||||
log::*,
|
||||
solana_genesis::Base64Account,
|
||||
solana_sdk::signature::{Keypair, Signer},
|
||||
std::{collections::HashMap, fs::File, path::Path, process::exit, sync::Arc},
|
||||
};
|
||||
|
||||
pub fn get_keypairs<T>(
|
||||
client: Arc<T>,
|
||||
id: &Keypair,
|
||||
keypair_count: usize,
|
||||
num_lamports_per_account: u64,
|
||||
client_ids_and_stake_file: &str,
|
||||
read_from_client_file: bool,
|
||||
) -> Vec<Keypair>
|
||||
where
|
||||
T: 'static + BenchTpsClient + Send + Sync,
|
||||
{
|
||||
if read_from_client_file {
|
||||
let path = Path::new(client_ids_and_stake_file);
|
||||
let file = File::open(path).unwrap();
|
||||
|
||||
info!("Reading {}", client_ids_and_stake_file);
|
||||
let accounts: HashMap<String, Base64Account> = serde_yaml::from_reader(file).unwrap();
|
||||
let mut keypairs = vec![];
|
||||
let mut last_balance = 0;
|
||||
|
||||
accounts
|
||||
.into_iter()
|
||||
.for_each(|(keypair, primordial_account)| {
|
||||
let bytes: Vec<u8> = serde_json::from_str(keypair.as_str()).unwrap();
|
||||
keypairs.push(Keypair::from_bytes(&bytes).unwrap());
|
||||
last_balance = primordial_account.balance;
|
||||
});
|
||||
|
||||
if keypairs.len() < keypair_count {
|
||||
eprintln!(
|
||||
"Expected {} accounts in {}, only received {} (--tx_count mismatch?)",
|
||||
keypair_count,
|
||||
client_ids_and_stake_file,
|
||||
keypairs.len(),
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
// Sort keypairs so that do_bench_tps() uses the same subset of accounts for each run.
|
||||
// This prevents the amount of storage needed for bench-tps accounts from creeping up
|
||||
// across multiple runs.
|
||||
keypairs.sort_by_key(|x| x.pubkey().to_string());
|
||||
fund_keypairs(
|
||||
client,
|
||||
id,
|
||||
&keypairs,
|
||||
keypairs.len().saturating_sub(keypair_count) as u64,
|
||||
last_balance,
|
||||
)
|
||||
.unwrap_or_else(|e| {
|
||||
eprintln!("Error could not fund keys: {:?}", e);
|
||||
exit(1);
|
||||
});
|
||||
keypairs
|
||||
} else {
|
||||
generate_and_fund_keypairs(client, id, keypair_count, num_lamports_per_account)
|
||||
.unwrap_or_else(|e| {
|
||||
eprintln!("Error could not fund keys: {:?}", e);
|
||||
exit(1);
|
||||
})
|
||||
}
|
||||
}
|
@@ -1,3 +1,6 @@
|
||||
#![allow(clippy::integer_arithmetic)]
|
||||
pub mod bench;
|
||||
pub mod bench_tps_client;
|
||||
pub mod cli;
|
||||
pub mod keypairs;
|
||||
mod perf_utils;
|
||||
|
@@ -2,15 +2,19 @@
|
||||
use {
|
||||
log::*,
|
||||
solana_bench_tps::{
|
||||
bench::{do_bench_tps, generate_and_fund_keypairs, generate_keypairs},
|
||||
cli,
|
||||
bench::{do_bench_tps, generate_keypairs},
|
||||
cli::{self, ExternalClientType},
|
||||
keypairs::get_keypairs,
|
||||
},
|
||||
solana_client::{
|
||||
connection_cache,
|
||||
rpc_client::RpcClient,
|
||||
tpu_client::{TpuClient, TpuClientConfig},
|
||||
},
|
||||
solana_genesis::Base64Account,
|
||||
solana_gossip::gossip_service::{discover_cluster, get_client, get_multi_client},
|
||||
solana_sdk::{
|
||||
fee_calculator::FeeRateGovernor,
|
||||
signature::{Keypair, Signer},
|
||||
system_program,
|
||||
commitment_config::CommitmentConfig, fee_calculator::FeeRateGovernor, system_program,
|
||||
},
|
||||
solana_streamer::socket::SocketAddrSpace,
|
||||
std::{collections::HashMap, fs::File, io::prelude::*, path::Path, process::exit, sync::Arc},
|
||||
@@ -28,7 +32,8 @@ fn main() {
|
||||
|
||||
let cli::Config {
|
||||
entrypoint_addr,
|
||||
faucet_addr,
|
||||
json_rpc_url,
|
||||
websocket_url,
|
||||
id,
|
||||
num_nodes,
|
||||
tx_count,
|
||||
@@ -40,6 +45,8 @@ fn main() {
|
||||
multi_client,
|
||||
num_lamports_per_account,
|
||||
target_node,
|
||||
external_client_type,
|
||||
use_quic,
|
||||
..
|
||||
} = &cli_config;
|
||||
|
||||
@@ -75,83 +82,93 @@ fn main() {
|
||||
}
|
||||
|
||||
info!("Connecting to the cluster");
|
||||
let nodes = discover_cluster(entrypoint_addr, *num_nodes, SocketAddrSpace::Unspecified)
|
||||
.unwrap_or_else(|err| {
|
||||
eprintln!("Failed to discover {} nodes: {:?}", num_nodes, err);
|
||||
exit(1);
|
||||
});
|
||||
|
||||
let client = if *multi_client {
|
||||
let (client, num_clients) = get_multi_client(&nodes, &SocketAddrSpace::Unspecified);
|
||||
if nodes.len() < num_clients {
|
||||
eprintln!(
|
||||
"Error: Insufficient nodes discovered. Expecting {} or more",
|
||||
num_nodes
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
Arc::new(client)
|
||||
} else if let Some(target_node) = target_node {
|
||||
info!("Searching for target_node: {:?}", target_node);
|
||||
let mut target_client = None;
|
||||
for node in nodes {
|
||||
if node.id == *target_node {
|
||||
target_client = Some(Arc::new(get_client(&[node], &SocketAddrSpace::Unspecified)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
target_client.unwrap_or_else(|| {
|
||||
eprintln!("Target node {} not found", target_node);
|
||||
exit(1);
|
||||
})
|
||||
} else {
|
||||
Arc::new(get_client(&nodes, &SocketAddrSpace::Unspecified))
|
||||
};
|
||||
|
||||
let keypairs = if *read_from_client_file {
|
||||
let path = Path::new(&client_ids_and_stake_file);
|
||||
let file = File::open(path).unwrap();
|
||||
|
||||
info!("Reading {}", client_ids_and_stake_file);
|
||||
let accounts: HashMap<String, Base64Account> = serde_yaml::from_reader(file).unwrap();
|
||||
let mut keypairs = vec![];
|
||||
let mut last_balance = 0;
|
||||
|
||||
accounts
|
||||
.into_iter()
|
||||
.for_each(|(keypair, primordial_account)| {
|
||||
let bytes: Vec<u8> = serde_json::from_str(keypair.as_str()).unwrap();
|
||||
keypairs.push(Keypair::from_bytes(&bytes).unwrap());
|
||||
last_balance = primordial_account.balance;
|
||||
});
|
||||
|
||||
if keypairs.len() < keypair_count {
|
||||
eprintln!(
|
||||
"Expected {} accounts in {}, only received {} (--tx_count mismatch?)",
|
||||
match external_client_type {
|
||||
ExternalClientType::RpcClient => {
|
||||
let client = Arc::new(RpcClient::new_with_commitment(
|
||||
json_rpc_url.to_string(),
|
||||
CommitmentConfig::confirmed(),
|
||||
));
|
||||
let keypairs = get_keypairs(
|
||||
client.clone(),
|
||||
id,
|
||||
keypair_count,
|
||||
*num_lamports_per_account,
|
||||
client_ids_and_stake_file,
|
||||
keypairs.len(),
|
||||
*read_from_client_file,
|
||||
);
|
||||
exit(1);
|
||||
do_bench_tps(client, cli_config, keypairs);
|
||||
}
|
||||
// Sort keypairs so that do_bench_tps() uses the same subset of accounts for each run.
|
||||
// This prevents the amount of storage needed for bench-tps accounts from creeping up
|
||||
// across multiple runs.
|
||||
keypairs.sort_by_key(|x| x.pubkey().to_string());
|
||||
keypairs
|
||||
} else {
|
||||
generate_and_fund_keypairs(
|
||||
client.clone(),
|
||||
Some(*faucet_addr),
|
||||
id,
|
||||
keypair_count,
|
||||
*num_lamports_per_account,
|
||||
)
|
||||
.unwrap_or_else(|e| {
|
||||
eprintln!("Error could not fund keys: {:?}", e);
|
||||
exit(1);
|
||||
})
|
||||
};
|
||||
|
||||
do_bench_tps(client, cli_config, keypairs);
|
||||
ExternalClientType::ThinClient => {
|
||||
let nodes = discover_cluster(entrypoint_addr, *num_nodes, SocketAddrSpace::Unspecified)
|
||||
.unwrap_or_else(|err| {
|
||||
eprintln!("Failed to discover {} nodes: {:?}", num_nodes, err);
|
||||
exit(1);
|
||||
});
|
||||
if *use_quic {
|
||||
connection_cache::set_use_quic(true);
|
||||
}
|
||||
let client = if *multi_client {
|
||||
let (client, num_clients) = get_multi_client(&nodes, &SocketAddrSpace::Unspecified);
|
||||
if nodes.len() < num_clients {
|
||||
eprintln!(
|
||||
"Error: Insufficient nodes discovered. Expecting {} or more",
|
||||
num_nodes
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
Arc::new(client)
|
||||
} else if let Some(target_node) = target_node {
|
||||
info!("Searching for target_node: {:?}", target_node);
|
||||
let mut target_client = None;
|
||||
for node in nodes {
|
||||
if node.id == *target_node {
|
||||
target_client =
|
||||
Some(Arc::new(get_client(&[node], &SocketAddrSpace::Unspecified)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
target_client.unwrap_or_else(|| {
|
||||
eprintln!("Target node {} not found", target_node);
|
||||
exit(1);
|
||||
})
|
||||
} else {
|
||||
Arc::new(get_client(&nodes, &SocketAddrSpace::Unspecified))
|
||||
};
|
||||
let keypairs = get_keypairs(
|
||||
client.clone(),
|
||||
id,
|
||||
keypair_count,
|
||||
*num_lamports_per_account,
|
||||
client_ids_and_stake_file,
|
||||
*read_from_client_file,
|
||||
);
|
||||
do_bench_tps(client, cli_config, keypairs);
|
||||
}
|
||||
ExternalClientType::TpuClient => {
|
||||
let rpc_client = Arc::new(RpcClient::new_with_commitment(
|
||||
json_rpc_url.to_string(),
|
||||
CommitmentConfig::confirmed(),
|
||||
));
|
||||
if *use_quic {
|
||||
connection_cache::set_use_quic(true);
|
||||
}
|
||||
let client = Arc::new(
|
||||
TpuClient::new(rpc_client, websocket_url, TpuClientConfig::default())
|
||||
.unwrap_or_else(|err| {
|
||||
eprintln!("Could not create TpuClient {:?}", err);
|
||||
exit(1);
|
||||
}),
|
||||
);
|
||||
let keypairs = get_keypairs(
|
||||
client.clone(),
|
||||
id,
|
||||
keypair_count,
|
||||
*num_lamports_per_account,
|
||||
client_ids_and_stake_file,
|
||||
*read_from_client_file,
|
||||
);
|
||||
do_bench_tps(client, cli_config, keypairs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
use {
|
||||
crate::bench_tps_client::BenchTpsClient,
|
||||
log::*,
|
||||
solana_sdk::{client::Client, commitment_config::CommitmentConfig, timing::duration_as_s},
|
||||
solana_sdk::{commitment_config::CommitmentConfig, timing::duration_as_s},
|
||||
std::{
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
@@ -27,7 +28,7 @@ pub fn sample_txs<T>(
|
||||
sample_period: u64,
|
||||
client: &Arc<T>,
|
||||
) where
|
||||
T: Client,
|
||||
T: BenchTpsClient,
|
||||
{
|
||||
let mut max_tps = 0.0;
|
||||
let mut total_elapsed;
|
||||
@@ -81,10 +82,7 @@ pub fn sample_txs<T>(
|
||||
elapsed: total_elapsed,
|
||||
txs: total_txs,
|
||||
};
|
||||
sample_stats
|
||||
.write()
|
||||
.unwrap()
|
||||
.push((client.tpu_addr(), stats));
|
||||
sample_stats.write().unwrap().push((client.addr(), stats));
|
||||
return;
|
||||
}
|
||||
sleep(Duration::from_secs(sample_period));
|
@@ -6,16 +6,24 @@ use {
|
||||
bench::{do_bench_tps, generate_and_fund_keypairs},
|
||||
cli::Config,
|
||||
},
|
||||
solana_client::thin_client::create_client,
|
||||
solana_client::{
|
||||
rpc_client::RpcClient,
|
||||
thin_client::create_client,
|
||||
tpu_client::{TpuClient, TpuClientConfig},
|
||||
},
|
||||
solana_core::validator::ValidatorConfig,
|
||||
solana_faucet::faucet::run_local_faucet_with_port,
|
||||
solana_gossip::cluster_info::VALIDATOR_PORT_RANGE,
|
||||
solana_faucet::faucet::{run_local_faucet, run_local_faucet_with_port},
|
||||
solana_local_cluster::{
|
||||
local_cluster::{ClusterConfig, LocalCluster},
|
||||
validator_configs::make_identical_validator_configs,
|
||||
},
|
||||
solana_sdk::signature::{Keypair, Signer},
|
||||
solana_rpc::rpc::JsonRpcConfig,
|
||||
solana_sdk::{
|
||||
commitment_config::CommitmentConfig,
|
||||
signature::{Keypair, Signer},
|
||||
},
|
||||
solana_streamer::socket::SocketAddrSpace,
|
||||
solana_test_validator::TestValidator,
|
||||
std::{sync::Arc, time::Duration},
|
||||
};
|
||||
|
||||
@@ -23,13 +31,34 @@ fn test_bench_tps_local_cluster(config: Config) {
|
||||
let native_instruction_processors = vec![];
|
||||
|
||||
solana_logger::setup();
|
||||
|
||||
let faucet_keypair = Keypair::new();
|
||||
let faucet_pubkey = faucet_keypair.pubkey();
|
||||
let (addr_sender, addr_receiver) = unbounded();
|
||||
run_local_faucet_with_port(faucet_keypair, addr_sender, None, 0);
|
||||
let faucet_addr = addr_receiver
|
||||
.recv_timeout(Duration::from_secs(2))
|
||||
.expect("run_local_faucet")
|
||||
.expect("faucet_addr");
|
||||
|
||||
const NUM_NODES: usize = 1;
|
||||
let mut validator_config = ValidatorConfig::default_for_test();
|
||||
validator_config.rpc_config = JsonRpcConfig {
|
||||
faucet_addr: Some(faucet_addr),
|
||||
..JsonRpcConfig::default_for_test()
|
||||
};
|
||||
let cluster = LocalCluster::new(
|
||||
&mut ClusterConfig {
|
||||
node_stakes: vec![999_990; NUM_NODES],
|
||||
cluster_lamports: 200_000_000,
|
||||
validator_configs: make_identical_validator_configs(
|
||||
&ValidatorConfig::default_for_test(),
|
||||
&ValidatorConfig {
|
||||
rpc_config: JsonRpcConfig {
|
||||
faucet_addr: Some(faucet_addr),
|
||||
..JsonRpcConfig::default_for_test()
|
||||
},
|
||||
..ValidatorConfig::default_for_test()
|
||||
},
|
||||
NUM_NODES,
|
||||
),
|
||||
native_instruction_processors,
|
||||
@@ -38,31 +67,55 @@ fn test_bench_tps_local_cluster(config: Config) {
|
||||
SocketAddrSpace::Unspecified,
|
||||
);
|
||||
|
||||
let faucet_keypair = Keypair::new();
|
||||
cluster.transfer(
|
||||
&cluster.funding_keypair,
|
||||
&faucet_keypair.pubkey(),
|
||||
100_000_000,
|
||||
);
|
||||
cluster.transfer(&cluster.funding_keypair, &faucet_pubkey, 100_000_000);
|
||||
|
||||
let client = Arc::new(create_client(
|
||||
(cluster.entry_point_info.rpc, cluster.entry_point_info.tpu),
|
||||
VALIDATOR_PORT_RANGE,
|
||||
));
|
||||
|
||||
let (addr_sender, addr_receiver) = unbounded();
|
||||
run_local_faucet_with_port(faucet_keypair, addr_sender, None, 0);
|
||||
let faucet_addr = addr_receiver
|
||||
.recv_timeout(Duration::from_secs(2))
|
||||
.expect("run_local_faucet")
|
||||
.expect("faucet_addr");
|
||||
let client = Arc::new(create_client((
|
||||
cluster.entry_point_info.rpc,
|
||||
cluster.entry_point_info.tpu,
|
||||
)));
|
||||
|
||||
let lamports_per_account = 100;
|
||||
|
||||
let keypair_count = config.tx_count * config.keypair_multiplier;
|
||||
let keypairs = generate_and_fund_keypairs(
|
||||
client.clone(),
|
||||
&config.id,
|
||||
keypair_count,
|
||||
lamports_per_account,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let _total = do_bench_tps(client, config, keypairs);
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
assert!(_total > 100);
|
||||
}
|
||||
|
||||
fn test_bench_tps_test_validator(config: Config) {
|
||||
solana_logger::setup();
|
||||
|
||||
let mint_keypair = Keypair::new();
|
||||
let mint_pubkey = mint_keypair.pubkey();
|
||||
|
||||
let faucet_addr = run_local_faucet(mint_keypair, None);
|
||||
|
||||
let test_validator =
|
||||
TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr), SocketAddrSpace::Unspecified);
|
||||
|
||||
let rpc_client = Arc::new(RpcClient::new_with_commitment(
|
||||
test_validator.rpc_url(),
|
||||
CommitmentConfig::processed(),
|
||||
));
|
||||
let websocket_url = test_validator.rpc_pubsub_url();
|
||||
|
||||
let client =
|
||||
Arc::new(TpuClient::new(rpc_client, &websocket_url, TpuClientConfig::default()).unwrap());
|
||||
|
||||
let lamports_per_account = 100;
|
||||
|
||||
let keypair_count = config.tx_count * config.keypair_multiplier;
|
||||
let keypairs = generate_and_fund_keypairs(
|
||||
client.clone(),
|
||||
Some(faucet_addr),
|
||||
&config.id,
|
||||
keypair_count,
|
||||
lamports_per_account,
|
||||
@@ -84,3 +137,13 @@ fn test_bench_tps_local_cluster_solana() {
|
||||
..Config::default()
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[serial]
|
||||
fn test_bench_tps_tpu_client() {
|
||||
test_bench_tps_test_validator(Config {
|
||||
tx_count: 100,
|
||||
duration: Duration::from_secs(10),
|
||||
..Config::default()
|
||||
});
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-bloom"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana bloom filter"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -17,9 +17,9 @@ rand = "0.7.0"
|
||||
rayon = "1.5.1"
|
||||
serde = { version = "1.0.136", features = ["rc"] }
|
||||
serde_derive = "1.0.103"
|
||||
solana-frozen-abi = { path = "../frozen-abi", version = "=1.10.8" }
|
||||
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-frozen-abi = { path = "../frozen-abi", version = "=1.10.9" }
|
||||
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-bucket-map"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "solana-bucket-map"
|
||||
homepage = "https://solana.com/"
|
||||
documentation = "https://docs.rs/solana-bucket-map"
|
||||
@@ -15,14 +15,14 @@ log = { version = "0.4.11" }
|
||||
memmap2 = "0.5.3"
|
||||
modular-bitfield = "0.11.2"
|
||||
rand = "0.7.0"
|
||||
solana-measure = { path = "../measure", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
tempfile = "3.3.0"
|
||||
|
||||
[dev-dependencies]
|
||||
fs_extra = "1.2.0"
|
||||
rayon = "1.5.0"
|
||||
solana-logger = { path = "../logger", version = "=1.10.8" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.9" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-clap-utils"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana utilities for the clap"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -13,9 +13,9 @@ edition = "2021"
|
||||
chrono = "0.4"
|
||||
clap = "2.33.0"
|
||||
rpassword = "6.0"
|
||||
solana-perf = { path = "../perf", version = "=1.10.8" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "=1.10.8", default-features = false }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-perf = { path = "../perf", version = "=1.10.9" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "=1.10.9", default-features = false }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
thiserror = "1.0.30"
|
||||
tiny-bip39 = "0.8.2"
|
||||
uriparse = "0.6.3"
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-cli-config"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -15,6 +15,8 @@ lazy_static = "1.4.0"
|
||||
serde = "1.0.136"
|
||||
serde_derive = "1.0.103"
|
||||
serde_yaml = "0.8.23"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
url = "2.2.2"
|
||||
|
||||
[dev-dependencies]
|
||||
|
126
cli-config/src/config_input.rs
Normal file
126
cli-config/src/config_input.rs
Normal file
@@ -0,0 +1,126 @@
|
||||
use {
|
||||
crate::Config, solana_clap_utils::input_validators::normalize_to_url_if_moniker,
|
||||
solana_sdk::commitment_config::CommitmentConfig, std::str::FromStr,
|
||||
};
|
||||
|
||||
pub enum SettingType {
|
||||
Explicit,
|
||||
Computed,
|
||||
SystemDefault,
|
||||
}
|
||||
|
||||
pub struct ConfigInput {
|
||||
pub json_rpc_url: String,
|
||||
pub websocket_url: String,
|
||||
pub keypair_path: String,
|
||||
pub commitment: CommitmentConfig,
|
||||
}
|
||||
|
||||
impl ConfigInput {
|
||||
fn default_keypair_path() -> String {
|
||||
Config::default().keypair_path
|
||||
}
|
||||
|
||||
fn default_json_rpc_url() -> String {
|
||||
Config::default().json_rpc_url
|
||||
}
|
||||
|
||||
fn default_websocket_url() -> String {
|
||||
Config::default().websocket_url
|
||||
}
|
||||
|
||||
fn default_commitment() -> CommitmentConfig {
|
||||
CommitmentConfig::confirmed()
|
||||
}
|
||||
|
||||
fn first_nonempty_setting(
|
||||
settings: std::vec::Vec<(SettingType, String)>,
|
||||
) -> (SettingType, String) {
|
||||
settings
|
||||
.into_iter()
|
||||
.find(|(_, value)| !value.is_empty())
|
||||
.expect("no nonempty setting")
|
||||
}
|
||||
|
||||
fn first_setting_is_some<T>(
|
||||
settings: std::vec::Vec<(SettingType, Option<T>)>,
|
||||
) -> (SettingType, T) {
|
||||
let (setting_type, setting_option) = settings
|
||||
.into_iter()
|
||||
.find(|(_, value)| value.is_some())
|
||||
.expect("all settings none");
|
||||
(setting_type, setting_option.unwrap())
|
||||
}
|
||||
|
||||
pub fn compute_websocket_url_setting(
|
||||
websocket_cmd_url: &str,
|
||||
websocket_cfg_url: &str,
|
||||
json_rpc_cmd_url: &str,
|
||||
json_rpc_cfg_url: &str,
|
||||
) -> (SettingType, String) {
|
||||
Self::first_nonempty_setting(vec![
|
||||
(SettingType::Explicit, websocket_cmd_url.to_string()),
|
||||
(SettingType::Explicit, websocket_cfg_url.to_string()),
|
||||
(
|
||||
SettingType::Computed,
|
||||
Config::compute_websocket_url(&normalize_to_url_if_moniker(json_rpc_cmd_url)),
|
||||
),
|
||||
(
|
||||
SettingType::Computed,
|
||||
Config::compute_websocket_url(&normalize_to_url_if_moniker(json_rpc_cfg_url)),
|
||||
),
|
||||
(SettingType::SystemDefault, Self::default_websocket_url()),
|
||||
])
|
||||
}
|
||||
|
||||
pub fn compute_json_rpc_url_setting(
|
||||
json_rpc_cmd_url: &str,
|
||||
json_rpc_cfg_url: &str,
|
||||
) -> (SettingType, String) {
|
||||
let (setting_type, url_or_moniker) = Self::first_nonempty_setting(vec![
|
||||
(SettingType::Explicit, json_rpc_cmd_url.to_string()),
|
||||
(SettingType::Explicit, json_rpc_cfg_url.to_string()),
|
||||
(SettingType::SystemDefault, Self::default_json_rpc_url()),
|
||||
]);
|
||||
(setting_type, normalize_to_url_if_moniker(&url_or_moniker))
|
||||
}
|
||||
|
||||
pub fn compute_keypair_path_setting(
|
||||
keypair_cmd_path: &str,
|
||||
keypair_cfg_path: &str,
|
||||
) -> (SettingType, String) {
|
||||
Self::first_nonempty_setting(vec![
|
||||
(SettingType::Explicit, keypair_cmd_path.to_string()),
|
||||
(SettingType::Explicit, keypair_cfg_path.to_string()),
|
||||
(SettingType::SystemDefault, Self::default_keypair_path()),
|
||||
])
|
||||
}
|
||||
|
||||
pub fn compute_commitment_config(
|
||||
commitment_cmd: &str,
|
||||
commitment_cfg: &str,
|
||||
) -> (SettingType, CommitmentConfig) {
|
||||
Self::first_setting_is_some(vec![
|
||||
(
|
||||
SettingType::Explicit,
|
||||
CommitmentConfig::from_str(commitment_cmd).ok(),
|
||||
),
|
||||
(
|
||||
SettingType::Explicit,
|
||||
CommitmentConfig::from_str(commitment_cfg).ok(),
|
||||
),
|
||||
(SettingType::SystemDefault, Some(Self::default_commitment())),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ConfigInput {
|
||||
fn default() -> ConfigInput {
|
||||
ConfigInput {
|
||||
json_rpc_url: Self::default_json_rpc_url(),
|
||||
websocket_url: Self::default_websocket_url(),
|
||||
keypair_path: Self::default_keypair_path(),
|
||||
commitment: CommitmentConfig::confirmed(),
|
||||
}
|
||||
}
|
||||
}
|
@@ -55,12 +55,16 @@
|
||||
extern crate lazy_static;
|
||||
|
||||
mod config;
|
||||
pub use config::{Config, CONFIG_FILE};
|
||||
mod config_input;
|
||||
use std::{
|
||||
fs::{create_dir_all, File},
|
||||
io::{self, Write},
|
||||
path::Path,
|
||||
};
|
||||
pub use {
|
||||
config::{Config, CONFIG_FILE},
|
||||
config_input::{ConfigInput, SettingType},
|
||||
};
|
||||
|
||||
/// Load a value from a file in YAML format.
|
||||
///
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-cli-output"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -17,14 +17,16 @@ clap = "2.33.0"
|
||||
console = "0.15.0"
|
||||
humantime = "2.0.1"
|
||||
indicatif = "0.16.2"
|
||||
semver = "1.0.6"
|
||||
serde = "1.0.136"
|
||||
serde_json = "1.0.79"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.10.8" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.10.8" }
|
||||
solana-client = { path = "../client", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.10.8" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.10.8" }
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.10.9" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.10.9" }
|
||||
solana-client = { path = "../client", version = "=1.10.9" }
|
||||
solana-cli-config = { path = "../cli-config", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.10.9" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.10.9" }
|
||||
spl-memo = { version = "=3.0.1", features = ["no-entrypoint"] }
|
||||
|
||||
[dev-dependencies]
|
||||
|
@@ -356,6 +356,7 @@ pub enum CliValidatorsSortOrder {
|
||||
SkipRate,
|
||||
Stake,
|
||||
VoteAccount,
|
||||
Version,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
@@ -494,6 +495,22 @@ impl fmt::Display for CliValidators {
|
||||
CliValidatorsSortOrder::Stake => {
|
||||
sorted_validators.sort_by_key(|a| a.activated_stake);
|
||||
}
|
||||
CliValidatorsSortOrder::Version => {
|
||||
sorted_validators.sort_by(|a, b| {
|
||||
use std::cmp::Ordering;
|
||||
let a_version = semver::Version::parse(a.version.as_str()).ok();
|
||||
let b_version = semver::Version::parse(b.version.as_str()).ok();
|
||||
match (a_version, b_version) {
|
||||
(None, None) => a.version.cmp(&b.version),
|
||||
(None, Some(_)) => Ordering::Less,
|
||||
(Some(_), None) => Ordering::Greater,
|
||||
(Some(va), Some(vb)) => match va.cmp(&vb) {
|
||||
Ordering::Equal => a.activated_stake.cmp(&b.activated_stake),
|
||||
ordering => ordering,
|
||||
},
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if self.validators_reverse_sort {
|
||||
|
@@ -3,6 +3,7 @@ use {
|
||||
chrono::{DateTime, Local, NaiveDateTime, SecondsFormat, TimeZone, Utc},
|
||||
console::style,
|
||||
indicatif::{ProgressBar, ProgressStyle},
|
||||
solana_cli_config::SettingType,
|
||||
solana_sdk::{
|
||||
clock::UnixTimestamp,
|
||||
hash::Hash,
|
||||
@@ -103,6 +104,21 @@ pub fn writeln_name_value(f: &mut dyn fmt::Write, name: &str, value: &str) -> fm
|
||||
writeln!(f, "{} {}", style(name).bold(), styled_value)
|
||||
}
|
||||
|
||||
pub fn println_name_value_or(name: &str, value: &str, setting_type: SettingType) {
|
||||
let description = match setting_type {
|
||||
SettingType::Explicit => "",
|
||||
SettingType::Computed => "(computed)",
|
||||
SettingType::SystemDefault => "(default)",
|
||||
};
|
||||
|
||||
println!(
|
||||
"{} {} {}",
|
||||
style(name).bold(),
|
||||
style(value),
|
||||
style(description).italic(),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn format_labeled_address(pubkey: &str, address_labels: &HashMap<String, String>) -> String {
|
||||
let label = address_labels.get(pubkey);
|
||||
match label {
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-cli"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -27,29 +27,29 @@ semver = "1.0.6"
|
||||
serde = "1.0.136"
|
||||
serde_derive = "1.0.103"
|
||||
serde_json = "1.0.79"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.10.8" }
|
||||
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "=1.10.8" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.10.8" }
|
||||
solana-cli-config = { path = "../cli-config", version = "=1.10.8" }
|
||||
solana-cli-output = { path = "../cli-output", version = "=1.10.8" }
|
||||
solana-client = { path = "../client", version = "=1.10.8" }
|
||||
solana-config-program = { path = "../programs/config", version = "=1.10.8" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.10.8" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.8" }
|
||||
solana-program-runtime = { path = "../program-runtime", version = "=1.10.8" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.10.8" }
|
||||
solana-version = { path = "../version", version = "=1.10.8" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.10.8" }
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.10.9" }
|
||||
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "=1.10.9" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.10.9" }
|
||||
solana-cli-config = { path = "../cli-config", version = "=1.10.9" }
|
||||
solana-cli-output = { path = "../cli-output", version = "=1.10.9" }
|
||||
solana-client = { path = "../client", version = "=1.10.9" }
|
||||
solana-config-program = { path = "../programs/config", version = "=1.10.9" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.10.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.9" }
|
||||
solana-program-runtime = { path = "../program-runtime", version = "=1.10.9" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.10.9" }
|
||||
solana-version = { path = "../version", version = "=1.10.9" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.10.9" }
|
||||
solana_rbpf = "=0.2.24"
|
||||
spl-memo = { version = "=3.0.1", features = ["no-entrypoint"] }
|
||||
thiserror = "1.0.30"
|
||||
tiny-bip39 = "0.8.2"
|
||||
|
||||
[dev-dependencies]
|
||||
solana-streamer = { path = "../streamer", version = "=1.10.8" }
|
||||
solana-test-validator = { path = "../test-validator", version = "=1.10.8" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.10.9" }
|
||||
solana-test-validator = { path = "../test-validator", version = "=1.10.9" }
|
||||
tempfile = "3.3.0"
|
||||
|
||||
[[bin]]
|
||||
|
121
cli/src/cli.rs
121
cli/src/cli.rs
@@ -7,7 +7,8 @@ use {
|
||||
log::*,
|
||||
num_traits::FromPrimitive,
|
||||
serde_json::{self, Value},
|
||||
solana_clap_utils::{self, input_parsers::*, input_validators::*, keypair::*},
|
||||
solana_clap_utils::{self, input_parsers::*, keypair::*},
|
||||
solana_cli_config::ConfigInput,
|
||||
solana_cli_output::{
|
||||
display::println_name_value, CliSignature, CliValidatorsSortOrder, OutputFormat,
|
||||
},
|
||||
@@ -456,129 +457,23 @@ impl From<nonce_utils::Error> for CliError {
|
||||
}
|
||||
}
|
||||
|
||||
pub enum SettingType {
|
||||
Explicit,
|
||||
Computed,
|
||||
SystemDefault,
|
||||
}
|
||||
|
||||
pub struct CliConfig<'a> {
|
||||
pub command: CliCommand,
|
||||
pub json_rpc_url: String,
|
||||
pub websocket_url: String,
|
||||
pub signers: Vec<&'a dyn Signer>,
|
||||
pub keypair_path: String,
|
||||
pub commitment: CommitmentConfig,
|
||||
pub signers: Vec<&'a dyn Signer>,
|
||||
pub rpc_client: Option<Arc<RpcClient>>,
|
||||
pub rpc_timeout: Duration,
|
||||
pub verbose: bool,
|
||||
pub output_format: OutputFormat,
|
||||
pub commitment: CommitmentConfig,
|
||||
pub send_transaction_config: RpcSendTransactionConfig,
|
||||
pub confirm_transaction_initial_timeout: Duration,
|
||||
pub address_labels: HashMap<String, String>,
|
||||
}
|
||||
|
||||
impl CliConfig<'_> {
|
||||
fn default_keypair_path() -> String {
|
||||
solana_cli_config::Config::default().keypair_path
|
||||
}
|
||||
|
||||
fn default_json_rpc_url() -> String {
|
||||
solana_cli_config::Config::default().json_rpc_url
|
||||
}
|
||||
|
||||
fn default_websocket_url() -> String {
|
||||
solana_cli_config::Config::default().websocket_url
|
||||
}
|
||||
|
||||
fn default_commitment() -> CommitmentConfig {
|
||||
CommitmentConfig::confirmed()
|
||||
}
|
||||
|
||||
fn first_nonempty_setting(
|
||||
settings: std::vec::Vec<(SettingType, String)>,
|
||||
) -> (SettingType, String) {
|
||||
settings
|
||||
.into_iter()
|
||||
.find(|(_, value)| !value.is_empty())
|
||||
.expect("no nonempty setting")
|
||||
}
|
||||
|
||||
fn first_setting_is_some<T>(
|
||||
settings: std::vec::Vec<(SettingType, Option<T>)>,
|
||||
) -> (SettingType, T) {
|
||||
let (setting_type, setting_option) = settings
|
||||
.into_iter()
|
||||
.find(|(_, value)| value.is_some())
|
||||
.expect("all settings none");
|
||||
(setting_type, setting_option.unwrap())
|
||||
}
|
||||
|
||||
pub fn compute_websocket_url_setting(
|
||||
websocket_cmd_url: &str,
|
||||
websocket_cfg_url: &str,
|
||||
json_rpc_cmd_url: &str,
|
||||
json_rpc_cfg_url: &str,
|
||||
) -> (SettingType, String) {
|
||||
Self::first_nonempty_setting(vec![
|
||||
(SettingType::Explicit, websocket_cmd_url.to_string()),
|
||||
(SettingType::Explicit, websocket_cfg_url.to_string()),
|
||||
(
|
||||
SettingType::Computed,
|
||||
solana_cli_config::Config::compute_websocket_url(&normalize_to_url_if_moniker(
|
||||
json_rpc_cmd_url,
|
||||
)),
|
||||
),
|
||||
(
|
||||
SettingType::Computed,
|
||||
solana_cli_config::Config::compute_websocket_url(&normalize_to_url_if_moniker(
|
||||
json_rpc_cfg_url,
|
||||
)),
|
||||
),
|
||||
(SettingType::SystemDefault, Self::default_websocket_url()),
|
||||
])
|
||||
}
|
||||
|
||||
pub fn compute_json_rpc_url_setting(
|
||||
json_rpc_cmd_url: &str,
|
||||
json_rpc_cfg_url: &str,
|
||||
) -> (SettingType, String) {
|
||||
let (setting_type, url_or_moniker) = Self::first_nonempty_setting(vec![
|
||||
(SettingType::Explicit, json_rpc_cmd_url.to_string()),
|
||||
(SettingType::Explicit, json_rpc_cfg_url.to_string()),
|
||||
(SettingType::SystemDefault, Self::default_json_rpc_url()),
|
||||
]);
|
||||
(setting_type, normalize_to_url_if_moniker(&url_or_moniker))
|
||||
}
|
||||
|
||||
pub fn compute_keypair_path_setting(
|
||||
keypair_cmd_path: &str,
|
||||
keypair_cfg_path: &str,
|
||||
) -> (SettingType, String) {
|
||||
Self::first_nonempty_setting(vec![
|
||||
(SettingType::Explicit, keypair_cmd_path.to_string()),
|
||||
(SettingType::Explicit, keypair_cfg_path.to_string()),
|
||||
(SettingType::SystemDefault, Self::default_keypair_path()),
|
||||
])
|
||||
}
|
||||
|
||||
pub fn compute_commitment_config(
|
||||
commitment_cmd: &str,
|
||||
commitment_cfg: &str,
|
||||
) -> (SettingType, CommitmentConfig) {
|
||||
Self::first_setting_is_some(vec![
|
||||
(
|
||||
SettingType::Explicit,
|
||||
CommitmentConfig::from_str(commitment_cmd).ok(),
|
||||
),
|
||||
(
|
||||
SettingType::Explicit,
|
||||
CommitmentConfig::from_str(commitment_cfg).ok(),
|
||||
),
|
||||
(SettingType::SystemDefault, Some(Self::default_commitment())),
|
||||
])
|
||||
}
|
||||
|
||||
pub(crate) fn pubkey(&self) -> Result<Pubkey, SignerError> {
|
||||
if !self.signers.is_empty() {
|
||||
self.signers[0].try_pubkey()
|
||||
@@ -609,15 +504,15 @@ impl Default for CliConfig<'_> {
|
||||
pubkey: Some(Pubkey::default()),
|
||||
use_lamports_unit: false,
|
||||
},
|
||||
json_rpc_url: Self::default_json_rpc_url(),
|
||||
websocket_url: Self::default_websocket_url(),
|
||||
json_rpc_url: ConfigInput::default().json_rpc_url,
|
||||
websocket_url: ConfigInput::default().websocket_url,
|
||||
keypair_path: ConfigInput::default().keypair_path,
|
||||
commitment: ConfigInput::default().commitment,
|
||||
signers: Vec::new(),
|
||||
keypair_path: Self::default_keypair_path(),
|
||||
rpc_client: None,
|
||||
rpc_timeout: Duration::from_secs(u64::from_str(DEFAULT_RPC_TIMEOUT_SECONDS).unwrap()),
|
||||
verbose: false,
|
||||
output_format: OutputFormat::Display,
|
||||
commitment: CommitmentConfig::confirmed(),
|
||||
send_transaction_config: RpcSendTransactionConfig::default(),
|
||||
confirm_transaction_initial_timeout: Duration::from_secs(
|
||||
u64::from_str(DEFAULT_CONFIRM_TX_TIMEOUT_SECONDS).unwrap(),
|
||||
|
@@ -379,6 +379,7 @@ impl ClusterQuerySubCommands for App<'_, '_> {
|
||||
"root",
|
||||
"skip-rate",
|
||||
"stake",
|
||||
"version",
|
||||
"vote-account",
|
||||
])
|
||||
.default_value("stake")
|
||||
@@ -650,6 +651,7 @@ pub fn parse_show_validators(matches: &ArgMatches<'_>) -> Result<CliCommandInfo,
|
||||
"skip-rate" => CliValidatorsSortOrder::SkipRate,
|
||||
"stake" => CliValidatorsSortOrder::Stake,
|
||||
"vote-account" => CliValidatorsSortOrder::VoteAccount,
|
||||
"version" => CliValidatorsSortOrder::Version,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
|
@@ -8,30 +8,18 @@ use {
|
||||
},
|
||||
solana_cli::{
|
||||
clap_app::get_clap_app,
|
||||
cli::{parse_command, process_command, CliCommandInfo, CliConfig, SettingType},
|
||||
cli::{parse_command, process_command, CliCommandInfo, CliConfig},
|
||||
},
|
||||
solana_cli_config::{Config, ConfigInput},
|
||||
solana_cli_output::{
|
||||
display::{println_name_value, println_name_value_or},
|
||||
OutputFormat,
|
||||
},
|
||||
solana_cli_config::Config,
|
||||
solana_cli_output::{display::println_name_value, OutputFormat},
|
||||
solana_client::rpc_config::RpcSendTransactionConfig,
|
||||
solana_remote_wallet::remote_wallet::RemoteWalletManager,
|
||||
std::{collections::HashMap, error, path::PathBuf, sync::Arc, time::Duration},
|
||||
};
|
||||
|
||||
pub fn println_name_value_or(name: &str, value: &str, setting_type: SettingType) {
|
||||
let description = match setting_type {
|
||||
SettingType::Explicit => "",
|
||||
SettingType::Computed => "(computed)",
|
||||
SettingType::SystemDefault => "(default)",
|
||||
};
|
||||
|
||||
println!(
|
||||
"{} {} {}",
|
||||
style(name).bold(),
|
||||
style(value),
|
||||
style(description).italic(),
|
||||
);
|
||||
}
|
||||
|
||||
fn parse_settings(matches: &ArgMatches<'_>) -> Result<bool, Box<dyn error::Error>> {
|
||||
let parse_args = match matches.subcommand() {
|
||||
("config", Some(matches)) => {
|
||||
@@ -50,17 +38,18 @@ fn parse_settings(matches: &ArgMatches<'_>) -> Result<bool, Box<dyn error::Error
|
||||
match matches.subcommand() {
|
||||
("get", Some(subcommand_matches)) => {
|
||||
let (url_setting_type, json_rpc_url) =
|
||||
CliConfig::compute_json_rpc_url_setting("", &config.json_rpc_url);
|
||||
let (ws_setting_type, websocket_url) = CliConfig::compute_websocket_url_setting(
|
||||
"",
|
||||
&config.websocket_url,
|
||||
"",
|
||||
&config.json_rpc_url,
|
||||
);
|
||||
ConfigInput::compute_json_rpc_url_setting("", &config.json_rpc_url);
|
||||
let (ws_setting_type, websocket_url) =
|
||||
ConfigInput::compute_websocket_url_setting(
|
||||
"",
|
||||
&config.websocket_url,
|
||||
"",
|
||||
&config.json_rpc_url,
|
||||
);
|
||||
let (keypair_setting_type, keypair_path) =
|
||||
CliConfig::compute_keypair_path_setting("", &config.keypair_path);
|
||||
ConfigInput::compute_keypair_path_setting("", &config.keypair_path);
|
||||
let (commitment_setting_type, commitment) =
|
||||
CliConfig::compute_commitment_config("", &config.commitment);
|
||||
ConfigInput::compute_commitment_config("", &config.commitment);
|
||||
|
||||
if let Some(field) = subcommand_matches.value_of("specific_setting") {
|
||||
let (field_name, value, setting_type) = match field {
|
||||
@@ -107,17 +96,18 @@ fn parse_settings(matches: &ArgMatches<'_>) -> Result<bool, Box<dyn error::Error
|
||||
config.save(config_file)?;
|
||||
|
||||
let (url_setting_type, json_rpc_url) =
|
||||
CliConfig::compute_json_rpc_url_setting("", &config.json_rpc_url);
|
||||
let (ws_setting_type, websocket_url) = CliConfig::compute_websocket_url_setting(
|
||||
"",
|
||||
&config.websocket_url,
|
||||
"",
|
||||
&config.json_rpc_url,
|
||||
);
|
||||
ConfigInput::compute_json_rpc_url_setting("", &config.json_rpc_url);
|
||||
let (ws_setting_type, websocket_url) =
|
||||
ConfigInput::compute_websocket_url_setting(
|
||||
"",
|
||||
&config.websocket_url,
|
||||
"",
|
||||
&config.json_rpc_url,
|
||||
);
|
||||
let (keypair_setting_type, keypair_path) =
|
||||
CliConfig::compute_keypair_path_setting("", &config.keypair_path);
|
||||
ConfigInput::compute_keypair_path_setting("", &config.keypair_path);
|
||||
let (commitment_setting_type, commitment) =
|
||||
CliConfig::compute_commitment_config("", &config.commitment);
|
||||
ConfigInput::compute_commitment_config("", &config.commitment);
|
||||
|
||||
println_name_value("Config File:", config_file);
|
||||
println_name_value_or("RPC URL:", &json_rpc_url, url_setting_type);
|
||||
@@ -158,7 +148,7 @@ pub fn parse_args<'a>(
|
||||
} else {
|
||||
Config::default()
|
||||
};
|
||||
let (_, json_rpc_url) = CliConfig::compute_json_rpc_url_setting(
|
||||
let (_, json_rpc_url) = ConfigInput::compute_json_rpc_url_setting(
|
||||
matches.value_of("json_rpc_url").unwrap_or(""),
|
||||
&config.json_rpc_url,
|
||||
);
|
||||
@@ -171,14 +161,14 @@ pub fn parse_args<'a>(
|
||||
let confirm_transaction_initial_timeout =
|
||||
Duration::from_secs(confirm_transaction_initial_timeout);
|
||||
|
||||
let (_, websocket_url) = CliConfig::compute_websocket_url_setting(
|
||||
let (_, websocket_url) = ConfigInput::compute_websocket_url_setting(
|
||||
matches.value_of("websocket_url").unwrap_or(""),
|
||||
&config.websocket_url,
|
||||
matches.value_of("json_rpc_url").unwrap_or(""),
|
||||
&config.json_rpc_url,
|
||||
);
|
||||
let default_signer_arg_name = "keypair".to_string();
|
||||
let (_, default_signer_path) = CliConfig::compute_keypair_path_setting(
|
||||
let (_, default_signer_path) = ConfigInput::compute_keypair_path_setting(
|
||||
matches.value_of(&default_signer_arg_name).unwrap_or(""),
|
||||
&config.keypair_path,
|
||||
);
|
||||
@@ -201,7 +191,7 @@ pub fn parse_args<'a>(
|
||||
let verbose = matches.is_present("verbose");
|
||||
let output_format = OutputFormat::from_matches(matches, "output_format", verbose);
|
||||
|
||||
let (_, commitment) = CliConfig::compute_commitment_config(
|
||||
let (_, commitment) = ConfigInput::compute_commitment_config(
|
||||
matches.value_of("commitment").unwrap_or(""),
|
||||
&config.commitment,
|
||||
);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-client-test"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana RPC Test"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -14,25 +14,25 @@ publish = false
|
||||
futures-util = "0.3.21"
|
||||
serde_json = "1.0.79"
|
||||
serial_test = "0.6.0"
|
||||
solana-client = { path = "../client", version = "=1.10.8" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.10.8" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.8" }
|
||||
solana-merkle-tree = { path = "../merkle-tree", version = "=1.10.8" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.10.8" }
|
||||
solana-perf = { path = "../perf", version = "=1.10.8" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.10.8" }
|
||||
solana-rpc = { path = "../rpc", version = "=1.10.8" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.10.8" }
|
||||
solana-test-validator = { path = "../test-validator", version = "=1.10.8" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.10.8" }
|
||||
solana-version = { path = "../version", version = "=1.10.8" }
|
||||
solana-client = { path = "../client", version = "=1.10.9" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.10.9" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.9" }
|
||||
solana-merkle-tree = { path = "../merkle-tree", version = "=1.10.9" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.10.9" }
|
||||
solana-perf = { path = "../perf", version = "=1.10.9" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.10.9" }
|
||||
solana-rpc = { path = "../rpc", version = "=1.10.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.10.9" }
|
||||
solana-test-validator = { path = "../test-validator", version = "=1.10.9" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.10.9" }
|
||||
solana-version = { path = "../version", version = "=1.10.9" }
|
||||
systemstat = "0.1.10"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
|
||||
[dev-dependencies]
|
||||
solana-logger = { path = "../logger", version = "=1.10.8" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.9" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-client"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana Client"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -25,7 +25,9 @@ itertools = "0.10.2"
|
||||
jsonrpc-core = "18.0.0"
|
||||
lazy_static = "1.4.0"
|
||||
log = "0.4.14"
|
||||
lru = "0.7.5"
|
||||
quinn = "0.8.0"
|
||||
quinn-proto = "0.8.0"
|
||||
rand = "0.7.0"
|
||||
rand_chacha = "0.2.2"
|
||||
rayon = "1.5.1"
|
||||
@@ -35,16 +37,17 @@ semver = "1.0.6"
|
||||
serde = "1.0.136"
|
||||
serde_derive = "1.0.103"
|
||||
serde_json = "1.0.79"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.10.8" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.10.8" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.10.8" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.8" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.10.8" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.10.8" }
|
||||
solana-version = { path = "../version", version = "=1.10.8" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.10.8" }
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.10.9" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.10.9" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.10.9" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.9" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.10.9" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.10.9" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.10.9" }
|
||||
solana-version = { path = "../version", version = "=1.10.9" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.10.9" }
|
||||
thiserror = "1.0"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
tokio-stream = "0.1.8"
|
||||
@@ -55,7 +58,7 @@ url = "2.2.2"
|
||||
[dev-dependencies]
|
||||
assert_matches = "1.5.0"
|
||||
jsonrpc-http-server = "18.0.0"
|
||||
solana-logger = { path = "../logger", version = "=1.10.8" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.9" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -1,13 +1,21 @@
|
||||
use {
|
||||
crate::{
|
||||
quic_client::QuicTpuConnection, tpu_connection::TpuConnection, udp_client::UdpTpuConnection,
|
||||
quic_client::QuicTpuConnection,
|
||||
tpu_connection::{ClientStats, TpuConnection},
|
||||
udp_client::UdpTpuConnection,
|
||||
},
|
||||
lazy_static::lazy_static,
|
||||
solana_sdk::{transaction::VersionedTransaction, transport::TransportError},
|
||||
lru::LruCache,
|
||||
solana_net_utils::VALIDATOR_PORT_RANGE,
|
||||
solana_sdk::{
|
||||
timing::AtomicInterval, transaction::VersionedTransaction, transport::TransportError,
|
||||
},
|
||||
std::{
|
||||
collections::{hash_map::Entry, BTreeMap, HashMap},
|
||||
net::{SocketAddr, UdpSocket},
|
||||
sync::{Arc, Mutex},
|
||||
net::{IpAddr, Ipv4Addr, SocketAddr},
|
||||
sync::{
|
||||
atomic::{AtomicU64, Ordering},
|
||||
Arc, Mutex,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -20,27 +28,108 @@ enum Connection {
|
||||
Quic(Arc<QuicTpuConnection>),
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct ConnectionCacheStats {
|
||||
cache_hits: AtomicU64,
|
||||
cache_misses: AtomicU64,
|
||||
sent_packets: AtomicU64,
|
||||
total_batches: AtomicU64,
|
||||
batch_success: AtomicU64,
|
||||
batch_failure: AtomicU64,
|
||||
|
||||
// Need to track these separately per-connection
|
||||
// because we need to track the base stat value from quinn
|
||||
total_client_stats: ClientStats,
|
||||
}
|
||||
|
||||
const CONNECTION_STAT_SUBMISSION_INTERVAL: u64 = 2000;
|
||||
|
||||
impl ConnectionCacheStats {
|
||||
fn add_client_stats(&self, client_stats: &ClientStats, num_packets: usize, is_success: bool) {
|
||||
self.total_client_stats.total_connections.fetch_add(
|
||||
client_stats.total_connections.load(Ordering::Relaxed),
|
||||
Ordering::Relaxed,
|
||||
);
|
||||
self.total_client_stats.connection_reuse.fetch_add(
|
||||
client_stats.connection_reuse.load(Ordering::Relaxed),
|
||||
Ordering::Relaxed,
|
||||
);
|
||||
self.sent_packets
|
||||
.fetch_add(num_packets as u64, Ordering::Relaxed);
|
||||
self.total_batches.fetch_add(1, Ordering::Relaxed);
|
||||
if is_success {
|
||||
self.batch_success.fetch_add(1, Ordering::Relaxed);
|
||||
} else {
|
||||
self.batch_failure.fetch_add(1, Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
fn report(&self) {
|
||||
datapoint_info!(
|
||||
"quic-client-connection-stats",
|
||||
(
|
||||
"cache_hits",
|
||||
self.cache_hits.swap(0, Ordering::Relaxed),
|
||||
i64
|
||||
),
|
||||
(
|
||||
"cache_misses",
|
||||
self.cache_misses.swap(0, Ordering::Relaxed),
|
||||
i64
|
||||
),
|
||||
(
|
||||
"total_connections",
|
||||
self.total_client_stats
|
||||
.total_connections
|
||||
.swap(0, Ordering::Relaxed),
|
||||
i64
|
||||
),
|
||||
(
|
||||
"connection_reuse",
|
||||
self.total_client_stats
|
||||
.connection_reuse
|
||||
.swap(0, Ordering::Relaxed),
|
||||
i64
|
||||
),
|
||||
(
|
||||
"congestion_events",
|
||||
self.total_client_stats.congestion_events.load_and_reset(),
|
||||
i64
|
||||
),
|
||||
(
|
||||
"tx_streams_blocked_uni",
|
||||
self.total_client_stats
|
||||
.tx_streams_blocked_uni
|
||||
.load_and_reset(),
|
||||
i64
|
||||
),
|
||||
(
|
||||
"tx_data_blocked",
|
||||
self.total_client_stats.tx_data_blocked.load_and_reset(),
|
||||
i64
|
||||
),
|
||||
(
|
||||
"tx_acks",
|
||||
self.total_client_stats.tx_acks.load_and_reset(),
|
||||
i64
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
struct ConnMap {
|
||||
// Keeps track of the connection associated with an addr and the last time it was used
|
||||
map: HashMap<SocketAddr, (Connection, u64)>,
|
||||
// Helps to find the least recently used connection. The search and inserts are O(log(n))
|
||||
// but since we're bounding the size of the collections, this should be constant
|
||||
// (and hopefully negligible) time. In theory, we can do this in constant time
|
||||
// with a queue implemented as a doubly-linked list (and all the
|
||||
// HashMap entries holding a "pointer" to the corresponding linked-list node),
|
||||
// so we can push, pop and bump a used connection back to the end of the queue in O(1) time, but
|
||||
// that seems non-"Rust-y" and low bang/buck. This is still pretty terrible though...
|
||||
last_used_times: BTreeMap<u64, SocketAddr>,
|
||||
ticks: u64,
|
||||
map: LruCache<SocketAddr, Connection>,
|
||||
stats: Arc<ConnectionCacheStats>,
|
||||
last_stats: AtomicInterval,
|
||||
use_quic: bool,
|
||||
}
|
||||
|
||||
impl ConnMap {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
map: HashMap::new(),
|
||||
last_used_times: BTreeMap::new(),
|
||||
ticks: 0,
|
||||
map: LruCache::new(MAX_CONNECTIONS),
|
||||
stats: Arc::new(ConnectionCacheStats::default()),
|
||||
last_stats: AtomicInterval::default(),
|
||||
use_quic: false,
|
||||
}
|
||||
}
|
||||
@@ -59,53 +148,75 @@ pub fn set_use_quic(use_quic: bool) {
|
||||
map.set_use_quic(use_quic);
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
// TODO: see https://github.com/solana-labs/solana/issues/23661
|
||||
// remove lazy_static and optimize and refactor this
|
||||
fn get_connection(addr: &SocketAddr) -> Connection {
|
||||
fn get_connection(addr: &SocketAddr) -> (Connection, Arc<ConnectionCacheStats>) {
|
||||
let mut map = (*CONNECTION_MAP).lock().unwrap();
|
||||
let ticks = map.ticks;
|
||||
let use_quic = map.use_quic;
|
||||
let (conn, target_ticks) = match map.map.entry(*addr) {
|
||||
Entry::Occupied(mut entry) => {
|
||||
let mut pair = entry.get_mut();
|
||||
let old_ticks = pair.1;
|
||||
pair.1 = ticks;
|
||||
(pair.0.clone(), old_ticks)
|
||||
}
|
||||
Entry::Vacant(entry) => {
|
||||
let send_socket = UdpSocket::bind("0.0.0.0:0").unwrap();
|
||||
// TODO: see https://github.com/solana-labs/solana/issues/23659
|
||||
// make it configurable (e.g. via the command line) whether to use UDP or Quic
|
||||
|
||||
let conn = if use_quic {
|
||||
if map
|
||||
.last_stats
|
||||
.should_update(CONNECTION_STAT_SUBMISSION_INTERVAL)
|
||||
{
|
||||
map.stats.report();
|
||||
}
|
||||
|
||||
let (connection, hit, maybe_stats) = match map.map.get(addr) {
|
||||
Some(connection) => {
|
||||
let mut stats = None;
|
||||
// update connection stats
|
||||
if let Connection::Quic(conn) = connection {
|
||||
stats = conn.stats().map(|s| (conn.base_stats(), s));
|
||||
}
|
||||
(connection.clone(), true, stats)
|
||||
}
|
||||
None => {
|
||||
let (_, send_socket) = solana_net_utils::bind_in_range(
|
||||
IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)),
|
||||
VALIDATOR_PORT_RANGE,
|
||||
)
|
||||
.unwrap();
|
||||
let connection = if map.use_quic {
|
||||
Connection::Quic(Arc::new(QuicTpuConnection::new(send_socket, *addr)))
|
||||
} else {
|
||||
Connection::Udp(Arc::new(UdpTpuConnection::new(send_socket, *addr)))
|
||||
};
|
||||
|
||||
entry.insert((conn.clone(), ticks));
|
||||
(conn, ticks)
|
||||
map.map.put(*addr, connection.clone());
|
||||
(connection, false, None)
|
||||
}
|
||||
};
|
||||
|
||||
let num_connections = map.map.len();
|
||||
if num_connections > MAX_CONNECTIONS {
|
||||
let (old_ticks, target_addr) = {
|
||||
let (old_ticks, target_addr) = map.last_used_times.iter().next().unwrap();
|
||||
(*old_ticks, *target_addr)
|
||||
};
|
||||
map.map.remove(&target_addr);
|
||||
map.last_used_times.remove(&old_ticks);
|
||||
if let Some((connection_stats, new_stats)) = maybe_stats {
|
||||
map.stats.total_client_stats.congestion_events.update_stat(
|
||||
&connection_stats.congestion_events,
|
||||
new_stats.path.congestion_events,
|
||||
);
|
||||
|
||||
map.stats
|
||||
.total_client_stats
|
||||
.tx_streams_blocked_uni
|
||||
.update_stat(
|
||||
&connection_stats.tx_streams_blocked_uni,
|
||||
new_stats.frame_tx.streams_blocked_uni,
|
||||
);
|
||||
|
||||
map.stats.total_client_stats.tx_data_blocked.update_stat(
|
||||
&connection_stats.tx_data_blocked,
|
||||
new_stats.frame_tx.data_blocked,
|
||||
);
|
||||
|
||||
map.stats
|
||||
.total_client_stats
|
||||
.tx_acks
|
||||
.update_stat(&connection_stats.tx_acks, new_stats.frame_tx.acks);
|
||||
}
|
||||
|
||||
if target_ticks != ticks {
|
||||
map.last_used_times.remove(&target_ticks);
|
||||
if hit {
|
||||
map.stats.cache_hits.fetch_add(1, Ordering::Relaxed);
|
||||
} else {
|
||||
map.stats.cache_misses.fetch_add(1, Ordering::Relaxed);
|
||||
}
|
||||
map.last_used_times.insert(ticks, *addr);
|
||||
|
||||
map.ticks += 1;
|
||||
conn
|
||||
(connection, map.stats.clone())
|
||||
}
|
||||
|
||||
// TODO: see https://github.com/solana-labs/solana/issues/23851
|
||||
@@ -121,44 +232,67 @@ pub fn send_wire_transaction_batch(
|
||||
packets: &[&[u8]],
|
||||
addr: &SocketAddr,
|
||||
) -> Result<(), TransportError> {
|
||||
let conn = get_connection(addr);
|
||||
match conn {
|
||||
Connection::Udp(conn) => conn.send_wire_transaction_batch(packets),
|
||||
Connection::Quic(conn) => conn.send_wire_transaction_batch(packets),
|
||||
}
|
||||
let (conn, stats) = get_connection(addr);
|
||||
let client_stats = ClientStats::default();
|
||||
let r = match conn {
|
||||
Connection::Udp(conn) => conn.send_wire_transaction_batch(packets, &client_stats),
|
||||
Connection::Quic(conn) => conn.send_wire_transaction_batch(packets, &client_stats),
|
||||
};
|
||||
stats.add_client_stats(&client_stats, packets.len(), r.is_ok());
|
||||
r
|
||||
}
|
||||
|
||||
pub fn send_wire_transaction_async(
|
||||
packets: Vec<u8>,
|
||||
addr: &SocketAddr,
|
||||
) -> Result<(), TransportError> {
|
||||
let (conn, stats) = get_connection(addr);
|
||||
let client_stats = Arc::new(ClientStats::default());
|
||||
let r = match conn {
|
||||
Connection::Udp(conn) => conn.send_wire_transaction_async(packets, client_stats.clone()),
|
||||
Connection::Quic(conn) => conn.send_wire_transaction_async(packets, client_stats.clone()),
|
||||
};
|
||||
stats.add_client_stats(&client_stats, 1, r.is_ok());
|
||||
r
|
||||
}
|
||||
|
||||
pub fn send_wire_transaction(
|
||||
wire_transaction: &[u8],
|
||||
addr: &SocketAddr,
|
||||
) -> Result<(), TransportError> {
|
||||
let conn = get_connection(addr);
|
||||
match conn {
|
||||
Connection::Udp(conn) => conn.send_wire_transaction(wire_transaction),
|
||||
Connection::Quic(conn) => conn.send_wire_transaction(wire_transaction),
|
||||
}
|
||||
send_wire_transaction_batch(&[wire_transaction], addr)
|
||||
}
|
||||
|
||||
pub fn serialize_and_send_transaction(
|
||||
transaction: &VersionedTransaction,
|
||||
addr: &SocketAddr,
|
||||
) -> Result<(), TransportError> {
|
||||
let conn = get_connection(addr);
|
||||
match conn {
|
||||
Connection::Udp(conn) => conn.serialize_and_send_transaction(transaction),
|
||||
Connection::Quic(conn) => conn.serialize_and_send_transaction(transaction),
|
||||
}
|
||||
let (conn, stats) = get_connection(addr);
|
||||
let client_stats = ClientStats::default();
|
||||
let r = match conn {
|
||||
Connection::Udp(conn) => conn.serialize_and_send_transaction(transaction, &client_stats),
|
||||
Connection::Quic(conn) => conn.serialize_and_send_transaction(transaction, &client_stats),
|
||||
};
|
||||
stats.add_client_stats(&client_stats, 1, r.is_ok());
|
||||
r
|
||||
}
|
||||
|
||||
pub fn par_serialize_and_send_transaction_batch(
|
||||
transactions: &[VersionedTransaction],
|
||||
addr: &SocketAddr,
|
||||
) -> Result<(), TransportError> {
|
||||
let conn = get_connection(addr);
|
||||
match conn {
|
||||
Connection::Udp(conn) => conn.par_serialize_and_send_transaction_batch(transactions),
|
||||
Connection::Quic(conn) => conn.par_serialize_and_send_transaction_batch(transactions),
|
||||
}
|
||||
let (conn, stats) = get_connection(addr);
|
||||
let client_stats = ClientStats::default();
|
||||
let r = match conn {
|
||||
Connection::Udp(conn) => {
|
||||
conn.par_serialize_and_send_transaction_batch(transactions, &client_stats)
|
||||
}
|
||||
Connection::Quic(conn) => {
|
||||
conn.par_serialize_and_send_transaction_batch(transactions, &client_stats)
|
||||
}
|
||||
};
|
||||
stats.add_client_stats(&client_stats, transactions.len(), r.is_ok());
|
||||
r
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -206,7 +340,7 @@ mod tests {
|
||||
// be lazy and not connect until first use or handle connection errors somehow
|
||||
// (without crashing, as would be required in a real practical validator)
|
||||
let first_addr = get_addr(&mut rng);
|
||||
assert!(ip(get_connection(&first_addr)) == first_addr.ip());
|
||||
assert!(ip(get_connection(&first_addr).0) == first_addr.ip());
|
||||
let addrs = (0..MAX_CONNECTIONS)
|
||||
.into_iter()
|
||||
.map(|_| {
|
||||
@@ -218,11 +352,11 @@ mod tests {
|
||||
{
|
||||
let map = (*CONNECTION_MAP).lock().unwrap();
|
||||
addrs.iter().for_each(|a| {
|
||||
let conn = map.map.get(a).expect("Address not found");
|
||||
assert!(a.ip() == ip(conn.0.clone()));
|
||||
let conn = map.map.peek(a).expect("Address not found");
|
||||
assert!(a.ip() == ip(conn.clone()));
|
||||
});
|
||||
|
||||
assert!(map.map.get(&first_addr).is_none());
|
||||
assert!(map.map.peek(&first_addr).is_none());
|
||||
}
|
||||
|
||||
// Test that get_connection updates which connection is next up for eviction
|
||||
@@ -235,7 +369,7 @@ mod tests {
|
||||
get_connection(&get_addr(&mut rng));
|
||||
|
||||
let map = (*CONNECTION_MAP).lock().unwrap();
|
||||
assert!(map.map.get(&addrs[0]).is_some());
|
||||
assert!(map.map.get(&addrs[1]).is_none());
|
||||
assert!(map.map.peek(&addrs[0]).is_some());
|
||||
assert!(map.map.peek(&addrs[1]).is_none());
|
||||
}
|
||||
}
|
||||
|
@@ -197,6 +197,10 @@ impl RpcSender for HttpSender {
|
||||
return Ok(json["result"].take());
|
||||
}
|
||||
}
|
||||
|
||||
fn url(&self) -> String {
|
||||
self.url.clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@@ -9,7 +9,6 @@ pub(crate) mod http_sender;
|
||||
pub(crate) mod mock_sender;
|
||||
pub mod nonblocking;
|
||||
pub mod nonce_utils;
|
||||
pub mod perf_utils;
|
||||
pub mod pubsub_client;
|
||||
pub mod quic_client;
|
||||
pub mod rpc_cache;
|
||||
@@ -28,6 +27,9 @@ pub mod tpu_connection;
|
||||
pub mod transaction_executor;
|
||||
pub mod udp_client;
|
||||
|
||||
#[macro_use]
|
||||
extern crate solana_metrics;
|
||||
|
||||
pub mod mock_sender_for_cli {
|
||||
/// Magic `SIGNATURE` value used by `solana-cli` unit tests.
|
||||
/// Please don't use this constant.
|
||||
|
@@ -468,4 +468,8 @@ impl RpcSender for MockSender {
|
||||
};
|
||||
Ok(val)
|
||||
}
|
||||
|
||||
fn url(&self) -> String {
|
||||
format!("MockSender: {}", self.url)
|
||||
}
|
||||
}
|
||||
|
@@ -502,6 +502,11 @@ impl RpcClient {
|
||||
Self::new_with_timeout(url, timeout)
|
||||
}
|
||||
|
||||
/// Get the configured url of the client's sender
|
||||
pub fn url(&self) -> String {
|
||||
self.sender.url()
|
||||
}
|
||||
|
||||
async fn get_node_version(&self) -> Result<semver::Version, RpcError> {
|
||||
let r_node_version = self.node_version.read().await;
|
||||
if let Some(version) = &*r_node_version {
|
||||
|
@@ -2,18 +2,24 @@
|
||||
//! an interface for sending transactions which is restricted by the server's flow control.
|
||||
|
||||
use {
|
||||
crate::{client_error::ClientErrorKind, tpu_connection::TpuConnection},
|
||||
crate::{
|
||||
client_error::ClientErrorKind,
|
||||
tpu_connection::{ClientStats, TpuConnection},
|
||||
},
|
||||
async_mutex::Mutex,
|
||||
futures::future::join_all,
|
||||
itertools::Itertools,
|
||||
lazy_static::lazy_static,
|
||||
log::*,
|
||||
quinn::{ClientConfig, Endpoint, EndpointConfig, NewConnection, WriteError},
|
||||
quinn_proto::ConnectionStats,
|
||||
solana_sdk::{
|
||||
quic::{QUIC_MAX_CONCURRENT_STREAMS, QUIC_PORT_OFFSET},
|
||||
transport::Result as TransportResult,
|
||||
},
|
||||
std::{
|
||||
net::{SocketAddr, UdpSocket},
|
||||
sync::Arc,
|
||||
sync::{atomic::Ordering, Arc},
|
||||
},
|
||||
tokio::runtime::Runtime,
|
||||
};
|
||||
@@ -39,18 +45,34 @@ impl rustls::client::ServerCertVerifier for SkipServerVerification {
|
||||
Ok(rustls::client::ServerCertVerified::assertion())
|
||||
}
|
||||
}
|
||||
lazy_static! {
|
||||
static ref RUNTIME: Runtime = tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
struct QuicClient {
|
||||
runtime: Runtime,
|
||||
endpoint: Endpoint,
|
||||
connection: Arc<Mutex<Option<Arc<NewConnection>>>>,
|
||||
addr: SocketAddr,
|
||||
stats: Arc<ClientStats>,
|
||||
}
|
||||
|
||||
pub struct QuicTpuConnection {
|
||||
client: Arc<QuicClient>,
|
||||
}
|
||||
|
||||
impl QuicTpuConnection {
|
||||
pub fn stats(&self) -> Option<ConnectionStats> {
|
||||
self.client.stats()
|
||||
}
|
||||
|
||||
pub fn base_stats(&self) -> Arc<ClientStats> {
|
||||
self.client.stats.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl TpuConnection for QuicTpuConnection {
|
||||
fn new(client_socket: UdpSocket, tpu_addr: SocketAddr) -> Self {
|
||||
let tpu_addr = SocketAddr::new(tpu_addr.ip(), tpu_addr.port() + QUIC_PORT_OFFSET);
|
||||
@@ -63,35 +85,59 @@ impl TpuConnection for QuicTpuConnection {
|
||||
&self.client.addr
|
||||
}
|
||||
|
||||
fn send_wire_transaction<T>(&self, wire_transaction: T) -> TransportResult<()>
|
||||
fn send_wire_transaction<T>(
|
||||
&self,
|
||||
wire_transaction: T,
|
||||
stats: &ClientStats,
|
||||
) -> TransportResult<()>
|
||||
where
|
||||
T: AsRef<[u8]>,
|
||||
{
|
||||
let _guard = self.client.runtime.enter();
|
||||
let send_buffer = self.client.send_buffer(wire_transaction);
|
||||
self.client.runtime.block_on(send_buffer)?;
|
||||
let _guard = RUNTIME.enter();
|
||||
let send_buffer = self.client.send_buffer(wire_transaction, stats);
|
||||
RUNTIME.block_on(send_buffer)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn send_wire_transaction_batch<T>(&self, buffers: &[T]) -> TransportResult<()>
|
||||
fn send_wire_transaction_batch<T>(
|
||||
&self,
|
||||
buffers: &[T],
|
||||
stats: &ClientStats,
|
||||
) -> TransportResult<()>
|
||||
where
|
||||
T: AsRef<[u8]>,
|
||||
{
|
||||
let _guard = self.client.runtime.enter();
|
||||
let send_batch = self.client.send_batch(buffers);
|
||||
self.client.runtime.block_on(send_batch)?;
|
||||
let _guard = RUNTIME.enter();
|
||||
let send_batch = self.client.send_batch(buffers, stats);
|
||||
RUNTIME.block_on(send_batch)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn send_wire_transaction_async(
|
||||
&self,
|
||||
wire_transaction: Vec<u8>,
|
||||
stats: Arc<ClientStats>,
|
||||
) -> TransportResult<()> {
|
||||
let _guard = RUNTIME.enter();
|
||||
//drop and detach the task
|
||||
let client = self.client.clone();
|
||||
inc_new_counter_info!("send_wire_transaction_async", 1);
|
||||
let _ = RUNTIME.spawn(async move {
|
||||
let send_buffer = client.send_buffer(wire_transaction, &stats);
|
||||
if let Err(e) = send_buffer.await {
|
||||
inc_new_counter_warn!("send_wire_transaction_async_fail", 1);
|
||||
warn!("Failed to send transaction async to {:?}", e);
|
||||
} else {
|
||||
inc_new_counter_info!("send_wire_transaction_async_pass", 1);
|
||||
}
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl QuicClient {
|
||||
pub fn new(client_socket: UdpSocket, addr: SocketAddr) -> Self {
|
||||
let runtime = tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let _guard = runtime.enter();
|
||||
let _guard = RUNTIME.enter();
|
||||
|
||||
let crypto = rustls::ClientConfig::builder()
|
||||
.with_safe_defaults()
|
||||
@@ -100,18 +146,24 @@ impl QuicClient {
|
||||
|
||||
let create_endpoint = QuicClient::create_endpoint(EndpointConfig::default(), client_socket);
|
||||
|
||||
let mut endpoint = runtime.block_on(create_endpoint);
|
||||
let mut endpoint = RUNTIME.block_on(create_endpoint);
|
||||
|
||||
endpoint.set_default_client_config(ClientConfig::new(Arc::new(crypto)));
|
||||
|
||||
Self {
|
||||
runtime,
|
||||
endpoint,
|
||||
connection: Arc::new(Mutex::new(None)),
|
||||
addr,
|
||||
stats: Arc::new(ClientStats::default()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn stats(&self) -> Option<ConnectionStats> {
|
||||
let conn_guard = self.connection.lock();
|
||||
let x = RUNTIME.block_on(conn_guard);
|
||||
x.as_ref().map(|c| c.connection.stats())
|
||||
}
|
||||
|
||||
// If this function becomes public, it should be changed to
|
||||
// not expose details of the specific Quic implementation we're using
|
||||
async fn create_endpoint(config: EndpointConfig, client_socket: UdpSocket) -> Endpoint {
|
||||
@@ -128,18 +180,35 @@ impl QuicClient {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn make_connection(&self, stats: &ClientStats) -> Result<Arc<NewConnection>, WriteError> {
|
||||
let connecting = self.endpoint.connect(self.addr, "connect").unwrap();
|
||||
stats.total_connections.fetch_add(1, Ordering::Relaxed);
|
||||
let connecting_result = connecting.await;
|
||||
if connecting_result.is_err() {
|
||||
stats.connection_errors.fetch_add(1, Ordering::Relaxed);
|
||||
}
|
||||
let connection = connecting_result?;
|
||||
Ok(Arc::new(connection))
|
||||
}
|
||||
|
||||
// Attempts to send data, connecting/reconnecting as necessary
|
||||
// On success, returns the connection used to successfully send the data
|
||||
async fn _send_buffer(&self, data: &[u8]) -> Result<Arc<NewConnection>, WriteError> {
|
||||
async fn _send_buffer(
|
||||
&self,
|
||||
data: &[u8],
|
||||
stats: &ClientStats,
|
||||
) -> Result<Arc<NewConnection>, WriteError> {
|
||||
let connection = {
|
||||
let mut conn_guard = self.connection.lock().await;
|
||||
|
||||
let maybe_conn = (*conn_guard).clone();
|
||||
match maybe_conn {
|
||||
Some(conn) => conn.clone(),
|
||||
Some(conn) => {
|
||||
stats.connection_reuse.fetch_add(1, Ordering::Relaxed);
|
||||
conn.clone()
|
||||
}
|
||||
None => {
|
||||
let connecting = self.endpoint.connect(self.addr, "connect").unwrap();
|
||||
let connection = Arc::new(connecting.await?);
|
||||
let connection = self.make_connection(stats).await?;
|
||||
*conn_guard = Some(connection.clone());
|
||||
connection
|
||||
}
|
||||
@@ -149,8 +218,7 @@ impl QuicClient {
|
||||
Ok(()) => Ok(connection),
|
||||
_ => {
|
||||
let connection = {
|
||||
let connecting = self.endpoint.connect(self.addr, "connect").unwrap();
|
||||
let connection = Arc::new(connecting.await?);
|
||||
let connection = self.make_connection(stats).await?;
|
||||
let mut conn_guard = self.connection.lock().await;
|
||||
*conn_guard = Some(connection.clone());
|
||||
connection
|
||||
@@ -161,15 +229,19 @@ impl QuicClient {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn send_buffer<T>(&self, data: T) -> Result<(), ClientErrorKind>
|
||||
pub async fn send_buffer<T>(&self, data: T, stats: &ClientStats) -> Result<(), ClientErrorKind>
|
||||
where
|
||||
T: AsRef<[u8]>,
|
||||
{
|
||||
self._send_buffer(data.as_ref()).await?;
|
||||
self._send_buffer(data.as_ref(), stats).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn send_batch<T>(&self, buffers: &[T]) -> Result<(), ClientErrorKind>
|
||||
pub async fn send_batch<T>(
|
||||
&self,
|
||||
buffers: &[T],
|
||||
stats: &ClientStats,
|
||||
) -> Result<(), ClientErrorKind>
|
||||
where
|
||||
T: AsRef<[u8]>,
|
||||
{
|
||||
@@ -187,7 +259,7 @@ impl QuicClient {
|
||||
if buffers.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
let connection = self._send_buffer(buffers[0].as_ref()).await?;
|
||||
let connection = self._send_buffer(buffers[0].as_ref(), stats).await?;
|
||||
|
||||
// Used to avoid dereferencing the Arc multiple times below
|
||||
// by just getting a reference to the NewConnection once
|
||||
|
@@ -535,6 +535,11 @@ impl RpcClient {
|
||||
Self::new_with_timeout(url, timeout)
|
||||
}
|
||||
|
||||
/// Get the configured url of the client's sender
|
||||
pub fn url(&self) -> String {
|
||||
self.rpc_client.url()
|
||||
}
|
||||
|
||||
/// Get the configured default [commitment level][cl].
|
||||
///
|
||||
/// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
|
||||
|
@@ -32,4 +32,5 @@ pub trait RpcSender {
|
||||
params: serde_json::Value,
|
||||
) -> Result<serde_json::Value>;
|
||||
fn get_transport_stats(&self) -> RpcTransportStats;
|
||||
fn url(&self) -> String;
|
||||
}
|
||||
|
@@ -5,8 +5,13 @@
|
||||
|
||||
use {
|
||||
crate::{
|
||||
rpc_client::RpcClient, rpc_config::RpcProgramAccountsConfig, rpc_response::Response,
|
||||
tpu_connection::TpuConnection, udp_client::UdpTpuConnection,
|
||||
connection_cache::{
|
||||
par_serialize_and_send_transaction_batch, send_wire_transaction,
|
||||
serialize_and_send_transaction,
|
||||
},
|
||||
rpc_client::RpcClient,
|
||||
rpc_config::RpcProgramAccountsConfig,
|
||||
rpc_response::Response,
|
||||
},
|
||||
log::*,
|
||||
solana_sdk::{
|
||||
@@ -29,7 +34,7 @@ use {
|
||||
},
|
||||
std::{
|
||||
io,
|
||||
net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket},
|
||||
net::SocketAddr,
|
||||
sync::{
|
||||
atomic::{AtomicBool, AtomicUsize, Ordering},
|
||||
RwLock,
|
||||
@@ -118,67 +123,55 @@ impl ClientOptimizer {
|
||||
}
|
||||
|
||||
/// An object for querying and sending transactions to the network.
|
||||
pub struct ThinClient<C: 'static + TpuConnection> {
|
||||
pub struct ThinClient {
|
||||
rpc_clients: Vec<RpcClient>,
|
||||
tpu_connections: Vec<C>,
|
||||
tpu_addrs: Vec<SocketAddr>,
|
||||
optimizer: ClientOptimizer,
|
||||
}
|
||||
|
||||
impl<C: 'static + TpuConnection> ThinClient<C> {
|
||||
impl ThinClient {
|
||||
/// Create a new ThinClient that will interface with the Rpc at `rpc_addr` using TCP
|
||||
/// and the Tpu at `tpu_addr` over `transactions_socket` using Quic or UDP
|
||||
/// (currently hardcoded to UDP)
|
||||
pub fn new(rpc_addr: SocketAddr, tpu_addr: SocketAddr, transactions_socket: UdpSocket) -> Self {
|
||||
let tpu_connection = C::new(transactions_socket, tpu_addr);
|
||||
|
||||
Self::new_from_client(RpcClient::new_socket(rpc_addr), tpu_connection)
|
||||
pub fn new(rpc_addr: SocketAddr, tpu_addr: SocketAddr) -> Self {
|
||||
Self::new_from_client(RpcClient::new_socket(rpc_addr), tpu_addr)
|
||||
}
|
||||
|
||||
pub fn new_socket_with_timeout(
|
||||
rpc_addr: SocketAddr,
|
||||
tpu_addr: SocketAddr,
|
||||
transactions_socket: UdpSocket,
|
||||
timeout: Duration,
|
||||
) -> Self {
|
||||
let rpc_client = RpcClient::new_socket_with_timeout(rpc_addr, timeout);
|
||||
let tpu_connection = C::new(transactions_socket, tpu_addr);
|
||||
Self::new_from_client(rpc_client, tpu_connection)
|
||||
Self::new_from_client(rpc_client, tpu_addr)
|
||||
}
|
||||
|
||||
fn new_from_client(rpc_client: RpcClient, tpu_connection: C) -> Self {
|
||||
fn new_from_client(rpc_client: RpcClient, tpu_addr: SocketAddr) -> Self {
|
||||
Self {
|
||||
rpc_clients: vec![rpc_client],
|
||||
tpu_connections: vec![tpu_connection],
|
||||
tpu_addrs: vec![tpu_addr],
|
||||
optimizer: ClientOptimizer::new(0),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_from_addrs(
|
||||
rpc_addrs: Vec<SocketAddr>,
|
||||
tpu_addrs: Vec<SocketAddr>,
|
||||
transactions_socket: UdpSocket,
|
||||
) -> Self {
|
||||
pub fn new_from_addrs(rpc_addrs: Vec<SocketAddr>, tpu_addrs: Vec<SocketAddr>) -> Self {
|
||||
assert!(!rpc_addrs.is_empty());
|
||||
assert_eq!(rpc_addrs.len(), tpu_addrs.len());
|
||||
|
||||
let rpc_clients: Vec<_> = rpc_addrs.into_iter().map(RpcClient::new_socket).collect();
|
||||
let optimizer = ClientOptimizer::new(rpc_clients.len());
|
||||
let tpu_connections: Vec<_> = tpu_addrs
|
||||
.into_iter()
|
||||
.map(|tpu_addr| C::new(transactions_socket.try_clone().unwrap(), tpu_addr))
|
||||
.collect();
|
||||
Self {
|
||||
rpc_clients,
|
||||
tpu_connections,
|
||||
tpu_addrs,
|
||||
optimizer,
|
||||
}
|
||||
}
|
||||
|
||||
fn tpu_connection(&self) -> &C {
|
||||
&self.tpu_connections[self.optimizer.best()]
|
||||
fn tpu_addr(&self) -> &SocketAddr {
|
||||
&self.tpu_addrs[self.optimizer.best()]
|
||||
}
|
||||
|
||||
fn rpc_client(&self) -> &RpcClient {
|
||||
pub fn rpc_client(&self) -> &RpcClient {
|
||||
&self.rpc_clients[self.optimizer.best()]
|
||||
}
|
||||
|
||||
@@ -220,8 +213,7 @@ impl<C: 'static + TpuConnection> ThinClient<C> {
|
||||
while now.elapsed().as_secs() < wait_time as u64 {
|
||||
if num_confirmed == 0 {
|
||||
// Send the transaction if there has been no confirmation (e.g. the first time)
|
||||
self.tpu_connection()
|
||||
.send_wire_transaction(&wire_transaction)?;
|
||||
send_wire_transaction(&wire_transaction, self.tpu_addr())?;
|
||||
}
|
||||
|
||||
if let Ok(confirmed_blocks) = self.poll_for_signature_confirmation(
|
||||
@@ -316,13 +308,13 @@ impl<C: 'static + TpuConnection> ThinClient<C> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<C: 'static + TpuConnection> Client for ThinClient<C> {
|
||||
impl Client for ThinClient {
|
||||
fn tpu_addr(&self) -> String {
|
||||
self.tpu_connection().tpu_addr().to_string()
|
||||
self.tpu_addr().to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl<C: 'static + TpuConnection> SyncClient for ThinClient<C> {
|
||||
impl SyncClient for ThinClient {
|
||||
fn send_and_confirm_message<T: Signers>(
|
||||
&self,
|
||||
keypairs: &T,
|
||||
@@ -602,18 +594,16 @@ impl<C: 'static + TpuConnection> SyncClient for ThinClient<C> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<C: 'static + TpuConnection> AsyncClient for ThinClient<C> {
|
||||
impl AsyncClient for ThinClient {
|
||||
fn async_send_transaction(&self, transaction: Transaction) -> TransportResult<Signature> {
|
||||
let transaction = VersionedTransaction::from(transaction);
|
||||
self.tpu_connection()
|
||||
.serialize_and_send_transaction(&transaction)?;
|
||||
serialize_and_send_transaction(&transaction, self.tpu_addr())?;
|
||||
Ok(transaction.signatures[0])
|
||||
}
|
||||
|
||||
fn async_send_batch(&self, transactions: Vec<Transaction>) -> TransportResult<()> {
|
||||
let batch: Vec<VersionedTransaction> = transactions.into_iter().map(Into::into).collect();
|
||||
self.tpu_connection()
|
||||
.par_serialize_and_send_transaction_batch(&batch[..])?;
|
||||
par_serialize_and_send_transaction_batch(&batch[..], self.tpu_addr())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -648,23 +638,15 @@ impl<C: 'static + TpuConnection> AsyncClient for ThinClient<C> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_client(
|
||||
(rpc, tpu): (SocketAddr, SocketAddr),
|
||||
range: (u16, u16),
|
||||
) -> ThinClient<UdpTpuConnection> {
|
||||
let (_, transactions_socket) =
|
||||
solana_net_utils::bind_in_range(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), range).unwrap();
|
||||
ThinClient::<UdpTpuConnection>::new(rpc, tpu, transactions_socket)
|
||||
pub fn create_client((rpc, tpu): (SocketAddr, SocketAddr)) -> ThinClient {
|
||||
ThinClient::new(rpc, tpu)
|
||||
}
|
||||
|
||||
pub fn create_client_with_timeout(
|
||||
(rpc, tpu): (SocketAddr, SocketAddr),
|
||||
range: (u16, u16),
|
||||
timeout: Duration,
|
||||
) -> ThinClient<UdpTpuConnection> {
|
||||
let (_, transactions_socket) =
|
||||
solana_net_utils::bind_in_range(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), range).unwrap();
|
||||
ThinClient::<UdpTpuConnection>::new_socket_with_timeout(rpc, tpu, transactions_socket, timeout)
|
||||
) -> ThinClient {
|
||||
ThinClient::new_socket_with_timeout(rpc, tpu, timeout)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@@ -1,6 +1,7 @@
|
||||
use {
|
||||
crate::{
|
||||
client_error::ClientError,
|
||||
connection_cache::send_wire_transaction_async,
|
||||
pubsub_client::{PubsubClient, PubsubClientError, PubsubClientSubscription},
|
||||
rpc_client::RpcClient,
|
||||
rpc_request::MAX_GET_SIGNATURE_STATUSES_QUERY_ITEMS,
|
||||
@@ -17,6 +18,7 @@ use {
|
||||
signature::SignerError,
|
||||
signers::Signers,
|
||||
transaction::{Transaction, TransactionError},
|
||||
transport::{Result as TransportResult, TransportError},
|
||||
},
|
||||
std::{
|
||||
collections::{HashMap, HashSet, VecDeque},
|
||||
@@ -73,7 +75,7 @@ impl Default for TpuClientConfig {
|
||||
/// Client which sends transactions directly to the current leader's TPU port over UDP.
|
||||
/// The client uses RPC to determine the current leader and fetch node contact info
|
||||
pub struct TpuClient {
|
||||
send_socket: UdpSocket,
|
||||
_deprecated: UdpSocket, // TpuClient now uses the connection_cache to choose a send_socket
|
||||
fanout_slots: u64,
|
||||
leader_tpu_service: LeaderTpuService,
|
||||
exit: Arc<AtomicBool>,
|
||||
@@ -85,25 +87,48 @@ impl TpuClient {
|
||||
/// size
|
||||
pub fn send_transaction(&self, transaction: &Transaction) -> bool {
|
||||
let wire_transaction = serialize(transaction).expect("serialization should succeed");
|
||||
self.send_wire_transaction(&wire_transaction)
|
||||
self.send_wire_transaction(wire_transaction)
|
||||
}
|
||||
|
||||
/// Send a wire transaction to the current and upcoming leader TPUs according to fanout size
|
||||
pub fn send_wire_transaction(&self, wire_transaction: &[u8]) -> bool {
|
||||
let mut sent = false;
|
||||
pub fn send_wire_transaction(&self, wire_transaction: Vec<u8>) -> bool {
|
||||
self.try_send_wire_transaction(wire_transaction).is_ok()
|
||||
}
|
||||
|
||||
/// Serialize and send transaction to the current and upcoming leader TPUs according to fanout
|
||||
/// size
|
||||
/// Returns the last error if all sends fail
|
||||
pub fn try_send_transaction(&self, transaction: &Transaction) -> TransportResult<()> {
|
||||
let wire_transaction = serialize(transaction).expect("serialization should succeed");
|
||||
self.try_send_wire_transaction(wire_transaction)
|
||||
}
|
||||
|
||||
/// Send a wire transaction to the current and upcoming leader TPUs according to fanout size
|
||||
/// Returns the last error if all sends fail
|
||||
fn try_send_wire_transaction(&self, wire_transaction: Vec<u8>) -> TransportResult<()> {
|
||||
let mut last_error: Option<TransportError> = None;
|
||||
let mut some_success = false;
|
||||
|
||||
for tpu_address in self
|
||||
.leader_tpu_service
|
||||
.leader_tpu_sockets(self.fanout_slots)
|
||||
{
|
||||
if self
|
||||
.send_socket
|
||||
.send_to(wire_transaction, tpu_address)
|
||||
.is_ok()
|
||||
{
|
||||
sent = true;
|
||||
let result = send_wire_transaction_async(wire_transaction.clone(), &tpu_address);
|
||||
if let Err(err) = result {
|
||||
last_error = Some(err);
|
||||
} else {
|
||||
some_success = true;
|
||||
}
|
||||
}
|
||||
sent
|
||||
if !some_success {
|
||||
Err(if let Some(err) = last_error {
|
||||
err
|
||||
} else {
|
||||
std::io::Error::new(std::io::ErrorKind::Other, "No sends attempted").into()
|
||||
})
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new client that disconnects when dropped
|
||||
@@ -117,7 +142,7 @@ impl TpuClient {
|
||||
LeaderTpuService::new(rpc_client.clone(), websocket_url, exit.clone())?;
|
||||
|
||||
Ok(Self {
|
||||
send_socket: UdpSocket::bind("0.0.0.0:0").unwrap(),
|
||||
_deprecated: UdpSocket::bind("0.0.0.0:0").unwrap(),
|
||||
fanout_slots: config.fanout_slots.min(MAX_FANOUT_SLOTS).max(1),
|
||||
leader_tpu_service,
|
||||
exit,
|
||||
@@ -266,6 +291,10 @@ impl TpuClient {
|
||||
}
|
||||
Err(TpuSenderError::Custom("Max retries exceeded".into()))
|
||||
}
|
||||
|
||||
pub fn rpc_client(&self) -> &RpcClient {
|
||||
&self.rpc_client
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TpuClient {
|
||||
|
@@ -1,9 +1,26 @@
|
||||
use {
|
||||
rayon::iter::{IntoParallelIterator, ParallelIterator},
|
||||
solana_metrics::MovingStat,
|
||||
solana_sdk::{transaction::VersionedTransaction, transport::Result as TransportResult},
|
||||
std::net::{SocketAddr, UdpSocket},
|
||||
std::{
|
||||
net::{SocketAddr, UdpSocket},
|
||||
sync::{atomic::AtomicU64, Arc},
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct ClientStats {
|
||||
pub total_connections: AtomicU64,
|
||||
pub connection_reuse: AtomicU64,
|
||||
pub connection_errors: AtomicU64,
|
||||
|
||||
// these will be the last values of these stats
|
||||
pub congestion_events: MovingStat,
|
||||
pub tx_streams_blocked_uni: MovingStat,
|
||||
pub tx_data_blocked: MovingStat,
|
||||
pub tx_acks: MovingStat,
|
||||
}
|
||||
|
||||
pub trait TpuConnection {
|
||||
fn new(client_socket: UdpSocket, tpu_addr: SocketAddr) -> Self;
|
||||
|
||||
@@ -12,29 +29,45 @@ pub trait TpuConnection {
|
||||
fn serialize_and_send_transaction(
|
||||
&self,
|
||||
transaction: &VersionedTransaction,
|
||||
stats: &ClientStats,
|
||||
) -> TransportResult<()> {
|
||||
let wire_transaction =
|
||||
bincode::serialize(transaction).expect("serialize Transaction in send_batch");
|
||||
self.send_wire_transaction(&wire_transaction)
|
||||
self.send_wire_transaction(&wire_transaction, stats)
|
||||
}
|
||||
|
||||
fn send_wire_transaction<T>(&self, wire_transaction: T) -> TransportResult<()>
|
||||
fn send_wire_transaction<T>(
|
||||
&self,
|
||||
wire_transaction: T,
|
||||
stats: &ClientStats,
|
||||
) -> TransportResult<()>
|
||||
where
|
||||
T: AsRef<[u8]>;
|
||||
|
||||
fn send_wire_transaction_async(
|
||||
&self,
|
||||
wire_transaction: Vec<u8>,
|
||||
stats: Arc<ClientStats>,
|
||||
) -> TransportResult<()>;
|
||||
|
||||
fn par_serialize_and_send_transaction_batch(
|
||||
&self,
|
||||
transactions: &[VersionedTransaction],
|
||||
stats: &ClientStats,
|
||||
) -> TransportResult<()> {
|
||||
let buffers = transactions
|
||||
.into_par_iter()
|
||||
.map(|tx| bincode::serialize(&tx).expect("serialize Transaction in send_batch"))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
self.send_wire_transaction_batch(&buffers)
|
||||
self.send_wire_transaction_batch(&buffers, stats)
|
||||
}
|
||||
|
||||
fn send_wire_transaction_batch<T>(&self, buffers: &[T]) -> TransportResult<()>
|
||||
fn send_wire_transaction_batch<T>(
|
||||
&self,
|
||||
buffers: &[T],
|
||||
stats: &ClientStats,
|
||||
) -> TransportResult<()>
|
||||
where
|
||||
T: AsRef<[u8]>;
|
||||
}
|
||||
|
@@ -2,11 +2,14 @@
|
||||
//! an interface for sending transactions
|
||||
|
||||
use {
|
||||
crate::tpu_connection::TpuConnection,
|
||||
crate::tpu_connection::{ClientStats, TpuConnection},
|
||||
core::iter::repeat,
|
||||
solana_sdk::transport::Result as TransportResult,
|
||||
solana_streamer::sendmmsg::batch_send,
|
||||
std::net::{SocketAddr, UdpSocket},
|
||||
std::{
|
||||
net::{SocketAddr, UdpSocket},
|
||||
sync::Arc,
|
||||
},
|
||||
};
|
||||
|
||||
pub struct UdpTpuConnection {
|
||||
@@ -26,7 +29,11 @@ impl TpuConnection for UdpTpuConnection {
|
||||
&self.addr
|
||||
}
|
||||
|
||||
fn send_wire_transaction<T>(&self, wire_transaction: T) -> TransportResult<()>
|
||||
fn send_wire_transaction<T>(
|
||||
&self,
|
||||
wire_transaction: T,
|
||||
_stats: &ClientStats,
|
||||
) -> TransportResult<()>
|
||||
where
|
||||
T: AsRef<[u8]>,
|
||||
{
|
||||
@@ -34,7 +41,20 @@ impl TpuConnection for UdpTpuConnection {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn send_wire_transaction_batch<T>(&self, buffers: &[T]) -> TransportResult<()>
|
||||
fn send_wire_transaction_async(
|
||||
&self,
|
||||
wire_transaction: Vec<u8>,
|
||||
_stats: Arc<ClientStats>,
|
||||
) -> TransportResult<()> {
|
||||
self.socket.send_to(wire_transaction.as_ref(), self.addr)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn send_wire_transaction_batch<T>(
|
||||
&self,
|
||||
buffers: &[T],
|
||||
_stats: &ClientStats,
|
||||
) -> TransportResult<()>
|
||||
where
|
||||
T: AsRef<[u8]>,
|
||||
{
|
||||
|
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "solana-core"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
homepage = "https://solana.com/"
|
||||
documentation = "https://docs.rs/solana-core"
|
||||
readme = "../README.md"
|
||||
@@ -33,30 +33,30 @@ rayon = "1.5.1"
|
||||
retain_mut = "0.1.7"
|
||||
serde = "1.0.136"
|
||||
serde_derive = "1.0.103"
|
||||
solana-address-lookup-table-program = { path = "../programs/address-lookup-table", version = "=1.10.8" }
|
||||
solana-bloom = { path = "../bloom", version = "=1.10.8" }
|
||||
solana-client = { path = "../client", version = "=1.10.8" }
|
||||
solana-entry = { path = "../entry", version = "=1.10.8" }
|
||||
solana-frozen-abi = { path = "../frozen-abi", version = "=1.10.8" }
|
||||
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.10.8" }
|
||||
solana-geyser-plugin-manager = { path = "../geyser-plugin-manager", version = "=1.10.8" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.10.8" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.10.8" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.8" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.10.8" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.10.8" }
|
||||
solana-perf = { path = "../perf", version = "=1.10.8" }
|
||||
solana-poh = { path = "../poh", version = "=1.10.8" }
|
||||
solana-program-runtime = { path = "../program-runtime", version = "=1.10.8" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.10.8" }
|
||||
solana-replica-lib = { path = "../replica-lib", version = "=1.10.8" }
|
||||
solana-rpc = { path = "../rpc", version = "=1.10.8" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-send-transaction-service = { path = "../send-transaction-service", version = "=1.10.8" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.10.8" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.10.8" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.10.8" }
|
||||
solana-address-lookup-table-program = { path = "../programs/address-lookup-table", version = "=1.10.9" }
|
||||
solana-bloom = { path = "../bloom", version = "=1.10.9" }
|
||||
solana-client = { path = "../client", version = "=1.10.9" }
|
||||
solana-entry = { path = "../entry", version = "=1.10.9" }
|
||||
solana-frozen-abi = { path = "../frozen-abi", version = "=1.10.9" }
|
||||
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.10.9" }
|
||||
solana-geyser-plugin-manager = { path = "../geyser-plugin-manager", version = "=1.10.9" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.10.9" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.10.9" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.9" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.10.9" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.10.9" }
|
||||
solana-perf = { path = "../perf", version = "=1.10.9" }
|
||||
solana-poh = { path = "../poh", version = "=1.10.9" }
|
||||
solana-program-runtime = { path = "../program-runtime", version = "=1.10.9" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.10.9" }
|
||||
solana-replica-lib = { path = "../replica-lib", version = "=1.10.9" }
|
||||
solana-rpc = { path = "../rpc", version = "=1.10.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
solana-send-transaction-service = { path = "../send-transaction-service", version = "=1.10.9" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.10.9" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.10.9" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.10.9" }
|
||||
sys-info = "0.9.1"
|
||||
tempfile = "3.3.0"
|
||||
thiserror = "1.0"
|
||||
@@ -69,10 +69,10 @@ raptorq = "1.6.5"
|
||||
reqwest = { version = "0.11.10", default-features = false, features = ["blocking", "rustls-tls", "json"] }
|
||||
serde_json = "1.0.79"
|
||||
serial_test = "0.6.0"
|
||||
solana-logger = { path = "../logger", version = "=1.10.8" }
|
||||
solana-program-runtime = { path = "../program-runtime", version = "=1.10.8" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "=1.10.8" }
|
||||
solana-version = { path = "../version", version = "=1.10.8" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.9" }
|
||||
solana-program-runtime = { path = "../program-runtime", version = "=1.10.9" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "=1.10.9" }
|
||||
solana-version = { path = "../version", version = "=1.10.9" }
|
||||
static_assertions = "1.1.0"
|
||||
systemstat = "0.1.10"
|
||||
|
||||
|
@@ -24,7 +24,6 @@ impl LeaderExecuteAndCommitTimings {
|
||||
saturating_add_assign!(self.record_us, other.record_us);
|
||||
saturating_add_assign!(self.commit_us, other.commit_us);
|
||||
saturating_add_assign!(self.find_and_send_votes_us, other.find_and_send_votes_us);
|
||||
saturating_add_assign!(self.commit_us, other.commit_us);
|
||||
self.record_transactions_timings
|
||||
.accumulate(&other.record_transactions_timings);
|
||||
self.execute_timings.accumulate(&other.execute_timings);
|
||||
|
@@ -3059,7 +3059,7 @@ curl http://localhost:8899 -X POST -H "Content-Type: application/json" -d '
|
||||
Result:
|
||||
|
||||
```json
|
||||
{ "jsonrpc": "2.0", "result": { "solana-core": "1.10.8" }, "id": 1 }
|
||||
{ "jsonrpc": "2.0", "result": { "solana-core": "1.10.9" }, "id": 1 }
|
||||
```
|
||||
|
||||
### getVoteAccounts
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-dos"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -15,18 +15,18 @@ clap = {version = "3.1.5", features = ["derive", "cargo"]}
|
||||
log = "0.4.14"
|
||||
rand = "0.7.0"
|
||||
serde = "1.0.136"
|
||||
solana-client = { path = "../client", version = "=1.10.8" }
|
||||
solana-core = { path = "../core", version = "=1.10.8" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.10.8" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.8" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.10.8" }
|
||||
solana-perf = { path = "../perf", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.10.8" }
|
||||
solana-version = { path = "../version", version = "=1.10.8" }
|
||||
solana-client = { path = "../client", version = "=1.10.9" }
|
||||
solana-core = { path = "../core", version = "=1.10.9" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.10.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.9" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.10.9" }
|
||||
solana-perf = { path = "../perf", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.10.9" }
|
||||
solana-version = { path = "../version", version = "=1.10.9" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
||||
[dev-dependencies]
|
||||
solana-local-cluster = { path = "../local-cluster", version = "=1.10.8" }
|
||||
solana-local-cluster = { path = "../local-cluster", version = "=1.10.9" }
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-download-utils"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana Download Utils"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -14,8 +14,8 @@ console = "0.15.0"
|
||||
indicatif = "0.16.2"
|
||||
log = "0.4.14"
|
||||
reqwest = { version = "0.11.10", default-features = false, features = ["blocking", "rustls-tls", "json"] }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-entry"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana Entry"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -18,16 +18,16 @@ log = "0.4.11"
|
||||
rand = "0.7.0"
|
||||
rayon = "1.5.1"
|
||||
serde = "1.0.136"
|
||||
solana-measure = { path = "../measure", version = "=1.10.8" }
|
||||
solana-merkle-tree = { path = "../merkle-tree", version = "=1.10.8" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.10.8" }
|
||||
solana-perf = { path = "../perf", version = "=1.10.8" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.9" }
|
||||
solana-merkle-tree = { path = "../merkle-tree", version = "=1.10.9" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.10.9" }
|
||||
solana-perf = { path = "../perf", version = "=1.10.9" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
|
||||
[dev-dependencies]
|
||||
matches = "0.1.9"
|
||||
solana-logger = { path = "../logger", version = "=1.10.8" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.9" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-faucet"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana Faucet"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -17,12 +17,12 @@ crossbeam-channel = "0.5"
|
||||
log = "0.4.14"
|
||||
serde = "1.0.136"
|
||||
serde_derive = "1.0.103"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.10.8" }
|
||||
solana-cli-config = { path = "../cli-config", version = "=1.10.8" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.8" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-version = { path = "../version", version = "=1.10.8" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.10.9" }
|
||||
solana-cli-config = { path = "../cli-config", version = "=1.10.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.9" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
solana-version = { path = "../version", version = "=1.10.9" }
|
||||
spl-memo = { version = "=3.0.1", features = ["no-entrypoint"] }
|
||||
thiserror = "1.0"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-frozen-abi"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana Frozen ABI"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -18,7 +18,7 @@ serde = "1.0.136"
|
||||
serde_derive = "1.0.103"
|
||||
serde_bytes = "0.11"
|
||||
sha2 = "0.10.2"
|
||||
solana-frozen-abi-macro = { path = "macro", version = "=1.10.8" }
|
||||
solana-frozen-abi-macro = { path = "macro", version = "=1.10.9" }
|
||||
thiserror = "1.0"
|
||||
|
||||
[target.'cfg(not(target_arch = "bpf"))'.dependencies]
|
||||
@@ -27,7 +27,7 @@ im = { version = "15.0.0", features = ["rayon", "serde"] }
|
||||
memmap2 = "0.5.3"
|
||||
|
||||
[target.'cfg(not(target_arch = "bpf"))'.dev-dependencies]
|
||||
solana-logger = { path = "../logger", version = "=1.10.8" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.9" }
|
||||
|
||||
[build-dependencies]
|
||||
rustc_version = "0.4"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-frozen-abi-macro"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana Frozen ABI Macro"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-genesis-utils"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana Genesis Utils"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -10,9 +10,9 @@ documentation = "https://docs.rs/solana-download-utils"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
solana-download-utils = { path = "../download-utils", version = "=1.10.8" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-download-utils = { path = "../download-utils", version = "=1.10.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-genesis"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -15,16 +15,16 @@ clap = "2.33.1"
|
||||
serde = "1.0.136"
|
||||
serde_json = "1.0.79"
|
||||
serde_yaml = "0.8.23"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.10.8" }
|
||||
solana-cli-config = { path = "../cli-config", version = "=1.10.8" }
|
||||
solana-entry = { path = "../entry", version = "=1.10.8" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.10.8" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.8" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "=1.10.8" }
|
||||
solana-version = { path = "../version", version = "=1.10.8" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.10.8" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.10.9" }
|
||||
solana-cli-config = { path = "../cli-config", version = "=1.10.9" }
|
||||
solana-entry = { path = "../entry", version = "=1.10.9" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.10.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "=1.10.9" }
|
||||
solana-version = { path = "../version", version = "=1.10.9" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.10.9" }
|
||||
tempfile = "3.3.0"
|
||||
|
||||
[[bin]]
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-geyser-plugin-interface"
|
||||
description = "The Solana Geyser plugin interface."
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -11,8 +11,8 @@ documentation = "https://docs.rs/solana-geyser-plugin-interface"
|
||||
|
||||
[dependencies]
|
||||
log = "0.4.11"
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.10.9" }
|
||||
thiserror = "1.0.30"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-geyser-plugin-manager"
|
||||
description = "The Solana Geyser plugin manager."
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -16,13 +16,13 @@ json5 = "0.4.1"
|
||||
libloading = "0.7.3"
|
||||
log = "0.4.11"
|
||||
serde_json = "1.0.79"
|
||||
solana-geyser-plugin-interface = { path = "../geyser-plugin-interface", version = "=1.10.8" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.8" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.10.8" }
|
||||
solana-rpc = { path = "../rpc", version = "=1.10.8" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.10.8" }
|
||||
solana-geyser-plugin-interface = { path = "../geyser-plugin-interface", version = "=1.10.9" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.9" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.10.9" }
|
||||
solana-rpc = { path = "../rpc", version = "=1.10.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.10.9" }
|
||||
thiserror = "1.0.30"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-gossip"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -27,24 +27,24 @@ rayon = "1.5.1"
|
||||
serde = "1.0.136"
|
||||
serde_bytes = "0.11"
|
||||
serde_derive = "1.0.103"
|
||||
solana-bloom = { path = "../bloom", version = "=1.10.8" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.10.8" }
|
||||
solana-client = { path = "../client", version = "=1.10.8" }
|
||||
solana-entry = { path = "../entry", version = "=1.10.8" }
|
||||
solana-frozen-abi = { path = "../frozen-abi", version = "=1.10.8" }
|
||||
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.10.8" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.10.8" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.8" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.8" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.10.8" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.10.8" }
|
||||
solana-perf = { path = "../perf", version = "=1.10.8" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.10.8" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.10.8" }
|
||||
solana-version = { path = "../version", version = "=1.10.8" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.10.8" }
|
||||
solana-bloom = { path = "../bloom", version = "=1.10.9" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.10.9" }
|
||||
solana-client = { path = "../client", version = "=1.10.9" }
|
||||
solana-entry = { path = "../entry", version = "=1.10.9" }
|
||||
solana-frozen-abi = { path = "../frozen-abi", version = "=1.10.9" }
|
||||
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.10.9" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.10.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.9" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.9" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.10.9" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.10.9" }
|
||||
solana-perf = { path = "../perf", version = "=1.10.9" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.10.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.10.9" }
|
||||
solana-version = { path = "../version", version = "=1.10.9" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.10.9" }
|
||||
thiserror = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
|
@@ -12,6 +12,13 @@
|
||||
//! * layer 2 - Everyone else, if layer 1 is `2^10`, layer 2 should be able to fit `2^20` number of nodes.
|
||||
//!
|
||||
//! Bank needs to provide an interface for us to query the stake weight
|
||||
|
||||
#[deprecated(
|
||||
since = "1.10.6",
|
||||
note = "Please use `solana_net_utils::{MINIMUM_VALIDATOR_PORT_RANGE_WIDTH, VALIDATOR_PORT_RANGE}` instead"
|
||||
)]
|
||||
#[allow(deprecated)]
|
||||
pub use solana_net_utils::{MINIMUM_VALIDATOR_PORT_RANGE_WIDTH, VALIDATOR_PORT_RANGE};
|
||||
use {
|
||||
crate::{
|
||||
cluster_info_metrics::{
|
||||
@@ -92,9 +99,6 @@ use {
|
||||
},
|
||||
};
|
||||
|
||||
pub const VALIDATOR_PORT_RANGE: PortRange = (8000, 10_000);
|
||||
pub const MINIMUM_VALIDATOR_PORT_RANGE_WIDTH: u16 = 12; // VALIDATOR_PORT_RANGE must be at least this wide
|
||||
|
||||
/// The Data plane fanout size, also used as the neighborhood size
|
||||
pub const DATA_PLANE_FANOUT: usize = 200;
|
||||
/// milliseconds we sleep for between gossip requests
|
||||
@@ -3075,6 +3079,7 @@ mod tests {
|
||||
rand::{seq::SliceRandom, SeedableRng},
|
||||
rand_chacha::ChaChaRng,
|
||||
solana_ledger::shred::Shredder,
|
||||
solana_net_utils::MINIMUM_VALIDATOR_PORT_RANGE_WIDTH,
|
||||
solana_sdk::signature::{Keypair, Signer},
|
||||
solana_vote_program::{vote_instruction, vote_state::Vote},
|
||||
std::{
|
||||
|
@@ -1,16 +1,10 @@
|
||||
//! The `gossip_service` module implements the network control plane.
|
||||
|
||||
use {
|
||||
crate::{
|
||||
cluster_info::{ClusterInfo, VALIDATOR_PORT_RANGE},
|
||||
contact_info::ContactInfo,
|
||||
},
|
||||
crate::{cluster_info::ClusterInfo, contact_info::ContactInfo},
|
||||
crossbeam_channel::{unbounded, Sender},
|
||||
rand::{thread_rng, Rng},
|
||||
solana_client::{
|
||||
thin_client::{create_client, ThinClient},
|
||||
udp_client::UdpTpuConnection,
|
||||
},
|
||||
solana_client::thin_client::{create_client, ThinClient},
|
||||
solana_perf::recycler::Recycler,
|
||||
solana_runtime::bank_forks::BankForks,
|
||||
solana_sdk::{
|
||||
@@ -20,7 +14,7 @@ use {
|
||||
solana_streamer::{socket::SocketAddrSpace, streamer},
|
||||
std::{
|
||||
collections::HashSet,
|
||||
net::{IpAddr, Ipv4Addr, SocketAddr, TcpListener, UdpSocket},
|
||||
net::{SocketAddr, TcpListener, UdpSocket},
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc, RwLock,
|
||||
@@ -197,51 +191,37 @@ pub fn discover(
|
||||
}
|
||||
|
||||
/// Creates a ThinClient per valid node
|
||||
pub fn get_clients(
|
||||
nodes: &[ContactInfo],
|
||||
socket_addr_space: &SocketAddrSpace,
|
||||
) -> Vec<ThinClient<UdpTpuConnection>> {
|
||||
pub fn get_clients(nodes: &[ContactInfo], socket_addr_space: &SocketAddrSpace) -> Vec<ThinClient> {
|
||||
nodes
|
||||
.iter()
|
||||
.filter_map(|node| ContactInfo::valid_client_facing_addr(node, socket_addr_space))
|
||||
.map(|addrs| create_client(addrs, VALIDATOR_PORT_RANGE))
|
||||
.map(create_client)
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Creates a ThinClient by selecting a valid node at random
|
||||
pub fn get_client(
|
||||
nodes: &[ContactInfo],
|
||||
socket_addr_space: &SocketAddrSpace,
|
||||
) -> ThinClient<UdpTpuConnection> {
|
||||
pub fn get_client(nodes: &[ContactInfo], socket_addr_space: &SocketAddrSpace) -> ThinClient {
|
||||
let nodes: Vec<_> = nodes
|
||||
.iter()
|
||||
.filter_map(|node| ContactInfo::valid_client_facing_addr(node, socket_addr_space))
|
||||
.collect();
|
||||
let select = thread_rng().gen_range(0, nodes.len());
|
||||
create_client(nodes[select], VALIDATOR_PORT_RANGE)
|
||||
create_client(nodes[select])
|
||||
}
|
||||
|
||||
pub fn get_multi_client(
|
||||
nodes: &[ContactInfo],
|
||||
socket_addr_space: &SocketAddrSpace,
|
||||
) -> (ThinClient<UdpTpuConnection>, usize) {
|
||||
) -> (ThinClient, usize) {
|
||||
let addrs: Vec<_> = nodes
|
||||
.iter()
|
||||
.filter_map(|node| ContactInfo::valid_client_facing_addr(node, socket_addr_space))
|
||||
.collect();
|
||||
let rpc_addrs: Vec<_> = addrs.iter().map(|addr| addr.0).collect();
|
||||
let tpu_addrs: Vec<_> = addrs.iter().map(|addr| addr.1).collect();
|
||||
let (_, transactions_socket) = solana_net_utils::bind_in_range(
|
||||
IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)),
|
||||
VALIDATOR_PORT_RANGE,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let num_nodes = tpu_addrs.len();
|
||||
(
|
||||
//TODO: make it configurable whether to use quic
|
||||
ThinClient::<UdpTpuConnection>::new_from_addrs(rpc_addrs, tpu_addrs, transactions_socket),
|
||||
num_nodes,
|
||||
)
|
||||
(ThinClient::new_from_addrs(rpc_addrs, tpu_addrs), num_nodes)
|
||||
}
|
||||
|
||||
fn spy(
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-install"
|
||||
description = "The solana cluster software installer"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -26,12 +26,12 @@ reqwest = { version = "0.11.10", default-features = false, features = ["blocking
|
||||
semver = "1.0.6"
|
||||
serde = { version = "1.0.136", features = ["derive"] }
|
||||
serde_yaml = "0.8.23"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.10.8" }
|
||||
solana-client = { path = "../client", version = "=1.10.8" }
|
||||
solana-config-program = { path = "../programs/config", version = "=1.10.8" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-version = { path = "../version", version = "=1.10.8" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.10.9" }
|
||||
solana-client = { path = "../client", version = "=1.10.9" }
|
||||
solana-config-program = { path = "../programs/config", version = "=1.10.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
solana-version = { path = "../version", version = "=1.10.9" }
|
||||
tar = "0.4.38"
|
||||
tempfile = "3.3.0"
|
||||
url = "2.2.2"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-keygen"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana key generation utility"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -14,11 +14,11 @@ bs58 = "0.4.0"
|
||||
clap = "2.33"
|
||||
dirs-next = "2.0.0"
|
||||
num_cpus = "1.13.1"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.10.8" }
|
||||
solana-cli-config = { path = "../cli-config", version = "=1.10.8" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-version = { path = "../version", version = "=1.10.8" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.10.9" }
|
||||
solana-cli-config = { path = "../cli-config", version = "=1.10.9" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
solana-version = { path = "../version", version = "=1.10.9" }
|
||||
tiny-bip39 = "0.8.2"
|
||||
|
||||
[[bin]]
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-ledger-tool"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -21,20 +21,20 @@ log = { version = "0.4.14" }
|
||||
regex = "1"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0.79"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.10.8" }
|
||||
solana-cli-output = { path = "../cli-output", version = "=1.10.8" }
|
||||
solana-core = { path = "../core", version = "=1.10.8" }
|
||||
solana-entry = { path = "../entry", version = "=1.10.8" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.10.8" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.8" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.8" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "=1.10.8" }
|
||||
solana-storage-bigtable = { path = "../storage-bigtable", version = "=1.10.8" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.10.8" }
|
||||
solana-version = { path = "../version", version = "=1.10.8" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.10.8" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.10.9" }
|
||||
solana-cli-output = { path = "../cli-output", version = "=1.10.9" }
|
||||
solana-core = { path = "../core", version = "=1.10.9" }
|
||||
solana-entry = { path = "../entry", version = "=1.10.9" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.10.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.9" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "=1.10.9" }
|
||||
solana-storage-bigtable = { path = "../storage-bigtable", version = "=1.10.9" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.10.9" }
|
||||
solana-version = { path = "../version", version = "=1.10.9" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.10.9" }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
|
||||
[target.'cfg(not(target_env = "msvc"))'.dependencies]
|
||||
|
@@ -16,6 +16,7 @@ use {
|
||||
},
|
||||
solana_ledger::{blockstore::Blockstore, blockstore_db::AccessType},
|
||||
solana_sdk::{clock::Slot, pubkey::Pubkey, signature::Signature},
|
||||
solana_storage_bigtable::CredentialType,
|
||||
solana_transaction_status::{
|
||||
BlockEncodingOptions, ConfirmedBlock, EncodeError, TransactionDetails,
|
||||
UiTransactionEncoding,
|
||||
@@ -34,8 +35,9 @@ async fn upload(
|
||||
starting_slot: Slot,
|
||||
ending_slot: Option<Slot>,
|
||||
force_reupload: bool,
|
||||
config: solana_storage_bigtable::LedgerStorageConfig,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let bigtable = solana_storage_bigtable::LedgerStorage::new(false, None, None)
|
||||
let bigtable = solana_storage_bigtable::LedgerStorage::new_with_config(config)
|
||||
.await
|
||||
.map_err(|err| format!("Failed to connect to storage: {:?}", err))?;
|
||||
|
||||
@@ -50,17 +52,22 @@ async fn upload(
|
||||
.await
|
||||
}
|
||||
|
||||
async fn delete_slots(slots: Vec<Slot>, dry_run: bool) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let read_only = dry_run;
|
||||
let bigtable = solana_storage_bigtable::LedgerStorage::new(read_only, None, None)
|
||||
async fn delete_slots(
|
||||
slots: Vec<Slot>,
|
||||
config: solana_storage_bigtable::LedgerStorageConfig,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let dry_run = config.read_only;
|
||||
let bigtable = solana_storage_bigtable::LedgerStorage::new_with_config(config)
|
||||
.await
|
||||
.map_err(|err| format!("Failed to connect to storage: {:?}", err))?;
|
||||
|
||||
solana_ledger::bigtable_delete::delete_confirmed_blocks(bigtable, slots, dry_run).await
|
||||
}
|
||||
|
||||
async fn first_available_block() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let bigtable = solana_storage_bigtable::LedgerStorage::new(true, None, None).await?;
|
||||
async fn first_available_block(
|
||||
config: solana_storage_bigtable::LedgerStorageConfig,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let bigtable = solana_storage_bigtable::LedgerStorage::new_with_config(config).await?;
|
||||
match bigtable.get_first_available_block().await? {
|
||||
Some(block) => println!("{}", block),
|
||||
None => println!("No blocks available"),
|
||||
@@ -69,8 +76,12 @@ async fn first_available_block() -> Result<(), Box<dyn std::error::Error>> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn block(slot: Slot, output_format: OutputFormat) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let bigtable = solana_storage_bigtable::LedgerStorage::new(false, None, None)
|
||||
async fn block(
|
||||
slot: Slot,
|
||||
output_format: OutputFormat,
|
||||
config: solana_storage_bigtable::LedgerStorageConfig,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let bigtable = solana_storage_bigtable::LedgerStorage::new_with_config(config)
|
||||
.await
|
||||
.map_err(|err| format!("Failed to connect to storage: {:?}", err))?;
|
||||
|
||||
@@ -101,8 +112,12 @@ async fn block(slot: Slot, output_format: OutputFormat) -> Result<(), Box<dyn st
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn blocks(starting_slot: Slot, limit: usize) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let bigtable = solana_storage_bigtable::LedgerStorage::new(false, None, None)
|
||||
async fn blocks(
|
||||
starting_slot: Slot,
|
||||
limit: usize,
|
||||
config: solana_storage_bigtable::LedgerStorageConfig,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let bigtable = solana_storage_bigtable::LedgerStorage::new_with_config(config)
|
||||
.await
|
||||
.map_err(|err| format!("Failed to connect to storage: {:?}", err))?;
|
||||
|
||||
@@ -116,11 +131,10 @@ async fn blocks(starting_slot: Slot, limit: usize) -> Result<(), Box<dyn std::er
|
||||
async fn compare_blocks(
|
||||
starting_slot: Slot,
|
||||
limit: usize,
|
||||
credential_path: String,
|
||||
config: solana_storage_bigtable::LedgerStorageConfig,
|
||||
ref_config: solana_storage_bigtable::LedgerStorageConfig,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
assert!(!credential_path.is_empty());
|
||||
|
||||
let owned_bigtable = solana_storage_bigtable::LedgerStorage::new(false, None, None)
|
||||
let owned_bigtable = solana_storage_bigtable::LedgerStorage::new_with_config(config)
|
||||
.await
|
||||
.map_err(|err| format!("failed to connect to owned bigtable: {:?}", err))?;
|
||||
let owned_bigtable_slots = owned_bigtable
|
||||
@@ -130,10 +144,9 @@ async fn compare_blocks(
|
||||
"owned bigtable {} blocks found ",
|
||||
owned_bigtable_slots.len()
|
||||
);
|
||||
let reference_bigtable =
|
||||
solana_storage_bigtable::LedgerStorage::new(false, None, Some(credential_path))
|
||||
.await
|
||||
.map_err(|err| format!("failed to connect to reference bigtable: {:?}", err))?;
|
||||
let reference_bigtable = solana_storage_bigtable::LedgerStorage::new_with_config(ref_config)
|
||||
.await
|
||||
.map_err(|err| format!("failed to connect to reference bigtable: {:?}", err))?;
|
||||
|
||||
let reference_bigtable_slots = reference_bigtable
|
||||
.get_confirmed_blocks(starting_slot, limit)
|
||||
@@ -160,8 +173,9 @@ async fn confirm(
|
||||
signature: &Signature,
|
||||
verbose: bool,
|
||||
output_format: OutputFormat,
|
||||
config: solana_storage_bigtable::LedgerStorageConfig,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let bigtable = solana_storage_bigtable::LedgerStorage::new(false, None, None)
|
||||
let bigtable = solana_storage_bigtable::LedgerStorage::new_with_config(config)
|
||||
.await
|
||||
.map_err(|err| format!("Failed to connect to storage: {:?}", err))?;
|
||||
|
||||
@@ -211,8 +225,9 @@ pub async fn transaction_history(
|
||||
verbose: bool,
|
||||
show_transactions: bool,
|
||||
query_chunk_size: usize,
|
||||
config: solana_storage_bigtable::LedgerStorageConfig,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let bigtable = solana_storage_bigtable::LedgerStorage::new(true, None, None).await?;
|
||||
let bigtable = solana_storage_bigtable::LedgerStorage::new_with_config(config).await?;
|
||||
|
||||
let mut loaded_block: Option<(Slot, ConfirmedBlock)> = None;
|
||||
while limit > 0 {
|
||||
@@ -308,6 +323,15 @@ impl BigTableSubCommand for App<'_, '_> {
|
||||
.about("Ledger data on a BigTable instance")
|
||||
.setting(AppSettings::InferSubcommands)
|
||||
.setting(AppSettings::SubcommandRequiredElseHelp)
|
||||
.arg(
|
||||
Arg::with_name("rpc_bigtable_instance_name")
|
||||
.global(true)
|
||||
.long("rpc-bigtable-instance-name")
|
||||
.takes_value(true)
|
||||
.value_name("INSTANCE_NAME")
|
||||
.default_value(solana_storage_bigtable::DEFAULT_INSTANCE_NAME)
|
||||
.help("Name of the target Bigtable instance")
|
||||
)
|
||||
.subcommand(
|
||||
SubCommand::with_name("upload")
|
||||
.about("Upload the ledger to BigTable")
|
||||
@@ -417,7 +441,8 @@ impl BigTableSubCommand for App<'_, '_> {
|
||||
.required(true)
|
||||
.default_value("1000")
|
||||
.help("Maximum number of slots to check"),
|
||||
).arg(
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("reference_credential")
|
||||
.long("reference-credential")
|
||||
.short("c")
|
||||
@@ -425,6 +450,14 @@ impl BigTableSubCommand for App<'_, '_> {
|
||||
.takes_value(true)
|
||||
.required(true)
|
||||
.help("File path for a credential to a reference bigtable"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("reference_instance_name")
|
||||
.long("reference-instance-name")
|
||||
.takes_value(true)
|
||||
.value_name("INSTANCE_NAME")
|
||||
.default_value(solana_storage_bigtable::DEFAULT_INSTANCE_NAME)
|
||||
.help("Name of the reference Bigtable instance to compare to")
|
||||
),
|
||||
)
|
||||
.subcommand(
|
||||
@@ -521,7 +554,28 @@ pub fn bigtable_process_command(ledger_path: &Path, matches: &ArgMatches<'_>) {
|
||||
let verbose = matches.is_present("verbose");
|
||||
let output_format = OutputFormat::from_matches(matches, "output_format", verbose);
|
||||
|
||||
let future = match matches.subcommand() {
|
||||
// this is kinda stupid, but there seems to be a bug in clap when a subcommand
|
||||
// arg is marked both `global(true)` and `default_value("default_value")`.
|
||||
// despite the "global", when the arg is specified on the subcommand, its value
|
||||
// is not propagated down to the (sub)subcommand args, resulting in the default
|
||||
// value when queried there. similarly, if the arg is specified on the
|
||||
// (sub)subcommand, the value is not propagated back up to the subcommand args,
|
||||
// again resulting in the default value. the arg having declared a
|
||||
// `default_value()` obviates `is_present(...)` tests since they will always
|
||||
// return true. so we consede and compare against the expected default. :/
|
||||
let (subcommand, sub_matches) = matches.subcommand();
|
||||
let on_command = matches
|
||||
.value_of("rpc_bigtable_instance_name")
|
||||
.map(|v| v != solana_storage_bigtable::DEFAULT_INSTANCE_NAME)
|
||||
.unwrap_or(false);
|
||||
let instance_name = if on_command {
|
||||
value_t_or_exit!(matches, "rpc_bigtable_instance_name", String)
|
||||
} else {
|
||||
let sub_matches = sub_matches.as_ref().unwrap();
|
||||
value_t_or_exit!(sub_matches, "rpc_bigtable_instance_name", String)
|
||||
};
|
||||
|
||||
let future = match (subcommand, sub_matches) {
|
||||
("upload", Some(arg_matches)) => {
|
||||
let starting_slot = value_t!(arg_matches, "starting_slot", Slot).unwrap_or(0);
|
||||
let ending_slot = value_t!(arg_matches, "ending_slot", Slot).ok();
|
||||
@@ -531,41 +585,81 @@ pub fn bigtable_process_command(ledger_path: &Path, matches: &ArgMatches<'_>) {
|
||||
AccessType::TryPrimaryThenSecondary,
|
||||
None,
|
||||
);
|
||||
|
||||
let config = solana_storage_bigtable::LedgerStorageConfig {
|
||||
read_only: false,
|
||||
instance_name,
|
||||
..solana_storage_bigtable::LedgerStorageConfig::default()
|
||||
};
|
||||
runtime.block_on(upload(
|
||||
blockstore,
|
||||
starting_slot,
|
||||
ending_slot,
|
||||
force_reupload,
|
||||
config,
|
||||
))
|
||||
}
|
||||
("delete-slots", Some(arg_matches)) => {
|
||||
let slots = values_t_or_exit!(arg_matches, "slots", Slot);
|
||||
let dry_run = !arg_matches.is_present("force");
|
||||
runtime.block_on(delete_slots(slots, dry_run))
|
||||
let config = solana_storage_bigtable::LedgerStorageConfig {
|
||||
read_only: !arg_matches.is_present("force"),
|
||||
instance_name,
|
||||
..solana_storage_bigtable::LedgerStorageConfig::default()
|
||||
};
|
||||
runtime.block_on(delete_slots(slots, config))
|
||||
}
|
||||
("first-available-block", Some(_arg_matches)) => {
|
||||
let config = solana_storage_bigtable::LedgerStorageConfig {
|
||||
read_only: true,
|
||||
instance_name,
|
||||
..solana_storage_bigtable::LedgerStorageConfig::default()
|
||||
};
|
||||
runtime.block_on(first_available_block(config))
|
||||
}
|
||||
("first-available-block", Some(_arg_matches)) => runtime.block_on(first_available_block()),
|
||||
("block", Some(arg_matches)) => {
|
||||
let slot = value_t_or_exit!(arg_matches, "slot", Slot);
|
||||
runtime.block_on(block(slot, output_format))
|
||||
let config = solana_storage_bigtable::LedgerStorageConfig {
|
||||
read_only: false,
|
||||
instance_name,
|
||||
..solana_storage_bigtable::LedgerStorageConfig::default()
|
||||
};
|
||||
runtime.block_on(block(slot, output_format, config))
|
||||
}
|
||||
("blocks", Some(arg_matches)) => {
|
||||
let starting_slot = value_t_or_exit!(arg_matches, "starting_slot", Slot);
|
||||
let limit = value_t_or_exit!(arg_matches, "limit", usize);
|
||||
let config = solana_storage_bigtable::LedgerStorageConfig {
|
||||
read_only: false,
|
||||
instance_name,
|
||||
..solana_storage_bigtable::LedgerStorageConfig::default()
|
||||
};
|
||||
|
||||
runtime.block_on(blocks(starting_slot, limit))
|
||||
runtime.block_on(blocks(starting_slot, limit, config))
|
||||
}
|
||||
("compare-blocks", Some(arg_matches)) => {
|
||||
let starting_slot = value_t_or_exit!(arg_matches, "starting_slot", Slot);
|
||||
let limit = value_t_or_exit!(arg_matches, "limit", usize);
|
||||
let reference_credential_filepath =
|
||||
value_t_or_exit!(arg_matches, "reference_credential", String);
|
||||
let config = solana_storage_bigtable::LedgerStorageConfig {
|
||||
read_only: false,
|
||||
instance_name,
|
||||
..solana_storage_bigtable::LedgerStorageConfig::default()
|
||||
};
|
||||
|
||||
runtime.block_on(compare_blocks(
|
||||
starting_slot,
|
||||
limit,
|
||||
reference_credential_filepath,
|
||||
))
|
||||
let credential_path = Some(value_t_or_exit!(
|
||||
arg_matches,
|
||||
"reference_credential",
|
||||
String
|
||||
));
|
||||
|
||||
let ref_instance_name =
|
||||
value_t_or_exit!(arg_matches, "reference_instance_name", String);
|
||||
let ref_config = solana_storage_bigtable::LedgerStorageConfig {
|
||||
read_only: false,
|
||||
credential_type: CredentialType::Filepath(credential_path),
|
||||
instance_name: ref_instance_name,
|
||||
..solana_storage_bigtable::LedgerStorageConfig::default()
|
||||
};
|
||||
|
||||
runtime.block_on(compare_blocks(starting_slot, limit, config, ref_config))
|
||||
}
|
||||
("confirm", Some(arg_matches)) => {
|
||||
let signature = arg_matches
|
||||
@@ -573,8 +667,13 @@ pub fn bigtable_process_command(ledger_path: &Path, matches: &ArgMatches<'_>) {
|
||||
.unwrap()
|
||||
.parse()
|
||||
.expect("Invalid signature");
|
||||
let config = solana_storage_bigtable::LedgerStorageConfig {
|
||||
read_only: false,
|
||||
instance_name,
|
||||
..solana_storage_bigtable::LedgerStorageConfig::default()
|
||||
};
|
||||
|
||||
runtime.block_on(confirm(&signature, verbose, output_format))
|
||||
runtime.block_on(confirm(&signature, verbose, output_format, config))
|
||||
}
|
||||
("transaction-history", Some(arg_matches)) => {
|
||||
let address = pubkey_of(arg_matches, "address").unwrap();
|
||||
@@ -587,6 +686,11 @@ pub fn bigtable_process_command(ledger_path: &Path, matches: &ArgMatches<'_>) {
|
||||
.value_of("until")
|
||||
.map(|signature| signature.parse().expect("Invalid signature"));
|
||||
let show_transactions = arg_matches.is_present("show_transactions");
|
||||
let config = solana_storage_bigtable::LedgerStorageConfig {
|
||||
read_only: true,
|
||||
instance_name,
|
||||
..solana_storage_bigtable::LedgerStorageConfig::default()
|
||||
};
|
||||
|
||||
runtime.block_on(transaction_history(
|
||||
&address,
|
||||
@@ -596,6 +700,7 @@ pub fn bigtable_process_command(ledger_path: &Path, matches: &ArgMatches<'_>) {
|
||||
verbose,
|
||||
show_transactions,
|
||||
query_chunk_size,
|
||||
config,
|
||||
))
|
||||
}
|
||||
_ => unreachable!(),
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-ledger"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana ledger"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -34,21 +34,21 @@ reed-solomon-erasure = { version = "5.0.1", features = ["simd-accel"] }
|
||||
serde = "1.0.136"
|
||||
serde_bytes = "0.11.5"
|
||||
sha2 = "0.10.2"
|
||||
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "=1.10.8" }
|
||||
solana-entry = { path = "../entry", version = "=1.10.8" }
|
||||
solana-frozen-abi = { path = "../frozen-abi", version = "=1.10.8" }
|
||||
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.10.8" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.8" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.10.8" }
|
||||
solana-perf = { path = "../perf", version = "=1.10.8" }
|
||||
solana-program-runtime = { path = "../program-runtime", version = "=1.10.8" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.10.8" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-storage-bigtable = { path = "../storage-bigtable", version = "=1.10.8" }
|
||||
solana-storage-proto = { path = "../storage-proto", version = "=1.10.8" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.10.8" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.10.8" }
|
||||
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "=1.10.9" }
|
||||
solana-entry = { path = "../entry", version = "=1.10.9" }
|
||||
solana-frozen-abi = { path = "../frozen-abi", version = "=1.10.9" }
|
||||
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.10.9" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.9" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.10.9" }
|
||||
solana-perf = { path = "../perf", version = "=1.10.9" }
|
||||
solana-program-runtime = { path = "../program-runtime", version = "=1.10.9" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.10.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
solana-storage-bigtable = { path = "../storage-bigtable", version = "=1.10.9" }
|
||||
solana-storage-proto = { path = "../storage-proto", version = "=1.10.9" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.10.9" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.10.9" }
|
||||
tempfile = "3.3.0"
|
||||
thiserror = "1.0"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
@@ -65,8 +65,8 @@ features = ["lz4"]
|
||||
[dev-dependencies]
|
||||
assert_matches = "1.5.0"
|
||||
matches = "0.1.9"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.10.8" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.8" }
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.10.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.9" }
|
||||
|
||||
[build-dependencies]
|
||||
rustc_version = "0.4"
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-local-cluster"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -16,25 +16,25 @@ itertools = "0.10.3"
|
||||
log = "0.4.14"
|
||||
rand = "0.7.0"
|
||||
rayon = "1.5.1"
|
||||
solana-client = { path = "../client", version = "=1.10.8" }
|
||||
solana-config-program = { path = "../programs/config", version = "=1.10.8" }
|
||||
solana-core = { path = "../core", version = "=1.10.8" }
|
||||
solana-entry = { path = "../entry", version = "=1.10.8" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.10.8" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.10.8" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "=1.10.8" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.10.8" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.10.8" }
|
||||
solana-client = { path = "../client", version = "=1.10.9" }
|
||||
solana-config-program = { path = "../programs/config", version = "=1.10.9" }
|
||||
solana-core = { path = "../core", version = "=1.10.9" }
|
||||
solana-entry = { path = "../entry", version = "=1.10.9" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.10.9" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.10.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "=1.10.9" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.10.9" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.10.9" }
|
||||
tempfile = "3.3.0"
|
||||
|
||||
[dev-dependencies]
|
||||
assert_matches = "1.5.0"
|
||||
gag = "1.0.0"
|
||||
serial_test = "0.6.0"
|
||||
solana-download-utils = { path = "../download-utils", version = "=1.10.8" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.8" }
|
||||
solana-download-utils = { path = "../download-utils", version = "=1.10.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.9" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -1,5 +1,5 @@
|
||||
use {
|
||||
solana_client::{thin_client::ThinClient, udp_client::UdpTpuConnection},
|
||||
solana_client::thin_client::ThinClient,
|
||||
solana_core::validator::{Validator, ValidatorConfig},
|
||||
solana_gossip::{cluster_info::Node, contact_info::ContactInfo},
|
||||
solana_sdk::{pubkey::Pubkey, signature::Keypair},
|
||||
@@ -36,7 +36,7 @@ impl ClusterValidatorInfo {
|
||||
|
||||
pub trait Cluster {
|
||||
fn get_node_pubkeys(&self) -> Vec<Pubkey>;
|
||||
fn get_validator_client(&self, pubkey: &Pubkey) -> Option<ThinClient<UdpTpuConnection>>;
|
||||
fn get_validator_client(&self, pubkey: &Pubkey) -> Option<ThinClient>;
|
||||
fn get_contact_info(&self, pubkey: &Pubkey) -> Option<&ContactInfo>;
|
||||
fn exit_node(&mut self, pubkey: &Pubkey) -> ClusterValidatorInfo;
|
||||
fn restart_node(
|
||||
|
@@ -10,7 +10,7 @@ use {
|
||||
solana_core::consensus::VOTE_THRESHOLD_DEPTH,
|
||||
solana_entry::entry::{Entry, EntrySlice},
|
||||
solana_gossip::{
|
||||
cluster_info::{self, VALIDATOR_PORT_RANGE},
|
||||
cluster_info,
|
||||
contact_info::ContactInfo,
|
||||
crds_value::{self, CrdsData, CrdsValue},
|
||||
gossip_error::GossipError,
|
||||
@@ -60,7 +60,7 @@ pub fn spend_and_verify_all_nodes<S: ::std::hash::BuildHasher + Sync + Send>(
|
||||
return;
|
||||
}
|
||||
let random_keypair = Keypair::new();
|
||||
let client = create_client(ingress_node.client_facing_addr(), VALIDATOR_PORT_RANGE);
|
||||
let client = create_client(ingress_node.client_facing_addr());
|
||||
let bal = client
|
||||
.poll_get_balance_with_commitment(
|
||||
&funding_keypair.pubkey(),
|
||||
@@ -81,7 +81,7 @@ pub fn spend_and_verify_all_nodes<S: ::std::hash::BuildHasher + Sync + Send>(
|
||||
if ignore_nodes.contains(&validator.id) {
|
||||
continue;
|
||||
}
|
||||
let client = create_client(validator.client_facing_addr(), VALIDATOR_PORT_RANGE);
|
||||
let client = create_client(validator.client_facing_addr());
|
||||
client.poll_for_signature_confirmation(&sig, confs).unwrap();
|
||||
}
|
||||
});
|
||||
@@ -91,7 +91,7 @@ pub fn verify_balances<S: ::std::hash::BuildHasher>(
|
||||
expected_balances: HashMap<Pubkey, u64, S>,
|
||||
node: &ContactInfo,
|
||||
) {
|
||||
let client = create_client(node.client_facing_addr(), VALIDATOR_PORT_RANGE);
|
||||
let client = create_client(node.client_facing_addr());
|
||||
for (pk, b) in expected_balances {
|
||||
let bal = client
|
||||
.poll_get_balance_with_commitment(&pk, CommitmentConfig::processed())
|
||||
@@ -106,7 +106,7 @@ pub fn send_many_transactions(
|
||||
max_tokens_per_transfer: u64,
|
||||
num_txs: u64,
|
||||
) -> HashMap<Pubkey, u64> {
|
||||
let client = create_client(node.client_facing_addr(), VALIDATOR_PORT_RANGE);
|
||||
let client = create_client(node.client_facing_addr());
|
||||
let mut expected_balances = HashMap::new();
|
||||
for _ in 0..num_txs {
|
||||
let random_keypair = Keypair::new();
|
||||
@@ -197,7 +197,7 @@ pub fn kill_entry_and_spend_and_verify_rest(
|
||||
let cluster_nodes =
|
||||
discover_cluster(&entry_point_info.gossip, nodes, socket_addr_space).unwrap();
|
||||
assert!(cluster_nodes.len() >= nodes);
|
||||
let client = create_client(entry_point_info.client_facing_addr(), VALIDATOR_PORT_RANGE);
|
||||
let client = create_client(entry_point_info.client_facing_addr());
|
||||
// sleep long enough to make sure we are in epoch 3
|
||||
let first_two_epoch_slots = MINIMUM_SLOTS_PER_EPOCH * (3 + 1);
|
||||
|
||||
@@ -225,7 +225,7 @@ pub fn kill_entry_and_spend_and_verify_rest(
|
||||
continue;
|
||||
}
|
||||
|
||||
let client = create_client(ingress_node.client_facing_addr(), VALIDATOR_PORT_RANGE);
|
||||
let client = create_client(ingress_node.client_facing_addr());
|
||||
let balance = client
|
||||
.poll_get_balance_with_commitment(
|
||||
&funding_keypair.pubkey(),
|
||||
@@ -296,7 +296,7 @@ pub fn check_for_new_roots(num_new_roots: usize, contact_infos: &[ContactInfo],
|
||||
assert!(loop_start.elapsed() < loop_timeout);
|
||||
|
||||
for (i, ingress_node) in contact_infos.iter().enumerate() {
|
||||
let client = create_client(ingress_node.client_facing_addr(), VALIDATOR_PORT_RANGE);
|
||||
let client = create_client(ingress_node.client_facing_addr());
|
||||
let root_slot = client
|
||||
.get_slot_with_commitment(CommitmentConfig::finalized())
|
||||
.unwrap_or(0);
|
||||
@@ -327,7 +327,7 @@ pub fn check_no_new_roots(
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, ingress_node)| {
|
||||
let client = create_client(ingress_node.client_facing_addr(), VALIDATOR_PORT_RANGE);
|
||||
let client = create_client(ingress_node.client_facing_addr());
|
||||
let initial_root = client
|
||||
.get_slot()
|
||||
.unwrap_or_else(|_| panic!("get_slot for {} failed", ingress_node.id));
|
||||
@@ -345,7 +345,7 @@ pub fn check_no_new_roots(
|
||||
let mut reached_end_slot = false;
|
||||
loop {
|
||||
for contact_info in contact_infos {
|
||||
let client = create_client(contact_info.client_facing_addr(), VALIDATOR_PORT_RANGE);
|
||||
let client = create_client(contact_info.client_facing_addr());
|
||||
current_slot = client
|
||||
.get_slot_with_commitment(CommitmentConfig::processed())
|
||||
.unwrap_or_else(|_| panic!("get_slot for {} failed", contact_infos[0].id));
|
||||
@@ -367,7 +367,7 @@ pub fn check_no_new_roots(
|
||||
}
|
||||
|
||||
for (i, ingress_node) in contact_infos.iter().enumerate() {
|
||||
let client = create_client(ingress_node.client_facing_addr(), VALIDATOR_PORT_RANGE);
|
||||
let client = create_client(ingress_node.client_facing_addr());
|
||||
assert_eq!(
|
||||
client
|
||||
.get_slot()
|
||||
@@ -387,7 +387,7 @@ fn poll_all_nodes_for_signature(
|
||||
if validator.id == entry_point_info.id {
|
||||
continue;
|
||||
}
|
||||
let client = create_client(validator.client_facing_addr(), VALIDATOR_PORT_RANGE);
|
||||
let client = create_client(validator.client_facing_addr());
|
||||
client.poll_for_signature_confirmation(sig, confs)?;
|
||||
}
|
||||
|
||||
|
@@ -6,18 +6,13 @@ use {
|
||||
},
|
||||
itertools::izip,
|
||||
log::*,
|
||||
solana_client::{
|
||||
thin_client::{create_client, ThinClient},
|
||||
udp_client::UdpTpuConnection,
|
||||
},
|
||||
solana_client::thin_client::{create_client, ThinClient},
|
||||
solana_core::{
|
||||
tower_storage::FileTowerStorage,
|
||||
validator::{Validator, ValidatorConfig, ValidatorStartProgress},
|
||||
},
|
||||
solana_gossip::{
|
||||
cluster_info::{Node, VALIDATOR_PORT_RANGE},
|
||||
contact_info::ContactInfo,
|
||||
gossip_service::discover_cluster,
|
||||
cluster_info::Node, contact_info::ContactInfo, gossip_service::discover_cluster,
|
||||
},
|
||||
solana_ledger::create_new_tmp_ledger,
|
||||
solana_runtime::genesis_utils::{
|
||||
@@ -393,10 +388,7 @@ impl LocalCluster {
|
||||
mut voting_keypair: Option<Arc<Keypair>>,
|
||||
socket_addr_space: SocketAddrSpace,
|
||||
) -> Pubkey {
|
||||
let client = create_client(
|
||||
self.entry_point_info.client_facing_addr(),
|
||||
VALIDATOR_PORT_RANGE,
|
||||
);
|
||||
let client = create_client(self.entry_point_info.client_facing_addr());
|
||||
|
||||
// Must have enough tokens to fund vote account and set delegate
|
||||
let should_create_vote_pubkey = voting_keypair.is_none();
|
||||
@@ -480,10 +472,7 @@ impl LocalCluster {
|
||||
}
|
||||
|
||||
pub fn transfer(&self, source_keypair: &Keypair, dest_pubkey: &Pubkey, lamports: u64) -> u64 {
|
||||
let client = create_client(
|
||||
self.entry_point_info.client_facing_addr(),
|
||||
VALIDATOR_PORT_RANGE,
|
||||
);
|
||||
let client = create_client(self.entry_point_info.client_facing_addr());
|
||||
Self::transfer_with_client(&client, source_keypair, dest_pubkey, lamports)
|
||||
}
|
||||
|
||||
@@ -538,7 +527,7 @@ impl LocalCluster {
|
||||
}
|
||||
|
||||
fn transfer_with_client(
|
||||
client: &ThinClient<UdpTpuConnection>,
|
||||
client: &ThinClient,
|
||||
source_keypair: &Keypair,
|
||||
dest_pubkey: &Pubkey,
|
||||
lamports: u64,
|
||||
@@ -567,7 +556,7 @@ impl LocalCluster {
|
||||
}
|
||||
|
||||
fn setup_vote_and_stake_accounts(
|
||||
client: &ThinClient<UdpTpuConnection>,
|
||||
client: &ThinClient,
|
||||
vote_account: &Keypair,
|
||||
from_account: &Arc<Keypair>,
|
||||
amount: u64,
|
||||
@@ -704,13 +693,10 @@ impl Cluster for LocalCluster {
|
||||
self.validators.keys().cloned().collect()
|
||||
}
|
||||
|
||||
fn get_validator_client(&self, pubkey: &Pubkey) -> Option<ThinClient<UdpTpuConnection>> {
|
||||
self.validators.get(pubkey).map(|f| {
|
||||
create_client(
|
||||
f.info.contact_info.client_facing_addr(),
|
||||
VALIDATOR_PORT_RANGE,
|
||||
)
|
||||
})
|
||||
fn get_validator_client(&self, pubkey: &Pubkey) -> Option<ThinClient> {
|
||||
self.validators
|
||||
.get(pubkey)
|
||||
.map(|f| create_client(f.info.contact_info.client_facing_addr()))
|
||||
}
|
||||
|
||||
fn exit_node(&mut self, pubkey: &Pubkey) -> ClusterValidatorInfo {
|
||||
|
@@ -17,7 +17,6 @@ use {
|
||||
rpc_config::{RpcProgramAccountsConfig, RpcSignatureSubscribeConfig},
|
||||
rpc_response::RpcSignatureResult,
|
||||
thin_client::{create_client, ThinClient},
|
||||
udp_client::UdpTpuConnection,
|
||||
},
|
||||
solana_core::{
|
||||
broadcast_stage::BroadcastStageType,
|
||||
@@ -28,7 +27,7 @@ use {
|
||||
validator::ValidatorConfig,
|
||||
},
|
||||
solana_download_utils::download_snapshot_archive,
|
||||
solana_gossip::{cluster_info::VALIDATOR_PORT_RANGE, gossip_service::discover_cluster},
|
||||
solana_gossip::gossip_service::discover_cluster,
|
||||
solana_ledger::{ancestor_iterator::AncestorIterator, blockstore::Blockstore},
|
||||
solana_local_cluster::{
|
||||
cluster::{Cluster, ClusterValidatorInfo},
|
||||
@@ -212,10 +211,7 @@ fn test_local_cluster_signature_subscribe() {
|
||||
.unwrap();
|
||||
let non_bootstrap_info = cluster.get_contact_info(&non_bootstrap_id).unwrap();
|
||||
|
||||
let tx_client = create_client(
|
||||
non_bootstrap_info.client_facing_addr(),
|
||||
VALIDATOR_PORT_RANGE,
|
||||
);
|
||||
let tx_client = create_client(non_bootstrap_info.client_facing_addr());
|
||||
let (blockhash, _) = tx_client
|
||||
.get_latest_blockhash_with_commitment(CommitmentConfig::processed())
|
||||
.unwrap();
|
||||
@@ -520,10 +516,7 @@ fn test_mainnet_beta_cluster_type() {
|
||||
.unwrap();
|
||||
assert_eq!(cluster_nodes.len(), 1);
|
||||
|
||||
let client = create_client(
|
||||
cluster.entry_point_info.client_facing_addr(),
|
||||
VALIDATOR_PORT_RANGE,
|
||||
);
|
||||
let client = create_client(cluster.entry_point_info.client_facing_addr());
|
||||
|
||||
// Programs that are available at epoch 0
|
||||
for program_id in [
|
||||
@@ -2663,8 +2656,8 @@ fn setup_transfer_scan_threads(
|
||||
num_starting_accounts: usize,
|
||||
exit: Arc<AtomicBool>,
|
||||
scan_commitment: CommitmentConfig,
|
||||
update_client_receiver: Receiver<ThinClient<UdpTpuConnection>>,
|
||||
scan_client_receiver: Receiver<ThinClient<UdpTpuConnection>>,
|
||||
update_client_receiver: Receiver<ThinClient>,
|
||||
scan_client_receiver: Receiver<ThinClient>,
|
||||
) -> (
|
||||
JoinHandle<()>,
|
||||
JoinHandle<()>,
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2021"
|
||||
name = "solana-log-analyzer"
|
||||
description = "The solana cluster network analysis tool"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -14,8 +14,8 @@ byte-unit = "4.0.14"
|
||||
clap = "2.33.1"
|
||||
serde = "1.0.136"
|
||||
serde_json = "1.0.79"
|
||||
solana-logger = { path = "../logger", version = "=1.10.8" }
|
||||
solana-version = { path = "../version", version = "=1.10.8" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.9" }
|
||||
solana-version = { path = "../version", version = "=1.10.9" }
|
||||
|
||||
[[bin]]
|
||||
name = "solana-log-analyzer"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-logger"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana Logger"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
|
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "solana-measure"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
homepage = "https://solana.com/"
|
||||
documentation = "https://docs.rs/solana-measure"
|
||||
readme = "../README.md"
|
||||
@@ -12,7 +12,7 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
log = "0.4.14"
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-merkle-root-bench"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -11,11 +11,11 @@ publish = false
|
||||
[dependencies]
|
||||
clap = "2.33.1"
|
||||
log = "0.4.14"
|
||||
solana-logger = { path = "../logger", version = "=1.10.8" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.8" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-version = { path = "../version", version = "=1.10.8" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.9" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
solana-version = { path = "../version", version = "=1.10.9" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-merkle-tree"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana Merkle Tree"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -11,7 +11,7 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
fast-math = "0.1"
|
||||
solana-program = { path = "../sdk/program", version = "=1.10.8" }
|
||||
solana-program = { path = "../sdk/program", version = "=1.10.9" }
|
||||
|
||||
# This can go once the BPF toolchain target Rust 1.42.0+
|
||||
[target.bpfel-unknown-unknown.dependencies]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-metrics"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana Metrics"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -15,7 +15,7 @@ gethostname = "0.2.3"
|
||||
lazy_static = "1.4.0"
|
||||
log = "0.4.14"
|
||||
reqwest = { version = "0.11.10", default-features = false, features = ["blocking", "rustls-tls", "json"] }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
|
||||
[dev-dependencies]
|
||||
env_logger = "0.9.0"
|
||||
|
@@ -3,7 +3,28 @@ pub mod counter;
|
||||
pub mod datapoint;
|
||||
mod metrics;
|
||||
pub use crate::metrics::{flush, query, set_host_id, set_panic_hook, submit};
|
||||
use std::sync::Arc;
|
||||
use std::sync::{
|
||||
atomic::{AtomicU64, Ordering},
|
||||
Arc,
|
||||
};
|
||||
|
||||
// To track an external counter which cannot be reset and is always increasing
|
||||
#[derive(Default)]
|
||||
pub struct MovingStat {
|
||||
value: AtomicU64,
|
||||
}
|
||||
|
||||
impl MovingStat {
|
||||
pub fn update_stat(&self, old_value: &MovingStat, new_value: u64) {
|
||||
let old = old_value.value.swap(new_value, Ordering::Acquire);
|
||||
self.value
|
||||
.fetch_add(new_value.saturating_sub(old), Ordering::Release);
|
||||
}
|
||||
|
||||
pub fn load_and_reset(&self) -> u64 {
|
||||
self.value.swap(0, Ordering::Acquire)
|
||||
}
|
||||
}
|
||||
|
||||
/// A helper that sends the count of created tokens as a datapoint.
|
||||
#[allow(clippy::redundant_allocation)]
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-net-shaper"
|
||||
description = "The solana cluster network shaping tool"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -14,7 +14,7 @@ clap = "2.33.1"
|
||||
rand = "0.7.0"
|
||||
serde = "1.0.136"
|
||||
serde_json = "1.0.79"
|
||||
solana-logger = { path = "../logger", version = "=1.10.8" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.9" }
|
||||
|
||||
[[bin]]
|
||||
name = "solana-net-shaper"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-net-utils"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana Network Utilities"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -19,9 +19,9 @@ rand = "0.7.0"
|
||||
serde = "1.0.136"
|
||||
serde_derive = "1.0.103"
|
||||
socket2 = "0.4.4"
|
||||
solana-logger = { path = "../logger", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-version = { path = "../version", version = "=1.10.8" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
solana-version = { path = "../version", version = "=1.10.9" }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
url = "2.2.2"
|
||||
|
||||
|
@@ -28,6 +28,9 @@ pub struct UdpSocketPair {
|
||||
|
||||
pub type PortRange = (u16, u16);
|
||||
|
||||
pub const VALIDATOR_PORT_RANGE: PortRange = (8000, 10_000);
|
||||
pub const MINIMUM_VALIDATOR_PORT_RANGE_WIDTH: u16 = 12; // VALIDATOR_PORT_RANGE must be at least this wide
|
||||
|
||||
pub(crate) const HEADER_LENGTH: usize = 4;
|
||||
pub(crate) const IP_ECHO_SERVER_RESPONSE_LENGTH: usize = HEADER_LENGTH + 23;
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-notifier"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana Notifier"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-perf"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana Performance APIs"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -22,10 +22,10 @@ log = "0.4.14"
|
||||
rand = "0.7.0"
|
||||
rayon = "1.5.1"
|
||||
serde = "1.0.136"
|
||||
solana-metrics = { path = "../metrics", version = "=1.10.8" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.10.8" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.10.9" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.10.9" }
|
||||
|
||||
[target."cfg(target_os = \"linux\")".dependencies]
|
||||
caps = "0.5.3"
|
||||
@@ -37,7 +37,7 @@ name = "solana_perf"
|
||||
|
||||
[dev-dependencies]
|
||||
matches = "0.1.9"
|
||||
solana-logger = { path = "../logger", version = "=1.10.8" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.9" }
|
||||
|
||||
[[bench]]
|
||||
name = "sigverify"
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-poh-bench"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -14,12 +14,12 @@ clap = "2.33.1"
|
||||
log = "0.4.14"
|
||||
rand = "0.7.0"
|
||||
rayon = "1.5.1"
|
||||
solana-entry = { path = "../entry", version = "=1.10.8" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.8" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.8" }
|
||||
solana-perf = { path = "../perf", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-version = { path = "../version", version = "=1.10.8" }
|
||||
solana-entry = { path = "../entry", version = "=1.10.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.9" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.9" }
|
||||
solana-perf = { path = "../perf", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
solana-version = { path = "../version", version = "=1.10.9" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-poh"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana PoH"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -13,21 +13,21 @@ edition = "2021"
|
||||
core_affinity = "0.5.10"
|
||||
crossbeam-channel = "0.5"
|
||||
log = "0.4.14"
|
||||
solana-entry = { path = "../entry", version = "=1.10.8" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.10.8" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.8" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.10.8" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-sys-tuner = { path = "../sys-tuner", version = "=1.10.8" }
|
||||
solana-entry = { path = "../entry", version = "=1.10.9" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.10.9" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.9" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.10.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
solana-sys-tuner = { path = "../sys-tuner", version = "=1.10.9" }
|
||||
thiserror = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
bincode = "1.3.3"
|
||||
matches = "0.1.9"
|
||||
rand = "0.7.0"
|
||||
solana-logger = { path = "../logger", version = "=1.10.8" }
|
||||
solana-perf = { path = "../perf", version = "=1.10.8" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.9" }
|
||||
solana-perf = { path = "../perf", version = "=1.10.9" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-program-runtime"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana program runtime"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -19,15 +19,15 @@ log = "0.4.14"
|
||||
num-derive = { version = "0.3" }
|
||||
num-traits = { version = "0.2" }
|
||||
serde = { version = "1.0.129", features = ["derive", "rc"] }
|
||||
solana-frozen-abi = { path = "../frozen-abi", version = "=1.10.8" }
|
||||
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.10.8" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-frozen-abi = { path = "../frozen-abi", version = "=1.10.9" }
|
||||
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.10.9" }
|
||||
solana-measure = { path = "../measure", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
thiserror = "1.0"
|
||||
enum-iterator = "0.7.0"
|
||||
|
||||
[dev-dependencies]
|
||||
solana-logger = { path = "../logger", version = "=1.10.8" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.9" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
@@ -5,7 +5,7 @@ edition = "2021"
|
||||
license = "Apache-2.0"
|
||||
name = "solana-program-test"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
|
||||
[dependencies]
|
||||
async-trait = "0.1.52"
|
||||
@@ -14,13 +14,13 @@ bincode = "1.3.3"
|
||||
chrono-humanize = "0.2.1"
|
||||
log = "0.4.14"
|
||||
serde = "1.0.136"
|
||||
solana-banks-client = { path = "../banks-client", version = "=1.10.8" }
|
||||
solana-banks-server = { path = "../banks-server", version = "=1.10.8" }
|
||||
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "=1.10.8" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.8" }
|
||||
solana-program-runtime = { path = "../program-runtime", version = "=1.10.8" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.8" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.10.8" }
|
||||
solana-banks-client = { path = "../banks-client", version = "=1.10.9" }
|
||||
solana-banks-server = { path = "../banks-server", version = "=1.10.9" }
|
||||
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "=1.10.9" }
|
||||
solana-logger = { path = "../logger", version = "=1.10.9" }
|
||||
solana-program-runtime = { path = "../program-runtime", version = "=1.10.9" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.10.9" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.10.9" }
|
||||
thiserror = "1.0"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-address-lookup-table-program-tests"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
@@ -14,9 +14,9 @@ publish = false
|
||||
[dev-dependencies]
|
||||
assert_matches = "1.5.0"
|
||||
bincode = "1.3.3"
|
||||
solana-address-lookup-table-program = { path = "../address-lookup-table", version = "=1.10.8" }
|
||||
solana-program-test = { path = "../../program-test", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../../sdk", version = "=1.10.8" }
|
||||
solana-address-lookup-table-program = { path = "../address-lookup-table", version = "=1.10.9" }
|
||||
solana-program-test = { path = "../../program-test", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../../sdk", version = "=1.10.9" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-address-lookup-table-program"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana address lookup table program"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -16,14 +16,14 @@ log = "0.4.14"
|
||||
num-derive = "0.3"
|
||||
num-traits = "0.2"
|
||||
serde = { version = "1.0.136", features = ["derive"] }
|
||||
solana-frozen-abi = { path = "../../frozen-abi", version = "=1.10.8" }
|
||||
solana-frozen-abi-macro = { path = "../../frozen-abi/macro", version = "=1.10.8" }
|
||||
solana-program = { path = "../../sdk/program", version = "=1.10.8" }
|
||||
solana-frozen-abi = { path = "../../frozen-abi", version = "=1.10.9" }
|
||||
solana-frozen-abi-macro = { path = "../../frozen-abi/macro", version = "=1.10.9" }
|
||||
solana-program = { path = "../../sdk/program", version = "=1.10.9" }
|
||||
thiserror = "1.0"
|
||||
|
||||
[target.'cfg(not(target_arch = "bpf"))'.dependencies]
|
||||
solana-program-runtime = { path = "../../program-runtime", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../../sdk", version = "=1.10.8" }
|
||||
solana-program-runtime = { path = "../../program-runtime", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../../sdk", version = "=1.10.9" }
|
||||
|
||||
[build-dependencies]
|
||||
rustc_version = "0.4"
|
||||
|
324
programs/bpf/Cargo.lock
generated
324
programs/bpf/Cargo.lock
generated
@@ -1620,6 +1620,15 @@ dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lru"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32613e41de4c47ab04970c348ca7ae7382cf116625755af070b008a15516a889"
|
||||
dependencies = [
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matches"
|
||||
version = "0.1.9"
|
||||
@@ -2799,7 +2808,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-account-decoder"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"base64 0.13.0",
|
||||
@@ -2820,7 +2829,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-address-lookup-table-program"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"bytemuck",
|
||||
@@ -2829,9 +2838,9 @@ dependencies = [
|
||||
"num-traits",
|
||||
"rustc_version 0.4.0",
|
||||
"serde",
|
||||
"solana-frozen-abi 1.10.8",
|
||||
"solana-frozen-abi-macro 1.10.8",
|
||||
"solana-program 1.10.8",
|
||||
"solana-frozen-abi 1.10.9",
|
||||
"solana-frozen-abi-macro 1.10.9",
|
||||
"solana-program 1.10.9",
|
||||
"solana-program-runtime",
|
||||
"solana-sdk",
|
||||
"thiserror",
|
||||
@@ -2839,12 +2848,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-banks-client"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"borsh",
|
||||
"futures",
|
||||
"solana-banks-interface",
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
"solana-sdk",
|
||||
"tarpc",
|
||||
"thiserror",
|
||||
@@ -2854,7 +2863,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-banks-interface"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"solana-sdk",
|
||||
@@ -2863,7 +2872,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-banks-server"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"crossbeam-channel",
|
||||
@@ -2880,7 +2889,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-loader-program"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"byteorder 1.4.3",
|
||||
@@ -2897,7 +2906,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-programs"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"byteorder 1.4.3",
|
||||
@@ -2912,7 +2921,7 @@ dependencies = [
|
||||
"solana-bpf-rust-realloc",
|
||||
"solana-bpf-rust-realloc-invoke",
|
||||
"solana-cli-output",
|
||||
"solana-logger 1.10.8",
|
||||
"solana-logger 1.10.9",
|
||||
"solana-measure",
|
||||
"solana-program-runtime",
|
||||
"solana-runtime",
|
||||
@@ -2924,171 +2933,171 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-128bit"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-bpf-rust-128bit-dep",
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-128bit-dep"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-alloc"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-call-depth"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-caller-access"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-custom-heap"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-dep-crate"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"byteorder 1.4.3",
|
||||
"solana-address-lookup-table-program",
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-deprecated-loader"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-dup-accounts"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-error-handling"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"num-derive",
|
||||
"num-traits",
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-external-spend"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-finalize"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-instruction-introspection"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-invoke"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-bpf-rust-invoked",
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-invoke-and-error"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-invoke-and-ok"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-invoke-and-return"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-invoked"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-iter"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-log-data"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-many-args"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-bpf-rust-many-args-dep",
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-many-args-dep"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-mem"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
"solana-program-runtime",
|
||||
"solana-program-test",
|
||||
"solana-sdk",
|
||||
@@ -3096,84 +3105,84 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-membuiltins"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-bpf-rust-mem",
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-noop"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-panic"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-param-passing"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-bpf-rust-param-passing-dep",
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-param-passing-dep"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-rand"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"getrandom 0.1.14",
|
||||
"rand 0.7.3",
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-realloc"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-realloc-invoke"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-bpf-rust-realloc",
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-ro-account_modify"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-ro-modify"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-sanity"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
"solana-program-runtime",
|
||||
"solana-program-test",
|
||||
"solana-sdk",
|
||||
@@ -3181,52 +3190,52 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-secp256k1-recover"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-sha"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"blake3 1.3.1",
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-sibling-instructions"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-sibling_inner-instructions"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-spoof1"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-spoof1-system"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-sysvar"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
"solana-program-runtime",
|
||||
"solana-program-test",
|
||||
"solana-sdk",
|
||||
@@ -3234,29 +3243,29 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-upgradeable"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-upgraded"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-zk_token_elgamal"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
"solana-zk-token-sdk",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bucket-map"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"log",
|
||||
"memmap2 0.5.3",
|
||||
@@ -3269,7 +3278,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-clap-utils"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"clap",
|
||||
@@ -3285,19 +3294,21 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-cli-config"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"dirs-next",
|
||||
"lazy_static",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_yaml",
|
||||
"solana-clap-utils",
|
||||
"solana-sdk",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-cli-output"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"base64 0.13.0",
|
||||
@@ -3306,10 +3317,12 @@ dependencies = [
|
||||
"console",
|
||||
"humantime",
|
||||
"indicatif",
|
||||
"semver 1.0.6",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"solana-account-decoder",
|
||||
"solana-clap-utils",
|
||||
"solana-cli-config",
|
||||
"solana-client",
|
||||
"solana-sdk",
|
||||
"solana-transaction-status",
|
||||
@@ -3319,7 +3332,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-client"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"async-mutex",
|
||||
"async-trait",
|
||||
@@ -3336,7 +3349,9 @@ dependencies = [
|
||||
"jsonrpc-core",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"lru",
|
||||
"quinn",
|
||||
"quinn-proto",
|
||||
"rand 0.7.3",
|
||||
"rand_chacha 0.2.2",
|
||||
"rayon",
|
||||
@@ -3350,6 +3365,7 @@ dependencies = [
|
||||
"solana-clap-utils",
|
||||
"solana-faucet",
|
||||
"solana-measure",
|
||||
"solana-metrics",
|
||||
"solana-net-utils",
|
||||
"solana-sdk",
|
||||
"solana-streamer",
|
||||
@@ -3366,7 +3382,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-compute-budget-program"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"solana-program-runtime",
|
||||
"solana-sdk",
|
||||
@@ -3374,7 +3390,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-config-program"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"chrono",
|
||||
@@ -3386,7 +3402,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-faucet"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"byteorder 1.4.3",
|
||||
@@ -3397,7 +3413,7 @@ dependencies = [
|
||||
"serde_derive",
|
||||
"solana-clap-utils",
|
||||
"solana-cli-config",
|
||||
"solana-logger 1.10.8",
|
||||
"solana-logger 1.10.9",
|
||||
"solana-metrics",
|
||||
"solana-sdk",
|
||||
"solana-version",
|
||||
@@ -3428,7 +3444,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-frozen-abi"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"bs58 0.4.0",
|
||||
"bv",
|
||||
@@ -3442,7 +3458,7 @@ dependencies = [
|
||||
"serde_bytes",
|
||||
"serde_derive",
|
||||
"sha2 0.10.2",
|
||||
"solana-frozen-abi-macro 1.10.8",
|
||||
"solana-frozen-abi-macro 1.10.9",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
@@ -3460,7 +3476,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-frozen-abi-macro"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.6",
|
||||
@@ -3481,7 +3497,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-logger"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"env_logger 0.9.0",
|
||||
"lazy_static",
|
||||
@@ -3490,7 +3506,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-measure"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"log",
|
||||
"solana-sdk",
|
||||
@@ -3498,7 +3514,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-metrics"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"gethostname",
|
||||
@@ -3510,7 +3526,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-net-utils"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"clap",
|
||||
@@ -3521,7 +3537,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"socket2",
|
||||
"solana-logger 1.10.8",
|
||||
"solana-logger 1.10.9",
|
||||
"solana-sdk",
|
||||
"solana-version",
|
||||
"tokio",
|
||||
@@ -3530,7 +3546,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-perf"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"bincode",
|
||||
@@ -3590,7 +3606,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-program"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"base64 0.13.0",
|
||||
"bincode",
|
||||
@@ -3621,16 +3637,16 @@ dependencies = [
|
||||
"serde_derive",
|
||||
"sha2 0.10.2",
|
||||
"sha3 0.10.1",
|
||||
"solana-frozen-abi 1.10.8",
|
||||
"solana-frozen-abi-macro 1.10.8",
|
||||
"solana-sdk-macro 1.10.8",
|
||||
"solana-frozen-abi 1.10.9",
|
||||
"solana-frozen-abi-macro 1.10.9",
|
||||
"solana-sdk-macro 1.10.9",
|
||||
"thiserror",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-program-runtime"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"base64 0.13.0",
|
||||
"bincode",
|
||||
@@ -3643,8 +3659,8 @@ dependencies = [
|
||||
"num-traits",
|
||||
"rustc_version 0.4.0",
|
||||
"serde",
|
||||
"solana-frozen-abi 1.10.8",
|
||||
"solana-frozen-abi-macro 1.10.8",
|
||||
"solana-frozen-abi 1.10.9",
|
||||
"solana-frozen-abi-macro 1.10.9",
|
||||
"solana-measure",
|
||||
"solana-sdk",
|
||||
"thiserror",
|
||||
@@ -3652,7 +3668,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-program-test"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base64 0.13.0",
|
||||
@@ -3663,7 +3679,7 @@ dependencies = [
|
||||
"solana-banks-client",
|
||||
"solana-banks-server",
|
||||
"solana-bpf-loader-program",
|
||||
"solana-logger 1.10.8",
|
||||
"solana-logger 1.10.9",
|
||||
"solana-program-runtime",
|
||||
"solana-runtime",
|
||||
"solana-sdk",
|
||||
@@ -3674,7 +3690,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-rayon-threadlimit"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"num_cpus",
|
||||
@@ -3682,7 +3698,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-remote-wallet"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"console",
|
||||
"dialoguer",
|
||||
@@ -3699,7 +3715,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-runtime"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"bincode",
|
||||
@@ -3733,8 +3749,8 @@ dependencies = [
|
||||
"solana-bucket-map",
|
||||
"solana-compute-budget-program",
|
||||
"solana-config-program",
|
||||
"solana-frozen-abi 1.10.8",
|
||||
"solana-frozen-abi-macro 1.10.8",
|
||||
"solana-frozen-abi 1.10.9",
|
||||
"solana-frozen-abi-macro 1.10.9",
|
||||
"solana-measure",
|
||||
"solana-metrics",
|
||||
"solana-program-runtime",
|
||||
@@ -3753,7 +3769,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-sdk"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"assert_matches",
|
||||
"base64 0.13.0",
|
||||
@@ -3790,11 +3806,11 @@ dependencies = [
|
||||
"serde_json",
|
||||
"sha2 0.10.2",
|
||||
"sha3 0.10.1",
|
||||
"solana-frozen-abi 1.10.8",
|
||||
"solana-frozen-abi-macro 1.10.8",
|
||||
"solana-logger 1.10.8",
|
||||
"solana-program 1.10.8",
|
||||
"solana-sdk-macro 1.10.8",
|
||||
"solana-frozen-abi 1.10.9",
|
||||
"solana-frozen-abi-macro 1.10.9",
|
||||
"solana-logger 1.10.9",
|
||||
"solana-program 1.10.9",
|
||||
"solana-sdk-macro 1.10.9",
|
||||
"thiserror",
|
||||
"uriparse",
|
||||
"wasm-bindgen",
|
||||
@@ -3815,7 +3831,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-sdk-macro"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"bs58 0.4.0",
|
||||
"proc-macro2 1.0.24",
|
||||
@@ -3826,7 +3842,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-send-transaction-service"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"log",
|
||||
@@ -3839,7 +3855,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-stake-program"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"log",
|
||||
@@ -3849,8 +3865,8 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"solana-config-program",
|
||||
"solana-frozen-abi 1.10.8",
|
||||
"solana-frozen-abi-macro 1.10.8",
|
||||
"solana-frozen-abi 1.10.9",
|
||||
"solana-frozen-abi-macro 1.10.9",
|
||||
"solana-metrics",
|
||||
"solana-program-runtime",
|
||||
"solana-sdk",
|
||||
@@ -3860,7 +3876,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-streamer"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"futures-util",
|
||||
@@ -3884,7 +3900,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-transaction-status"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"base64 0.13.0",
|
||||
@@ -3909,20 +3925,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-version"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"log",
|
||||
"rustc_version 0.4.0",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"solana-frozen-abi 1.10.8",
|
||||
"solana-frozen-abi-macro 1.10.8",
|
||||
"solana-frozen-abi 1.10.9",
|
||||
"solana-frozen-abi-macro 1.10.9",
|
||||
"solana-sdk",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-vote-program"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"log",
|
||||
@@ -3931,8 +3947,8 @@ dependencies = [
|
||||
"rustc_version 0.4.0",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"solana-frozen-abi 1.10.8",
|
||||
"solana-frozen-abi-macro 1.10.8",
|
||||
"solana-frozen-abi 1.10.9",
|
||||
"solana-frozen-abi-macro 1.10.9",
|
||||
"solana-metrics",
|
||||
"solana-program-runtime",
|
||||
"solana-sdk",
|
||||
@@ -3941,7 +3957,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-zk-token-proof-program"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"getrandom 0.1.14",
|
||||
@@ -3954,7 +3970,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-zk-token-sdk"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
dependencies = [
|
||||
"aes-gcm-siv",
|
||||
"arrayref",
|
||||
@@ -3973,7 +3989,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha3 0.9.1",
|
||||
"solana-program 1.10.8",
|
||||
"solana-program 1.10.9",
|
||||
"solana-sdk",
|
||||
"subtle",
|
||||
"thiserror",
|
||||
|
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "solana-bpf-programs"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
documentation = "https://docs.rs/solana"
|
||||
homepage = "https://solana.com/"
|
||||
readme = "README.md"
|
||||
@@ -26,19 +26,19 @@ itertools = "0.10.1"
|
||||
log = "0.4.11"
|
||||
miow = "0.3.6"
|
||||
net2 = "0.2.37"
|
||||
solana-bpf-rust-invoke = { path = "rust/invoke", version = "=1.10.8"}
|
||||
solana-bpf-loader-program = { path = "../bpf_loader", version = "=1.10.8"}
|
||||
solana-bpf-rust-realloc = { path = "rust/realloc", version = "=1.10.8"}
|
||||
solana-bpf-rust-realloc-invoke = { path = "rust/realloc_invoke", version = "=1.10.8"}
|
||||
solana-cli-output = { path = "../../cli-output", version = "=1.10.8" }
|
||||
solana-logger = { path = "../../logger", version = "=1.10.8" }
|
||||
solana-measure = { path = "../../measure", version = "=1.10.8" }
|
||||
solana-bpf-rust-invoke = { path = "rust/invoke", version = "=1.10.9"}
|
||||
solana-bpf-loader-program = { path = "../bpf_loader", version = "=1.10.9"}
|
||||
solana-bpf-rust-realloc = { path = "rust/realloc", version = "=1.10.9"}
|
||||
solana-bpf-rust-realloc-invoke = { path = "rust/realloc_invoke", version = "=1.10.9"}
|
||||
solana-cli-output = { path = "../../cli-output", version = "=1.10.9" }
|
||||
solana-logger = { path = "../../logger", version = "=1.10.9" }
|
||||
solana-measure = { path = "../../measure", version = "=1.10.9" }
|
||||
solana_rbpf = "=0.2.24"
|
||||
solana-runtime = { path = "../../runtime", version = "=1.10.8" }
|
||||
solana-program-runtime = { path = "../../program-runtime", version = "=1.10.8" }
|
||||
solana-sdk = { path = "../../sdk", version = "=1.10.8" }
|
||||
solana-transaction-status = { path = "../../transaction-status", version = "=1.10.8" }
|
||||
solana-account-decoder = { path = "../../account-decoder", version = "=1.10.8" }
|
||||
solana-runtime = { path = "../../runtime", version = "=1.10.9" }
|
||||
solana-program-runtime = { path = "../../program-runtime", version = "=1.10.9" }
|
||||
solana-sdk = { path = "../../sdk", version = "=1.10.9" }
|
||||
solana-transaction-status = { path = "../../transaction-status", version = "=1.10.9" }
|
||||
solana-account-decoder = { path = "../../account-decoder", version = "=1.10.9" }
|
||||
|
||||
[[bench]]
|
||||
name = "bpf_loader"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-bpf-rust-128bit"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -10,8 +10,8 @@ documentation = "https://docs.rs/solana-bpf-rust-128bit"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
solana-program = { path = "../../../../sdk/program", version = "=1.10.8" }
|
||||
solana-bpf-rust-128bit-dep = { path = "../128bit_dep", version = "=1.10.8" }
|
||||
solana-program = { path = "../../../../sdk/program", version = "=1.10.9" }
|
||||
solana-bpf-rust-128bit-dep = { path = "../128bit_dep", version = "=1.10.9" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-bpf-rust-128bit-dep"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -10,7 +10,7 @@ documentation = "https://docs.rs/solana-bpf-rust-128bit-dep"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
solana-program = { path = "../../../../sdk/program", version = "=1.10.8" }
|
||||
solana-program = { path = "../../../../sdk/program", version = "=1.10.9" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-bpf-rust-alloc"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -10,7 +10,7 @@ documentation = "https://docs.rs/solana-bpf-rust-alloc"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
solana-program = { path = "../../../../sdk/program", version = "=1.10.8" }
|
||||
solana-program = { path = "../../../../sdk/program", version = "=1.10.9" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-bpf-rust-call-depth"
|
||||
version = "1.10.8"
|
||||
version = "1.10.9"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -10,7 +10,7 @@ documentation = "https://docs.rs/solana-bpf-rust-call-depth"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
solana-program = { path = "../../../../sdk/program", version = "=1.10.8" }
|
||||
solana-program = { path = "../../../../sdk/program", version = "=1.10.9" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user