-
Notifications
You must be signed in to change notification settings - Fork 120
/
Copy pathstart.rs
112 lines (97 loc) · 3.61 KB
/
start.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
//! `start` subcommand - entry point for starting a zebra node
//!
//! ## Application Structure
//!
//! A zebra node consists of the following services and tasks:
//!
//! * Network Service
//! * primary interface to the node
//! * handles all external network requests for the Zcash protocol
//! * via zebra_network::Message and zebra_network::Response
//! * provides an interface to the rest of the network for other services and
//! tasks running within this node
//! * via zebra_network::Request
//! * Consensus Service
//! * handles all validation logic for the node
//! * verifies blocks using zebra-chain and zebra-script, then stores verified
//! blocks in zebra-state
//! * Sync Task
//! * This task runs in the background and continuously queries the network for
//! new blocks to be verified and added to the local state
use abscissa_core::{config, Command, FrameworkError, Options, Runnable};
use color_eyre::eyre::{eyre, Report};
use tokio::sync::oneshot;
use tower::builder::ServiceBuilder;
use crate::components::{tokio::RuntimeRun, Inbound};
use crate::config::ZebradConfig;
use crate::{
components::{tokio::TokioComponent, ChainSync},
prelude::*,
};
/// `start` subcommand
#[derive(Command, Debug, Options)]
pub struct StartCmd {
/// Filter strings
#[options(free)]
filters: Vec<String>,
}
impl StartCmd {
async fn start(&self) -> Result<(), Report> {
let config = app_config().clone();
info!(?config);
info!("initializing node state");
let state = ServiceBuilder::new().buffer(20).service(zebra_state::init(
config.state.clone(),
config.network.network,
));
info!("initializing chain verifier");
let verifier = zebra_consensus::chain::init(
config.consensus.clone(),
config.network.network,
state.clone(),
)
.await;
info!("initializing network");
// The service that our node uses to respond to requests by peers. The
// load_shed middleware ensures that we reduce the size of the peer set
// in response to excess load.
let (setup_tx, setup_rx) = oneshot::channel();
let inbound = ServiceBuilder::new()
.load_shed()
.buffer(20)
.service(Inbound::new(setup_rx, state.clone(), verifier.clone()));
let (peer_set, address_book) = zebra_network::init(config.network.clone(), inbound).await;
setup_tx
.send((peer_set.clone(), address_book))
.map_err(|_| eyre!("could not send setup data to inbound service"))?;
info!("initializing syncer");
let syncer = ChainSync::new(&config, peer_set, state, verifier);
syncer.sync().await
}
}
impl Runnable for StartCmd {
/// Start the application.
fn run(&self) {
info!("Starting zebrad");
let rt = app_writer()
.state_mut()
.components
.get_downcast_mut::<TokioComponent>()
.expect("TokioComponent should be available")
.rt
.take();
rt.expect("runtime should not already be taken")
.run(self.start());
}
}
impl config::Override<ZebradConfig> for StartCmd {
// Process the given command line options, overriding settings from
// a configuration file using explicit flags taken from command-line
// arguments.
fn override_config(&self, mut config: ZebradConfig) -> Result<ZebradConfig, FrameworkError> {
if !self.filters.is_empty() {
config.tracing.filter = Some(self.filters.join(","));
}
Ok(config)
}
}