Updating wallet info through operation instead through database.modify() for persistance

This commit is contained in:
Srdjan Obucina 2020-01-27 13:14:22 +01:00
parent 8399008e7d
commit 0142348a9c
7 changed files with 92 additions and 38 deletions

View file

@ -11,16 +11,18 @@ namespace graphene { namespace peerplays_sidechain {
class sidechain_net_handler {
public:
sidechain_net_handler(std::shared_ptr<graphene::chain::database> db, const boost::program_options::variables_map& options);
sidechain_net_handler(peerplays_sidechain_plugin& _plugin, const boost::program_options::variables_map& options);
virtual ~sidechain_net_handler();
graphene::peerplays_sidechain::sidechain_type get_sidechain();
std::vector<std::string> get_sidechain_addresses();
virtual son_wallet_update_operation recreate_primary_wallet() = 0;
virtual string recreate_primary_wallet(const vector<string>& participants) = 0;
protected:
std::shared_ptr<graphene::chain::database> database;
peerplays_sidechain_plugin& plugin;
graphene::chain::database& database;
graphene::peerplays_sidechain::sidechain_type sidechain;
void sidechain_event_data_received(const sidechain_event_data& sed);

View file

@ -57,9 +57,10 @@ private:
class sidechain_net_handler_bitcoin : public sidechain_net_handler {
public:
sidechain_net_handler_bitcoin(std::shared_ptr<graphene::chain::database> db, const boost::program_options::variables_map& options);
sidechain_net_handler_bitcoin(peerplays_sidechain_plugin& _plugin, const boost::program_options::variables_map& options);
virtual ~sidechain_net_handler_bitcoin();
son_wallet_update_operation recreate_primary_wallet();
string recreate_primary_wallet(const vector<string>& participants);
bool connection_is_not_defined() const;

View file

@ -12,13 +12,15 @@ namespace graphene { namespace peerplays_sidechain {
class sidechain_net_manager {
public:
sidechain_net_manager(std::shared_ptr<graphene::chain::database> db);
sidechain_net_manager(peerplays_sidechain_plugin& _plugin);
virtual ~sidechain_net_manager();
bool create_handler(peerplays_sidechain::sidechain_type sidechain, const boost::program_options::variables_map& options);
signed_transaction recreate_primary_wallet();
string recreate_primary_wallet(peerplays_sidechain::sidechain_type sidechain, const vector<string>& participants);
private:
std::shared_ptr<graphene::chain::database> database;
peerplays_sidechain_plugin& plugin;
graphene::chain::database& database;
std::vector<std::unique_ptr<sidechain_net_handler>> net_handlers;
};

View file

@ -132,7 +132,7 @@ void peerplays_sidechain_plugin_impl::plugin_initialize(const boost::program_opt
throw;
}
net_manager = std::unique_ptr<sidechain_net_manager>(new sidechain_net_manager(plugin.app().chain_database()));
net_manager = std::unique_ptr<sidechain_net_manager>(new sidechain_net_manager(plugin));
config_ready_bitcoin = options.count( "bitcoin-node-ip" ) &&
options.count( "bitcoin-node-zmq-port" ) && options.count( "bitcoin-node-rpc-port" ) &&
@ -282,31 +282,18 @@ void peerplays_sidechain_plugin_impl::create_son_down_proposals() {
void peerplays_sidechain_plugin_impl::recreate_primary_wallet()
{
chain::database& d = plugin.database();
signed_transaction trx = net_manager->recreate_primary_wallet();
auto dyn_props = d.get_dynamic_global_properties();
trx.set_reference_block( dyn_props.head_block_id );
trx.set_expiration( d.head_block_time() + d.get_global_properties().parameters.maximum_time_until_expiration );
d.current_fee_schedule().set_fee( trx.operations.back() );
const auto& idx_swi = d.get_index_type<son_wallet_index>().indices().get<by_id>();
auto obj = idx_swi.rbegin();
if (obj != idx_swi.rend()) {
trx.sign(_private_keys.begin()->second, d.get_chain_id());
if ((obj->addresses.find(sidechain_type::bitcoin) == obj->addresses.end()) ||
(obj->addresses.at(sidechain_type::bitcoin).empty())) {
auto active_sons = d.get_global_properties().active_sons;
vector<string> son_pubkeys_bitcoin;
for ( const son_info& si : active_sons ) {
son_pubkeys_bitcoin.push_back(si.sidechain_public_keys.at(sidechain_type::bitcoin));
}
string reply_str = net_manager->recreate_primary_wallet(sidechain_type::bitcoin, son_pubkeys_bitcoin);
std::stringstream ss(reply_str);
boost::property_tree::ptree pt;
boost::property_tree::read_json( ss, pt );
if( pt.count( "error" ) && pt.get_child( "error" ).empty() ) {
d.modify(*obj, [&, obj, pt](son_wallet_object &swo) {
std::stringstream ss;
boost::property_tree::json_parser::write_json(ss, pt.get_child("result"));
swo.addresses[sidechain_type::bitcoin] = ss.str();
});
}
}
try {
d.push_transaction(trx, database::validation_steps::skip_block_size_check);
} catch (fc::exception e) {
ilog("peerplays_sidechain_plugin_impl: sending son wallet update operations failed with exception ${e}",("e", e.what()));
}
}

View file

@ -6,8 +6,9 @@
namespace graphene { namespace peerplays_sidechain {
sidechain_net_handler::sidechain_net_handler(std::shared_ptr<graphene::chain::database> db, const boost::program_options::variables_map& options) :
database(db)
sidechain_net_handler::sidechain_net_handler(peerplays_sidechain_plugin& _plugin, const boost::program_options::variables_map& options) :
plugin(_plugin),
database(_plugin.database())
{
}
@ -24,7 +25,7 @@ std::vector<std::string> sidechain_net_handler::get_sidechain_addresses() {
switch (sidechain) {
case sidechain_type::bitcoin:
{
const auto& sidechain_addresses_idx = database->get_index_type<sidechain_address_index>();
const auto& sidechain_addresses_idx = database.get_index_type<sidechain_address_index>();
const auto& sidechain_addresses_by_sidechain_idx = sidechain_addresses_idx.indices().get<by_sidechain>();
const auto& sidechain_addresses_by_sidechain_range = sidechain_addresses_by_sidechain_idx.equal_range(sidechain);
std::for_each(sidechain_addresses_by_sidechain_range.first, sidechain_addresses_by_sidechain_range.second,

View file

@ -12,6 +12,9 @@
#include <fc/network/ip.hpp>
#include <graphene/chain/sidechain_address_object.hpp>
#include <graphene/chain/son_info.hpp>
#include <graphene/chain/son_wallet_object.hpp>
#include <graphene/chain/protocol/son_wallet.hpp>
namespace graphene { namespace peerplays_sidechain {
@ -221,8 +224,8 @@ void zmq_listener::handle_zmq() {
// =============================================================================
sidechain_net_handler_bitcoin::sidechain_net_handler_bitcoin(std::shared_ptr<graphene::chain::database> db, const boost::program_options::variables_map& options) :
sidechain_net_handler(db, options) {
sidechain_net_handler_bitcoin::sidechain_net_handler_bitcoin(peerplays_sidechain_plugin& _plugin, const boost::program_options::variables_map& options) :
sidechain_net_handler(_plugin, options) {
sidechain = sidechain_type::bitcoin;
ip = options.at("bitcoin-node-ip").as<std::string>();
@ -250,6 +253,41 @@ sidechain_net_handler_bitcoin::sidechain_net_handler_bitcoin(std::shared_ptr<gra
sidechain_net_handler_bitcoin::~sidechain_net_handler_bitcoin() {
}
son_wallet_update_operation sidechain_net_handler_bitcoin::recreate_primary_wallet() {
const auto& idx_swi = database.get_index_type<son_wallet_index>().indices().get<by_id>();
auto obj = idx_swi.rbegin();
if (obj != idx_swi.rend()) {
if ((obj->addresses.find(sidechain_type::bitcoin) == obj->addresses.end()) ||
(obj->addresses.at(sidechain_type::bitcoin).empty())) {
auto active_sons = database.get_global_properties().active_sons;
vector<string> son_pubkeys_bitcoin;
for ( const son_info& si : active_sons ) {
son_pubkeys_bitcoin.push_back(si.sidechain_public_keys.at(sidechain_type::bitcoin));
}
string reply_str = create_multisignature_wallet(son_pubkeys_bitcoin);
ilog(reply_str);
std::stringstream ss(reply_str);
boost::property_tree::ptree pt;
boost::property_tree::read_json( ss, pt );
if( pt.count( "error" ) && pt.get_child( "error" ).empty() ) {
ilog(__FUNCTION__);
son_wallet_update_operation op;
op.payer = database.get_global_properties().parameters.get_son_btc_account_id();
op.son_wallet_id = (*obj).id;
op.sidechain = sidechain_type::bitcoin;
op.address = ss.str();
return op;
}
}
}
return {};
}
string sidechain_net_handler_bitcoin::recreate_primary_wallet( const vector<string>& participants ) {
ilog(__FUNCTION__);
string result = create_multisignature_wallet(participants);
@ -289,7 +327,7 @@ void sidechain_net_handler_bitcoin::handle_event( const std::string& event_data
if( block != "" ) {
const auto& vins = extract_info_from_block( block );
const auto& sidechain_addresses_idx = database->get_index_type<sidechain_address_index>().indices().get<by_sidechain_and_address>();
const auto& sidechain_addresses_idx = database.get_index_type<sidechain_address_index>().indices().get<by_sidechain_and_address>();
for( const auto& v : vins ) {
const auto& addr_itr = sidechain_addresses_idx.find(std::make_tuple(sidechain_type::bitcoin, v.address));

View file

@ -1,12 +1,14 @@
#include <graphene/peerplays_sidechain/sidechain_net_manager.hpp>
#include <fc/log/logger.hpp>
#include <graphene/chain/son_wallet_object.hpp>
#include <graphene/peerplays_sidechain/sidechain_net_handler_bitcoin.hpp>
namespace graphene { namespace peerplays_sidechain {
sidechain_net_manager::sidechain_net_manager(std::shared_ptr<graphene::chain::database> db) :
database(db)
sidechain_net_manager::sidechain_net_manager(peerplays_sidechain_plugin& _plugin) :
plugin(_plugin),
database(_plugin.database())
{
ilog(__FUNCTION__);
}
@ -22,7 +24,7 @@ bool sidechain_net_manager::create_handler(peerplays_sidechain::sidechain_type s
switch (sidechain) {
case sidechain_type::bitcoin: {
std::unique_ptr<sidechain_net_handler> h = std::unique_ptr<sidechain_net_handler>(new sidechain_net_handler_bitcoin(database, options));
std::unique_ptr<sidechain_net_handler> h = std::unique_ptr<sidechain_net_handler>(new sidechain_net_handler_bitcoin(plugin, options));
net_handlers.push_back(std::move(h));
ret_val = true;
break;
@ -34,6 +36,27 @@ bool sidechain_net_manager::create_handler(peerplays_sidechain::sidechain_type s
return ret_val;
}
signed_transaction sidechain_net_manager::recreate_primary_wallet() {
ilog(__FUNCTION__);
signed_transaction trx = {};
const auto& idx = database.get_index_type<son_wallet_index>().indices().get<by_id>();
auto swo = idx.rbegin();
for ( size_t i = 0; i < net_handlers.size(); i++ ) {
son_wallet_update_operation op = net_handlers.at(i)->recreate_primary_wallet();
if (swo != idx.rend()) {
if (op.son_wallet_id == swo->id) {
trx.operations.push_back(op);
}
}
}
return trx;
}
string sidechain_net_manager::recreate_primary_wallet(peerplays_sidechain::sidechain_type sidechain, const vector<string>& participants) {
ilog(__FUNCTION__);
for ( size_t i = 0; i < net_handlers.size(); i++ ) {