Update balance evaluator / authority checks

- move balance_claim_evalautor implementation from header
- remove authority check from balance_claim evaluator, added to
other_auths defined by the operation
This commit is contained in:
Daniel Larimer 2015-07-07 11:39:16 -04:00
parent 93aff09685
commit e873d3e650
8 changed files with 77 additions and 54 deletions

2
docs

@ -1 +1 @@
Subproject commit d0d1fd5b5e7eaab29d94b6b0388c5d6673f1a134
Subproject commit f3012a7328227e90da6ded944c3c4bf2a4ab94a0

View file

@ -13,6 +13,7 @@ add_library( graphene_chain
operations.cpp
evaluator.cpp
balance_evaluator.cpp
global_parameters_evaluator.cpp
account_evaluator.cpp
assert_evaluator.cpp

View file

@ -0,0 +1,58 @@
#include <graphene/chain/balance_evaluator.hpp>
namespace graphene { namespace chain {
void_result balance_claim_evaluator::do_evaluate(const balance_claim_operation& op)
{
database& d = db();
balance = &op.balance_to_claim(d);
FC_ASSERT(op.balance_owner_key == balance->owner ||
pts_address(op.balance_owner_key, false, 56) == balance->owner ||
pts_address(op.balance_owner_key, true, 56) == balance->owner ||
pts_address(op.balance_owner_key, false, 0) == balance->owner ||
pts_address(op.balance_owner_key, true, 0) == balance->owner,
"balance_owner_key does not match balance's owner");
if( !(d.get_node_properties().skip_flags & (database::skip_authority_check |
database::skip_transaction_signatures)) )
FC_ASSERT(op.total_claimed.asset_id == balance->asset_type());
if( balance->is_vesting_balance() ) {
if( !balance->vesting_policy->is_withdraw_allowed({balance->balance,
d.head_block_time(),
op.total_claimed}) )
FC_THROW_EXCEPTION(invalid_claim_amount,
"Attempted to claim ${c} from a vesting balance with ${a} available",
("c", op.total_claimed)("a", balance->available(d.head_block_time())));
if( d.head_block_time() - balance->last_claim_date < fc::days(1) )
FC_THROW_EXCEPTION(balance_claimed_too_often,
"Genesis vesting balances may not be claimed more than once per day.");
return {};
}
FC_ASSERT(op.total_claimed == balance->balance);
return {};
}
/**
* @note the fee is always 0 for this particular operation because once the
* balance is claimed it frees up memory and it cannot be used to spam the network
*/
void_result balance_claim_evaluator::do_apply(const balance_claim_operation& op)
{
database& d = db();
if( balance->is_vesting_balance() && op.total_claimed < balance->balance )
d.modify(*balance, [&](balance_object& b) {
b.vesting_policy->on_withdraw({b.balance, d.head_block_time(), op.total_claimed});
b.balance -= op.total_claimed;
b.last_claim_date = d.head_block_time();
});
else
d.remove(*balance);
d.adjust_balance(op.deposit_to_account, op.total_claimed);
return {};
}
} } // namespace graphene::chain

View file

@ -97,7 +97,7 @@ database& generic_evaluator::db()const { return trx_state->db(); }
FC_ASSERT(verify_authority(id(db()), authority::owner), "", ("id", id));
for( const auto& auth : other_auths )
FC_ASSERT(trx_state->check_authority(auth));
FC_ASSERT(trx_state->check_authority(auth), "invalid authority", ("auth",auth)("sigs",trx_state->_sigs));
} FC_CAPTURE_AND_RETHROW( (op) ) }

View file

@ -2,7 +2,6 @@
#include <graphene/chain/database.hpp>
#include <graphene/chain/transaction.hpp>
#include <graphene/chain/transaction_evaluation_state.hpp>
#include <graphene/chain/balance_object.hpp>
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/exceptions.hpp>
@ -16,59 +15,13 @@ public:
const balance_object* balance = nullptr;
void_result do_evaluate(const balance_claim_operation& op)
{
database& d = db();
balance = &op.balance_to_claim(d);
FC_ASSERT(op.balance_owner_key == balance->owner ||
pts_address(op.balance_owner_key, false, 56) == balance->owner ||
pts_address(op.balance_owner_key, true, 56) == balance->owner ||
pts_address(op.balance_owner_key, false, 0) == balance->owner ||
pts_address(op.balance_owner_key, true, 0) == balance->owner,
"balance_owner_key does not match balance's owner");
if( !(d.get_node_properties().skip_flags & (database::skip_authority_check |
database::skip_transaction_signatures)) )
FC_ASSERT(trx_state->signed_by(op.balance_owner_key));
FC_ASSERT(op.total_claimed.asset_id == balance->asset_type());
if( balance->is_vesting_balance() ) {
if( !balance->vesting_policy->is_withdraw_allowed({balance->balance,
d.head_block_time(),
op.total_claimed}) )
FC_THROW_EXCEPTION(invalid_claim_amount,
"Attempted to claim ${c} from a vesting balance with ${a} available",
("c", op.total_claimed)("a", balance->available(d.head_block_time())));
if( d.head_block_time() - balance->last_claim_date < fc::days(1) )
FC_THROW_EXCEPTION(balance_claimed_too_often,
"Genesis vesting balances may not be claimed more than once per day.");
return {};
}
FC_ASSERT(op.total_claimed == balance->balance);
return {};
}
void_result do_evaluate(const balance_claim_operation& op);
/**
* @note the fee is always 0 for this particular operation because once the
* balance is claimed it frees up memory and it cannot be used to spam the network
*/
void_result do_apply(const balance_claim_operation& op)
{
database& d = db();
if( balance->is_vesting_balance() && op.total_claimed < balance->balance )
d.modify(*balance, [&](balance_object& b) {
b.vesting_policy->on_withdraw({b.balance, d.head_block_time(), op.total_claimed});
b.balance -= op.total_claimed;
b.last_claim_date = d.head_block_time();
});
else
d.remove(*balance);
d.adjust_balance(op.deposit_to_account, op.total_claimed);
return {};
}
void_result do_apply(const balance_claim_operation& op);
};
} } // graphene::chain

View file

@ -842,6 +842,11 @@ struct required_auth_visitor
/** for most operations this is a no-op */
template<typename T>
void operator()(const T& )const {}
void operator()( const balance_claim_operation& o )const
{
result.push_back( authority( 1, o.balance_owner_key, 1 ) );
}
};
struct required_active_visitor

View file

@ -53,7 +53,13 @@ namespace graphene { namespace chain {
}
bool transaction_evaluation_state::check_authority( const authority& au, authority::classification auth_class, int depth )
{
{ try {
if( (!_is_proposed_trx) && (_db->get_node_properties().skip_flags & database::skip_authority_check) )
return true;
if( (!_is_proposed_trx) && (_db->get_node_properties().skip_flags & database::skip_transaction_signatures) )
return true;
uint32_t total_weight = 0;
for( const auto& auth : au.account_auths )
{
@ -86,7 +92,7 @@ namespace graphene { namespace chain {
}
return total_weight >= au.weight_threshold;
}
} FC_CAPTURE_AND_RETHROW( (au)(auth_class)(depth) ) }
bool transaction_evaluation_state::signed_by(const public_key_type& k)
{

@ -1 +1 @@
Subproject commit 1ce9f4c37e6d3b7672ca9cfb152d236085f31f74
Subproject commit 443544be4f58f47e6432a2676ff81d8b782ce1b6