Merge branch 'master' of github.com:cryptonomex/graphene

This commit is contained in:
Daniel Larimer 2015-09-02 09:03:26 -04:00
commit 195373210a
7 changed files with 203 additions and 45 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

@ -116,49 +116,8 @@ void witness_plugin::plugin_startup()
{ try {
ilog("witness plugin: plugin_startup() begin");
chain::database& d = database();
std::set<chain::witness_id_type> bad_wits;
//Start NTP time client
graphene::time::now();
for( auto wit : _witnesses )
{
if( d.find(wit) == nullptr )
{
if( app().is_finished_syncing() )
{
elog("ERROR: Unable to find witness ${w}, even though syncing has finished. This witness will be ignored.",
("w", wit));
continue;
} else {
wlog("WARNING: Unable to find witness ${w}. Postponing initialization until syncing finishes.",
("w", wit));
app().syncing_finished.connect([this]{plugin_startup();});
return;
}
}
auto signing_key = wit(d).signing_key;
if( !_private_keys.count(signing_key) )
{
// Check if it's a duplicate key of one I do have
bool found_duplicate = false;
for( const auto& private_key : _private_keys )
if( chain::public_key_type(private_key.second.get_public_key()) == signing_key )
{
ilog("Found duplicate key: ${k1} matches ${k2}; using this key to sign for ${w}",
("k1", private_key.first)("k2", signing_key)("w", wit));
_private_keys[signing_key] = private_key.second;
found_duplicate = true;
break;
}
if( found_duplicate )
continue;
elog("Unable to find key for witness ${w}. Removing it from my witnesses.", ("w", wit));
bad_wits.insert(wit);
}
}
for( auto wit : bad_wits )
_witnesses.erase(wit);
if( !_witnesses.empty() )
{
@ -211,7 +170,7 @@ block_production_condition::block_production_condition_enum witness_plugin::bloc
switch( result )
{
case block_production_condition::produced:
ilog("Generated block #${n} with timestamp ${t} at time ${c}", ("n",capture)("t",capture)("c",capture));
ilog("Generated block #${n} with timestamp ${t} at time ${c}", (capture));
break;
case block_production_condition::not_synced:
ilog("Not producing block because production is disabled until we receive a recent block (see: --enable-stale-production)");
@ -223,10 +182,10 @@ block_production_condition::block_production_condition_enum witness_plugin::bloc
ilog("Not producing block because slot has not yet arrived");
break;
case block_production_condition::no_private_key:
ilog("Not producing block because I don't have the private key for ${scheduled_key}", ("scheduled_key",capture) );
ilog("Not producing block because I don't have the private key for ${scheduled_key}", (capture) );
break;
case block_production_condition::low_participation:
elog("Not producing block because node appears to be on a minority fork with only ${pct}% witness participation", ("pct",capture) );
elog("Not producing block because node appears to be on a minority fork with only ${pct}% witness participation", (capture) );
break;
case block_production_condition::lag:
elog("Not producing block because node didn't wake up within 500ms of the slot time.");

View file

@ -219,7 +219,23 @@ struct signed_block_with_info : public signed_block
signed_block_with_info( const signed_block_with_info& block ) = default;
block_id_type block_id;
fc::ecc::public_key signing_key;
public_key_type 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 {
@ -1086,6 +1102,40 @@ class wallet_api
string url,
bool broadcast = false);
/**
* Update a witness object owned by the given account.
*
* @param witness The name of the witness's owner account. Also accepts the ID of the owner account or the ID of the witness.
* @param url Same as for create_witness. The empty string makes it remain the same.
* @param block_signing_key The new block signing public key. The empty string makes it remain the same.
* @param broadcast true if you wish to broadcast the transaction.
*/
signed_transaction update_witness(string witness_name,
string url,
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
@ -1314,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)
@ -1364,6 +1417,9 @@ FC_API( graphene::wallet::wallet_api,
(list_witnesses)
(list_committee_members)
(create_witness)
(update_witness)
(get_vesting_balances)
(withdraw_vesting)
(vote_for_committee_member)
(vote_for_witness)
(set_voting_proxy)

View file

@ -1318,6 +1318,90 @@ public:
return sign_transaction( tx, broadcast );
} FC_CAPTURE_AND_RETHROW( (owner_account)(broadcast) ) }
signed_transaction update_witness(string witness_name,
string url,
string block_signing_key,
bool broadcast /* = false */)
{ try {
witness_object witness = get_witness(witness_name);
account_object witness_account = get_account( witness.witness_account );
fc::ecc::private_key active_private_key = get_private_key_for_account(witness_account);
witness_update_operation witness_update_op;
witness_update_op.witness = witness.id;
witness_update_op.witness_account = witness_account.id;
if( url != "" )
witness_update_op.new_url = url;
if( block_signing_key != "" )
witness_update_op.new_signing_key = public_key_type( block_signing_key );
signed_transaction tx;
tx.operations.push_back( witness_update_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)(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,
@ -2546,6 +2630,29 @@ signed_transaction wallet_api::create_witness(string owner_account,
return my->create_witness(owner_account, url, broadcast);
}
signed_transaction wallet_api::update_witness(
string witness_name,
string url,
string block_signing_key,
bool broadcast /* = false */)
{
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,
@ -3396,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)