Merge branch 'rock-paper-scissors-ro' into rock-paper-scissors

This commit is contained in:
Roman Olearski 2016-11-08 16:26:43 +01:00
commit b72eae0941
10 changed files with 377 additions and 143 deletions

View file

@ -201,6 +201,16 @@
"distribution_base_fee": 0,
"distribution_fee_per_holder": 0
}
],[
47,{
"fee": 100000
}
],[
48,{
"fee": 51000000
}
],[
49,{}
]
],
"scale": 10

View file

@ -327,7 +327,16 @@ void database::init_genesis(const genesis_state_type& genesis_state)
a.network_fee_percentage = 0;
a.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT;
}).get_id() == GRAPHENE_PROXY_TO_SELF_ACCOUNT);
FC_ASSERT(create<account_object>([this](account_object& a) {
a.name = "test-dividend-distribution";
a.statistics = create<account_statistics_object>([&](account_statistics_object& s){s.owner = a.id;}).id;
a.owner.weight_threshold = 1;
a.active.weight_threshold = 1;
a.registrar = a.lifetime_referrer = a.referrer = GRAPHENE_PROXY_TO_SELF_ACCOUNT;
a.membership_expiration_date = time_point_sec::maximum();
a.network_fee_percentage = 0;
a.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT;
}).get_id() == TOURNAMENT_RAKE_FEE_ACCOUNT_ID);
// Create more special accounts
while( true )
{
@ -353,6 +362,22 @@ void database::init_genesis(const genesis_state_type& genesis_state)
create<asset_dynamic_data_object>([&](asset_dynamic_data_object& a) {
a.current_supply = GRAPHENE_MAX_SHARE_SUPPLY;
});
const asset_dividend_data_object& div_asset =
create<asset_dividend_data_object>([&](asset_dividend_data_object& a) {
a.options.minimum_distribution_interval = 3*24*60*60;
a.options.minimum_fee_percentage = 10*GRAPHENE_1_PERCENT;
a.options.next_payout_time = genesis_state.initial_timestamp + fc::hours(1);
a.options.payout_interval = 7*24*60*60;
a.dividend_distribution_account = TOURNAMENT_RAKE_FEE_ACCOUNT_ID;
});
const asset_bitasset_data_object& bit_asset =
create<asset_bitasset_data_object>([&](asset_bitasset_data_object& a) {
a.current_feed.maintenance_collateral_ratio = 1750;
a.current_feed.maximum_short_squeeze_ratio = 1500;
a.current_feed_publication_time = genesis_state.initial_timestamp + fc::hours(1);
});
const asset_object& core_asset =
create<asset_object>( [&]( asset_object& a ) {
a.symbol = GRAPHENE_SYMBOL;
@ -360,15 +385,58 @@ void database::init_genesis(const genesis_state_type& genesis_state)
a.precision = GRAPHENE_BLOCKCHAIN_PRECISION_DIGITS;
a.options.flags = 0;
a.options.issuer_permissions = 0;
a.issuer = GRAPHENE_NULL_ACCOUNT;
a.issuer = GRAPHENE_COMMITTEE_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;
});
a.dividend_data_id = div_asset.id;
a.bitasset_data_id = bit_asset.id;
});
assert( asset_id_type(core_asset.id) == asset().asset_id );
assert( get_balance(account_id_type(), asset_id_type()) == asset(dyn_asset.current_supply) );
#ifdef _DEFAULT_DIVIDEND_ASSET
// Create default dividend asset
const asset_dynamic_data_object& dyn_asset1 =
create<asset_dynamic_data_object>([&](asset_dynamic_data_object& a) {
a.current_supply = GRAPHENE_MAX_SHARE_SUPPLY;
});
const asset_dividend_data_object& div_asset1 =
create<asset_dividend_data_object>([&](asset_dividend_data_object& a) {
a.options.minimum_distribution_interval = 3*24*60*60;
a.options.minimum_fee_percentage = 10*GRAPHENE_1_PERCENT;
a.options.next_payout_time = genesis_state.initial_timestamp + fc::hours(1);
a.options.payout_interval = 7*24*60*60;
a.dividend_distribution_account = TOURNAMENT_RAKE_FEE_ACCOUNT_ID;
});
const asset_bitasset_data_object& bit_asset1 =
create<asset_bitasset_data_object>([&](asset_bitasset_data_object& a) {
a.current_feed.maintenance_collateral_ratio = 1750;
a.current_feed.maximum_short_squeeze_ratio = 1500;
a.current_feed_publication_time = genesis_state.initial_timestamp + fc::hours(1);
});
const asset_object& default_asset =
create<asset_object>( [&]( asset_object& a ) {
a.symbol = "DEFAULT";
a.options.max_market_fee =
a.options.max_supply = genesis_state.max_core_supply;
a.precision = GRAPHENE_BLOCKCHAIN_PRECISION_DIGITS;
a.options.flags = 0;
a.options.issuer_permissions = 79;
a.issuer = TOURNAMENT_RAKE_FEE_ACCOUNT_ID;
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(1);
a.dynamic_asset_data_id = dyn_asset1.id;
a.dividend_data_id = div_asset1.id;
a.bitasset_data_id = bit_asset1.id;
});
assert( default_asset.id == asset_id_type(1) );
#endif
// Create more special assets
while( true )
{
@ -634,6 +702,12 @@ void database::init_genesis(const genesis_state_type& genesis_state)
{
total_supplies[ asset_id_type(0) ] = GRAPHENE_MAX_SHARE_SUPPLY;
}
#ifdef _DEFAULT_DIVIDEND_ASSET
total_debts[ asset_id_type(1) ] =
total_supplies[ asset_id_type(1) ] = 0;
#endif
// it is workaround, should be clarified
total_debts[ asset_id_type() ] = total_supplies[ asset_id_type() ];
const auto& idx = get_index_type<asset_index>().indices().get<by_symbol>();
auto it = idx.begin();
@ -653,6 +727,7 @@ void database::init_genesis(const genesis_state_type& genesis_state)
elog( "Genesis for asset ${aname} is not balanced\n"
" Debt is ${debt}\n"
" Supply is ${supply}\n",
("aname", debt_itr->first)
("debt", debt_itr->second)
("supply", supply_itr->second)
);

View file

@ -352,6 +352,8 @@ FC_REFLECT_DERIVED( graphene::chain::asset_dividend_data_object, (graphene::db::
(options)
(last_scheduled_payout_time)
(last_payout_time )
(last_scheduled_distribution_time)
(last_distribution_time)
(dividend_distribution_account)
)
@ -369,4 +371,5 @@ FC_REFLECT_DERIVED( graphene::chain::asset_object, (graphene::db::object),
(dynamic_asset_data_id)
(bitasset_data_id)
(buyback_account)
(dividend_data_id)
)

View file

@ -168,6 +168,8 @@
#define GRAPHENE_TEMP_ACCOUNT (graphene::chain::account_id_type(4))
/// Represents the canonical account for specifying you will vote directly (as opposed to a proxy)
#define GRAPHENE_PROXY_TO_SELF_ACCOUNT (graphene::chain::account_id_type(5))
///
#define TOURNAMENT_RAKE_FEE_ACCOUNT_ID (graphene::chain::account_id_type(6))
/// Sentinel value used in the scheduler.
#define GRAPHENE_NULL_WITNESS (graphene::chain::witness_id_type(0))
///@}

View file

@ -595,6 +595,8 @@ FC_REFLECT( graphene::chain::asset_options,
FC_REFLECT( graphene::chain::dividend_asset_options,
(next_payout_time)
(payout_interval)
(minimum_fee_percentage)
(minimum_distribution_interval)
(extensions)
)

View file

@ -268,13 +268,12 @@ namespace graphene { namespace chain {
assert(event.match.match_winners.size() == 1);
const account_id_type& winner = *event.match.match_winners.begin();
uint16_t rake_fee_percentage = event.db.get_global_properties().parameters.rake_fee_percentage;
share_type rake_amount = (fc::uint128_t(fsm.tournament_obj->prize_pool.value) * rake_fee_percentage / GRAPHENE_1_PERCENT).to_uint64();
share_type rake_amount = (fc::uint128_t(fsm.tournament_obj->prize_pool.value) * rake_fee_percentage / GRAPHENE_1_PERCENT / 100).to_uint64();
event.db.adjust_balance(account_id_type(TOURNAMENT_RAKE_FEE_ACCOUNT_ID),
asset(rake_amount, fsm.tournament_obj->options.buy_in.asset_id));
event.db.adjust_balance(winner, asset(fsm.tournament_obj->prize_pool - rake_amount,
fsm.tournament_obj->options.buy_in.asset_id));
tournament_object& tournament = *fsm.tournament_obj;
tournament.end_time = event.db.head_block_time();
fsm.tournament_obj->end_time = event.db.head_block_time();
}
};

View file

@ -32,7 +32,10 @@
#include <fc/smart_ref_impl.hpp>
#include <fc/thread/thread.hpp>
#include <graphene/chain/market_object.hpp>
#include <iostream>
#include <fstream>
using namespace graphene::generate_genesis_plugin;
using std::string;
@ -41,187 +44,246 @@ using std::vector;
namespace bpo = boost::program_options;
void generate_genesis_plugin::plugin_set_program_options(
boost::program_options::options_description& command_line_options,
boost::program_options::options_description& config_file_options)
boost::program_options::options_description& command_line_options,
boost::program_options::options_description& config_file_options)
{
command_line_options.add_options()
("output-genesis-file,o", bpo::value<std::string>()->default_value("genesis.json"), "Genesis file to create")
("snapshot-block-number", bpo::value<uint32_t>()->default_value(0), "Block number at which to snapshot balances")
;
config_file_options.add(command_line_options);
command_line_options.add_options()
("output-genesis-file,o", bpo::value<std::string>()->default_value("genesis.json"), "Genesis file to create")
("output-csvlog-file,o", bpo::value<std::string>()->default_value("log.csv"), "CSV log file to create")
("snapshot-block-number", bpo::value<uint32_t>()->default_value(0), "Block number at which to snapshot balances")
;
config_file_options.add(command_line_options);
}
std::string generate_genesis_plugin::plugin_name()const
{
return "generate_genesis";
return "generate_genesis";
}
void generate_genesis_plugin::plugin_initialize(const boost::program_options::variables_map& options)
{ try {
ilog("generate genesis plugin: plugin_initialize() begin");
_options = &options;
ilog("generate genesis plugin: plugin_initialize() begin");
_options = &options;
_genesis_filename = options["output-genesis-file"].as<std::string>();
_block_to_snapshot = options["snapshot-block-number"].as<uint32_t>();
database().applied_block.connect([this](const graphene::chain::signed_block& b){ block_applied(b); });
ilog("generate genesis plugin: plugin_initialize() end");
} FC_LOG_AND_RETHROW() }
_genesis_filename = options["output-genesis-file"].as<std::string>();
_csvlog_filename = options["output-csvlog-file"].as<std::string>();
_block_to_snapshot = options["snapshot-block-number"].as<uint32_t>();
database().applied_block.connect([this](const graphene::chain::signed_block& b){ block_applied(b); });
ilog("generate genesis plugin: plugin_initialize() end");
} FC_LOG_AND_RETHROW() }
void generate_genesis_plugin::plugin_startup()
{ try {
ilog("generate genesis plugin: plugin_startup() begin");
chain::database& d = database();
if (d.head_block_num() == _block_to_snapshot)
{
ilog("generate genesis plugin: already at snapshot block");
generate_snapshot();
}
else if (d.head_block_num() > _block_to_snapshot)
elog("generate genesis plugin: already passed snapshot block, you must reindex to return to the snapshot state");
else
elog("generate genesis plugin: waiting for block ${snapshot_block} to generate snapshot, current head is ${head}",
("snapshot_block", _block_to_snapshot)("head", d.head_block_num()));
ilog("generate genesis plugin: plugin_startup() begin");
chain::database& d = database();
if (d.head_block_num() == _block_to_snapshot)
{
ilog("generate genesis plugin: already at snapshot block");
generate_snapshot();
}
else if (d.head_block_num() > _block_to_snapshot)
elog("generate genesis plugin: already passed snapshot block, you must reindex to return to the snapshot state");
else
elog("generate genesis plugin: waiting for block ${snapshot_block} to generate snapshot, current head is ${head}",
("snapshot_block", _block_to_snapshot)("head", d.head_block_num()));
ilog("generate genesis plugin: plugin_startup() end");
} FC_CAPTURE_AND_RETHROW() }
ilog("generate genesis plugin: plugin_startup() end");
} FC_CAPTURE_AND_RETHROW() }
void generate_genesis_plugin::block_applied(const graphene::chain::signed_block& b)
{
if (b.block_num() == _block_to_snapshot)
{
ilog("generate genesis plugin: snapshot block has arrived");
generate_snapshot();
}
if (b.block_num() == _block_to_snapshot)
{
ilog("generate genesis plugin: snapshot block has arrived");
generate_snapshot();
}
}
std::string modify_account_name(const std::string& name)
{
return std::string("bts-") + name;
return std::string("bts-") + name;
}
bool is_special_account(const graphene::chain::account_id_type& account_id)
{
return account_id.instance < 100;
return account_id.instance < 100;
}
bool is_exchange(const std::string& account_name)
{
return account_name == "poloniexcoldstorage" ||
account_name == "btc38-public-for-bts-cold" ||
account_name == "poloniexwallet" ||
account_name == "btercom" ||
account_name == "yunbi-cold-wallet" ||
account_name == "btc38-btsx-octo-72722" ||
account_name == "bittrex-deposit" ||
account_name == "btc38btsxwithdrawal";
return account_name == "poloniexcoldstorage" ||
account_name == "btc38-public-for-bts-cold" ||
account_name == "poloniexwallet" ||
account_name == "btercom" ||
account_name == "yunbi-cold-wallet" ||
account_name == "btc38-btsx-octo-72722" ||
account_name == "bittrex-deposit" ||
account_name == "btc38btsxwithdrawal";
}
void generate_genesis_plugin::generate_snapshot()
{
ilog("generate genesis plugin: generating snapshot now");
graphene::chain::genesis_state_type new_genesis_state;
chain::database& d = database();
ilog("generate genesis plugin: generating snapshot now");
graphene::chain::genesis_state_type new_genesis_state;
chain::database& d = database();
// we'll distribute 5% of 1,000,000 tokens, so:
graphene::chain::share_type total_amount_to_distribute = 50000 * GRAPHENE_BLOCKCHAIN_PRECISION;
// we'll distribute 5% of 1,000,000 tokens, so:
graphene::chain::share_type total_amount_to_distribute = 50000 * GRAPHENE_BLOCKCHAIN_PRECISION;
// we need collection of mutable objects
std::vector<my_account_balance_object> db_balances;
// copy const objects to our collection
auto& balance_index = d.get_index_type<graphene::chain::account_balance_index>().indices().get<graphene::chain::by_asset_balance>();
for (auto balance_iter = balance_index.begin(); balance_iter != balance_index.end() && balance_iter->asset_type == graphene::chain::asset_id_type(); ++balance_iter)
if (!is_special_account(balance_iter->owner) && !is_exchange(balance_iter->owner(d).name))
{
// it is possible due to constructor
db_balances.emplace_back(*balance_iter);
}
// walk through the balances; this index has the largest BTS balances first
// First, calculate the combined value of all BTS
auto& balance_index = d.get_index_type<graphene::chain::account_balance_index>().indices().get<graphene::chain::by_asset_balance>();
graphene::chain::share_type total_bts_balance;
graphene::chain::share_type total_shares_dropped;
for (auto balance_iter = balance_index.begin(); balance_iter != balance_index.end() && balance_iter->asset_type == graphene::chain::asset_id_type(); ++balance_iter)
if (!is_special_account(balance_iter->owner) && !is_exchange(balance_iter->owner(d).name))
total_bts_balance += balance_iter->balance;
// walk through the balances; this index has the largest BTS balances first
// first, calculate orders and collaterals
// second, update balance
graphene::chain::share_type orders;
graphene::chain::share_type collaterals;
graphene::chain::share_type total_bts_balance;
std::ofstream logfile;
// Now, we assume we're distributing balances to all BTS holders proportionally, figure
// the smallest balance we can distribute and still assign the user a satoshi of the share drop
graphene::chain::share_type effective_total_bts_balance;
auto balance_iter = balance_index.begin();
for (; balance_iter != balance_index.end() && balance_iter->asset_type == graphene::chain::asset_id_type(); ++balance_iter)
if (!is_special_account(balance_iter->owner) && !is_exchange(balance_iter->owner(d).name))
{
fc::uint128 share_drop_amount = total_amount_to_distribute.value;
share_drop_amount *= balance_iter->balance.value;
share_drop_amount /= total_bts_balance.value;
if (!share_drop_amount.to_uint64())
bool sort = false;
for (auto balance_iter = db_balances.begin(); balance_iter != db_balances.end(); ++balance_iter)
{
orders = 0;
collaterals = 0;
// BTS tied up in market orders
auto order_range = d.get_index_type<graphene::chain::limit_order_index>().indices().get<graphene::chain::by_account>().equal_range(balance_iter->owner);
std::for_each(order_range.first, order_range.second,
[&orders] (const graphene::chain::limit_order_object& order) {
if (order.amount_for_sale().asset_id == graphene::chain::asset_id_type())
orders += order.amount_for_sale().amount;
});
// BTS tied up in collateral for SmartCoins
auto collateral_range = d.get_index_type<graphene::chain::call_order_index>().indices().get<graphene::chain::by_account>().equal_range(balance_iter->owner);
std::for_each(collateral_range.first, collateral_range.second,
[&collaterals] (const graphene::chain::call_order_object& order) {
collaterals += order.collateral;
});
balance_iter->initial_balance = balance_iter->balance;
balance_iter->orders = orders;
balance_iter->collaterals = collaterals;
balance_iter->balance += orders + collaterals;
sort = sort || orders.value > 0 || collaterals.value > 0;
total_bts_balance += balance_iter->balance;
}
if (sort)
{
ilog("generate genesis plugin: sorting");
std::sort(db_balances.begin(), db_balances.end(),
[](const my_account_balance_object & a, const my_account_balance_object & b) -> bool
{
return a.balance.value > b.balance.value;
});
}
graphene::chain::share_type total_shares_dropped;
// Now, we assume we're distributing balances to all BTS holders proportionally, figure
// the smallest balance we can distribute and still assign the user a satoshi of the share drop
graphene::chain::share_type effective_total_bts_balance;
auto balance_iter = db_balances.begin();
for (balance_iter = db_balances.begin(); balance_iter != db_balances.end(); ++balance_iter)
{
fc::uint128 share_drop_amount = total_amount_to_distribute.value;
share_drop_amount *= balance_iter->balance.value;
share_drop_amount /= total_bts_balance.value;
if (!share_drop_amount.to_uint64())
break; // balances are decreasing, so every balance after will also round to zero
total_shares_dropped += share_drop_amount.to_uint64();
effective_total_bts_balance += balance_iter->balance;
}
total_shares_dropped += share_drop_amount.to_uint64();
effective_total_bts_balance += balance_iter->balance;
}
// our iterator is just after the smallest balance we will process,
// walk it backwards towards the larger balances, distributing the sharedrop as we go
graphene::chain::share_type remaining_amount_to_distribute = total_amount_to_distribute;
graphene::chain::share_type bts_balance_remaining = effective_total_bts_balance;
std::map<graphene::chain::account_id_type, graphene::chain::share_type> sharedrop_balances;
// our iterator is just after the smallest balance we will process,
// walk it backwards towards the larger balances, distributing the sharedrop as we go
graphene::chain::share_type remaining_amount_to_distribute = total_amount_to_distribute;
graphene::chain::share_type bts_balance_remaining = effective_total_bts_balance;
std::map<graphene::chain::account_id_type, graphene::chain::share_type> sharedrop_balances;
do {
--balance_iter;
if (!is_special_account(balance_iter->owner) && !is_exchange(balance_iter->owner(d).name))
{
fc::uint128 share_drop_amount = remaining_amount_to_distribute.value;
share_drop_amount *= balance_iter->balance.value;
share_drop_amount /= bts_balance_remaining.value;
graphene::chain::share_type amount_distributed = share_drop_amount.to_uint64();
sharedrop_balances[balance_iter->owner] = amount_distributed;
do {
--balance_iter;
fc::uint128 share_drop_amount = remaining_amount_to_distribute.value;
share_drop_amount *= balance_iter->balance.value;
share_drop_amount /= bts_balance_remaining.value;
graphene::chain::share_type amount_distributed = share_drop_amount.to_uint64();
sharedrop_balances[balance_iter->owner] = amount_distributed;
balance_iter->sharedrop = amount_distributed;
remaining_amount_to_distribute -= amount_distributed;
bts_balance_remaining -= balance_iter->balance.value;
}
} while (balance_iter != balance_index.begin());
assert(remaining_amount_to_distribute == 0);
remaining_amount_to_distribute -= amount_distributed;
bts_balance_remaining -= balance_iter->balance.value;
} while (balance_iter != db_balances.begin());
assert(remaining_amount_to_distribute == 0);
auto& account_index = d.get_index_type<graphene::chain::account_index>();
auto& account_by_id_index = account_index.indices().get<graphene::chain::by_id>();
// inefficient way of crawling the graph, but we only do it once
std::set<graphene::chain::account_id_type> already_generated;
for (;;)
{
unsigned accounts_generated_this_round = 0;
for (const auto& sharedrop_value : sharedrop_balances)
{
const graphene::chain::account_id_type& account_id = sharedrop_value.first;
const graphene::chain::share_type& sharedrop_amount = sharedrop_value.second;
const graphene::chain::account_object& account_obj = account_id(d);
if (already_generated.find(account_id) == already_generated.end())
{
graphene::chain::genesis_state_type::initial_bts_account_type::initial_authority owner;
owner.weight_threshold = account_obj.owner.weight_threshold;
owner.key_auths = account_obj.owner.key_auths;
for (const auto& value : account_obj.owner.account_auths)
logfile.open(_csvlog_filename);
assert(logfile.is_open());
logfile << "name,balance+orders+collaterals,balance,orders,collaterals,sharedrop\n";
char del = ',';
char nl = '\n';
for(const auto& o : db_balances)
{
logfile << o.owner(d).name << del << o.balance.value << del << o.initial_balance.value << del << o.orders.value << del << o.collaterals.value << del << o.sharedrop.value << nl;
}
ilog("CSV log written to file ${filename}", ("filename", _csvlog_filename));
logfile.close();
//auto& account_index = d.get_index_type<graphene::chain::account_index>();
//auto& account_by_id_index = account_index.indices().get<graphene::chain::by_id>();
// inefficient way of crawling the graph, but we only do it once
std::set<graphene::chain::account_id_type> already_generated;
for (;;)
{
unsigned accounts_generated_this_round = 0;
for (const auto& sharedrop_value : sharedrop_balances)
{
const graphene::chain::account_id_type& account_id = sharedrop_value.first;
const graphene::chain::share_type& sharedrop_amount = sharedrop_value.second;
const graphene::chain::account_object& account_obj = account_id(d);
if (already_generated.find(account_id) == already_generated.end())
{
owner.account_auths.insert(std::make_pair(modify_account_name(value.first(d).name), value.second));
sharedrop_balances[value.first] += 0; // make sure the account is generated, even if it has a zero balance
}
owner.key_auths = account_obj.owner.key_auths;
owner.address_auths = account_obj.owner.address_auths;
graphene::chain::genesis_state_type::initial_bts_account_type::initial_authority active;
active.weight_threshold = account_obj.active.weight_threshold;
active.key_auths = account_obj.active.key_auths;
for (const auto& value : account_obj.active.account_auths)
{
active.account_auths.insert(std::make_pair(modify_account_name(value.first(d).name), value.second));
sharedrop_balances[value.first] += 0; // make sure the account is generated, even if it has a zero balance
}
active.key_auths = account_obj.active.key_auths;
active.address_auths = account_obj.active.address_auths;
graphene::chain::genesis_state_type::initial_bts_account_type::initial_authority owner;
owner.weight_threshold = account_obj.owner.weight_threshold;
owner.key_auths = account_obj.owner.key_auths;
for (const auto& value : account_obj.owner.account_auths)
{
owner.account_auths.insert(std::make_pair(modify_account_name(value.first(d).name), value.second));
sharedrop_balances[value.first] += 0; // make sure the account is generated, even if it has a zero balance
}
owner.key_auths = account_obj.owner.key_auths;
owner.address_auths = account_obj.owner.address_auths;
new_genesis_state.initial_bts_accounts.emplace_back(
graphene::chain::genesis_state_type::initial_bts_account_type(modify_account_name(account_obj.name),
owner, active,
sharedrop_amount));
already_generated.insert(account_id);
++accounts_generated_this_round;
}
}
if (accounts_generated_this_round == 0)
break;
}
fc::json::save_to_file(new_genesis_state, _genesis_filename);
ilog("New genesis state written to file ${filename}", ("filename", _genesis_filename));
graphene::chain::genesis_state_type::initial_bts_account_type::initial_authority active;
active.weight_threshold = account_obj.active.weight_threshold;
active.key_auths = account_obj.active.key_auths;
for (const auto& value : account_obj.active.account_auths)
{
active.account_auths.insert(std::make_pair(modify_account_name(value.first(d).name), value.second));
sharedrop_balances[value.first] += 0; // make sure the account is generated, even if it has a zero balance
}
active.key_auths = account_obj.active.key_auths;
active.address_auths = account_obj.active.address_auths;
new_genesis_state.initial_bts_accounts.emplace_back(
graphene::chain::genesis_state_type::initial_bts_account_type(modify_account_name(account_obj.name),
owner, active,
sharedrop_amount));
already_generated.insert(account_id);
++accounts_generated_this_round;
}
}
if (accounts_generated_this_round == 0)
break;
}
fc::json::save_to_file(new_genesis_state, _genesis_filename);
ilog("New genesis state written to file ${filename}", ("filename", _genesis_filename));
}
void generate_genesis_plugin::plugin_shutdown()

