libbitcoin client work in progress
This commit is contained in:
parent
789c0547cf
commit
a47498f642
5 changed files with 202 additions and 18 deletions
3
libraries/plugins/peerplays_sidechain/CMakeLists.txt
Executable file → Normal file
3
libraries/plugins/peerplays_sidechain/CMakeLists.txt
Executable file → Normal file
|
|
@ -15,6 +15,7 @@ add_library( peerplays_sidechain
|
|||
bitcoin/segwit_addr.cpp
|
||||
bitcoin/utils.cpp
|
||||
bitcoin/sign_bitcoin_transaction.cpp
|
||||
bitcoin/libbitcoin_client.cpp
|
||||
common/rpc_client.cpp
|
||||
common/utils.cpp
|
||||
hive/asset.cpp
|
||||
|
|
@ -36,7 +37,7 @@ endif()
|
|||
unset(ENABLE_PEERPLAYS_ASSET_DEPOSITS)
|
||||
unset(ENABLE_PEERPLAYS_ASSET_DEPOSITS CACHE)
|
||||
|
||||
target_link_libraries( peerplays_sidechain PRIVATE curl graphene_plugin zmq )
|
||||
target_link_libraries( peerplays_sidechain PRIVATE curl graphene_plugin zmq bitcoin-system bitcoin-network bitcoin-client )
|
||||
target_include_directories( peerplays_sidechain
|
||||
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,87 @@
|
|||
|
||||
#include <graphene/peerplays_sidechain/bitcoin/libbitcoin_client.hpp>
|
||||
|
||||
#include <system_error>
|
||||
|
||||
#include <bitcoin/system/config/hash256.hpp>
|
||||
|
||||
namespace graphene { namespace peerplays_sidechain {
|
||||
|
||||
libbitcoin_client::libbitcoin_client() :
|
||||
obelisk_client(10, 100) {
|
||||
libbitcoin::client::connection_type connection;
|
||||
connection.retries = 100;
|
||||
connection.server = libbitcoin::config::endpoint("tcp://localhost", 9091);
|
||||
|
||||
if (!obelisk_client.connect(connection)) {
|
||||
//display_connection_failure(error, connection.server);
|
||||
//return console_result::failure;
|
||||
std::cout << "Can't connect" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void libbitcoin_client::send_transaction(std::string tx) {
|
||||
// std::cout<<"Enter in function"<<std::endl;
|
||||
// auto error_handler = [&](const std::error_code &ec) {
|
||||
// std::cout << "Error code: " << ec << std::endl;
|
||||
// };
|
||||
|
||||
// auto result_handler = [&](libbitcoin::code result_code) {
|
||||
// std::cout << "result is: " << result_code << std::endl;
|
||||
// };
|
||||
|
||||
// std::cout<<"Transaction: "<<tx<<std::endl;
|
||||
// libbitcoin::explorer::config::transaction transaction(tx);
|
||||
|
||||
// // This validates the tx, submits it to local tx pool, and notifies peers.
|
||||
// libbitcoin_client.transaction_pool_broadcast(error_handler, result_handler, transaction);
|
||||
// libbitcoin_client.wait();
|
||||
}
|
||||
|
||||
void libbitcoin_client::fetch_trx_by_address(std::string address, double amount) {
|
||||
auto error_handler = [&](const std::error_code &ec) {
|
||||
std::cout << "Error code: " << ec << std::endl;
|
||||
};
|
||||
|
||||
auto history_handler = [&](const libbitcoin::chain::history::list &rows) {
|
||||
for (auto &row : rows) {
|
||||
std::cout << "LIB Hash: " << libbitcoin::config::hash256(row.output.hash()) << std::endl;
|
||||
std::cout << "LIB Amount: " << row.value;
|
||||
}
|
||||
};
|
||||
|
||||
libbitcoin::wallet::payment_address payment_address(address);
|
||||
|
||||
obelisk_client.blockchain_fetch_history3(error_handler,
|
||||
history_handler, address);
|
||||
|
||||
obelisk_client.wait();
|
||||
}
|
||||
|
||||
std::vector<list_unspent_replay> libbitcoin_client::list_unspent(std::string address, double amount) {
|
||||
std::vector<list_unspent_replay> result;
|
||||
|
||||
auto error_handler = [&](const std::error_code &ec) {
|
||||
std::cout << "Error code: " << ec << std::endl;
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
obelisk_client.blockchain_fetch_unspent_outputs(error_handler,
|
||||
replay_handler, payment_address, 100000000, libbitcoin::wallet::select_outputs::algorithm::individual);
|
||||
|
||||
obelisk_client.wait();
|
||||
|
||||
return result;
|
||||
}
|
||||
}} // namespace graphene::peerplays_sidechain
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
#pragma once
|
||||
|
||||
#include <bitcoin/client/obelisk_client.hpp>
|
||||
|
||||
namespace graphene { namespace peerplays_sidechain {
|
||||
|
||||
struct list_unspent_replay {
|
||||
std::string hash;
|
||||
uint64_t value;
|
||||
uint32_t index;
|
||||
};
|
||||
|
||||
class libbitcoin_client {
|
||||
public:
|
||||
libbitcoin_client();
|
||||
// test methods for libbitcoin
|
||||
void send_transaction(std::string tx);
|
||||
void fetch_trx_by_address(std::string address, double amount);
|
||||
std::vector<list_unspent_replay> list_unspent(std::string address, double amount);
|
||||
|
||||
private:
|
||||
libbitcoin::client::obelisk_client obelisk_client;
|
||||
};
|
||||
|
||||
}} // namespace graphene::peerplays_sidechain
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <graphene/peerplays_sidechain/bitcoin/libbitcoin_client.hpp>
|
||||
#include <graphene/peerplays_sidechain/common/rpc_client.hpp>
|
||||
#include <graphene/peerplays_sidechain/sidechain_net_handler.hpp>
|
||||
|
||||
|
|
@ -23,7 +24,7 @@ public:
|
|||
uint64_t amount_;
|
||||
};
|
||||
|
||||
class bitcoin_rpc_client : public rpc_client {
|
||||
class bitcoin_client {
|
||||
public:
|
||||
enum class multi_type {
|
||||
script,
|
||||
|
|
@ -41,10 +42,20 @@ public:
|
|||
std::string label;
|
||||
};
|
||||
|
||||
virtual uint64_t estimatesmartfee(uint16_t conf_target = 128) = 0;
|
||||
virtual std::string getblock(const std::string &block_hash, int32_t verbosity = 2) = 0;
|
||||
virtual std::string getrawtransaction(const std::string &txid, const bool verbose = false) = 0;
|
||||
virtual std::string getnetworkinfo() = 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::string sendrawtransaction(const std::string &tx_hex) = 0;
|
||||
};
|
||||
|
||||
class bitcoin_rpc_client : public bitcoin_client, public rpc_client {
|
||||
public:
|
||||
public:
|
||||
bitcoin_rpc_client(std::string _url, std::string _user, std::string _password, bool _debug_rpc_calls);
|
||||
|
||||
std::string createwallet(const std::string &wallet_name);
|
||||
uint64_t estimatesmartfee(uint16_t conf_target = 128);
|
||||
std::string getblock(const std::string &block_hash, int32_t verbosity = 2);
|
||||
std::string getrawtransaction(const std::string &txid, const bool verbose = false);
|
||||
|
|
@ -60,13 +71,23 @@ public:
|
|||
|
||||
private:
|
||||
std::string ip;
|
||||
uint32_t rpc_port;
|
||||
std::string user;
|
||||
std::string password;
|
||||
std::string wallet;
|
||||
std::string wallet_password;
|
||||
};
|
||||
|
||||
class bitcoin_libbitcoin_client : public bitcoin_client, public libbitcoin_client {
|
||||
public:
|
||||
uint64_t estimatesmartfee(uint16_t conf_target = 128);
|
||||
std::string getblock(const std::string &block_hash, int32_t verbosity = 2);
|
||||
std::string getrawtransaction(const std::string &txid, const bool verbose = false);
|
||||
std::string getnetworkinfo();
|
||||
std::string getblockchaininfo();
|
||||
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::string sendrawtransaction(const std::string &tx_hex);
|
||||
};
|
||||
|
||||
// =============================================================================
|
||||
|
||||
class zmq_listener {
|
||||
|
|
@ -118,6 +139,7 @@ private:
|
|||
std::string wallet_password;
|
||||
|
||||
std::unique_ptr<bitcoin_rpc_client> bitcoin_client;
|
||||
std::unique_ptr<bitcoin_libbitcoin_client> lib_bitcoin_client;
|
||||
std::unique_ptr<zmq_listener> listener;
|
||||
|
||||
fc::future<void> on_changed_objects_task;
|
||||
|
|
|
|||
|
|
@ -29,12 +29,6 @@ bitcoin_rpc_client::bitcoin_rpc_client(std::string _url, std::string _user, std:
|
|||
rpc_client(_url, _user, _password, _debug_rpc_calls) {
|
||||
}
|
||||
|
||||
std::string bitcoin_rpc_client::createwallet(const std::string &wallet_name) {
|
||||
std::string params = std::string("[\"") + wallet_name + std::string("\"]");
|
||||
std::string str = send_post_request("createwallet", params, debug_rpc_calls);
|
||||
return str;
|
||||
}
|
||||
|
||||
uint64_t bitcoin_rpc_client::estimatesmartfee(uint16_t conf_target) {
|
||||
std::string params = std::string("[") + std::to_string(conf_target) + std::string("]");
|
||||
std::string str = send_post_request("estimatesmartfee", params, debug_rpc_calls);
|
||||
|
|
@ -110,11 +104,11 @@ void bitcoin_rpc_client::importmulti(const std::vector<multi_params> &address_or
|
|||
|
||||
//! Note
|
||||
/* Creation time of the key expressed in UNIX epoch time,
|
||||
or the string "now" to substitute the current synced blockchain time. The timestamp of the oldest
|
||||
key will determine how far back blockchain rescans need to begin for missing wallet transactions.
|
||||
"now" can be specified to bypass scanning, for keys which are known to never have been used, and
|
||||
0 can be specified to scan the entire blockchain. Blocks up to 2 hours before the earliest key
|
||||
creation time of all keys being imported by the importmulti call will be scanned.*/
|
||||
or the string "now" to substitute the current synced blockchain time. The timestamp of the oldest
|
||||
key will determine how far back blockchain rescans need to begin for missing wallet transactions.
|
||||
"now" can be specified to bypass scanning, for keys which are known to never have been used, and
|
||||
0 can be specified to scan the entire blockchain. Blocks up to 2 hours before the earliest key
|
||||
creation time of all keys being imported by the importmulti call will be scanned.*/
|
||||
|
||||
if (¶m != &address_or_script_array.back()) {
|
||||
argument_1 += ", ";
|
||||
|
|
@ -251,6 +245,58 @@ bool bitcoin_rpc_client::walletpassphrase(const std::string &passphrase, uint32_
|
|||
return true;
|
||||
}
|
||||
|
||||
uint64_t bitcoin_libbitcoin_client::estimatesmartfee(uint16_t conf_target) {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string bitcoin_libbitcoin_client::getblock(const std::string &block_hash, int32_t verbosity) {
|
||||
// TODO
|
||||
return std::string("");
|
||||
}
|
||||
|
||||
std::string bitcoin_libbitcoin_client::getrawtransaction(const std::string &txid, const bool verbose) {
|
||||
// TODO
|
||||
return std::string("");
|
||||
}
|
||||
|
||||
std::string bitcoin_libbitcoin_client::getnetworkinfo() {
|
||||
// TODO
|
||||
return std::string("");
|
||||
}
|
||||
|
||||
std::string bitcoin_libbitcoin_client::getblockchaininfo() {
|
||||
// TODO
|
||||
return std::string("");
|
||||
}
|
||||
|
||||
std::vector<btc_txout> bitcoin_libbitcoin_client::listunspent_by_address_and_amount(const std::string &address, double transfer_amount, const uint32_t minconf, const uint32_t maxconf) {
|
||||
|
||||
std::vector<btc_txout> result;
|
||||
std::vector<list_unspent_replay> outputs = list_unspent(address, 0);
|
||||
uint8_t counter{0};
|
||||
for (auto &output : outputs) {
|
||||
btc_txout txo;
|
||||
txo.txid_ = output.hash;
|
||||
txo.out_num_ = output.index;
|
||||
txo.amount_ = output.value;
|
||||
result.push_back(txo);
|
||||
}
|
||||
|
||||
std::cout << "libbitcoin: ===>" << std::endl;
|
||||
for (auto &res : result) {
|
||||
std::cout << "Hash: " << res.txid_ << " out_num: " << res.out_num_ << " amount: " << res.amount_ << std::endl;
|
||||
}
|
||||
std::cout << "==================================>" << std::endl;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string bitcoin_libbitcoin_client::sendrawtransaction(const std::string &tx_hex) {
|
||||
// TODO
|
||||
return std::string("");
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
||||
zmq_listener::zmq_listener(std::string _ip, uint32_t _zmq) :
|
||||
|
|
@ -338,7 +384,7 @@ sidechain_net_handler_bitcoin::sidechain_net_handler_bitcoin(peerplays_sidechain
|
|||
rpc_port = options.at("bitcoin-node-rpc-port").as<uint32_t>();
|
||||
rpc_user = options.at("bitcoin-node-rpc-user").as<std::string>();
|
||||
rpc_password = options.at("bitcoin-node-rpc-password").as<std::string>();
|
||||
wallet = "";
|
||||
std::string wallet = "";
|
||||
if (options.count("bitcoin-wallet")) {
|
||||
wallet = options.at("bitcoin-wallet").as<std::string>();
|
||||
}
|
||||
|
|
@ -365,6 +411,7 @@ sidechain_net_handler_bitcoin::sidechain_net_handler_bitcoin(peerplays_sidechain
|
|||
}
|
||||
|
||||
bitcoin_client = std::unique_ptr<bitcoin_rpc_client>(new bitcoin_rpc_client(url, rpc_user, rpc_password, debug_rpc_calls));
|
||||
lib_bitcoin_client = std::unique_ptr<bitcoin_libbitcoin_client>(new bitcoin_libbitcoin_client());
|
||||
if (!wallet.empty()) {
|
||||
bitcoin_client->loadwallet(wallet);
|
||||
}
|
||||
|
|
@ -421,7 +468,7 @@ sidechain_net_handler_bitcoin::~sidechain_net_handler_bitcoin() {
|
|||
|
||||
bool sidechain_net_handler_bitcoin::process_proposal(const proposal_object &po) {
|
||||
|
||||
//ilog("Proposal to process: ${po}, SON id ${son_id}", ("po", po.id)("son_id", plugin.get_current_son_id(sidechain)));
|
||||
// ilog("Proposal to process: ${po}, SON id ${son_id}", ("po", po.id)("son_id", plugin.get_current_son_id(sidechain)));
|
||||
|
||||
bool should_approve = false;
|
||||
|
||||
|
|
@ -1062,6 +1109,7 @@ std::string sidechain_net_handler_bitcoin::create_primary_wallet_transaction(con
|
|||
|
||||
uint64_t total_amount = 0.0;
|
||||
std::vector<btc_txout> inputs = bitcoin_client->listunspent_by_address_and_amount(prev_pw_address, 0);
|
||||
inputs = lib_bitcoin_client->listunspent_by_address_and_amount(prev_pw_address, 0);
|
||||
|
||||
if (inputs.size() == 0) {
|
||||
elog("Failed to find UTXOs to spend for ${pw}", ("pw", prev_pw_address));
|
||||
|
|
@ -1152,6 +1200,7 @@ std::string sidechain_net_handler_bitcoin::create_withdrawal_transaction(const s
|
|||
|
||||
int64_t total_amount = 0;
|
||||
std::vector<btc_txout> inputs = bitcoin_client->listunspent_by_address_and_amount(pw_address, 0);
|
||||
inputs = lib_bitcoin_client->listunspent_by_address_and_amount(pw_address, 0);
|
||||
|
||||
if (inputs.size() == 0) {
|
||||
elog("Failed to find UTXOs to spend for ${pw}", ("pw", pw_address));
|
||||
|
|
@ -1444,7 +1493,7 @@ void sidechain_net_handler_bitcoin::on_changed_objects_cb(const vector<object_id
|
|||
}
|
||||
|
||||
//! importmulti
|
||||
bitcoin_client->importmulti(address_or_script_array);
|
||||
// bitcoin_client->importmulti(address_or_script_array);
|
||||
|
||||
//! Lock wallet
|
||||
bitcoin_client->walletlock();
|
||||
|
|
|
|||
Loading…
Reference in a new issue