feat(zebra-network): add user agent argument (#6601)

* add user agent as argument, use git to auto build zebra user agent

* try to fix test

* fix typo

* change expect text

* remove newline

* fix some docs

Co-authored-by: Marek <mail@marek.onl>

---------

Co-authored-by: Marek <mail@marek.onl>
This commit is contained in:
Alfredo Garcia 2023-05-04 21:29:14 -03:00 committed by GitHub
parent ce0d98739b
commit 7c67512cd5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 77 additions and 41 deletions

View File

@ -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`

View File

@ -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.

View File

@ -87,6 +87,7 @@ pub async fn init<S, C>(
config: Config,
inbound_service: S,
latest_chain_tip: C,
user_agent: String,
) -> (
Buffer<BoxService<Request, Response, BoxError>, Request>,
Arc<std::sync::Mutex<AddressBook>>,
@ -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()

View File

@ -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
}

View File

@ -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<GetInfo> {
// 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)

View File

@ -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]"
}),

View File

@ -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;

View File

@ -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 {

View File

@ -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) =

View File

@ -648,6 +648,7 @@ async fn setup(
network_config,
inbound_service.clone(),
latest_chain_tip.clone(),
"Zebra user agent".to_string(),
)
.await;

View File

@ -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);

View File

@ -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(())
}