Compare commits

...

24 Commits

Author SHA1 Message Date
Jon Cinque
f2561ea547 v1.10-ci: Fix downstream build (#24404) 2022-04-16 12:45:01 +02:00
mergify[bot]
b98e133f2d Add Ident case (#24390) (#24402)
(cherry picked from commit a0e3e3c193)

Co-authored-by: Tyera Eulberg <tyera@solana.com>
2022-04-15 22:48:36 -06:00
Trent Nelson
25274e8a33 rpc-pubsub: reduce metrics/log spam
(cherry picked from commit 50fba01842)
2022-04-15 22:21:44 -06:00
mergify[bot]
3bf00e4af5 cli: sort option for validators by version (#24237)
(cherry picked from commit 91993d89b0)

# Conflicts:
#	Cargo.lock
#	cli-output/Cargo.toml
#	programs/bpf/Cargo.lock

Co-authored-by: Trent Nelson <trent@solana.com>
2022-04-15 09:19:12 +00:00
mergify[bot]
c289cd2a4b Do not require default keypair to exist for bench-tps (#24356) (#24365)
(cherry picked from commit 5e8c12ebdf)

Co-authored-by: Tyera Eulberg <tyera@solana.com>
2022-04-15 03:09:34 +00:00
mergify[bot]
84ac4ff57f add metrics around rewards (#24160) (#24168)
(cherry picked from commit 48d1af01c8)

Co-authored-by: Jeff Washington (jwash) <wash678@gmail.com>
2022-04-14 23:04:56 +00:00
mergify[bot]
58ef6b31f9 Quic client stats (#24195) (#24305)
* Add metrics to connection-cache to measure cache hits and misses

* Add congestion stats

* Add more client stats

* Review comments

Co-authored-by: Ryan Leung <ryan.leung@solana.com>

Co-authored-by: sakridge <sakridge@gmail.com>
Co-authored-by: Ryan Leung <ryan.leung@solana.com>
2022-04-14 16:42:20 -04:00
mergify[bot]
304cd65ecb Support quic in bench-tps (#24295) (#24317)
* Update comment

* Use connection_cache in tpu_client

* Add --tpu-use-quic to bench-tps

* Use connection_cache async send

(cherry picked from commit 26899359d1)

Co-authored-by: Tyera Eulberg <tyera@solana.com>
2022-04-13 22:56:29 -06:00
mergify[bot]
3bee921088 Add a stringified credential option for LedgerStorage (#24314) (#24324)
* add a stringified credential option for LedgerStorage

* fix clippy::useless-format warning

* change CredentialOption to enum CredentialType

* rename credential_option to credential_type

* restore LedgerStorage new fn signature

* fmt

Co-authored-by: Tyera Eulberg <tyera@solana.com>

Co-authored-by: Rachael Pai <komimi.p@gmail.com>
Co-authored-by: Tyera Eulberg <tyera@solana.com>
2022-04-13 22:17:56 -06:00
mergify[bot]
35d4f390ad Add RpcClient support to bench-tps (#24297) (#24320)
* Impl BenchTpsClient for RpcClient

* Support RpcClient in bench-tps

(cherry picked from commit 96e3555e93)

Co-authored-by: Tyera Eulberg <tyera@solana.com>
2022-04-13 19:33:11 -06:00
mergify[bot]
785481ace4 Async send for send transaction service (backport #24265) (#24323)
* Async send for send transaction service (#24265)

* async send

(cherry picked from commit 474080608a)

# Conflicts:
#	client/Cargo.toml

* Fix conflicts

Co-authored-by: anatoly yakovenko <anatoly@solana.com>
Co-authored-by: Tyera Eulberg <tyera@solana.com>
2022-04-13 19:29:03 -06:00
mergify[bot]
0e6ba29859 Use LRU in connection-cache (#24109) (#24322)
Switch to using LRU for connection-cache

Co-authored-by: ryleung-solana <91908731+ryleung-solana@users.noreply.github.com>
2022-04-13 21:21:19 -04:00
mergify[bot]
ec1d06240c Add ability to interact with a Bigtable with a custom instance id (backport #23779) (#24325)
* Refactor validator bigtable config

(cherry picked from commit 63ee00e647)

* bigtable: add a config ctor for `LedgerStorage`

(cherry picked from commit f513195468)

* bigtable: allow custom instance names

(cherry picked from commit 9b32b72990)

# Conflicts:
#	validator/Cargo.toml

* Add ability to query bigtable via solana-test-validator, with hidden params

(cherry picked from commit 9c60991cd3)

* Fix conflicts

Co-authored-by: Tyera Eulberg <tyera@solana.com>
Co-authored-by: Trent Nelson <trent@solana.com>
2022-04-13 19:00:47 -06:00
mergify[bot]
32dea4427b Bump bpf-tools to v1.25 (#24290)
- Tweak linker script
  Ensure that all read only sections end up in one segment, and
  everything else in other segments. Discard .eh_frame, .hash and
  .gnu.hash since they are unused.
- Don't create invalid string slices in stdout/stderr on Solana
- Report exceeded stack size as a warning if dynamic frames are off
- Native support for signed division in SBF
  Adds BPF_SDIV, which is enabled only for the SBF subtarget.
- Introduce dynamic stack frames and the SBFv2 flag
  Dynamic stack frames  are currently opt-in and enabled setting
  cpu=sbfv2. When sbfv2 is used, ELF files are flagged with
  e_flags=EF_SBF_V2 so the runtime can detect it and react
  accordingly.

(cherry picked from commit 6b611e1c52)

Co-authored-by: Dmitri Makarov <dmakarov@alumni.stanford.edu>
2022-04-13 20:26:13 +00:00
mergify[bot]
9aa95870fa Make tpu_use_quic a flag only without argument (#24018) (#24027)
(cherry picked from commit 98525ddea9)

Co-authored-by: Lijun Wang <83639177+lijunwangs@users.noreply.github.com>
2022-04-13 13:00:49 -06:00
Dmitri Makarov
d48e9b3a7b Bump sbf-tools version to v1.24
(cherry picked from commit 689064a4f4)
2022-04-13 09:15:12 -07:00
Dmitri Makarov
95a279f310 Double the chunk size for sending the program binary data in tx
(cherry picked from commit 03ed334ebb)

# Conflicts:
#	programs/bpf/tests/programs.rs
2022-04-13 09:15:12 -07:00
mergify[bot]
1700820583 Add TpuClient support to bench-tps (backport #24227) (#24284)
* Add TpuClient support to bench-tps (#24227)

* Add fallible send methods, and rpc_client helper

* Add helper to return RpcClient url

* Implement BenchTpsClient for TpuClient

* Add cli rpc and identity handling

* Handle different kinds of clients in main, use TpuClient

* Add tpu_client integration test

(cherry picked from commit 8487030ea6)

# Conflicts:
#	bench-tps/Cargo.toml

* Fix conflicts

Co-authored-by: Tyera Eulberg <tyera@solana.com>
2022-04-12 13:12:33 -06:00
mergify[bot]
0745738eb1 Add resolver = 2 to fix Windows build error on Travis CI (#24196) (#24259)
(cherry picked from commit a5e740431a)

Co-authored-by: Will Hickey <will.hickey@solana.com>
2022-04-12 14:05:18 -05:00
mergify[bot]
d02bf12976 Add BenchTpsClient trait (backport #24208) (#24256)
* Add BenchTpsClient trait (#24208)

* Add BenchTpsClient

* Impl BenchTpsClient for used clients

* Use BenchTpsClient in do_bench

* Update integration test to use faucet via rpc

* Support keypairs from file that are not prefunded

* Remove old perf-utils

(cherry picked from commit 3871c85fd7)

# Conflicts:
#	bench-tps/Cargo.toml

* Fix conflicts

Co-authored-by: Tyera Eulberg <tyera@solana.com>
2022-04-12 07:45:46 +00:00
mergify[bot]
587d45769d Thin client quic (#23973) (#24266)
Change thin-client to use connection-cache

(cherry picked from commit 8b72200afb)

Co-authored-by: ryleung-solana <91908731+ryleung-solana@users.noreply.github.com>
2022-04-11 23:54:39 -06:00
mergify[bot]
f495024591 Move helpers to solana-cli-config (#24246) (#24250)
* Add solana-cli-utils crate

* Use cli-utils in cli

* Move println fn to cli-output

* Use cli-config instead

(cherry picked from commit 8a73badf3d)

Co-authored-by: Tyera Eulberg <tyera@solana.com>
2022-04-11 22:17:01 -06:00
mergify[bot]
28a681a7bf Remove duplicate increment (#24219) (#24226)
(cherry picked from commit ff3b6d2b8b)

Co-authored-by: carllin <carl@solana.com>
2022-04-11 17:19:48 -04:00
Tyera Eulberg
15acdcc19a Bump version to v1.10.9 (#24253) 2022-04-11 13:30:11 -06:00
199 changed files with 3216 additions and 1851 deletions

343
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -88,3 +88,6 @@ members = [
exclude = [
"programs/bpf",
]
# This prevents a Travis CI error when building for Windows.
resolver = "2"

View File

@@ -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"

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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]

View File

@@ -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"] }

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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);
}
}
}

View 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;

View 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)
}
}

View 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())
}
}

View 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())
}
}

View 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())
}
}

View File

@@ -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
View 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);
})
}
}

View File

@@ -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;

View File

@@ -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);
}
}
}

