Many changes, including a start to supporting peerplays games in the cli wallet
This commit is contained in:
parent
eb8929f6fa
commit
baab40070d
16 changed files with 179871 additions and 96 deletions
179490
genesis.json
179490
genesis.json
File diff suppressed because one or more lines are too long
|
|
@ -152,21 +152,7 @@ namespace detail {
|
|||
else
|
||||
{
|
||||
vector<string> seeds = {
|
||||
"faucet.bitshares.org:1776",
|
||||
"bitshares.openledger.info:1776",
|
||||
"114.92.254.159:62015",
|
||||
"seed.blocktrades.us:1776",
|
||||
"seed04.bitsharesnodes.com:1776", // thom
|
||||
"seed05.bitsharesnodes.com:1776", // thom
|
||||
"seed06.bitsharesnodes.com:1776", // thom
|
||||
"seed07.bitsharesnodes.com:1776", // thom
|
||||
"128.199.131.4:1777", // cube
|
||||
"54.85.252.77:39705", // lafona
|
||||
"104.236.144.84:1777", // puppies
|
||||
"40.127.190.171:1777", // betax
|
||||
"185.25.22.21:1776", // liondani (greece)
|
||||
"23.95.43.126:50696", // iHashFury
|
||||
"109.73.172.144:50696" // iHashFury
|
||||
"peerplays.blocktrades.info:2776"
|
||||
};
|
||||
for( const string& endpoint_string : seeds )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -140,6 +140,8 @@ class database_api_impl : public std::enable_shared_from_this<database_api_impl>
|
|||
|
||||
// Tournaments
|
||||
vector<tournament_object> get_upcoming_tournaments(fc::optional<account_id_type> account_filter, uint32_t limit)const;
|
||||
vector<tournament_object> get_active_tournaments(fc::optional<account_id_type> account_filter, uint32_t limit)const;
|
||||
|
||||
|
||||
//private:
|
||||
template<typename T>
|
||||
|
|
@ -1783,7 +1785,46 @@ vector<tournament_object> database_api_impl::get_upcoming_tournaments(fc::option
|
|||
if (tournament_obj.options.whitelist.empty() ||
|
||||
!account_filter ||
|
||||
tournament_obj.options.whitelist.find(*account_filter) != tournament_obj.options.whitelist.end())
|
||||
{
|
||||
result.emplace_back(tournament_obj);
|
||||
subscribe_to_item( tournament_obj.id );
|
||||
}
|
||||
|
||||
if (result.size() >= limit)
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
vector<tournament_object> database_api::get_active_tournaments(fc::optional<account_id_type> account_filter, uint32_t limit)const
|
||||
{
|
||||
return my->get_active_tournaments(account_filter, limit);
|
||||
}
|
||||
|
||||
vector<tournament_object> database_api_impl::get_active_tournaments(fc::optional<account_id_type> account_filter, uint32_t limit)const
|
||||
{
|
||||
vector<tournament_object> result;
|
||||
const auto& start_time_index = _db.get_index_type<tournament_index>().indices().get<by_start_time>();
|
||||
|
||||
const auto begin = start_time_index.lower_bound(boost::make_tuple(tournament_state::awaiting_start));
|
||||
const auto end = start_time_index.upper_bound(boost::make_tuple(tournament_state::in_progress));
|
||||
for (const tournament_object& tournament_obj : boost::make_iterator_range(begin, end))
|
||||
{
|
||||
if (account_filter)
|
||||
{
|
||||
const tournament_details_object& tournament_details_obj = tournament_obj.tournament_details_id(_db);
|
||||
if (tournament_details_obj.registered_players.find(*account_filter) != tournament_details_obj.registered_players.end())
|
||||
{
|
||||
result.emplace_back(tournament_obj);
|
||||
subscribe_to_item( tournament_obj.id );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.emplace_back(tournament_obj);
|
||||
subscribe_to_item( tournament_obj.id );
|
||||
}
|
||||
|
||||
if (result.size() >= limit)
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -559,6 +559,12 @@ class database_api
|
|||
*/
|
||||
vector<tournament_object> get_upcoming_tournaments(fc::optional<account_id_type> account_filter, uint32_t limit)const;
|
||||
|
||||
/**
|
||||
* @return the list of tournaments that are either in-progress or fully-registered and just waiting on their start
|
||||
* time to arrive
|
||||
*/
|
||||
vector<tournament_object> get_active_tournaments(fc::optional<account_id_type> account_filter, uint32_t limit)const;
|
||||
|
||||
private:
|
||||
std::shared_ptr< database_api_impl > my;
|
||||
};
|
||||
|
|
@ -662,4 +668,5 @@ FC_API(graphene::app::database_api,
|
|||
|
||||
// Tournaments
|
||||
(get_upcoming_tournaments)
|
||||
(get_active_tournaments)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -416,6 +416,19 @@ void database::init_genesis(const genesis_state_type& genesis_state)
|
|||
} );
|
||||
create<block_summary_object>([&](block_summary_object&) {});
|
||||
|
||||
// Create initial accounts from graphene-based chains
|
||||
// graphene accounts can refer to other accounts in their authorities, so
|
||||
// we first create all accounts with dummy authorities, then go back and
|
||||
// set up the authorities once the accounts all have ids assigned.
|
||||
for( const auto& account : genesis_state.initial_bts_accounts )
|
||||
{
|
||||
account_create_operation cop;
|
||||
cop.name = account.name;
|
||||
cop.registrar = GRAPHENE_TEMP_ACCOUNT;
|
||||
cop.owner = authority(1, GRAPHENE_TEMP_ACCOUNT, 1);
|
||||
account_id_type account_id(apply_operation(genesis_eval_state, cop).get<object_id_type>());
|
||||
}
|
||||
|
||||
// Create initial accounts
|
||||
for( const auto& account : genesis_state.initial_accounts )
|
||||
{
|
||||
|
|
@ -454,6 +467,32 @@ void database::init_genesis(const genesis_state_type& genesis_state)
|
|||
return itr->get_id();
|
||||
};
|
||||
|
||||
for( const auto& account : genesis_state.initial_bts_accounts )
|
||||
{
|
||||
account_update_operation op;
|
||||
op.account = get_account_id(account.name);
|
||||
|
||||
authority owner_authority;
|
||||
owner_authority.weight_threshold = account.owner_authority.weight_threshold;
|
||||
for (const auto& value : account.owner_authority.account_auths)
|
||||
owner_authority.account_auths.insert(std::make_pair(get_account_id(value.first), value.second));
|
||||
owner_authority.key_auths = account.owner_authority.key_auths;
|
||||
owner_authority.address_auths = account.owner_authority.address_auths;
|
||||
|
||||
op.owner = std::move(owner_authority);
|
||||
|
||||
authority active_authority;
|
||||
active_authority.weight_threshold = account.active_authority.weight_threshold;
|
||||
for (const auto& value : account.active_authority.account_auths)
|
||||
active_authority.account_auths.insert(std::make_pair(get_account_id(value.first), value.second));
|
||||
active_authority.key_auths = account.active_authority.key_auths;
|
||||
active_authority.address_auths = account.active_authority.address_auths;
|
||||
|
||||
op.active = std::move(active_authority);
|
||||
|
||||
apply_operation(genesis_eval_state, op);
|
||||
}
|
||||
|
||||
// Helper function to get asset ID by symbol
|
||||
const auto& assets_by_symbol = get_index_type<asset_index>().indices().get<by_symbol>();
|
||||
const auto get_asset_id = [&assets_by_symbol](const string& symbol) {
|
||||
|
|
@ -539,6 +578,14 @@ void database::init_genesis(const genesis_state_type& genesis_state)
|
|||
});
|
||||
}
|
||||
|
||||
// Create balances for all bts accounts
|
||||
for( const auto& account : genesis_state.initial_bts_accounts )
|
||||
if (account.core_balance != share_type())
|
||||
create<account_balance_object>([&](account_balance_object& b) {
|
||||
b.owner = get_account_id(account.name);
|
||||
b.balance = account.core_balance;
|
||||
});
|
||||
|
||||
// Create initial balances
|
||||
share_type total_allocation;
|
||||
for( const auto& handout : genesis_state.initial_balances )
|
||||
|
|
|
|||
|
|
@ -369,6 +369,7 @@ void database::initialize_budget_record( fc::time_point_sec now, budget_record&
|
|||
*/
|
||||
void database::process_budget()
|
||||
{
|
||||
return;
|
||||
try
|
||||
{
|
||||
const global_property_object& gpo = get_global_properties();
|
||||
|
|
@ -405,9 +406,9 @@ void database::process_budget()
|
|||
rec.witness_budget = witness_budget;
|
||||
available_funds -= witness_budget;
|
||||
|
||||
fc::uint128_t worker_budget_u128 = gpo.parameters.worker_budget_per_day.value;
|
||||
worker_budget_u128 *= uint64_t(time_to_maint);
|
||||
worker_budget_u128 /= 60*60*24;
|
||||
fc::uint128_t worker_budget_u128 = uint64_t(1); //DLN Q&D HACK gpo.parameters.worker_budget_per_day.value;
|
||||
//DLN worker_budget_u128 *= uint64_t(time_to_maint);
|
||||
//DLN worker_budget_u128 /= 60*60*24;
|
||||
|
||||
share_type worker_budget;
|
||||
if( worker_budget_u128 >= available_funds.value )
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#define GRAPHENE_SYMBOL "BTS"
|
||||
#define GRAPHENE_ADDRESS_PREFIX "BTS"
|
||||
#define GRAPHENE_SYMBOL "TEST"
|
||||
#define GRAPHENE_ADDRESS_PREFIX "TEST"
|
||||
|
||||
#define GRAPHENE_MIN_ACCOUNT_NAME_LENGTH 1
|
||||
#define GRAPHENE_MAX_ACCOUNT_NAME_LENGTH 63
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ namespace graphene { namespace chain {
|
|||
|
||||
void pack_impl(std::ostream& stream) const;
|
||||
void unpack_impl(std::istream& stream);
|
||||
void on_initiate_match(database& db, const vector<account_id_type>& players);
|
||||
game_id_type start_next_game(database& db, match_id_type match_id);
|
||||
|
||||
class impl;
|
||||
|
|
|
|||
|
|
@ -39,14 +39,15 @@ namespace graphene { namespace chain {
|
|||
namespace
|
||||
{
|
||||
// Events
|
||||
struct previous_round_complete
|
||||
struct initiate_match
|
||||
{
|
||||
database& db;
|
||||
vector<account_id_type> players;
|
||||
previous_round_complete(database& db, const vector<account_id_type> players) :
|
||||
initiate_match(database& db, const vector<account_id_type>& players) :
|
||||
db(db), players(players)
|
||||
{}
|
||||
};
|
||||
|
||||
struct game_complete
|
||||
{
|
||||
database& db;
|
||||
|
|
@ -64,7 +65,7 @@ namespace graphene { namespace chain {
|
|||
struct waiting_on_previous_matches : public msm::front::state<>{};
|
||||
struct match_in_progress : public msm::front::state<>
|
||||
{
|
||||
void on_entry(const game_complete& event, match_state_machine_& fsm)
|
||||
void on_entry(const initiate_match& event, match_state_machine_& fsm)
|
||||
{
|
||||
fc_ilog(fc::logger::get("tournament"),
|
||||
"Match ${id} is now in progress",
|
||||
|
|
@ -104,7 +105,7 @@ namespace graphene { namespace chain {
|
|||
struct transition_table : mpl::vector<
|
||||
// Start Event Next Action Guard
|
||||
// +-------------------------------+-------------------------+----------------------------+---------------------+----------------------+
|
||||
_row < waiting_on_previous_matches, previous_round_complete, match_in_progress >,
|
||||
_row < waiting_on_previous_matches, initiate_match , match_in_progress >,
|
||||
// +-------------------------------+-------------------------+----------------------------+---------------------+----------------------+
|
||||
a_row < match_in_progress, game_complete, match_in_progress, &x::start_next_game >,
|
||||
g_row < match_in_progress, game_complete, match_complete, &x::was_final_game >
|
||||
|
|
@ -216,6 +217,11 @@ namespace graphene { namespace chain {
|
|||
ia >> my->state_machine;
|
||||
}
|
||||
|
||||
void match_object::on_initiate_match(database& db, const vector<account_id_type>& players)
|
||||
{
|
||||
my->state_machine.process_event(initiate_match(db, players));
|
||||
}
|
||||
|
||||
game_id_type match_object::start_next_game(database& db, match_id_type match_id)
|
||||
{
|
||||
const game_object& game =
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@
|
|||
|
||||
#define GRAPHENE_NET_TEST_SEED_IP "104.236.44.210" // autogenerated
|
||||
#define GRAPHENE_NET_TEST_P2P_PORT 1700
|
||||
#define GRAPHENE_NET_DEFAULT_P2P_PORT 1776
|
||||
#define GRAPHENE_NET_DEFAULT_P2P_PORT 2776
|
||||
#define GRAPHENE_NET_DEFAULT_DESIRED_CONNECTIONS 20
|
||||
#define GRAPHENE_NET_DEFAULT_MAX_CONNECTIONS 200
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
file(GLOB HEADERS "include/graphene/generate_genesis/*.hpp")
|
||||
|
||||
add_library( grapehen_generate_genesis
|
||||
add_library( graphene_generate_genesis
|
||||
generate_genesis.cpp
|
||||
)
|
||||
|
||||
target_link_libraries( grapehen_generate_genesis graphene_chain graphene_app graphene_time )
|
||||
target_include_directories( grapehen_generate_genesis
|
||||
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )
|
||||
target_link_libraries( graphene_generate_genesis graphene_chain graphene_app graphene_time )
|
||||
target_include_directories( graphene_generate_genesis
|
||||
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )
|
||||
|
||||
install( TARGETS
|
||||
grapehen_generate_genesis
|
||||
graphene_generate_genesis
|
||||
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
|
|
|
|||
|
|
@ -21,12 +21,11 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#include <graphene/generate_genesis/generate_genesis.hpp>
|
||||
#include <graphene/generate_genesis/generate_genesis_plugin.hpp>
|
||||
|
||||
#include <graphene/chain/database.hpp>
|
||||
#include <graphene/chain/genesis_state.hpp>
|
||||
#include <graphene/chain/witness_object.hpp>
|
||||
#include <graphene/time/time.hpp>
|
||||
|
||||
#include <graphene/utilities/key_conversion.hpp>
|
||||
|
||||
|
|
@ -47,7 +46,7 @@ void generate_genesis_plugin::plugin_set_program_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(1), "Block number at which to snapshot balances")
|
||||
("snapshot-block-number", bpo::value<uint32_t>()->default_value(0), "Block number at which to snapshot balances")
|
||||
;
|
||||
config_file_options.add(command_line_options);
|
||||
}
|
||||
|
|
@ -95,17 +94,134 @@ void generate_genesis_plugin::block_applied(const graphene::chain::signed_block&
|
|||
}
|
||||
}
|
||||
|
||||
std::string modify_account_name(const std::string& name)
|
||||
{
|
||||
return std::string("bts-") + name;
|
||||
}
|
||||
|
||||
bool is_special_account(const graphene::chain::account_id_type& account_id)
|
||||
{
|
||||
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";
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
|
||||
// we'll distribute 5% of 1,000,000 tokens, so:
|
||||
graphene::chain::share_type total_amount_to_distribute = 50000 * GRAPHENE_BLOCKCHAIN_PRECISION;
|
||||
|
||||
// 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;
|
||||
|
||||
// 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())
|
||||
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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
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);
|
||||
|
||||
auto& account_index = d.get_index_type<graphene::chain::account_index>();
|
||||
auto& account_by_id_index = account_index.indices().get<graphene::chain::by_id>();
|
||||
for (const graphene::chain::account_object& account_obj : account_by_id_index)
|
||||
// inefficient way of crawling the graph, but we only do it once
|
||||
std::set<graphene::chain::account_id_type> already_generated;
|
||||
for (;;)
|
||||
{
|
||||
//new_genesis_state.initial_accounts.emplace_back(genesis_state_type::initial_account_type(account_obj.name, account
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Cryptonomex, Inc., and contributors.
|
||||
*
|
||||
* The MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <graphene/app/plugin.hpp>
|
||||
#include <graphene/chain/database.hpp>
|
||||
|
||||
#include <fc/thread/future.hpp>
|
||||
|
||||
namespace graphene { namespace generate_genesis_plugin {
|
||||
|
||||
class generate_genesis_plugin : public graphene::app::plugin {
|
||||
public:
|
||||
~generate_genesis_plugin() {
|
||||
}
|
||||
|
||||
std::string plugin_name()const override;
|
||||
|
||||
virtual void plugin_set_program_options(
|
||||
boost::program_options::options_description &command_line_options,
|
||||
boost::program_options::options_description &config_file_options
|
||||
) override;
|
||||
|
||||
virtual void plugin_initialize( const boost::program_options::variables_map& options ) override;
|
||||
virtual void plugin_startup() override;
|
||||
virtual void plugin_shutdown() override;
|
||||
|
||||
private:
|
||||
void block_applied(const graphene::chain::signed_block& b);
|
||||
void generate_snapshot();
|
||||
|
||||
boost::program_options::variables_map _options;
|
||||
|
||||
uint32_t _block_to_snapshot;
|
||||
std::string _genesis_filename;
|
||||
};
|
||||
|
||||
} } //graphene::generate_genesis_plugin
|
||||
|
|
@ -339,6 +339,69 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
fc::mutex _subscribed_object_changed_mutex;
|
||||
void subscribed_object_changed(const variant& changed_objects_variant)
|
||||
{
|
||||
fc::scoped_lock<fc::mutex> lock(_resync_mutex);
|
||||
fc::variants changed_objects = changed_objects_variant.get_array();
|
||||
for (const variant& changed_object_variant : changed_objects)
|
||||
{
|
||||
// changed_object_variant is either the object, or just the id if the object was removed
|
||||
if (changed_object_variant.is_object())
|
||||
{
|
||||
try
|
||||
{
|
||||
object_id_type id = changed_object_variant["id"].as<tournament_id_type>();
|
||||
tournament_object current_tournament_obj = changed_object_variant.as<tournament_object>();
|
||||
auto tournament_cache_iter = tournament_cache.find(id);
|
||||
if (tournament_cache_iter != tournament_cache.end())
|
||||
{
|
||||
const tournament_object& cached_tournament_obj = *tournament_cache_iter;
|
||||
if (cached_tournament_obj.get_state() != current_tournament_obj.get_state())
|
||||
{
|
||||
ilog("Tournament ${id} changed state from ${old} to ${new}",
|
||||
("id", id)
|
||||
("old", cached_tournament_obj.get_state())
|
||||
("new", current_tournament_obj.get_state()));
|
||||
if (current_tournament_obj.get_state() == tournament_state::in_progress)
|
||||
monitor_matches_in_tournament(current_tournament_obj);
|
||||
}
|
||||
tournament_cache.modify(tournament_cache_iter, [&](tournament_object& obj) { obj = current_tournament_obj; });
|
||||
}
|
||||
continue;
|
||||
}
|
||||
catch (const fc::exception& e)
|
||||
{
|
||||
// idump((e));
|
||||
}
|
||||
try
|
||||
{
|
||||
object_id_type id = changed_object_variant["id"].as<match_id_type>();
|
||||
match_object current_match_obj = changed_object_variant.as<match_object>();
|
||||
auto match_cache_iter = match_cache.find(id);
|
||||
if (match_cache_iter != match_cache.end())
|
||||
{
|
||||
const match_object& cached_match_obj = *match_cache_iter;
|
||||
if (cached_match_obj.get_state() != current_match_obj.get_state())
|
||||
{
|
||||
ilog("match ${id} changed state from ${old} to ${new}",
|
||||
("id", id)
|
||||
("old", cached_match_obj.get_state())
|
||||
("new", current_match_obj.get_state()));
|
||||
match_in_new_state(current_match_obj);
|
||||
}
|
||||
match_cache.modify(match_cache_iter, [&](match_object& obj) { obj = current_match_obj; });
|
||||
}
|
||||
continue;
|
||||
}
|
||||
catch (const fc::exception& e)
|
||||
{
|
||||
// idump((e));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void enable_umask_protection()
|
||||
{
|
||||
#ifdef __unix__
|
||||
|
|
@ -411,10 +474,16 @@ public:
|
|||
on_block_applied( block_id );
|
||||
} );
|
||||
|
||||
_remote_db->set_subscribe_callback( [this](const variant& object )
|
||||
{
|
||||
on_subscribe_callback( object );
|
||||
}, false );
|
||||
|
||||
_wallet.chain_id = _chain_id;
|
||||
_wallet.ws_server = initial_data.ws_server;
|
||||
_wallet.ws_user = initial_data.ws_user;
|
||||
_wallet.ws_password = initial_data.ws_password;
|
||||
|
||||
}
|
||||
virtual ~wallet_api_impl()
|
||||
{
|
||||
|
|
@ -449,6 +518,12 @@ public:
|
|||
fc::async([this]{resync();}, "Resync after block");
|
||||
}
|
||||
|
||||
void on_subscribe_callback( const variant& object )
|
||||
{
|
||||
//idump((object));
|
||||
fc::async([this, object]{subscribed_object_changed(object);}, "Object changed");
|
||||
}
|
||||
|
||||
bool copy_wallet_file( string destination_filename )
|
||||
{
|
||||
fc::path src_path = get_wallet_filename();
|
||||
|
|
@ -712,6 +787,35 @@ public:
|
|||
|
||||
vector< signed_transaction > import_balance( string name_or_id, const vector<string>& wif_keys, bool broadcast );
|
||||
|
||||
void match_in_new_state(const match_object& match_obj)
|
||||
{
|
||||
if (match_obj.get_state() == match_state::match_in_progress)
|
||||
{
|
||||
for (const account_id_type& account_id : match_obj.players)
|
||||
{
|
||||
if (_wallet.my_accounts.find(account_id) != _wallet.my_accounts.end())
|
||||
{
|
||||
ilog("Match ${match} is now in progress for player ${account}",
|
||||
("match", match_obj.id)("account", get_account(account_id).name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cache all matches in the tournament, which will also register us for
|
||||
// updates on those matches
|
||||
void monitor_matches_in_tournament(const tournament_object& tournament_obj)
|
||||
{
|
||||
tournament_details_object tournament_details = get_object<tournament_details_object>(tournament_obj.tournament_details_id);
|
||||
for (const match_id_type& match_id : tournament_details.matches)
|
||||
{
|
||||
match_object match_obj = get_object<match_object>(match_id);
|
||||
auto insert_result = match_cache.insert(match_obj);
|
||||
if (insert_result.second)
|
||||
match_in_new_state(match_obj);
|
||||
}
|
||||
}
|
||||
|
||||
bool load_wallet_file(string wallet_filename = "")
|
||||
{
|
||||
// TODO: Merge imported wallet with existing wallet,
|
||||
|
|
@ -772,6 +876,29 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
// check to see if any of our accounts are registered for tournaments
|
||||
// the real purpose of this is to ensure that we are subscribed for callbacks on these tournaments
|
||||
ilog("Checking my accounts for active tournaments",);
|
||||
for (const account_object& my_account : _wallet.my_accounts)
|
||||
{
|
||||
std::vector<tournament_object> tournaments = _remote_db->get_active_tournaments(my_account.id, 100);
|
||||
std::vector<tournament_id_type> tournament_ids;
|
||||
for (const tournament_object& tournament : tournaments)
|
||||
{
|
||||
auto insert_result = tournament_cache.insert(tournament);
|
||||
if (insert_result.second)
|
||||
{
|
||||
// then this is the first time we've seen this tournament
|
||||
monitor_matches_in_tournament(tournament);
|
||||
}
|
||||
tournament_ids.push_back(tournament.id);
|
||||
}
|
||||
if (!tournaments.empty())
|
||||
ilog("Account ${my_account} is registered for tournaments: ${tournaments}", ("my_account", my_account.name)("tournaments", tournament_ids));
|
||||
else
|
||||
ilog("Account ${my_account} is not registered for any tournaments", ("my_account", my_account.name));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
void save_wallet_file(string wallet_filename = "")
|
||||
|
|
@ -2584,6 +2711,18 @@ public:
|
|||
|
||||
static_variant_map _operation_which_map = create_static_variant_map< operation >();
|
||||
|
||||
typedef multi_index_container<
|
||||
tournament_object,
|
||||
indexed_by<
|
||||
ordered_unique< tag<by_id>, member< object, object_id_type, &object::id > > > > tournament_index_type;
|
||||
tournament_index_type tournament_cache;
|
||||
|
||||
typedef multi_index_container<
|
||||
match_object,
|
||||
indexed_by<
|
||||
ordered_unique< tag<by_id>, member< object, object_id_type, &object::id > > > > match_index_type;
|
||||
match_index_type match_cache;
|
||||
|
||||
#ifdef __unix__
|
||||
mode_t _old_umask;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ if( GPERFTOOLS_FOUND )
|
|||
endif()
|
||||
|
||||
target_link_libraries( witness_node
|
||||
PRIVATE graphene_app graphene_account_history graphene_market_history graphene_witness graphene_chain graphene_egenesis_full fc ${CMAKE_DL_LIBS} ${PLATFORM_SPECIFIC_LIBS} )
|
||||
PRIVATE graphene_app graphene_account_history graphene_market_history graphene_generate_genesis graphene_witness graphene_chain graphene_egenesis_full fc ${CMAKE_DL_LIBS} ${PLATFORM_SPECIFIC_LIBS} )
|
||||
|
||||
install( TARGETS
|
||||
witness_node
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include <graphene/witness/witness.hpp>
|
||||
#include <graphene/account_history/account_history_plugin.hpp>
|
||||
#include <graphene/market_history/market_history_plugin.hpp>
|
||||
#include <graphene/generate_genesis/generate_genesis_plugin.hpp>
|
||||
|
||||
#include <fc/exception/exception.hpp>
|
||||
#include <fc/thread/thread.hpp>
|
||||
|
|
@ -74,6 +75,7 @@ int main(int argc, char** argv) {
|
|||
auto witness_plug = node->register_plugin<witness_plugin::witness_plugin>();
|
||||
auto history_plug = node->register_plugin<account_history::account_history_plugin>();
|
||||
auto market_history_plug = node->register_plugin<market_history::market_history_plugin>();
|
||||
auto generate_genesis_plug = node->register_plugin<generate_genesis_plugin::generate_genesis_plugin>();
|
||||
|
||||
try
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue