Deposit/withdraw process and sidechain transaction creation in single proposal

This commit is contained in:
Srdjan Obucina 2020-04-19 04:04:37 +02:00
parent 1caaab2cef
commit 9c550956dc
5 changed files with 167 additions and 155 deletions

View file

@ -16,12 +16,26 @@ add_library( peerplays_sidechain
)
if (ENABLE_DEV_FEATURES)
message ("Dev features enabled")
target_compile_definitions(peerplays_sidechain PRIVATE ENABLE_DEV_FEATURES)
set(ENABLE_MULTIPLE_SONS 1)
set(ENABLE_PEERPLAYS_ASSET_DEPOSITS 1)
endif()
unset(ENABLE_DEV_FEATURES)
unset(ENABLE_DEV_FEATURES CACHE)
if (ENABLE_MULTIPLE_SONS)
message ("Multiple SONs per software instance are supported")
target_compile_definitions(peerplays_sidechain PRIVATE ENABLE_MULTIPLE_SONS)
endif()
unset(ENABLE_MULTIPLE_SONS)
unset(ENABLE_MULTIPLE_SONS CACHE)
if (ENABLE_PEERPLAYS_ASSET_DEPOSITS)
message ("Depositing Peerplays assets enabled")
target_compile_definitions(peerplays_sidechain PRIVATE ENABLE_PEERPLAYS_ASSET_DEPOSITS)
endif()
unset(ENABLE_PEERPLAYS_ASSET_DEPOSITS)
unset(ENABLE_PEERPLAYS_ASSET_DEPOSITS CACHE)
target_link_libraries( peerplays_sidechain graphene_chain graphene_app fc zmq )
target_include_directories( peerplays_sidechain
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )

View file

