Moving json transaction parsing
Moving json transaction parsing in getrawtransaction and forming btc_tx object
This commit is contained in:
parent
a47498f642
commit
6aee0c6f82
5 changed files with 132 additions and 108 deletions
|
|
@ -37,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 bitcoin-system bitcoin-network bitcoin-client )
|
||||
target_link_libraries( peerplays_sidechain PRIVATE curl graphene_plugin zmq bitcoin-system bitcoin-protocol bitcoin-client bitcoin-explorer )
|
||||
target_include_directories( peerplays_sidechain
|
||||
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,10 @@
|
|||
#include <system_error>
|
||||
|
||||
#include <bitcoin/system/config/hash256.hpp>
|
||||
#include <bitcoin/explorer/config/transaction.hpp>
|
||||
|
||||
#include <fc/log/logger.hpp>
|
||||
#include <fc/crypto/hex.hpp>
|
||||
|
||||
namespace graphene { namespace peerplays_sidechain {
|
||||
|
||||
|
|
@ -21,39 +25,37 @@ libbitcoin_client::libbitcoin_client() :
|
|||
}
|
||||
|
||||
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;
|
||||
// };
|
||||
auto error_handler = [&](const std::error_code &ec) {
|
||||
elog("error on sending bitcoin transaction ${error_code}", ("error_code", ec.message()));
|
||||
};
|
||||
|
||||
// std::cout<<"Transaction: "<<tx<<std::endl;
|
||||
// libbitcoin::explorer::config::transaction transaction(tx);
|
||||
auto result_handler = [&](libbitcoin::code result_code) {
|
||||
ilog("result code on sending transaction ${result_code}", ("result_code", result_code.message()));
|
||||
};
|
||||
|
||||
// // 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();
|
||||
libbitcoin::explorer::config::transaction transaction(tx);
|
||||
|
||||
libbitcoin::chain::transaction trx;
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
void libbitcoin_client::fetch_trx_by_address(std::string address, double amount) {
|
||||
void libbitcoin_client::get_transaction(std::string tx_id) {
|
||||
|
||||
auto error_handler = [&](const std::error_code &ec) {
|
||||
std::cout << "Error code: " << ec << std::endl;
|
||||
elog("error on fetch_trx_by_address ${error_code}", ("error_code", ec.message()));
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
auto transaction_handler = [&] (const libbitcoin::chain::transaction& tx_handler) {
|
||||
|
||||
};
|
||||
|
||||
libbitcoin::wallet::payment_address payment_address(address);
|
||||
libbitcoin::hash_digest tx_hash = libbitcoin::config::hash256(tx_id);
|
||||
|
||||
obelisk_client.blockchain_fetch_history3(error_handler,
|
||||
history_handler, address);
|
||||
obelisk_client.blockchain_fetch_transaction (error_handler, transaction_handler,tx_hash);
|
||||
|
||||
obelisk_client.wait();
|
||||
}
|
||||
|
|
@ -62,7 +64,7 @@ std::vector<list_unspent_replay> libbitcoin_client::list_unspent(std::string add
|
|||
std::vector<list_unspent_replay> result;
|
||||
|
||||
auto error_handler = [&](const std::error_code &ec) {
|
||||
std::cout << "Error code: " << ec << std::endl;
|
||||
elog("error on list_unspent ${error_code}", ("error_code", ec.message()));
|
||||
};
|
||||
|
||||
auto replay_handler = [&](const libbitcoin::chain::points_value &points) {
|
||||
|
|
|
|||
|
|
@ -13,9 +13,8 @@ struct list_unspent_replay {
|
|||
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);
|
||||
void get_transaction (std::string tx_id);
|
||||
std::vector<list_unspent_replay> list_unspent(std::string address, double amount);
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
#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>
|
||||
#include <graphene/peerplays_sidechain/bitcoin/libbitcoin_client.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
|
@ -24,6 +24,20 @@ public:
|
|||
uint64_t amount_;
|
||||
};
|
||||
|
||||
class btc_txin {
|
||||
public:
|
||||
std::vector<std::string> tx_address;
|
||||
uint64_t tx_amount;
|
||||
uint64_t tx_vout;
|
||||
};
|
||||
|
||||
class btc_tx {
|
||||
public:
|
||||
std::string tx_txid;
|
||||
uint32_t tx_confirmations;
|
||||
std::vector<btc_txin> tx_in_list;
|
||||
};
|
||||
|
||||
class bitcoin_client {
|
||||
public:
|
||||
enum class multi_type {
|
||||
|
|
@ -44,8 +58,8 @@ public:
|
|||
|
||||
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 btc_tx getrawtransaction(const std::string &txid, const bool verbose = false) = 0;
|
||||
virtual void 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;
|
||||
|
|
@ -58,8 +72,8 @@ 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();
|
||||
btc_tx getrawtransaction(const std::string &txid, const bool verbose = false);
|
||||
void getnetworkinfo();
|
||||
std::string getblockchaininfo();
|
||||
void importmulti(const std::vector<multi_params> &address_or_script_array, const bool rescan = true);
|
||||
std::vector<btc_txout> listunspent(const uint32_t minconf = 1, const uint32_t maxconf = 9999999);
|
||||
|
|
@ -75,14 +89,15 @@ private:
|
|||
std::string password;
|
||||
std::string wallet;
|
||||
std::string wallet_password;
|
||||
uint32_t bitcoin_major_version;
|
||||
};
|
||||
|
||||
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();
|
||||
btc_tx getrawtransaction(const std::string &txid, const bool verbose = false);
|
||||
void 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);
|
||||
|
|
@ -132,7 +147,6 @@ private:
|
|||
std::string ip;
|
||||
uint32_t zmq_port;
|
||||
uint32_t rpc_port;
|
||||
uint32_t bitcoin_major_version;
|
||||
std::string rpc_user;
|
||||
std::string rpc_password;
|
||||
std::string wallet;
|
||||
|
|
|
|||
|
|
@ -59,16 +59,58 @@ std::string bitcoin_rpc_client::getblock(const std::string &block_hash, int32_t
|
|||
return str;
|
||||
}
|
||||
|
||||
std::string bitcoin_rpc_client::getnetworkinfo() {
|
||||
void bitcoin_rpc_client::getnetworkinfo() {
|
||||
std::string params = std::string("[]");
|
||||
std::string str = send_post_request("getnetworkinfo", params, debug_rpc_calls);
|
||||
return str;
|
||||
|
||||
std::stringstream network_info_ss(str);
|
||||
boost::property_tree::ptree network_info_json;
|
||||
boost::property_tree::read_json(network_info_ss, network_info_json);
|
||||
|
||||
bitcoin_major_version = network_info_json.get<uint32_t>("result.version") / 10000;
|
||||
ilog("Bitcoin major version is: '${version}'", ("version", bitcoin_major_version));
|
||||
}
|
||||
|
||||
std::string bitcoin_rpc_client::getrawtransaction(const std::string &txid, const bool verbose) {
|
||||
btc_tx bitcoin_rpc_client::getrawtransaction(const std::string &txid, const bool verbose) {
|
||||
std::string params = std::string("[\"") + txid + std::string("\",") + (verbose ? "true" : "false") + std::string("]");
|
||||
std::string str = send_post_request("getrawtransaction", params, debug_rpc_calls);
|
||||
return str;
|
||||
|
||||
btc_tx tx;
|
||||
|
||||
std::stringstream tx_ss(str);
|
||||
boost::property_tree::ptree tx_json;
|
||||
boost::property_tree::read_json(tx_ss, tx_json);
|
||||
|
||||
if (tx_json.count("error") && tx_json.get_child("error").empty()) {
|
||||
|
||||
std::string tx_txid = tx_json.get<std::string>("result.txid");
|
||||
uint32_t tx_confirmations = tx_json.get<uint32_t>("result.confirmations");
|
||||
|
||||
tx.tx_txid = tx_txid;
|
||||
tx.tx_confirmations = tx_confirmations;
|
||||
|
||||
for (auto &input : tx_json.get_child("result.vout")) {
|
||||
btc_txin tx_in;
|
||||
std::string tx_vout_s = input.second.get<std::string>("n");
|
||||
tx_in.tx_vout = std::stoll(tx_vout_s);
|
||||
if (bitcoin_major_version > 21) {
|
||||
std::string address = input.second.get<std::string>("scriptPubKey.address");
|
||||
tx_in.tx_address.emplace_back(address);
|
||||
} else {
|
||||
for (auto &address : input.second.get_child("scriptPubKey.addresses")) {
|
||||
tx_in.tx_address.emplace_back(address.second.data());
|
||||
}
|
||||
}
|
||||
|
||||
std::string tx_amount_s = input.second.get<std::string>("value");
|
||||
tx_amount_s.erase(std::remove(tx_amount_s.begin(), tx_amount_s.end(), '.'), tx_amount_s.end());
|
||||
tx_in.tx_amount = std::stoll(tx_amount_s);
|
||||
|
||||
tx.tx_in_list.emplace_back(tx_in);
|
||||
}
|
||||
}
|
||||
|
||||
return tx;
|
||||
}
|
||||
|
||||
std::string bitcoin_rpc_client::getblockchaininfo() {
|
||||
|
|
@ -213,6 +255,8 @@ std::string bitcoin_rpc_client::sendrawtransaction(const std::string &tx_hex) {
|
|||
}
|
||||
|
||||
return json.get<std::string>("result");
|
||||
std::cout << "Result of transaction: " << std::endl;
|
||||
std::cout << ss.str() << std::endl;
|
||||
}
|
||||
|
||||
return str;
|
||||
|
|
@ -255,14 +299,14 @@ std::string bitcoin_libbitcoin_client::getblock(const std::string &block_hash, i
|
|||
return std::string("");
|
||||
}
|
||||
|
||||
std::string bitcoin_libbitcoin_client::getrawtransaction(const std::string &txid, const bool verbose) {
|
||||
btc_tx bitcoin_libbitcoin_client::getrawtransaction(const std::string &txid, const bool verbose) {
|
||||
// TODO
|
||||
return std::string("");
|
||||
btc_tx tx;
|
||||
return tx;
|
||||
}
|
||||
|
||||
std::string bitcoin_libbitcoin_client::getnetworkinfo() {
|
||||
void bitcoin_libbitcoin_client::getnetworkinfo() {
|
||||
// TODO
|
||||
return std::string("");
|
||||
}
|
||||
|
||||
std::string bitcoin_libbitcoin_client::getblockchaininfo() {
|
||||
|
|
@ -435,13 +479,7 @@ sidechain_net_handler_bitcoin::sidechain_net_handler_bitcoin(peerplays_sidechain
|
|||
}
|
||||
}
|
||||
|
||||
std::string network_info_str = bitcoin_client->getnetworkinfo();
|
||||
std::stringstream network_info_ss(network_info_str);
|
||||
boost::property_tree::ptree network_info_json;
|
||||
boost::property_tree::read_json(network_info_ss, network_info_json);
|
||||
|
||||
bitcoin_major_version = network_info_json.get<uint32_t>("result.version") / 10000;
|
||||
ilog("Bitcoin major version is: '${version}'", ("version", bitcoin_major_version));
|
||||
bitcoin_client->getnetworkinfo();
|
||||
|
||||
listener = std::unique_ptr<zmq_listener>(new zmq_listener(ip, zmq_port));
|
||||
listener->start();
|
||||
|
|
@ -577,39 +615,28 @@ bool sidechain_net_handler_bitcoin::process_proposal(const proposal_object &po)
|
|||
uint64_t swdo_amount = swdo->sidechain_amount.value;
|
||||
uint64_t swdo_vout = std::stoll(swdo->sidechain_uid.substr(swdo->sidechain_uid.find_last_of("-") + 1));
|
||||
|
||||
std::string tx_str = bitcoin_client->getrawtransaction(swdo_txid, true);
|
||||
std::stringstream tx_ss(tx_str);
|
||||
boost::property_tree::ptree tx_json;
|
||||
boost::property_tree::read_json(tx_ss, tx_json);
|
||||
btc_tx tx = bitcoin_client->getrawtransaction(swdo_txid, true);
|
||||
// lib_bitcoin_client->get_transaction(swdo_txid);
|
||||
|
||||
if (tx_json.count("error") && tx_json.get_child("error").empty()) {
|
||||
if (!tx.tx_in_list.empty()) {
|
||||
|
||||
std::string tx_txid = tx_json.get<std::string>("result.txid");
|
||||
uint32_t tx_confirmations = tx_json.get<uint32_t>("result.confirmations");
|
||||
std::string tx_txid = tx.tx_txid;
|
||||
uint32_t tx_confirmations = tx.tx_confirmations;
|
||||
std::string tx_address = "";
|
||||
uint64_t tx_amount = -1;
|
||||
uint64_t tx_vout = -1;
|
||||
|
||||
for (auto &input : tx_json.get_child("result.vout")) {
|
||||
std::string tx_vout_s = input.second.get<std::string>("n");
|
||||
tx_vout = std::stoll(tx_vout_s);
|
||||
for (auto &input : tx.tx_in_list) {
|
||||
tx_vout = input.tx_vout;
|
||||
if (tx_vout == swdo_vout) {
|
||||
if (bitcoin_major_version > 21) {
|
||||
std::string address = input.second.get<std::string>("scriptPubKey.address");
|
||||
for (auto &address : input.tx_address) {
|
||||
if (address == swdo_address) {
|
||||
tx_address = address;
|
||||
}
|
||||
} else {
|
||||
for (auto &address : input.second.get_child("scriptPubKey.addresses")) {
|
||||
if (address.second.data() == swdo_address) {
|
||||
tx_address = address.second.data();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
std::string tx_amount_s = input.second.get<std::string>("value");
|
||||
tx_amount_s.erase(std::remove(tx_amount_s.begin(), tx_amount_s.end(), '.'), tx_amount_s.end());
|
||||
tx_amount = std::stoll(tx_amount_s);
|
||||
|
||||
tx_amount = input.tx_amount;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -992,12 +1019,9 @@ bool sidechain_net_handler_bitcoin::settle_sidechain_transaction(const sidechain
|
|||
return false;
|
||||
}
|
||||
|
||||
std::string tx_str = bitcoin_client->getrawtransaction(sto.sidechain_transaction, true);
|
||||
std::stringstream tx_ss(tx_str);
|
||||
boost::property_tree::ptree tx_json;
|
||||
boost::property_tree::read_json(tx_ss, tx_json);
|
||||
btc_tx tx = bitcoin_client->getrawtransaction(sto.sidechain_transaction, true);
|
||||
|
||||
if ((tx_json.count("error")) && (!tx_json.get_child("error").empty())) {
|
||||
if (tx.tx_in_list.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1017,29 +1041,18 @@ bool sidechain_net_handler_bitcoin::settle_sidechain_transaction(const sidechain
|
|||
|
||||
btc_weighted_multisig_address addr(pubkey_weights, network_type, payment_type_address);
|
||||
|
||||
std::string tx_txid = tx_json.get<std::string>("result.txid");
|
||||
uint32_t tx_confirmations = tx_json.get<uint32_t>("result.confirmations");
|
||||
std::string tx_txid = tx.tx_txid;
|
||||
uint32_t tx_confirmations = tx.tx_confirmations;
|
||||
std::string tx_address = addr.get_address();
|
||||
int64_t tx_amount = -1;
|
||||
|
||||
if (tx_confirmations >= gpo.parameters.son_bitcoin_min_tx_confirmations()) {
|
||||
if (sto.object_id.is<son_wallet_deposit_id_type>()) {
|
||||
for (auto &input : tx_json.get_child("result.vout")) {
|
||||
if (bitcoin_major_version > 21) {
|
||||
std::string address = input.second.get<std::string>("scriptPubKey.address");
|
||||
for (auto &input : tx.tx_in_list) {
|
||||
for (auto &address : input.tx_address) {
|
||||
if (address == tx_address) {
|
||||
std::string tx_amount_s = input.second.get<std::string>("value");
|
||||
tx_amount_s.erase(std::remove(tx_amount_s.begin(), tx_amount_s.end(), '.'), tx_amount_s.end());
|
||||
tx_amount = std::stoll(tx_amount_s);
|
||||
}
|
||||
} else {
|
||||
for (auto &address : input.second.get_child("scriptPubKey.addresses")) {
|
||||
if (address.second.data() == tx_address) {
|
||||
std::string tx_amount_s = input.second.get<std::string>("value");
|
||||
tx_amount_s.erase(std::remove(tx_amount_s.begin(), tx_amount_s.end(), '.'), tx_amount_s.end());
|
||||
tx_amount = std::stoll(tx_amount_s);
|
||||
break;
|
||||
}
|
||||
tx_amount = input.tx_amount;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1321,8 +1334,9 @@ std::string sidechain_net_handler_bitcoin::send_transaction(const sidechain_tran
|
|||
|
||||
std::string final_tx_hex = fc::to_hex(pack(tx));
|
||||
std::string res = bitcoin_client->sendrawtransaction(final_tx_hex);
|
||||
// lib_bitcoin_client->send_transaction(final_tx_hex);
|
||||
|
||||
return res;
|
||||
return tx.get_txid().str();
|
||||
}
|
||||
|
||||
void sidechain_net_handler_bitcoin::handle_event(const std::string &event_data) {
|
||||
|
|
@ -1413,16 +1427,19 @@ std::vector<info_for_vin> sidechain_net_handler_bitcoin::extract_info_from_block
|
|||
|
||||
for (const auto &o : tx.get_child("vout")) {
|
||||
const auto script = o.second.get_child("scriptPubKey");
|
||||
std::vector<std::string> address_list;
|
||||
|
||||
if (bitcoin_major_version > 21) {
|
||||
if (!script.count("address"))
|
||||
continue;
|
||||
if (script.count("address")) {
|
||||
address_list.emplace_back(script.get<std::string>("address"));
|
||||
} else if (script.count("addresses")) {
|
||||
for (const auto &addr : script.get_child("addresses")) {
|
||||
address_list.emplace_back(addr.second.get_value<std::string>());
|
||||
}
|
||||
} else {
|
||||
if (!script.count("addresses"))
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
|
||||
auto sort_out_vin = [&](std::string address) {
|
||||
for (auto &address : address_list) {
|
||||
const auto address_base58 = address;
|
||||
info_for_vin vin;
|
||||
vin.out.hash_tx = tx.get_child("txid").get_value<std::string>();
|
||||
|
|
@ -1432,14 +1449,6 @@ std::vector<info_for_vin> sidechain_net_handler_bitcoin::extract_info_from_block
|
|||
vin.out.n_vout = o.second.get_child("n").get_value<uint32_t>();
|
||||
vin.address = address_base58;
|
||||
result.push_back(vin);
|
||||
};
|
||||
|
||||
if (bitcoin_major_version > 21) {
|
||||
std::string address = script.get<std::string>("address");
|
||||
sort_out_vin(address);
|
||||
} else {
|
||||
for (const auto &addr : script.get_child("addresses")) // in which cases there can be more addresses?
|
||||
sort_out_vin(addr.second.get_value<std::string>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue