scheduler: Refactor 26007bb655 to use witness_schedule_object

The functionality is equivalent, but it now uses a separate witness_schedule_object,
and the code now lives in db_witness_schedule.cpp.
This commit is contained in:
theoreticalbts 2015-09-18 14:05:38 -04:00
parent 7237ef618f
commit f7980f5252
8 changed files with 100 additions and 41 deletions

View file

@ -292,6 +292,7 @@ namespace graphene { namespace app {
} case impl_block_summary_object_type:{
} case impl_account_transaction_history_object_type:{
} case impl_chain_property_object_type: {
} case impl_witness_schedule_object_type: {
}
}
}

View file

@ -485,7 +485,7 @@ void database::_apply_block( const signed_block& next_block )
// update_global_dynamic_data() as perhaps these methods only need
// to be called for header validation?
update_maintenance_flag( maint_needed );
shuffle_witnesses();
update_witness_schedule();
// notify observers that the block has been applied
applied_block( next_block ); //emit
@ -494,37 +494,6 @@ void database::_apply_block( const signed_block& next_block )
notify_changed_objects();
} FC_CAPTURE_AND_RETHROW( (next_block.block_num()) ) }
void database::shuffle_witnesses() {
const auto& dgp = get_global_properties();
if( head_block_num() % dgp.active_witnesses.size() == 0 ) {
modify( dgp, [&]( global_property_object& props ) {
props.current_shuffled_witnesses.clear();
props.current_shuffled_witnesses.reserve( props.active_witnesses.size() );
for( auto w : props.active_witnesses )
props.current_shuffled_witnesses.push_back(w);
auto now_hi = uint64_t(head_block_time().sec_since_epoch()) << 32;
for( uint32_t i = 0; i < props.current_shuffled_witnesses.size(); ++i )
{
/// High performance random generator
/// http://xorshift.di.unimi.it/
uint64_t k = now_hi + uint64_t(i)*2685821657736338717ULL;
k ^= (k >> 12);
k ^= (k << 25);
k ^= (k >> 27);
k *= 2685821657736338717ULL;
uint32_t jmax = props.current_shuffled_witnesses.size() - i;
uint32_t j = i + k%jmax;
std::swap( props.current_shuffled_witnesses[i],
props.current_shuffled_witnesses[j] );
}
// edump( (props.current_shuffled_witnesses) );
});
}
}
void database::notify_changed_objects()
{ try {
if( _undo_db.enabled() )

View file

@ -30,6 +30,7 @@
#include <graphene/chain/vesting_balance_object.hpp>
#include <graphene/chain/withdraw_permission_object.hpp>
#include <graphene/chain/witness_object.hpp>
#include <graphene/chain/witness_schedule_object.hpp>
#include <graphene/chain/account_evaluator.hpp>
#include <graphene/chain/asset_evaluator.hpp>
@ -192,6 +193,7 @@ void database::initialize_indexes()
add_index< primary_index<simple_index<asset_dynamic_data_object >> >();
add_index< primary_index<flat_index< block_summary_object >> >();
add_index< primary_index<simple_index<chain_property_object > > >();
add_index< primary_index<simple_index<witness_schedule_object > > >();
}
void database::init_genesis(const genesis_state_type& genesis_state)
@ -592,7 +594,6 @@ void database::init_genesis(const genesis_state_type& genesis_state)
{
p.active_witnesses.insert(i);
p.witness_accounts.insert(get(witness_id_type(i)).witness_account);
p.current_shuffled_witnesses.push_back( witness_id_type(i) );
}
});
@ -601,6 +602,13 @@ void database::init_genesis(const genesis_state_type& genesis_state)
p.parameters.current_fees = genesis_state.initial_parameters.current_fees;
});
// Create witness scheduler
create<witness_schedule_object>([&]( witness_schedule_object& wso )
{
for( const witness_id_type& wid : get_global_properties().active_witnesses )
wso.current_shuffled_witnesses.push_back( wid );
});
_undo_db.enable();
} FC_CAPTURE_AND_RETHROW() }

View file

@ -20,6 +20,7 @@
#include <graphene/chain/database.hpp>
#include <graphene/chain/global_property_object.hpp>
#include <graphene/chain/witness_object.hpp>
#include <graphene/chain/witness_schedule_object.hpp>
namespace graphene { namespace chain {
@ -27,10 +28,10 @@ using boost::container::flat_set;
witness_id_type database::get_scheduled_witness( uint32_t slot_num )const
{
const auto& dgp = get_dynamic_global_properties();
const auto& gp = get_global_properties();
auto current_aslot = dgp.current_aslot + slot_num;
return gp.current_shuffled_witnesses[current_aslot%gp.current_shuffled_witnesses.size()];
const dynamic_global_property_object& dpo = get_dynamic_global_properties();
const witness_schedule_object& wso = witness_schedule_id_type()(*this);
uint64_t current_aslot = dpo.current_aslot + slot_num;
return wso.current_shuffled_witnesses[ current_aslot % wso.current_shuffled_witnesses.size() ];
}
fc::time_point_sec database::get_slot_time(uint32_t slot_num)const
@ -81,4 +82,39 @@ uint32_t database::witness_participation_rate()const
return uint64_t(GRAPHENE_100_PERCENT) * dpo.recent_slots_filled.popcount() / 128;
}
void database::update_witness_schedule()
{
const witness_schedule_object& wso = witness_schedule_id_type()(*this);
const global_property_object& gpo = get_global_properties();
if( head_block_num() % gpo.active_witnesses.size() == 0 )
{
modify( wso, [&]( witness_schedule_object& _wso )
{
_wso.current_shuffled_witnesses.clear();
_wso.current_shuffled_witnesses.reserve( gpo.active_witnesses.size() );
for( const witness_id_type& w : gpo.active_witnesses )
_wso.current_shuffled_witnesses.push_back( w );
auto now_hi = uint64_t(head_block_time().sec_since_epoch()) << 32;
for( uint32_t i = 0; i < _wso.current_shuffled_witnesses.size(); ++i )
{
/// High performance random generator
/// http://xorshift.di.unimi.it/
uint64_t k = now_hi + uint64_t(i)*2685821657736338717ULL;
k ^= (k >> 12);
k ^= (k << 25);
k ^= (k >> 27);
k *= 2685821657736338717ULL;
uint32_t jmax = _wso.current_shuffled_witnesses.size() - i;
uint32_t j = i + k%jmax;
std::swap( _wso.current_shuffled_witnesses[i],
_wso.current_shuffled_witnesses[j] );
}
});
}
}
} }

View file

@ -227,6 +227,8 @@ namespace graphene { namespace chain {
*/
uint32_t get_slot_at_time(fc::time_point_sec when)const;
void update_witness_schedule();
//////////////////// db_getter.cpp ////////////////////
const chain_id_type& get_chain_id()const;
@ -424,7 +426,6 @@ namespace graphene { namespace chain {
void update_expired_feeds();
void update_maintenance_flag( bool new_maintenance_flag );
void update_withdraw_permissions();
void shuffle_witnesses();
///Steps performed only at maintenance intervals
///@{

View file

@ -47,7 +47,6 @@ namespace graphene { namespace chain {
flat_set<witness_id_type> active_witnesses; // updated once per maintenance interval
// n.b. witness scheduling is done by witness_schedule object
flat_set<account_id_type> witness_accounts; // updated once per maintenance interval
vector<witness_id_type> current_shuffled_witnesses;
};
/**
@ -138,5 +137,4 @@ FC_REFLECT_DERIVED( graphene::chain::global_property_object, (graphene::db::obje
(next_available_vote_id)
(active_committee_members)
(active_witnesses)
(current_shuffled_witnesses)
)

View file

@ -141,7 +141,8 @@ namespace graphene { namespace chain {
impl_block_summary_object_type,
impl_account_transaction_history_object_type,
impl_blinded_balance_object_type,
impl_chain_property_object_type
impl_chain_property_object_type,
impl_witness_schedule_object_type
};
enum meta_info_object_type
@ -194,6 +195,7 @@ namespace graphene { namespace chain {
class block_summary_object;
class account_transaction_history_object;
class chain_property_object;
class witness_schedule_object;
typedef object_id< implementation_ids, impl_global_property_object_type, global_property_object> global_property_id_type;
typedef object_id< implementation_ids, impl_dynamic_global_property_object_type, dynamic_global_property_object> dynamic_global_property_id_type;
@ -208,6 +210,7 @@ namespace graphene { namespace chain {
impl_account_transaction_history_object_type,
account_transaction_history_object> account_transaction_history_id_type;
typedef object_id< implementation_ids, impl_chain_property_object_type, chain_property_object> chain_property_id_type;
typedef object_id< implementation_ids, impl_witness_schedule_object_type, witness_schedule_object> witness_schedule_id_type;
typedef fc::array<char, GRAPHENE_MAX_ASSET_SYMBOL_LENGTH> symbol_type;
typedef fc::ripemd160 block_id_type;
@ -284,6 +287,7 @@ FC_REFLECT_ENUM( graphene::chain::impl_object_type,
(impl_account_transaction_history_object_type)
(impl_blinded_balance_object_type)
(impl_chain_property_object_type)
(impl_witness_schedule_object_type)
)
FC_REFLECT_ENUM( graphene::chain::meta_info_object_type, (meta_account_object_type)(meta_asset_object_type) )

View file

@ -0,0 +1,42 @@
/*
* Copyright (c) 2015, Cryptonomex, Inc.
* All rights reserved.
*
* This source code is provided for evaluation in private test networks only, until September 8, 2015. After this date, this license expires and
* the code may not be used, modified or distributed for any purpose. Redistribution and use in source and binary forms, with or without modification,
* are permitted until September 8, 2015, provided that the following conditions are met:
*
* 1. The code and/or derivative works are used only for private test networks consisting of no more than 10 P2P nodes.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>
namespace graphene { namespace chain {
class witness_schedule_object;
class witness_schedule_object : public graphene::db::abstract_object<witness_schedule_object>
{
public:
static const uint8_t space_id = implementation_ids;
static const uint8_t type_id = impl_witness_schedule_object_type;
vector< witness_id_type > current_shuffled_witnesses;
};
} }
FC_REFLECT_DERIVED(
graphene::chain::witness_schedule_object,
(graphene::db::object),
(current_shuffled_witnesses)
)