Refactor libbitcoin client

This commit is contained in:
Vlad Dobromyslov 2023-11-01 10:00:28 +03:00
parent 41f53b3196
commit d76fd8d012
4 changed files with 56 additions and 69 deletions

View file

@ -3,7 +3,6 @@
#include <system_error> #include <system_error>
#include <bitcoin/explorer/callback_state.hpp>
#include <bitcoin/explorer/config/transaction.hpp> #include <bitcoin/explorer/config/transaction.hpp>
#include <bitcoin/system/config/hash256.hpp> #include <bitcoin/system/config/hash256.hpp>
@ -14,7 +13,7 @@
namespace graphene { namespace peerplays_sidechain { namespace graphene { namespace peerplays_sidechain {
libbitcoin_client::libbitcoin_client(std::string url) : libbitcoin_client::libbitcoin_client(const std::string &url) :
obelisk_client(LIBBITCOIN_SERVER_TIMEOUT, LIBBITCOIN_SERVER_RETRIES) { obelisk_client(LIBBITCOIN_SERVER_TIMEOUT, LIBBITCOIN_SERVER_RETRIES) {
std::string reg_expr = "^((?P<Protocol>https|http|tcp):\\/\\/)?(?P<Host>[a-zA-Z0-9\\-\\.]+)(:(?P<Port>\\d{1,5}))?(?P<Target>\\/.+)?"; std::string reg_expr = "^((?P<Protocol>https|http|tcp):\\/\\/)?(?P<Host>[a-zA-Z0-9\\-\\.]+)(:(?P<Port>\\d{1,5}))?(?P<Target>\\/.+)?";
@ -51,8 +50,6 @@ libbitcoin_client::libbitcoin_client(std::string url) :
if (!obelisk_client.connect(connection)) { if (!obelisk_client.connect(connection)) {
elog("Can't connect libbitcoin for url: ${url}", ("url", final_url)); elog("Can't connect libbitcoin for url: ${url}", ("url", final_url));
} }
is_connected = true;
} }
libbitcoin_client::~libbitcoin_client() { libbitcoin_client::~libbitcoin_client() {
@ -65,7 +62,7 @@ libbitcoin_client::~libbitcoin_client() {
sub_thr.detach(); sub_thr.detach();
} }
std::string libbitcoin_client::send_transaction(std::string tx) { std::string libbitcoin_client::send_transaction(const std::string &tx) {
std::string res; std::string res;
@ -89,7 +86,7 @@ std::string libbitcoin_client::send_transaction(std::string tx) {
return res; return res;
} }
bool libbitcoin_client::get_transaction(const std::string tx, libbitcoin::chain::transaction &trx) { bool libbitcoin_client::get_transaction(const std::string &tx, libbitcoin::chain::transaction &trx) {
bool result = false; bool result = false;
auto error_handler = [&](const std::error_code &ec) { auto error_handler = [&](const std::error_code &ec) {
elog("error on fetch_trx_by_hash: ${hash} ${error_code}", ("hash", tx)("error_code", ec.message())); elog("error on fetch_trx_by_hash: ${hash} ${error_code}", ("hash", tx)("error_code", ec.message()));
@ -111,7 +108,7 @@ bool libbitcoin_client::get_transaction(const std::string tx, libbitcoin::chain:
return result; return result;
} }
libbitcoin::chain::output::list libbitcoin_client::get_transaction_outs(std::string tx_id, std::string &tx_hash, uint32_t &confirmitions) { libbitcoin::chain::output::list libbitcoin_client::get_transaction_outs(const std::string &tx_id, std::string &tx_hash, uint32_t &confirmitions) {
libbitcoin::chain::output::list outs; libbitcoin::chain::output::list outs;
libbitcoin::chain::transaction trx; libbitcoin::chain::transaction trx;
@ -127,7 +124,7 @@ libbitcoin::chain::output::list libbitcoin_client::get_transaction_outs(std::str
return outs; return outs;
} }
std::vector<list_unspent_replay> libbitcoin_client::listunspent(std::string address, double amount) { std::vector<list_unspent_replay> libbitcoin_client::listunspent(const std::string &address, double amount) {
std::vector<list_unspent_replay> result; std::vector<list_unspent_replay> result;
auto error_handler = [&](const std::error_code &ec) { auto error_handler = [&](const std::error_code &ec) {
@ -180,7 +177,7 @@ bool libbitcoin_client::get_is_test_net() {
return is_test_net; return is_test_net;
} }
uint64_t libbitcoin_client::get_fee_from_trx(libbitcoin::chain::transaction trx) { uint64_t libbitcoin_client::get_fee_from_trx(const libbitcoin::chain::transaction &trx) {
bool general_fee_est_error = false; bool general_fee_est_error = false;
if (trx.is_coinbase()) { if (trx.is_coinbase()) {
@ -229,7 +226,7 @@ uint64_t libbitcoin_client::get_fee_from_trx(libbitcoin::chain::transaction trx)
} }
} }
uint64_t libbitcoin_client::get_average_fee_from_trxs(std::vector<libbitcoin::chain::transaction> trx_list) { uint64_t libbitcoin_client::get_average_fee_from_trxs(const std::vector<libbitcoin::chain::transaction> &trx_list) {
std::vector<uint64_t> fee_per_trxs; std::vector<uint64_t> fee_per_trxs;
for (auto &trx : trx_list) { for (auto &trx : trx_list) {
@ -253,7 +250,7 @@ uint64_t libbitcoin_client::get_average_fee_from_trxs(std::vector<libbitcoin::ch
return average_estimated_fee; return average_estimated_fee;
} }
void libbitcoin_client::subscribe_to_address(const std::string address_str, address_update_handler address_updated_callback_handler, void libbitcoin_client::subscribe_to_address(const std::string &address_str, address_update_handler address_updated_callback_handler,
subscription_expired_handler subcription_expired_callback_handler) { subscription_expired_handler subcription_expired_callback_handler) {
subscription_add = address_str; subscription_add = address_str;

View file

@ -20,14 +20,8 @@
namespace graphene { namespace peerplays_sidechain { namespace graphene { namespace peerplays_sidechain {
typedef std::function<void(const libbitcoin::chain::block &)> using address_update_handler = std::function<void(const libbitcoin::chain::transaction &trx, const bool &is_test_net)>;
block_update_handler; using subscription_expired_handler = std::function<void(const std::string &)>;
typedef std::function<void(const libbitcoin::chain::transaction &trx, const bool &is_test_net)>
address_update_handler;
typedef std::function<void(const std::string &)>
subscription_expired_handler;
struct list_unspent_replay { struct list_unspent_replay {
std::string hash; std::string hash;
@ -37,16 +31,16 @@ struct list_unspent_replay {
class libbitcoin_client { class libbitcoin_client {
public: public:
libbitcoin_client(std::string url); explicit libbitcoin_client(const std::string &url);
~libbitcoin_client(); ~libbitcoin_client();
std::string send_transaction(const std::string tx); std::string send_transaction(const std::string &tx);
bool get_transaction(const std::string tx, libbitcoin::chain::transaction &trx); bool get_transaction(const std::string &tx, libbitcoin::chain::transaction &trx);
libbitcoin::chain::output::list get_transaction_outs(std::string tx_id, std::string &tx_hash, uint32_t &confirmitions); libbitcoin::chain::output::list get_transaction_outs(const std::string &tx_id, std::string &tx_hash, uint32_t &confirmitions);
std::vector<list_unspent_replay> listunspent(std::string address, double amount); std::vector<list_unspent_replay> listunspent(const std::string &address, double amount);
uint64_t get_average_fee_from_trxs(std::vector<libbitcoin::chain::transaction> trx_list); uint64_t get_average_fee_from_trxs(const std::vector<libbitcoin::chain::transaction> &trx_list);
uint64_t get_fee_from_trx(libbitcoin::chain::transaction trx); uint64_t get_fee_from_trx(const libbitcoin::chain::transaction &trx);
bool get_is_test_net(); bool get_is_test_net();
void subscribe_to_address(const std::string address_str, address_update_handler address_updated_callback_handler, void subscribe_to_address(const std::string &address_str, address_update_handler address_updated_callback_handler,
subscription_expired_handler subcription_expired_callback_handler); subscription_expired_handler subcription_expired_callback_handler);
bool is_target_trxs_pool_empty(); bool is_target_trxs_pool_empty();
@ -69,7 +63,6 @@ private:
std::mutex trxs_pool_mutex; std::mutex trxs_pool_mutex;
std::condition_variable poller_transacion_done; std::condition_variable poller_transacion_done;
bool is_connected = false;
int16_t is_test_net = -1; int16_t is_test_net = -1;
std::thread sub_thr; std::thread sub_thr;
std::thread poller_trx_thr; std::thread poller_trx_thr;

View file

@ -65,6 +65,7 @@ public:
std::string label; std::string label;
}; };
virtual ~bitcoin_client_base() = default;
virtual uint64_t estimatesmartfee(uint16_t conf_target = 1) = 0; virtual uint64_t estimatesmartfee(uint16_t conf_target = 1) = 0;
virtual std::vector<info_for_vin> getblock(const block_data &block, int32_t verbosity = 2) = 0; virtual std::vector<info_for_vin> getblock(const block_data &block, int32_t verbosity = 2) = 0;
virtual btc_tx getrawtransaction(const std::string &txid, const bool verbose = false) = 0; virtual btc_tx getrawtransaction(const std::string &txid, const bool verbose = false) = 0;
@ -72,9 +73,7 @@ public:
virtual std::string getblockchaininfo() = 0; virtual std::string getblockchaininfo() = 0;
virtual std::vector<btc_txout> listunspent_by_address_and_amount(const std::string &address, double transfer_amount, const uint32_t minconf = 1, const uint32_t maxconf = 9999999) = 0; virtual std::vector<btc_txout> listunspent_by_address_and_amount(const std::string &address, double transfer_amount, const uint32_t minconf = 1, const uint32_t maxconf = 9999999) = 0;
virtual std::string sendrawtransaction(const std::string &tx_hex) = 0; virtual std::string sendrawtransaction(const std::string &tx_hex) = 0;
virtual void importmulti(const std::vector<multi_params> &address_or_script_array, const bool rescan = true) { virtual void importmulti(const std::vector<multi_params> &address_or_script_array, const bool rescan = true){};
;
};
virtual std::string loadwallet(const std::string &filename) { virtual std::string loadwallet(const std::string &filename) {
return ""; return "";
}; };
@ -102,20 +101,20 @@ public:
public: public:
bitcoin_rpc_client(const std::vector<rpc_credentials> &_credentials, bool _debug_rpc_calls, bool _simulate_connection_reselection); bitcoin_rpc_client(const std::vector<rpc_credentials> &_credentials, bool _debug_rpc_calls, bool _simulate_connection_reselection);
uint64_t estimatesmartfee(uint16_t conf_target = 1); uint64_t estimatesmartfee(uint16_t conf_target = 1) final;
std::vector<info_for_vin> getblock(const block_data &block, int32_t verbosity = 2); std::vector<info_for_vin> getblock(const block_data &block, int32_t verbosity = 2);
btc_tx getrawtransaction(const std::string &txid, const bool verbose = false); btc_tx getrawtransaction(const std::string &txid, const bool verbose = false) final;
void getnetworkinfo(); void getnetworkinfo() final;
std::string getblockchaininfo(); std::string getblockchaininfo() final;
void importmulti(const std::vector<multi_params> &address_or_script_array, const bool rescan = true); void importmulti(const std::vector<multi_params> &address_or_script_array, const bool rescan = true) final;
std::vector<btc_txout> listunspent(const uint32_t minconf = 1, const uint32_t maxconf = 9999999); std::vector<btc_txout> listunspent(const uint32_t minconf = 1, const uint32_t maxconf = 9999999);
std::vector<btc_txout> listunspent_by_address_and_amount(const std::string &address, double transfer_amount, const uint32_t minconf = 1, const uint32_t maxconf = 9999999); std::vector<btc_txout> listunspent_by_address_and_amount(const std::string &address, double transfer_amount, const uint32_t minconf = 1, const uint32_t maxconf = 9999999) final;
std::string loadwallet(const std::string &filename); std::string loadwallet(const std::string &filename) final;
std::string sendrawtransaction(const std::string &tx_hex); std::string sendrawtransaction(const std::string &tx_hex) final;
std::string walletlock(); std::string walletlock() final;
bool walletpassphrase(const std::string &passphrase, uint32_t timeout = 60); bool walletpassphrase(const std::string &passphrase, uint32_t timeout = 60) final;
virtual uint64_t ping(rpc_connection &conn) const override; uint64_t ping(rpc_connection &conn) const final;
private: private:
std::string ip; std::string ip;
@ -128,14 +127,14 @@ private:
class bitcoin_libbitcoin_client : public bitcoin_client_base, public libbitcoin_client { class bitcoin_libbitcoin_client : public bitcoin_client_base, public libbitcoin_client {
public: public:
bitcoin_libbitcoin_client(std::string url); explicit bitcoin_libbitcoin_client(const std::string &url);
uint64_t estimatesmartfee(uint16_t conf_target = 1); uint64_t estimatesmartfee(uint16_t conf_target = 1) final;
std::vector<info_for_vin> getblock(const block_data &block, int32_t verbosity = 2); std::vector<info_for_vin> getblock(const block_data &block, int32_t verbosity = 2);
btc_tx getrawtransaction(const std::string &txid, const bool verbose = false); btc_tx getrawtransaction(const std::string &txid, const bool verbose = false) final;
void getnetworkinfo(); void getnetworkinfo() final;
std::string getblockchaininfo(); std::string getblockchaininfo() final;
std::vector<btc_txout> listunspent_by_address_and_amount(const std::string &address, double transfer_amount, const uint32_t minconf = 1, const uint32_t maxconf = 9999999); std::vector<btc_txout> listunspent_by_address_and_amount(const std::string &address, double transfer_amount, const uint32_t minconf = 1, const uint32_t maxconf = 9999999) final;
std::string sendrawtransaction(const std::string &tx_hex); std::string sendrawtransaction(const std::string &tx_hex) final;
private: private:
bool is_test_net = false; bool is_test_net = false;
@ -147,13 +146,11 @@ private:
class zmq_listener_base { class zmq_listener_base {
public: public:
virtual ~zmq_listener_base(){}; virtual ~zmq_listener_base() = default;
zmq_listener_base(std::string _ip, uint32_t _block_zmq_port, uint32_t _trx_zmq_port = 0) { zmq_listener_base(const std::string &_ip, uint32_t _block_zmq_port, uint32_t _trx_zmq_port = 0) :
ip = _ip; ip(_ip),
block_zmq_port = _block_zmq_port; block_zmq_port(_block_zmq_port),
trx_zmq_port = _trx_zmq_port; trx_zmq_port(_trx_zmq_port){};
stopped = false;
};
virtual void start() = 0; virtual void start() = 0;
boost::signals2::signal<void(const block_data &)> block_event_received; boost::signals2::signal<void(const block_data &)> block_event_received;
boost::signals2::signal<void(const libbitcoin::chain::transaction &)> trx_event_received; boost::signals2::signal<void(const libbitcoin::chain::transaction &)> trx_event_received;
@ -162,16 +159,16 @@ protected:
std::string ip; std::string ip;
uint32_t block_zmq_port; uint32_t block_zmq_port;
uint32_t trx_zmq_port; uint32_t trx_zmq_port;
std::atomic_bool stopped; std::atomic_bool stopped{false};
std::thread block_thr; std::thread block_thr;
std::thread trx_thr; std::thread trx_thr;
}; };
class zmq_listener : public zmq_listener_base { class zmq_listener : public zmq_listener_base {
public: public:
zmq_listener(std::string _ip, uint32_t _block_zmq_port, uint32_t _trx_zmq_port = 0); zmq_listener(const std::string &_ip, uint32_t _block_zmq_port, uint32_t _trx_zmq_port = 0);
virtual ~zmq_listener(); ~zmq_listener() final;
void start(); void start() final;
private: private:
void handle_zmq(); void handle_zmq();
@ -183,9 +180,9 @@ private:
class zmq_listener_libbitcoin : public zmq_listener_base { class zmq_listener_libbitcoin : public zmq_listener_base {
public: public:
zmq_listener_libbitcoin(std::string _ip, uint32_t _block_zmq_port = 9093, uint32_t _trx_zmq_port = 9094); zmq_listener_libbitcoin(const std::string &_ip, uint32_t _block_zmq_port = 9093, uint32_t _trx_zmq_port = 9094);
virtual ~zmq_listener_libbitcoin(); ~zmq_listener_libbitcoin() final;
void start(); void start() final;
private: private:
void handle_block(); void handle_block();
@ -234,7 +231,7 @@ private:
uint32_t bitcoin_major_version; uint32_t bitcoin_major_version;
std::mutex event_handler_mutex; std::mutex event_handler_mutex;
typedef std::lock_guard<decltype(event_handler_mutex)> scoped_lock; using scoped_lock = std::lock_guard<decltype(event_handler_mutex)>;
std::string create_primary_wallet_address(const std::vector<son_sidechain_info> &son_pubkeys); std::string create_primary_wallet_address(const std::vector<son_sidechain_info> &son_pubkeys);
@ -246,7 +243,7 @@ private:
std::string sign_transaction(const sidechain_transaction_object &sto); std::string sign_transaction(const sidechain_transaction_object &sto);
std::string send_transaction(const sidechain_transaction_object &sto); std::string send_transaction(const sidechain_transaction_object &sto);
void extract_deposit(const std::vector<info_for_vin> vins); void extract_deposit(const std::vector<info_for_vin> &vins);
void block_handle_event(const block_data &event_data); void block_handle_event(const block_data &event_data);
void subscribe_address_thread(); void subscribe_address_thread();
void trx_handle_event(const libbitcoin::chain::transaction &event_data); void trx_handle_event(const libbitcoin::chain::transaction &event_data);

View file

@ -333,7 +333,7 @@ bool bitcoin_rpc_client::walletpassphrase(const std::string &passphrase, uint32_
else else
return true; return true;
} }
bitcoin_libbitcoin_client::bitcoin_libbitcoin_client(std::string url) : bitcoin_libbitcoin_client::bitcoin_libbitcoin_client(const std::string &url) :
libbitcoin_client(url) { libbitcoin_client(url) {
estimate_fee_ext = std::unique_ptr<estimate_fee_external>(new estimate_fee_external()); estimate_fee_ext = std::unique_ptr<estimate_fee_external>(new estimate_fee_external());
@ -508,7 +508,7 @@ uint64_t bitcoin_rpc_client::ping(rpc_connection &conn) const {
// ============================================================================= // =============================================================================
zmq_listener::zmq_listener(std::string _ip, uint32_t _zmq_block_port, uint32_t _zmq_trx_port) : zmq_listener::zmq_listener(const std::string &_ip, uint32_t _zmq_block_port, uint32_t _zmq_trx_port) :
zmq_listener_base(_ip, _zmq_block_port, _zmq_trx_port), zmq_listener_base(_ip, _zmq_block_port, _zmq_trx_port),
ctx(1), ctx(1),
socket(ctx, ZMQ_SUB) { socket(ctx, ZMQ_SUB) {
@ -578,7 +578,7 @@ void zmq_listener::handle_zmq() {
// ============================================================================= // =============================================================================
zmq_listener_libbitcoin::zmq_listener_libbitcoin(std::string _ip, uint32_t _block_zmq_port, uint32_t _trx_zmq_port) : zmq_listener_libbitcoin::zmq_listener_libbitcoin(const std::string &_ip, uint32_t _block_zmq_port, uint32_t _trx_zmq_port) :
zmq_listener_base(_ip, _block_zmq_port, _trx_zmq_port), zmq_listener_base(_ip, _block_zmq_port, _trx_zmq_port),
block_socket(block_context, libbitcoin::protocol::zmq::socket::role::subscriber), block_socket(block_context, libbitcoin::protocol::zmq::socket::role::subscriber),
trx_socket(trx_context, libbitcoin::protocol::zmq::socket::role::subscriber) { trx_socket(trx_context, libbitcoin::protocol::zmq::socket::role::subscriber) {
@ -1736,7 +1736,7 @@ void sidechain_net_handler_bitcoin::trx_event(const libbitcoin::chain::transacti
extract_deposit(result); extract_deposit(result);
} }
void sidechain_net_handler_bitcoin::extract_deposit(const std::vector<info_for_vin> vins) { void sidechain_net_handler_bitcoin::extract_deposit(const std::vector<info_for_vin> &vins) {
const auto &sidechain_addresses_idx = database.get_index_type<sidechain_address_index>().indices().get<by_sidechain_and_deposit_address_and_expires>(); const auto &sidechain_addresses_idx = database.get_index_type<sidechain_address_index>().indices().get<by_sidechain_and_deposit_address_and_expires>();
for (const auto &v : vins) { for (const auto &v : vins) {
// !!! EXTRACT DEPOSIT ADDRESS FROM SIDECHAIN ADDRESS OBJECT // !!! EXTRACT DEPOSIT ADDRESS FROM SIDECHAIN ADDRESS OBJECT