From 0d1adde0a65735269181b749c3f2dd841f5771ac Mon Sep 17 00:00:00 2001 From: gladcow Date: Tue, 25 Feb 2020 16:55:52 +0300 Subject: [PATCH] Create weighted multisig address --- .../peerplays_sidechain/bitcoin_utils.cpp | 9 +++ .../peerplays_sidechain/bitcoin_utils.hpp | 1 + .../sidechain_net_handler_bitcoin.hpp | 1 + .../sidechain_net_handler_bitcoin.cpp | 81 ++++++++++--------- 4 files changed, 53 insertions(+), 39 deletions(-) diff --git a/libraries/plugins/peerplays_sidechain/bitcoin_utils.cpp b/libraries/plugins/peerplays_sidechain/bitcoin_utils.cpp index a11647de..51870311 100644 --- a/libraries/plugins/peerplays_sidechain/bitcoin_utils.cpp +++ b/libraries/plugins/peerplays_sidechain/bitcoin_utils.cpp @@ -677,4 +677,13 @@ bytes add_signatures_to_unsigned_tx(const bytes &unsigned_tx, const std::vector< return ret; } +std::string get_weighted_multisig_address(const std::vector > &public_keys) +{ + std::vector> key_data; + for(auto p: public_keys) + key_data.push_back(std::make_pair(fc::ecc::public_key::from_base58(p.first), p.second)); + bytes redeem_script = generate_redeem_script(key_data); + return p2wsh_address_from_redeem_script(redeem_script); +} + }} // namespace graphene::peerplays_sidechain diff --git a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/bitcoin_utils.hpp b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/bitcoin_utils.hpp index 9b2dc0c1..18adb3ca 100644 --- a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/bitcoin_utils.hpp +++ b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/bitcoin_utils.hpp @@ -13,6 +13,7 @@ enum bitcoin_network { bytes generate_redeem_script(std::vector> key_data); std::string p2wsh_address_from_redeem_script(const bytes &script, bitcoin_network network = mainnet); bytes lock_script_for_redeem_script(const bytes &script); +std::string get_weighted_multisig_address(const std::vector>& public_keys); std::vector signatures_for_raw_transaction(const bytes &unsigned_tx, std::vector in_amounts, 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 ec9689f6..30016f01 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 @@ -104,6 +104,7 @@ private: std::string sign_transaction(const std::string &transaction); std::string send_transaction(const std::string &transaction); std::string sign_and_send_transaction_with_wallet(const std::string &tx_json); + std::string create_weighted_multisignature_wallet( const std::vector>& public_keys ); std::string transfer_all_btc(const std::string &from_address, const std::string &to_address); std::string transfer_deposit_to_primary_wallet(const son_wallet_deposit_object &swdo); std::string transfer_withdrawal_from_primary_wallet(const son_wallet_withdraw_object &swwo); diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp index 7eaa4d44..a68b39be 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -615,53 +616,49 @@ void sidechain_net_handler_bitcoin::recreate_primary_wallet() { const chain::global_property_object &gpo = database.get_global_properties(); 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)); + vector> son_pubkeys_bitcoin; + for ( const son_info& si : active_sons ) { + son_pubkeys_bitcoin.push_back( + make_pair( + si.sidechain_public_keys.at(sidechain_type::bitcoin), + si.total_votes + ) + ); } - string reply_str = create_multisignature_wallet(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()) { + string address = create_weighted_multisignature_wallet(son_pubkeys_bitcoin); + bytes redeem_script = get_weighted_multisig_redeem_script(son_pubkeys_bitcoin); - std::stringstream res; - boost::property_tree::json_parser::write_json(res, active_pw_pt.get_child("result")); + ilog(address); - son_wallet_update_operation op; - op.payer = GRAPHENE_SON_ACCOUNT; - op.son_wallet_id = (*active_sw).id; - op.sidechain = sidechain_type::bitcoin; - op.address = res.str(); + son_wallet_update_operation op; + op.payer = GRAPHENE_SON_ACCOUNT; + op.son_wallet_id = (*active_sw).id; + op.sidechain = sidechain_type::bitcoin; + op.address = address; - proposal_create_operation proposal_op; - proposal_op.fee_paying_account = plugin.get_son_object(plugin.get_current_son_id()).son_account; - proposal_op.proposed_ops.emplace_back(op_wrapper(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); + proposal_create_operation proposal_op; + proposal_op.fee_paying_account = plugin.get_son_object(plugin.get_current_son_id()).son_account; + proposal_op.proposed_ops.emplace_back( op_wrapper( 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 { - 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)); - } catch (fc::exception e) { - ilog("sidechain_net_handler: sending proposal for son wallet update operation failed with exception ${e}", ("e", e.what())); - return; - } + signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op); + try { + 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)); + } catch(fc::exception e){ + ilog("sidechain_net_handler: sending proposal for son wallet update operation failed with exception ${e}",("e", e.what())); + return; + } - const auto &prev_sw = std::next(active_sw); - if (prev_sw != swi.rend()) { - std::stringstream prev_sw_ss(prev_sw->addresses.at(sidechain_type::bitcoin)); - boost::property_tree::ptree prev_sw_pt; - boost::property_tree::read_json(prev_sw_ss, prev_sw_pt); + const auto &prev_sw = std::next(active_sw); + if (prev_sw != swi.rend()) { + std::string prev_pw_address = prev_sw->addresses.at(sidechain_type::bitcoin); + std::string active_pw_address = address; - std::string active_pw_address = active_pw_pt.get_child("result").get("address"); - std::string prev_pw_address = prev_sw_pt.get("address"); - - transfer_all_btc(prev_pw_address, active_pw_address); - } + transfer_all_btc(prev_pw_address, active_pw_address); } } } @@ -679,6 +676,12 @@ std::string sidechain_net_handler_bitcoin::create_multisignature_wallet(const st return bitcoin_client->addmultisigaddress(public_keys); } +std::string sidechain_net_handler_bitcoin::create_weighted_multisignature_wallet(const std::vector> &public_keys) { + string address = get_weighted_multisig_address(public_keys); + bitcoin_client->importaddress(address); + return address; +} + std::string sidechain_net_handler_bitcoin::transfer(const std::string &from, const std::string &to, const uint64_t amount) { return ""; }