Move transfer inside son_wallet_transfer_process_operation

This commit is contained in:
Srdjan Obucina 2020-02-10 19:17:56 +01:00
parent 95ad384f0c
commit df369df421
6 changed files with 73 additions and 32 deletions

View file

@ -19,6 +19,7 @@ namespace graphene { namespace chain {
int64_t sidechain_amount;
chain::account_id_type peerplays_from;
chain::account_id_type peerplays_to;
chain::asset peerplays_amount;
account_id_type fee_payer()const { return payer; }
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
@ -41,7 +42,7 @@ namespace graphene { namespace chain {
FC_REFLECT(graphene::chain::son_wallet_transfer_create_operation::fee_parameters_type, (fee) )
FC_REFLECT(graphene::chain::son_wallet_transfer_create_operation, (fee)(payer)
(timestamp) (sidechain) (sidechain_uid) (sidechain_transaction_id) (sidechain_from) (sidechain_to) (sidechain_amount) (peerplays_from) (peerplays_to))
(timestamp) (sidechain) (sidechain_uid) (sidechain_transaction_id) (sidechain_from) (sidechain_to) (sidechain_amount) (peerplays_from) (peerplays_to) (peerplays_amount))
FC_REFLECT(graphene::chain::son_wallet_transfer_process_operation::fee_parameters_type, (fee) )
FC_REFLECT(graphene::chain::son_wallet_transfer_process_operation, (fee)(payer)
(son_wallet_transfer_id))

View file

@ -26,6 +26,7 @@ namespace graphene { namespace chain {
int64_t sidechain_amount;
chain::account_id_type peerplays_from;
chain::account_id_type peerplays_to;
chain::asset peerplays_amount;
bool processed;
};
@ -63,5 +64,5 @@ namespace graphene { namespace chain {
FC_REFLECT_DERIVED( graphene::chain::son_wallet_transfer_object, (graphene::db::object),
(timestamp) (sidechain) (confirmations)
(sidechain_uid) (sidechain_transaction_id) (sidechain_from) (sidechain_to) (sidechain_amount)
(peerplays_from) (peerplays_to)
(peerplays_from) (peerplays_to) (peerplays_amount)
(processed) )

View file

@ -1,6 +1,7 @@
#include <graphene/chain/son_wallet_transfer_evaluator.hpp>
#include <graphene/chain/database.hpp>
#include <graphene/chain/is_authorized_asset.hpp>
#include <graphene/chain/son_wallet_transfer_object.hpp>
namespace graphene { namespace chain {
@ -32,6 +33,7 @@ object_id_type create_son_wallet_transfer_evaluator::do_apply(const son_wallet_t
swto.sidechain_amount = op.sidechain_amount;
swto.peerplays_from = op.peerplays_from;
swto.peerplays_to = op.peerplays_to;
swto.peerplays_amount = op.peerplays_amount;
swto.processed = false;
});
return new_son_wallet_transfer_object.id;
@ -52,8 +54,48 @@ void_result process_son_wallet_transfer_evaluator::do_evaluate(const son_wallet_
const auto& idx = db().get_index_type<son_wallet_transfer_index>().indices().get<by_id>();
const auto& itr = idx.find(op.son_wallet_transfer_id);
FC_ASSERT(itr != idx.end(), "Son wallet transfer not found");
FC_ASSERT(itr->processed == false, "Son wallet transfer is already processed");
return void_result();
//FC_ASSERT(itr->processed == false, "Son wallet transfer is already processed");
const database& d = db();
const account_object& from_account = itr->peerplays_to(d); // reversed, for deposit
const account_object& to_account = itr->peerplays_from(d); // reversed, for deposit
const asset_object& asset_type = itr->peerplays_amount.asset_id(d);
try {
GRAPHENE_ASSERT(
is_authorized_asset( d, from_account, asset_type ),
transfer_from_account_not_whitelisted,
"'from' account ${from} is not whitelisted for asset ${asset}",
("from",from_account.id)
("asset",itr->peerplays_amount.asset_id)
);
GRAPHENE_ASSERT(
is_authorized_asset( d, to_account, asset_type ),
transfer_to_account_not_whitelisted,
"'to' account ${to} is not whitelisted for asset ${asset}",
("to",to_account.id)
("asset",itr->peerplays_amount.asset_id)
);
if( asset_type.is_transfer_restricted() )
{
GRAPHENE_ASSERT(
from_account.id == asset_type.issuer || to_account.id == asset_type.issuer,
transfer_restricted_transfer_asset,
"Asset {asset} has transfer_restricted flag enabled",
("asset", itr->peerplays_amount.asset_id)
);
}
bool insufficient_balance = d.get_balance( from_account, asset_type ).amount >= itr->peerplays_amount.amount;
FC_ASSERT( insufficient_balance,
"Insufficient Balance: ${balance}, unable to transfer '${total_transfer}' from account '${a}' to '${t}'",
("a",from_account.name)("t",to_account.name)("total_transfer",d.to_pretty_string(itr->peerplays_amount))("balance",d.to_pretty_string(d.get_balance(from_account, asset_type))) );
return void_result();
} FC_RETHROW_EXCEPTIONS( error, "Unable to transfer ${a} from ${f} to ${t}", ("a",d.to_pretty_string(itr->peerplays_amount))("f",from_account.name)("t",to_account.name) );
} FC_CAPTURE_AND_RETHROW( (op) ) }
object_id_type process_son_wallet_transfer_evaluator::do_apply(const son_wallet_transfer_process_operation& op)
@ -62,9 +104,17 @@ object_id_type process_son_wallet_transfer_evaluator::do_apply(const son_wallet_
auto itr = idx.find(op.son_wallet_transfer_id);
if(itr != idx.end())
{
db().modify(*itr, [&op](son_wallet_transfer_object &swto) {
swto.processed = true;
});
if (itr->processed == false) {
db().modify(*itr, [&op](son_wallet_transfer_object &swto) {
swto.processed = true;
});
const account_id_type from_account = itr->peerplays_to; // reversed, for deposit
const account_id_type to_account = itr->peerplays_from; // reversed, for deposit
db().adjust_balance( from_account, -itr->peerplays_amount );
db().adjust_balance( to_account, itr->peerplays_amount );
}
}
return op.son_wallet_transfer_id;
} FC_CAPTURE_AND_RETHROW( (op) ) }

View file

@ -365,21 +365,16 @@ void peerplays_sidechain_plugin_impl::process_deposits() {
const chain::global_property_object& gpo = plugin.database().get_global_properties();
son_wallet_transfer_process_operation p_op;
p_op.payer = gpo.parameters.get_son_btc_account_id();
p_op.son_wallet_transfer_id = swto.id;
transfer_operation t_op;
t_op.from = gpo.parameters.get_son_btc_account_id();;
t_op.to = swto.peerplays_from;
t_op.amount = asset(swto.sidechain_amount / 1000000); // For Bitcoin, the exchange rate is 1:1, for others, get the exchange rate from market
for (son_id_type son_id : plugin.get_sons()) {
if (plugin.is_active_son(son_id)) {
son_wallet_transfer_process_operation p_op;
p_op.payer = gpo.parameters.get_son_btc_account_id();
p_op.son_wallet_transfer_id = swto.id;
proposal_create_operation proposal_op;
proposal_op.fee_paying_account = plugin.get_son_object(son_id).son_account;
proposal_op.proposed_ops.emplace_back( op_wrapper( p_op ) );
proposal_op.proposed_ops.emplace_back( op_wrapper( t_op ) );
uint32_t lifetime = ( gpo.parameters.block_interval * gpo.active_witnesses.size() ) * 3;
proposal_op.expiration_time = time_point_sec( plugin.database().head_block_time().sec_since_epoch() + lifetime );
@ -389,6 +384,8 @@ void peerplays_sidechain_plugin_impl::process_deposits() {
ilog("sidechain_net_handler: transaction validated ${swto} by ${son}", ("swto", swto.id) ("son", son_id));
try {
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));
} catch(fc::exception e){
ilog("sidechain_net_handler: sending proposal for transfer operation failed with exception ${e}",("e", e.what()));
}
@ -484,21 +481,8 @@ void peerplays_sidechain_plugin_impl::on_objects_new(const vector<object_id_type
continue;
}
//if(proposal->proposed_transaction.operations.size() == 1
//&& proposal->proposed_transaction.operations[0].which() == chain::operation::tag<chain::son_wallet_transfer_process_operation>::value) {
// approve_proposal( son_id, proposal->id );
// continue;
//}
//if(proposal->proposed_transaction.operations.size() == 1
//&& proposal->proposed_transaction.operations[0].which() == chain::operation::tag<chain::transfer_operation>::value) {
// approve_proposal( son_id, proposal->id );
// continue;
//}
if(proposal->proposed_transaction.operations.size() == 2
&& proposal->proposed_transaction.operations[0].which() == chain::operation::tag<chain::son_wallet_transfer_process_operation>::value
&& proposal->proposed_transaction.operations[1].which() == chain::operation::tag<chain::transfer_operation>::value) {
if(proposal->proposed_transaction.operations.size() == 1
&& proposal->proposed_transaction.operations[0].which() == chain::operation::tag<chain::son_wallet_transfer_process_operation>::value) {
approve_proposal( son_id, proposal->id );
continue;
}

View file

@ -66,6 +66,7 @@ void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_
op.sidechain_amount = sed.sidechain_amount;
op.peerplays_from = sed.peerplays_from;
op.peerplays_to = sed.peerplays_to;
op.peerplays_amount = asset(sed.sidechain_amount / 1000); // For Bitcoin, the exchange rate is 1:1, for others, get the exchange rate from market
for (son_id_type son_id : plugin.get_sons()) {
if (plugin.is_active_son(son_id)) {
@ -79,6 +80,8 @@ void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_
signed_transaction trx = plugin.database().create_signed_transaction(plugin.get_private_key(son_id), proposal_op);
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){
ilog("sidechain_net_handler: sending proposal for son wallet transfer create operation by ${son} failed with exception ${e}", ("son", son_id) ("e", e.what()));
}

View file

@ -297,6 +297,8 @@ void sidechain_net_handler_bitcoin::recreate_primary_wallet() {
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(son_id), proposal_op);
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){
ilog("sidechain_net_handler: sending proposal for son wallet update operation failed with exception ${e}",("e", e.what()));
}