void account_history_plugin_impl::update_account_histories( const signed_block& b ) { graphene::chain::database& db = database(); const vector<operation_history_object>& hist = db.get_applied_operations(); for( auto op : hist ) { // add to the operation history index const auto& oho = db.create<operation_history_object>( [&]( operation_history_object& h ){ h = op; }); // get the set of accounts this operation applies to flat_set<account_id_type> impacted; vector<authority> other; operation_get_required_authorities( op.op, impacted, impacted, other ); op.op.visit( operation_get_impacted_accounts( oho, _self, impacted ) ); for( auto& a : other ) for( auto& item : a.account_auths ) impacted.insert( item.first ); // for each operation this account applies to that is in the config link it into the history if( _tracked_accounts.size() == 0 ) { for( auto& account_id : impacted ) { // we don't do index_account_keys here anymore, because // that indexing now happens in observers' post_evaluate() // add history const auto& stats_obj = account_id(db).statistics(db); const auto& ath = db.create<account_transaction_history_object>( [&]( account_transaction_history_object& obj ){ obj.operation_id = oho.id; obj.next = stats_obj.most_recent_op; }); db.modify( stats_obj, [&]( account_statistics_object& obj ){ obj.most_recent_op = ath.id; }); } } else { for( auto account_id : _tracked_accounts ) { if( impacted.find( account_id ) != impacted.end() ) { // add history const auto& stats_obj = account_id(db).statistics(db); const auto& ath = db.create<account_transaction_history_object>( [&]( account_transaction_history_object& obj ){ obj.operation_id = oho.id; obj.next = stats_obj.most_recent_op; }); db.modify( stats_obj, [&]( account_statistics_object& obj ){ obj.most_recent_op = ath.id; }); } } } } }
void verify_authority( const vector<operation>& ops, const flat_set<public_key_type>& sigs, const std::function<const authority*(account_id_type)>& get_active, const std::function<const authority*(account_id_type)>& get_owner, uint32_t max_recursion_depth, bool allow_committe, const flat_set<account_id_type>& active_aprovals, const flat_set<account_id_type>& owner_approvals ) { try { flat_set<account_id_type> required_active; flat_set<account_id_type> required_owner; vector<authority> other; for( const auto& op : ops ) operation_get_required_authorities( op, required_active, required_owner, other ); if( !allow_committe ) GRAPHENE_ASSERT( required_active.find(GRAPHENE_COMMITTEE_ACCOUNT) == required_active.end(), invalid_committee_approval, "Committee account may only propose transactions" ); sign_state s(sigs,get_active); s.max_recursion = max_recursion_depth; for( auto& id : active_aprovals ) s.approved_by.insert( id ); for( auto& id : owner_approvals ) s.approved_by.insert( id ); for( const auto& auth : other ) { GRAPHENE_ASSERT( s.check_authority(&auth), tx_missing_other_auth, "Missing Authority", ("auth",auth)("sigs",sigs) ); } // fetch all of the top level authorities for( auto id : required_active ) { GRAPHENE_ASSERT( s.check_authority(id) || s.check_authority(get_owner(id)), tx_missing_active_auth, "Missing Active Authority ${id}", ("id",id)("auth",*get_active(id))("owner",*get_owner(id)) ); } for( auto id : required_owner ) { GRAPHENE_ASSERT( owner_approvals.find(id) != owner_approvals.end() || s.check_authority(get_owner(id)), tx_missing_owner_auth, "Missing Owner Authority ${id}", ("id",id)("auth",*get_owner(id)) ); } GRAPHENE_ASSERT( !s.remove_unused_signatures(), tx_irrelevant_sig, "Unnecessary signature(s) detected" ); } FC_CAPTURE_AND_RETHROW( (ops)(sigs) ) }
void elasticsearch_plugin_impl::update_account_histories( const signed_block& b ) { graphene::chain::database& db = database(); const vector<optional< operation_history_object > >& hist = db.get_applied_operations(); for( const optional< operation_history_object >& o_op : hist ) { optional <operation_history_object> oho; auto create_oho = [&]() { return optional<operation_history_object>( db.create<operation_history_object>([&](operation_history_object &h) { if (o_op.valid()) { h.op = o_op->op; h.result = o_op->result; h.block_num = o_op->block_num; h.trx_in_block = o_op->trx_in_block; h.op_in_trx = o_op->op_in_trx; h.virtual_op = o_op->virtual_op; } })); }; if( !o_op.valid() ) { _oho_index->use_next_id(); continue; } oho = create_oho(); const operation_history_object& op = *o_op; // get the set of accounts this operation applies to flat_set<account_id_type> impacted; vector<authority> other; operation_get_required_authorities( op.op, impacted, impacted, other ); // fee_payer is added here if( op.op.which() == operation::tag< account_create_operation >::value ) impacted.insert( op.result.get<object_id_type>() ); else graphene::app::operation_get_impacted_accounts( op.op, impacted ); for( auto& a : other ) for( auto& item : a.account_auths ) impacted.insert( item.first ); for( auto& account_id : impacted ) { add_elasticsearch( account_id, oho, b ); } } }
void transaction::get_required_authorities( flat_set<account_id_type>& active, flat_set<account_id_type>& owner, vector<authority>& other )const { for( const auto& op : operations ) operation_get_required_authorities( op, active, owner, other ); }