casper_node/
lib.rs

1//! # Casper blockchain node
2//!
3//! This crate contain the core application for the Casper blockchain. Run with `--help` to see
4//! available command-line arguments.
5//!
6//! ## Application structure
7//!
8//! While the [`main`](fn.main.html) function is the central entrypoint for the node application,
9//! its core event loop is found inside the [reactor](reactor/index.html).
10
11#![doc(html_root_url = "https://docs.rs/casper-node/2.0.3")]
12#![doc(
13    html_favicon_url = "https://raw.githubusercontent.com/casper-network/casper-node/blob/dev/images/Casper_Logo_Favicon_48.png",
14    html_logo_url = "https://raw.githubusercontent.com/casper-network/casper-node/blob/dev/images/Casper_Logo_Favicon.png",
15    test(attr(deny(warnings)))
16)]
17#![warn(
18    missing_docs,
19    trivial_casts,
20    trivial_numeric_casts,
21    unused_qualifications
22)]
23#![allow(clippy::bool_comparison)]
24
25pub mod cli;
26pub(crate) mod components;
27mod config_migration;
28mod data_migration;
29pub(crate) mod effect;
30#[cfg_attr(not(feature = "failpoints"), path = "failpoints_disabled.rs")]
31pub(crate) mod failpoints;
32
33pub mod logging;
34pub(crate) mod protocol;
35pub(crate) mod reactor;
36#[cfg(test)]
37pub(crate) mod testing;
38pub(crate) mod tls;
39pub mod types;
40pub mod utils;
41
42use std::{
43    env,
44    sync::{atomic::AtomicUsize, Arc},
45};
46
47use ansi_term::Color::Red;
48use once_cell::sync::Lazy;
49#[cfg(not(test))]
50use rand::SeedableRng;
51use signal_hook::{consts::TERM_SIGNALS, flag};
52use tracing::warn;
53
54pub(crate) use components::{
55    binary_port::Config as BinaryPortConfig, block_accumulator::Config as BlockAccumulatorConfig,
56    block_synchronizer::Config as BlockSynchronizerConfig,
57    block_validator::Config as BlockValidatorConfig, consensus::Config as ConsensusConfig,
58    contract_runtime::Config as ContractRuntimeConfig,
59    diagnostics_port::Config as DiagnosticsPortConfig,
60    event_stream_server::Config as EventStreamServerConfig, fetcher::Config as FetcherConfig,
61    gossiper::Config as GossipConfig, network::Config as NetworkConfig,
62    rest_server::Config as RestServerConfig,
63    transaction_acceptor::Config as TransactionAcceptorConfig,
64    transaction_buffer::Config as TransactionBufferConfig,
65    upgrade_watcher::Config as UpgradeWatcherConfig,
66};
67pub use components::{
68    consensus, contract_runtime,
69    storage::{self, Config as StorageConfig},
70};
71pub use reactor::main_reactor::Config as MainReactorConfig;
72pub(crate) use types::NodeRng;
73pub use utils::WithDir;
74
75/// The maximum thread count which should be spawned by the tokio runtime.
76pub const MAX_THREAD_COUNT: usize = 512;
77
78fn version_string(color: bool) -> String {
79    let mut version = env!("CARGO_PKG_VERSION").to_string();
80    if let Some(git_sha) = option_env!("NODE_GIT_SHA") {
81        version = format!("{}-{}", version, git_sha);
82    } else {
83        warn!(
84            "git sha env var unavailable, casper-node build version will not include git short hash"
85        );
86    }
87
88    // Add a `@DEBUG` (or similar) tag to release string on non-release builds.
89    if env!("NODE_BUILD_PROFILE") != "release" {
90        version += "@";
91        let profile = env!("NODE_BUILD_PROFILE").to_uppercase();
92        version.push_str(&if color {
93            Red.paint(&profile).to_string()
94        } else {
95            profile
96        });
97    }
98
99    version
100}
101
102/// Color version string for the compiled node. Filled in at build time, output allocated at
103/// runtime.
104pub(crate) static VERSION_STRING_COLOR: Lazy<String> = Lazy::new(|| version_string(true));
105
106/// Version string for the compiled node. Filled in at build time, output allocated at runtime.
107pub(crate) static VERSION_STRING: Lazy<String> = Lazy::new(|| version_string(false));
108
109/// Global value that indicates the currently running reactor should exit if it is non-zero.
110pub(crate) static TERMINATION_REQUESTED: Lazy<Arc<AtomicUsize>> =
111    Lazy::new(|| Arc::new(AtomicUsize::new(0)));
112
113/// Setup UNIX signal hooks for current application.
114pub(crate) fn setup_signal_hooks() {
115    for signal in TERM_SIGNALS {
116        flag::register_usize(
117            *signal,
118            Arc::clone(&*TERMINATION_REQUESTED),
119            *signal as usize,
120        )
121        .unwrap_or_else(|error| panic!("failed to register signal {}: {}", signal, error));
122    }
123}
124
125/// Constructs a new `NodeRng`.
126#[cfg(not(test))]
127pub(crate) fn new_rng() -> NodeRng {
128    NodeRng::from_entropy()
129}
130
131/// Constructs a new `NodeRng`.
132#[cfg(test)]
133pub(crate) fn new_rng() -> NodeRng {
134    NodeRng::new()
135}
136
137#[cfg(test)]
138mod tests {
139    use super::*;
140
141    #[test]
142    fn version_string_format() {
143        let string = version_string(false);
144        let (prefix, profile) = string.split_once('@').unwrap_or((string.as_str(), ""));
145        let (version, sha) = prefix.split_once('-').unwrap_or((prefix, ""));
146
147        assert_eq!(version, env!("CARGO_PKG_VERSION"));
148        assert_eq!(sha, env::var("NODE_GIT_SHA").unwrap_or_default().as_str());
149        if env!("NODE_BUILD_PROFILE") == "release" {
150            assert_eq!(profile, "");
151        } else {
152            assert_eq!(profile, env!("NODE_BUILD_PROFILE").to_uppercase())
153        }
154    }
155
156    #[test]
157    fn version_string_color_format() {
158        let string = version_string(true);
159        let (prefix, profile) = string.split_once('@').unwrap_or((string.as_str(), ""));
160        let (version, sha) = prefix.split_once('-').unwrap_or((prefix, ""));
161
162        assert_eq!(version, env!("CARGO_PKG_VERSION"));
163        assert_eq!(sha, env::var("NODE_GIT_SHA").unwrap_or_default().as_str());
164        if env!("NODE_BUILD_PROFILE") == "release" {
165            assert_eq!(profile, "");
166        } else {
167            assert_eq!(
168                profile,
169                Red.paint(env!("NODE_BUILD_PROFILE").to_uppercase())
170                    .to_string()
171            );
172        }
173    }
174}