massa_final_state/lib.rs
1//! Copyright (c) 2022 MASSA LABS <info@massa.net>
2
3//! # General description
4//!
5//! This crate implements a final state that encompasses a final ledger and asynchronous message pool.
6//! Nodes store only one copy of this final state which is very large
7//! (the copy is attached to the output of the last executed final slot),
8//! and apply speculative changes on it to deduce its value at a non-final slot
9//! (see `massa-execution-exports` crate for more details).
10//! Nodes joining the network need to bootstrap this state.
11//!
12//! # Architecture
13//!
14//! ## `final_state.rs`
15//! Defines the `FinalState` that matches that represents the state of the node at
16//! the latest executed final slot. It contains the final ledger and the asynchronous event pool.
17//! It can be manipulated using `StateChanges` (see `state_changes.rs`).
18//! The `FinalState` is bootstrapped using tooling available in bootstrap.rs
19//!
20//! ## `state_changes.rs`
21//! Represents a list of changes the final state.
22//! It can be modified, combined or applied to the final ledger.
23//!
24//! ## `executed_ops.rs`
25//! Defines a structure to list and prune previously executed operations.
26//! Used to detect operation reuse.
27//!
28//! ## `bootstrap.rs`
29//! Provides serializable structures and tools for bootstrapping the final state.
30//!
31//! ## Test exports
32//!
33//! When the crate feature `test-exports` is enabled, tooling useful for test-exports purposes is exported.
34//! See `test_exports/mod.rs` for details.
35//!
36//! # Network restart documentation
37//!
38//! ## Goals of the network restart
39//! If the blockchain crashes (corrupted / attacked ledger, all nodes crash, etc.) and we want to keep the same main parameters of the network (same `GENESIS_TIMESTAMP`, same ledger, same final_state, etc.), then we can restart the network.
40//!
41//! **ONE** node should restart from a snapshot (which is just the RocksDB ledger, read as usual), and the other nodes should bootstrap from it.
42//!
43//! ## Command line
44//!
45//! ```sh
46//! cargo run --release -- --restart-from-snapshot-at-period 200
47//! ```
48//!
49//! Means: the node will restart from the ledger and final_state on disk (usual path in the config). Block production will start once the period given in args is reached (here, 200).
50//!
51//! ## Scenario
52//!
53//! 1. At period 40, the network crashes.
54//! 2. We restart one node N0, at the time of period 80, with `cargo run --release -- --restart-from-snapshot-at-period 200`
55//! 3. We start one other node N1, at the time of period 100, with `cargo run --release`
56//! 4. The node N1 will bootstrap from N0. No blocks are produced yet.
57//! 5. At the time of period 200, block production starts again.
58//!
59//! ## Additional notes
60//!
61//! ### Why is block production delayed?
62//!
63//! In order to give time to all nodes to rejoin the network after a crash and bootstrap. If we don't give them the time, their rolls would be sold because most stakers would have a lot of block miss.
64//!
65//! ### In sandbox
66//!
67//! Sandbox feature can be enabled. For instance, here is a test scenario:
68//!
69//! 1. Run the node as usual: `cargo run --release --features sandbox`
70//! 2. Make transaction, buy rolls, etc.
71//! 3. Shut down the node at slot S_0.
72//! 4. Restart the network: `cargo run --release --features sandbox --restart-from-snapshot-at-period S_1`
73//!
74//! Here, the network will restart, and the network will start producing blocks again 10 seconds after launch.
75//!
76//! **/!\ This means that the genesis timestamp will be different between runs, but it should not matter in most cases.**
77//!
78//! ### Backups
79//!
80//! By default, the network restarts from the state associated with the last final slot before the shutdown.
81//! However, we may sometimes want to recover from an earlier state (e.g. if an attacker stole 50% of all Massa, we want to restart with the state before the attack.
82//! We use RocksDB checkpoint system to save the state at regular interval (see the `ledger_backup_periods_interval` in the `massa-node` config).
83//! Backups for `Slot {period, thread}` are stored in `massa > massa-node > storage > ledger > rocks_db_backup > backup_[period]_[thread]`
84//! Backups are hard links of the rocks_db, so the overhead of storing them should be minimal.
85//! To recover from a backup, simply replace the contents of the rocks_db folder by the contents of the target backup folder.
86
87#![warn(missing_docs)]
88#![warn(unused_crate_dependencies)]
89// `FinalStateError` is large by design. Boxing it would be an API break, so the
90// lint is silenced crate-wide rather than on each fallible function.
91#![allow(clippy::result_large_err)]
92
93mod config;
94mod controller_trait;
95mod error;
96mod final_state;
97mod mapping_grpc;
98mod state_changes;
99
100pub use config::FinalStateConfig;
101pub use controller_trait::FinalStateController;
102pub use error::FinalStateError;
103pub use final_state::FinalState;
104use num as _;
105pub use state_changes::StateChanges;
106
107#[cfg(feature = "test-exports")]
108pub use controller_trait::MockFinalStateController;
109
110#[cfg(test)]
111mod tests;
112
113#[cfg(feature = "test-exports")]
114pub mod test_exports;