Refactor multiple SON support processing
This commit is contained in:
parent
90e58cd01f
commit
84c9ea1a53
4 changed files with 133 additions and 101 deletions
|
|
@ -27,8 +27,9 @@ public:
|
|||
std::unique_ptr<detail::peerplays_sidechain_plugin_impl> my;
|
||||
|
||||
std::set<chain::son_id_type> &get_sons();
|
||||
son_id_type &get_current_son_id();
|
||||
son_object get_son_object(son_id_type son_id);
|
||||
const son_id_type get_current_son_id();
|
||||
const son_object get_current_son_object();
|
||||
const son_object get_son_object(son_id_type son_id);
|
||||
bool is_active_son(son_id_type son_id);
|
||||
fc::ecc::private_key get_private_key(son_id_type son_id);
|
||||
fc::ecc::private_key get_private_key(chain::public_key_type public_key);
|
||||
|
|
|
|||
|
|
@ -33,8 +33,9 @@ public:
|
|||
void plugin_startup();
|
||||
|
||||
std::set<chain::son_id_type> &get_sons();
|
||||
son_id_type &get_current_son_id();
|
||||
son_object get_son_object(son_id_type son_id);
|
||||
const son_id_type get_current_son_id();
|
||||
const son_object get_current_son_object();
|
||||
const son_object get_son_object(son_id_type son_id);
|
||||
bool is_active_son(son_id_type son_id);
|
||||
fc::ecc::private_key get_private_key(son_id_type son_id);
|
||||
fc::ecc::private_key get_private_key(chain::public_key_type public_key);
|
||||
|
|
@ -226,11 +227,15 @@ std::set<chain::son_id_type> &peerplays_sidechain_plugin_impl::get_sons() {
|
|||
return sons;
|
||||
}
|
||||
|
||||
son_id_type &peerplays_sidechain_plugin_impl::get_current_son_id() {
|
||||
const son_id_type peerplays_sidechain_plugin_impl::get_current_son_id() {
|
||||
return current_son_id;
|
||||
}
|
||||
|
||||
son_object peerplays_sidechain_plugin_impl::get_son_object(son_id_type son_id) {
|
||||
const son_object peerplays_sidechain_plugin_impl::get_current_son_object() {
|
||||
return get_son_object(current_son_id);
|
||||
}
|
||||
|
||||
const son_object peerplays_sidechain_plugin_impl::get_son_object(son_id_type son_id) {
|
||||
const auto &idx = plugin.database().get_index_type<chain::son_index>().indices().get<by_id>();
|
||||
auto son_obj = idx.find(son_id);
|
||||
if (son_obj == idx.end())
|
||||
|
|
@ -289,7 +294,7 @@ void peerplays_sidechain_plugin_impl::heartbeat_loop() {
|
|||
for (son_id_type son_id : sons) {
|
||||
if (is_active_son(son_id) || get_son_object(son_id).status == chain::son_status::in_maintenance) {
|
||||
|
||||
ilog("peerplays_sidechain_plugin: sending heartbeat for SON ${son}", ("son", son_id));
|
||||
ilog("Sending heartbeat for SON ${son}", ("son", son_id));
|
||||
chain::son_heartbeat_operation op;
|
||||
op.owner_account = get_son_object(son_id).son_account;
|
||||
op.son_id = son_id;
|
||||
|
|
@ -302,7 +307,7 @@ void peerplays_sidechain_plugin_impl::heartbeat_loop() {
|
|||
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
|
||||
return true;
|
||||
} catch (fc::exception e) {
|
||||
ilog("peerplays_sidechain_plugin_impl: sending heartbeat failed with exception ${e}", ("e", e.what()));
|
||||
elog("Sending heartbeat failed with exception ${e}", ("e", e.what()));
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
|
@ -328,38 +333,63 @@ void peerplays_sidechain_plugin_impl::son_processing() {
|
|||
return;
|
||||
}
|
||||
|
||||
chain::son_id_type next_son_id = plugin.database().get_scheduled_son(1);
|
||||
ilog("peerplays_sidechain_plugin_impl: Scheduled SON ${son}", ("son", next_son_id));
|
||||
|
||||
// Tasks that are executed by all active SONs, no matter if scheduled
|
||||
// E.g. sending approvals and signing
|
||||
approve_proposals();
|
||||
|
||||
// Tasks that are executed by scheduled and active SON
|
||||
if (sons.find(next_son_id) != sons.end()) {
|
||||
|
||||
current_son_id = next_son_id;
|
||||
|
||||
create_son_down_proposals();
|
||||
|
||||
create_son_deregister_proposals();
|
||||
|
||||
recreate_primary_wallet();
|
||||
|
||||
process_deposits();
|
||||
|
||||
process_withdrawals();
|
||||
|
||||
process_sidechain_transactions();
|
||||
|
||||
send_sidechain_transactions();
|
||||
fc::time_point now_fine = fc::time_point::now();
|
||||
fc::time_point_sec now = now_fine + fc::microseconds(500000);
|
||||
if (plugin.database().get_slot_time(1) < now) {
|
||||
return; // Not synced
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t slot = 1; //plugin.database().get_slot_at_time(now);
|
||||
if (slot == 0) {
|
||||
return; // Not time yet
|
||||
}
|
||||
|
||||
//assert(now > plugin.database().head_block_time());
|
||||
|
||||
chain::son_id_type scheduled_son_id = plugin.database().get_scheduled_son(slot);
|
||||
fc::time_point_sec scheduled_time = plugin.database().get_slot_time(slot);
|
||||
ilog("Slot: ${slot} Scheduled SON: ${scheduled_son_id} Scheduled time: ${scheduled_time} Now: ${now} ",
|
||||
("slot", slot)("scheduled_son_id", scheduled_son_id)("scheduled_time", scheduled_time)("now", now));
|
||||
|
||||
for (son_id_type son_id : plugin.get_sons()) {
|
||||
|
||||
if (plugin.is_active_son(son_id)) {
|
||||
|
||||
current_son_id = son_id;
|
||||
|
||||
// Tasks that are executed by all active SONs, no matter if scheduled
|
||||
// E.g. sending approvals and signing
|
||||
approve_proposals();
|
||||
process_sidechain_transactions();
|
||||
|
||||
// Tasks that are executed by scheduled and active SON
|
||||
if (current_son_id == scheduled_son_id) {
|
||||
|
||||
create_son_down_proposals();
|
||||
|
||||
create_son_deregister_proposals();
|
||||
|
||||
recreate_primary_wallet();
|
||||
|
||||
process_deposits();
|
||||
|
||||
process_withdrawals();
|
||||
|
||||
send_sidechain_transactions();
|
||||
}
|
||||
} else {
|
||||
// Tasks that are executed by previously active SONs
|
||||
// E.g. sending approvals and signing that SON was required to do while it was active
|
||||
//approve_leftover_proposals(); ???
|
||||
//process_leftover_sidechain_transactions(); ???
|
||||
}
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
void peerplays_sidechain_plugin_impl::approve_proposals() {
|
||||
|
||||
auto approve_proposal = [&](const chain::son_id_type &son_id, const chain::proposal_id_type &proposal_id) {
|
||||
ilog("peerplays_sidechain_plugin: sending approval for ${p} from ${s}", ("p", proposal_id)("s", son_id));
|
||||
ilog("Sending approval for ${p} from ${s}", ("p", proposal_id)("s", son_id));
|
||||
chain::proposal_update_operation puo;
|
||||
puo.fee_paying_account = get_son_object(son_id).son_account;
|
||||
puo.proposal = proposal_id;
|
||||
|
|
@ -372,7 +402,7 @@ void peerplays_sidechain_plugin_impl::approve_proposals() {
|
|||
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
|
||||
return true;
|
||||
} catch (fc::exception e) {
|
||||
ilog("peerplays_sidechain_plugin_impl: sending approval failed with exception ${e}", ("e", e.what()));
|
||||
elog("Sending approval failed with exception ${e}", ("e", e.what()));
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
|
@ -386,59 +416,54 @@ void peerplays_sidechain_plugin_impl::approve_proposals() {
|
|||
}
|
||||
|
||||
for (const auto proposal_id : proposals) {
|
||||
for (son_id_type son_id : sons) {
|
||||
if (!is_active_son(son_id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const object *obj = plugin.database().find_object(proposal_id);
|
||||
const chain::proposal_object *proposal_ptr = dynamic_cast<const chain::proposal_object *>(obj);
|
||||
if (proposal_ptr == nullptr) {
|
||||
continue;
|
||||
}
|
||||
const proposal_object proposal = *proposal_ptr;
|
||||
|
||||
if (proposal.available_active_approvals.find(get_son_object(son_id).son_account) != proposal.available_active_approvals.end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (proposal.proposed_transaction.operations.size() == 1 && proposal.proposed_transaction.operations[0].which() == chain::operation::tag<chain::son_report_down_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::son_delete_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::son_wallet_update_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::son_wallet_deposit_create_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::son_wallet_deposit_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::son_wallet_withdraw_create_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::son_wallet_withdraw_process_operation>::value) {
|
||||
approve_proposal(son_id, proposal.id);
|
||||
continue;
|
||||
}
|
||||
|
||||
approve_proposal(son_id, proposal.id);
|
||||
const object *obj = plugin.database().find_object(proposal_id);
|
||||
const chain::proposal_object *proposal_ptr = dynamic_cast<const chain::proposal_object *>(obj);
|
||||
if (proposal_ptr == nullptr) {
|
||||
continue;
|
||||
}
|
||||
const proposal_object proposal = *proposal_ptr;
|
||||
|
||||
if (proposal.available_active_approvals.find(get_current_son_object().son_account) != proposal.available_active_approvals.end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (proposal.proposed_transaction.operations.size() == 1 && proposal.proposed_transaction.operations[0].which() == chain::operation::tag<chain::son_report_down_operation>::value) {
|
||||
approve_proposal(get_current_son_id(), proposal.id);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (proposal.proposed_transaction.operations.size() == 1 && proposal.proposed_transaction.operations[0].which() == chain::operation::tag<chain::son_delete_operation>::value) {
|
||||
approve_proposal(get_current_son_id(), proposal.id);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (proposal.proposed_transaction.operations.size() == 1 && proposal.proposed_transaction.operations[0].which() == chain::operation::tag<chain::son_wallet_update_operation>::value) {
|
||||
approve_proposal(get_current_son_id(), proposal.id);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (proposal.proposed_transaction.operations.size() == 1 && proposal.proposed_transaction.operations[0].which() == chain::operation::tag<chain::son_wallet_deposit_create_operation>::value) {
|
||||
approve_proposal(get_current_son_id(), proposal.id);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (proposal.proposed_transaction.operations.size() == 1 && proposal.proposed_transaction.operations[0].which() == chain::operation::tag<chain::son_wallet_deposit_process_operation>::value) {
|
||||
approve_proposal(get_current_son_id(), proposal.id);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (proposal.proposed_transaction.operations.size() == 1 && proposal.proposed_transaction.operations[0].which() == chain::operation::tag<chain::son_wallet_withdraw_create_operation>::value) {
|
||||
approve_proposal(get_current_son_id(), proposal.id);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (proposal.proposed_transaction.operations.size() == 1 && proposal.proposed_transaction.operations[0].which() == chain::operation::tag<chain::son_wallet_withdraw_process_operation>::value) {
|
||||
approve_proposal(get_current_son_id(), proposal.id);
|
||||
continue;
|
||||
}
|
||||
|
||||
approve_proposal(get_current_son_id(), proposal.id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -477,7 +502,7 @@ void peerplays_sidechain_plugin_impl::create_son_down_proposals() {
|
|||
int64_t down_threshold = gpo.parameters.son_down_time();
|
||||
if (((son_obj->status == chain::son_status::active) || (son_obj->status == chain::son_status::request_maintenance)) &&
|
||||
((fc::time_point::now() - last_active_ts) > fc::seconds(down_threshold))) {
|
||||
ilog("peerplays_sidechain_plugin: sending son down proposal for ${t} from ${s}", ("t", std::string(object_id_type(son_obj->id)))("s", std::string(object_id_type(my_son_id))));
|
||||
ilog("Sending son down proposal for ${t} from ${s}", ("t", std::string(object_id_type(son_obj->id)))("s", std::string(object_id_type(my_son_id))));
|
||||
chain::proposal_create_operation op = create_son_down_proposal(son_inf.son_id, last_active_ts);
|
||||
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([&]() {
|
||||
|
|
@ -487,7 +512,7 @@ void peerplays_sidechain_plugin_impl::create_son_down_proposals() {
|
|||
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
|
||||
return true;
|
||||
} catch (fc::exception e) {
|
||||
ilog("peerplays_sidechain_plugin_impl: sending son down proposal failed with exception ${e}", ("e", e.what()));
|
||||
elog("Sending son down proposal failed with exception ${e}", ("e", e.what()));
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
|
@ -512,7 +537,7 @@ void peerplays_sidechain_plugin_impl::create_son_deregister_proposals() {
|
|||
auto op = d.create_son_deregister_proposal(son, get_son_object(my_son_id).son_account);
|
||||
if (op.valid()) {
|
||||
// Signing and pushing into the txs to be included in the block
|
||||
ilog("peerplays_sidechain_plugin: sending son deregister proposal for ${p} from ${s}", ("p", son)("s", my_son_id));
|
||||
ilog("Sending son deregister proposal for ${p} from ${s}", ("p", son)("s", my_son_id));
|
||||
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 {
|
||||
|
|
@ -521,7 +546,7 @@ void peerplays_sidechain_plugin_impl::create_son_deregister_proposals() {
|
|||
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
|
||||
return true;
|
||||
} catch (fc::exception e) {
|
||||
ilog("peerplays_sidechain_plugin_impl: sending son dereg proposal failed with exception ${e}", ("e", e.what()));
|
||||
elog("Sending son deregister proposal failed with exception ${e}", ("e", e.what()));
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
|
@ -560,7 +585,7 @@ void peerplays_sidechain_plugin_impl::on_applied_block(const signed_block &b) {
|
|||
}
|
||||
}
|
||||
|
||||
} // end namespace detail
|
||||
} // namespace detail
|
||||
|
||||
peerplays_sidechain_plugin::peerplays_sidechain_plugin() :
|
||||
my(new detail::peerplays_sidechain_plugin_impl(*this)) {
|
||||
|
|
@ -581,24 +606,30 @@ void peerplays_sidechain_plugin::plugin_set_program_options(
|
|||
}
|
||||
|
||||
void peerplays_sidechain_plugin::plugin_initialize(const boost::program_options::variables_map &options) {
|
||||
ilog("peerplays sidechain plugin: plugin_initialize()");
|
||||
ilog("peerplays sidechain plugin: plugin_initialize() begin");
|
||||
my->plugin_initialize(options);
|
||||
ilog("peerplays sidechain plugin: plugin_initialize() end");
|
||||
}
|
||||
|
||||
void peerplays_sidechain_plugin::plugin_startup() {
|
||||
ilog("peerplays sidechain plugin: plugin_startup()");
|
||||
ilog("peerplays sidechain plugin: plugin_startup() begin");
|
||||
my->plugin_startup();
|
||||
ilog("peerplays sidechain plugin: plugin_startup() end");
|
||||
}
|
||||
|
||||
std::set<chain::son_id_type> &peerplays_sidechain_plugin::get_sons() {
|
||||
return my->get_sons();
|
||||
}
|
||||
|
||||
son_id_type &peerplays_sidechain_plugin::get_current_son_id() {
|
||||
const son_id_type peerplays_sidechain_plugin::get_current_son_id() {
|
||||
return my->get_current_son_id();
|
||||
}
|
||||
|
||||
son_object peerplays_sidechain_plugin::get_son_object(son_id_type son_id) {
|
||||
const son_object peerplays_sidechain_plugin::get_current_son_object() {
|
||||
return my->get_current_son_object();
|
||||
}
|
||||
|
||||
const son_object peerplays_sidechain_plugin::get_son_object(son_id_type son_id) {
|
||||
return my->get_son_object(son_id);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -269,8 +269,6 @@ void sidechain_net_handler::process_sidechain_transactions() {
|
|||
const auto &idx_range = idx.equal_range(std::make_tuple(sidechain, false));
|
||||
|
||||
std::for_each(idx_range.first, idx_range.second, [&](const sidechain_transaction_object &sto) {
|
||||
ilog("Sidechain transaction to process: ${sto}", ("sto", sto));
|
||||
|
||||
son_id_type invalid_signer = son_id_type(0xFFFFFFFF);
|
||||
son_id_type next_signer = invalid_signer;
|
||||
for (auto &signer : sto.signers) {
|
||||
|
|
@ -281,6 +279,8 @@ void sidechain_net_handler::process_sidechain_transactions() {
|
|||
}
|
||||
|
||||
if ((next_signer != invalid_signer) && (next_signer == plugin.get_current_son_id())) {
|
||||
ilog("Sidechain transaction to process: ${sto}", ("sto", sto));
|
||||
|
||||
bool complete = false;
|
||||
std::string processed_sidechain_tx = process_sidechain_transaction(sto, complete);
|
||||
|
||||
|
|
|
|||
|
|
@ -660,10 +660,10 @@ fc::http::reply bitcoin_rpc_client::send_post_request(std::string body, bool sho
|
|||
|
||||
show_log = true; // Log all requests temporary
|
||||
if (show_log) {
|
||||
ilog(" ### Request URL: ${url} ###", ("url", url));
|
||||
ilog(" ### Request: ${body} ###", ("body", body));
|
||||
ilog("### Request URL: ${url}", ("url", url));
|
||||
ilog("### Request: ${body}", ("body", body));
|
||||
std::stringstream ss(std::string(reply.body.begin(), reply.body.end()));
|
||||
ilog(" ### Response: ${ss} ###", ("ss", ss.str()));
|
||||
ilog("### Response: ${ss}", ("ss", ss.str()));
|
||||
}
|
||||
|
||||
return reply;
|
||||
|
|
|
|||
Loading…
Reference in a new issue