GET for /snapshot.tar.bz2 now redirects to the latest snapshot
This commit is contained in:
parent
ae817722d8
commit
0f31adeafb
|
@ -10,7 +10,11 @@ use jsonrpc_http_server::{
|
||||||
RequestMiddlewareAction, ServerBuilder,
|
RequestMiddlewareAction, ServerBuilder,
|
||||||
};
|
};
|
||||||
use regex::Regex;
|
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 solana_sdk::hash::Hash;
|
||||||
use std::{
|
use std::{
|
||||||
net::SocketAddr,
|
net::SocketAddr,
|
||||||
|
@ -32,16 +36,27 @@ pub struct JsonRpcService {
|
||||||
struct RpcRequestMiddleware {
|
struct RpcRequestMiddleware {
|
||||||
ledger_path: PathBuf,
|
ledger_path: PathBuf,
|
||||||
snapshot_archive_path_regex: Regex,
|
snapshot_archive_path_regex: Regex,
|
||||||
|
snapshot_config: Option<SnapshotConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RpcRequestMiddleware {
|
impl RpcRequestMiddleware {
|
||||||
pub fn new(ledger_path: PathBuf) -> Self {
|
pub fn new(ledger_path: PathBuf, snapshot_config: Option<SnapshotConfig>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
ledger_path,
|
ledger_path,
|
||||||
snapshot_archive_path_regex: Regex::new(r"/snapshot-\d+-[[:alnum:]]+\.tar\.bz2$")
|
snapshot_archive_path_regex: Regex::new(r"/snapshot-\d+-[[:alnum:]]+\.tar\.bz2$")
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
|
snapshot_config,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn redirect(location: &str) -> hyper::Response<hyper::Body> {
|
||||||
|
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::Body> {
|
fn not_found() -> hyper::Response<hyper::Body> {
|
||||||
hyper::Response::builder()
|
hyper::Response::builder()
|
||||||
.status(hyper::StatusCode::NOT_FOUND)
|
.status(hyper::StatusCode::NOT_FOUND)
|
||||||
|
@ -59,7 +74,13 @@ impl RpcRequestMiddleware {
|
||||||
fn is_get_path(&self, path: &str) -> bool {
|
fn is_get_path(&self, path: &str) -> bool {
|
||||||
match path {
|
match path {
|
||||||
"/genesis.tar.bz2" => true,
|
"/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<hyper::Body>) -> RequestMiddlewareAction {
|
fn on_request(&self, request: hyper::Request<hyper::Body>) -> RequestMiddlewareAction {
|
||||||
trace!("request uri: {}", request.uri());
|
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()) {
|
if self.is_get_path(request.uri().path()) {
|
||||||
self.get(request.uri().path())
|
self.get(request.uri().path())
|
||||||
} else {
|
} else {
|
||||||
|
@ -105,6 +152,7 @@ impl JsonRpcService {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
rpc_addr: SocketAddr,
|
rpc_addr: SocketAddr,
|
||||||
config: JsonRpcConfig,
|
config: JsonRpcConfig,
|
||||||
|
snapshot_config: Option<SnapshotConfig>,
|
||||||
bank_forks: Arc<RwLock<BankForks>>,
|
bank_forks: Arc<RwLock<BankForks>>,
|
||||||
block_commitment_cache: Arc<RwLock<BlockCommitmentCache>>,
|
block_commitment_cache: Arc<RwLock<BlockCommitmentCache>>,
|
||||||
blockstore: Arc<Blockstore>,
|
blockstore: Arc<Blockstore>,
|
||||||
|
@ -148,7 +196,7 @@ impl JsonRpcService {
|
||||||
AccessControlAllowOrigin::Any,
|
AccessControlAllowOrigin::Any,
|
||||||
]))
|
]))
|
||||||
.cors_max_age(86400)
|
.cors_max_age(86400)
|
||||||
.request_middleware(RpcRequestMiddleware::new(ledger_path))
|
.request_middleware(RpcRequestMiddleware::new(ledger_path, snapshot_config))
|
||||||
.start_http(&rpc_addr);
|
.start_http(&rpc_addr);
|
||||||
if let Err(e) = server {
|
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());
|
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(
|
let mut rpc_service = JsonRpcService::new(
|
||||||
rpc_addr,
|
rpc_addr,
|
||||||
JsonRpcConfig::default(),
|
JsonRpcConfig::default(),
|
||||||
|
None,
|
||||||
bank_forks,
|
bank_forks,
|
||||||
block_commitment_cache,
|
block_commitment_cache,
|
||||||
Arc::new(blockstore),
|
Arc::new(blockstore),
|
||||||
|
@ -253,16 +302,27 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_is_get_path() {
|
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("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!(
|
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(
|
assert!(!rrm.is_get_path(
|
||||||
"/snapshot-notaslotnumber-AvFf9oS8A8U78HdjT9YG2sTTThLHJZmhaMn2g8vkWYnr.tar.bz2"
|
"/snapshot-notaslotnumber-AvFf9oS8A8U78HdjT9YG2sTTThLHJZmhaMn2g8vkWYnr.tar.bz2"
|
||||||
));
|
));
|
||||||
|
|
|
@ -2,7 +2,7 @@ use bzip2::bufread::BzDecoder;
|
||||||
use clap::{
|
use clap::{
|
||||||
crate_description, crate_name, value_t, value_t_or_exit, values_t_or_exit, App, Arg, ArgMatches,
|
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 indicatif::{ProgressBar, ProgressStyle};
|
||||||
use log::*;
|
use log::*;
|
||||||
use rand::{thread_rng, Rng};
|
use rand::{thread_rng, Rng};
|
||||||
|
@ -953,12 +953,6 @@ pub fn main() {
|
||||||
warn!("--vote-signer-address ignored");
|
warn!("--vote-signer-address ignored");
|
||||||
}
|
}
|
||||||
|
|
||||||
println!(
|
|
||||||
"{} {}",
|
|
||||||
style(crate_name!()).bold(),
|
|
||||||
solana_clap_utils::version!()
|
|
||||||
);
|
|
||||||
|
|
||||||
let _log_redirect = {
|
let _log_redirect = {
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
{
|
{
|
||||||
|
@ -996,6 +990,7 @@ pub fn main() {
|
||||||
.join(","),
|
.join(","),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
info!("{} {}", crate_name!(), solana_clap_utils::version!());
|
||||||
info!("Starting validator with: {:#?}", std::env::args_os());
|
info!("Starting validator with: {:#?}", std::env::args_os());
|
||||||
|
|
||||||
let vote_account = pubkey_of(&matches, "vote_account").unwrap_or_else(|| {
|
let vote_account = pubkey_of(&matches, "vote_account").unwrap_or_else(|| {
|
||||||
|
|
Loading…
Reference in New Issue