From 5dcf3f9be38d7f4e686dd2490652a06e8ae6e5f1 Mon Sep 17 00:00:00 2001 From: Srdjan Obucina Date: Fri, 28 Feb 2020 01:04:50 +0100 Subject: [PATCH] Refactoring - Better exposure of sidechain private keys in sidechain handlers - Support non default Bitcoin wallets --- .../peerplays_sidechain_plugin.hpp | 1 - .../sidechain_net_handler.hpp | 3 ++ .../sidechain_net_handler_bitcoin.hpp | 28 +++++++++-------- .../sidechain_net_handler_peerplays.hpp | 4 +-- .../peerplays_sidechain_plugin.cpp | 31 ++++++------------- .../sidechain_net_handler.cpp | 8 +++++ .../sidechain_net_handler_bitcoin.cpp | 22 ++++++++----- 7 files changed, 52 insertions(+), 45 deletions(-) diff --git a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/peerplays_sidechain_plugin.hpp b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/peerplays_sidechain_plugin.hpp index bc1f6d21..80f77106 100644 --- a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/peerplays_sidechain_plugin.hpp +++ b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/peerplays_sidechain_plugin.hpp @@ -31,7 +31,6 @@ class peerplays_sidechain_plugin : public graphene::app::plugin son_id_type& get_current_son_id(); son_object get_son_object(son_id_type son_id); bool is_active_son(son_id_type son_id); - std::map& get_private_keys(); fc::ecc::private_key get_private_key(son_id_type son_id); fc::ecc::private_key get_private_key(chain::public_key_type public_key); }; diff --git a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler.hpp b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler.hpp index 52218427..8df08bcf 100644 --- a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler.hpp +++ b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler.hpp @@ -18,6 +18,7 @@ public: graphene::peerplays_sidechain::sidechain_type get_sidechain(); std::vector get_sidechain_deposit_addresses(); std::vector get_sidechain_withdraw_addresses(); + std::string get_private_key(std::string public_key); void sidechain_event_data_received(const sidechain_event_data& sed); void process_deposits(); @@ -32,6 +33,8 @@ protected: graphene::chain::database& database; graphene::peerplays_sidechain::sidechain_type sidechain; + std::map private_keys; + virtual std::string create_multisignature_wallet( const std::vector public_keys ) = 0; virtual std::string transfer( const std::string& from, const std::string& to, const uint64_t amount ) = 0; virtual std::string sign_transaction( const std::string& transaction ) = 0; 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 1ae195ba..197e329e 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 @@ -22,7 +22,7 @@ public: class bitcoin_rpc_client { public: - bitcoin_rpc_client( std::string _ip, uint32_t _rpc, std::string _user, std::string _password) ; + bitcoin_rpc_client( std::string _ip, uint32_t _rpc, std::string _user, std::string _password, std::string _wallet, std::string _wallet_password) ; bool connection_is_not_defined() const; std::string addmultisigaddress( const std::vector public_keys ); @@ -44,6 +44,8 @@ private: uint32_t rpc_port; std::string user; std::string password; + std::string wallet; + std::string wallet_password; fc::http::header authorization; }; @@ -78,6 +80,18 @@ public: void process_deposit(const son_wallet_deposit_object& swdo); void process_withdrawal(const son_wallet_withdraw_object& swwo); +private: + std::string ip; + uint32_t zmq_port; + uint32_t rpc_port; + std::string rpc_user; + std::string rpc_password; + std::string wallet; + std::string wallet_password; + + std::unique_ptr listener; + std::unique_ptr bitcoin_client; + std::string create_multisignature_wallet( const std::vector public_keys ); std::string transfer( const std::string& from, const std::string& to, const uint64_t amount ); std::string sign_transaction( const std::string& transaction ); @@ -87,18 +101,6 @@ public: 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); - -private: - std::string ip; - uint32_t zmq_port; - uint32_t rpc_port; - std::string rpc_user; - std::string rpc_password; - std::map _private_keys; - - std::unique_ptr listener; - std::unique_ptr bitcoin_client; - void handle_event( const std::string& event_data); std::vector extract_info_from_block( const std::string& _block ); }; diff --git a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler_peerplays.hpp b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler_peerplays.hpp index 9db3405a..213e9649 100644 --- a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler_peerplays.hpp +++ b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler_peerplays.hpp @@ -17,13 +17,13 @@ public: void process_deposit(const son_wallet_deposit_object& swdo); void process_withdrawal(const son_wallet_withdraw_object& swwo); +private: + std::string create_multisignature_wallet( const std::vector public_keys ); std::string transfer( const std::string& from, const std::string& to, const uint64_t amount ); std::string sign_transaction( const std::string& transaction ); std::string send_transaction( const std::string& transaction ); -private: - void on_applied_block(const signed_block& b); }; diff --git a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp index 3578dc6e..8496b55c 100644 --- a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp +++ b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp @@ -38,7 +38,6 @@ class peerplays_sidechain_plugin_impl son_id_type& get_current_son_id(); son_object get_son_object(son_id_type son_id); bool is_active_son(son_id_type son_id); - std::map& get_private_keys(); fc::ecc::private_key get_private_key(son_id_type son_id); fc::ecc::private_key get_private_key(chain::public_key_type public_key); @@ -63,7 +62,7 @@ class peerplays_sidechain_plugin_impl std::unique_ptr net_manager; std::set _sons; - std::map _private_keys; + std::map private_keys; fc::future _heartbeat_task; fc::future _son_processing_task; @@ -122,12 +121,11 @@ void peerplays_sidechain_plugin_impl::plugin_set_program_options( ("bitcoin-node-rpc-port", bpo::value()->default_value(22222), "RPC port of Bitcoin node") ("bitcoin-node-rpc-user", bpo::value()->default_value("1"), "Bitcoin RPC user") ("bitcoin-node-rpc-password", bpo::value()->default_value("1"), "Bitcoin RPC password") - ("bitcoin-address", bpo::value()->default_value("2N911a7smwDzUGARg8s7Q1ViizFCw6gWcbR"), "Bitcoin address") - ("bitcoin-public-key", bpo::value()->default_value("02d0f137e717fb3aab7aff99904001d49a0a636c5e1342f8927a4ba2eaee8e9772"), "Bitcoin public key") - ("bitcoin-private-key", bpo::value()->default_value("cVN31uC9sTEr392DLVUEjrtMgLA8Yb3fpYmTRj7bomTm6nn2ANPr"), "Bitcoin private key") - ("bitcoin-private-keys", bpo::value>()->composing()->multitoken()-> + ("bitcoin-wallet", bpo::value(), "Bitcoin wallet") + ("bitcoin-wallet-password", bpo::value(), "Bitcoin wallet password") + ("bitcoin-private-key", bpo::value>()->composing()->multitoken()-> DEFAULT_VALUE_VECTOR(std::make_pair("02d0f137e717fb3aab7aff99904001d49a0a636c5e1342f8927a4ba2eaee8e9772", "cVN31uC9sTEr392DLVUEjrtMgLA8Yb3fpYmTRj7bomTm6nn2ANPr")), - "Tuple of [Bitcoin PublicKey, Bitcoin Private key] (may specify multiple times)") + "Tuple of [Bitcoin public key, Bitcoin private key] (may specify multiple times)") ; cfg.add(cli); } @@ -166,7 +164,7 @@ void peerplays_sidechain_plugin_impl::plugin_initialize(const boost::program_opt FC_THROW("Invalid WIF-format private key ${key_string}", ("key_string", key_id_to_wif_pair.second)); } } - _private_keys[key_id_to_wif_pair.first] = *private_key; + private_keys[key_id_to_wif_pair.first] = *private_key; } } } else { @@ -181,7 +179,8 @@ void peerplays_sidechain_plugin_impl::plugin_initialize(const boost::program_opt 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-address" ) && options.count( "bitcoin-public-key" ) && options.count( "bitcoin-private-key" ); + options.count( "bitcoin-wallet" ) && options.count( "bitcoin-wallet-password" ) && + options.count( "bitcoin-private-key" ); if (config_ready_bitcoin) { net_manager->create_handler(sidechain_type::bitcoin, options); ilog("Bitcoin sidechain handler created"); @@ -274,11 +273,6 @@ bool peerplays_sidechain_plugin_impl::is_active_son(son_id_type son_id) return (it != active_son_ids.end()); } -std::map& peerplays_sidechain_plugin_impl::get_private_keys() -{ - return _private_keys; -} - fc::ecc::private_key peerplays_sidechain_plugin_impl::get_private_key(son_id_type son_id) { return get_private_key(get_son_object(son_id).signing_key); @@ -286,8 +280,8 @@ fc::ecc::private_key peerplays_sidechain_plugin_impl::get_private_key(son_id_typ fc::ecc::private_key peerplays_sidechain_plugin_impl::get_private_key(chain::public_key_type public_key) { - auto private_key_itr = _private_keys.find( public_key ); - if( private_key_itr != _private_keys.end() ) { + auto private_key_itr = private_keys.find( public_key ); + if( private_key_itr != private_keys.end() ) { return private_key_itr->second; } return {}; @@ -579,11 +573,6 @@ bool peerplays_sidechain_plugin::is_active_son(son_id_type son_id) return my->is_active_son(son_id); } -std::map& peerplays_sidechain_plugin::get_private_keys() -{ - return my->get_private_keys(); -} - fc::ecc::private_key peerplays_sidechain_plugin::get_private_key(son_id_type son_id) { return my->get_private_key(son_id); diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp index 9c193e10..10576b42 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp @@ -47,6 +47,14 @@ std::vector sidechain_net_handler::get_sidechain_withdraw_addresses return result; } +std::string sidechain_net_handler::get_private_key(std::string public_key) { + auto private_key_itr = private_keys.find( public_key ); + if( private_key_itr != private_keys.end() ) { + return private_key_itr->second; + } + return std::string(); +} + void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_data& sed) { ilog( "sidechain_event_data:" ); ilog( " timestamp: ${timestamp}", ( "timestamp", sed.timestamp ) ); diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp index b6652f7d..60e2356e 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp @@ -21,8 +21,8 @@ namespace graphene { namespace peerplays_sidechain { // ============================================================================= -bitcoin_rpc_client::bitcoin_rpc_client( std::string _ip, uint32_t _rpc, std::string _user, std::string _password ): - ip( _ip ), rpc_port( _rpc ), user( _user ), password( _password ) +bitcoin_rpc_client::bitcoin_rpc_client( std::string _ip, uint32_t _rpc, std::string _user, std::string _password, std::string _wallet, std::string _wallet_password ): + ip( _ip ), rpc_port( _rpc ), user( _user ), password( _password ), wallet( _wallet ), wallet_password( _wallet_password ) { authorization.key = "Authorization"; authorization.val = "Basic " + fc::base64_encode( user + ":" + password ); @@ -326,7 +326,11 @@ fc::http::reply bitcoin_rpc_client::send_post_request( std::string body ) fc::http::connection conn; conn.connect_to( fc::ip::endpoint( fc::ip::address( ip ), rpc_port ) ); - const auto url = "http://" + ip + ":" + std::to_string( rpc_port ); + std::string url = "http://" + ip + ":" + std::to_string( rpc_port ); + + if (wallet.length() > 0) { + url = url + "/wallet/" + wallet; + } return conn.request( "POST", url, body, fc::http::headers{authorization} ); } @@ -382,19 +386,21 @@ sidechain_net_handler_bitcoin::sidechain_net_handler_bitcoin(peerplays_sidechain rpc_port = options.at("bitcoin-node-rpc-port").as(); rpc_user = options.at("bitcoin-node-rpc-user").as(); rpc_password = options.at("bitcoin-node-rpc-password").as(); + wallet = options.at("bitcoin-wallet").as(); + wallet_password = options.at("bitcoin-wallet-password").as(); - if( options.count("bitcoin-private-keys") ) + if( options.count("bitcoin-private-key") ) { - const std::vector pub_priv_keys = options["bitcoin-private-keys"].as>(); + const std::vector pub_priv_keys = options["bitcoin-private-key"].as>(); for (const std::string& itr_key_pair : pub_priv_keys) { auto key_pair = graphene::app::dejsonify >(itr_key_pair, 5); - ilog("Public Key: ${public}", ("public", key_pair.first)); + ilog("Bitcoin 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; + private_keys[key_pair.first] = key_pair.second; } } @@ -407,7 +413,7 @@ sidechain_net_handler_bitcoin::sidechain_net_handler_bitcoin(peerplays_sidechain } listener = std::unique_ptr( new zmq_listener( ip, zmq_port ) ); - bitcoin_client = std::unique_ptr( new bitcoin_rpc_client( ip, rpc_port, rpc_user, rpc_password ) ); + bitcoin_client = std::unique_ptr( new bitcoin_rpc_client( ip, rpc_port, rpc_user, rpc_password, wallet, wallet_password ) ); listener->event_received.connect([this]( const std::string& event_data ) { std::thread( &sidechain_net_handler_bitcoin::handle_event, this, event_data ).detach();