Progress #98: add some vesting genesis balance testing

This commit is contained in:
Nathan Hourt 2015-07-06 17:38:37 -04:00
parent ab740d6aaa
commit 24496932d4
5 changed files with 202 additions and 107 deletions

View file

@ -15,9 +15,8 @@ public:
typedef balance_claim_operation operation_type;
const balance_object* balance = nullptr;
asset amount_withdrawn;
asset do_evaluate(const balance_claim_operation& op)
void_result do_evaluate(const balance_claim_operation& op)
{
database& d = db();
balance = &op.balance_to_claim(d);
@ -33,39 +32,42 @@ public:
FC_ASSERT(trx_state->signed_by(op.balance_owner_key));
FC_ASSERT(op.total_claimed.asset_id == balance->asset_type());
if( balance->vesting_policy.valid() ) {
FC_ASSERT(op.total_claimed.amount == 0);
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 amount_withdrawn = balance->vesting_policy->get_allowed_withdraw({balance->balance,
d.head_block_time(),
{}});
return {};
}
FC_ASSERT(op.total_claimed == balance->balance);
return amount_withdrawn = op.total_claimed;
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
*/
asset do_apply(const balance_claim_operation& op)
void_result do_apply(const balance_claim_operation& op)
{
database& d = db();
if( balance->vesting_policy.valid() && amount_withdrawn < balance->balance )
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(), amount_withdrawn});
b.balance -= amount_withdrawn;
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, amount_withdrawn);
return amount_withdrawn;
d.adjust_balance(op.deposit_to_account, op.total_claimed);
return {};
}
};

View file

@ -10,6 +10,14 @@ namespace graphene { namespace chain {
static const uint8_t space_id = protocol_ids;
static const uint8_t type_id = balance_object_type;
bool is_vesting_balance()const
{ return vesting_policy.valid(); }
asset available(fc::time_point_sec now)const
{
return is_vesting_balance()? vesting_policy->get_allowed_withdraw({balance, now, {}})
: balance;
}
address owner;
asset balance;
optional<linear_vesting_policy> vesting_policy;

View file

@ -133,7 +133,7 @@ namespace graphene { namespace chain {
// after all observers receive evaluation_failed)
T eval;
optional< fc::exception > evaluation_exception;
shared_ptr<fc::exception> evaluation_exception;
size_t observer_count = 0;
operation_result result;
@ -156,7 +156,7 @@ namespace graphene { namespace chain {
}
catch( const fc::exception& e )
{
evaluation_exception = e;
evaluation_exception = e.dynamic_copy_exception();
}
while( observer_count > 0 )
@ -165,7 +165,7 @@ namespace graphene { namespace chain {
const auto& obs = eval_observers[observer_count];
try
{
if( !evaluation_exception.valid() )
if( evaluation_exception )
obs->post_evaluate(eval_state, op, apply, &eval, result);
else
obs->evaluation_failed(eval_state, op, apply, &eval, result);
@ -176,8 +176,8 @@ namespace graphene { namespace chain {
}
}
if( evaluation_exception.valid() )
throw *evaluation_exception;
if( evaluation_exception )
evaluation_exception->dynamic_rethrow_exception();
return result;
}
};

View file

@ -22,93 +22,94 @@
namespace graphene { namespace chain {
// registered in chain_database.cpp
FC_DECLARE_EXCEPTION( chain_exception, 30000, "Blockchain Exception" );
FC_DECLARE_DERIVED_EXCEPTION( invalid_pts_address, graphene::chain::chain_exception, 30001, "invalid pts address" );
FC_DECLARE_DERIVED_EXCEPTION( addition_overflow, graphene::chain::chain_exception, 30002, "addition overflow" );
FC_DECLARE_DERIVED_EXCEPTION( subtraction_overflow, graphene::chain::chain_exception, 30003, "subtraction overflow" );
FC_DECLARE_DERIVED_EXCEPTION( asset_type_mismatch, graphene::chain::chain_exception, 30004, "asset/price mismatch" );
FC_DECLARE_DERIVED_EXCEPTION( unsupported_chain_operation, graphene::chain::chain_exception, 30005, "unsupported chain operation" );
FC_DECLARE_DERIVED_EXCEPTION( unknown_transaction, graphene::chain::chain_exception, 30006, "unknown transaction" );
FC_DECLARE_DERIVED_EXCEPTION( duplicate_transaction, graphene::chain::chain_exception, 30007, "duplicate transaction" );
FC_DECLARE_DERIVED_EXCEPTION( zero_amount, graphene::chain::chain_exception, 30008, "zero amount" );
FC_DECLARE_DERIVED_EXCEPTION( zero_price, graphene::chain::chain_exception, 30009, "zero price" );
FC_DECLARE_DERIVED_EXCEPTION( asset_divide_by_self, graphene::chain::chain_exception, 30010, "asset divide by self" );
FC_DECLARE_DERIVED_EXCEPTION( asset_divide_by_zero, graphene::chain::chain_exception, 30011, "asset divide by zero" );
FC_DECLARE_DERIVED_EXCEPTION( new_database_version, graphene::chain::chain_exception, 30012, "new database version" );
FC_DECLARE_DERIVED_EXCEPTION( unlinkable_block, graphene::chain::chain_exception, 30013, "unlinkable block" );
FC_DECLARE_DERIVED_EXCEPTION( price_out_of_range, graphene::chain::chain_exception, 30014, "price out of range" );
FC_DECLARE_EXCEPTION( chain_exception, 30000, "Blockchain Exception" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_pts_address, graphene::chain::chain_exception, 30001, "invalid pts address" )
FC_DECLARE_DERIVED_EXCEPTION( addition_overflow, graphene::chain::chain_exception, 30002, "addition overflow" )
FC_DECLARE_DERIVED_EXCEPTION( subtraction_overflow, graphene::chain::chain_exception, 30003, "subtraction overflow" )
FC_DECLARE_DERIVED_EXCEPTION( asset_type_mismatch, graphene::chain::chain_exception, 30004, "asset/price mismatch" )
FC_DECLARE_DERIVED_EXCEPTION( unsupported_chain_operation, graphene::chain::chain_exception, 30005, "unsupported chain operation" )
FC_DECLARE_DERIVED_EXCEPTION( unknown_transaction, graphene::chain::chain_exception, 30006, "unknown transaction" )
FC_DECLARE_DERIVED_EXCEPTION( duplicate_transaction, graphene::chain::chain_exception, 30007, "duplicate transaction" )
FC_DECLARE_DERIVED_EXCEPTION( zero_amount, graphene::chain::chain_exception, 30008, "zero amount" )
FC_DECLARE_DERIVED_EXCEPTION( zero_price, graphene::chain::chain_exception, 30009, "zero price" )
FC_DECLARE_DERIVED_EXCEPTION( asset_divide_by_self, graphene::chain::chain_exception, 30010, "asset divide by self" )
FC_DECLARE_DERIVED_EXCEPTION( asset_divide_by_zero, graphene::chain::chain_exception, 30011, "asset divide by zero" )
FC_DECLARE_DERIVED_EXCEPTION( new_database_version, graphene::chain::chain_exception, 30012, "new database version" )
FC_DECLARE_DERIVED_EXCEPTION( unlinkable_block, graphene::chain::chain_exception, 30013, "unlinkable block" )
FC_DECLARE_DERIVED_EXCEPTION( price_out_of_range, graphene::chain::chain_exception, 30014, "price out of range" )
FC_DECLARE_DERIVED_EXCEPTION( block_numbers_not_sequential, graphene::chain::chain_exception, 30015, "block numbers not sequential" );
FC_DECLARE_DERIVED_EXCEPTION( invalid_previous_block_id, graphene::chain::chain_exception, 30016, "invalid previous block" );
FC_DECLARE_DERIVED_EXCEPTION( invalid_block_time, graphene::chain::chain_exception, 30017, "invalid block time" );
FC_DECLARE_DERIVED_EXCEPTION( time_in_past, graphene::chain::chain_exception, 30018, "time is in the past" );
FC_DECLARE_DERIVED_EXCEPTION( time_in_future, graphene::chain::chain_exception, 30019, "time is in the future" );
FC_DECLARE_DERIVED_EXCEPTION( invalid_block_digest, graphene::chain::chain_exception, 30020, "invalid block digest" );
FC_DECLARE_DERIVED_EXCEPTION( invalid_delegate_signee, graphene::chain::chain_exception, 30021, "invalid delegate signee" );
FC_DECLARE_DERIVED_EXCEPTION( failed_checkpoint_verification, graphene::chain::chain_exception, 30022, "failed checkpoint verification" );
FC_DECLARE_DERIVED_EXCEPTION( wrong_chain_id, graphene::chain::chain_exception, 30023, "wrong chain id" );
FC_DECLARE_DERIVED_EXCEPTION( unknown_block, graphene::chain::chain_exception, 30024, "unknown block" );
FC_DECLARE_DERIVED_EXCEPTION( block_older_than_undo_history, graphene::chain::chain_exception, 30025, "block is older than our undo history allows us to process" );
FC_DECLARE_DERIVED_EXCEPTION( block_numbers_not_sequential, graphene::chain::chain_exception, 30015, "block numbers not sequential" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_previous_block_id, graphene::chain::chain_exception, 30016, "invalid previous block" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_block_time, graphene::chain::chain_exception, 30017, "invalid block time" )
FC_DECLARE_DERIVED_EXCEPTION( time_in_past, graphene::chain::chain_exception, 30018, "time is in the past" )
FC_DECLARE_DERIVED_EXCEPTION( time_in_future, graphene::chain::chain_exception, 30019, "time is in the future" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_block_digest, graphene::chain::chain_exception, 30020, "invalid block digest" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_delegate_signee, graphene::chain::chain_exception, 30021, "invalid delegate signee" )
FC_DECLARE_DERIVED_EXCEPTION( failed_checkpoint_verification, graphene::chain::chain_exception, 30022, "failed checkpoint verification" )
FC_DECLARE_DERIVED_EXCEPTION( wrong_chain_id, graphene::chain::chain_exception, 30023, "wrong chain id" )
FC_DECLARE_DERIVED_EXCEPTION( unknown_block, graphene::chain::chain_exception, 30024, "unknown block" )
FC_DECLARE_DERIVED_EXCEPTION( block_older_than_undo_history, graphene::chain::chain_exception, 30025, "block is older than our undo history allows us to process" )
FC_DECLARE_EXCEPTION( evaluation_error, 31000, "Evaluation Error" );
FC_DECLARE_DERIVED_EXCEPTION( negative_deposit, graphene::chain::evaluation_error, 31001, "negative deposit" );
FC_DECLARE_DERIVED_EXCEPTION( not_a_delegate, graphene::chain::evaluation_error, 31002, "not a delegate" );
FC_DECLARE_DERIVED_EXCEPTION( unknown_balance_record, graphene::chain::evaluation_error, 31003, "unknown balance record" );
FC_DECLARE_DERIVED_EXCEPTION( insufficient_funds, graphene::chain::evaluation_error, 31004, "insufficient funds" );
FC_DECLARE_DERIVED_EXCEPTION( missing_signature, graphene::chain::evaluation_error, 31005, "missing signature" );
FC_DECLARE_DERIVED_EXCEPTION( invalid_claim_password, graphene::chain::evaluation_error, 31006, "invalid claim password" );
FC_DECLARE_DERIVED_EXCEPTION( invalid_withdraw_condition, graphene::chain::evaluation_error, 31007, "invalid withdraw condition" );
FC_DECLARE_DERIVED_EXCEPTION( negative_withdraw, graphene::chain::evaluation_error, 31008, "negative withdraw" );
FC_DECLARE_DERIVED_EXCEPTION( not_an_active_delegate, graphene::chain::evaluation_error, 31009, "not an active delegate" );
FC_DECLARE_DERIVED_EXCEPTION( expired_transaction, graphene::chain::evaluation_error, 31010, "expired transaction" );
FC_DECLARE_DERIVED_EXCEPTION( invalid_transaction_expiration, graphene::chain::evaluation_error, 31011, "invalid transaction expiration" );
FC_DECLARE_DERIVED_EXCEPTION( oversized_transaction, graphene::chain::evaluation_error, 31012, "transaction exceeded the maximum transaction size" );
FC_DECLARE_DERIVED_EXCEPTION( balance_claimed_too_often, graphene::chain::evaluation_error, 31013, "balance claimed too often" );
FC_DECLARE_EXCEPTION( evaluation_error, 31000, "Evaluation Error" )
FC_DECLARE_DERIVED_EXCEPTION( negative_deposit, graphene::chain::evaluation_error, 31001, "negative deposit" )
FC_DECLARE_DERIVED_EXCEPTION( not_a_delegate, graphene::chain::evaluation_error, 31002, "not a delegate" )
FC_DECLARE_DERIVED_EXCEPTION( unknown_balance_record, graphene::chain::evaluation_error, 31003, "unknown balance record" )
FC_DECLARE_DERIVED_EXCEPTION( insufficient_funds, graphene::chain::evaluation_error, 31004, "insufficient funds" )
FC_DECLARE_DERIVED_EXCEPTION( missing_signature, graphene::chain::evaluation_error, 31005, "missing signature" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_claim_password, graphene::chain::evaluation_error, 31006, "invalid claim password" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_withdraw_condition, graphene::chain::evaluation_error, 31007, "invalid withdraw condition" )
FC_DECLARE_DERIVED_EXCEPTION( negative_withdraw, graphene::chain::evaluation_error, 31008, "negative withdraw" )
FC_DECLARE_DERIVED_EXCEPTION( not_an_active_delegate, graphene::chain::evaluation_error, 31009, "not an active delegate" )
FC_DECLARE_DERIVED_EXCEPTION( expired_transaction, graphene::chain::evaluation_error, 31010, "expired transaction" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_transaction_expiration, graphene::chain::evaluation_error, 31011, "invalid transaction expiration" )
FC_DECLARE_DERIVED_EXCEPTION( oversized_transaction, graphene::chain::evaluation_error, 31012, "transaction exceeded the maximum transaction size" )
FC_DECLARE_DERIVED_EXCEPTION( balance_claimed_too_often, graphene::chain::evaluation_error, 31013, "balance claimed too often" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_claim_amount, graphene::chain::evaluation_error, 31013, "invalid claim amount" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_account_name, graphene::chain::evaluation_error, 32001, "invalid account name" );
FC_DECLARE_DERIVED_EXCEPTION( unknown_account_id, graphene::chain::evaluation_error, 32002, "unknown account id" );
FC_DECLARE_DERIVED_EXCEPTION( unknown_account_name, graphene::chain::evaluation_error, 32003, "unknown account name" );
FC_DECLARE_DERIVED_EXCEPTION( missing_parent_account_signature, graphene::chain::evaluation_error, 32004, "missing parent account signature" );
FC_DECLARE_DERIVED_EXCEPTION( parent_account_retracted, graphene::chain::evaluation_error, 32005, "parent account retracted" );
FC_DECLARE_DERIVED_EXCEPTION( account_expired, graphene::chain::evaluation_error, 32006, "account expired" );
FC_DECLARE_DERIVED_EXCEPTION( account_already_registered, graphene::chain::evaluation_error, 32007, "account already registered" );
FC_DECLARE_DERIVED_EXCEPTION( account_key_in_use, graphene::chain::evaluation_error, 32008, "account key already in use" );
FC_DECLARE_DERIVED_EXCEPTION( account_retracted, graphene::chain::evaluation_error, 32009, "account retracted" );
FC_DECLARE_DERIVED_EXCEPTION( unknown_parent_account_name, graphene::chain::evaluation_error, 32010, "unknown parent account name" );
FC_DECLARE_DERIVED_EXCEPTION( unknown_delegate_slate, graphene::chain::evaluation_error, 32011, "unknown delegate slate" );
FC_DECLARE_DERIVED_EXCEPTION( too_may_delegates_in_slate, graphene::chain::evaluation_error, 32012, "too many delegates in slate" );
FC_DECLARE_DERIVED_EXCEPTION( pay_balance_remaining, graphene::chain::evaluation_error, 32013, "pay balance remaining" );
FC_DECLARE_DERIVED_EXCEPTION( invalid_account_name, graphene::chain::evaluation_error, 32001, "invalid account name" )
FC_DECLARE_DERIVED_EXCEPTION( unknown_account_id, graphene::chain::evaluation_error, 32002, "unknown account id" )
FC_DECLARE_DERIVED_EXCEPTION( unknown_account_name, graphene::chain::evaluation_error, 32003, "unknown account name" )
FC_DECLARE_DERIVED_EXCEPTION( missing_parent_account_signature, graphene::chain::evaluation_error, 32004, "missing parent account signature" )
FC_DECLARE_DERIVED_EXCEPTION( parent_account_retracted, graphene::chain::evaluation_error, 32005, "parent account retracted" )
FC_DECLARE_DERIVED_EXCEPTION( account_expired, graphene::chain::evaluation_error, 32006, "account expired" )
FC_DECLARE_DERIVED_EXCEPTION( account_already_registered, graphene::chain::evaluation_error, 32007, "account already registered" )
FC_DECLARE_DERIVED_EXCEPTION( account_key_in_use, graphene::chain::evaluation_error, 32008, "account key already in use" )
FC_DECLARE_DERIVED_EXCEPTION( account_retracted, graphene::chain::evaluation_error, 32009, "account retracted" )
FC_DECLARE_DERIVED_EXCEPTION( unknown_parent_account_name, graphene::chain::evaluation_error, 32010, "unknown parent account name" )
FC_DECLARE_DERIVED_EXCEPTION( unknown_delegate_slate, graphene::chain::evaluation_error, 32011, "unknown delegate slate" )
FC_DECLARE_DERIVED_EXCEPTION( too_may_delegates_in_slate, graphene::chain::evaluation_error, 32012, "too many delegates in slate" )
FC_DECLARE_DERIVED_EXCEPTION( pay_balance_remaining, graphene::chain::evaluation_error, 32013, "pay balance remaining" )
FC_DECLARE_DERIVED_EXCEPTION( not_a_delegate_signature, graphene::chain::evaluation_error, 33002, "not delegates signature" );
FC_DECLARE_DERIVED_EXCEPTION( not_a_delegate_signature, graphene::chain::evaluation_error, 33002, "not delegates signature" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_precision, graphene::chain::evaluation_error, 35001, "invalid precision" );
FC_DECLARE_DERIVED_EXCEPTION( invalid_asset_symbol, graphene::chain::evaluation_error, 35002, "invalid asset symbol" );
FC_DECLARE_DERIVED_EXCEPTION( unknown_asset_id, graphene::chain::evaluation_error, 35003, "unknown asset id" );
FC_DECLARE_DERIVED_EXCEPTION( asset_symbol_in_use, graphene::chain::evaluation_error, 35004, "asset symbol in use" );
FC_DECLARE_DERIVED_EXCEPTION( invalid_asset_amount, graphene::chain::evaluation_error, 35005, "invalid asset amount" );
FC_DECLARE_DERIVED_EXCEPTION( negative_issue, graphene::chain::evaluation_error, 35006, "negative issue" );
FC_DECLARE_DERIVED_EXCEPTION( over_issue, graphene::chain::evaluation_error, 35007, "over issue" );
FC_DECLARE_DERIVED_EXCEPTION( unknown_asset_symbol, graphene::chain::evaluation_error, 35008, "unknown asset symbol" );
FC_DECLARE_DERIVED_EXCEPTION( asset_id_in_use, graphene::chain::evaluation_error, 35009, "asset id in use" );
FC_DECLARE_DERIVED_EXCEPTION( not_user_issued, graphene::chain::evaluation_error, 35010, "not user issued" );
FC_DECLARE_DERIVED_EXCEPTION( invalid_asset_name, graphene::chain::evaluation_error, 35011, "invalid asset name" );
FC_DECLARE_DERIVED_EXCEPTION( invalid_precision, graphene::chain::evaluation_error, 35001, "invalid precision" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_asset_symbol, graphene::chain::evaluation_error, 35002, "invalid asset symbol" )
FC_DECLARE_DERIVED_EXCEPTION( unknown_asset_id, graphene::chain::evaluation_error, 35003, "unknown asset id" )
FC_DECLARE_DERIVED_EXCEPTION( asset_symbol_in_use, graphene::chain::evaluation_error, 35004, "asset symbol in use" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_asset_amount, graphene::chain::evaluation_error, 35005, "invalid asset amount" )
FC_DECLARE_DERIVED_EXCEPTION( negative_issue, graphene::chain::evaluation_error, 35006, "negative issue" )
FC_DECLARE_DERIVED_EXCEPTION( over_issue, graphene::chain::evaluation_error, 35007, "over issue" )
FC_DECLARE_DERIVED_EXCEPTION( unknown_asset_symbol, graphene::chain::evaluation_error, 35008, "unknown asset symbol" )
FC_DECLARE_DERIVED_EXCEPTION( asset_id_in_use, graphene::chain::evaluation_error, 35009, "asset id in use" )
FC_DECLARE_DERIVED_EXCEPTION( not_user_issued, graphene::chain::evaluation_error, 35010, "not user issued" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_asset_name, graphene::chain::evaluation_error, 35011, "invalid asset name" )
FC_DECLARE_DERIVED_EXCEPTION( delegate_vote_limit, graphene::chain::evaluation_error, 36001, "delegate_vote_limit" );
FC_DECLARE_DERIVED_EXCEPTION( insufficient_fee, graphene::chain::evaluation_error, 36002, "insufficient fee" );
FC_DECLARE_DERIVED_EXCEPTION( negative_fee, graphene::chain::evaluation_error, 36003, "negative fee" );
FC_DECLARE_DERIVED_EXCEPTION( missing_deposit, graphene::chain::evaluation_error, 36004, "missing deposit" );
FC_DECLARE_DERIVED_EXCEPTION( insufficient_relay_fee, graphene::chain::evaluation_error, 36005, "insufficient relay fee" );
FC_DECLARE_DERIVED_EXCEPTION( delegate_vote_limit, graphene::chain::evaluation_error, 36001, "delegate_vote_limit" )
FC_DECLARE_DERIVED_EXCEPTION( insufficient_fee, graphene::chain::evaluation_error, 36002, "insufficient fee" )
FC_DECLARE_DERIVED_EXCEPTION( negative_fee, graphene::chain::evaluation_error, 36003, "negative fee" )
FC_DECLARE_DERIVED_EXCEPTION( missing_deposit, graphene::chain::evaluation_error, 36004, "missing deposit" )
FC_DECLARE_DERIVED_EXCEPTION( insufficient_relay_fee, graphene::chain::evaluation_error, 36005, "insufficient relay fee" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_market, graphene::chain::evaluation_error, 37001, "invalid market" );
FC_DECLARE_DERIVED_EXCEPTION( unknown_market_order, graphene::chain::evaluation_error, 37002, "unknown market order" );
FC_DECLARE_DERIVED_EXCEPTION( shorting_base_shares, graphene::chain::evaluation_error, 37003, "shorting base shares" );
FC_DECLARE_DERIVED_EXCEPTION( insufficient_collateral, graphene::chain::evaluation_error, 37004, "insufficient collateral" );
FC_DECLARE_DERIVED_EXCEPTION( insufficient_depth, graphene::chain::evaluation_error, 37005, "insufficient depth" );
FC_DECLARE_DERIVED_EXCEPTION( insufficient_feeds, graphene::chain::evaluation_error, 37006, "insufficient feeds" );
FC_DECLARE_DERIVED_EXCEPTION( invalid_feed_price, graphene::chain::evaluation_error, 37007, "invalid feed price" );
FC_DECLARE_DERIVED_EXCEPTION( invalid_market, graphene::chain::evaluation_error, 37001, "invalid market" )
FC_DECLARE_DERIVED_EXCEPTION( unknown_market_order, graphene::chain::evaluation_error, 37002, "unknown market order" )
FC_DECLARE_DERIVED_EXCEPTION( shorting_base_shares, graphene::chain::evaluation_error, 37003, "shorting base shares" )
FC_DECLARE_DERIVED_EXCEPTION( insufficient_collateral, graphene::chain::evaluation_error, 37004, "insufficient collateral" )
FC_DECLARE_DERIVED_EXCEPTION( insufficient_depth, graphene::chain::evaluation_error, 37005, "insufficient depth" )
FC_DECLARE_DERIVED_EXCEPTION( insufficient_feeds, graphene::chain::evaluation_error, 37006, "insufficient feeds" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_feed_price, graphene::chain::evaluation_error, 37007, "invalid feed price" )
FC_DECLARE_DERIVED_EXCEPTION( price_multiplication_overflow, graphene::chain::evaluation_error, 38001, "price multiplication overflow" );
FC_DECLARE_DERIVED_EXCEPTION( price_multiplication_underflow, graphene::chain::evaluation_error, 38002, "price multiplication underflow" );
FC_DECLARE_DERIVED_EXCEPTION( price_multiplication_undefined, graphene::chain::evaluation_error, 38003, "price multiplication undefined product 0*inf" );
FC_DECLARE_DERIVED_EXCEPTION( price_multiplication_overflow, graphene::chain::evaluation_error, 38001, "price multiplication overflow" )
FC_DECLARE_DERIVED_EXCEPTION( price_multiplication_underflow, graphene::chain::evaluation_error, 38002, "price multiplication underflow" )
FC_DECLARE_DERIVED_EXCEPTION( price_multiplication_undefined, graphene::chain::evaluation_error, 38003, "price multiplication undefined product 0*inf" )
} } // graphene::chain

View file

@ -28,7 +28,7 @@
#include <graphene/chain/call_order_object.hpp>
#include <graphene/chain/vesting_balance_object.hpp>
#include <graphene/chain/withdraw_permission_object.hpp>
#include <graphene/chain/exceptions.hpp>
#include <graphene/chain/predicate.hpp>
#include <graphene/chain/db_reflect_cmp.hpp>
@ -980,9 +980,28 @@ BOOST_AUTO_TEST_CASE( balance_object_test )
fc::temp_directory td;
genesis_state.initial_balances.push_back({generate_private_key("n").get_public_key(), GRAPHENE_SYMBOL, 1});
genesis_state.initial_balances.push_back({generate_private_key("x").get_public_key(), GRAPHENE_SYMBOL, 1});
// genesis_state.initial_vesting_balances.push_back({generate_private_key("v").get_public_key(), GRAPHENE_SYMBOL, 1});
// TODO: vesting genesis balances
genesis_state.initial_accounts.emplace_back("n", generate_private_key("n").get_public_key());
auto starting_time = time_point_sec((time_point::now().sec_since_epoch() / GRAPHENE_DEFAULT_BLOCK_INTERVAL + 1) *
GRAPHENE_DEFAULT_BLOCK_INTERVAL);
auto n_key = generate_private_key("n");
auto x_key = generate_private_key("x");
auto v1_key = generate_private_key("v1");
auto v2_key = generate_private_key("v2");
genesis_state_type::initial_vesting_balance_type vest;
vest.owner = v1_key.get_public_key();
vest.asset_symbol = GRAPHENE_SYMBOL;
vest.amount = 500;
vest.begin_balance = vest.amount;
vest.begin_timestamp = starting_time;
vest.vesting_duration_seconds = 60;
genesis_state.initial_vesting_balances.push_back(vest);
vest.owner = v2_key.get_public_key();
vest.begin_timestamp -= fc::seconds(30);
vest.amount = 400;
genesis_state.initial_vesting_balances.push_back(vest);
genesis_state.initial_accounts.emplace_back("n", n_key.get_public_key());
db.open(td.path(), genesis_state);
const balance_object& balance = balance_id_type()(db);
@ -993,22 +1012,87 @@ BOOST_AUTO_TEST_CASE( balance_object_test )
op.deposit_to_account = db.get_index_type<account_index>().indices().get<by_name>().find("n")->get_id();
op.total_claimed = asset(1);
op.balance_to_claim = balance_id_type(1);
op.balance_owner_key = generate_private_key("x").get_public_key();
op.balance_owner_key = x_key.get_public_key();
trx.operations = {op};
trx.sign(generate_private_key("n"));
trx.sign(n_key);
// Fail because I'm claiming from an address which hasn't signed
BOOST_CHECK_THROW(db.push_transaction(trx), fc::exception);
trx.clear();
op.balance_to_claim = balance_id_type();
op.balance_owner_key = generate_private_key("n").get_public_key();
op.balance_owner_key = n_key.get_public_key();
trx.operations = {op};
trx.sign(generate_private_key("n"));
trx.sign(n_key);
db.push_transaction(trx);
// Not using fixture's get_balance() here because it uses fixture's db, not my override
BOOST_CHECK_EQUAL(db.get_balance(op.deposit_to_account, asset_id_type()).amount.value, 1);
BOOST_CHECK(db.find_object(balance_id_type()) == nullptr);
BOOST_CHECK(db.find_object(balance_id_type(1)) != nullptr);
auto slot = db.get_slot_at_time(starting_time);
db.generate_block(starting_time, db.get_scheduled_witness(slot).first, delegate_priv_key, database::skip_nothing);
const balance_object& vesting_balance_1 = balance_id_type(2)(db);
const balance_object& vesting_balance_2 = balance_id_type(3)(db);
BOOST_CHECK(vesting_balance_1.is_vesting_balance());
BOOST_CHECK_EQUAL(vesting_balance_1.balance.amount.value, 500);
BOOST_CHECK_EQUAL(vesting_balance_1.available(db.head_block_time()).amount.value, 0);
BOOST_CHECK(vesting_balance_2.is_vesting_balance());
BOOST_CHECK_EQUAL(vesting_balance_2.balance.amount.value, 400);
BOOST_CHECK_EQUAL(vesting_balance_2.available(db.head_block_time()).amount.value, 150);
op.balance_to_claim = vesting_balance_1.id;
op.total_claimed = asset(1);
op.balance_owner_key = v1_key.get_public_key();
trx.clear();
trx.set_expiration(db.head_block_id());
trx.operations = {op};
trx.sign(n_key);
trx.sign(v1_key);
// Attempting to claim 1 from a balance with 0 available
BOOST_CHECK_THROW(db.push_transaction(trx), invalid_claim_amount);
op.balance_to_claim = vesting_balance_2.id;
op.total_claimed.amount = 151;
op.balance_owner_key = v2_key.get_public_key();
trx.operations = {op};
trx.signatures.clear();
trx.sign(n_key);
trx.sign(v2_key);
// Attempting to claim 151 from a balance with 150 available
BOOST_CHECK_THROW(db.push_transaction(trx), invalid_claim_amount);
op.balance_to_claim = vesting_balance_2.id;
op.total_claimed.amount = 100;
op.balance_owner_key = v2_key.get_public_key();
trx.operations = {op};
trx.signatures.clear();
trx.sign(n_key);
trx.sign(v2_key);
db.push_transaction(trx);
BOOST_CHECK_EQUAL(db.get_balance(op.deposit_to_account, asset_id_type()).amount.value, 101);
op.total_claimed.amount = 10;
trx.operations = {op};
trx.signatures.clear();
trx.sign(n_key);
trx.sign(v2_key);
// Attempting to claim twice within a day
BOOST_CHECK_THROW(db.push_transaction(trx), balance_claimed_too_often);
// TODO: test withdrawing entire vesting_balance_1 balance, remainder of vesting_balance_2 balance
// slot = db.get_slot_at_time(vesting_balance_1.vesting_policy->begin_timestamp + 60);
// db.generate_block(starting_time, db.get_scheduled_witness(slot).first, delegate_priv_key, database::skip_nothing);
// op.balance_to_claim = vesting_balance_1.id;
// op.total_claimed.amount = 500;
// op.balance_owner_key = v1_key.get_public_key();
// trx.operations = {op};
// trx.signatures.clear();
// trx.sign(n_key);
// trx.sign(v2_key);
// db.push_transaction(trx);
// BOOST_CHECK(db.find_object(op.balance_to_claim) == nullptr);
} FC_LOG_AND_RETHROW() }
// TODO: Write linear VBO tests