View file

@ -54,6 +54,19 @@ private:
uint32_t _block_to_snapshot;
std::string _genesis_filename;
std::string _csvlog_filename;
};
class my_account_balance_object : public graphene::chain::account_balance_object
{
public:
// constructor copying from base class
my_account_balance_object(const graphene::chain::account_balance_object& abo) : graphene::chain::account_balance_object(abo) {}
graphene::chain::share_type initial_balance;
graphene::chain::share_type orders;
graphene::chain::share_type collaterals;
graphene::chain::share_type sharedrop;
};
} } //graphene::generate_genesis_plugin

View file

@ -1451,6 +1451,20 @@ class wallet_api
const variant_object& changed_values,
bool broadcast = false);
/** Propose a dividend asset update.
*
* @param proposing_account The account paying the fee to propose the tx
* @param expiration_time Timestamp specifying when the proposal will either take effect or expire.
* @param changed_values dividend asset parameters to update
* @param broadcast true if you wish to broadcast the transaction
* @return the signed version of the transaction
*/
signed_transaction propose_dividend_asset_update(
const string& proposing_account,
fc::time_point_sec expiration_time,
const variant_object& changed_values,
bool broadcast = false);
/** Approve or disapprove a proposal.
*
* @param fee_paying_account The account paying the fee for the op.
@ -1682,6 +1696,7 @@ FC_API( graphene::wallet::wallet_api,
(get_prototype_operation)
(propose_parameter_change)
(propose_fee_change)
(propose_dividend_asset_update)
(approve_proposal)
(dbg_make_uia)
(dbg_make_mia)

View file

@ -2804,6 +2804,46 @@ public:
return sign_transaction(tx, broadcast);
}
signed_transaction propose_dividend_asset_update(
const string& proposing_account,
fc::time_point_sec expiration_time,
const variant_object& changed_values,
bool broadcast = false)
{
FC_ASSERT( changed_values.contains("asset_to_update") );
const chain_parameters& current_params = get_global_properties().parameters;
asset_update_dividend_operation changed_op;
fc::reflector<asset_update_dividend_operation>::visit(
fc::from_variant_visitor<asset_update_dividend_operation>( changed_values, changed_op )
);
optional<asset_object> asset_to_update = find_asset(changed_op.asset_to_update);
if (!asset_to_update)
FC_THROW("No asset with that symbol exists!");
asset_update_dividend_operation update_op;
update_op.issuer = asset_to_update->issuer;
update_op.asset_to_update = asset_to_update->id;
update_op.new_options = changed_op.new_options;
proposal_create_operation prop_op;
prop_op.expiration_time = expiration_time;
prop_op.review_period_seconds = current_params.committee_proposal_review_period;
prop_op.fee_paying_account = get_account(proposing_account).id;
prop_op.proposed_ops.emplace_back( update_op );
current_params.current_fees->set_fee( prop_op.proposed_ops.back().op );
signed_transaction tx;
tx.operations.push_back(prop_op);
set_operation_fees(tx, current_params.current_fees);
tx.validate();
return sign_transaction(tx, broadcast);
}
signed_transaction approve_proposal(
const string& fee_paying_account,
const string& proposal_id,
@ -3877,6 +3917,16 @@ signed_transaction wallet_api::propose_fee_change(
return my->propose_fee_change( proposing_account, expiration_time, changed_fees, broadcast );
}
signed_transaction wallet_api::propose_dividend_asset_update(
const string& proposing_account,
fc::time_point_sec expiration_time,
const variant_object& changed_fees,
bool broadcast /* = false */
)
{
return my->propose_dividend_asset_update( proposing_account, expiration_time, changed_fees, broadcast );
}
signed_transaction wallet_api::approve_proposal(
const string& fee_paying_account,
const string& proposal_id,
@ -3887,6 +3937,9 @@ signed_transaction wallet_api::approve_proposal(
return my->approve_proposal( fee_paying_account, proposal_id, delta, broadcast );
}
global_property_object wallet_api::get_global_properties() const
{
return my->get_global_properties();