From 1cc66f0cd7ace46d174a277718f243b453341fa9 Mon Sep 17 00:00:00 2001 From: sakridge Date: Mon, 16 Mar 2020 14:29:44 -0700 Subject: [PATCH] Add Accounts hash consistency halting (#8772) (#8889) * Accounts hash consistency halting * Add option to inject account hash faults for testing. Enable option in local cluster test to see that node halts. --- Cargo.lock | 670 +++++++++++++-------------- core/src/accounts_hash_verifier.rs | 196 ++++++++ core/src/cluster_info.rs | 56 ++- core/src/crds_value.rs | 45 +- core/src/lib.rs | 1 + core/src/replay_stage.rs | 14 +- core/src/tvu.rs | 44 +- core/src/validator.rs | 18 +- local-cluster/tests/local_cluster.rs | 89 ++++ multinode-demo/validator.sh | 3 + validator/src/main.rs | 11 + 11 files changed, 763 insertions(+), 384 deletions(-) create mode 100644 core/src/accounts_hash_verifier.rs diff --git a/Cargo.lock b/Cargo.lock index 3702a16bed..8226dcad53 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -314,7 +314,7 @@ dependencies = [ [[package]] name = "btc_spv_bin" -version = "1.0.7" +version = "1.0.8" dependencies = [ "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3582,22 +3582,22 @@ dependencies = [ [[package]] name = "solana-archiver" -version = "1.0.7" +version = "1.0.8" dependencies = [ "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "console 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-archiver-lib 1.0.7", - "solana-clap-utils 1.0.7", - "solana-core 1.0.7", - "solana-logger 1.0.7", - "solana-metrics 1.0.7", - "solana-net-utils 1.0.7", - "solana-sdk 1.0.7", + "solana-archiver-lib 1.0.8", + "solana-clap-utils 1.0.8", + "solana-core 1.0.8", + "solana-logger 1.0.8", + "solana-metrics 1.0.8", + "solana-net-utils 1.0.8", + "solana-sdk 1.0.8", ] [[package]] name = "solana-archiver-lib" -version = "1.0.7" +version = "1.0.8" dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3609,55 +3609,55 @@ dependencies = [ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-archiver-utils 1.0.7", - "solana-chacha 1.0.7", - "solana-chacha-sys 1.0.7", - "solana-client 1.0.7", - "solana-core 1.0.7", - "solana-ledger 1.0.7", - "solana-logger 1.0.7", - "solana-metrics 1.0.7", - "solana-net-utils 1.0.7", - "solana-perf 1.0.7", - "solana-sdk 1.0.7", - "solana-storage-program 1.0.7", + "solana-archiver-utils 1.0.8", + "solana-chacha 1.0.8", + "solana-chacha-sys 1.0.8", + "solana-client 1.0.8", + "solana-core 1.0.8", + "solana-ledger 1.0.8", + "solana-logger 1.0.8", + "solana-metrics 1.0.8", + "solana-net-utils 1.0.8", + "solana-perf 1.0.8", + "solana-sdk 1.0.8", + "solana-storage-program 1.0.8", "thiserror 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-archiver-utils" -version = "1.0.7" +version = "1.0.8" dependencies = [ "hex 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-chacha 1.0.7", - "solana-chacha-sys 1.0.7", - "solana-ledger 1.0.7", - "solana-logger 1.0.7", - "solana-perf 1.0.7", - "solana-sdk 1.0.7", + "solana-chacha 1.0.8", + "solana-chacha-sys 1.0.8", + "solana-ledger 1.0.8", + "solana-logger 1.0.8", + "solana-perf 1.0.8", + "solana-sdk 1.0.8", ] [[package]] name = "solana-banking-bench" -version = "1.0.7" +version = "1.0.8" dependencies = [ "crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-core 1.0.7", - "solana-ledger 1.0.7", - "solana-logger 1.0.7", - "solana-measure 1.0.7", - "solana-runtime 1.0.7", - "solana-sdk 1.0.7", + "solana-core 1.0.8", + "solana-ledger 1.0.8", + "solana-logger 1.0.8", + "solana-measure 1.0.8", + "solana-runtime 1.0.8", + "solana-sdk 1.0.8", ] [[package]] name = "solana-bench-exchange" -version = "1.0.7" +version = "1.0.8" dependencies = [ "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3668,34 +3668,34 @@ dependencies = [ "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-clap-utils 1.0.7", - "solana-client 1.0.7", - "solana-core 1.0.7", - "solana-exchange-program 1.0.7", - "solana-faucet 1.0.7", - "solana-genesis 1.0.7", - "solana-local-cluster 1.0.7", - "solana-logger 1.0.7", - "solana-metrics 1.0.7", - "solana-net-utils 1.0.7", - "solana-runtime 1.0.7", - "solana-sdk 1.0.7", + "solana-clap-utils 1.0.8", + "solana-client 1.0.8", + "solana-core 1.0.8", + "solana-exchange-program 1.0.8", + "solana-faucet 1.0.8", + "solana-genesis 1.0.8", + "solana-local-cluster 1.0.8", + "solana-logger 1.0.8", + "solana-metrics 1.0.8", + "solana-net-utils 1.0.8", + "solana-runtime 1.0.8", + "solana-sdk 1.0.8", ] [[package]] name = "solana-bench-streamer" -version = "1.0.7" +version = "1.0.8" dependencies = [ "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-clap-utils 1.0.7", - "solana-core 1.0.7", - "solana-logger 1.0.7", - "solana-net-utils 1.0.7", + "solana-clap-utils 1.0.8", + "solana-core 1.0.8", + "solana-logger 1.0.8", + "solana-net-utils 1.0.8", ] [[package]] name = "solana-bench-tps" -version = "1.0.7" +version = "1.0.8" dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3705,25 +3705,25 @@ dependencies = [ "serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)", "serial_test 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "serial_test_derive 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-clap-utils 1.0.7", - "solana-client 1.0.7", - "solana-core 1.0.7", - "solana-faucet 1.0.7", - "solana-genesis 1.0.7", - "solana-librapay 1.0.7", - "solana-local-cluster 1.0.7", - "solana-logger 1.0.7", - "solana-measure 1.0.7", - "solana-metrics 1.0.7", - "solana-move-loader-program 1.0.7", - "solana-net-utils 1.0.7", - "solana-runtime 1.0.7", - "solana-sdk 1.0.7", + "solana-clap-utils 1.0.8", + "solana-client 1.0.8", + "solana-core 1.0.8", + "solana-faucet 1.0.8", + "solana-genesis 1.0.8", + "solana-librapay 1.0.8", + "solana-local-cluster 1.0.8", + "solana-logger 1.0.8", + "solana-measure 1.0.8", + "solana-metrics 1.0.8", + "solana-move-loader-program 1.0.8", + "solana-net-utils 1.0.8", + "solana-runtime 1.0.8", + "solana-sdk 1.0.8", ] [[package]] name = "solana-bpf-loader-program" -version = "1.0.7" +version = "1.0.8" dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3731,15 +3731,15 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num-derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-logger 1.0.7", - "solana-sdk 1.0.7", + "solana-logger 1.0.8", + "solana-sdk 1.0.8", "solana_rbpf 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-btc-spv-program" -version = "1.0.7" +version = "1.0.8" dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3748,12 +3748,12 @@ dependencies = [ "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk 1.0.7", + "solana-sdk 1.0.8", ] [[package]] name = "solana-budget-program" -version = "1.0.7" +version = "1.0.8" dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3762,56 +3762,56 @@ dependencies = [ "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-runtime 1.0.7", - "solana-sdk 1.0.7", + "solana-runtime 1.0.8", + "solana-sdk 1.0.8", "thiserror 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-chacha" -version = "1.0.7" +version = "1.0.8" dependencies = [ "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-chacha-sys 1.0.7", - "solana-ledger 1.0.7", - "solana-logger 1.0.7", - "solana-perf 1.0.7", - "solana-sdk 1.0.7", + "solana-chacha-sys 1.0.8", + "solana-ledger 1.0.8", + "solana-logger 1.0.8", + "solana-perf 1.0.8", + "solana-sdk 1.0.8", ] [[package]] name = "solana-chacha-cuda" -version = "1.0.7" +version = "1.0.8" dependencies = [ "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-archiver-utils 1.0.7", - "solana-chacha 1.0.7", - "solana-ledger 1.0.7", - "solana-logger 1.0.7", - "solana-perf 1.0.7", - "solana-sdk 1.0.7", + "solana-archiver-utils 1.0.8", + "solana-chacha 1.0.8", + "solana-ledger 1.0.8", + "solana-logger 1.0.8", + "solana-perf 1.0.8", + "solana-sdk 1.0.8", ] [[package]] name = "solana-chacha-sys" -version = "1.0.7" +version = "1.0.8" dependencies = [ "cc 1.0.49 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-clap-utils" -version = "1.0.7" +version = "1.0.8" dependencies = [ "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "rpassword 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-remote-wallet 1.0.7", - "solana-sdk 1.0.7", + "solana-remote-wallet 1.0.8", + "solana-sdk 1.0.8", "thiserror 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-bip39 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3819,7 +3819,7 @@ dependencies = [ [[package]] name = "solana-cli" -version = "1.0.7" +version = "1.0.8" dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3838,22 +3838,22 @@ dependencies = [ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-budget-program 1.0.7", - "solana-clap-utils 1.0.7", - "solana-cli-config 1.0.7", - "solana-client 1.0.7", - "solana-config-program 1.0.7", - "solana-core 1.0.7", - "solana-faucet 1.0.7", - "solana-logger 1.0.7", - "solana-net-utils 1.0.7", - "solana-remote-wallet 1.0.7", - "solana-runtime 1.0.7", - "solana-sdk 1.0.7", - "solana-stake-program 1.0.7", - "solana-storage-program 1.0.7", - "solana-vote-program 1.0.7", - "solana-vote-signer 1.0.7", + "solana-budget-program 1.0.8", + "solana-clap-utils 1.0.8", + "solana-cli-config 1.0.8", + "solana-client 1.0.8", + "solana-config-program 1.0.8", + "solana-core 1.0.8", + "solana-faucet 1.0.8", + "solana-logger 1.0.8", + "solana-net-utils 1.0.8", + "solana-remote-wallet 1.0.8", + "solana-runtime 1.0.8", + "solana-sdk 1.0.8", + "solana-stake-program 1.0.8", + "solana-storage-program 1.0.8", + "solana-vote-program 1.0.8", + "solana-vote-signer 1.0.8", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "titlecase 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3862,7 +3862,7 @@ dependencies = [ [[package]] name = "solana-cli-config" -version = "1.0.7" +version = "1.0.8" dependencies = [ "dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3874,7 +3874,7 @@ dependencies = [ [[package]] name = "solana-client" -version = "1.0.7" +version = "1.0.8" dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3887,9 +3887,9 @@ dependencies = [ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-logger 1.0.7", - "solana-net-utils 1.0.7", - "solana-sdk 1.0.7", + "solana-logger 1.0.8", + "solana-net-utils 1.0.8", + "solana-sdk 1.0.8", "thiserror 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "tungstenite 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3897,20 +3897,20 @@ dependencies = [ [[package]] name = "solana-config-program" -version = "1.0.7" +version = "1.0.8" dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-logger 1.0.7", - "solana-sdk 1.0.7", + "solana-logger 1.0.8", + "solana-sdk 1.0.8", ] [[package]] name = "solana-core" -version = "1.0.7" +version = "1.0.8" dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3944,26 +3944,26 @@ dependencies = [ "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "serial_test 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "serial_test_derive 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-budget-program 1.0.7", - "solana-chacha-cuda 1.0.7", - "solana-clap-utils 1.0.7", - "solana-client 1.0.7", - "solana-faucet 1.0.7", - "solana-ledger 1.0.7", - "solana-logger 1.0.7", - "solana-measure 1.0.7", - "solana-merkle-tree 1.0.7", - "solana-metrics 1.0.7", - "solana-net-utils 1.0.7", - "solana-perf 1.0.7", - "solana-rayon-threadlimit 1.0.7", - "solana-runtime 1.0.7", - "solana-sdk 1.0.7", - "solana-stake-program 1.0.7", - "solana-storage-program 1.0.7", - "solana-sys-tuner 1.0.7", - "solana-vote-program 1.0.7", - "solana-vote-signer 1.0.7", + "solana-budget-program 1.0.8", + "solana-chacha-cuda 1.0.8", + "solana-clap-utils 1.0.8", + "solana-client 1.0.8", + "solana-faucet 1.0.8", + "solana-ledger 1.0.8", + "solana-logger 1.0.8", + "solana-measure 1.0.8", + "solana-merkle-tree 1.0.8", + "solana-metrics 1.0.8", + "solana-net-utils 1.0.8", + "solana-perf 1.0.8", + "solana-rayon-threadlimit 1.0.8", + "solana-runtime 1.0.8", + "solana-sdk 1.0.8", + "solana-stake-program 1.0.8", + "solana-storage-program 1.0.8", + "solana-sys-tuner 1.0.8", + "solana-vote-program 1.0.8", + "solana-vote-signer 1.0.8", "sys-info 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", "systemstat 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3977,7 +3977,7 @@ dependencies = [ [[package]] name = "solana-crate-features" -version = "1.0.7" +version = "1.0.8" dependencies = [ "backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4000,7 +4000,7 @@ dependencies = [ [[package]] name = "solana-exchange-program" -version = "1.0.7" +version = "1.0.8" dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4008,24 +4008,24 @@ dependencies = [ "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-logger 1.0.7", - "solana-metrics 1.0.7", - "solana-runtime 1.0.7", - "solana-sdk 1.0.7", + "solana-logger 1.0.8", + "solana-metrics 1.0.8", + "solana-runtime 1.0.8", + "solana-sdk 1.0.8", "thiserror 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-failure-program" -version = "1.0.7" +version = "1.0.8" dependencies = [ - "solana-runtime 1.0.7", - "solana-sdk 1.0.7", + "solana-runtime 1.0.8", + "solana-sdk 1.0.8", ] [[package]] name = "solana-faucet" -version = "1.0.7" +version = "1.0.8" dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4034,17 +4034,17 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-clap-utils 1.0.7", - "solana-logger 1.0.7", - "solana-metrics 1.0.7", - "solana-sdk 1.0.7", + "solana-clap-utils 1.0.8", + "solana-logger 1.0.8", + "solana-metrics 1.0.8", + "solana-sdk 1.0.8", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-genesis" -version = "1.0.7" +version = "1.0.8" dependencies = [ "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4052,49 +4052,49 @@ dependencies = [ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-clap-utils 1.0.7", - "solana-genesis-programs 1.0.7", - "solana-ledger 1.0.7", - "solana-sdk 1.0.7", - "solana-stake-program 1.0.7", - "solana-storage-program 1.0.7", - "solana-vote-program 1.0.7", + "solana-clap-utils 1.0.8", + "solana-genesis-programs 1.0.8", + "solana-ledger 1.0.8", + "solana-sdk 1.0.8", + "solana-stake-program 1.0.8", + "solana-storage-program 1.0.8", + "solana-vote-program 1.0.8", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-genesis-programs" -version = "1.0.7" +version = "1.0.8" dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-bpf-loader-program 1.0.7", - "solana-budget-program 1.0.7", - "solana-config-program 1.0.7", - "solana-exchange-program 1.0.7", - "solana-runtime 1.0.7", - "solana-sdk 1.0.7", - "solana-stake-program 1.0.7", - "solana-storage-program 1.0.7", - "solana-vest-program 1.0.7", - "solana-vote-program 1.0.7", + "solana-bpf-loader-program 1.0.8", + "solana-budget-program 1.0.8", + "solana-config-program 1.0.8", + "solana-exchange-program 1.0.8", + "solana-runtime 1.0.8", + "solana-sdk 1.0.8", + "solana-stake-program 1.0.8", + "solana-storage-program 1.0.8", + "solana-vest-program 1.0.8", + "solana-vote-program 1.0.8", ] [[package]] name = "solana-gossip" -version = "1.0.7" +version = "1.0.8" dependencies = [ "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-clap-utils 1.0.7", - "solana-client 1.0.7", - "solana-core 1.0.7", - "solana-logger 1.0.7", - "solana-net-utils 1.0.7", - "solana-sdk 1.0.7", + "solana-clap-utils 1.0.8", + "solana-client 1.0.8", + "solana-core 1.0.8", + "solana-logger 1.0.8", + "solana-net-utils 1.0.8", + "solana-sdk 1.0.8", ] [[package]] name = "solana-install" -version = "1.0.7" +version = "1.0.8" dependencies = [ "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4112,11 +4112,11 @@ dependencies = [ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-clap-utils 1.0.7", - "solana-client 1.0.7", - "solana-config-program 1.0.7", - "solana-logger 1.0.7", - "solana-sdk 1.0.7", + "solana-clap-utils 1.0.8", + "solana-client 1.0.8", + "solana-config-program 1.0.8", + "solana-logger 1.0.8", + "solana-sdk 1.0.8", "tar 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4126,22 +4126,22 @@ dependencies = [ [[package]] name = "solana-keygen" -version = "1.0.7" +version = "1.0.8" dependencies = [ "bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-clap-utils 1.0.7", - "solana-cli-config 1.0.7", - "solana-remote-wallet 1.0.7", - "solana-sdk 1.0.7", + "solana-clap-utils 1.0.8", + "solana-cli-config 1.0.8", + "solana-remote-wallet 1.0.8", + "solana-sdk 1.0.8", "tiny-bip39 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-ledger" -version = "1.0.7" +version = "1.0.8" dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4165,20 +4165,20 @@ dependencies = [ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_bytes 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-budget-program 1.0.7", - "solana-client 1.0.7", - "solana-genesis-programs 1.0.7", - "solana-logger 1.0.7", - "solana-measure 1.0.7", - "solana-merkle-tree 1.0.7", - "solana-metrics 1.0.7", - "solana-perf 1.0.7", - "solana-rayon-threadlimit 1.0.7", + "solana-budget-program 1.0.8", + "solana-client 1.0.8", + "solana-genesis-programs 1.0.8", + "solana-logger 1.0.8", + "solana-measure 1.0.8", + "solana-merkle-tree 1.0.8", + "solana-metrics 1.0.8", + "solana-perf 1.0.8", + "solana-rayon-threadlimit 1.0.8", "solana-reed-solomon-erasure 4.0.1-3 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-runtime 1.0.7", - "solana-sdk 1.0.7", - "solana-stake-program 1.0.7", - "solana-vote-program 1.0.7", + "solana-runtime 1.0.8", + "solana-sdk 1.0.8", + "solana-stake-program 1.0.8", + "solana-vote-program 1.0.8", "symlink 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "sys-info 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", "tar 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4188,7 +4188,7 @@ dependencies = [ [[package]] name = "solana-ledger-tool" -version = "1.0.7" +version = "1.0.8" dependencies = [ "assert_cmd 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4196,31 +4196,31 @@ dependencies = [ "histogram 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-clap-utils 1.0.7", - "solana-ledger 1.0.7", - "solana-logger 1.0.7", - "solana-runtime 1.0.7", - "solana-sdk 1.0.7", - "solana-vote-program 1.0.7", + "solana-clap-utils 1.0.8", + "solana-ledger 1.0.8", + "solana-logger 1.0.8", + "solana-runtime 1.0.8", + "solana-sdk 1.0.8", + "solana-vote-program 1.0.8", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-librapay" -version = "1.0.7" +version = "1.0.8" dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-logger 1.0.7", - "solana-move-loader-program 1.0.7", - "solana-runtime 1.0.7", - "solana-sdk 1.0.7", + "solana-logger 1.0.8", + "solana-move-loader-program 1.0.8", + "solana-runtime 1.0.8", + "solana-sdk 1.0.8", "solana_libra_types 0.0.1-sol4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-local-cluster" -version = "1.0.7" +version = "1.0.8" dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4228,40 +4228,40 @@ dependencies = [ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "serial_test 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "serial_test_derive 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-archiver-lib 1.0.7", - "solana-client 1.0.7", - "solana-config-program 1.0.7", - "solana-core 1.0.7", - "solana-exchange-program 1.0.7", - "solana-faucet 1.0.7", - "solana-genesis-programs 1.0.7", - "solana-ledger 1.0.7", - "solana-logger 1.0.7", - "solana-rayon-threadlimit 1.0.7", - "solana-runtime 1.0.7", - "solana-sdk 1.0.7", - "solana-stake-program 1.0.7", - "solana-storage-program 1.0.7", - "solana-vest-program 1.0.7", - "solana-vote-program 1.0.7", + "solana-archiver-lib 1.0.8", + "solana-client 1.0.8", + "solana-config-program 1.0.8", + "solana-core 1.0.8", + "solana-exchange-program 1.0.8", + "solana-faucet 1.0.8", + "solana-genesis-programs 1.0.8", + "solana-ledger 1.0.8", + "solana-logger 1.0.8", + "solana-rayon-threadlimit 1.0.8", + "solana-runtime 1.0.8", + "solana-sdk 1.0.8", + "solana-stake-program 1.0.8", + "solana-storage-program 1.0.8", + "solana-vest-program 1.0.8", + "solana-vote-program 1.0.8", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-log-analyzer" -version = "1.0.7" +version = "1.0.8" dependencies = [ "byte-unit 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-clap-utils 1.0.7", - "solana-logger 1.0.7", + "solana-clap-utils 1.0.8", + "solana-logger 1.0.8", ] [[package]] name = "solana-logger" -version = "1.0.7" +version = "1.0.8" dependencies = [ "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4270,26 +4270,26 @@ dependencies = [ [[package]] name = "solana-measure" -version = "1.0.7" +version = "1.0.8" dependencies = [ "jemalloc-ctl 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "jemallocator 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-metrics 1.0.7", - "solana-sdk 1.0.7", + "solana-metrics 1.0.8", + "solana-sdk 1.0.8", ] [[package]] name = "solana-merkle-tree" -version = "1.0.7" +version = "1.0.8" dependencies = [ "hex 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk 1.0.7", + "solana-sdk 1.0.8", ] [[package]] name = "solana-metrics" -version = "1.0.7" +version = "1.0.8" dependencies = [ "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4298,13 +4298,13 @@ dependencies = [ "reqwest 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "serial_test 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "serial_test_derive 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk 1.0.7", + "solana-sdk 1.0.8", "sys-info 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-move-loader-program" -version = "1.0.7" +version = "1.0.8" dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4315,8 +4315,8 @@ dependencies = [ "serde_bytes 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-logger 1.0.7", - "solana-sdk 1.0.7", + "solana-logger 1.0.8", + "solana-sdk 1.0.8", "solana_libra_bytecode_verifier 0.0.1-sol4 (registry+https://github.com/rust-lang/crates.io-index)", "solana_libra_canonical_serialization 0.0.1-sol4 (registry+https://github.com/rust-lang/crates.io-index)", "solana_libra_compiler 0.0.1-sol4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4333,19 +4333,19 @@ dependencies = [ [[package]] name = "solana-net-shaper" -version = "1.0.7" +version = "1.0.8" dependencies = [ "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-clap-utils 1.0.7", - "solana-logger 1.0.7", + "solana-clap-utils 1.0.8", + "solana-logger 1.0.8", ] [[package]] name = "solana-net-utils" -version = "1.0.7" +version = "1.0.8" dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4356,36 +4356,36 @@ dependencies = [ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-clap-utils 1.0.7", - "solana-logger 1.0.7", + "solana-clap-utils 1.0.8", + "solana-logger 1.0.8", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-noop-program" -version = "1.0.7" +version = "1.0.8" dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-logger 1.0.7", - "solana-sdk 1.0.7", + "solana-logger 1.0.8", + "solana-sdk 1.0.8", ] [[package]] name = "solana-ownable" -version = "1.0.7" +version = "1.0.8" dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "num-derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-runtime 1.0.7", - "solana-sdk 1.0.7", + "solana-runtime 1.0.8", + "solana-sdk 1.0.8", "thiserror 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-perf" -version = "1.0.7" +version = "1.0.8" dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "dlopen 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4396,16 +4396,16 @@ dependencies = [ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-budget-program 1.0.7", - "solana-logger 1.0.7", - "solana-metrics 1.0.7", - "solana-rayon-threadlimit 1.0.7", - "solana-sdk 1.0.7", + "solana-budget-program 1.0.8", + "solana-logger 1.0.8", + "solana-metrics 1.0.8", + "solana-rayon-threadlimit 1.0.8", + "solana-sdk 1.0.8", ] [[package]] name = "solana-rayon-threadlimit" -version = "1.0.7" +version = "1.0.8" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "sys-info 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4423,7 +4423,7 @@ dependencies = [ [[package]] name = "solana-remote-wallet" -version = "1.0.7" +version = "1.0.8" dependencies = [ "base32 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "console 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4432,14 +4432,14 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk 1.0.7", + "solana-sdk 1.0.8", "thiserror 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-runtime" -version = "1.0.7" +version = "1.0.8" dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4458,16 +4458,16 @@ dependencies = [ "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-bpf-loader-program 1.0.7", - "solana-logger 1.0.7", - "solana-measure 1.0.7", - "solana-metrics 1.0.7", - "solana-noop-program 1.0.7", - "solana-rayon-threadlimit 1.0.7", - "solana-sdk 1.0.7", - "solana-stake-program 1.0.7", - "solana-storage-program 1.0.7", - "solana-vote-program 1.0.7", + "solana-bpf-loader-program 1.0.8", + "solana-logger 1.0.8", + "solana-measure 1.0.8", + "solana-metrics 1.0.8", + "solana-noop-program 1.0.8", + "solana-rayon-threadlimit 1.0.8", + "solana-sdk 1.0.8", + "solana-stake-program 1.0.8", + "solana-storage-program 1.0.8", + "solana-vote-program 1.0.8", "sys-info 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4475,7 +4475,7 @@ dependencies = [ [[package]] name = "solana-scripts" -version = "1.0.7" +version = "1.0.8" dependencies = [ "csv 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4483,7 +4483,7 @@ dependencies = [ [[package]] name = "solana-sdk" -version = "1.0.7" +version = "1.0.8" dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4508,16 +4508,16 @@ dependencies = [ "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-crate-features 1.0.7", - "solana-logger 1.0.7", - "solana-sdk-macro 1.0.7", + "solana-crate-features 1.0.8", + "solana-logger 1.0.8", + "solana-sdk-macro 1.0.8", "thiserror 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-bip39 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-sdk-c" -version = "1.0.7" +version = "1.0.8" dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4526,12 +4526,12 @@ dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk 1.0.7", + "solana-sdk 1.0.8", ] [[package]] name = "solana-sdk-macro" -version = "1.0.7" +version = "1.0.8" dependencies = [ "bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4541,7 +4541,7 @@ dependencies = [ [[package]] name = "solana-stake-program" -version = "1.0.7" +version = "1.0.8" dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4549,17 +4549,17 @@ dependencies = [ "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-config-program 1.0.7", - "solana-logger 1.0.7", - "solana-metrics 1.0.7", - "solana-sdk 1.0.7", - "solana-vote-program 1.0.7", + "solana-config-program 1.0.8", + "solana-logger 1.0.8", + "solana-metrics 1.0.8", + "solana-sdk 1.0.8", + "solana-vote-program 1.0.8", "thiserror 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-storage-program" -version = "1.0.7" +version = "1.0.8" dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4569,20 +4569,20 @@ dependencies = [ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-logger 1.0.7", - "solana-sdk 1.0.7", + "solana-logger 1.0.8", + "solana-sdk 1.0.8", ] [[package]] name = "solana-sys-tuner" -version = "1.0.7" +version = "1.0.8" dependencies = [ "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-clap-utils 1.0.7", - "solana-logger 1.0.7", + "solana-clap-utils 1.0.8", + "solana-logger 1.0.8", "sysctl 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "unix_socket2 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "users 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4590,15 +4590,15 @@ dependencies = [ [[package]] name = "solana-upload-perf" -version = "1.0.7" +version = "1.0.8" dependencies = [ "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-metrics 1.0.7", + "solana-metrics 1.0.8", ] [[package]] name = "solana-validator" -version = "1.0.7" +version = "1.0.8" dependencies = [ "bzip2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4610,25 +4610,25 @@ dependencies = [ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-clap-utils 1.0.7", - "solana-client 1.0.7", - "solana-core 1.0.7", - "solana-faucet 1.0.7", - "solana-ledger 1.0.7", - "solana-logger 1.0.7", - "solana-metrics 1.0.7", - "solana-net-utils 1.0.7", - "solana-perf 1.0.7", - "solana-runtime 1.0.7", - "solana-sdk 1.0.7", - "solana-vote-program 1.0.7", - "solana-vote-signer 1.0.7", + "solana-clap-utils 1.0.8", + "solana-client 1.0.8", + "solana-core 1.0.8", + "solana-faucet 1.0.8", + "solana-ledger 1.0.8", + "solana-logger 1.0.8", + "solana-metrics 1.0.8", + "solana-net-utils 1.0.8", + "solana-perf 1.0.8", + "solana-runtime 1.0.8", + "solana-sdk 1.0.8", + "solana-vote-program 1.0.8", + "solana-vote-signer 1.0.8", "tar 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-vest-program" -version = "1.0.7" +version = "1.0.8" dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4636,15 +4636,15 @@ dependencies = [ "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-config-program 1.0.7", - "solana-runtime 1.0.7", - "solana-sdk 1.0.7", + "solana-config-program 1.0.8", + "solana-runtime 1.0.8", + "solana-sdk 1.0.8", "thiserror 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-vote-program" -version = "1.0.7" +version = "1.0.8" dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4652,15 +4652,15 @@ dependencies = [ "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-logger 1.0.7", - "solana-metrics 1.0.7", - "solana-sdk 1.0.7", + "solana-logger 1.0.8", + "solana-metrics 1.0.8", + "solana-sdk 1.0.8", "thiserror 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-vote-signer" -version = "1.0.7" +version = "1.0.8" dependencies = [ "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4668,25 +4668,25 @@ dependencies = [ "jsonrpc-http-server 14.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-clap-utils 1.0.7", - "solana-metrics 1.0.7", - "solana-sdk 1.0.7", + "solana-clap-utils 1.0.8", + "solana-metrics 1.0.8", + "solana-sdk 1.0.8", ] [[package]] name = "solana-watchtower" -version = "1.0.7" +version = "1.0.8" dependencies = [ "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-clap-utils 1.0.7", - "solana-cli-config 1.0.7", - "solana-client 1.0.7", - "solana-logger 1.0.7", - "solana-metrics 1.0.7", - "solana-sdk 1.0.7", + "solana-clap-utils 1.0.8", + "solana-cli-config 1.0.8", + "solana-client 1.0.8", + "solana-logger 1.0.8", + "solana-metrics 1.0.8", + "solana-sdk 1.0.8", ] [[package]] diff --git a/core/src/accounts_hash_verifier.rs b/core/src/accounts_hash_verifier.rs new file mode 100644 index 0000000000..7824d4d414 --- /dev/null +++ b/core/src/accounts_hash_verifier.rs @@ -0,0 +1,196 @@ +// Service to verify accounts hashes with other trusted validator nodes. +// +// Each interval, publish the snapshat hash which is the full accounts state +// hash on gossip. Monitor gossip for messages from validators in the --trusted-validators +// set and halt the node if a mismatch is detected. + +use crate::cluster_info::ClusterInfo; +use solana_ledger::{ + snapshot_package::SnapshotPackage, snapshot_package::SnapshotPackageReceiver, + snapshot_package::SnapshotPackageSender, +}; +use solana_sdk::{clock::Slot, hash::Hash, pubkey::Pubkey}; +use std::collections::{HashMap, HashSet}; +use std::{ + sync::{ + atomic::{AtomicBool, Ordering}, + mpsc::RecvTimeoutError, + Arc, RwLock, + }, + thread::{self, Builder, JoinHandle}, + time::Duration, +}; + +pub struct AccountsHashVerifier { + t_accounts_hash_verifier: JoinHandle<()>, +} + +impl AccountsHashVerifier { + pub fn new( + snapshot_package_receiver: SnapshotPackageReceiver, + snapshot_package_sender: Option, + exit: &Arc, + cluster_info: &Arc>, + trusted_validators: Option>, + halt_on_trusted_validators_accounts_hash_mismatch: bool, + fault_injection_rate_slots: u64, + ) -> Self { + let exit = exit.clone(); + let cluster_info = cluster_info.clone(); + let t_accounts_hash_verifier = Builder::new() + .name("solana-accounts-hash".to_string()) + .spawn(move || { + let mut hashes = vec![]; + loop { + if exit.load(Ordering::Relaxed) { + break; + } + + match snapshot_package_receiver.recv_timeout(Duration::from_secs(1)) { + Ok(snapshot_package) => { + Self::process_snapshot( + snapshot_package, + &cluster_info, + &trusted_validators, + halt_on_trusted_validators_accounts_hash_mismatch, + &snapshot_package_sender, + &mut hashes, + &exit, + fault_injection_rate_slots, + ); + } + Err(RecvTimeoutError::Disconnected) => break, + Err(RecvTimeoutError::Timeout) => (), + } + } + }) + .unwrap(); + Self { + t_accounts_hash_verifier, + } + } + + fn process_snapshot( + snapshot_package: SnapshotPackage, + cluster_info: &Arc>, + trusted_validators: &Option>, + halt_on_trusted_validator_accounts_hash_mismatch: bool, + snapshot_package_sender: &Option, + hashes: &mut Vec<(Slot, Hash)>, + exit: &Arc, + fault_injection_rate_slots: u64, + ) { + if fault_injection_rate_slots != 0 + && snapshot_package.root % fault_injection_rate_slots == 0 + { + // For testing, publish an invalid hash to gossip. + use rand::{thread_rng, Rng}; + use solana_sdk::hash::extend_and_hash; + warn!("inserting fault at slot: {}", snapshot_package.root); + let rand = thread_rng().gen_range(0, 10); + let hash = extend_and_hash(&snapshot_package.hash, &[rand]); + hashes.push((snapshot_package.root, hash)); + } else { + hashes.push((snapshot_package.root, snapshot_package.hash)); + } + + if halt_on_trusted_validator_accounts_hash_mismatch { + let mut slot_to_hash = HashMap::new(); + for (slot, hash) in hashes.iter() { + slot_to_hash.insert(*slot, *hash); + } + if Self::should_halt(&cluster_info, trusted_validators, &mut slot_to_hash) { + exit.store(true, Ordering::Relaxed); + } + } + if let Some(sender) = snapshot_package_sender.as_ref() { + if sender.send(snapshot_package).is_err() {} + } + + cluster_info + .write() + .unwrap() + .push_accounts_hashes(hashes.clone()); + } + + fn should_halt( + cluster_info: &Arc>, + trusted_validators: &Option>, + slot_to_hash: &mut HashMap, + ) -> bool { + if let Some(trusted_validators) = trusted_validators.as_ref() { + for trusted_validator in trusted_validators { + let cluster_info_r = cluster_info.read().unwrap(); + if let Some(accounts_hashes) = + cluster_info_r.get_accounts_hash_for_node(trusted_validator) + { + for (slot, hash) in accounts_hashes { + if let Some(reference_hash) = slot_to_hash.get(slot) { + if *hash != *reference_hash { + error!("Trusted validator {} produced conflicting hashes for slot: {} ({} != {})", + trusted_validator, + slot, + hash, + reference_hash, + ); + + return true; + } + } else { + slot_to_hash.insert(*slot, *hash); + } + } + } + } + } + false + } + + pub fn join(self) -> thread::Result<()> { + self.t_accounts_hash_verifier.join() + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::cluster_info::make_accounts_hashes_message; + use crate::contact_info::ContactInfo; + use solana_sdk::{ + hash::hash, + signature::{Keypair, Signer}, + }; + + #[test] + fn test_should_halt() { + let keypair = Keypair::new(); + + let contact_info = ContactInfo::new_localhost(&keypair.pubkey(), 0); + let cluster_info = ClusterInfo::new_with_invalid_keypair(contact_info); + let cluster_info = Arc::new(RwLock::new(cluster_info)); + + let mut trusted_validators = HashSet::new(); + let mut slot_to_hash = HashMap::new(); + assert!(!AccountsHashVerifier::should_halt( + &cluster_info, + &Some(trusted_validators.clone()), + &mut slot_to_hash, + )); + + let validator1 = Keypair::new(); + let hash1 = hash(&[1]); + let hash2 = hash(&[2]); + { + let message = make_accounts_hashes_message(&validator1, vec![(0, hash1)]).unwrap(); + let mut cluster_info_w = cluster_info.write().unwrap(); + cluster_info_w.push_message(message); + } + slot_to_hash.insert(0, hash2); + trusted_validators.insert(validator1.pubkey()); + assert!(AccountsHashVerifier::should_halt( + &cluster_info, + &Some(trusted_validators.clone()), + &mut slot_to_hash, + )); + } +} diff --git a/core/src/cluster_info.rs b/core/src/cluster_info.rs index d29e7d4d4c..150aeaa5c3 100644 --- a/core/src/cluster_info.rs +++ b/core/src/cluster_info.rs @@ -48,7 +48,7 @@ use solana_sdk::timing::duration_as_s; use solana_sdk::{ clock::{Slot, DEFAULT_MS_PER_SLOT}, pubkey::Pubkey, - signature::{Keypair, Signable, Signature}, + signature::{Keypair, Signable, Signature, Signer}, timing::{duration_as_ms, timestamp}, transaction::Transaction, }; @@ -180,6 +180,14 @@ struct PullData { pub filter: CrdsFilter, } +pub fn make_accounts_hashes_message( + keypair: &Keypair, + accounts_hashes: Vec<(Slot, Hash)>, +) -> Option { + let message = CrdsData::AccountsHashes(SnapshotHash::new(keypair.pubkey(), accounts_hashes)); + Some(CrdsValue::new_signed(message, keypair)) +} + // TODO These messages should go through the gpu pipeline for spam filtering #[derive(Serialize, Deserialize, Debug)] #[allow(clippy::large_enum_variant)] @@ -443,22 +451,36 @@ impl ClusterInfo { .process_push_message(&self.id(), vec![entry], now); } - pub fn push_snapshot_hashes(&mut self, snapshot_hashes: Vec<(Slot, Hash)>) { - if snapshot_hashes.len() > MAX_SNAPSHOT_HASHES { + pub fn push_message(&mut self, message: CrdsValue) { + let now = message.wallclock(); + let id = message.pubkey(); + self.gossip.process_push_message(&id, vec![message], now); + } + + pub fn push_accounts_hashes(&mut self, accounts_hashes: Vec<(Slot, Hash)>) { + if accounts_hashes.len() > MAX_SNAPSHOT_HASHES { warn!( - "snapshot_hashes too large, ignored: {}", - snapshot_hashes.len() + "accounts hashes too large, ignored: {}", + accounts_hashes.len(), ); return; } - let now = timestamp(); - let entry = CrdsValue::new_signed( - CrdsData::SnapshotHash(SnapshotHash::new(self.id(), snapshot_hashes, now)), - &self.keypair, - ); - self.gossip - .process_push_message(&self.id(), vec![entry], now); + let message = CrdsData::AccountsHashes(SnapshotHash::new(self.id(), accounts_hashes)); + self.push_message(CrdsValue::new_signed(message, &self.keypair)); + } + + pub fn push_snapshot_hashes(&mut self, snapshot_hashes: Vec<(Slot, Hash)>) { + if snapshot_hashes.len() > MAX_SNAPSHOT_HASHES { + warn!( + "snapshot hashes too large, ignored: {}", + snapshot_hashes.len(), + ); + return; + } + + let message = CrdsData::SnapshotHashes(SnapshotHash::new(self.id(), snapshot_hashes)); + self.push_message(CrdsValue::new_signed(message, &self.keypair)); } pub fn push_vote(&mut self, tower_index: usize, vote: Transaction) { @@ -518,11 +540,19 @@ impl ClusterInfo { .collect() } + pub fn get_accounts_hash_for_node(&self, pubkey: &Pubkey) -> Option<&Vec<(Slot, Hash)>> { + self.gossip + .crds + .table + .get(&CrdsValueLabel::AccountsHashes(*pubkey)) + .map(|x| &x.value.accounts_hash().unwrap().hashes) + } + pub fn get_snapshot_hash_for_node(&self, pubkey: &Pubkey) -> Option<&Vec<(Slot, Hash)>> { self.gossip .crds .table - .get(&CrdsValueLabel::SnapshotHash(*pubkey)) + .get(&CrdsValueLabel::SnapshotHashes(*pubkey)) .map(|x| &x.value.snapshot_hash().unwrap().hashes) } diff --git a/core/src/crds_value.rs b/core/src/crds_value.rs index 098db8729c..7c8161b931 100644 --- a/core/src/crds_value.rs +++ b/core/src/crds_value.rs @@ -1,5 +1,6 @@ use crate::contact_info::ContactInfo; use bincode::{serialize, serialized_size}; +use solana_sdk::timing::timestamp; use solana_sdk::{ clock::Slot, hash::Hash, @@ -62,7 +63,8 @@ pub enum CrdsData { ContactInfo(ContactInfo), Vote(VoteIndex, Vote), EpochSlots(EpochSlotIndex, EpochSlots), - SnapshotHash(SnapshotHash), + SnapshotHashes(SnapshotHash), + AccountsHashes(SnapshotHash), } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] @@ -93,11 +95,11 @@ pub struct SnapshotHash { } impl SnapshotHash { - pub fn new(from: Pubkey, hashes: Vec<(Slot, Hash)>, wallclock: u64) -> Self { + pub fn new(from: Pubkey, hashes: Vec<(Slot, Hash)>) -> Self { Self { from, hashes, - wallclock, + wallclock: timestamp(), } } } @@ -156,7 +158,8 @@ pub enum CrdsValueLabel { ContactInfo(Pubkey), Vote(VoteIndex, Pubkey), EpochSlots(Pubkey), - SnapshotHash(Pubkey), + SnapshotHashes(Pubkey), + AccountsHashes(Pubkey), } impl fmt::Display for CrdsValueLabel { @@ -165,7 +168,8 @@ impl fmt::Display for CrdsValueLabel { CrdsValueLabel::ContactInfo(_) => write!(f, "ContactInfo({})", self.pubkey()), CrdsValueLabel::Vote(ix, _) => write!(f, "Vote({}, {})", ix, self.pubkey()), CrdsValueLabel::EpochSlots(_) => write!(f, "EpochSlots({})", self.pubkey()), - CrdsValueLabel::SnapshotHash(_) => write!(f, "SnapshotHash({})", self.pubkey()), + CrdsValueLabel::SnapshotHashes(_) => write!(f, "SnapshotHashes({})", self.pubkey()), + CrdsValueLabel::AccountsHashes(_) => write!(f, "AccountsHashes({})", self.pubkey()), } } } @@ -176,7 +180,8 @@ impl CrdsValueLabel { CrdsValueLabel::ContactInfo(p) => *p, CrdsValueLabel::Vote(_, p) => *p, CrdsValueLabel::EpochSlots(p) => *p, - CrdsValueLabel::SnapshotHash(p) => *p, + CrdsValueLabel::SnapshotHashes(p) => *p, + CrdsValueLabel::AccountsHashes(p) => *p, } } } @@ -202,7 +207,8 @@ impl CrdsValue { CrdsData::ContactInfo(contact_info) => contact_info.wallclock, CrdsData::Vote(_, vote) => vote.wallclock, CrdsData::EpochSlots(_, vote) => vote.wallclock, - CrdsData::SnapshotHash(hash) => hash.wallclock, + CrdsData::SnapshotHashes(hash) => hash.wallclock, + CrdsData::AccountsHashes(hash) => hash.wallclock, } } pub fn pubkey(&self) -> Pubkey { @@ -210,7 +216,8 @@ impl CrdsValue { CrdsData::ContactInfo(contact_info) => contact_info.id, CrdsData::Vote(_, vote) => vote.from, CrdsData::EpochSlots(_, slots) => slots.from, - CrdsData::SnapshotHash(hash) => hash.from, + CrdsData::SnapshotHashes(hash) => hash.from, + CrdsData::AccountsHashes(hash) => hash.from, } } pub fn label(&self) -> CrdsValueLabel { @@ -218,7 +225,8 @@ impl CrdsValue { CrdsData::ContactInfo(_) => CrdsValueLabel::ContactInfo(self.pubkey()), CrdsData::Vote(ix, _) => CrdsValueLabel::Vote(*ix, self.pubkey()), CrdsData::EpochSlots(_, _) => CrdsValueLabel::EpochSlots(self.pubkey()), - CrdsData::SnapshotHash(_) => CrdsValueLabel::SnapshotHash(self.pubkey()), + CrdsData::SnapshotHashes(_) => CrdsValueLabel::SnapshotHashes(self.pubkey()), + CrdsData::AccountsHashes(_) => CrdsValueLabel::AccountsHashes(self.pubkey()), } } pub fn contact_info(&self) -> Option<&ContactInfo> { @@ -250,7 +258,14 @@ impl CrdsValue { pub fn snapshot_hash(&self) -> Option<&SnapshotHash> { match &self.data { - CrdsData::SnapshotHash(slots) => Some(slots), + CrdsData::SnapshotHashes(slots) => Some(slots), + _ => None, + } + } + + pub fn accounts_hash(&self) -> Option<&SnapshotHash> { + match &self.data { + CrdsData::AccountsHashes(slots) => Some(slots), _ => None, } } @@ -260,7 +275,8 @@ impl CrdsValue { let mut labels = vec![ CrdsValueLabel::ContactInfo(*key), CrdsValueLabel::EpochSlots(*key), - CrdsValueLabel::SnapshotHash(*key), + CrdsValueLabel::SnapshotHashes(*key), + CrdsValueLabel::AccountsHashes(*key), ]; labels.extend((0..MAX_VOTES).map(|ix| CrdsValueLabel::Vote(ix, *key))); labels @@ -310,14 +326,15 @@ mod test { #[test] fn test_labels() { - let mut hits = [false; 3 + MAX_VOTES as usize]; + let mut hits = [false; 4 + MAX_VOTES as usize]; // this method should cover all the possible labels for v in &CrdsValue::record_labels(&Pubkey::default()) { match v { CrdsValueLabel::ContactInfo(_) => hits[0] = true, CrdsValueLabel::EpochSlots(_) => hits[1] = true, - CrdsValueLabel::SnapshotHash(_) => hits[2] = true, - CrdsValueLabel::Vote(ix, _) => hits[*ix as usize + 3] = true, + CrdsValueLabel::SnapshotHashes(_) => hits[2] = true, + CrdsValueLabel::AccountsHashes(_) => hits[3] = true, + CrdsValueLabel::Vote(ix, _) => hits[*ix as usize + 4] = true, } } assert!(hits.iter().all(|x| *x)); diff --git a/core/src/lib.rs b/core/src/lib.rs index d0bd3b53f0..9e027b8dde 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -5,6 +5,7 @@ //! command-line tools to spin up validators and a Rust library //! +pub mod accounts_hash_verifier; pub mod banking_stage; pub mod broadcast_stage; pub mod cluster_info_vote_listener; diff --git a/core/src/replay_stage.rs b/core/src/replay_stage.rs index c2e6ebc486..926dabb061 100644 --- a/core/src/replay_stage.rs +++ b/core/src/replay_stage.rs @@ -76,7 +76,7 @@ pub struct ReplayStageConfig { pub leader_schedule_cache: Arc, pub slot_full_senders: Vec>, pub latest_root_senders: Vec>, - pub snapshot_package_sender: Option, + pub accounts_hash_sender: Option, pub block_commitment_cache: Arc>, pub transaction_status_sender: Option, pub rewards_recorder_sender: Option, @@ -179,7 +179,7 @@ impl ReplayStage { leader_schedule_cache, slot_full_senders, latest_root_senders, - snapshot_package_sender, + accounts_hash_sender, block_commitment_cache, transaction_status_sender, rewards_recorder_sender, @@ -334,7 +334,7 @@ impl ReplayStage { &root_bank_sender, total_staked, &lockouts_sender, - &snapshot_package_sender, + &accounts_hash_sender, &latest_root_senders, )?; } @@ -605,7 +605,7 @@ impl ReplayStage { root_bank_sender: &Sender>>, total_staked: u64, lockouts_sender: &Sender, - snapshot_package_sender: &Option, + accounts_hash_sender: &Option, latest_root_senders: &[Sender], ) -> Result<()> { if bank.is_empty() { @@ -632,7 +632,7 @@ impl ReplayStage { blockstore .set_roots(&rooted_slots) .expect("Ledger set roots failed"); - Self::handle_new_root(new_root, &bank_forks, progress, snapshot_package_sender); + Self::handle_new_root(new_root, &bank_forks, progress, accounts_hash_sender); latest_root_senders.iter().for_each(|s| { if let Err(e) = s.send(new_root) { trace!("latest root send failed: {:?}", e); @@ -959,12 +959,12 @@ impl ReplayStage { new_root: u64, bank_forks: &RwLock, progress: &mut HashMap, - snapshot_package_sender: &Option, + accounts_hash_sender: &Option, ) { bank_forks .write() .unwrap() - .set_root(new_root, snapshot_package_sender); + .set_root(new_root, accounts_hash_sender); let r_bank_forks = bank_forks.read().unwrap(); progress.retain(|k, _| r_bank_forks.get(*k).is_some()); } diff --git a/core/src/tvu.rs b/core/src/tvu.rs index 913eb0be7a..f1af0aaa5a 100644 --- a/core/src/tvu.rs +++ b/core/src/tvu.rs @@ -2,6 +2,7 @@ //! validation pipeline in software. use crate::{ + accounts_hash_verifier::AccountsHashVerifier, blockstream_service::BlockstreamService, cluster_info::ClusterInfo, commitment::BlockCommitmentCache, @@ -28,6 +29,7 @@ use solana_sdk::{ pubkey::Pubkey, signature::{Keypair, Signer}, }; +use std::collections::HashSet; use std::{ net::UdpSocket, path::PathBuf, @@ -47,6 +49,7 @@ pub struct Tvu { blockstream_service: Option, ledger_cleanup_service: Option, storage_stage: StorageStage, + accounts_hash_verifier: AccountsHashVerifier, } pub struct Sockets { @@ -56,6 +59,16 @@ pub struct Sockets { pub forwards: Vec, } +#[derive(Default)] +pub struct TvuConfig { + pub max_ledger_slots: Option, + pub sigverify_disabled: bool, + pub shred_version: u16, + pub halt_on_trusted_validators_accounts_hash_mismatch: bool, + pub trusted_validators: Option>, + pub accounts_hash_fault_injection_slots: u64, +} + impl Tvu { /// This service receives messages from a leader in the network and processes the transactions /// on the bank state. @@ -74,7 +87,6 @@ impl Tvu { blockstore: Arc, storage_state: &StorageState, blockstream_unix_socket: Option<&PathBuf>, - max_ledger_slots: Option, ledger_signal_receiver: Receiver, subscriptions: &Arc, poh_recorder: &Arc>, @@ -82,12 +94,11 @@ impl Tvu { exit: &Arc, completed_slots_receiver: CompletedSlotsReceiver, block_commitment_cache: Arc>, - sigverify_disabled: bool, cfg: Option>, - shred_version: u16, transaction_status_sender: Option, rewards_recorder_sender: Option, snapshot_package_sender: Option, + tvu_config: TvuConfig, ) -> Self { let keypair: Arc = cluster_info .read() @@ -117,7 +128,7 @@ impl Tvu { ); let (verified_sender, verified_receiver) = unbounded(); - let sigverify_stage = if !sigverify_disabled { + let sigverify_stage = if !tvu_config.sigverify_disabled { SigVerifyStage::new( fetch_receiver, verified_sender, @@ -143,12 +154,23 @@ impl Tvu { completed_slots_receiver, *bank_forks.read().unwrap().working_bank().epoch_schedule(), cfg, - shred_version, + tvu_config.shred_version, ); let (blockstream_slot_sender, blockstream_slot_receiver) = channel(); let (ledger_cleanup_slot_sender, ledger_cleanup_slot_receiver) = channel(); + let (accounts_hash_sender, accounts_hash_receiver) = channel(); + let accounts_hash_verifier = AccountsHashVerifier::new( + accounts_hash_receiver, + snapshot_package_sender, + exit, + cluster_info, + tvu_config.trusted_validators.clone(), + tvu_config.halt_on_trusted_validators_accounts_hash_mismatch, + tvu_config.accounts_hash_fault_injection_slots, + ); + let replay_stage_config = ReplayStageConfig { my_pubkey: keypair.pubkey(), vote_account: *vote_account, @@ -158,7 +180,7 @@ impl Tvu { leader_schedule_cache: leader_schedule_cache.clone(), slot_full_senders: vec![blockstream_slot_sender], latest_root_senders: vec![ledger_cleanup_slot_sender], - snapshot_package_sender, + accounts_hash_sender: Some(accounts_hash_sender), block_commitment_cache, transaction_status_sender, rewards_recorder_sender, @@ -185,7 +207,7 @@ impl Tvu { None }; - let ledger_cleanup_service = max_ledger_slots.map(|max_ledger_slots| { + let ledger_cleanup_service = tvu_config.max_ledger_slots.map(|max_ledger_slots| { LedgerCleanupService::new( ledger_cleanup_slot_receiver, blockstore.clone(), @@ -213,6 +235,7 @@ impl Tvu { blockstream_service, ledger_cleanup_service, storage_stage, + accounts_hash_verifier, } } @@ -228,6 +251,7 @@ impl Tvu { self.ledger_cleanup_service.unwrap().join()?; } self.replay_stage.join()?; + self.accounts_hash_verifier.join()?; Ok(()) } } @@ -288,7 +312,6 @@ pub mod tests { blockstore, &StorageState::default(), None, - None, l_receiver, &Arc::new(RpcSubscriptions::new(&exit)), &poh_recorder, @@ -296,12 +319,11 @@ pub mod tests { &exit, completed_slots_receiver, block_commitment_cache, - false, - None, - 0, None, None, None, + None, + TvuConfig::default(), ); exit.store(true, Ordering::Relaxed); tvu.join().unwrap(); diff --git a/core/src/validator.rs b/core/src/validator.rs index c6e2d6eeef..fd718fb80f 100644 --- a/core/src/validator.rs +++ b/core/src/validator.rs @@ -20,7 +20,7 @@ use crate::{ storage_stage::StorageState, tpu::Tpu, transaction_status_service::TransactionStatusService, - tvu::{Sockets, Tvu}, + tvu::{Sockets, Tvu, TvuConfig}, }; use crossbeam_channel::unbounded; use solana_ledger::{ @@ -76,6 +76,8 @@ pub struct ValidatorConfig { pub wait_for_supermajority: Option, pub new_hard_forks: Option>, pub trusted_validators: Option>, // None = trust all + pub halt_on_trusted_validators_accounts_hash_mismatch: bool, + pub accounts_hash_fault_injection_slots: u64, // 0 = no fault injection } impl Default for ValidatorConfig { @@ -99,6 +101,8 @@ impl Default for ValidatorConfig { wait_for_supermajority: None, new_hard_forks: None, trusted_validators: None, + halt_on_trusted_validators_accounts_hash_mismatch: false, + accounts_hash_fault_injection_slots: 0, } } } @@ -416,7 +420,6 @@ impl Validator { blockstore.clone(), &storage_state, config.blockstream_unix_socket.as_ref(), - config.max_ledger_slots, ledger_signal_receiver, &subscriptions, &poh_recorder, @@ -424,12 +427,19 @@ impl Validator { &exit, completed_slots_receiver, block_commitment_cache, - config.dev_sigverify_disabled, config.enable_partition.clone(), - node.info.shred_version, transaction_status_sender.clone(), rewards_recorder_sender, snapshot_package_sender, + TvuConfig { + max_ledger_slots: config.max_ledger_slots, + sigverify_disabled: config.dev_sigverify_disabled, + halt_on_trusted_validators_accounts_hash_mismatch: config + .halt_on_trusted_validators_accounts_hash_mismatch, + shred_version: node.info.shred_version, + trusted_validators: config.trusted_validators.clone(), + accounts_hash_fault_injection_slots: config.accounts_hash_fault_injection_slots, + }, ); if config.dev_sigverify_disabled { diff --git a/local-cluster/tests/local_cluster.rs b/local-cluster/tests/local_cluster.rs index 84d3203404..2b22c4bd85 100644 --- a/local-cluster/tests/local_cluster.rs +++ b/local-cluster/tests/local_cluster.rs @@ -606,6 +606,95 @@ fn test_softlaunch_operating_mode() { } } +#[test] +#[serial] +fn test_consistency_halt() { + solana_logger::setup(); + let snapshot_interval_slots = 20; + let num_account_paths = 1; + + // Create cluster with a leader producing bad snapshot hashes. + let mut leader_snapshot_test_config = + setup_snapshot_validator_config(snapshot_interval_slots, num_account_paths); + leader_snapshot_test_config + .validator_config + .accounts_hash_fault_injection_slots = 40; + + let validator_stake = 10_000; + let config = ClusterConfig { + node_stakes: vec![validator_stake], + cluster_lamports: 100_000, + validator_configs: vec![leader_snapshot_test_config.validator_config.clone()], + ..ClusterConfig::default() + }; + + let mut cluster = LocalCluster::new(&config); + + sleep(Duration::from_millis(5000)); + let (cluster_nodes, _) = discover_cluster(&cluster.entry_point_info.gossip, 1).unwrap(); + info!("num_nodes: {}", cluster_nodes.len()); + + // Add a validator with the leader as trusted, it should halt when it detects + // mismatch. + let mut validator_snapshot_test_config = + setup_snapshot_validator_config(snapshot_interval_slots, num_account_paths); + + let mut trusted_validators = HashSet::new(); + trusted_validators.insert(cluster_nodes[0].id); + + validator_snapshot_test_config + .validator_config + .trusted_validators = Some(trusted_validators); + validator_snapshot_test_config + .validator_config + .halt_on_trusted_validators_accounts_hash_mismatch = true; + + warn!("adding a validator"); + cluster.add_validator( + &validator_snapshot_test_config.validator_config, + validator_stake as u64, + Arc::new(Keypair::new()), + ); + let num_nodes = 2; + assert_eq!( + discover_cluster(&cluster.entry_point_info.gossip, num_nodes) + .unwrap() + .0 + .len(), + num_nodes + ); + + // Check for only 1 node on the network. + let mut encountered_error = false; + loop { + let discover = discover_cluster(&cluster.entry_point_info.gossip, 2); + match discover { + Err(_) => { + encountered_error = true; + break; + } + Ok(nodes) => { + if nodes.0.len() < 2 { + encountered_error = true; + break; + } + info!("checking cluster for fewer nodes.. {:?}", nodes.0.len()); + } + } + let client = cluster + .get_validator_client(&cluster.entry_point_info.id) + .unwrap(); + if let Ok(slot) = client.get_slot() { + if slot > 210 { + break; + } + info!("slot: {}", slot); + } + sleep(Duration::from_millis(1000)); + } + assert!(encountered_error); +} + #[allow(unused_attributes)] #[test] #[serial] diff --git a/multinode-demo/validator.sh b/multinode-demo/validator.sh index 951bc47f87..407c7187c3 100755 --- a/multinode-demo/validator.sh +++ b/multinode-demo/validator.sh @@ -145,6 +145,9 @@ while [[ -n $1 ]]; do elif [[ $1 = --trusted-validator ]]; then args+=("$1" "$2") shift 2 + elif [[ $1 = --halt-on-trusted-validators-accounts-hash-mismatch ]]; then + args+=("$1") + shift elif [[ $1 = -h ]]; then usage "$@" else diff --git a/validator/src/main.rs b/validator/src/main.rs index d6fef40385..38c187707f 100644 --- a/validator/src/main.rs +++ b/validator/src/main.rs @@ -851,6 +851,13 @@ pub fn main() { .validator(solana_net_utils::is_host) .help("IP address to bind the RPC port [default: use --bind-address]"), ) + .arg( + clap::Arg::with_name("halt_on_trusted_validators_accounts_hash_mismatch") + .long("halt-on-trusted-validators-accounts-hash-mismatch") + .requires("trusted_validators") + .takes_value(false) + .help("Abort the validator if a bank hash mismatch is detected within trusted validator set"), + ) .get_matches(); let identity_keypair = Arc::new(keypair_of(&matches, "identity").unwrap_or_else(Keypair::new)); @@ -1009,6 +1016,10 @@ pub fn main() { validator_config.max_ledger_slots = Some(limit_ledger_size); } + if matches.is_present("halt_on_trusted_validators_accounts_hash_mismatch") { + validator_config.halt_on_trusted_validators_accounts_hash_mismatch = true; + } + if matches.value_of("signer_addr").is_some() { warn!("--vote-signer-address ignored"); }