2023-11-30 04:59:15 -08:00
|
|
|
//! Initializing the scanner.
|
|
|
|
|
2024-01-24 14:37:03 -08:00
|
|
|
use std::sync::{mpsc, Arc};
|
|
|
|
|
2023-11-30 04:59:15 -08:00
|
|
|
use color_eyre::Report;
|
2024-01-24 14:37:03 -08:00
|
|
|
use tokio::{sync::oneshot, task::JoinHandle};
|
2024-01-25 17:29:37 -08:00
|
|
|
use tower::ServiceBuilder;
|
2023-11-30 04:59:15 -08:00
|
|
|
|
2024-01-25 17:29:37 -08:00
|
|
|
use zebra_chain::{parameters::Network, transaction::Transaction};
|
2023-12-03 13:58:48 -08:00
|
|
|
use zebra_state::ChainTipChange;
|
2023-11-30 04:59:15 -08:00
|
|
|
|
2024-01-25 17:29:37 -08:00
|
|
|
use crate::{scan, service::ScanService, Config};
|
2023-11-30 04:59:15 -08:00
|
|
|
|
2024-01-24 14:37:03 -08:00
|
|
|
#[derive(Debug)]
|
|
|
|
/// Commands that can be sent to [`ScanTask`]
|
|
|
|
pub enum ScanTaskCommand {
|
|
|
|
/// Start scanning for new viewing keys
|
|
|
|
RegisterKeys(Vec<()>), // TODO: send `ViewingKeyWithHash`es
|
|
|
|
|
|
|
|
/// Stop scanning for deleted viewing keys
|
|
|
|
RemoveKeys {
|
|
|
|
/// Notify the caller once the key is removed (so the caller can wait before clearing results)
|
|
|
|
done_tx: oneshot::Sender<()>,
|
|
|
|
|
|
|
|
/// Key hashes that are to be removed
|
2024-01-31 11:34:24 -08:00
|
|
|
keys: Vec<String>,
|
2024-01-24 14:37:03 -08:00
|
|
|
},
|
|
|
|
|
|
|
|
/// Start sending results for key hashes to `result_sender`
|
|
|
|
SubscribeResults {
|
|
|
|
/// Sender for results
|
|
|
|
result_sender: mpsc::Sender<Arc<Transaction>>,
|
|
|
|
|
|
|
|
/// Key hashes to send the results of to result channel
|
|
|
|
key_hashes: Vec<()>,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2024-01-31 11:34:24 -08:00
|
|
|
#[derive(Debug, Clone)]
|
2024-01-24 14:37:03 -08:00
|
|
|
/// Scan task handle and command channel sender
|
|
|
|
pub struct ScanTask {
|
|
|
|
/// [`JoinHandle`] of scan task
|
2024-01-31 11:34:24 -08:00
|
|
|
pub handle: Arc<JoinHandle<Result<(), Report>>>,
|
2024-01-24 14:37:03 -08:00
|
|
|
|
|
|
|
/// Task command channel sender
|
2024-01-31 11:34:24 -08:00
|
|
|
pub cmd_sender: mpsc::Sender<ScanTaskCommand>,
|
2024-01-24 14:37:03 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl ScanTask {
|
2024-01-25 17:29:37 -08:00
|
|
|
/// Spawns a new [`ScanTask`] for tests.
|
2024-01-31 11:34:24 -08:00
|
|
|
#[cfg(any(test, feature = "proptest-impl"))]
|
|
|
|
pub fn mock() -> (Self, mpsc::Receiver<ScanTaskCommand>) {
|
|
|
|
let (cmd_sender, cmd_receiver) = mpsc::channel();
|
|
|
|
|
|
|
|
(
|
|
|
|
Self {
|
|
|
|
handle: Arc::new(tokio::spawn(std::future::pending())),
|
|
|
|
cmd_sender,
|
|
|
|
},
|
|
|
|
cmd_receiver,
|
|
|
|
)
|
2024-01-25 17:29:37 -08:00
|
|
|
}
|
|
|
|
|
2024-01-24 14:37:03 -08:00
|
|
|
/// Spawns a new [`ScanTask`].
|
|
|
|
pub fn spawn(
|
|
|
|
config: &Config,
|
|
|
|
network: Network,
|
|
|
|
state: scan::State,
|
|
|
|
chain_tip_change: ChainTipChange,
|
|
|
|
) -> Self {
|
2024-01-31 11:34:24 -08:00
|
|
|
let (cmd_sender, cmd_receiver) = mpsc::channel();
|
2024-01-24 14:37:03 -08:00
|
|
|
|
|
|
|
Self {
|
2024-01-31 11:34:24 -08:00
|
|
|
handle: Arc::new(scan::spawn_init(
|
|
|
|
config,
|
|
|
|
network,
|
|
|
|
state,
|
|
|
|
chain_tip_change,
|
|
|
|
cmd_receiver,
|
|
|
|
)),
|
2024-01-24 14:37:03 -08:00
|
|
|
cmd_sender,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Sends a command to the scan task
|
|
|
|
pub fn send(
|
|
|
|
&mut self,
|
|
|
|
command: ScanTaskCommand,
|
|
|
|
) -> Result<(), mpsc::SendError<ScanTaskCommand>> {
|
|
|
|
self.cmd_sender.send(command)
|
|
|
|
}
|
|
|
|
|
2024-01-31 11:34:24 -08:00
|
|
|
/// Sends a message to the scan task to remove the provided viewing keys.
|
|
|
|
pub fn remove_keys(
|
|
|
|
&mut self,
|
|
|
|
keys: &[String],
|
|
|
|
) -> Result<oneshot::Receiver<()>, mpsc::SendError<ScanTaskCommand>> {
|
|
|
|
let (done_tx, done_rx) = oneshot::channel();
|
|
|
|
|
|
|
|
self.send(ScanTaskCommand::RemoveKeys {
|
|
|
|
keys: keys.to_vec(),
|
|
|
|
done_tx,
|
|
|
|
})?;
|
|
|
|
|
|
|
|
Ok(done_rx)
|
|
|
|
}
|
2023-11-30 13:27:46 -08:00
|
|
|
}
|
|
|
|
|
2024-01-25 17:29:37 -08:00
|
|
|
/// Initialize [`ScanService`] based on its config.
|
2023-11-30 13:27:46 -08:00
|
|
|
///
|
|
|
|
/// TODO: add a test for this function.
|
2023-12-03 13:58:48 -08:00
|
|
|
pub async fn init(
|
|
|
|
config: Config,
|
|
|
|
network: Network,
|
|
|
|
state: scan::State,
|
|
|
|
chain_tip_change: ChainTipChange,
|
|
|
|
) -> Result<(), Report> {
|
2024-01-25 17:29:37 -08:00
|
|
|
let scan_service = ServiceBuilder::new().buffer(10).service(ScanService::new(
|
|
|
|
&config,
|
|
|
|
network,
|
|
|
|
state,
|
|
|
|
chain_tip_change,
|
|
|
|
));
|
|
|
|
|
|
|
|
// Start the gRPC server.
|
|
|
|
zebra_grpc::server::init(scan_service).await?;
|
2023-11-30 04:59:15 -08:00
|
|
|
|
2024-01-25 17:29:37 -08:00
|
|
|
Ok(())
|
2023-11-30 04:59:15 -08:00
|
|
|
}
|