peerplays_migrated/libraries/plugins/peerplays_sidechain/bitcoin/libbitcoin_client.cpp

156 lines
4.9 KiB
C++
Raw Normal View History

2022-09-06 12:12:01 +00:00
#include <graphene/peerplays_sidechain/bitcoin/libbitcoin_client.hpp>
#include <system_error>
#include <bitcoin/explorer/config/transaction.hpp>
2022-09-19 23:06:33 +00:00
#include <bitcoin/system/config/hash256.hpp>
#include <boost/xpressive/xpressive.hpp>
#include <fc/crypto/hex.hpp>
2022-09-19 23:06:33 +00:00
#include <fc/log/logger.hpp>
2022-09-06 12:12:01 +00:00
namespace graphene { namespace peerplays_sidechain {
2022-09-19 23:06:33 +00:00
libbitcoin_client::libbitcoin_client(std::string url) :
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>\\/.+)?";
boost::xpressive::sregex sr = boost::xpressive::sregex::compile(reg_expr);
boost::xpressive::smatch sm;
if (boost::xpressive::regex_search(url, sm, sr)) {
protocol = sm["Protocol"];
if (protocol.empty()) {
protocol = "tcp";
}
host = sm["Host"];
if (host.empty()) {
host + "localhost";
}
port = sm["Port"];
if (port.empty()) {
port = "9091";
}
}
uint16_t port_num = std::stoi(port);
std::string final_url = protocol + "://" + host;
libbitcoin::config::endpoint address(final_url, port_num);
2022-09-06 12:12:01 +00:00
libbitcoin::client::connection_type connection;
2022-09-19 23:06:33 +00:00
connection.retries = LIBBITCOIN_SERVER_RETRIES;
connection.server = address;
2022-09-06 12:12:01 +00:00
if (!obelisk_client.connect(connection)) {
2022-09-19 23:06:33 +00:00
elog("Can't connect libbitcoin for url: ${url}", ("url", final_url));
2022-09-06 12:12:01 +00:00
}
2022-09-19 23:06:33 +00:00
is_connected = true;
2022-09-06 12:12:01 +00:00
}
2022-09-19 23:06:33 +00:00
std::string libbitcoin_client::send_transaction(std::string tx) {
std::string res;
2022-09-06 12:12:01 +00:00
auto error_handler = [&](const std::error_code &ec) {
elog("error on sending bitcoin transaction ${error_code}", ("error_code", ec.message()));
};
auto result_handler = [&](libbitcoin::code result_code) {
ilog("result code on sending transaction ${result_code}", ("result_code", result_code.message()));
2022-09-19 23:06:33 +00:00
res = std::to_string(result_code.value());
};
libbitcoin::explorer::config::transaction transaction(tx);
2022-09-06 12:12:01 +00:00
libbitcoin::chain::transaction trx;
2022-09-06 12:12:01 +00:00
2022-09-19 23:06:33 +00:00
// This validates the tx, submits it to local tx pool, and notifies peers.
obelisk_client.transaction_pool_broadcast(error_handler, result_handler, transaction);
obelisk_client.wait();
return res;
2022-09-06 12:12:01 +00:00
}
2022-09-19 23:06:33 +00:00
libbitcoin::chain::output::list libbitcoin_client::get_transaction(std::string tx_id, std::string &tx_hash, uint32_t &confirmitions) {
libbitcoin::chain::output::list outs;
2022-09-06 12:12:01 +00:00
auto error_handler = [&](const std::error_code &ec) {
2022-09-19 23:06:33 +00:00
elog("error on fetch_trx_by_hash: ${hash} ${error_code}", ("hash", tx_id)("error_code", ec.message()));
2022-09-06 12:12:01 +00:00
};
2022-09-19 23:06:33 +00:00
auto transaction_handler = [&](const libbitcoin::chain::transaction &tx_handler) {
tx_hash = libbitcoin::config::hash256(tx_handler.hash(false)).to_string();
// TODO try to find this value (confirmitions)
confirmitions = 1;
outs = tx_handler.outputs();
2022-09-06 12:12:01 +00:00
};
2022-09-19 23:06:33 +00:00
libbitcoin::hash_digest hash = libbitcoin::config::hash256(tx_id);
2022-09-06 12:12:01 +00:00
2022-09-19 23:06:33 +00:00
// obelisk_client.blockchain_fetch_transaction (error_handler, transaction_handler,hash);
obelisk_client.blockchain_fetch_transaction2(error_handler, transaction_handler, hash);
2022-09-06 12:12:01 +00:00
obelisk_client.wait();
2022-09-19 23:06:33 +00:00
return outs;
2022-09-06 12:12:01 +00:00
}
2022-09-19 23:06:33 +00:00
std::vector<list_unspent_replay> libbitcoin_client::listunspent(std::string address, double amount) {
2022-09-06 12:12:01 +00:00
std::vector<list_unspent_replay> result;
auto error_handler = [&](const std::error_code &ec) {
elog("error on list_unspent ${error_code}", ("error_code", ec.message()));
2022-09-06 12:12:01 +00:00
};
auto replay_handler = [&](const libbitcoin::chain::points_value &points) {
for (auto &point : points.points) {
list_unspent_replay output;
output.hash = libbitcoin::config::hash256(point.hash()).to_string();
output.value = point.value();
output.index = point.index();
result.emplace_back(output);
}
};
libbitcoin::wallet::payment_address payment_address(address);
2022-09-19 23:06:33 +00:00
uint64_t satoshi = 100000000 * amount;
2022-09-06 12:12:01 +00:00
obelisk_client.blockchain_fetch_unspent_outputs(error_handler,
2022-09-19 23:06:33 +00:00
replay_handler, payment_address, satoshi, libbitcoin::wallet::select_outputs::algorithm::individual);
obelisk_client.wait();
return result;
}
bool libbitcoin_client::get_is_test_net() {
bool result = false;
auto error_handler = [&](const std::error_code &ec) {
elog("error on fetching genesis block ${error_code}", ("error_code", ec.message()));
};
auto block_header_handler = [&](const libbitcoin::chain::header &block_header) {
std::string hash_str = libbitcoin::config::hash256(block_header.hash()).to_string();
if (hash_str == GENESIS_TESTNET_HASH || hash_str == GENESIS_REGTEST_HASH) {
result = true;
}
};
obelisk_client.blockchain_fetch_block_header(error_handler, block_header_handler, 0);
2022-09-06 12:12:01 +00:00
obelisk_client.wait();
return result;
}
2022-09-19 23:06:33 +00:00
}
} // namespace graphene::peerplays_sidechain