View File

@@ -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));

View File

@@ -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()
});
}

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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"

View File

@@ -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]

View 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(),
}
}
}

View File

@@ -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.
///

View File

@@ -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]

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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]]

View File

@@ -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(),

View File

@@ -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!(),
};

View File

@@ -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,
);

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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());
}
}

View File

@@ -197,6 +197,10 @@ impl RpcSender for HttpSender {
return Ok(json["result"].take());
}
}
fn url(&self) -> String {
self.url.clone()
}
}
#[cfg(test)]

View File

@@ -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.

View File

@@ -468,4 +468,8 @@ impl RpcSender for MockSender {
};
Ok(val)
}
fn url(&self) -> String {
format!("MockSender: {}", self.url)
}
}

View File

@@ -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 {

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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)]

View File

@@ -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 {

View File

@@ -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]>;
}

View File

@@ -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]>,
{

View File

@@ -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"

View File

@@ -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);

View File

@@ -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

View File

@@ -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" }

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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"] }

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"]

View File

@@ -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]]

View File

@@ -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]

View File

@@ -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]

View File

@@ -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]

View File

@@ -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::{

View File

@@ -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(

View File

@@ -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"

View File

@@ -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]]

View File

@@ -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]

View File

@@ -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!(),

View File

@@ -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"

View File

@@ -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"]

View File

@@ -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(

View File

@@ -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)?;
}

View File

@@ -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 {

View File

@@ -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<()>,

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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]

View File

@@ -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"

View File

@@ -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)]

View File

@@ -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"

View File

@@ -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"

View File

@@ -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;

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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"] }

View File

@@ -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"]

View File

@@ -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
View File

@@ -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",

View File

@@ -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"

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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