2024-03-22 11:22:38 -07:00
|
|
|
use solana_lite_rpc_core::types::BlockInfoStream;
|
2023-08-31 03:34:13 -07:00
|
|
|
use solana_lite_rpc_core::{
|
2023-09-13 08:15:28 -07:00
|
|
|
stores::data_cache::DataCache,
|
|
|
|
structures::notifications::NotificationSender,
|
|
|
|
types::{BlockStream, ClusterInfoStream, SlotStream, VoteAccountStream},
|
2023-08-31 03:34:13 -07:00
|
|
|
AnyhowJoinHandle,
|
|
|
|
};
|
2024-04-07 04:55:40 -07:00
|
|
|
use solana_lite_rpc_services::tpu_utils::tpu_connection_path::TpuConnectionPath;
|
2023-08-31 03:34:13 -07:00
|
|
|
use solana_lite_rpc_services::{
|
|
|
|
data_caching_service::DataCachingService,
|
|
|
|
metrics_capture::MetricsCapture,
|
|
|
|
prometheus_sync::PrometheusSync,
|
|
|
|
tpu_utils::tpu_service::TpuService,
|
|
|
|
transaction_replayer::TransactionReplayer,
|
|
|
|
transaction_service::{TransactionService, TransactionServiceBuilder},
|
|
|
|
tx_sender::TxSender,
|
|
|
|
};
|
|
|
|
use std::time::Duration;
|
2024-04-07 04:55:40 -07:00
|
|
|
use std::net::{SocketAddr, ToSocketAddrs};
|
2024-03-22 11:22:38 -07:00
|
|
|
|
2023-08-31 03:34:13 -07:00
|
|
|
pub struct ServiceSpawner {
|
|
|
|
pub data_cache: DataCache,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ServiceSpawner {
|
|
|
|
/// spawn services that support the whole system
|
2024-04-02 05:26:54 -07:00
|
|
|
pub async fn spawn_support_services(&self, prometheus_addr: String) -> anyhow::Result<()> {
|
2023-08-31 03:34:13 -07:00
|
|
|
// spawn prometheus
|
2024-04-02 05:26:54 -07:00
|
|
|
let prometheus = PrometheusSync::sync(prometheus_addr.clone());
|
2023-08-31 03:34:13 -07:00
|
|
|
|
|
|
|
// spawn metrics capture
|
|
|
|
let metrics = MetricsCapture::new(self.data_cache.txs.clone()).capture();
|
|
|
|
|
|
|
|
tokio::select! {
|
|
|
|
prometheus_res = prometheus => {
|
|
|
|
anyhow::bail!("Prometheus exited unexpectedly: {prometheus_res:?}");
|
|
|
|
}
|
|
|
|
metrics_res = metrics => {
|
|
|
|
anyhow::bail!("Metrics capture exited unexpectedly: {metrics_res:?}");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-22 11:22:38 -07:00
|
|
|
// TODO remove
|
|
|
|
pub async fn _spawn_data_caching_service(
|
2023-08-31 03:34:13 -07:00
|
|
|
&self,
|
|
|
|
block_notifier: BlockStream,
|
2024-03-22 11:22:38 -07:00
|
|
|
blockinfo_notifier: BlockInfoStream,
|
2023-08-31 03:34:13 -07:00
|
|
|
slot_notification: SlotStream,
|
|
|
|
cluster_info_notification: ClusterInfoStream,
|
|
|
|
va_notification: VoteAccountStream,
|
|
|
|
) -> Vec<AnyhowJoinHandle> {
|
|
|
|
let data_service = DataCachingService {
|
|
|
|
data_cache: self.data_cache.clone(),
|
|
|
|
clean_duration: Duration::from_secs(120),
|
|
|
|
};
|
|
|
|
|
|
|
|
data_service.listen(
|
|
|
|
block_notifier,
|
2024-03-22 11:22:38 -07:00
|
|
|
blockinfo_notifier,
|
2023-08-31 03:34:13 -07:00
|
|
|
slot_notification,
|
|
|
|
cluster_info_notification,
|
|
|
|
va_notification,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[allow(clippy::too_many_arguments)]
|
|
|
|
pub fn spawn_tx_service(
|
|
|
|
&self,
|
|
|
|
tx_sender: TxSender,
|
|
|
|
tx_replayer: TransactionReplayer,
|
|
|
|
tpu_service: TpuService,
|
|
|
|
max_nb_txs_in_queue: usize,
|
|
|
|
notifier: Option<NotificationSender>,
|
|
|
|
max_retries: usize,
|
|
|
|
slot_notifications: SlotStream,
|
|
|
|
) -> (TransactionService, AnyhowJoinHandle) {
|
|
|
|
let service_builder = TransactionServiceBuilder::new(
|
|
|
|
tx_sender,
|
|
|
|
tx_replayer,
|
|
|
|
tpu_service,
|
|
|
|
max_nb_txs_in_queue,
|
|
|
|
);
|
|
|
|
service_builder.start(
|
|
|
|
notifier,
|
2023-09-21 00:56:51 -07:00
|
|
|
self.data_cache.block_information_store.clone(),
|
2023-08-31 03:34:13 -07:00
|
|
|
max_retries,
|
|
|
|
slot_notifications,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
2024-04-07 04:55:40 -07:00
|
|
|
|
|
|
|
|
|
|
|
pub fn configure_tpu_connection_path(quic_proxy_addr: Option<String>) -> TpuConnectionPath {
|
|
|
|
match quic_proxy_addr {
|
|
|
|
None => TpuConnectionPath::QuicDirectPath,
|
|
|
|
Some(prox_address) => {
|
|
|
|
let proxy_socket_addr = parse_host_port(prox_address.as_str()).unwrap();
|
|
|
|
TpuConnectionPath::QuicForwardProxyPath {
|
|
|
|
// e.g. "127.0.0.1:11111" or "localhost:11111"
|
|
|
|
forward_proxy_address: proxy_socket_addr,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn parse_host_port(host_port: &str) -> Result<SocketAddr, String> {
|
|
|
|
let addrs: Vec<_> = host_port
|
|
|
|
.to_socket_addrs()
|
|
|
|
.map_err(|err| format!("Unable to resolve host {host_port}: {err}"))?
|
|
|
|
.collect();
|
|
|
|
if addrs.is_empty() {
|
|
|
|
Err(format!("Unable to resolve host: {host_port}"))
|
|
|
|
} else if addrs.len() > 1 {
|
|
|
|
Err(format!("Multiple addresses resolved for host: {host_port}"))
|
|
|
|
} else {
|
|
|
|
Ok(addrs[0])
|
|
|
|
}
|
|
|
|
}
|