Merge branch 'bitshares' of https://github.com/bitshares/bitshares-2 into bitshares
This commit is contained in:
commit
4e443bded5
6 changed files with 231 additions and 31 deletions
|
|
@ -97,17 +97,11 @@ void account_statistics_object::process_fees(const account_object& a, database&
|
||||||
assert( referrer_cut + registrar_cut + accumulated + reserveed + lifetime_cut == core_fee_total );
|
assert( referrer_cut + registrar_cut + accumulated + reserveed + lifetime_cut == core_fee_total );
|
||||||
};
|
};
|
||||||
|
|
||||||
share_type vesting_fee_subtotal(pending_fees);
|
pay_out_fees(a, pending_fees, true);
|
||||||
share_type vested_fee_subtotal(pending_vested_fees);
|
pay_out_fees(a, pending_vested_fees, false);
|
||||||
share_type vesting_cashback, vested_cashback;
|
|
||||||
|
|
||||||
pay_out_fees(a, vesting_fee_subtotal, true);
|
d.modify(*this, [&](account_statistics_object& s) {
|
||||||
d.deposit_cashback(a, vesting_cashback, true);
|
s.lifetime_fees_paid += pending_fees + pending_vested_fees;
|
||||||
pay_out_fees(a, vested_fee_subtotal, false);
|
|
||||||
d.deposit_cashback(a, vested_cashback, false);
|
|
||||||
|
|
||||||
d.modify(*this, [vested_fee_subtotal, vesting_fee_subtotal](account_statistics_object& s) {
|
|
||||||
s.lifetime_fees_paid += vested_fee_subtotal + vesting_fee_subtotal;
|
|
||||||
s.pending_fees = 0;
|
s.pending_fees = 0;
|
||||||
s.pending_vested_fees = 0;
|
s.pending_vested_fees = 0;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -463,24 +463,7 @@ void_result asset_publish_feeds_evaluator::do_evaluate(const asset_publish_feed_
|
||||||
const asset_bitasset_data_object& bitasset = base.bitasset_data(d);
|
const asset_bitasset_data_object& bitasset = base.bitasset_data(d);
|
||||||
FC_ASSERT( !bitasset.has_settlement(), "No further feeds may be published after a settlement event" );
|
FC_ASSERT( !bitasset.has_settlement(), "No further feeds may be published after a settlement event" );
|
||||||
|
|
||||||
//
|
|
||||||
// many of these checks should be moved to price_feed.validate()
|
|
||||||
// or the operation validator when new network is started
|
|
||||||
//
|
|
||||||
if( !o.feed.core_exchange_rate.is_null() )
|
|
||||||
{
|
|
||||||
o.feed.core_exchange_rate.validate();
|
|
||||||
}
|
|
||||||
if( (!o.feed.settlement_price.is_null()) && (!o.feed.core_exchange_rate.is_null()) )
|
|
||||||
{
|
|
||||||
FC_ASSERT( o.feed.settlement_price.base.asset_id == o.feed.core_exchange_rate.base.asset_id );
|
|
||||||
FC_ASSERT( o.feed.settlement_price.quote.asset_id == o.feed.core_exchange_rate.quote.asset_id );
|
|
||||||
}
|
|
||||||
|
|
||||||
FC_ASSERT( !o.feed.settlement_price.is_null() );
|
|
||||||
FC_ASSERT( !o.feed.core_exchange_rate.is_null() );
|
|
||||||
FC_ASSERT( o.feed.settlement_price.quote.asset_id == bitasset.options.short_backing_asset );
|
FC_ASSERT( o.feed.settlement_price.quote.asset_id == bitasset.options.short_backing_asset );
|
||||||
FC_ASSERT( o.feed.is_for( o.asset_id ) );
|
|
||||||
|
|
||||||
//Verify that the publisher is authoritative to publish a feed
|
//Verify that the publisher is authoritative to publish a feed
|
||||||
if( base.options.flags & witness_fed_asset )
|
if( base.options.flags & witness_fed_asset )
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,21 @@ void asset_publish_feed_operation::validate()const
|
||||||
{
|
{
|
||||||
FC_ASSERT( fee.amount >= 0 );
|
FC_ASSERT( fee.amount >= 0 );
|
||||||
feed.validate();
|
feed.validate();
|
||||||
|
|
||||||
|
// maybe some of these could be moved to feed.validate()
|
||||||
|
if( !feed.core_exchange_rate.is_null() )
|
||||||
|
{
|
||||||
|
feed.core_exchange_rate.validate();
|
||||||
|
}
|
||||||
|
if( (!feed.settlement_price.is_null()) && (!feed.core_exchange_rate.is_null()) )
|
||||||
|
{
|
||||||
|
FC_ASSERT( feed.settlement_price.base.asset_id == feed.core_exchange_rate.base.asset_id );
|
||||||
|
FC_ASSERT( feed.settlement_price.quote.asset_id == feed.core_exchange_rate.quote.asset_id );
|
||||||
|
}
|
||||||
|
|
||||||
|
FC_ASSERT( !feed.settlement_price.is_null() );
|
||||||
|
FC_ASSERT( !feed.core_exchange_rate.is_null() );
|
||||||
|
FC_ASSERT( feed.is_for( asset_id ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void asset_reserve_operation::validate()const
|
void asset_reserve_operation::validate()const
|
||||||
|
|
|
||||||
|
|
@ -53,16 +53,34 @@ struct static_variant_map_visitor
|
||||||
int which;
|
int which;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template< typename StaticVariant >
|
||||||
|
struct from_which_visitor
|
||||||
|
{
|
||||||
|
typedef StaticVariant result_type;
|
||||||
|
|
||||||
|
template< typename Member > // Member is member of static_variant
|
||||||
|
result_type operator()( const Member& dummy )
|
||||||
|
{
|
||||||
|
Member result;
|
||||||
|
from_variant( v, result );
|
||||||
|
return result; // converted from StaticVariant to Result automatically due to return type
|
||||||
|
}
|
||||||
|
|
||||||
|
const variant& v;
|
||||||
|
|
||||||
|
from_which_visitor( const variant& _v ) : v(_v) {}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace impl
|
} // namespace impl
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
T from_which_variant( int which, const variant& v )
|
T from_which_variant( int which, const variant& v )
|
||||||
{
|
{
|
||||||
// Parse a variant for a known which()
|
// Parse a variant for a known which()
|
||||||
T result;
|
T dummy;
|
||||||
result.set_which( which );
|
dummy.set_which( which );
|
||||||
from_variant( v, result );
|
impl::from_which_visitor< T > vtor(v);
|
||||||
return result;
|
return dummy.visit( vtor );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
|
||||||
|
|
@ -216,6 +216,13 @@ struct approval_delta
|
||||||
vector<string> key_approvals_to_remove;
|
vector<string> key_approvals_to_remove;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct worker_vote_delta
|
||||||
|
{
|
||||||
|
flat_set<worker_id_type> vote_for;
|
||||||
|
flat_set<worker_id_type> vote_against;
|
||||||
|
flat_set<worker_id_type> vote_abstain;
|
||||||
|
};
|
||||||
|
|
||||||
struct signed_block_with_info : public signed_block
|
struct signed_block_with_info : public signed_block
|
||||||
{
|
{
|
||||||
signed_block_with_info( const signed_block& block );
|
signed_block_with_info( const signed_block& block );
|
||||||
|
|
@ -1124,6 +1131,43 @@ class wallet_api
|
||||||
string block_signing_key,
|
string block_signing_key,
|
||||||
bool broadcast = false);
|
bool broadcast = false);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a worker object.
|
||||||
|
*
|
||||||
|
* @param owner_account The account which owns the worker and will be paid
|
||||||
|
* @param work_begin_date When the work begins
|
||||||
|
* @param work_end_date When the work ends
|
||||||
|
* @param daily_pay Amount of pay per day (NOT per maint interval)
|
||||||
|
* @param name Any text
|
||||||
|
* @param url Any text
|
||||||
|
* @param worker_settings {"type" : "burn"|"refund"|"vesting", "pay_vesting_period_days" : x}
|
||||||
|
* @param broadcast true if you wish to broadcast the transaction.
|
||||||
|
*/
|
||||||
|
signed_transaction create_worker(
|
||||||
|
string owner_account,
|
||||||
|
time_point_sec work_begin_date,
|
||||||
|
time_point_sec work_end_date,
|
||||||
|
share_type daily_pay,
|
||||||
|
string name,
|
||||||
|
string url,
|
||||||
|
variant worker_settings,
|
||||||
|
bool broadcast = false
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update your votes for a worker
|
||||||
|
*
|
||||||
|
* @param account The account which will pay the fee and update votes.
|
||||||
|
* @param worker_vote_delta {"vote_for" : [...], "vote_against" : [...], "vote_abstain" : [...]}
|
||||||
|
* @param broadcast true if you wish to broadcast the transaction.
|
||||||
|
*/
|
||||||
|
signed_transaction update_worker_votes(
|
||||||
|
string account,
|
||||||
|
worker_vote_delta delta,
|
||||||
|
bool broadcast = false
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get information about a vesting balance object.
|
* Get information about a vesting balance object.
|
||||||
*
|
*
|
||||||
|
|
@ -1380,6 +1424,12 @@ FC_REFLECT( graphene::wallet::approval_delta,
|
||||||
(key_approvals_to_remove)
|
(key_approvals_to_remove)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
FC_REFLECT( graphene::wallet::worker_vote_delta,
|
||||||
|
(vote_for)
|
||||||
|
(vote_against)
|
||||||
|
(vote_abstain)
|
||||||
|
)
|
||||||
|
|
||||||
FC_REFLECT_DERIVED( graphene::wallet::signed_block_with_info, (graphene::chain::signed_block),
|
FC_REFLECT_DERIVED( graphene::wallet::signed_block_with_info, (graphene::chain::signed_block),
|
||||||
(block_id)(signing_key) )
|
(block_id)(signing_key) )
|
||||||
|
|
||||||
|
|
@ -1440,6 +1490,8 @@ FC_API( graphene::wallet::wallet_api,
|
||||||
(list_committee_members)
|
(list_committee_members)
|
||||||
(create_witness)
|
(create_witness)
|
||||||
(update_witness)
|
(update_witness)
|
||||||
|
(create_worker)
|
||||||
|
(update_worker_votes)
|
||||||
(get_vesting_balances)
|
(get_vesting_balances)
|
||||||
(withdraw_vesting)
|
(withdraw_vesting)
|
||||||
(vote_for_committee_member)
|
(vote_for_committee_member)
|
||||||
|
|
|
||||||
|
|
@ -1407,6 +1407,122 @@ public:
|
||||||
return sign_transaction( tx, broadcast );
|
return sign_transaction( tx, broadcast );
|
||||||
} FC_CAPTURE_AND_RETHROW( (witness_name)(url)(block_signing_key)(broadcast) ) }
|
} FC_CAPTURE_AND_RETHROW( (witness_name)(url)(block_signing_key)(broadcast) ) }
|
||||||
|
|
||||||
|
template<typename WorkerInit>
|
||||||
|
static WorkerInit _create_worker_initializer( const variant& worker_settings )
|
||||||
|
{
|
||||||
|
WorkerInit result;
|
||||||
|
from_variant( worker_settings, result );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
signed_transaction create_worker(
|
||||||
|
string owner_account,
|
||||||
|
time_point_sec work_begin_date,
|
||||||
|
time_point_sec work_end_date,
|
||||||
|
share_type daily_pay,
|
||||||
|
string name,
|
||||||
|
string url,
|
||||||
|
variant worker_settings,
|
||||||
|
bool broadcast
|
||||||
|
)
|
||||||
|
{
|
||||||
|
worker_initializer init;
|
||||||
|
std::string wtype = worker_settings["type"].get_string();
|
||||||
|
|
||||||
|
// TODO: Use introspection to do this dispatch
|
||||||
|
if( wtype == "burn" )
|
||||||
|
init = _create_worker_initializer< burn_worker_initializer >( worker_settings );
|
||||||
|
else if( wtype == "refund" )
|
||||||
|
init = _create_worker_initializer< refund_worker_initializer >( worker_settings );
|
||||||
|
else if( wtype == "vesting" )
|
||||||
|
init = _create_worker_initializer< vesting_balance_worker_initializer >( worker_settings );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FC_ASSERT( false, "unknown worker[\"type\"] value" );
|
||||||
|
}
|
||||||
|
|
||||||
|
worker_create_operation op;
|
||||||
|
op.owner = get_account( owner_account ).id;
|
||||||
|
op.work_begin_date = work_begin_date;
|
||||||
|
op.work_end_date = work_end_date;
|
||||||
|
op.daily_pay = daily_pay;
|
||||||
|
op.name = name;
|
||||||
|
op.url = url;
|
||||||
|
op.initializer = init;
|
||||||
|
|
||||||
|
signed_transaction tx;
|
||||||
|
tx.operations.push_back( op );
|
||||||
|
set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees );
|
||||||
|
tx.validate();
|
||||||
|
|
||||||
|
return sign_transaction( tx, broadcast );
|
||||||
|
}
|
||||||
|
|
||||||
|
signed_transaction update_worker_votes(
|
||||||
|
string account,
|
||||||
|
worker_vote_delta delta,
|
||||||
|
bool broadcast
|
||||||
|
)
|
||||||
|
{
|
||||||
|
account_object acct = get_account( account );
|
||||||
|
account_update_operation op;
|
||||||
|
|
||||||
|
// you could probably use a faster algorithm for this, but flat_set is fast enough :)
|
||||||
|
flat_set< worker_id_type > merged;
|
||||||
|
merged.reserve( delta.vote_for.size() + delta.vote_against.size() + delta.vote_abstain.size() );
|
||||||
|
for( const worker_id_type& wid : delta.vote_for )
|
||||||
|
{
|
||||||
|
bool inserted = merged.insert( wid ).second;
|
||||||
|
FC_ASSERT( inserted, "worker ${wid} specified multiple times", ("wid", wid) );
|
||||||
|
}
|
||||||
|
for( const worker_id_type& wid : delta.vote_against )
|
||||||
|
{
|
||||||
|
bool inserted = merged.insert( wid ).second;
|
||||||
|
FC_ASSERT( inserted, "worker ${wid} specified multiple times", ("wid", wid) );
|
||||||
|
}
|
||||||
|
for( const worker_id_type& wid : delta.vote_abstain )
|
||||||
|
{
|
||||||
|
bool inserted = merged.insert( wid ).second;
|
||||||
|
FC_ASSERT( inserted, "worker ${wid} specified multiple times", ("wid", wid) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// should be enforced by FC_ASSERT's above
|
||||||
|
assert( merged.size() == delta.vote_for.size() + delta.vote_against.size() + delta.vote_abstain.size() );
|
||||||
|
|
||||||
|
vector< object_id_type > query_ids;
|
||||||
|
for( const worker_id_type& wid : merged )
|
||||||
|
query_ids.push_back( wid );
|
||||||
|
|
||||||
|
flat_set<vote_id_type> new_votes( acct.options.votes );
|
||||||
|
|
||||||
|
fc::variants objects = _remote_db->get_objects( query_ids );
|
||||||
|
for( const variant& obj : objects )
|
||||||
|
{
|
||||||
|
worker_object wo;
|
||||||
|
from_variant( obj, wo );
|
||||||
|
new_votes.erase( wo.vote_for );
|
||||||
|
new_votes.erase( wo.vote_against );
|
||||||
|
if( delta.vote_for.find( wo.id ) != delta.vote_for.end() )
|
||||||
|
new_votes.insert( wo.vote_for );
|
||||||
|
else if( delta.vote_against.find( wo.id ) != delta.vote_against.end() )
|
||||||
|
new_votes.insert( wo.vote_against );
|
||||||
|
else
|
||||||
|
assert( delta.vote_abstain.find( wo.id ) != delta.vote_abstain.end() );
|
||||||
|
}
|
||||||
|
|
||||||
|
account_update_operation update_op;
|
||||||
|
update_op.account = acct.id;
|
||||||
|
update_op.new_options = acct.options;
|
||||||
|
update_op.new_options->votes = new_votes;
|
||||||
|
|
||||||
|
signed_transaction tx;
|
||||||
|
tx.operations.push_back( update_op );
|
||||||
|
set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees );
|
||||||
|
tx.validate();
|
||||||
|
|
||||||
|
return sign_transaction( tx, broadcast );
|
||||||
|
}
|
||||||
|
|
||||||
vector< vesting_balance_object_with_info > get_vesting_balances( string account_name )
|
vector< vesting_balance_object_with_info > get_vesting_balances( string account_name )
|
||||||
{ try {
|
{ try {
|
||||||
fc::optional<vesting_balance_id_type> vbid = maybe_id<vesting_balance_id_type>( account_name );
|
fc::optional<vesting_balance_id_type> vbid = maybe_id<vesting_balance_id_type>( account_name );
|
||||||
|
|
@ -2864,6 +2980,28 @@ signed_transaction wallet_api::create_witness(string owner_account,
|
||||||
return my->create_witness(owner_account, url, broadcast);
|
return my->create_witness(owner_account, url, broadcast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
signed_transaction wallet_api::create_worker(
|
||||||
|
string owner_account,
|
||||||
|
time_point_sec work_begin_date,
|
||||||
|
time_point_sec work_end_date,
|
||||||
|
share_type daily_pay,
|
||||||
|
string name,
|
||||||
|
string url,
|
||||||
|
variant worker_settings,
|
||||||
|
bool broadcast /* = false */)
|
||||||
|
{
|
||||||
|
return my->create_worker( owner_account, work_begin_date, work_end_date,
|
||||||
|
daily_pay, name, url, worker_settings, broadcast );
|
||||||
|
}
|
||||||
|
|
||||||
|
signed_transaction wallet_api::update_worker_votes(
|
||||||
|
string owner_account,
|
||||||
|
worker_vote_delta delta,
|
||||||
|
bool broadcast /* = false */)
|
||||||
|
{
|
||||||
|
return my->update_worker_votes( owner_account, delta, broadcast );
|
||||||
|
}
|
||||||
|
|
||||||
signed_transaction wallet_api::update_witness(
|
signed_transaction wallet_api::update_witness(
|
||||||
string witness_name,
|
string witness_name,
|
||||||
string url,
|
string url,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue