diff --git a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler_bitcoin.hpp b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler_bitcoin.hpp index 7182f117..a9d52d23 100644 --- a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler_bitcoin.hpp +++ b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler_bitcoin.hpp @@ -23,6 +23,7 @@ public: std::string addmultisigaddress(const uint32_t nrequired, const std::vector public_keys); std::string combinepsbt(const vector &psbts); + std::string createmultisig(const uint32_t nrequired, const std::vector public_keys); std::string createpsbt(const std::vector &ins, const fc::flat_map outs); std::string createrawtransaction(const std::vector &ins, const fc::flat_map outs); std::string createwallet(const std::string &wallet_name); diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp index ca8a3637..13e7b2bf 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp @@ -211,7 +211,7 @@ void sidechain_net_handler::process_proposals() { switch (op_idx_0) { case chain::operation::tag::value: { - should_process = true; + should_process = (op_obj_idx_0.get().sidechain == sidechain); break; } @@ -243,9 +243,9 @@ void sidechain_net_handler::process_proposals() { default: should_process = false; - ilog("=================================================="); - ilog("Proposal not processed ${po}", ("po", *po)); - ilog("=================================================="); + elog("=================================================="); + elog("Proposal not processed ${po}", ("po", *po)); + elog("=================================================="); } if (should_process) { diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp index 93018734..381a848e 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp @@ -45,9 +45,9 @@ std::string bitcoin_rpc_client::addmultisigaddress(const uint32_t nrequired, con pubkeys = pubkeys + std::string("\"") + pubkey + std::string("\""); } params = params + pubkeys + std::string("]"); - body = body + params + std::string("] }"); + body = body + params + std::string(", null, \"p2sh-segwit\"] }"); - const auto reply = send_post_request(body); + const auto reply = send_post_request(body, true); if (reply.body.empty()) { wlog("Bitcoin RPC call ${function} failed", ("function", __FUNCTION__)); @@ -102,6 +102,41 @@ std::string bitcoin_rpc_client::combinepsbt(const vector &psbts) { return ""; } +std::string bitcoin_rpc_client::createmultisig(const uint32_t nrequired, const std::vector public_keys) { + std::string body = std::string("{\"jsonrpc\": \"1.0\", \"id\":\"createmultisig\", " + "\"method\": \"createmultisig\", \"params\": ["); + std::string params = std::to_string(nrequired) + ", ["; + std::string pubkeys = ""; + for (std::string pubkey : public_keys) { + if (!pubkeys.empty()) { + pubkeys = pubkeys + ","; + } + pubkeys = pubkeys + std::string("\"") + pubkey + std::string("\""); + } + params = params + pubkeys + std::string("]"); + body = body + params + std::string(", \"p2sh-segwit\" ] }"); + + const auto reply = send_post_request(body, true); + + if (reply.body.empty()) { + wlog("Bitcoin 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("Bitcoin RPC call ${function} with body ${body} failed with reply '${msg}'", ("function", __FUNCTION__)("body", body)("msg", ss.str())); + } + return ""; +} + std::string bitcoin_rpc_client::createpsbt(const std::vector &ins, const fc::flat_map outs) { std::string body("{\"jsonrpc\": \"1.0\", \"id\":\"createpsbt\", " "\"method\": \"createpsbt\", \"params\": ["); @@ -894,7 +929,42 @@ bool sidechain_net_handler_bitcoin::process_proposal(const proposal_object &po) switch (op_idx_0) { case chain::operation::tag::value: { - should_approve = true; + son_wallet_id_type swo_id = op_obj_idx_0.get().son_wallet_id; + const auto &idx = database.get_index_type().indices().get(); + const auto swo = idx.find(swo_id); + if (swo != idx.end()) { + auto active_sons = gpo.active_sons; + vector wallet_sons = swo->sons; + + bool son_sets_equal = (active_sons.size() == wallet_sons.size()); + + if (son_sets_equal) { + for (size_t i = 0; i < active_sons.size(); i++) { + son_sets_equal = son_sets_equal && active_sons.at(i) == wallet_sons.at(i); + } + } + + if (son_sets_equal) { + auto active_sons = gpo.active_sons; + vector son_pubkeys_bitcoin; + for (const son_info &si : active_sons) { + son_pubkeys_bitcoin.push_back(si.sidechain_public_keys.at(sidechain_type::bitcoin)); + } + + uint32_t nrequired = son_pubkeys_bitcoin.size() * 2 / 3 + 1; + string reply_str = bitcoin_client->createmultisig(nrequired, son_pubkeys_bitcoin); + + std::stringstream active_pw_ss(reply_str); + boost::property_tree::ptree active_pw_pt; + boost::property_tree::read_json(active_pw_ss, active_pw_pt); + if (active_pw_pt.count("error") && active_pw_pt.get_child("error").empty()) { + std::stringstream res; + boost::property_tree::json_parser::write_json(res, active_pw_pt.get_child("result")); + + should_approve = (op_obj_idx_0.get().address == res.str()); + } + } + } break; } @@ -954,6 +1024,9 @@ bool sidechain_net_handler_bitcoin::process_proposal(const proposal_object &po) default: should_approve = false; + elog("=================================================="); + elog("Proposal not considered for approval ${po}", ("po", po)); + elog("=================================================="); } return should_approve; diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_peerplays.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_peerplays.cpp index 42d1757d..c9c47e4b 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_peerplays.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_peerplays.cpp @@ -128,6 +128,9 @@ bool sidechain_net_handler_peerplays::process_proposal(const proposal_object &po default: should_approve = false; + elog("=================================================="); + elog("Proposal not considered for approval ${po}", ("po", po)); + elog("=================================================="); } return should_approve;