Merge branch 'origin/feature/SONs-base' into SON-291

This commit is contained in:
satyakoneru 2020-04-03 17:44:57 +00:00
commit 4ef94d9ae6
20 changed files with 173 additions and 106 deletions

View file

@ -110,6 +110,8 @@ void_result account_create_evaluator::do_evaluate( const account_create_operatio
} }
if( d.head_block_time() < HARDFORK_999_TIME ) if( d.head_block_time() < HARDFORK_999_TIME )
FC_ASSERT( !op.extensions.value.affiliate_distributions.valid(), "Affiliate reward distributions not allowed yet" ); FC_ASSERT( !op.extensions.value.affiliate_distributions.valid(), "Affiliate reward distributions not allowed yet" );
if (d.head_block_time() < HARDFORK_SON_TIME)
FC_ASSERT(op.name != "son-account", "Son account creation before SON hardfork");
FC_ASSERT( fee_paying_account->is_lifetime_member(), "Only Lifetime members may register an account." ); FC_ASSERT( fee_paying_account->is_lifetime_member(), "Only Lifetime members may register an account." );
FC_ASSERT( op.referrer(d).is_member(d.head_block_time()), "The referrer must be either a lifetime or annual subscriber." ); FC_ASSERT( op.referrer(d).is_member(d.head_block_time()), "The referrer must be either a lifetime or annual subscriber." );

View file

@ -42,6 +42,9 @@ void_result asset_create_evaluator::do_evaluate( const asset_create_operation& o
database& d = db(); database& d = db();
if (d.head_block_time() < HARDFORK_SON_TIME)
FC_ASSERT(op.symbol != "BTC", "BTC asset creation before SON hardfork");
const auto& chain_parameters = d.get_global_properties().parameters; const auto& chain_parameters = d.get_global_properties().parameters;
FC_ASSERT( op.common_options.whitelist_authorities.size() <= chain_parameters.maximum_asset_whitelist_authorities ); FC_ASSERT( op.common_options.whitelist_authorities.size() <= chain_parameters.maximum_asset_whitelist_authorities );
FC_ASSERT( op.common_options.blacklist_authorities.size() <= chain_parameters.maximum_asset_whitelist_authorities ); FC_ASSERT( op.common_options.blacklist_authorities.size() <= chain_parameters.maximum_asset_whitelist_authorities );

View file

@ -196,8 +196,6 @@ void database::pay_sons()
if(s.txs_signed > 0){ if(s.txs_signed > 0){
auto son_params = get_global_properties().parameters; auto son_params = get_global_properties().parameters;
share_type pay = (s.txs_signed * son_budget.value)/total_txs_signed; share_type pay = (s.txs_signed * son_budget.value)/total_txs_signed;
// TODO: Remove me after QA
ilog( "pay ${p} to ${s} for ${t} transactions signed", ("p", pay.value)("s", s.id)("t",s.txs_signed) );
const auto& idx = get_index_type<son_index>().indices().get<by_id>(); const auto& idx = get_index_type<son_index>().indices().get<by_id>();
auto son_obj = idx.find( s.owner ); auto son_obj = idx.find( s.owner );
modify( *son_obj, [&]( son_object& _son_obj) modify( *son_obj, [&]( son_object& _son_obj)
@ -365,6 +363,8 @@ void database::update_son_wallet(const vector<son_info>& new_active_sons)
} }
} }
should_recreate_pw = should_recreate_pw && (new_active_sons.size() >= get_chain_properties().immutable_parameters.min_son_count);
if (should_recreate_pw) { if (should_recreate_pw) {
// Create new son_wallet_object, to initiate wallet recreation // Create new son_wallet_object, to initiate wallet recreation
create<son_wallet_object>( [&]( son_wallet_object& obj ) { create<son_wallet_object>( [&]( son_wallet_object& obj ) {
@ -863,7 +863,7 @@ void database::process_budget()
pay_sons(); pay_sons();
rec.leftover_son_funds = dpo.son_budget; rec.leftover_son_funds = dpo.son_budget;
available_funds += rec.leftover_son_funds; available_funds += rec.leftover_son_funds;
son_budget = gpo.parameters.son_pay_daily_max(); son_budget = gpo.parameters.son_pay_max();
son_budget = std::min(son_budget, available_funds); son_budget = std::min(son_budget, available_funds);
rec.son_budget = son_budget; rec.son_budget = son_budget;
available_funds -= son_budget; available_funds -= son_budget;
@ -1889,12 +1889,40 @@ void perform_son_tasks(database& db)
a.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT - GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE; a.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT - GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
}); });
db.modify( gpo, [&]( global_property_object& gpo ) { db.modify( gpo, [&son_account]( global_property_object& gpo ) {
gpo.parameters.extensions.value.son_account = son_account.get_id(); gpo.parameters.extensions.value.son_account = son_account.get_id();
if( gpo.pending_parameters ) if( gpo.pending_parameters )
gpo.pending_parameters->extensions.value.son_account = son_account.get_id(); gpo.pending_parameters->extensions.value.son_account = son_account.get_id();
}); });
} }
// create BTC asset here because son_account is the issuer of the BTC
if (gpo.parameters.btc_asset() == asset_id_type() && db.head_block_time() >= HARDFORK_SON_TIME)
{
const asset_dynamic_data_object& dyn_asset =
db.create<asset_dynamic_data_object>([](asset_dynamic_data_object& a) {
a.current_supply = 0;
});
const asset_object& btc_asset =
db.create<asset_object>( [&gpo, &dyn_asset]( asset_object& a ) {
a.symbol = "BTC";
a.options.max_supply = GRAPHENE_MAX_SHARE_SUPPLY;
a.precision = 8;
a.options.flags = 0;
a.options.issuer_permissions = 0;
a.issuer = gpo.parameters.son_account();
a.options.core_exchange_rate.base.amount = 1;
a.options.core_exchange_rate.base.asset_id = asset_id_type(0);
a.options.core_exchange_rate.quote.amount = 1;
a.options.core_exchange_rate.quote.asset_id = asset_id_type(0);
a.dynamic_asset_data_id = dyn_asset.id;
});
db.modify( gpo, [&btc_asset]( global_property_object& gpo ) {
gpo.parameters.extensions.value.btc_asset = btc_asset.get_id();
if( gpo.pending_parameters )
gpo.pending_parameters->extensions.value.btc_asset = btc_asset.get_id();
});
}
} }
void database::perform_chain_maintenance(const signed_block& next_block, const global_property_object& global_props) void database::perform_chain_maintenance(const signed_block& next_block, const global_property_object& global_props)
@ -2095,6 +2123,20 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
p.pending_parameters->extensions.value.gpos_subperiod = p.parameters.extensions.value.gpos_subperiod; p.pending_parameters->extensions.value.gpos_subperiod = p.parameters.extensions.value.gpos_subperiod;
if( !p.pending_parameters->extensions.value.gpos_vesting_lockin_period.valid() ) if( !p.pending_parameters->extensions.value.gpos_vesting_lockin_period.valid() )
p.pending_parameters->extensions.value.gpos_vesting_lockin_period = p.parameters.extensions.value.gpos_vesting_lockin_period; p.pending_parameters->extensions.value.gpos_vesting_lockin_period = p.parameters.extensions.value.gpos_vesting_lockin_period;
if( !p.pending_parameters->extensions.value.son_vesting_amount.valid() )
p.pending_parameters->extensions.value.son_vesting_amount = p.parameters.extensions.value.son_vesting_amount;
if( !p.pending_parameters->extensions.value.son_vesting_period.valid() )
p.pending_parameters->extensions.value.son_vesting_period = p.parameters.extensions.value.son_vesting_period;
if( !p.pending_parameters->extensions.value.son_pay_max.valid() )
p.pending_parameters->extensions.value.son_pay_max = p.parameters.extensions.value.son_pay_max;
if( !p.pending_parameters->extensions.value.son_pay_time.valid() )
p.pending_parameters->extensions.value.son_pay_time = p.parameters.extensions.value.son_pay_time;
if( !p.pending_parameters->extensions.value.son_deregister_time.valid() )
p.pending_parameters->extensions.value.son_deregister_time = p.parameters.extensions.value.son_deregister_time;
if( !p.pending_parameters->extensions.value.son_heartbeat_frequency.valid() )
p.pending_parameters->extensions.value.son_heartbeat_frequency = p.parameters.extensions.value.son_heartbeat_frequency;
if( !p.pending_parameters->extensions.value.son_down_time.valid() )
p.pending_parameters->extensions.value.son_down_time = p.parameters.extensions.value.son_down_time;
p.parameters = std::move(*p.pending_parameters); p.parameters = std::move(*p.pending_parameters);
p.pending_parameters.reset(); p.pending_parameters.reset();
} }

