Merge branches '492-bugfix-close-logic', '550-cleanup-remove-evaluation-observer' and '581-cleanup-object-operators' into develop

This commit is contained in:
theoreticalbts 2016-02-15 16:01:27 -05:00
commit 4a6de2fba7
7 changed files with 28 additions and 163 deletions

View file

@ -417,9 +417,10 @@ void database::pop_block()
auto head_id = head_block_id(); auto head_id = head_block_id();
optional<signed_block> head_block = fetch_block_by_id( head_id ); optional<signed_block> head_block = fetch_block_by_id( head_id );
GRAPHENE_ASSERT( head_block.valid(), pop_empty_chain, "there are no blocks to pop" ); GRAPHENE_ASSERT( head_block.valid(), pop_empty_chain, "there are no blocks to pop" );
pop_undo();
_block_id_to_block.remove( head_id );
_fork_db.pop_block(); _fork_db.pop_block();
_block_id_to_block.remove( head_id );
pop_undo();
_popped_tx.insert( _popped_tx.begin(), head_block->transactions.begin(), head_block->transactions.end() ); _popped_tx.insert( _popped_tx.begin(), head_block->transactions.begin(), head_block->transactions.end() );

View file

@ -38,7 +38,10 @@ void fork_database::reset()
void fork_database::pop_block() void fork_database::pop_block()
{ {
if( _head ) _head = _head->prev.lock(); FC_ASSERT( _head, "no blocks to pop" );
auto prev = _head->prev.lock();
FC_ASSERT( prev, "poping block would leave head block null" );
_head = prev;
} }
void fork_database::start_block(signed_block b) void fork_database::start_block(signed_block b)

View file

