SON listener for Hive

This commit is contained in:
serkixenos 2021-03-05 16:24:09 +01:00
parent ae712122d4
commit 5920356b5d
10 changed files with 610 additions and 33 deletions

View file

@ -9,7 +9,8 @@ enum class sidechain_type {
bitcoin,
ethereum,
eos,
peerplays
peerplays,
hive
};
} }
@ -19,4 +20,5 @@ FC_REFLECT_ENUM(graphene::chain::sidechain_type,
(bitcoin)
(ethereum)
(eos)
(hive)
(peerplays) )

View file

@ -5,6 +5,7 @@ add_library( peerplays_sidechain
sidechain_net_manager.cpp
sidechain_net_handler.cpp
sidechain_net_handler_bitcoin.cpp
sidechain_net_handler_hive.cpp
sidechain_net_handler_peerplays.cpp
bitcoin/bech32.cpp
bitcoin/bitcoin_address.cpp

View file

@ -23,6 +23,7 @@ public:
boost::program_options::options_description &cfg) override;
virtual void plugin_initialize(const boost::program_options::variables_map &options) override;
virtual void plugin_startup() override;
virtual void plugin_shutdown() override;
std::unique_ptr<detail::peerplays_sidechain_plugin_impl> my;

View file

@ -0,0 +1,63 @@
#pragma once
#include <graphene/peerplays_sidechain/sidechain_net_handler.hpp>
#include <string>
#include <fc/network/http/connection.hpp>
#include <fc/signals.hpp>
namespace graphene { namespace peerplays_sidechain {
class hive_rpc_client {
public:
hive_rpc_client(std::string _ip, uint32_t _rpc_port, std::string _user, std::string _password);
std::string block_api_get_block(uint32_t block_number);
std::string database_api_get_dynamic_global_properties();
private:
std::string send_post_request(std::string method, std::string params, bool show_log);
fc::http::reply send_post_request(std::string body, bool show_log);
std::string ip;
uint32_t rpc_port;
std::string user;
std::string password;
fc::http::header authorization;
};
class sidechain_net_handler_hive : public sidechain_net_handler {
public:
sidechain_net_handler_hive(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options);
virtual ~sidechain_net_handler_hive();
bool process_proposal(const proposal_object &po);
void process_primary_wallet();
void process_sidechain_addresses();
bool process_deposit(const son_wallet_deposit_object &swdo);
bool process_withdrawal(const son_wallet_withdraw_object &swwo);
std::string process_sidechain_transaction(const sidechain_transaction_object &sto);
std::string send_sidechain_transaction(const sidechain_transaction_object &sto);
int64_t settle_sidechain_transaction(const sidechain_transaction_object &sto);
private:
std::string ip;
uint32_t rpc_port;
std::string rpc_user;
std::string rpc_password;
hive_rpc_client *rpc_client;
uint64_t last_block_received;
fc::future<void> _listener_task;
fc::signal<void(const std::string &)> event_received;
void schedule_hive_listener();
void hive_listener_loop();
void handle_event(const std::string &event_data);
void on_applied_block(const signed_block &b);
};
}} // namespace graphene::peerplays_sidechain

View file