View file

@ -229,14 +229,13 @@
#define TOURNAMENT_MAX_WHITELIST_LENGTH 1000 #define TOURNAMENT_MAX_WHITELIST_LENGTH 1000
#define TOURNAMENT_MAX_START_TIME_IN_FUTURE (60*60*24*7*4) // 1 month #define TOURNAMENT_MAX_START_TIME_IN_FUTURE (60*60*24*7*4) // 1 month
#define TOURNAMENT_MAX_START_DELAY (60*60*24*7) // 1 week #define TOURNAMENT_MAX_START_DELAY (60*60*24*7) // 1 week
#define MIN_SON_MEMBER_COUNT 15
#define SON_VESTING_AMOUNT (50*GRAPHENE_BLOCKCHAIN_PRECISION) // 50 PPY #define SON_VESTING_AMOUNT (50*GRAPHENE_BLOCKCHAIN_PRECISION) // 50 PPY
#define SON_VESTING_PERIOD (60*60*24*2) // 2 days #define SON_VESTING_PERIOD (60*60*24*2) // 2 days
#define SON_DEREGISTER_TIME (60*60*12) // 12 Hours in seconds #define SON_DEREGISTER_TIME (60*60*12) // 12 Hours in seconds
#define SON_HEARTBEAT_FREQUENCY (60*3) // 3 minutes in seconds #define SON_HEARTBEAT_FREQUENCY (60*3) // 3 minutes in seconds
#define SON_DOWN_TIME (60*3*2) // 2 Heartbeats in seconds #define SON_DOWN_TIME (60*3*2) // 2 Heartbeats in seconds
#define SON_PAY_TIME (60*60*24) // 1 day #define SON_PAY_TIME (60*60*24) // 1 day
#define MIN_SON_PAY_DAILY_MAX (GRAPHENE_BLOCKCHAIN_PRECISION * int64_t(200)) #define SON_PAY_MAX (GRAPHENE_BLOCKCHAIN_PRECISION * int64_t(200))
#define SWEEPS_DEFAULT_DISTRIBUTION_PERCENTAGE (2*GRAPHENE_1_PERCENT) #define SWEEPS_DEFAULT_DISTRIBUTION_PERCENTAGE (2*GRAPHENE_1_PERCENT)
#define SWEEPS_DEFAULT_DISTRIBUTION_ASSET (graphene::chain::asset_id_type(0)) #define SWEEPS_DEFAULT_DISTRIBUTION_ASSET (graphene::chain::asset_id_type(0))
#define SWEEPS_VESTING_BALANCE_MULTIPLIER 100000000 #define SWEEPS_VESTING_BALANCE_MULTIPLIER 100000000