@ -26,9 +26,9 @@
namespace graphene { namespace chain { namespace graphene { namespace chain {
class transfer_to_blind_operation; struct transfer_to_blind_operation;
class transfer_from_blind_operation; struct transfer_from_blind_operation;
class blind_transfer_operation; struct blind_transfer_operation;
class transfer_to_blind_evaluator : public evaluator<transfer_to_blind_evaluator> class transfer_to_blind_evaluator : public evaluator<transfer_to_blind_evaluator>
{ {

View file

@ -273,14 +273,6 @@ namespace graphene { namespace chain {
operation::tag<typename EvaluatorType::operation_type>::value].reset( new op_evaluator_impl<EvaluatorType>() ); operation::tag<typename EvaluatorType::operation_type>::value].reset( new op_evaluator_impl<EvaluatorType>() );
} }
template<typename EvaluatorType>
void register_evaluation_observer( evaluation_observer& observer )
{
unique_ptr<op_evaluator>& op_eval = _operation_evaluators[operation::tag<typename EvaluatorType::operation_type>::value];
op_eval->eval_observers.push_back( &observer );
return;
}
//////////////////// db_balance.cpp //////////////////// //////////////////// db_balance.cpp ////////////////////
/** /**

View file

@ -33,47 +33,6 @@ namespace graphene { namespace chain {
class generic_evaluator; class generic_evaluator;
class transaction_evaluation_state; class transaction_evaluation_state;
/**
* Observes evaluation events, providing
* pre- and post-evaluation hooks.
*
* Every call to pre_evaluate() is followed by
* a call to either post_evaluate() or evaluation_failed().
*
* A subclass which needs to do a "diff" can gather some
* "before" state into its members in pre_evaluate(),
* then post_evaluate() will have both "before"
* and "after" state, and will be able to do the diff.
*
* evaluation_failed() is a cleanup method which notifies
* the subclass to "throw away" the diff.
*/
class evaluation_observer
{
public:
virtual ~evaluation_observer(){}
virtual void pre_evaluate(const transaction_evaluation_state& eval_state,
const operation& op,
bool apply,
generic_evaluator* ge)
{}
virtual void post_evaluate(const transaction_evaluation_state& eval_state,
const operation& op,
bool apply,
generic_evaluator* ge,
const operation_result& result)
{}
virtual void evaluation_failed(const transaction_evaluation_state& eval_state,
const operation& op,
bool apply,
generic_evaluator* ge,
const operation_result& result)
{}
};
class generic_evaluator class generic_evaluator
{ {
public: public:
@ -157,8 +116,6 @@ namespace graphene { namespace chain {
public: public:
virtual ~op_evaluator(){} virtual ~op_evaluator(){}
virtual operation_result evaluate(transaction_evaluation_state& eval_state, const operation& op, bool apply) = 0; virtual operation_result evaluate(transaction_evaluation_state& eval_state, const operation& op, bool apply) = 0;
vector<evaluation_observer*> eval_observers;
}; };
template<typename T> template<typename T>
@ -167,57 +124,8 @@ namespace graphene { namespace chain {
public: public:
virtual operation_result evaluate(transaction_evaluation_state& eval_state, const operation& op, bool apply = true) override virtual operation_result evaluate(transaction_evaluation_state& eval_state, const operation& op, bool apply = true) override
{ {
// fc::exception from observers are suppressed.
// fc::exception from evaluation is deferred (re-thrown
// after all observers receive evaluation_failed)
T eval; T eval;
shared_ptr<fc::exception> evaluation_exception; return eval.start_evaluate(eval_state, op, apply);
size_t observer_count = 0;
operation_result result;
for( const auto& obs : eval_observers )
{
try
{
obs->pre_evaluate(eval_state, op, apply, &eval);
}
catch( const fc::exception& e )
{
elog( "suppressed exception in observer pre method:\n${e}", ( "e", e.to_detail_string() ) );
}
observer_count++;
}
try
{
result = eval.start_evaluate(eval_state, op, apply);
}
catch( const fc::exception& e )
{
evaluation_exception = e.dynamic_copy_exception();
}
while( observer_count > 0 )
{
--observer_count;
const auto& obs = eval_observers[observer_count];
try
{
if( evaluation_exception )
obs->post_evaluate(eval_state, op, apply, &eval, result);
else
obs->evaluation_failed(eval_state, op, apply, &eval, result);
}
catch( const fc::exception& e )
{
elog( "suppressed exception in observer post method:\n${e}", ( "e", e.to_detail_string() ) );
}
}
if( evaluation_exception )
evaluation_exception->dynamic_rethrow_exception();
return result;
} }
}; };

View file

@ -31,9 +31,9 @@ namespace graphene { namespace chain {
class asset_object; class asset_object;
class asset_bitasset_data_object; class asset_bitasset_data_object;
class call_order_object; class call_order_object;
class call_order_update_operation; struct call_order_update_operation;
class limit_order_cancel_operation; struct limit_order_cancel_operation;
class limit_order_create_operation; struct limit_order_create_operation;
class limit_order_create_evaluator : public evaluator<limit_order_create_evaluator> class limit_order_create_evaluator : public evaluator<limit_order_create_evaluator>
{ {

View file

@ -53,37 +53,22 @@ namespace graphene { namespace db {
bool is_null()const { return number == 0; } bool is_null()const { return number == 0; }
explicit operator uint64_t()const { return number; } explicit operator uint64_t()const { return number; }
friend bool operator == ( const object_id_type& a, const object_id_type& b ) friend bool operator == ( const object_id_type& a, const object_id_type& b ) { return a.number == b.number; }
{ friend bool operator != ( const object_id_type& a, const object_id_type& b ) { return a.number != b.number; }
return a.number == b.number; friend bool operator < ( const object_id_type& a, const object_id_type& b ) { return a.number < b.number; }
} friend bool operator > ( const object_id_type& a, const object_id_type& b ) { return a.number > b.number; }
friend bool operator != ( const object_id_type& a, const object_id_type& b )
{
return a.number != b.number;
}
object_id_type& operator++(int) { ++number; return *this; } object_id_type& operator++(int) { ++number; return *this; }
object_id_type& operator++() { ++number; return *this; } object_id_type& operator++() { ++number; return *this; }
friend object_id_type operator+(const object_id_type& a, int delta ) { friend object_id_type operator+(const object_id_type& a, int delta ) {
return object_id_type( a.space(), a.type(), a.instance() + delta ); return object_id_type( a.space(), a.type(), a.instance() + delta );
} }
friend object_id_type operator+(const object_id_type& a, int64_t delta ) { friend object_id_type operator+(const object_id_type& a, int64_t delta ) {
return object_id_type( a.space(), a.type(), a.instance() + delta ); return object_id_type( a.space(), a.type(), a.instance() + delta );
} }
friend size_t hash_value( object_id_type v ) { return std::hash<uint64_t>()(v.number); } friend size_t hash_value( object_id_type v ) { return std::hash<uint64_t>()(v.number); }
friend bool operator< ( const object_id_type& a, const object_id_type& b )
{
return a.number < b.number;
}
friend bool operator> ( const object_id_type& a, const object_id_type& b )
{
return a.number > b.number;
}
template< typename T > template< typename T >
bool is() const bool is() const
{ {
@ -134,40 +119,16 @@ namespace graphene { namespace db {
template<typename DB> template<typename DB>
const T& operator()(const DB& db)const { return db.get(*this); } const T& operator()(const DB& db)const { return db.get(*this); }
friend bool operator != ( const object_id& a, const object_id& b ) friend bool operator == ( const object_id& a, const object_id& b ) { return a.instance == b.instance; }
{ friend bool operator != ( const object_id& a, const object_id& b ) { return a.instance != b.instance; }
return a.instance != b.instance; friend bool operator == ( const object_id_type& a, const object_id& b ) { return a == object_id_type(b); }
} friend bool operator != ( const object_id_type& a, const object_id& b ) { return a != object_id_type(b); }
friend bool operator != ( const object_id_type& a, const object_id& b ) friend bool operator == ( const object_id& b, const object_id_type& a ) { return a == object_id_type(b); }
{ friend bool operator != ( const object_id& b, const object_id_type& a ) { return a != object_id_type(b); }
return a != object_id_type(b);
}
friend bool operator != ( const object_id& a, const object_id_type& b )
{
return object_id_type(a) != b;
}
friend bool operator < ( const object_id& a, const object_id& b ) { return a.instance.value < b.instance.value; }
friend bool operator > ( const object_id& a, const object_id& b ) { return a.instance.value > b.instance.value; }
friend bool operator == ( const object_id& a, const object_id& b )
{
return a.instance == b.instance;
}
friend bool operator == ( const object_id_type& a, const object_id& b )
{
return a == object_id_type(b);
}
friend bool operator == ( const object_id& b, const object_id_type& a )
{
return a == object_id_type(b);
}
friend bool operator < ( const object_id& a, const object_id& b )
{
return a.instance.value < b.instance.value;
}
friend bool operator > ( const object_id& a, const object_id& b )
{
return a.instance.value > b.instance.value;
}
friend size_t hash_value( object_id v ) { return std::hash<uint64_t>()(v.instance.value); } friend size_t hash_value( object_id v ) { return std::hash<uint64_t>()(v.instance.value); }
unsigned_int instance; unsigned_int instance;