Handle peerplays deposits with transaction settling
This commit is contained in:
parent
66713f0b48
commit
7dd0afe257
2 changed files with 128 additions and 26 deletions
|
|
@ -426,7 +426,7 @@ void sidechain_net_handler::settle_sidechain_transactions() {
|
|||
|
||||
int64_t settle_amount = settle_sidechain_transaction(sto);
|
||||
|
||||
if (settle_amount == -1) {
|
||||
if (settle_amount < 0) {
|
||||
wlog("Sidechain transaction not settled: ${sto}", ("sto", sto.id));
|
||||
return;
|
||||
}
|
||||
|
|
@ -437,29 +437,29 @@ void sidechain_net_handler::settle_sidechain_transactions() {
|
|||
sts_op.payer = gpo.parameters.son_account();
|
||||
sts_op.sidechain_transaction_id = sto.id;
|
||||
|
||||
operation s_op;
|
||||
|
||||
if (sto.object_id.is<son_wallet_deposit_id_type>()) {
|
||||
asset_issue_operation ai_op;
|
||||
ai_op.fee = asset(2001000);
|
||||
ai_op.issuer = gpo.parameters.son_account();
|
||||
ai_op.asset_to_issue = asset(settle_amount, database.get_global_properties().parameters.btc_asset());
|
||||
ai_op.issue_to_account = database.get<son_wallet_deposit_object>(sto.object_id).peerplays_from;
|
||||
s_op = ai_op;
|
||||
}
|
||||
|
||||
if (sto.object_id.is<son_wallet_withdraw_id_type>()) {
|
||||
asset_reserve_operation ar_op;
|
||||
ar_op.fee = asset(2001000);
|
||||
ar_op.payer = gpo.parameters.son_account();
|
||||
ar_op.amount_to_reserve = asset(settle_amount, database.get_global_properties().parameters.btc_asset());
|
||||
s_op = ar_op;
|
||||
}
|
||||
|
||||
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);
|
||||
proposal_op.proposed_ops.emplace_back(s_op);
|
||||
|
||||
if (settle_amount != 0) {
|
||||
if (sto.object_id.is<son_wallet_deposit_id_type>()) {
|
||||
asset_issue_operation ai_op;
|
||||
ai_op.fee = asset(2001000);
|
||||
ai_op.issuer = gpo.parameters.son_account();
|
||||
ai_op.asset_to_issue = asset(settle_amount, database.get_global_properties().parameters.btc_asset());
|
||||
ai_op.issue_to_account = database.get<son_wallet_deposit_object>(sto.object_id).peerplays_from;
|
||||
proposal_op.proposed_ops.emplace_back(ai_op);
|
||||
}
|
||||
|
||||
if (sto.object_id.is<son_wallet_withdraw_id_type>()) {
|
||||
asset_reserve_operation ar_op;
|
||||
ar_op.fee = asset(2001000);
|
||||
ar_op.payer = gpo.parameters.son_account();
|
||||
ar_op.amount_to_reserve = asset(settle_amount, database.get_global_properties().parameters.btc_asset());
|
||||
proposal_op.proposed_ops.emplace_back(ar_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);
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <boost/property_tree/ptree.hpp>
|
||||
|
||||
#include <fc/crypto/base64.hpp>
|
||||
#include <fc/crypto/hex.hpp>
|
||||
#include <fc/log/logger.hpp>
|
||||
#include <fc/network/ip.hpp>
|
||||
|
||||
|
|
@ -15,12 +16,26 @@
|
|||
#include <graphene/chain/protocol/son_wallet.hpp>
|
||||
#include <graphene/chain/son_info.hpp>
|
||||
#include <graphene/chain/son_wallet_object.hpp>
|
||||
#include <graphene/utilities/key_conversion.hpp>
|
||||
|
||||
namespace graphene { namespace peerplays_sidechain {
|
||||
|
||||
sidechain_net_handler_peerplays::sidechain_net_handler_peerplays(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options) :
|
||||
sidechain_net_handler(_plugin, options) {
|
||||
sidechain = sidechain_type::peerplays;
|
||||
|
||||
if (options.count("peerplays-private-key")) {
|
||||
const std::vector<std::string> pub_priv_keys = options["peerplays-private-key"].as<std::vector<std::string>>();
|
||||
for (const std::string &itr_key_pair : pub_priv_keys) {
|
||||
auto key_pair = graphene::app::dejsonify<std::pair<std::string, std::string>>(itr_key_pair, 5);
|
||||
ilog("Peerplays Public Key: ${public}", ("public", key_pair.first));
|
||||
if (!key_pair.first.length() || !key_pair.second.length()) {
|
||||
FC_THROW("Invalid public private key pair.");
|
||||
}
|
||||
private_keys[key_pair.first] = key_pair.second;
|
||||
}
|
||||
}
|
||||
|
||||
database.applied_block.connect([&](const signed_block &b) {
|
||||
on_applied_block(b);
|
||||
});
|
||||
|
|
@ -115,7 +130,7 @@ bool sidechain_net_handler_peerplays::process_proposal(const proposal_object &po
|
|||
}
|
||||
|
||||
case chain::operation::tag<chain::sidechain_transaction_create_operation>::value: {
|
||||
should_approve = false;
|
||||
should_approve = true;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -139,7 +154,55 @@ void sidechain_net_handler_peerplays::process_primary_wallet() {
|
|||
}
|
||||
|
||||
bool sidechain_net_handler_peerplays::process_deposit(const son_wallet_deposit_object &swdo) {
|
||||
return true;
|
||||
|
||||
const chain::global_property_object &gpo = database.get_global_properties();
|
||||
|
||||
asset_issue_operation ai_op;
|
||||
ai_op.issuer = gpo.parameters.son_account();
|
||||
price btc_price = database.get<asset_object>(database.get_global_properties().parameters.btc_asset()).options.core_exchange_rate;
|
||||
ai_op.asset_to_issue = asset(swdo.peerplays_asset.amount * btc_price.quote.amount / btc_price.base.amount, database.get_global_properties().parameters.btc_asset());
|
||||
ai_op.issue_to_account = swdo.peerplays_from;
|
||||
|
||||
signed_transaction tx;
|
||||
auto dyn_props = database.get_dynamic_global_properties();
|
||||
tx.set_reference_block(dyn_props.head_block_id);
|
||||
tx.set_expiration(database.head_block_time() + gpo.parameters.maximum_time_until_expiration);
|
||||
tx.operations.push_back(ai_op);
|
||||
database.current_fee_schedule().set_fee(tx.operations.back());
|
||||
|
||||
std::stringstream ss;
|
||||
fc::raw::pack(ss, tx, 1000);
|
||||
std::string tx_str = boost::algorithm::hex(ss.str());
|
||||
|
||||
if (!tx_str.empty()) {
|
||||
const chain::global_property_object &gpo = database.get_global_properties();
|
||||
|
||||
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 {
|
||||
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));
|
||||
return true;
|
||||
} catch (fc::exception e) {
|
||||
elog("Sending proposal for deposit sidechain transaction create operation failed with exception ${e}", ("e", e.what()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool sidechain_net_handler_peerplays::process_withdrawal(const son_wallet_withdraw_object &swwo) {
|
||||
|
|
@ -147,15 +210,54 @@ bool sidechain_net_handler_peerplays::process_withdrawal(const son_wallet_withdr
|
|||
}
|
||||
|
||||
std::string sidechain_net_handler_peerplays::process_sidechain_transaction(const sidechain_transaction_object &sto) {
|
||||
return sto.transaction;
|
||||
|
||||
std::stringstream ss_trx(boost::algorithm::unhex(sto.transaction));
|
||||
signed_transaction trx;
|
||||
fc::raw::unpack(ss_trx, trx, 1000);
|
||||
|
||||
fc::optional<fc::ecc::private_key> privkey = graphene::utilities::wif_to_key(get_private_key(plugin.get_current_son_object().sidechain_public_keys.at(sidechain)));
|
||||
signature_type st = trx.sign(*privkey, database.get_chain_id());
|
||||
|
||||
std::stringstream ss_st;
|
||||
fc::raw::pack(ss_st, st, 1000);
|
||||
std::string st_str = boost::algorithm::hex(ss_st.str());
|
||||
|
||||
return st_str;
|
||||
}
|
||||
|
||||
std::string sidechain_net_handler_peerplays::send_sidechain_transaction(const sidechain_transaction_object &sto) {
|
||||
return sto.transaction;
|
||||
|
||||
std::stringstream ss_trx(boost::algorithm::unhex(sto.transaction));
|
||||
signed_transaction trx;
|
||||
fc::raw::unpack(ss_trx, trx, 1000);
|
||||
|
||||
for (auto signature : sto.signatures) {
|
||||
if (!signature.second.empty()) {
|
||||
std::stringstream ss_st(boost::algorithm::unhex(signature.second));
|
||||
signature_type st;
|
||||
fc::raw::unpack(ss_st, st, 1000);
|
||||
|
||||
trx.signatures.push_back(st);
|
||||
trx.signees.clear();
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
return trx.id().str();
|
||||
} catch (fc::exception e) {
|
||||
elog("Sending proposal for deposit sidechain transaction create operation failed with exception ${e}", ("e", e.what()));
|
||||
return "";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
int64_t sidechain_net_handler_peerplays::settle_sidechain_transaction(const sidechain_transaction_object &sto) {
|
||||
int64_t settle_amount = -1;
|
||||
int64_t settle_amount = 0;
|
||||
return settle_amount;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue