Merge branch 'master' of github.com:cryptonomex/graphene
This commit is contained in:
commit
195373210a
7 changed files with 203 additions and 45 deletions
|
|
@ -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>();
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.");
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in a new issue