diff --git a/Cargo.lock b/Cargo.lock index bfeda0b4ea7..168625db7bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2412,6 +2412,7 @@ dependencies = [ "massa_time", "massa_versioning", "massa_wallet", + "num", "parking_lot", "paw", "rand 0.8.5", @@ -2576,6 +2577,7 @@ dependencies = [ "mio", "mockall", "nom", + "num", "num_enum", "parking_lot", "rand 0.8.5", @@ -2804,6 +2806,7 @@ dependencies = [ "massa_time", "massa_versioning", "massa_wallet", + "num", "parking_lot", "tracing", ] @@ -2829,6 +2832,7 @@ dependencies = [ "massa_time", "massa_versioning", "nom", + "num", "parking_lot", "serde", "tempfile", @@ -2859,6 +2863,7 @@ dependencies = [ "massa_time", "massa_versioning", "massa_wallet", + "num", "serde", "thiserror", "tokio", @@ -3103,6 +3108,7 @@ dependencies = [ "massa_time", "massa_versioning", "nom", + "num", "num_enum", "parking_lot", "peernet", diff --git a/massa-bootstrap/Cargo.toml b/massa-bootstrap/Cargo.toml index 0899eb328d0..52fa6d2a549 100644 --- a/massa-bootstrap/Cargo.toml +++ b/massa-bootstrap/Cargo.toml @@ -43,6 +43,7 @@ bitvec = { version = "1.0", features = ["serde"] } lazy_static = "1.4" tempfile = "3.3" serial_test = "2.0.0" +num = "0.4" massa_final_state = { path = "../massa-final-state", features = ["testing"] } massa_async_pool = { path = "../massa-async-pool", features = ["testing"] } massa_ledger_exports = { path = "../massa-ledger-exports" } diff --git a/massa-bootstrap/src/tests/tools.rs b/massa-bootstrap/src/tests/tools.rs index 80164047b46..79fec33a010 100644 --- a/massa-bootstrap/src/tests/tools.rs +++ b/massa-bootstrap/src/tests/tools.rs @@ -58,6 +58,7 @@ use massa_serialization::{DeserializeError, Deserializer, Serializer}; use massa_signature::KeyPair; use massa_time::MassaTime; use massa_versioning::versioning::{MipStatsConfig, MipStore}; +use num::rational::Ratio; use rand::Rng; use std::collections::{HashMap, HashSet}; use std::str::FromStr; @@ -338,6 +339,7 @@ pub fn get_random_final_state_bootstrap( [], MipStatsConfig { block_count_considered: 10, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }, )) .unwrap(); @@ -453,7 +455,7 @@ pub fn get_boot_state() -> BootstrapableGraph { header: BlockHeader::new_verifiable( BlockHeader { current_version: 0, - announced_version: 0, + announced_version: None, // associated slot // all header endorsements are supposed to point towards this one slot: Slot::new(1, 0), diff --git a/massa-consensus-exports/src/export_active_block.rs b/massa-consensus-exports/src/export_active_block.rs index e36dc43df19..823b959aa40 100644 --- a/massa-consensus-exports/src/export_active_block.rs +++ b/massa-consensus-exports/src/export_active_block.rs @@ -175,7 +175,7 @@ impl Deserializer for ExportActiveBlockDeserializer { /// let orig_header = BlockHeader::new_verifiable( /// BlockHeader { /// current_version: 0, - /// announced_version: 0, + /// announced_version: None, /// slot: Slot::new(1, 1), /// parents, /// operation_merkle_root: Hash::compute_from("mno".as_bytes()), diff --git a/massa-consensus-worker/src/tests/tools.rs b/massa-consensus-worker/src/tests/tools.rs index 2a01e6b8696..9dda69d141b 100644 --- a/massa-consensus-worker/src/tests/tools.rs +++ b/massa-consensus-worker/src/tests/tools.rs @@ -147,7 +147,7 @@ pub fn create_block_with_merkle_root( let header = BlockHeader::new_verifiable( BlockHeader { current_version: 0, - announced_version: 0, + announced_version: None, denunciations: vec![], slot, parents: best_parents, diff --git a/massa-consensus-worker/src/worker/init.rs b/massa-consensus-worker/src/worker/init.rs index 41a12efbca9..1253afa768e 100644 --- a/massa-consensus-worker/src/worker/init.rs +++ b/massa-consensus-worker/src/worker/init.rs @@ -45,7 +45,7 @@ pub fn create_genesis_block( // VERSIONNING TODO: what to implement here in case of restart? BlockHeader { current_version: 0, - announced_version: 0, + announced_version: None, slot: Slot::new(cfg.last_start_period, thread_number), parents: Vec::new(), operation_merkle_root: Hash::compute_from(&Vec::new()), diff --git a/massa-execution-exports/src/types.rs b/massa-execution-exports/src/types.rs index 281e2d5891a..94a6f1bc52b 100644 --- a/massa-execution-exports/src/types.rs +++ b/massa-execution-exports/src/types.rs @@ -211,7 +211,7 @@ pub struct ExecutedBlockInfo { /// Current network version (see Versioning doc) pub current_version: u32, /// Announced network version (see Versioning doc) - pub announced_version: u32, + pub announced_version: Option, } /// structure describing the output of a single execution diff --git a/massa-execution-worker/src/interface_impl.rs b/massa-execution-worker/src/interface_impl.rs index 92db72e067e..bf6013b1f2d 100644 --- a/massa-execution-worker/src/interface_impl.rs +++ b/massa-execution-worker/src/interface_impl.rs @@ -18,6 +18,8 @@ use massa_models::{ }; use massa_sc_runtime::RuntimeModule; use massa_sc_runtime::{Interface, InterfaceClone}; +#[cfg(feature = "testing")] +use num::rational::Ratio; use parking_lot::Mutex; use rand::Rng; use sha2::{Digest, Sha256}; @@ -101,6 +103,7 @@ impl InterfaceImpl { // create an empty default store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).expect("Cannot create an empty MIP store"); diff --git a/massa-execution-worker/src/tests/mock.rs b/massa-execution-worker/src/tests/mock.rs index fb7bd0b26b5..a99a6be5d34 100644 --- a/massa-execution-worker/src/tests/mock.rs +++ b/massa-execution-worker/src/tests/mock.rs @@ -24,6 +24,7 @@ use massa_pos_worker::start_selector_worker; use massa_signature::KeyPair; use massa_time::MassaTime; use massa_versioning::versioning::{MipStatsConfig, MipStore}; +use num::rational::Ratio; use parking_lot::RwLock; use std::str::FromStr; use std::{ @@ -117,6 +118,7 @@ pub fn get_sample_state( [], MipStatsConfig { block_count_considered: 10, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }, )) .unwrap(); @@ -172,7 +174,7 @@ pub fn create_block( let header = BlockHeader::new_verifiable( BlockHeader { current_version: 0, - announced_version: 0, + announced_version: None, slot, parents: vec![], operation_merkle_root, diff --git a/massa-execution-worker/src/tests/scenarios_mandatories.rs b/massa-execution-worker/src/tests/scenarios_mandatories.rs index 995aec9b937..30d41f5eeca 100644 --- a/massa-execution-worker/src/tests/scenarios_mandatories.rs +++ b/massa-execution-worker/src/tests/scenarios_mandatories.rs @@ -62,6 +62,7 @@ mod tests { // init the MIP store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); @@ -101,6 +102,7 @@ mod tests { // init the MIP store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); @@ -148,6 +150,7 @@ mod tests { // init the MIP store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); // get a sample final state @@ -258,6 +261,7 @@ mod tests { // init the MIP store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); // get a sample final state @@ -425,6 +429,7 @@ mod tests { // init the MIP store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); // get a sample final state @@ -587,6 +592,7 @@ mod tests { // init the MIP store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); @@ -704,6 +710,7 @@ mod tests { // init the MIP store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); @@ -812,6 +819,7 @@ mod tests { // init the MIP store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); @@ -942,6 +950,7 @@ mod tests { // init the MIP store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); @@ -1061,6 +1070,7 @@ mod tests { // init the MIP store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); @@ -1221,6 +1231,7 @@ mod tests { // init the MIP store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); @@ -1326,6 +1337,7 @@ mod tests { // init the MIP store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); @@ -1446,6 +1458,7 @@ mod tests { // init the MIP store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); @@ -1549,6 +1562,7 @@ mod tests { // init the MIP store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); @@ -1654,6 +1668,7 @@ mod tests { // init the MIP store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); @@ -1865,6 +1880,7 @@ mod tests { // init the MIP store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); @@ -2033,6 +2049,7 @@ mod tests { // init the MIP store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); @@ -2208,6 +2225,7 @@ mod tests { // init the MIP store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); @@ -2303,6 +2321,7 @@ mod tests { // init the MIP store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); @@ -2395,6 +2414,7 @@ mod tests { // init the MIP store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); @@ -2487,6 +2507,7 @@ mod tests { // init the MIP store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); @@ -2640,6 +2661,7 @@ mod tests { // init the MIP store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); @@ -2756,6 +2778,7 @@ mod tests { // init the MIP store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); @@ -2907,6 +2930,7 @@ mod tests { // init the MIP store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); // init the storage @@ -3008,6 +3032,7 @@ mod tests { // init the MIP store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); // init the storage diff --git a/massa-factory-exports/src/test_exports/tools.rs b/massa-factory-exports/src/test_exports/tools.rs index fa27485cf31..8474c806a13 100644 --- a/massa-factory-exports/src/test_exports/tools.rs +++ b/massa-factory-exports/src/test_exports/tools.rs @@ -12,7 +12,7 @@ pub fn create_empty_block(keypair: &KeyPair, slot: &Slot) -> SecureShareBlock { let header = BlockHeader::new_verifiable( BlockHeader { current_version: 0, - announced_version: 0, + announced_version: None, slot: *slot, parents: Vec::new(), operation_merkle_root: Hash::compute_from(&Vec::new()), diff --git a/massa-factory-worker/Cargo.toml b/massa-factory-worker/Cargo.toml index a29ea5df486..bd56b9002b1 100644 --- a/massa-factory-worker/Cargo.toml +++ b/massa-factory-worker/Cargo.toml @@ -24,6 +24,7 @@ massa_pool_exports = { path = "../massa-pool-exports" } massa_versioning = { path = "../massa-versioning" } [dev-dependencies] +num = "0.4" massa_protocol_exports = { path = "../massa-protocol-exports", features=["testing"] } massa_consensus_exports = { path = "../massa-consensus-exports", features = ["testing"] } massa_factory_exports = { path = "../massa-factory-exports", features=["testing"] } diff --git a/massa-factory-worker/src/tests/tools.rs b/massa-factory-worker/src/tests/tools.rs index 7a027e2148f..7ed37259563 100644 --- a/massa-factory-worker/src/tests/tools.rs +++ b/massa-factory-worker/src/tests/tools.rs @@ -5,6 +5,7 @@ use massa_consensus_exports::test_exports::{ use massa_models::config::MIP_STORE_STATS_BLOCK_CONSIDERED; use massa_versioning::versioning::MipStatsConfig; use massa_versioning::versioning::MipStore; +use num::rational::Ratio; use parking_lot::RwLock; use std::{sync::Arc, thread::sleep, time::Duration}; @@ -83,6 +84,7 @@ impl TestFactory { // create an empty default store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).expect("Cannot create an empty MIP store"); diff --git a/massa-final-state/Cargo.toml b/massa-final-state/Cargo.toml index ab44e0e5dc8..f0d76c6a27c 100644 --- a/massa-final-state/Cargo.toml +++ b/massa-final-state/Cargo.toml @@ -11,6 +11,7 @@ nom = "=7.1" bs58 = { version = "0.4", features = ["check"] } thiserror = "1.0" tracing = "0.1" +num = "0.4" # custom modules massa_ledger_exports = { path = "../massa-ledger-exports" } diff --git a/massa-final-state/src/lib.rs b/massa-final-state/src/lib.rs index 4a87a2b5778..ce80ba4fc78 100644 --- a/massa-final-state/src/lib.rs +++ b/massa-final-state/src/lib.rs @@ -99,6 +99,7 @@ mod state_changes; pub use config::FinalStateConfig; pub use error::FinalStateError; pub use final_state::FinalState; +use num as _; pub use state_changes::{StateChanges, StateChangesDeserializer, StateChangesSerializer}; #[cfg(test)] diff --git a/massa-final-state/src/test_exports/config.rs b/massa-final-state/src/test_exports/config.rs index 7fc8e4f3357..e19dab417b3 100644 --- a/massa-final-state/src/test_exports/config.rs +++ b/massa-final-state/src/test_exports/config.rs @@ -4,6 +4,8 @@ use std::path::PathBuf; +use num::rational::Ratio; + use crate::{FinalState, FinalStateConfig}; use massa_async_pool::{AsyncPool, AsyncPoolConfig}; use massa_db_exports::ShareableMassaDBController; @@ -41,6 +43,7 @@ impl FinalState { [], MipStatsConfig { block_count_considered: 10, + warn_announced_version_ratio: Ratio::new(30, 100), }, )) .unwrap(), diff --git a/massa-final-state/src/tests/scenarios.rs b/massa-final-state/src/tests/scenarios.rs index bc2c71b99bf..ace75f0b66d 100644 --- a/massa-final-state/src/tests/scenarios.rs +++ b/massa-final-state/src/tests/scenarios.rs @@ -105,6 +105,7 @@ fn create_final_state(temp_dir: &TempDir, reset_final_state: bool) -> Arc Arc, dst: impl AsRef) -> io::Result<()> { diff --git a/massa-grpc/Cargo.toml b/massa-grpc/Cargo.toml index c7e362b9f94..b3735bb5a62 100644 --- a/massa-grpc/Cargo.toml +++ b/massa-grpc/Cargo.toml @@ -41,5 +41,6 @@ massa_serialization = { path = "../massa-serialization" } massa_versioning = { path = "../massa-versioning" } [dev-dependencies] +num = "0.4" massa_consensus_exports = { path = "../massa-consensus-exports", features = ["testing"] } massa_channel = { path = "../massa-channel" } diff --git a/massa-grpc/src/tests/test.rs b/massa-grpc/src/tests/test.rs index 287a207a66e..7081eb79c39 100644 --- a/massa-grpc/src/tests/test.rs +++ b/massa-grpc/src/tests/test.rs @@ -19,6 +19,7 @@ use massa_pos_exports::test_exports::MockSelectorController; use massa_proto_rs::massa::api::v1::massa_service_client::MassaServiceClient; use massa_protocol_exports::MockProtocolController; use massa_versioning::versioning::{MipStatsConfig, MipStore}; +use num::rational::Ratio; use std::{ net::{IpAddr, Ipv4Addr, SocketAddr}, path::PathBuf, @@ -99,6 +100,7 @@ async fn test_start_grpc_server() { let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); diff --git a/massa-models/src/block.rs b/massa-models/src/block.rs index 67b460d7db5..5cf973db17f 100644 --- a/massa-models/src/block.rs +++ b/massa-models/src/block.rs @@ -159,7 +159,7 @@ impl Serializer for BlockSerializer { /// let orig_header = BlockHeader::new_verifiable( /// BlockHeader { /// current_version: 0, - /// announced_version: 0, + /// announced_version: None, /// slot: Slot::new(1, 1), /// parents, /// operation_merkle_root: Hash::compute_from("mno".as_bytes()), @@ -262,7 +262,7 @@ impl Deserializer for BlockDeserializer { /// let orig_header = BlockHeader::new_verifiable( /// BlockHeader { /// current_version: 0, - /// announced_version: 0, + /// announced_version: None, /// slot: Slot::new(1, 1), /// parents: parents.clone(), /// operation_merkle_root: Hash::compute_from("mno".as_bytes()), @@ -476,7 +476,7 @@ mod test { let orig_header = BlockHeader::new_verifiable( BlockHeader { current_version: 0, - announced_version: 0, + announced_version: None, slot: Slot::new(1, 0), parents, operation_merkle_root: Hash::compute_from("mno".as_bytes()), @@ -560,7 +560,7 @@ mod test { let orig_header = BlockHeader::new_verifiable( BlockHeader { current_version: 0, - announced_version: 0, + announced_version: None, slot: Slot::new(0, 1), parents, operation_merkle_root: Hash::compute_from("mno".as_bytes()), @@ -648,7 +648,7 @@ mod test { let orig_header = BlockHeader::new_verifiable( BlockHeader { current_version: 0, - announced_version: 0, + announced_version: None, slot: Slot::new(0, 1), parents, operation_merkle_root: Hash::compute_from("mno".as_bytes()), @@ -710,7 +710,7 @@ mod test { let orig_header = BlockHeader::new_verifiable( BlockHeader { current_version: 0, - announced_version: 0, + announced_version: None, slot: Slot::new(0, 1), parents, operation_merkle_root: Hash::compute_from("mno".as_bytes()), @@ -762,7 +762,7 @@ mod test { let orig_header = BlockHeader::new_verifiable( BlockHeader { current_version: 0, - announced_version: 0, + announced_version: None, slot: Slot::new(1, 1), parents: vec![], operation_merkle_root: Hash::compute_from("mno".as_bytes()), @@ -817,7 +817,7 @@ mod test { let orig_header = BlockHeader::new_verifiable( BlockHeader { current_version: 0, - announced_version: 0, + announced_version: None, slot: Slot::new(1, 1), parents, operation_merkle_root: Hash::compute_from("mno".as_bytes()), @@ -894,7 +894,7 @@ mod test { let orig_header = BlockHeader::new_verifiable( BlockHeader { current_version: 0, - announced_version: 0, + announced_version: None, slot: Slot::new(1, 0), parents, operation_merkle_root: Hash::compute_from("mno".as_bytes()), @@ -951,7 +951,7 @@ mod test { let orig_header = BlockHeader::new_verifiable( BlockHeader { current_version: 0, - announced_version: 0, + announced_version: None, slot: Slot::new(1, 1), parents, operation_merkle_root: Hash::compute_from("mno".as_bytes()), @@ -1020,7 +1020,7 @@ mod test { let orig_header = BlockHeader::new_verifiable( BlockHeader { current_version: 0, - announced_version: 0, + announced_version: None, slot: Slot::new(1, 1), parents, operation_merkle_root: Hash::compute_from("mno".as_bytes()), @@ -1094,7 +1094,7 @@ mod test { let orig_header = BlockHeader::new_verifiable( BlockHeader { current_version: 0, - announced_version: 0, + announced_version: None, slot: Slot::new(1, 0), parents, operation_merkle_root: Hash::compute_from("mno".as_bytes()), @@ -1180,7 +1180,7 @@ mod test { let orig_header = BlockHeader::new_verifiable( BlockHeader { current_version: 0, - announced_version: 0, + announced_version: None, slot: Slot::new(1, 0), parents, operation_merkle_root: Hash::compute_from("mno".as_bytes()), diff --git a/massa-models/src/block_header.rs b/massa-models/src/block_header.rs index e0204ca5a03..d9fd73a0f51 100644 --- a/massa-models/src/block_header.rs +++ b/massa-models/src/block_header.rs @@ -10,7 +10,8 @@ use crate::secure_share::{ use crate::slot::{Slot, SlotDeserializer, SlotSerializer}; use massa_hash::{Hash, HashDeserializer}; use massa_serialization::{ - Deserializer, SerializeError, Serializer, U32VarIntDeserializer, U32VarIntSerializer, + Deserializer, OptionDeserializer, OptionSerializer, SerializeError, Serializer, + U32VarIntDeserializer, U32VarIntSerializer, }; use massa_signature::PublicKey; use nom::branch::alt; @@ -30,7 +31,7 @@ pub struct BlockHeader { /// current network version pub current_version: u32, /// announced network version - pub announced_version: u32, + pub announced_version: Option, /// slot pub slot: Slot, /// parents @@ -139,6 +140,7 @@ pub struct BlockHeaderSerializer { endorsement_content_serializer: EndorsementSerializerLW, denunciation_serializer: DenunciationSerializer, u32_serializer: U32VarIntSerializer, + opt_serializer: OptionSerializer, } impl BlockHeaderSerializer { @@ -148,6 +150,7 @@ impl BlockHeaderSerializer { slot_serializer: SlotSerializer::new(), endorsement_serializer: SecureShareSerializer::new(), u32_serializer: U32VarIntSerializer::new(), + opt_serializer: OptionSerializer::new(U32VarIntSerializer), endorsement_content_serializer: EndorsementSerializerLW::new(), denunciation_serializer: DenunciationSerializer::new(), } @@ -177,7 +180,7 @@ impl Serializer for BlockHeaderSerializer { /// .collect(); /// let header = BlockHeader { /// current_version: 0, - /// announced_version: 0, + /// announced_version: None, /// slot: Slot::new(1, 1), /// parents, /// operation_merkle_root: Hash::compute_from("mno".as_bytes()), @@ -212,7 +215,7 @@ impl Serializer for BlockHeaderSerializer { // network versions self.u32_serializer .serialize(&value.current_version, buffer)?; - self.u32_serializer + self.opt_serializer .serialize(&value.announced_version, buffer)?; // slot @@ -272,6 +275,7 @@ pub struct BlockHeaderDeserializer { denunciation_len_deserializer: U32VarIntDeserializer, denunciation_deserializer: DenunciationDeserializer, network_versions_deserializer: U32VarIntDeserializer, + opt_deserializer: OptionDeserializer, } impl BlockHeaderDeserializer { @@ -302,6 +306,10 @@ impl BlockHeaderDeserializer { Included(0), Included(u32::MAX), ), + opt_deserializer: OptionDeserializer::new(U32VarIntDeserializer::new( + Included(0), + Included(u32::MAX), + )), denunciation_deserializer: DenunciationDeserializer::new( thread_count, endorsement_count, @@ -330,7 +338,7 @@ impl Deserializer for BlockHeaderDeserializer { /// .collect(); /// let header = BlockHeader { /// current_version: 0, - /// announced_version: 0, + /// announced_version: None, /// slot: Slot::new(1, 1), /// parents: parents.clone(), /// operation_merkle_root: Hash::compute_from("mno".as_bytes()), @@ -373,14 +381,14 @@ impl Deserializer for BlockHeaderDeserializer { ) -> IResult<&'a [u8], BlockHeader, E> { let (rest, (current_version, announced_version, slot, parents, operation_merkle_root)): ( &[u8], - (u32, u32, Slot, Vec, Hash), + (u32, Option, Slot, Vec, Hash), ) = context("Failed BlockHeader deserialization", |input| { let (rest, (current_version, announced_version, slot, parents)) = tuple(( context("Failed current_version deserialization", |input| { self.network_versions_deserializer.deserialize(input) }), context("Failed announced_version deserialization", |input| { - self.network_versions_deserializer.deserialize(input) + self.opt_deserializer.deserialize(input) }), context("Failed slot deserialization", |input| { self.slot_deserializer.deserialize(input) @@ -645,7 +653,7 @@ mod test { let block_header_1 = BlockHeader { current_version: 0, - announced_version: 0, + announced_version: None, slot, parents: parents_1, operation_merkle_root: Hash::compute_from("mno".as_bytes()), diff --git a/massa-models/src/test_exports/data.rs b/massa-models/src/test_exports/data.rs index a01a31eab9e..df1bf95b2a2 100644 --- a/massa-models/src/test_exports/data.rs +++ b/massa-models/src/test_exports/data.rs @@ -88,7 +88,7 @@ pub fn gen_block_headers_for_denunciation( let block_header_1 = BlockHeader { current_version: 0, - announced_version: 0, + announced_version: None, slot, parents: parents_1, operation_merkle_root: Hash::compute_from("mno".as_bytes()), @@ -106,7 +106,7 @@ pub fn gen_block_headers_for_denunciation( let block_header_2 = BlockHeader { current_version: 0, - announced_version: 0, + announced_version: None, slot, parents: parents_2, operation_merkle_root: Hash::compute_from("mno".as_bytes()), @@ -124,7 +124,7 @@ pub fn gen_block_headers_for_denunciation( let block_header_3 = BlockHeader { current_version: 0, - announced_version: 0, + announced_version: None, slot, parents: parents_3, operation_merkle_root: Hash::compute_from("mno".as_bytes()), diff --git a/massa-node/Cargo.toml b/massa-node/Cargo.toml index 5f61dfa59b6..b28c6ff6a48 100644 --- a/massa-node/Cargo.toml +++ b/massa-node/Cargo.toml @@ -13,6 +13,7 @@ lazy_static = "1.4" parking_lot = { version = "0.12", features = ["deadlock_detection"] } serde = { version = "1.0", features = ["derive"] } tokio = { version = "1.23", features = ["full"] } +num = "0.4" tracing = { version = "0.1", features = [ "max_level_debug", "release_max_level_debug", diff --git a/massa-node/base_config/config.toml b/massa-node/base_config/config.toml index 40813ae6ba9..e31a846c7d3 100644 --- a/massa-node/base_config/config.toml +++ b/massa-node/base_config/config.toml @@ -309,3 +309,7 @@ staking_wallet_path = "config/staking_wallet.dat" # stop or not the production in case we are not connected to anyone stop_production_when_zero_connections = true + +[versioning] + # Warn user to update its node if we reach this percentage for announced network versions + mip_stats_warn_announced_version = 30 diff --git a/massa-node/src/main.rs b/massa-node/src/main.rs index 934be7ffbb3..895ccec36f8 100644 --- a/massa-node/src/main.rs +++ b/massa-node/src/main.rs @@ -87,6 +87,7 @@ use massa_time::MassaTime; use massa_versioning::mips::get_mip_list; use massa_versioning::versioning::{MipStatsConfig, MipStore}; use massa_wallet::Wallet; +use num::rational::Ratio; use parking_lot::RwLock; use std::collections::HashMap; use std::path::PathBuf; @@ -277,7 +278,12 @@ async fn launch( // Creates an empty default store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new( + u64::from(SETTINGS.versioning.mip_stats_warn_announced_version), + 100, + ), }; + // Ratio::new_raw(*SETTINGS.versioning.warn_announced_version_ratio, 100), let mip_list = get_mip_list(); debug!("MIP list: {:?}", mip_list); diff --git a/massa-node/src/settings.rs b/massa-node/src/settings.rs index 660e8a5cb31..1ffb857bd6c 100644 --- a/massa-node/src/settings.rs +++ b/massa-node/src/settings.rs @@ -138,6 +138,7 @@ pub struct Settings { pub factory: FactorySettings, pub grpc: GrpcSettings, pub metrics: MetricsSettings, + pub versioning: VersioningSettings, } /// Consensus configuration @@ -316,6 +317,12 @@ pub struct GrpcSettings { pub client_certificate_authority_root_path: PathBuf, } +#[derive(Debug, Deserialize, Clone)] +pub struct VersioningSettings { + // Warn user to update its node if we reach this percentage for announced network versions + pub(crate) mip_stats_warn_announced_version: u32, +} + #[cfg(test)] #[test] fn test_load_node_config() { diff --git a/massa-pool-worker/src/denunciation_pool.rs b/massa-pool-worker/src/denunciation_pool.rs index 9e7818b17e2..330b245eb7e 100644 --- a/massa-pool-worker/src/denunciation_pool.rs +++ b/massa-pool-worker/src/denunciation_pool.rs @@ -317,7 +317,7 @@ mod tests { let de_status_iter = (1..bound_1).map(|i| { let block_header_1 = BlockHeader { current_version: 0, - announced_version: 0, + announced_version: None, slot: Slot::new(i, 0), parents: vec![], operation_merkle_root: Hash::compute_from("mno".as_bytes()), diff --git a/massa-protocol-exports/src/error.rs b/massa-protocol-exports/src/error.rs index b98a2231db2..ff612f9ddf4 100644 --- a/massa-protocol-exports/src/error.rs +++ b/massa-protocol-exports/src/error.rs @@ -43,13 +43,20 @@ pub enum ProtocolError { InvalidOperationError(String), /// Listener error: {0} ListenerError(String), - /// Incompatible newtork version: local current is {local} received is {received} + /// Incompatible network version: local current is {local} received is {received} IncompatibleNetworkVersion { /// local current version local: u32, - /// received version from incoming header + /// received current network version from incoming header received: u32, }, + /// Invalid announced network version + OutdatedAnnouncedNetworkVersion { + /// local current version + local: u32, + /// received announced network version + announced_received: u32, + }, /// Versioned factory error: {0} FactoryError(#[from] FactoryError), /// PoS error: {0} diff --git a/massa-protocol-exports/src/test_exports/tools.rs b/massa-protocol-exports/src/test_exports/tools.rs index eba78ff387f..83fffd65841 100644 --- a/massa-protocol-exports/src/test_exports/tools.rs +++ b/massa-protocol-exports/src/test_exports/tools.rs @@ -23,7 +23,7 @@ pub fn create_block(keypair: &KeyPair) -> SecureShareBlock { let header = BlockHeader::new_verifiable( BlockHeader { current_version: 0, - announced_version: 0, + announced_version: None, slot: Slot::new(1, 0), parents: vec![ BlockId(Hash::compute_from("Genesis 0".as_bytes())), @@ -67,7 +67,7 @@ pub fn create_block_with_operations( let header = BlockHeader::new_verifiable( BlockHeader { current_version: 0, - announced_version: 0, + announced_version: None, slot, parents: vec![ BlockId(Hash::compute_from("Genesis 0".as_bytes())), @@ -107,7 +107,7 @@ pub fn create_block_with_endorsements( let header = BlockHeader::new_verifiable( BlockHeader { current_version: 0, - announced_version: 0, + announced_version: None, slot, parents: vec![ BlockId(Hash::compute_from("Genesis 0".as_bytes())), diff --git a/massa-protocol-worker/Cargo.toml b/massa-protocol-worker/Cargo.toml index 7eb3dd01b54..76bfbf8856b 100644 --- a/massa-protocol-worker/Cargo.toml +++ b/massa-protocol-worker/Cargo.toml @@ -37,6 +37,7 @@ massa_versioning = { path = "../massa-versioning" } [dev-dependencies] tempfile = "3.3" serial_test = "2.0.0" +num = "0.4" [features] testing = ["massa_protocol_exports/testing", "tempfile", "massa_pool_exports/testing", "massa_consensus_exports/testing", "massa_metrics/testing"] diff --git a/massa-protocol-worker/src/handlers/block_handler/retrieval.rs b/massa-protocol-worker/src/handlers/block_handler/retrieval.rs index 6a7d05a7d90..c6033655597 100644 --- a/massa-protocol-worker/src/handlers/block_handler/retrieval.rs +++ b/massa-protocol-worker/src/handlers/block_handler/retrieval.rs @@ -456,13 +456,24 @@ impl RetrievalThread { self.config.genesis_timestamp, slot, )?; - let version = self.mip_store.get_network_version_active_at(ts); - if header.content.current_version != version { + let current_version = self.mip_store.get_network_version_active_at(ts); + if header.content.current_version != current_version { + // Received a current version different from current version (given by mip store) Err(ProtocolError::IncompatibleNetworkVersion { - local: version, + local: current_version, received: header.content.current_version, }) } else { + if let Some(announced_version) = header.content.announced_version { + if announced_version <= current_version { + // Received an announced network version that is already known + return Err(ProtocolError::OutdatedAnnouncedNetworkVersion { + local: current_version, + announced_received: announced_version, + }); + } + } + Ok(()) } } diff --git a/massa-protocol-worker/src/tests/context.rs b/massa-protocol-worker/src/tests/context.rs index e2830db5129..94de2a35f9d 100644 --- a/massa-protocol-worker/src/tests/context.rs +++ b/massa-protocol-worker/src/tests/context.rs @@ -29,6 +29,7 @@ use massa_serialization::U64VarIntDeserializer; use massa_signature::KeyPair; use massa_storage::Storage; use massa_versioning::versioning::{MipStatsConfig, MipStore}; +use num::rational::Ratio; use parking_lot::RwLock; use std::ops::Bound::Included; use tracing::{debug, log::warn}; @@ -103,6 +104,7 @@ pub fn start_protocol_controller_with_mock_network( let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); diff --git a/massa-protocol-worker/src/tests/mod.rs b/massa-protocol-worker/src/tests/mod.rs index 02d271c9475..7c6cff2fc89 100644 --- a/massa-protocol-worker/src/tests/mod.rs +++ b/massa-protocol-worker/src/tests/mod.rs @@ -1,3 +1,4 @@ +use num::rational::Ratio; use std::{collections::HashMap, fs::read_to_string, time::Duration}; use massa_consensus_exports::test_exports::ConsensusControllerImpl; @@ -133,6 +134,7 @@ fn basic() { // Setup the MIP store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); @@ -280,6 +282,7 @@ fn stop_with_controller_still_exists() { // Setup the MIP store let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)).unwrap(); let metrics = MassaMetrics::new( diff --git a/massa-serialization/src/lib.rs b/massa-serialization/src/lib.rs index f9483226513..60f5778d575 100644 --- a/massa-serialization/src/lib.rs +++ b/massa-serialization/src/lib.rs @@ -306,7 +306,7 @@ where T: Clone, DT: Deserializer, { - pub fn new(data_deserializer: DT) -> Self { + pub const fn new(data_deserializer: DT) -> Self { OptionDeserializer { data_deserializer, phantom_t: std::marker::PhantomData, diff --git a/massa-versioning/src/versioning.rs b/massa-versioning/src/versioning.rs index a4fee1b873d..5638cd5521d 100644 --- a/massa-versioning/src/versioning.rs +++ b/massa-versioning/src/versioning.rs @@ -9,7 +9,7 @@ use num::{rational::Ratio, Zero}; use num_enum::{FromPrimitive, IntoPrimitive, TryFromPrimitive}; use parking_lot::RwLock; use thiserror::Error; -use tracing::debug; +use tracing::{debug, warn}; use massa_db_exports::{ DBBatch, ShareableMassaDBController, MIP_STORE_PREFIX, MIP_STORE_STATS_PREFIX, STATE_CF, @@ -555,30 +555,25 @@ impl MipStore { /// Retrieve the network version number to announce in block header /// return 0 is there is nothing to announce - pub fn get_network_version_to_announce(&self) -> u32 { + pub fn get_network_version_to_announce(&self) -> Option { let lock = self.0.read(); let store = lock.deref(); // Announce the latest versioning info in Started / LockedIn state // Defined == Not yet ready to announce // Active == current version - store - .store - .iter() - .rev() - .find_map(|(k, v)| { - matches!( - &v.state, - &ComponentState::Started(_) | &ComponentState::LockedIn(_) - ) - .then_some(k.version) - }) - .unwrap_or(0) + store.store.iter().rev().find_map(|(k, v)| { + matches!( + &v.state, + &ComponentState::Started(_) | &ComponentState::LockedIn(_) + ) + .then_some(k.version) + }) } pub fn update_network_version_stats( &mut self, slot_timestamp: MassaTime, - network_versions: Option<(u32, u32)>, + network_versions: Option<(u32, Option)>, ) { let mut lock = self.0.write(); lock.update_network_version_stats(slot_timestamp, network_versions); @@ -680,12 +675,13 @@ impl TryFrom<([(MipInfo, MipState); N], MipStatsConfig)> for Mip #[derive(Debug, Clone, PartialEq)] pub struct MipStatsConfig { pub block_count_considered: usize, + pub warn_announced_version_ratio: Ratio, } /// In order for a MIP to be accepted, we compute statistics about other node 'network' version announcement #[derive(Debug, Clone, PartialEq)] pub(crate) struct MipStoreStats { - // config for max counters + block to consider when computing the vote ratio + // config for block count to consider when computing the vote ratio pub(crate) config: MipStatsConfig, // Last network version announcements (in last block header) // Used to clean up the field: network_version_counters (pop the oldest then subtract matching counter) @@ -879,9 +875,11 @@ impl MipStoreRaw { fn update_network_version_stats( &mut self, slot_timestamp: MassaTime, - network_versions: Option<(u32, u32)>, + network_versions: Option<(u32, Option)>, ) { - if let Some((_current_network_version, announced_network_version)) = network_versions { + if let Some((_current_network_version, announced_network_version_)) = network_versions { + let announced_network_version = announced_network_version_.unwrap_or(0); + let removed_version_ = match self.stats.latest_announcements.len() { n if n >= self.stats.config.block_count_considered => { self.stats.latest_announcements.pop_front() @@ -893,7 +891,8 @@ impl MipStoreRaw { .push_back(announced_network_version); // We update the count of the received version (example: update counter for version 1) - self.stats + let mut network_version_count = *self + .stats .network_version_counters .entry(announced_network_version) .and_modify(|v| *v = v.saturating_add(1)) @@ -908,11 +907,36 @@ impl MipStoreRaw { { let entry_value = e.get_mut(); *entry_value = entry_value.saturating_sub(1); + network_version_count = *entry_value; if *entry_value == 0 { self.stats.network_version_counters.remove(&removed_version); } } } + + if announced_network_version != 0 { + let vote_ratio = Ratio::new( + network_version_count, + self.stats.config.block_count_considered as u64, + ); + + if vote_ratio > self.stats.config.warn_announced_version_ratio { + let last_key_value = self.store.last_key_value(); + if let Some((mi, _ms)) = last_key_value { + if announced_network_version > mi.version { + // Vote ratio is > 30% + // announced version is not known (not in MIP store) + // announced version is > to the last known network version in MIP store + // -> Warn the user to update + warn!("{} our of {} last blocks advertised that they are willing to transition to version {}. You should update your node if you wish to move to that version.", + network_version_count, + self.stats.config.block_count_considered, + announced_network_version + ); + } + } + } + } } debug!( @@ -1177,8 +1201,10 @@ impl MipStoreRaw { ) -> Result<(Vec, BTreeMap), ExtendFromDbError> { let mip_info_deser = MipInfoDeserializer::new(); let mip_state_deser = MipStateDeserializer::new(); - let mip_store_stats_deser = - MipStoreStatsDeserializer::new(MIP_STORE_STATS_BLOCK_CONSIDERED); + let mip_store_stats_deser = MipStoreStatsDeserializer::new( + MIP_STORE_STATS_BLOCK_CONSIDERED, + self.stats.config.warn_announced_version_ratio, + ); let db = db.read(); @@ -1211,6 +1237,10 @@ impl MipStoreRaw { stats: MipStoreStats { config: MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: self + .stats + .config + .warn_announced_version_ratio, }, latest_announcements: Default::default(), network_version_counters: Default::default(), @@ -1260,6 +1290,10 @@ impl MipStoreRaw { stats: MipStoreStats { config: MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: self + .stats + .config + .warn_announced_version_ratio, }, latest_announcements: Default::default(), network_version_counters: Default::default(), @@ -1580,6 +1614,7 @@ mod test { // TODO: Have VersioningStore::from ? let mip_stats_cfg = MipStatsConfig { block_count_considered: 10, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let vs_raw = MipStoreRaw { store: BTreeMap::from([(mi.clone(), vs_1), (mi_2.clone(), vs_2)]), @@ -1589,7 +1624,7 @@ mod test { let vs = MipStore(Arc::new(RwLock::new(vs_raw))); assert_eq!(vs.get_network_version_current(), mi.version); - assert_eq!(vs.get_network_version_to_announce(), mi_2.version); + assert_eq!(vs.get_network_version_to_announce(), Some(mi_2.version)); // Test also an empty versioning store let vs_raw = MipStoreRaw { @@ -1598,7 +1633,7 @@ mod test { }; let vs = MipStore(Arc::new(RwLock::new(vs_raw))); assert_eq!(vs.get_network_version_current(), 0); - assert_eq!(vs.get_network_version_to_announce(), 0); + assert_eq!(vs.get_network_version_to_announce(), None); } #[test] @@ -1704,6 +1739,7 @@ mod test { let mip_stats_cfg = MipStatsConfig { block_count_considered: 10, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mut vs_raw_1 = MipStoreRaw::try_from(( [(vi_1.clone(), vs_1.clone()), (vi_2.clone(), vs_2.clone())], @@ -1763,6 +1799,7 @@ mod test { let mip_stats_cfg = MipStatsConfig { block_count_considered: 10, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; // case 1 @@ -1840,6 +1877,7 @@ mod test { // part 0 - defines data for the test let mip_stats_cfg = MipStatsConfig { block_count_considered: 10, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mi_1 = MipInfo { name: "MIP-0002".to_string(), @@ -1890,6 +1928,7 @@ mod test { let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_store = MipStore::try_from(([], mip_stats_config)); @@ -1903,6 +1942,7 @@ mod test { // data let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mut mip_store_raw_1 = MipStoreRaw::try_from(([], mip_stats_config.clone())).unwrap(); @@ -1990,6 +2030,7 @@ mod test { let mip_stats_cfg = MipStatsConfig { block_count_considered: 10, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mut mi_1 = MipInfo { name: "MIP-0002".to_string(), @@ -2116,7 +2157,7 @@ mod test { // Update stats - so should force transitions if any store.update_network_version_stats( get_slot_ts(shutdown_end.get_next_slot(THREAD_COUNT).unwrap()), - Some((1, 0)), + Some((1, None)), ); let (first_mi_info, first_mi_state) = store.store.first_key_value().unwrap(); @@ -2188,6 +2229,7 @@ mod test { let mip_stats_config = MipStatsConfig { block_count_considered: MIP_STORE_STATS_BLOCK_CONSIDERED, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mut mip_store = MipStore::try_from(( [(mi_1.clone(), ms_1.clone()), (mi_2.clone(), ms_2.clone())], @@ -2284,6 +2326,7 @@ mod test { let mip_stats_config = MipStatsConfig { block_count_considered: 2, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let activation_delay = MassaTime::from_millis(100); let timeout = MassaTime::now() @@ -2303,11 +2346,11 @@ mod test { MipStoreRaw::try_from(([(mi_1.clone(), ms_1)], mip_stats_config)).unwrap(); // Current network version is 0, next one is 1 - mip_store.update_network_version_stats(get_slot_ts(Slot::new(1, 0)), Some((0, 1))); + mip_store.update_network_version_stats(get_slot_ts(Slot::new(1, 0)), Some((0, Some(1)))); assert_eq!(mip_store.stats.network_version_counters.len(), 1); assert_eq!(mip_store.stats.network_version_counters.get(&1), Some(&1)); - mip_store.update_network_version_stats(get_slot_ts(Slot::new(1, 0)), Some((0, 1))); + mip_store.update_network_version_stats(get_slot_ts(Slot::new(1, 0)), Some((0, Some(1)))); assert_eq!(mip_store.stats.network_version_counters.len(), 1); assert_eq!(mip_store.stats.network_version_counters.get(&1), Some(&2)); @@ -2324,7 +2367,7 @@ mod test { ); // Now network version is 1, next one is 2 - mip_store.update_network_version_stats(get_slot_ts(Slot::new(1, 0)), Some((1, 2))); + mip_store.update_network_version_stats(get_slot_ts(Slot::new(1, 0)), Some((1, Some(2)))); // Counter for announced version: 1 & 2 assert_eq!(mip_store.stats.network_version_counters.len(), 2); // First announced version 1 was removed and so the counter decremented diff --git a/massa-versioning/src/versioning_factory.rs b/massa-versioning/src/versioning_factory.rs index 8a853929401..bf90935d9b8 100644 --- a/massa-versioning/src/versioning_factory.rs +++ b/massa-versioning/src/versioning_factory.rs @@ -169,6 +169,7 @@ pub trait VersioningFactory { mod test { use super::*; + use num::rational::Ratio; use std::collections::BTreeMap; use crate::test_helpers::versioning_helpers::advance_state_until; @@ -296,6 +297,7 @@ mod test { let mip_stats_cfg = MipStatsConfig { block_count_considered: 10, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let vs = MipStore::try_from(( @@ -386,6 +388,7 @@ mod test { let mip_stats_cfg = MipStatsConfig { block_count_considered: 10, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let vs = MipStore::try_from(( diff --git a/massa-versioning/src/versioning_ser_der.rs b/massa-versioning/src/versioning_ser_der.rs index 9d84132a7ea..8fe3e5a76a1 100644 --- a/massa-versioning/src/versioning_ser_der.rs +++ b/massa-versioning/src/versioning_ser_der.rs @@ -9,6 +9,7 @@ use nom::{ sequence::tuple, IResult, Parser, }; +use num::rational::Ratio; use crate::versioning::{ Active, Advance, ComponentState, ComponentStateTypeId, LockedIn, MipComponent, MipInfo, @@ -680,10 +681,11 @@ pub struct MipStoreStatsDeserializer { impl MipStoreStatsDeserializer { /// Creates a new `` - pub fn new(block_count_considered: usize) -> Self { + pub fn new(block_count_considered: usize, warn_announced_version_ratio: Ratio) -> Self { Self { config: MipStatsConfig { block_count_considered, + warn_announced_version_ratio, }, u32_deserializer: U32VarIntDeserializer::new(Included(0), Included(u32::MAX)), u64_deserializer: U64VarIntDeserializer::new(Included(0), Included(u64::MAX)), @@ -703,12 +705,6 @@ impl Deserializer for MipStoreStatsDeserializer { nom::error::ErrorKind::Fail, )) })?; - // let cfg_counter_max: u32 = u32::try_from(self.config.counters_max).map_err(|_e| { - // nom::Err::Error(ParseError::from_error_kind( - // buffer, - // nom::error::ErrorKind::Fail, - // )) - // })?; let (rem3, latest_annoucements_) = context( "Failed MipStoreStats latest announcements der", @@ -825,7 +821,7 @@ pub struct MipStoreRawDeserializer { impl MipStoreRawDeserializer { /// Creates a new `` - pub fn new(block_count_considered: usize) -> Self { + pub fn new(block_count_considered: usize, warn_announced_version_ratio: Ratio) -> Self { Self { u32_deserializer: U32VarIntDeserializer::new( Included(0), @@ -833,7 +829,10 @@ impl MipStoreRawDeserializer { ), info_deserializer: MipInfoDeserializer::new(), state_deserializer: MipStateDeserializer::new(), - stats_deserializer: MipStoreStatsDeserializer::new(block_count_considered), + stats_deserializer: MipStoreStatsDeserializer::new( + block_count_considered, + warn_announced_version_ratio, + ), } } } @@ -1038,6 +1037,7 @@ mod test { fn test_mip_store_stats_ser_der() { let mip_stats_cfg = MipStatsConfig { block_count_considered: 10, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mip_stats = MipStoreStats { @@ -1050,7 +1050,10 @@ mod test { let store_stats_ser = MipStoreStatsSerializer::new(); store_stats_ser.serialize(&mip_stats, &mut buf).unwrap(); - let store_stats_der = MipStoreStatsDeserializer::new(mip_stats_cfg.block_count_considered); + let store_stats_der = MipStoreStatsDeserializer::new( + mip_stats_cfg.block_count_considered, + mip_stats_cfg.warn_announced_version_ratio, + ); let (rem, store_stats_der_res) = store_stats_der .deserialize::(&buf) .unwrap(); @@ -1063,6 +1066,7 @@ mod test { fn test_mip_store_raw_ser_der() { let mip_stats_cfg = MipStatsConfig { block_count_considered: 10, + warn_announced_version_ratio: Ratio::new_raw(30, 100), }; let mi_2 = MipInfo { @@ -1088,13 +1092,17 @@ mod test { let state_3 = advance_state_until(ComponentState::started(Ratio::new_raw(42, 100)), &mi_3); let store_raw = - MipStoreRaw::try_from(([(mi_2, state_2), (mi_3, state_3)], mip_stats_cfg)).unwrap(); + MipStoreRaw::try_from(([(mi_2, state_2), (mi_3, state_3)], mip_stats_cfg.clone())) + .unwrap(); let mut buf = Vec::new(); let store_raw_ser = MipStoreRawSerializer::new(); store_raw_ser.serialize(&store_raw, &mut buf).unwrap(); - let store_raw_der = MipStoreRawDeserializer::new(10); + let store_raw_der = MipStoreRawDeserializer::new( + mip_stats_cfg.block_count_considered, + mip_stats_cfg.warn_announced_version_ratio, + ); let (rem, store_raw_der_res) = store_raw_der.deserialize::(&buf).unwrap(); assert!(rem.is_empty()); @@ -1147,6 +1155,7 @@ mod test { store: BTreeMap::from_iter(store_raw_.into_iter()), stats: MipStoreStats::new(MipStatsConfig { block_count_considered: 10, + warn_announced_version_ratio: Ratio::new(30, 100), }), }; assert_eq!(store_raw.store.len(), MIP_STORE_MAX_ENTRIES as usize); @@ -1162,7 +1171,7 @@ mod test { .serialize(&store_raw, &mut buf) .expect("Unable to serialize"); - let store_raw_der = MipStoreRawDeserializer::new(10); + let store_raw_der = MipStoreRawDeserializer::new(10, Ratio::new(30, 100)); let (rem, store_raw_der_res) = store_raw_der.deserialize::(&buf).unwrap(); assert!(rem.is_empty());