From f3f60ca370343a213f5a1c6f436bf5fb3d95468f Mon Sep 17 00:00:00 2001 From: Conor Schaefer Date: Mon, 18 Sep 2023 12:07:20 -0700 Subject: [PATCH] feat(pd): migrate tendermint -> cometbft We're targeting cometbft v0.34.27, which is essentially the same code as the Tendermint v0.34.x series we've been tracking. Updates have been made throughout: * pd var names * deployment files * documentation There are still a ton of "tendermint" references in the repo, such as `tendermint-rs`, but that's fine. --- .github/workflows/smoke.yml | 22 +++----------- crates/bin/pcli/tests/network_integration.rs | 2 +- crates/bin/pd/src/main.rs | 26 ++++++++-------- crates/bin/pd/src/testnet/config.rs | 32 ++++++++++---------- deployments/compose/docker-compose.yml | 8 ++--- deployments/scripts/smoke-test.sh | 14 ++++++--- deployments/systemd/cometbft.service | 11 +++++++ deployments/systemd/tendermint.service | 11 ------- docs/guide/src/pd/build.md | 24 ++++++--------- 9 files changed, 70 insertions(+), 80 deletions(-) create mode 100644 deployments/systemd/cometbft.service delete mode 100644 deployments/systemd/tendermint.service diff --git a/.github/workflows/smoke.yml b/.github/workflows/smoke.yml index 650e74975e..4c8f3957b2 100644 --- a/.github/workflows/smoke.yml +++ b/.github/workflows/smoke.yml @@ -23,28 +23,16 @@ jobs: - name: Load rust cache uses: astriaorg/buildjet-rust-cache@v2.5.1 - - name: Install tendermint binary + - name: Install cometbft binary run: | - curl -L -O "https://github.com/tendermint/tendermint/releases/download/v0.34.24/tendermint_0.34.24_linux_amd64.tar.gz" - tar xzf tendermint_0.34.24_linux_amd64.tar.gz tendermint + curl -L -O "https://github.com/cometbft/cometbft/releases/download/v0.34.27/cometbft_0.34.27_linux_amd64.tar.gz" + tar -xzf "cometbft_0.34.27_linux_amd64.tar.gz" cometbft mkdir -p $HOME/bin - cp tendermint $HOME/bin + cp cometbft $HOME/bin echo $PATH export PATH=$HOME/bin:$PATH - which tendermint + which cometbft - # The point of these was to do compilation upfront, doesn't seem to be effective - #- name: Build `pd` - # uses: actions-rs/cargo@v1 - # with: - # command: build - # args: --release --package pd - #- name: Build `pcli` tests - # uses: actions-rs/cargo@v1 - # with: - # command: test - # args: --release --features sct-divergence-check --package pcli --no-run - - name: Run the smoke test suite run: | export PATH=$HOME/bin:$PATH diff --git a/crates/bin/pcli/tests/network_integration.rs b/crates/bin/pcli/tests/network_integration.rs index d058e4b3af..296902b875 100644 --- a/crates/bin/pcli/tests/network_integration.rs +++ b/crates/bin/pcli/tests/network_integration.rs @@ -940,7 +940,7 @@ fn mismatched_consensus_key_update_fails() { ".penumbra", "testnet_data", "node0", - "tendermint", + "cometbft", "config", "priv_validator_key.json", ] diff --git a/crates/bin/pd/src/main.rs b/crates/bin/pd/src/main.rs index 07aed01ff0..99c85d8949 100644 --- a/crates/bin/pd/src/main.rs +++ b/crates/bin/pd/src/main.rs @@ -100,21 +100,23 @@ enum RootCommand { display_order = 300 )] metrics_bind: SocketAddr, - /// The JSON-RPC address of the Tendermint node driving this `pd` + /// The JSON-RPC address of the CometBFT node driving this `pd` /// instance. /// - /// This is used to proxy requests from the gRPC server to Tendermint, + /// This is used to proxy requests from the gRPC server to CometBFT, /// so clients only need to connect to one endpoint and don't need to - /// worry about the peculiarities of Tendermint's JSON-RPC encoding + /// worry about the peculiarities of CometBFT's JSON-RPC encoding /// format. #[clap( short, long, - env = "PENUMBRA_PD_TM_PROXY_URL", + env = "PENUMBRA_PD_COMETBFT_PROXY_URL", default_value = "http://127.0.0.1:26657", - display_order = 401 + display_order = 401, + // Support old arg name for a while, as we migrate Tendermint -> CometBFT. + alias = "tendermint-addr", )] - tendermint_addr: Url, + cometbft_addr: Url, }, /// Generate, join, or reset a testnet. Testnet { @@ -263,22 +265,22 @@ async fn main() -> anyhow::Result<()> { grpc_bind, grpc_auto_https, metrics_bind, - tendermint_addr, + cometbft_addr, } => { tracing::info!( ?abci_bind, ?grpc_bind, ?grpc_auto_https, ?metrics_bind, - %tendermint_addr, + %cometbft_addr, "starting pd" ); // Ensure we have all necessary parts in the URL - if !url_has_necessary_parts(&tendermint_addr) { + if !url_has_necessary_parts(&cometbft_addr) { anyhow::bail!( - "Failed to parse '--tendermint-addr' as URL: {}", - tendermint_addr + "Failed to parse '--cometbft-addr' as URL: {}", + cometbft_addr ) } @@ -314,7 +316,7 @@ async fn main() -> anyhow::Result<()> { async move { pd::Mempool::new(storage.clone(), queue).await?.run().await } })); let info = pd::Info::new(storage.clone()); - let tm_proxy = TendermintProxy::new(tendermint_addr); + let tm_proxy = TendermintProxy::new(cometbft_addr); let snapshot = pd::Snapshot {}; let abci_server = tokio::task::Builder::new() diff --git a/crates/bin/pd/src/testnet/config.rs b/crates/bin/pd/src/testnet/config.rs index d1f1ee363d..03705b4af4 100644 --- a/crates/bin/pd/src/testnet/config.rs +++ b/crates/bin/pd/src/testnet/config.rs @@ -75,24 +75,24 @@ impl TestnetTendermintConfig { ) -> anyhow::Result<()> { // We'll also create the pd state directory here, since it's convenient. let pd_dir = node_dir.clone().join("pd"); - let tm_data_dir = node_dir.clone().join("tendermint").join("data"); - let tm_config_dir = node_dir.clone().join("tendermint").join("config"); + let cb_data_dir = node_dir.clone().join("cometbft").join("data"); + let cb_config_dir = node_dir.clone().join("cometbft").join("config"); tracing::info!(config_dir = %node_dir.display(), "Writing validator configs to"); fs::create_dir_all(pd_dir)?; - fs::create_dir_all(&tm_data_dir)?; - fs::create_dir_all(&tm_config_dir)?; + fs::create_dir_all(&cb_data_dir)?; + fs::create_dir_all(&cb_config_dir)?; - let genesis_file_path = tm_config_dir.clone().join("genesis.json"); + let genesis_file_path = cb_config_dir.clone().join("genesis.json"); tracing::debug!(genesis_file_path = %genesis_file_path.display(), "writing genesis"); let mut genesis_file = File::create(genesis_file_path)?; genesis_file.write_all(serde_json::to_string_pretty(&genesis)?.as_bytes())?; - let tm_config_filepath = tm_config_dir.clone().join("config.toml"); - tracing::debug!(tendermint_config = %tm_config_filepath.display(), "writing tendermint config.toml"); - let mut tm_config_file = File::create(tm_config_filepath)?; - tm_config_file.write_all(toml::to_string(&self.0)?.as_bytes())?; + let cb_config_filepath = cb_config_dir.clone().join("config.toml"); + tracing::debug!(cometbft_config = %cb_config_filepath.display(), "writing cometbft config.toml"); + let mut cb_config_file = File::create(cb_config_filepath)?; + cb_config_file.write_all(toml::to_string(&self.0)?.as_bytes())?; // Write this node's node_key.json // the underlying type doesn't implement Copy or Clone (for the best) @@ -105,13 +105,13 @@ impl TestnetTendermintConfig { ); let node_key = NodeKey { priv_key }; - let tm_node_key_filepath = tm_config_dir.clone().join("node_key.json"); - tracing::debug!(tm_node_key_filepath = %tm_node_key_filepath.display(), "writing node key file"); - let mut tm_node_key_file = File::create(tm_node_key_filepath)?; - tm_node_key_file.write_all(serde_json::to_string_pretty(&node_key)?.as_bytes())?; + let cb_node_key_filepath = cb_config_dir.clone().join("node_key.json"); + tracing::debug!(cb_node_key_filepath = %cb_node_key_filepath.display(), "writing node key file"); + let mut cb_node_key_file = File::create(cb_node_key_filepath)?; + cb_node_key_file.write_all(serde_json::to_string_pretty(&node_key)?.as_bytes())?; // Write this node's priv_validator_key.json - let priv_validator_key_filepath = tm_config_dir.clone().join("priv_validator_key.json"); + let priv_validator_key_filepath = cb_config_dir.clone().join("priv_validator_key.json"); tracing::debug!(priv_validator_key_filepath = %priv_validator_key_filepath.display(), "writing validator private key"); let mut priv_validator_key_file = File::create(priv_validator_key_filepath)?; let priv_validator_key: PrivValidatorKey = v.keys.priv_validator_key()?; @@ -119,13 +119,13 @@ impl TestnetTendermintConfig { .write_all(serde_json::to_string_pretty(&priv_validator_key)?.as_bytes())?; // Write the initial validator state: - let priv_validator_state_filepath = tm_data_dir.clone().join("priv_validator_state.json"); + let priv_validator_state_filepath = cb_data_dir.clone().join("priv_validator_state.json"); tracing::debug!(priv_validator_state_filepath = %priv_validator_state_filepath.display(), "writing validator state"); let mut priv_validator_state_file = File::create(priv_validator_state_filepath)?; priv_validator_state_file.write_all(TestnetValidator::initial_state().as_bytes())?; // Write the validator's spend key: - let validator_spend_key_filepath = tm_config_dir.clone().join("validator_custody.json"); + let validator_spend_key_filepath = cb_config_dir.clone().join("validator_custody.json"); tracing::debug!(validator_spend_key_filepath = %validator_spend_key_filepath.display(), "writing validator custody file"); let mut validator_spend_key_file = File::create(validator_spend_key_filepath)?; let validator_wallet = KeyStore { diff --git a/deployments/compose/docker-compose.yml b/deployments/compose/docker-compose.yml index 63221eebbb..96be98b8dc 100644 --- a/deployments/compose/docker-compose.yml +++ b/deployments/compose/docker-compose.yml @@ -31,19 +31,19 @@ services: - "26658:26658" - "8080:8080" - # The Tendermint node + # The CometBFT node tendermint-node0: - image: "docker.io/tendermint/tendermint:v0.34.23" + image: "docker.io/cometbft/cometbft:v0.34.27" user: "${UID:-1000}" ports: - "26656:26656" - "26657:26657" volumes: - - ~/.penumbra/testnet_data/node0/tendermint:/tendermint + - ~/.penumbra/testnet_data/node0/cometbft:/cometbft entrypoint: tendermint command: start --proxy_app=tcp://pd-node0:26658 environment: - ID=0 - - LOG=${LOG:-tendermint.log} + - LOG=${LOG:-cometbft.log} depends_on: - pd-node0 diff --git a/deployments/scripts/smoke-test.sh b/deployments/scripts/smoke-test.sh index 18a524c6c1..feae5a25e2 100755 --- a/deployments/scripts/smoke-test.sh +++ b/deployments/scripts/smoke-test.sh @@ -21,6 +21,12 @@ if [[ -d ~/.penumbra/testnet_data ]] ; then exit 1 fi +if ! hash cometbft > /dev/null 2>&1 ; then + >&2 echo "ERROR: cometbft not found in PATH" + >&2 echo "See install guide: https://guide.penumbra.zone/main/pd/build.html" + exit 1 +fi + export RUST_LOG="pclientd=info,pcli=info,pd=info,penumbra=info" # Duration that the network will be left running before script exits. @@ -33,15 +39,15 @@ EPOCH_DURATION="${EPOCH_DURATION:-100}" cargo run --quiet --release --bin pd -- testnet generate --epoch-duration "$EPOCH_DURATION" --timeout-commit 500ms echo "Starting Tendermint..." -tendermint start --log_level=error --home "${HOME}/.penumbra/testnet_data/node0/tendermint" & -tendermint_pid="$!" +cometbft start --log_level=error --home "${HOME}/.penumbra/testnet_data/node0/cometbft" & +cometbft_pid="$!" echo "Starting pd..." cargo run --quiet --release --bin pd -- start --home "${HOME}/.penumbra/testnet_data/node0/pd" & pd_pid="$!" # Ensure processes are cleaned up after script exits, regardless of status. -trap 'kill -9 "$tendermint_pid" "$pd_pid"' EXIT +trap 'kill -9 "$cometbft_pid" "$pd_pid"' EXIT echo "Waiting $TESTNET_BOOTTIME seconds for network to boot..." sleep "$TESTNET_BOOTTIME" @@ -61,7 +67,7 @@ sleep "$TESTNET_RUNTIME" # `kill -0` checks existence of pid, i.e. whether the process is still running. # It doesn't inspect errors, but the only reason the process would be stopped # is if it failed, so it's good enough for our needs. -if ! kill -0 "$tendermint_pid" || ! kill -0 "$pd_pid" ; then +if ! kill -0 "$cometbft_pid" || ! kill -0 "$pd_pid" ; then >&2 echo "ERROR: smoke test process exited early" exit 1 else diff --git a/deployments/systemd/cometbft.service b/deployments/systemd/cometbft.service new file mode 100644 index 0000000000..efac3a2285 --- /dev/null +++ b/deployments/systemd/cometbft.service @@ -0,0 +1,11 @@ +[Unit] +Description=CometBFT for Penumbra + +[Service] +ExecStart=/usr/local/bin/cometbft start --home $HOME/.penumbra/testnet_data/node0/cometbft +Restart=on-failure +RestartSec=5 +User=$USER + +[Install] +WantedBy=default.target diff --git a/deployments/systemd/tendermint.service b/deployments/systemd/tendermint.service deleted file mode 100644 index 983a48376d..0000000000 --- a/deployments/systemd/tendermint.service +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=Tendermint for Penumbra - -[Service] -ExecStart=/usr/local/bin/tendermint start --home $HOME/.penumbra/testnet_data/node0/tendermint -Restart=on-failure -RestartSec=5 -User=$USER - -[Install] -WantedBy=default.target diff --git a/docs/guide/src/pd/build.md b/docs/guide/src/pd/build.md index 3369a28fe9..93d4d9c881 100644 --- a/docs/guide/src/pd/build.md +++ b/docs/guide/src/pd/build.md @@ -12,24 +12,18 @@ cargo build --release --bin pd Because you are building a work-in-progress version of the node software, you may see compilation warnings, which you can safely ignore. -### Installing Tendermint +### Installing CometBFT -You'll need to have [Tendermint installed](https://docs.tendermint.com/v0.34/introduction/install.html) -on your system to join your node to the testnet. +You'll need to have [CometBFT installed](https://docs.cometbft.com/v0.34/guides/install) +on your system to join your node to the testnet. -**NOTE**: Previous versions of Penumbra used Tendermint 0.35, which -has now been [officially -deprecated](https://interchain-io.medium.com/discontinuing-tendermint-v0-35-a-postmortem-on-the-new-networking-layer-3696c811dabc) -by the Tendermint Council. We have now [rolled back to -v0.34](https://github.com/penumbra-zone/penumbra/issues/1271). -**Do not use** Tendermint `0.35`, which will no longer work with `pd`. -that can prevent nodes from staying online. +**NOTE**: Previous versions of Penumbra used Tendermint, but as of Testnet 61 (released 2023-09-25), +only CometBFT is supported. **Do not use** any version of Tendermint, which may not work with `pd`. -Follow [Tendermint's installation instructions](https://docs.tendermint.com/v0.34/introduction/install.html), -but before you start compiling, make sure you are compiling version `v0.34.23`. +Follow the [CometBFT installation instructions](https://docs.cometbft.com/v0.34/guides/install) +to install a binary. If you prefer to compile from source instead, +make sure you are compiling version `v0.34.27`: ```bash -git checkout v0.34.23 +git checkout v0.34.27 ``` - -[protoc-install]: https://grpc.io/docs/protoc-installation/