Skip to content

Commit

Permalink
Merge #4502
Browse files Browse the repository at this point in the history
4502: Check and add some old consensus tests r=Leo-Besancon a=Leo-Besancon

Related to #2893

* [ ] document all added functions
* [ ] try in sandbox /simulation/labnet
  * [ ] if part of node-launch, checked using the `resync_check` flag
* [ ] unit tests on the added/changed features
  * [ ] make tests compile
  * [ ] make tests pass 
* [ ] add logs allowing easy debugging in case the changes caused problems
* [ ] if the API has changed, update the API specification

Co-authored-by: Leo-Besancon <[email protected]>
  • Loading branch information
bors[bot] and Leo-Besancon authored Oct 27, 2023
2 parents 99ccf9a + b7ddc8d commit e2511a9
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 16 deletions.
2 changes: 2 additions & 0 deletions massa-consensus-worker/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ crossbeam-channel = {workspace = true, "optional" = true} # BOM UPGRADE Re
massa_pool_exports = {workspace = true, features = ["test-exports"]}
massa_pos_exports = {workspace = true, features = ["test-exports"]}
massa_protocol_exports = {workspace = true, features = ["test-exports"]}
massa_execution_exports = {workspace = true, features = ["test-exports"]}
massa_consensus_exports = {workspace = true, features = ["test-exports"]}
massa_test_framework = {workspace = true}
mockall = {workspace = true}
rand = {workspace = true}
Expand Down
6 changes: 1 addition & 5 deletions massa-consensus-worker/src/tests/certik/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1 @@
mod tools;

pub mod scenarios;
pub mod two_threads_scenarios;
pub mod four_threads_scenarios;
mod tools;
137 changes: 136 additions & 1 deletion massa-consensus-worker/src/tests/scenarios.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ use super::{
use crate::tests::tools::create_block;
use massa_consensus_exports::ConsensusConfig;
use massa_execution_exports::MockExecutionController;
use massa_models::{address::Address, block_id::BlockId, config::ENDORSEMENT_COUNT, slot::Slot};
use massa_models::{
address::Address, block::BlockGraphStatus, block_id::BlockId, config::ENDORSEMENT_COUNT,
slot::Slot,
};
use massa_pool_exports::MockPoolController;
use massa_pos_exports::{MockSelectorController, Selection};
use massa_signature::KeyPair;
Expand All @@ -19,6 +22,43 @@ use massa_test_framework::TestUniverse;
use massa_time::MassaTime;
use mockall::Sequence;

#[test]
fn test_genesis_block_creation() {
let staking_key: KeyPair = KeyPair::generate(0).unwrap();
let thread_count = 2;
let cfg = ConsensusConfig {
t0: MassaTime::from_millis(1000),
thread_count,
genesis_timestamp: MassaTime::now().unwrap(),
force_keep_final_periods: 50,
force_keep_final_periods_without_ops: 128,
max_future_processing_blocks: 10,
genesis_key: staking_key.clone(),
..ConsensusConfig::default()
};
let mut foreign_controllers = ConsensusForeignControllers::new_with_mocks();

foreign_controllers
.execution_controller
.expect_update_blockclique_status()
.return_once(|_, _, _| {});
foreign_controllers
.pool_controller
.expect_notify_final_cs_periods()
.returning(|_| {});
foreign_controllers
.pool_controller
.expect_add_denunciation_precursor()
.returning(|_| {});
let universe = ConsensusTestUniverse::new(foreign_controllers, cfg);
let genesis_hashes = universe
.module_controller
.get_block_graph_status(None, None)
.expect("could not get block graph status")
.genesis_blocks;
assert_eq!(genesis_hashes.len() as u8, thread_count);
}

/// This test tests that the blocks are well processed by consensus even if they are not sent in a sorted way.
#[test]
fn test_unsorted_block() {
Expand Down Expand Up @@ -265,3 +305,98 @@ fn test_parallel_incompatibility() {
},
);
}

