diff --git a/.github/PULL_REQUEST_TEMPLATE/release-checklist.md b/.github/PULL_REQUEST_TEMPLATE/release-checklist.md index b494d975..b3952bdb 100644 --- a/.github/PULL_REQUEST_TEMPLATE/release-checklist.md +++ b/.github/PULL_REQUEST_TEMPLATE/release-checklist.md @@ -43,7 +43,6 @@ Once you know which versions you want to increment, you can find them in the: zebrad (rc): - [ ] zebrad `Cargo.toml` -- [ ] `zebra-network` release version (`RELEASE_VERSION`): https://github.com/ZcashFoundation/zebra/blob/main/zebra-network/src/constants.rs - [ ] `README.md` - [ ] `book/src/user/docker.md` diff --git a/zebra-network/src/constants.rs b/zebra-network/src/constants.rs index ba6da14b..67e73874 100644 --- a/zebra-network/src/constants.rs +++ b/zebra-network/src/constants.rs @@ -269,13 +269,6 @@ pub const MAX_ADDRS_IN_ADDRESS_BOOK: usize = /// messages from each of our peers. pub const TIMESTAMP_TRUNCATION_SECONDS: u32 = 30 * 60; -/// Release version name is used to form user agent string. -/// Can be also used in other parts of Zebra to identify the current release. -/// -// -// TODO: generate this from crate metadata (#2375) -pub const RELEASE_VERSION: &str = "1.0.0-rc.7"; - /// The Zcash network protocol version implemented by this crate, and advertised /// during connection setup. /// @@ -334,13 +327,6 @@ lazy_static! { } else { Regex::new("(access a socket in a way forbidden by its access permissions)|(Only one usage of each socket address)") }.expect("regex is valid"); - - /// The User-Agent string provided by the node. - /// - /// This must be a valid [BIP 14] user agent. - /// - /// [BIP 14]: https://github.com/bitcoin/bips/blob/master/bip-0014.mediawiki - pub static ref USER_AGENT: String = format!("/Zebra:{RELEASE_VERSION}/"); } /// The timeout for DNS lookups. diff --git a/zebra-network/src/peer_set/initialize.rs b/zebra-network/src/peer_set/initialize.rs index 21993ea6..664e483d 100644 --- a/zebra-network/src/peer_set/initialize.rs +++ b/zebra-network/src/peer_set/initialize.rs @@ -87,6 +87,7 @@ pub async fn init( config: Config, inbound_service: S, latest_chain_tip: C, + user_agent: String, ) -> ( Buffer, Request>, Arc>, @@ -131,7 +132,7 @@ where .with_inventory_collector(inv_sender) .with_address_book_updater(address_book_updater.clone()) .with_advertised_services(PeerServices::NODE_NETWORK) - .with_user_agent(crate::constants::USER_AGENT.to_string()) + .with_user_agent(user_agent) .with_latest_chain_tip(latest_chain_tip.clone()) .want_transactions(true) .finish() diff --git a/zebra-network/src/peer_set/initialize/tests/vectors.rs b/zebra-network/src/peer_set/initialize/tests/vectors.rs index 62955c61..8bab47c0 100644 --- a/zebra-network/src/peer_set/initialize/tests/vectors.rs +++ b/zebra-network/src/peer_set/initialize/tests/vectors.rs @@ -1245,7 +1245,7 @@ async fn remnant_nonces_from_outbound_connections_are_limited() { let hs = peer::Handshake::builder() .with_config(config.clone()) .with_inbound_service(nil_inbound_service) - .with_user_agent(crate::constants::USER_AGENT.to_string()) + .with_user_agent(("Test user agent").to_string()) .with_latest_chain_tip(NoChainTip) .want_transactions(true) .finish() @@ -1351,7 +1351,12 @@ async fn add_initial_peers_deadlock() { let nil_inbound_service = service_fn(|_| async { Ok(Response::Nil) }); - let init_future = init(config, nil_inbound_service, NoChainTip); + let init_future = init( + config, + nil_inbound_service, + NoChainTip, + "Test user agent".to_string(), + ); assert!(tokio::time::timeout(TIME_LIMIT, init_future).await.is_ok()); } @@ -1372,7 +1377,13 @@ async fn local_listener_port_with(listen_addr: SocketAddr, network: Network) { let inbound_service = service_fn(|_| async { unreachable!("inbound service should never be called") }); - let (_peer_service, address_book) = init(config, inbound_service, NoChainTip).await; + let (_peer_service, address_book) = init( + config, + inbound_service, + NoChainTip, + "Test user agent".to_string(), + ) + .await; let local_listener = address_book.lock().unwrap().local_listener_meta_addr(); if listen_addr.port() == 0 { @@ -1429,7 +1440,13 @@ where ..default_config }; - let (_peer_service, address_book) = init(config, inbound_service, NoChainTip).await; + let (_peer_service, address_book) = init( + config, + inbound_service, + NoChainTip, + "Test user agent".to_string(), + ) + .await; address_book } diff --git a/zebra-rpc/src/methods.rs b/zebra-rpc/src/methods.rs index b23bbc9d..f1a9f2ef 100644 --- a/zebra-rpc/src/methods.rs +++ b/zebra-rpc/src/methods.rs @@ -28,7 +28,6 @@ use zebra_chain::{ transaction::{self, SerializedTransaction, Transaction, UnminedTx}, transparent::{self, Address}, }; -use zebra_network::constants::USER_AGENT; use zebra_node_services::mempool; use zebra_state::{HashOrHeight, MinedTx, OutputIndex, OutputLocation, TransactionLocation}; @@ -365,10 +364,25 @@ where State::Future: Send, Tip: ChainTip + Clone + Send + Sync + 'static, { + #[allow(clippy::unwrap_in_result)] fn get_info(&self) -> Result { + // Build a [BIP 14] valid user agent with release info. + // + // [BIP 14]: https://github.com/bitcoin/bips/blob/master/bip-0014.mediawiki + let release_version = self + .app_version + // remove everything after the `+` character if any + .split('+') + .next() + .expect("always at least 1 slice") + // remove the previously added `v` character at the start since it's not a part of the user agent. + .strip_prefix('v') + .expect("we are always expecting the `v` prefix"); + let user_agent = format!("/Zebra:{release_version}/"); + let response = GetInfo { build: self.app_version.clone(), - subversion: USER_AGENT.to_string(), + subversion: user_agent, }; Ok(response) diff --git a/zebra-rpc/src/methods/tests/snapshot.rs b/zebra-rpc/src/methods/tests/snapshot.rs index e28af914..341c0ab6 100644 --- a/zebra-rpc/src/methods/tests/snapshot.rs +++ b/zebra-rpc/src/methods/tests/snapshot.rs @@ -14,7 +14,6 @@ use zebra_chain::{ parameters::Network::{Mainnet, Testnet}, serialization::ZcashDeserializeInto, }; -use zebra_network::constants::USER_AGENT; use zebra_test::mock_service::MockService; use super::super::*; @@ -267,7 +266,7 @@ fn snapshot_rpc_getinfo(info: GetInfo, settings: &insta::Settings) { insta::assert_json_snapshot!("get_info", info, { ".subversion" => dynamic_redaction(|value, _path| { // assert that the subversion value is user agent - assert_eq!(value.as_str().unwrap(), USER_AGENT.to_string()); + assert_eq!(value.as_str().unwrap(), format!("/Zebra:RPC test/")); // replace with: "[SubVersion]" }), diff --git a/zebra-rpc/src/methods/tests/vectors.rs b/zebra-rpc/src/methods/tests/vectors.rs index 5ec79b7d..eb495918 100644 --- a/zebra-rpc/src/methods/tests/vectors.rs +++ b/zebra-rpc/src/methods/tests/vectors.rs @@ -14,7 +14,6 @@ use zebra_chain::{ transaction::{UnminedTx, UnminedTxId}, transparent, }; -use zebra_network::constants::USER_AGENT; use zebra_node_services::BoxError; use zebra_test::mock_service::MockService; @@ -46,7 +45,7 @@ async fn rpc_getinfo() { // make sure there is a `subversion` field, // and that is equal to the Zebra user agent. - assert_eq!(get_info.subversion, USER_AGENT.to_string()); + assert_eq!(get_info.subversion, format!("/Zebra:RPC test/")); mempool.expect_no_requests().await; state.expect_no_requests().await; diff --git a/zebrad/src/application.rs b/zebrad/src/application.rs index fab48a59..256da88d 100644 --- a/zebrad/src/application.rs +++ b/zebrad/src/application.rs @@ -96,6 +96,26 @@ pub fn app_version() -> Version { } } +/// The Zebra current release version. +pub fn release_version() -> String { + app_version() + .to_string() + .split('+') + .next() + .expect("always at least 1 slice") + .to_string() +} + +/// The User-Agent string provided by the node. +/// +/// This must be a valid [BIP 14] user agent. +/// +/// [BIP 14]: https://github.com/bitcoin/bips/blob/master/bip-0014.mediawiki +pub fn user_agent() -> String { + let release_version = release_version(); + format!("/Zebra:{release_version}/") +} + /// Zebrad Application #[derive(Debug)] pub struct ZebradApp { diff --git a/zebrad/src/commands/start.rs b/zebrad/src/commands/start.rs index ddff2f21..ab57713a 100644 --- a/zebrad/src/commands/start.rs +++ b/zebrad/src/commands/start.rs @@ -79,7 +79,7 @@ use zebra_consensus::chain::BackgroundTaskHandles; use zebra_rpc::server::RpcServer; use crate::{ - application::app_version, + application::{app_version, user_agent}, components::{ inbound::{self, InboundSetupData}, mempool::{self, Mempool}, @@ -138,8 +138,13 @@ impl StartCmd { setup_rx, )); - let (peer_set, address_book) = - zebra_network::init(config.network.clone(), inbound, latest_chain_tip.clone()).await; + let (peer_set, address_book) = zebra_network::init( + config.network.clone(), + inbound, + latest_chain_tip.clone(), + user_agent(), + ) + .await; info!("initializing verifiers"); let (chain_verifier, tx_verifier, consensus_task_handles, max_checkpoint_height) = diff --git a/zebrad/src/components/inbound/tests/real_peer_set.rs b/zebrad/src/components/inbound/tests/real_peer_set.rs index c610f1a1..6e176cf3 100644 --- a/zebrad/src/components/inbound/tests/real_peer_set.rs +++ b/zebrad/src/components/inbound/tests/real_peer_set.rs @@ -648,6 +648,7 @@ async fn setup( network_config, inbound_service.clone(), latest_chain_tip.clone(), + "Zebra user agent".to_string(), ) .await; diff --git a/zebrad/src/components/sync/end_of_support.rs b/zebrad/src/components/sync/end_of_support.rs index bad99cf1..0763ccb8 100644 --- a/zebrad/src/components/sync/end_of_support.rs +++ b/zebrad/src/components/sync/end_of_support.rs @@ -3,7 +3,6 @@ use std::time::Duration; use color_eyre::Report; -use lazy_static::lazy_static; use zebra_chain::{ block::Height, @@ -11,12 +10,7 @@ use zebra_chain::{ parameters::{Network, NetworkUpgrade}, }; -use zebra_network::constants::RELEASE_VERSION; - -lazy_static! { - /// The name of the current Zebra release. - pub static ref RELEASE_NAME: String = format!("Zebra {}", RELEASE_VERSION); -} +use crate::application::release_version; /// The estimated height that this release started to run. pub const ESTIMATED_RELEASE_HEIGHT: u32 = 2_026_000; @@ -88,13 +82,13 @@ pub fn check(tip_height: Height, network: Network) { "{EOS_PANIC_MESSAGE_HEADER} if the release date is older than {EOS_PANIC_AFTER} days. \ \nRelease name: {}, Estimated release height: {ESTIMATED_RELEASE_HEIGHT} \ \nHint: Download and install the latest Zebra release from: https://github.com/ZcashFoundation/zebra/releases/latest", - *RELEASE_NAME + release_version() ); } else if tip_height > warn_height { warn!( "{EOS_WARN_MESSAGE_HEADER} at block {}. \ \nRelease name: {}, Estimated release height: {ESTIMATED_RELEASE_HEIGHT} \ - \nHint: Download and install the latest Zebra release from: https://github.com/ZcashFoundation/zebra/releases/latest", panic_height.0, RELEASE_NAME.to_string() + \nHint: Download and install the latest Zebra release from: https://github.com/ZcashFoundation/zebra/releases/latest", panic_height.0, release_version() ); } else { info!("Zebra release is supported until block {}, please report bugs at https://github.com/ZcashFoundation/zebra/issues", panic_height.0); diff --git a/zebrad/tests/common/lightwalletd/wallet_grpc_test.rs b/zebrad/tests/common/lightwalletd/wallet_grpc_test.rs index 6771958c..4b84e4e7 100644 --- a/zebrad/tests/common/lightwalletd/wallet_grpc_test.rs +++ b/zebrad/tests/common/lightwalletd/wallet_grpc_test.rs @@ -43,8 +43,6 @@ use zebra_chain::{ serialization::ZcashDeserializeInto, }; -use zebra_network::constants::USER_AGENT; - use crate::common::{ launch::spawn_zebrad_for_rpc, lightwalletd::{ @@ -358,7 +356,10 @@ pub async fn run() -> Result<()> { let lightd_info = rpc_client.get_lightd_info(Empty {}).await?.into_inner(); // Make sure the subversion field is zebra the user agent - assert_eq!(lightd_info.zcashd_subversion, USER_AGENT.to_string()); + assert_eq!( + lightd_info.zcashd_subversion, + zebrad::application::user_agent() + ); Ok(()) }