Compare commits

..

46 Commits

Author SHA1 Message Date
Dan Albert
b2a5cf57ad Remove validator-info publish from net scripts 2020-04-22 18:06:46 -06:00
mergify[bot]
33c51ee75d Add getLowestNonpurgedBlock rpc; use blockstore api in getConfirmedBlocks (#9656) (#9663)
automerge
2020-04-22 15:17:51 -07:00
mergify[bot]
d8aa107fae Extend snapshot interval in multinode demo (#9657) (#9660)
automerge
2020-04-22 13:45:01 -07:00
mergify[bot]
82e02d0734 Relax setting withdraw authority during lockup (#9644) (#9645)
automerge
2020-04-21 22:35:27 -07:00
mergify[bot]
dae59bb3e1 Flag test_tvu_exit as serial to hopefully reduce CI flakiness (bp #9509) (#9636)
automerge
2020-04-21 17:16:05 -07:00
mergify[bot]
e0e7fc8e52 Wait for supermajority of cluster to have rooted a transaction to consider it finalized (#9618) (#9626)
automerge
2020-04-21 01:09:26 -07:00
mergify[bot]
9abc84c583 Move streamer test to integration test (#9050) (#9624)
automerge
2020-04-21 00:50:46 -07:00
Stephen Akridge
db6540772c Check distance for timestamp 2020-04-20 11:36:17 -07:00
mergify[bot]
840ebfe625 Error for invalid shred. (#9588) (#9596)
automerge
2020-04-19 22:42:48 -07:00
Michael Vines
953282dbf4 Budget for gossip traffic (#9550) (#9583)
automerge
2020-04-19 09:43:44 -07:00
mergify[bot]
788d1199ac Fix local-cluster test - archiver should wait for itself + 1 validator (#9577) (#9584)
automerge
2020-04-19 01:36:14 -07:00
Michael Vines
f6a8f718a8 Make rpc_subscriptions.rs tests serial (#9556)
automerge

(cherry picked from commit b58338b066)
2020-04-17 11:40:31 -07:00
sakridge
f225bf6f01 Make rpc tests serial (#9537)
(cherry picked from commit e655cba5bd)
2020-04-16 22:17:41 -07:00
Michael Vines
b5f03a380b Only build x86_64-unknown-linux-gnu on docs.rs 2020-04-16 19:07:43 -07:00
Michael Vines
140c75f613 Don't upload tarballs to buildkite to speed up build 2020-04-16 13:55:15 -07:00
Stephen Akridge
6a59f67fdc Write wallet key to explicit file
(cherry picked from commit 93669ab1fc)
2020-04-16 13:41:14 -07:00
Michael Vines
5943747001 Bump version to 1.0.19 2020-04-16 12:19:48 -07:00
mergify[bot]
f26f18d29d Don't unwrap on session new (#9531)
automerge
2020-04-16 10:05:41 -07:00
mergify[bot]
9b58d72f52 Rpc: Speed up getBlockTime (#9510) (#9513)
automerge
2020-04-16 00:19:50 -07:00
Michael Vines
0c885d6a04 Default to RUST_BACKTRACE=1 for more informative validator logs
(cherry picked from commit 4ac15e68cf)
2020-04-15 22:46:24 -07:00
Michael Vines
70b51c0a5a Pacify shellcheck 2020-04-15 17:53:23 -07:00
Michael Vines
560660ae11 Always run shellcheck 2020-04-15 17:53:03 -07:00
Michael Vines
5436855b67 Update build-cli-usage.sh 2020-04-15 17:49:15 -07:00
Michael Vines
7351e5ed2c Use $rust_stable
(cherry picked from commit d567799d43)

# Conflicts:
#	docs/build-cli-usage.sh
2020-04-15 17:49:15 -07:00
mergify[bot]
7ee993fadf RPC: Add health check URI (bp #9499) (#9504)
automerge
2020-04-15 12:31:08 -07:00
sakridge
9bf459e82f Fix race in multi_bind_in_range (#9493)
(cherry picked from commit ee72714c08)
2020-04-14 17:59:15 -07:00
sakridge
545090ff17 limit test jobs to 16 to prevent OOM (#9500)
(cherry picked from commit 2b2b2cac1f)
2020-04-14 17:52:05 -07:00
Michael Vines
bd8074507f Bump version to v1.0.18 2020-04-14 09:58:33 -07:00
Ryo Onodera
cfc7b22c4c Use type alias 2020-04-13 21:12:44 -07:00
Ryo Onodera
5f1c637508 Conditionally change max_age 2020-04-13 21:12:44 -07:00
Ryo Onodera
d888e0a6d7 Use same max_age regardless of leader/not-leader 2020-04-13 21:12:44 -07:00
Michael Vines
10e808e1bd Fail coverage faster in CI 2020-04-13 21:09:26 -07:00
Michael Vines
d9b03ca38b Assume json_rpc_url can be upgrade to a websocket if no port is supplied
(cherry picked from commit bcfadd6085)
2020-04-13 20:32:26 -07:00
Michael Vines
608d75b348 Unfold coverage test failures
(cherry picked from commit d4ea1ec6ad)
2020-04-13 18:08:25 -07:00
Michael Vines
cee3cee4ef Reorder CI jobs to allow for more concurrent PRs
(cherry picked from commit ce027da236)
2020-04-13 13:00:39 -07:00
Dan Albert
09e51323f0 Update buildkite-tests.yml
(cherry picked from commit 92a5a51632)
2020-04-13 11:01:00 -07:00
Michael Vines
da6f702129 Bump version to 1.0.17 2020-04-11 19:32:42 -07:00
mergify[bot]
02a83e7c6e Allow lower shred count (#9410) (#9451)
automerge
2020-04-11 14:49:32 -07:00
sakridge
83263e1737 Calculate account refs fix (#9448) 2020-04-11 12:56:20 -07:00
mergify[bot]
1f7ac22b60 Don't subject authorizing a new stake authority to lockup (#9434) (#9441)
automerge
2020-04-10 17:25:15 -07:00
Michael Vines
747debae56 Cache downloads to speed up CI
(cherry picked from commit b4e00275b2)
2020-04-10 12:25:49 -07:00
mergify[bot]
00b4186469 Improve coverage.sh usability when used locally (#9054) (#9424)
automerge
2020-04-10 05:59:35 -07:00
mergify[bot]
b087dabf4f Rpc: Add getConfirmedSignaturesForAddress (#9407) (#9417)
automerge
2020-04-09 21:20:28 -07:00
mergify[bot]
e00eb0a069 Remove Trust Wallet Beta install instructions (#9396) (#9397)
automerge
2020-04-09 08:52:04 -07:00
mergify[bot]
d4e49ffd06 Rpc: Add getConfirmedTransaction (#9381) (#9392)
automerge
2020-04-09 01:00:34 -07:00
Michael Vines
0f34a190ea Bump version to 1.0.16 2020-04-09 00:05:16 -07:00
123 changed files with 2579 additions and 1220 deletions

704
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-archiver-lib"
version = "1.0.15"
version = "1.0.19"
description = "Solana Archiver Library"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -15,25 +15,28 @@ ed25519-dalek = "=1.0.0-pre.1"
log = "0.4.8"
rand = "0.6.5"
rand_chacha = "0.1.1"
solana-client = { path = "../client", version = "1.0.15" }
solana-storage-program = { path = "../programs/storage", version = "1.0.15" }
solana-client = { path = "../client", version = "1.0.19" }
solana-storage-program = { path = "../programs/storage", version = "1.0.19" }
thiserror = "1.0"
serde = "1.0.104"
serde_json = "1.0.46"
serde_derive = "1.0.103"
solana-net-utils = { path = "../net-utils", version = "1.0.15" }
solana-chacha = { path = "../chacha", version = "1.0.15" }
solana-chacha-sys = { path = "../chacha-sys", version = "1.0.15" }
solana-ledger = { path = "../ledger", version = "1.0.15" }
solana-logger = { path = "../logger", version = "1.0.15" }
solana-perf = { path = "../perf", version = "1.0.15" }
solana-sdk = { path = "../sdk", version = "1.0.15" }
solana-core = { path = "../core", version = "1.0.15" }
solana-archiver-utils = { path = "../archiver-utils", version = "1.0.15" }
solana-metrics = { path = "../metrics", version = "1.0.15" }
solana-net-utils = { path = "../net-utils", version = "1.0.19" }
solana-chacha = { path = "../chacha", version = "1.0.19" }
solana-chacha-sys = { path = "../chacha-sys", version = "1.0.19" }
solana-ledger = { path = "../ledger", version = "1.0.19" }
solana-logger = { path = "../logger", version = "1.0.19" }
solana-perf = { path = "../perf", version = "1.0.19" }
solana-sdk = { path = "../sdk", version = "1.0.19" }
solana-core = { path = "../core", version = "1.0.19" }
solana-archiver-utils = { path = "../archiver-utils", version = "1.0.19" }
solana-metrics = { path = "../metrics", version = "1.0.19" }
[dev-dependencies]
hex = "0.4.0"
[lib]
name = "solana_archiver_lib"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -199,7 +199,7 @@ impl Archiver {
info!("Connecting to the cluster via {:?}", cluster_entrypoint);
let (nodes, _) =
match solana_core::gossip_service::discover_cluster(&cluster_entrypoint.gossip, 1) {
match solana_core::gossip_service::discover_cluster(&cluster_entrypoint.gossip, 2) {
Ok(nodes_and_archivers) => nodes_and_archivers,
Err(e) => {
//shutdown services before exiting

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-archiver-utils"
version = "1.0.15"
version = "1.0.19"
description = "Solana Archiver Utils"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -11,15 +11,18 @@ edition = "2018"
[dependencies]
log = "0.4.8"
rand = "0.6.5"
solana-chacha = { path = "../chacha", version = "1.0.15" }
solana-chacha-sys = { path = "../chacha-sys", version = "1.0.15" }
solana-ledger = { path = "../ledger", version = "1.0.15" }
solana-logger = { path = "../logger", version = "1.0.15" }
solana-perf = { path = "../perf", version = "1.0.15" }
solana-sdk = { path = "../sdk", version = "1.0.15" }
solana-chacha = { path = "../chacha", version = "1.0.19" }
solana-chacha-sys = { path = "../chacha-sys", version = "1.0.19" }
solana-ledger = { path = "../ledger", version = "1.0.19" }
solana-logger = { path = "../logger", version = "1.0.19" }
solana-perf = { path = "../perf", version = "1.0.19" }
solana-sdk = { path = "../sdk", version = "1.0.19" }
[dev-dependencies]
hex = "0.4.0"
[lib]
name = "solana_archiver_utils"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -2,7 +2,7 @@
authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-archiver"
version = "1.0.15"
version = "1.0.19"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -10,11 +10,14 @@ homepage = "https://solana.com/"
[dependencies]
clap = "2.33.0"
console = "0.9.2"
solana-clap-utils = { path = "../clap-utils", version = "1.0.15" }
solana-core = { path = "../core", version = "1.0.15" }
solana-logger = { path = "../logger", version = "1.0.15" }
solana-metrics = { path = "../metrics", version = "1.0.15" }
solana-archiver-lib = { path = "../archiver-lib", version = "1.0.15" }
solana-net-utils = { path = "../net-utils", version = "1.0.15" }
solana-sdk = { path = "../sdk", version = "1.0.15" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.19" }
solana-core = { path = "../core", version = "1.0.19" }
solana-logger = { path = "../logger", version = "1.0.19" }
solana-metrics = { path = "../metrics", version = "1.0.19" }
solana-archiver-lib = { path = "../archiver-lib", version = "1.0.19" }
solana-net-utils = { path = "../net-utils", version = "1.0.19" }
solana-sdk = { path = "../sdk", version = "1.0.19" }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -2,7 +2,7 @@
authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-banking-bench"
version = "1.0.15"
version = "1.0.19"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -10,11 +10,14 @@ homepage = "https://solana.com/"
[dependencies]
log = "0.4.6"
rayon = "1.2.0"
solana-core = { path = "../core", version = "1.0.15" }
solana-ledger = { path = "../ledger", version = "1.0.15" }
solana-logger = { path = "../logger", version = "1.0.15" }
solana-runtime = { path = "../runtime", version = "1.0.15" }
solana-measure = { path = "../measure", version = "1.0.15" }
solana-sdk = { path = "../sdk", version = "1.0.15" }
solana-core = { path = "../core", version = "1.0.19" }
solana-ledger = { path = "../ledger", version = "1.0.19" }
solana-logger = { path = "../logger", version = "1.0.19" }
solana-runtime = { path = "../runtime", version = "1.0.19" }
solana-measure = { path = "../measure", version = "1.0.19" }
solana-sdk = { path = "../sdk", version = "1.0.19" }
rand = "0.6.5"
crossbeam-channel = "0.3"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -2,7 +2,7 @@
authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-bench-exchange"
version = "1.0.15"
version = "1.0.19"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -18,17 +18,20 @@ rand = "0.6.5"
rayon = "1.2.0"
serde_json = "1.0.46"
serde_yaml = "0.8.11"
solana-clap-utils = { path = "../clap-utils", version = "1.0.15" }
solana-core = { path = "../core", version = "1.0.15" }
solana-genesis = { path = "../genesis", version = "1.0.15" }
solana-client = { path = "../client", version = "1.0.15" }
solana-faucet = { path = "../faucet", version = "1.0.15" }
solana-exchange-program = { path = "../programs/exchange", version = "1.0.15" }
solana-logger = { path = "../logger", version = "1.0.15" }
solana-metrics = { path = "../metrics", version = "1.0.15" }
solana-net-utils = { path = "../net-utils", version = "1.0.15" }
solana-runtime = { path = "../runtime", version = "1.0.15" }
solana-sdk = { path = "../sdk", version = "1.0.15" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.19" }
solana-core = { path = "../core", version = "1.0.19" }
solana-genesis = { path = "../genesis", version = "1.0.19" }
solana-client = { path = "../client", version = "1.0.19" }
solana-faucet = { path = "../faucet", version = "1.0.19" }
solana-exchange-program = { path = "../programs/exchange", version = "1.0.19" }
solana-logger = { path = "../logger", version = "1.0.19" }
solana-metrics = { path = "../metrics", version = "1.0.19" }
solana-net-utils = { path = "../net-utils", version = "1.0.19" }
solana-runtime = { path = "../runtime", version = "1.0.19" }
solana-sdk = { path = "../sdk", version = "1.0.19" }
[dev-dependencies]
solana-local-cluster = { path = "../local-cluster", version = "1.0.15" }
solana-local-cluster = { path = "../local-cluster", version = "1.0.19" }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -2,14 +2,17 @@
authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-bench-streamer"
version = "1.0.15"
version = "1.0.19"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
[dependencies]
clap = "2.33.0"
solana-clap-utils = { path = "../clap-utils", version = "1.0.15" }
solana-core = { path = "../core", version = "1.0.15" }
solana-logger = { path = "../logger", version = "1.0.15" }
solana-net-utils = { path = "../net-utils", version = "1.0.15" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.19" }
solana-core = { path = "../core", version = "1.0.19" }
solana-logger = { path = "../logger", version = "1.0.19" }
solana-net-utils = { path = "../net-utils", version = "1.0.19" }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -2,7 +2,7 @@
authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-bench-tps"
version = "1.0.15"
version = "1.0.19"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -14,24 +14,27 @@ log = "0.4.8"
rayon = "1.2.0"
serde_json = "1.0.46"
serde_yaml = "0.8.11"
solana-clap-utils = { path = "../clap-utils", version = "1.0.15" }
solana-core = { path = "../core", version = "1.0.15" }
solana-genesis = { path = "../genesis", version = "1.0.15" }
solana-client = { path = "../client", version = "1.0.15" }
solana-faucet = { path = "../faucet", version = "1.0.15" }
solana-librapay = { path = "../programs/librapay", version = "1.0.15", optional = true }
solana-logger = { path = "../logger", version = "1.0.15" }
solana-metrics = { path = "../metrics", version = "1.0.15" }
solana-measure = { path = "../measure", version = "1.0.15" }
solana-net-utils = { path = "../net-utils", version = "1.0.15" }
solana-runtime = { path = "../runtime", version = "1.0.15" }
solana-sdk = { path = "../sdk", version = "1.0.15" }
solana-move-loader-program = { path = "../programs/move_loader", version = "1.0.15", optional = true }
solana-clap-utils = { path = "../clap-utils", version = "1.0.19" }
solana-core = { path = "../core", version = "1.0.19" }
solana-genesis = { path = "../genesis", version = "1.0.19" }
solana-client = { path = "../client", version = "1.0.19" }
solana-faucet = { path = "../faucet", version = "1.0.19" }
solana-librapay = { path = "../programs/librapay", version = "1.0.19", optional = true }
solana-logger = { path = "../logger", version = "1.0.19" }
solana-metrics = { path = "../metrics", version = "1.0.19" }
solana-measure = { path = "../measure", version = "1.0.19" }
solana-net-utils = { path = "../net-utils", version = "1.0.19" }
solana-runtime = { path = "../runtime", version = "1.0.19" }
solana-sdk = { path = "../sdk", version = "1.0.19" }
solana-move-loader-program = { path = "../programs/move_loader", version = "1.0.19", optional = true }
[dev-dependencies]
serial_test = "0.3.2"
serial_test_derive = "0.4.0"
solana-local-cluster = { path = "../local-cluster", version = "1.0.15" }
solana-local-cluster = { path = "../local-cluster", version = "1.0.19" }
[features]
move = ["solana-librapay", "solana-move-loader-program"]
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-chacha-cuda"
version = "1.0.15"
version = "1.0.19"
description = "Solana Chacha Cuda APIs"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -10,15 +10,18 @@ edition = "2018"
[dependencies]
log = "0.4.8"
solana-archiver-utils = { path = "../archiver-utils", version = "1.0.15" }
solana-chacha = { path = "../chacha", version = "1.0.15" }
solana-ledger = { path = "../ledger", version = "1.0.15" }
solana-logger = { path = "../logger", version = "1.0.15" }
solana-perf = { path = "../perf", version = "1.0.15" }
solana-sdk = { path = "../sdk", version = "1.0.15" }
solana-archiver-utils = { path = "../archiver-utils", version = "1.0.19" }
solana-chacha = { path = "../chacha", version = "1.0.19" }
solana-ledger = { path = "../ledger", version = "1.0.19" }
solana-logger = { path = "../logger", version = "1.0.19" }
solana-perf = { path = "../perf", version = "1.0.19" }
solana-sdk = { path = "../sdk", version = "1.0.19" }
[dev-dependencies]
hex-literal = "0.2.1"
[lib]
name = "solana_chacha_cuda"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-chacha-sys"
version = "1.0.15"
version = "1.0.19"
description = "Solana chacha-sys"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -10,3 +10,6 @@ edition = "2018"
[build-dependencies]
cc = "1.0.49"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-chacha"
version = "1.0.15"
version = "1.0.19"
description = "Solana Chacha APIs"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,14 +12,17 @@ edition = "2018"
log = "0.4.8"
rand = "0.6.5"
rand_chacha = "0.1.1"
solana-chacha-sys = { path = "../chacha-sys", version = "1.0.15" }
solana-ledger = { path = "../ledger", version = "1.0.15" }
solana-logger = { path = "../logger", version = "1.0.15" }
solana-perf = { path = "../perf", version = "1.0.15" }
solana-sdk = { path = "../sdk", version = "1.0.15" }
solana-chacha-sys = { path = "../chacha-sys", version = "1.0.19" }
solana-ledger = { path = "../ledger", version = "1.0.19" }
solana-logger = { path = "../logger", version = "1.0.19" }
solana-perf = { path = "../perf", version = "1.0.19" }
solana-sdk = { path = "../sdk", version = "1.0.19" }
[dev-dependencies]
hex-literal = "0.2.1"
[lib]
name = "solana_chacha"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -18,3 +18,6 @@ steps:
- command: "ci/publish-docs.sh"
timeout_in_minutes: 15
name: "publish docs"
- command: ". ci/rust-version.sh; ci/docker-run.sh $$rust_stable_docker_image ci/test-move.sh"
name: "move"
timeout_in_minutes: 20

View File

@@ -2,12 +2,15 @@
# other than those in docs/ are modified
steps:
- command: "ci/shellcheck.sh"
name: "shellcheck"
timeout_in_minutes: 5
- command: ". ci/rust-version.sh; ci/docker-run.sh $$rust_nightly_docker_image ci/test-coverage.sh"
name: "coverage"
timeout_in_minutes: 30
- wait
- command: ". ci/rust-version.sh; ci/docker-run.sh $$rust_stable_docker_image ci/test-stable.sh"
name: "stable"
timeout_in_minutes: 60
artifact_paths: "log-*.txt"
- wait
- command: "ci/test-stable-perf.sh"
name: "stable-perf"
timeout_in_minutes: 40
@@ -17,21 +20,7 @@ steps:
- command: "ci/test-bench.sh"
name: "bench"
timeout_in_minutes: 30
- command: ". ci/rust-version.sh; ci/docker-run.sh $$rust_stable_docker_image ci/test-stable.sh"
name: "stable"
timeout_in_minutes: 60
artifact_paths: "log-*.txt"
agents:
- "queue=rpc-test-capable"
- command: ". ci/rust-version.sh; ci/docker-run.sh $$rust_stable_docker_image ci/test-move.sh"
name: "move"
timeout_in_minutes: 20
- command: ". ci/rust-version.sh; ci/docker-run.sh $$rust_stable_docker_image ci/test-local-cluster.sh"
name: "local-cluster"
timeout_in_minutes: 45
artifact_paths: "log-*.txt"
- command: ". ci/rust-version.sh; ci/docker-run.sh $$rust_nightly_docker_image ci/test-coverage.sh"
name: "coverage"
timeout_in_minutes: 30
agents:
- "queue=rpc-test-capable"

View File

@@ -8,6 +8,9 @@ steps:
- command: ". ci/rust-version.sh; ci/docker-run.sh $$rust_nightly_docker_image ci/test-checks.sh"
name: "checks"
timeout_in_minutes: 20
- command: "ci/shellcheck.sh"
name: "shellcheck"
timeout_in_minutes: 5
- wait

View File

@@ -95,9 +95,8 @@ fi
source ci/upload-ci-artifact.sh
for file in solana-release-$TARGET.tar.bz2 solana-release-$TARGET.yml solana-install-init-"$TARGET"* $MAYBE_TARBALLS; do
upload-ci-artifact "$file"
if [[ -n $DO_NOT_PUBLISH_TAR ]]; then
upload-ci-artifact "$file"
echo "Skipped $file due to DO_NOT_PUBLISH_TAR"
continue
fi

View File

@@ -38,10 +38,15 @@ test -d target/release/bpf && find target/release/bpf -name '*.d' -delete
# Clear the BPF sysroot files, they are not automatically rebuilt
rm -rf target/xargo # Issue #3105
# Limit compiler jobs to reduce memory usage
# on machines with 1gb/thread of memory
NPROC=$(nproc)
NPROC=$((NPROC>16 ? 16 : NPROC))
echo "Executing $testName"
case $testName in
test-stable)
_ cargo +"$rust_stable" test --all --exclude solana-local-cluster ${V:+--verbose} -- --nocapture
_ cargo +"$rust_stable" test --jobs "$NPROC" --all --exclude solana-local-cluster ${V:+--verbose} -- --nocapture
_ cargo +"$rust_stable" test --manifest-path bench-tps/Cargo.toml --features=move ${V:+--verbose} test_bench_tps_local_cluster_move -- --nocapture
;;
test-stable-perf)

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-clap-utils"
version = "1.0.15"
version = "1.0.19"
description = "Solana utilities for the clap"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -11,8 +11,8 @@ edition = "2018"
[dependencies]
clap = "2.33.0"
rpassword = "4.0"
solana-remote-wallet = { path = "../remote-wallet", version = "1.0.15" }
solana-sdk = { path = "../sdk", version = "1.0.15" }
solana-remote-wallet = { path = "../remote-wallet", version = "1.0.19" }
solana-sdk = { path = "../sdk", version = "1.0.19" }
thiserror = "1.0.11"
tiny-bip39 = "0.7.0"
url = "2.1.0"
@@ -20,3 +20,6 @@ chrono = "0.4"
[lib]
name = "solana_clap_utils"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-cli-config"
description = "Blockchain, Rebuilt for Scale"
version = "1.0.15"
version = "1.0.19"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -15,3 +15,6 @@ serde = "1.0.104"
serde_derive = "1.0.103"
serde_yaml = "0.8.11"
url = "2.1.1"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -60,17 +60,38 @@ impl Config {
ws_url
.set_scheme(if is_secure { "wss" } else { "ws" })
.expect("unable to set scheme");
let ws_port = match json_rpc_url.port() {
Some(port) => port + 1,
None => {
if is_secure {
8901
} else {
8900
}
}
};
ws_url.set_port(Some(ws_port)).expect("unable to set port");
if let Some(port) = json_rpc_url.port() {
ws_url.set_port(Some(port + 1)).expect("unable to set port");
}
ws_url.to_string()
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn compute_websocket_url() {
assert_eq!(
Config::compute_websocket_url(&"http://devnet.solana.com"),
"ws://devnet.solana.com/".to_string()
);
assert_eq!(
Config::compute_websocket_url(&"https://devnet.solana.com"),
"wss://devnet.solana.com/".to_string()
);
assert_eq!(
Config::compute_websocket_url(&"http://example.com:8899"),
"ws://example.com:8900/".to_string()
);
assert_eq!(
Config::compute_websocket_url(&"https://example.com:1234"),
"wss://example.com:1235/".to_string()
);
assert_eq!(Config::compute_websocket_url(&"garbage"), String::new());
}
}

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-cli"
description = "Blockchain, Rebuilt for Scale"
version = "1.0.15"
version = "1.0.19"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -26,30 +26,33 @@ reqwest = { version = "0.10.1", default-features = false, features = ["blocking"
serde = "1.0.104"
serde_derive = "1.0.103"
serde_json = "1.0.46"
solana-budget-program = { path = "../programs/budget", version = "1.0.15" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.15" }
solana-cli-config = { path = "../cli-config", version = "1.0.15" }
solana-client = { path = "../client", version = "1.0.15" }
solana-config-program = { path = "../programs/config", version = "1.0.15" }
solana-faucet = { path = "../faucet", version = "1.0.15" }
solana-logger = { path = "../logger", version = "1.0.15" }
solana-net-utils = { path = "../net-utils", version = "1.0.15" }
solana-remote-wallet = { path = "../remote-wallet", version = "1.0.15" }
solana-runtime = { path = "../runtime", version = "1.0.15" }
solana-sdk = { path = "../sdk", version = "1.0.15" }
solana-stake-program = { path = "../programs/stake", version = "1.0.15" }
solana-storage-program = { path = "../programs/storage", version = "1.0.15" }
solana-vote-program = { path = "../programs/vote", version = "1.0.15" }
solana-vote-signer = { path = "../vote-signer", version = "1.0.15" }
solana-budget-program = { path = "../programs/budget", version = "1.0.19" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.19" }
solana-cli-config = { path = "../cli-config", version = "1.0.19" }
solana-client = { path = "../client", version = "1.0.19" }
solana-config-program = { path = "../programs/config", version = "1.0.19" }
solana-faucet = { path = "../faucet", version = "1.0.19" }
solana-logger = { path = "../logger", version = "1.0.19" }
solana-net-utils = { path = "../net-utils", version = "1.0.19" }
solana-remote-wallet = { path = "../remote-wallet", version = "1.0.19" }
solana-runtime = { path = "../runtime", version = "1.0.19" }
solana-sdk = { path = "../sdk", version = "1.0.19" }
solana-stake-program = { path = "../programs/stake", version = "1.0.19" }
solana-storage-program = { path = "../programs/storage", version = "1.0.19" }
solana-vote-program = { path = "../programs/vote", version = "1.0.19" }
solana-vote-signer = { path = "../vote-signer", version = "1.0.19" }
titlecase = "1.1.0"
thiserror = "1.0.11"
url = "2.1.1"
[dev-dependencies]
solana-core = { path = "../core", version = "1.0.15" }
solana-budget-program = { path = "../programs/budget", version = "1.0.15" }
solana-core = { path = "../core", version = "1.0.19" }
solana-budget-program = { path = "../programs/budget", version = "1.0.19" }
tempfile = "3.1.0"
[[bin]]
name = "solana"
path = "src/main.rs"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-client"
version = "1.0.15"
version = "1.0.19"
description = "Solana Client"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -19,10 +19,10 @@ reqwest = { version = "0.10.1", default-features = false, features = ["blocking"
serde = "1.0.104"
serde_derive = "1.0.103"
serde_json = "1.0.46"
solana-net-utils = { path = "../net-utils", version = "1.0.15" }
solana-sdk = { path = "../sdk", version = "1.0.15" }
solana-transaction-status = { path = "../transaction-status", version = "1.0.15" }
solana-vote-program = { path = "../programs/vote", version = "1.0.15" }
solana-net-utils = { path = "../net-utils", version = "1.0.19" }
solana-sdk = { path = "../sdk", version = "1.0.19" }
solana-transaction-status = { path = "../transaction-status", version = "1.0.19" }
solana-vote-program = { path = "../programs/vote", version = "1.0.19" }
thiserror = "1.0"
tungstenite = "0.10.1"
url = "2.1.1"
@@ -31,4 +31,7 @@ url = "2.1.1"
assert_matches = "1.3.0"
jsonrpc-core = "14.0.5"
jsonrpc-http-server = "14.0.6"
solana-logger = { path = "../logger", version = "1.0.15" }
solana-logger = { path = "../logger", version = "1.0.19" }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,7 +1,7 @@
[package]
name = "solana-core"
description = "Blockchain, Rebuilt for Scale"
version = "1.0.15"
version = "1.0.19"
documentation = "https://docs.rs/solana"
homepage = "https://solana.com/"
readme = "../README.md"
@@ -43,34 +43,34 @@ regex = "1.3.4"
serde = "1.0.104"
serde_derive = "1.0.103"
serde_json = "1.0.46"
solana-budget-program = { path = "../programs/budget", version = "1.0.15" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.15" }
solana-client = { path = "../client", version = "1.0.15" }
solana-transaction-status = { path = "../transaction-status", version = "1.0.15" }
solana-faucet = { path = "../faucet", version = "1.0.15" }
solana-budget-program = { path = "../programs/budget", version = "1.0.19" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.19" }
solana-client = { path = "../client", version = "1.0.19" }
solana-transaction-status = { path = "../transaction-status", version = "1.0.19" }
solana-faucet = { path = "../faucet", version = "1.0.19" }
ed25519-dalek = "=1.0.0-pre.1"
solana-ledger = { path = "../ledger", version = "1.0.15" }
solana-logger = { path = "../logger", version = "1.0.15" }
solana-merkle-tree = { path = "../merkle-tree", version = "1.0.15" }
solana-metrics = { path = "../metrics", version = "1.0.15" }
solana-measure = { path = "../measure", version = "1.0.15" }
solana-net-utils = { path = "../net-utils", version = "1.0.15" }
solana-chacha-cuda = { path = "../chacha-cuda", version = "1.0.15" }
solana-perf = { path = "../perf", version = "1.0.15" }
solana-runtime = { path = "../runtime", version = "1.0.15" }
solana-sdk = { path = "../sdk", version = "1.0.15" }
solana-stake-program = { path = "../programs/stake", version = "1.0.15" }
solana-storage-program = { path = "../programs/storage", version = "1.0.15" }
solana-vote-program = { path = "../programs/vote", version = "1.0.15" }
solana-vote-signer = { path = "../vote-signer", version = "1.0.15" }
solana-sys-tuner = { path = "../sys-tuner", version = "1.0.15" }
solana-ledger = { path = "../ledger", version = "1.0.19" }
solana-logger = { path = "../logger", version = "1.0.19" }
solana-merkle-tree = { path = "../merkle-tree", version = "1.0.19" }
solana-metrics = { path = "../metrics", version = "1.0.19" }
solana-measure = { path = "../measure", version = "1.0.19" }
solana-net-utils = { path = "../net-utils", version = "1.0.19" }
solana-chacha-cuda = { path = "../chacha-cuda", version = "1.0.19" }
solana-perf = { path = "../perf", version = "1.0.19" }
solana-runtime = { path = "../runtime", version = "1.0.19" }
solana-sdk = { path = "../sdk", version = "1.0.19" }
solana-stake-program = { path = "../programs/stake", version = "1.0.19" }
solana-storage-program = { path = "../programs/storage", version = "1.0.19" }
solana-vote-program = { path = "../programs/vote", version = "1.0.19" }
solana-vote-signer = { path = "../vote-signer", version = "1.0.19" }
solana-sys-tuner = { path = "../sys-tuner", version = "1.0.19" }
tempfile = "3.1.0"
thiserror = "1.0"
tokio = "0.1"
tokio-codec = "0.1"
tokio-fs = "0.1"
tokio-io = "0.1"
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.0.15" }
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.0.19" }
trees = "0.2.1"
[dev-dependencies]
@@ -104,3 +104,6 @@ name = "cluster_info"
[[bench]]
name = "chacha"
required-features = ["chacha"]
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -27,6 +27,11 @@ use crate::{
sendmmsg::{multicast, send_mmsg},
weighted_shuffle::{weighted_best, weighted_shuffle},
};
use rand::distributions::{Distribution, WeightedIndex};
use rand::SeedableRng;
use rand_chacha::ChaChaRng;
use bincode::{serialize, serialized_size};
use compression::prelude::*;
use core::cmp;
@@ -35,6 +40,7 @@ use rayon::iter::IntoParallelIterator;
use rayon::iter::ParallelIterator;
use rayon::ThreadPool;
use solana_ledger::{bank_forks::BankForks, staking_utils};
use solana_measure::measure::Measure;
use solana_measure::thread_mem_usage;
use solana_metrics::{datapoint_debug, inc_new_counter_debug, inc_new_counter_error};
use solana_net_utils::{
@@ -95,6 +101,12 @@ pub enum ClusterInfoError {
BadGossipAddress,
}
#[derive(Clone)]
pub struct DataBudget {
bytes: usize, // amount of bytes we have in the budget to send
last_timestamp_ms: u64, // Last time that we upped the bytes count,
// used to detect when to up the bytes budget again
}
#[derive(Clone)]
pub struct ClusterInfo {
/// The network
pub gossip: CrdsGossip,
@@ -103,6 +115,8 @@ pub struct ClusterInfo {
/// The network entrypoint
entrypoint: Option<ContactInfo>,
last_datapoint_submit: Instant,
outbound_budget: DataBudget,
}
#[derive(Default, Clone)]
@@ -188,6 +202,14 @@ pub fn make_accounts_hashes_message(
Some(CrdsValue::new_signed(message, keypair))
}
fn distance(a: u64, b: u64) -> u64 {
if a > b {
a - b
} else {
b - a
}
}
// TODO These messages should go through the gpu pipeline for spam filtering
#[derive(Serialize, Deserialize, Debug)]
#[allow(clippy::large_enum_variant)]
@@ -199,6 +221,17 @@ enum Protocol {
PruneMessage(Pubkey, PruneData),
}
// Rating for pull requests
// A response table is generated as a
// 2-d table arranged by target nodes and a
// list of responses for that node,
// to/responses_index is a location in that table.
struct ResponseScore {
to: usize, // to, index of who the response is to
responses_index: usize, // index into the list of responses for a given to
score: u64, // Relative score of the response
}
impl ClusterInfo {
/// Without a valid keypair gossip will not function. Only useful for tests.
pub fn new_with_invalid_keypair(contact_info: ContactInfo) -> Self {
@@ -211,6 +244,10 @@ impl ClusterInfo {
keypair,
entrypoint: None,
last_datapoint_submit: Instant::now(),
outbound_budget: DataBudget {
bytes: 0,
last_timestamp_ms: 0,
},
};
let id = contact_info.id;
me.gossip.set_self(&id);
@@ -1003,7 +1040,7 @@ impl ClusterInfo {
let mut num_live_peers = 1i64;
peers.iter().for_each(|p| {
// A peer is considered live if they generated their contact info recently
if timestamp() - p.wallclock <= CRDS_GOSSIP_PULL_CRDS_TIMEOUT_MS {
if distance(timestamp(), p.wallclock) <= CRDS_GOSSIP_PULL_CRDS_TIMEOUT_MS {
num_live_peers += 1;
}
});
@@ -1419,20 +1456,43 @@ impl ClusterInfo {
})
});
// process the collected pulls together
let rsp = Self::handle_pull_requests(me, recycler, gossip_pull_data);
let rsp = Self::handle_pull_requests(me, recycler, gossip_pull_data, stakes);
if let Some(rsp) = rsp {
let _ignore_disconnect = response_sender.send(rsp);
}
}
// Pull requests take an incoming bloom filter of contained entries from a node
// and tries to send back to them the values it detects are missing.
fn handle_pull_requests(
me: &Arc<RwLock<Self>>,
recycler: &PacketsRecycler,
requests: Vec<PullData>,
stakes: &HashMap<Pubkey, u64>,
) -> Option<Packets> {
// split the requests into addrs and filters
let mut caller_and_filters = vec![];
let mut addrs = vec![];
let mut time = Measure::start("handle_pull_requests");
{
let mut cluster_info = me.write().unwrap();
let now = timestamp();
const INTERVAL_MS: u64 = 100;
// allow 50kBps per staked validator, epoch slots + votes ~= 1.5kB/slot ~= 4kB/s
const BYTES_PER_INTERVAL: usize = 5000;
const MAX_BUDGET_MULTIPLE: usize = 5; // allow budget build-up to 5x the interval default
if now - cluster_info.outbound_budget.last_timestamp_ms > INTERVAL_MS {
let len = std::cmp::max(stakes.len(), 2);
cluster_info.outbound_budget.bytes += len * BYTES_PER_INTERVAL;
cluster_info.outbound_budget.bytes = std::cmp::min(
cluster_info.outbound_budget.bytes,
MAX_BUDGET_MULTIPLE * len * BYTES_PER_INTERVAL,
);
cluster_info.outbound_budget.last_timestamp_ms = now;
}
}
for pull_data in requests {
caller_and_filters.push((pull_data.caller, pull_data.filter));
addrs.push(pull_data.from_addr);
@@ -1444,30 +1504,101 @@ impl ClusterInfo {
.unwrap()
.gossip
.process_pull_requests(caller_and_filters, now);
let mut packets = Packets::new_with_recycler(recycler.clone(), 64, "handle_pull_requests");
pull_responses
// Filter bad to addresses
let pull_responses: Vec<_> = pull_responses
.into_iter()
.zip(addrs.into_iter())
.for_each(|(response, from_addr)| {
if !from_addr.ip().is_unspecified() && from_addr.port() != 0 {
let len = response.len();
trace!("get updates since response {}", len);
inc_new_counter_debug!("cluster_info-pull_request-rsp", len);
Self::split_gossip_messages(response)
.into_iter()
.for_each(|payload| {
let protocol = Protocol::PullResponse(self_id, payload);
// The remote node may not know its public IP:PORT. Instead of responding to the caller's
// gossip addr, respond to the origin addr. The last origin addr is picked from the list of
// addrs.
packets
.packets
.push(Packet::from_data(&from_addr, protocol))
})
.filter_map(|(responses, from_addr)| {
if !from_addr.ip().is_unspecified()
&& from_addr.port() != 0
&& !responses.is_empty()
{
Some((responses, from_addr))
} else {
trace!("Dropping Gossip pull response, as destination is unknown");
None
}
});
})
.collect();
if pull_responses.is_empty() {
return None;
}
let mut stats: Vec<_> = pull_responses
.iter()
.enumerate()
.map(|(i, (responses, _from_addr))| {
let score: u64 = if stakes.get(&responses[0].pubkey()).is_some() {
2
} else {
1
};
responses
.iter()
.enumerate()
.map(|(j, _response)| ResponseScore {
to: i,
responses_index: j,
score,
})
.collect::<Vec<ResponseScore>>()
})
.flatten()
.collect();
stats.sort_by(|a, b| a.score.cmp(&b.score));
let weights: Vec<_> = stats.iter().map(|stat| stat.score).collect();
let seed = [48u8; 32];
let rng = &mut ChaChaRng::from_seed(seed);
let weighted_index = WeightedIndex::new(weights).unwrap();
let mut packets = Packets::new_with_recycler(recycler.clone(), 64, "handle_pull_requests");
let mut total_bytes = 0;
let outbound_budget = me.read().unwrap().outbound_budget.bytes;
let mut sent = HashSet::new();
while sent.len() < stats.len() {
let index = weighted_index.sample(rng);
if sent.contains(&index) {
continue;
}
sent.insert(index);
let stat = &stats[index];
let from_addr = pull_responses[stat.to].1;
let response = pull_responses[stat.to].0[stat.responses_index].clone();
let protocol = Protocol::PullResponse(self_id, vec![response]);
packets
.packets
.push(Packet::from_data(&from_addr, protocol));
let len = packets.packets.len();
total_bytes += packets.packets[len - 1].meta.size;
if total_bytes > outbound_budget {
inc_new_counter_info!("gossip_pull_request-no_budget", 1);
break;
}
}
{
let mut cluster_info = me.write().unwrap();
cluster_info.outbound_budget.bytes = cluster_info
.outbound_budget
.bytes
.saturating_sub(total_bytes);
}
time.stop();
inc_new_counter_info!("gossip_pull_request-sent_requests", sent.len());
inc_new_counter_info!(
"gossip_pull_request-dropped_requests",
stats.len() - sent.len()
);
debug!(
"handle_pull_requests: {} sent: {} total: {} total_bytes: {}",
time,
sent.len(),
stats.len(),
total_bytes
);
if packets.is_empty() {
return None;
}

View File

@@ -13,9 +13,11 @@ use std::{
time::Duration,
};
pub type BlockCommitmentArray = [u64; MAX_LOCKOUT_HISTORY + 1];
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
pub struct BlockCommitment {
pub commitment: [u64; MAX_LOCKOUT_HISTORY],
pub commitment: BlockCommitmentArray,
}
impl BlockCommitment {
@@ -28,8 +30,17 @@ impl BlockCommitment {
assert!(confirmation_count > 0 && confirmation_count <= MAX_LOCKOUT_HISTORY);
self.commitment[confirmation_count - 1]
}
pub fn increase_rooted_stake(&mut self, stake: u64) {
self.commitment[MAX_LOCKOUT_HISTORY] += stake;
}
pub fn get_rooted_stake(&self) -> u64 {
self.commitment[MAX_LOCKOUT_HISTORY]
}
#[cfg(test)]
pub(crate) fn new(commitment: [u64; MAX_LOCKOUT_HISTORY]) -> Self {
pub(crate) fn new(commitment: BlockCommitmentArray) -> Self {
Self { commitment }
}
}
@@ -110,6 +121,16 @@ impl BlockCommitmentCache {
0
})
}
pub fn is_confirmed_rooted(&self, slot: Slot) -> bool {
self.get_block_commitment(slot)
.map(|block_commitment| {
(block_commitment.get_rooted_stake() as f64 / self.total_stake as f64)
> VOTE_THRESHOLD_SIZE
})
.unwrap_or(false)
}
#[cfg(test)]
pub fn new_for_tests() -> Self {
let mut block_commitment: HashMap<Slot, BlockCommitment> = HashMap::new();
@@ -259,7 +280,7 @@ impl AggregateCommitmentService {
commitment
.entry(*a)
.or_insert_with(BlockCommitment::default)
.increase_confirmation_stake(MAX_LOCKOUT_HISTORY, lamports);
.increase_rooted_stake(lamports);
} else {
ancestors_index = i;
break;
@@ -351,7 +372,7 @@ mod tests {
for a in ancestors {
let mut expected = BlockCommitment::default();
expected.increase_confirmation_stake(MAX_LOCKOUT_HISTORY, lamports);
expected.increase_rooted_stake(lamports);
assert_eq!(*commitment.get(&a).unwrap(), expected);
}
}
@@ -376,7 +397,7 @@ mod tests {
for a in ancestors {
if a <= root {
let mut expected = BlockCommitment::default();
expected.increase_confirmation_stake(MAX_LOCKOUT_HISTORY, lamports);
expected.increase_rooted_stake(lamports);
assert_eq!(*commitment.get(&a).unwrap(), expected);
} else {
let mut expected = BlockCommitment::default();
@@ -408,7 +429,7 @@ mod tests {
for (i, a) in ancestors.iter().enumerate() {
if *a <= root {
let mut expected = BlockCommitment::default();
expected.increase_confirmation_stake(MAX_LOCKOUT_HISTORY, lamports);
expected.increase_rooted_stake(lamports);
assert_eq!(*commitment.get(&a).unwrap(), expected);
} else if i <= 4 {
let mut expected = BlockCommitment::default();

View File

@@ -13,15 +13,18 @@ use std::thread;
use std::thread::{Builder, JoinHandle};
use std::time::Duration;
// - To try and keep the RocksDB size under 512GB:
// Seeing about 1600b/shred, using 2000b/shred for margin, so 250m shreds can be stored in 512gb.
// at 5k shreds/slot at 50k tps, this is 500k slots (~5.5 hours).
// - To try and keep the RocksDB size under 400GB:
// Seeing about 1600b/shred, using 2000b/shred for margin, so 200m shreds can be stored in 400gb.
// at 5k shreds/slot at 50k tps, this is 500k slots (~5 hours).
// At idle, 60 shreds/slot this is about 4m slots (18 days)
// This is chosen to allow enough time for
// - A validator to download a snapshot from a peer and boot from it
// - To make sure that if a validator needs to reboot from its own snapshot, it has enough slots locally
// to catch back up to where it was when it stopped
pub const DEFAULT_MAX_LEDGER_SHREDS: u64 = 250_000_000;
pub const DEFAULT_MAX_LEDGER_SHREDS: u64 = 200_000_000;
// Allow down to 50m, or 3.5 days at idle, 1hr at 50k load, around ~100GB
pub const DEFAULT_MIN_MAX_LEDGER_SHREDS: u64 = 50_000_000;
// Check for removing slots at this interval so we don't purge too often
// and starve other blockstore users.

View File

@@ -213,49 +213,4 @@ mod tests {
assert_eq!(packets[i].meta.addr(), saddr2);
}
}
#[cfg(target_os = "linux")]
#[test]
pub fn test_recv_mmsg_batch_size() {
let reader = UdpSocket::bind("127.0.0.1:0").expect("bind");
let addr = reader.local_addr().unwrap();
let sender = UdpSocket::bind("127.0.0.1:0").expect("bind");
const TEST_BATCH_SIZE: usize = 64;
let sent = TEST_BATCH_SIZE;
let mut elapsed_in_max_batch = 0;
(0..1000).for_each(|_| {
for _ in 0..sent {
let data = [0; PACKET_DATA_SIZE];
sender.send_to(&data[..], &addr).unwrap();
}
let mut packets = vec![Packet::default(); TEST_BATCH_SIZE];
let now = Instant::now();
let recv = recv_mmsg(&reader, &mut packets[..]).unwrap().1;
elapsed_in_max_batch += now.elapsed().as_nanos();
assert_eq!(TEST_BATCH_SIZE, recv);
});
let mut elapsed_in_small_batch = 0;
(0..1000).for_each(|_| {
for _ in 0..sent {
let data = [0; PACKET_DATA_SIZE];
sender.send_to(&data[..], &addr).unwrap();
}
let mut packets = vec![Packet::default(); 4];
let mut recv = 0;
let now = Instant::now();
while let Ok(num) = recv_mmsg(&reader, &mut packets[..]) {
recv += num.1;
if recv >= TEST_BATCH_SIZE {
break;
}
}
elapsed_in_small_batch += now.elapsed().as_nanos();
assert_eq!(TEST_BATCH_SIZE, recv);
});
assert!(elapsed_in_max_batch <= elapsed_in_small_batch);
}
}

View File

@@ -26,6 +26,7 @@ use solana_metrics::inc_new_counter_info;
use solana_runtime::bank::Bank;
use solana_sdk::{
clock::Slot,
genesis_config::GenesisConfig,
hash::Hash,
pubkey::Pubkey,
signature::{Keypair, Signer},
@@ -80,6 +81,7 @@ pub struct ReplayStageConfig {
pub block_commitment_cache: Arc<RwLock<BlockCommitmentCache>>,
pub transaction_status_sender: Option<TransactionStatusSender>,
pub rewards_recorder_sender: Option<RewardsRecorderSender>,
pub genesis_config: GenesisConfig,
}
pub struct ReplayStage {
@@ -183,6 +185,7 @@ impl ReplayStage {
block_commitment_cache,
transaction_status_sender,
rewards_recorder_sender,
genesis_config,
} = config;
let (root_bank_sender, root_bank_receiver) = channel();
@@ -246,6 +249,7 @@ impl ReplayStage {
&slot_full_senders,
transaction_status_sender.clone(),
&verify_recyclers,
&genesis_config,
);
datapoint_debug!(
"replay_stage-memory",
@@ -551,6 +555,7 @@ impl ReplayStage {
bank_progress: &mut ForkProgress,
transaction_status_sender: Option<TransactionStatusSender>,
verify_recyclers: &VerifyRecyclers,
genesis_config: &GenesisConfig,
) -> result::Result<usize, BlockstoreProcessorError> {
let tx_count_before = bank_progress.replay_progress.num_txs;
let confirm_result = blockstore_processor::confirm_slot(
@@ -562,6 +567,7 @@ impl ReplayStage {
transaction_status_sender,
None,
verify_recyclers,
Some(genesis_config),
);
let tx_count_after = bank_progress.replay_progress.num_txs;
let tx_count = tx_count_after - tx_count_before;
@@ -737,6 +743,7 @@ impl ReplayStage {
slot_full_senders: &[Sender<(u64, Pubkey)>],
transaction_status_sender: Option<TransactionStatusSender>,
verify_recyclers: &VerifyRecyclers,
genesis_config: &GenesisConfig,
) -> bool {
let mut did_complete_bank = false;
let mut tx_count = 0;
@@ -765,6 +772,7 @@ impl ReplayStage {
bank_progress,
transaction_status_sender.clone(),
verify_recyclers,
genesis_config,
);
match replay_result {
Ok(replay_tx_count) => tx_count += replay_tx_count,
@@ -1709,6 +1717,7 @@ pub(crate) mod tests {
&mut bank0_progress,
None,
&VerifyRecyclers::default(),
&genesis_config,
);
// Check that the erroring bank was marked as dead in the progress map

View File

@@ -1,17 +1,19 @@
//! The `rpc` module implements the Solana RPC interface.
use crate::{
cluster_info::ClusterInfo, commitment::BlockCommitmentCache, contact_info::ContactInfo,
packet::PACKET_DATA_SIZE, storage_stage::StorageState, validator::ValidatorExit,
cluster_info::ClusterInfo,
commitment::{BlockCommitmentArray, BlockCommitmentCache},
contact_info::ContactInfo,
packet::PACKET_DATA_SIZE,
storage_stage::StorageState,
validator::ValidatorExit,
};
use bincode::serialize;
use jsonrpc_core::{Error, Metadata, Result};
use jsonrpc_derive::rpc;
use solana_client::rpc_response::*;
use solana_faucet::faucet::request_airdrop_transaction;
use solana_ledger::{
bank_forks::BankForks, blockstore::Blockstore, rooted_slot_iterator::RootedSlotIterator,
};
use solana_ledger::{bank_forks::BankForks, blockstore::Blockstore};
use solana_runtime::bank::Bank;
use solana_sdk::{
clock::{Slot, UnixTimestamp},
@@ -24,7 +26,9 @@ use solana_sdk::{
timing::slot_duration_from_slots_per_year,
transaction::{self, Transaction},
};
use solana_transaction_status::{ConfirmedBlock, TransactionEncoding, TransactionStatus};
use solana_transaction_status::{
ConfirmedBlock, ConfirmedTransaction, TransactionEncoding, TransactionStatus,
};
use solana_vote_program::vote_state::{VoteState, MAX_LOCKOUT_HISTORY};
use std::{
collections::HashMap,
@@ -36,6 +40,7 @@ use std::{
};
const MAX_QUERY_ITEMS: usize = 256;
const MAX_SLOT_RANGE: u64 = 10_000;
type RpcResponse<T> = Result<Response<T>>;
@@ -215,7 +220,7 @@ impl JsonRpcRequestProcessor {
}
}
fn get_block_commitment(&self, block: Slot) -> RpcBlockCommitment<[u64; MAX_LOCKOUT_HISTORY]> {
fn get_block_commitment(&self, block: Slot) -> RpcBlockCommitment<BlockCommitmentArray> {
let r_block_commitment = self.block_commitment_cache.read().unwrap();
RpcBlockCommitment {
commitment: r_block_commitment
@@ -374,18 +379,12 @@ impl JsonRpcRequestProcessor {
if end_slot < start_slot {
return Ok(vec![]);
}
let start_slot = (start_slot..end_slot).find(|&slot| self.blockstore.is_root(slot));
if let Some(start_slot) = start_slot {
let mut slots: Vec<Slot> = RootedSlotIterator::new(start_slot, &self.blockstore)
.unwrap()
.map(|(slot, _)| slot)
.collect();
slots.retain(|&x| x <= end_slot);
Ok(slots)
} else {
Ok(vec![])
}
Ok(self
.blockstore
.rooted_slot_iterator(start_slot)
.map_err(|_| Error::internal_error())?
.filter(|&slot| slot <= end_slot)
.collect())
}
pub fn get_block_time(&self, slot: Slot) -> Result<Option<UnixTimestamp>> {
@@ -487,7 +486,9 @@ impl JsonRpcRequestProcessor {
.map(|(slot, status)| {
let r_block_commitment_cache = self.block_commitment_cache.read().unwrap();
let confirmations = if r_block_commitment_cache.root() >= slot {
let confirmations = if r_block_commitment_cache.root() >= slot
&& r_block_commitment_cache.is_confirmed_rooted(slot)
{
None
} else {
r_block_commitment_cache
@@ -503,6 +504,44 @@ impl JsonRpcRequestProcessor {
}
})
}
pub fn get_confirmed_transaction(
&self,
signature: Signature,
encoding: Option<TransactionEncoding>,
) -> Result<Option<ConfirmedTransaction>> {
if self.config.enable_rpc_transaction_history {
Ok(self
.blockstore
.get_confirmed_transaction(signature, encoding)
.unwrap_or(None))
} else {
Ok(None)
}
}
pub fn get_confirmed_signatures_for_address(
&self,
pubkey: Pubkey,
start_slot: Slot,
end_slot: Slot,
) -> Result<Vec<Signature>> {
if self.config.enable_rpc_transaction_history {
Ok(self
.blockstore
.get_confirmed_signatures_for_address(pubkey, start_slot, end_slot)
.unwrap_or_else(|_| vec![]))
} else {
Ok(vec![])
}
}
pub fn get_first_available_block(&self) -> Result<Slot> {
Ok(self
.blockstore
.get_first_available_block()
.unwrap_or_default())
}
}
fn get_tpu_addr(cluster_info: &Arc<RwLock<ClusterInfo>>) -> Result<SocketAddr> {
@@ -614,7 +653,7 @@ pub trait RpcSol {
&self,
meta: Self::Metadata,
block: Slot,
) -> Result<RpcBlockCommitment<[u64; MAX_LOCKOUT_HISTORY]>>;
) -> Result<RpcBlockCommitment<BlockCommitmentArray>>;
#[rpc(meta, name = "getGenesisHash")]
fn get_genesis_hash(&self, meta: Self::Metadata) -> Result<String>;
@@ -744,6 +783,26 @@ pub trait RpcSol {
start_slot: Slot,
end_slot: Option<Slot>,
) -> Result<Vec<Slot>>;
#[rpc(meta, name = "getConfirmedTransaction")]
fn get_confirmed_transaction(
&self,
meta: Self::Metadata,
signature_str: String,
encoding: Option<TransactionEncoding>,
) -> Result<Option<ConfirmedTransaction>>;
#[rpc(meta, name = "getConfirmedSignaturesForAddress")]
fn get_confirmed_signatures_for_address(
&self,
meta: Self::Metadata,
pubkey_str: String,
start_slot: Slot,
end_slot: Slot,
) -> Result<Vec<String>>;
#[rpc(meta, name = "getFirstAvailableBlock")]
fn get_first_available_block(&self, meta: Self::Metadata) -> Result<Slot>;
}
pub struct RpcSolImpl;
@@ -901,7 +960,7 @@ impl RpcSol for RpcSolImpl {
&self,
meta: Self::Metadata,
block: Slot,
) -> Result<RpcBlockCommitment<[u64; MAX_LOCKOUT_HISTORY]>> {
) -> Result<RpcBlockCommitment<BlockCommitmentArray>> {
Ok(meta
.request_processor
.read()
@@ -1287,6 +1346,58 @@ impl RpcSol for RpcSolImpl {
fn get_block_time(&self, meta: Self::Metadata, slot: Slot) -> Result<Option<UnixTimestamp>> {
meta.request_processor.read().unwrap().get_block_time(slot)
}
fn get_confirmed_transaction(
&self,
meta: Self::Metadata,
signature_str: String,
encoding: Option<TransactionEncoding>,
) -> Result<Option<ConfirmedTransaction>> {
let signature = verify_signature(&signature_str)?;
meta.request_processor
.read()
.unwrap()
.get_confirmed_transaction(signature, encoding)
}
fn get_confirmed_signatures_for_address(
&self,
meta: Self::Metadata,
pubkey_str: String,
start_slot: Slot,
end_slot: Slot,
) -> Result<Vec<String>> {
let pubkey = verify_pubkey(pubkey_str)?;
if end_slot <= start_slot {
return Err(Error::invalid_params(format!(
"start_slot {} must be smaller than end_slot {}",
start_slot, end_slot
)));
}
if end_slot - start_slot > MAX_SLOT_RANGE {
return Err(Error::invalid_params(format!(
"Slot range too large; max {}",
MAX_SLOT_RANGE
)));
}
meta.request_processor
.read()
.unwrap()
.get_confirmed_signatures_for_address(pubkey, start_slot, end_slot)
.map(|signatures| {
signatures
.iter()
.map(|signature| signature.to_string())
.collect()
})
}
fn get_first_available_block(&self, meta: Self::Metadata) -> Result<Slot> {
meta.request_processor
.read()
.unwrap()
.get_first_available_block()
}
}
#[cfg(test)]
@@ -1977,7 +2088,7 @@ pub mod tests {
.expect("actual response deserialization");
let result = result.as_ref().unwrap();
assert_eq!(expected_res, result.status);
assert_eq!(None, result.confirmations);
assert_eq!(Some(2), result.confirmations);
// Test getSignatureStatus request on unprocessed tx
let tx = system_transaction::transfer(&alice, &bob_pubkey, 10, blockhash);
@@ -2328,8 +2439,8 @@ pub mod tests {
let validator_exit = create_validator_exit(&exit);
let bank_forks = new_bank_forks().0;
let commitment_slot0 = BlockCommitment::new([8; MAX_LOCKOUT_HISTORY]);
let commitment_slot1 = BlockCommitment::new([9; MAX_LOCKOUT_HISTORY]);
let commitment_slot0 = BlockCommitment::new([8; MAX_LOCKOUT_HISTORY + 1]);
let commitment_slot1 = BlockCommitment::new([9; MAX_LOCKOUT_HISTORY + 1]);
let mut block_commitment: HashMap<u64, BlockCommitment> = HashMap::new();
block_commitment
.entry(0)
@@ -2421,7 +2532,7 @@ pub mod tests {
let res = io.handle_request_sync(&req, meta);
let result: Response = serde_json::from_str(&res.expect("actual response"))
.expect("actual response deserialization");
let commitment_response: RpcBlockCommitment<[u64; MAX_LOCKOUT_HISTORY]> =
let commitment_response: RpcBlockCommitment<BlockCommitmentArray> =
if let Response::Single(res) = result {
if let Output::Success(res) = res {
serde_json::from_value(res.result).unwrap()

View File

@@ -321,6 +321,7 @@ mod tests {
};
use jsonrpc_core::{futures::sync::mpsc, Response};
use jsonrpc_pubsub::{PubSubHandler, Session};
use serial_test_derive::serial;
use solana_budget_program::{self, budget_instruction};
use solana_ledger::bank_forks::BankForks;
use solana_runtime::bank::Bank;
@@ -357,6 +358,7 @@ mod tests {
}
#[test]
#[serial]
fn test_signature_subscribe() {
let GenesisConfigInfo {
genesis_config,
@@ -403,6 +405,7 @@ mod tests {
}
#[test]
#[serial]
fn test_signature_unsubscribe() {
let GenesisConfigInfo {
genesis_config,
@@ -451,6 +454,7 @@ mod tests {
}
#[test]
#[serial]
fn test_account_subscribe() {
let GenesisConfigInfo {
mut genesis_config,
@@ -561,6 +565,7 @@ mod tests {
}
#[test]
#[serial]
fn test_account_unsubscribe() {
let bob_pubkey = Pubkey::new_rand();
let session = create_session();
@@ -721,6 +726,7 @@ mod tests {
}
#[test]
#[serial]
fn test_slot_subscribe() {
let rpc = RpcSolPubSubImpl::default();
let session = create_session();
@@ -745,6 +751,7 @@ mod tests {
}
#[test]
#[serial]
fn test_slot_unsubscribe() {
let rpc = RpcSolPubSubImpl::default();
let session = create_session();

View File

@@ -15,8 +15,9 @@ use solana_ledger::{
blockstore::Blockstore,
snapshot_utils,
};
use solana_sdk::hash::Hash;
use solana_sdk::{hash::Hash, pubkey::Pubkey};
use std::{
collections::HashSet,
net::SocketAddr,
path::{Path, PathBuf},
sync::{mpsc::channel, Arc, RwLock},
@@ -24,6 +25,10 @@ use std::{
};
use tokio::prelude::Future;
// If trusted validators are specified, consider this validator healthy if its latest account hash
// is no further behind than this distance from the latest trusted validator account hash
const HEALTH_CHECK_SLOT_DISTANCE: u64 = 150;
pub struct JsonRpcService {
thread_hdl: JoinHandle<()>,
@@ -37,15 +42,24 @@ struct RpcRequestMiddleware {
ledger_path: PathBuf,
snapshot_archive_path_regex: Regex,
snapshot_config: Option<SnapshotConfig>,
cluster_info: Arc<RwLock<ClusterInfo>>,
trusted_validators: Option<HashSet<Pubkey>>,
}
impl RpcRequestMiddleware {
pub fn new(ledger_path: PathBuf, snapshot_config: Option<SnapshotConfig>) -> Self {
pub fn new(
ledger_path: PathBuf,
snapshot_config: Option<SnapshotConfig>,
cluster_info: Arc<RwLock<ClusterInfo>>,
trusted_validators: Option<HashSet<Pubkey>>,
) -> Self {
Self {
ledger_path,
snapshot_archive_path_regex: Regex::new(r"/snapshot-\d+-[[:alnum:]]+\.tar\.bz2$")
.unwrap(),
snapshot_config,
cluster_info,
trusted_validators,
}
}
@@ -104,6 +118,58 @@ impl RpcRequestMiddleware {
),
}
}
fn health_check(&self) -> &'static str {
let response = if let Some(trusted_validators) = &self.trusted_validators {
let (latest_account_hash_slot, latest_trusted_validator_account_hash_slot) = {
let cluster_info = self.cluster_info.read().unwrap();
(
cluster_info
.get_accounts_hash_for_node(&cluster_info.id())
.map(|hashes| hashes.iter().max_by(|a, b| a.0.cmp(&b.0)))
.flatten()
.map(|slot_hash| slot_hash.0)
.unwrap_or(0),
trusted_validators
.iter()
.map(|trusted_validator| {
cluster_info
.get_accounts_hash_for_node(&trusted_validator)
.map(|hashes| hashes.iter().max_by(|a, b| a.0.cmp(&b.0)))
.flatten()
.map(|slot_hash| slot_hash.0)
.unwrap_or(0)
})
.max()
.unwrap_or(0),
)
};
// This validator is considered healthy if its latest account hash slot is within
// `HEALTH_CHECK_SLOT_DISTANCE` of the latest trusted validator's account hash slot
if latest_account_hash_slot > 0
&& latest_trusted_validator_account_hash_slot > 0
&& latest_account_hash_slot
> latest_trusted_validator_account_hash_slot
.saturating_sub(HEALTH_CHECK_SLOT_DISTANCE)
{
"ok"
} else {
warn!(
"health check: me={}, latest trusted_validator={}",
latest_account_hash_slot, latest_trusted_validator_account_hash_slot
);
"behind"
}
} else {
// No trusted validator point of reference available, so this validator is healthy
// because it's running
"ok"
};
info!("health check: {}", response);
response
}
}
impl RequestMiddleware for RpcRequestMiddleware {
@@ -138,6 +204,16 @@ impl RequestMiddleware for RpcRequestMiddleware {
}
if self.is_get_path(request.uri().path()) {
self.get(request.uri().path())
} else if request.uri().path() == "/health" {
RequestMiddlewareAction::Respond {
should_validate_hosts: true,
response: Box::new(jsonrpc_core::futures::future::ok(
hyper::Response::builder()
.status(hyper::StatusCode::OK)
.body(hyper::Body::from(self.health_check()))
.unwrap(),
)),
}
} else {
RequestMiddlewareAction::Proceed {
should_continue_on_invalid_cors: false,
@@ -161,6 +237,7 @@ impl JsonRpcService {
ledger_path: &Path,
storage_state: StorageState,
validator_exit: Arc<RwLock<Option<ValidatorExit>>>,
trusted_validators: Option<HashSet<Pubkey>>,
) -> Self {
info!("rpc bound to {:?}", rpc_addr);
info!("rpc configuration: {:?}", config);
@@ -186,20 +263,35 @@ impl JsonRpcService {
let rpc = RpcSolImpl;
io.extend_with(rpc.to_delegate());
let server =
ServerBuilder::with_meta_extractor(io, move |_req: &hyper::Request<hyper::Body>| Meta {
let request_middleware = RpcRequestMiddleware::new(
ledger_path,
snapshot_config,
cluster_info.clone(),
trusted_validators,
);
let server = ServerBuilder::with_meta_extractor(
io,
move |_req: &hyper::Request<hyper::Body>| Meta {
request_processor: request_processor.clone(),
cluster_info: cluster_info.clone(),
genesis_hash
}).threads(4)
.cors(DomainsValidation::AllowOnly(vec![
AccessControlAllowOrigin::Any,
]))
.cors_max_age(86400)
.request_middleware(RpcRequestMiddleware::new(ledger_path, snapshot_config))
.start_http(&rpc_addr);
genesis_hash,
},
)
.threads(4)
.cors(DomainsValidation::AllowOnly(vec![
AccessControlAllowOrigin::Any,
]))
.cors_max_age(86400)
.request_middleware(request_middleware)
.start_http(&rpc_addr);
if let Err(e) = server {
warn!("JSON RPC service unavailable error: {:?}. \nAlso, check that port {} is not already in use by another application", e, rpc_addr.port());
warn!(
"JSON RPC service unavailable error: {:?}. \n\
Also, check that port {} is not already in use by another application",
e,
rpc_addr.port()
);
return;
}
@@ -240,6 +332,7 @@ mod tests {
use super::*;
use crate::{
contact_info::ContactInfo,
crds_value::{CrdsData, CrdsValue, SnapshotHash},
genesis_utils::{create_genesis_config, GenesisConfigInfo},
rpc::tests::create_validator_exit,
};
@@ -283,6 +376,7 @@ mod tests {
&PathBuf::from("farf"),
StorageState::default(),
validator_exit,
None,
);
let thread = rpc_service.thread_hdl.thread();
assert_eq!(thread.name().unwrap(), "solana-jsonrpc");
@@ -303,7 +397,11 @@ mod tests {
#[test]
fn test_is_get_path() {
let rrm = RpcRequestMiddleware::new(PathBuf::from("/"), None);
let cluster_info = Arc::new(RwLock::new(ClusterInfo::new_with_invalid_keypair(
ContactInfo::default(),
)));
let rrm = RpcRequestMiddleware::new(PathBuf::from("/"), None, cluster_info.clone(), None);
let rrm_with_snapshot_config = RpcRequestMiddleware::new(
PathBuf::from("/"),
Some(SnapshotConfig {
@@ -311,6 +409,8 @@ mod tests {
snapshot_package_output_path: PathBuf::from("/"),
snapshot_path: PathBuf::from("/"),
}),
cluster_info,
None,
);
assert!(rrm.is_get_path("/genesis.tar.bz2"));
@@ -332,4 +432,95 @@ mod tests {
assert!(!rrm.is_get_path(".."));
assert!(!rrm.is_get_path("🎣"));
}
#[test]
fn test_health_check_with_no_trusted_validators() {
let cluster_info = Arc::new(RwLock::new(ClusterInfo::new_with_invalid_keypair(
ContactInfo::default(),
)));
let rm = RpcRequestMiddleware::new(PathBuf::from("/"), None, cluster_info.clone(), None);
assert_eq!(rm.health_check(), "ok");
}
#[test]
fn test_health_check_with_trusted_validators() {
let cluster_info = Arc::new(RwLock::new(ClusterInfo::new_with_invalid_keypair(
ContactInfo::default(),
)));
let trusted_validators = vec![Pubkey::new_rand(), Pubkey::new_rand(), Pubkey::new_rand()];
let rm = RpcRequestMiddleware::new(
PathBuf::from("/"),
None,
cluster_info.clone(),
Some(trusted_validators.clone().into_iter().collect()),
);
// No account hashes for this node or any trusted validators == "behind"
assert_eq!(rm.health_check(), "behind");
// No account hashes for any trusted validators == "behind"
{
let mut cluster_info = cluster_info.write().unwrap();
cluster_info
.push_accounts_hashes(vec![(1000, Hash::default()), (900, Hash::default())]);
}
assert_eq!(rm.health_check(), "behind");
// This node is ahead of the trusted validators == "ok"
{
let mut cluster_info = cluster_info.write().unwrap();
cluster_info
.gossip
.crds
.insert(
CrdsValue::new_unsigned(CrdsData::AccountsHashes(SnapshotHash::new(
trusted_validators[0].clone(),
vec![
(1, Hash::default()),
(1001, Hash::default()),
(2, Hash::default()),
],
))),
1,
)
.unwrap();
}
assert_eq!(rm.health_check(), "ok");
// Node is slightly behind the trusted validators == "ok"
{
let mut cluster_info = cluster_info.write().unwrap();
cluster_info
.gossip
.crds
.insert(
CrdsValue::new_unsigned(CrdsData::AccountsHashes(SnapshotHash::new(
trusted_validators[1].clone(),
vec![(1000 + HEALTH_CHECK_SLOT_DISTANCE - 1, Hash::default())],
))),
1,
)
.unwrap();
}
assert_eq!(rm.health_check(), "ok");
// Node is far behind the trusted validators == "behind"
{
let mut cluster_info = cluster_info.write().unwrap();
cluster_info
.gossip
.crds
.insert(
CrdsValue::new_unsigned(CrdsData::AccountsHashes(SnapshotHash::new(
trusted_validators[2].clone(),
vec![(1000 + HEALTH_CHECK_SLOT_DISTANCE, Hash::default())],
))),
1,
)
.unwrap();
}
assert_eq!(rm.health_check(), "behind");
}
}

View File

@@ -622,6 +622,7 @@ pub(crate) mod tests {
};
use jsonrpc_core::futures::{self, stream::Stream};
use jsonrpc_pubsub::typed::Subscriber;
use serial_test_derive::serial;
use solana_budget_program;
use solana_sdk::{
signature::{Keypair, Signer},
@@ -656,6 +657,7 @@ pub(crate) mod tests {
}
#[test]
#[serial]
fn test_check_account_subscribe() {
let GenesisConfigInfo {
genesis_config,
@@ -728,6 +730,7 @@ pub(crate) mod tests {
}
#[test]
#[serial]
fn test_check_program_subscribe() {
let GenesisConfigInfo {
genesis_config,
@@ -808,6 +811,7 @@ pub(crate) mod tests {
}
#[test]
#[serial]
fn test_check_signature_subscribe() {
let GenesisConfigInfo {
genesis_config,
@@ -949,6 +953,7 @@ pub(crate) mod tests {
}
#[test]
#[serial]
fn test_check_slot_subscribe() {
let (subscriber, _id_receiver, transport_receiver) =
Subscriber::new_test("slotNotification");
@@ -990,6 +995,7 @@ pub(crate) mod tests {
}
#[test]
#[serial]
fn test_check_root_subscribe() {
let (subscriber, _id_receiver, mut transport_receiver) =
Subscriber::new_test("rootNotification");
@@ -1030,6 +1036,7 @@ pub(crate) mod tests {
}
#[test]
#[serial]
fn test_add_and_remove_subscription() {
let mut subscriptions: HashMap<u64, HashMap<SubscriptionId, (Sink<()>, Confirmations)>> =
HashMap::new();

View File

@@ -26,6 +26,7 @@ use solana_ledger::{
snapshot_package::SnapshotPackageSender,
};
use solana_sdk::{
genesis_config::GenesisConfig,
pubkey::Pubkey,
signature::{Keypair, Signer},
};
@@ -67,6 +68,7 @@ pub struct TvuConfig {
pub halt_on_trusted_validators_accounts_hash_mismatch: bool,
pub trusted_validators: Option<HashSet<Pubkey>>,
pub accounts_hash_fault_injection_slots: u64,
pub genesis_config: GenesisConfig,
}
impl Tvu {
@@ -185,6 +187,7 @@ impl Tvu {
block_commitment_cache: block_commitment_cache.clone(),
transaction_status_sender,
rewards_recorder_sender,
genesis_config: tvu_config.genesis_config,
};
let (replay_stage, root_bank_receiver) = ReplayStage::new(
@@ -264,11 +267,13 @@ pub mod tests {
use crate::banking_stage::create_test_recorder;
use crate::cluster_info::{ClusterInfo, Node};
use crate::genesis_utils::{create_genesis_config, GenesisConfigInfo};
use serial_test_derive::serial;
use solana_ledger::create_new_tmp_ledger;
use solana_runtime::bank::Bank;
use std::sync::atomic::Ordering;
#[test]
#[serial]
fn test_tvu_exit() {
solana_logger::setup();
let leader = Node::new_localhost();

View File

@@ -262,6 +262,7 @@ impl Validator {
ledger_path,
storage_state.clone(),
validator_exit.clone(),
config.trusted_validators.clone(),
),
PubSubService::new(
&subscriptions,
@@ -316,7 +317,7 @@ impl Validator {
std::thread::park();
}
let poh_config = Arc::new(genesis_config.poh_config);
let poh_config = Arc::new(genesis_config.poh_config.clone());
let (mut poh_recorder, entry_receiver) = PohRecorder::new_with_clear_signal(
bank.tick_height(),
bank.last_blockhash(),
@@ -443,6 +444,7 @@ impl Validator {
shred_version: node.info.shred_version,
trusted_validators: config.trusted_validators.clone(),
accounts_hash_fault_injection_slots: config.accounts_hash_fault_injection_slots,
genesis_config,
},
);

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-crate-features"
version = "1.0.15"
version = "1.0.19"
description = "Solana Crate Features"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -26,3 +26,6 @@ syn_0_15 = { package = "syn", version = "0.15.42", features = ["extra-traits", "
syn_1_0 = { package = "syn", version = "1.0.3", features = ["extra-traits", "fold", "full"] }
tokio = { version = "0.1.22",features=["bytes", "codec", "default", "fs", "io", "mio", "num_cpus", "reactor", "rt-full", "sync", "tcp", "timer", "tokio-codec", "tokio-current-thread", "tokio-executor", "tokio-io", "tokio-io", "tokio-reactor", "tokio-tcp", "tokio-tcp", "tokio-threadpool", "tokio-timer", "tokio-udp", "tokio-uds", "udp", "uds"] }
winapi = { version = "0.3.8", features=["basetsd", "consoleapi", "errhandlingapi", "fileapi", "handleapi", "impl-debug", "impl-default", "knownfolders", "libloaderapi", "memoryapi", "minwinbase", "minwindef", "ntdef", "ntsecapi", "ntstatus", "objbase", "processenv", "processthreadsapi", "profileapi", "shlobj", "std", "synchapi", "sysinfoapi", "timezoneapi", "utilapiset", "winbase", "wincon", "windef", "winerror", "winnls", "winnt", "winreg", "winsock2", "winuser", "ws2def", "ws2ipdef", "ws2tcpip", "wtypesbase"] }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -3,7 +3,9 @@ set -e
cd "$(dirname "$0")"
usage=$(cargo -q run -p solana-cli -- -C ~/.foo --help | sed 's|'"$HOME"'|~|g')
: "${rust_stable:=}" # Pacify shellcheck
usage=$(cargo +"$rust_stable" -q run -p solana-cli -- -C ~/.foo --help | sed -e 's|'"$HOME"'|~|g' -e 's/[[:space:]]\+$//')
out=${1:-src/cli/usage.md}
@@ -29,6 +31,6 @@ in_subcommands=0
while read -r subcommand rest; do
[[ $subcommand == "SUBCOMMANDS:" ]] && in_subcommands=1 && continue
if ((in_subcommands)); then
section "$(cargo -q run -p solana-cli -- help "$subcommand" | sed 's|'"$HOME"'|~|g')" "####" >> "$out"
section "$(cargo +"$rust_stable" -q run -p solana-cli -- help "$subcommand" | sed 's|'"$HOME"'|~|g')" "####" >> "$out"
fi
done <<<"$usage">>"$out"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

View File

@@ -21,10 +21,13 @@ To interact with a Solana node inside a JavaScript application, use the [solana-
* [getClusterNodes](jsonrpc-api.md#getclusternodes)
* [getConfirmedBlock](jsonrpc-api.md#getconfirmedblock)
* [getConfirmedBlocks](jsonrpc-api.md#getconfirmedblocks)
* [getConfirmedSignaturesForAddress](jsonrpc-api.md#getconfirmedsignaturesforaddress)
* [getConfirmedTransaction](jsonrpc-api.md#getconfirmedtransaction)
* [getEpochInfo](jsonrpc-api.md#getepochinfo)
* [getEpochSchedule](jsonrpc-api.md#getepochschedule)
* [getFeeCalculatorForBlockhash](jsonrpc-api.md#getfeecalculatorforblockhash)
* [getFeeRateGovernor](jsonrpc-api.md#getfeerategovernor)
* [getFirstAvailableBlock](jsonrpc-api.md#getfirstavailableblock)
* [getGenesisHash](jsonrpc-api.md#getgenesishash)
* [getIdentity](jsonrpc-api.md#getidentity)
* [getInflation](jsonrpc-api.md#getinflation)
@@ -113,6 +116,16 @@ Many methods that take a commitment parameter return an RpcResponse JSON object
* `value` : The value returned by the operation itself.
## Health Check
Although not a JSON RPC API, a `GET /heath` at the RPC HTTP Endpoint provides a
health-check mechanism for use by load balancers or other network
infrastructure. This request will always return a HTTP 200 OK response with a body of
"ok" or "behind" based on the following conditions:
1. If one or more `--trusted-validator` arguments are provided to `solana-validator`, "ok" is returned
when the node has within `HEALTH_CHECK_SLOT_DISTANCE` slots of the highest trusted validator,
otherwise "behind" is returned.
2. "ok" is always returned if no trusted validators are provided.
## JSON RPC API Reference
### getAccountInfo
@@ -268,22 +281,24 @@ Returns identity and transaction information about a confirmed block in the ledg
The result field will be an object with the following fields:
* `blockhash: <string>` - the blockhash of this block, as base-58 encoded string
* `previousBlockhash: <string>` - the blockhash of this block's parent, as base-58 encoded string
* `parentSlot: <u64>` - the slot index of this block's parent
* `transactions: <array>` - an array of JSON objects containing:
* `transaction: <object|string>` - [Transaction](#transaction-structure) object, either in JSON format or base-58 encoded binary data, depending on encoding parameter
* `meta: <object>` - transaction status metadata object, containing `null` or:
* `err: <object | null>` - Error if transaction failed, null if transaction succeeded. [TransactionError definitions](https://github.com/solana-labs/solana/blob/master/sdk/src/transaction.rs#L14)
* `fee: <u64>` - fee this transaction was charged, as u64 integer
* `preBalances: <array>` - array of u64 account balances from before the transaction was processed
* `postBalances: <array>` - array of u64 account balances after the transaction was processed
* DEPRECATED: `status: <object>` - Transaction status
* `"Ok": <null>` - Transaction was successful
* `"Err": <ERR>` - Transaction failed with TransactionError
* `rewards: <array>` - an array of JSON objects containing:
* `pubkey: <string>` - The public key, as base-58 encoded string, of the account that received the reward
* `lamports: <i64>`- number of reward lamports credited or debited by the account, as a i64
* `<null>` - if specified block is not confirmed
* `<object>` - if block is confirmed, an object with the following fields:
* `blockhash: <string>` - the blockhash of this block, as base-58 encoded string
* `previousBlockhash: <string>` - the blockhash of this block's parent, as base-58 encoded string; if the parent block is not available due to ledger cleanup, this field will return "11111111111111111111111111111111"
* `parentSlot: <u64>` - the slot index of this block's parent
* `transactions: <array>` - an array of JSON objects containing:
* `transaction: <object|string>` - [Transaction](#transaction-structure) object, either in JSON format or base-58 encoded binary data, depending on encoding parameter
* `meta: <object>` - transaction status metadata object, containing `null` or:
* `err: <object | null>` - Error if transaction failed, null if transaction succeeded. [TransactionError definitions](https://github.com/solana-labs/solana/blob/master/sdk/src/transaction.rs#L14)
* `fee: <u64>` - fee this transaction was charged, as u64 integer
* `preBalances: <array>` - array of u64 account balances from before the transaction was processed
* `postBalances: <array>` - array of u64 account balances after the transaction was processed
* DEPRECATED: `status: <object>` - Transaction status
* `"Ok": <null>` - Transaction was successful
* `"Err": <ERR>` - Transaction failed with TransactionError
* `rewards: <array>` - an array of JSON objects containing:
* `pubkey: <string>` - The public key, as base-58 encoded string, of the account that received the reward
* `lamports: <i64>`- number of reward lamports credited or debited by the account, as a i64
#### Example:
@@ -345,6 +360,72 @@ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"m
{"jsonrpc":"2.0","result":[5,6,7,8,9,10],"id":1}
```
### getConfirmedSignaturesForAddress
Returns a list of all the confirmed signatures for transactions involving an address, within a specified Slot range. Max range allowed is 10_000 Slots.
#### Parameters:
* `<string>` - account address as base-58 encoded string
* `<u64>` - start slot, inclusive
* `<u64>` - end slot, inclusive
#### Results:
The result field will be an array of:
* `<string>` - transaction signature as base-58 encoded string
The signatures will be ordered based on the Slot in which they were confirmed in, from lowest to highest Slot
#### Example:
```bash
// Request
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"method":"getConfirmedSignaturesForAddress","params":["6H94zdiaYfRfPfKjYLjyr2VFBg6JHXygy84r3qhc3NsC", 0, 100]}' localhost:8899
// Result
{"jsonrpc":"2.0","result":{["35YGay1Lwjwgxe9zaH6APSHbt9gYQUCtBWTNL3aVwVGn9xTFw2fgds7qK5AL29mP63A9j3rh8KpN1TgSR62XCaby","4bJdGN8Tt2kLWZ3Fa1dpwPSEkXWWTSszPSf1rRVsCwNjxbbUdwTeiWtmi8soA26YmwnKD4aAxNp8ci1Gjpdv4gsr","4LQ14a7BYY27578Uj8LPCaVhSdJGLn9DJqnUJHpy95FMqdKf9acAhUhecPQNjNUy6VoNFUbvwYkPociFSf87cWbG"]},"id":1}
```
### getConfirmedTransaction
Returns transaction details for a confirmed transaction
#### Parameters:
* `<string>` - transaction signature as base-58 encoded string
* `<string>` - (optional) encoding for the returned Transaction, either "json" or "binary". If not provided, the default encoding is JSON.
#### Results:
The result field will be an object with the following fields:
* `slot: <u64>` - the slot this transaction was processed in
* `transaction: <object|string>` - [Transaction](#transaction-structure) object, either in JSON format or base-58 encoded binary data, depending on encoding parameter
* `meta: <object>` - transaction status metadata object, containing `null` or:
* `err: <object | null>` - Error if transaction failed, null if transaction succeeded. [TransactionError definitions](https://github.com/solana-labs/solana/blob/master/sdk/src/transaction.rs#L14)
* `fee: <u64>` - fee this transaction was charged, as u64 integer
* `preBalances: <array>` - array of u64 account balances from before the transaction was processed
* `postBalances: <array>` - array of u64 account balances after the transaction was processed
* DEPRECATED: `status: <object>` - Transaction status
* `"Ok": <null>` - Transaction was successful
* `"Err": <ERR>` - Transaction failed with TransactionError
#### Example:
```bash
// Request
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"method":"getConfirmedTransaction","params":["35YGay1Lwjwgxe9zaH6APSHbt9gYQUCtBWTNL3aVwVGn9xTFw2fgds7qK5AL29mP63A9j3rh8KpN1TgSR62XCaby", "json"]}' localhost:8899
// Result
{"jsonrpc":"2.0","result":{"slot":430,"transaction":{"message":{"accountKeys":["6H94zdiaYfRfPfKjYLjyr2VFBg6JHXygy84r3qhc3NsC","39UAy8hsoYPywGPGdmun747omSr79zLSjqvPJN3zetoH","SysvarS1otHashes111111111111111111111111111","SysvarC1ock11111111111111111111111111111111","Vote111111111111111111111111111111111111111"],"header":{"numReadonlySignedAccounts":0,"numReadonlyUnsignedAccounts":3,"numRequiredSignatures":2},"instructions":[{"accounts":[1,2,3],"data":"29z5mr1JoRmJYQ6ynmk3pf31cGFRziAF1M3mT3L6sFXf5cKLdkEaMXMT8AqLpD4CpcupHmuMEmtZHpomrwfdZetSomNy3d","programIdIndex":4}],"recentBlockhash":"EFejToxii1L5aUF2NrK9dsbAEmZSNyN5nsipmZHQR1eA"},"signatures":["35YGay1Lwjwgxe9zaH6APSHbt9gYQUCtBWTNL3aVwVGn9xTFw2fgds7qK5AL29mP63A9j3rh8KpN1TgSR62XCaby","4vANMjSKiwEchGSXwVrQkwHnmsbKQmy9vdrsYxWdCup1bLsFzX8gKrFTSVDCZCae2dbxJB9mPNhqB2sD1vvr4sAD"]},"meta":{"err":null,"fee":18000,"postBalances":[499999972500,15298080,1,1,1],"preBalances":[499999990500,15298080,1,1,1],"status":{"Ok":null}}},"id":1}
// Request
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"method":"getConfirmedTransaction","params":["35YGay1Lwjwgxe9zaH6APSHbt9gYQUCtBWTNL3aVwVGn9xTFw2fgds7qK5AL29mP63A9j3rh8KpN1TgSR62XCaby", "binary"]}' localhost:8899
// Result
{"jsonrpc":"2.0","result":{"slot":430,"transaction":"81UZJt4dh4Do66jDhrgkQudS8J2N6iG3jaVav7gJrqJSFY4Ug53iA9JFJZh2gxKWcaFdLJwhHx9mRdg9JwDAWB4ywiu5154CRwXV4FMdnPLg7bhxRLwhhYaLsVgMF5AyNRcTzjCVoBvqFgDU7P8VEKDEiMvD3qxzm1pLZVxDG1LTQpT3Dz4Uviv4KQbFQNuC22KupBoyHFB7Zh6KFdMqux4M9PvhoqcoJsJKwXjWpKu7xmEKnnrSbfLadkgjBmmjhW3fdTrFvnhQdTkhtdJxUL1xS9GMuJQer8YgSKNtUXB1eXZQwXU8bU2BjYkZE6Q5Xww8hu9Z4E4Mo4QsooVtHoP6BM3NKw8zjVbWfoCQqxTrwuSzrNCWCWt58C24LHecH67CTt2uXbYSviixvrYkK7A3t68BxTJcF1dXJitEPTFe2ceTkauLJqrJgnER4iUrsjr26T8YgWvpY9wkkWFSviQW6wV5RASTCUasVEcrDiaKj8EQMkgyDoe9HyKitSVg67vMWJFpUXpQobseWJUs5FTWWzmfHmFp8FZ","meta":{"err":null,"fee":18000,"postBalances":[499999972500,15298080,1,1,1],"preBalances":[499999990500,15298080,1,1,1],"status":{"Ok":null}}},"id":1}
```
### getEpochInfo
Returns information about the current epoch
@@ -452,6 +533,28 @@ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "m
{"jsonrpc":"2.0","result":{"context":{"slot":54},"value":{"feeRateGovernor":{"burnPercent":50,"maxLamportsPerSignature":100000,"minLamportsPerSignature":5000,"targetLamportsPerSignature":10000,"targetSignaturesPerSlot":20000}}},"id":1}
```
### getFirstAvailableBlock
Returns the slot of the lowest confirmed block that has not been purged from the ledger
#### Parameters:
None
#### Results:
* `<u64>` - Slot
#### Example:
```bash
// Request
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getFirstAvailableBlock"}' http://localhost:8899
// Result
{"jsonrpc":"2.0","result":250000,"id":1}
```
### getGenesisHash
Returns the genesis hash
@@ -655,7 +758,7 @@ An array of:
* `<null>` - Unknown transaction
* `<object>`
* `slot: <u64>` - The slot the transaction was processed
* `confirmations: <usize | null>` - Number of blocks since signature confirmation, null if rooted
* `confirmations: <usize | null>` - Number of blocks since signature confirmation, null if rooted, as well as finalized by a supermajority of the cluster
* `err: <object | null>` - Error if transaction failed, null if transaction succeeded. [TransactionError definitions](https://github.com/solana-labs/solana/blob/master/sdk/src/transaction.rs#L14)
* DEPRECATED: `status: <object>` - Transaction status
* `"Ok": <null>` - Transaction was successful
@@ -872,7 +975,7 @@ The result field will be a JSON object with the following fields:
// Request
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getVersion"}' http://localhost:8899
// Result
{"jsonrpc":"2.0","result":{"solana-core": "1.0.15"},"id":1}
{"jsonrpc":"2.0","result":{"solana-core": "1.0.19"},"id":1}
```
### getVoteAccounts

View File

@@ -171,7 +171,7 @@ $ solana send-timestamp <PUBKEY> <PROCESS_ID> --date 2018-12-24T23:59:00
## Usage
### solana-cli
```text
solana-cli 1.0.15 [channel=unknown commit=unknown]
solana-cli 1.0.19 [channel=unknown commit=unknown]
Blockchain, Rebuilt for Scale
USAGE:

View File

@@ -5,50 +5,18 @@ simplest way for most users to get started with a Solana wallet.
## Install Trust Wallet
#### iOS
- Open the App Store
- Download “Trust: Crypto & Bitcoin Wallet” from Six Days LLC
- Requires iOS 13.0 or higher
- Open Trust Wallet and follow the app prompts to get started
***
#### Android
**NOTE: At this time, Solana's SOL tokens are only supported in the Beta version
of Trust Wallet for Android. The following steps explain how to install this
Beta version to start using your Solana wallet. Check back here or check the
latest official Trust Wallet release notes for when support is added to their
official Android release.**
- Open the Play Store
- Download the official version of Trust Wallet
- “Trust: Crypto & Bitcoin Wallet” from Six Days LLC
- Download “Trust Crypto Wallet” from Six Days LLC
- Requires Android 6.0 or higher
![Install the Official Version of Trust Wallet](../.gitbook/assets/install-official-trust-wallet.png)
##### Enable Beta version of Trust Wallet
- Make sure you already have the official version installed
- Open Play Store and view Trust Wallet's app page
- Scroll down to the bottom to the "Beta" section and tap "Join"
- It may take a few minutes for your device to get access to the Beta version
![Join the Beta program](../.gitbook/assets/join-beta-trust-wallet.png)
##### Upgrade to the Beta version
- Open Play Store .
- Tap Menu --> My apps and games --> Beta.
- Tap Trust Wallet
- Tap Upgrade when brought back to the Trust Wallet (Beta) install page
![Find Beta app you've joined](../.gitbook/assets/find-beta-apps.png)
***
![Upgrade to Trust Wallet Beta](../.gitbook/assets/update-trust-wallet-to-beta.png)
##### Beta Install Support for Android
- [Google's Official Help for Installing Beta Versions of Apps](https://support.google.com/googleplay/answer/7003180?hl=en)
- Open Trust Wallet and follow the app prompts to get started
## Add Solana (SOL) tokens to your wallet
- From the main page, go to the “Tokens” tab at the top of the screen

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-faucet"
version = "1.0.15"
version = "1.0.19"
description = "Solana Faucet"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -19,10 +19,10 @@ clap = "2.33"
log = "0.4.8"
serde = "1.0.104"
serde_derive = "1.0.103"
solana-clap-utils = { path = "../clap-utils", version = "1.0.15" }
solana-logger = { path = "../logger", version = "1.0.15" }
solana-metrics = { path = "../metrics", version = "1.0.15" }
solana-sdk = { path = "../sdk", version = "1.0.15" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.19" }
solana-logger = { path = "../logger", version = "1.0.19" }
solana-metrics = { path = "../metrics", version = "1.0.19" }
solana-sdk = { path = "../sdk", version = "1.0.19" }
tokio = "0.1"
tokio-codec = "0.1"
@@ -33,3 +33,6 @@ name = "solana_faucet"
[[bin]]
name = "solana-faucet"
path = "src/bin/faucet.rs"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-genesis-programs"
version = "1.0.15"
version = "1.0.19"
description = "Solana genesis programs"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -10,17 +10,20 @@ edition = "2018"
[dependencies]
log = { version = "0.4.8" }
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "1.0.15" }
solana-budget-program = { path = "../programs/budget", version = "1.0.15" }
solana-config-program = { path = "../programs/config", version = "1.0.15" }
solana-exchange-program = { path = "../programs/exchange", version = "1.0.15" }
solana-runtime = { path = "../runtime", version = "1.0.15" }
solana-sdk = { path = "../sdk", version = "1.0.15" }
solana-stake-program = { path = "../programs/stake", version = "1.0.15" }
solana-storage-program = { path = "../programs/storage", version = "1.0.15" }
solana-vest-program = { path = "../programs/vest", version = "1.0.15" }
solana-vote-program = { path = "../programs/vote", version = "1.0.15" }
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "1.0.19" }
solana-budget-program = { path = "../programs/budget", version = "1.0.19" }
solana-config-program = { path = "../programs/config", version = "1.0.19" }
solana-exchange-program = { path = "../programs/exchange", version = "1.0.19" }
solana-runtime = { path = "../runtime", version = "1.0.19" }
solana-sdk = { path = "../sdk", version = "1.0.19" }
solana-stake-program = { path = "../programs/stake", version = "1.0.19" }
solana-storage-program = { path = "../programs/storage", version = "1.0.19" }
solana-vest-program = { path = "../programs/vest", version = "1.0.19" }
solana-vote-program = { path = "../programs/vote", version = "1.0.19" }
[lib]
crate-type = ["lib"]
name = "solana_genesis_programs"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-genesis"
description = "Blockchain, Rebuilt for Scale"
version = "1.0.15"
version = "1.0.19"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -15,13 +15,13 @@ chrono = "0.4"
serde = "1.0.104"
serde_json = "1.0.46"
serde_yaml = "0.8.11"
solana-clap-utils = { path = "../clap-utils", version = "1.0.15" }
solana-genesis-programs = { path = "../genesis-programs", version = "1.0.15" }
solana-ledger = { path = "../ledger", version = "1.0.15" }
solana-sdk = { path = "../sdk", version = "1.0.15" }
solana-stake-program = { path = "../programs/stake", version = "1.0.15" }
solana-storage-program = { path = "../programs/storage", version = "1.0.15" }
solana-vote-program = { path = "../programs/vote", version = "1.0.15" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.19" }
solana-genesis-programs = { path = "../genesis-programs", version = "1.0.19" }
solana-ledger = { path = "../ledger", version = "1.0.19" }
solana-sdk = { path = "../sdk", version = "1.0.19" }
solana-stake-program = { path = "../programs/stake", version = "1.0.19" }
solana-storage-program = { path = "../programs/storage", version = "1.0.19" }
solana-vote-program = { path = "../programs/vote", version = "1.0.19" }
tempfile = "3.1.0"
[[bin]]
@@ -31,3 +31,6 @@ path = "src/main.rs"
[lib]
name = "solana_genesis"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -3,19 +3,22 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-gossip"
description = "Blockchain, Rebuilt for Scale"
version = "1.0.15"
version = "1.0.19"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
[dependencies]
clap = "2.33.0"
solana-clap-utils = { path = "../clap-utils", version = "1.0.15" }
solana-core = { path = "../core", version = "1.0.15" }
solana-client = { path = "../client", version = "1.0.15" }
solana-logger = { path = "../logger", version = "1.0.15" }
solana-net-utils = { path = "../net-utils", version = "1.0.15" }
solana-sdk = { path = "../sdk", version = "1.0.15" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.19" }
solana-core = { path = "../core", version = "1.0.19" }
solana-client = { path = "../client", version = "1.0.19" }
solana-logger = { path = "../logger", version = "1.0.19" }
solana-net-utils = { path = "../net-utils", version = "1.0.19" }
solana-sdk = { path = "../sdk", version = "1.0.19" }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-install"
description = "The solana cluster software installer"
version = "1.0.15"
version = "1.0.19"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -24,11 +24,11 @@ reqwest = { version = "0.10.1", default-features = false, features = ["blocking"
serde = "1.0.104"
serde_derive = "1.0.103"
serde_yaml = "0.8.11"
solana-clap-utils = { path = "../clap-utils", version = "1.0.15" }
solana-client = { path = "../client", version = "1.0.15" }
solana-config-program = { path = "../programs/config", version = "1.0.15" }
solana-logger = { path = "../logger", version = "1.0.15" }
solana-sdk = { path = "../sdk", version = "1.0.15" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.19" }
solana-client = { path = "../client", version = "1.0.19" }
solana-config-program = { path = "../programs/config", version = "1.0.19" }
solana-logger = { path = "../logger", version = "1.0.19" }
solana-sdk = { path = "../sdk", version = "1.0.19" }
semver = "0.9.0"
tar = "0.4.26"
tempdir = "0.3.7"
@@ -45,3 +45,6 @@ path = "src/main-install.rs"
[[bin]]
name = "solana-install-init"
path = "src/main-install-init.rs"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-keygen"
version = "1.0.15"
version = "1.0.19"
description = "Solana key generation utility"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -13,12 +13,15 @@ bs58 = "0.3.0"
clap = "2.33"
dirs = "2.0.2"
num_cpus = "1.12.0"
solana-clap-utils = { path = "../clap-utils", version = "1.0.15" }
solana-cli-config = { path = "../cli-config", version = "1.0.15" }
solana-remote-wallet = { path = "../remote-wallet", version = "1.0.15" }
solana-sdk = { path = "../sdk", version = "1.0.15" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.19" }
solana-cli-config = { path = "../cli-config", version = "1.0.19" }
solana-remote-wallet = { path = "../remote-wallet", version = "1.0.19" }
solana-sdk = { path = "../sdk", version = "1.0.19" }
tiny-bip39 = "0.7.0"
[[bin]]
name = "solana-keygen"
path = "src/keygen.rs"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-ledger-tool"
description = "Blockchain, Rebuilt for Scale"
version = "1.0.15"
version = "1.0.19"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -14,14 +14,17 @@ clap = "2.33.0"
histogram = "*"
serde_json = "1.0.46"
serde_yaml = "0.8.11"
solana-clap-utils = { path = "../clap-utils", version = "1.0.15" }
solana-ledger = { path = "../ledger", version = "1.0.15" }
solana-logger = { path = "../logger", version = "1.0.15" }
solana-runtime = { path = "../runtime", version = "1.0.15" }
solana-sdk = { path = "../sdk", version = "1.0.15" }
solana-vote-program = { path = "../programs/vote", version = "1.0.15" }
solana-stake-program = { path = "../programs/stake", version = "1.0.15" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.19" }
solana-ledger = { path = "../ledger", version = "1.0.19" }
solana-logger = { path = "../logger", version = "1.0.19" }
solana-runtime = { path = "../runtime", version = "1.0.19" }
solana-sdk = { path = "../sdk", version = "1.0.19" }
solana-vote-program = { path = "../programs/vote", version = "1.0.19" }
solana-stake-program = { path = "../programs/stake", version = "1.0.19" }
tempfile = "3.1.0"
[dev-dependencies]
assert_cmd = "0.12"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-ledger"
version = "1.0.15"
version = "1.0.19"
description = "Solana ledger"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -28,19 +28,19 @@ reed-solomon-erasure = { package = "solana-reed-solomon-erasure", version = "4.0
regex = "1.3.4"
serde = "1.0.104"
serde_bytes = "0.11.3"
solana-transaction-status = { path = "../transaction-status", version = "1.0.15" }
solana-genesis-programs = { path = "../genesis-programs", version = "1.0.15" }
solana-logger = { path = "../logger", version = "1.0.15" }
solana-measure = { path = "../measure", version = "1.0.15" }
solana-merkle-tree = { path = "../merkle-tree", version = "1.0.15" }
solana-metrics = { path = "../metrics", version = "1.0.15" }
solana-perf = { path = "../perf", version = "1.0.15" }
solana-transaction-status = { path = "../transaction-status", version = "1.0.19" }
solana-genesis-programs = { path = "../genesis-programs", version = "1.0.19" }
solana-logger = { path = "../logger", version = "1.0.19" }
solana-measure = { path = "../measure", version = "1.0.19" }
solana-merkle-tree = { path = "../merkle-tree", version = "1.0.19" }
solana-metrics = { path = "../metrics", version = "1.0.19" }
solana-perf = { path = "../perf", version = "1.0.19" }
ed25519-dalek = "1.0.0-pre.1"
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.0.15" }
solana-runtime = { path = "../runtime", version = "1.0.15" }
solana-sdk = { path = "../sdk", version = "1.0.15" }
solana-stake-program = { path = "../programs/stake", version = "1.0.15" }
solana-vote-program = { path = "../programs/vote", version = "1.0.15" }
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.0.19" }
solana-runtime = { path = "../runtime", version = "1.0.19" }
solana-sdk = { path = "../sdk", version = "1.0.19" }
solana-stake-program = { path = "../programs/stake", version = "1.0.19" }
solana-vote-program = { path = "../programs/vote", version = "1.0.19" }
symlink = "0.1.0"
tar = "0.4.26"
thiserror = "1.0"
@@ -57,7 +57,7 @@ features = ["lz4"]
[dev-dependencies]
assert_matches = "1.3.0"
matches = "0.1.6"
solana-budget-program = { path = "../programs/budget", version = "1.0.15" }
solana-budget-program = { path = "../programs/budget", version = "1.0.19" }
[lib]
crate-type = ["lib"]
@@ -65,3 +65,6 @@ name = "solana_ledger"
[[bench]]
name = "sigverify_shreds"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -12,7 +12,6 @@ use crate::{
erasure::ErasureConfig,
leader_schedule_cache::LeaderScheduleCache,
next_slots_iterator::NextSlotsIterator,
rooted_slot_iterator::RootedSlotIterator,
shred::{Shred, Shredder},
};
use bincode::deserialize;
@@ -37,8 +36,8 @@ use solana_sdk::{
transaction::Transaction,
};
use solana_transaction_status::{
ConfirmedBlock, EncodedTransaction, Rewards, RpcTransactionStatusMeta, TransactionEncoding,
TransactionStatusMeta, TransactionWithStatusMeta,
ConfirmedBlock, ConfirmedTransaction, EncodedTransaction, Rewards, RpcTransactionStatusMeta,
TransactionEncoding, TransactionStatusMeta, TransactionWithStatusMeta,
};
use solana_vote_program::{vote_instruction::VoteInstruction, vote_state::TIMESTAMP_SLOT_INTERVAL};
use std::{
@@ -66,7 +65,7 @@ thread_local!(static PAR_THREAD_POOL: RefCell<ThreadPool> = RefCell::new(rayon::
pub const MAX_COMPLETED_SLOTS_IN_CHANNEL: usize = 100_000;
pub const MAX_TURBINE_PROPAGATION_IN_MS: u64 = 100;
pub const MAX_TURBINE_DELAY_IN_TICKS: u64 = MAX_TURBINE_PROPAGATION_IN_MS / MS_PER_TICK;
const TIMESTAMP_SLOT_RANGE: usize = 50;
const TIMESTAMP_SLOT_RANGE: usize = 16;
// An upper bound on maximum number of data shreds we can handle in a slot
// 32K shreds would allow ~320K peak TPS
@@ -414,7 +413,7 @@ impl Blockstore {
write_timer.stop();
datapoint_info!(
"blockstore-purge",
("write_batch_ns", write_timer.as_us() as i64, i64)
("write_batch_us", write_timer.as_us() as i64, i64)
);
Ok(columns_empty)
}
@@ -1383,6 +1382,10 @@ impl Blockstore {
slot_duration: Duration,
stakes: &HashMap<Pubkey, (u64, Account)>,
) -> Result<Option<UnixTimestamp>> {
datapoint_info!(
"blockstore-rpc-api",
("method", "get_block_time".to_string(), String)
);
let lowest_cleanup_slot = self.lowest_cleanup_slot.read().unwrap();
// lowest_cleanup_slot is the last slot that was not cleaned up by
// LedgerCleanupService
@@ -1390,18 +1393,34 @@ impl Blockstore {
return Err(BlockstoreError::SlotCleanedUp);
}
let mut get_unique_timestamps = Measure::start("get_unique_timestamps");
let unique_timestamps: HashMap<Pubkey, (Slot, UnixTimestamp)> = self
.get_timestamp_slots(slot, TIMESTAMP_SLOT_INTERVAL, TIMESTAMP_SLOT_RANGE)
.into_iter()
.flat_map(|query_slot| self.get_block_timestamps(query_slot).unwrap_or_default())
.collect();
get_unique_timestamps.stop();
Ok(calculate_stake_weighted_timestamp(
unique_timestamps,
stakes,
slot,
slot_duration,
))
let mut calculate_timestamp = Measure::start("calculate_timestamp");
let stake_weighted_timestamps =
calculate_stake_weighted_timestamp(unique_timestamps, stakes, slot, slot_duration);
calculate_timestamp.stop();
datapoint_info!(
"blockstore-get-block-time",
("slot", slot as i64, i64),
(
"get_unique_timestamps_us",
get_unique_timestamps.as_us() as i64,
i64
),
(
"calculate_stake_weighted_timestamp_us",
calculate_timestamp.as_us() as i64,
i64
)
);
Ok(stake_weighted_timestamps)
}
fn get_timestamp_slots(
@@ -1410,41 +1429,47 @@ impl Blockstore {
timestamp_interval: u64,
timestamp_sample_range: usize,
) -> Vec<Slot> {
let root_iterator = self.db.iter::<cf::Root>(IteratorMode::Start);
let baseline_slot = slot - (slot % timestamp_interval);
let root_iterator = self.db.iter::<cf::Root>(IteratorMode::From(
baseline_slot,
IteratorDirection::Forward,
));
if !self.is_root(slot) || root_iterator.is_err() {
return vec![];
}
let lowest_nonzero_root = root_iterator.unwrap().map(|(slot, _)| slot).nth(1).unwrap();
let rooted_slots = RootedSlotIterator::new(lowest_nonzero_root, &self);
let slots: Vec<Slot> = rooted_slots
let mut get_slots = Measure::start("get_slots");
let mut slots: Vec<Slot> = root_iterator
.unwrap()
.map(|(iter_slot, _)| iter_slot)
.take(timestamp_sample_range)
.filter(|&iter_slot| iter_slot <= slot)
.collect();
if slots.len() < timestamp_sample_range {
return slots;
if slots.len() < timestamp_sample_range && baseline_slot >= timestamp_interval {
let earlier_baseline = baseline_slot - timestamp_interval;
let earlier_root_iterator = self.db.iter::<cf::Root>(IteratorMode::From(
earlier_baseline,
IteratorDirection::Forward,
));
if let Ok(iterator) = earlier_root_iterator {
slots = iterator
.map(|(iter_slot, _)| iter_slot)
.take(timestamp_sample_range)
.collect();
}
}
get_slots.stop();
datapoint_info!(
"blockstore-get-timestamp-slots",
("slot", slot as i64, i64),
("get_slots_us", get_slots.as_us() as i64, i64)
);
slots
}
let recent_timestamp_slot_position = slots
.iter()
.position(|&x| x >= slot - (slot % timestamp_interval))
.unwrap();
let filtered_iter =
if slots.len() - timestamp_sample_range >= recent_timestamp_slot_position {
slots.iter().skip(recent_timestamp_slot_position)
} else {
let earlier_timestamp_slot_position = slots
.iter()
.position(|&x| x >= slot - (slot % timestamp_interval) - timestamp_interval)
.unwrap();
slots.iter().skip(earlier_timestamp_slot_position)
};
filtered_iter
.take(timestamp_sample_range)
.cloned()
.collect()
pub fn get_first_available_block(&self) -> Result<Slot> {
let mut root_iterator = self.rooted_slot_iterator(0)?;
Ok(root_iterator.next().unwrap_or_default())
}
pub fn get_confirmed_block(
@@ -1452,6 +1477,10 @@ impl Blockstore {
slot: Slot,
encoding: Option<TransactionEncoding>,
) -> Result<ConfirmedBlock> {
datapoint_info!(
"blockstore-rpc-api",
("method", "get_confirmed_block".to_string(), String)
);
let lowest_cleanup_slot = self.lowest_cleanup_slot.read().unwrap();
// lowest_cleanup_slot is the last slot that was not cleaned up by
// LedgerCleanupService
@@ -1475,7 +1504,9 @@ impl Blockstore {
.iter()
.cloned()
.flat_map(|entry| entry.transactions);
let parent_slot_entries = self.get_slot_entries(slot_meta.parent_slot, 0, None)?;
let parent_slot_entries = self
.get_slot_entries(slot_meta.parent_slot, 0, None)
.unwrap_or_default();
let previous_blockhash = if !parent_slot_entries.is_empty() {
get_last_hash(parent_slot_entries.iter()).unwrap()
} else {
@@ -1633,20 +1664,14 @@ impl Blockstore {
.put((primary_index, signature, slot), status)?;
for address in writable_keys {
self.address_signatures_cf.put(
(primary_index, *address, slot),
&AddressSignatureMeta {
signature,
writeable: true,
},
(primary_index, *address, slot, signature),
&AddressSignatureMeta { writeable: true },
)?;
}
for address in readonly_keys {
self.address_signatures_cf.put(
(primary_index, *address, slot),
&AddressSignatureMeta {
signature,
writeable: false,
},
(primary_index, *address, slot, signature),
&AddressSignatureMeta { writeable: false },
)?;
}
Ok(())
@@ -1683,10 +1708,105 @@ impl Blockstore {
&self,
signature: Signature,
) -> Result<Option<(Slot, TransactionStatusMeta)>> {
datapoint_info!(
"blockstore-rpc-api",
("method", "get_transaction_status".to_string(), String)
);
self.get_transaction_status_with_counter(signature)
.map(|(status, _)| status)
}
/// Returns a complete transaction if it was processed in a root
pub fn get_confirmed_transaction(
&self,
signature: Signature,
encoding: Option<TransactionEncoding>,
) -> Result<Option<ConfirmedTransaction>> {
datapoint_info!(
"blockstore-rpc-api",
("method", "get_confirmed_transaction".to_string(), String)
);
if let Some((slot, status)) = self.get_transaction_status(signature.clone())? {
let transaction = self.find_transaction_in_slot(slot, signature)?
.expect("Transaction to exist in slot entries if it exists in statuses and hasn't been cleaned up");
let encoding = encoding.unwrap_or(TransactionEncoding::Json);
let encoded_transaction = EncodedTransaction::encode(transaction, encoding);
Ok(Some(ConfirmedTransaction {
slot,
transaction: TransactionWithStatusMeta {
transaction: encoded_transaction,
meta: Some(status.into()),
},
}))
} else {
Ok(None)
}
}
fn find_transaction_in_slot(
&self,
slot: Slot,
signature: Signature,
) -> Result<Option<Transaction>> {
let slot_entries = self.get_slot_entries(slot, 0, None)?;
Ok(slot_entries
.iter()
.cloned()
.flat_map(|entry| entry.transactions)
.find(|transaction| transaction.signatures[0] == signature))
}
// Returns all cached signatures for an address, ordered by slot that the transaction was
// processed in
fn find_address_signatures(
&self,
pubkey: Pubkey,
start_slot: Slot,
end_slot: Slot,
) -> Result<Vec<(Slot, Signature)>> {
let mut signatures: Vec<(Slot, Signature)> = vec![];
for transaction_status_cf_primary_index in 0..=1 {
let index_iterator = self.address_signatures_cf.iter(IteratorMode::From(
(
transaction_status_cf_primary_index,
pubkey,
start_slot,
Signature::default(),
),
IteratorDirection::Forward,
))?;
for ((i, address, slot, signature), _) in index_iterator {
if i != transaction_status_cf_primary_index || slot > end_slot || address != pubkey
{
break;
}
if self.is_root(slot) {
signatures.push((slot, signature));
}
}
}
signatures.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap());
Ok(signatures)
}
pub fn get_confirmed_signatures_for_address(
&self,
pubkey: Pubkey,
start_slot: Slot,
end_slot: Slot,
) -> Result<Vec<Signature>> {
datapoint_info!(
"blockstore-rpc-api",
(
"method",
"get_confirmed_signatures_for_address".to_string(),
String
)
);
self.find_address_signatures(pubkey, start_slot, end_slot)
.map(|signatures| signatures.iter().map(|(_, signature)| *signature).collect())
}
pub fn read_rewards(&self, index: Slot) -> Result<Option<Rewards>> {
self.rewards_cf.get(index)
}
@@ -2822,7 +2942,7 @@ pub mod tests {
.iter::<cf::AddressSignatures>(IteratorMode::Start)
.unwrap()
.next()
.map(|((primary_index, _, slot), _)| {
.map(|((primary_index, _, slot, _), _)| {
slot >= min_slot || (primary_index == 2 && slot == 0)
})
.unwrap_or(true)
@@ -4946,11 +5066,11 @@ pub mod tests {
assert_eq!(
blockstore.get_timestamp_slots(2, timestamp_interval, timestamp_sample_range),
vec![1, 2]
vec![0, 1, 2]
);
assert_eq!(
blockstore.get_timestamp_slots(3, timestamp_interval, timestamp_sample_range),
vec![1, 2, 3]
vec![0, 1, 2, 3]
);
drop(blockstore);
@@ -4986,11 +5106,15 @@ pub mod tests {
assert_eq!(
blockstore.get_timestamp_slots(2, timestamp_interval, timestamp_sample_range),
vec![1, 2]
vec![0, 1, 2]
);
assert_eq!(
blockstore.get_timestamp_slots(6, timestamp_interval, timestamp_sample_range),
vec![0, 1, 2, 3, 4]
);
assert_eq!(
blockstore.get_timestamp_slots(8, timestamp_interval, timestamp_sample_range),
vec![1, 2, 3, 4, 5]
vec![0, 1, 2, 3, 4]
);
assert_eq!(
blockstore.get_timestamp_slots(13, timestamp_interval, timestamp_sample_range),
@@ -5430,7 +5554,7 @@ pub mod tests {
let first_status_entry = blockstore
.db
.iter::<cf::TransactionStatus>(IteratorMode::From(
(0, Signature::default(), 0),
cf::TransactionStatus::as_index(0),
IteratorDirection::Forward,
))
.unwrap()
@@ -5442,7 +5566,7 @@ pub mod tests {
let first_address_entry = blockstore
.db
.iter::<cf::AddressSignatures>(IteratorMode::From(
(0, Pubkey::default(), 0),
cf::AddressSignatures::as_index(0),
IteratorDirection::Forward,
))
.unwrap()
@@ -5500,7 +5624,7 @@ pub mod tests {
let first_status_entry = blockstore
.db
.iter::<cf::TransactionStatus>(IteratorMode::From(
(0, Signature::default(), 0),
cf::TransactionStatus::as_index(0),
IteratorDirection::Forward,
))
.unwrap()
@@ -5512,7 +5636,7 @@ pub mod tests {
let first_address_entry = blockstore
.db
.iter::<cf::AddressSignatures>(IteratorMode::From(
(0, Pubkey::default(), 0),
cf::AddressSignatures::as_index(0),
IteratorDirection::Forward,
))
.unwrap()
@@ -5525,7 +5649,7 @@ pub mod tests {
let index1_first_status_entry = blockstore
.db
.iter::<cf::TransactionStatus>(IteratorMode::From(
(1, Signature::default(), 0),
cf::TransactionStatus::as_index(1),
IteratorDirection::Forward,
))
.unwrap()
@@ -5537,7 +5661,7 @@ pub mod tests {
let index1_first_address_entry = blockstore
.db
.iter::<cf::AddressSignatures>(IteratorMode::From(
(1, Pubkey::default(), 0),
cf::AddressSignatures::as_index(1),
IteratorDirection::Forward,
))
.unwrap()
@@ -5568,7 +5692,7 @@ pub mod tests {
let first_status_entry = blockstore
.db
.iter::<cf::TransactionStatus>(IteratorMode::From(
(0, Signature::default(), 0),
cf::TransactionStatus::as_index(0),
IteratorDirection::Forward,
))
.unwrap()
@@ -5580,7 +5704,7 @@ pub mod tests {
let first_address_entry = blockstore
.db
.iter::<cf::AddressSignatures>(IteratorMode::From(
(0, Pubkey::default(), 0),
cf::AddressSignatures::as_index(0),
IteratorDirection::Forward,
))
.unwrap()
@@ -5617,7 +5741,7 @@ pub mod tests {
let mut status_entry_iterator = blockstore
.db
.iter::<cf::TransactionStatus>(IteratorMode::From(
(0, Signature::default(), 0),
cf::TransactionStatus::as_index(0),
IteratorDirection::Forward,
))
.unwrap();
@@ -5629,7 +5753,7 @@ pub mod tests {
let mut address_transactions_iterator = blockstore
.db
.iter::<cf::AddressSignatures>(IteratorMode::From(
(0, Pubkey::default(), 0),
(0, Pubkey::default(), 0, Signature::default()),
IteratorDirection::Forward,
))
.unwrap();
@@ -5651,7 +5775,7 @@ pub mod tests {
let mut status_entry_iterator = blockstore
.db
.iter::<cf::TransactionStatus>(IteratorMode::From(
(0, Signature::default(), 0),
cf::TransactionStatus::as_index(0),
IteratorDirection::Forward,
))
.unwrap();
@@ -5663,7 +5787,7 @@ pub mod tests {
let mut address_transactions_iterator = blockstore
.db
.iter::<cf::AddressSignatures>(IteratorMode::From(
(0, Pubkey::default(), 0),
cf::AddressSignatures::as_index(0),
IteratorDirection::Forward,
))
.unwrap();
@@ -5685,7 +5809,7 @@ pub mod tests {
let mut status_entry_iterator = blockstore
.db
.iter::<cf::TransactionStatus>(IteratorMode::From(
(0, Signature::default(), 0),
cf::TransactionStatus::as_index(0),
IteratorDirection::Forward,
))
.unwrap();
@@ -5697,7 +5821,7 @@ pub mod tests {
let mut address_transactions_iterator = blockstore
.db
.iter::<cf::AddressSignatures>(IteratorMode::From(
(0, Pubkey::default(), 0),
cf::AddressSignatures::as_index(0),
IteratorDirection::Forward,
))
.unwrap();
@@ -5718,7 +5842,7 @@ pub mod tests {
let mut status_entry_iterator = blockstore
.db
.iter::<cf::TransactionStatus>(IteratorMode::From(
(0, Signature::default(), 0),
cf::TransactionStatus::as_index(0),
IteratorDirection::Forward,
))
.unwrap();
@@ -5729,7 +5853,7 @@ pub mod tests {
let mut address_transactions_iterator = blockstore
.db
.iter::<cf::AddressSignatures>(IteratorMode::From(
(0, Pubkey::default(), 0),
cf::AddressSignatures::as_index(0),
IteratorDirection::Forward,
))
.unwrap();
@@ -5877,6 +6001,226 @@ pub mod tests {
Blockstore::destroy(&blockstore_path).expect("Expected successful database destruction");
}
#[test]
fn test_get_confirmed_transaction() {
let slot = 2;
let entries = make_slot_entries_with_transactions(5);
let shreds = entries_to_test_shreds(entries.clone(), slot, slot - 1, true, 0);
let ledger_path = get_tmp_ledger_path!();
let blockstore = Blockstore::open(&ledger_path).unwrap();
blockstore.insert_shreds(shreds, None, false).unwrap();
blockstore.set_roots(&[slot - 1, slot]).unwrap();
let expected_transactions: Vec<(Transaction, Option<RpcTransactionStatusMeta>)> = entries
.iter()
.cloned()
.filter(|entry| !entry.is_tick())
.flat_map(|entry| entry.transactions)
.map(|transaction| {
let mut pre_balances: Vec<u64> = vec![];
let mut post_balances: Vec<u64> = vec![];
for (i, _account_key) in transaction.message.account_keys.iter().enumerate() {
pre_balances.push(i as u64 * 10);
post_balances.push(i as u64 * 11);
}
let signature = transaction.signatures[0];
blockstore
.transaction_status_cf
.put(
(0, signature, slot),
&TransactionStatusMeta {
status: Ok(()),
fee: 42,
pre_balances: pre_balances.clone(),
post_balances: post_balances.clone(),
},
)
.unwrap();
(
transaction,
Some(
TransactionStatusMeta {
status: Ok(()),
fee: 42,
pre_balances,
post_balances,
}
.into(),
),
)
})
.collect();
for (transaction, status) in expected_transactions.clone() {
let signature = transaction.signatures[0];
let encoded_transaction =
EncodedTransaction::encode(transaction, TransactionEncoding::Json);
let expected_transaction = ConfirmedTransaction {
slot,
transaction: TransactionWithStatusMeta {
transaction: encoded_transaction,
meta: status,
},
};
assert_eq!(
blockstore
.get_confirmed_transaction(signature, None)
.unwrap(),
Some(expected_transaction)
);
}
blockstore.run_purge(0, 2).unwrap();
*blockstore.lowest_cleanup_slot.write().unwrap() = slot;
for (transaction, _) in expected_transactions {
let signature = transaction.signatures[0];
assert_eq!(
blockstore
.get_confirmed_transaction(signature, None)
.unwrap(),
None,
);
}
}
#[test]
fn test_get_confirmed_signatures_for_address() {
let blockstore_path = get_tmp_ledger_path!();
{
let blockstore = Blockstore::open(&blockstore_path).unwrap();
let address0 = Pubkey::new_rand();
let address1 = Pubkey::new_rand();
let slot0 = 10;
for x in 1..5 {
let signature = Signature::new(&[x; 64]);
blockstore
.write_transaction_status(
slot0,
signature,
vec![&address0],
vec![&address1],
&TransactionStatusMeta::default(),
)
.unwrap();
}
// Purge to freeze index 0
blockstore.run_purge(0, 1).unwrap();
let slot1 = 20;
for x in 5..9 {
let signature = Signature::new(&[x; 64]);
blockstore
.write_transaction_status(
slot1,
signature,
vec![&address0],
vec![&address1],
&TransactionStatusMeta::default(),
)
.unwrap();
}
blockstore.set_roots(&[slot0, slot1]).unwrap();
let all0 = blockstore
.get_confirmed_signatures_for_address(address0, 0, 50)
.unwrap();
assert_eq!(all0.len(), 8);
for x in 1..9 {
let expected_signature = Signature::new(&[x; 64]);
assert_eq!(all0[x as usize - 1], expected_signature);
}
assert_eq!(
blockstore
.get_confirmed_signatures_for_address(address0, 20, 50)
.unwrap()
.len(),
4
);
assert_eq!(
blockstore
.get_confirmed_signatures_for_address(address0, 0, 10)
.unwrap()
.len(),
4
);
assert!(blockstore
.get_confirmed_signatures_for_address(address0, 1, 5)
.unwrap()
.is_empty());
assert_eq!(
blockstore
.get_confirmed_signatures_for_address(address0, 1, 15)
.unwrap()
.len(),
4
);
let all1 = blockstore
.get_confirmed_signatures_for_address(address1, 0, 50)
.unwrap();
assert_eq!(all1.len(), 8);
for x in 1..9 {
let expected_signature = Signature::new(&[x; 64]);
assert_eq!(all1[x as usize - 1], expected_signature);
}
// Purge index 0
blockstore.run_purge(0, 10).unwrap();
assert_eq!(
blockstore
.get_confirmed_signatures_for_address(address0, 0, 50)
.unwrap()
.len(),
4
);
assert_eq!(
blockstore
.get_confirmed_signatures_for_address(address0, 20, 50)
.unwrap()
.len(),
4
);
assert!(blockstore
.get_confirmed_signatures_for_address(address0, 0, 10)
.unwrap()
.is_empty());
assert!(blockstore
.get_confirmed_signatures_for_address(address0, 1, 5)
.unwrap()
.is_empty());
assert_eq!(
blockstore
.get_confirmed_signatures_for_address(address0, 1, 25)
.unwrap()
.len(),
4
);
// Test sort, regardless of entry order or signature value
for slot in (21..25).rev() {
let random_bytes: Vec<u8> = (0..64).map(|_| rand::random::<u8>()).collect();
let signature = Signature::new(&random_bytes);
blockstore
.write_transaction_status(
slot,
signature,
vec![&address0],
vec![&address1],
&TransactionStatusMeta::default(),
)
.unwrap();
}
blockstore.set_roots(&[21, 22, 23, 24]).unwrap();
let mut past_slot = 0;
for (slot, _) in blockstore.find_address_signatures(address0, 1, 25).unwrap() {
assert!(slot >= past_slot);
past_slot = slot;
}
}
Blockstore::destroy(&blockstore_path).expect("Expected successful database destruction");
}
#[test]
fn test_get_last_hash() {
let mut entries: Vec<Entry> = vec![];

View File

@@ -356,21 +356,23 @@ impl ColumnName for columns::TransactionStatus {
}
impl Column for columns::AddressSignatures {
type Index = (u64, Pubkey, Slot);
type Index = (u64, Pubkey, Slot, Signature);
fn key((index, pubkey, slot): (u64, Pubkey, Slot)) -> Vec<u8> {
let mut key = vec![0; 8 + 32 + 8]; // size_of u64 + size_of Pubkey + size_of Slot
fn key((index, pubkey, slot, signature): (u64, Pubkey, Slot, Signature)) -> Vec<u8> {
let mut key = vec![0; 8 + 32 + 8 + 64]; // size_of u64 + size_of Pubkey + size_of Slot + size_of Signature
BigEndian::write_u64(&mut key[0..8], index);
key[8..40].clone_from_slice(&pubkey.as_ref()[0..32]);
BigEndian::write_u64(&mut key[40..48], slot);
key[48..112].clone_from_slice(&signature.as_ref()[0..64]);
key
}
fn index(key: &[u8]) -> (u64, Pubkey, Slot) {
fn index(key: &[u8]) -> (u64, Pubkey, Slot, Signature) {
let index = BigEndian::read_u64(&key[0..8]);
let pubkey = Pubkey::new(&key[8..40]);
let slot = BigEndian::read_u64(&key[40..48]);
(index, pubkey, slot)
let signature = Signature::new(&key[48..112]);
(index, pubkey, slot, signature)
}
fn primary_index(index: Self::Index) -> u64 {
@@ -378,7 +380,7 @@ impl Column for columns::AddressSignatures {
}
fn as_index(index: u64) -> Self::Index {
(index, Pubkey::default(), 0)
(index, Pubkey::default(), 0, Signature::default())
}
}

View File

@@ -1,6 +1,6 @@
use crate::erasure::ErasureConfig;
use serde::{Deserialize, Serialize};
use solana_sdk::{clock::Slot, signature::Signature};
use solana_sdk::clock::Slot;
use std::{collections::BTreeSet, ops::RangeBounds};
#[derive(Clone, Debug, Default, Deserialize, Serialize, Eq, PartialEq)]
@@ -230,7 +230,6 @@ pub struct TransactionStatusIndexMeta {
#[derive(Debug, Default, Deserialize, Serialize, PartialEq)]
pub struct AddressSignatureMeta {
pub signature: Signature,
pub writeable: bool,
}

View File

@@ -20,8 +20,8 @@ use solana_runtime::{
transaction_batch::TransactionBatch,
};
use solana_sdk::{
clock::{Slot, MAX_RECENT_BLOCKHASHES},
genesis_config::GenesisConfig,
clock::{Epoch, Slot, MAX_PROCESSING_AGE, MAX_RECENT_BLOCKHASHES},
genesis_config::{GenesisConfig, OperatingMode},
hash::Hash,
pubkey::Pubkey,
signature::Keypair,
@@ -57,11 +57,22 @@ fn first_err(results: &[Result<()>]) -> Result<()> {
Ok(())
}
const MAX_AGE_CORRECTION_EPOCH: Epoch = 14;
fn execute_batch(
batch: &TransactionBatch,
bank: &Arc<Bank>,
transaction_status_sender: Option<TransactionStatusSender>,
genesis_config: Option<&GenesisConfig>,
) -> Result<()> {
// See https://github.com/solana-labs/solana/pull/9423
let max_age_reduced = if let Some(genesis_config) = genesis_config {
genesis_config.operating_mode == OperatingMode::Stable
&& bank.epoch() >= MAX_AGE_CORRECTION_EPOCH
} else {
false
};
let (
TransactionResults {
fee_collection_results,
@@ -70,7 +81,11 @@ fn execute_batch(
balances,
) = batch.bank().load_execute_and_commit_transactions(
batch,
MAX_RECENT_BLOCKHASHES,
if max_age_reduced {
MAX_PROCESSING_AGE
} else {
MAX_RECENT_BLOCKHASHES
},
transaction_status_sender.is_some(),
);
@@ -112,6 +127,7 @@ fn execute_batches(
batches: &[TransactionBatch],
entry_callback: Option<&ProcessCallback>,
transaction_status_sender: Option<TransactionStatusSender>,
genesis_config: Option<&GenesisConfig>,
) -> Result<()> {
inc_new_counter_debug!("bank-par_execute_entries-count", batches.len());
let results: Vec<Result<()>> = PAR_THREAD_POOL.with(|thread_pool| {
@@ -119,7 +135,7 @@ fn execute_batches(
batches
.into_par_iter()
.map_with(transaction_status_sender, |sender, batch| {
let result = execute_batch(batch, bank, sender.clone());
let result = execute_batch(batch, bank, sender.clone(), genesis_config);
if let Some(entry_callback) = entry_callback {
entry_callback(bank);
}
@@ -143,7 +159,14 @@ pub fn process_entries(
randomize: bool,
transaction_status_sender: Option<TransactionStatusSender>,
) -> Result<()> {
process_entries_with_callback(bank, entries, randomize, None, transaction_status_sender)
process_entries_with_callback(
bank,
entries,
randomize,
None,
transaction_status_sender,
Some(&GenesisConfig::default()),
)
}
fn process_entries_with_callback(
@@ -152,6 +175,7 @@ fn process_entries_with_callback(
randomize: bool,
entry_callback: Option<&ProcessCallback>,
transaction_status_sender: Option<TransactionStatusSender>,
genesis_config: Option<&GenesisConfig>,
) -> Result<()> {
// accumulator for entries that can be processed in parallel
let mut batches = vec![];
@@ -168,6 +192,7 @@ fn process_entries_with_callback(
&batches,
entry_callback,
transaction_status_sender.clone(),
genesis_config,
)?;
batches.clear();
for hash in &tick_hashes {
@@ -223,12 +248,19 @@ fn process_entries_with_callback(
&batches,
entry_callback,
transaction_status_sender.clone(),
genesis_config,
)?;
batches.clear();
}
}
}
execute_batches(bank, &batches, entry_callback, transaction_status_sender)?;
execute_batches(
bank,
&batches,
entry_callback,
transaction_status_sender,
genesis_config,
)?;
for hash in tick_hashes {
bank.register_tick(&hash);
}
@@ -363,6 +395,7 @@ pub fn process_blockstore_from_root(
&mut rooted_path,
opts,
recyclers,
genesis_config,
)?;
let (banks, bank_forks_info): (Vec<_>, Vec<_>) =
fork_info.into_iter().map(|(_, v)| v).unzip();
@@ -456,6 +489,7 @@ fn confirm_full_slot(
last_entry_hash: &Hash,
opts: &ProcessOptions,
recyclers: &VerifyRecyclers,
genesis_config: Option<&GenesisConfig>,
) -> result::Result<(), BlockstoreProcessorError> {
let mut timing = ConfirmationTiming::default();
let mut progress = ConfirmationProgress::new(*last_entry_hash);
@@ -469,6 +503,7 @@ fn confirm_full_slot(
None,
opts.entry_callback.as_ref(),
recyclers,
genesis_config,
)?;
if !bank.is_complete() {
@@ -527,6 +562,7 @@ pub fn confirm_slot(
transaction_status_sender: Option<TransactionStatusSender>,
entry_callback: Option<&ProcessCallback>,
recyclers: &VerifyRecyclers,
genesis_config: Option<&GenesisConfig>,
) -> result::Result<(), BlockstoreProcessorError> {
let slot = bank.slot();
@@ -592,6 +628,7 @@ pub fn confirm_slot(
true,
entry_callback,
transaction_status_sender,
genesis_config,
)
.map_err(BlockstoreProcessorError::from);
replay_elapsed.stop();
@@ -625,8 +662,15 @@ fn process_bank_0(
recyclers: &VerifyRecyclers,
) -> result::Result<(), BlockstoreProcessorError> {
assert_eq!(bank0.slot(), 0);
confirm_full_slot(blockstore, bank0, &bank0.last_blockhash(), opts, recyclers)
.expect("processing for bank 0 must succceed");
confirm_full_slot(
blockstore,
bank0,
&bank0.last_blockhash(),
opts,
recyclers,
None,
)
.expect("processing for bank 0 must succceed");
bank0.freeze();
Ok(())
}
@@ -701,6 +745,7 @@ fn process_pending_slots(
rooted_path: &mut Vec<u64>,
opts: &ProcessOptions,
recyclers: &VerifyRecyclers,
genesis_config: &GenesisConfig,
) -> result::Result<HashMap<u64, (Arc<Bank>, BankForksInfo)>, BlockstoreProcessorError> {
let mut fork_info = HashMap::new();
let mut last_status_report = Instant::now();
@@ -730,7 +775,16 @@ fn process_pending_slots(
let allocated = thread_mem_usage::Allocatedp::default();
let initial_allocation = allocated.get();
if process_single_slot(blockstore, &bank, &last_entry_hash, opts, recyclers).is_err() {
if process_single_slot(
blockstore,
&bank,
&last_entry_hash,
opts,
recyclers,
genesis_config,
)
.is_err()
{
continue;
}
@@ -778,10 +832,19 @@ fn process_single_slot(
last_entry_hash: &Hash,
opts: &ProcessOptions,
recyclers: &VerifyRecyclers,
genesis_config: &GenesisConfig,
) -> result::Result<(), BlockstoreProcessorError> {
// Mark corrupt slots as dead so validators don't replay this slot and
// see DuplicateSignature errors later in ReplayStage
confirm_full_slot(blockstore, bank, last_entry_hash, opts, recyclers).map_err(|err| {
confirm_full_slot(
blockstore,
bank,
last_entry_hash,
opts,
recyclers,
Some(genesis_config),
)
.map_err(|err| {
let slot = bank.slot();
blockstore
.set_dead_slot(slot)
@@ -2444,6 +2507,7 @@ pub mod tests {
&bank0.last_blockhash(),
&opts,
&recyclers,
None,
)
.unwrap();
bank1.squash();
@@ -2609,7 +2673,7 @@ pub mod tests {
let entry = next_entry(&new_blockhash, 1, vec![tx]);
entries.push(entry);
process_entries_with_callback(&bank0, &entries, true, None, None).unwrap();
process_entries_with_callback(&bank0, &entries, true, None, None, None).unwrap();
assert_eq!(bank0.get_balance(&keypair.pubkey()), 1)
}

View File

@@ -74,6 +74,11 @@ pub enum ShredError {
#[error("serialization error")]
Serialize(#[from] Box<bincode::ErrorKind>),
#[error(
"invalid parent offset; parent_offset {parent_offset} must be larger than slot {slot}"
)]
InvalidParentOffset { slot: Slot, parent_offset: u16 },
}
pub type Result<T> = std::result::Result<T, ShredError>;
@@ -230,6 +235,12 @@ impl Shred {
} else if common_header.shred_type == ShredType(DATA_SHRED) {
let data_header: DataShredHeader =
Self::deserialize_obj(&mut start, SIZE_OF_DATA_SHRED_HEADER, &payload)?;
if u64::from(data_header.parent_offset) > common_header.slot {
return Err(ShredError::InvalidParentOffset {
slot: common_header.slot,
parent_offset: data_header.parent_offset,
});
}
Self {
common_header,
data_header,
@@ -764,7 +775,7 @@ impl Shredder {
return Err(reed_solomon_erasure::Error::TooFewShardsPresent);
}
let session = Session::new(num_data, num_coding).unwrap();
let session = Session::new(num_data, num_coding)?;
let valid_data_len = PACKET_DATA_SIZE - SIZE_OF_DATA_SHRED_IGNORED_TAIL;
let coding_block_offset = SIZE_OF_CODING_SHRED_HEADER + SIZE_OF_COMMON_SHRED_HEADER;
@@ -1558,4 +1569,19 @@ pub mod tests {
MAX_DATA_SHREDS_PER_FEC_BLOCK as usize * 2
);
}
#[test]
fn test_invalid_parent_offset() {
let shred = Shred::new_from_data(10, 0, 1000, Some(&[1, 2, 3]), false, false, 0, 1, 0);
let mut packet = Packet::default();
shred.copy_to_packet(&mut packet);
let shred_res = Shred::new_from_serialized_shred(packet.data.to_vec());
assert_matches!(
shred_res,
Err(ShredError::InvalidParentOffset {
slot: 10,
parent_offset: 1000
})
);
}
}

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-local-cluster"
description = "Blockchain, Rebuilt for Scale"
version = "1.0.15"
version = "1.0.19"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -12,25 +12,28 @@ homepage = "https://solana.com/"
itertools = "0.8.1"
log = "0.4.8"
rand = "0.6.5"
solana-archiver-lib = { path = "../archiver-lib", version = "1.0.15" }
solana-config-program = { path = "../programs/config", version = "1.0.15" }
solana-core = { path = "../core", version = "1.0.15" }
solana-client = { path = "../client", version = "1.0.15" }
solana-faucet = { path = "../faucet", version = "1.0.15" }
solana-exchange-program = { path = "../programs/exchange", version = "1.0.15" }
solana-genesis-programs = { path = "../genesis-programs", version = "1.0.15" }
solana-ledger = { path = "../ledger", version = "1.0.15" }
solana-logger = { path = "../logger", version = "1.0.15" }
solana-runtime = { path = "../runtime", version = "1.0.15" }
solana-sdk = { path = "../sdk", version = "1.0.15" }
solana-stake-program = { path = "../programs/stake", version = "1.0.15" }
solana-storage-program = { path = "../programs/storage", version = "1.0.15" }
solana-vest-program = { path = "../programs/vest", version = "1.0.15" }
solana-vote-program = { path = "../programs/vote", version = "1.0.15" }
solana-archiver-lib = { path = "../archiver-lib", version = "1.0.19" }
solana-config-program = { path = "../programs/config", version = "1.0.19" }
solana-core = { path = "../core", version = "1.0.19" }
solana-client = { path = "../client", version = "1.0.19" }
solana-faucet = { path = "../faucet", version = "1.0.19" }
solana-exchange-program = { path = "../programs/exchange", version = "1.0.19" }
solana-genesis-programs = { path = "../genesis-programs", version = "1.0.19" }
solana-ledger = { path = "../ledger", version = "1.0.19" }
solana-logger = { path = "../logger", version = "1.0.19" }
solana-runtime = { path = "../runtime", version = "1.0.19" }
solana-sdk = { path = "../sdk", version = "1.0.19" }
solana-stake-program = { path = "../programs/stake", version = "1.0.19" }
solana-storage-program = { path = "../programs/storage", version = "1.0.19" }
solana-vest-program = { path = "../programs/vest", version = "1.0.19" }
solana-vote-program = { path = "../programs/vote", version = "1.0.19" }
tempfile = "3.1.0"
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.0.15" }
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.0.19" }
[dev-dependencies]
assert_matches = "1.3.0"
serial_test = "0.3.2"
serial_test_derive = "0.4.0"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-log-analyzer"
description = "The solana cluster network analysis tool"
version = "1.0.15"
version = "1.0.19"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -14,9 +14,12 @@ byte-unit = "3.0.3"
clap = "2.33.0"
serde = "1.0.104"
serde_json = "1.0.46"
solana-clap-utils = { path = "../clap-utils", version = "1.0.15" }
solana-logger = { path = "../logger", version = "1.0.15" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.19" }
solana-logger = { path = "../logger", version = "1.0.19" }
[[bin]]
name = "solana-log-analyzer"
path = "src/main.rs"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-logger"
version = "1.0.15"
version = "1.0.19"
description = "Solana Logger"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -15,3 +15,6 @@ log = "0.4.8"
[lib]
name = "solana_logger"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,7 +1,7 @@
[package]
name = "solana-measure"
description = "Blockchain, Rebuilt for Scale"
version = "1.0.15"
version = "1.0.19"
documentation = "https://docs.rs/solana"
homepage = "https://solana.com/"
readme = "../README.md"
@@ -12,9 +12,12 @@ edition = "2018"
[dependencies]
log = "0.4.8"
solana-sdk = { path = "../sdk", version = "1.0.15" }
solana-metrics = { path = "../metrics", version = "1.0.15" }
solana-sdk = { path = "../sdk", version = "1.0.19" }
solana-metrics = { path = "../metrics", version = "1.0.19" }
[target."cfg(unix)".dependencies]
jemallocator = "0.3.2"
jemalloc-ctl = "0.3.2"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-merkle-tree"
version = "1.0.15"
version = "1.0.19"
description = "Solana Merkle Tree"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../sdk", version = "1.0.15" }
solana-sdk = { path = "../sdk", version = "1.0.19" }
[dev-dependencies]
hex = "0.4.0"
@@ -17,3 +17,6 @@ hex = "0.4.0"
[lib]
crate-type = ["lib"]
name = "solana_merkle_tree"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-metrics"
version = "1.0.15"
version = "1.0.19"
description = "Solana Metrics"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -14,7 +14,7 @@ gethostname = "0.2.1"
lazy_static = "1.4.0"
log = "0.4.8"
reqwest = { version = "0.10.1", default-features = false, features = ["blocking", "rustls-tls"] }
solana-sdk = { path = "../sdk", version = "1.0.15" }
solana-sdk = { path = "../sdk", version = "1.0.19" }
[dev-dependencies]
rand = "0.6.5"
@@ -23,3 +23,6 @@ serial_test_derive = "0.4.0"
[lib]
name = "solana_metrics"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -83,7 +83,7 @@ args+=(
--enable-rpc-set-log-filter
--ledger "$ledger_dir"
--rpc-port 8899
--snapshot-interval-slots 100
--snapshot-interval-slots 200
--identity "$identity"
--vote-account "$vote_account"
--rpc-faucet-address 127.0.0.1:9900

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-net-shaper"
description = "The solana cluster network shaping tool"
version = "1.0.15"
version = "1.0.19"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -13,10 +13,13 @@ publish = false
clap = "2.33.0"
serde = "1.0.104"
serde_json = "1.0.46"
solana-clap-utils = { path = "../clap-utils", version = "1.0.15" }
solana-logger = { path = "../logger", version = "1.0.15" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.19" }
solana-logger = { path = "../logger", version = "1.0.19" }
rand = "0.6.5"
[[bin]]
name = "solana-net-shaper"
path = "src/main.rs"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-net-utils"
version = "1.0.15"
version = "1.0.19"
description = "Solana Network Utilities"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -18,8 +18,8 @@ rand = "0.6.1"
serde = "1.0.104"
serde_derive = "1.0.103"
socket2 = "0.3.11"
solana-clap-utils = { path = "../clap-utils", version = "1.0.15" }
solana-logger = { path = "../logger", version = "1.0.15" }
solana-clap-utils = { path = "../clap-utils", version = "1.0.19" }
solana-logger = { path = "../logger", version = "1.0.19" }
tokio = "0.1"
tokio-codec = "0.1"
@@ -33,3 +33,6 @@ path = "src/bin/ip_address.rs"
[[bin]]
name = "solana-ip-address-server"
path = "src/bin/ip_address_server.rs"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -327,13 +327,32 @@ pub fn multi_bind_in_range(
}
let mut sockets = Vec::with_capacity(num);
let port = {
let (port, _) = bind_in_range(ip_addr, range)?;
port
}; // drop the probe, port should be available... briefly.
const NUM_TRIES: usize = 100;
let mut port = 0;
let mut error = None;
for _ in 0..NUM_TRIES {
port = {
let (port, _) = bind_in_range(ip_addr, range)?;
port
}; // drop the probe, port should be available... briefly.
for _ in 0..num {
sockets.push(bind_to(ip_addr, port, true)?);
for _ in 0..num {
let sock = bind_to(ip_addr, port, true);
if let Ok(sock) = sock {
sockets.push(sock);
} else {
error = Some(sock);
break;
}
}
if sockets.len() == num {
break;
} else {
sockets.clear();
}
}
if sockets.len() != num {
error.unwrap()?;
}
Ok((port, sockets))
}

View File

@@ -96,7 +96,7 @@ waitForNodeToInit() {
echo "--- waiting for $hostname to boot up"
SECONDS=
while [[ ! -r $initCompleteFile ]]; do
if [[ $SECONDS -ge 240 ]]; then
if [[ $SECONDS -ge 600 ]]; then
echo "^^^ +++"
echo "Error: $initCompleteFile not found in $SECONDS seconds"
exit 1
@@ -253,12 +253,6 @@ cat >> ~/solana/on-reboot <<EOF
EOF
~/solana/on-reboot
waitForNodeToInit
if [[ $skipSetup != true ]]; then
solana --url http://"$entrypointIp":8899 \
--keypair ~/solana/config/bootstrap-validator/identity.json \
validator-info publish "$(hostname)" -n team/solana --force || true
fi
;;
validator|blockstreamer)
if [[ $deployMethod != skip ]]; then
@@ -394,12 +388,6 @@ EOF
multinode-demo/delegate-stake.sh "${args[@]}" "$internalNodesStakeLamports"
fi
if [[ $skipSetup != true ]]; then
solana --url http://"$entrypointIp":8899 \
--keypair config/validator-identity.json \
validator-info publish "$(hostname)" -n team/solana --force || true
fi
;;
archiver)
if [[ $deployMethod != skip ]]; then

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-perf"
version = "1.0.15"
version = "1.0.19"
description = "Solana Performance APIs"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -17,11 +17,11 @@ serde = "1.0.104"
dlopen_derive = "0.1.4"
lazy_static = "1.4.0"
log = "0.4.8"
solana-sdk = { path = "../sdk", version = "1.0.15" }
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.0.15" }
solana-budget-program = { path = "../programs/budget", version = "1.0.15" }
solana-logger = { path = "../logger", version = "1.0.15" }
solana-metrics = { path = "../metrics", version = "1.0.15" }
solana-sdk = { path = "../sdk", version = "1.0.19" }
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "1.0.19" }
solana-budget-program = { path = "../programs/budget", version = "1.0.19" }
solana-logger = { path = "../logger", version = "1.0.19" }
solana-metrics = { path = "../metrics", version = "1.0.19" }
[lib]
name = "solana_perf"
@@ -31,3 +31,6 @@ matches = "0.1.6"
[[bench]]
name = "sigverify"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,7 +1,7 @@
[package]
name = "solana-bpf-programs"
description = "Blockchain, Rebuilt for Scale"
version = "1.0.15"
version = "1.0.19"
documentation = "https://docs.rs/solana"
homepage = "https://solana.com/"
readme = "README.md"
@@ -22,10 +22,10 @@ walkdir = "2"
bincode = "1.1.4"
byteorder = "1.3.2"
elf = "0.0.10"
solana-bpf-loader-program = { path = "../bpf_loader", version = "1.0.15" }
solana-logger = { path = "../../logger", version = "1.0.15" }
solana-runtime = { path = "../../runtime", version = "1.0.15" }
solana-sdk = { path = "../../sdk", version = "1.0.15" }
solana-bpf-loader-program = { path = "../bpf_loader", version = "1.0.19" }
solana-logger = { path = "../../logger", version = "1.0.19" }
solana-runtime = { path = "../../runtime", version = "1.0.19" }
solana-sdk = { path = "../../sdk", version = "1.0.19" }
solana_rbpf = "=0.1.21"
[[bench]]
@@ -49,3 +49,6 @@ members = [
"rust/param_passing_dep",
"rust/sysval",
]
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-128bit"
version = "1.0.15"
version = "1.0.19"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,11 +12,11 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "1.0.15", default-features = false }
solana-bpf-rust-128bit-dep = { path = "../128bit_dep", version = "1.0.15" }
solana-sdk = { path = "../../../../sdk/", version = "1.0.19", default-features = false }
solana-bpf-rust-128bit-dep = { path = "../128bit_dep", version = "1.0.19" }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.15" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.19" }
[features]
program = ["solana-sdk/program"]
@@ -25,3 +25,6 @@ default = ["program"]
[lib]
name = "solana_bpf_rust_128bit"
crate-type = ["cdylib"]
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-128bit-dep"
version = "1.0.15"
version = "1.0.19"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,11 +12,14 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "1.0.15", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "1.0.19", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.15" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.19" }
[features]
program = ["solana-sdk/program"]
default = ["program"]
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-alloc"
version = "1.0.15"
version = "1.0.19"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,10 +12,10 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "1.0.15", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "1.0.19", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.15" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.19" }
[features]
program = ["solana-sdk/program"]
@@ -24,3 +24,6 @@ default = ["program"]
[lib]
name = "solana_bpf_rust_alloc"
crate-type = ["cdylib"]
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-dep-crate"
version = "1.0.15"
version = "1.0.19"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -13,10 +13,10 @@ edition = "2018"
[dependencies]
byteorder = { version = "1", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "1.0.15", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "1.0.19", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.15" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.19" }
[features]
program = ["solana-sdk/program"]
@@ -25,3 +25,6 @@ default = ["program"]
[lib]
name = "solana_bpf_rust_dep_crate"
crate-type = ["cdylib"]
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-dup-accounts"
version = "1.0.15"
version = "1.0.19"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,10 +12,10 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "1.0.15", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "1.0.19", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.15" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.19" }
[features]
program = ["solana-sdk/program"]
@@ -24,3 +24,6 @@ default = ["program"]
[lib]
name = "solana_bpf_rust_dup_accounts"
crate-type = ["cdylib"]
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-error-handling"
version = "1.0.15"
version = "1.0.19"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -14,11 +14,11 @@ edition = "2018"
[dependencies]
num-derive = "0.2"
num-traits = "0.2"
solana-sdk = { path = "../../../../sdk/", version = "1.0.15", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "1.0.19", default-features = false }
thiserror = "1.0"
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.15" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.19" }
[features]
program = ["solana-sdk/program"]
@@ -27,3 +27,6 @@ default = ["program"]
[lib]
name = "solana_bpf_rust_error_handling"
crate-type = ["cdylib"]
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-external-spend"
version = "1.0.15"
version = "1.0.19"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,10 +12,10 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "1.0.15", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "1.0.19", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.15" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.19" }
[features]
program = ["solana-sdk/program"]
@@ -24,3 +24,6 @@ default = ["program"]
[lib]
name = "solana_bpf_rust_external_spend"
crate-type = ["cdylib"]
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-iter"
version = "1.0.15"
version = "1.0.19"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,10 +12,10 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "1.0.15", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "1.0.19", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.15" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.19" }
[features]
program = ["solana-sdk/program"]
@@ -24,3 +24,6 @@ default = ["program"]
[lib]
name = "solana_bpf_rust_iter"
crate-type = ["cdylib"]
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-many-args"
version = "1.0.15"
version = "1.0.19"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,11 +12,11 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "1.0.15", default-features = false }
solana-bpf-rust-many-args-dep = { path = "../many_args_dep", version = "1.0.15" }
solana-sdk = { path = "../../../../sdk/", version = "1.0.19", default-features = false }
solana-bpf-rust-many-args-dep = { path = "../many_args_dep", version = "1.0.19" }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.15" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.19" }
[features]
program = ["solana-sdk/program"]
@@ -25,3 +25,6 @@ default = ["program"]
[lib]
name = "solana_bpf_rust_many_args"
crate-type = ["cdylib"]
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-many-args-dep"
version = "1.0.15"
version = "1.0.19"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,11 +12,14 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "1.0.15", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "1.0.19", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.15" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.19" }
[features]
program = ["solana-sdk/program"]
default = ["program"]
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-noop"
version = "1.0.15"
version = "1.0.19"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,10 +12,10 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "1.0.15", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "1.0.19", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.15" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.19" }
[features]
program = ["solana-sdk/program"]
@@ -24,3 +24,6 @@ default = ["program"]
[lib]
name = "solana_bpf_rust_noop"
crate-type = ["cdylib"]
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-panic"
version = "1.0.15"
version = "1.0.19"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,10 +12,10 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "1.0.15", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "1.0.19", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.15" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.19" }
[features]
program = ["solana-sdk/program"]
@@ -24,3 +24,6 @@ default = ["program"]
[lib]
name = "solana_bpf_rust_panic"
crate-type = ["cdylib"]
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-param-passing"
version = "1.0.15"
version = "1.0.19"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,11 +12,11 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "1.0.15", default-features = false }
solana-bpf-rust-param-passing-dep = { path = "../param_passing_dep", version = "1.0.15" }
solana-sdk = { path = "../../../../sdk/", version = "1.0.19", default-features = false }
solana-bpf-rust-param-passing-dep = { path = "../param_passing_dep", version = "1.0.19" }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.15" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.19" }
[features]
program = ["solana-sdk/program"]
@@ -25,3 +25,6 @@ default = ["program"]
[lib]
name = "solana_bpf_rust_param_passing"
crate-type = ["cdylib"]
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-param-passing-dep"
version = "1.0.15"
version = "1.0.19"
description = "Solana BPF program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,11 +12,14 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "1.0.15", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "1.0.19", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.15" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.19" }
[features]
program = ["solana-sdk/program"]
default = ["program"]
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-sysval"
version = "1.0.15"
version = "1.0.19"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,10 +12,10 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "1.0.15", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "1.0.19", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.15" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "1.0.19" }
[features]
program = ["solana-sdk/program"]
@@ -24,3 +24,6 @@ default = ["program"]
[lib]
name = "solana_bpf_rust_sysval"
crate-type = ["cdylib"]
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-loader-program"
version = "1.0.15"
version = "1.0.19"
description = "Solana BPF loader"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -15,11 +15,14 @@ libc = "0.2.66"
log = "0.4.8"
num-derive = { version = "0.3" }
num-traits = { version = "0.2" }
solana-logger = { path = "../../logger", version = "1.0.15" }
solana-sdk = { path = "../../sdk", version = "1.0.15" }
solana-logger = { path = "../../logger", version = "1.0.19" }
solana-sdk = { path = "../../sdk", version = "1.0.19" }
solana_rbpf = "=0.1.21"
thiserror = "1.0"
[lib]
crate-type = ["lib", "cdylib"]
name = "solana_bpf_loader_program"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-btc-spv-program"
version = "1.0.15"
version = "1.0.19"
description = "Solana Bitcoin spv parsing program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -15,9 +15,12 @@ num-derive = "0.3"
num-traits = "0.2"
serde = "1.0.104"
serde_derive = "1.0.103"
solana-sdk = { path = "../../sdk", version = "1.0.15"}
solana-sdk = { path = "../../sdk", version = "1.0.19"}
hex = "0.3.2"
[lib]
crate-type = ["lib", "cdylib"]
name = "solana_btc_spv_program"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,6 @@
[package]
name = "btc_spv_bin"
version = "1.0.15"
version = "1.0.19"
description = "Solana Bitcoin spv parsing program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -22,3 +22,6 @@ path = "src/blockheade.rs"
[[bin]]
name = "blocks"
path = "src/block.rs"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-budget-program"
version = "1.0.15"
version = "1.0.19"
description = "Solana Budget program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -16,12 +16,15 @@ num-derive = "0.3"
num-traits = "0.2"
serde = "1.0.104"
serde_derive = "1.0.103"
solana-sdk = { path = "../../sdk", version = "1.0.15" }
solana-sdk = { path = "../../sdk", version = "1.0.19" }
thiserror = "1.0"
[dev-dependencies]
solana-runtime = { path = "../../runtime", version = "1.0.15" }
solana-runtime = { path = "../../runtime", version = "1.0.19" }
[lib]
crate-type = ["lib", "cdylib"]
name = "solana_budget_program"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-config-program"
version = "1.0.15"
version = "1.0.19"
description = "Solana Config program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -14,9 +14,12 @@ chrono = { version = "0.4.10", features = ["serde"] }
log = "0.4.8"
serde = "1.0.104"
serde_derive = "1.0.103"
solana-logger = { path = "../../logger", version = "1.0.15" }
solana-sdk = { path = "../../sdk", version = "1.0.15" }
solana-logger = { path = "../../logger", version = "1.0.19" }
solana-sdk = { path = "../../sdk", version = "1.0.19" }
[lib]
crate-type = ["lib", "cdylib"]
name = "solana_config_program"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-exchange-program"
version = "1.0.15"
version = "1.0.19"
description = "Solana Exchange program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -15,14 +15,17 @@ num-derive = { version = "0.3" }
num-traits = { version = "0.2" }
serde = "1.0.104"
serde_derive = "1.0.103"
solana-logger = { path = "../../logger", version = "1.0.15" }
solana-metrics = { path = "../../metrics", version = "1.0.15" }
solana-sdk = { path = "../../sdk", version = "1.0.15" }
solana-logger = { path = "../../logger", version = "1.0.19" }
solana-metrics = { path = "../../metrics", version = "1.0.19" }
solana-sdk = { path = "../../sdk", version = "1.0.19" }
thiserror = "1.0"
[dev-dependencies]
solana-runtime = { path = "../../runtime", version = "1.0.15" }
solana-runtime = { path = "../../runtime", version = "1.0.19" }
[lib]
crate-type = ["lib", "cdylib"]
name = "solana_exchange_program"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-failure-program"
version = "1.0.15"
version = "1.0.19"
description = "Solana failure program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,12 +9,15 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../sdk", version = "1.0.15" }
solana-sdk = { path = "../../sdk", version = "1.0.19" }
[dev-dependencies]
solana-runtime = { path = "../../runtime", version = "1.0.15" }
solana-runtime = { path = "../../runtime", version = "1.0.19" }
[lib]
crate-type = ["lib", "cdylib"]
name = "solana_failure_program"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-librapay"
version = "1.0.15"
version = "1.0.19"
description = "Solana Libra Payment"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -11,12 +11,15 @@ edition = "2018"
[dependencies]
bincode = "1.2.0"
log = "0.4.8"
solana-logger = { path = "../../logger", version = "1.0.15" }
solana-move-loader-program = { path = "../move_loader", version = "1.0.15" }
solana-runtime = { path = "../../runtime", version = "1.0.15" }
solana-sdk = { path = "../../sdk", version = "1.0.15" }
solana-logger = { path = "../../logger", version = "1.0.19" }
solana-move-loader-program = { path = "../move_loader", version = "1.0.19" }
solana-runtime = { path = "../../runtime", version = "1.0.19" }
solana-sdk = { path = "../../sdk", version = "1.0.19" }
types = { version = "0.0.1-sol4", package = "solana_libra_types" }
[lib]
crate-type = ["lib", "cdylib"]
name = "solana_librapay"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-move-loader-program"
version = "1.0.15"
version = "1.0.19"
description = "Solana Move loader"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -16,8 +16,8 @@ serde = "1.0.104"
serde_bytes = "0.11"
serde_derive = "1.0.103"
serde_json = "1.0.46"
solana-logger = { path = "../../logger", version = "1.0.15" }
solana-sdk = { path = "../../sdk", version = "1.0.15" }
solana-logger = { path = "../../logger", version = "1.0.19" }
solana-sdk = { path = "../../sdk", version = "1.0.19" }
bytecode_verifier = { version = "0.0.1-sol4", package = "solana_libra_bytecode_verifier" }
canonical_serialization = { version = "0.0.1-sol4", package = "solana_libra_canonical_serialization" }
@@ -37,3 +37,6 @@ vm_runtime_types = { version = "0.0.1-sol4", package = "solana_libra_vm_runtime_
[lib]
crate-type = ["lib", "cdylib"]
name = "solana_move_loader_program"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-noop-program"
version = "1.0.15"
version = "1.0.19"
description = "Solana Noop program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -10,10 +10,13 @@ edition = "2018"
[dependencies]
log = "0.4.8"
solana-logger = { path = "../../logger", version = "1.0.15" }
solana-sdk = { path = "../../sdk", version = "1.0.15" }
solana-logger = { path = "../../logger", version = "1.0.19" }
solana-sdk = { path = "../../sdk", version = "1.0.19" }
[lib]
crate-type = ["lib", "cdylib"]
name = "solana_noop_program"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-ownable"
version = "1.0.15"
version = "1.0.19"
description = "ownable program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -10,14 +10,17 @@ edition = "2018"
[dependencies]
bincode = "1.2.1"
solana-sdk = { path = "../../sdk", version = "1.0.15" }
solana-sdk = { path = "../../sdk", version = "1.0.19" }
num-derive = "0.3"
num-traits = "0.2"
thiserror = "1.0"
[dev-dependencies]
solana-runtime = { path = "../../runtime", version = "1.0.15" }
solana-runtime = { path = "../../runtime", version = "1.0.19" }
[lib]
crate-type = ["lib", "cdylib"]
name = "solana_ownable"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-stake-program"
version = "1.0.15"
version = "1.0.19"
description = "Solana Stake program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -15,13 +15,16 @@ num-derive = "0.3"
num-traits = "0.2"
serde = "1.0.104"
serde_derive = "1.0.103"
solana-logger = { path = "../../logger", version = "1.0.15" }
solana-metrics = { path = "../../metrics", version = "1.0.15" }
solana-sdk = { path = "../../sdk", version = "1.0.15" }
solana-vote-program = { path = "../vote", version = "1.0.15" }
solana-config-program = { path = "../config", version = "1.0.15" }
solana-logger = { path = "../../logger", version = "1.0.19" }
solana-metrics = { path = "../../metrics", version = "1.0.19" }
solana-sdk = { path = "../../sdk", version = "1.0.19" }
solana-vote-program = { path = "../vote", version = "1.0.19" }
solana-config-program = { path = "../config", version = "1.0.19" }
thiserror = "1.0"
[lib]
crate-type = ["lib", "cdylib"]
name = "solana_stake_program"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -62,7 +62,8 @@ pub enum StakeInstruction {
/// Expects 2 Accounts:
/// 0 - StakeAccount to be updated with the Pubkey for
/// authorization
/// 1 - Clock sysvar Account that carries clock bank epoch
/// 1 - (reserved for future use) Clock sysvar Account that carries
/// clock bank epoch
Authorize(Pubkey, StakeAuthorize),
/// `Delegate` a stake to a particular vote account
@@ -397,12 +398,9 @@ pub fn process_instruction(
&lockup,
&Rent::from_keyed_account(next_keyed_account(keyed_accounts)?)?,
),
StakeInstruction::Authorize(authorized_pubkey, stake_authorize) => me.authorize(
&authorized_pubkey,
stake_authorize,
&signers,
&Clock::from_keyed_account(next_keyed_account(keyed_accounts)?)?,
),
StakeInstruction::Authorize(authorized_pubkey, stake_authorize) => {
me.authorize(&authorized_pubkey, stake_authorize, &signers)
}
StakeInstruction::DelegateStake => {
let vote = next_keyed_account(keyed_accounts)?;

View File

@@ -142,10 +142,9 @@ impl Meta {
Ok(())
}
pub fn authorize(
pub fn authorize_withdraw(
&mut self,
authority: &Pubkey,
stake_authorize: StakeAuthorize,
signers: &HashSet<Pubkey>,
clock: &Clock,
) -> Result<(), InstructionError> {
@@ -155,7 +154,7 @@ impl Meta {
return Err(StakeError::LockupInForce.into());
}
self.authorized
.authorize(signers, authority, stake_authorize)
.authorize(signers, authority, StakeAuthorize::Withdrawer)
}
}
@@ -523,7 +522,6 @@ pub trait StakeAccount {
authority: &Pubkey,
stake_authorize: StakeAuthorize,
signers: &HashSet<Pubkey>,
clock: &Clock,
) -> Result<(), InstructionError>;
fn delegate(
&self,
@@ -587,15 +585,16 @@ impl<'a> StakeAccount for KeyedAccount<'a> {
authority: &Pubkey,
stake_authorize: StakeAuthorize,
signers: &HashSet<Pubkey>,
clock: &Clock,
) -> Result<(), InstructionError> {
match self.state()? {
StakeState::Stake(mut meta, stake) => {
meta.authorize(authority, stake_authorize, signers, clock)?;
meta.authorized
.authorize(signers, authority, stake_authorize)?;
self.set_state(&StakeState::Stake(meta, stake))
}
StakeState::Initialized(mut meta) => {
meta.authorize(authority, stake_authorize, signers, clock)?;
meta.authorized
.authorize(signers, authority, stake_authorize)?;
self.set_state(&StakeState::Initialized(meta))
}
_ => Err(InstructionError::InvalidAccountData),
@@ -923,7 +922,23 @@ mod tests {
}
#[test]
fn test_meta_authorize() {
fn test_authorized_authorize() {
let staker = Pubkey::new_rand();
let mut authorized = Authorized::auto(&staker);
let mut signers = HashSet::new();
assert_eq!(
authorized.authorize(&signers, &staker, StakeAuthorize::Staker),
Err(InstructionError::MissingRequiredSignature)
);
signers.insert(staker);
assert_eq!(
authorized.authorize(&signers, &staker, StakeAuthorize::Staker),
Ok(())
);
}
#[test]
fn test_meta_authorize_withdraw() {
let staker = Pubkey::new_rand();
let custodian = Pubkey::new_rand();
let mut meta = Meta {
@@ -937,36 +952,22 @@ mod tests {
};
// verify sig check
let mut signers = HashSet::new();
signers.insert(staker);
let mut clock = Clock::default();
assert_eq!(
meta.authorize(&staker, StakeAuthorize::Staker, &signers, &clock),
Err(InstructionError::MissingRequiredSignature)
);
signers.insert(staker);
assert_eq!(
meta.authorize(&staker, StakeAuthorize::Staker, &signers, &clock),
Ok(())
);
// verify lockup check
meta.lockup.epoch = 1;
assert_eq!(
meta.authorize(&staker, StakeAuthorize::Staker, &signers, &clock),
meta.authorize_withdraw(&staker, &signers, &clock),
Err(StakeError::LockupInForce.into())
);
// verify lockup check defeated by custodian
signers.insert(custodian);
assert_eq!(
meta.authorize(&staker, StakeAuthorize::Staker, &signers, &clock),
Ok(())
);
assert_eq!(meta.authorize_withdraw(&staker, &signers, &clock), Ok(()));
// verify lock expiry
signers.remove(&custodian);
clock.epoch = 1;
assert_eq!(
meta.authorize(&staker, StakeAuthorize::Staker, &signers, &clock),
Ok(())
);
assert_eq!(meta.authorize_withdraw(&staker, &signers, &clock), Ok(()));
}
#[test]
@@ -1606,7 +1607,7 @@ mod tests {
// wrong state, should fail
let stake_keyed_account = KeyedAccount::new(&stake_pubkey, false, &stake_account);
assert_eq!(
stake_keyed_account.set_lockup(&LockupArgs::default(), &HashSet::default(),),
stake_keyed_account.set_lockup(&LockupArgs::default(), &HashSet::default()),
Err(InstructionError::InvalidAccountData)
);
@@ -1625,7 +1626,7 @@ mod tests {
.unwrap();
assert_eq!(
stake_keyed_account.set_lockup(&LockupArgs::default(), &HashSet::default(),),
stake_keyed_account.set_lockup(&LockupArgs::default(), &HashSet::default()),
Err(InstructionError::MissingRequiredSignature)
);
@@ -2276,12 +2277,7 @@ mod tests {
let stake_keyed_account = KeyedAccount::new(&stake_pubkey, true, &stake_account);
let signers = vec![stake_pubkey].into_iter().collect();
assert_eq!(
stake_keyed_account.authorize(
&stake_pubkey,
StakeAuthorize::Staker,
&signers,
&Clock::default()
),
stake_keyed_account.authorize(&stake_pubkey, StakeAuthorize::Staker, &signers),
Err(InstructionError::InvalidAccountData)
);
}
@@ -2308,21 +2304,11 @@ mod tests {
let stake_pubkey0 = Pubkey::new_rand();
let signers = vec![stake_pubkey].into_iter().collect();
assert_eq!(
stake_keyed_account.authorize(
&stake_pubkey0,
StakeAuthorize::Staker,
&signers,
&Clock::default()
),
stake_keyed_account.authorize(&stake_pubkey0, StakeAuthorize::Staker, &signers),
Ok(())
);
assert_eq!(
stake_keyed_account.authorize(
&stake_pubkey0,
StakeAuthorize::Withdrawer,
&signers,
&Clock::default()
),
stake_keyed_account.authorize(&stake_pubkey0, StakeAuthorize::Withdrawer, &signers),
Ok(())
);
if let StakeState::Initialized(Meta { authorized, .. }) =
@@ -2337,12 +2323,7 @@ mod tests {
// A second authorization signed by the stake_keyed_account should fail
let stake_pubkey1 = Pubkey::new_rand();
assert_eq!(
stake_keyed_account.authorize(
&stake_pubkey1,
StakeAuthorize::Staker,
&signers,
&Clock::default()
),
stake_keyed_account.authorize(&stake_pubkey1, StakeAuthorize::Staker, &signers),
Err(InstructionError::MissingRequiredSignature)
);
@@ -2351,12 +2332,7 @@ mod tests {
// Test a second authorization by the newly authorized pubkey
let stake_pubkey2 = Pubkey::new_rand();
assert_eq!(
stake_keyed_account.authorize(
&stake_pubkey2,
StakeAuthorize::Staker,
&signers0,
&Clock::default()
),
stake_keyed_account.authorize(&stake_pubkey2, StakeAuthorize::Staker, &signers0),
Ok(())
);
if let StakeState::Initialized(Meta { authorized, .. }) =
@@ -2366,12 +2342,7 @@ mod tests {
}
assert_eq!(
stake_keyed_account.authorize(
&stake_pubkey2,
StakeAuthorize::Withdrawer,
&signers0,
&Clock::default()
),
stake_keyed_account.authorize(&stake_pubkey2, StakeAuthorize::Withdrawer, &signers0),
Ok(())
);
if let StakeState::Initialized(Meta { authorized, .. }) =
@@ -2426,12 +2397,7 @@ mod tests {
let stake_pubkey = Pubkey::new_rand();
let signers = vec![withdrawer_pubkey].into_iter().collect();
assert_eq!(
stake_keyed_account.authorize(
&stake_pubkey,
StakeAuthorize::Staker,
&signers,
&Clock::default()
),
stake_keyed_account.authorize(&stake_pubkey, StakeAuthorize::Staker, &signers),
Ok(())
);
@@ -2439,48 +2405,28 @@ mod tests {
let mallory_pubkey = Pubkey::new_rand();
let signers = vec![stake_pubkey].into_iter().collect();
assert_eq!(
stake_keyed_account.authorize(
&mallory_pubkey,
StakeAuthorize::Staker,
&signers,
&Clock::default()
),
stake_keyed_account.authorize(&mallory_pubkey, StakeAuthorize::Staker, &signers),
Ok(())
);
// Verify the original staker no longer has access.
let new_stake_pubkey = Pubkey::new_rand();
assert_eq!(
stake_keyed_account.authorize(
&new_stake_pubkey,
StakeAuthorize::Staker,
&signers,
&Clock::default()
),
stake_keyed_account.authorize(&new_stake_pubkey, StakeAuthorize::Staker, &signers),
Err(InstructionError::MissingRequiredSignature)
);
// Verify the withdrawer (pulled from cold storage) can save the day.
let signers = vec![withdrawer_pubkey].into_iter().collect();
assert_eq!(
stake_keyed_account.authorize(
&new_stake_pubkey,
StakeAuthorize::Withdrawer,
&signers,
&Clock::default()
),
stake_keyed_account.authorize(&new_stake_pubkey, StakeAuthorize::Withdrawer, &signers),
Ok(())
);
// Attack! Verify the staker cannot be used to authorize a withdraw.
let signers = vec![new_stake_pubkey].into_iter().collect();
assert_eq!(
stake_keyed_account.authorize(
&mallory_pubkey,
StakeAuthorize::Withdrawer,
&signers,
&Clock::default()
),
stake_keyed_account.authorize(&mallory_pubkey, StakeAuthorize::Withdrawer, &signers),
Ok(())
);
}
@@ -3021,12 +2967,7 @@ mod tests {
let new_staker_pubkey = Pubkey::new_rand();
assert_eq!(
stake_keyed_account.authorize(
&new_staker_pubkey,
StakeAuthorize::Staker,
&signers,
&clock,
),
stake_keyed_account.authorize(&new_staker_pubkey, StakeAuthorize::Staker, &signers),
Ok(())
);
let authorized =

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-storage-program"
version = "1.0.15"
version = "1.0.19"
description = "Solana Storage program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -16,8 +16,8 @@ num-derive = "0.3"
num-traits = "0.2"
serde = "1.0.104"
serde_derive = "1.0.103"
solana-logger = { path = "../../logger", version = "1.0.15" }
solana-sdk = { path = "../../sdk", version = "1.0.15" }
solana-logger = { path = "../../logger", version = "1.0.19" }
solana-sdk = { path = "../../sdk", version = "1.0.19" }
[dev-dependencies]
assert_matches = "1.3.0"
@@ -25,3 +25,6 @@ assert_matches = "1.3.0"
[lib]
crate-type = ["lib", "cdylib"]
name = "solana_storage_program"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-vest-program"
version = "1.0.15"
version = "1.0.19"
description = "Solana Vest program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -15,13 +15,16 @@ num-derive = "0.2"
num-traits = "0.2"
serde = "1.0.104"
serde_derive = "1.0.103"
solana-sdk = { path = "../../sdk", version = "1.0.15" }
solana-config-program = { path = "../config", version = "1.0.15" }
solana-sdk = { path = "../../sdk", version = "1.0.19" }
solana-config-program = { path = "../config", version = "1.0.19" }
thiserror = "1.0"
[dev-dependencies]
solana-runtime = { path = "../../runtime", version = "1.0.15" }
solana-runtime = { path = "../../runtime", version = "1.0.19" }
[lib]
crate-type = ["lib"]
name = "solana_vest_program"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

Some files were not shown because too many files have changed in this diff Show More