@ -143,7 +143,7 @@ void peerplays_sidechain_plugin_impl::plugin_initialize(const boost::program_opt
boost::insert(sons, fc::json::from_string(options.at("son-ids").as<string>()).as<vector<chain::son_id_type>>(5));
config_ready_son = config_ready_son && !sons.empty();
#ifndef ENABLE_DEV_FEATURES
#ifndef ENABLE_MULTIPLE_SONS
if (sons.size() > 1) {
FC_THROW("Invalid configuration, multiple SON IDs provided");
}
@ -346,6 +346,7 @@ void peerplays_sidechain_plugin_impl::heartbeat_loop() {
chain::signed_transaction trx = d.create_signed_transaction(plugin.get_private_key(son_id), op);
fc::future<bool> fut = fc::async([&]() {
try {
trx.validate();
d.push_transaction(trx, database::validation_steps::skip_block_size_check);
if (plugin.app().p2p_node())
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
@ -455,6 +456,7 @@ void peerplays_sidechain_plugin_impl::approve_proposals() {
chain::signed_transaction trx = plugin.database().create_signed_transaction(plugin.get_private_key(son_id), puo);
fc::future<bool> fut = fc::async([&]() {
try {
trx.validate();
plugin.database().push_transaction(trx, database::validation_steps::skip_block_size_check);
if (plugin.app().p2p_node())
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
@ -530,6 +532,7 @@ void peerplays_sidechain_plugin_impl::create_son_down_proposals() {
chain::signed_transaction trx = d.create_signed_transaction(plugin.get_private_key(get_son_object(my_son_id).signing_key), op);
fc::future<bool> fut = fc::async([&]() {
try {
trx.validate();
d.push_transaction(trx, database::validation_steps::skip_block_size_check);
if (plugin.app().p2p_node())
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
@ -564,6 +567,7 @@ void peerplays_sidechain_plugin_impl::create_son_deregister_proposals() {
chain::signed_transaction trx = d.create_signed_transaction(plugin.get_private_key(get_son_object(my_son_id).signing_key), *op);
fc::future<bool> fut = fc::async([&]() {
try {
trx.validate();
d.push_transaction(trx, database::validation_steps::skip_block_size_check);
if (plugin.app().p2p_node())
plugin.app().p2p_node()->broadcast(net::trx_message(trx));

View file

@ -92,11 +92,6 @@ bool sidechain_net_handler::proposal_exists(int32_t operation_tag, const object_
break;
}
case chain::operation::tag<chain::sidechain_transaction_create_operation>::value: {
result = (op_obj_idx_0.get<sidechain_transaction_create_operation>().object_id == object_id);
break;
}
default:
return false;
}
@ -116,11 +111,12 @@ bool sidechain_net_handler::approve_proposal(const proposal_id_type &proposal_id
op.proposal = proposal_id;
op.active_approvals_to_add = {plugin.get_son_object(son_id).son_account};
signed_transaction tx = database.create_signed_transaction(plugin.get_private_key(son_id), op);
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(son_id), op);
try {
database.push_transaction(tx, database::validation_steps::skip_block_size_check);
trx.validate();
database.push_transaction(trx, database::validation_steps::skip_block_size_check);
if (plugin.app().p2p_node())
plugin.app().p2p_node()->broadcast(net::trx_message(tx));
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
return true;
} catch (fc::exception e) {
elog("Sending approval from ${son_id} for proposal ${proposal_id} failed with exception ${e}",
@ -151,7 +147,7 @@ void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_
fc::to_string(btc_asset_id.type_id) + "." +
fc::to_string((uint64_t)btc_asset_id.instance);
#ifdef ENABLE_DEV_FEATURES
#ifdef ENABLE_PEERPLAYS_ASSET_DEPOSITS
// Accepts BTC and peerplays asset deposits
bool deposit_condition = ((sed.peerplays_to == gpo.parameters.son_account()) && (sed.sidechain_currency.compare(btc_asset_id_str) != 0));
bool withdraw_condition = ((sed.peerplays_to == gpo.parameters.son_account()) && (sed.sidechain_currency.compare(btc_asset_id_str) == 0));
@ -185,6 +181,7 @@ void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(son_id), op);
try {
trx.validate();
database.push_transaction(trx, database::validation_steps::skip_block_size_check);
if (plugin.app().p2p_node())
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
@ -226,6 +223,7 @@ void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(son_id), op);
try {
trx.validate();
database.push_transaction(trx, database::validation_steps::skip_block_size_check);
if (plugin.app().p2p_node())
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
@ -264,6 +262,14 @@ void sidechain_net_handler::process_proposals() {
op_obj_idx_0 = po->proposed_transaction.operations[0];
}
int32_t op_idx_1 = -1;
chain::operation op_obj_idx_1;
if (po->proposed_transaction.operations.size() >= 2) {
op_idx_1 = po->proposed_transaction.operations[1].which();
op_obj_idx_1 = po->proposed_transaction.operations[1];
}
switch (op_idx_0) {
case chain::operation::tag<chain::son_wallet_update_operation>::value: {
should_process = (op_obj_idx_0.get<son_wallet_update_operation>().sidechain == sidechain);
@ -285,17 +291,11 @@ void sidechain_net_handler::process_proposals() {
const auto &idx = database.get_index_type<son_wallet_withdraw_index>().indices().get<by_id>();
const auto swwo = idx.find(swwo_id);
if (swwo != idx.end()) {
should_process = (swwo->sidechain == sidechain);
should_process = (swwo->withdraw_sidechain == sidechain);
}
break;
}
case chain::operation::tag<chain::sidechain_transaction_create_operation>::value: {
sidechain_type sc = op_obj_idx_0.get<sidechain_transaction_create_operation>().sidechain;
should_process = (sc == sidechain);
break;
}
case chain::operation::tag<chain::sidechain_transaction_settle_operation>::value: {
sidechain_transaction_id_type st_id = op_obj_idx_0.get<sidechain_transaction_settle_operation>().sidechain_transaction_id;
const auto &idx = database.get_index_type<sidechain_transaction_index>().indices().get<by_id>();
@ -343,8 +343,9 @@ void sidechain_net_handler::process_deposits() {
const auto &idx_range = idx.equal_range(std::make_tuple(sidechain, true, false));
std::for_each(idx_range.first, idx_range.second, [&](const son_wallet_deposit_object &swdo) {
if (swdo.id == object_id_type(0, 0, 0))
if (swdo.id == object_id_type(0, 0, 0)) {
return;
}
ilog("Deposit to process: ${swdo}", ("swdo", swdo));
@ -354,28 +355,6 @@ void sidechain_net_handler::process_deposits() {
wlog("Deposit not processed: ${swdo}", ("swdo", swdo));
return;
}
const chain::global_property_object &gpo = database.get_global_properties();
son_wallet_deposit_process_operation swdp_op;
swdp_op.payer = gpo.parameters.son_account();
swdp_op.son_wallet_deposit_id = swdo.id;
proposal_create_operation proposal_op;
proposal_op.fee_paying_account = plugin.get_current_son_object().son_account;
proposal_op.proposed_ops.emplace_back(swdp_op);
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);
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op);
trx.validate();
try {
database.push_transaction(trx, database::validation_steps::skip_block_size_check);
if (plugin.app().p2p_node())
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
} catch (fc::exception e) {
elog("Sending proposal for son wallet deposit process operation failed with exception ${e}", ("e", e.what()));
}
});
}
@ -388,8 +367,9 @@ void sidechain_net_handler::process_withdrawals() {
const auto &idx_range = idx.equal_range(std::make_tuple(sidechain, true, false));
std::for_each(idx_range.first, idx_range.second, [&](const son_wallet_withdraw_object &swwo) {
if (swwo.id == object_id_type(0, 0, 0))
if (swwo.id == object_id_type(0, 0, 0)) {
return;
}
ilog("Withdraw to process: ${swwo}", ("swwo", swwo));
@ -399,28 +379,6 @@ void sidechain_net_handler::process_withdrawals() {
wlog("Withdraw not processed: ${swwo}", ("swwo", swwo));
return;
}
const chain::global_property_object &gpo = database.get_global_properties();
son_wallet_withdraw_process_operation swwp_op;
swwp_op.payer = gpo.parameters.son_account();
swwp_op.son_wallet_withdraw_id = swwo.id;
proposal_create_operation proposal_op;
proposal_op.fee_paying_account = plugin.get_current_son_object().son_account;
proposal_op.proposed_ops.emplace_back(swwp_op);
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);
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op);
trx.validate();
try {
database.push_transaction(trx, database::validation_steps::skip_block_size_check);
if (plugin.app().p2p_node())
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
} catch (fc::exception e) {
elog("Sending proposal for son wallet withdraw process operation failed with exception ${e}", ("e", e.what()));
}
});
}
@ -429,8 +387,9 @@ void sidechain_net_handler::process_sidechain_transactions() {
const auto &idx_range = idx.equal_range(std::make_tuple(sidechain, sidechain_transaction_status::valid));
std::for_each(idx_range.first, idx_range.second, [&](const sidechain_transaction_object &sto) {
if (sto.id == object_id_type(0, 0, 0))
if (sto.id == object_id_type(0, 0, 0)) {
return;
}
ilog("Sidechain transaction to process: ${sto}", ("sto", sto.id));
@ -447,8 +406,8 @@ void sidechain_net_handler::process_sidechain_transactions() {
sts_op.signature = processed_sidechain_tx;
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), sts_op);
trx.validate();
try {
trx.validate();
database.push_transaction(trx, database::validation_steps::skip_block_size_check);
if (plugin.app().p2p_node())
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
@ -463,8 +422,9 @@ void sidechain_net_handler::send_sidechain_transactions() {
const auto &idx_range = idx.equal_range(std::make_tuple(sidechain, sidechain_transaction_status::complete));
std::for_each(idx_range.first, idx_range.second, [&](const sidechain_transaction_object &sto) {
if (sto.id == object_id_type(0, 0, 0))
if (sto.id == object_id_type(0, 0, 0)) {
return;
}
ilog("Sidechain transaction to send: ${sto}", ("sto", sto.id));
@ -481,8 +441,8 @@ void sidechain_net_handler::send_sidechain_transactions() {
sts_op.sidechain_transaction = sidechain_transaction;
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), sts_op);
trx.validate();
try {
trx.validate();
database.push_transaction(trx, database::validation_steps::skip_block_size_check);
if (plugin.app().p2p_node())
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
@ -497,6 +457,10 @@ void sidechain_net_handler::settle_sidechain_transactions() {
const auto &idx_range = idx.equal_range(std::make_tuple(sidechain, sidechain_transaction_status::sent));
std::for_each(idx_range.first, idx_range.second, [&](const sidechain_transaction_object &sto) {
if (sto.id == object_id_type(0, 0, 0)) {
return;
}
ilog("Sidechain transaction to settle: ${sto}", ("sto", sto.id));
int64_t settle_amount = settle_sidechain_transaction(sto);
@ -508,12 +472,14 @@ void sidechain_net_handler::settle_sidechain_transactions() {
const chain::global_property_object &gpo = database.get_global_properties();
proposal_create_operation proposal_op;
proposal_op.fee_paying_account = plugin.get_current_son_object().son_account;
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);
sidechain_transaction_settle_operation sts_op;
sts_op.payer = gpo.parameters.son_account();
sts_op.sidechain_transaction_id = sto.id;
proposal_create_operation proposal_op;
proposal_op.fee_paying_account = plugin.get_current_son_object().son_account;
proposal_op.proposed_ops.emplace_back(sts_op);
if (settle_amount != 0) {
@ -535,12 +501,9 @@ void sidechain_net_handler::settle_sidechain_transactions() {
}
}
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);
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op);
trx.validate();
try {
trx.validate();
database.push_transaction(trx, database::validation_steps::skip_block_size_check);
if (plugin.app().p2p_node())
plugin.app().p2p_node()->broadcast(net::trx_message(trx));

View file

@ -1015,6 +1015,8 @@ bool sidechain_net_handler_bitcoin::process_proposal(const proposal_object &po)
}
case chain::operation::tag<chain::son_wallet_deposit_process_operation>::value: {
bool process_ok = false;
bool transaction_ok = false;
son_wallet_deposit_id_type swdo_id = op_obj_idx_0.get<son_wallet_deposit_process_operation>().son_wallet_deposit_id;
const auto &idx = database.get_index_type<son_wallet_deposit_index>().indices().get<by_id>();
const auto swdo = idx.find(swdo_id);
@ -1050,49 +1052,99 @@ bool sidechain_net_handler_bitcoin::process_proposal(const proposal_object &po)
}
}
should_approve = (swdo_txid == tx_txid) &&
(swdo_address == tx_address) &&
(swdo_amount == tx_amount) &&
(swdo_vout == tx_vout) &&
(gpo.parameters.son_bitcoin_min_tx_confirmations() <= tx_confirmations);
process_ok = (swdo_txid == tx_txid) &&
(swdo_address == tx_address) &&
(swdo_amount == tx_amount) &&
(swdo_vout == tx_vout) &&
(gpo.parameters.son_bitcoin_min_tx_confirmations() <= tx_confirmations);
}
object_id_type object_id = op_obj_idx_1.get<sidechain_transaction_create_operation>().object_id;
std::string op_tx_str = op_obj_idx_1.get<sidechain_transaction_create_operation>().transaction;
const auto &st_idx = database.get_index_type<sidechain_transaction_index>().indices().get<by_object_id>();
const auto st = st_idx.find(object_id);
if (st == st_idx.end()) {
std::string tx_str = "";
if (object_id.is<son_wallet_deposit_id_type>()) {
const auto &idx = database.get_index_type<son_wallet_deposit_index>().indices().get<by_id>();
const auto swdo = idx.find(object_id);
if (swdo != idx.end()) {
tx_str = create_deposit_transaction(*swdo);
}
}
if (object_id.is<son_wallet_withdraw_id_type>()) {
const auto &idx = database.get_index_type<son_wallet_withdraw_index>().indices().get<by_id>();
const auto swwo = idx.find(object_id);
if (swwo != idx.end()) {
tx_str = create_withdrawal_transaction(*swwo);
}
}
transaction_ok = (op_tx_str == tx_str);
}
}
should_approve = process_ok &&
transaction_ok;
break;
}
case chain::operation::tag<chain::son_wallet_withdraw_process_operation>::value: {
should_approve = false;
break;
}
bool process_ok = false;
bool transaction_ok = false;
son_wallet_withdraw_id_type swwo_id = op_obj_idx_0.get<son_wallet_withdraw_process_operation>().son_wallet_withdraw_id;
const auto &idx = database.get_index_type<son_wallet_withdraw_index>().indices().get<by_id>();
const auto swwo = idx.find(swwo_id);
if (swwo != idx.end()) {
case chain::operation::tag<chain::sidechain_transaction_create_operation>::value: {
object_id_type object_id = op_obj_idx_0.get<sidechain_transaction_create_operation>().object_id;
std::string op_tx_str = op_obj_idx_0.get<sidechain_transaction_create_operation>().transaction;
uint32_t swwo_block_num = swwo->block_num;
std::string swwo_peerplays_transaction_id = swwo->peerplays_transaction_id;
uint32_t swwo_op_idx = std::stoll(swwo->peerplays_uid.substr(swwo->peerplays_uid.find_last_of("-") + 1));
const auto &st_idx = database.get_index_type<sidechain_transaction_index>().indices().get<by_object_id>();
const auto st = st_idx.find(object_id);
if (st == st_idx.end()) {
const auto &block = database.fetch_block_by_number(swwo_block_num);
std::string tx_str = "";
for (const auto &tx : block->transactions) {
if (tx.id().str() == swwo_peerplays_transaction_id) {
operation op = tx.operations[swwo_op_idx];
transfer_operation t_op = op.get<transfer_operation>();
if (object_id.is<son_wallet_deposit_id_type>()) {
const auto &idx = database.get_index_type<son_wallet_deposit_index>().indices().get<by_id>();
const auto swdo = idx.find(object_id);
if (swdo != idx.end()) {
tx_str = create_deposit_transaction(*swdo);
price asset_price = database.get<asset_object>(t_op.amount.asset_id).options.core_exchange_rate;
asset peerplays_asset = asset(t_op.amount.amount * asset_price.base.amount / asset_price.quote.amount);
process_ok = (t_op.to == gpo.parameters.son_account()) &&
(swwo->peerplays_from == t_op.from) &&
(swwo->peerplays_asset == peerplays_asset);
break;
}
}
if (object_id.is<son_wallet_withdraw_id_type>()) {
const auto &idx = database.get_index_type<son_wallet_withdraw_index>().indices().get<by_id>();
const auto swwo = idx.find(object_id);
if (swwo != idx.end()) {
tx_str = create_withdrawal_transaction(*swwo);
}
}
object_id_type object_id = op_obj_idx_1.get<sidechain_transaction_create_operation>().object_id;
std::string op_tx_str = op_obj_idx_1.get<sidechain_transaction_create_operation>().transaction;
should_approve = (op_tx_str == tx_str);
const auto &st_idx = database.get_index_type<sidechain_transaction_index>().indices().get<by_object_id>();
const auto st = st_idx.find(object_id);
if (st == st_idx.end()) {
std::string tx_str = "";
if (object_id.is<son_wallet_withdraw_id_type>()) {
const auto &idx = database.get_index_type<son_wallet_withdraw_index>().indices().get<by_id>();
const auto swwo = idx.find(object_id);
if (swwo != idx.end()) {
tx_str = create_withdrawal_transaction(*swwo);
}
}
transaction_ok = (op_tx_str == tx_str);
}
}
should_approve = process_ok &&
transaction_ok;
break;
}
@ -1166,6 +1218,7 @@ void sidechain_net_handler_bitcoin::process_primary_wallet() {
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op);
try {
trx.validate();
database.push_transaction(trx, database::validation_steps::skip_block_size_check);
if (plugin.app().p2p_node())
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
@ -1209,8 +1262,8 @@ void sidechain_net_handler_bitcoin::process_sidechain_addresses() {
op.withdraw_address = sao.withdraw_address;
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), op);
trx.validate();
try {
trx.validate();
database.push_transaction(trx, database::validation_steps::skip_block_size_check);
if (plugin.app().p2p_node())
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
@ -1233,22 +1286,27 @@ bool sidechain_net_handler_bitcoin::process_deposit(const son_wallet_deposit_obj
if (!tx_str.empty()) {
const chain::global_property_object &gpo = database.get_global_properties();
proposal_create_operation proposal_op;
proposal_op.fee_paying_account = plugin.get_current_son_object().son_account;
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);
son_wallet_deposit_process_operation swdp_op;
swdp_op.payer = gpo.parameters.son_account();
swdp_op.son_wallet_deposit_id = swdo.id;
proposal_op.proposed_ops.emplace_back(swdp_op);
sidechain_transaction_create_operation stc_op;
stc_op.payer = gpo.parameters.son_account();
stc_op.object_id = swdo.id;
stc_op.sidechain = sidechain;
stc_op.transaction = tx_str;
stc_op.signers = gpo.active_sons;
proposal_create_operation proposal_op;
proposal_op.fee_paying_account = plugin.get_current_son_object().son_account;
proposal_op.proposed_ops.emplace_back(stc_op);
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);
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op);
trx.validate();
try {
trx.validate();
database.push_transaction(trx, database::validation_steps::skip_block_size_check);
if (plugin.app().p2p_node())
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
@ -1272,22 +1330,27 @@ bool sidechain_net_handler_bitcoin::process_withdrawal(const son_wallet_withdraw
if (!tx_str.empty()) {
const chain::global_property_object &gpo = database.get_global_properties();
proposal_create_operation proposal_op;
proposal_op.fee_paying_account = plugin.get_current_son_object().son_account;
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);
son_wallet_withdraw_process_operation swwp_op;
swwp_op.payer = gpo.parameters.son_account();
swwp_op.son_wallet_withdraw_id = swwo.id;
proposal_op.proposed_ops.emplace_back(swwp_op);
sidechain_transaction_create_operation stc_op;
stc_op.payer = gpo.parameters.son_account();
stc_op.object_id = swwo.id;
stc_op.sidechain = sidechain;
stc_op.transaction = tx_str;
stc_op.signers = gpo.active_sons;
proposal_create_operation proposal_op;
proposal_op.fee_paying_account = plugin.get_current_son_object().son_account;
proposal_op.proposed_ops.emplace_back(stc_op);
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);
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op);
trx.validate();
try {
trx.validate();
database.push_transaction(trx, database::validation_steps::skip_block_size_check);
if (plugin.app().p2p_node())
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
@ -1316,7 +1379,7 @@ int64_t sidechain_net_handler_bitcoin::settle_sidechain_transaction(const sidech
return settle_amount;
}
std::string tx_str = bitcoin_client->gettransaction(sto.sidechain_transaction);
std::string tx_str = bitcoin_client->gettransaction(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);
@ -1346,6 +1409,8 @@ int64_t sidechain_net_handler_bitcoin::settle_sidechain_transaction(const sidech
}
if (sto.object_id.is<son_wallet_withdraw_id_type>()) {
auto swwo = database.get<son_wallet_withdraw_object>(sto.object_id);
settle_amount = swwo.peerplays_asset.amount.value;
}
}
return settle_amount;
@ -1500,7 +1565,6 @@ std::string sidechain_net_handler_bitcoin::create_withdrawal_transaction(const s
return create_transaction(inputs, outputs, redeem_script);
}
// Function to actually create transaction should return transaction string, or empty string in case of failure
std::string sidechain_net_handler_bitcoin::create_transaction(const std::vector<btc_txout> &inputs, const fc::flat_map<std::string, double> outputs, std::string &redeem_script) {
using namespace bitcoin;
@ -1522,12 +1586,9 @@ std::string sidechain_net_handler_bitcoin::create_transaction(const std::vector<
const auto tx = tb.get_transaction();
std::string hex_tx = fc::to_hex(pack(tx));
std::string tx_raw = write_transaction_data(hex_tx, in_amounts, redeem_script);
ilog("Raw transaction ${tx}", ("tx", tx_raw));
return tx_raw;
}
// Adds signature to transaction
// Function to actually add signature should return transaction with added signature string, or empty string in case of failure
std::string sidechain_net_handler_bitcoin::sign_transaction(const sidechain_transaction_object &sto) {
using namespace bitcoin;
std::string pubkey = plugin.get_current_son_object().sidechain_public_keys.at(sidechain);

View file

@ -100,37 +100,7 @@ bool sidechain_net_handler_peerplays::process_proposal(const proposal_object &po
}
case chain::operation::tag<chain::son_wallet_withdraw_process_operation>::value: {
son_wallet_withdraw_id_type swwo_id = op_obj_idx_0.get<son_wallet_withdraw_process_operation>().son_wallet_withdraw_id;
const auto &idx = database.get_index_type<son_wallet_withdraw_index>().indices().get<by_id>();
const auto swwo = idx.find(swwo_id);
if (swwo != idx.end()) {
uint32_t swwo_block_num = swwo->block_num;
std::string swwo_peerplays_transaction_id = swwo->peerplays_transaction_id;
uint32_t swwo_op_idx = std::stoll(swwo->peerplays_uid.substr(swwo->peerplays_uid.find_last_of("-") + 1));
const auto &block = database.fetch_block_by_number(swwo_block_num);
for (const auto &tx : block->transactions) {
if (tx.id().str() == swwo_peerplays_transaction_id) {
operation op = tx.operations[swwo_op_idx];
transfer_operation t_op = op.get<transfer_operation>();
price asset_price = database.get<asset_object>(t_op.amount.asset_id).options.core_exchange_rate;
asset peerplays_asset = asset(t_op.amount.amount * asset_price.base.amount / asset_price.quote.amount);
should_approve = (t_op.to == gpo.parameters.son_account()) &&
(swwo->peerplays_from == t_op.from) &&
(swwo->peerplays_asset == peerplays_asset);
break;
}
}
}
break;
}
case chain::operation::tag<chain::sidechain_transaction_create_operation>::value: {
should_approve = true;
should_approve = false;
break;
}
@ -195,8 +165,8 @@ bool sidechain_net_handler_peerplays::process_deposit(const son_wallet_deposit_o
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);
trx.validate();
try {
trx.validate();
database.push_transaction(trx, database::validation_steps::skip_block_size_check);
if (plugin.app().p2p_node())
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
@ -246,8 +216,8 @@ std::string sidechain_net_handler_peerplays::send_sidechain_transaction(const si
}
}
trx.validate();
try {
trx.validate();
database.push_transaction(trx, database::validation_steps::skip_block_size_check);
if (plugin.app().p2p_node())
plugin.app().p2p_node()->broadcast(net::trx_message(trx));