From 0f31adeafb9edeccd2b2cb09f6702756ce72dfe1 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Fri, 28 Feb 2020 17:57:50 -0700 Subject: [PATCH] GET for /snapshot.tar.bz2 now redirects to the latest snapshot --- core/src/rpc_service.rs | 74 +++++++++++++++++++++++++++++++++++++---- validator/src/main.rs | 9 ++--- 2 files changed, 69 insertions(+), 14 deletions(-) diff --git a/core/src/rpc_service.rs b/core/src/rpc_service.rs index d0747ecb6..d728b6a4b 100644 --- a/core/src/rpc_service.rs +++ b/core/src/rpc_service.rs @@ -10,7 +10,11 @@ use jsonrpc_http_server::{ RequestMiddlewareAction, ServerBuilder, }; use regex::Regex; -use solana_ledger::{bank_forks::BankForks, blockstore::Blockstore}; +use solana_ledger::{ + bank_forks::{BankForks, SnapshotConfig}, + blockstore::Blockstore, + snapshot_utils, +}; use solana_sdk::hash::Hash; use std::{ net::SocketAddr, @@ -32,16 +36,27 @@ pub struct JsonRpcService { struct RpcRequestMiddleware { ledger_path: PathBuf, snapshot_archive_path_regex: Regex, + snapshot_config: Option, } + impl RpcRequestMiddleware { - pub fn new(ledger_path: PathBuf) -> Self { + pub fn new(ledger_path: PathBuf, snapshot_config: Option) -> Self { Self { ledger_path, snapshot_archive_path_regex: Regex::new(r"/snapshot-\d+-[[:alnum:]]+\.tar\.bz2$") .unwrap(), + snapshot_config, } } + fn redirect(location: &str) -> hyper::Response { + hyper::Response::builder() + .status(hyper::StatusCode::SEE_OTHER) + .header(hyper::header::LOCATION, location) + .body(hyper::Body::from(String::from(location))) + .unwrap() + } + fn not_found() -> hyper::Response { hyper::Response::builder() .status(hyper::StatusCode::NOT_FOUND) @@ -59,7 +74,13 @@ impl RpcRequestMiddleware { fn is_get_path(&self, path: &str) -> bool { match path { "/genesis.tar.bz2" => true, - _ => self.snapshot_archive_path_regex.is_match(path), + _ => { + if self.snapshot_config.is_some() { + self.snapshot_archive_path_regex.is_match(path) + } else { + false + } + } } } @@ -89,6 +110,32 @@ impl RequestMiddleware for RpcRequestMiddleware { fn on_request(&self, request: hyper::Request) -> RequestMiddlewareAction { trace!("request uri: {}", request.uri()); + if let Some(ref snapshot_config) = self.snapshot_config { + if request.uri().path() == "/snapshot.tar.bz2" { + // Convenience redirect to the latest snapshot + return RequestMiddlewareAction::Respond { + should_validate_hosts: true, + response: Box::new(jsonrpc_core::futures::future::ok( + if let Some((snapshot_archive, _)) = + snapshot_utils::get_highest_snapshot_archive_path( + &snapshot_config.snapshot_package_output_path, + ) + { + RpcRequestMiddleware::redirect(&format!( + "/{}", + snapshot_archive + .file_name() + .unwrap_or_else(|| std::ffi::OsStr::new("")) + .to_str() + .unwrap_or(&"") + )) + } else { + RpcRequestMiddleware::not_found() + }, + )), + }; + } + } if self.is_get_path(request.uri().path()) { self.get(request.uri().path()) } else { @@ -105,6 +152,7 @@ impl JsonRpcService { pub fn new( rpc_addr: SocketAddr, config: JsonRpcConfig, + snapshot_config: Option, bank_forks: Arc>, block_commitment_cache: Arc>, blockstore: Arc, @@ -148,7 +196,7 @@ impl JsonRpcService { AccessControlAllowOrigin::Any, ])) .cors_max_age(86400) - .request_middleware(RpcRequestMiddleware::new(ledger_path)) + .request_middleware(RpcRequestMiddleware::new(ledger_path, snapshot_config)) .start_http(&rpc_addr); if let Err(e) = server { warn!("JSON RPC service unavailable error: {:?}. \nAlso, check that port {} is not already in use by another application", e, rpc_addr.port()); @@ -225,6 +273,7 @@ mod tests { let mut rpc_service = JsonRpcService::new( rpc_addr, JsonRpcConfig::default(), + None, bank_forks, block_commitment_cache, Arc::new(blockstore), @@ -253,16 +302,27 @@ mod tests { #[test] fn test_is_get_path() { - let rrm = RpcRequestMiddleware::new(PathBuf::from("/")); + let rrm = RpcRequestMiddleware::new(PathBuf::from("/"), None); + let rrm_with_snapshot_config = RpcRequestMiddleware::new( + PathBuf::from("/"), + Some(SnapshotConfig { + snapshot_interval_slots: 0, + snapshot_package_output_path: PathBuf::from("/"), + snapshot_path: PathBuf::from("/"), + }), + ); assert!(rrm.is_get_path("/genesis.tar.bz2")); assert!(!rrm.is_get_path("genesis.tar.bz2")); - assert!(!rrm.is_get_path("/snapshot.tar.bz2")); + assert!(!rrm.is_get_path("/snapshot.tar.bz2")); // This is a redirect assert!( - rrm.is_get_path("/snapshot-100-AvFf9oS8A8U78HdjT9YG2sTTThLHJZmhaMn2g8vkWYnr.tar.bz2") + !rrm.is_get_path("/snapshot-100-AvFf9oS8A8U78HdjT9YG2sTTThLHJZmhaMn2g8vkWYnr.tar.bz2") ); + assert!(rrm_with_snapshot_config + .is_get_path("/snapshot-100-AvFf9oS8A8U78HdjT9YG2sTTThLHJZmhaMn2g8vkWYnr.tar.bz2")); + assert!(!rrm.is_get_path( "/snapshot-notaslotnumber-AvFf9oS8A8U78HdjT9YG2sTTThLHJZmhaMn2g8vkWYnr.tar.bz2" )); diff --git a/validator/src/main.rs b/validator/src/main.rs index f8f0ba528..c316f146f 100644 --- a/validator/src/main.rs +++ b/validator/src/main.rs @@ -2,7 +2,7 @@ use bzip2::bufread::BzDecoder; use clap::{ crate_description, crate_name, value_t, value_t_or_exit, values_t_or_exit, App, Arg, ArgMatches, }; -use console::{style, Emoji}; +use console::Emoji; use indicatif::{ProgressBar, ProgressStyle}; use log::*; use rand::{thread_rng, Rng}; @@ -953,12 +953,6 @@ pub fn main() { warn!("--vote-signer-address ignored"); } - println!( - "{} {}", - style(crate_name!()).bold(), - solana_clap_utils::version!() - ); - let _log_redirect = { #[cfg(unix)] { @@ -996,6 +990,7 @@ pub fn main() { .join(","), ); + info!("{} {}", crate_name!(), solana_clap_utils::version!()); info!("Starting validator with: {:#?}", std::env::args_os()); let vote_account = pubkey_of(&matches, "vote_account").unwrap_or_else(|| {