#[test]
fn test_parent_in_the_future() {
let staking_key: KeyPair = KeyPair::generate(0).unwrap();
let cfg = ConsensusConfig {
t0: MassaTime::from_millis(1000),
thread_count: 2,
genesis_timestamp: MassaTime::now().unwrap(),
force_keep_final_periods: 50,
force_keep_final_periods_without_ops: 128,
max_future_processing_blocks: 2,
block_db_prune_interval: MassaTime::from_millis(250),
genesis_key: staking_key.clone(),
..ConsensusConfig::default()
};
let staking_address = Address::from_public_key(&staking_key.get_public_key());
let start_period = 100;

let mut foreign_controllers = ConsensusForeignControllers::new_with_mocks();
let storage = foreign_controllers.storage.clone();

foreign_controllers
.execution_controller
.expect_update_blockclique_status()
.returning(|_, _, _| {});
foreign_controllers
.pool_controller
.expect_notify_final_cs_periods()
.returning(|_| {});
foreign_controllers
.pool_controller
.expect_add_denunciation_precursor()
.returning(|_| {});
foreign_controllers
.selector_controller
.expect_get_producer()
.returning(move |_| Ok(staking_address));
foreign_controllers
.selector_controller
.expect_get_selection()
.returning(move |_| {
Ok(Selection {
producer: staking_address,
endorsements: vec![staking_address; ENDORSEMENT_COUNT as usize],
})
});

let universe = ConsensusTestUniverse::new(foreign_controllers, cfg);
let genesis_hashes = universe
.module_controller
.get_block_graph_status(None, None)
.expect("could not get block graph status")
.genesis_blocks;
// create test blocks

let t0s1 = create_block(
Slot::new(start_period, 0),
genesis_hashes.clone(),
&staking_key,
);

let t1s1 = create_block(
Slot::new(start_period, 1),
genesis_hashes.clone(),
&staking_key,
);

let t0s2 = create_block(
Slot::new(start_period.saturating_add(1), 0),
vec![t0s1.id, t1s1.id],
&staking_key,
);

// send blocks t0s1, t1s1,
register_block(&universe.module_controller, t0s1.clone(), storage.clone());
register_block(&universe.module_controller, t1s1.clone(), storage.clone());
//register blocks t0s2
register_block(&universe.module_controller, t0s2.clone(), storage.clone());

// Wait for blocks_db to be pruned
std::thread::sleep(Duration::from_millis(1500));
// We only keep t0s2 and t1s1 because of max_future_processing_blocks set to 2
let status = universe
.module_controller
.get_block_statuses(&[t0s1.id, t1s1.id, t0s2.id]);
assert_eq!(
status,
vec![
BlockGraphStatus::WaitingForSlot,
BlockGraphStatus::WaitingForSlot,
BlockGraphStatus::NotFound
],
"wrong status"
);
}
1 change: 0 additions & 1 deletion massa-consensus-worker/src/worker/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ pub fn create_genesis_block(
) -> Result<SecureShareBlock, ConsensusError> {
let keypair = &cfg.genesis_key;
let header = BlockHeader::new_verifiable(
// VERSIONNING TODO: what to implement here in case of restart?
BlockHeader {
current_version: 0,
announced_version: None,
Expand Down
6 changes: 1 addition & 5 deletions massa-db-worker/src/massa_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -878,11 +878,7 @@ mod test {
// Check not allowed to init a second instance
let db2 = MassaDB::new_with_options(db_config, db_opts.clone());
assert!(db2.is_err());
assert!(db2
.err()
.unwrap()
.into_string()
.contains("IO error: lock hold by current process"));
assert!(db2.err().unwrap().into_string().contains("IO error"));
}

#[test]
Expand Down
44 changes: 40 additions & 4 deletions massa-execution-worker/src/tests/scenarios_mandatories.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1451,11 +1451,30 @@ mod tests {
&keypair,
)
.unwrap();

let balance_initial = sample_state.read().ledger.get_balance(&address).unwrap();
let roll_count_too_high = balance_initial
.checked_div(exec_cfg.roll_price)
.unwrap()
.saturating_add(10);
// This second operation will fail as the price is too high
let operation_too_expensive = Operation::new_verifiable(
Operation {
fee: Amount::zero(),
expire_period: 10,
op: OperationType::RollBuy {
roll_count: roll_count_too_high,
},
},
OperationSerializer::new(),
&keypair,
)
.unwrap();
// create the block containing the roll buy operation
storage.store_operations(vec![operation.clone()]);
storage.store_operations(vec![operation.clone(), operation_too_expensive.clone()]);
let block = create_block(
KeyPair::generate(0).unwrap(),
vec![operation],
vec![operation, operation_too_expensive],
vec![],
Slot::new(1, 0),
)
Expand Down Expand Up @@ -1558,6 +1577,7 @@ mod tests {
let roll_count_initial = sample_state.read().pos_state.get_rolls_for(&address);
let roll_sell_1 = 10;
let roll_sell_2 = 1;
let roll_sell_3 = roll_count_initial.saturating_add(10);

let initial_deferred_credits = Amount::from_str("100").unwrap();

Expand Down Expand Up @@ -1602,11 +1622,27 @@ mod tests {
&keypair,
)
.unwrap();
let operation3 = Operation::new_verifiable(
Operation {
fee: Amount::zero(),
expire_period: 10,
op: OperationType::RollSell {
roll_count: roll_sell_3,
},
},
OperationSerializer::new(),
&keypair,
)
.unwrap();
// create the block containing the roll buy operation
storage.store_operations(vec![operation1.clone(), operation2.clone()]);
storage.store_operations(vec![
operation1.clone(),
operation2.clone(),
operation3.clone(),
]);
let block = create_block(
KeyPair::generate(0).unwrap(),
vec![operation1, operation2],
vec![operation1, operation2, operation3],
vec![],
Slot::new(3, 0),
)
Expand Down

0 comments on commit e2511a9

Please sign in to comment.