Compare commits
46 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
b2a5cf57ad | ||
|
33c51ee75d | ||
|
d8aa107fae | ||
|
82e02d0734 | ||
|
dae59bb3e1 | ||
|
e0e7fc8e52 | ||
|
9abc84c583 | ||
|
db6540772c | ||
|
840ebfe625 | ||
|
953282dbf4 | ||
|
788d1199ac | ||
|
f6a8f718a8 | ||
|
f225bf6f01 | ||
|
b5f03a380b | ||
|
140c75f613 | ||
|
6a59f67fdc | ||
|
5943747001 | ||
|
f26f18d29d | ||
|
9b58d72f52 | ||
|
0c885d6a04 | ||
|
70b51c0a5a | ||
|
560660ae11 | ||
|
5436855b67 | ||
|
7351e5ed2c | ||
|
7ee993fadf | ||
|
9bf459e82f | ||
|
545090ff17 | ||
|
bd8074507f | ||
|
cfc7b22c4c | ||
|
5f1c637508 | ||
|
d888e0a6d7 | ||
|
10e808e1bd | ||
|
d9b03ca38b | ||
|
608d75b348 | ||
|
cee3cee4ef | ||
|
09e51323f0 | ||
|
da6f702129 | ||
|
02a83e7c6e | ||
|
83263e1737 | ||
|
1f7ac22b60 | ||
|
747debae56 | ||
|
00b4186469 | ||
|
b087dabf4f | ||
|
e00eb0a069 | ||
|
d4e49ffd06 | ||
|
0f34a190ea |
704
Cargo.lock
generated
704
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -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"]
|
||||
|
@@ -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
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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
|
||||
|
@@ -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"
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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());
|
||||
}
|
||||
}
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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();
|
||||
|
@@ -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.
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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
|
||||
|
163
core/src/rpc.rs
163
core/src/rpc.rs
@@ -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()
|
||||
|
@@ -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();
|
||||
|
@@ -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");
|
||||
}
|
||||
}
|
||||
|
@@ -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();
|
||||
|
@@ -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();
|
||||
|
@@ -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,
|
||||
},
|
||||
);
|
||||
|
||||
|
@@ -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"]
|
||||
|
@@ -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 |
@@ -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
|
||||
|
@@ -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:
|
||||
|
@@ -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
|
||||
|
||||

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

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

|
||||
|
||||
***
|
||||
|
||||

|
||||
|
||||
##### 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
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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![];
|
||||
|
@@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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,
|
||||
}
|
||||
|
||||
|
@@ -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)
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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))
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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"]
|
||||
|
@@ -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)?;
|
||||
|
||||
|
@@ -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 =
|
||||
|
@@ -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"]
|
||||
|
@@ -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
Reference in New Issue
Block a user