set<public_key_type> signed_transaction::get_required_signatures( const chain_id_type& chain_id, const flat_set<public_key_type>& available_keys, 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 )const { flat_set<account_id_type> required_active; flat_set<account_id_type> required_owner; vector<authority> other; get_required_authorities( required_active, required_owner, other ); sign_state s(get_signature_keys( chain_id ),get_active,available_keys); s.max_recursion = max_recursion_depth; for( const auto& auth : other ) s.check_authority(&auth); for( auto& owner : required_owner ) s.check_authority( get_owner( owner ) ); for( auto& active : required_active ) s.check_authority( active ); s.remove_unused_signatures(); set<public_key_type> result; for( auto& provided_sig : s.provided_signatures ) if( available_keys.find( provided_sig.first ) != available_keys.end() ) result.insert( provided_sig.first ); return result; }
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) ) }
bool has_permission( account_name n )const { return _provided_auths.find(n) != _provided_auths.end(); }