diff --git a/.github/scripts/downstream-project-spl-common.sh b/.github/scripts/downstream-project-spl-common.sh index c6dcfaca007867..861be12c7d1a45 100644 --- a/.github/scripts/downstream-project-spl-common.sh +++ b/.github/scripts/downstream-project-spl-common.sh @@ -22,3 +22,6 @@ if semverGT "$project_used_solana_version" "$SOLANA_VER"; then fi ./patch.crates-io.sh "$SOLANA_DIR" + +# anza migration stopgap. can be removed when agave is fully recommended for public usage. +sed -i 's/solana-geyser-plugin-interface/agave-geyser-plugin-interface/g' ./Cargo.toml diff --git a/.github/workflows/release-artifacts.yml b/.github/workflows/release-artifacts.yml index d8e22c42ce5da8..45be181c3ce9e1 100644 --- a/.github/workflows/release-artifacts.yml +++ b/.github/workflows/release-artifacts.yml @@ -70,7 +70,7 @@ jobs: mkdir -p "windows-release/$FOLDER_NAME" cp -v "solana-release-x86_64-pc-windows-msvc.tar.bz2" "windows-release/$FOLDER_NAME/" cp -v "solana-release-x86_64-pc-windows-msvc.yml" "windows-release/$FOLDER_NAME/" - cp -v "solana-install-init-x86_64-pc-windows-msvc"* "windows-release/$FOLDER_NAME" + cp -v "agave-install-init-x86_64-pc-windows-msvc"* "windows-release/$FOLDER_NAME" - name: Upload Artifacts if: ${{ steps.build.outputs.channel != '' || steps.build.outputs.tag != '' }} diff --git a/Cargo.lock b/Cargo.lock index 49c4372bb316c1..bdb501fc1f9ad0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -63,6 +63,216 @@ dependencies = [ "zeroize", ] +[[package]] +name = "agave-cargo-registry" +version = "1.18.0" +dependencies = [ + "clap 2.33.3", + "flate2", + "hex", + "hyper", + "log", + "rustc_version 0.4.0", + "serde", + "serde_json", + "sha2 0.10.8", + "solana-clap-utils", + "solana-cli", + "solana-cli-config", + "solana-cli-output", + "solana-logger", + "solana-remote-wallet", + "solana-rpc-client", + "solana-rpc-client-api", + "solana-sdk", + "solana-version", + "tar", + "tempfile", + "tokio", + "toml 0.8.10", +] + +[[package]] +name = "agave-geyser-plugin-interface" +version = "1.18.0" +dependencies = [ + "log", + "solana-sdk", + "solana-transaction-status", + "thiserror", +] + +[[package]] +name = "agave-install" +version = "1.18.0" +dependencies = [ + "atty", + "bincode", + "bzip2", + "chrono", + "clap 2.33.3", + "console", + "crossbeam-channel", + "ctrlc", + "dirs-next", + "indicatif", + "lazy_static", + "nix 0.26.4", + "reqwest", + "scopeguard", + "semver 1.0.22", + "serde", + "serde_yaml 0.8.26", + "serde_yaml 0.9.32", + "solana-clap-utils", + "solana-config-program", + "solana-logger", + "solana-rpc-client", + "solana-sdk", + "solana-version", + "tar", + "tempfile", + "url 2.5.0", + "winapi 0.3.9", + "winreg", +] + +[[package]] +name = "agave-ledger-tool" +version = "1.18.0" +dependencies = [ + "assert_cmd", + "bs58", + "bytecount", + "chrono", + "clap 2.33.3", + "crossbeam-channel", + "csv", + "dashmap", + "futures 0.3.30", + "histogram", + "itertools", + "log", + "num_cpus", + "regex", + "serde", + "serde_json", + "signal-hook", + "solana-account-decoder", + "solana-accounts-db", + "solana-bpf-loader-program", + "solana-clap-utils", + "solana-cli-output", + "solana-core", + "solana-cost-model", + "solana-entry", + "solana-geyser-plugin-manager", + "solana-gossip", + "solana-ledger", + "solana-logger", + "solana-measure", + "solana-program-runtime", + "solana-rpc", + "solana-runtime", + "solana-sdk", + "solana-stake-program", + "solana-storage-bigtable", + "solana-streamer", + "solana-svm", + "solana-transaction-status", + "solana-unified-scheduler-pool", + "solana-version", + "solana-vote-program", + "solana_rbpf", + "thiserror", + "tikv-jemallocator", + "tokio", +] + +[[package]] +name = "agave-validator" +version = "1.18.0" +dependencies = [ + "agave-geyser-plugin-interface", + "chrono", + "clap 2.33.3", + "console", + "core_affinity", + "crossbeam-channel", + "fd-lock", + "indicatif", + "itertools", + "jsonrpc-core", + "jsonrpc-core-client", + "jsonrpc-derive", + "jsonrpc-ipc-server", + "jsonrpc-server-utils", + "lazy_static", + "libc", + "libloading", + "log", + "num_cpus", + "rand 0.8.5", + "rayon", + "serde", + "serde_json", + "serde_yaml 0.9.32", + "signal-hook", + "solana-account-decoder", + "solana-accounts-db", + "solana-clap-utils", + "solana-cli-config", + "solana-core", + "solana-download-utils", + "solana-entry", + "solana-faucet", + "solana-genesis-utils", + "solana-geyser-plugin-manager", + "solana-gossip", + "solana-ledger", + "solana-logger", + "solana-metrics", + "solana-net-utils", + "solana-perf", + "solana-poh", + "solana-rpc", + "solana-rpc-client", + "solana-rpc-client-api", + "solana-runtime", + "solana-sdk", + "solana-send-transaction-service", + "solana-storage-bigtable", + "solana-streamer", + "solana-svm", + "solana-test-validator", + "solana-tpu-client", + "solana-version", + "solana-vote-program", + "spl-token-2022", + "symlink", + "thiserror", + "tikv-jemallocator", +] + +[[package]] +name = "agave-watchtower" +version = "1.18.0" +dependencies = [ + "clap 2.33.3", + "humantime", + "log", + "solana-clap-utils", + "solana-cli-config", + "solana-cli-output", + "solana-logger", + "solana-metrics", + "solana-notifier", + "solana-rpc-client", + "solana-rpc-client-api", + "solana-sdk", + "solana-version", +] + [[package]] name = "ahash" version = "0.7.6" @@ -6010,6 +6220,7 @@ dependencies = [ ] [[package]] +<<<<<<< HEAD name = "solana-geyser-plugin-interface" version = "1.17.23" dependencies = [ @@ -6020,9 +6231,12 @@ dependencies = [ ] [[package]] +======= +>>>>>>> e1e36d2fea ([anza migration] rename crates (#10)) name = "solana-geyser-plugin-manager" version = "1.17.23" dependencies = [ + "agave-geyser-plugin-interface", "bs58", "crossbeam-channel", "json5", @@ -6033,7 +6247,6 @@ dependencies = [ "serde_json", "solana-accounts-db", "solana-entry", - "solana-geyser-plugin-interface", "solana-ledger", "solana-measure", "solana-metrics", @@ -6096,6 +6309,7 @@ dependencies = [ ] [[package]] +<<<<<<< HEAD name = "solana-install" version = "1.17.23" dependencies = [ @@ -6131,6 +6345,8 @@ dependencies = [ ] [[package]] +======= +>>>>>>> e1e36d2fea ([anza migration] rename crates (#10)) name = "solana-keygen" version = "1.17.23" dependencies = [ @@ -6216,6 +6432,7 @@ dependencies = [ ] [[package]] +<<<<<<< HEAD name = "solana-ledger-tool" version = "1.17.23" dependencies = [ @@ -6265,6 +6482,8 @@ dependencies = [ ] [[package]] +======= +>>>>>>> e1e36d2fea ([anza migration] rename crates (#10)) name = "solana-loader-v4-program" version = "1.17.23" dependencies = [ @@ -7360,6 +7579,7 @@ dependencies = [ ] [[package]] +<<<<<<< HEAD name = "solana-validator" version = "1.17.23" dependencies = [ @@ -7424,6 +7644,8 @@ dependencies = [ ] [[package]] +======= +>>>>>>> e1e36d2fea ([anza migration] rename crates (#10)) name = "solana-version" version = "1.17.23" dependencies = [ @@ -7480,6 +7702,7 @@ dependencies = [ ] [[package]] +<<<<<<< HEAD name = "solana-watchtower" version = "1.17.23" dependencies = [ @@ -7496,6 +7719,27 @@ dependencies = [ "solana-rpc-client-api", "solana-sdk", "solana-version", +======= +name = "solana-wen-restart" +version = "1.18.0" +dependencies = [ + "log", + "prost", + "prost-build", + "prost-types", + "protobuf-src", + "rustc_version 0.4.0", + "serial_test", + "solana-entry", + "solana-gossip", + "solana-ledger", + "solana-logger", + "solana-program", + "solana-runtime", + "solana-sdk", + "solana-streamer", + "solana-vote-program", +>>>>>>> e1e36d2fea ([anza migration] rename crates (#10)) ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index b40dbd3510bc20..a563a01cf82c92 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -298,6 +298,90 @@ siphasher = "0.3.11" smpl_jwt = "0.7.1" socket2 = "0.5.4" soketto = "0.7" +<<<<<<< HEAD +======= +solana-account-decoder = { path = "account-decoder", version = "=1.18.0" } +solana-accounts-db = { path = "accounts-db", version = "=1.18.0" } +solana-address-lookup-table-program = { path = "programs/address-lookup-table", version = "=1.18.0" } +solana-banks-client = { path = "banks-client", version = "=1.18.0" } +solana-banks-interface = { path = "banks-interface", version = "=1.18.0" } +solana-banks-server = { path = "banks-server", version = "=1.18.0" } +solana-bench-tps = { path = "bench-tps", version = "=1.18.0" } +solana-bloom = { path = "bloom", version = "=1.18.0" } +solana-bpf-loader-program = { path = "programs/bpf_loader", version = "=1.18.0" } +solana-bucket-map = { path = "bucket_map", version = "=1.18.0" } +agave-cargo-registry = { path = "cargo-registry", version = "=1.18.0" } +solana-clap-utils = { path = "clap-utils", version = "=1.18.0" } +solana-clap-v3-utils = { path = "clap-v3-utils", version = "=1.18.0" } +solana-cli = { path = "cli", version = "=1.18.0" } +solana-cli-config = { path = "cli-config", version = "=1.18.0" } +solana-cli-output = { path = "cli-output", version = "=1.18.0" } +solana-client = { path = "client", version = "=1.18.0" } +solana-compute-budget-program = { path = "programs/compute-budget", version = "=1.18.0" } +solana-config-program = { path = "programs/config", version = "=1.18.0" } +solana-connection-cache = { path = "connection-cache", version = "=1.18.0", default-features = false } +solana-core = { path = "core", version = "=1.18.0" } +solana-cost-model = { path = "cost-model", version = "=1.18.0" } +solana-download-utils = { path = "download-utils", version = "=1.18.0" } +solana-entry = { path = "entry", version = "=1.18.0" } +solana-faucet = { path = "faucet", version = "=1.18.0" } +solana-frozen-abi = { path = "frozen-abi", version = "=1.18.0" } +solana-frozen-abi-macro = { path = "frozen-abi/macro", version = "=1.18.0" } +solana-genesis = { path = "genesis", version = "=1.18.0" } +solana-genesis-utils = { path = "genesis-utils", version = "=1.18.0" } +agave-geyser-plugin-interface = { path = "geyser-plugin-interface", version = "=1.18.0" } +solana-geyser-plugin-manager = { path = "geyser-plugin-manager", version = "=1.18.0" } +solana-gossip = { path = "gossip", version = "=1.18.0" } +solana-ledger = { path = "ledger", version = "=1.18.0" } +solana-loader-v4-program = { path = "programs/loader-v4", version = "=1.18.0" } +solana-local-cluster = { path = "local-cluster", version = "=1.18.0" } +solana-logger = { path = "logger", version = "=1.18.0" } +solana-measure = { path = "measure", version = "=1.18.0" } +solana-merkle-tree = { path = "merkle-tree", version = "=1.18.0" } +solana-metrics = { path = "metrics", version = "=1.18.0" } +solana-net-utils = { path = "net-utils", version = "=1.18.0" } +solana-nohash-hasher = "0.2.1" +solana-notifier = { path = "notifier", version = "=1.18.0" } +solana-perf = { path = "perf", version = "=1.18.0" } +solana-poh = { path = "poh", version = "=1.18.0" } +solana-program = { path = "sdk/program", version = "=1.18.0" } +solana-program-runtime = { path = "program-runtime", version = "=1.18.0" } +solana-program-test = { path = "program-test", version = "=1.18.0" } +solana-pubsub-client = { path = "pubsub-client", version = "=1.18.0" } +solana-quic-client = { path = "quic-client", version = "=1.18.0" } +solana-rayon-threadlimit = { path = "rayon-threadlimit", version = "=1.18.0" } +solana-remote-wallet = { path = "remote-wallet", version = "=1.18.0", default-features = false } +solana-unified-scheduler-logic = { path = "unified-scheduler-logic", version = "=1.18.0" } +solana-unified-scheduler-pool = { path = "unified-scheduler-pool", version = "=1.18.0" } +solana-rpc = { path = "rpc", version = "=1.18.0" } +solana-rpc-client = { path = "rpc-client", version = "=1.18.0", default-features = false } +solana-rpc-client-api = { path = "rpc-client-api", version = "=1.18.0" } +solana-rpc-client-nonce-utils = { path = "rpc-client-nonce-utils", version = "=1.18.0" } +solana-runtime = { path = "runtime", version = "=1.18.0" } +solana-runtime-transaction = { path = "runtime-transaction", version = "=1.18.0" } +solana-sdk = { path = "sdk", version = "=1.18.0" } +solana-sdk-macro = { path = "sdk/macro", version = "=1.18.0" } +solana-send-transaction-service = { path = "send-transaction-service", version = "=1.18.0" } +solana-stake-program = { path = "programs/stake", version = "=1.18.0" } +solana-storage-bigtable = { path = "storage-bigtable", version = "=1.18.0" } +solana-storage-proto = { path = "storage-proto", version = "=1.18.0" } +solana-streamer = { path = "streamer", version = "=1.18.0" } +solana-svm = { path = "svm", version = "=1.18.0" } +solana-system-program = { path = "programs/system", version = "=1.18.0" } +solana-test-validator = { path = "test-validator", version = "=1.18.0" } +solana-thin-client = { path = "thin-client", version = "=1.18.0" } +solana-tpu-client = { path = "tpu-client", version = "=1.18.0", default-features = false } +solana-transaction-status = { path = "transaction-status", version = "=1.18.0" } +solana-turbine = { path = "turbine", version = "=1.18.0" } +solana-udp-client = { path = "udp-client", version = "=1.18.0" } +solana-version = { path = "version", version = "=1.18.0" } +solana-vote = { path = "vote", version = "=1.18.0" } +solana-vote-program = { path = "programs/vote", version = "=1.18.0" } +solana-wen-restart = { path = "wen-restart", version = "=1.18.0" } +solana-zk-keygen = { path = "zk-keygen", version = "=1.18.0" } +solana-zk-token-proof-program = { path = "programs/zk-token-proof", version = "=1.18.0" } +solana-zk-token-sdk = { path = "zk-token-sdk", version = "=1.18.0" } +>>>>>>> e1e36d2fea ([anza migration] rename crates (#10)) solana_rbpf = "=0.8.0" solana-account-decoder = { path = "account-decoder", version = "=1.17.23" } solana-accounts-db = { path = "accounts-db", version = "=1.17.23" } diff --git a/cargo-registry/Cargo.toml b/cargo-registry/Cargo.toml new file mode 100644 index 00000000000000..395493a8e85f00 --- /dev/null +++ b/cargo-registry/Cargo.toml @@ -0,0 +1,45 @@ +[package] +name = "agave-cargo-registry" +description = "Solana cargo registry" +documentation = "https://docs.rs/agave-cargo-registry" +version = { workspace = true } +authors = { workspace = true } +repository = { workspace = true } +homepage = { workspace = true } +license = { workspace = true } +edition = { workspace = true } + +[dependencies] +clap = { workspace = true } +flate2 = { workspace = true } +hex = { workspace = true } +hyper = { workspace = true, features = ["full"] } +log = { workspace = true } +serde = { workspace = true, features = ["derive"] } +serde_json = { workspace = true } +sha2 = { workspace = true } +solana-clap-utils = { workspace = true } +solana-cli = { workspace = true } +solana-cli-config = { workspace = true } +solana-cli-output = { workspace = true } +solana-logger = { workspace = true } +solana-remote-wallet = { workspace = true, features = ["default"] } +solana-rpc-client = { workspace = true, features = ["default"] } +solana-rpc-client-api = { workspace = true } +solana-sdk = { workspace = true } +solana-version = { workspace = true } +tar = { workspace = true } +tempfile = { workspace = true } +tokio = { workspace = true, features = ["full"] } +toml = { workspace = true } + +[dev-dependencies] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[build-dependencies] +rustc_version = { workspace = true } + +[features] +dev-context-only-utils = [] diff --git a/ci/localnet-sanity.sh b/ci/localnet-sanity.sh index e6734e180aa2da..b01eca31d50d81 100755 --- a/ci/localnet-sanity.sh +++ b/ci/localnet-sanity.sh @@ -202,8 +202,8 @@ killNodes() { # Try to use the RPC exit API to cleanly exit the first two nodes # (dynamic nodes, -x, are just killed) echo "--- RPC exit" - $solana_validator --ledger "$SOLANA_CONFIG_DIR"/bootstrap-validator exit --force || true - $solana_validator --ledger "$SOLANA_CONFIG_DIR"/validator exit --force || true + $agave_validator --ledger "$SOLANA_CONFIG_DIR"/bootstrap-validator exit --force || true + $agave_validator --ledger "$SOLANA_CONFIG_DIR"/validator exit --force || true # Give the nodes a splash of time to cleanly exit before killing them sleep 2 diff --git a/ci/publish-installer.sh b/ci/publish-installer.sh index e58fd939dd1a40..f7d98ffd5ddcf9 100755 --- a/ci/publish-installer.sh +++ b/ci/publish-installer.sh @@ -31,7 +31,7 @@ SOLANA_RELEASE=$CHANNEL_OR_TAG SOLANA_INSTALL_INIT_ARGS=$CHANNEL_OR_TAG SOLANA_DOWNLOAD_ROOT=https://release.anza.xyz EOF -cat install/solana-install-init.sh >>release.anza.xyz-install +cat install/agave-install-init.sh >>release.anza.xyz-install echo --- GCS: "install" upload-gcs-artifact "/solana/release.anza.xyz-install" "gs://anza-release/$CHANNEL_OR_TAG/install" diff --git a/ci/publish-tarball.sh b/ci/publish-tarball.sh index 5c64f09564fe9f..da5862fb3de1d2 100755 --- a/ci/publish-tarball.sh +++ b/ci/publish-tarball.sh @@ -93,7 +93,7 @@ echo --- Creating release tarball tar cvf "${TARBALL_BASENAME}"-$TARGET.tar "${RELEASE_BASENAME}" bzip2 "${TARBALL_BASENAME}"-$TARGET.tar - cp "${RELEASE_BASENAME}"/bin/solana-install-init solana-install-init-$TARGET + cp "${RELEASE_BASENAME}"/bin/agave-install-init agave-install-init-$TARGET cp "${RELEASE_BASENAME}"/version.yml "${TARBALL_BASENAME}"-$TARGET.yml ) @@ -110,7 +110,7 @@ fi source ci/upload-ci-artifact.sh -for file in "${TARBALL_BASENAME}"-$TARGET.tar.bz2 "${TARBALL_BASENAME}"-$TARGET.yml solana-install-init-"$TARGET"* $MAYBE_TARBALLS; do +for file in "${TARBALL_BASENAME}"-$TARGET.tar.bz2 "${TARBALL_BASENAME}"-$TARGET.yml agave-install-init-"$TARGET"* $MAYBE_TARBALLS; do if [[ -n $DO_NOT_PUBLISH_TAR ]]; then upload-ci-artifact "$file" echo "Skipped $file due to DO_NOT_PUBLISH_TAR" diff --git a/ci/run-sanity.sh b/ci/run-sanity.sh index 3e674d92f4eb25..d9527def4e23eb 100755 --- a/ci/run-sanity.sh +++ b/ci/run-sanity.sh @@ -31,7 +31,7 @@ while [[ $latest_slot -le $((snapshot_slot + 1)) ]]; do latest_slot=$($solana_cli --url http://localhost:8899 slot --commitment processed) done -$solana_validator --ledger config/ledger exit --force || true +$agave_validator --ledger config/ledger exit --force || true wait $pid diff --git a/docs/src/cli/install-solana-cli-tools.md b/docs/src/cli/install-solana-cli-tools.md index 26a4ede5af62b7..db0b30b607e0a7 100644 --- a/docs/src/cli/install-solana-cli-tools.md +++ b/docs/src/cli/install-solana-cli-tools.md @@ -54,7 +54,7 @@ Please update your PATH environment variable to include the solana programs: solana --version ``` -- After a successful install, `solana-install update` may be used to easily +- After a successful install, `agave-install update` may be used to easily update the Solana software to a newer version at any time. --- @@ -72,7 +72,7 @@ solana --version installer into a temporary directory: ```bash -cmd /c "curl https://release.solana.com/LATEST_SOLANA_RELEASE_VERSION/solana-install-init-x86_64-pc-windows-msvc.exe --output C:\solana-install-tmp\solana-install-init.exe --create-dirs" +cmd /c "curl https://release.solana.com/LATEST_SOLANA_RELEASE_VERSION/agave-install-init-x86_64-pc-windows-msvc.exe --output C:\agave-install-tmp\agave-install-init.exe --create-dirs" ``` - Copy and paste the following command, then press Enter to install the latest @@ -80,7 +80,7 @@ cmd /c "curl https://release.solana.com/LATEST_SOLANA_RELEASE_VERSION/solana-ins to allow the program to run. ```bash -C:\solana-install-tmp\solana-install-init.exe LATEST_SOLANA_RELEASE_VERSION +C:\agave-install-tmp\agave-install-init.exe LATEST_SOLANA_RELEASE_VERSION ``` - When the installer is finished, press Enter. @@ -95,12 +95,12 @@ C:\solana-install-tmp\solana-install-init.exe LATEST_SOLANA_RELEASE_VERSION solana --version ``` -- After a successful install, `solana-install update` may be used to easily +- After a successful install, `agave-install update` may be used to easily update the Solana software to a newer version at any time. ## Download Prebuilt Binaries -If you would rather not use `solana-install` to manage the install, you can +If you would rather not use `agave-install` to manage the install, you can manually download and install the binaries. ### Linux @@ -161,7 +161,7 @@ You can then run the following command to obtain the same result as with prebuilt binaries: ```bash -solana-install init +agave-install init ``` ## Use Homebrew diff --git a/docs/src/cluster/bench-tps.md b/docs/src/cluster/bench-tps.md index d913f9e5f16392..35978cdd0967dd 100644 --- a/docs/src/cluster/bench-tps.md +++ b/docs/src/cluster/bench-tps.md @@ -108,7 +108,7 @@ For example Generally we are using `debug` for infrequent debug messages, `trace` for potentially frequent messages and `info` for performance-related logging. -You can also attach to a running process with GDB. The leader's process is named _solana-validator_: +You can also attach to a running process with GDB. The leader's process is named _agave-validator_: ```bash sudo gdb diff --git a/docs/src/clusters.md b/docs/src/clusters.md index 5d59e7ea6cc40e..08102c68a8a7fe 100644 --- a/docs/src/clusters.md +++ b/docs/src/clusters.md @@ -39,10 +39,10 @@ export SOLANA_METRICS_CONFIG="host=https://metrics.solana.com:8086,db=devnet,u=s solana config set --url https://api.devnet.solana.com ``` -##### Example `solana-validator` command-line +##### Example `agave-validator` command-line ```bash -$ solana-validator \ +$ agave-validator \ --identity validator-keypair.json \ --vote-account vote-account-keypair.json \ --known-validator dv1ZAGvdsz5hHLwWXsVnM94hWf1pjbKVau1QVkaMJ92 \ @@ -91,10 +91,10 @@ export SOLANA_METRICS_CONFIG="host=https://metrics.solana.com:8086,db=tds,u=test solana config set --url https://api.testnet.solana.com ``` -##### Example `solana-validator` command-line +##### Example `agave-validator` command-line ```bash -$ solana-validator \ +$ agave-validator \ --identity validator-keypair.json \ --vote-account vote-account-keypair.json \ --known-validator 5D1fNXzvv5NjV1ysLjirC4WY92RNsVH18vjmcszZd8on \ @@ -143,10 +143,10 @@ export SOLANA_METRICS_CONFIG="host=https://metrics.solana.com:8086,db=mainnet-be solana config set --url https://api.mainnet-beta.solana.com ``` -##### Example `solana-validator` command-line +##### Example `agave-validator` command-line ```bash -$ solana-validator \ +$ agave-validator \ --identity ~/validator-keypair.json \ --vote-account ~/vote-account-keypair.json \ --known-validator 7Np41oeYqPefeNQEHSv1UDhYrehxin3NStELsSKCT4K2 \ diff --git a/docs/src/developing/backwards-compatibility.md b/docs/src/developing/backwards-compatibility.md index 4a3c60b8e129bd..0fdc388ea2dbae 100644 --- a/docs/src/developing/backwards-compatibility.md +++ b/docs/src/developing/backwards-compatibility.md @@ -76,7 +76,7 @@ Major releases: - [`solana-program`](https://docs.rs/solana-program/) - Rust SDK for writing programs - [`solana-client`](https://docs.rs/solana-client/) - Rust client for connecting to RPC API - [`solana-cli-config`](https://docs.rs/solana-cli-config/) - Rust client for managing Solana CLI config files -- [`solana-geyser-plugin-interface`](https://docs.rs/solana-geyser-plugin-interface/) - Rust interface for developing Solana Geyser plugins. +- [`agave-geyser-plugin-interface`](https://docs.rs/agave-geyser-plugin-interface/) - Rust interface for developing Solana Geyser plugins. Patch releases: diff --git a/docs/src/developing/plugins/geyser-plugins.md b/docs/src/developing/plugins/geyser-plugins.md index 3ea07473a61f88..41e1b655e94bdd 100644 --- a/docs/src/developing/plugins/geyser-plugins.md +++ b/docs/src/developing/plugins/geyser-plugins.md @@ -22,20 +22,20 @@ implementation for the PostgreSQL database. ### Important Crates: -- [`solana-geyser-plugin-interface`] — This crate defines the plugin +- [`agave-geyser-plugin-interface`] — This crate defines the plugin interfaces. - [`solana-accountsdb-plugin-postgres`] — The crate for the referential plugin implementation for the PostgreSQL database. -[`solana-geyser-plugin-interface`]: https://docs.rs/solana-geyser-plugin-interface +[`agave-geyser-plugin-interface`]: https://docs.rs/agave-geyser-plugin-interface [`solana-accountsdb-plugin-postgres`]: https://docs.rs/solana-accountsdb-plugin-postgres [`solana-sdk`]: https://docs.rs/solana-sdk [`solana-transaction-status`]: https://docs.rs/solana-transaction-status ## The Plugin Interface -The Plugin interface is declared in [`solana-geyser-plugin-interface`]. It +The Plugin interface is declared in [`agave-geyser-plugin-interface`]. It is defined by the trait `GeyserPlugin`. The plugin should implement the trait and expose a "C" function `_create_plugin` to return the pointer to this trait. For example, in the referential implementation, the following code @@ -164,7 +164,7 @@ please refer to [`solana-sdk`] and [`solana-transaction-status`] The `slot` points to the slot the transaction is executed at. For more details, please refer to the Rust documentation in -[`solana-geyser-plugin-interface`]. +[`agave-geyser-plugin-interface`]. ## Example PostgreSQL Plugin diff --git a/docs/src/implemented-proposals/installer.md b/docs/src/implemented-proposals/installer.md index a3ad797171c5b8..c052aa7b4e54e5 100644 --- a/docs/src/implemented-proposals/installer.md +++ b/docs/src/implemented-proposals/installer.md @@ -13,16 +13,16 @@ This document proposes an easy to use software install and updater that can be u The easiest install method for supported platforms: ```bash -$ curl -sSf https://raw.githubusercontent.com/solana-labs/solana/v1.0.0/install/solana-install-init.sh | sh +$ curl -sSf https://raw.githubusercontent.com/solana-labs/solana/v1.0.0/install/agave-install-init.sh | sh ``` -This script will check github for the latest tagged release and download and run the `solana-install-init` binary from there. +This script will check github for the latest tagged release and download and run the `agave-install-init` binary from there. If additional arguments need to be specified during the installation, the following shell syntax is used: ```bash -$ init_args=.... # arguments for `solana-install-init ...` -$ curl -sSf https://raw.githubusercontent.com/solana-labs/solana/v1.0.0/install/solana-install-init.sh | sh -s - ${init_args} +$ init_args=.... # arguments for `agave-install-init ...` +$ curl -sSf https://raw.githubusercontent.com/solana-labs/solana/v1.0.0/install/agave-install-init.sh | sh -s - ${init_args} ``` ### Fetch and run a pre-built installer from a Github release @@ -30,9 +30,9 @@ $ curl -sSf https://raw.githubusercontent.com/solana-labs/solana/v1.0.0/install/ With a well-known release URL, a pre-built binary can be obtained for supported platforms: ```bash -$ curl -o solana-install-init https://github.com/solana-labs/solana/releases/download/v1.0.0/solana-install-init-x86_64-apple-darwin -$ chmod +x ./solana-install-init -$ ./solana-install-init --help +$ curl -o agave-install-init https://github.com/solana-labs/solana/releases/download/v1.0.0/agave-install-init-x86_64-apple-darwin +$ chmod +x ./agave-install-init +$ ./agave-install-init --help ``` ### Build and run the installer from source @@ -51,16 +51,16 @@ Given a solana release tarball \(as created by `ci/publish-tarball.sh`\) that ha ```bash $ solana-keygen new -o update-manifest.json # <-- only generated once, the public key is shared with users -$ solana-install deploy http://example.com/path/to/solana-release.tar.bz2 update-manifest.json +$ agave-install deploy http://example.com/path/to/solana-release.tar.bz2 update-manifest.json ``` ### Run a validator node that auto updates itself ```bash -$ solana-install init --pubkey 92DMonmBYXwEMHJ99c9ceRSpAmk9v6i3RdvDdXaVcrfj # <-- pubkey is obtained from whoever is deploying the updates -$ export PATH=~/.local/share/solana-install/bin:$PATH +$ agave-install init --pubkey 92DMonmBYXwEMHJ99c9ceRSpAmk9v6i3RdvDdXaVcrfj # <-- pubkey is obtained from whoever is deploying the updates +$ export PATH=~/.local/share/agave-install/bin:$PATH $ solana-keygen ... # <-- runs the latest solana-keygen -$ solana-install run solana-validator ... # <-- runs a validator, restarting it as necessary when an update is applied +$ agave-install run agave-validator ... # <-- runs a validator, restarting it as necessary when an update is applied ``` ## On-chain Update Manifest @@ -87,9 +87,9 @@ pub struct SignedUpdateManifest { } ``` -Note that the `manifest` field itself contains a corresponding signature \(`manifest_signature`\) to guard against man-in-the-middle attacks between the `solana-install` tool and the solana cluster RPC API. +Note that the `manifest` field itself contains a corresponding signature \(`manifest_signature`\) to guard against man-in-the-middle attacks between the `agave-install` tool and the solana cluster RPC API. -To guard against rollback attacks, `solana-install` will refuse to install an update with an older `timestamp_secs` than what is currently installed. +To guard against rollback attacks, `agave-install` will refuse to install an update with an older `timestamp_secs` than what is currently installed. ## Release Archive Contents @@ -101,17 +101,17 @@ A release archive is expected to be a tar file compressed with bzip2 with the fo - `/bin/` -- directory containing available programs in the release. - `solana-install` will symlink this directory to + `agave-install` will symlink this directory to - `~/.local/share/solana-install/bin` for use by the `PATH` environment + `~/.local/share/agave-install/bin` for use by the `PATH` environment variable. - `...` -- any additional files and directories are permitted -## solana-install Tool +## agave-install Tool -The `solana-install` tool is used by the user to install and update their cluster software. +The `agave-install` tool is used by the user to install and update their cluster software. It manages the following files and directories in the user's home directory: @@ -122,11 +122,11 @@ It manages the following files and directories in the user's home directory: ### Command-line Interface ```text -solana-install 0.16.0 +agave-install 0.16.0 The solana cluster software installer USAGE: - solana-install [OPTIONS] + agave-install [OPTIONS] FLAGS: -h, --help Prints help information @@ -145,11 +145,11 @@ SUBCOMMANDS: ``` ```text -solana-install-init +agave-install-init initializes a new installation USAGE: - solana-install init [OPTIONS] + agave-install init [OPTIONS] FLAGS: -h, --help Prints help information @@ -161,11 +161,11 @@ OPTIONS: ``` ```text -solana-install info +agave-install info displays information about the current installation USAGE: - solana-install info [FLAGS] + agave-install info [FLAGS] FLAGS: -h, --help Prints help information @@ -173,11 +173,11 @@ FLAGS: ``` ```text -solana-install deploy +agave-install deploy deploys a new update USAGE: - solana-install deploy + agave-install deploy FLAGS: -h, --help Prints help information @@ -188,22 +188,22 @@ ARGS: ``` ```text -solana-install update +agave-install update checks for an update, and if available downloads and applies it USAGE: - solana-install update + agave-install update FLAGS: -h, --help Prints help information ``` ```text -solana-install run +agave-install run Runs a program while periodically checking and applying software updates USAGE: - solana-install run [program_arguments]... + agave-install run [program_arguments]... FLAGS: -h, --help Prints help information diff --git a/docs/src/implemented-proposals/rpc-transaction-history.md b/docs/src/implemented-proposals/rpc-transaction-history.md index c8eb878eae45ce..1082c063f8d372 100644 --- a/docs/src/implemented-proposals/rpc-transaction-history.md +++ b/docs/src/implemented-proposals/rpc-transaction-history.md @@ -67,9 +67,15 @@ results of BigTable queries more complicated but is not a significant issue. ## Data Population +<<<<<<< HEAD The ongoing population of instance data will occur on an epoch cadence through the use of a new `solana-ledger-tool` command that will convert rocksdb data for a given slot range into the instance schema. +======= +The ongoing population of instance data will occur on an epoch cadence through +the use of a new `agave-ledger-tool` command that will convert rocksdb data for +a given slot range into the instance schema. +>>>>>>> e1e36d2fea ([anza migration] rename crates (#10)) The same process will be run once, manually, to backfill the existing ledger data. diff --git a/docs/src/operations/best-practices/general.md b/docs/src/operations/best-practices/general.md new file mode 100644 index 00000000000000..3e531b0160c571 --- /dev/null +++ b/docs/src/operations/best-practices/general.md @@ -0,0 +1,237 @@ +--- +title: Solana Validator Operations Best Practices +sidebar_label: General Operations +pagination_label: "Best Practices: Validator Operations" +--- + +After you have successfully setup and started a +[validator on testnet](../setup-a-validator.md) (or another cluster +of your choice), you will want to become familiar with how to operate your +validator on a day-to-day basis. During daily operations, you will be +[monitoring your server](./monitoring.md), updating software regularly (both the +Solana validator software and operating system packages), and managing your vote +account and identity account. + +All of these skills are critical to practice. Maximizing your validator uptime +is an important part of being a good operator. + +## Educational Workshops + +The Solana validator community holds regular educational workshops. You can +watch past workshops through the +[Solana validator educational workshops playlist](https://www.youtube.com/watch?v=86zySQ5vGW8&list=PLilwLeBwGuK6jKrmn7KOkxRxS9tvbRa5p). + +## Help with the validator command line + +From within the Solana CLI, you can execute the `agave-validator` command with +the `--help` flag to get a better understanding of the flags and sub commands +available. + +``` +agave-validator --help +``` + +## Restarting your validator + +There are many operational reasons you may want to restart your validator. As a +best practice, you should avoid a restart during a leader slot. A +[leader slot](https://solana.com/docs/terminology#leader-schedule) is the time +when your validator is expected to produce blocks. For the health of the cluster +and also for your validator's ability to earn transaction fee rewards, you do +not want your validator to be offline during an opportunity to produce blocks. + +To see the full leader schedule for an epoch, use the following command: + +``` +solana leader-schedule +``` + +Based on the current slot and the leader schedule, you can calculate open time +windows where your validator is not expected to produce blocks. + +Assuming you are ready to restart, you may use the `agave-validator exit` +command. The command exits your validator process when an appropriate idle time +window is reached. Assuming that you have systemd implemented for your validator +process, the validator should restart automatically after the exit. See the +below help command for details: + +``` +agave-validator exit --help +``` + +## Upgrading + +There are many ways to upgrade the +[Solana CLI software](../../cli/install.md). As an operator, you +will need to upgrade often, so it is important to get comfortable with this +process. + +> **Note** validator nodes do not need to be offline while the newest version is +> being downloaded or built from source. All methods below can be done before +> the validator process is restarted. + +### Building From Source + +It is a best practice to always build your Solana binaries from source. If you +build from source, you are certain that the code you are building has not been +tampered with before the binary was created. You may also be able to optimize +your `agave-validator` binary to your specific hardware. + +If you build from source on the validator machine (or a machine with the same +CPU), you can target your specific architecture using the `-march` flag. Refer +to the following doc for +[instructions on building from source](../../cli/install.md#build-from-source). + +### agave-install + +If you are not comfortable building from source, or you need to quickly install +a new version to test something out, you could instead try using the +`agave-install` command. + +Assuming you want to install Solana version `1.14.17`, you would execute the +following: + +``` +agave-install init 1.14.17 +``` + +This command downloads the executable for `1.14.17` and installs it into a +`.local` directory. You can also look at `agave-install --help` for more +options. + +> **Note** this command only works if you already have the solana cli installed. +> If you do not have the cli installed, refer to +> [install solana cli tools](../../cli/install.md) + +### Restart + +For all install methods, the validator process will need to be restarted before +the newly installed version is in use. Use `agave-validator exit` to restart +your validator process. + +### Verifying version + +The best way to verify that your validator process has changed to the desired +version is to grep the logs after a restart. The following grep command should +show you the version that your validator restarted with: + +``` +grep -B1 'Starting validator with' +``` + +## Snapshots + +Validators operators who have not experienced significant downtime (multiple +hours of downtime), should avoid downloading snapshots. It is important for the +health of the cluster as well as your validator history to maintain the local +ledger. Therefore, you should not download a new snapshot any time your +validator is offline or experiences an issue. Downloading a snapshot should only +be reserved for occasions when you do not have local state. Prolonged downtime +or the first install of a new validator are examples of times when you may not +have state locally. In other cases such as restarts for upgrades, a snapshot +download should be avoided. + +To avoid downloading a snapshot on restart, add the following flag to the +`agave-validator` command: + +``` +--no-snapshot-fetch +``` + +If you use this flag with the `agave-validator` command, make sure that you run +`solana catchup ` after your validator starts to make sure that the +validator is catching up in a reasonable time. After some time (potentially a +few hours), if it appears that your validator continues to fall behind, then you +may have to download a new snapshot. + +### Downloading Snapshots + +If you are starting a validator for the first time, or your validator has fallen +too far behind after a restart, then you may have to download a snapshot. + +To download a snapshot, you must **_NOT_** use the `--no-snapshot-fetch` flag. +Without the flag, your validator will automatically download a snapshot from +your known validators that you specified with the `--known-validator` flag. + +If one of the known validators is downloading slowly, you can try adding the +`--minimal-snapshot-download-speed` flag to your validator. This flag will +switch to another known validator if the initial download speed is below the +threshold that you set. + +### Manually Downloading Snapshots + +In the case that there are network troubles with one or more of your known +validators, then you may have to manually download the snapshot. To manually +download a snapshot from one of your known validators, first, find the IP +address of the validator in using the `solana gossip` command. In the example +below, `5D1fNXzvv5NjV1ysLjirC4WY92RNsVH18vjmcszZd8on` is the pubkey of one of my +known validators: + +``` +solana gossip | grep 5D1fNXzvv5NjV1ysLjirC4WY92RNsVH18vjmcszZd8on +``` + +The IP address of the validators is `139.178.68.207` and the open port on this +validator is `80`. You can see the IP address and port in the fifth column in +the gossip output: + +``` +139.178.68.207 | 5D1fNXzvv5NjV1ysLjirC4WY92RNsVH18vjmcszZd8on | 8001 | 8004 | 139.178.68.207:80 | 1.10.27 | 1425680972 +``` + +Now that the IP and port are known, you can download a full snapshot or an +incremental snapshot: + +``` +wget --trust-server-names http://139.178.68.207:80/snapshot.tar.bz2 +wget --trust-server-names http://139.178.68.207:80/incremental-snapshot.tar.bz2 +``` + +Now move those files into your snapshot directory. If you have not specified a +snapshot directory, then you should put the files in your ledger directory. + +Once you have a local snapshot, you can restart your validator with the +`--no-snapshot-fetch` flag. + +## Regularly Check Account Balances + +It is important that you do not accidentally run out of funds in your identity +account, as your node will stop voting. It is also important to note that this +account keypair is the most vulnerable of the three keypairs in a vote account +because the keypair for the identity account is stored on your validator when +running the `agave-validator` software. How much SOL you should store there is +up to you. As a best practice, make sure to check the account regularly and +refill or deduct from it as needed. To check the account balance do: + +``` +solana balance validator-keypair.json +``` + +> **Note** `agave-watchtower` can monitor for a minimum validator identity +> balance. See [monitoring best practices](./monitoring.md) for details. + +## Withdrawing From The Vote Account + +As a reminder, your withdrawer's keypair should **_NEVER_** be stored on your +server. It should be stored on a hardware wallet, paper wallet, or multisig +mitigates the risk of hacking and theft of funds. + +To withdraw your funds from your vote account, you will need to run +`solana withdraw-from-vote-account` on a trusted computer. For example, on a +trusted computer, you could withdraw all of the funds from your vote account +(excluding the rent exempt minimum). The below example assumes you have a +separate keypair to store your funds called `person-keypair.json` + +``` +solana withdraw-from-vote-account \ + vote-account-keypair.json \ + person-keypair.json ALL \ + --authorized-withdrawer authorized-withdrawer-keypair.json +``` + +To get more information on the command, use +`solana withdraw-from-vote-account --help`. + +For a more detailed explanation of the different keypairs and other related +operations refer to +[vote account management](../guides/vote-accounts.md). diff --git a/docs/src/running-validator/restart-cluster.md b/docs/src/running-validator/restart-cluster.md index 4039f69a6b468f..4823ae2fd5c900 100644 --- a/docs/src/running-validator/restart-cluster.md +++ b/docs/src/running-validator/restart-cluster.md @@ -5,7 +5,7 @@ In Solana 1.14 or greater, run the following command to output the latest optimistically confirmed slot your validator observed: ```bash -solana-ledger-tool -l ledger latest-optimistic-slots +agave-ledger-tool -l ledger latest-optimistic-slots ``` In Solana 1.13 or less, the latest optimistically confirmed can be found by looking for the more recent occurrence of @@ -28,11 +28,11 @@ instead. ### Step 4. Create a new snapshot for slot `SLOT_X` with a hard fork at slot `SLOT_X` ```bash -$ solana-ledger-tool -l --snapshot-archive-path --incremental-snapshot-archive-path create-snapshot SLOT_X --hard-fork SLOT_X +$ agave-ledger-tool -l --snapshot-archive-path --incremental-snapshot-archive-path create-snapshot SLOT_X --hard-fork SLOT_X ``` The snapshots directory should now contain the new snapshot. -`solana-ledger-tool create-snapshot` will also output the new shred version, and bank hash value, +`agave-ledger-tool create-snapshot` will also output the new shred version, and bank hash value, call this NEW_SHRED_VERSION and NEW_BANK_HASH respectively. Adjust your validator's arguments: @@ -62,7 +62,7 @@ Post something like the following to #announcements (adjusting the text as appro > 2. a. Preferred method, start from your local ledger with: > > ```bash -> solana-validator +> agave-validator > --wait-for-supermajority SLOT_X # <-- NEW! IMPORTANT! REMOVE AFTER THIS RESTART > --expected-bank-hash NEW_BANK_HASH # <-- NEW! IMPORTANT! REMOVE AFTER THIS RESTART > --hard-fork SLOT_X # <-- NEW! IMPORTANT! REMOVE AFTER THIS RESTART @@ -78,7 +78,7 @@ Post something like the following to #announcements (adjusting the text as appro > b. If your validator doesn't have ledger up to slot SLOT_X or if you have deleted your ledger, have it instead download a snapshot with: > > ```bash -> solana-validator +> agave-validator > --wait-for-supermajority SLOT_X # <-- NEW! IMPORTANT! REMOVE AFTER THIS RESTART > --expected-bank-hash NEW_BANK_HASH # <-- NEW! IMPORTANT! REMOVE AFTER THIS RESTART > --entrypoint entrypoint.testnet.solana.com:8001 @@ -89,7 +89,7 @@ Post something like the following to #announcements (adjusting the text as appro > ... # <-- your other --identity/--vote-account/etc arguments > ``` > -> You can check for which slots your ledger has with: `solana-ledger-tool -l path/to/ledger bounds` +> You can check for which slots your ledger has with: `agave-ledger-tool -l path/to/ledger bounds` > > 3. Wait until 80% of the stake comes online > @@ -116,7 +116,7 @@ and create a new snapshot with additional `--destake-vote-account ` arguments for each of the non-responsive validator's vote account address ```bash -$ solana-ledger-tool -l ledger create-snapshot SLOT_X ledger --hard-fork SLOT_X \ +$ agave-ledger-tool -l ledger create-snapshot SLOT_X ledger --hard-fork SLOT_X \ --destake-vote-account \ --destake-vote-account \ . diff --git a/docs/src/running-validator/validator-failover.md b/docs/src/running-validator/validator-failover.md index 34968b73640933..1329dd58b2281c 100644 --- a/docs/src/running-validator/validator-failover.md +++ b/docs/src/running-validator/validator-failover.md @@ -82,11 +82,11 @@ For more information on etcd TLS setup, please refer to https://etcd.io/docs/v3.5/op-guide/security/#example-2-client-to-server-authentication-with-https-client-certificates ### Primary Validator -The following additional `solana-validator` parameters are required to enable +The following additional `agave-validator` parameters are required to enable tower storage into etcd: ``` -solana-validator ... \ +agave-validator ... \ --tower-storage etcd \ --etcd-cacert-file certs/etcd-ca.pem \ --etcd-cert-file certs/validator.pem \ @@ -100,7 +100,7 @@ that your etcd endpoint remain accessible at all times. ### Secondary Validator Configure the secondary validator like the primary with the exception of the -following `solana-validator` command-line argument changes: +following `agave-validator` command-line argument changes: * Generate and use a secondary validator identity: `--identity secondary-validator-keypair.json` * Add `--no-check-vote-account` * Add `--authorized-voter validator-keypair.json` (where @@ -111,8 +111,8 @@ When both validators are running normally and caught up to the cluster, a failover from primary to secondary can be triggered by running the following command on the secondary validator: ```bash -$ solana-validator wait-for-restart-window --identity validator-keypair.json \ - && solana-validator set-identity validator-keypair.json +$ agave-validator wait-for-restart-window --identity validator-keypair.json \ + && agave-validator set-identity validator-keypair.json ``` The secondary validator will acquire a lock on the tower in etcd to ensure @@ -128,7 +128,7 @@ exit. However if/when the secondary validator restarts, it will do so using the secondary validator identity and thus the restart cycle is broken. ## Triggering a failover via monitoring -Monitoring of your choosing can invoke the `solana-validator set-identity +Monitoring of your choosing can invoke the `agave-validator set-identity validator-keypair.json` command mentioned in the previous section. It is not necessary to guarantee the primary validator has halted before failing diff --git a/docs/src/running-validator/validator-start.md b/docs/src/running-validator/validator-start.md index ccd012aa79997c..d9f2163af54252 100644 --- a/docs/src/running-validator/validator-start.md +++ b/docs/src/running-validator/validator-start.md @@ -29,7 +29,7 @@ detail on cluster activity. ## Enabling CUDA If your machine has a GPU with CUDA installed \(Linux-only currently\), include -the `--cuda` argument to `solana-validator`. +the `--cuda` argument to `agave-validator`. When your validator is started look for the following log message to indicate that CUDA is enabled: `"[ solana::validator] CUDA is enabled"` @@ -44,7 +44,7 @@ the following commands. #### **Optimize sysctl knobs** ```bash -sudo bash -c "cat >/etc/sysctl.d/21-solana-validator.conf </etc/sysctl.d/21-agave-validator.conf <` -argument to `solana-validator`. You can specify multiple ones by repeating the argument `--known-validator --known-validator `. +argument to `agave-validator`. You can specify multiple ones by repeating the argument `--known-validator --known-validator `. This has two effects, one is when the validator is booting with `--only-known-rpc`, it will only ask that set of known nodes for downloading genesis and snapshot data. Another is that in combination with the `--halt-on-known-validators-accounts-hash-mismatch` option, it will monitor the merkle root hash of the entire accounts state of other known nodes on gossip and if the hashes produce any mismatch, @@ -280,13 +280,13 @@ account state divergence. Connect to the cluster by running: ```bash -solana-validator \ +agave-validator \ --identity ~/validator-keypair.json \ --vote-account ~/vote-account-keypair.json \ --rpc-port 8899 \ --entrypoint entrypoint.devnet.solana.com:8001 \ --limit-ledger-size \ - --log ~/solana-validator.log + --log ~/agave-validator.log ``` To force validator logging to the console add a `--log -` argument, otherwise @@ -299,7 +299,7 @@ The ledger will be placed in the `ledger/` directory by default, use the > [paper wallet seed phrase](../wallet-guide/paper-wallet.md) > for your `--identity` and/or > `--authorized-voter` keypairs. To use these, pass the respective argument as -> `solana-validator --identity ASK ... --authorized-voter ASK ...` +> `agave-validator --identity ASK ... --authorized-voter ASK ...` > and you will be prompted to enter your seed phrases and optional passphrase. Confirm your validator is connected to the network by opening a new terminal and @@ -315,7 +315,7 @@ If your validator is connected, its public key and IP address will appear in the By default the validator will dynamically select available network ports in the 8000-10000 range, and may be overridden with `--dynamic-port-range`. For -example, `solana-validator --dynamic-port-range 11000-11020 ...` will restrict +example, `agave-validator --dynamic-port-range 11000-11020 ...` will restrict the validator to ports 11000-11020. ### Limiting ledger size to conserve disk space @@ -369,8 +369,8 @@ WantedBy=multi-user.target ``` Now create `/home/sol/bin/validator.sh` to include the desired -`solana-validator` command-line. Ensure that the 'exec' command is used to -start the validator process (i.e. "exec solana-validator ..."). This is +`agave-validator` command-line. Ensure that the 'exec' command is used to +start the validator process (i.e. "exec agave-validator ..."). This is important because without it, logrotate will end up killing the validator every time the logs are rotated. @@ -397,14 +397,14 @@ to be reverted and the issue reproduced before help can be provided. #### Log rotation -The validator log file, as specified by `--log ~/solana-validator.log`, can get +The validator log file, as specified by `--log ~/agave-validator.log`, can get very large over time and it's recommended that log rotation be configured. The validator will re-open its log file when it receives the `USR1` signal, which is the basic primitive that enables log rotation. If the validator is being started by a wrapper shell script, it is important to -launch the process with `exec` (`exec solana-validator ...`) when using logrotate. +launch the process with `exec` (`exec agave-validator ...`) when using logrotate. This will prevent the `USR1` signal from being sent to the script's process instead of the validator's, which will kill them both. @@ -412,13 +412,13 @@ instead of the validator's, which will kill them both. An example setup for the `logrotate`, which assumes that the validator is running as a systemd service called `sol.service` and writes a log file at -/home/sol/solana-validator.log: +/home/sol/agave-validator.log: ```bash # Setup log rotation cat > logrotate.sol <>>>>>> e1e36d2fea ([anza migration] rename crates (#10)):docs/src/operations/guides/validator-start.md diff --git a/docs/src/running-validator/vote-accounts.md b/docs/src/running-validator/vote-accounts.md index 6bb021588d7698..a6f3ed3736a4ce 100644 --- a/docs/src/running-validator/vote-accounts.md +++ b/docs/src/running-validator/vote-accounts.md @@ -87,6 +87,7 @@ The vote authority can be changed later with the [vote-authorize-voter-checked](../cli/usage.md#solana-vote-authorize-voter-checked) command. The vote authority can be changed at most once per epoch. If the authority is +<<<<<<< HEAD:docs/src/running-validator/vote-accounts.md changed with [vote-authorize-voter-checked](../cli/usage.md#solana-vote-authorize-voter-checked), this will not take effect until the beginning of the next epoch. To support a smooth transition of the vote signing, @@ -94,6 +95,15 @@ To support a smooth transition of the vote signing, multiple times. This allows the validator process to keep voting successfully when the network reaches an epoch boundary at which the validator's vote authority account changes. +======= +changed with +[vote-authorize-voter-checked](../../cli/usage.md#solana-vote-authorize-voter-checked), +this will not take effect until the beginning of the next epoch. To support a +smooth transition of the vote signing, `agave-validator` allows the +`--authorized-voter` argument to be specified multiple times. This allows the +validator process to keep voting successfully when the network reaches an epoch +boundary at which the validator's vote authority account changes. +>>>>>>> e1e36d2fea ([anza migration] rename crates (#10)):docs/src/operations/guides/vote-accounts.md ### Authorized Withdrawer @@ -198,7 +208,7 @@ no longer listed in the `solana leader-schedule` output. ### Vote Account Authorized Voter The _vote authority_ keypair may only be changed at epoch boundaries and -requires some additional arguments to `solana-validator` for a seamless +requires some additional arguments to `agave-validator` for a seamless migration. 1. Run `solana epoch-info`. If there is not much time remaining time in the @@ -208,14 +218,22 @@ migration. 3. Determine the current _vote authority_ keypair by running `solana vote-account ~/vote-account-keypair.json`. It may be validator's identity account (the default) or some other keypair. The following steps assume that `~/validator-keypair.json` is that keypair. +<<<<<<< HEAD:docs/src/running-validator/vote-accounts.md 4. Run `solana vote-authorize-voter-checked ~/vote-account-keypair.json ~/validator-keypair.json ~/new-vote-authority.json`. The new vote authority is scheduled to become active starting at the next epoch. 5. `solana-validator` now needs to be restarted with the old and new vote +======= +4. Run + `solana vote-authorize-voter-checked ~/vote-account-keypair.json ~/validator-keypair.json ~/new-vote-authority.json`. + The new vote authority is scheduled to become active starting at the next + epoch. +5. `agave-validator` now needs to be restarted with the old and new vote +>>>>>>> e1e36d2fea ([anza migration] rename crates (#10)):docs/src/operations/guides/vote-accounts.md authority keypairs, so that it can smoothly transition at the next epoch. Add the two arguments on restart: `--authorized-voter ~/validator-keypair.json --authorized-voter ~/new-vote-authority.json` 6. After the cluster reaches the next epoch, remove the `--authorized-voter ~/validator-keypair.json` argument and restart - `solana-validator`, as the old vote authority keypair is no longer required. + `agave-validator`, as the old vote authority keypair is no longer required. ### Vote Account Authorized Withdrawer diff --git a/docs/src/validator/best-practices/monitoring.md b/docs/src/validator/best-practices/monitoring.md index b866a88b869531..5f0c760dc95ac0 100644 --- a/docs/src/validator/best-practices/monitoring.md +++ b/docs/src/validator/best-practices/monitoring.md @@ -3,34 +3,34 @@ title: Validator Monitoring Best Practices sidebar_label: Monitoring --- -It is essential that you have monitoring in place on your validator. In the event that your validator is delinquent (behind the rest of the network) you want to respond immediately to fix the issue. One very useful tool to monitor your validator is [`solana-watchtower`](#solana-watchtower). +It is essential that you have monitoring in place on your validator. In the event that your validator is delinquent (behind the rest of the network) you want to respond immediately to fix the issue. One very useful tool to monitor your validator is [`agave-watchtower`](#agave-watchtower). ## Solana Watchtower -Solana Watchtower is an extremely useful monitoring tool that will regularly monitor the health of your validator. It can monitor your validator for delinquency then notify you on your application of choice: Slack, Discord, Telegram or Twilio. Additionally, `solana-watchtower` has the ability to monitor the health of the entire cluster so that you can be aware of any cluster wide problems. +Solana Watchtower is an extremely useful monitoring tool that will regularly monitor the health of your validator. It can monitor your validator for delinquency then notify you on your application of choice: Slack, Discord, Telegram or Twilio. Additionally, `agave-watchtower` has the ability to monitor the health of the entire cluster so that you can be aware of any cluster wide problems. ### Getting Started -To get started with Solana Watchtower, run `solana-watchtower --help`. From the help menu, you can see the optional flags and an explanation of the command. +To get started with Solana Watchtower, run `agave-watchtower --help`. From the help menu, you can see the optional flags and an explanation of the command. Here is a sample command that will monitor a validator node with an identity public key of `2uTk98rqqwENevkPH2AHHzGHXgeGc1h6ku8hQUqWeXZp`: ``` -solana-watchtower --monitor-active-stake --validator-identity \ +agave-watchtower --monitor-active-stake --validator-identity \ 2uTk98rqqwENevkPH2AHHzGHXgeGc1h6ku8hQUqWeXZp ``` -The command will monitor your validator, but you will not get notifications unless you added the environment variables mentioned in `solana-watchtower --help`. Since getting each of these services setup for notifications is not straight forward, the next section will walk through [setting up watchtower notifications on Telegram](#setup-telegram-notifications). +The command will monitor your validator, but you will not get notifications unless you added the environment variables mentioned in `agave-watchtower --help`. Since getting each of these services setup for notifications is not straight forward, the next section will walk through [setting up watchtower notifications on Telegram](#setup-telegram-notifications). ### Best Practices -It is a best practice to run the `solana-watchtower` command on a separate server from your validator. +It is a best practice to run the `agave-watchtower` command on a separate server from your validator. -In the case that you run `solana-watchtower` on the same computer as your `solana-validator` process, then during catastrophic events like a power outage, you will not be aware of the issue, because your `solana-watchtower` process will stop at the same time as your `solana-validator` process. +In the case that you run `agave-watchtower` on the same computer as your `agave-validator` process, then during catastrophic events like a power outage, you will not be aware of the issue, because your `agave-watchtower` process will stop at the same time as your `agave-validator` process. -Additionally, while running the `solana-watchtower` process manually with environment variables set in the terminal is a good way to test out the command, it is not operationally sound because the process will not be restarted when the terminal closes or during a system restart. +Additionally, while running the `agave-watchtower` process manually with environment variables set in the terminal is a good way to test out the command, it is not operationally sound because the process will not be restarted when the terminal closes or during a system restart. -Instead, you could run your `solana-watchtower` command as a system process similar to `solana-validator`. In the system process file, you can specify the environment variables for your bot. +Instead, you could run your `agave-watchtower` command as a system process similar to `agave-validator`. In the system process file, you can specify the environment variables for your bot. ### Setup Telegram Notifications @@ -40,7 +40,7 @@ To send validator health notifications to your Telegram account, we are going to 2. Send a message to the bot 3. Create a Telegram group that will get the watchtower notifications 4. Add the environment variables to your command line environment -5. Restart the `solana-watchtower` command +5. Restart the `agave-watchtower` command #### Create a Bot Using BotFather @@ -60,7 +60,7 @@ In Telegram, click on the new message icon and then select new group. Find your Now that you have a bot setup, you will need to set the environment variables for the bot so that watchtower can send notifications. -First, recall the chat message that you got from _@BotFather_. In the message, there was an HTTP API token for your bot. The token will have this format: `389178471:MMTKMrnZB4ErUzJmuFIXTKE6DupLSgoa7h4o`. You will use that token to set the `TELEGRAM_BOT_TOKEN` environment variable. In the terminal where you plan to run `solana-watchtower`, run the following: +First, recall the chat message that you got from _@BotFather_. In the message, there was an HTTP API token for your bot. The token will have this format: `389178471:MMTKMrnZB4ErUzJmuFIXTKE6DupLSgoa7h4o`. You will use that token to set the `TELEGRAM_BOT_TOKEN` environment variable. In the terminal where you plan to run `agave-watchtower`, run the following: ``` export TELEGRAM_BOT_TOKEN= @@ -72,14 +72,14 @@ Next, in your browser, go to `https://api.telegram.org/bot/getUp The response should be in JSON. Search for the string `"chat":` in the JSON. The `id` value of that chat is your `TELEGRAM_CHAT_ID`. It will be a negative number like: `-781559558`. Remember to include the negative sign! If you cannot find `"chat":` in the JSON, then you may have to remove the bot from your chat group and add it again. -With your Telegram chat id in hand, export the environment variable where you plan to run `solana-watchtower`: +With your Telegram chat id in hand, export the environment variable where you plan to run `agave-watchtower`: ``` export TELEGRAM_CHAT_ID= ``` -#### Restart solana-watchtower +#### Restart agave-watchtower -Once your environment variables are set, restart `solana-watchtower`. You should see output about your validator. +Once your environment variables are set, restart `agave-watchtower`. You should see output about your validator. To test that your Telegram configuration is working properly, you could stop your validator briefly until it is labeled as delinquent. Up to a minute after the validator is delinquent, you should receive a message in the Telegram group from your bot. Start the validator again and verify that you get another message in your Telegram group from the bot. The message should say `all clear`. \ No newline at end of file diff --git a/docs/src/validator/get-started/setup-a-validator.md b/docs/src/validator/get-started/setup-a-validator.md index 6598400bda5a37..83682f681a1f22 100644 --- a/docs/src/validator/get-started/setup-a-validator.md +++ b/docs/src/validator/get-started/setup-a-validator.md @@ -245,7 +245,7 @@ Your system will need to be tuned in order to run properly. Your validator may n #### **Optimize sysctl knobs** ```bash -sudo bash -c "cat >/etc/sysctl.d/21-solana-validator.conf </etc/sysctl.d/21-agave-validator.conf <>>>>>> e1e36d2fea ([anza migration] rename crates (#10)):docs/src/operations/setup-a-validator.md ## Verifying Your Validator Is Working @@ -368,13 +374,23 @@ Test that your `validator.sh` file is running properly by executing the `validat /home/sol/bin/validator.sh ``` +<<<<<<< HEAD:docs/src/validator/get-started/setup-a-validator.md The script should execute the `solana-validator` process. In a new terminal window, shh into your server, then verify that the process is running: +======= +The script should execute the `agave-validator` process. In a new terminal +window, shh into your server, then verify that the process is running: +>>>>>>> e1e36d2fea ([anza migration] rename crates (#10)):docs/src/operations/setup-a-validator.md ``` -ps aux | grep solana-validator +ps aux | grep agave-validator ``` +<<<<<<< HEAD:docs/src/validator/get-started/setup-a-validator.md You should see a line in the output that includes `solana-validator` with all the flags that were added to your `validator.sh` script. +======= +You should see a line in the output that includes `agave-validator` with all +the flags that were added to your `validator.sh` script. +>>>>>>> e1e36d2fea ([anza migration] rename crates (#10)):docs/src/operations/setup-a-validator.md Next, we need to look at the logs to make sure everything is operating properly. @@ -386,7 +402,7 @@ In a new terminal window, ssh into your validator machine, switch users to the ` ``` su - sol -tail -f solana-validator.log +tail -f agave-validator.log ``` The `tail` command will continue to display the output of a file as the file changes. You should see a continuous stream of log output as your validator runs. Keep an eye out for any lines that say `_ERROR_`. @@ -458,12 +474,19 @@ sudo systemctl enable --now sol Now verify that the validator is running properly by tailing the logs and using the commands mentioned earlier to check gossip and Solana validators: ``` -tail -f /home/sol/solana-validator*.log +tail -f /home/sol/agave-validator*.log ``` ## Monitoring +<<<<<<< HEAD:docs/src/validator/get-started/setup-a-validator.md `solana-watchtower` is a command you can run on a separate machine to monitor your server. You can read more about handling [automatic restarts and monitoring](../best-practices/monitoring.md#solana-watchtower) using Solana Watchtower here in the docs. +======= +`agave-watchtower` is a command you can run on a separate machine to monitor +your server. You can read more about handling +[automatic restarts and monitoring](./best-practices/monitoring.md#agave-watchtower) +using Solana Watchtower here in the docs. +>>>>>>> e1e36d2fea ([anza migration] rename crates (#10)):docs/src/operations/setup-a-validator.md ## Common issues diff --git a/docs/src/validator/get-started/setup-an-rpc-node.md b/docs/src/validator/get-started/setup-an-rpc-node.md index 2c3f35031042e7..9743b25b1bc1a2 100644 --- a/docs/src/validator/get-started/setup-an-rpc-node.md +++ b/docs/src/validator/get-started/setup-an-rpc-node.md @@ -17,11 +17,11 @@ You will want to be aware of the following flags: - `--no-voting`: runs the validator without participating in consensus. Typically, you do not want to run a validator as _both_ a consensus node and a full RPC node due to resource constraints. - `--private-rpc`: does not publish the validator's open RPC port in the `solana gossip` command -> For more explanation on the flags used in the command, refer to the `solana-validator --help` command +> For more explanation on the flags used in the command, refer to the `agave-validator --help` command ``` #!/bin/bash -exec solana-validator \ +exec agave-validator \ --identity /home/sol/validator-keypair.json \ --known-validator 5D1fNXzvv5NjV1ysLjirC4WY92RNsVH18vjmcszZd8on \ --known-validator dDzy5SR3AXdYWVqbDEkVFdvSPCtS9ihF5kJkHCtXoFs \ diff --git a/geyser-plugin-interface/Cargo.toml b/geyser-plugin-interface/Cargo.toml index af99758b47d630..56f42fd4612cec 100644 --- a/geyser-plugin-interface/Cargo.toml +++ b/geyser-plugin-interface/Cargo.toml @@ -1,7 +1,7 @@ [package] -name = "solana-geyser-plugin-interface" +name = "agave-geyser-plugin-interface" description = "The Solana Geyser plugin interface." -documentation = "https://docs.rs/solana-geyser-plugin-interface" +documentation = "https://docs.rs/agave-geyser-plugin-interface" version = { workspace = true } authors = { workspace = true } repository = { workspace = true } diff --git a/geyser-plugin-interface/src/geyser_plugin_interface.rs b/geyser-plugin-interface/src/geyser_plugin_interface.rs index b2bbb5a4953aed..e7d058f9d94340 100644 --- a/geyser-plugin-interface/src/geyser_plugin_interface.rs +++ b/geyser-plugin-interface/src/geyser_plugin_interface.rs @@ -287,6 +287,38 @@ pub type Result = std::result::Result; /// Geyser plugins must describe desired behavior for load and unload, /// as well as how they will handle streamed data. pub trait GeyserPlugin: Any + Send + Sync + std::fmt::Debug { +<<<<<<< HEAD +======= + /// The callback to allow the plugin to setup the logging configuration using the logger + /// and log level specified by the validator. Will be called first on load/reload, before any other + /// callback, and only called once. + /// # Examples + /// + /// ``` + /// use agave_geyser_plugin_interface::geyser_plugin_interface::{GeyserPlugin, + /// GeyserPluginError, Result}; + /// + /// #[derive(Debug)] + /// struct SamplePlugin; + /// impl GeyserPlugin for SamplePlugin { + /// fn setup_logger(&self, logger: &'static dyn log::Log, level: log::LevelFilter) -> Result<()> { + /// log::set_max_level(level); + /// if let Err(err) = log::set_logger(logger) { + /// return Err(GeyserPluginError::Custom(Box::new(err))); + /// } + /// Ok(()) + /// } + /// fn name(&self) -> &'static str { + /// &"sample" + /// } + /// } + /// ``` + #[allow(unused_variables)] + fn setup_logger(&self, logger: &'static dyn log::Log, level: log::LevelFilter) -> Result<()> { + Ok(()) + } + +>>>>>>> e1e36d2fea ([anza migration] rename crates (#10)) fn name(&self) -> &'static str; /// The callback called when a plugin is loaded by the system, diff --git a/geyser-plugin-manager/Cargo.toml b/geyser-plugin-manager/Cargo.toml index 9b4468eddaea9b..fd5a599deacb18 100644 --- a/geyser-plugin-manager/Cargo.toml +++ b/geyser-plugin-manager/Cargo.toml @@ -10,7 +10,11 @@ license = { workspace = true } edition = { workspace = true } [dependencies] +<<<<<<< HEAD +======= +agave-geyser-plugin-interface = { workspace = true } +>>>>>>> e1e36d2fea ([anza migration] rename crates (#10)) bs58 = { workspace = true } crossbeam-channel = { workspace = true } json5 = { workspace = true } @@ -21,7 +25,6 @@ log = { workspace = true } serde_json = { workspace = true } solana-accounts-db = { workspace = true } solana-entry = { workspace = true } -solana-geyser-plugin-interface = { workspace = true } solana-ledger = { workspace = true } solana-measure = { workspace = true } solana-metrics = { workspace = true } diff --git a/geyser-plugin-manager/src/accounts_update_notifier.rs b/geyser-plugin-manager/src/accounts_update_notifier.rs index 7c7e3370fc00eb..90ab0b7998a35c 100644 --- a/geyser-plugin-manager/src/accounts_update_notifier.rs +++ b/geyser-plugin-manager/src/accounts_update_notifier.rs @@ -1,14 +1,14 @@ /// Module responsible for notifying plugins of account updates use { crate::geyser_plugin_manager::GeyserPluginManager, + agave_geyser_plugin_interface::geyser_plugin_interface::{ + ReplicaAccountInfoV3, ReplicaAccountInfoVersions, + }, log::*, solana_accounts_db::{ account_storage::meta::StoredAccountMeta, accounts_update_notifier_interface::AccountsUpdateNotifierInterface, }, - solana_geyser_plugin_interface::geyser_plugin_interface::{ - ReplicaAccountInfoV3, ReplicaAccountInfoVersions, - }, solana_measure::measure::Measure, solana_metrics::*, solana_sdk::{ diff --git a/geyser-plugin-manager/src/block_metadata_notifier.rs b/geyser-plugin-manager/src/block_metadata_notifier.rs index ab56cf3be81701..b436552383a4e5 100644 --- a/geyser-plugin-manager/src/block_metadata_notifier.rs +++ b/geyser-plugin-manager/src/block_metadata_notifier.rs @@ -3,11 +3,16 @@ use { block_metadata_notifier_interface::BlockMetadataNotifier, geyser_plugin_manager::GeyserPluginManager, }, +<<<<<<< HEAD log::*, solana_accounts_db::stake_rewards::RewardInfo, solana_geyser_plugin_interface::geyser_plugin_interface::{ +======= + agave_geyser_plugin_interface::geyser_plugin_interface::{ +>>>>>>> e1e36d2fea ([anza migration] rename crates (#10)) ReplicaBlockInfoV3, ReplicaBlockInfoVersions, }, + log::*, solana_measure::measure::Measure, solana_metrics::*, solana_sdk::{clock::UnixTimestamp, pubkey::Pubkey}, diff --git a/geyser-plugin-manager/src/entry_notifier.rs b/geyser-plugin-manager/src/entry_notifier.rs index ce6c3239c0946c..7a58b5a6fac745 100644 --- a/geyser-plugin-manager/src/entry_notifier.rs +++ b/geyser-plugin-manager/src/entry_notifier.rs @@ -1,11 +1,18 @@ /// Module responsible for notifying plugins about entries use { crate::geyser_plugin_manager::GeyserPluginManager, +<<<<<<< HEAD log::*, solana_entry::entry::EntrySummary, solana_geyser_plugin_interface::geyser_plugin_interface::{ ReplicaEntryInfo, ReplicaEntryInfoVersions, +======= + agave_geyser_plugin_interface::geyser_plugin_interface::{ + ReplicaEntryInfoV2, ReplicaEntryInfoVersions, +>>>>>>> e1e36d2fea ([anza migration] rename crates (#10)) }, + log::*, + solana_entry::entry::EntrySummary, solana_ledger::entry_notifier_interface::EntryNotifier, solana_measure::measure::Measure, solana_metrics::*, diff --git a/geyser-plugin-manager/src/geyser_plugin_manager.rs b/geyser-plugin-manager/src/geyser_plugin_manager.rs index c5da56859e2b36..48ee75e80b9bb2 100644 --- a/geyser-plugin-manager/src/geyser_plugin_manager.rs +++ b/geyser-plugin-manager/src/geyser_plugin_manager.rs @@ -1,9 +1,9 @@ use { + agave_geyser_plugin_interface::geyser_plugin_interface::GeyserPlugin, jsonrpc_core::{ErrorCode, Result as JsonRpcResult}, jsonrpc_server_utils::tokio::sync::oneshot::Sender as OneShotSender, libloading::Library, log::*, - solana_geyser_plugin_interface::geyser_plugin_interface::GeyserPlugin, std::{ ops::{Deref, DerefMut}, path::Path, @@ -419,8 +419,8 @@ mod tests { crate::geyser_plugin_manager::{ GeyserPluginManager, LoadedGeyserPlugin, TESTPLUGIN2_CONFIG, TESTPLUGIN_CONFIG, }, + agave_geyser_plugin_interface::geyser_plugin_interface::GeyserPlugin, libloading::Library, - solana_geyser_plugin_interface::geyser_plugin_interface::GeyserPlugin, std::sync::{Arc, RwLock}, }; diff --git a/geyser-plugin-manager/src/slot_status_notifier.rs b/geyser-plugin-manager/src/slot_status_notifier.rs index 587abe2f79d4de..1557bb2d4d8c36 100644 --- a/geyser-plugin-manager/src/slot_status_notifier.rs +++ b/geyser-plugin-manager/src/slot_status_notifier.rs @@ -1,7 +1,7 @@ use { crate::geyser_plugin_manager::GeyserPluginManager, + agave_geyser_plugin_interface::geyser_plugin_interface::SlotStatus, log::*, - solana_geyser_plugin_interface::geyser_plugin_interface::SlotStatus, solana_measure::measure::Measure, solana_metrics::*, solana_sdk::clock::Slot, diff --git a/geyser-plugin-manager/src/transaction_notifier.rs b/geyser-plugin-manager/src/transaction_notifier.rs index ab821e811047d2..b757c1202b377d 100644 --- a/geyser-plugin-manager/src/transaction_notifier.rs +++ b/geyser-plugin-manager/src/transaction_notifier.rs @@ -1,10 +1,10 @@ /// Module responsible for notifying plugins of transactions use { crate::geyser_plugin_manager::GeyserPluginManager, - log::*, - solana_geyser_plugin_interface::geyser_plugin_interface::{ + agave_geyser_plugin_interface::geyser_plugin_interface::{ ReplicaTransactionInfoV2, ReplicaTransactionInfoVersions, }, + log::*, solana_measure::measure::Measure, solana_metrics::*, solana_rpc::transaction_notifier_interface::TransactionNotifier, diff --git a/install/Cargo.toml b/install/Cargo.toml index 588d4315df5f35..c40a0ee6e9eee3 100644 --- a/install/Cargo.toml +++ b/install/Cargo.toml @@ -1,7 +1,7 @@ [package] -name = "solana-install" +name = "agave-install" description = "The solana cluster software installer" -documentation = "https://docs.rs/solana-install" +documentation = "https://docs.rs/agave-install" version = { workspace = true } authors = { workspace = true } repository = { workspace = true } diff --git a/install/solana-install-init.sh b/install/agave-install-init.sh similarity index 89% rename from install/solana-install-init.sh rename to install/agave-install-init.sh index 4f28e300be52ab..cf2d1babf3c306 100755 --- a/install/solana-install-init.sh +++ b/install/agave-install-init.sh @@ -10,7 +10,7 @@ # except according to those terms. # This is just a little script that can be downloaded from the internet to -# install solana-install. It just does platform detection, downloads the installer +# install agave-install. It just does platform detection, downloads the installer # and runs it. { # this ensures the entire script is downloaded # @@ -24,11 +24,11 @@ set -e usage() { cat 1>&2 < --pubkey + agave-install-init [FLAGS] [OPTIONS] --data_dir --pubkey FLAGS: -h, --help Prints help information @@ -81,7 +81,7 @@ main() { esac TARGET="${_cputype}-${_ostype}" - temp_dir="$(mktemp -d 2>/dev/null || ensure mktemp -d -t solana-install-init)" + temp_dir="$(mktemp -d 2>/dev/null || ensure mktemp -d -t agave-install-init)" ensure mkdir -p "$temp_dir" # Check for SOLANA_RELEASE environment variable override. Otherwise fetch @@ -101,8 +101,8 @@ main() { fi fi - download_url="$SOLANA_DOWNLOAD_ROOT/$release/solana-install-init-$TARGET" - solana_install_init="$temp_dir/solana-install-init" + download_url="$SOLANA_DOWNLOAD_ROOT/$release/agave-install-init-$TARGET" + solana_install_init="$temp_dir/agave-install-init" printf 'downloading %s installer\n' "$release" 1>&2 @@ -111,7 +111,7 @@ main() { ensure chmod u+x "$solana_install_init" if [ ! -x "$solana_install_init" ]; then printf '%s\n' "Cannot execute $solana_install_init (likely because of mounting /tmp as noexec)." 1>&2 - printf '%s\n' "Please copy the file to a location where you can execute binaries and run ./solana-install-init." 1>&2 + printf '%s\n' "Please copy the file to a location where you can execute binaries and run ./agave-install-init." 1>&2 exit 1 fi @@ -130,7 +130,7 @@ main() { } err() { - printf 'solana-install-init: %s\n' "$1" >&2 + printf 'agave-install-init: %s\n' "$1" >&2 exit 1 } diff --git a/install/install-help.sh b/install/install-help.sh index 9fb08afa6d14c9..7604777e378677 100755 --- a/install/install-help.sh +++ b/install/install-help.sh @@ -4,11 +4,11 @@ set -e cd "$(dirname "$0")"/.. cargo="$(readlink -f "./cargo")" -"$cargo" build --package solana-install +"$cargo" build --package agave-install export PATH=$PWD/target/debug:$PATH echo "\`\`\`manpage" -solana-install --help +agave-install --help echo "\`\`\`" echo "" @@ -16,7 +16,7 @@ commands=(init info deploy update run) for x in "${commands[@]}"; do echo "\`\`\`manpage" - solana-install "${x}" --help + agave-install "${x}" --help echo "\`\`\`" echo "" done diff --git a/install/src/bin/solana-install-init.rs b/install/src/bin/agave-install-init.rs similarity index 92% rename from install/src/bin/solana-install-init.rs rename to install/src/bin/agave-install-init.rs index ec888d8f452090..84c154ac12b35e 100644 --- a/install/src/bin/solana-install-init.rs +++ b/install/src/bin/agave-install-init.rs @@ -16,7 +16,7 @@ fn press_enter() { } fn main() { - solana_install::main_init().unwrap_or_else(|err| { + agave_install::main_init().unwrap_or_else(|err| { println!("Error: {err}"); press_enter(); exit(1); diff --git a/install/src/command.rs b/install/src/command.rs index 6f720c395bc331..996799835fa6ba 100644 --- a/install/src/command.rs +++ b/install/src/command.rs @@ -541,7 +541,7 @@ pub fn init( explicit_release: Option, ) -> Result<(), String> { let config = { - // Write new config file only if different, so that running |solana-install init| + // Write new config file only if different, so that running |agave-install init| // repeatedly doesn't unnecessarily re-download let mut current_config = Config::load(config_file).unwrap_or_default(); current_config.current_update_manifest = None; @@ -871,7 +871,7 @@ fn check_for_newer_github_release( prerelease_allowed: bool, ) -> Result, String> { let client = reqwest::blocking::Client::builder() - .user_agent("solana-install") + .user_agent("agave-install") .build() .map_err(|err| err.to_string())?; diff --git a/install/src/lib.rs b/install/src/lib.rs index 159317edd2e5a8..a28b963d65f825 100644 --- a/install/src/lib.rs +++ b/install/src/lib.rs @@ -281,7 +281,7 @@ pub fn main() -> Result<(), String> { pub fn main_init() -> Result<(), String> { solana_logger::setup(); - let matches = App::new("solana-install-init") + let matches = App::new("agave-install-init") .about("Initializes a new installation") .version(solana_version::version!()) .arg({ diff --git a/install/src/main.rs b/install/src/main.rs index c7b15aa6a67206..245f09825ddc6a 100644 --- a/install/src/main.rs +++ b/install/src/main.rs @@ -1,3 +1,3 @@ fn main() -> Result<(), String> { - solana_install::main() + agave_install::main() } diff --git a/ledger-tool/Cargo.toml b/ledger-tool/Cargo.toml index fb387773c14cfa..66b4b551064a8c 100644 --- a/ledger-tool/Cargo.toml +++ b/ledger-tool/Cargo.toml @@ -1,7 +1,7 @@ [package] -name = "solana-ledger-tool" +name = "agave-ledger-tool" description = "Blockchain, Rebuilt for Scale" -documentation = "https://docs.rs/solana-ledger-tool" +documentation = "https://docs.rs/agave-ledger-tool" version = { workspace = true } authors = { workspace = true } repository = { workspace = true } diff --git a/ledger-tool/src/blockstore.rs b/ledger-tool/src/blockstore.rs new file mode 100644 index 00000000000000..bd9e9809da3b9d --- /dev/null +++ b/ledger-tool/src/blockstore.rs @@ -0,0 +1,1127 @@ +//! The `blockstore` subcommand + +use { + crate::{ + ledger_path::canonicalize_ledger_path, + ledger_utils::{get_program_ids, get_shred_storage_type}, + output::{output_ledger, output_slot, SlotBounds, SlotInfo}, + }, + chrono::{DateTime, Utc}, + clap::{ + value_t, value_t_or_exit, values_t_or_exit, App, AppSettings, Arg, ArgMatches, SubCommand, + }, + itertools::Itertools, + log::*, + regex::Regex, + serde_json::json, + solana_clap_utils::{hidden_unless_forced, input_validators::is_slot}, + solana_cli_output::OutputFormat, + solana_ledger::{ + ancestor_iterator::AncestorIterator, + blockstore::{Blockstore, PurgeType}, + blockstore_db::{self, Column, ColumnName, Database}, + blockstore_options::{AccessType, BLOCKSTORE_DIRECTORY_ROCKS_FIFO}, + shred::Shred, + }, + solana_sdk::{ + clock::{Slot, UnixTimestamp}, + hash::Hash, + }, + std::{ + collections::{BTreeMap, BTreeSet, HashMap}, + fs::File, + io::{stdout, BufRead, BufReader, Write}, + path::{Path, PathBuf}, + sync::atomic::AtomicBool, + time::{Duration, UNIX_EPOCH}, + }, +}; + +fn analyze_column< + C: solana_ledger::blockstore_db::Column + solana_ledger::blockstore_db::ColumnName, +>( + db: &Database, + name: &str, +) { + let mut key_len: u64 = 0; + let mut key_tot: u64 = 0; + let mut val_hist = histogram::Histogram::new(); + let mut val_tot: u64 = 0; + let mut row_hist = histogram::Histogram::new(); + for (key, val) in db.iter::(blockstore_db::IteratorMode::Start).unwrap() { + // Key length is fixed, only need to calculate it once + if key_len == 0 { + key_len = C::key(key).len() as u64; + } + let val_len = val.len() as u64; + + key_tot += key_len; + val_hist.increment(val_len).unwrap(); + val_tot += val_len; + + row_hist.increment(key_len + val_len).unwrap(); + } + + let json_result = if val_hist.entries() > 0 { + json!({ + "column":name, + "entries":val_hist.entries(), + "key_stats":{ + "max":key_len, + "total_bytes":key_tot, + }, + "val_stats":{ + "p50":val_hist.percentile(50.0).unwrap(), + "p90":val_hist.percentile(90.0).unwrap(), + "p99":val_hist.percentile(99.0).unwrap(), + "p999":val_hist.percentile(99.9).unwrap(), + "min":val_hist.minimum().unwrap(), + "max":val_hist.maximum().unwrap(), + "stddev":val_hist.stddev().unwrap(), + "total_bytes":val_tot, + }, + "row_stats":{ + "p50":row_hist.percentile(50.0).unwrap(), + "p90":row_hist.percentile(90.0).unwrap(), + "p99":row_hist.percentile(99.0).unwrap(), + "p999":row_hist.percentile(99.9).unwrap(), + "min":row_hist.minimum().unwrap(), + "max":row_hist.maximum().unwrap(), + "stddev":row_hist.stddev().unwrap(), + "total_bytes":key_tot + val_tot, + }, + }) + } else { + json!({ + "column":name, + "entries":val_hist.entries(), + "key_stats":{ + "max":key_len, + "total_bytes":0, + }, + "val_stats":{ + "total_bytes":0, + }, + "row_stats":{ + "total_bytes":0, + }, + }) + }; + + println!("{}", serde_json::to_string_pretty(&json_result).unwrap()); +} + +fn analyze_storage(database: &Database) { + use solana_ledger::blockstore_db::columns::*; + analyze_column::(database, "SlotMeta"); + analyze_column::(database, "Orphans"); + analyze_column::(database, "DeadSlots"); + analyze_column::(database, "DuplicateSlots"); + analyze_column::(database, "ErasureMeta"); + analyze_column::(database, "BankHash"); + analyze_column::(database, "Root"); + analyze_column::(database, "Index"); + analyze_column::(database, "ShredData"); + analyze_column::(database, "ShredCode"); + analyze_column::(database, "TransactionStatus"); + analyze_column::(database, "AddressSignatures"); + analyze_column::(database, "TransactionMemos"); + analyze_column::(database, "TransactionStatusIndex"); + analyze_column::(database, "Rewards"); + analyze_column::(database, "Blocktime"); + analyze_column::(database, "PerfSamples"); + analyze_column::(database, "BlockHeight"); + analyze_column::(database, "ProgramCosts"); + analyze_column::(database, "OptimisticSlots"); +} + +fn raw_key_to_slot(key: &[u8], column_name: &str) -> Option { + use solana_ledger::blockstore_db::columns as cf; + match column_name { + cf::SlotMeta::NAME => Some(cf::SlotMeta::slot(cf::SlotMeta::index(key))), + cf::Orphans::NAME => Some(cf::Orphans::slot(cf::Orphans::index(key))), + cf::DeadSlots::NAME => Some(cf::SlotMeta::slot(cf::SlotMeta::index(key))), + cf::DuplicateSlots::NAME => Some(cf::SlotMeta::slot(cf::SlotMeta::index(key))), + cf::ErasureMeta::NAME => Some(cf::ErasureMeta::slot(cf::ErasureMeta::index(key))), + cf::BankHash::NAME => Some(cf::BankHash::slot(cf::BankHash::index(key))), + cf::Root::NAME => Some(cf::Root::slot(cf::Root::index(key))), + cf::Index::NAME => Some(cf::Index::slot(cf::Index::index(key))), + cf::ShredData::NAME => Some(cf::ShredData::slot(cf::ShredData::index(key))), + cf::ShredCode::NAME => Some(cf::ShredCode::slot(cf::ShredCode::index(key))), + cf::TransactionStatus::NAME => Some(cf::TransactionStatus::slot( + cf::TransactionStatus::index(key), + )), + cf::AddressSignatures::NAME => Some(cf::AddressSignatures::slot( + cf::AddressSignatures::index(key), + )), + cf::TransactionMemos::NAME => None, // does not implement slot() + cf::TransactionStatusIndex::NAME => None, // does not implement slot() + cf::Rewards::NAME => Some(cf::Rewards::slot(cf::Rewards::index(key))), + cf::Blocktime::NAME => Some(cf::Blocktime::slot(cf::Blocktime::index(key))), + cf::PerfSamples::NAME => Some(cf::PerfSamples::slot(cf::PerfSamples::index(key))), + cf::BlockHeight::NAME => Some(cf::BlockHeight::slot(cf::BlockHeight::index(key))), + cf::ProgramCosts::NAME => None, // does not implement slot() + cf::OptimisticSlots::NAME => { + Some(cf::OptimisticSlots::slot(cf::OptimisticSlots::index(key))) + } + &_ => None, + } +} + +/// Returns true if the supplied slot contains any nonvote transactions +fn slot_contains_nonvote_tx(blockstore: &Blockstore, slot: Slot) -> bool { + let (entries, _, _) = blockstore + .get_slot_entries_with_shred_info(slot, 0, false) + .expect("Failed to get slot entries"); + let contains_nonvote = entries + .iter() + .flat_map(|entry| entry.transactions.iter()) + .flat_map(get_program_ids) + .any(|program_id| *program_id != solana_vote_program::id()); + contains_nonvote +} + +type OptimisticSlotInfo = (Slot, Option<(Hash, UnixTimestamp)>, bool); + +/// Return the latest `num_slots` optimistically confirmed slots, including +/// ancestors of optimistically confirmed slots that may not have been marked +/// as optimistically confirmed themselves. +fn get_latest_optimistic_slots( + blockstore: &Blockstore, + num_slots: usize, + exclude_vote_only_slots: bool, +) -> Vec { + // Consider a chain X -> Y -> Z where X and Z have been optimistically + // confirmed. Given that Y is an ancestor of Z, Y can implicitly be + // considered as optimistically confirmed. However, there isn't an explicit + // guarantee that Y will be marked as optimistically confirmed in the + // blockstore. + // + // Because retrieving optimistically confirmed slots is an important part + // of cluster restarts, exercise caution in this function and manually walk + // the ancestors of the latest optimistically confirmed slot instead of + // solely relying on the contents of the optimistically confirmed column. + let Some(latest_slot) = blockstore + .get_latest_optimistic_slots(1) + .expect("get_latest_optimistic_slots() failed") + .pop() + else { + eprintln!("Blockstore does not contain any optimistically confirmed slots"); + return vec![]; + }; + let latest_slot = latest_slot.0; + + let slot_iter = AncestorIterator::new_inclusive(latest_slot, blockstore).map(|slot| { + let contains_nonvote_tx = slot_contains_nonvote_tx(blockstore, slot); + let hash_and_timestamp_opt = blockstore + .get_optimistic_slot(slot) + .expect("get_optimistic_slot() failed"); + if hash_and_timestamp_opt.is_none() { + warn!( + "Slot {slot} is an ancestor of latest optimistically confirmed slot \ + {latest_slot}, but was not marked as optimistically confirmed in blockstore." + ); + } + (slot, hash_and_timestamp_opt, contains_nonvote_tx) + }); + + if exclude_vote_only_slots { + slot_iter + .filter(|(_, _, contains_nonvote)| *contains_nonvote) + .take(num_slots) + .collect() + } else { + slot_iter.take(num_slots).collect() + } +} + +fn print_blockstore_file_metadata( + blockstore: &Blockstore, + file_name: &Option<&str>, +) -> Result<(), String> { + let live_files = blockstore + .live_files_metadata() + .map_err(|err| format!("{err:?}"))?; + + // All files under live_files_metadata are prefixed with "/". + let sst_file_name = file_name.as_ref().map(|name| format!("/{name}")); + for file in live_files { + if sst_file_name.is_none() || file.name.eq(sst_file_name.as_ref().unwrap()) { + println!( + "[{}] cf_name: {}, level: {}, start_slot: {:?}, end_slot: {:?}, size: {}, \ + num_entries: {}", + file.name, + file.column_family_name, + file.level, + raw_key_to_slot(&file.start_key.unwrap(), &file.column_family_name), + raw_key_to_slot(&file.end_key.unwrap(), &file.column_family_name), + file.size, + file.num_entries, + ); + if sst_file_name.is_some() { + return Ok(()); + } + } + } + if sst_file_name.is_some() { + return Err(format!( + "Failed to find or load the metadata of the specified file {file_name:?}" + )); + } + Ok(()) +} + +pub trait BlockstoreSubCommand { + fn blockstore_subcommand(self) -> Self; +} + +impl BlockstoreSubCommand for App<'_, '_> { + fn blockstore_subcommand(self) -> Self { + self.subcommand( + SubCommand::with_name("blockstore") + .about("Commands to interact with a local Blockstore") + .setting(AppSettings::InferSubcommands) + .setting(AppSettings::SubcommandRequiredElseHelp) + .subcommands(blockstore_subcommands(false)), + ) + } +} + +pub fn blockstore_subcommands<'a, 'b>(hidden: bool) -> Vec> { + let hidden = if hidden { + vec![AppSettings::Hidden] + } else { + vec![] + }; + + let starting_slot_arg = Arg::with_name("starting_slot") + .long("starting-slot") + .value_name("SLOT") + .takes_value(true) + .default_value("0") + .help("Start at this slot"); + let ending_slot_arg = Arg::with_name("ending_slot") + .long("ending-slot") + .value_name("SLOT") + .takes_value(true) + .help("The last slot to iterate to"); + let allow_dead_slots_arg = Arg::with_name("allow_dead_slots") + .long("allow-dead-slots") + .takes_value(false) + .help("Output dead slots as well"); + + vec![ + SubCommand::with_name("analyze-storage") + .about( + "Output statistics in JSON format about all column families in the ledger \ + rocksdb", + ) + .settings(&hidden), + SubCommand::with_name("bounds") + .about( + "Print lowest and highest non-empty slots. Note that there may be empty slots \ + within the bounds", + ) + .settings(&hidden) + .arg( + Arg::with_name("all") + .long("all") + .takes_value(false) + .required(false) + .help("Additionally print all the non-empty slots within the bounds"), + ), + SubCommand::with_name("copy") + .about("Copy the ledger") + .settings(&hidden) + .arg(&starting_slot_arg) + .arg(&ending_slot_arg) + .arg( + Arg::with_name("target_db") + .long("target-db") + .value_name("DIR") + .takes_value(true) + .help("Target db"), + ), + SubCommand::with_name("dead-slots") + .about("Print all the dead slots in the ledger") + .settings(&hidden) + .arg(&starting_slot_arg), + SubCommand::with_name("duplicate-slots") + .about("Print all the duplicate slots in the ledger") + .settings(&hidden) + .arg(&starting_slot_arg), + SubCommand::with_name("json") + .about("Print the ledger in JSON format") + .settings(&hidden) + .arg(&starting_slot_arg) + .arg(&ending_slot_arg) + .arg(&allow_dead_slots_arg), + SubCommand::with_name("latest-optimistic-slots") + .about( + "Output up to the most recent optimistic slots with their hashes \ + and timestamps.", + ) + // This command is important in cluster restart scenarios, so do not hide it ever + // such that the subcommand will be visible as the top level of agave-ledger-tool + .arg( + Arg::with_name("num_slots") + .long("num-slots") + .value_name("NUM") + .takes_value(true) + .default_value("1") + .required(false) + .help("Number of slots in the output"), + ) + .arg( + Arg::with_name("exclude_vote_only_slots") + .long("exclude-vote-only-slots") + .required(false) + .help("Exclude slots that contain only votes from output"), + ), + SubCommand::with_name("list-roots") + .about( + "Output up to last root hashes and their heights starting at the \ + given block height", + ) + .settings(&hidden) + .arg( + Arg::with_name("max_height") + .long("max-height") + .value_name("NUM") + .takes_value(true) + .help("Maximum block height"), + ) + .arg( + Arg::with_name("start_root") + .long("start-root") + .value_name("NUM") + .takes_value(true) + .help("First root to start searching from"), + ) + .arg( + Arg::with_name("slot_list") + .long("slot-list") + .value_name("FILENAME") + .required(false) + .takes_value(true) + .help( + "The location of the output YAML file. A list of rollback slot \ + heights and hashes will be written to the file", + ), + ) + .arg( + Arg::with_name("num_roots") + .long("num-roots") + .value_name("NUM") + .takes_value(true) + .default_value("1") + .required(false) + .help("Number of roots in the output"), + ), + SubCommand::with_name("parse_full_frozen") + .about( + "Parses log for information about critical events about ancestors of the given \ + `ending_slot`", + ) + .settings(&hidden) + .arg(&starting_slot_arg) + .arg(&ending_slot_arg) + .arg( + Arg::with_name("log_path") + .long("log-path") + .value_name("PATH") + .takes_value(true) + .help("path to log file to parse"), + ), + SubCommand::with_name("print") + .about("Print the ledger") + .settings(&hidden) + .arg(&starting_slot_arg) + .arg(&ending_slot_arg) + .arg(&allow_dead_slots_arg) + .arg( + Arg::with_name("num_slots") + .long("num-slots") + .value_name("SLOT") + .validator(is_slot) + .takes_value(true) + .help("Number of slots to print"), + ) + .arg( + Arg::with_name("only_rooted") + .long("only-rooted") + .takes_value(false) + .help("Only print root slots"), + ), + SubCommand::with_name("print-file-metadata") + .about( + "Print the metadata of the specified ledger-store file. If no file name is \ + specified, it will print the metadata of all ledger files.", + ) + .settings(&hidden) + .arg( + Arg::with_name("file_name") + .long("file-name") + .takes_value(true) + .value_name("SST_FILE_NAME") + .help( + "The ledger file name (e.g. 011080.sst.) If no file name is \ + specified, it will print the metadata of all ledger files.", + ), + ), + SubCommand::with_name("purge") + .about("Delete a range of slots from the ledger") + .settings(&hidden) + .arg( + Arg::with_name("start_slot") + .index(1) + .value_name("SLOT") + .takes_value(true) + .required(true) + .help("Start slot to purge from (inclusive)"), + ) + .arg(Arg::with_name("end_slot").index(2).value_name("SLOT").help( + "Ending slot to stop purging (inclusive) \ + [default: the highest slot in the ledger]", + )) + .arg( + Arg::with_name("batch_size") + .long("batch-size") + .value_name("NUM") + .takes_value(true) + .default_value("1000") + .help("Removes at most BATCH_SIZE slots while purging in loop"), + ) + .arg( + Arg::with_name("no_compaction") + .long("no-compaction") + .required(false) + .takes_value(false) + .help( + "--no-compaction is deprecated, ledger compaction after purge is \ + disabled by default", + ) + .conflicts_with("enable_compaction") + .hidden(hidden_unless_forced()), + ) + .arg( + Arg::with_name("enable_compaction") + .long("enable-compaction") + .required(false) + .takes_value(false) + .help( + "Perform ledger compaction after purge. Compaction will optimize \ + storage space, but may take a long time to complete.", + ) + .conflicts_with("no_compaction"), + ) + .arg( + Arg::with_name("dead_slots_only") + .long("dead-slots-only") + .required(false) + .takes_value(false) + .help("Limit purging to dead slots only"), + ), + SubCommand::with_name("remove-dead-slot") + .about("Remove the dead flag for a slot") + .settings(&hidden) + .arg( + Arg::with_name("slots") + .index(1) + .value_name("SLOTS") + .validator(is_slot) + .takes_value(true) + .multiple(true) + .required(true) + .help("Slots to mark as not dead"), + ), + SubCommand::with_name("repair-roots") + .about( + "Traverses the AncestorIterator backward from a last known root to restore \ + missing roots to the Root column", + ) + .settings(&hidden) + .arg( + Arg::with_name("start_root") + .long("before") + .value_name("NUM") + .takes_value(true) + .help("Recent root after the range to repair"), + ) + .arg( + Arg::with_name("end_root") + .long("until") + .value_name("NUM") + .takes_value(true) + .help("Earliest slot to check for root repair"), + ) + .arg( + Arg::with_name("max_slots") + .long("repair-limit") + .value_name("NUM") + .takes_value(true) + .default_value("2000") + .required(true) + .help("Override the maximum number of slots to check for root repair"), + ), + SubCommand::with_name("set-dead-slot") + .about("Mark one or more slots dead") + .settings(&hidden) + .arg( + Arg::with_name("slots") + .index(1) + .value_name("SLOTS") + .validator(is_slot) + .takes_value(true) + .multiple(true) + .required(true) + .help("Slots to mark dead"), + ), + SubCommand::with_name("shred-meta") + .about("Prints raw shred metadata") + .settings(&hidden) + .arg(&starting_slot_arg) + .arg(&ending_slot_arg), + SubCommand::with_name("slot") + .about("Print the contents of one or more slots") + .settings(&hidden) + .arg(&allow_dead_slots_arg) + .arg( + Arg::with_name("slots") + .index(1) + .value_name("SLOTS") + .validator(is_slot) + .takes_value(true) + .multiple(true) + .required(true) + .help("Slots to print"), + ), + ] +} + +pub fn blockstore_process_command(ledger_path: &Path, matches: &ArgMatches<'_>) { + let ledger_path = canonicalize_ledger_path(ledger_path); + let verbose_level = matches.occurrences_of("verbose"); + + match matches.subcommand() { + ("analyze-storage", Some(arg_matches)) => { + analyze_storage( + &crate::open_blockstore(&ledger_path, arg_matches, AccessType::Secondary).db(), + ); + } + ("bounds", Some(arg_matches)) => { + let blockstore = + crate::open_blockstore(&ledger_path, arg_matches, AccessType::Secondary); + + match blockstore.slot_meta_iterator(0) { + Ok(metas) => { + let output_format = + OutputFormat::from_matches(arg_matches, "output_format", false); + let all = arg_matches.is_present("all"); + + let slots: Vec<_> = metas.map(|(slot, _)| slot).collect(); + + let slot_bounds = if slots.is_empty() { + SlotBounds::default() + } else { + // Collect info about slot bounds + let mut bounds = SlotBounds { + slots: SlotInfo { + total: slots.len(), + first: Some(*slots.first().unwrap()), + last: Some(*slots.last().unwrap()), + ..SlotInfo::default() + }, + ..SlotBounds::default() + }; + if all { + bounds.all_slots = Some(&slots); + } + + // Consider also rooted slots, if present + if let Ok(rooted) = blockstore.rooted_slot_iterator(0) { + let mut first_rooted = None; + let mut last_rooted = None; + let mut total_rooted = 0; + for (i, slot) in rooted.into_iter().enumerate() { + if i == 0 { + first_rooted = Some(slot); + } + last_rooted = Some(slot); + total_rooted += 1; + } + let last_root_for_comparison = last_rooted.unwrap_or_default(); + let count_past_root = slots + .iter() + .rev() + .take_while(|slot| *slot > &last_root_for_comparison) + .count(); + + bounds.roots = SlotInfo { + total: total_rooted, + first: first_rooted, + last: last_rooted, + num_after_last_root: Some(count_past_root), + }; + } + bounds + }; + + // Print collected data + println!("{}", output_format.formatted_string(&slot_bounds)); + } + Err(err) => { + eprintln!("Unable to read the Ledger: {err:?}"); + std::process::exit(1); + } + }; + } + ("copy", Some(arg_matches)) => { + let starting_slot = value_t_or_exit!(arg_matches, "starting_slot", Slot); + let ending_slot = value_t_or_exit!(arg_matches, "ending_slot", Slot); + let target_db = PathBuf::from(value_t_or_exit!(arg_matches, "target_db", String)); + + let source = crate::open_blockstore(&ledger_path, arg_matches, AccessType::Secondary); + + // Check if shred storage type can be inferred; if not, a new + // ledger is being created. open_blockstore() will attempt to + // to infer shred storage type as well, but this check provides + // extra insight to user on how to create a FIFO ledger. + let _ = get_shred_storage_type( + &target_db, + &format!( + "No --target-db ledger at {:?} was detected, default compaction \ + (RocksLevel) will be used. Fifo compaction can be enabled for a new \ + ledger by manually creating {BLOCKSTORE_DIRECTORY_ROCKS_FIFO} directory \ + within the specified --target_db directory.", + &target_db + ), + ); + let target = crate::open_blockstore(&target_db, arg_matches, AccessType::Primary); + for (slot, _meta) in source.slot_meta_iterator(starting_slot).unwrap() { + if slot > ending_slot { + break; + } + if let Ok(shreds) = source.get_data_shreds_for_slot(slot, 0) { + if target.insert_shreds(shreds, None, true).is_err() { + warn!("error inserting shreds for slot {}", slot); + } + } + } + } + ("dead-slots", Some(arg_matches)) => { + let blockstore = + crate::open_blockstore(&ledger_path, arg_matches, AccessType::Secondary); + let starting_slot = value_t_or_exit!(arg_matches, "starting_slot", Slot); + for slot in blockstore.dead_slots_iterator(starting_slot).unwrap() { + println!("{slot}"); + } + } + ("duplicate-slots", Some(arg_matches)) => { + let blockstore = + crate::open_blockstore(&ledger_path, arg_matches, AccessType::Secondary); + let starting_slot = value_t_or_exit!(arg_matches, "starting_slot", Slot); + for slot in blockstore.duplicate_slots_iterator(starting_slot).unwrap() { + println!("{slot}"); + } + } + ("json", Some(arg_matches)) => { + let starting_slot = value_t_or_exit!(arg_matches, "starting_slot", Slot); + let ending_slot = value_t!(arg_matches, "ending_slot", Slot).unwrap_or(Slot::MAX); + let allow_dead_slots = arg_matches.is_present("allow_dead_slots"); + output_ledger( + crate::open_blockstore(&ledger_path, arg_matches, AccessType::Secondary), + starting_slot, + ending_slot, + allow_dead_slots, + OutputFormat::Json, + None, + std::u64::MAX, + true, + ); + } + ("latest-optimistic-slots", Some(arg_matches)) => { + let blockstore = + crate::open_blockstore(&ledger_path, arg_matches, AccessType::Secondary); + let num_slots = value_t_or_exit!(arg_matches, "num_slots", usize); + let exclude_vote_only_slots = arg_matches.is_present("exclude_vote_only_slots"); + let slots = + get_latest_optimistic_slots(&blockstore, num_slots, exclude_vote_only_slots); + + println!( + "{:>20} {:>44} {:>32} {:>13}", + "Slot", "Hash", "Timestamp", "Vote Only?" + ); + for (slot, hash_and_timestamp_opt, contains_nonvote) in slots.iter() { + let (time_str, hash_str) = if let Some((hash, timestamp)) = hash_and_timestamp_opt { + let secs: u64 = (timestamp / 1_000) as u64; + let nanos: u32 = ((timestamp % 1_000) * 1_000_000) as u32; + let t = UNIX_EPOCH + Duration::new(secs, nanos); + let datetime: DateTime = t.into(); + + (datetime.to_rfc3339(), format!("{hash}")) + } else { + let unknown = "Unknown"; + (String::from(unknown), String::from(unknown)) + }; + println!( + "{:>20} {:>44} {:>32} {:>13}", + slot, &hash_str, &time_str, !contains_nonvote + ); + } + } + ("list-roots", Some(arg_matches)) => { + let blockstore = + crate::open_blockstore(&ledger_path, arg_matches, AccessType::Secondary); + + let max_height = value_t!(arg_matches, "max_height", usize).unwrap_or(usize::MAX); + let start_root = value_t!(arg_matches, "start_root", Slot).unwrap_or(0); + let num_roots = value_t_or_exit!(arg_matches, "num_roots", usize); + + let iter = blockstore + .rooted_slot_iterator(start_root) + .expect("Failed to get rooted slot"); + + let mut output: Box = if let Some(path) = arg_matches.value_of("slot_list") { + match File::create(path) { + Ok(file) => Box::new(file), + _ => Box::new(stdout()), + } + } else { + Box::new(stdout()) + }; + + iter.take(num_roots) + .take_while(|slot| *slot <= max_height as u64) + .collect::>() + .into_iter() + .rev() + .for_each(|slot| { + let blockhash = blockstore + .get_slot_entries(slot, 0) + .unwrap() + .last() + .unwrap() + .hash; + + writeln!(output, "{slot}: {blockhash:?}").expect("failed to write"); + }); + } + ("parse_full_frozen", Some(arg_matches)) => { + let starting_slot = value_t_or_exit!(arg_matches, "starting_slot", Slot); + let ending_slot = value_t_or_exit!(arg_matches, "ending_slot", Slot); + let blockstore = + crate::open_blockstore(&ledger_path, arg_matches, AccessType::Secondary); + let mut ancestors = BTreeSet::new(); + assert!( + blockstore.meta(ending_slot).unwrap().is_some(), + "Ending slot doesn't exist" + ); + for a in AncestorIterator::new(ending_slot, &blockstore) { + ancestors.insert(a); + if a <= starting_slot { + break; + } + } + println!("ancestors: {:?}", ancestors.iter()); + + let mut frozen = BTreeMap::new(); + let mut full = BTreeMap::new(); + let frozen_regex = Regex::new(r"bank frozen: (\d*)").unwrap(); + let full_regex = Regex::new(r"slot (\d*) is full").unwrap(); + + let log_file = PathBuf::from(value_t_or_exit!(arg_matches, "log_path", String)); + let f = BufReader::new(File::open(log_file).unwrap()); + println!("Reading log file"); + for line in f.lines().map_while(Result::ok) { + let parse_results = { + if let Some(slot_string) = frozen_regex.captures_iter(&line).next() { + Some((slot_string, &mut frozen)) + } else { + full_regex + .captures_iter(&line) + .next() + .map(|slot_string| (slot_string, &mut full)) + } + }; + + if let Some((slot_string, map)) = parse_results { + let slot = slot_string + .get(1) + .expect("Only one match group") + .as_str() + .parse::() + .unwrap(); + if ancestors.contains(&slot) && !map.contains_key(&slot) { + map.insert(slot, line); + } + if slot == ending_slot && frozen.contains_key(&slot) && full.contains_key(&slot) + { + break; + } + } + } + + for ((slot1, frozen_log), (slot2, full_log)) in frozen.iter().zip(full.iter()) { + assert_eq!(slot1, slot2); + println!("Slot: {slot1}\n, full: {full_log}\n, frozen: {frozen_log}"); + } + } + ("print", Some(arg_matches)) => { + let starting_slot = value_t_or_exit!(arg_matches, "starting_slot", Slot); + let ending_slot = value_t!(arg_matches, "ending_slot", Slot).unwrap_or(Slot::MAX); + let num_slots = value_t!(arg_matches, "num_slots", Slot).ok(); + let allow_dead_slots = arg_matches.is_present("allow_dead_slots"); + let only_rooted = arg_matches.is_present("only_rooted"); + output_ledger( + crate::open_blockstore(&ledger_path, arg_matches, AccessType::Secondary), + starting_slot, + ending_slot, + allow_dead_slots, + OutputFormat::Display, + num_slots, + verbose_level, + only_rooted, + ); + } + ("print-file-metadata", Some(arg_matches)) => { + let blockstore = + crate::open_blockstore(&ledger_path, arg_matches, AccessType::Secondary); + let sst_file_name = arg_matches.value_of("file_name"); + if let Err(err) = print_blockstore_file_metadata(&blockstore, &sst_file_name) { + eprintln!("{err}"); + } + } + ("purge", Some(arg_matches)) => { + let start_slot = value_t_or_exit!(arg_matches, "start_slot", Slot); + let end_slot = value_t!(arg_matches, "end_slot", Slot).ok(); + let perform_compaction = arg_matches.is_present("enable_compaction"); + if arg_matches.is_present("no_compaction") { + warn!("--no-compaction is deprecated and is now the default behavior."); + } + let dead_slots_only = arg_matches.is_present("dead_slots_only"); + let batch_size = value_t_or_exit!(arg_matches, "batch_size", usize); + + let blockstore = crate::open_blockstore( + &ledger_path, + arg_matches, + AccessType::PrimaryForMaintenance, + ); + + let end_slot = match end_slot { + Some(end_slot) => end_slot, + None => match blockstore.slot_meta_iterator(start_slot) { + Ok(metas) => { + let slots: Vec<_> = metas.map(|(slot, _)| slot).collect(); + if slots.is_empty() { + eprintln!("Purge range is empty"); + std::process::exit(1); + } + *slots.last().unwrap() + } + Err(err) => { + eprintln!("Unable to read the Ledger: {err:?}"); + std::process::exit(1); + } + }, + }; + + if end_slot < start_slot { + eprintln!("end slot {end_slot} is less than start slot {start_slot}"); + std::process::exit(1); + } + info!( + "Purging data from slots {} to {} ({} slots) (do compaction: {}) \ + (dead slot only: {})", + start_slot, + end_slot, + end_slot - start_slot, + perform_compaction, + dead_slots_only, + ); + let purge_from_blockstore = |start_slot, end_slot| { + blockstore.purge_from_next_slots(start_slot, end_slot); + if perform_compaction { + blockstore.purge_and_compact_slots(start_slot, end_slot); + } else { + blockstore.purge_slots(start_slot, end_slot, PurgeType::Exact); + } + }; + if !dead_slots_only { + let slots_iter = &(start_slot..=end_slot).chunks(batch_size); + for slots in slots_iter { + let slots = slots.collect::>(); + assert!(!slots.is_empty()); + + let start_slot = *slots.first().unwrap(); + let end_slot = *slots.last().unwrap(); + info!( + "Purging chunked slots from {} to {} ({} slots)", + start_slot, + end_slot, + end_slot - start_slot + ); + purge_from_blockstore(start_slot, end_slot); + } + } else { + let dead_slots_iter = blockstore + .dead_slots_iterator(start_slot) + .unwrap() + .take_while(|s| *s <= end_slot); + for dead_slot in dead_slots_iter { + info!("Purging dead slot {}", dead_slot); + purge_from_blockstore(dead_slot, dead_slot); + } + } + } + ("remove-dead-slot", Some(arg_matches)) => { + let slots = values_t_or_exit!(arg_matches, "slots", Slot); + let blockstore = crate::open_blockstore(&ledger_path, arg_matches, AccessType::Primary); + for slot in slots { + match blockstore.remove_dead_slot(slot) { + Ok(_) => println!("Slot {slot} not longer marked dead"), + Err(err) => { + eprintln!("Failed to remove dead flag for slot {slot}, {err:?}") + } + } + } + } + ("repair-roots", Some(arg_matches)) => { + let blockstore = crate::open_blockstore(&ledger_path, arg_matches, AccessType::Primary); + + let start_root = + value_t!(arg_matches, "start_root", Slot).unwrap_or_else(|_| blockstore.max_root()); + let max_slots = value_t_or_exit!(arg_matches, "max_slots", u64); + let end_root = value_t!(arg_matches, "end_root", Slot) + .unwrap_or_else(|_| start_root.saturating_sub(max_slots)); + assert!(start_root > end_root); + let num_slots = start_root - end_root - 1; // Adjust by one since start_root need not be checked + if arg_matches.is_present("end_root") && num_slots > max_slots { + eprintln!( + "Requested range {num_slots} too large, max {max_slots}. Either adjust \ + `--until` value, or pass a larger `--repair-limit` to override the limit", + ); + std::process::exit(1); + } + + let num_repaired_roots = blockstore + .scan_and_fix_roots(Some(start_root), Some(end_root), &AtomicBool::new(false)) + .unwrap_or_else(|err| { + eprintln!("Unable to repair roots: {err}"); + std::process::exit(1); + }); + println!("Successfully repaired {num_repaired_roots} roots"); + } + ("set-dead-slot", Some(arg_matches)) => { + let slots = values_t_or_exit!(arg_matches, "slots", Slot); + let blockstore = crate::open_blockstore(&ledger_path, arg_matches, AccessType::Primary); + for slot in slots { + match blockstore.set_dead_slot(slot) { + Ok(_) => println!("Slot {slot} dead"), + Err(err) => eprintln!("Failed to set slot {slot} dead slot: {err:?}"), + } + } + } + ("shred-meta", Some(arg_matches)) => { + #[derive(Debug)] + #[allow(dead_code)] + struct ShredMeta<'a> { + slot: Slot, + full_slot: bool, + shred_index: usize, + data: bool, + code: bool, + last_in_slot: bool, + data_complete: bool, + shred: &'a Shred, + } + let starting_slot = value_t_or_exit!(arg_matches, "starting_slot", Slot); + let ending_slot = value_t!(arg_matches, "ending_slot", Slot).unwrap_or(Slot::MAX); + let ledger = crate::open_blockstore(&ledger_path, arg_matches, AccessType::Secondary); + for (slot, _meta) in ledger + .slot_meta_iterator(starting_slot) + .unwrap() + .take_while(|(slot, _)| *slot <= ending_slot) + { + let full_slot = ledger.is_full(slot); + if let Ok(shreds) = ledger.get_data_shreds_for_slot(slot, 0) { + for (shred_index, shred) in shreds.iter().enumerate() { + println!( + "{:#?}", + ShredMeta { + slot, + full_slot, + shred_index, + data: shred.is_data(), + code: shred.is_code(), + data_complete: shred.data_complete(), + last_in_slot: shred.last_in_slot(), + shred, + } + ); + } + } + } + } + ("slot", Some(arg_matches)) => { + let slots = values_t_or_exit!(arg_matches, "slots", Slot); + let allow_dead_slots = arg_matches.is_present("allow_dead_slots"); + let blockstore = + crate::open_blockstore(&ledger_path, arg_matches, AccessType::Secondary); + for slot in slots { + println!("Slot {slot}"); + if let Err(err) = output_slot( + &blockstore, + slot, + allow_dead_slots, + &OutputFormat::Display, + verbose_level, + &mut HashMap::new(), + ) { + eprintln!("{err}"); + } + } + } + _ => unreachable!(), + } +} + +#[cfg(test)] +pub mod tests { + use { + super::*, + solana_ledger::{blockstore::make_many_slot_entries, get_tmp_ledger_path_auto_delete}, + }; + + #[test] + fn test_latest_optimistic_ancestors() { + let ledger_path = get_tmp_ledger_path_auto_delete!(); + let blockstore = Blockstore::open(ledger_path.path()).unwrap(); + + // Insert 5 slots into blockstore + let start_slot = 0; + let num_slots = 5; + let entries_per_shred = 5; + let (shreds, _) = make_many_slot_entries(start_slot, num_slots, entries_per_shred); + blockstore.insert_shreds(shreds, None, false).unwrap(); + + // Mark even shreds as optimistically confirmed + (0..num_slots).step_by(2).for_each(|slot| { + blockstore + .insert_optimistic_slot(slot, &Hash::default(), UnixTimestamp::default()) + .unwrap(); + }); + + let exclude_vote_only_slots = false; + let optimistic_slots: Vec<_> = + get_latest_optimistic_slots(&blockstore, num_slots as usize, exclude_vote_only_slots) + .iter() + .map(|(slot, _, _)| *slot) + .collect(); + + // Should see all slots here since they're all chained, despite only evens getting marked + // get_latest_optimistic_slots() returns slots in descending order so use .rev() + let expected: Vec<_> = (start_slot..num_slots).rev().collect(); + assert_eq!(optimistic_slots, expected); + } +} diff --git a/ledger-tool/src/ledger_utils.rs b/ledger-tool/src/ledger_utils.rs index 6514312bc5d43d..e96034077f077d 100644 --- a/ledger-tool/src/ledger_utils.rs +++ b/ledger-tool/src/ledger_utils.rs @@ -137,14 +137,14 @@ pub fn load_and_process_ledger( } let account_paths = if let Some(account_paths) = arg_matches.value_of("account_paths") { - // If this blockstore access is Primary, no other process (solana-validator) can hold + // If this blockstore access is Primary, no other process (agave-validator) can hold // Primary access. So, allow a custom accounts path without worry of wiping the accounts - // of solana-validator. + // of agave-validator. if !blockstore.is_primary_access() { // Attempt to open the Blockstore in Primary access; if successful, no other process // was holding Primary so allow things to proceed with custom accounts path. Release - // the Primary access instead of holding it to give priority to solana-validator over - // solana-ledger-tool should solana-validator start before we've finished. + // the Primary access instead of holding it to give priority to agave-validator over + // agave-ledger-tool should agave-validator start before we've finished. info!( "Checking if another process currently holding Primary access to {:?}", blockstore.ledger_path() diff --git a/ledger/src/blockstore_db.rs b/ledger/src/blockstore_db.rs index 30cb4b2e9779a4..ab66a7dd9f08ba 100644 --- a/ledger/src/blockstore_db.rs +++ b/ledger/src/blockstore_db.rs @@ -407,8 +407,14 @@ impl Rocks { let secondary_path = path.join("solana-secondary"); info!( +<<<<<<< HEAD "Opening Rocks with secondary (read only) access at: {:?}", secondary_path +======= + "Opening Rocks with secondary (read only) access at: {secondary_path:?}. \ + This secondary access could temporarily degrade other accesses, such as \ + by agave-validator" +>>>>>>> e1e36d2fea ([anza migration] rename crates (#10)) ); info!("This secondary access could temporarily degrade other accesses, such as by solana-validator"); diff --git a/local-cluster/tests/local_cluster.rs b/local-cluster/tests/local_cluster.rs index fc08389947d581..c654efdd35de85 100644 --- a/local-cluster/tests/local_cluster.rs +++ b/local-cluster/tests/local_cluster.rs @@ -2315,13 +2315,13 @@ fn test_hard_fork_with_gap_in_roots() { ); // create hard-forked snapshot only for validator a, emulating the manual cluster restart - // procedure with `solana-ledger-tool create-snapshot` + // procedure with `agave-ledger-tool create-snapshot` let genesis_slot = 0; { let blockstore_a = Blockstore::open(&val_a_ledger_path).unwrap(); create_snapshot_to_hard_fork(&blockstore_a, hard_fork_slot, vec![hard_fork_slot]); - // Intentionally make solana-validator unbootable by replaying blocks from the genesis to + // Intentionally make agave-validator unbootable by replaying blocks from the genesis to // ensure the hard-forked snapshot is used always. Otherwise, we couldn't create a gap // in the ledger roots column family reliably. // There was a bug which caused the hard-forked snapshot at an unrooted slot to forget diff --git a/multinode-demo/bootstrap-validator.sh b/multinode-demo/bootstrap-validator.sh index f69c05d1ed3d7f..98d40e9adf3b19 100755 --- a/multinode-demo/bootstrap-validator.sh +++ b/multinode-demo/bootstrap-validator.sh @@ -14,9 +14,9 @@ if [[ "$SOLANA_GPU_MISSING" -eq 1 ]]; then fi if [[ -n $SOLANA_CUDA ]]; then - program=$solana_validator_cuda + program=$agave_validator_cuda else - program=$solana_validator + program=$agave_validator fi no_restart=0 diff --git a/multinode-demo/common.sh b/multinode-demo/common.sh index 9ae9331cb7a11d..1643208947b643 100644 --- a/multinode-demo/common.sh +++ b/multinode-demo/common.sh @@ -40,6 +40,8 @@ else if [[ -z $program ]]; then crate="cli" program="solana" + elif [[ $program == "validator" || $program == "ledger-tool" || $program == "watchtower" || $program == "install" ]]; then + program="agave-$program" else program="solana-$program" fi @@ -63,8 +65,8 @@ fi solana_bench_tps=$(solana_program bench-tps) solana_faucet=$(solana_program faucet) -solana_validator=$(solana_program validator) -solana_validator_cuda="$solana_validator --cuda" +agave_validator=$(solana_program validator) +agave_validator_cuda="$agave_validator --cuda" solana_genesis=$(solana_program genesis) solana_gossip=$(solana_program gossip) solana_keygen=$(solana_program keygen) diff --git a/multinode-demo/validator.sh b/multinode-demo/validator.sh index 9090055b908b10..a122b8523b5ea6 100755 --- a/multinode-demo/validator.sh +++ b/multinode-demo/validator.sh @@ -64,7 +64,7 @@ while [[ -n $1 ]]; do elif [[ $1 = --no-airdrop ]]; then airdrops_enabled=0 shift - # solana-validator options + # agave-validator options elif [[ $1 = --expected-genesis-hash ]]; then args+=("$1" "$2") shift 2 @@ -267,9 +267,9 @@ if [[ $maybeRequireTower = true ]]; then fi if [[ -n $SOLANA_CUDA ]]; then - program=$solana_validator_cuda + program=$agave_validator_cuda else - program=$solana_validator + program=$agave_validator fi set -e diff --git a/net/net.sh b/net/net.sh index 1106fe8e90a9bc..00261a135826d0 100755 --- a/net/net.sh +++ b/net/net.sh @@ -120,7 +120,7 @@ Operate a configured testnet sanity/start-specific options: -F - Discard validator nodes that didn't bootup successfully - -o noInstallCheck - Skip solana-install sanity + -o noInstallCheck - Skip agave-install sanity -o rejectExtraNodes - Require the exact number of nodes stop-specific options: @@ -136,7 +136,7 @@ Operate a configured testnet --netem-cmd - Optional command argument to netem. Default is "add". Use "cleanup" to remove rules. update-specific options: - --platform linux|osx|windows - Deploy the tarball using 'solana-install deploy ...' for the + --platform linux|osx|windows - Deploy the tarball using 'agave-install deploy ...' for the given platform (multiple platforms may be specified) (-t option must be supplied as well) @@ -511,11 +511,11 @@ deployUpdate() { declare bootstrapLeader=${validatorIpList[0]} for updatePlatform in $updatePlatforms; do - echo "--- Deploying solana-install update: $updatePlatform" + echo "--- Deploying agave-install update: $updatePlatform" ( set -x - scripts/solana-install-update-manifest-keypair.sh "$updatePlatform" + scripts/agave-install-update-manifest-keypair.sh "$updatePlatform" timeout 30s scp "${sshOptions[@]}" \ update_manifest_keypair.json "$bootstrapLeader:solana/update_manifest_keypair.json" diff --git a/net/remote/remote-deploy-update.sh b/net/remote/remote-deploy-update.sh index dd772927c0e119..3a71cf5725123e 100755 --- a/net/remote/remote-deploy-update.sh +++ b/net/remote/remote-deploy-update.sh @@ -35,6 +35,6 @@ loadConfigFile PATH="$HOME"/.cargo/bin:"$PATH" set -x -scripts/solana-install-deploy.sh \ +scripts/agave-install-deploy.sh \ --keypair config/faucet.json \ localhost "$releaseChannel" "$updatePlatform" diff --git a/net/remote/remote-node.sh b/net/remote/remote-node.sh index aeb920bd50bab0..b7d224088da9f9 100755 --- a/net/remote/remote-node.sh +++ b/net/remote/remote-node.sh @@ -121,7 +121,7 @@ cat >> ~/solana/on-reboot < system-stats.pid if ${GPU_CUDA_OK} && [[ -e /dev/nvidia0 ]]; then - echo Selecting solana-validator-cuda + echo Selecting agave-validator-cuda export SOLANA_CUDA=1 elif ${GPU_FAIL_IF_NONE} ; then echo "Expected GPU, found none!" @@ -257,13 +257,13 @@ EOF if [[ -n "$maybeWarpSlot" ]]; then # shellcheck disable=SC2086 # Do not want to quote $maybeWarSlot - solana-ledger-tool -l config/bootstrap-validator create-snapshot 0 config/bootstrap-validator $maybeWarpSlot + agave-ledger-tool -l config/bootstrap-validator create-snapshot 0 config/bootstrap-validator $maybeWarpSlot fi - solana-ledger-tool -l config/bootstrap-validator shred-version --max-genesis-archive-unpacked-size 1073741824 | tee config/shred-version + agave-ledger-tool -l config/bootstrap-validator shred-version --max-genesis-archive-unpacked-size 1073741824 | tee config/shred-version if [[ -n "$maybeWaitForSupermajority" ]]; then - bankHash=$(solana-ledger-tool -l config/bootstrap-validator bank-hash --halt-at-slot 0) + bankHash=$(agave-ledger-tool -l config/bootstrap-validator bank-hash --halt-at-slot 0) extraNodeArgs="$extraNodeArgs --expected-bank-hash $bankHash" echo "$bankHash" > config/bank-hash fi diff --git a/net/remote/remote-sanity.sh b/net/remote/remote-sanity.sh index 8c36e99ffdf936..91dae4b57336fa 100755 --- a/net/remote/remote-sanity.sh +++ b/net/remote/remote-sanity.sh @@ -65,7 +65,7 @@ local|tar|skip) export USE_INSTALL=1 solana_cli=solana solana_gossip=solana-gossip - solana_install=solana-install + solana_install=agave-install ;; *) echo "Unknown deployment method: $deployMethod" @@ -122,7 +122,7 @@ else fi if $installCheck && [[ -r update_manifest_keypair.json ]]; then - echo "--- $sanityTargetIp: solana-install test" + echo "--- $sanityTargetIp: agave-install test" ( set -x diff --git a/notifier/src/lib.rs b/notifier/src/lib.rs index a369225772492c..75406d2fbdae33 100644 --- a/notifier/src/lib.rs +++ b/notifier/src/lib.rs @@ -19,7 +19,7 @@ /// /// To receive a Twilio SMS notification on failure, having a Twilio account, /// and a sending number owned by that account, -/// define environment variable before running `solana-watchtower`: +/// define environment variable before running `agave-watchtower`: /// ```bash /// export TWILIO_CONFIG='ACCOUNT=,TOKEN=,TO=,FROM=' /// ``` @@ -208,7 +208,7 @@ impl Notifier { NotificationType::Resolve { ref incident } => incident.clone().to_string(), }; - let data = json!({"payload":{"summary":msg,"source":"solana-watchtower","severity":"critical"},"routing_key":routing_key,"event_action":event_action,"dedup_key":dedup_key}); + let data = json!({"payload":{"summary":msg,"source":"agave-watchtower","severity":"critical"},"routing_key":routing_key,"event_action":event_action,"dedup_key":dedup_key}); let url = "https://events.pagerduty.com/v2/enqueue"; if let Err(err) = self.client.post(url).json(&data).send() { diff --git a/programs/sbf/Cargo.lock b/programs/sbf/Cargo.lock index db7494244b294a..69ab7531c5b373 100644 --- a/programs/sbf/Cargo.lock +++ b/programs/sbf/Cargo.lock @@ -63,6 +63,79 @@ dependencies = [ "zeroize", ] +[[package]] +name = "agave-geyser-plugin-interface" +version = "1.18.0" +dependencies = [ + "log", + "solana-sdk", + "solana-transaction-status", + "thiserror", +] + +[[package]] +name = "agave-validator" +version = "1.18.0" +dependencies = [ + "agave-geyser-plugin-interface", + "chrono", + "clap 2.33.3", + "console", + "core_affinity", + "crossbeam-channel", + "fd-lock", + "indicatif", + "itertools", + "jsonrpc-core", + "jsonrpc-core-client", + "jsonrpc-derive", + "jsonrpc-ipc-server", + "jsonrpc-server-utils", + "lazy_static", + "libc", + "libloading", + "log", + "num_cpus", + "rand 0.8.5", + "rayon", + "serde", + "serde_json", + "serde_yaml", + "signal-hook", + "solana-accounts-db", + "solana-clap-utils", + "solana-cli-config", + "solana-core", + "solana-download-utils", + "solana-entry", + "solana-faucet", + "solana-genesis-utils", + "solana-geyser-plugin-manager", + "solana-gossip", + "solana-ledger", + "solana-logger", + "solana-metrics", + "solana-net-utils", + "solana-perf", + "solana-poh", + "solana-rpc", + "solana-rpc-client", + "solana-rpc-client-api", + "solana-runtime", + "solana-sdk", + "solana-send-transaction-service", + "solana-storage-bigtable", + "solana-streamer", + "solana-svm", + "solana-test-validator", + "solana-tpu-client", + "solana-version", + "solana-vote-program", + "symlink", + "thiserror", + "tikv-jemallocator", +] + [[package]] name = "ahash" version = "0.7.6" @@ -4970,6 +5043,7 @@ dependencies = [ ] [[package]] +<<<<<<< HEAD name = "solana-geyser-plugin-interface" version = "1.17.23" dependencies = [ @@ -4980,9 +5054,12 @@ dependencies = [ ] [[package]] +======= +>>>>>>> e1e36d2fea ([anza migration] rename crates (#10)) name = "solana-geyser-plugin-manager" version = "1.17.23" dependencies = [ + "agave-geyser-plugin-interface", "bs58", "crossbeam-channel", "json5", @@ -4993,7 +5070,6 @@ dependencies = [ "serde_json", "solana-accounts-db", "solana-entry", - "solana-geyser-plugin-interface", "solana-ledger", "solana-measure", "solana-metrics", @@ -5969,11 +6045,11 @@ dependencies = [ name = "solana-sbf-rust-simulation" version = "1.17.23" dependencies = [ + "agave-validator", "solana-logger", "solana-program", "solana-program-test", "solana-sdk", - "solana-validator", ] [[package]] @@ -6336,6 +6412,7 @@ dependencies = [ ] [[package]] +<<<<<<< HEAD name = "solana-validator" version = "1.17.23" dependencies = [ @@ -6395,6 +6472,28 @@ dependencies = [ "symlink", "thiserror", "tikv-jemallocator", +======= +name = "solana-unified-scheduler-logic" +version = "1.18.0" +dependencies = [ + "solana-sdk", +] + +[[package]] +name = "solana-unified-scheduler-pool" +version = "1.18.0" +dependencies = [ + "assert_matches", + "crossbeam-channel", + "derivative", + "log", + "solana-ledger", + "solana-program-runtime", + "solana-runtime", + "solana-sdk", + "solana-unified-scheduler-logic", + "solana-vote", +>>>>>>> e1e36d2fea ([anza migration] rename crates (#10)) ] [[package]] diff --git a/programs/sbf/Cargo.toml b/programs/sbf/Cargo.toml index 0dd476feee125b..8c88aff6fd2f5a 100644 --- a/programs/sbf/Cargo.toml +++ b/programs/sbf/Cargo.toml @@ -25,6 +25,32 @@ rand = "0.8" rustversion = "1.0.14" serde = "1.0.112" serde_json = "1.0.56" +<<<<<<< HEAD +======= +solana-account-decoder = { path = "../../account-decoder", version = "=1.18.0" } +solana-accounts-db = { path = "../../accounts-db", version = "=1.18.0" } +solana-bpf-loader-program = { path = "../bpf_loader", version = "=1.18.0" } +solana-cli-output = { path = "../../cli-output", version = "=1.18.0" } +solana-ledger = { path = "../../ledger", version = "=1.18.0" } +solana-logger = { path = "../../logger", version = "=1.18.0" } +solana-measure = { path = "../../measure", version = "=1.18.0" } +solana-program = { path = "../../sdk/program", version = "=1.18.0" } +solana-program-runtime = { path = "../../program-runtime", version = "=1.18.0" } +solana-program-test = { path = "../../program-test", version = "=1.18.0" } +solana-runtime = { path = "../../runtime", version = "=1.18.0" } +solana-sbf-rust-128bit-dep = { path = "rust/128bit_dep", version = "=1.18.0" } +solana-sbf-rust-invoke = { path = "rust/invoke", version = "=1.18.0" } +solana-sbf-rust-invoked = { path = "rust/invoked", version = "=1.18.0", default-features = false } +solana-sbf-rust-many-args-dep = { path = "rust/many_args_dep", version = "=1.18.0" } +solana-sbf-rust-mem = { path = "rust/mem", version = "=1.18.0" } +solana-sbf-rust-param-passing-dep = { path = "rust/param_passing_dep", version = "=1.18.0" } +solana-sbf-rust-realloc = { path = "rust/realloc", version = "=1.18.0", default-features = false } +solana-sbf-rust-realloc-invoke = { path = "rust/realloc_invoke", version = "=1.18.0" } +solana-sdk = { path = "../../sdk", version = "=1.18.0" } +solana-transaction-status = { path = "../../transaction-status", version = "=1.18.0" } +agave-validator = { path = "../../validator", version = "=1.18.0" } +solana-zk-token-sdk = { path = "../../zk-token-sdk", version = "=1.18.0" } +>>>>>>> e1e36d2fea ([anza migration] rename crates (#10)) solana_rbpf = "=0.8.0" solana-account-decoder = { path = "../../account-decoder", version = "=1.17.23" } solana-accounts-db = { path = "../../accounts-db", version = "=1.17.23" } diff --git a/programs/sbf/rust/simulation/Cargo.toml b/programs/sbf/rust/simulation/Cargo.toml index 7091ef9d5ade0c..e9728e5916b801 100644 --- a/programs/sbf/rust/simulation/Cargo.toml +++ b/programs/sbf/rust/simulation/Cargo.toml @@ -16,10 +16,10 @@ test-bpf = [] solana-program = { workspace = true } [dev-dependencies] +agave-validator = { workspace = true } solana-logger = { workspace = true } solana-program-test = { workspace = true } solana-sdk = { workspace = true } -solana-validator = { workspace = true } [lib] crate-type = ["cdylib", "lib"] diff --git a/programs/sbf/rust/simulation/tests/validator.rs b/programs/sbf/rust/simulation/tests/validator.rs index 3044ad9a642629..17de51e665e3ec 100644 --- a/programs/sbf/rust/simulation/tests/validator.rs +++ b/programs/sbf/rust/simulation/tests/validator.rs @@ -1,13 +1,13 @@ #![cfg(feature = "test-bpf")] use { + agave_validator::test_validator::*, solana_program::{ instruction::{AccountMeta, Instruction}, pubkey::Pubkey, sysvar, }, solana_sdk::{signature::Signer, transaction::Transaction}, - solana_validator::test_validator::*, }; #[test] diff --git a/pubsub-client/src/nonblocking/pubsub_client.rs b/pubsub-client/src/nonblocking/pubsub_client.rs index fe0540ebed4227..c14b6ee1b08781 100644 --- a/pubsub-client/src/nonblocking/pubsub_client.rs +++ b/pubsub-client/src/nonblocking/pubsub_client.rs @@ -33,7 +33,7 @@ //! By default the [`block_subscribe`] and [`vote_subscribe`] events are //! disabled on RPC nodes. They can be enabled by passing //! `--rpc-pubsub-enable-block-subscription` and -//! `--rpc-pubsub-enable-vote-subscription` to `solana-validator`. When these +//! `--rpc-pubsub-enable-vote-subscription` to `agave-validator`. When these //! methods are disabled, the RPC server will return a "Method not found" error //! message. //! @@ -381,7 +381,7 @@ impl PubsubClient { /// Receives messages of type [`RpcBlockUpdate`] when a block is confirmed or finalized. /// /// This method is disabled by default. It can be enabled by passing - /// `--rpc-pubsub-enable-block-subscription` to `solana-validator`. + /// `--rpc-pubsub-enable-block-subscription` to `agave-validator`. /// /// # RPC Reference /// @@ -452,7 +452,7 @@ impl PubsubClient { /// votes are observed prior to confirmation and may never be confirmed. /// /// This method is disabled by default. It can be enabled by passing - /// `--rpc-pubsub-enable-vote-subscription` to `solana-validator`. + /// `--rpc-pubsub-enable-vote-subscription` to `agave-validator`. /// /// # RPC Reference /// diff --git a/pubsub-client/src/pubsub_client.rs b/pubsub-client/src/pubsub_client.rs index 612df285d8e5e3..49139983521627 100644 --- a/pubsub-client/src/pubsub_client.rs +++ b/pubsub-client/src/pubsub_client.rs @@ -32,7 +32,7 @@ //! By default the [`block_subscribe`] and [`vote_subscribe`] events are //! disabled on RPC nodes. They can be enabled by passing //! `--rpc-pubsub-enable-block-subscription` and -//! `--rpc-pubsub-enable-vote-subscription` to `solana-validator`. When these +//! `--rpc-pubsub-enable-vote-subscription` to `agave-validator`. When these //! methods are disabled, the RPC server will return a "Method not found" error //! message. //! @@ -416,7 +416,7 @@ impl PubsubClient { /// Receives messages of type [`RpcBlockUpdate`] when a block is confirmed or finalized. /// /// This method is disabled by default. It can be enabled by passing - /// `--rpc-pubsub-enable-block-subscription` to `solana-validator`. + /// `--rpc-pubsub-enable-block-subscription` to `agave-validator`. /// /// # RPC Reference /// @@ -578,7 +578,7 @@ impl PubsubClient { /// votes are observed prior to confirmation and may never be confirmed. /// /// This method is disabled by default. It can be enabled by passing - /// `--rpc-pubsub-enable-vote-subscription` to `solana-validator`. + /// `--rpc-pubsub-enable-vote-subscription` to `agave-validator`. /// /// # RPC Reference /// diff --git a/rbpf-cli/src/main.rs b/rbpf-cli/src/main.rs index e7db982026f82a..9e243f0836aa0f 100644 --- a/rbpf-cli/src/main.rs +++ b/rbpf-cli/src/main.rs @@ -1,6 +1,6 @@ fn main() { println!( - r##"rbpf-cli is replaced by solana-ledger-tool program run subcommand. -Please, use 'solana-ledger-tool program run --help' for more information."## + r##"rbpf-cli is replaced by agave-ledger-tool program run subcommand. +Please, use 'agave-ledger-tool program run --help' for more information."## ); } diff --git a/rpc/src/rpc.rs b/rpc/src/rpc.rs index d7d0d8b6cc172d..a10f3cd14a7e1d 100644 --- a/rpc/src/rpc.rs +++ b/rpc/src/rpc.rs @@ -2550,7 +2550,7 @@ pub mod rpc_minimal { #[rpc(meta, name = "getVersion")] fn get_version(&self, meta: Self::Metadata) -> Result; - // TODO: Refactor `solana-validator wait-for-restart-window` to not require this method, so + // TODO: Refactor `agave-validator wait-for-restart-window` to not require this method, so // it can be removed from rpc_minimal #[rpc(meta, name = "getVoteAccounts")] fn get_vote_accounts( @@ -2559,7 +2559,7 @@ pub mod rpc_minimal { config: Option, ) -> Result; - // TODO: Refactor `solana-validator wait-for-restart-window` to not require this method, so + // TODO: Refactor `agave-validator wait-for-restart-window` to not require this method, so // it can be removed from rpc_minimal #[rpc(meta, name = "getLeaderSchedule")] fn get_leader_schedule( @@ -2685,7 +2685,7 @@ pub mod rpc_minimal { }) } - // TODO: Refactor `solana-validator wait-for-restart-window` to not require this method, so + // TODO: Refactor `agave-validator wait-for-restart-window` to not require this method, so // it can be removed from rpc_minimal fn get_vote_accounts( &self, @@ -2696,7 +2696,7 @@ pub mod rpc_minimal { meta.get_vote_accounts(config) } - // TODO: Refactor `solana-validator wait-for-restart-window` to not require this method, so + // TODO: Refactor `agave-validator wait-for-restart-window` to not require this method, so // it can be removed from rpc_minimal fn get_leader_schedule( &self, diff --git a/scripts/solana-install-deploy.sh b/scripts/agave-install-deploy.sh similarity index 90% rename from scripts/solana-install-deploy.sh rename to scripts/agave-install-deploy.sh index ea77ca34bc9ea3..a8f8eeb65b3857 100755 --- a/scripts/solana-install-deploy.sh +++ b/scripts/agave-install-deploy.sh @@ -26,7 +26,7 @@ if [[ -z $URL || -z $TAG ]]; then fi if [[ ! -f update_manifest_keypair.json ]]; then - "$SOLANA_ROOT"/scripts/solana-install-update-manifest-keypair.sh "$OS" + "$SOLANA_ROOT"/scripts/agave-install-update-manifest-keypair.sh "$OS" fi case "$OS" in @@ -76,4 +76,4 @@ if [[ $balance = "0 lamports" ]]; then fi # shellcheck disable=SC2086 # Don't want to double quote $maybeKeypair -solana-install deploy $maybeKeypair --url "$URL" "$DOWNLOAD_URL" update_manifest_keypair.json +agave-install deploy $maybeKeypair --url "$URL" "$DOWNLOAD_URL" update_manifest_keypair.json diff --git a/scripts/cargo-install-all.sh b/scripts/cargo-install-all.sh index 549aa15550b0eb..029b1fbf27943d 100755 --- a/scripts/cargo-install-all.sh +++ b/scripts/cargo-install-all.sh @@ -91,8 +91,8 @@ if [[ $CI_OS_NAME = windows ]]; then cargo-test-bpf cargo-test-sbf solana - solana-install - solana-install-init + agave-install + agave-install-init solana-keygen solana-stake-accounts solana-test-validator @@ -106,12 +106,12 @@ else solana-bench-tps solana-faucet solana-gossip - solana-install + agave-install solana-keygen - solana-ledger-tool + agave-ledger-tool solana-log-analyzer solana-net-shaper - solana-validator + agave-validator rbpf-cli ) @@ -123,11 +123,11 @@ else cargo-test-bpf cargo-test-sbf solana-dos - solana-install-init + agave-install-init solana-stake-accounts solana-test-validator solana-tokens - solana-watchtower + agave-watchtower ) fi diff --git a/scripts/check-dev-context-only-utils.sh b/scripts/check-dev-context-only-utils.sh index debb323db113c4..de6d7475c5d10d 100755 --- a/scripts/check-dev-context-only-utils.sh +++ b/scripts/check-dev-context-only-utils.sh @@ -29,6 +29,12 @@ source ci/rust-version.sh nightly # reason to bend dev-context-only-utils's original intention and that listed # package isn't part of released binaries. declare tainted_packages=( +<<<<<<< HEAD +======= + solana-accounts-bench + solana-banking-bench + agave-ledger-tool +>>>>>>> e1e36d2fea ([anza migration] rename crates (#10)) ) # convert to comma separeted (ref: https://stackoverflow.com/a/53839433) diff --git a/scripts/run.sh b/scripts/run.sh index 699bfce3e253e3..2d8e1ec88ac450 100755 --- a/scripts/run.sh +++ b/scripts/run.sh @@ -23,9 +23,11 @@ fi PATH=$PWD/target/$profile:$PATH ok=true -for program in solana-{faucet,genesis,keygen,validator}; do +for program in solana-{faucet,genesis,keygen}; do $program -V || ok=false done +agave-validator -V || ok=false + $ok || { echo echo "Unable to locate required programs. Try building them first with:" @@ -115,7 +117,7 @@ args=( --no-os-network-limits-test ) # shellcheck disable=SC2086 -solana-validator "${args[@]}" $SOLANA_RUN_SH_VALIDATOR_ARGS & +agave-validator "${args[@]}" $SOLANA_RUN_SH_VALIDATOR_ARGS & validator=$! wait "$validator" diff --git a/system-test/abi-testcases/mixed-validator-test.sh b/system-test/abi-testcases/mixed-validator-test.sh index 8ab673b26a3d21..c0400560dc519e 100755 --- a/system-test/abi-testcases/mixed-validator-test.sh +++ b/system-test/abi-testcases/mixed-validator-test.sh @@ -30,14 +30,14 @@ solanaInstallGlobalOpts=( bootstrapInstall() { declare v=$1 if [[ ! -h $solanaInstallDataDir/active_release ]]; then - sh "$SOLANA_ROOT"/install/solana-install-init.sh "$v" "${solanaInstallGlobalOpts[@]}" + sh "$SOLANA_ROOT"/install/agave-install-init.sh "$v" "${solanaInstallGlobalOpts[@]}" fi export PATH="$solanaInstallDataDir/active_release/bin/:$PATH" } bootstrapInstall "$baselineVersion" for v in "${otherVersions[@]}"; do - solana-install-init "${solanaInstallGlobalOpts[@]}" "$v" + agave-install-init "${solanaInstallGlobalOpts[@]}" "$v" solana -V done @@ -113,7 +113,7 @@ for v in "${otherVersions[@]}"; do ( set -x tmux new-window -t abi -n "$v" " \ - $SOLANA_BIN/solana-validator \ + $SOLANA_BIN/agave-validator \ --ledger $ledger \ --no-snapshot-fetch \ --entrypoint 127.0.0.1:8001 \ diff --git a/system-test/stability-testcases/gossip-dos-test.sh b/system-test/stability-testcases/gossip-dos-test.sh index f8afade75dc847..68c3c540d5948c 100755 --- a/system-test/stability-testcases/gossip-dos-test.sh +++ b/system-test/stability-testcases/gossip-dos-test.sh @@ -19,14 +19,14 @@ solanaInstallGlobalOpts=( bootstrapInstall() { declare v=$1 if [[ ! -h $solanaInstallDataDir/active_release ]]; then - sh "$SOLANA_ROOT"/install/solana-install-init.sh "$v" "${solanaInstallGlobalOpts[@]}" + sh "$SOLANA_ROOT"/install/agave-install-init.sh "$v" "${solanaInstallGlobalOpts[@]}" fi export PATH="$solanaInstallDataDir/active_release/bin/:$PATH" } bootstrapInstall "edge" -solana-install-init --version -solana-install-init edge +agave-install-init --version +agave-install-init edge solana-gossip --version solana-dos --version diff --git a/validator/Cargo.toml b/validator/Cargo.toml index 845bdda7eeab6b..7882762c6a0721 100644 --- a/validator/Cargo.toml +++ b/validator/Cargo.toml @@ -1,8 +1,8 @@ [package] -name = "solana-validator" +name = "agave-validator" description = "Blockchain, Rebuilt for Scale" -documentation = "https://docs.rs/solana-validator" -default-run = "solana-validator" +documentation = "https://docs.rs/agave-validator" +default-run = "agave-validator" version = { workspace = true } authors = { workspace = true } repository = { workspace = true } @@ -11,6 +11,7 @@ license = { workspace = true } edition = { workspace = true } [dependencies] +agave-geyser-plugin-interface = { workspace = true } chrono = { workspace = true, features = ["default", "serde"] } clap = { workspace = true } console = { workspace = true } @@ -41,7 +42,6 @@ solana-download-utils = { workspace = true } solana-entry = { workspace = true } solana-faucet = { workspace = true } solana-genesis-utils = { workspace = true } -solana-geyser-plugin-interface = { workspace = true } solana-geyser-plugin-manager = { workspace = true } solana-gossip = { workspace = true } solana-ledger = { workspace = true } diff --git a/validator/src/bin/solana-test-validator.rs b/validator/src/bin/solana-test-validator.rs index aee5fc039df410..139ad6804f0bc0 100644 --- a/validator/src/bin/solana-test-validator.rs +++ b/validator/src/bin/solana-test-validator.rs @@ -1,4 +1,8 @@ use { + agave_validator::{ + admin_rpc_service, cli, dashboard::Dashboard, ledger_lockfile, lock_ledger, + println_name_value, redirect_stderr_to_file, + }, clap::{crate_name, value_t, value_t_or_exit, values_t_or_exit}, crossbeam_channel::unbounded, itertools::Itertools, @@ -28,10 +32,6 @@ use { }, solana_streamer::socket::SocketAddrSpace, solana_test_validator::*, - solana_validator::{ - admin_rpc_service, cli, dashboard::Dashboard, ledger_lockfile, lock_ledger, - println_name_value, redirect_stderr_to_file, - }, std::{ collections::HashSet, fs, io, diff --git a/validator/src/bootstrap.rs b/validator/src/bootstrap.rs index 88a45fdad50635..0fe1ae7e6d5eda 100644 --- a/validator/src/bootstrap.rs +++ b/validator/src/bootstrap.rs @@ -444,7 +444,7 @@ pub fn attempt_download_genesis_and_snapshot( ) .unwrap_or_else(|err| { // Consider failures here to be more likely due to user error (eg, - // incorrect `solana-validator` command-line arguments) rather than the + // incorrect `agave-validator` command-line arguments) rather than the // RPC node failing. // // Power users can always use the `--no-check-vote-account` option to diff --git a/validator/src/main.rs b/validator/src/main.rs index f5b0ce1a0609e7..680397a9d3c73c 100644 --- a/validator/src/main.rs +++ b/validator/src/main.rs @@ -2,6 +2,15 @@ #[cfg(not(target_env = "msvc"))] use jemallocator::Jemalloc; use { + agave_validator::{ + admin_rpc_service, + admin_rpc_service::{load_staked_nodes_overrides, StakedNodesOverrides}, + bootstrap, + cli::{app, warn_for_deprecated_arguments, DefaultArgs}, + dashboard::Dashboard, + ledger_lockfile, lock_ledger, new_spinner_progress_bar, println_name_value, + redirect_stderr_to_file, + }, clap::{crate_name, value_t, value_t_or_exit, values_t, values_t_or_exit, ArgMatches}, console::style, crossbeam_channel::unbounded, @@ -65,15 +74,6 @@ use { solana_send_transaction_service::send_transaction_service, solana_streamer::socket::SocketAddrSpace, solana_tpu_client::tpu_client::DEFAULT_TPU_ENABLE_UDP, - solana_validator::{ - admin_rpc_service, - admin_rpc_service::{load_staked_nodes_overrides, StakedNodesOverrides}, - bootstrap, - cli::{app, warn_for_deprecated_arguments, DefaultArgs}, - dashboard::Dashboard, - ledger_lockfile, lock_ledger, new_spinner_progress_bar, println_name_value, - redirect_stderr_to_file, - }, std::{ collections::{HashSet, VecDeque}, env, @@ -899,7 +899,7 @@ pub fn main() { let logfile = matches .value_of("logfile") .map(|s| s.into()) - .unwrap_or_else(|| format!("solana-validator-{}.log", identity_keypair.pubkey())); + .unwrap_or_else(|| format!("agave-validator-{}.log", identity_keypair.pubkey())); if logfile == "-" { None diff --git a/watchtower/Cargo.toml b/watchtower/Cargo.toml index d8bad3cf4d18f0..4088ee7d9b51ab 100644 --- a/watchtower/Cargo.toml +++ b/watchtower/Cargo.toml @@ -1,7 +1,7 @@ [package] -name = "solana-watchtower" +name = "agave-watchtower" description = "Blockchain, Rebuilt for Scale" -documentation = "https://docs.rs/solana-watchtower" +documentation = "https://docs.rs/agave-watchtower" version = { workspace = true } authors = { workspace = true } repository = { workspace = true } diff --git a/watchtower/README.md b/watchtower/README.md index 33bad3e458c449..5c548d405a248c 100644 --- a/watchtower/README.md +++ b/watchtower/README.md @@ -1,4 +1,4 @@ -The `solana-watchtower` program is used to monitor the health of a cluster. It +The `agave-watchtower` program is used to monitor the health of a cluster. It periodically polls the cluster over an RPC API to confirm that the transaction count is advancing, new blockhashes are available, and no validators are delinquent. Results are reported as InfluxDB metrics, with an optional push diff --git a/watchtower/src/main.rs b/watchtower/src/main.rs index f42acdaadaabc6..341b7903c0a33e 100644 --- a/watchtower/src/main.rs +++ b/watchtower/src/main.rs @@ -47,7 +47,7 @@ fn get_config() -> Config { .version(solana_version::version!()) .after_help("ADDITIONAL HELP: To receive a Slack, Discord, PagerDuty and/or Telegram notification on sanity failure, - define environment variables before running `solana-watchtower`: + define environment variables before running `agave-watchtower`: export SLACK_WEBHOOK=... export DISCORD_WEBHOOK=... @@ -63,7 +63,7 @@ fn get_config() -> Config { To receive a Twilio SMS notification on failure, having a Twilio account, and a sending number owned by that account, - define environment variable before running `solana-watchtower`: + define environment variable before running `agave-watchtower`: export TWILIO_CONFIG='ACCOUNT=,TOKEN=,TO=,FROM='") .arg({ @@ -166,7 +166,7 @@ fn get_config() -> Config { .value_name("SUFFIX") .takes_value(true) .default_value("") - .help("Add this string into all notification messages after \"solana-watchtower\"") + .help("Add this string into all notification messages after \"agave-watchtower\"") ) .get_matches(); @@ -381,7 +381,7 @@ fn main() -> Result<(), Box> { if let Some((failure_test_name, failure_error_message)) = &failure { let notification_msg = format!( - "solana-watchtower{}: Error: {}: {}", + "agave-watchtower{}: Error: {}: {}", config.name_suffix, failure_test_name, failure_error_message ); num_consecutive_failures += 1; @@ -415,7 +415,7 @@ fn main() -> Result<(), Box> { ); info!("{}", all_clear_msg); notifier.send( - &format!("solana-watchtower{}: {}", config.name_suffix, all_clear_msg), + &format!("agave-watchtower{}: {}", config.name_suffix, all_clear_msg), &NotificationType::Resolve { incident }, ); }