From 1c7cea1af428990b496cbe0a3436f321b5dacf5b Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Fri, 3 Apr 2020 15:11:42 -0700 Subject: [PATCH] Add stake-monitor --- Cargo.lock | 733 ++++++++++++++++++---------------- Cargo.toml | 1 + cli-config/src/config.rs | 22 +- cli-config/src/lib.rs | 34 ++ client/src/rpc_client.rs | 12 +- scripts/cargo-install-all.sh | 1 + stake-monitor/.gitignore | 2 + stake-monitor/Cargo.toml | 35 ++ stake-monitor/README.md | 14 + stake-monitor/src/lib.rs | 297 ++++++++++++++ stake-monitor/src/main.rs | 188 +++++++++ transaction-status/src/lib.rs | 9 + 12 files changed, 986 insertions(+), 362 deletions(-) create mode 100644 stake-monitor/.gitignore create mode 100644 stake-monitor/Cargo.toml create mode 100644 stake-monitor/README.md create mode 100644 stake-monitor/src/lib.rs create mode 100644 stake-monitor/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 7e070807cc..b8646e08c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -314,7 +314,7 @@ dependencies = [ [[package]] name = "btc_spv_bin" -version = "1.0.13" +version = "1.0.14" 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)", @@ -595,6 +595,21 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "console" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "clicolors-control 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "encode_unicode 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "constant_time_eq" version = "0.1.3" @@ -3421,6 +3436,16 @@ dependencies = [ "serial_test_derive 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "serial_test" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serial_test_derive 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "serial_test_derive" version = "0.3.2" @@ -3591,22 +3616,22 @@ dependencies = [ [[package]] name = "solana-archiver" -version = "1.0.13" +version = "1.0.14" 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.13", - "solana-clap-utils 1.0.13", - "solana-core 1.0.13", - "solana-logger 1.0.13", - "solana-metrics 1.0.13", - "solana-net-utils 1.0.13", - "solana-sdk 1.0.13", + "solana-archiver-lib 1.0.14", + "solana-clap-utils 1.0.14", + "solana-core 1.0.14", + "solana-logger 1.0.14", + "solana-metrics 1.0.14", + "solana-net-utils 1.0.14", + "solana-sdk 1.0.14", ] [[package]] name = "solana-archiver-lib" -version = "1.0.13" +version = "1.0.14" 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)", @@ -3618,55 +3643,55 @@ dependencies = [ "serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.105 (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.13", - "solana-chacha 1.0.13", - "solana-chacha-sys 1.0.13", - "solana-client 1.0.13", - "solana-core 1.0.13", - "solana-ledger 1.0.13", - "solana-logger 1.0.13", - "solana-metrics 1.0.13", - "solana-net-utils 1.0.13", - "solana-perf 1.0.13", - "solana-sdk 1.0.13", - "solana-storage-program 1.0.13", + "solana-archiver-utils 1.0.14", + "solana-chacha 1.0.14", + "solana-chacha-sys 1.0.14", + "solana-client 1.0.14", + "solana-core 1.0.14", + "solana-ledger 1.0.14", + "solana-logger 1.0.14", + "solana-metrics 1.0.14", + "solana-net-utils 1.0.14", + "solana-perf 1.0.14", + "solana-sdk 1.0.14", + "solana-storage-program 1.0.14", "thiserror 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-archiver-utils" -version = "1.0.13" +version = "1.0.14" 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.13", - "solana-chacha-sys 1.0.13", - "solana-ledger 1.0.13", - "solana-logger 1.0.13", - "solana-perf 1.0.13", - "solana-sdk 1.0.13", + "solana-chacha 1.0.14", + "solana-chacha-sys 1.0.14", + "solana-ledger 1.0.14", + "solana-logger 1.0.14", + "solana-perf 1.0.14", + "solana-sdk 1.0.14", ] [[package]] name = "solana-banking-bench" -version = "1.0.13" +version = "1.0.14" 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.13", - "solana-ledger 1.0.13", - "solana-logger 1.0.13", - "solana-measure 1.0.13", - "solana-runtime 1.0.13", - "solana-sdk 1.0.13", + "solana-core 1.0.14", + "solana-ledger 1.0.14", + "solana-logger 1.0.14", + "solana-measure 1.0.14", + "solana-runtime 1.0.14", + "solana-sdk 1.0.14", ] [[package]] name = "solana-bench-exchange" -version = "1.0.13" +version = "1.0.14" 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)", @@ -3677,34 +3702,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.13", - "solana-client 1.0.13", - "solana-core 1.0.13", - "solana-exchange-program 1.0.13", - "solana-faucet 1.0.13", - "solana-genesis 1.0.13", - "solana-local-cluster 1.0.13", - "solana-logger 1.0.13", - "solana-metrics 1.0.13", - "solana-net-utils 1.0.13", - "solana-runtime 1.0.13", - "solana-sdk 1.0.13", + "solana-clap-utils 1.0.14", + "solana-client 1.0.14", + "solana-core 1.0.14", + "solana-exchange-program 1.0.14", + "solana-faucet 1.0.14", + "solana-genesis 1.0.14", + "solana-local-cluster 1.0.14", + "solana-logger 1.0.14", + "solana-metrics 1.0.14", + "solana-net-utils 1.0.14", + "solana-runtime 1.0.14", + "solana-sdk 1.0.14", ] [[package]] name = "solana-bench-streamer" -version = "1.0.13" +version = "1.0.14" dependencies = [ "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-clap-utils 1.0.13", - "solana-core 1.0.13", - "solana-logger 1.0.13", - "solana-net-utils 1.0.13", + "solana-clap-utils 1.0.14", + "solana-core 1.0.14", + "solana-logger 1.0.14", + "solana-net-utils 1.0.14", ] [[package]] name = "solana-bench-tps" -version = "1.0.13" +version = "1.0.14" 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)", @@ -3714,25 +3739,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.13", - "solana-client 1.0.13", - "solana-core 1.0.13", - "solana-faucet 1.0.13", - "solana-genesis 1.0.13", - "solana-librapay 1.0.13", - "solana-local-cluster 1.0.13", - "solana-logger 1.0.13", - "solana-measure 1.0.13", - "solana-metrics 1.0.13", - "solana-move-loader-program 1.0.13", - "solana-net-utils 1.0.13", - "solana-runtime 1.0.13", - "solana-sdk 1.0.13", + "solana-clap-utils 1.0.14", + "solana-client 1.0.14", + "solana-core 1.0.14", + "solana-faucet 1.0.14", + "solana-genesis 1.0.14", + "solana-librapay 1.0.14", + "solana-local-cluster 1.0.14", + "solana-logger 1.0.14", + "solana-measure 1.0.14", + "solana-metrics 1.0.14", + "solana-move-loader-program 1.0.14", + "solana-net-utils 1.0.14", + "solana-runtime 1.0.14", + "solana-sdk 1.0.14", ] [[package]] name = "solana-bpf-loader-program" -version = "1.0.13" +version = "1.0.14" 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)", @@ -3740,15 +3765,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.13", - "solana-sdk 1.0.13", + "solana-logger 1.0.14", + "solana-sdk 1.0.14", "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.13" +version = "1.0.14" 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)", @@ -3757,12 +3782,12 @@ dependencies = [ "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk 1.0.13", + "solana-sdk 1.0.14", ] [[package]] name = "solana-budget-program" -version = "1.0.13" +version = "1.0.14" 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)", @@ -3771,56 +3796,56 @@ dependencies = [ "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-runtime 1.0.13", - "solana-sdk 1.0.13", + "solana-runtime 1.0.14", + "solana-sdk 1.0.14", "thiserror 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-chacha" -version = "1.0.13" +version = "1.0.14" 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.13", - "solana-ledger 1.0.13", - "solana-logger 1.0.13", - "solana-perf 1.0.13", - "solana-sdk 1.0.13", + "solana-chacha-sys 1.0.14", + "solana-ledger 1.0.14", + "solana-logger 1.0.14", + "solana-perf 1.0.14", + "solana-sdk 1.0.14", ] [[package]] name = "solana-chacha-cuda" -version = "1.0.13" +version = "1.0.14" 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.13", - "solana-chacha 1.0.13", - "solana-ledger 1.0.13", - "solana-logger 1.0.13", - "solana-perf 1.0.13", - "solana-sdk 1.0.13", + "solana-archiver-utils 1.0.14", + "solana-chacha 1.0.14", + "solana-ledger 1.0.14", + "solana-logger 1.0.14", + "solana-perf 1.0.14", + "solana-sdk 1.0.14", ] [[package]] name = "solana-chacha-sys" -version = "1.0.13" +version = "1.0.14" dependencies = [ "cc 1.0.49 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-clap-utils" -version = "1.0.13" +version = "1.0.14" 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.13", - "solana-sdk 1.0.13", + "solana-remote-wallet 1.0.14", + "solana-sdk 1.0.14", "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)", @@ -3828,7 +3853,7 @@ dependencies = [ [[package]] name = "solana-cli" -version = "1.0.13" +version = "1.0.14" 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)", @@ -3847,22 +3872,22 @@ dependencies = [ "serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.105 (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.13", - "solana-clap-utils 1.0.13", - "solana-cli-config 1.0.13", - "solana-client 1.0.13", - "solana-config-program 1.0.13", - "solana-core 1.0.13", - "solana-faucet 1.0.13", - "solana-logger 1.0.13", - "solana-net-utils 1.0.13", - "solana-remote-wallet 1.0.13", - "solana-runtime 1.0.13", - "solana-sdk 1.0.13", - "solana-stake-program 1.0.13", - "solana-storage-program 1.0.13", - "solana-vote-program 1.0.13", - "solana-vote-signer 1.0.13", + "solana-budget-program 1.0.14", + "solana-clap-utils 1.0.14", + "solana-cli-config 1.0.14", + "solana-client 1.0.14", + "solana-config-program 1.0.14", + "solana-core 1.0.14", + "solana-faucet 1.0.14", + "solana-logger 1.0.14", + "solana-net-utils 1.0.14", + "solana-remote-wallet 1.0.14", + "solana-runtime 1.0.14", + "solana-sdk 1.0.14", + "solana-stake-program 1.0.14", + "solana-storage-program 1.0.14", + "solana-vote-program 1.0.14", + "solana-vote-signer 1.0.14", "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)", @@ -3871,7 +3896,7 @@ dependencies = [ [[package]] name = "solana-cli-config" -version = "1.0.13" +version = "1.0.14" 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)", @@ -3883,7 +3908,7 @@ dependencies = [ [[package]] name = "solana-client" -version = "1.0.13" +version = "1.0.14" 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)", @@ -3897,11 +3922,11 @@ dependencies = [ "serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.105 (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.13", - "solana-net-utils 1.0.13", - "solana-sdk 1.0.13", - "solana-transaction-status 1.0.13", - "solana-vote-program 1.0.13", + "solana-logger 1.0.14", + "solana-net-utils 1.0.14", + "solana-sdk 1.0.14", + "solana-transaction-status 1.0.14", + "solana-vote-program 1.0.14", "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)", @@ -3909,20 +3934,20 @@ dependencies = [ [[package]] name = "solana-config-program" -version = "1.0.13" +version = "1.0.14" 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.105 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-logger 1.0.13", - "solana-sdk 1.0.13", + "solana-logger 1.0.14", + "solana-sdk 1.0.14", ] [[package]] name = "solana-core" -version = "1.0.13" +version = "1.0.14" 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)", @@ -3958,27 +3983,27 @@ 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.13", - "solana-chacha-cuda 1.0.13", - "solana-clap-utils 1.0.13", - "solana-client 1.0.13", - "solana-faucet 1.0.13", - "solana-ledger 1.0.13", - "solana-logger 1.0.13", - "solana-measure 1.0.13", - "solana-merkle-tree 1.0.13", - "solana-metrics 1.0.13", - "solana-net-utils 1.0.13", - "solana-perf 1.0.13", - "solana-rayon-threadlimit 1.0.13", - "solana-runtime 1.0.13", - "solana-sdk 1.0.13", - "solana-stake-program 1.0.13", - "solana-storage-program 1.0.13", - "solana-sys-tuner 1.0.13", - "solana-transaction-status 1.0.13", - "solana-vote-program 1.0.13", - "solana-vote-signer 1.0.13", + "solana-budget-program 1.0.14", + "solana-chacha-cuda 1.0.14", + "solana-clap-utils 1.0.14", + "solana-client 1.0.14", + "solana-faucet 1.0.14", + "solana-ledger 1.0.14", + "solana-logger 1.0.14", + "solana-measure 1.0.14", + "solana-merkle-tree 1.0.14", + "solana-metrics 1.0.14", + "solana-net-utils 1.0.14", + "solana-perf 1.0.14", + "solana-rayon-threadlimit 1.0.14", + "solana-runtime 1.0.14", + "solana-sdk 1.0.14", + "solana-stake-program 1.0.14", + "solana-storage-program 1.0.14", + "solana-sys-tuner 1.0.14", + "solana-transaction-status 1.0.14", + "solana-vote-program 1.0.14", + "solana-vote-signer 1.0.14", "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)", "thiserror 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3991,7 +4016,7 @@ dependencies = [ [[package]] name = "solana-crate-features" -version = "1.0.13" +version = "1.0.14" 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)", @@ -4014,7 +4039,7 @@ dependencies = [ [[package]] name = "solana-exchange-program" -version = "1.0.13" +version = "1.0.14" 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)", @@ -4022,24 +4047,24 @@ dependencies = [ "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-logger 1.0.13", - "solana-metrics 1.0.13", - "solana-runtime 1.0.13", - "solana-sdk 1.0.13", + "solana-logger 1.0.14", + "solana-metrics 1.0.14", + "solana-runtime 1.0.14", + "solana-sdk 1.0.14", "thiserror 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-failure-program" -version = "1.0.13" +version = "1.0.14" dependencies = [ - "solana-runtime 1.0.13", - "solana-sdk 1.0.13", + "solana-runtime 1.0.14", + "solana-sdk 1.0.14", ] [[package]] name = "solana-faucet" -version = "1.0.13" +version = "1.0.14" 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)", @@ -4048,17 +4073,17 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-clap-utils 1.0.13", - "solana-logger 1.0.13", - "solana-metrics 1.0.13", - "solana-sdk 1.0.13", + "solana-clap-utils 1.0.14", + "solana-logger 1.0.14", + "solana-metrics 1.0.14", + "solana-sdk 1.0.14", "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.13" +version = "1.0.14" 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)", @@ -4066,49 +4091,49 @@ dependencies = [ "serde 1.0.105 (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.13", - "solana-genesis-programs 1.0.13", - "solana-ledger 1.0.13", - "solana-sdk 1.0.13", - "solana-stake-program 1.0.13", - "solana-storage-program 1.0.13", - "solana-vote-program 1.0.13", + "solana-clap-utils 1.0.14", + "solana-genesis-programs 1.0.14", + "solana-ledger 1.0.14", + "solana-sdk 1.0.14", + "solana-stake-program 1.0.14", + "solana-storage-program 1.0.14", + "solana-vote-program 1.0.14", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-genesis-programs" -version = "1.0.13" +version = "1.0.14" dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-bpf-loader-program 1.0.13", - "solana-budget-program 1.0.13", - "solana-config-program 1.0.13", - "solana-exchange-program 1.0.13", - "solana-runtime 1.0.13", - "solana-sdk 1.0.13", - "solana-stake-program 1.0.13", - "solana-storage-program 1.0.13", - "solana-vest-program 1.0.13", - "solana-vote-program 1.0.13", + "solana-bpf-loader-program 1.0.14", + "solana-budget-program 1.0.14", + "solana-config-program 1.0.14", + "solana-exchange-program 1.0.14", + "solana-runtime 1.0.14", + "solana-sdk 1.0.14", + "solana-stake-program 1.0.14", + "solana-storage-program 1.0.14", + "solana-vest-program 1.0.14", + "solana-vote-program 1.0.14", ] [[package]] name = "solana-gossip" -version = "1.0.13" +version = "1.0.14" dependencies = [ "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-clap-utils 1.0.13", - "solana-client 1.0.13", - "solana-core 1.0.13", - "solana-logger 1.0.13", - "solana-net-utils 1.0.13", - "solana-sdk 1.0.13", + "solana-clap-utils 1.0.14", + "solana-client 1.0.14", + "solana-core 1.0.14", + "solana-logger 1.0.14", + "solana-net-utils 1.0.14", + "solana-sdk 1.0.14", ] [[package]] name = "solana-install" -version = "1.0.13" +version = "1.0.14" 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)", @@ -4126,11 +4151,11 @@ dependencies = [ "serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.105 (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.13", - "solana-client 1.0.13", - "solana-config-program 1.0.13", - "solana-logger 1.0.13", - "solana-sdk 1.0.13", + "solana-clap-utils 1.0.14", + "solana-client 1.0.14", + "solana-config-program 1.0.14", + "solana-logger 1.0.14", + "solana-sdk 1.0.14", "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)", @@ -4140,22 +4165,22 @@ dependencies = [ [[package]] name = "solana-keygen" -version = "1.0.13" +version = "1.0.14" 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.13", - "solana-cli-config 1.0.13", - "solana-remote-wallet 1.0.13", - "solana-sdk 1.0.13", + "solana-clap-utils 1.0.14", + "solana-cli-config 1.0.14", + "solana-remote-wallet 1.0.14", + "solana-sdk 1.0.14", "tiny-bip39 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-ledger" -version = "1.0.13" +version = "1.0.14" 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)", @@ -4180,20 +4205,20 @@ dependencies = [ "serde 1.0.105 (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.13", - "solana-genesis-programs 1.0.13", - "solana-logger 1.0.13", - "solana-measure 1.0.13", - "solana-merkle-tree 1.0.13", - "solana-metrics 1.0.13", - "solana-perf 1.0.13", - "solana-rayon-threadlimit 1.0.13", + "solana-budget-program 1.0.14", + "solana-genesis-programs 1.0.14", + "solana-logger 1.0.14", + "solana-measure 1.0.14", + "solana-merkle-tree 1.0.14", + "solana-metrics 1.0.14", + "solana-perf 1.0.14", + "solana-rayon-threadlimit 1.0.14", "solana-reed-solomon-erasure 4.0.1-3 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-runtime 1.0.13", - "solana-sdk 1.0.13", - "solana-stake-program 1.0.13", - "solana-transaction-status 1.0.13", - "solana-vote-program 1.0.13", + "solana-runtime 1.0.14", + "solana-sdk 1.0.14", + "solana-stake-program 1.0.14", + "solana-transaction-status 1.0.14", + "solana-vote-program 1.0.14", "symlink 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tar 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4202,7 +4227,7 @@ dependencies = [ [[package]] name = "solana-ledger-tool" -version = "1.0.13" +version = "1.0.14" 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)", @@ -4210,32 +4235,32 @@ 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.13", - "solana-ledger 1.0.13", - "solana-logger 1.0.13", - "solana-runtime 1.0.13", - "solana-sdk 1.0.13", - "solana-stake-program 1.0.13", - "solana-vote-program 1.0.13", + "solana-clap-utils 1.0.14", + "solana-ledger 1.0.14", + "solana-logger 1.0.14", + "solana-runtime 1.0.14", + "solana-sdk 1.0.14", + "solana-stake-program 1.0.14", + "solana-vote-program 1.0.14", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-librapay" -version = "1.0.13" +version = "1.0.14" 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.13", - "solana-move-loader-program 1.0.13", - "solana-runtime 1.0.13", - "solana-sdk 1.0.13", + "solana-logger 1.0.14", + "solana-move-loader-program 1.0.14", + "solana-runtime 1.0.14", + "solana-sdk 1.0.14", "solana_libra_types 0.0.1-sol4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-local-cluster" -version = "1.0.13" +version = "1.0.14" 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)", @@ -4243,40 +4268,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.13", - "solana-client 1.0.13", - "solana-config-program 1.0.13", - "solana-core 1.0.13", - "solana-exchange-program 1.0.13", - "solana-faucet 1.0.13", - "solana-genesis-programs 1.0.13", - "solana-ledger 1.0.13", - "solana-logger 1.0.13", - "solana-rayon-threadlimit 1.0.13", - "solana-runtime 1.0.13", - "solana-sdk 1.0.13", - "solana-stake-program 1.0.13", - "solana-storage-program 1.0.13", - "solana-vest-program 1.0.13", - "solana-vote-program 1.0.13", + "solana-archiver-lib 1.0.14", + "solana-client 1.0.14", + "solana-config-program 1.0.14", + "solana-core 1.0.14", + "solana-exchange-program 1.0.14", + "solana-faucet 1.0.14", + "solana-genesis-programs 1.0.14", + "solana-ledger 1.0.14", + "solana-logger 1.0.14", + "solana-rayon-threadlimit 1.0.14", + "solana-runtime 1.0.14", + "solana-sdk 1.0.14", + "solana-stake-program 1.0.14", + "solana-storage-program 1.0.14", + "solana-vest-program 1.0.14", + "solana-vote-program 1.0.14", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-log-analyzer" -version = "1.0.13" +version = "1.0.14" 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.105 (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.13", - "solana-logger 1.0.13", + "solana-clap-utils 1.0.14", + "solana-logger 1.0.14", ] [[package]] name = "solana-logger" -version = "1.0.13" +version = "1.0.14" 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)", @@ -4285,26 +4310,26 @@ dependencies = [ [[package]] name = "solana-measure" -version = "1.0.13" +version = "1.0.14" 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.13", - "solana-sdk 1.0.13", + "solana-metrics 1.0.14", + "solana-sdk 1.0.14", ] [[package]] name = "solana-merkle-tree" -version = "1.0.13" +version = "1.0.14" dependencies = [ "hex 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk 1.0.13", + "solana-sdk 1.0.14", ] [[package]] name = "solana-metrics" -version = "1.0.13" +version = "1.0.14" dependencies = [ "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "gethostname 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4314,12 +4339,12 @@ 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.13", + "solana-sdk 1.0.14", ] [[package]] name = "solana-move-loader-program" -version = "1.0.13" +version = "1.0.14" 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)", @@ -4330,8 +4355,8 @@ dependencies = [ "serde_bytes 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.105 (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.13", - "solana-sdk 1.0.13", + "solana-logger 1.0.14", + "solana-sdk 1.0.14", "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)", @@ -4348,19 +4373,19 @@ dependencies = [ [[package]] name = "solana-net-shaper" -version = "1.0.13" +version = "1.0.14" 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.105 (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.13", - "solana-logger 1.0.13", + "solana-clap-utils 1.0.14", + "solana-logger 1.0.14", ] [[package]] name = "solana-net-utils" -version = "1.0.13" +version = "1.0.14" 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)", @@ -4371,36 +4396,36 @@ dependencies = [ "serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.105 (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.13", - "solana-logger 1.0.13", + "solana-clap-utils 1.0.14", + "solana-logger 1.0.14", "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.13" +version = "1.0.14" dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-logger 1.0.13", - "solana-sdk 1.0.13", + "solana-logger 1.0.14", + "solana-sdk 1.0.14", ] [[package]] name = "solana-ownable" -version = "1.0.13" +version = "1.0.14" 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.13", - "solana-sdk 1.0.13", + "solana-runtime 1.0.14", + "solana-sdk 1.0.14", "thiserror 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-perf" -version = "1.0.13" +version = "1.0.14" 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)", @@ -4411,16 +4436,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.105 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-budget-program 1.0.13", - "solana-logger 1.0.13", - "solana-metrics 1.0.13", - "solana-rayon-threadlimit 1.0.13", - "solana-sdk 1.0.13", + "solana-budget-program 1.0.14", + "solana-logger 1.0.14", + "solana-metrics 1.0.14", + "solana-rayon-threadlimit 1.0.14", + "solana-sdk 1.0.14", ] [[package]] name = "solana-rayon-threadlimit" -version = "1.0.13" +version = "1.0.14" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4438,7 +4463,7 @@ dependencies = [ [[package]] name = "solana-remote-wallet" -version = "1.0.13" +version = "1.0.14" 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)", @@ -4447,14 +4472,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.13", + "solana-sdk 1.0.14", "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.13" +version = "1.0.14" 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)", @@ -4474,23 +4499,23 @@ dependencies = [ "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-bpf-loader-program 1.0.13", - "solana-logger 1.0.13", - "solana-measure 1.0.13", - "solana-metrics 1.0.13", - "solana-noop-program 1.0.13", - "solana-rayon-threadlimit 1.0.13", - "solana-sdk 1.0.13", - "solana-stake-program 1.0.13", - "solana-storage-program 1.0.13", - "solana-vote-program 1.0.13", + "solana-bpf-loader-program 1.0.14", + "solana-logger 1.0.14", + "solana-measure 1.0.14", + "solana-metrics 1.0.14", + "solana-noop-program 1.0.14", + "solana-rayon-threadlimit 1.0.14", + "solana-sdk 1.0.14", + "solana-stake-program 1.0.14", + "solana-storage-program 1.0.14", + "solana-vote-program 1.0.14", "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)", ] [[package]] name = "solana-scripts" -version = "1.0.13" +version = "1.0.14" dependencies = [ "csv 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4498,7 +4523,7 @@ dependencies = [ [[package]] name = "solana-sdk" -version = "1.0.13" +version = "1.0.14" 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)", @@ -4523,16 +4548,16 @@ dependencies = [ "serde_derive 1.0.105 (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.13", - "solana-logger 1.0.13", - "solana-sdk-macro 1.0.13", + "solana-crate-features 1.0.14", + "solana-logger 1.0.14", + "solana-sdk-macro 1.0.14", "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.13" +version = "1.0.14" 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)", @@ -4541,12 +4566,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.13", + "solana-sdk 1.0.14", ] [[package]] name = "solana-sdk-macro" -version = "1.0.13" +version = "1.0.14" 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)", @@ -4554,9 +4579,33 @@ dependencies = [ "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "solana-stake-monitor" +version = "1.0.14" +dependencies = [ + "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "console 0.10.0 (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.105 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)", + "serial_test 0.4.0 (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.14", + "solana-cli-config 1.0.14", + "solana-client 1.0.14", + "solana-core 1.0.14", + "solana-local-cluster 1.0.14", + "solana-logger 1.0.14", + "solana-metrics 1.0.14", + "solana-sdk 1.0.14", + "solana-stake-program 1.0.14", + "solana-transaction-status 1.0.14", + "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "solana-stake-program" -version = "1.0.13" +version = "1.0.14" 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)", @@ -4564,17 +4613,17 @@ dependencies = [ "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-config-program 1.0.13", - "solana-logger 1.0.13", - "solana-metrics 1.0.13", - "solana-sdk 1.0.13", - "solana-vote-program 1.0.13", + "solana-config-program 1.0.14", + "solana-logger 1.0.14", + "solana-metrics 1.0.14", + "solana-sdk 1.0.14", + "solana-vote-program 1.0.14", "thiserror 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-storage-program" -version = "1.0.13" +version = "1.0.14" 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)", @@ -4584,20 +4633,20 @@ dependencies = [ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-logger 1.0.13", - "solana-sdk 1.0.13", + "solana-logger 1.0.14", + "solana-sdk 1.0.14", ] [[package]] name = "solana-sys-tuner" -version = "1.0.13" +version = "1.0.14" 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.13", - "solana-logger 1.0.13", + "solana-clap-utils 1.0.14", + "solana-logger 1.0.14", "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)", @@ -4605,26 +4654,26 @@ dependencies = [ [[package]] name = "solana-transaction-status" -version = "1.0.13" +version = "1.0.14" 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)", "serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk 1.0.13", + "solana-sdk 1.0.14", ] [[package]] name = "solana-upload-perf" -version = "1.0.13" +version = "1.0.14" dependencies = [ "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-metrics 1.0.13", + "solana-metrics 1.0.14", ] [[package]] name = "solana-validator" -version = "1.0.13" +version = "1.0.14" 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)", @@ -4636,25 +4685,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.13", - "solana-client 1.0.13", - "solana-core 1.0.13", - "solana-faucet 1.0.13", - "solana-ledger 1.0.13", - "solana-logger 1.0.13", - "solana-metrics 1.0.13", - "solana-net-utils 1.0.13", - "solana-perf 1.0.13", - "solana-runtime 1.0.13", - "solana-sdk 1.0.13", - "solana-vote-program 1.0.13", - "solana-vote-signer 1.0.13", + "solana-clap-utils 1.0.14", + "solana-client 1.0.14", + "solana-core 1.0.14", + "solana-faucet 1.0.14", + "solana-ledger 1.0.14", + "solana-logger 1.0.14", + "solana-metrics 1.0.14", + "solana-net-utils 1.0.14", + "solana-perf 1.0.14", + "solana-runtime 1.0.14", + "solana-sdk 1.0.14", + "solana-vote-program 1.0.14", + "solana-vote-signer 1.0.14", "tar 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-vest-program" -version = "1.0.13" +version = "1.0.14" 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)", @@ -4662,15 +4711,15 @@ dependencies = [ "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-config-program 1.0.13", - "solana-runtime 1.0.13", - "solana-sdk 1.0.13", + "solana-config-program 1.0.14", + "solana-runtime 1.0.14", + "solana-sdk 1.0.14", "thiserror 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-vote-program" -version = "1.0.13" +version = "1.0.14" 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)", @@ -4678,15 +4727,15 @@ dependencies = [ "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-logger 1.0.13", - "solana-metrics 1.0.13", - "solana-sdk 1.0.13", + "solana-logger 1.0.14", + "solana-metrics 1.0.14", + "solana-sdk 1.0.14", "thiserror 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-vote-signer" -version = "1.0.13" +version = "1.0.14" 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)", @@ -4694,25 +4743,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.13", - "solana-metrics 1.0.13", - "solana-sdk 1.0.13", + "solana-clap-utils 1.0.14", + "solana-metrics 1.0.14", + "solana-sdk 1.0.14", ] [[package]] name = "solana-watchtower" -version = "1.0.13" +version = "1.0.14" 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.13", - "solana-cli-config 1.0.13", - "solana-client 1.0.13", - "solana-logger 1.0.13", - "solana-metrics 1.0.13", - "solana-sdk 1.0.13", + "solana-clap-utils 1.0.14", + "solana-cli-config 1.0.14", + "solana-client 1.0.14", + "solana-logger 1.0.14", + "solana-metrics 1.0.14", + "solana-sdk 1.0.14", ] [[package]] @@ -6274,6 +6323,7 @@ dependencies = [ "checksum colored 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6cdb90b60f2927f8d76139c72dbde7e10c3a2bc47c8594c9c7a66529f2687c03" "checksum combine 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1645a65a99c7c8d345761f4b75a6ffe5be3b3b27a93ee731fccc5050ba6be97c" "checksum compression 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3a82b366ae14633c67a1cbb4aa3738210a23f77d2868a0fd50faa23a956f9ec4" +"checksum console 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6728a28023f207181b193262711102bfbaf47cc9d13bc71d0736607ef8efe88c" "checksum console 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "45e0f3986890b3acbc782009e2629dfe2baa430ac091519ce3be26164a2ae6c0" "checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" "checksum cookie 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "888604f00b3db336d2af898ec3c1d5d0ddf5e6d462220f2ededc33a87ac4bbd5" @@ -6583,6 +6633,7 @@ dependencies = [ "checksum serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" "checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" "checksum serial_test 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f74862f16557830c73deefde614c906f8af0157e064b64f156e32a0b12d7114c" +"checksum serial_test 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fef5f7c7434b2f2c598adc6f9494648a1e41274a75c0ba4056f680ae0c117fd6" "checksum serial_test_derive 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3c188479c8b700998829c168d7a4c21032660b0dd2ed87a0b166c85811750740" "checksum serial_test_derive 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d08338d8024b227c62bd68a12c7c9883f5c66780abaef15c550dc56f46ee6515" "checksum sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68" diff --git a/Cargo.toml b/Cargo.toml index ab422aafd9..260038faee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,6 +48,7 @@ members = [ "sdk", "sdk-c", "scripts", + "stake-monitor", "sys-tuner", "transaction-status", "upload-perf", diff --git a/cli-config/src/config.rs b/cli-config/src/config.rs index 6503dc4b5e..876ffc01bd 100644 --- a/cli-config/src/config.rs +++ b/cli-config/src/config.rs @@ -1,10 +1,6 @@ // Wallet settings that can be configured for long-term use use serde_derive::{Deserialize, Serialize}; -use std::{ - fs::{create_dir_all, File}, - io::{self, Write}, - path::Path, -}; +use std::io; use url::Url; lazy_static! { @@ -46,23 +42,11 @@ impl Default for Config { impl Config { pub fn load(config_file: &str) -> Result { - let file = File::open(config_file.to_string())?; - let config = serde_yaml::from_reader(file) - .map_err(|err| io::Error::new(io::ErrorKind::Other, format!("{:?}", err)))?; - Ok(config) + crate::load_config_file(config_file) } pub fn save(&self, config_file: &str) -> Result<(), io::Error> { - let serialized = serde_yaml::to_string(self) - .map_err(|err| io::Error::new(io::ErrorKind::Other, format!("{:?}", err)))?; - - if let Some(outdir) = Path::new(&config_file).parent() { - create_dir_all(outdir)?; - } - let mut file = File::create(config_file)?; - file.write_all(&serialized.into_bytes())?; - - Ok(()) + crate::save_config_file(self, config_file) } pub fn compute_websocket_url(json_rpc_url: &str) -> String { diff --git a/cli-config/src/lib.rs b/cli-config/src/lib.rs index 80853fe50d..435e9762c3 100644 --- a/cli-config/src/lib.rs +++ b/cli-config/src/lib.rs @@ -3,3 +3,37 @@ extern crate lazy_static; mod config; pub use config::{Config, CONFIG_FILE}; + +use std::{ + fs::{create_dir_all, File}, + io::{self, Write}, + path::Path, +}; + +pub fn load_config_file(config_file: P) -> Result +where + T: serde::de::DeserializeOwned, + P: AsRef, +{ + let file = File::open(config_file)?; + let config = serde_yaml::from_reader(file) + .map_err(|err| io::Error::new(io::ErrorKind::Other, format!("{:?}", err)))?; + Ok(config) +} + +pub fn save_config_file(config: &T, config_file: P) -> Result<(), io::Error> +where + T: serde::ser::Serialize, + P: AsRef, +{ + let serialized = serde_yaml::to_string(config) + .map_err(|err| io::Error::new(io::ErrorKind::Other, format!("{:?}", err)))?; + + if let Some(outdir) = config_file.as_ref().parent() { + create_dir_all(outdir)?; + } + let mut file = File::create(config_file)?; + file.write_all(&serialized.into_bytes())?; + + Ok(()) +} diff --git a/client/src/rpc_client.rs b/client/src/rpc_client.rs index 06de0485d8..d95d562614 100644 --- a/client/src/rpc_client.rs +++ b/client/src/rpc_client.rs @@ -27,7 +27,7 @@ use solana_sdk::{ signers::Signers, transaction::{self, Transaction, TransactionError}, }; -use solana_transaction_status::{ConfirmedBlock, TransactionStatus}; +use solana_transaction_status::{ConfirmedBlock, TransactionEncoding, TransactionStatus}; use solana_vote_program::vote_state::MAX_LOCKOUT_HISTORY; use std::{ error, @@ -177,9 +177,17 @@ impl RpcClient { } pub fn get_confirmed_block(&self, slot: Slot) -> ClientResult { + self.get_confirmed_block_with_encoding(slot, TransactionEncoding::Json) + } + + pub fn get_confirmed_block_with_encoding( + &self, + slot: Slot, + encoding: TransactionEncoding, + ) -> ClientResult { let response = self .client - .send(&RpcRequest::GetConfirmedBlock, json!([slot]), 0) + .send(&RpcRequest::GetConfirmedBlock, json!([slot, encoding]), 0) .map_err(|err| err.into_with_command("GetConfirmedBlock"))?; serde_json::from_value(response) diff --git a/scripts/cargo-install-all.sh b/scripts/cargo-install-all.sh index 0e35cbae2d..54f2b007b2 100755 --- a/scripts/cargo-install-all.sh +++ b/scripts/cargo-install-all.sh @@ -95,6 +95,7 @@ else solana-ledger-tool solana-log-analyzer solana-net-shaper + solana-stake-monitor solana-sys-tuner solana-validator solana-watchtower diff --git a/stake-monitor/.gitignore b/stake-monitor/.gitignore new file mode 100644 index 0000000000..5404b132db --- /dev/null +++ b/stake-monitor/.gitignore @@ -0,0 +1,2 @@ +/target/ +/farf/ diff --git a/stake-monitor/Cargo.toml b/stake-monitor/Cargo.toml new file mode 100644 index 0000000000..cf23bdc7bd --- /dev/null +++ b/stake-monitor/Cargo.toml @@ -0,0 +1,35 @@ +[package] +authors = ["Solana Maintainers "] +edition = "2018" +name = "solana-stake-monitor" +description = "Blockchain, Rebuilt for Scale" +version = "1.0.14" +repository = "https://github.com/solana-labs/solana" +license = "Apache-2.0" +homepage = "https://solana.com/" + +[dependencies] +clap = "2.33.0" +console = "0.10.0" +log = "0.4.8" +serde = "1.0.105" +serde_yaml = "0.8.11" +solana-clap-utils = { path = "../clap-utils", version = "1.0.14" } +solana-cli-config = { path = "../cli-config", version = "1.0.14" } +solana-client = { path = "../client", version = "1.0.14" } +solana-logger = { path = "../logger", version = "1.0.14" } +solana-metrics = { path = "../metrics", version = "1.0.14" } +solana-sdk = { path = "../sdk", version = "1.0.14" } +solana-stake-program = { path = "../programs/stake", version = "1.0.14" } +solana-transaction-status = { path = "../transaction-status", version = "1.0.14" } + +[dev-dependencies] +serial_test = "0.4.0" +serial_test_derive = "0.4.0" +solana-local-cluster = { path = "../local-cluster", version = "1.0.14" } +solana-core = { path = "../core", version = "1.0.14" } +tempfile = "3.1.0" + +[[bin]] +name = "solana-stake-monitor" +path = "src/main.rs" diff --git a/stake-monitor/README.md b/stake-monitor/README.md new file mode 100644 index 0000000000..736f274752 --- /dev/null +++ b/stake-monitor/README.md @@ -0,0 +1,14 @@ +## Overview +`solana-stake-monitor` is a utility that scans all transactions to ensure that stake accounts remain in compliance with the following rules: + +1. The stake account must be created after genesis +1. The "compliant balance" of a stake account is set upon stake account initialization, system transfers of additional funds into a compliant stake account are excluded from the "compliant balance" +1. The stake account cannot have a lockup or custodian +1. Withdrawing funds from the stake account trigger non-compliance +1. Stake accounts split from a compliant stake account remain compliant, and the "compliant balance" is adjusted accordingly for the original stake account + +In terms of `solana` command-line subcommands: +* `create-stake-account`: Creates a compliant stake account provided the `--lockup-date`, `--lockup-epoch`, or `--custodian` options are not specified +* `delegate-stake` / `deactivate-stake` / `stake-authorize` / `split-stake`: These commands do not affect compliance +* `withdraw-stake` / `stake-set-lockup`: These commands will cause non-compliance +* `transfer`: Any additional funds transferred after `create-stake-account` are excluded from the "compliant balance" diff --git a/stake-monitor/src/lib.rs b/stake-monitor/src/lib.rs new file mode 100644 index 0000000000..16c3e94e7b --- /dev/null +++ b/stake-monitor/src/lib.rs @@ -0,0 +1,297 @@ +use log::*; +use serde::{Deserialize, Serialize}; +use solana_client::{client_error::Result as ClientResult, rpc_client::RpcClient}; +use solana_metrics::{datapoint_error, datapoint_info}; +use solana_sdk::{clock::Slot, program_utils::limited_deserialize, transaction::Transaction}; +use solana_stake_program::{stake_instruction::StakeInstruction, stake_state::Lockup}; +use solana_transaction_status::{ConfirmedBlock, TransactionEncoding, TransactionStatusMeta}; +use std::{collections::HashMap, thread::sleep, time::Duration}; + +pub type PubkeyString = String; +pub type SignatureString = String; + +#[derive(Serialize, Deserialize, Debug, PartialEq)] +pub enum StakeAccountOperation { + Initialize, + Withdraw, + SplitSource, + SplitDestination, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct StakeAccountTransactionInfo { + pub op: StakeAccountOperation, + pub slot: Slot, // Slot the transaction completed in + pub signature: SignatureString, // Transaction signature +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct StakeAccountInfo { + pub compliant_since: Option, // The slot when the account was first in compliance + pub lamports: u64, // Account balance + pub transactions: Vec, // Transactions affecting the account +} + +#[derive(Serialize, Deserialize, Default, Debug)] +pub struct StakeAccountsInfo { + pub slot: Slot, // Latest processed slot + pub account_info: HashMap, +} + +fn process_transaction( + slot: Slot, + transaction: &Transaction, + meta: &TransactionStatusMeta, + stake_accounts: &mut HashMap, +) { + let mut last_instruction = true; + let message = &transaction.message; + for instruction in message.instructions.iter().rev() { + let program_pubkey = message.account_keys[instruction.program_id_index as usize]; + if program_pubkey != solana_stake_program::id() { + continue; + } + + // Only look for stake instructions in the last instruction of a + // transaction. This ensures that the `meta.post_balances` for the + // transaction reflects the account balances after the stake instruction + // executed. At this time the `solana` cli will only create transactions with the stake + // instruction as the last instruction. + if !last_instruction { + datapoint_error!( + "stake-monitor-failure", + ("slot", slot, i64), + ("err", "Stake instruction ignored", String) + ); + continue; + } + last_instruction = false; + + match limited_deserialize::(&instruction.data) { + Err(err) => datapoint_error!( + "stake-monitor-failure", + ("slot", slot, i64), + ( + "err", + format!("Failed to deserialize stake instruction: {}", err), + String + ) + ), + Ok(stake_instruction) => { + let signature = transaction.signatures[0].to_string(); + + match stake_instruction { + StakeInstruction::Initialize(_authorized, lockup) => { + // The initialized stake account is at instruction account 0 + let stake_account_index = instruction.accounts[0] as usize; + + let stake_pubkey = message.account_keys[stake_account_index].to_string(); + + // The amount staked is the stake account's post balance + let lamports = meta.post_balances[stake_account_index]; + + stake_accounts.insert( + stake_pubkey, + StakeAccountInfo { + compliant_since: if lockup != Lockup::default() { + None // Initialize with a lockup or custodian is non-compliant + } else { + Some(slot) + }, + lamports, + transactions: vec![StakeAccountTransactionInfo { + op: StakeAccountOperation::Initialize, + slot, + signature, + }], + }, + ); + } + StakeInstruction::Authorize(_, _) + | StakeInstruction::DelegateStake + | StakeInstruction::Deactivate => { + // These instructions are always permitted + } + StakeInstruction::Split(lamports) => { + // Split is permitted and propagates compliance + let source_stake_account_index = instruction.accounts[0] as usize; + let split_stake_account_index = instruction.accounts[1] as usize; + + let source_stake_pubkey = + message.account_keys[source_stake_account_index].to_string(); + let split_stake_pubkey = + message.account_keys[split_stake_account_index].to_string(); + + if let Some(mut source_stake_account_info) = + stake_accounts.get_mut(&source_stake_pubkey) + { + if source_stake_account_info.compliant_since.is_some() { + source_stake_account_info.transactions.push( + StakeAccountTransactionInfo { + op: StakeAccountOperation::SplitSource, + slot, + signature: signature.clone(), + }, + ); + source_stake_account_info.lamports -= lamports; + + let split_stake_account_info = StakeAccountInfo { + compliant_since: source_stake_account_info.compliant_since, + lamports, + transactions: vec![StakeAccountTransactionInfo { + op: StakeAccountOperation::SplitDestination, + slot, + signature, + }], + }; + stake_accounts.insert(split_stake_pubkey, split_stake_account_info); + } + } + } + StakeInstruction::Withdraw(_) => { + // Withdrawing is not permitted + + let stake_account_index = instruction.accounts[0] as usize; + let stake_pubkey = message.account_keys[stake_account_index].to_string(); + + if let Some(mut stake_account_info) = stake_accounts.get_mut(&stake_pubkey) + { + if stake_account_info.compliant_since.is_some() { + stake_account_info.compliant_since = None; + stake_account_info + .transactions + .push(StakeAccountTransactionInfo { + op: StakeAccountOperation::Withdraw, + slot, + signature, + }); + } + } + } + StakeInstruction::SetLockup(_lockup_args) => { + // No processing is required because SetLockup requires a custodian key, + // and this is already blocked in the StakeInstruction::Initialize + // processing + } + } + } + } + } +} + +fn process_confirmed_block( + slot: Slot, + confirmed_block: ConfirmedBlock, + stake_accounts: &mut HashMap, +) { + for rpc_transaction in confirmed_block.transactions { + match rpc_transaction.meta { + None => { + datapoint_error!( + "stake-monitor-failure", + ("slot", slot, i64), + ("err", "Transaction meta not available", String) + ); + } + Some(meta) => { + if meta.status.is_ok() { + if let Some(transaction) = rpc_transaction.transaction.decode() { + if transaction.verify().is_ok() { + process_transaction(slot, &transaction, &meta, stake_accounts); + } else { + datapoint_error!( + "stake-monitor-failure", + ("slot", slot, i64), + ("err", "Transaction signature verification failed", String) + ); + } + } + } + } + } + } +} + +fn load_blocks( + rpc_client: &RpcClient, + start_slot: Slot, + end_slot: Slot, +) -> ClientResult> { + info!( + "Loading confirmed blocks between slots: {} - {}", + start_slot, end_slot + ); + + let slots = rpc_client.get_confirmed_blocks(start_slot, Some(end_slot))?; + + let mut blocks = vec![]; + for slot in slots.into_iter() { + let block = + rpc_client.get_confirmed_block_with_encoding(slot, TransactionEncoding::Binary)?; + blocks.push((slot, block)); + } + Ok(blocks) +} + +pub fn process_slots( + rpc_client: &RpcClient, + stake_accounts_info: &mut StakeAccountsInfo, + batch_size: u64, +) { + let end_slot = stake_accounts_info.slot + batch_size; + loop { + let start_slot = stake_accounts_info.slot + 1; + info!("start_slot:{} - end_slot:{}", start_slot, end_slot); + if start_slot >= end_slot { + break; + } + let latest_available_slot = rpc_client.get_slot().unwrap_or_else(|err| { + datapoint_error!( + "stake-monitor-failure", + ("err", format!("get_slot() failed: {}", err), String) + ); + 0 + }); + + if stake_accounts_info.slot >= latest_available_slot { + info!( + "Waiting for a slot greater than {}...", + stake_accounts_info.slot + ); + sleep(Duration::from_secs(5)); + continue; + } + + match load_blocks(&rpc_client, start_slot, end_slot) { + Ok(blocks) => { + info!("Loaded {} blocks", blocks.len()); + + if blocks.is_empty() && end_slot < latest_available_slot { + stake_accounts_info.slot = end_slot; + } else { + for (slot, block) in blocks.into_iter() { + process_confirmed_block(slot, block, &mut stake_accounts_info.account_info); + stake_accounts_info.slot = slot; + } + } + datapoint_info!( + "stake-monitor-slot", + ("slot", stake_accounts_info.slot, i64) + ); + } + Err(err) => { + datapoint_error!( + "stake-monitor-failure", + ( + "err", + format!( + "failed to get blocks in range ({},{}): {}", + start_slot, end_slot, err + ), + String + ) + ); + } + } + } +} diff --git a/stake-monitor/src/main.rs b/stake-monitor/src/main.rs new file mode 100644 index 0000000000..45d9a0b94d --- /dev/null +++ b/stake-monitor/src/main.rs @@ -0,0 +1,188 @@ +use clap::{ + crate_description, crate_name, value_t, value_t_or_exit, App, AppSettings, Arg, SubCommand, +}; +use console::Emoji; +use log::*; +use solana_clap_utils::{ + input_parsers::pubkey_of, + input_validators::{is_pubkey, is_slot, is_url}, +}; +use solana_client::rpc_client::RpcClient; +use solana_metrics::datapoint_error; +use solana_sdk::{clock::Slot, native_token::lamports_to_sol, pubkey::Pubkey}; +use solana_stake_monitor::*; +use std::{fs, io, process}; + +fn load_stake_accounts_info(data_file: &str) -> StakeAccountsInfo { + let data_file_new = data_file.to_owned() + "new"; + let stake_accounts_info = solana_cli_config::load_config_file(&data_file_new) + .or_else(|_| solana_cli_config::load_config_file(data_file)) + .unwrap_or_default(); + + // Ensure `data_file` always exists + save_stake_accounts_info(data_file, &stake_accounts_info).expect("save_stake_accounts_info"); + + stake_accounts_info +} + +fn save_stake_accounts_info( + data_file: &str, + stake_accounts_info: &StakeAccountsInfo, +) -> io::Result<()> { + let data_file_new = data_file.to_owned() + "new"; + solana_cli_config::save_config_file(&stake_accounts_info, &data_file_new)?; + let _ = fs::remove_file(data_file); + fs::rename(&data_file_new, data_file) +} + +fn command_record(data_file: String, json_rpc_url: String, first_slot: Slot, batch_size: u64) { + let mut stake_accounts_info = load_stake_accounts_info(&data_file); + + info!("RPC URL: {}", json_rpc_url); + let rpc_client = RpcClient::new(json_rpc_url); + if stake_accounts_info.slot < first_slot { + stake_accounts_info.slot = first_slot; + } + loop { + process_slots(&rpc_client, &mut stake_accounts_info, batch_size); + save_stake_accounts_info(&data_file, &stake_accounts_info).unwrap_or_else(|err| { + datapoint_error!( + "stake-monitor-failure", + ( + "err", + format!("failed to save stake_accounts_info: {}", err), + String + ) + ); + }); + } +} + +fn command_check(data_file: String, stake_account_pubkey: Pubkey) { + let stake_accounts_info = load_stake_accounts_info(&data_file); + + if let Some(stake_account_info) = stake_accounts_info + .account_info + .get(&stake_account_pubkey.to_string()) + { + if let Some(slot) = stake_account_info.compliant_since { + println!( + "{}Stake account compliant since slot {} with a balance of {} SOL", + Emoji("✅ ", ""), + slot, + lamports_to_sol(stake_account_info.lamports) + ); + process::exit(0); + } else { + eprintln!( + "{}Stake account not compliant due to: {:?}", + Emoji("❌ ", ""), + stake_account_info.transactions.last().unwrap() + ); + process::exit(1); + } + } else { + eprintln!("{} Unknown stake account", Emoji("⚠️ ", "")); + process::exit(1); + } +} + +fn main() { + solana_logger::setup_with_default("solana=info"); + solana_metrics::set_panic_hook("stake-monitor"); + + let matches = App::new(crate_name!()) + .about(crate_description!()) + .version(solana_clap_utils::version!()) + .setting(AppSettings::SubcommandRequiredElseHelp) + .arg( + Arg::with_name("data_file") + .long("data-file") + .value_name("PATH") + .takes_value(true) + .default_value("stake-info.yml") + .global(true) + .help( + "Output YAML file that receives the information for all stake accounts.\ + This file is updated atomically after each batch of slots is processed.", + ), + ) + .subcommand( + SubCommand::with_name("record") + .about("Monitor all Cluster transactions for state account compliance") + .arg({ + let arg = Arg::with_name("config_file") + .short("C") + .long("config") + .value_name("PATH") + .takes_value(true) + .help("Configuration file to use"); + if let Some(ref config_file) = *solana_cli_config::CONFIG_FILE { + arg.default_value(&config_file) + } else { + arg + } + }) + .arg( + Arg::with_name("json_rpc_url") + .long("url") + .value_name("URL") + .takes_value(true) + .validator(is_url) + .help("JSON RPC URL for the cluster"), + ) + .arg( + Arg::with_name("first_slot") + .long("--first-slot") + .value_name("SLOT") + .validator(is_slot) + .takes_value(true) + .default_value("0") + .help("Don't process slots lower than this value"), + ) + .arg( + Arg::with_name("batch_size") + .long("--batch-size") + .value_name("NUMBER") + .takes_value(true) + .default_value("10") + .help("Process up to this many slots in one batch"), + ), + ) + .subcommand( + SubCommand::with_name("check") + .about("Check if a state account is in compliance") + .arg( + Arg::with_name("stake_account_pubkey") + .index(1) + .value_name("ADDRESS") + .validator(is_pubkey) + .required(true) + .help("Stake account address"), + ), + ) + .get_matches(); + + let data_file = value_t_or_exit!(matches, "data_file", String); + + match matches.subcommand() { + ("record", Some(matches)) => { + let batch_size = value_t_or_exit!(matches, "batch_size", u64); + let first_slot = value_t_or_exit!(matches, "first_slot", Slot); + let json_rpc_url = value_t!(matches, "json_rpc_url", String).unwrap_or_else(|_| { + let config = if let Some(config_file) = matches.value_of("config_file") { + solana_cli_config::Config::load(config_file).unwrap_or_default() + } else { + solana_cli_config::Config::default() + }; + config.json_rpc_url + }); + command_record(data_file, json_rpc_url, first_slot, batch_size); + } + ("check", Some(matches)) => { + let stake_account_pubkey = pubkey_of(&matches, "stake_account_pubkey").unwrap(); + command_check(data_file, stake_account_pubkey); + } + _ => unreachable!(), + } +} diff --git a/transaction-status/src/lib.rs b/transaction-status/src/lib.rs index 3a410340d8..203f01e9d3 100644 --- a/transaction-status/src/lib.rs +++ b/transaction-status/src/lib.rs @@ -125,4 +125,13 @@ impl EncodedTransaction { EncodedTransaction::Binary(bs58::encode(serialize(&transaction).unwrap()).into_string()) } } + pub fn decode(&self) -> Option { + match self { + EncodedTransaction::Json(_) => None, + EncodedTransaction::Binary(blob) => bs58::decode(blob) + .into_vec() + .ok() + .and_then(|bytes| bincode::deserialize(&bytes).ok()), + } + } }