Code formatting

This commit is contained in:
Srdjan Obucina 2020-03-14 02:18:03 +01:00
parent b1fbd26bcf
commit 2b6c700644
5 changed files with 152 additions and 186 deletions

View file

@ -377,15 +377,14 @@ const char *charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
/** The Bech32 character set for decoding. */ /** The Bech32 character set for decoding. */
const int8_t charset_rev[128] = { const int8_t charset_rev[128] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
15, -1, 10, 17, 21, 20, 26, 30, 7, 5, -1, -1, -1, -1, -1, -1, 15, -1, 10, 17, 21, 20, 26, 30, 7, 5, -1, -1, -1, -1, -1, -1,
-1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1, -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1, 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1,
-1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1, -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1};
};
/** Concatenate two byte arrays. */ /** Concatenate two byte arrays. */
bytes cat(bytes x, const bytes &y) { bytes cat(bytes x, const bytes &y) {
@ -422,18 +421,17 @@ uint32_t polymod(const bytes &values) {
} }
/** Expand a HRP for use in checksum computation. */ /** Expand a HRP for use in checksum computation. */
bytes bech32_expand_hrp(const std::string& hrp) bytes bech32_expand_hrp(const std::string &hrp) {
{ bytes ret;
bytes ret; ret.reserve(hrp.size() + 90);
ret.reserve(hrp.size() + 90); ret.resize(hrp.size() * 2 + 1);
ret.resize(hrp.size() * 2 + 1); for (size_t i = 0; i < hrp.size(); ++i) {
for (size_t i = 0; i < hrp.size(); ++i) { unsigned char c = hrp[i];
unsigned char c = hrp[i]; ret[i] = c >> 5;
ret[i] = c >> 5; ret[i + hrp.size() + 1] = c & 0x1f;
ret[i + hrp.size() + 1] = c & 0x1f; }
} ret[hrp.size()] = 0;
ret[hrp.size()] = 0; return ret;
return ret;
} }
/** Create a checksum. */ /** Create a checksum. */
@ -450,17 +448,16 @@ bytes bech32_checksum(const std::string &hrp, const bytes &values) {
} }
/** Verify a checksum. */ /** Verify a checksum. */
bool bech32_verify_checksum(const std::string& hrp, const bytes& values) bool bech32_verify_checksum(const std::string &hrp, const bytes &values) {
{ // PolyMod computes what value to xor into the final values to make the checksum 0. However,
// PolyMod computes what value to xor into the final values to make the checksum 0. However, // if we required that the checksum was 0, it would be the case that appending a 0 to a valid
// if we required that the checksum was 0, it would be the case that appending a 0 to a valid // list of values would result in a new valid list. For that reason, Bech32 requires the
// list of values would result in a new valid list. For that reason, Bech32 requires the // resulting checksum to be 1 instead.
// resulting checksum to be 1 instead. return polymod(cat(bech32_expand_hrp(hrp), values)) == 1;
return polymod(cat(bech32_expand_hrp(hrp), values)) == 1;
} }
/** Encode a Bech32 string. */ /** Encode a Bech32 string. */
std::string bech32_encode(const std::string& hrp, const bytes& values) { std::string bech32_encode(const std::string &hrp, const bytes &values) {
bytes checksum = bech32_checksum(hrp, values); bytes checksum = bech32_checksum(hrp, values);
bytes combined = cat(values, checksum); bytes combined = cat(values, checksum);
std::string ret = hrp + '1'; std::string ret = hrp + '1';
@ -472,10 +469,10 @@ std::string bech32_encode(const std::string& hrp, const bytes& values) {
} }
/** Decode a Bech32 string. */ /** Decode a Bech32 string. */
bytes bech32_decode(const std::string& str) { bytes bech32_decode(const std::string &str) {
if (str.size() > 90) if (str.size() > 90)
FC_THROW("Invalid bech32 string ${a}", ("a", str)); FC_THROW("Invalid bech32 string ${a}", ("a", str));
for (unsigned char c: str) { for (unsigned char c : str) {
if (c < 33 || c > 126) if (c < 33 || c > 126)
FC_THROW("Invalid bech32 string ${a}", ("a", str)); FC_THROW("Invalid bech32 string ${a}", ("a", str));
if (c >= 'A' && c <= 'Z') if (c >= 'A' && c <= 'Z')
@ -524,32 +521,28 @@ bool convertbits(bytes &out, const bytes &in) {
} }
/** Encode a SegWit address. */ /** Encode a SegWit address. */
std::string segwit_addr_encode(const std::string& hrp, uint8_t witver, const bytes& witprog) std::string segwit_addr_encode(const std::string &hrp, uint8_t witver, const bytes &witprog) {
{ bytes enc;
bytes enc; enc.push_back(witver);
enc.push_back(witver); convertbits<8, 5, true>(enc, witprog);
convertbits<8, 5, true>(enc, witprog); std::string ret = bech32_encode(hrp, enc);
std::string ret = bech32_encode(hrp, enc); return ret;
return ret;
} }
/** Decode a SegWit address. */ /** Decode a SegWit address. */
bytes segwit_addr_decode(const std::string& addr) bytes segwit_addr_decode(const std::string &addr) {
{
bytes dec = bech32_decode(addr); bytes dec = bech32_decode(addr);
if (dec.size() < 1) if (dec.size() < 1)
FC_THROW("Invalid bech32 address ${a}", ("a", addr)); FC_THROW("Invalid bech32 address ${a}", ("a", addr));
bytes conv; bytes conv;
if (!convertbits<5, 8, false>(conv, bytes(dec.begin() + 1, dec.end())) || if (!convertbits<5, 8, false>(conv, bytes(dec.begin() + 1, dec.end())) ||
conv.size() < 2 || conv.size() > 40 || dec[0] > 16 || (dec[0] == 0 && conv.size() < 2 || conv.size() > 40 || dec[0] > 16 || (dec[0] == 0 && conv.size() != 20 && conv.size() != 32)) {
conv.size() != 20 && conv.size() != 32)) { FC_THROW("Invalid bech32 address ${a}", ("a", addr));
FC_THROW("Invalid bech32 address ${a}", ("a", addr)); }
} return conv;
return conv;
} }
std::string p2wsh_address_from_redeem_script(const bytes& script, bitcoin_network network) std::string p2wsh_address_from_redeem_script(const bytes &script, bitcoin_network network) {
{
// calc script hash // calc script hash
fc::sha256 sh = fc::sha256::hash(reinterpret_cast<const char *>(&script[0]), script.size()); fc::sha256 sh = fc::sha256::hash(reinterpret_cast<const char *>(&script[0]), script.size());
bytes wp(sh.data(), sh.data() + sh.data_size()); bytes wp(sh.data(), sh.data() + sh.data_size());
@ -766,19 +759,17 @@ bytes add_signatures_to_unsigned_tx(const bytes &unsigned_tx, const std::vector<
return ret; return ret;
} }
std::string get_weighted_multisig_address(const std::vector<std::pair<std::string, uint64_t> > &public_keys) std::string get_weighted_multisig_address(const std::vector<std::pair<std::string, uint64_t>> &public_keys) {
{
std::vector<std::pair<fc::ecc::public_key, uint64_t>> key_data; std::vector<std::pair<fc::ecc::public_key, uint64_t>> key_data;
for(auto p: public_keys) for (auto p : public_keys)
key_data.push_back(std::make_pair(fc::ecc::public_key::from_base58(p.first), p.second)); key_data.push_back(std::make_pair(fc::ecc::public_key::from_base58(p.first), p.second));
bytes redeem_script = generate_redeem_script(key_data); bytes redeem_script = generate_redeem_script(key_data);
return p2wsh_address_from_redeem_script(redeem_script); return p2wsh_address_from_redeem_script(redeem_script);
} }
bytes get_weighted_multisig_redeem_script(std::vector<std::pair<std::string, uint64_t> > public_keys) bytes get_weighted_multisig_redeem_script(std::vector<std::pair<std::string, uint64_t>> public_keys) {
{
std::vector<std::pair<fc::ecc::public_key, uint64_t>> key_data; std::vector<std::pair<fc::ecc::public_key, uint64_t>> key_data;
for(auto p: public_keys) for (auto p : public_keys)
key_data.push_back(std::make_pair(fc::ecc::public_key::from_base58(p.first), p.second)); key_data.push_back(std::make_pair(fc::ecc::public_key::from_base58(p.first), p.second));
return generate_redeem_script(key_data); return generate_redeem_script(key_data);
} }

View file

@ -15,8 +15,8 @@ std::string p2wsh_address_from_redeem_script(const bytes &script, bitcoin_networ
bytes lock_script_for_redeem_script(const bytes &script); bytes lock_script_for_redeem_script(const bytes &script);
bytes lock_script_from_pw_address(const std::string &address); bytes lock_script_from_pw_address(const std::string &address);
std::string get_weighted_multisig_address(const std::vector<std::pair<std::string, uint64_t>>& public_keys); std::string get_weighted_multisig_address(const std::vector<std::pair<std::string, uint64_t>> &public_keys);
bytes get_weighted_multisig_redeem_script(std::vector<std::pair<std::string, uint64_t> > public_keys); bytes get_weighted_multisig_redeem_script(std::vector<std::pair<std::string, uint64_t>> public_keys);
std::vector<bytes> signatures_for_raw_transaction(const bytes &unsigned_tx, std::vector<bytes> signatures_for_raw_transaction(const bytes &unsigned_tx,
std::vector<uint64_t> in_amounts, std::vector<uint64_t> in_amounts,
@ -78,12 +78,11 @@ struct btc_outpoint {
struct btc_in { struct btc_in {
btc_in() = default; btc_in() = default;
btc_in(const btc_in&) = default; btc_in(const btc_in &) = default;
btc_in(btc_in&&) = default; btc_in(btc_in &&) = default;
btc_in& operator=(const btc_in&) = default; btc_in &operator=(const btc_in &) = default;
btc_in(const std::string& txid, uint32_t out, uint32_t sequence = 0xffffffff) btc_in(const std::string &txid, uint32_t out, uint32_t sequence = 0xffffffff) {
{
prevout.n = out; prevout.n = out;
prevout.hash = fc::uint256(txid); prevout.hash = fc::uint256(txid);
// reverse hash due to the different from_hex algo in bitcoin // reverse hash due to the different from_hex algo in bitcoin
@ -102,14 +101,13 @@ struct btc_in {
struct btc_out { struct btc_out {
btc_out() = default; btc_out() = default;
btc_out(const btc_out&) = default; btc_out(const btc_out &) = default;
btc_out(btc_out&&) = default; btc_out(btc_out &&) = default;
btc_out& operator=(const btc_out&) = default; btc_out &operator=(const btc_out &) = default;
btc_out(const std::string& address, uint64_t amount) : btc_out(const std::string &address, uint64_t amount) :
nValue(amount), nValue(amount),
scriptPubKey(lock_script_from_pw_address(address)) scriptPubKey(lock_script_from_pw_address(address)) {
{
} }
int64_t nValue; int64_t nValue;

View file

@ -106,8 +106,8 @@ private:
std::string sign_transaction(const std::string &transaction) override; std::string sign_transaction(const std::string &transaction) override;
std::string send_transaction(const std::string &transaction) override; std::string send_transaction(const std::string &transaction) override;
std::string sign_and_send_transaction_with_wallet(const std::string &tx_json); std::string sign_and_send_transaction_with_wallet(const std::string &tx_json);
std::string create_weighted_multisignature_wallet( const std::vector<std::pair<std::string, uint64_t>>& public_keys ); std::string create_weighted_multisignature_wallet(const std::vector<std::pair<std::string, uint64_t>> &public_keys);
void transfer_all_btc(const std::string& from_address, const vector<son_info>& from_sons, const std::string& to_address); void transfer_all_btc(const std::string &from_address, const vector<son_info> &from_sons, const std::string &to_address);
std::string transfer_deposit_to_primary_wallet(const son_wallet_deposit_object &swdo); 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); std::string transfer_withdrawal_from_primary_wallet(const son_wallet_withdraw_object &swwo);
void publish_btc_tx(const bitcoin_transaction_object &tx_object); void publish_btc_tx(const bitcoin_transaction_object &tx_object);

View file

@ -13,8 +13,8 @@
#include <graphene/chain/sidechain_transaction_object.hpp> #include <graphene/chain/sidechain_transaction_object.hpp>
#include <graphene/chain/son_wallet_object.hpp> #include <graphene/chain/son_wallet_object.hpp>
#include <graphene/chain/son_wallet_withdraw_object.hpp> #include <graphene/chain/son_wallet_withdraw_object.hpp>
#include <graphene/peerplays_sidechain/sidechain_net_manager.hpp>
#include <graphene/peerplays_sidechain/bitcoin_utils.hpp> #include <graphene/peerplays_sidechain/bitcoin_utils.hpp>
#include <graphene/peerplays_sidechain/sidechain_net_manager.hpp>
#include <graphene/utilities/key_conversion.hpp> #include <graphene/utilities/key_conversion.hpp>
namespace bpo = boost::program_options; namespace bpo = boost::program_options;
@ -352,7 +352,6 @@ void peerplays_sidechain_plugin_impl::son_processing() {
process_withdrawals(); process_withdrawals();
complete_signing(); complete_signing();
} }
} }

View file

@ -1,5 +1,5 @@
#include <graphene/peerplays_sidechain/sidechain_net_handler_bitcoin.hpp>
#include <graphene/peerplays_sidechain/bitcoin_utils.hpp> #include <graphene/peerplays_sidechain/bitcoin_utils.hpp>
#include <graphene/peerplays_sidechain/sidechain_net_handler_bitcoin.hpp>
#include <algorithm> #include <algorithm>
#include <thread> #include <thread>
@ -14,8 +14,8 @@
#include <fc/network/ip.hpp> #include <fc/network/ip.hpp>
#include <graphene/chain/account_object.hpp> #include <graphene/chain/account_object.hpp>
#include <graphene/chain/protocol/son_wallet.hpp>
#include <graphene/chain/proposal_object.hpp> #include <graphene/chain/proposal_object.hpp>
#include <graphene/chain/protocol/son_wallet.hpp>
#include <graphene/chain/sidechain_address_object.hpp> #include <graphene/chain/sidechain_address_object.hpp>
#include <graphene/chain/sidechain_transaction_object.hpp> #include <graphene/chain/sidechain_transaction_object.hpp>
#include <graphene/chain/son_info.hpp> #include <graphene/chain/son_info.hpp>
@ -553,7 +553,7 @@ void zmq_listener::handle_zmq() {
const auto header = std::string(static_cast<char *>(msg[0].data()), msg[0].size()); const auto header = std::string(static_cast<char *>(msg[0].data()), msg[0].size());
const auto block_hash = boost::algorithm::hex(std::string(static_cast<char *>(msg[1].data()), msg[1].size())); const auto block_hash = boost::algorithm::hex(std::string(static_cast<char *>(msg[1].data()), msg[1].size()));
event_received(block_hash); event_received(block_hash);
} catch (zmq::error_t& e) { } catch (zmq::error_t &e) {
} }
} }
} }
@ -624,13 +624,11 @@ void sidechain_net_handler_bitcoin::recreate_primary_wallet() {
auto active_sons = gpo.active_sons; auto active_sons = gpo.active_sons;
vector<pair<string, uint64_t>> son_pubkeys_bitcoin; vector<pair<string, uint64_t>> son_pubkeys_bitcoin;
for ( const son_info& si : active_sons ) { for (const son_info &si : active_sons) {
son_pubkeys_bitcoin.push_back( son_pubkeys_bitcoin.push_back(
make_pair( make_pair(
si.sidechain_public_keys.at(sidechain_type::bitcoin), si.sidechain_public_keys.at(sidechain_type::bitcoin),
si.total_votes si.total_votes));
)
);
} }
string address = create_weighted_multisignature_wallet(son_pubkeys_bitcoin); string address = create_weighted_multisignature_wallet(son_pubkeys_bitcoin);
@ -645,17 +643,17 @@ void sidechain_net_handler_bitcoin::recreate_primary_wallet() {
proposal_create_operation proposal_op; proposal_create_operation proposal_op;
proposal_op.fee_paying_account = plugin.get_son_object(plugin.get_current_son_id()).son_account; proposal_op.fee_paying_account = plugin.get_son_object(plugin.get_current_son_id()).son_account;
proposal_op.proposed_ops.emplace_back( op_wrapper( op ) ); proposal_op.proposed_ops.emplace_back(op_wrapper(op));
uint32_t lifetime = ( gpo.parameters.block_interval * gpo.active_witnesses.size() ) * 3; uint32_t lifetime = (gpo.parameters.block_interval * gpo.active_witnesses.size()) * 3;
proposal_op.expiration_time = time_point_sec( database.head_block_time().sec_since_epoch() + lifetime ); proposal_op.expiration_time = time_point_sec(database.head_block_time().sec_since_epoch() + lifetime);
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op); signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op);
try { try {
database.push_transaction(trx, database::validation_steps::skip_block_size_check); database.push_transaction(trx, database::validation_steps::skip_block_size_check);
if(plugin.app().p2p_node()) if (plugin.app().p2p_node())
plugin.app().p2p_node()->broadcast(net::trx_message(trx)); plugin.app().p2p_node()->broadcast(net::trx_message(trx));
} catch(fc::exception e){ } catch (fc::exception e) {
ilog("sidechain_net_handler: sending proposal for son wallet update operation failed with exception ${e}",("e", e.what())); ilog("sidechain_net_handler: sending proposal for son wallet update operation failed with exception ${e}", ("e", e.what()));
return; return;
} }
@ -681,13 +679,12 @@ void sidechain_net_handler_bitcoin::process_withdrawal(const son_wallet_withdraw
static bool has_enough_signatures(const bitcoin_transaction_object &tx_object) { static bool has_enough_signatures(const bitcoin_transaction_object &tx_object) {
// TODO: Verify with weights calculation // TODO: Verify with weights calculation
bool has_empty = false; bool has_empty = false;
for(auto s: tx_object.signatures) for (auto s : tx_object.signatures)
has_empty |= s.second.empty(); has_empty |= s.second.empty();
return !has_empty; return !has_empty;
} }
void sidechain_net_handler_bitcoin::process_signing() void sidechain_net_handler_bitcoin::process_signing() {
{
const auto &idx = plugin.database().get_index_type<proposal_index>().indices().get<by_id>(); const auto &idx = plugin.database().get_index_type<proposal_index>().indices().get<by_id>();
vector<proposal_id_type> proposals; vector<proposal_id_type> proposals;
for (const auto &proposal : idx) { for (const auto &proposal : idx) {
@ -703,10 +700,9 @@ void sidechain_net_handler_bitcoin::process_signing()
auto it = tx_object.signatures.find(son_id); auto it = tx_object.signatures.find(son_id);
if (it == tx_object.signatures.end()) if (it == tx_object.signatures.end())
continue; continue;
if (it->second.empty()) if (it->second.empty()) {
{
bitcoin_transaction_sign_operation op; bitcoin_transaction_sign_operation op;
son_object s_obj= plugin.get_son_object(son_id); son_object s_obj = plugin.get_son_object(son_id);
op.payer = s_obj.son_account; op.payer = s_obj.son_account;
op.proposal_id = proposal.id; op.proposal_id = proposal.id;
fc::ecc::private_key k = plugin.get_private_key(son_id); fc::ecc::private_key k = plugin.get_private_key(son_id);
@ -715,10 +711,10 @@ void sidechain_net_handler_bitcoin::process_signing()
signed_transaction trx = plugin.database().create_signed_transaction(k, op); signed_transaction trx = plugin.database().create_signed_transaction(k, op);
try { try {
plugin.database().push_transaction(trx, database::validation_steps::skip_block_size_check); plugin.database().push_transaction(trx, database::validation_steps::skip_block_size_check);
if(plugin.app().p2p_node()) if (plugin.app().p2p_node())
plugin.app().p2p_node()->broadcast(net::trx_message(trx)); plugin.app().p2p_node()->broadcast(net::trx_message(trx));
} catch(fc::exception e){ } catch (fc::exception e) {
ilog("sidechain_net_handler: bitcoin transaction signing failed with exception ${e}",("e", e.what())); ilog("sidechain_net_handler: bitcoin transaction signing failed with exception ${e}", ("e", e.what()));
return; return;
} }
} }
@ -726,37 +722,36 @@ void sidechain_net_handler_bitcoin::process_signing()
} }
} }
void sidechain_net_handler_bitcoin::complete_signing() void sidechain_net_handler_bitcoin::complete_signing() {
{
const auto &idx = plugin.database().get_index_type<bitcoin_transaction_index>().indices().get<by_processed>(); const auto &idx = plugin.database().get_index_type<bitcoin_transaction_index>().indices().get<by_processed>();
const auto &idx_range = idx.equal_range(false); const auto &idx_range = idx.equal_range(false);
std::for_each(idx_range.first, idx_range.second, std::for_each(idx_range.first, idx_range.second,
[&](const bitcoin_transaction_object &tx_object) { [&](const bitcoin_transaction_object &tx_object) {
// check if all signatures collected // check if all signatures collected
if (has_enough_signatures(tx_object)) { if (has_enough_signatures(tx_object)) {
publish_btc_tx(tx_object); publish_btc_tx(tx_object);
bitcoin_send_transaction_process_operation op; bitcoin_send_transaction_process_operation op;
op.payer = GRAPHENE_SON_ACCOUNT; op.payer = GRAPHENE_SON_ACCOUNT;
op.bitcoin_transaction_id = tx_object.id; op.bitcoin_transaction_id = tx_object.id;
const chain::global_property_object& gpo = database.get_global_properties(); const chain::global_property_object &gpo = database.get_global_properties();
proposal_create_operation proposal_op; proposal_create_operation proposal_op;
proposal_op.fee_paying_account = plugin.get_son_object(plugin.get_current_son_id()).son_account; proposal_op.fee_paying_account = plugin.get_son_object(plugin.get_current_son_id()).son_account;
proposal_op.proposed_ops.emplace_back( op_wrapper( op ) ); proposal_op.proposed_ops.emplace_back(op_wrapper(op));
uint32_t lifetime = ( gpo.parameters.block_interval * gpo.active_witnesses.size() ) * 3; uint32_t lifetime = (gpo.parameters.block_interval * gpo.active_witnesses.size()) * 3;
proposal_op.expiration_time = time_point_sec( database.head_block_time().sec_since_epoch() + lifetime ); proposal_op.expiration_time = time_point_sec(database.head_block_time().sec_since_epoch() + lifetime);
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op); signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op);
try { try {
database.push_transaction(trx, database::validation_steps::skip_block_size_check); database.push_transaction(trx, database::validation_steps::skip_block_size_check);
if(plugin.app().p2p_node()) if (plugin.app().p2p_node())
plugin.app().p2p_node()->broadcast(net::trx_message(trx)); plugin.app().p2p_node()->broadcast(net::trx_message(trx));
} catch(fc::exception e){ } catch (fc::exception e) {
ilog("sidechain_net_handler_bitcoin: sending proposal for bitcoin send operation failed with exception ${e}",("e", e.what())); ilog("sidechain_net_handler_bitcoin: sending proposal for bitcoin send operation failed with exception ${e}", ("e", e.what()));
return; return;
} }
} }
}); });
} }
std::string sidechain_net_handler_bitcoin::create_multisignature_wallet(const std::vector<std::string> public_keys) { std::string sidechain_net_handler_bitcoin::create_multisignature_wallet(const std::vector<std::string> public_keys) {
@ -781,8 +776,7 @@ std::string sidechain_net_handler_bitcoin::send_transaction(const std::string &t
return ""; return "";
} }
std::string sidechain_net_handler_bitcoin::sign_and_send_transaction_with_wallet ( const std::string& tx_json ) std::string sidechain_net_handler_bitcoin::sign_and_send_transaction_with_wallet(const std::string &tx_json) {
{
if (!wallet_password.empty()) { if (!wallet_password.empty()) {
bitcoin_client->walletpassphrase(wallet_password, 60); bitcoin_client->walletpassphrase(wallet_password, 60);
} }
@ -810,8 +804,7 @@ std::string sidechain_net_handler_bitcoin::sign_and_send_transaction_with_wallet
return reply_str; return reply_str;
} }
void sidechain_net_handler_bitcoin::transfer_all_btc(const std::string& from_address, const vector<son_info>& from_sons, const std::string& to_address) void sidechain_net_handler_bitcoin::transfer_all_btc(const std::string &from_address, const vector<son_info> &from_sons, const std::string &to_address) {
{
uint64_t fee_rate = bitcoin_client->estimatesmartfee(); uint64_t fee_rate = bitcoin_client->estimatesmartfee();
uint64_t min_fee_rate = 1000; uint64_t min_fee_rate = 1000;
fee_rate = std::max(fee_rate, min_fee_rate); fee_rate = std::max(fee_rate, min_fee_rate);
@ -820,16 +813,16 @@ void sidechain_net_handler_bitcoin::transfer_all_btc(const std::string& from_add
double total_amount = 0.0; double total_amount = 0.0;
std::vector<btc_txout> unspent_utxo = bitcoin_client->listunspent_by_address_and_amount(from_address, 0); std::vector<btc_txout> unspent_utxo = bitcoin_client->listunspent_by_address_and_amount(from_address, 0);
if(unspent_utxo.size() == 0) { if (unspent_utxo.size() == 0) {
wlog("Failed to find UTXOs to spend for ${pw}",("pw", from_address)); wlog("Failed to find UTXOs to spend for ${pw}", ("pw", from_address));
return; return;
} else { } else {
for(const auto& utx: unspent_utxo) { for (const auto &utx : unspent_utxo) {
total_amount += utx.amount_; total_amount += utx.amount_;
} }
if(min_amount >= total_amount) { if (min_amount >= total_amount) {
wlog("Failed not enough BTC to transfer from ${fa}",("fa", from_address)); wlog("Failed not enough BTC to transfer from ${fa}", ("fa", from_address));
return; return;
} }
} }
@ -839,24 +832,21 @@ void sidechain_net_handler_bitcoin::transfer_all_btc(const std::string& from_add
tx.nVersion = 2; tx.nVersion = 2;
tx.nLockTime = 0; tx.nLockTime = 0;
std::vector<uint64_t> amounts; std::vector<uint64_t> amounts;
for(const auto& utx: unspent_utxo) for (const auto &utx : unspent_utxo) {
{
tx.vin.push_back(btc_in(utx.txid_, utx.out_num_)); tx.vin.push_back(btc_in(utx.txid_, utx.out_num_));
amounts.push_back(uint64_t(utx.amount_ * 100000000.0)); amounts.push_back(uint64_t(utx.amount_ * 100000000.0));
} }
tx.vout.push_back(btc_out(to_address, uint64_t((total_amount - min_amount) * 100000000.0))); tx.vout.push_back(btc_out(to_address, uint64_t((total_amount - min_amount) * 100000000.0)));
std::vector<std::pair<fc::ecc::public_key, uint64_t> > key_data; std::vector<std::pair<fc::ecc::public_key, uint64_t>> key_data;
for(auto si: from_sons) for (auto si : from_sons) {
{
fc::ecc::public_key pk = si.signing_key; fc::ecc::public_key pk = si.signing_key;
key_data.push_back(std::make_pair(pk, si.total_votes)); key_data.push_back(std::make_pair(pk, si.total_votes));
} }
std::sort(key_data.begin(), key_data.end(), std::sort(key_data.begin(), key_data.end(),
[](std::pair<fc::ecc::public_key, uint64_t> p1, std::pair<fc::ecc::public_key, uint64_t> p2){ [](std::pair<fc::ecc::public_key, uint64_t> p1, std::pair<fc::ecc::public_key, uint64_t> p2) {
return (p1.second > p2.second); return (p1.second > p2.second);
} });
);
bytes from_redeem_script = generate_redeem_script(key_data); bytes from_redeem_script = generate_redeem_script(key_data);
bitcoin_transaction_send_operation op; bitcoin_transaction_send_operation op;
@ -866,34 +856,30 @@ void sidechain_net_handler_bitcoin::transfer_all_btc(const std::string& from_add
tx.to_bytes(op.unsigned_tx); tx.to_bytes(op.unsigned_tx);
// add signatures // add signatures
std::set<son_id_type> plugin_sons = plugin.get_sons(); std::set<son_id_type> plugin_sons = plugin.get_sons();
for(auto si: from_sons) for (auto si : from_sons) {
{ if (plugin_sons.find(si.son_id) != plugin_sons.end()) {
if (plugin_sons.find(si.son_id) != plugin_sons.end())
{
fc::ecc::private_key k = plugin.get_private_key(si.son_id); fc::ecc::private_key k = plugin.get_private_key(si.son_id);
std::vector<bytes> signatures = signatures_for_raw_transaction(op.unsigned_tx, amounts, from_redeem_script, k); std::vector<bytes> signatures = signatures_for_raw_transaction(op.unsigned_tx, amounts, from_redeem_script, k);
op.signatures[si.son_id] = signatures; op.signatures[si.son_id] = signatures;
} } else {
else
{
op.signatures[si.son_id]; op.signatures[si.son_id];
} }
} }
const chain::global_property_object& gpo = database.get_global_properties(); const chain::global_property_object &gpo = database.get_global_properties();
proposal_create_operation proposal_op; proposal_create_operation proposal_op;
proposal_op.fee_paying_account = plugin.get_son_object(plugin.get_current_son_id()).son_account; proposal_op.fee_paying_account = plugin.get_son_object(plugin.get_current_son_id()).son_account;
proposal_op.proposed_ops.emplace_back( op_wrapper( op ) ); proposal_op.proposed_ops.emplace_back(op_wrapper(op));
uint32_t lifetime = ( gpo.parameters.block_interval * gpo.active_witnesses.size() ) * 3; uint32_t lifetime = (gpo.parameters.block_interval * gpo.active_witnesses.size()) * 3;
proposal_op.expiration_time = time_point_sec( database.head_block_time().sec_since_epoch() + lifetime ); proposal_op.expiration_time = time_point_sec(database.head_block_time().sec_since_epoch() + lifetime);
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op); signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op);
try { try {
database.push_transaction(trx, database::validation_steps::skip_block_size_check); database.push_transaction(trx, database::validation_steps::skip_block_size_check);
if(plugin.app().p2p_node()) if (plugin.app().p2p_node())
plugin.app().p2p_node()->broadcast(net::trx_message(trx)); plugin.app().p2p_node()->broadcast(net::trx_message(trx));
} catch(fc::exception e){ } catch (fc::exception e) {
ilog("sidechain_net_handler: sending proposal for son wallet update operation failed with exception ${e}",("e", e.what())); ilog("sidechain_net_handler: sending proposal for son wallet update operation failed with exception ${e}", ("e", e.what()));
return; return;
} }
} }
@ -926,7 +912,7 @@ std::string sidechain_net_handler_bitcoin::transfer_deposit_to_primary_wallet(co
bytes unsigned_tx; bytes unsigned_tx;
tx.to_bytes(unsigned_tx); tx.to_bytes(unsigned_tx);
std::string reply_str = fc::to_hex((char*)&unsigned_tx[0], unsigned_tx.size()); std::string reply_str = fc::to_hex((char *)&unsigned_tx[0], unsigned_tx.size());
return sign_and_send_transaction_with_wallet(reply_str); return sign_and_send_transaction_with_wallet(reply_str);
} }
@ -966,30 +952,26 @@ std::string sidechain_net_handler_bitcoin::transfer_withdrawal_from_primary_wall
tx.nLockTime = 0; tx.nLockTime = 0;
tx.hasWitness = true; tx.hasWitness = true;
std::vector<uint64_t> amounts; std::vector<uint64_t> amounts;
for(const auto& utxo: unspent_utxo) for (const auto &utxo : unspent_utxo) {
{
tx.vin.push_back(btc_in(utxo.txid_, utxo.amount_)); tx.vin.push_back(btc_in(utxo.txid_, utxo.amount_));
amounts.push_back(uint64_t(utxo.amount_ * 100000000.0)); amounts.push_back(uint64_t(utxo.amount_ * 100000000.0));
} }
tx.vout.push_back(btc_out(swwo.withdraw_address, swwo.withdraw_amount.value)); tx.vout.push_back(btc_out(swwo.withdraw_address, swwo.withdraw_amount.value));
if((total_amount - min_amount) > 0.0) if ((total_amount - min_amount) > 0.0) {
{
tx.vout.push_back(btc_out(pw_address, (total_amount - min_amount) * 100000000.0)); tx.vout.push_back(btc_out(pw_address, (total_amount - min_amount) * 100000000.0));
} }
auto from_sons = obj->sons; auto from_sons = obj->sons;
std::vector<std::pair<fc::ecc::public_key, uint64_t> > key_data; std::vector<std::pair<fc::ecc::public_key, uint64_t>> key_data;
for(auto si: from_sons) for (auto si : from_sons) {
{
fc::ecc::public_key pk = si.signing_key; fc::ecc::public_key pk = si.signing_key;
key_data.push_back(std::make_pair(pk, si.total_votes)); key_data.push_back(std::make_pair(pk, si.total_votes));
} }
std::sort(key_data.begin(), key_data.end(), std::sort(key_data.begin(), key_data.end(),
[](std::pair<fc::ecc::public_key, uint64_t> p1, std::pair<fc::ecc::public_key, uint64_t> p2){ [](std::pair<fc::ecc::public_key, uint64_t> p1, std::pair<fc::ecc::public_key, uint64_t> p2) {
return (p1.second > p2.second); return (p1.second > p2.second);
} });
);
bytes from_redeem_script = generate_redeem_script(key_data); bytes from_redeem_script = generate_redeem_script(key_data);
bitcoin_transaction_send_operation op; bitcoin_transaction_send_operation op;
@ -999,48 +981,44 @@ std::string sidechain_net_handler_bitcoin::transfer_withdrawal_from_primary_wall
tx.to_bytes(op.unsigned_tx); tx.to_bytes(op.unsigned_tx);
// add signatures // add signatures
std::set<son_id_type> plugin_sons = plugin.get_sons(); std::set<son_id_type> plugin_sons = plugin.get_sons();
for(auto si: from_sons) for (auto si : from_sons) {
{ if (plugin_sons.find(si.son_id) != plugin_sons.end()) {
if (plugin_sons.find(si.son_id) != plugin_sons.end())
{
fc::ecc::private_key k = plugin.get_private_key(si.son_id); fc::ecc::private_key k = plugin.get_private_key(si.son_id);
std::vector<bytes> signatures = signatures_for_raw_transaction(op.unsigned_tx, amounts, from_redeem_script, k); std::vector<bytes> signatures = signatures_for_raw_transaction(op.unsigned_tx, amounts, from_redeem_script, k);
op.signatures[si.son_id] = signatures; op.signatures[si.son_id] = signatures;
} } else {
else
{
op.signatures[si.son_id]; op.signatures[si.son_id];
} }
} }
const chain::global_property_object& gpo = database.get_global_properties(); const chain::global_property_object &gpo = database.get_global_properties();
proposal_create_operation proposal_op; proposal_create_operation proposal_op;
proposal_op.fee_paying_account = plugin.get_son_object(plugin.get_current_son_id()).son_account; proposal_op.fee_paying_account = plugin.get_son_object(plugin.get_current_son_id()).son_account;
proposal_op.proposed_ops.emplace_back( op_wrapper( op ) ); proposal_op.proposed_ops.emplace_back(op_wrapper(op));
uint32_t lifetime = ( gpo.parameters.block_interval * gpo.active_witnesses.size() ) * 3; uint32_t lifetime = (gpo.parameters.block_interval * gpo.active_witnesses.size()) * 3;
proposal_op.expiration_time = time_point_sec( database.head_block_time().sec_since_epoch() + lifetime ); proposal_op.expiration_time = time_point_sec(database.head_block_time().sec_since_epoch() + lifetime);
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op); signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op);
try { try {
database.push_transaction(trx, database::validation_steps::skip_block_size_check); database.push_transaction(trx, database::validation_steps::skip_block_size_check);
if(plugin.app().p2p_node()) if (plugin.app().p2p_node())
plugin.app().p2p_node()->broadcast(net::trx_message(trx)); plugin.app().p2p_node()->broadcast(net::trx_message(trx));
} catch(fc::exception e){ } catch (fc::exception e) {
ilog("sidechain_net_handler: sending proposal for son wallet update operation failed with exception ${e}",("e", e.what())); ilog("sidechain_net_handler: sending proposal for son wallet update operation failed with exception ${e}", ("e", e.what()));
return ""; return "";
} }
return ""; return "";
} }
void sidechain_net_handler_bitcoin::publish_btc_tx(const bitcoin_transaction_object &tx_object) void sidechain_net_handler_bitcoin::publish_btc_tx(const bitcoin_transaction_object &tx_object) {
{
std::vector<std::vector<bytes>> signatures; std::vector<std::vector<bytes>> signatures;
signatures.resize(tx_object.signatures.size()); signatures.resize(tx_object.signatures.size());
std::transform(tx_object.signatures.begin(), tx_object.signatures.end(), std::transform(tx_object.signatures.begin(), tx_object.signatures.end(),
signatures.begin(), [](const std::pair<son_id_type, std::vector<bytes>>& p) { return p.second; } signatures.begin(), [](const std::pair<son_id_type, std::vector<bytes>> &p) {
); return p.second;
});
bytes signed_tx = add_signatures_to_unsigned_tx(tx_object.unsigned_tx, signatures, tx_object.redeem_script); bytes signed_tx = add_signatures_to_unsigned_tx(tx_object.unsigned_tx, signatures, tx_object.redeem_script);
bitcoin_client->sendrawtransaction(fc::to_hex((const char*)&signed_tx[0], signed_tx.size())); bitcoin_client->sendrawtransaction(fc::to_hex((const char *)&signed_tx[0], signed_tx.size()));
} }
void sidechain_net_handler_bitcoin::handle_event(const std::string &event_data) { void sidechain_net_handler_bitcoin::handle_event(const std::string &event_data) {