pub mod config;
pub mod error;
pub mod handle;
pub mod service;
use crate::base_node_service::{
config::BaseNodeServiceConfig,
handle::BaseNodeServiceHandle,
service::BaseNodeService,
};
use futures::{future, Future, Stream, StreamExt};
use log::*;
use std::sync::Arc;
use tari_comms_dht::Dht;
use tari_core::proto::base_node as proto;
use tari_p2p::{
comms_connector::SubscriptionFactory,
domain_message::DomainMessage,
services::utils::{map_decode, ok_or_skip_result},
tari_message::TariMessageType,
};
use tari_service_framework::{
reply_channel,
ServiceInitializationError,
ServiceInitializer,
ServiceInitializerContext,
};
use tokio::sync::broadcast;
const LOG_TARGET: &str = "wallet::base_node_service";
const SUBSCRIPTION_LABEL: &str = "Base Node";
pub struct BaseNodeServiceInitializer {
config: BaseNodeServiceConfig,
subscription_factory: Arc<SubscriptionFactory>,
}
impl BaseNodeServiceInitializer {
pub fn new(config: BaseNodeServiceConfig, subscription_factory: Arc<SubscriptionFactory>) -> Self {
Self {
config,
subscription_factory,
}
}
fn base_node_response_stream(&self) -> impl Stream<Item = DomainMessage<proto::BaseNodeServiceResponse>> {
trace!(
target: LOG_TARGET,
"Subscription '{}' for topic '{:?}' created.",
SUBSCRIPTION_LABEL,
TariMessageType::BaseNodeResponse
);
self.subscription_factory
.get_subscription(TariMessageType::BaseNodeResponse, SUBSCRIPTION_LABEL)
.map(map_decode::<proto::BaseNodeServiceResponse>)
.filter_map(ok_or_skip_result)
}
}
impl ServiceInitializer for BaseNodeServiceInitializer {
type Future = impl Future<Output = Result<(), ServiceInitializationError>>;
fn initialize(&mut self, context: ServiceInitializerContext) -> Self::Future {
info!(target: LOG_TARGET, "Wallet base node service initializing.");
let (sender, request_stream) = reply_channel::unbounded();
let base_node_response_stream = self.base_node_response_stream();
let (event_publisher, _) = broadcast::channel(200);
let basenode_service_handle = BaseNodeServiceHandle::new(sender, event_publisher.clone());
context.register_handle(basenode_service_handle);
let config = self.config.clone();
context.spawn_when_ready(move |handles| async move {
let dht = handles.expect_handle::<Dht>();
let outbound_messaging = dht.outbound_requester();
let service = BaseNodeService::new(
config,
base_node_response_stream,
request_stream,
outbound_messaging,
event_publisher,
handles.get_shutdown_signal(),
)
.start();
futures::pin_mut!(service);
future::select(service, handles.get_shutdown_signal()).await;
info!(target: LOG_TARGET, "Wallet Base Node Service shutdown");
});
future::ready(Ok(()))
}
}