intense_tests: Implement delegate_groups_mc_test

This commit is contained in:
theoreticalbts 2015-06-11 10:31:19 -04:00
parent e638efdbcb
commit c6a7cdf5a3
2 changed files with 74 additions and 19 deletions

View file

@ -16,6 +16,7 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <bitset>
#include <iostream>
#include <boost/test/unit_test.hpp>
@ -236,4 +237,77 @@ BOOST_FIXTURE_TEST_CASE( update_account_keys, 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( delegate_groups_mc_test, database_fixture )
{
try {
size_t num_witnesses = db.get_global_properties().active_witnesses.size();
size_t dmin = num_witnesses >> 1;
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 )
{
witness_id_type wid = db.get_scheduled_witness( 1 ).first;
full_schedule.push_back( wid );
cur_round.push_back( wid );
if( cur_round.size() == num_witnesses )
{
wdump( (cur_round) );
// 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();
}
generate_block();
}
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()

View file

@ -1969,25 +1969,6 @@ BOOST_AUTO_TEST_CASE( witness_withdraw_pay_test )
BOOST_CHECK_EQUAL(witness->accumulated_income.value, 0);
} FC_LOG_AND_RETHROW() }
/**
* 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.
*/
BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES( unimp_delegate_groups_test, 1 )
BOOST_AUTO_TEST_CASE( unimp_delegate_groups_test )
{
BOOST_FAIL( "not implemented" );
}
/**
* This test should simulate a prediction market which means the following:
*