Separate transaction settling from deposit/withdrawal processing
This commit is contained in:
parent
c77c19563c
commit
66713f0b48
18 changed files with 200 additions and 132 deletions
2
docs
2
docs
|
|
@ -1 +1 @@
|
|||
Subproject commit 8d8b69d82482101279460fa02f814d0e4030966f
|
||||
Subproject commit 740407c22154634aa0881e6b85e19ad0191e8325
|
||||
|
|
@ -272,6 +272,7 @@ void database::initialize_evaluators()
|
|||
register_evaluator<sidechain_transaction_create_evaluator>();
|
||||
register_evaluator<sidechain_transaction_sign_evaluator>();
|
||||
register_evaluator<sidechain_transaction_send_evaluator>();
|
||||
register_evaluator<sidechain_transaction_settle_evaluator>();
|
||||
}
|
||||
|
||||
void database::initialize_indexes()
|
||||
|
|
|
|||
|
|
@ -347,6 +347,9 @@ struct get_impacted_account_visitor
|
|||
void operator()( const sidechain_transaction_send_operation& op ) {
|
||||
_impacted.insert( op.payer );
|
||||
}
|
||||
void operator()( const sidechain_transaction_settle_operation& op ) {
|
||||
_impacted.insert( op.payer );
|
||||
}
|
||||
};
|
||||
|
||||
void graphene::chain::operation_get_impacted_accounts( const operation& op, flat_set<account_id_type>& result )
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@
|
|||
#define SON_DEREGISTER_TIME (60*60*12) // 12 Hours in seconds
|
||||
#define SON_HEARTBEAT_FREQUENCY (60*3) // 3 minutes in seconds
|
||||
#define SON_DOWN_TIME (60*3*2) // 2 Heartbeats in seconds
|
||||
#define SON_BITCOIN_MIN_TX_CONFIRMATIONS (1)
|
||||
#define SON_BITCOIN_MIN_TX_CONFIRMATIONS (6)
|
||||
#define SON_PAY_TIME (60*60*24) // 1 day
|
||||
#define SON_PAY_MAX (GRAPHENE_BLOCKCHAIN_PRECISION * int64_t(200))
|
||||
#define SWEEPS_DEFAULT_DISTRIBUTION_PERCENTAGE (2*GRAPHENE_1_PERCENT)
|
||||
|
|
|
|||
|
|
@ -159,7 +159,8 @@ namespace graphene { namespace chain {
|
|||
sidechain_address_delete_operation,
|
||||
sidechain_transaction_create_operation,
|
||||
sidechain_transaction_sign_operation,
|
||||
sidechain_transaction_send_operation
|
||||
sidechain_transaction_send_operation,
|
||||
sidechain_transaction_settle_operation
|
||||
> operation;
|
||||
|
||||
/// @} // operations group
|
||||
|
|
|
|||
|
|
@ -50,6 +50,19 @@ namespace graphene { namespace chain {
|
|||
share_type calculate_fee( const fee_parameters_type& k )const { return 0; }
|
||||
};
|
||||
|
||||
struct sidechain_transaction_settle_operation : public base_operation
|
||||
{
|
||||
struct fee_parameters_type { uint64_t fee = 0; };
|
||||
|
||||
asset fee;
|
||||
account_id_type payer;
|
||||
|
||||
sidechain_transaction_id_type sidechain_transaction_id;
|
||||
|
||||
account_id_type fee_payer()const { return payer; }
|
||||
share_type calculate_fee( const fee_parameters_type& k )const { return 0; }
|
||||
};
|
||||
|
||||
} } // graphene::chain
|
||||
|
||||
FC_REFLECT( graphene::chain::sidechain_transaction_create_operation::fee_parameters_type, (fee) )
|
||||
|
|
@ -68,3 +81,7 @@ FC_REFLECT( graphene::chain::sidechain_transaction_send_operation::fee_parameter
|
|||
FC_REFLECT( graphene::chain::sidechain_transaction_send_operation, (fee)(payer)
|
||||
(sidechain_transaction_id)
|
||||
(sidechain_transaction) )
|
||||
|
||||
FC_REFLECT( graphene::chain::sidechain_transaction_settle_operation::fee_parameters_type, (fee) )
|
||||
FC_REFLECT( graphene::chain::sidechain_transaction_settle_operation, (fee)(payer)
|
||||
(sidechain_transaction_id) )
|
||||
|
|
|
|||
|
|
@ -31,4 +31,13 @@ public:
|
|||
object_id_type do_apply(const sidechain_transaction_send_operation& o);
|
||||
};
|
||||
|
||||
class sidechain_transaction_settle_evaluator : public evaluator<sidechain_transaction_settle_evaluator>
|
||||
{
|
||||
public:
|
||||
typedef sidechain_transaction_settle_operation operation_type;
|
||||
|
||||
void_result do_evaluate(const sidechain_transaction_settle_operation& o);
|
||||
object_id_type do_apply(const sidechain_transaction_settle_operation& o);
|
||||
};
|
||||
|
||||
} } // namespace graphene::chain
|
||||
|
|
@ -7,6 +7,14 @@
|
|||
namespace graphene { namespace chain {
|
||||
using namespace graphene::db;
|
||||
|
||||
enum class sidechain_transaction_status {
|
||||
invalid,
|
||||
valid,
|
||||
complete,
|
||||
sent,
|
||||
settled
|
||||
};
|
||||
|
||||
/**
|
||||
* @class sidechain_transaction_object
|
||||
* @brief tracks state of sidechain transaction during signing process.
|
||||
|
|
@ -28,14 +36,12 @@ namespace graphene { namespace chain {
|
|||
uint32_t total_weight = 0;
|
||||
uint32_t current_weight = 0;
|
||||
uint32_t threshold = 0;
|
||||
bool valid = false;
|
||||
bool complete = false;
|
||||
bool sent = false;
|
||||
|
||||
sidechain_transaction_status status;
|
||||
};
|
||||
|
||||
struct by_object_id;
|
||||
struct by_sidechain_and_complete;
|
||||
struct by_sidechain_and_complete_and_sent;
|
||||
struct by_sidechain_and_status;
|
||||
using sidechain_transaction_multi_index_type = multi_index_container<
|
||||
sidechain_transaction_object,
|
||||
indexed_by<
|
||||
|
|
@ -45,17 +51,10 @@ namespace graphene { namespace chain {
|
|||
ordered_unique< tag<by_object_id>,
|
||||
member<sidechain_transaction_object, object_id_type, &sidechain_transaction_object::object_id>
|
||||
>,
|
||||
ordered_non_unique< tag<by_sidechain_and_complete>,
|
||||
ordered_non_unique< tag<by_sidechain_and_status>,
|
||||
composite_key<sidechain_transaction_object,
|
||||
member<sidechain_transaction_object, sidechain_type, &sidechain_transaction_object::sidechain>,
|
||||
member<sidechain_transaction_object, bool, &sidechain_transaction_object::complete>
|
||||
>
|
||||
>,
|
||||
ordered_non_unique< tag<by_sidechain_and_complete_and_sent>,
|
||||
composite_key<sidechain_transaction_object,
|
||||
member<sidechain_transaction_object, sidechain_type, &sidechain_transaction_object::sidechain>,
|
||||
member<sidechain_transaction_object, bool, &sidechain_transaction_object::complete>,
|
||||
member<sidechain_transaction_object, bool, &sidechain_transaction_object::sent>
|
||||
member<sidechain_transaction_object, sidechain_transaction_status, &sidechain_transaction_object::status>
|
||||
>
|
||||
>
|
||||
>
|
||||
|
|
@ -63,6 +62,13 @@ namespace graphene { namespace chain {
|
|||
using sidechain_transaction_index = generic_index<sidechain_transaction_object, sidechain_transaction_multi_index_type>;
|
||||
} } // graphene::chain
|
||||
|
||||
FC_REFLECT_ENUM( graphene::chain::sidechain_transaction_status,
|
||||
(invalid)
|
||||
(valid)
|
||||
(complete)
|
||||
(sent)
|
||||
(settled) )
|
||||
|
||||
FC_REFLECT_DERIVED( graphene::chain::sidechain_transaction_object, (graphene::db::object ),
|
||||
(sidechain)
|
||||
(object_id)
|
||||
|
|
@ -73,6 +79,4 @@ FC_REFLECT_DERIVED( graphene::chain::sidechain_transaction_object, (graphene::db
|
|||
(total_weight)
|
||||
(current_weight)
|
||||
(threshold)
|
||||
(valid)
|
||||
(complete)
|
||||
(sent) )
|
||||
(status) )
|
||||
|
|
|
|||
|
|
@ -41,9 +41,7 @@ object_id_type sidechain_transaction_create_evaluator::do_apply(const sidechain_
|
|||
sto.sidechain_transaction = "";
|
||||
sto.current_weight = 0;
|
||||
sto.threshold = sto.total_weight * 2 / 3 + 1;
|
||||
sto.valid = true;
|
||||
sto.complete = false;
|
||||
sto.sent = false;
|
||||
sto.status = sidechain_transaction_status::valid;
|
||||
});
|
||||
return new_sidechain_transaction_object.id;
|
||||
} FC_CAPTURE_AND_RETHROW( ( op ) ) }
|
||||
|
|
@ -68,9 +66,7 @@ void_result sidechain_transaction_sign_evaluator::do_evaluate(const sidechain_tr
|
|||
}
|
||||
FC_ASSERT(expected, "Signer not expected");
|
||||
|
||||
FC_ASSERT(sto_obj->valid, "Transaction not valid");
|
||||
FC_ASSERT(!sto_obj->complete, "Transaction signing completed");
|
||||
FC_ASSERT(!sto_obj->sent, "Transaction already sent");
|
||||
FC_ASSERT(sto_obj->status == sidechain_transaction_status::valid, "Invalid transaction status");
|
||||
|
||||
return void_result();
|
||||
} FC_CAPTURE_AND_RETHROW( ( op ) ) }
|
||||
|
|
@ -94,7 +90,9 @@ object_id_type sidechain_transaction_sign_evaluator::do_apply(const sidechain_tr
|
|||
sto.current_weight = sto.current_weight + sto.signers.at(i).weight;
|
||||
}
|
||||
}
|
||||
sto.complete = (sto.current_weight >= sto.threshold);
|
||||
if (sto.current_weight >= sto.threshold) {
|
||||
sto.status = sidechain_transaction_status::complete;
|
||||
}
|
||||
});
|
||||
|
||||
db().modify(son_obj->statistics(db()), [&](son_statistics_object& sso) {
|
||||
|
|
@ -112,9 +110,7 @@ void_result sidechain_transaction_send_evaluator::do_evaluate(const sidechain_tr
|
|||
const auto &sto_obj = sto_idx.find(op.sidechain_transaction_id);
|
||||
FC_ASSERT(sto_obj != sto_idx.end(), "Sidechain transaction object not found");
|
||||
|
||||
FC_ASSERT(sto_obj->valid, "Transaction not valid");
|
||||
FC_ASSERT(sto_obj->complete, "Transaction signing not complete");
|
||||
FC_ASSERT(!sto_obj->sent, "Transaction already sent");
|
||||
FC_ASSERT(sto_obj->status == sidechain_transaction_status::complete, "Invalid transaction status");
|
||||
|
||||
return void_result();
|
||||
} FC_CAPTURE_AND_RETHROW( ( op ) ) }
|
||||
|
|
@ -126,7 +122,33 @@ object_id_type sidechain_transaction_send_evaluator::do_apply(const sidechain_tr
|
|||
|
||||
db().modify(*sto_obj, [&](sidechain_transaction_object &sto) {
|
||||
sto.sidechain_transaction = op.sidechain_transaction;
|
||||
sto.sent = true;
|
||||
sto.status = sidechain_transaction_status::sent;
|
||||
});
|
||||
|
||||
return op.sidechain_transaction_id;
|
||||
} FC_CAPTURE_AND_RETHROW( ( op ) ) }
|
||||
|
||||
|
||||
void_result sidechain_transaction_settle_evaluator::do_evaluate(const sidechain_transaction_settle_operation &op)
|
||||
{ try {
|
||||
FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK"); // can be removed after HF date pass
|
||||
|
||||
const auto &sto_idx = db().get_index_type<sidechain_transaction_index>().indices().get<by_id>();
|
||||
const auto &sto_obj = sto_idx.find(op.sidechain_transaction_id);
|
||||
FC_ASSERT(sto_obj != sto_idx.end(), "Sidechain transaction object not found");
|
||||
|
||||
FC_ASSERT(sto_obj->status == sidechain_transaction_status::sent, "Invalid transaction status");
|
||||
|
||||
return void_result();
|
||||
} FC_CAPTURE_AND_RETHROW( ( op ) ) }
|
||||
|
||||
object_id_type sidechain_transaction_settle_evaluator::do_apply(const sidechain_transaction_settle_operation &op)
|
||||
{ try {
|
||||
const auto &sto_idx = db().get_index_type<sidechain_transaction_index>().indices().get<by_id>();
|
||||
auto sto_obj = sto_idx.find(op.sidechain_transaction_id);
|
||||
|
||||
db().modify(*sto_obj, [&](sidechain_transaction_object &sto) {
|
||||
sto.status = sidechain_transaction_status::settled;
|
||||
});
|
||||
|
||||
return op.sidechain_transaction_id;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ public:
|
|||
void process_withdrawals();
|
||||
void process_sidechain_transactions();
|
||||
void send_sidechain_transactions();
|
||||
void process_sidechain_transaction_results();
|
||||
void settle_sidechain_transactions();
|
||||
|
||||
virtual bool process_proposal(const proposal_object &po) = 0;
|
||||
virtual void process_primary_wallet() = 0;
|
||||
|
|
@ -42,7 +42,7 @@ public:
|
|||
virtual bool process_withdrawal(const son_wallet_withdraw_object &swwo) = 0;
|
||||
virtual std::string process_sidechain_transaction(const sidechain_transaction_object &sto) = 0;
|
||||
virtual std::string send_sidechain_transaction(const sidechain_transaction_object &sto) = 0;
|
||||
virtual std::string process_sidechain_transaction_result(const sidechain_transaction_object &sto) = 0;
|
||||
virtual int64_t settle_sidechain_transaction(const sidechain_transaction_object &sto) = 0;
|
||||
|
||||
protected:
|
||||
peerplays_sidechain_plugin &plugin;
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ public:
|
|||
bool process_withdrawal(const son_wallet_withdraw_object &swwo);
|
||||
std::string process_sidechain_transaction(const sidechain_transaction_object &sto);
|
||||
std::string send_sidechain_transaction(const sidechain_transaction_object &sto);
|
||||
std::string process_sidechain_transaction_result(const sidechain_transaction_object &sto);
|
||||
int64_t settle_sidechain_transaction(const sidechain_transaction_object &sto);
|
||||
|
||||
private:
|
||||
std::string ip;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ public:
|
|||
bool process_withdrawal(const son_wallet_withdraw_object &swwo);
|
||||
std::string process_sidechain_transaction(const sidechain_transaction_object &sto);
|
||||
std::string send_sidechain_transaction(const sidechain_transaction_object &sto);
|
||||
std::string process_sidechain_transaction_result(const sidechain_transaction_object &sto);
|
||||
int64_t settle_sidechain_transaction(const sidechain_transaction_object &sto);
|
||||
|
||||
private:
|
||||
void on_applied_block(const signed_block &b);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ public:
|
|||
void process_withdrawals();
|
||||
void process_sidechain_transactions();
|
||||
void send_sidechain_transactions();
|
||||
void process_sidechain_transaction_results();
|
||||
void settle_sidechain_transactions();
|
||||
|
||||
private:
|
||||
peerplays_sidechain_plugin &plugin;
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ public:
|
|||
void process_withdrawals();
|
||||
void process_sidechain_transactions();
|
||||
void send_sidechain_transactions();
|
||||
void process_sidechain_transaction_results();
|
||||
void settle_sidechain_transactions();
|
||||
|
||||
private:
|
||||
peerplays_sidechain_plugin &plugin;
|
||||
|
|
@ -403,7 +403,7 @@ void peerplays_sidechain_plugin_impl::son_processing() {
|
|||
|
||||
send_sidechain_transactions();
|
||||
|
||||
process_sidechain_transaction_results();
|
||||
settle_sidechain_transactions();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -589,8 +589,8 @@ void peerplays_sidechain_plugin_impl::send_sidechain_transactions() {
|
|||
net_manager->send_sidechain_transactions();
|
||||
}
|
||||
|
||||
void peerplays_sidechain_plugin_impl::process_sidechain_transaction_results() {
|
||||
net_manager->process_sidechain_transaction_results();
|
||||
void peerplays_sidechain_plugin_impl::settle_sidechain_transactions() {
|
||||
net_manager->settle_sidechain_transactions();
|
||||
}
|
||||
|
||||
void peerplays_sidechain_plugin_impl::on_applied_block(const signed_block &b) {
|
||||
|
|
|
|||
|
|
@ -234,6 +234,16 @@ void sidechain_net_handler::process_proposals() {
|
|||
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>();
|
||||
const auto sto = idx.find(st_id);
|
||||
if (sto != idx.end()) {
|
||||
should_process = (sto->sidechain == sidechain);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
should_process = false;
|
||||
elog("==================================================");
|
||||
|
|
@ -285,17 +295,9 @@ void sidechain_net_handler::process_deposits() {
|
|||
swdp_op.payer = gpo.parameters.son_account();
|
||||
swdp_op.son_wallet_deposit_id = swdo.id;
|
||||
|
||||
asset_issue_operation ai_op;
|
||||
ai_op.fee = asset(2001000);
|
||||
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;
|
||||
|
||||
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);
|
||||
proposal_op.proposed_ops.emplace_back(ai_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);
|
||||
|
||||
|
|
@ -335,15 +337,9 @@ void sidechain_net_handler::process_withdrawals() {
|
|||
swwp_op.payer = gpo.parameters.son_account();
|
||||
swwp_op.son_wallet_withdraw_id = swwo.id;
|
||||
|
||||
asset_reserve_operation ar_op;
|
||||
ar_op.fee = asset(2001000);
|
||||
ar_op.payer = gpo.parameters.son_account();
|
||||
ar_op.amount_to_reserve = asset(swwo.withdraw_amount, database.get_global_properties().parameters.btc_asset());
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
|
|
@ -360,8 +356,8 @@ void sidechain_net_handler::process_withdrawals() {
|
|||
}
|
||||
|
||||
void sidechain_net_handler::process_sidechain_transactions() {
|
||||
const auto &idx = database.get_index_type<sidechain_transaction_index>().indices().get<by_sidechain_and_complete>();
|
||||
const auto &idx_range = idx.equal_range(std::make_tuple(sidechain, false));
|
||||
const auto &idx = database.get_index_type<sidechain_transaction_index>().indices().get<by_sidechain_and_status>();
|
||||
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) {
|
||||
ilog("Sidechain transaction to process: ${sto}", ("sto", sto.id));
|
||||
|
|
@ -391,8 +387,8 @@ void sidechain_net_handler::process_sidechain_transactions() {
|
|||
}
|
||||
|
||||
void sidechain_net_handler::send_sidechain_transactions() {
|
||||
const auto &idx = database.get_index_type<sidechain_transaction_index>().indices().get<by_sidechain_and_complete_and_sent>();
|
||||
const auto &idx_range = idx.equal_range(std::make_tuple(sidechain, true, false));
|
||||
const auto &idx = database.get_index_type<sidechain_transaction_index>().indices().get<by_sidechain_and_status>();
|
||||
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) {
|
||||
ilog("Sidechain transaction to send: ${sto}", ("sto", sto.id));
|
||||
|
|
@ -421,63 +417,62 @@ void sidechain_net_handler::send_sidechain_transactions() {
|
|||
});
|
||||
}
|
||||
|
||||
void sidechain_net_handler::process_sidechain_transaction_results() {
|
||||
const auto &idx = database.get_index_type<sidechain_transaction_index>().indices().get<by_sidechain_and_complete_and_sent>();
|
||||
const auto &idx_range = idx.equal_range(std::make_tuple(sidechain, true, true));
|
||||
void sidechain_net_handler::settle_sidechain_transactions() {
|
||||
const auto &idx = database.get_index_type<sidechain_transaction_index>().indices().get<by_sidechain_and_status>();
|
||||
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) {
|
||||
ilog("Sidechain transaction to send: ${sto}", ("sto", sto.id));
|
||||
ilog("Sidechain transaction to settle: ${sto}", ("sto", sto.id));
|
||||
|
||||
std::string sidechain_transaction = process_sidechain_transaction_result(sto);
|
||||
int64_t settle_amount = settle_sidechain_transaction(sto);
|
||||
|
||||
if (sidechain_transaction.empty()) {
|
||||
wlog("Sidechain transaction not sent: ${sto}", ("sto", sto.id));
|
||||
if (settle_amount == -1) {
|
||||
wlog("Sidechain transaction not settled: ${sto}", ("sto", sto.id));
|
||||
return;
|
||||
}
|
||||
|
||||
sidechain_transaction_send_operation sts_op;
|
||||
sts_op.payer = plugin.get_current_son_object().son_account;
|
||||
sts_op.sidechain_transaction_id = sto.id;
|
||||
sts_op.sidechain_transaction = sidechain_transaction;
|
||||
const chain::global_property_object &gpo = database.get_global_properties();
|
||||
|
||||
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), sts_op);
|
||||
sidechain_transaction_settle_operation sts_op;
|
||||
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);
|
||||
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 sidechain transaction send operation failed with exception ${e}", ("e", e.what()));
|
||||
elog("Sending proposal for sidechain transaction settle operation failed with exception ${e}", ("e", e.what()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bool sidechain_net_handler::process_proposal(const proposal_object &po) {
|
||||
FC_ASSERT(false, "process_proposal not implemented");
|
||||
}
|
||||
|
||||
void sidechain_net_handler::process_primary_wallet() {
|
||||
FC_ASSERT(false, "process_primary_wallet not implemented");
|
||||
}
|
||||
|
||||
bool sidechain_net_handler::process_deposit(const son_wallet_deposit_object &swdo) {
|
||||
FC_ASSERT(false, "process_deposit not implemented");
|
||||
}
|
||||
|
||||
bool sidechain_net_handler::process_withdrawal(const son_wallet_withdraw_object &swwo) {
|
||||
FC_ASSERT(false, "process_withdrawal not implemented");
|
||||
}
|
||||
|
||||
std::string sidechain_net_handler::process_sidechain_transaction(const sidechain_transaction_object &sto) {
|
||||
FC_ASSERT(false, "process_sidechain_transaction not implemented");
|
||||
}
|
||||
|
||||
std::string sidechain_net_handler::send_sidechain_transaction(const sidechain_transaction_object &sto) {
|
||||
FC_ASSERT(false, "send_sidechain_transaction not implemented");
|
||||
}
|
||||
|
||||
std::string sidechain_net_handler::process_sidechain_transaction_result(const sidechain_transaction_object &sto) {
|
||||
FC_ASSERT(false, "process_sidechain_transaction_result not implemented");
|
||||
}
|
||||
|
||||
}} // namespace graphene::peerplays_sidechain
|
||||
|
|
|
|||
|
|
@ -979,17 +979,19 @@ bool sidechain_net_handler_bitcoin::process_proposal(const proposal_object &po)
|
|||
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_address = "";
|
||||
uint64_t tx_amount = 0;
|
||||
uint64_t tx_vout = 0;
|
||||
int64_t tx_amount = -1;
|
||||
int64_t tx_vout = -1;
|
||||
|
||||
for (auto &input : tx_json.get_child("result.details")) {
|
||||
tx_address = input.second.get<std::string>("address");
|
||||
std::string tx_amount_s = input.second.get<std::string>("amount");
|
||||
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);
|
||||
std::string tx_vout_s = input.second.get<std::string>("vout");
|
||||
tx_vout = std::stoll(tx_vout_s);
|
||||
break;
|
||||
if ((tx_address == swdo_address) && (input.second.get<std::string>("category") == "receive")) {
|
||||
std::string tx_amount_s = input.second.get<std::string>("amount");
|
||||
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);
|
||||
std::string tx_vout_s = input.second.get<std::string>("vout");
|
||||
tx_vout = std::stoll(tx_vout_s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
should_approve = (swdo_txid == tx_txid) &&
|
||||
|
|
@ -1046,6 +1048,11 @@ bool sidechain_net_handler_bitcoin::process_proposal(const proposal_object &po)
|
|||
break;
|
||||
}
|
||||
|
||||
case chain::operation::tag<chain::sidechain_transaction_settle_operation>::value: {
|
||||
should_approve = true;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
should_approve = false;
|
||||
elog("==================================================");
|
||||
|
|
@ -1238,10 +1245,12 @@ std::string sidechain_net_handler_bitcoin::send_sidechain_transaction(const side
|
|||
return send_transaction(sto);
|
||||
}
|
||||
|
||||
std::string sidechain_net_handler_bitcoin::process_sidechain_transaction_result(const sidechain_transaction_object &sto) {
|
||||
int64_t sidechain_net_handler_bitcoin::settle_sidechain_transaction(const sidechain_transaction_object &sto) {
|
||||
|
||||
int64_t settle_amount = -1;
|
||||
|
||||
if (sto.sidechain_transaction.empty()) {
|
||||
return "";
|
||||
return settle_amount;
|
||||
}
|
||||
|
||||
std::string tx_str = bitcoin_client->gettransaction(sto.sidechain_transaction);
|
||||
|
|
@ -1250,32 +1259,33 @@ std::string sidechain_net_handler_bitcoin::process_sidechain_transaction_result(
|
|||
boost::property_tree::read_json(tx_ss, tx_json);
|
||||
|
||||
if ((tx_json.count("error")) && (!tx_json.get_child("error").empty())) {
|
||||
return "";
|
||||
return settle_amount;
|
||||
}
|
||||
|
||||
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_address = "";
|
||||
uint64_t tx_amount = 0;
|
||||
uint64_t tx_vout = 0;
|
||||
int64_t tx_amount = -1;
|
||||
|
||||
for (auto &input : tx_json.get_child("result.details")) {
|
||||
tx_address = input.second.get<std::string>("address");
|
||||
std::string tx_amount_s = input.second.get<std::string>("amount");
|
||||
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);
|
||||
std::string tx_vout_s = input.second.get<std::string>("vout");
|
||||
tx_vout = std::stoll(tx_vout_s);
|
||||
break;
|
||||
const chain::global_property_object &gpo = database.get_global_properties();
|
||||
|
||||
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.details")) {
|
||||
if (input.second.get<std::string>("category") == "receive") {
|
||||
std::string tx_amount_s = input.second.get<std::string>("amount");
|
||||
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;
|
||||
}
|
||||
}
|
||||
settle_amount = tx_amount;
|
||||
}
|
||||
|
||||
if (sto.object_id.is<son_wallet_withdraw_id_type>()) {
|
||||
}
|
||||
}
|
||||
|
||||
if (sto.object_id.is<son_wallet_deposit_id_type>()) {
|
||||
}
|
||||
|
||||
if (sto.object_id.is<son_wallet_withdraw_id_type>()) {
|
||||
}
|
||||
|
||||
return "";
|
||||
return settle_amount;
|
||||
}
|
||||
|
||||
std::string sidechain_net_handler_bitcoin::create_primary_wallet_transaction() {
|
||||
|
|
|
|||
|
|
@ -119,6 +119,11 @@ bool sidechain_net_handler_peerplays::process_proposal(const proposal_object &po
|
|||
break;
|
||||
}
|
||||
|
||||
case chain::operation::tag<chain::sidechain_transaction_settle_operation>::value: {
|
||||
should_approve = true;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
should_approve = false;
|
||||
elog("==================================================");
|
||||
|
|
@ -149,8 +154,9 @@ std::string sidechain_net_handler_peerplays::send_sidechain_transaction(const si
|
|||
return sto.transaction;
|
||||
}
|
||||
|
||||
std::string sidechain_net_handler_peerplays::process_sidechain_transaction_result(const sidechain_transaction_object &sto) {
|
||||
return sto.transaction;
|
||||
int64_t sidechain_net_handler_peerplays::settle_sidechain_transaction(const sidechain_transaction_object &sto) {
|
||||
int64_t settle_amount = -1;
|
||||
return settle_amount;
|
||||
}
|
||||
|
||||
void sidechain_net_handler_peerplays::on_applied_block(const signed_block &b) {
|
||||
|
|
|
|||
|
|
@ -75,9 +75,9 @@ void sidechain_net_manager::send_sidechain_transactions() {
|
|||
}
|
||||
}
|
||||
|
||||
void sidechain_net_manager::process_sidechain_transaction_results() {
|
||||
void sidechain_net_manager::settle_sidechain_transactions() {
|
||||
for (size_t i = 0; i < net_handlers.size(); i++) {
|
||||
net_handlers.at(i)->process_sidechain_transaction_results();
|
||||
net_handlers.at(i)->settle_sidechain_transactions();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue