intense_tests: Implement generic_scheduler_mc_test
This commit is contained in:
parent
e8154f62a2
commit
b7a44c6e6a
1 changed files with 89 additions and 0 deletions
|
|
@ -26,6 +26,7 @@
|
||||||
#include <graphene/chain/key_object.hpp>
|
#include <graphene/chain/key_object.hpp>
|
||||||
#include <graphene/chain/account_object.hpp>
|
#include <graphene/chain/account_object.hpp>
|
||||||
#include <graphene/chain/proposal_object.hpp>
|
#include <graphene/chain/proposal_object.hpp>
|
||||||
|
#include <graphene/chain/witness_schedule_object.hpp>
|
||||||
|
|
||||||
#include <fc/crypto/digest.hpp>
|
#include <fc/crypto/digest.hpp>
|
||||||
|
|
||||||
|
|
@ -310,4 +311,92 @@ BOOST_FIXTURE_TEST_CASE( delegate_groups_mc_test, database_fixture )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To have a secure random number we need to ensure that the same
|
||||||
|
* delegate does not get to produce two blocks in a row. There is
|
||||||
|
* always a chance that the last delegate of one round will be the
|
||||||
|
* first delegate of the next round.
|
||||||
|
*
|
||||||
|
* This means that when we shuffle delegates we need to make sure
|
||||||
|
* that there is at least N/2 delegates between consecutive turns
|
||||||
|
* of the same delegate. This means that durring the random
|
||||||
|
* shuffle we need to restrict the placement of delegates to maintain
|
||||||
|
* this invariant.
|
||||||
|
*
|
||||||
|
* This test checks the requirement using Monte Carlo approach
|
||||||
|
* (produce lots of blocks and check the invariant holds).
|
||||||
|
*/
|
||||||
|
BOOST_FIXTURE_TEST_CASE( generic_scheduler_mc_test, database_fixture )
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
size_t num_witnesses = db.get_global_properties().active_witnesses.size();
|
||||||
|
size_t dmin = num_witnesses >> 1;
|
||||||
|
witness_scheduler_rng rng(
|
||||||
|
// - - - - + - - - - 1 - - - - + - - - - 2 - - - - + - - -
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||||
|
);
|
||||||
|
witness_scheduler scheduler;
|
||||||
|
vector< witness_id_type > witness_ids;
|
||||||
|
|
||||||
|
witness_ids.reserve( num_witnesses );
|
||||||
|
for( size_t i=0; i<num_witnesses; i++ )
|
||||||
|
witness_ids.push_back( witness_id_type(i) );
|
||||||
|
|
||||||
|
scheduler._min_token_count = num_witnesses / 2;
|
||||||
|
|
||||||
|
scheduler.insert_all( witness_ids );
|
||||||
|
for( size_t i=0; i<num_witnesses; i++ )
|
||||||
|
scheduler.produce_schedule( rng );
|
||||||
|
|
||||||
|
vector< witness_id_type > cur_round;
|
||||||
|
vector< witness_id_type > full_schedule;
|
||||||
|
// if we make the maximum witness count testable,
|
||||||
|
// we'll need to enlarge this.
|
||||||
|
std::bitset< 0x40 > witness_seen;
|
||||||
|
size_t total_blocks = 1000000;
|
||||||
|
|
||||||
|
cur_round.reserve( num_witnesses );
|
||||||
|
full_schedule.reserve( total_blocks );
|
||||||
|
|
||||||
|
// we assert so the test doesn't continue, which would
|
||||||
|
// corrupt memory
|
||||||
|
assert( num_witnesses <= witness_seen.size() );
|
||||||
|
|
||||||
|
while( full_schedule.size() < total_blocks )
|
||||||
|
{
|
||||||
|
scheduler.produce_schedule( rng );
|
||||||
|
witness_id_type wid = scheduler.consume_schedule();
|
||||||
|
full_schedule.push_back( wid );
|
||||||
|
cur_round.push_back( wid );
|
||||||
|
if( cur_round.size() == num_witnesses )
|
||||||
|
{
|
||||||
|
// check that the current round contains exactly 1 copy
|
||||||
|
// of each witness
|
||||||
|
witness_seen.reset();
|
||||||
|
for( const witness_id_type& w : cur_round )
|
||||||
|
{
|
||||||
|
uint64_t inst = w.instance.value;
|
||||||
|
BOOST_CHECK( !witness_seen.test( inst ) );
|
||||||
|
assert( !witness_seen.test( inst ) );
|
||||||
|
witness_seen.set( inst );
|
||||||
|
}
|
||||||
|
cur_round.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for( size_t i=0,m=full_schedule.size(); i<m; i++ )
|
||||||
|
{
|
||||||
|
for( size_t j=i+1,n=std::min( m, i+dmin ); j<n; j++ )
|
||||||
|
{
|
||||||
|
BOOST_CHECK( full_schedule[i] != full_schedule[j] );
|
||||||
|
assert( full_schedule[i] != full_schedule[j] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (fc::exception& e) {
|
||||||
|
edump((e.to_detail_string()));
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue