database: Make functions which don't take skip_flags arg, use them to implement old API which does

This commit is contained in:
theoreticalbts 2015-06-17 22:22:54 -04:00
parent e6246bf9a0
commit 2ec92c6695
4 changed files with 131 additions and 6 deletions

View file

@ -81,7 +81,18 @@ const signed_transaction& database::get_recent_transaction(const transaction_id_
* @return true if we switched forks as a result of this push. * @return true if we switched forks as a result of this push.
*/ */
bool database::push_block( const signed_block& new_block, uint32_t skip ) bool database::push_block( const signed_block& new_block, uint32_t skip )
{
bool result;
with_skip_flags( skip, [&]()
{
result = _push_block( new_block );
} );
return result;
}
bool database::_push_block( const signed_block& new_block )
{ try { { try {
uint32_t skip = get_node_properties().skip_flags;
if( !(skip&skip_fork_db) ) if( !(skip&skip_fork_db) )
{ {
auto new_head = _fork_db.push_block( new_block ); auto new_head = _fork_db.push_block( new_block );
@ -182,12 +193,23 @@ bool database::push_block( const signed_block& new_block, uint32_t skip )
*/ */
processed_transaction database::push_transaction( const signed_transaction& trx, uint32_t skip ) processed_transaction database::push_transaction( const signed_transaction& trx, uint32_t skip )
{ {
processed_transaction result;
with_skip_flags( skip, [&]()
{
result = _push_transaction( trx );
} );
return result;
}
processed_transaction database::_push_transaction( const signed_transaction& trx )
{
uint32_t skip = get_node_properties().skip_flags;
//wdump((trx.digest())(trx.id())); //wdump((trx.digest())(trx.id()));
// If this is the first transaction pushed after applying a block, start a new undo session. // If this is the first transaction pushed after applying a block, start a new undo session.
// This allows us to quickly rewind to the clean state of the head block, in case a new block arrives. // This allows us to quickly rewind to the clean state of the head block, in case a new block arrives.
if( !_pending_block_session ) _pending_block_session = _undo_db.start_undo_session(); if( !_pending_block_session ) _pending_block_session = _undo_db.start_undo_session();
auto session = _undo_db.start_undo_session(); auto session = _undo_db.start_undo_session();
auto processed_trx = apply_transaction( trx, skip ); auto processed_trx = _apply_transaction( trx );
_pending_block.transactions.push_back(processed_trx); _pending_block.transactions.push_back(processed_trx);
FC_ASSERT( (skip & skip_block_size_check) || FC_ASSERT( (skip & skip_block_size_check) ||
@ -240,8 +262,23 @@ signed_block database::generate_block(
const fc::ecc::private_key& block_signing_private_key, const fc::ecc::private_key& block_signing_private_key,
uint32_t skip /* = 0 */ uint32_t skip /* = 0 */
) )
{
signed_block result;
with_skip_flags( skip, [&]()
{
result = _generate_block( when, witness_id, block_signing_private_key );
} );
return result;
}
signed_block database::_generate_block(
fc::time_point_sec when,
witness_id_type witness_id,
const fc::ecc::private_key& block_signing_private_key
)
{ {
try { try {
uint32_t skip = get_node_properties().skip_flags;
uint32_t slot_num = get_slot_at_time( when ); uint32_t slot_num = get_slot_at_time( when );
witness_id_type scheduled_witness = get_scheduled_witness( slot_num ).first; witness_id_type scheduled_witness = get_scheduled_witness( slot_num ).first;
FC_ASSERT( scheduled_witness == witness_id ); FC_ASSERT( scheduled_witness == witness_id );
@ -322,7 +359,17 @@ const vector<operation_history_object>& database::get_applied_operations() const
//////////////////// private methods //////////////////// //////////////////// private methods ////////////////////
void database::apply_block( const signed_block& next_block, uint32_t skip ) void database::apply_block( const signed_block& next_block, uint32_t skip )
{
with_skip_flags( skip, [&]()
{
_apply_block( next_block );
} );
return;
}
void database::_apply_block( const signed_block& next_block )
{ try { { try {
uint32_t skip = get_node_properties().skip_flags;
_applied_ops.clear(); _applied_ops.clear();
FC_ASSERT( (skip & skip_merkle_check) || next_block.transaction_merkle_root == next_block.calculate_merkle_root(), "", ("next_block.transaction_merkle_root",next_block.transaction_merkle_root)("calc",next_block.calculate_merkle_root())("next_block",next_block)("id",next_block.id()) ); FC_ASSERT( (skip & skip_merkle_check) || next_block.transaction_merkle_root == next_block.calculate_merkle_root(), "", ("next_block.transaction_merkle_root",next_block.transaction_merkle_root)("calc",next_block.calculate_merkle_root())("next_block",next_block)("id",next_block.id()) );
@ -375,16 +422,27 @@ void database::apply_block( const signed_block& next_block, uint32_t skip )
update_pending_block(next_block, current_block_interval); update_pending_block(next_block, current_block_interval);
} FC_CAPTURE_AND_RETHROW( (next_block.block_num())(skip) ) } } FC_CAPTURE_AND_RETHROW( (next_block.block_num()) ) }
processed_transaction database::apply_transaction( const signed_transaction& trx, uint32_t skip ) processed_transaction database::apply_transaction( const signed_transaction& trx, uint32_t skip )
{
processed_transaction result;
with_skip_flags( skip, [&]()
{
result = _apply_transaction( trx );
} );
return result;
}
processed_transaction database::_apply_transaction( const signed_transaction& trx )
{ try { { try {
uint32_t skip = get_node_properties().skip_flags;
trx.validate(); trx.validate();
auto& trx_idx = get_mutable_index_type<transaction_index>(); auto& trx_idx = get_mutable_index_type<transaction_index>();
auto trx_id = trx.id(); auto trx_id = trx.id();
FC_ASSERT( (skip & skip_transaction_dupe_check) || FC_ASSERT( (skip & skip_transaction_dupe_check) ||
trx_idx.indices().get<by_trx_id>().find(trx_id) == trx_idx.indices().get<by_trx_id>().end() ); trx_idx.indices().get<by_trx_id>().find(trx_id) == trx_idx.indices().get<by_trx_id>().end() );
transaction_evaluation_state eval_state(this, skip&skip_authority_check ); transaction_evaluation_state eval_state(this);
const chain_parameters& chain_parameters = get_global_properties().parameters; const chain_parameters& chain_parameters = get_global_properties().parameters;
eval_state._trx = &trx; eval_state._trx = &trx;

View file

@ -63,4 +63,14 @@ decltype( chain_parameters::block_interval ) database::block_interval( )const
return get_global_properties().parameters.block_interval; return get_global_properties().parameters.block_interval;
} }
const node_property_object& database::get_node_properties()const
{
return _node_property_object;
}
node_property_object& database::node_properties()
{
return _node_property_object;
}
} } } }

View file

@ -64,6 +64,31 @@ namespace graphene { namespace chain {
vector<initial_committee_member_type> initial_committee; vector<initial_committee_member_type> initial_committee;
}; };
namespace detail
{
/**
* Class used to help the with_skip_flags implementation.
* It must be defined in this header because it must be
* available to the with_skip_flags implementation,
* which is a template and therefore must also be defined
* in this header.
*/
struct skip_flags_restorer
{
skip_flags_restorer( node_property_object& npo, uint32_t old_skip_flags )
: _npo( npo ), _old_skip_flags( old_skip_flags )
{}
~skip_flags_restorer()
{
_npo.skip_flags = _old_skip_flags;
}
node_property_object& _npo;
uint32_t _old_skip_flags;
};
}
/** /**
* @class database * @class database
* @brief tracks the blockchain state in an extensible manner * @brief tracks the blockchain state in an extensible manner
@ -124,6 +149,9 @@ namespace graphene { namespace chain {
bool push_block( const signed_block& b, uint32_t skip = skip_nothing ); bool push_block( const signed_block& b, uint32_t skip = skip_nothing );
processed_transaction push_transaction( const signed_transaction& trx, uint32_t skip = skip_nothing ); processed_transaction push_transaction( const signed_transaction& trx, uint32_t skip = skip_nothing );
bool _push_block( const signed_block& b );
processed_transaction _push_transaction( const signed_transaction& trx );
///@throws fc::exception if the proposed transaction fails to apply. ///@throws fc::exception if the proposed transaction fails to apply.
processed_transaction push_proposal( const proposal_object& proposal ); processed_transaction push_proposal( const proposal_object& proposal );
@ -131,7 +159,12 @@ namespace graphene { namespace chain {
const fc::time_point_sec when, const fc::time_point_sec when,
witness_id_type witness_id, witness_id_type witness_id,
const fc::ecc::private_key& block_signing_private_key, const fc::ecc::private_key& block_signing_private_key,
uint32_t skip = 0 uint32_t skip
);
signed_block _generate_block(
const fc::time_point_sec when,
witness_id_type witness_id,
const fc::ecc::private_key& block_signing_private_key
); );
void pop_block(); void pop_block();
@ -225,6 +258,25 @@ namespace graphene { namespace chain {
decltype( chain_parameters::block_interval ) block_interval( )const; decltype( chain_parameters::block_interval ) block_interval( )const;
node_property_object& node_properties();
/**
* Set the skip_flags to the given value, call callback,
* then reset skip_flags to their previous value after
* callback is done.
*/
template< typename Lambda >
void with_skip_flags(
uint32_t skip_flags,
Lambda callback )
{
node_property_object& npo = node_properties();
detail::skip_flags_restorer restorer( npo, npo.skip_flags );
npo.skip_flags = skip_flags;
callback();
return;
}
//////////////////// db_init.cpp //////////////////// //////////////////// db_init.cpp ////////////////////
void initialize_evaluators(); void initialize_evaluators();
@ -350,12 +402,15 @@ namespace graphene { namespace chain {
void apply_block( const signed_block& next_block, uint32_t skip = skip_nothing ); void apply_block( const signed_block& next_block, uint32_t skip = skip_nothing );
processed_transaction apply_transaction( const signed_transaction& trx, uint32_t skip = skip_nothing ); processed_transaction apply_transaction( const signed_transaction& trx, uint32_t skip = skip_nothing );
void _apply_block( const signed_block& next_block );
processed_transaction _apply_transaction( const signed_transaction& trx );
operation_result apply_operation( transaction_evaluation_state& eval_state, const operation& op ); operation_result apply_operation( transaction_evaluation_state& eval_state, const operation& op );
///Steps involved in applying a new block ///Steps involved in applying a new block
///@{ ///@{
const witness_object& validate_block_header( const signed_block& next_block )const; const witness_object& validate_block_header( uint32_t skip, const signed_block& next_block )const;
const witness_object& _validate_block_header( const signed_block& next_block )const;
void create_block_summary(const signed_block& next_block); void create_block_summary(const signed_block& next_block);
//////////////////// db_update.cpp //////////////////// //////////////////// db_update.cpp ////////////////////
@ -419,6 +474,8 @@ namespace graphene { namespace chain {
vector<uint64_t> _witness_count_histogram_buffer; vector<uint64_t> _witness_count_histogram_buffer;
vector<uint64_t> _committee_count_histogram_buffer; vector<uint64_t> _committee_count_histogram_buffer;
uint64_t _total_voting_stake; uint64_t _total_voting_stake;
node_property_object _node_property_object;
}; };
namespace detail namespace detail

View file

@ -36,6 +36,6 @@ namespace graphene { namespace chain {
node_property_object() : skip_flags(0) {} node_property_object() : skip_flags(0) {}
~node_property_object(){} ~node_property_object(){}
bool skip_authority_check; uint32_t skip_flags;
}; };
} } // graphene::chain } } // graphene::chain