Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion massa-execution-exports/src/test_exports/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use std::{
/// and is emitted in a thread-safe way by the mock whenever that method is called.
/// Some variants wait for a response on their `response_tx` field, if present.
/// See the documentation of `ExecutionController` for details on parameters and return values.
#[derive(Clone)]
#[derive(Debug, Clone)]
pub enum MockExecutionControllerMessage {
/// update blockclique status
UpdateBlockcliqueStatus {
Expand Down
5 changes: 5 additions & 0 deletions massa-pool-worker/src/operation_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ impl OperationPool {
}

/// get operations for block creation
///
/// Searches the available operations, and selects the sub-set of operations that:
/// - fit inside the block
/// - is the most profitable for block producer
pub fn get_block_operations(&self, slot: &Slot) -> (Vec<OperationId>, Storage) {
// init list of selected operation IDs
let mut op_ids = Vec::new();
Expand Down Expand Up @@ -222,6 +226,7 @@ impl OperationPool {
.unexecuted_ops_among(&vec![op_info.id].into_iter().collect(), slot.thread)
.is_empty()
{
// this is never outputted
continue;
}

Expand Down
31 changes: 27 additions & 4 deletions massa-pool-worker/src/tests/operation_pool_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
//!
use super::tools::{create_some_operations, operation_pool_test};
use crate::operation_pool::OperationPool;
use massa_execution_exports::test_exports::MockExecutionController;
use massa_execution_exports::test_exports::{
MockExecutionController, MockExecutionControllerMessage,
};
use massa_models::{
address::Address,
amount::Amount,
Expand All @@ -31,7 +33,7 @@ use massa_models::{
use massa_pool_exports::{PoolChannels, PoolConfig};
use massa_signature::KeyPair;
use massa_storage::Storage;
use std::str::FromStr;
use std::{str::FromStr, time::Duration};
use tokio::sync::broadcast;

#[test]
Expand Down Expand Up @@ -78,7 +80,7 @@ fn get_transaction(expire_period: u64, fee: u64) -> SecureShareOperation {
#[test]
#[ignore]
fn test_pool() {
let (execution_controller, _execution_receiver) = MockExecutionController::new_with_receiver();
let (execution_controller, execution_receiver) = MockExecutionController::new_with_receiver();
let pool_config = PoolConfig::default();
let storage_base = Storage::create_root();
let operation_sender = broadcast::channel(pool_config.broadcast_operations_capacity).0;
Expand Down Expand Up @@ -117,6 +119,26 @@ fn test_pool() {
.get_thread(pool_config.thread_count);
thread_tx_lists[op_thread as usize].push((op, start_period..=expire_period));
}
std::thread::spawn(move || loop {
match execution_receiver.recv_timeout(Duration::from_millis(100)) {
// forward on the operations
Ok(MockExecutionControllerMessage::UnexecutedOpsAmong {
ops, response_tx, ..
}) => {
response_tx.send(ops).unwrap();
}
// we want the operations to be paid for...
Ok(MockExecutionControllerMessage::GetFinalAndCandidateBalance {
response_tx, ..
}) => response_tx
.send(vec![(
Some(Amount::from_raw(60 * 1000000000)),
Some(Amount::from_raw(60 * 1000000000)),
)])
.unwrap(),
_ => {}
}
});

// sort from bigger fee to smaller and truncate
for lst in thread_tx_lists.iter_mut() {
Expand All @@ -130,6 +152,7 @@ fn test_pool() {
let target_slot = Slot::new(period, thread);
let max_count = 3;
let (ids, storage) = pool.get_block_operations(&target_slot);

assert!(ids
.iter()
.map(|id| (
Expand Down Expand Up @@ -189,7 +212,7 @@ fn test_pool() {
let fee = 1000;
let expire_period: u64 = 300;
let op = get_transaction(expire_period, fee);
let mut storage = Storage::create_root();
let mut storage = storage_base.clone_without_refs();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was it the case in the past that you could create multiple instances of storage without panic!ing? That could explain the need for this change.

storage.store_operations(vec![op.clone()]);
pool.add_operations(storage);
//TODO: compare
Expand Down
40 changes: 28 additions & 12 deletions massa-pool-worker/src/tests/scenario.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use crate::tests::tools::create_some_operations;
use crate::tests::tools::pool_test;
use massa_execution_exports::test_exports::MockExecutionControllerMessage as ControllerMsg;
use massa_models::address::Address;
use massa_models::amount::Amount;
use massa_models::operation::OperationId;
use massa_models::prehash::PreHashSet;
use massa_models::slot::Slot;
Expand All @@ -44,7 +45,6 @@ use massa_signature::KeyPair;
/// The block operation storage built for all threads is expected to have the
/// same length than those added previously.
#[test]
#[ignore]
fn test_simple_get_operations() {
let config = PoolConfig::default();
pool_test(
Expand All @@ -58,14 +58,14 @@ fn test_simple_get_operations() {
let unexecuted_ops = storage.get_op_refs().clone();
pool_controller.add_operations(storage);

// start mock execution thread
// Start mock execution thread.
// Provides the data for `pool_controller.get_block_operations`
std::thread::spawn(move || {
// TODO following behavior is not valid anymore
match execution_receiver.recv_timeout(Duration::from_millis(100)) {
Ok(ControllerMsg::UnexecutedOpsAmong { response_tx, .. }) => {
response_tx.send(unexecuted_ops.clone()).unwrap();
}
Ok(_) => panic!("unexpected controller request"),
Ok(op) => panic!("expected `ControllerMsg::UnexecutedOpsAmong`, got {:?}", op),
Err(_) => panic!("execution never called"),
}
match execution_receiver.recv_timeout(Duration::from_millis(100)) {
Expand All @@ -76,22 +76,29 @@ fn test_simple_get_operations() {
}) => {
assert_eq!(addresses.len(), 1);
assert_eq!(addresses[0], creator_address);
response_tx.send(vec![]).unwrap();
response_tx
.send(vec![(Some(Amount::from_raw(1)), Some(Amount::from_raw(1)))])
.unwrap();
}
Ok(_) => panic!("unexpected controller request"),
Ok(op) => panic!(
"Expected `ControllerMsg::GetFinalAndCandidateBalance`, got {:?}",
op
),
Err(_) => panic!("execution never called"),
}

(0..9).for_each(|_| {
match execution_receiver.recv_timeout(Duration::from_millis(100)) {
Ok(ControllerMsg::UnexecutedOpsAmong { response_tx, .. }) => {
response_tx.send(unexecuted_ops.clone()).unwrap();
}
Ok(_) => panic!("unexpected controller request"),
Ok(op) => panic!("ControllerMsg::UnexecutedOpsAmong, got {:?}", op),
Err(_) => panic!("execution never called"),
}
})
});

// This is what we are testing....
let block_operations_storage = pool_controller
.get_block_operations(&Slot::new(1, creator_thread))
.1;
Expand All @@ -114,12 +121,22 @@ fn launch_basic_get_block_operation_execution_mock(
use ControllerMsg::GetFinalAndCandidateBalance as GetFinal;
use ControllerMsg::UnexecutedOpsAmong as Unexecuted;

if let Ok(Unexecuted { response_tx, .. }) = receive(&recvr) {
response_tx.send(unexecuted_ops.clone()).unwrap();
match receive(&recvr) {
Ok(Unexecuted { response_tx, .. }) => response_tx.send(unexecuted_ops.clone()).unwrap(),
Ok(op) => panic!("expected `ControllerMsg::UnexecutedOpsAmong`, got {:?}", op),
Err(_) => panic!("execution never called"),
}
if let Ok(GetFinal { response_tx, .. }) = receive(&recvr) {
response_tx.send(vec![]).unwrap();
match receive(&recvr) {
Ok(GetFinal { response_tx, .. }) => response_tx
.send(vec![(Some(Amount::from_raw(1)), Some(Amount::from_raw(1)))])
.unwrap(),
Ok(op) => panic!(
"Expected `ControllerMsg::GetFinalAndCandidateBalance`, got {:?}",
op
),
Err(_) => panic!("execution never called"),
}

(1..operations_len).for_each(|_| {
if let Ok(Unexecuted { response_tx, .. }) = receive(&recvr) {
response_tx.send(unexecuted_ops.clone()).unwrap();
Expand All @@ -143,7 +160,6 @@ fn launch_basic_get_block_operation_execution_mock(
/// The block operation storage built for all threads is expected to have
/// only 5 operations.
#[test]
#[ignore]
fn test_get_operations_overflow() {
static OP_LEN: usize = 10;
static MAX_OP_LEN: usize = 5;
Expand Down
2 changes: 2 additions & 0 deletions massa-pool-worker/src/tests/tools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ pub fn create_some_operations(
.collect()
}

/// Used to creates the module mocks, and deploys them using the passed in
pub fn pool_test<F>(cfg: PoolConfig, test: F)
where
F: FnOnce(
Expand All @@ -63,6 +64,7 @@ where
{
let storage: Storage = Storage::create_root();
let operation_sender = broadcast::channel(5000).0;
// as if we started an execution module, but it's just something that....
let (execution_controller, execution_receiver) = MockExecutionController::new_with_receiver();
let (pool_manager, pool_controller) = start_pool_controller(
cfg,
Expand Down