View file

@ -50,15 +50,16 @@ namespace graphene { namespace chain {
optional < uint32_t > gpos_period_start = HARDFORK_GPOS_TIME.sec_since_epoch(); optional < uint32_t > gpos_period_start = HARDFORK_GPOS_TIME.sec_since_epoch();
optional < uint32_t > gpos_vesting_lockin_period = GPOS_VESTING_LOCKIN_PERIOD; optional < uint32_t > gpos_vesting_lockin_period = GPOS_VESTING_LOCKIN_PERIOD;
optional < uint16_t > son_count; optional < uint32_t > son_vesting_amount = SON_VESTING_AMOUNT;
optional < uint32_t > son_vesting_amount; optional < uint32_t > son_vesting_period = SON_VESTING_PERIOD;
optional < uint32_t > son_vesting_period; optional < uint32_t > son_pay_max = SON_PAY_MAX;
optional < uint32_t > son_pay_daily_max; optional < uint32_t > son_pay_time = SON_PAY_TIME;
optional < uint32_t > son_pay_time; optional < uint32_t > son_deregister_time = SON_DEREGISTER_TIME;
optional < uint32_t > son_deregister_time; optional < uint32_t > son_heartbeat_frequency = SON_HEARTBEAT_FREQUENCY;
optional < uint32_t > son_heartbeat_frequency; optional < uint32_t > son_down_time = SON_DOWN_TIME;
optional < uint32_t > son_down_time;
optional < account_id_type > son_account; optional < account_id_type > son_account;
optional < asset_id_type > btc_asset;
}; };
struct chain_parameters struct chain_parameters
@ -139,17 +140,14 @@ namespace graphene { namespace chain {
inline account_id_type sweeps_vesting_accumulator_account()const { inline account_id_type sweeps_vesting_accumulator_account()const {
return extensions.value.sweeps_vesting_accumulator_account.valid() ? *extensions.value.sweeps_vesting_accumulator_account : SWEEPS_ACCUMULATOR_ACCOUNT; return extensions.value.sweeps_vesting_accumulator_account.valid() ? *extensions.value.sweeps_vesting_accumulator_account : SWEEPS_ACCUMULATOR_ACCOUNT;
} }
inline uint16_t son_count()const {
return extensions.value.son_count.valid() ? *extensions.value.son_count : MIN_SON_MEMBER_COUNT;
}
inline uint32_t son_vesting_amount()const { inline uint32_t son_vesting_amount()const {
return extensions.value.son_vesting_amount.valid() ? *extensions.value.son_vesting_amount : SON_VESTING_AMOUNT; /// current period start date return extensions.value.son_vesting_amount.valid() ? *extensions.value.son_vesting_amount : SON_VESTING_AMOUNT; /// current period start date
} }
inline uint32_t son_vesting_period()const { inline uint32_t son_vesting_period()const {
return extensions.value.son_vesting_period.valid() ? *extensions.value.son_vesting_period : SON_VESTING_PERIOD; /// current period start date return extensions.value.son_vesting_period.valid() ? *extensions.value.son_vesting_period : SON_VESTING_PERIOD; /// current period start date
} }
inline uint16_t son_pay_daily_max()const { inline uint16_t son_pay_max()const {
return extensions.value.son_pay_daily_max.valid() ? *extensions.value.son_pay_daily_max : MIN_SON_PAY_DAILY_MAX; return extensions.value.son_pay_max.valid() ? *extensions.value.son_pay_max : SON_PAY_MAX;
} }
inline uint16_t son_pay_time()const { inline uint16_t son_pay_time()const {
return extensions.value.son_pay_time.valid() ? *extensions.value.son_pay_time : SON_PAY_TIME; return extensions.value.son_pay_time.valid() ? *extensions.value.son_pay_time : SON_PAY_TIME;
@ -178,6 +176,9 @@ namespace graphene { namespace chain {
inline account_id_type son_account() const { inline account_id_type son_account() const {
return extensions.value.son_account.valid() ? *extensions.value.son_account : GRAPHENE_NULL_ACCOUNT; return extensions.value.son_account.valid() ? *extensions.value.son_account : GRAPHENE_NULL_ACCOUNT;
} }
inline asset_id_type btc_asset() const {
return extensions.value.btc_asset.valid() ? *extensions.value.btc_asset : asset_id_type();
}
}; };
} } // graphene::chain } } // graphene::chain
@ -188,7 +189,6 @@ FC_REFLECT( graphene::chain::parameter_extension,
(betting_rake_fee_percentage) (betting_rake_fee_percentage)
(permitted_betting_odds_increments) (permitted_betting_odds_increments)
(live_betting_delay_time) (live_betting_delay_time)
(son_count)
(sweeps_distribution_percentage) (sweeps_distribution_percentage)
(sweeps_distribution_asset) (sweeps_distribution_asset)
(sweeps_vesting_accumulator_account) (sweeps_vesting_accumulator_account)
@ -198,12 +198,13 @@ FC_REFLECT( graphene::chain::parameter_extension,
(gpos_vesting_lockin_period) (gpos_vesting_lockin_period)
(son_vesting_amount) (son_vesting_amount)
(son_vesting_period) (son_vesting_period)
(son_pay_daily_max) (son_pay_max)
(son_pay_time) (son_pay_time)
(son_deregister_time) (son_deregister_time)
(son_heartbeat_frequency) (son_heartbeat_frequency)
(son_down_time) (son_down_time)
(son_account) (son_account)
(btc_asset)
) )
FC_REFLECT( graphene::chain::chain_parameters, FC_REFLECT( graphene::chain::chain_parameters,

View file

@ -145,8 +145,6 @@ object_id_type son_heartbeat_evaluator::do_apply(const son_heartbeat_operation&
{ {
sso.current_interval_downtime += op.ts.sec_since_epoch() - sso.last_down_timestamp.sec_since_epoch(); sso.current_interval_downtime += op.ts.sec_since_epoch() - sso.last_down_timestamp.sec_since_epoch();
sso.last_active_timestamp = op.ts; sso.last_active_timestamp = op.ts;
// TODO: Remove me after sidechain tx signing is finished
sso.txs_signed = sso.txs_signed + 1;
} ); } );
db().modify(*itr, [&is_son_active](son_object &so) { db().modify(*itr, [&is_son_active](son_object &so) {
@ -160,8 +158,6 @@ object_id_type son_heartbeat_evaluator::do_apply(const son_heartbeat_operation&
db().modify( itr->statistics( db() ), [&]( son_statistics_object& sso ) db().modify( itr->statistics( db() ), [&]( son_statistics_object& sso )
{ {
sso.last_active_timestamp = op.ts; sso.last_active_timestamp = op.ts;
// TODO: Remove me after sidechain tx signing is finished
sso.txs_signed = sso.txs_signed + 1;
} ); } );
} }
} }

View file

@ -1,6 +1,7 @@
#include <graphene/chain/son_wallet_deposit_evaluator.hpp> #include <graphene/chain/son_wallet_deposit_evaluator.hpp>
#include <graphene/chain/database.hpp> #include <graphene/chain/database.hpp>
#include <graphene/chain/chain_property_object.hpp>
#include <graphene/chain/is_authorized_asset.hpp> #include <graphene/chain/is_authorized_asset.hpp>
#include <graphene/chain/son_object.hpp> #include <graphene/chain/son_object.hpp>
#include <graphene/chain/son_wallet_deposit_object.hpp> #include <graphene/chain/son_wallet_deposit_object.hpp>
@ -130,6 +131,7 @@ void_result process_son_wallet_deposit_evaluator::do_evaluate(const son_wallet_d
{ try{ { try{
FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK"); FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK");
FC_ASSERT( op.payer == db().get_global_properties().parameters.son_account(), "SON paying account must be set as payer." ); FC_ASSERT( op.payer == db().get_global_properties().parameters.son_account(), "SON paying account must be set as payer." );
FC_ASSERT(db().get_global_properties().active_sons.size() >= db().get_chain_properties().immutable_parameters.min_son_count, "Min required voted SONs not present");
const auto& idx = db().get_index_type<son_wallet_deposit_index>().indices().get<by_id>(); const auto& idx = db().get_index_type<son_wallet_deposit_index>().indices().get<by_id>();
const auto& itr = idx.find(op.son_wallet_deposit_id); const auto& itr = idx.find(op.son_wallet_deposit_id);

View file

@ -1,6 +1,7 @@
#include <graphene/chain/son_wallet_withdraw_evaluator.hpp> #include <graphene/chain/son_wallet_withdraw_evaluator.hpp>
#include <graphene/chain/database.hpp> #include <graphene/chain/database.hpp>
#include <graphene/chain/chain_property_object.hpp>
#include <graphene/chain/is_authorized_asset.hpp> #include <graphene/chain/is_authorized_asset.hpp>
#include <graphene/chain/son_object.hpp> #include <graphene/chain/son_object.hpp>
#include <graphene/chain/son_wallet_withdraw_object.hpp> #include <graphene/chain/son_wallet_withdraw_object.hpp>
@ -128,6 +129,7 @@ void_result process_son_wallet_withdraw_evaluator::do_evaluate(const son_wallet_
{ try{ { try{
FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK"); FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK");
FC_ASSERT( op.payer == db().get_global_properties().parameters.son_account(), "SON paying account must be set as payer." ); FC_ASSERT( op.payer == db().get_global_properties().parameters.son_account(), "SON paying account must be set as payer." );
FC_ASSERT(db().get_global_properties().active_sons.size() >= db().get_chain_properties().immutable_parameters.min_son_count, "Min required voted SONs not present");
const auto& idx = db().get_index_type<son_wallet_withdraw_index>().indices().get<by_id>(); const auto& idx = db().get_index_type<son_wallet_withdraw_index>().indices().get<by_id>();
const auto& itr = idx.find(op.son_wallet_withdraw_id); const auto& itr = idx.find(op.son_wallet_withdraw_id);

View file

@ -139,7 +139,7 @@ void_result vesting_balance_withdraw_evaluator::do_evaluate( const vesting_balan
const time_point_sec now = d.head_block_time(); const time_point_sec now = d.head_block_time();
const vesting_balance_object& vbo = op.vesting_balance( d ); const vesting_balance_object& vbo = op.vesting_balance( d );
if(vbo.balance_type == vesting_balance_type::normal) if(vbo.balance_type == vesting_balance_type::normal || vbo.balance_type == vesting_balance_type::son)
{ {
FC_ASSERT( op.owner == vbo.owner, "", ("op.owner", op.owner)("vbo.owner", vbo.owner) ); FC_ASSERT( op.owner == vbo.owner, "", ("op.owner", op.owner)("vbo.owner", vbo.owner) );
FC_ASSERT( vbo.is_withdraw_allowed( now, op.amount ), "Account has insufficient ${balance_type} Vested Balance to withdraw", FC_ASSERT( vbo.is_withdraw_allowed( now, op.amount ), "Account has insufficient ${balance_type} Vested Balance to withdraw",
@ -179,7 +179,7 @@ void_result vesting_balance_withdraw_evaluator::do_apply( const vesting_balance_
//Handling all GPOS withdrawls separately from normal and SONs(future extension). //Handling all GPOS withdrawls separately from normal and SONs(future extension).
// One request/transaction would be sufficient to withdraw from multiple vesting balance ids // One request/transaction would be sufficient to withdraw from multiple vesting balance ids
const vesting_balance_object& vbo = op.vesting_balance( d ); const vesting_balance_object& vbo = op.vesting_balance( d );
if(vbo.balance_type == vesting_balance_type::normal) if(vbo.balance_type == vesting_balance_type::normal || vbo.balance_type == vesting_balance_type::son)
{ {
// Allow zero balance objects to stick around, (1) to comply // Allow zero balance objects to stick around, (1) to comply
// with the chain's "objects live forever" design principle, (2) // with the chain's "objects live forever" design principle, (2)

View file

@ -6,6 +6,7 @@
#include <fc/signals.hpp> #include <fc/signals.hpp>
#include <graphene/chain/global_property_object.hpp> #include <graphene/chain/global_property_object.hpp>
#include <graphene/chain/chain_property_object.hpp>
#include <graphene/chain/sidechain_address_object.hpp> #include <graphene/chain/sidechain_address_object.hpp>
#include <graphene/chain/sidechain_transaction_object.hpp> #include <graphene/chain/sidechain_transaction_object.hpp>
#include <graphene/chain/son_wallet_deposit_object.hpp> #include <graphene/chain/son_wallet_deposit_object.hpp>

View file

@ -428,10 +428,6 @@ bool peerplays_sidechain_plugin_impl::is_valid_son_proposal(const chain::proposa
return true; return true;
} }
if (op_idx_0 == chain::operation::tag<chain::son_wallet_withdraw_process_operation>::value) {
return true;
}
if (op_idx_0 == chain::operation::tag<chain::sidechain_transaction_create_operation>::value) { if (op_idx_0 == chain::operation::tag<chain::sidechain_transaction_create_operation>::value) {
return true; return true;
} }
@ -440,14 +436,16 @@ bool peerplays_sidechain_plugin_impl::is_valid_son_proposal(const chain::proposa
int32_t op_idx_1 = proposal.proposed_transaction.operations[1].which(); int32_t op_idx_1 = proposal.proposed_transaction.operations[1].which();
if ((op_idx_0 == chain::operation::tag<chain::son_wallet_deposit_process_operation>::value) && if ((op_idx_0 == chain::operation::tag<chain::son_wallet_deposit_process_operation>::value) &&
(op_idx_1 == chain::operation::tag<chain::transfer_operation>::value)) { (op_idx_1 == chain::operation::tag<chain::asset_issue_operation>::value)) {
return true; return true;
} }
if ((op_idx_0 == chain::operation::tag<chain::son_wallet_withdraw_process_operation>::value) &&
(op_idx_1 == chain::operation::tag<chain::asset_reserve_operation>::value)) {
return true;
}
} }
ilog("==================================================");
ilog("Proposal not approved ${proposal}", ("proposal", proposal));
ilog("==================================================");
return false; return false;
} }

View file

@ -68,7 +68,7 @@ void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_
const chain::global_property_object &gpo = database.get_global_properties(); const chain::global_property_object &gpo = database.get_global_properties();
// Deposit request // Deposit request
if ((sed.peerplays_to == gpo.parameters.son_account()) && (sed.sidechain_currency.compare("1.3.0") != 0)) { if ((sed.peerplays_from == gpo.parameters.son_account()) && (sed.sidechain_currency != fc::variant(gpo.parameters.btc_asset(), 1).as<std::string>(1))) {
for (son_id_type son_id : plugin.get_sons()) { for (son_id_type son_id : plugin.get_sons()) {
if (plugin.is_active_son(son_id)) { if (plugin.is_active_son(son_id)) {
@ -102,7 +102,7 @@ void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_
} }
// Withdrawal request // Withdrawal request
if ((sed.peerplays_to == gpo.parameters.son_account()) && (sed.sidechain_currency.compare("1.3.0") == 0)) { if ((sed.peerplays_to == gpo.parameters.son_account()) && (sed.sidechain_currency == fc::variant(gpo.parameters.btc_asset(), 1).as<std::string>(1))) {
// BTC Payout only (for now) // BTC Payout only (for now)
const auto &sidechain_addresses_idx = database.get_index_type<sidechain_address_index>().indices().get<by_account_and_sidechain>(); const auto &sidechain_addresses_idx = database.get_index_type<sidechain_address_index>().indices().get<by_account_and_sidechain>();
const auto &addr_itr = sidechain_addresses_idx.find(std::make_tuple(sed.peerplays_from, sidechain_type::bitcoin)); const auto &addr_itr = sidechain_addresses_idx.find(std::make_tuple(sed.peerplays_from, sidechain_type::bitcoin));
@ -124,7 +124,7 @@ void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_
op.withdraw_sidechain = sidechain_type::bitcoin; // BTC payout only (for now) op.withdraw_sidechain = sidechain_type::bitcoin; // BTC payout only (for now)
op.withdraw_address = addr_itr->withdraw_address; // BTC payout only (for now) op.withdraw_address = addr_itr->withdraw_address; // BTC payout only (for now)
op.withdraw_currency = "BTC"; // BTC payout only (for now) op.withdraw_currency = "BTC"; // BTC payout only (for now)
op.withdraw_amount = sed.peerplays_asset.amount * 1000; // BTC payout only (for now) op.withdraw_amount = sed.peerplays_asset.amount; // BTC payout only (for now)
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(son_id), op); signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(son_id), op);
try { try {
@ -143,6 +143,10 @@ void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_
} }
void sidechain_net_handler::process_deposits() { void sidechain_net_handler::process_deposits() {
if (database.get_global_properties().active_sons.size() < database.get_chain_properties().immutable_parameters.min_son_count) {
return;
}
const auto &idx = database.get_index_type<son_wallet_deposit_index>().indices().get<by_sidechain_and_confirmed_and_processed>(); const auto &idx = database.get_index_type<son_wallet_deposit_index>().indices().get<by_sidechain_and_confirmed_and_processed>();
const auto &idx_range = idx.equal_range(std::make_tuple(sidechain, true, false)); const auto &idx_range = idx.equal_range(std::make_tuple(sidechain, true, false));
@ -162,16 +166,16 @@ void sidechain_net_handler::process_deposits() {
swdp_op.payer = gpo.parameters.son_account(); swdp_op.payer = gpo.parameters.son_account();
swdp_op.son_wallet_deposit_id = swdo.id; swdp_op.son_wallet_deposit_id = swdo.id;
transfer_operation t_op; asset_issue_operation i_op;
t_op.fee = asset(2000000); i_op.fee = asset(2001000);
t_op.from = swdo.peerplays_to; // gpo.parameters.son_account() i_op.issuer = gpo.parameters.son_account();
t_op.to = swdo.peerplays_from; i_op.asset_to_issue = swdo.peerplays_asset;
t_op.amount = swdo.peerplays_asset; i_op.issue_to_account = swdo.peerplays_to;
proposal_create_operation proposal_op; proposal_create_operation proposal_op;
proposal_op.fee_paying_account = plugin.get_current_son_object().son_account; proposal_op.fee_paying_account = plugin.get_current_son_object().son_account;
proposal_op.proposed_ops.emplace_back(swdp_op); proposal_op.proposed_ops.emplace_back(swdp_op);
proposal_op.proposed_ops.emplace_back(t_op); proposal_op.proposed_ops.emplace_back(i_op);
uint32_t lifetime = (gpo.parameters.block_interval * gpo.active_witnesses.size()) * 3; uint32_t lifetime = (gpo.parameters.block_interval * gpo.active_witnesses.size()) * 3;
proposal_op.expiration_time = time_point_sec(database.head_block_time().sec_since_epoch() + lifetime); proposal_op.expiration_time = time_point_sec(database.head_block_time().sec_since_epoch() + lifetime);
@ -188,6 +192,10 @@ void sidechain_net_handler::process_deposits() {
} }
void sidechain_net_handler::process_withdrawals() { void sidechain_net_handler::process_withdrawals() {
if (database.get_global_properties().active_sons.size() < database.get_chain_properties().immutable_parameters.min_son_count) {
return;
}
const auto &idx = database.get_index_type<son_wallet_withdraw_index>().indices().get<by_withdraw_sidechain_and_confirmed_and_processed>(); const auto &idx = database.get_index_type<son_wallet_withdraw_index>().indices().get<by_withdraw_sidechain_and_confirmed_and_processed>();
const auto &idx_range = idx.equal_range(std::make_tuple(sidechain, true, false)); const auto &idx_range = idx.equal_range(std::make_tuple(sidechain, true, false));
@ -207,9 +215,16 @@ void sidechain_net_handler::process_withdrawals() {
swwp_op.payer = gpo.parameters.son_account(); swwp_op.payer = gpo.parameters.son_account();
swwp_op.son_wallet_withdraw_id = swwo.id; swwp_op.son_wallet_withdraw_id = swwo.id;
asset_reserve_operation r_op;
r_op.fee = asset(2001000);
r_op.payer = gpo.parameters.son_account();
asset_object btc_asset_obj = gpo.parameters.btc_asset()(database);
r_op.amount_to_reserve = btc_asset_obj.amount(swwo.withdraw_amount);
proposal_create_operation proposal_op; proposal_create_operation proposal_op;
proposal_op.fee_paying_account = plugin.get_current_son_object().son_account; proposal_op.fee_paying_account = plugin.get_current_son_object().son_account;
proposal_op.proposed_ops.emplace_back(swwp_op); proposal_op.proposed_ops.emplace_back(swwp_op);
proposal_op.proposed_ops.emplace_back(r_op);
uint32_t lifetime = (gpo.parameters.block_interval * gpo.active_witnesses.size()) * 3; uint32_t lifetime = (gpo.parameters.block_interval * gpo.active_witnesses.size()) * 3;
proposal_op.expiration_time = time_point_sec(database.head_block_time().sec_since_epoch() + lifetime); proposal_op.expiration_time = time_point_sec(database.head_block_time().sec_since_epoch() + lifetime);

View file

@ -1410,9 +1410,11 @@ void sidechain_net_handler_bitcoin::handle_event(const std::string &event_data)
sed.sidechain_to = v.address; sed.sidechain_to = v.address;
sed.sidechain_currency = "BTC"; sed.sidechain_currency = "BTC";
sed.sidechain_amount = v.out.amount; sed.sidechain_amount = v.out.amount;
sed.peerplays_from = addr_itr->sidechain_address_account; sed.peerplays_from = database.get_global_properties().parameters.son_account();
sed.peerplays_to = database.get_global_properties().parameters.son_account(); sed.peerplays_to = addr_itr->sidechain_address_account;
sed.peerplays_asset = asset(sed.sidechain_amount / 1000); // For Bitcoin, the exchange rate is 1:1, for others, get the exchange rate from market asset_id_type btc_asset_id = database.get_global_properties().parameters.btc_asset();
asset_object btc_asset = btc_asset_id(database);
sed.peerplays_asset = btc_asset.amount(sed.sidechain_amount);
sidechain_event_data_received(sed); sidechain_event_data_received(sed);
} }
} }

View file

@ -61,6 +61,9 @@ void sidechain_net_handler_peerplays::on_applied_block(const signed_block &b) {
if (transfer_op.to != plugin.database().get_global_properties().parameters.son_account()) { if (transfer_op.to != plugin.database().get_global_properties().parameters.son_account()) {
continue; continue;
} }
// only bitcoin withdraws acepted for now
if (transfer_op.amount.asset_id != plugin.database().get_global_properties().parameters.btc_asset())
continue;
std::stringstream ss; std::stringstream ss;
ss << "peerplays" ss << "peerplays"
@ -78,8 +81,7 @@ void sidechain_net_handler_peerplays::on_applied_block(const signed_block &b) {
sed.sidechain_amount = transfer_op.amount.amount; sed.sidechain_amount = transfer_op.amount.amount;
sed.peerplays_from = transfer_op.from; sed.peerplays_from = transfer_op.from;
sed.peerplays_to = transfer_op.to; sed.peerplays_to = transfer_op.to;
// We should calculate exchange rate between CORE/TEST and other Peerplays asset sed.peerplays_asset = transfer_op.amount;
sed.peerplays_asset = asset(transfer_op.amount.amount / transfer_op.amount.asset_id(database).options.core_exchange_rate.quote.amount);
sidechain_event_data_received(sed); sidechain_event_data_received(sed);
} }
} }

View file

@ -2414,8 +2414,8 @@ public:
vesting_balance_object vbo = get_object< vesting_balance_object >( *vbid ); vesting_balance_object vbo = get_object< vesting_balance_object >( *vbid );
if(vbo.balance_type != vesting_balance_type::normal) if(vbo.balance_type == vesting_balance_type::gpos)
FC_THROW("Allowed to withdraw only Normal type vest balances with this method"); FC_THROW("Allowed to withdraw only Normal and Son type vest balances with this method");
vesting_balance_withdraw_operation vesting_balance_withdraw_op; vesting_balance_withdraw_operation vesting_balance_withdraw_op;
@ -6729,7 +6729,8 @@ vesting_balance_object_with_info::vesting_balance_object_with_info( const vestin
: vesting_balance_object( vbo ) : vesting_balance_object( vbo )
{ {
allowed_withdraw = get_allowed_withdraw( now ); allowed_withdraw = get_allowed_withdraw( now );
if(vbo.balance_type == vesting_balance_type::gpos) if(vbo.balance_type == vesting_balance_type::gpos ||
((vbo.balance_type == vesting_balance_type::son) && (vbo.policy.which() == vesting_policy::tag<linear_vesting_policy>::value)))
allowed_withdraw_time = vbo.policy.get<linear_vesting_policy>().begin_timestamp + vbo.policy.get<linear_vesting_policy>().vesting_cliff_seconds; allowed_withdraw_time = vbo.policy.get<linear_vesting_policy>().begin_timestamp + vbo.policy.get<linear_vesting_policy>().vesting_cliff_seconds;
else else
allowed_withdraw_time = now; allowed_withdraw_time = now;

View file

@ -344,6 +344,7 @@
"maximum_asset_feed_publishers": 10, "maximum_asset_feed_publishers": 10,
"maximum_witness_count": 1001, "maximum_witness_count": 1001,
"maximum_committee_count": 1001, "maximum_committee_count": 1001,
"maximum_son_count": 15,
"maximum_authority_membership": 10, "maximum_authority_membership": 10,
"reserve_percent_of_fee": 2000, "reserve_percent_of_fee": 2000,
"network_percent_of_fee": 2000, "network_percent_of_fee": 2000,
@ -383,7 +384,7 @@
"gpos_vesting_lockin_period": 2592000, "gpos_vesting_lockin_period": 2592000,
"son_vesting_amount": 5000000, "son_vesting_amount": 5000000,
"son_vesting_period": 172800, "son_vesting_period": 172800,
"son_pay_daily_max": 20000000, "son_pay_max": 20000000,
"son_pay_time": 86400, "son_pay_time": 86400,
"son_deregister_time": 43200, "son_deregister_time": 43200,
"son_heartbeat_frequency": 180, "son_heartbeat_frequency": 180,

View file

@ -231,7 +231,7 @@ BOOST_AUTO_TEST_CASE(elasticsearch_history_api) {
create_bitasset("USD", account_id_type()); // create op 0 create_bitasset("USD", account_id_type()); // create op 0
const account_object& dan = create_account("dan"); // create op 1 const account_object& dan = create_account("dan"); // create op 1
create_bitasset("CNY", dan.id); // create op 2 create_bitasset("CNY", dan.id); // create op 2
create_bitasset("BTC", account_id_type()); // create op 3 create_bitasset("BTCTEST", account_id_type()); // create op 3
create_bitasset("XMR", dan.id); // create op 4 create_bitasset("XMR", dan.id); // create op 4
create_bitasset("EUR", account_id_type()); // create op 5 create_bitasset("EUR", account_id_type()); // create op 5
create_bitasset("OIL", dan.id); // create op 6 create_bitasset("OIL", dan.id); // create op 6

View file

@ -289,7 +289,7 @@ BOOST_AUTO_TEST_CASE( affiliate_payout_helper_test )
{ {
ACTORS( (irene) ); ACTORS( (irene) );
const asset_id_type btc_id = create_user_issued_asset( "BTC", irene, 0 ).id; const asset_id_type btc_id = create_user_issued_asset( "BTCTEST", irene, 0 ).id;
issue_uia( irene, asset( 100000, btc_id ) ); issue_uia( irene, asset( 100000, btc_id ) );
affiliate_test_helper ath( *this ); affiliate_test_helper ath( *this );
@ -517,7 +517,7 @@ BOOST_AUTO_TEST_CASE( bookie_payout_test )
{ try { { try {
ACTORS( (irene) ); ACTORS( (irene) );
const asset_id_type btc_id = create_user_issued_asset( "BTC", irene, 0 ).id; const asset_id_type btc_id = create_user_issued_asset( "BTCTEST", irene, 0 ).id;
affiliate_test_helper ath( *this ); affiliate_test_helper ath( *this );
@ -616,7 +616,7 @@ BOOST_AUTO_TEST_CASE( statistics_test )
INVOKE(bookie_payout_test); INVOKE(bookie_payout_test);
const asset_id_type btc_id = get_asset( "BTC" ).id; const asset_id_type btc_id = get_asset( "BTCTEST" ).id;
transfer( ath.alice_id, ath.ann_id, asset( 100, btc_id ), asset(0) ); transfer( ath.alice_id, ath.ann_id, asset( 100, btc_id ), asset(0) );
transfer( ath.alice_id, ath.audrey_id, asset( 100, btc_id ), asset(0) ); transfer( ath.alice_id, ath.audrey_id, asset( 100, btc_id ), asset(0) );

View file

@ -120,7 +120,7 @@ BOOST_AUTO_TEST_CASE(get_account_history_additional) {
const account_object& dan = create_account("dan"); // create op 1 const account_object& dan = create_account("dan"); // create op 1
create_bitasset("CNY", dan.id); // create op 2 create_bitasset("CNY", dan.id); // create op 2
create_bitasset("BTC", account_id_type()); // create op 3 create_bitasset("BTCTEST", account_id_type()); // create op 3
create_bitasset("XMR", dan.id); // create op 4 create_bitasset("XMR", dan.id); // create op 4
create_bitasset("EUR", account_id_type()); // create op 5 create_bitasset("EUR", account_id_type()); // create op 5
create_bitasset("OIL", dan.id); // create op 6 create_bitasset("OIL", dan.id); // create op 6
@ -454,7 +454,7 @@ BOOST_AUTO_TEST_CASE(track_account) {
BOOST_CHECK_EQUAL(histories[1].id.instance(), 3u); BOOST_CHECK_EQUAL(histories[1].id.instance(), 3u);
// create more ops, starting with an untracked account // create more ops, starting with an untracked account
create_bitasset( "BTC", account_id_type() ); create_bitasset( "BTCTEST", account_id_type() );
create_bitasset( "GBP", dan_id ); create_bitasset( "GBP", dan_id );
generate_block( ~database::skip_fork_db ); generate_block( ~database::skip_fork_db );
@ -468,7 +468,7 @@ BOOST_AUTO_TEST_CASE(track_account) {
db.pop_block(); db.pop_block();
// Try again, should result in same object IDs // Try again, should result in same object IDs
create_bitasset( "BTC", account_id_type() ); create_bitasset( "BTCTEST", account_id_type() );
create_bitasset( "GBP", dan_id ); create_bitasset( "GBP", dan_id );
generate_block(); generate_block();

View file

@ -329,7 +329,7 @@ BOOST_AUTO_TEST_CASE( son_pay_test )
// Make witness budget zero so that amount can be allocated to SON // Make witness budget zero so that amount can be allocated to SON
db.modify( db.get_global_properties(), [&]( global_property_object& _gpo ) db.modify( db.get_global_properties(), [&]( global_property_object& _gpo )
{ {
_gpo.parameters.extensions.value.son_pay_daily_max = 200; _gpo.parameters.extensions.value.son_pay_max = 200;
_gpo.parameters.witness_pay_per_block = 0; _gpo.parameters.witness_pay_per_block = 0;
} ); } );
// Upgrades pay fee and this goes to reserve // Upgrades pay fee and this goes to reserve