@ -29,6 +29,7 @@ public:
boost::program_options::options_description &cfg);
void plugin_initialize(const boost::program_options::variables_map &opt);
void plugin_startup();
void plugin_shutdown();
std::set<chain::son_id_type> &get_sons();
const son_id_type get_current_son_id();
@ -66,8 +67,15 @@ private:
bool config_ready_son;
bool config_ready_bitcoin;
bool config_ready_ethereum;
bool config_ready_hive;
bool config_ready_peerplays;
bool sidechain_enabled_bitcoin;
bool sidechain_enabled_ethereum;
bool sidechain_enabled_hive;
bool sidechain_enabled_peerplays;
son_id_type current_son_id;
std::unique_ptr<peerplays_sidechain::sidechain_net_manager> net_manager;
@ -84,7 +92,13 @@ peerplays_sidechain_plugin_impl::peerplays_sidechain_plugin_impl(peerplays_sidec
plugin(_plugin),
config_ready_son(false),
config_ready_bitcoin(false),
config_ready_ethereum(false),
config_ready_hive(false),
config_ready_peerplays(false),
sidechain_enabled_bitcoin(false),
sidechain_enabled_ethereum(false),
sidechain_enabled_hive(false),
sidechain_enabled_peerplays(false),
current_son_id(son_id_type(std::numeric_limits<uint32_t>().max())),
net_manager(nullptr),
first_block_skipped(false) {
@ -121,6 +135,8 @@ void peerplays_sidechain_plugin_impl::plugin_set_program_options(
cli.add_options()("son-ids", bpo::value<string>(), ("IDs of multiple SONs controlled by this node (e.g. [" + son_id_example + ", " + son_id_example2 + "], quotes are required)").c_str());
cli.add_options()("peerplays-private-key", bpo::value<vector<string>>()->composing()->multitoken()->DEFAULT_VALUE_VECTOR(std::make_pair(chain::public_key_type(default_priv_key.get_public_key()), graphene::utilities::key_to_wif(default_priv_key))),
"Tuple of [PublicKey, WIF private key] (may specify multiple times)");
cli.add_options()("bitcoin-sidechain-enabled", bpo::value<bool>()->default_value(false), "Bitcoin sidechain handler enabled");
cli.add_options()("bitcoin-node-ip", bpo::value<string>()->default_value("127.0.0.1"), "IP address of Bitcoin node");
cli.add_options()("bitcoin-node-zmq-port", bpo::value<uint32_t>()->default_value(11111), "ZMQ port of Bitcoin node");
cli.add_options()("bitcoin-node-rpc-port", bpo::value<uint32_t>()->default_value(8332), "RPC port of Bitcoin node");
@ -130,6 +146,15 @@ void peerplays_sidechain_plugin_impl::plugin_set_program_options(
cli.add_options()("bitcoin-wallet-password", bpo::value<string>(), "Bitcoin wallet password");
cli.add_options()("bitcoin-private-key", bpo::value<vector<string>>()->composing()->multitoken()->DEFAULT_VALUE_VECTOR(std::make_pair("02d0f137e717fb3aab7aff99904001d49a0a636c5e1342f8927a4ba2eaee8e9772", "cVN31uC9sTEr392DLVUEjrtMgLA8Yb3fpYmTRj7bomTm6nn2ANPr")),
"Tuple of [Bitcoin public key, Bitcoin private key] (may specify multiple times)");
cli.add_options()("hive-sidechain-enabled", bpo::value<bool>()->default_value(false), "Hive sidechain handler enabled");
cli.add_options()("hive-node-ip", bpo::value<string>()->default_value("127.0.0.1"), "IP address of Hive node");
cli.add_options()("hive-node-rpc-port", bpo::value<uint32_t>()->default_value(28090), "RPC port of Hive node");
cli.add_options()("hive-node-rpc-user", bpo::value<string>(), "Hive RPC user");
cli.add_options()("hive-node-rpc-password", bpo::value<string>(), "Hive RPC password");
cli.add_options()("hive-private-key", bpo::value<vector<string>>()->composing()->multitoken()->DEFAULT_VALUE_VECTOR(std::make_pair("TST6LLegbAgLAy28EHrffBVuANFWcFgmqRMW13wBmTExqFE9SCkg4", "5JNHfZYKGaomSFvd4NUdQ9qMcEAC43kujbfjueTHpVapX1Kzq2n")),
"Tuple of [Hive public key, Hive private key] (may specify multiple times)");
cfg.add(cli);
}
@ -175,27 +200,48 @@ void peerplays_sidechain_plugin_impl::plugin_initialize(const boost::program_opt
throw;
}
sidechain_enabled_bitcoin = options.at("bitcoin-sidechain-enabled").as<bool>();
config_ready_bitcoin = options.count("bitcoin-node-ip") &&
options.count("bitcoin-node-zmq-port") && options.count("bitcoin-node-rpc-port") &&
options.count("bitcoin-node-rpc-user") && options.count("bitcoin-node-rpc-password") &&
/*options.count( "bitcoin-wallet" ) && options.count( "bitcoin-wallet-password" ) &&*/
/*options.count("bitcoin-wallet") && options.count("bitcoin-wallet-password") &&*/
options.count("bitcoin-private-key");
if (!config_ready_bitcoin) {
wlog("Haven't set up Bitcoin sidechain parameters");
}
//config_ready_ethereum = options.count( "ethereum-node-ip" ) &&
// options.count( "ethereum-address" ) && options.count( "ethereum-public-key" ) && options.count( "ethereum-private-key" );
//sidechain_enabled_ethereum = options.at("ethereum-sidechain-enabled").as<bool>();
//config_ready_ethereum = options.count("ethereum-node-ip") &&
// options.count("ethereum-address") &&
// options.count("ethereum-public-key") && options.count("ethereum-private-key");
//if (!config_ready_ethereum) {
// wlog("Haven't set up Ethereum sidechain parameters");
//}
sidechain_enabled_hive = options.at("hive-sidechain-enabled").as<bool>();
config_ready_hive = options.count("hive-node-ip") &&
options.count("hive-node-rpc-port") &&
/*options.count("hive-node-rpc-user") && options.count("bitcoin-node-rpc-password") &&*/
/*options.count("hive-wallet") && options.count("hive-wallet-password") &&*/
options.count("hive-private-key");
if (!config_ready_hive) {
wlog("Haven't set up Hive sidechain parameters");
}
#ifdef ENABLE_PEERPLAYS_ASSET_DEPOSITS
sidechain_enabled_peerplays = true; //options.at("peerplays-sidechain-enabled").as<bool>();
#else
sidechain_enabled_peerplays = false;
#endif
config_ready_peerplays = true;
if (!config_ready_peerplays) {
wlog("Haven't set up Peerplays sidechain parameters");
}
if (!(config_ready_bitcoin /*&& config_ready_ethereum*/ && config_ready_peerplays)) {
if (!(config_ready_bitcoin &&
/*config_ready_ethereum &&*/
config_ready_hive &&
config_ready_peerplays)) {
wlog("Haven't set up any sidechain parameters");
throw;
}
@ -213,17 +259,22 @@ void peerplays_sidechain_plugin_impl::plugin_startup() {
net_manager = std::unique_ptr<sidechain_net_manager>(new sidechain_net_manager(plugin));
if (config_ready_bitcoin) {
if (sidechain_enabled_bitcoin && config_ready_bitcoin) {
net_manager->create_handler(sidechain_type::bitcoin, options);
ilog("Bitcoin sidechain handler running");
}
//if (config_ready_ethereum) {
//if (sidechain_enabled_ethereum && config_ready_ethereum) {
// net_manager->create_handler(sidechain_type::ethereum, options);
// ilog("Ethereum sidechain handler running");
//}
if (config_ready_peerplays) {
if (sidechain_enabled_hive && config_ready_hive) {
net_manager->create_handler(sidechain_type::hive, options);
ilog("Hive sidechain handler running");
}
if (sidechain_enabled_peerplays && config_ready_peerplays) {
net_manager->create_handler(sidechain_type::peerplays, options);
ilog("Peerplays sidechain handler running");
}
@ -233,6 +284,9 @@ void peerplays_sidechain_plugin_impl::plugin_startup() {
});
}
void peerplays_sidechain_plugin_impl::plugin_shutdown() {
}
std::set<chain::son_id_type> &peerplays_sidechain_plugin_impl::get_sons() {
return sons;
}
@ -279,7 +333,7 @@ bool peerplays_sidechain_plugin_impl::is_son_deregistered(son_id_type son_id) {
if (son_obj == idx.end())
return true;
if(son_obj->status == chain::son_status::deregistered) {
if (son_obj->status == chain::son_status::deregistered) {
return true;
}
@ -663,6 +717,12 @@ void peerplays_sidechain_plugin::plugin_startup() {
ilog("peerplays sidechain plugin: plugin_startup() end");
}
void peerplays_sidechain_plugin::plugin_shutdown() {
ilog("peerplays sidechain plugin: plugin_shutdown() begin");
my->plugin_shutdown();
ilog("peerplays sidechain plugin: plugin_shutdown() end");
}
std::set<chain::son_id_type> &peerplays_sidechain_plugin::get_sons() {
return my->get_sons();
}

View file

@ -283,7 +283,7 @@ void sidechain_net_handler::process_proposals() {
int32_t op_idx_1 = -1;
chain::operation op_obj_idx_1;
(void) op_idx_1;
(void)op_idx_1;
if (po->proposed_transaction.operations.size() >= 2) {
op_idx_1 = po->proposed_transaction.operations[1].which();

View file

@ -1005,7 +1005,7 @@ bool sidechain_net_handler_bitcoin::process_proposal(const proposal_object &po)
int32_t op_idx_1 = -1;
chain::operation op_obj_idx_1;
(void) op_idx_1;
(void)op_idx_1;
if (po.proposed_transaction.operations.size() >= 2) {
op_idx_1 = po.proposed_transaction.operations[1].which();

View file

@ -0,0 +1,443 @@
#include <graphene/peerplays_sidechain/sidechain_net_handler_hive.hpp>
#include <algorithm>
#include <thread>
#include <boost/algorithm/hex.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#include <fc/crypto/base64.hpp>
#include <fc/crypto/hex.hpp>
#include <fc/log/logger.hpp>
#include <fc/network/ip.hpp>
#include <fc/smart_ref_impl.hpp>
#include <graphene/chain/account_object.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp>
#include <graphene/chain/protocol/son_wallet.hpp>
#include <graphene/chain/son_info.hpp>
#include <graphene/chain/son_wallet_object.hpp>
#include <graphene/utilities/key_conversion.hpp>
namespace graphene { namespace peerplays_sidechain {
hive_rpc_client::hive_rpc_client(std::string _ip, uint32_t _rpc_port, std::string _user, std::string _password) :
ip(_ip),
rpc_port(_rpc_port),
user(_user),
password(_password) {
authorization.key = "Authorization";
authorization.val = "Basic " + fc::base64_encode(user + ":" + password);
}
std::string hive_rpc_client::block_api_get_block(uint32_t block_number) {
std::string params = "{ \"block_num\": " + std::to_string(block_number) + " }";
return send_post_request("block_api.get_block", params, true);
}
std::string hive_rpc_client::database_api_get_dynamic_global_properties() {
return send_post_request("database_api.get_dynamic_global_properties", "", false);
}
std::string hive_rpc_client::send_post_request(std::string method, std::string params, bool show_log) {
std::stringstream body;
body << "{ \"jsonrpc\": \"2.0\", \"id\": \"" << method << "\", \"method\": \"" << method << "\"";
if (!params.empty()) {
body << ", \"params\": " << params << "}";
}
body << " }";
const auto reply = send_post_request(body.str(), show_log);
if (reply.body.empty()) {
wlog("Hive RPC call ${function} failed", ("function", __FUNCTION__));
return "";
}
std::stringstream ss(std::string(reply.body.begin(), reply.body.end()));
boost::property_tree::ptree json;
boost::property_tree::read_json(ss, json);
if (reply.status == 200) {
return ss.str();
}
if (json.count("error") && !json.get_child("error").empty()) {
wlog("Hive RPC call ${function} with body ${body} failed with reply '${msg}'", ("function", __FUNCTION__)("body", body.str())("msg", ss.str()));
}
return "";
}
fc::http::reply hive_rpc_client::send_post_request(std::string body, bool show_log) {
fc::http::connection conn;
conn.connect_to(fc::ip::endpoint(fc::ip::address(ip), rpc_port));
std::string url = "http://" + ip + ":" + std::to_string(rpc_port);
//if (wallet.length() > 0) {
// url = url + "/wallet/" + wallet;
//}
fc::http::reply reply = conn.request("POST", url, body, fc::http::headers{authorization});
if (show_log) {
ilog("### Request URL: ${url}", ("url", url));
ilog("### Request: ${body}", ("body", body));
std::stringstream ss(std::string(reply.body.begin(), reply.body.end()));
ilog("### Response: ${ss}", ("ss", ss.str()));
}
return reply;
}
sidechain_net_handler_hive::sidechain_net_handler_hive(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options) :
sidechain_net_handler(_plugin, options) {
sidechain = sidechain_type::hive;
ip = options.at("hive-node-ip").as<std::string>();
rpc_port = options.at("hive-node-rpc-port").as<uint32_t>();
if (options.count("hive-node-rpc-user")) {
rpc_user = options.at("hive-node-rpc-user").as<std::string>();
} else {
rpc_user = "";
}
if (options.count("hive-node-rpc-password")) {
rpc_password = options.at("hive-node-rpc-password").as<std::string>();
} else {
rpc_password = "";
}
if (options.count("hive-private-key")) {
const std::vector<std::string> pub_priv_keys = options["hive-private-key"].as<std::vector<std::string>>();
for (const std::string &itr_key_pair : pub_priv_keys) {
auto key_pair = graphene::app::dejsonify<std::pair<std::string, std::string>>(itr_key_pair, 5);
ilog("Hive Public Key: ${public}", ("public", key_pair.first));
if (!key_pair.first.length() || !key_pair.second.length()) {
FC_THROW("Invalid public private key pair.");
}
private_keys[key_pair.first] = key_pair.second;
}
}
fc::http::connection conn;
try {
conn.connect_to(fc::ip::endpoint(fc::ip::address(ip), rpc_port));
} catch (fc::exception &e) {
elog("No Hive node running at ${ip} or wrong rpc port: ${port}", ("ip", ip)("port", rpc_port));
FC_ASSERT(false);
}
rpc_client = new hive_rpc_client(ip, rpc_port, rpc_user, rpc_password);
last_block_received = 0;
schedule_hive_listener();
event_received.connect([this](const std::string &event_data) {
std::thread(&sidechain_net_handler_hive::handle_event, this, event_data).detach();
});
}
sidechain_net_handler_hive::~sidechain_net_handler_hive() {
}
bool sidechain_net_handler_hive::process_proposal(const proposal_object &po) {
ilog("Proposal to process: ${po}, SON id ${son_id}", ("po", po.id)("son_id", plugin.get_current_son_id()));
bool should_approve = false;
// const chain::global_property_object &gpo = database.get_global_properties();
//
// int32_t op_idx_0 = -1;
// chain::operation op_obj_idx_0;
//
// if (po.proposed_transaction.operations.size() >= 1) {
// op_idx_0 = po.proposed_transaction.operations[0].which();
// op_obj_idx_0 = po.proposed_transaction.operations[0];
// }
//
// switch (op_idx_0) {
//
// case chain::operation::tag<chain::son_wallet_update_operation>::value: {
// should_approve = false;
// break;
// }
//
// case chain::operation::tag<chain::son_wallet_deposit_process_operation>::value: {
// son_wallet_deposit_id_type swdo_id = op_obj_idx_0.get<son_wallet_deposit_process_operation>().son_wallet_deposit_id;
// const auto &idx = database.get_index_type<son_wallet_deposit_index>().indices().get<by_id>();
// const auto swdo = idx.find(swdo_id);
// if (swdo != idx.end()) {
//
// uint32_t swdo_block_num = swdo->block_num;
// std::string swdo_sidechain_transaction_id = swdo->sidechain_transaction_id;
// uint32_t swdo_op_idx = std::stoll(swdo->sidechain_uid.substr(swdo->sidechain_uid.find_last_of("-") + 1));
//
// const auto &block = database.fetch_block_by_number(swdo_block_num);
//
// for (const auto &tx : block->transactions) {
// if (tx.id().str() == swdo_sidechain_transaction_id) {
// operation op = tx.operations[swdo_op_idx];
// transfer_operation t_op = op.get<transfer_operation>();
//
// asset sidechain_asset = asset(swdo->sidechain_amount, fc::variant(swdo->sidechain_currency, 1).as<asset_id_type>(1));
// price sidechain_asset_price = database.get<asset_object>(sidechain_asset.asset_id).options.core_exchange_rate;
// asset peerplays_asset = asset(sidechain_asset.amount * sidechain_asset_price.base.amount / sidechain_asset_price.quote.amount);
//
// should_approve = (gpo.parameters.son_account() == t_op.to) &&
// (swdo->peerplays_from == t_op.from) &&
// (sidechain_asset == t_op.amount) &&
// (swdo->peerplays_asset == peerplays_asset);
// break;
// }
// }
// }
// break;
// }
//
// case chain::operation::tag<chain::son_wallet_withdraw_process_operation>::value: {
// should_approve = false;
// break;
// }
//
// case chain::operation::tag<chain::sidechain_transaction_settle_operation>::value: {
// should_approve = true;
// break;
// }
//
// default:
// should_approve = false;
// elog("==================================================");
// elog("Proposal not considered for approval ${po}", ("po", po));
// elog("==================================================");
// }
return should_approve;
}
void sidechain_net_handler_hive::process_primary_wallet() {
return;
}
void sidechain_net_handler_hive::process_sidechain_addresses() {
// 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,
// [&](const sidechain_address_object &sao) {
// bool retval = true;
// if (sao.expires == time_point_sec::maximum()) {
// if (sao.deposit_address == "") {
// sidechain_address_update_operation op;
// op.payer = plugin.get_current_son_object().son_account;
// op.sidechain_address_id = sao.id;
// op.sidechain_address_account = sao.sidechain_address_account;
// op.sidechain = sao.sidechain;
// op.deposit_public_key = sao.deposit_public_key;
// op.deposit_address = sao.withdraw_address;
// op.deposit_address_data = sao.withdraw_address;
// op.withdraw_public_key = sao.withdraw_public_key;
// op.withdraw_address = sao.withdraw_address;
//
// signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), op);
// try {
// trx.validate();
// database.push_transaction(trx, database::validation_steps::skip_block_size_check);
// if (plugin.app().p2p_node())
// plugin.app().p2p_node()->broadcast(net::trx_message(trx));
// retval = true;
// } catch (fc::exception &e) {
// elog("Sending transaction for update deposit address operation failed with exception ${e}", ("e", e.what()));
// retval = false;
// }
// }
// }
// return retval;
// });
return;
}
bool sidechain_net_handler_hive::process_deposit(const son_wallet_deposit_object &swdo) {
// const chain::global_property_object &gpo = database.get_global_properties();
//
// asset_issue_operation ai_op;
// ai_op.issuer = gpo.parameters.son_account();
// price btc_price = database.get<asset_object>(database.get_global_properties().parameters.btc_asset()).options.core_exchange_rate;
// ai_op.asset_to_issue = asset(swdo.peerplays_asset.amount * btc_price.quote.amount / btc_price.base.amount, database.get_global_properties().parameters.btc_asset());
// ai_op.issue_to_account = swdo.peerplays_from;
//
// signed_transaction tx;
// auto dyn_props = database.get_dynamic_global_properties();
// tx.set_reference_block(dyn_props.head_block_id);
// tx.set_expiration(database.head_block_time() + gpo.parameters.maximum_time_until_expiration);
// tx.operations.push_back(ai_op);
// database.current_fee_schedule().set_fee(tx.operations.back());
//
// std::stringstream ss;
// fc::raw::pack(ss, tx, 1000);
// std::string tx_str = boost::algorithm::hex(ss.str());
//
// if (!tx_str.empty()) {
// const chain::global_property_object &gpo = database.get_global_properties();
//
// sidechain_transaction_create_operation stc_op;
// stc_op.payer = gpo.parameters.son_account();
// stc_op.object_id = swdo.id;
// stc_op.sidechain = sidechain;
// stc_op.transaction = tx_str;
// stc_op.signers = gpo.active_sons;
//
// proposal_create_operation proposal_op;
// proposal_op.fee_paying_account = plugin.get_current_son_object().son_account;
// proposal_op.proposed_ops.emplace_back(stc_op);
// 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);
//
// signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op);
// try {
// trx.validate();
// database.push_transaction(trx, database::validation_steps::skip_block_size_check);
// if (plugin.app().p2p_node())
// plugin.app().p2p_node()->broadcast(net::trx_message(trx));
// return true;
// } catch (fc::exception &e) {
// elog("Sending proposal for deposit sidechain transaction create operation failed with exception ${e}", ("e", e.what()));
// return false;
// }
// }
return false;
}
bool sidechain_net_handler_hive::process_withdrawal(const son_wallet_withdraw_object &swwo) {
return false;
}
std::string sidechain_net_handler_hive::process_sidechain_transaction(const sidechain_transaction_object &sto) {
// std::stringstream ss_trx(boost::algorithm::unhex(sto.transaction));
// signed_transaction trx;
// fc::raw::unpack(ss_trx, trx, 1000);
//
// fc::optional<fc::ecc::private_key> privkey = graphene::utilities::wif_to_key(get_private_key(plugin.get_current_son_object().sidechain_public_keys.at(sidechain)));
// signature_type st = trx.sign(*privkey, database.get_chain_id());
//
std::stringstream ss_st;
// fc::raw::pack(ss_st, st, 1000);
std::string st_str = boost::algorithm::hex(ss_st.str());
return st_str;
}
std::string sidechain_net_handler_hive::send_sidechain_transaction(const sidechain_transaction_object &sto) {
// std::stringstream ss_trx(boost::algorithm::unhex(sto.transaction));
// signed_transaction trx;
// fc::raw::unpack(ss_trx, trx, 1000);
//
// for (auto signature : sto.signatures) {
// if (!signature.second.empty()) {
// std::stringstream ss_st(boost::algorithm::unhex(signature.second));
// signature_type st;
// fc::raw::unpack(ss_st, st, 1000);
//
// trx.signatures.push_back(st);
// trx.signees.clear();
// }
// }
//
// try {
// trx.validate();
// database.push_transaction(trx, database::validation_steps::skip_block_size_check);
// if (plugin.app().p2p_node())
// plugin.app().p2p_node()->broadcast(net::trx_message(trx));
// return trx.id().str();
// } catch (fc::exception &e) {
// elog("Sidechain transaction failed with exception ${e}", ("e", e.what()));
// return "";
// }
return "";
}
int64_t sidechain_net_handler_hive::settle_sidechain_transaction(const sidechain_transaction_object &sto) {
int64_t settle_amount = 0;
return settle_amount;
}
void sidechain_net_handler_hive::schedule_hive_listener() {
fc::time_point now = fc::time_point::now();
int64_t time_to_next = 1000;
fc::time_point next_wakeup(now + fc::milliseconds(time_to_next));
_listener_task = fc::schedule([this] {
hive_listener_loop();
},
next_wakeup, "SON Hive listener task");
}
void sidechain_net_handler_hive::hive_listener_loop() {
schedule_hive_listener();
std::string reply = rpc_client->database_api_get_dynamic_global_properties();
if (!reply.empty()) {
std::stringstream ss(reply);
boost::property_tree::ptree json;
boost::property_tree::read_json(ss, json);
if (json.count("result")) {
uint64_t head_block_number = json.get<uint64_t>("result.head_block_number");
if (head_block_number != last_block_received) {
std::string event_data = std::to_string(head_block_number);
handle_event(event_data);
last_block_received = head_block_number;
}
}
}
}
void sidechain_net_handler_hive::handle_event(const std::string &event_data) {
std::string block = rpc_client->block_api_get_block(std::atoll(event_data.c_str()));
}
void sidechain_net_handler_hive::on_applied_block(const signed_block &b) {
// for (const auto &trx : b.transactions) {
// size_t operation_index = -1;
// for (auto op : trx.operations) {
// operation_index = operation_index + 1;
// if (op.which() == operation::tag<transfer_operation>::value) {
// transfer_operation transfer_op = op.get<transfer_operation>();
// if (transfer_op.to != plugin.database().get_global_properties().parameters.son_account()) {
// continue;
// }
//
// std::stringstream ss;
// ss << "peerplays"
// << "-" << trx.id().str() << "-" << operation_index;
// std::string sidechain_uid = ss.str();
//
// sidechain_event_data sed;
// sed.timestamp = database.head_block_time();
// sed.block_num = database.head_block_num();
// sed.sidechain = sidechain_type::peerplays;
// sed.sidechain_uid = sidechain_uid;
// sed.sidechain_transaction_id = trx.id().str();
// sed.sidechain_from = fc::to_string(transfer_op.from.space_id) + "." + fc::to_string(transfer_op.from.type_id) + "." + fc::to_string((uint64_t)transfer_op.from.instance);
// sed.sidechain_to = fc::to_string(transfer_op.to.space_id) + "." + fc::to_string(transfer_op.to.type_id) + "." + fc::to_string((uint64_t)transfer_op.to.instance);
// sed.sidechain_currency = fc::to_string(transfer_op.amount.asset_id.space_id) + "." + fc::to_string(transfer_op.amount.asset_id.type_id) + "." + fc::to_string((uint64_t)transfer_op.amount.asset_id.instance);
// sed.sidechain_amount = transfer_op.amount.amount;
// sed.peerplays_from = transfer_op.from;
// sed.peerplays_to = transfer_op.to;
// price asset_price = database.get<asset_object>(transfer_op.amount.asset_id).options.core_exchange_rate;
// sed.peerplays_asset = asset(transfer_op.amount.amount * asset_price.base.amount / asset_price.quote.amount);
// sidechain_event_data_received(sed);
// }
// }
// }
}
}} // namespace graphene::peerplays_sidechain

View file

@ -131,34 +131,34 @@ void sidechain_net_handler_peerplays::process_sidechain_addresses() {
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,
[&](const sidechain_address_object &sao) {
bool retval = true;
bool retval = true;
if (sao.expires == time_point_sec::maximum()) {
if (sao.deposit_address == "") {
sidechain_address_update_operation op;
op.payer = plugin.get_current_son_object().son_account;
op.sidechain_address_id = sao.id;
op.sidechain_address_account = sao.sidechain_address_account;
op.sidechain = sao.sidechain;
op.deposit_public_key = sao.deposit_public_key;
op.deposit_address = sao.withdraw_address;
op.deposit_address_data = sao.withdraw_address;
op.withdraw_public_key = sao.withdraw_public_key;
op.withdraw_address = sao.withdraw_address;
op.payer = plugin.get_current_son_object().son_account;
op.sidechain_address_id = sao.id;
op.sidechain_address_account = sao.sidechain_address_account;
op.sidechain = sao.sidechain;
op.deposit_public_key = sao.deposit_public_key;
op.deposit_address = sao.withdraw_address;
op.deposit_address_data = sao.withdraw_address;
op.withdraw_public_key = sao.withdraw_public_key;
op.withdraw_address = sao.withdraw_address;
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), op);
try {
trx.validate();
database.push_transaction(trx, database::validation_steps::skip_block_size_check);
if (plugin.app().p2p_node())
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
retval = true;
} catch (fc::exception &e) {
elog("Sending transaction for update deposit address operation failed with exception ${e}", ("e", e.what()));
retval = false;
}
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), op);
try {
trx.validate();
database.push_transaction(trx, database::validation_steps::skip_block_size_check);
if (plugin.app().p2p_node())
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
retval = true;
} catch (fc::exception &e) {
elog("Sending transaction for update deposit address operation failed with exception ${e}", ("e", e.what()));
retval = false;
}
}
}
return retval;
return retval;
});
return;
}

View file

@ -3,6 +3,7 @@
#include <fc/log/logger.hpp>
#include <graphene/chain/son_wallet_object.hpp>
#include <graphene/peerplays_sidechain/sidechain_net_handler_bitcoin.hpp>
#include <graphene/peerplays_sidechain/sidechain_net_handler_hive.hpp>
#include <graphene/peerplays_sidechain/sidechain_net_handler_peerplays.hpp>
namespace graphene { namespace peerplays_sidechain {
@ -26,6 +27,12 @@ bool sidechain_net_manager::create_handler(sidechain_type sidechain, const boost
ret_val = true;
break;
}
case sidechain_type::hive: {
std::unique_ptr<sidechain_net_handler> h = std::unique_ptr<sidechain_net_handler>(new sidechain_net_handler_hive(plugin, options));
net_handlers.push_back(std::move(h));
ret_val = true;
break;
}
case sidechain_type::peerplays: {
std::unique_ptr<sidechain_net_handler> h = std::unique_ptr<sidechain_net_handler>(new sidechain_net_handler_peerplays(plugin, options));
net_handlers.push_back(std::move(h));