Merge branch 'auth_refactor'
This commit is contained in:
commit
2492df752d
12 changed files with 179 additions and 154 deletions
|
|
@ -43,7 +43,6 @@ add_library( graphene_chain
|
|||
proposal_object.cpp
|
||||
vesting_balance_object.cpp
|
||||
|
||||
transaction_evaluation_state.cpp
|
||||
fork_database.cpp
|
||||
block_database.cpp
|
||||
|
||||
|
|
|
|||
|
|
@ -215,20 +215,6 @@ processed_transaction database::push_proposal(const proposal_object& proposal)
|
|||
transaction_evaluation_state eval_state(this);
|
||||
eval_state._is_proposed_trx = true;
|
||||
|
||||
//Inject the approving authorities into the transaction eval state
|
||||
std::transform(proposal.required_active_approvals.begin(),
|
||||
proposal.required_active_approvals.end(),
|
||||
std::inserter(eval_state.approved_by, eval_state.approved_by.begin()),
|
||||
[]( account_id_type id ) {
|
||||
return std::make_pair(id, authority::active);
|
||||
});
|
||||
std::transform(proposal.required_owner_approvals.begin(),
|
||||
proposal.required_owner_approvals.end(),
|
||||
std::inserter(eval_state.approved_by, eval_state.approved_by.begin()),
|
||||
[]( account_id_type id ) {
|
||||
return std::make_pair(id, authority::owner);
|
||||
});
|
||||
|
||||
eval_state.operation_results.reserve(proposal.proposed_transaction.operations.size());
|
||||
processed_transaction ptrx(proposal.proposed_transaction);
|
||||
eval_state._trx = &ptrx;
|
||||
|
|
@ -482,16 +468,11 @@ processed_transaction database::_apply_transaction(const signed_transaction& trx
|
|||
const chain_parameters& chain_parameters = get_global_properties().parameters;
|
||||
eval_state._trx = &trx;
|
||||
|
||||
if( !(skip & skip_transaction_signatures) )
|
||||
if( !(skip & (skip_transaction_signatures | skip_authority_check) ) )
|
||||
{
|
||||
eval_state._sigs.reserve(trx.signatures.size());
|
||||
|
||||
for( const auto& sig : trx.signatures )
|
||||
{
|
||||
FC_ASSERT( eval_state._sigs.insert(std::make_pair(public_key_type(fc::ecc::public_key(sig, trx.digest())),
|
||||
false)).second,
|
||||
"Multiple signatures by same key detected" );
|
||||
}
|
||||
auto get_active = [&]( account_id_type id ) { return &id(*this).active; };
|
||||
auto get_owner = [&]( account_id_type id ) { return &id(*this).owner; };
|
||||
trx.verify_authority( get_active, get_owner );
|
||||
}
|
||||
|
||||
//Skip all manner of expiration and TaPoS checking if we're on block 1; It's impossible that the transaction is
|
||||
|
|
@ -537,15 +518,6 @@ processed_transaction database::_apply_transaction(const signed_transaction& trx
|
|||
auto range = index.equal_range(GRAPHENE_TEMP_ACCOUNT);
|
||||
std::for_each(range.first, range.second, [](const account_balance_object& b) { FC_ASSERT(b.balance == 0); });
|
||||
|
||||
//Make sure all signatures were needed to validate the transaction
|
||||
if( !(skip & (skip_transaction_signatures|skip_authority_check)) )
|
||||
{
|
||||
for( const auto& item : eval_state._sigs )
|
||||
{
|
||||
FC_ASSERT( item.second, "All signatures must be used", ("item",item) );
|
||||
}
|
||||
}
|
||||
|
||||
return ptrx;
|
||||
} FC_CAPTURE_AND_RETHROW( (trx) ) }
|
||||
|
||||
|
|
@ -564,7 +536,7 @@ operation_result database::apply_operation(transaction_evaluation_state& eval_st
|
|||
auto result = eval->evaluate( eval_state, op, true );
|
||||
set_applied_operation_result( op_id, result );
|
||||
return result;
|
||||
} FC_CAPTURE_AND_RETHROW( (eval_state._sigs) ) }
|
||||
} FC_CAPTURE_AND_RETHROW( ) }
|
||||
|
||||
const witness_object& database::validate_block_header( uint32_t skip, const signed_block& next_block )const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ database& generic_evaluator::db()const { return trx_state->db(); }
|
|||
operation_result generic_evaluator::start_evaluate( transaction_evaluation_state& eval_state, const operation& op, bool apply )
|
||||
{ try {
|
||||
trx_state = &eval_state;
|
||||
check_required_authorities(op);
|
||||
//check_required_authorities(op);
|
||||
auto result = evaluate( op );
|
||||
|
||||
if( apply ) result = this->apply( op );
|
||||
|
|
@ -77,6 +77,7 @@ database& generic_evaluator::db()const { return trx_state->db(); }
|
|||
});
|
||||
} FC_CAPTURE_AND_RETHROW() }
|
||||
|
||||
/*
|
||||
bool generic_evaluator::verify_authority( const account_object& a, authority::classification c )
|
||||
{ try {
|
||||
return trx_state->check_authority( a, c );
|
||||
|
|
@ -117,6 +118,7 @@ database& generic_evaluator::db()const { return trx_state->db(); }
|
|||
}
|
||||
|
||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||
*/
|
||||
|
||||
void generic_evaluator::verify_authority_accounts( const authority& a )const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ namespace graphene { namespace chain {
|
|||
|
||||
database& db()const;
|
||||
|
||||
void check_required_authorities(const operation& op);
|
||||
//void check_required_authorities(const operation& op);
|
||||
protected:
|
||||
/**
|
||||
* @brief Fetch objects relevant to fee payer and set pointer members
|
||||
|
|
@ -98,7 +98,7 @@ namespace graphene { namespace chain {
|
|||
/// Pays the fee and returns the number of CORE asset that were paid.
|
||||
void pay_fee();
|
||||
|
||||
bool verify_authority(const account_object&, authority::classification);
|
||||
//bool verify_authority(const account_object&, authority::classification);
|
||||
object_id_type get_relative_id( object_id_type rel_id )const;
|
||||
|
||||
void verify_authority_accounts( const authority& a )const;
|
||||
|
|
|
|||
|
|
@ -73,7 +73,9 @@ namespace graphene { namespace chain {
|
|||
FC_DECLARE_DERIVED_EXCEPTION( tx_missing_active_auth, graphene::chain::transaction_exception, 3030001, "missing required active authority" )
|
||||
FC_DECLARE_DERIVED_EXCEPTION( tx_missing_owner_auth, graphene::chain::transaction_exception, 3030002, "missing required owner authority" )
|
||||
FC_DECLARE_DERIVED_EXCEPTION( tx_missing_other_auth, graphene::chain::transaction_exception, 3030003, "missing required other authority" )
|
||||
//FC_DECLARE_DERIVED_EXCEPTION( tx_irrelevant_authority, graphene::chain::transaction_exception, 3030004, "irrelevant authority" )
|
||||
FC_DECLARE_DERIVED_EXCEPTION( tx_irrelevant_authority, graphene::chain::transaction_exception, 3030004, "irrelevant authority" )
|
||||
FC_DECLARE_DERIVED_EXCEPTION( invalid_committee_approval, graphene::chain::transaction_exception, 3030005,
|
||||
"committee account cannot directly approve transaction" )
|
||||
|
||||
FC_DECLARE_DERIVED_EXCEPTION( invalid_pts_address, graphene::chain::utility_exception, 3060001, "invalid pts address" )
|
||||
FC_DECLARE_DERIVED_EXCEPTION( insufficient_feeds, graphene::chain::chain_exception, 37006, "insufficient feeds" )
|
||||
|
|
|
|||
|
|
@ -118,23 +118,19 @@ namespace graphene { namespace chain {
|
|||
|
||||
/**
|
||||
* The purpose of this method is to identify the minimal subset of @ref available_keys that are
|
||||
* required to sign
|
||||
* required to sign given the signatures that are already provided.
|
||||
*/
|
||||
set<public_key_type> get_required_signatures( const set<public_key_type>& available_keys,
|
||||
const map<account_id_type,authority>& active_authorities,
|
||||
const map<account_id_type,authority>& owner_authorities )const;
|
||||
set<public_key_type> get_required_signatures( 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 = GRAPHENE_MAX_SIG_CHECK_DEPTH
|
||||
)const;
|
||||
|
||||
/**
|
||||
* Given a set of private keys sign this transaction with a minimial subset of required keys.
|
||||
*
|
||||
* @pram get_auth - used to fetch the active authority required for an account referenced by another authority
|
||||
*/
|
||||
void sign( const vector<private_key_type>& keys,
|
||||
const std::function<const authority*(account_id_type)>& get_active,
|
||||
const std::function<const authority*(account_id_type)>& get_owner );
|
||||
|
||||
bool verify( const std::function<const authority*(account_id_type)>& get_active,
|
||||
const std::function<const authority*(account_id_type)>& get_owner )const;
|
||||
void verify_authority( const std::function<const authority*(account_id_type)>& get_active,
|
||||
const std::function<const authority*(account_id_type)>& get_owner,
|
||||
uint32_t max_recursion = GRAPHENE_MAX_SIG_CHECK_DEPTH )const;
|
||||
|
||||
flat_set<public_key_type> get_signature_keys()const;
|
||||
|
||||
vector<signature_type> signatures;
|
||||
|
||||
|
|
@ -142,6 +138,14 @@ namespace graphene { namespace chain {
|
|||
void clear() { operations.clear(); signatures.clear(); }
|
||||
};
|
||||
|
||||
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 = GRAPHENE_MAX_SIG_CHECK_DEPTH,
|
||||
bool allow_committe = false,
|
||||
const flat_set<account_id_type>& active_aprovals = flat_set<account_id_type>(),
|
||||
const flat_set<account_id_type>& owner_approvals = flat_set<account_id_type>());
|
||||
|
||||
/**
|
||||
* @brief captures the result of evaluating the operations contained in the transaction
|
||||
*
|
||||
|
|
|
|||
|
|
@ -32,30 +32,10 @@ namespace graphene { namespace chain {
|
|||
transaction_evaluation_state( database* db = nullptr )
|
||||
:_db(db){}
|
||||
|
||||
bool check_authority(const account_object&,
|
||||
authority::classification auth_class = authority::active,
|
||||
int depth = 0);
|
||||
|
||||
bool check_authority(const authority&,
|
||||
authority::classification auth_class = authority::active,
|
||||
int depth = 0);
|
||||
|
||||
database& db()const { FC_ASSERT( _db ); return *_db; }
|
||||
|
||||
bool signed_by(const public_key_type& k);
|
||||
bool signed_by(const address& k);
|
||||
|
||||
/// cached approval (accounts and keys)
|
||||
flat_set<pair<object_id_type,authority::classification>> approved_by;
|
||||
|
||||
/// Used to look up new objects using transaction relative IDs
|
||||
database& db()const { assert( _db ); return *_db; }
|
||||
vector<operation_result> operation_results;
|
||||
|
||||
/**
|
||||
* When an address is referenced via check authority it is flagged as being used, all addresses must be
|
||||
* flagged as being used or the transaction will fail.
|
||||
*/
|
||||
flat_map<public_key_type, bool> _sigs;
|
||||
const signed_transaction* _trx = nullptr;
|
||||
database* _db = nullptr;
|
||||
bool _is_proposed_trx = false;
|
||||
|
|
|
|||
|
|
@ -121,7 +121,6 @@ void_result proposal_update_evaluator::do_evaluate(const proposal_update_operati
|
|||
}
|
||||
|
||||
/* All authority checks happen outside of evaluators
|
||||
*/
|
||||
if( (d.get_node_properties().skip_flags & database::skip_authority_check) == 0 )
|
||||
{
|
||||
for( const auto& id : o.key_approvals_to_add )
|
||||
|
|
@ -133,6 +132,7 @@ void_result proposal_update_evaluator::do_evaluate(const proposal_update_operati
|
|||
FC_ASSERT( trx_state->signed_by(id) );
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return void_result();
|
||||
} FC_CAPTURE_AND_RETHROW( (o) ) }
|
||||
|
|
|
|||
|
|
@ -24,6 +24,27 @@ namespace graphene { namespace chain {
|
|||
bool proposal_object::is_authorized_to_execute(database& db) const
|
||||
{
|
||||
transaction_evaluation_state dry_run_eval(&db);
|
||||
|
||||
try {
|
||||
verify_authority( proposed_transaction.operations,
|
||||
available_key_approvals,
|
||||
[&]( account_id_type id ){ return &id(db).active; },
|
||||
[&]( account_id_type id ){ return &id(db).owner; },
|
||||
GRAPHENE_MAX_SIG_CHECK_DEPTH, // TODO make chain param
|
||||
true, /* allow committeee */
|
||||
available_active_approvals,
|
||||
available_owner_approvals );
|
||||
}
|
||||
catch ( const fc::exception& e )
|
||||
{
|
||||
//idump((available_active_approvals));
|
||||
//wlog((e.to_detail_string()));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
|
||||
/*
|
||||
dry_run_eval._is_proposed_trx = true;
|
||||
std::transform(available_active_approvals.begin(), available_active_approvals.end(),
|
||||
std::inserter(dry_run_eval.approved_by, dry_run_eval.approved_by.end()), [](object_id_type id) {
|
||||
|
|
@ -50,8 +71,8 @@ bool proposal_object::is_authorized_to_execute(database& db) const
|
|||
for( const auto& id : required_owner_approvals )
|
||||
if( !dry_run_eval.check_authority(id(db), authority::owner) )
|
||||
return false;
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@
|
|||
* 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.
|
||||
*/
|
||||
#include <graphene/chain/protocol/transaction.hpp>
|
||||
#include <graphene/chain/exceptions.hpp>
|
||||
#include <graphene/chain/protocol/fee_schedule.hpp>
|
||||
#include <graphene/chain/protocol/fee_schedule.hpp>
|
||||
#include <fc/io/raw.hpp>
|
||||
#include <fc/bitutil.hpp>
|
||||
|
|
@ -79,6 +80,9 @@ void transaction::get_required_authorities( flat_set<account_id_type>& active, f
|
|||
operation_get_required_authorities( op, active, owner, other );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
struct sign_state
|
||||
{
|
||||
/** returns true if we have a signature for this key or can
|
||||
|
|
@ -86,20 +90,21 @@ struct sign_state
|
|||
*/
|
||||
bool signed_by( const public_key_type& k )
|
||||
{
|
||||
auto itr = signatures.find(k);
|
||||
if( itr == signatures.end() )
|
||||
auto itr = provided_signatures.find(k);
|
||||
if( itr == provided_signatures.end() )
|
||||
{
|
||||
auto pk = keys.find(k);
|
||||
if( pk != keys.end() )
|
||||
{
|
||||
signatures[k] = trx.sign(pk->second);
|
||||
checked_sigs.insert(k);
|
||||
return true;
|
||||
}
|
||||
auto pk = available_keys.find(k);
|
||||
if( pk != available_keys.end() )
|
||||
return provided_signatures[k] = true;
|
||||
return false;
|
||||
}
|
||||
checked_sigs.insert(k);
|
||||
return true;
|
||||
return itr->second = true;
|
||||
}
|
||||
|
||||
bool check_authority( account_id_type id )
|
||||
{
|
||||
if( approved_by.find(id) != approved_by.end() ) return true;
|
||||
return check_authority( get_active(id) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -124,7 +129,7 @@ struct sign_state
|
|||
{
|
||||
if( approved_by.find(a.first) == approved_by.end() )
|
||||
{
|
||||
if( depth == GRAPHENE_MAX_SIG_CHECK_DEPTH )
|
||||
if( depth == max_recursion )
|
||||
return false;
|
||||
if( check_authority( get_active( a.first ), depth+1 ) )
|
||||
{
|
||||
|
|
@ -147,89 +152,127 @@ struct sign_state
|
|||
bool remove_unused_signatures()
|
||||
{
|
||||
vector<public_key_type> remove_sigs;
|
||||
for( const auto& sig : signatures )
|
||||
if( checked_sigs.find(sig.first) == checked_sigs.end() )
|
||||
remove_sigs.push_back( sig.first );
|
||||
for( const auto& sig : provided_signatures )
|
||||
if( !sig.second ) remove_sigs.push_back( sig.first );
|
||||
|
||||
for( auto& sig : remove_sigs )
|
||||
signatures.erase(sig);
|
||||
provided_signatures.erase(sig);
|
||||
|
||||
return remove_sigs.size() != 0;
|
||||
}
|
||||
|
||||
sign_state( const signed_transaction& t, const std::function<const authority*(account_id_type)>& a,
|
||||
const vector<private_key_type>& kys = vector<private_key_type>() )
|
||||
:trx(t),get_active(a)
|
||||
sign_state( const flat_set<public_key_type>& sigs,
|
||||
const std::function<const authority*(account_id_type)>& a,
|
||||
const flat_set<public_key_type>& keys = flat_set<public_key_type>() )
|
||||
:get_active(a),available_keys(keys)
|
||||
{
|
||||
auto d = trx.digest();
|
||||
for( const auto& sig : trx.signatures )
|
||||
signatures[ fc::ecc::public_key( sig, d ) ] = sig;
|
||||
|
||||
for( const auto& key : kys )
|
||||
keys[key.get_public_key()] = key;
|
||||
for( const auto& key : sigs )
|
||||
provided_signatures[ key ] = false;
|
||||
approved_by.insert( GRAPHENE_TEMP_ACCOUNT );
|
||||
}
|
||||
|
||||
const signed_transaction& trx;
|
||||
const std::function<const authority*(account_id_type)>& get_active;
|
||||
const flat_set<public_key_type>& available_keys;
|
||||
|
||||
flat_map<public_key_type,private_key_type> keys;
|
||||
flat_map<public_key_type,signature_type> signatures;
|
||||
|
||||
set<public_key_type> checked_sigs;
|
||||
flat_set<account_id_type> approved_by;
|
||||
|
||||
flat_map<public_key_type,bool> provided_signatures;
|
||||
flat_set<account_id_type> approved_by;
|
||||
uint32_t max_recursion = GRAPHENE_MAX_SIG_CHECK_DEPTH;
|
||||
};
|
||||
|
||||
/**
|
||||
* Given a set of private keys sign this transaction with a minimial subset of required keys.
|
||||
*/
|
||||
void signed_transaction::sign( const vector<private_key_type>& keys,
|
||||
const std::function<const authority*(account_id_type)>& get_active,
|
||||
const std::function<const authority*(account_id_type)>& get_owner )
|
||||
{
|
||||
|
||||
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;
|
||||
get_required_authorities( required_active, required_owner, other );
|
||||
|
||||
sign_state s(*this,get_active,keys);
|
||||
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 )
|
||||
s.check_authority(&auth);
|
||||
for( auto id : required_active )
|
||||
s.check_authority(get_active(id));
|
||||
for( auto id : required_owner )
|
||||
s.check_authority(get_owner(id));
|
||||
|
||||
s.remove_unused_signatures();
|
||||
|
||||
signatures.clear();
|
||||
for( const auto& sig : s.signatures )
|
||||
signatures.push_back(sig.second);
|
||||
}
|
||||
|
||||
bool signed_transaction::verify( const std::function<const authority*(account_id_type)>& get_active,
|
||||
const std::function<const authority*(account_id_type)>& get_owner )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(*this,get_active);
|
||||
|
||||
for( const auto& auth : other )
|
||||
if( !s.check_authority(&auth) )
|
||||
return false;
|
||||
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 )
|
||||
if( !s.check_authority(get_active(id)) )
|
||||
return false;
|
||||
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 )
|
||||
if( !s.check_authority(get_owner(id)) )
|
||||
return false;
|
||||
if( s.remove_unused_signatures() )
|
||||
return false;
|
||||
return true;
|
||||
GRAPHENE_ASSERT( owner_approvals.find(id) != owner_approvals.end() ||
|
||||
s.check_authority(get_owner(id)),
|
||||
tx_missing_other_auth, "Missing Owner Authority ${id}", ("id",id)("auth",*get_owner(id)) );
|
||||
|
||||
FC_ASSERT( !s.remove_unused_signatures(), "Unnecessary signatures detected" );
|
||||
} FC_CAPTURE_AND_RETHROW( (ops)(sigs) ) }
|
||||
|
||||
|
||||
flat_set<public_key_type> signed_transaction::get_signature_keys()const
|
||||
{ try {
|
||||
auto d = digest();
|
||||
flat_set<public_key_type> result;
|
||||
for( const auto& sig : signatures )
|
||||
FC_ASSERT( result.insert( fc::ecc::public_key(sig,d) ).second, "Duplicate Signature detected" );
|
||||
return result;
|
||||
} FC_CAPTURE_AND_RETHROW() }
|
||||
|
||||
|
||||
|
||||
set<public_key_type> signed_transaction::get_required_signatures( 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(),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 signed_transaction::verify_authority( const std::function<const authority*(account_id_type)>& get_active,
|
||||
const std::function<const authority*(account_id_type)>& get_owner,
|
||||
uint32_t max_recursion )const
|
||||
{ try {
|
||||
graphene::chain::verify_authority( operations, get_signature_keys(), get_active, get_owner, max_recursion );
|
||||
} FC_CAPTURE_AND_RETHROW( (*this) ) }
|
||||
|
||||
} } // graphene::chain
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include <graphene/chain/exceptions.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
/*
|
||||
bool transaction_evaluation_state::check_authority( const account_object& account, authority::classification auth_class, int depth )
|
||||
{
|
||||
if( (!_is_proposed_trx) && (_db->get_node_properties().skip_flags & database::skip_authority_check) )
|
||||
|
|
@ -121,5 +122,6 @@ namespace graphene { namespace chain {
|
|||
if( itr->first == k ) return itr->second = true;
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
} } // namespace graphene::chain
|
||||
|
|
|
|||
|
|
@ -340,7 +340,6 @@ BOOST_AUTO_TEST_CASE( proposed_single_account )
|
|||
trx.set_expiration( db.head_block_time() + fc::seconds( 3 * db.get_global_properties().parameters.block_interval ));
|
||||
trx.set_reference_block( db.head_block_id() );
|
||||
|
||||
//idump((moneyman));
|
||||
trx.sign( init_account_priv_key );
|
||||
const proposal_object& proposal = db.get<proposal_object>(PUSH_TX( db, trx ).operation_results.front().get<object_id_type>());
|
||||
|
||||
|
|
@ -353,6 +352,7 @@ BOOST_AUTO_TEST_CASE( proposed_single_account )
|
|||
proposal_update_operation pup;
|
||||
pup.proposal = proposal.id;
|
||||
pup.fee_paying_account = nathan.id;
|
||||
BOOST_TEST_MESSAGE( "Updating the proposal to have nathan's authority" );
|
||||
pup.active_approvals_to_add.insert(nathan.id);
|
||||
|
||||
trx.operations = {pup};
|
||||
|
|
@ -399,13 +399,13 @@ BOOST_AUTO_TEST_CASE( committee_authority )
|
|||
p.parameters.committee_proposal_review_period = fc::days(1).to_seconds();
|
||||
});
|
||||
|
||||
BOOST_TEST_MESSAGE( "transfering 100000 CORE to nathan, signing with committee key" );
|
||||
BOOST_TEST_MESSAGE( "transfering 100000 CORE to nathan, signing with committee key should fail because this requires it to be part of a proposal" );
|
||||
transfer_operation top;
|
||||
top.to = nathan.id;
|
||||
top.amount = asset(100000);
|
||||
trx.operations.push_back(top);
|
||||
sign(trx, committee_key);
|
||||
GRAPHENE_CHECK_THROW(PUSH_TX( db, trx ), fc::exception);
|
||||
GRAPHENE_CHECK_THROW(PUSH_TX( db, trx ), graphene::chain::invalid_committee_approval );
|
||||
|
||||
auto sign = [&] { trx.signatures.clear(); trx.sign(nathan_key); };
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue