cli_wallet: Implement withdrawal for vesting balance objects #286

This commit is contained in:
theoreticalbts 2015-09-01 14:19:34 -04:00
parent 2f88cc86ba
commit efac97e060
6 changed files with 151 additions and 0 deletions

View file

@ -1186,6 +1186,21 @@ namespace graphene { namespace app {
return result;
} FC_CAPTURE_AND_RETHROW( (objs) ) }
vector<vesting_balance_object> database_api::get_vesting_balances( account_id_type account_id )const
{
try
{
vector<vesting_balance_object> result;
auto vesting_range = _db.get_index_type<vesting_balance_index>().indices().get<by_account>().equal_range(account_id);
std::for_each(vesting_range.first, vesting_range.second,
[&result](const vesting_balance_object& balance) {
result.emplace_back(balance);
});
return result;
}
FC_CAPTURE_AND_RETHROW( (account_id) );
}
vector<balance_object> database_api::get_balance_objects( const vector<address>& addrs )const
{ try {
const auto& bal_idx = _db.get_index_type<balance_index>();

View file

@ -322,6 +322,7 @@ namespace graphene { namespace app {
vector<asset> get_vested_balances( const vector<balance_id_type>& objs )const;
vector<vesting_balance_object> get_vesting_balances( account_id_type account_id )const;
/**
* This API will take a partially signed transaction and a set of public keys that the owner has the ability to sign for
@ -579,6 +580,7 @@ FC_API(graphene::app::database_api,
(get_margin_positions)
(get_balance_objects)
(get_vested_balances)
(get_vesting_balances)
(get_required_signatures)
(get_potential_signatures)
(verify_authority)

View file

@ -155,6 +155,11 @@ namespace graphene { namespace chain {
*/
void withdraw(const fc::time_point_sec& now, const asset& amount);
bool is_withdraw_allowed(const fc::time_point_sec& now, const asset& amount)const;
/**
* Get amount of allowed withdrawal.
*/
asset get_allowed_withdraw(const time_point_sec& now)const;
};
/**
* @ingroup object_index

View file

@ -182,6 +182,7 @@ VESTING_VISITOR(on_withdraw,);
VESTING_VISITOR(is_deposit_allowed, const);
VESTING_VISITOR(is_deposit_vested_allowed, const);
VESTING_VISITOR(is_withdraw_allowed, const);
VESTING_VISITOR(get_allowed_withdraw, const);
bool vesting_balance_object::is_deposit_allowed(const time_point_sec& now, const asset& amount)const
{
@ -224,4 +225,10 @@ void vesting_balance_object::withdraw(const time_point_sec& now, const asset& am
balance -= amount;
}
asset vesting_balance_object::get_allowed_withdraw(const time_point_sec& now)const
{
asset amount = asset();
return policy.visit(get_allowed_withdraw_visitor(balance, now, amount));
}
} } // graphene::chain

View file

@ -222,6 +222,22 @@ struct signed_block_with_info : public signed_block
fc::ecc::public_key signing_key;
};
struct vesting_balance_object_with_info : public vesting_balance_object
{
vesting_balance_object_with_info( const vesting_balance_object& vbo, fc::time_point_sec now );
vesting_balance_object_with_info( const vesting_balance_object_with_info& vbo ) = default;
/**
* How much is allowed to be withdrawn.
*/
asset allowed_withdraw;
/**
* The time at which allowed_withdrawal was calculated.
*/
fc::time_point_sec allowed_withdraw_time;
};
namespace detail {
class wallet_api_impl;
}
@ -1099,6 +1115,27 @@ class wallet_api
string block_signing_key,
bool broadcast = false);
/**
* Get information about a vesting balance object.
*
* @param account_name An account name, account ID, or vesting balance object ID.
*/
vector< vesting_balance_object_with_info > get_vesting_balances( string account_name );
/**
* Withdraw a vesting balance.
*
* @param witness_name The account name of the witness, also accepts account ID or vesting balance ID type.
* @param amount The amount to withdraw.
* @param asset_symbol The symbol of the asset to withdraw.
* @param broadcast true if you wish to broadcast the transaction
*/
signed_transaction withdraw_vesting(
string witness_name,
string amount,
string asset_symbol,
bool broadcast = false);
/** Vote for a given committee_member.
*
* An account can publish a list of all committee_memberes they approve of. This
@ -1327,6 +1364,9 @@ FC_REFLECT( graphene::wallet::approval_delta,
FC_REFLECT_DERIVED( graphene::wallet::signed_block_with_info, (graphene::chain::signed_block),
(block_id)(signing_key) )
FC_REFLECT_DERIVED( graphene::wallet::vesting_balance_object_with_info, (graphene::chain::vesting_balance_object),
(allowed_withdraw)(allowed_withdraw_time) )
FC_API( graphene::wallet::wallet_api,
(help)
(gethelp)
@ -1378,6 +1418,8 @@ FC_API( graphene::wallet::wallet_api,
(list_committee_members)
(create_witness)
(update_witness)
(get_vesting_balances)
(withdraw_vesting)
(vote_for_committee_member)
(vote_for_witness)
(set_voting_proxy)

View file

@ -1343,6 +1343,65 @@ public:
return sign_transaction( tx, broadcast );
} FC_CAPTURE_AND_RETHROW( (witness_name)(url)(block_signing_key)(broadcast) ) }
vector< vesting_balance_object_with_info > get_vesting_balances( string account_name )
{ try {
fc::optional<vesting_balance_id_type> vbid = maybe_id<vesting_balance_id_type>( account_name );
std::vector<vesting_balance_object_with_info> result;
fc::time_point_sec now = _remote_db->get_dynamic_global_properties().time;
if( vbid )
{
result.emplace_back( get_object<vesting_balance_object>(*vbid), now );
return result;
}
// try casting to avoid a round-trip if we were given an account ID
fc::optional<account_id_type> acct_id = maybe_id<account_id_type>( account_name );
if( !acct_id )
acct_id = get_account( account_name ).id;
vector< vesting_balance_object > vbos = _remote_db->get_vesting_balances( *acct_id );
if( vbos.size() == 0 )
return result;
for( const vesting_balance_object& vbo : vbos )
result.emplace_back( vbo, now );
return result;
} FC_CAPTURE_AND_RETHROW( (account_name) )
}
signed_transaction withdraw_vesting(
string witness_name,
string amount,
string asset_symbol,
bool broadcast = false )
{ try {
asset_object asset_obj = get_asset( asset_symbol );
fc::optional<vesting_balance_id_type> vbid = maybe_id<vesting_balance_id_type>(witness_name);
if( !vbid )
{
witness_object wit = get_witness( witness_name );
FC_ASSERT( wit.pay_vb );
vbid = wit.pay_vb;
}
vesting_balance_object vbo = get_object< vesting_balance_object >( *vbid );
vesting_balance_withdraw_operation vesting_balance_withdraw_op;
vesting_balance_withdraw_op.vesting_balance = *vbid;
vesting_balance_withdraw_op.owner = vbo.owner;
vesting_balance_withdraw_op.amount = asset_obj.amount_from_string(amount);
signed_transaction tx;
tx.operations.push_back( vesting_balance_withdraw_op );
set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees );
tx.validate();
return sign_transaction( tx, broadcast );
} FC_CAPTURE_AND_RETHROW( (witness_name)(amount) )
}
signed_transaction vote_for_committee_member(string voting_account,
string committee_member,
bool approve,
@ -2580,6 +2639,20 @@ signed_transaction wallet_api::update_witness(
return my->update_witness(witness_name, url, block_signing_key, broadcast);
}
vector< vesting_balance_object_with_info > wallet_api::get_vesting_balances( string account_name )
{
return my->get_vesting_balances( account_name );
}
signed_transaction wallet_api::withdraw_vesting(
string witness_name,
string amount,
string asset_symbol,
bool broadcast /* = false */)
{
return my->withdraw_vesting( witness_name, amount, asset_symbol, broadcast );
}
signed_transaction wallet_api::vote_for_committee_member(string voting_account,
string witness,
bool approve,
@ -3430,6 +3503,13 @@ signed_block_with_info::signed_block_with_info( const signed_block& block )
signing_key = signee();
}
vesting_balance_object_with_info::vesting_balance_object_with_info( const vesting_balance_object& vbo, fc::time_point_sec now )
: vesting_balance_object( vbo )
{
allowed_withdraw = get_allowed_withdraw( now );
allowed_withdraw_time = now;
}
} } // graphene::wallet
void fc::to_variant(const account_multi_index_type& accts, fc::variant& vo)