From 36006e9e62f79bb25311392c7717c88152211fb6 Mon Sep 17 00:00:00 2001 From: oldcold Date: Mon, 8 Jul 2019 11:42:42 +0800 Subject: [PATCH 1/6] valid new view before emit --- libraries/chain/include/eosio/chain/pbft.hpp | 4 ++-- libraries/chain/pbft.cpp | 24 ++++++++------------ libraries/chain/pbft_database.cpp | 10 ++++++-- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/libraries/chain/include/eosio/chain/pbft.hpp b/libraries/chain/include/eosio/chain/pbft.hpp index ba78d3ab1ea..05e34596a7a 100644 --- a/libraries/chain/include/eosio/chain/pbft.hpp +++ b/libraries/chain/include/eosio/chain/pbft.hpp @@ -40,7 +40,7 @@ namespace eosio { void on_prepare(pbft_metadata_ptr e); void on_commit(pbft_metadata_ptr e); void on_view_change(pbft_metadata_ptr e); - void on_new_view(const pbft_metadata_ptr &e); + void on_new_view(pbft_metadata_ptr e); void send_prepare(); void send_commit(); @@ -187,7 +187,7 @@ namespace eosio { void on_pbft_prepare(pbft_metadata_ptr p); void on_pbft_commit(pbft_metadata_ptr c); void on_pbft_view_change(pbft_metadata_ptr vc); - void on_pbft_new_view(const pbft_metadata_ptr &nv); + void on_pbft_new_view(pbft_metadata_ptr nv); void on_pbft_checkpoint(const pbft_metadata_ptr &cp); private: diff --git a/libraries/chain/pbft.cpp b/libraries/chain/pbft.cpp index 8789abce3cf..92b646c8af5 100644 --- a/libraries/chain/pbft.cpp +++ b/libraries/chain/pbft.cpp @@ -81,8 +81,8 @@ namespace eosio { state_machine->on_view_change(std::move(vc)); } - void pbft_controller::on_pbft_new_view(const pbft_metadata_ptr &nv) { - state_machine->on_new_view(nv); + void pbft_controller::on_pbft_new_view(pbft_metadata_ptr nv) { + state_machine->on_new_view(std::move(nv)); } void pbft_controller::on_pbft_checkpoint(const pbft_metadata_ptr &cp) { @@ -137,20 +137,21 @@ namespace eosio { current->send_view_change(shared_from_this(), pbft_db); } - void psm_machine::on_new_view(const pbft_metadata_ptr &e) { - if (e->msg.new_view <= get_current_view()) return; + void psm_machine::on_new_view(pbft_metadata_ptr e) { + auto nv = std::move(e); + if (nv->msg.new_view <= get_current_view()) return; try { - pbft_db.validate_new_view(e->msg, e->sender_key); + pbft_db.validate_new_view(nv->msg, nv->sender_key); } catch (const fc::exception& ex) { elog("bad new view, ${s} ", ("s",ex.to_string())); return; } try { - transit_to_new_view(e, current); + transit_to_new_view(nv, current); } catch(...) { - elog("apply new view failed, waiting for next round.. ${nv} ", ("nv", e->msg)); + elog("apply new view failed, waiting for next round.. ${nv} ", ("nv", nv->msg)); } } @@ -366,6 +367,7 @@ namespace eosio { auto prepares = pbft_db.send_and_add_pbft_prepare(pbft_prepare(), get_current_view()); set_prepares_cache(prepares); + //TODO: reset prepare timer; set_view_changes_cache(pbft_view_change()); set_view_change_timer(0); @@ -378,6 +380,7 @@ namespace eosio { auto commits = pbft_db.send_and_add_pbft_commit(pbft_commit(), get_current_view()); set_commits_cache(commits); + //TODO: reset commit timer; set_view_changes_cache(pbft_view_change()); @@ -419,13 +422,6 @@ namespace eosio { if (nv_msg.empty()) return false; - try { - pbft_db.validate_new_view(nv_msg, pk); - } catch (const fc::exception& ex) { - elog("bad new view, ${s} ", ("s", ex.to_string())); - return false; - } - try { transit_to_new_view(std::make_shared>(nv_msg, pbft_db.get_chain_id()), s); return true; diff --git a/libraries/chain/pbft_database.cpp b/libraries/chain/pbft_database.cpp index 7ef06c068cd..a6df008f755 100644 --- a/libraries/chain/pbft_database.cpp +++ b/libraries/chain/pbft_database.cpp @@ -605,8 +605,14 @@ namespace eosio { nv.stable_checkpoint=highest_sc; nv.view_changed_cert=vcc; nv.sender_signature = sp_itr->second(nv.digest(chain_id)); - emit(pbft_outgoing_new_view, nv); - return nv; + try { + validate_new_view(nv, sp_itr->first); + emit(pbft_outgoing_new_view, nv); + return nv; + } catch (const fc::exception& ex) { + elog("bad new view, ${s} ", ("s", ex.to_string())); + return pbft_new_view(); + } } pbft_prepared_certificate pbft_database::generate_prepared_certificate() { From 019f595ff14e8ec8cacdfb3309b238cb1257bca2 Mon Sep 17 00:00:00 2001 From: oldcold Date: Tue, 9 Jul 2019 18:17:41 +0800 Subject: [PATCH 2/6] add necessary validations before trying to relay new view msgs; optimise pbft signals. --- libraries/chain/include/eosio/chain/pbft.hpp | 72 +++---- .../include/eosio/chain/pbft_database.hpp | 31 ++- libraries/chain/pbft.cpp | 84 ++++---- libraries/chain/pbft_database.cpp | 20 +- .../include/eosio/chain/plugin_interface.hpp | 10 +- plugins/chain_plugin/chain_plugin.cpp | 40 ++-- plugins/net_plugin/net_plugin.cpp | 180 +++++++++--------- unittests/pbft_tests.cpp | 18 +- 8 files changed, 229 insertions(+), 226 deletions(-) diff --git a/libraries/chain/include/eosio/chain/pbft.hpp b/libraries/chain/include/eosio/chain/pbft.hpp index 05e34596a7a..2bebe05cc79 100644 --- a/libraries/chain/include/eosio/chain/pbft.hpp +++ b/libraries/chain/include/eosio/chain/pbft.hpp @@ -37,18 +37,18 @@ namespace eosio { return current; } - void on_prepare(pbft_metadata_ptr e); - void on_commit(pbft_metadata_ptr e); - void on_view_change(pbft_metadata_ptr e); - void on_new_view(pbft_metadata_ptr e); + void on_prepare(const pbft_metadata_ptr& e); + void on_commit(const pbft_metadata_ptr& e); + void on_view_change(const pbft_metadata_ptr& e); + void on_new_view(const pbft_metadata_ptr& e); void send_prepare(); void send_commit(); void send_view_change(); - void transit_to_committed_state(psm_state_ptr s, bool to_new_view); - void transit_to_prepared_state(psm_state_ptr s); - void transit_to_view_change_state(psm_state_ptr s); + void transit_to_committed_state(const psm_state_ptr& s, bool to_new_view); + void transit_to_prepared_state(const psm_state_ptr& s); + void transit_to_view_change_state(const psm_state_ptr& s); void transit_to_new_view(const pbft_metadata_ptr& e, const psm_state_ptr& s); void do_send_view_change(); @@ -106,13 +106,13 @@ namespace eosio { psm_state(); ~psm_state(); - virtual void on_prepare(psm_machine_ptr m, pbft_metadata_ptr e, pbft_database &pbft_db) = 0; - virtual void on_commit(psm_machine_ptr m, pbft_metadata_ptr e, pbft_database &pbft_db) = 0; - virtual void on_view_change(psm_machine_ptr m, pbft_metadata_ptr e, pbft_database &pbft_db) = 0; + virtual void on_prepare(const psm_machine_ptr& m, const pbft_metadata_ptr& e, pbft_database &pbft_db) = 0; + virtual void on_commit(const psm_machine_ptr& m, const pbft_metadata_ptr& e, pbft_database &pbft_db) = 0; + virtual void on_view_change(const psm_machine_ptr& m, const pbft_metadata_ptr& e, pbft_database &pbft_db) = 0; - virtual void send_prepare(psm_machine_ptr m, pbft_database &pbft_db) = 0; - virtual void send_commit(psm_machine_ptr m, pbft_database &pbft_db) = 0; - virtual void send_view_change(psm_machine_ptr m, pbft_database &pbft_db) = 0; + virtual void send_prepare(const psm_machine_ptr& m, pbft_database &pbft_db) = 0; + virtual void send_commit(const psm_machine_ptr& m, pbft_database &pbft_db) = 0; + virtual void send_view_change(const psm_machine_ptr& m, pbft_database &pbft_db) = 0; virtual const char* get_name() = 0; std::shared_ptr get_self() { return shared_from_this(); }; @@ -124,13 +124,13 @@ namespace eosio { psm_prepared_state(); ~psm_prepared_state(); - void on_prepare(psm_machine_ptr m, pbft_metadata_ptr e, pbft_database &pbft_db) override; - void on_commit(psm_machine_ptr m, pbft_metadata_ptr e, pbft_database &pbft_db) override; - void on_view_change(psm_machine_ptr m, pbft_metadata_ptr e, pbft_database &pbft_db) override; + void on_prepare(const psm_machine_ptr& m, const pbft_metadata_ptr& e, pbft_database &pbft_db) override; + void on_commit(const psm_machine_ptr& m, const pbft_metadata_ptr& e, pbft_database &pbft_db) override; + void on_view_change(const psm_machine_ptr& m, const pbft_metadata_ptr& e, pbft_database &pbft_db) override; - void send_prepare(psm_machine_ptr m, pbft_database &pbft_db) override; - void send_commit(psm_machine_ptr m, pbft_database &pbft_db) override; - void send_view_change(psm_machine_ptr m, pbft_database &pbft_db) override; + void send_prepare(const psm_machine_ptr& m, pbft_database &pbft_db) override; + void send_commit(const psm_machine_ptr& m, pbft_database &pbft_db) override; + void send_view_change(const psm_machine_ptr& m, pbft_database &pbft_db) override; bool pending_commit_local; @@ -142,13 +142,13 @@ namespace eosio { psm_committed_state(); ~psm_committed_state(); - void on_prepare(psm_machine_ptr m, pbft_metadata_ptr e, pbft_database &pbft_db) override; - void on_commit(psm_machine_ptr m, pbft_metadata_ptr e, pbft_database &pbft_db) override; - void on_view_change(psm_machine_ptr m, pbft_metadata_ptr e, pbft_database &pbft_db) override; + void on_prepare(const psm_machine_ptr& m, const pbft_metadata_ptr& e, pbft_database &pbft_db) override; + void on_commit(const psm_machine_ptr& m, const pbft_metadata_ptr& e, pbft_database &pbft_db) override; + void on_view_change(const psm_machine_ptr& m, const pbft_metadata_ptr& e, pbft_database &pbft_db) override; - void send_prepare(psm_machine_ptr m, pbft_database &pbft_db) override; - void send_commit(psm_machine_ptr m, pbft_database &pbft_db) override; - void send_view_change(psm_machine_ptr m, pbft_database &pbft_db) override; + void send_prepare(const psm_machine_ptr& m, pbft_database &pbft_db) override; + void send_commit(const psm_machine_ptr& m, pbft_database &pbft_db) override; + void send_view_change(const psm_machine_ptr& m, pbft_database &pbft_db) override; const char* get_name() override { return "{==== COMMITTED ====}"; } }; @@ -158,13 +158,13 @@ namespace eosio { psm_view_change_state(); ~psm_view_change_state(); - void on_prepare(psm_machine_ptr m, pbft_metadata_ptr e, pbft_database &pbft_db) override; - void on_commit(psm_machine_ptr m, pbft_metadata_ptr e, pbft_database &pbft_db) override; - void on_view_change(psm_machine_ptr m, pbft_metadata_ptr e, pbft_database &pbft_db) override; + void on_prepare(const psm_machine_ptr& m, const pbft_metadata_ptr& e, pbft_database &pbft_db) override; + void on_commit(const psm_machine_ptr& m, const pbft_metadata_ptr& e, pbft_database &pbft_db) override; + void on_view_change(const psm_machine_ptr& m, const pbft_metadata_ptr& e, pbft_database &pbft_db) override; - void send_prepare(psm_machine_ptr m, pbft_database &pbft_db) override; - void send_commit(psm_machine_ptr m, pbft_database &pbft_db) override; - void send_view_change(psm_machine_ptr m, pbft_database &pbft_db) override; + void send_prepare(const psm_machine_ptr& m, pbft_database &pbft_db) override; + void send_commit(const psm_machine_ptr& m, pbft_database &pbft_db) override; + void send_view_change(const psm_machine_ptr& m, pbft_database &pbft_db) override; const char* get_name() override { return "{==== VIEW CHANGE ====}"; } }; @@ -184,11 +184,11 @@ namespace eosio { void maybe_pbft_view_change(); void maybe_pbft_checkpoint(); - void on_pbft_prepare(pbft_metadata_ptr p); - void on_pbft_commit(pbft_metadata_ptr c); - void on_pbft_view_change(pbft_metadata_ptr vc); - void on_pbft_new_view(pbft_metadata_ptr nv); - void on_pbft_checkpoint(const pbft_metadata_ptr &cp); + void on_pbft_prepare(const pbft_metadata_ptr& p); + void on_pbft_commit(const pbft_metadata_ptr& c); + void on_pbft_view_change(const pbft_metadata_ptr& vc); + void on_pbft_new_view(const pbft_metadata_ptr& nv); + void on_pbft_checkpoint(const pbft_metadata_ptr& cp); private: fc::path datadir; diff --git a/libraries/chain/include/eosio/chain/pbft_database.hpp b/libraries/chain/include/eosio/chain/pbft_database.hpp index 7fd03ebb3e7..b72f9645b66 100644 --- a/libraries/chain/include/eosio/chain/pbft_database.hpp +++ b/libraries/chain/include/eosio/chain/pbft_database.hpp @@ -61,7 +61,7 @@ namespace eosio { template struct pbft_message_metadata { - explicit pbft_message_metadata(pbft_message_body m, chain_id_type chain_id): msg{m} { + explicit pbft_message_metadata(pbft_message_body m, chain_id_type& chain_id): msg{m} { try { sender_key = crypto::public_key(msg.sender_signature, msg.digest(chain_id), true); } catch (fc::exception & /*e*/) { @@ -110,6 +110,8 @@ namespace eosio { } }; + using pbft_prepare_ptr = std::shared_ptr; + struct pbft_commit { explicit pbft_commit() = default; @@ -166,6 +168,8 @@ namespace eosio { } }; + using pbft_checkpoint_ptr = std::shared_ptr; + struct pbft_stable_checkpoint { explicit pbft_stable_checkpoint() = default; @@ -252,6 +256,8 @@ namespace eosio { } }; + using pbft_view_change_ptr = std::shared_ptr; + struct pbft_view_changed_certificate { explicit pbft_view_changed_certificate() = default; @@ -301,6 +307,8 @@ namespace eosio { } }; + using pbft_new_view_ptr = std::shared_ptr; + struct pbft_state { block_id_type block_id; block_num_type block_num = 0; @@ -465,7 +473,7 @@ namespace eosio { bool should_recv_pbft_msg(const public_key_type &pub_key); bool pending_pbft_lib(); - chain_id_type get_chain_id() {return chain_id;} + chain_id_type& get_chain_id() {return chain_id;} pbft_stable_checkpoint get_stable_checkpoint_by_id(const block_id_type &block_id, bool incl_blk_extn = true); pbft_stable_checkpoint fetch_stable_checkpoint_from_blk_extn(const signed_block_ptr &b); block_info_type cal_pending_stable_checkpoint() const; @@ -481,20 +489,11 @@ namespace eosio { flat_map get_pbft_fork_schedules() const; - signal pbft_outgoing_prepare; - signal pbft_incoming_prepare; - - signal pbft_outgoing_commit; - signal pbft_incoming_commit; - - signal pbft_outgoing_view_change; - signal pbft_incoming_view_change; - - signal pbft_outgoing_new_view; - signal pbft_incoming_new_view; - - signal pbft_outgoing_checkpoint; - signal pbft_incoming_checkpoint; + signal pbft_outgoing_prepare; + signal pbft_outgoing_commit; + signal pbft_outgoing_view_change; + signal pbft_outgoing_new_view; + signal pbft_outgoing_checkpoint; private: controller &ctrl; diff --git a/libraries/chain/pbft.cpp b/libraries/chain/pbft.cpp index 92b646c8af5..5679b332733 100644 --- a/libraries/chain/pbft.cpp +++ b/libraries/chain/pbft.cpp @@ -69,20 +69,20 @@ namespace eosio { pbft_db.checkpoint_local(); } - void pbft_controller::on_pbft_prepare(pbft_metadata_ptr p) { - state_machine->on_prepare(std::move(p)); + void pbft_controller::on_pbft_prepare(const pbft_metadata_ptr& p) { + state_machine->on_prepare(p); } - void pbft_controller::on_pbft_commit(pbft_metadata_ptr c) { - state_machine->on_commit(std::move(c)); + void pbft_controller::on_pbft_commit(const pbft_metadata_ptr& c) { + state_machine->on_commit(c); } - void pbft_controller::on_pbft_view_change(pbft_metadata_ptr vc) { - state_machine->on_view_change(std::move(vc)); + void pbft_controller::on_pbft_view_change(const pbft_metadata_ptr& vc) { + state_machine->on_view_change(vc); } - void pbft_controller::on_pbft_new_view(pbft_metadata_ptr nv) { - state_machine->on_new_view(std::move(nv)); + void pbft_controller::on_pbft_new_view(const pbft_metadata_ptr& nv) { + state_machine->on_new_view(nv); } void pbft_controller::on_pbft_checkpoint(const pbft_metadata_ptr &cp) { @@ -113,45 +113,44 @@ namespace eosio { psm_machine::~psm_machine() = default; - void psm_machine::on_prepare(pbft_metadata_ptr e) { - current->on_prepare(shared_from_this(), std::move(e), pbft_db); + void psm_machine::on_prepare(const pbft_metadata_ptr& e) { + current->on_prepare(shared_from_this(), e, pbft_db); } void psm_machine::send_prepare() { current->send_prepare(shared_from_this(), pbft_db); } - void psm_machine::on_commit(pbft_metadata_ptr e) { - current->on_commit(shared_from_this(), std::move(e), pbft_db); + void psm_machine::on_commit(const pbft_metadata_ptr& e) { + current->on_commit(shared_from_this(), e, pbft_db); } void psm_machine::send_commit() { current->send_commit(shared_from_this(), pbft_db); } - void psm_machine::on_view_change(pbft_metadata_ptr e) { - current->on_view_change(shared_from_this(), std::move(e), pbft_db); + void psm_machine::on_view_change(const pbft_metadata_ptr& e) { + current->on_view_change(shared_from_this(), e, pbft_db); } void psm_machine::send_view_change() { current->send_view_change(shared_from_this(), pbft_db); } - void psm_machine::on_new_view(pbft_metadata_ptr e) { - auto nv = std::move(e); - if (nv->msg.new_view <= get_current_view()) return; + void psm_machine::on_new_view(const pbft_metadata_ptr& e) { + if (e->msg.new_view <= get_current_view()) return; try { - pbft_db.validate_new_view(nv->msg, nv->sender_key); + pbft_db.validate_new_view(e->msg, e->sender_key); } catch (const fc::exception& ex) { elog("bad new view, ${s} ", ("s",ex.to_string())); return; } try { - transit_to_new_view(nv, current); + transit_to_new_view(e, current); } catch(...) { - elog("apply new view failed, waiting for next round.. ${nv} ", ("nv", nv->msg)); + elog("apply new view failed, waiting for next round.. ${nv} ", ("nv", e->msg)); } } @@ -168,18 +167,18 @@ namespace eosio { psm_prepared_state::psm_prepared_state() {pending_commit_local = false;} psm_prepared_state::~psm_prepared_state() = default; - void psm_prepared_state::on_prepare(psm_machine_ptr m, pbft_metadata_ptr e, pbft_database &pbft_db) { + void psm_prepared_state::on_prepare(const psm_machine_ptr& m, const pbft_metadata_ptr& e, pbft_database &pbft_db) { //ignore } - void psm_prepared_state::send_prepare(psm_machine_ptr m, pbft_database &pbft_db) { + void psm_prepared_state::send_prepare(const psm_machine_ptr& m, pbft_database &pbft_db) { //retry if (m->get_prepares_cache().empty()) return; pbft_db.send_and_add_pbft_prepare(m->get_prepares_cache(), m->get_current_view()); } - void psm_prepared_state::on_commit(psm_machine_ptr m, pbft_metadata_ptr e, pbft_database &pbft_db) { + void psm_prepared_state::on_commit(const psm_machine_ptr& m, const pbft_metadata_ptr& e, pbft_database &pbft_db) { if (e->msg.view < m->get_current_view()) return; if (!pbft_db.is_valid_commit(e->msg, e->sender_key)) return; @@ -202,7 +201,7 @@ namespace eosio { } } - void psm_prepared_state::send_commit(psm_machine_ptr m, pbft_database &pbft_db) { + void psm_prepared_state::send_commit(const psm_machine_ptr& m, pbft_database &pbft_db) { auto commits = pbft_db.send_and_add_pbft_commit(m->get_commits_cache(), m->get_current_view()); if (!commits.empty()) { @@ -221,7 +220,7 @@ namespace eosio { } } - void psm_prepared_state::on_view_change(psm_machine_ptr m, pbft_metadata_ptr e, pbft_database &pbft_db) { + void psm_prepared_state::on_view_change(const psm_machine_ptr& m, const pbft_metadata_ptr& e, pbft_database &pbft_db) { if (e->msg.target_view <= m->get_current_view()) return; if (!pbft_db.is_valid_view_change(e->msg, e->sender_key)) return; @@ -236,7 +235,7 @@ namespace eosio { } } - void psm_prepared_state::send_view_change(psm_machine_ptr m, pbft_database &pbft_db) { + void psm_prepared_state::send_view_change(const psm_machine_ptr& m, pbft_database &pbft_db) { m->transit_to_view_change_state(shared_from_this()); } @@ -247,7 +246,7 @@ namespace eosio { /** * psm_committed_state */ - void psm_committed_state::on_prepare(psm_machine_ptr m, pbft_metadata_ptr e, pbft_database &pbft_db) { + void psm_committed_state::on_prepare(const psm_machine_ptr& m, const pbft_metadata_ptr& e, pbft_database &pbft_db) { //validate if (e->msg.view < m->get_current_view()) return; if (!pbft_db.is_valid_prepare(e->msg, e->sender_key)) return; @@ -259,7 +258,7 @@ namespace eosio { if (pbft_db.should_prepared()) m->transit_to_prepared_state(shared_from_this()); } - void psm_committed_state::send_prepare(psm_machine_ptr m, pbft_database &pbft_db) { + void psm_committed_state::send_prepare(const psm_machine_ptr& m, pbft_database &pbft_db) { auto prepares = pbft_db.send_and_add_pbft_prepare(m->get_prepares_cache(), m->get_current_view()); @@ -271,7 +270,7 @@ namespace eosio { if (pbft_db.should_prepared()) m->transit_to_prepared_state(shared_from_this()); } - void psm_committed_state::on_commit(psm_machine_ptr m, pbft_metadata_ptr e, pbft_database &pbft_db) { + void psm_committed_state::on_commit(const psm_machine_ptr& m, const pbft_metadata_ptr& e, pbft_database &pbft_db) { if (e->msg.view < m->get_current_view()) return; if (!pbft_db.is_valid_commit(e->msg, e->sender_key)) return; @@ -279,14 +278,14 @@ namespace eosio { pbft_db.add_pbft_commit(e->msg, e->sender_key); } - void psm_committed_state::send_commit(psm_machine_ptr m, pbft_database &pbft_db) { + void psm_committed_state::send_commit(const psm_machine_ptr& m, pbft_database &pbft_db) { if (m->get_commits_cache().empty()) return; pbft_db.send_and_add_pbft_commit(m->get_commits_cache(), m->get_current_view()); } - void psm_committed_state::on_view_change(psm_machine_ptr m, pbft_metadata_ptr e, pbft_database &pbft_db) { + void psm_committed_state::on_view_change(const psm_machine_ptr& m, const pbft_metadata_ptr& e, pbft_database &pbft_db) { if (e->msg.target_view <= m->get_current_view()) return; if (!pbft_db.is_valid_view_change(e->msg, e->sender_key)) return; @@ -301,7 +300,7 @@ namespace eosio { } } - void psm_committed_state::send_view_change(psm_machine_ptr m, pbft_database &pbft_db) { + void psm_committed_state::send_view_change(const psm_machine_ptr& m, pbft_database &pbft_db) { m->transit_to_view_change_state(shared_from_this()); } @@ -310,23 +309,23 @@ namespace eosio { /** * psm_view_change_state */ - void psm_view_change_state::on_prepare(psm_machine_ptr m, pbft_metadata_ptr e, pbft_database &pbft_db) { + void psm_view_change_state::on_prepare(const psm_machine_ptr& m, const pbft_metadata_ptr& e, pbft_database &pbft_db) { //ignore; } - void psm_view_change_state::send_prepare(psm_machine_ptr m, pbft_database &pbft_db) { + void psm_view_change_state::send_prepare(const psm_machine_ptr& m, pbft_database &pbft_db) { //ignore; } - void psm_view_change_state::on_commit(psm_machine_ptr m, pbft_metadata_ptr e, pbft_database &pbft_db) { + void psm_view_change_state::on_commit(const psm_machine_ptr& m, const pbft_metadata_ptr& e, pbft_database &pbft_db) { //ignore; } - void psm_view_change_state::send_commit(psm_machine_ptr m, pbft_database &pbft_db) { + void psm_view_change_state::send_commit(const psm_machine_ptr& m, pbft_database &pbft_db) { //ignore; } - void psm_view_change_state::on_view_change(psm_machine_ptr m, pbft_metadata_ptr e, pbft_database &pbft_db) { + void psm_view_change_state::on_view_change(const psm_machine_ptr& m, const pbft_metadata_ptr& e, pbft_database &pbft_db) { //skip from view change state if my lib is higher than my view change state height. auto vc = m->get_view_changes_cache(); @@ -343,7 +342,7 @@ namespace eosio { m->maybe_new_view(shared_from_this()); } - void psm_view_change_state::send_view_change(psm_machine_ptr m, pbft_database &pbft_db) { + void psm_view_change_state::send_view_change(const psm_machine_ptr& m, pbft_database &pbft_db) { //skip from view change state if my lib is higher than my view change state height. auto vc = m->get_view_changes_cache(); @@ -357,7 +356,7 @@ namespace eosio { m->maybe_new_view(shared_from_this()); } - void psm_machine::transit_to_committed_state(psm_state_ptr s, bool to_new_view) { + void psm_machine::transit_to_committed_state(const psm_state_ptr& s, bool to_new_view) { if (!to_new_view) { auto nv = pbft_db.get_committed_view(); @@ -373,10 +372,9 @@ namespace eosio { set_view_change_timer(0); set_current(std::make_shared()); - s.reset(); } - void psm_machine::transit_to_prepared_state(psm_state_ptr s) { + void psm_machine::transit_to_prepared_state(const psm_state_ptr& s) { auto commits = pbft_db.send_and_add_pbft_commit(pbft_commit(), get_current_view()); set_commits_cache(commits); @@ -385,10 +383,9 @@ namespace eosio { set_view_changes_cache(pbft_view_change()); set_current(std::make_shared()); - s.reset(); } - void psm_machine::transit_to_view_change_state(psm_state_ptr s) { + void psm_machine::transit_to_view_change_state(const psm_state_ptr& s) { set_commits_cache(pbft_commit()); set_prepares_cache(pbft_prepare()); @@ -402,7 +399,6 @@ namespace eosio { auto nv = maybe_new_view(s); if (nv) return; } - s.reset(); } bool psm_machine::maybe_new_view(const psm_state_ptr &s) { diff --git a/libraries/chain/pbft_database.cpp b/libraries/chain/pbft_database.cpp index a6df008f755..10f05347f1c 100644 --- a/libraries/chain/pbft_database.cpp +++ b/libraries/chain/pbft_database.cpp @@ -181,7 +181,7 @@ namespace eosio { if (lib == block_id_type()) return true; auto forks = ctrl.fork_db().fetch_branch_from(in, lib); - //`branch_type` will always contain at least the common ancestor. + //`branch_type` will always contain at least themselves. //`in` block num should be higher than lib, yet fall on the same branch with lib. return forks.first.size() > 1 && forks.second.size() == 1; }; @@ -193,7 +193,7 @@ namespace eosio { auto retry_p = cached_prepare; retry_p.common.timestamp = time_point::now(); retry_p.sender_signature = sp.second(retry_p.digest(chain_id)); - emit(pbft_outgoing_prepare, retry_p); + emit(pbft_outgoing_prepare, std::make_shared(retry_p)); } return prepare_to_be_cached; } else if (reserve_prepare(my_prepare)) { @@ -201,7 +201,7 @@ namespace eosio { pbft_prepare reserve_p; reserve_p.view=current_view; reserve_p.block_info={my_prepare}; reserve_p.sender_signature = sp.second(reserve_p.digest(chain_id)); - emit(pbft_outgoing_prepare, reserve_p); + emit(pbft_outgoing_prepare, std::make_shared(reserve_p)); if (prepare_to_be_cached.empty()) prepare_to_be_cached = reserve_p; } return prepare_to_be_cached; @@ -225,7 +225,7 @@ namespace eosio { new_p.view=current_view; new_p.block_info={hwbs->id}; new_p.sender_signature = sp.second(new_p.digest(chain_id)); if (is_valid_prepare(new_p, sp.first)) { - emit(pbft_outgoing_prepare, new_p); + emit(pbft_outgoing_prepare, std::make_shared(new_p)); add_pbft_prepare(new_p, sp.first); sent = true; if (prepare_to_be_cached.empty()) prepare_to_be_cached = new_p; @@ -330,7 +330,7 @@ namespace eosio { auto retry_c = cached_commit; retry_c.common.timestamp = time_point::now(); retry_c.sender_signature = sp.second(retry_c.digest(chain_id)); - emit(pbft_outgoing_commit, retry_c); + emit(pbft_outgoing_commit, std::make_shared(retry_c)); } return commit_to_be_cached; } else { @@ -351,7 +351,7 @@ namespace eosio { new_c.sender_signature = sp.second(new_c.digest(chain_id)); if (is_valid_commit(new_c, sp.first)) { - emit(pbft_outgoing_commit, new_c); + emit(pbft_outgoing_commit, std::make_shared(new_c)); add_pbft_commit(new_c, sp.first); if (commit_to_be_cached.empty()) commit_to_be_cached = new_c; } @@ -515,7 +515,7 @@ namespace eosio { auto retry_vc = cached_view_change; retry_vc.common.timestamp = time_point::now(); retry_vc.sender_signature = sp.second(retry_vc.digest(chain_id)); - emit(pbft_outgoing_view_change, retry_vc); + emit(pbft_outgoing_view_change, std::make_shared(retry_vc)); } return view_change_to_be_cached; } else { @@ -531,7 +531,7 @@ namespace eosio { new_vc.stable_checkpoint=my_lsc; new_vc.sender_signature = my_sp.second(new_vc.digest(chain_id)); if (is_valid_view_change(new_vc, my_sp.first)) { - emit(pbft_outgoing_view_change, new_vc); + emit(pbft_outgoing_view_change, std::make_shared(new_vc)); add_pbft_view_change(new_vc, my_sp.first); if (view_change_to_be_cached.empty()) view_change_to_be_cached = new_vc; } @@ -607,7 +607,7 @@ namespace eosio { nv.sender_signature = sp_itr->second(nv.digest(chain_id)); try { validate_new_view(nv, sp_itr->first); - emit(pbft_outgoing_new_view, nv); + emit(pbft_outgoing_new_view, std::make_shared(nv)); return nv; } catch (const fc::exception& ex) { elog("bad new view, ${s} ", ("s", ex.to_string())); @@ -1329,7 +1329,7 @@ namespace eosio { void pbft_database::send_pbft_checkpoint() { auto cps_to_send = generate_and_add_pbft_checkpoint(); for (auto const &cp: cps_to_send) { - emit(pbft_outgoing_checkpoint, cp); + emit(pbft_outgoing_checkpoint, std::make_shared(cp)); } } diff --git a/plugins/chain_interface/include/eosio/chain/plugin_interface.hpp b/plugins/chain_interface/include/eosio/chain/plugin_interface.hpp index a168ea54928..81935707abe 100644 --- a/plugins/chain_interface/include/eosio/chain/plugin_interface.hpp +++ b/plugins/chain_interface/include/eosio/chain/plugin_interface.hpp @@ -73,11 +73,11 @@ namespace eosio { namespace chain { namespace plugin_interface { } namespace outgoing { - using prepare_channel = channel_decl; - using commit_channel = channel_decl; - using view_change_channel = channel_decl; - using new_view_channel = channel_decl; - using checkpoint_channel = channel_decl; + using prepare_channel = channel_decl; + using commit_channel = channel_decl; + using view_change_channel = channel_decl; + using new_view_channel = channel_decl; + using checkpoint_channel = channel_decl; } } diff --git a/plugins/chain_plugin/chain_plugin.cpp b/plugins/chain_plugin/chain_plugin.cpp index ce0eab28de5..581bcb80443 100644 --- a/plugins/chain_plugin/chain_plugin.cpp +++ b/plugins/chain_plugin/chain_plugin.cpp @@ -178,11 +178,11 @@ class chain_plugin_impl { fc::microseconds abi_serializer_max_time_ms; fc::optional snapshot_path; - void on_pbft_incoming_prepare(pbft_metadata_ptr p); - void on_pbft_incoming_commit(pbft_metadata_ptr c); - void on_pbft_incoming_view_change(pbft_metadata_ptr vc); - void on_pbft_incoming_new_view(pbft_metadata_ptr nv); - void on_pbft_incoming_checkpoint(pbft_metadata_ptr cp); + void on_pbft_incoming_prepare(const pbft_metadata_ptr& p); + void on_pbft_incoming_commit(const pbft_metadata_ptr& c); + void on_pbft_incoming_view_change(const pbft_metadata_ptr& vc); + void on_pbft_incoming_new_view(const pbft_metadata_ptr& nv); + void on_pbft_incoming_checkpoint(const pbft_metadata_ptr& cp); // retained references to channels for easy publication channels::pre_accepted_block::channel_type& pre_accepted_block_channel; @@ -805,48 +805,48 @@ void chain_plugin::plugin_initialize(const variables_map& options) { //pbft - my->pbft_incoming_prepare_subscription = my->pbft_incoming_prepare_channel.subscribe( [this]( pbft_metadata_ptr p ){ + my->pbft_incoming_prepare_subscription = my->pbft_incoming_prepare_channel.subscribe( [this]( const pbft_metadata_ptr& p ){ my->on_pbft_incoming_prepare(p); }); - my->pbft_incoming_commit_subscription = my->pbft_incoming_commit_channel.subscribe( [this]( pbft_metadata_ptr c ){ + my->pbft_incoming_commit_subscription = my->pbft_incoming_commit_channel.subscribe( [this]( const pbft_metadata_ptr& c ){ my->on_pbft_incoming_commit(c); }); - my->pbft_incoming_view_change_subscription = my->pbft_incoming_view_change_channel.subscribe( [this]( pbft_metadata_ptr vc ){ + my->pbft_incoming_view_change_subscription = my->pbft_incoming_view_change_channel.subscribe( [this]( const pbft_metadata_ptr& vc ){ my->on_pbft_incoming_view_change(vc); }); - my->pbft_incoming_new_view_subscription = my->pbft_incoming_new_view_channel.subscribe( [this]( pbft_metadata_ptr nv ){ + my->pbft_incoming_new_view_subscription = my->pbft_incoming_new_view_channel.subscribe( [this]( const pbft_metadata_ptr& nv ){ my->on_pbft_incoming_new_view(nv); }); - my->pbft_incoming_checkpoint_subscription = my->pbft_incoming_checkpoint_channel.subscribe( [this]( pbft_metadata_ptr cp ){ + my->pbft_incoming_checkpoint_subscription = my->pbft_incoming_checkpoint_channel.subscribe( [this]( const pbft_metadata_ptr& cp ){ my->on_pbft_incoming_checkpoint(cp); }); my->pbft_outgoing_prepare_connection = my->pbft_ctrl->pbft_db.pbft_outgoing_prepare.connect( - [this]( const pbft_prepare& prepare ) { + [this]( const pbft_prepare_ptr& prepare ) { my->pbft_outgoing_prepare_channel.publish( prepare ); }); my->pbft_outgoing_commit_connection = my->pbft_ctrl->pbft_db.pbft_outgoing_commit.connect( - [this]( const pbft_commit& commit ) { + [this]( const pbft_commit_ptr& commit ) { my->pbft_outgoing_commit_channel.publish( commit ); }); my->pbft_outgoing_view_change_connection = my->pbft_ctrl->pbft_db.pbft_outgoing_view_change.connect( - [this]( const pbft_view_change& view_change ) { + [this]( const pbft_view_change_ptr& view_change ) { my->pbft_outgoing_view_change_channel.publish( view_change ); }); my->pbft_outgoing_new_view_connection = my->pbft_ctrl->pbft_db.pbft_outgoing_new_view.connect( - [this]( const pbft_new_view& new_view ) { + [this]( const pbft_new_view_ptr& new_view ) { my->pbft_outgoing_new_view_channel.publish( new_view ); }); my->pbft_outgoing_checkpoint_connection = my->pbft_ctrl->pbft_db.pbft_outgoing_checkpoint.connect( - [this]( const pbft_checkpoint& checkpoint ) { + [this]( const pbft_checkpoint_ptr& checkpoint ) { my->pbft_outgoing_checkpoint_channel.publish( checkpoint ); }); @@ -856,23 +856,23 @@ void chain_plugin::plugin_initialize(const variables_map& options) { } -void chain_plugin_impl::on_pbft_incoming_prepare(pbft_metadata_ptr p){ +void chain_plugin_impl::on_pbft_incoming_prepare(const pbft_metadata_ptr& p){ pbft_ctrl->on_pbft_prepare(p); } -void chain_plugin_impl::on_pbft_incoming_commit(pbft_metadata_ptr c){ +void chain_plugin_impl::on_pbft_incoming_commit(const pbft_metadata_ptr& c){ pbft_ctrl->on_pbft_commit(c); } -void chain_plugin_impl::on_pbft_incoming_view_change(pbft_metadata_ptr vc){ +void chain_plugin_impl::on_pbft_incoming_view_change(const pbft_metadata_ptr& vc){ pbft_ctrl->on_pbft_view_change(vc); } -void chain_plugin_impl::on_pbft_incoming_new_view(pbft_metadata_ptr nv){ +void chain_plugin_impl::on_pbft_incoming_new_view(const pbft_metadata_ptr& nv){ pbft_ctrl->on_pbft_new_view(nv); } -void chain_plugin_impl::on_pbft_incoming_checkpoint(pbft_metadata_ptr cp){ +void chain_plugin_impl::on_pbft_incoming_checkpoint(const pbft_metadata_ptr& cp){ pbft_ctrl->on_pbft_checkpoint(cp); } diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index 15bdb522743..78402c21dd7 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -255,22 +255,22 @@ namespace eosio { void bcast_pbft_msg(const net_message &msg, int ttl); - void forward_pbft_msg(connection_ptr c, const net_message &msg, int ttl); - - void pbft_outgoing_prepare(const pbft_prepare &prepare); - void pbft_outgoing_commit(const pbft_commit &commit); - void pbft_outgoing_view_change(const pbft_view_change &view_change); - void pbft_outgoing_new_view(const pbft_new_view &new_view); - void pbft_outgoing_checkpoint(const pbft_checkpoint &checkpoint); - - void handle_message( connection_ptr c, const pbft_prepare &msg); - void handle_message( connection_ptr c, const pbft_commit &msg); - void handle_message( connection_ptr c, const pbft_view_change &msg); - void handle_message( connection_ptr c, const pbft_new_view &msg); - void handle_message( connection_ptr c, const pbft_checkpoint &msg); - void handle_message( connection_ptr c, const pbft_stable_checkpoint &msg); - void handle_message( connection_ptr c, const checkpoint_request_message &msg); - void handle_message( connection_ptr c, const compressed_pbft_message &msg); + void forward_pbft_msg(const connection_ptr& c, const net_message &msg, int ttl); + + void pbft_outgoing_prepare(const pbft_prepare_ptr& prepare); + void pbft_outgoing_commit(const pbft_commit_ptr& commit); + void pbft_outgoing_view_change(const pbft_view_change_ptr& view_change); + void pbft_outgoing_new_view(const pbft_new_view_ptr& new_view); + void pbft_outgoing_checkpoint(const pbft_checkpoint_ptr& checkpoint); + + void handle_message( const connection_ptr& c, pbft_prepare &msg); + void handle_message( const connection_ptr& c, pbft_commit &msg); + void handle_message( const connection_ptr& c, pbft_view_change &msg); + void handle_message( const connection_ptr& c, pbft_new_view &msg); + void handle_message( const connection_ptr& c, pbft_checkpoint &msg); + void handle_message( const connection_ptr& c, pbft_stable_checkpoint &msg); + void handle_message( const connection_ptr& c, const checkpoint_request_message &msg); + void handle_message( const connection_ptr& c, compressed_pbft_message &msg); void start_conn_timer(boost::asio::steady_timer::duration du, std::weak_ptr from_connection); void start_txn_timer(); @@ -2831,7 +2831,7 @@ namespace eosio { trx->get_signatures().size() * sizeof(signature_type); } - void net_plugin_impl::handle_message( connection_ptr c, const checkpoint_request_message &msg) { + void net_plugin_impl::handle_message( const connection_ptr& c, const checkpoint_request_message &msg) { if ( msg.end_block == 0 || msg.end_block < msg.start_block) return; @@ -3020,7 +3020,7 @@ namespace eosio { } } - void net_plugin_impl::forward_pbft_msg(connection_ptr c, const net_message &msg, int ttl) { + void net_plugin_impl::forward_pbft_msg(const connection_ptr& c, const net_message &msg, int ttl) { auto deadline = time_point_sec(time_point::now()) + ttl; for (auto &conn: connections) { @@ -3030,54 +3030,52 @@ namespace eosio { } } - void net_plugin_impl::pbft_outgoing_prepare(const pbft_prepare &msg) { - auto added = maybe_add_to_pbft_cache(std::string(msg.sender_signature)); + void net_plugin_impl::pbft_outgoing_prepare(const pbft_prepare_ptr& msg) { + auto added = maybe_add_to_pbft_cache(std::string(msg->sender_signature)); if (!added) return; pbft_controller &pcc = my_impl->chain_plug->pbft_ctrl(); - bcast_pbft_msg(msg, pbft_message_TTL); - fc_dlog( logger, "sent prepare at height: ${n}, view: ${v} ", ("n", msg.block_info.block_num())("v", msg.view)); + bcast_pbft_msg(*msg, pbft_message_TTL); + fc_dlog( logger, "sent prepare at height: ${n}, view: ${v} ", ("n", msg->block_info.block_num())("v", msg->view)); } - void net_plugin_impl::pbft_outgoing_commit(const pbft_commit &msg) { - auto added = maybe_add_to_pbft_cache(std::string(msg.sender_signature)); + void net_plugin_impl::pbft_outgoing_commit(const pbft_commit_ptr& msg) { + auto added = maybe_add_to_pbft_cache(std::string(msg->sender_signature)); if (!added) return; pbft_controller &pcc = my_impl->chain_plug->pbft_ctrl(); - bcast_pbft_msg(msg, pbft_message_TTL); - fc_dlog( logger, "sent commit at height: ${n}, view: ${v} ", ("n", msg.block_info.block_num())("v", msg.view)); + bcast_pbft_msg(*msg, pbft_message_TTL); + fc_dlog( logger, "sent commit at height: ${n}, view: ${v} ", ("n", msg->block_info.block_num())("v", msg->view)); } - void net_plugin_impl::pbft_outgoing_view_change(const pbft_view_change &msg) { - auto added = maybe_add_to_pbft_cache(std::string(msg.sender_signature)); + void net_plugin_impl::pbft_outgoing_view_change(const pbft_view_change_ptr& msg) { + auto added = maybe_add_to_pbft_cache(std::string(msg->sender_signature)); if (!added) return; pbft_controller &pcc = my_impl->chain_plug->pbft_ctrl(); - bcast_pbft_msg(msg, pbft_message_TTL); - fc_dlog( logger, "sent view change {cv: ${cv}, tv: ${tv}}", ("cv", msg.current_view)("tv", msg.target_view)); + bcast_pbft_msg(*msg, pbft_message_TTL); + fc_dlog( logger, "sent view change {cv: ${cv}, tv: ${tv}}", ("cv", msg->current_view)("tv", msg->target_view)); } - void net_plugin_impl::pbft_outgoing_new_view(const pbft_new_view &msg) { - auto added = maybe_add_to_pbft_cache(std::string(msg.sender_signature)); + void net_plugin_impl::pbft_outgoing_new_view(const pbft_new_view_ptr& msg) { + auto added = maybe_add_to_pbft_cache(std::string(msg->sender_signature)); if (!added) return; - pbft_controller &pcc = my_impl->chain_plug->pbft_ctrl(); - - bcast_pbft_msg(msg, INT_MAX); - fc_dlog( logger, "sent new view at view: ${v} ", ("v", msg.new_view)); + bcast_pbft_msg(*msg, INT_MAX); + fc_dlog( logger, "sent new view at view: ${v} ", ("v", msg->new_view)); } - void net_plugin_impl::pbft_outgoing_checkpoint(const pbft_checkpoint &msg) { - auto added = maybe_add_to_pbft_cache(std::string(msg.sender_signature)); + void net_plugin_impl::pbft_outgoing_checkpoint(const pbft_checkpoint_ptr& msg) { + auto added = maybe_add_to_pbft_cache(std::string(msg->sender_signature)); if (!added) return; pbft_controller &pcc = my_impl->chain_plug->pbft_ctrl(); - bcast_pbft_msg(msg, pbft_message_TTL); - fc_dlog( logger, "sent checkpoint at height: ${n} ", ("n", msg.block_info.block_num())); + bcast_pbft_msg(*msg, pbft_message_TTL); + fc_dlog( logger, "sent checkpoint at height: ${n} ", ("n", msg->block_info.block_num())); } bool net_plugin_impl::maybe_add_to_pbft_cache(const string &key){ @@ -3091,7 +3089,7 @@ namespace eosio { } void net_plugin_impl::clean_expired_pbft_messages(){ - pbft_message_cache_ticker (); + pbft_message_cache_ticker(); auto itr = pbft_message_cache.begin(); auto now = time_point::now(); @@ -3104,57 +3102,58 @@ namespace eosio { } } - void net_plugin_impl::handle_message( connection_ptr c, const pbft_prepare &msg) { + void net_plugin_impl::handle_message( const connection_ptr& c, pbft_prepare &msg) { - if (!is_pbft_msg_valid(msg)) return; + auto pmm = pbft_message_metadata(std::move(msg), chain_id); - auto added = maybe_add_to_pbft_cache(std::string(msg.sender_signature)); - if (!added) return; + if (!is_pbft_msg_valid(pmm.msg)) return; - auto pmm = pbft_message_metadata(msg, chain_id); + auto added = maybe_add_to_pbft_cache(std::string(pmm.msg.sender_signature)); + if (!added) return; pbft_controller &pcc = my_impl->chain_plug->pbft_ctrl(); - if (!pcc.pbft_db.is_valid_prepare(msg, pmm.sender_key)) return; + if (!pcc.pbft_db.is_valid_prepare(pmm.msg, pmm.sender_key)) return; - forward_pbft_msg(c, msg, pbft_message_TTL); - fc_dlog( logger, "received prepare at height: ${n}, view: ${v}, from ${k}, ", ("n", msg.block_info.block_num())("v", msg.view)("k", pmm.sender_key)); + forward_pbft_msg(c, pmm.msg, pbft_message_TTL); + fc_dlog( logger, "received prepare at height: ${n}, view: ${v}, from ${k}, ", ("n", pmm.msg.block_info.block_num())("v", pmm.msg.view)("k", pmm.sender_key)); - pbft_incoming_prepare_channel.publish(std::make_shared>(pmm)); + pbft_incoming_prepare_channel.publish(std::make_shared>(std::move(pmm))); } - void net_plugin_impl::handle_message( connection_ptr c, const pbft_commit &msg) { + void net_plugin_impl::handle_message( const connection_ptr& c, pbft_commit &msg) { - if (!is_pbft_msg_valid(msg)) return; + auto pmm = pbft_message_metadata(std::move(msg), chain_id); - auto added = maybe_add_to_pbft_cache(std::string(msg.sender_signature)); + if (!is_pbft_msg_valid(pmm.msg)) return; + + auto added = maybe_add_to_pbft_cache(std::string(pmm.msg.sender_signature)); if (!added) return; - auto pmm = pbft_message_metadata(msg, chain_id); pbft_controller &pcc = my_impl->chain_plug->pbft_ctrl(); - if (!pcc.pbft_db.is_valid_commit(msg, pmm.sender_key)) return; + if (!pcc.pbft_db.is_valid_commit(pmm.msg, pmm.sender_key)) return; - forward_pbft_msg(c, msg, pbft_message_TTL); - fc_dlog( logger, "received commit at height: ${n}, view: ${v}, from ${k}, ", ("n", msg.block_info.block_num())("v", msg.view)("k", pmm.sender_key)); + forward_pbft_msg(c, pmm.msg, pbft_message_TTL); + fc_dlog( logger, "received commit at height: ${n}, view: ${v}, from ${k}, ", ("n", pmm.msg.block_info.block_num())("v", pmm.msg.view)("k", pmm.sender_key)); - pbft_incoming_commit_channel.publish(std::make_shared>(pmm)); + pbft_incoming_commit_channel.publish(std::make_shared>(std::move(pmm))); } - void net_plugin_impl::handle_message( connection_ptr c, const pbft_view_change &msg) { + void net_plugin_impl::handle_message( const connection_ptr& c, pbft_view_change &msg) { - if (!is_pbft_msg_valid(msg)) return; + auto pmm = pbft_message_metadata( std::move(msg), chain_id); - auto added = maybe_add_to_pbft_cache(std::string(msg.sender_signature)); - if (!added) return; + if (!is_pbft_msg_valid(pmm.msg)) return; - auto pmm = pbft_message_metadata(msg, chain_id); + auto added = maybe_add_to_pbft_cache(std::string(pmm.msg.sender_signature)); + if (!added) return; pbft_controller &pcc = my_impl->chain_plug->pbft_ctrl(); controller &ctrl = my_impl->chain_plug->chain(); - if (!pcc.pbft_db.is_valid_view_change(msg, pmm.sender_key)) return; + if (!pcc.pbft_db.is_valid_view_change(pmm.msg, pmm.sender_key)) return; auto missing_blocks = set{}; - for (auto const &b: msg.prepared_cert.pre_prepares) { + for (auto const &b: pmm.msg.prepared_cert.pre_prepares) { if (!ctrl.fetch_block_by_id(b)) missing_blocks.emplace(b); } @@ -3169,29 +3168,36 @@ namespace eosio { c->enqueue(req); } - forward_pbft_msg(c, msg, pbft_message_TTL); - fc_dlog( logger, "received view change {cv: ${cv}, tv: ${tv}} from ${v}", ("cv", msg.current_view)("tv", msg.target_view)("v", pmm.sender_key)); + forward_pbft_msg(c, pmm.msg, pbft_message_TTL); + fc_dlog( logger, "received view change {cv: ${cv}, tv: ${tv}} from ${v}", ("cv", pmm.msg.current_view)("tv", pmm.msg.target_view)("v", pmm.sender_key)); - pbft_incoming_view_change_channel.publish(std::make_shared>(pmm)); + pbft_incoming_view_change_channel.publish(std::make_shared>(std::move(pmm))); } - void net_plugin_impl::handle_message( connection_ptr c, const pbft_new_view &msg) { + void net_plugin_impl::handle_message( const connection_ptr& c, pbft_new_view &msg) { + + auto pmm = pbft_message_metadata(std::move(msg), chain_id); - auto added = maybe_add_to_pbft_cache(std::string(msg.sender_signature)); + auto added = maybe_add_to_pbft_cache(std::string(pmm.msg.sender_signature)); if (!added) return; - auto pmm = pbft_message_metadata(msg, chain_id); + pbft_controller &pcc = my_impl->chain_plug->pbft_ctrl(); - pbft_controller &pcc = my_impl->chain_plug->pbft_ctrl(); - if (pmm.sender_key != pcc.pbft_db.get_new_view_primary_key(msg.new_view)) return; + if (time_point_sec(time_point::now()) > time_point_sec(pmm.msg.common.timestamp) + 60 * pbft_message_TTL + || pmm.msg.new_view <= pcc.state_machine->get_current_view()) { + //skip new view messages that are too old or whose target views are lower than mine. + return; + } - forward_pbft_msg(c, msg, INT_MAX); - fc_dlog( logger, "received new view: ${n}, from ${v}", ("n", msg)("v", pmm.sender_key)); + if (pmm.sender_key != pcc.pbft_db.get_new_view_primary_key(pmm.msg.new_view)) return; - pbft_incoming_new_view_channel.publish(std::make_shared>(pmm)); + forward_pbft_msg(c, pmm.msg, INT_MAX); + fc_dlog( logger, "received new view: ${n}, from ${v}", ("n", pmm.msg)("v", pmm.sender_key)); + + pbft_incoming_new_view_channel.publish(std::make_shared>(std::move(pmm))); } - void net_plugin_impl::handle_message( connection_ptr c, const compressed_pbft_message &msg) { + void net_plugin_impl::handle_message( const connection_ptr& c, compressed_pbft_message &msg) { auto decompressed_msg = decompress_pbft(msg.content); @@ -3207,25 +3213,25 @@ namespace eosio { } } - void net_plugin_impl::handle_message( connection_ptr c, const pbft_checkpoint &msg) { + void net_plugin_impl::handle_message( const connection_ptr& c, pbft_checkpoint &msg) { - if (!is_pbft_msg_valid(msg)) return; + auto pmm = pbft_message_metadata(std::move(msg), chain_id); - auto added = maybe_add_to_pbft_cache(std::string(msg.sender_signature)); - if (!added) return; + if (!is_pbft_msg_valid(pmm.msg)) return; - auto pmm = pbft_message_metadata(msg, chain_id); + auto added = maybe_add_to_pbft_cache(std::string(pmm.msg.sender_signature)); + if (!added) return; pbft_controller &pcc = my_impl->chain_plug->pbft_ctrl(); - if (!pcc.pbft_db.is_valid_checkpoint(msg, pmm.sender_key)) return; + if (!pcc.pbft_db.is_valid_checkpoint(pmm.msg, pmm.sender_key)) return; - forward_pbft_msg(c, msg, pbft_message_TTL); - fc_dlog( logger, "received checkpoint at ${n}, from ${v}", ("n", msg.block_info.block_num())("v", pmm.sender_key)); + forward_pbft_msg(c, pmm.msg, pbft_message_TTL); + fc_dlog( logger, "received checkpoint at ${n}, from ${v}", ("n", pmm.msg.block_info.block_num())("v", pmm.sender_key)); - pbft_incoming_checkpoint_channel.publish(std::make_shared>(pmm)); + pbft_incoming_checkpoint_channel.publish(std::make_shared>(std::move(pmm))); } - void net_plugin_impl::handle_message( connection_ptr c, const pbft_stable_checkpoint &msg) { + void net_plugin_impl::handle_message( const connection_ptr& c, pbft_stable_checkpoint &msg) { pbft_controller &pcc = my_impl->chain_plug->pbft_ctrl(); diff --git a/unittests/pbft_tests.cpp b/unittests/pbft_tests.cpp index 266a043bf5a..a0c5e3b45be 100644 --- a/unittests/pbft_tests.cpp +++ b/unittests/pbft_tests.cpp @@ -60,7 +60,7 @@ std::map make_signature_ BOOST_AUTO_TEST_CASE(can_init) { tester tester; - controller &ctrl = *tester.control.get(); + controller &ctrl = *tester.control; pbft_controller pbft_ctrl{ctrl}; tester.produce_block(); @@ -70,7 +70,7 @@ BOOST_AUTO_TEST_CASE(can_init) { BOOST_AUTO_TEST_CASE(can_advance_lib_in_old_version) { tester tester; - controller &ctrl = *tester.control.get(); + controller &ctrl = *tester.control; pbft_controller pbft_ctrl{ctrl}; auto msp = make_signature_provider(); @@ -86,7 +86,7 @@ BOOST_AUTO_TEST_CASE(can_advance_lib_in_old_version) { BOOST_AUTO_TEST_CASE(can_advance_lib_after_upgrade) { tester tester; - controller &ctrl = *tester.control.get(); + controller &ctrl = *tester.control; pbft_controller pbft_ctrl{ctrl}; ctrl.set_upo(150); @@ -130,7 +130,7 @@ BOOST_AUTO_TEST_CASE(can_advance_lib_after_upgrade) { BOOST_AUTO_TEST_CASE(can_advance_lib_after_upgrade_with_four_producers) { tester tester; - controller &ctrl = *tester.control.get(); + controller &ctrl = *tester.control; pbft_controller pbft_ctrl{ctrl}; ctrl.set_upo(109); @@ -229,11 +229,11 @@ BOOST_AUTO_TEST_CASE(view_change_validation) { BOOST_AUTO_TEST_CASE(switch_fork_when_accept_new_view_with_prepare_certificate_on_short_fork) { tester short_prepared_fork, long_non_prepared_fork, new_view_generator; - controller &ctrl_short_prepared_fork = *short_prepared_fork.control.get(); + controller &ctrl_short_prepared_fork = *short_prepared_fork.control; pbft_controller pbft_short_prepared_fork{ctrl_short_prepared_fork}; - controller &ctrl_long_non_prepared_fork = *long_non_prepared_fork.control.get(); + controller &ctrl_long_non_prepared_fork = *long_non_prepared_fork.control; pbft_controller pbft_long_non_prepared_fork{ctrl_long_non_prepared_fork}; - controller &ctrl_new_view_generator = *new_view_generator.control.get(); + controller &ctrl_new_view_generator = *new_view_generator.control; pbft_controller pbft_new_view_generator{ctrl_new_view_generator}; auto msp = make_signature_provider(); @@ -304,6 +304,7 @@ BOOST_AUTO_TEST_CASE(switch_fork_when_accept_new_view_with_prepare_certificate_o //generate new view with short fork prepare certificate pbft_new_view_generator.state_machine->set_prepares_cache(pbft_prepare()); BOOST_CHECK_EQUAL(pbft_new_view_generator.pbft_db.should_send_pbft_msg(), true); + ctrl_new_view_generator.reset_pbft_my_prepare(); pbft_new_view_generator.maybe_pbft_prepare(); BOOST_CHECK_EQUAL(pbft_new_view_generator.pbft_db.should_prepared(), true); BOOST_CHECK_EQUAL(ctrl_new_view_generator.head_block_num(), 136); @@ -330,7 +331,8 @@ BOOST_AUTO_TEST_CASE(switch_fork_when_accept_new_view_with_prepare_certificate_o BOOST_CHECK_EQUAL(ctrl_short_prepared_fork.head_block_num(), 137); //can switch fork after apply prepare certificate in new view - pbft_short_prepared_fork.state_machine->on_new_view(std::make_shared>(nv_msg, ctrl_new_view_generator.get_chain_id())); + auto pmm = pbft_message_metadata(nv_msg, pbft_short_prepared_fork.pbft_db.get_chain_id()); + pbft_short_prepared_fork.on_pbft_new_view(std::make_shared>(pmm)); BOOST_CHECK_EQUAL(ctrl_short_prepared_fork.head_block_num(), 136); BOOST_CHECK_EQUAL(ctrl_short_prepared_fork.last_irreversible_block_num(), 101); From 20e08dbacb7b59e1760798e5ade18f4a330b3eb2 Mon Sep 17 00:00:00 2001 From: oldcold Date: Thu, 11 Jul 2019 18:20:25 +0800 Subject: [PATCH 3/6] optimise transit_to_new_view; optimise handle pbft messages; --- libraries/chain/pbft.cpp | 3 ++ libraries/chain/pbft_database.cpp | 2 - plugins/net_plugin/net_plugin.cpp | 69 ++++++++++++++++--------------- 3 files changed, 38 insertions(+), 36 deletions(-) diff --git a/libraries/chain/pbft.cpp b/libraries/chain/pbft.cpp index 5679b332733..ccc5598dc63 100644 --- a/libraries/chain/pbft.cpp +++ b/libraries/chain/pbft.cpp @@ -456,6 +456,9 @@ namespace eosio { } } + if (pbft_db.should_committed()) { + pbft_db.commit_local(); + } transit_to_committed_state(s, true); } diff --git a/libraries/chain/pbft_database.cpp b/libraries/chain/pbft_database.cpp index 10f05347f1c..3e2a71fd86f 100644 --- a/libraries/chain/pbft_database.cpp +++ b/libraries/chain/pbft_database.cpp @@ -849,8 +849,6 @@ namespace eosio { if (add_to_pbft_db) add_pbft_commit(c, pmm.sender_key); } - if (add_to_pbft_db && should_committed()) commit_local(); - auto cert_id = certificate.block_info.block_id; auto cert_bs = ctrl.fetch_block_state_by_id(cert_id); auto producer_schedule = lscb_active_producers(); diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index 78402c21dd7..49eb8e9b191 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -263,14 +263,14 @@ namespace eosio { void pbft_outgoing_new_view(const pbft_new_view_ptr& new_view); void pbft_outgoing_checkpoint(const pbft_checkpoint_ptr& checkpoint); - void handle_message( const connection_ptr& c, pbft_prepare &msg); - void handle_message( const connection_ptr& c, pbft_commit &msg); - void handle_message( const connection_ptr& c, pbft_view_change &msg); - void handle_message( const connection_ptr& c, pbft_new_view &msg); - void handle_message( const connection_ptr& c, pbft_checkpoint &msg); - void handle_message( const connection_ptr& c, pbft_stable_checkpoint &msg); + void handle_message( const connection_ptr& c, const pbft_prepare &msg); + void handle_message( const connection_ptr& c, const pbft_commit &msg); + void handle_message( const connection_ptr& c, const pbft_view_change &msg); + void handle_message( const connection_ptr& c, const pbft_new_view &msg); + void handle_message( const connection_ptr& c, const pbft_checkpoint &msg); + void handle_message( const connection_ptr& c, const pbft_stable_checkpoint &msg); void handle_message( const connection_ptr& c, const checkpoint_request_message &msg); - void handle_message( const connection_ptr& c, compressed_pbft_message &msg); + void handle_message( const connection_ptr& c, const compressed_pbft_message &msg); void start_conn_timer(boost::asio::steady_timer::duration du, std::weak_ptr from_connection); void start_txn_timer(); @@ -3102,15 +3102,16 @@ namespace eosio { } } - void net_plugin_impl::handle_message( const connection_ptr& c, pbft_prepare &msg) { + void net_plugin_impl::handle_message( const connection_ptr& c, const pbft_prepare &msg) { - auto pmm = pbft_message_metadata(std::move(msg), chain_id); - - if (!is_pbft_msg_valid(pmm.msg)) return; + if (!is_pbft_msg_valid(msg)) return; - auto added = maybe_add_to_pbft_cache(std::string(pmm.msg.sender_signature)); + auto added = maybe_add_to_pbft_cache(std::string(msg.sender_signature)); if (!added) return; + auto pmm = pbft_message_metadata(std::move(msg), chain_id); + + pbft_controller &pcc = my_impl->chain_plug->pbft_ctrl(); if (!pcc.pbft_db.is_valid_prepare(pmm.msg, pmm.sender_key)) return; @@ -3120,15 +3121,15 @@ namespace eosio { pbft_incoming_prepare_channel.publish(std::make_shared>(std::move(pmm))); } - void net_plugin_impl::handle_message( const connection_ptr& c, pbft_commit &msg) { + void net_plugin_impl::handle_message( const connection_ptr& c, const pbft_commit &msg) { - auto pmm = pbft_message_metadata(std::move(msg), chain_id); - if (!is_pbft_msg_valid(pmm.msg)) return; + if (!is_pbft_msg_valid(msg)) return; - auto added = maybe_add_to_pbft_cache(std::string(pmm.msg.sender_signature)); + auto added = maybe_add_to_pbft_cache(std::string(msg.sender_signature)); if (!added) return; + auto pmm = pbft_message_metadata(std::move(msg), chain_id); pbft_controller &pcc = my_impl->chain_plug->pbft_ctrl(); if (!pcc.pbft_db.is_valid_commit(pmm.msg, pmm.sender_key)) return; @@ -3139,15 +3140,15 @@ namespace eosio { pbft_incoming_commit_channel.publish(std::make_shared>(std::move(pmm))); } - void net_plugin_impl::handle_message( const connection_ptr& c, pbft_view_change &msg) { + void net_plugin_impl::handle_message( const connection_ptr& c, const pbft_view_change &msg) { - auto pmm = pbft_message_metadata( std::move(msg), chain_id); + if (!is_pbft_msg_valid(msg)) return; - if (!is_pbft_msg_valid(pmm.msg)) return; - - auto added = maybe_add_to_pbft_cache(std::string(pmm.msg.sender_signature)); + auto added = maybe_add_to_pbft_cache(std::string(msg.sender_signature)); if (!added) return; + auto pmm = pbft_message_metadata( std::move(msg), chain_id); + pbft_controller &pcc = my_impl->chain_plug->pbft_ctrl(); controller &ctrl = my_impl->chain_plug->chain(); if (!pcc.pbft_db.is_valid_view_change(pmm.msg, pmm.sender_key)) return; @@ -3174,21 +3175,21 @@ namespace eosio { pbft_incoming_view_change_channel.publish(std::make_shared>(std::move(pmm))); } - void net_plugin_impl::handle_message( const connection_ptr& c, pbft_new_view &msg) { - - auto pmm = pbft_message_metadata(std::move(msg), chain_id); + void net_plugin_impl::handle_message( const connection_ptr& c, const pbft_new_view &msg) { - auto added = maybe_add_to_pbft_cache(std::string(pmm.msg.sender_signature)); + auto added = maybe_add_to_pbft_cache(std::string(msg.sender_signature)); if (!added) return; pbft_controller &pcc = my_impl->chain_plug->pbft_ctrl(); - if (time_point_sec(time_point::now()) > time_point_sec(pmm.msg.common.timestamp) + 60 * pbft_message_TTL - || pmm.msg.new_view <= pcc.state_machine->get_current_view()) { + if (time_point_sec(time_point::now()) > time_point_sec(msg.common.timestamp) + 60 * pbft_message_TTL + || msg.new_view <= pcc.state_machine->get_current_view()) { //skip new view messages that are too old or whose target views are lower than mine. return; } + auto pmm = pbft_message_metadata(std::move(msg), chain_id); + if (pmm.sender_key != pcc.pbft_db.get_new_view_primary_key(pmm.msg.new_view)) return; forward_pbft_msg(c, pmm.msg, INT_MAX); @@ -3197,7 +3198,7 @@ namespace eosio { pbft_incoming_new_view_channel.publish(std::make_shared>(std::move(pmm))); } - void net_plugin_impl::handle_message( const connection_ptr& c, compressed_pbft_message &msg) { + void net_plugin_impl::handle_message( const connection_ptr& c, const compressed_pbft_message &msg) { auto decompressed_msg = decompress_pbft(msg.content); @@ -3213,15 +3214,15 @@ namespace eosio { } } - void net_plugin_impl::handle_message( const connection_ptr& c, pbft_checkpoint &msg) { + void net_plugin_impl::handle_message( const connection_ptr& c, const pbft_checkpoint &msg) { - auto pmm = pbft_message_metadata(std::move(msg), chain_id); - - if (!is_pbft_msg_valid(pmm.msg)) return; + if (!is_pbft_msg_valid(msg)) return; - auto added = maybe_add_to_pbft_cache(std::string(pmm.msg.sender_signature)); + auto added = maybe_add_to_pbft_cache(std::string(msg.sender_signature)); if (!added) return; + auto pmm = pbft_message_metadata(std::move(msg), chain_id); + pbft_controller &pcc = my_impl->chain_plug->pbft_ctrl(); if (!pcc.pbft_db.is_valid_checkpoint(pmm.msg, pmm.sender_key)) return; @@ -3231,7 +3232,7 @@ namespace eosio { pbft_incoming_checkpoint_channel.publish(std::make_shared>(std::move(pmm))); } - void net_plugin_impl::handle_message( const connection_ptr& c, pbft_stable_checkpoint &msg) { + void net_plugin_impl::handle_message( const connection_ptr& c, const pbft_stable_checkpoint &msg) { pbft_controller &pcc = my_impl->chain_plug->pbft_ctrl(); From f4c83c22b59078a7eb5d40273c432789224e44b5 Mon Sep 17 00:00:00 2001 From: oldcold Date: Fri, 12 Jul 2019 18:24:20 +0800 Subject: [PATCH 4/6] net_plugin revert. --- plugins/net_plugin/net_plugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index 49eb8e9b191..529bd3ed900 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -2318,7 +2318,7 @@ namespace eosio { void net_plugin_impl::start_read_message(const connection_ptr& conn) { try { - if(!conn->socket || !conn->socket->is_open()) { + if(!conn->socket) { return; } connection_wptr weak_conn = conn; From 8916700639ef6d9f11944c0b776afd792554d05f Mon Sep 17 00:00:00 2001 From: Frank-AFN Date: Mon, 15 Jul 2019 17:37:50 +0800 Subject: [PATCH 5/6] Add: switch fork reserve prepare and fetch branch from function test case --- unittests/pbft_tests.cpp | 397 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 397 insertions(+) diff --git a/unittests/pbft_tests.cpp b/unittests/pbft_tests.cpp index a0c5e3b45be..ea0420c24a2 100644 --- a/unittests/pbft_tests.cpp +++ b/unittests/pbft_tests.cpp @@ -350,5 +350,402 @@ BOOST_AUTO_TEST_CASE(switch_fork_when_accept_new_view_with_prepare_certificate_o } +private_key_type get_private_key( name keyname, string role ) { + return private_key_type::regenerate(fc::sha256::hash(string(keyname)+role)); +} + +public_key_type get_public_key( name keyname, string role ){ + return get_private_key( keyname, role ).get_public_key(); +} + +BOOST_AUTO_TEST_CASE(switch_fork_reserve_prepare) { + const char* curr_state; + tester c1, c2, c2_prime, c3, c3_final; + controller &c1_fork = *c1.control.get(); + pbft_controller c1_pbft_controller{c1_fork}; + controller &c2_fork = *c2.control.get(); + pbft_controller c2_pbft_controller{c2_fork}; + controller &c2_fork_prime = c2_fork; + pbft_controller c2_prime_pbft_controller{c2_fork_prime}; + controller &c3_fork = *c3.control.get(); + pbft_controller c3_pbft_controller{c3_fork}; + controller &c3_final_fork = *c3_final.control.get(); + pbft_controller c3_final_pbft_controller{c3_final_fork}; + + + c1_fork.set_upo(48); + c2_fork.set_upo(48); + c2_fork_prime.set_upo(48); + c3_fork.set_upo(48); + c3_final_fork.set_upo(48); + + /// c1 + c1.produce_block(); + c1.create_accounts( {N(alice), N(bob)} ); + c1.produce_block(); + + // make and get signature provider for c1 + std::map msp_c1; + auto priv_alice = tester::get_private_key( N(alice), "active" ); + auto pub_alice = tester::get_public_key( N(alice), "active"); + auto sp_alice = [priv_alice]( const eosio::chain::digest_type& digest ) { + return priv_alice.sign(digest); + }; + msp_c1[pub_alice]=sp_alice; + c1_fork.set_my_signature_providers(msp_c1); + + c1.set_producers( {N(alice), N(bob)} ); + + vector c1_sch = { {N(alice),get_public_key(N(alice), "active")} }; + + + /// c2 + c2.produce_block(); + c2.create_accounts( {N(alice), N(bob)} ); + c2.produce_block(); + + // make and get signature provider for c2 + std::map msp_c2; + msp_c2[pub_alice]=sp_alice; + + auto priv_bob = tester::get_private_key( N(bob), "active" ); + auto pub_bob = tester::get_public_key( N(bob), "active"); + auto sp_bob = [priv_bob]( const eosio::chain::digest_type& digest ) { + return priv_bob.sign(digest); + }; + msp_c2[pub_bob]=sp_bob; + c2_fork.set_my_signature_providers(msp_c2); + + c2.set_producers( {N(alice), N(bob)} ); + + vector c2_sch = { {N(alice),get_public_key(N(alice), "active")}, + {N(bob),get_public_key(N(bob), "active")}}; + + + c2.produce_blocks(95); + c2_pbft_controller.maybe_pbft_prepare(); + c2_pbft_controller.maybe_pbft_commit(); + c2.produce_block(); + BOOST_CHECK_EQUAL(c2.control->last_irreversible_block_num(), 98); + + + /// c3 + c3.produce_block(); + c3.create_accounts( {N(alice), N(bob)} ); + c3.produce_block(); + + // make and get signature provider for c3 + std::map msp_c3; + msp_c3[pub_bob]=sp_bob; + + c3_fork.set_my_signature_providers(msp_c3); + + c3.set_producers( {N(alice), N(bob)} ); + + vector c3_sch = { {N(bob),get_public_key(N(bob), "active")} }; + + /// c3 final + c3_final.produce_block(); + c3_final.create_accounts( {N(alice), N(bob)} ); + c3_final.produce_block(); + + // make and get signature provider for c3 + std::map msp_c3_final; + msp_c3_final[pub_bob]=sp_bob; + + c3_final_fork.set_my_signature_providers(msp_c3_final); + + c3_final.set_producers( {N(alice), N(bob)} ); + + vector c3_final_sch = { {N(bob),get_public_key(N(bob), "active")} }; + + push_blocks(c2, c3_final); + + + push_blocks(c2, c1); + /// make c1 lib 98 c3 lib 99 + c1_pbft_controller.maybe_pbft_prepare(); + pbft_prepare c2_prepare_ = c2_pbft_controller.state_machine->get_prepares_cache(); + // check c3 prepare at 63 + BOOST_CHECK_EQUAL(c2_prepare_.block_info.block_num(), 98); + c1_pbft_controller.state_machine->on_prepare(std::make_shared>(c2_prepare_, c2_pbft_controller.pbft_db.get_chain_id())); + c1_pbft_controller.maybe_pbft_commit(); + + pbft_commit c2_commit_ = c2_pbft_controller.state_machine->get_commits_cache(); + c1_pbft_controller.state_machine->on_commit(std::make_shared>(c2_commit_, c2_pbft_controller.pbft_db.get_chain_id())); + c1.produce_block(); + c1_pbft_controller.maybe_pbft_commit(); + BOOST_CHECK_EQUAL(c1.control->last_irreversible_block_num(), 98); + + c2_pbft_controller.maybe_pbft_commit(); + + /// make c3_final lib 98 + c3_final_pbft_controller.maybe_pbft_prepare(); + pbft_prepare c1_prepare_ = c1_pbft_controller.state_machine->get_prepares_cache(); + BOOST_CHECK_EQUAL(c1_prepare_.block_info.block_num(), 99); + c3_final_pbft_controller.state_machine->on_prepare(std::make_shared>(c1_prepare_, c1_pbft_controller.pbft_db.get_chain_id())); + c3_final_pbft_controller.maybe_pbft_commit(); + + pbft_commit c1_commit_ = c1_pbft_controller.state_machine->get_commits_cache(); + c3_final_pbft_controller.state_machine->on_commit(std::make_shared>(c1_commit_, c1_pbft_controller.pbft_db.get_chain_id())); + c3_final.produce_block(); + c3_final_pbft_controller.maybe_pbft_commit(); + BOOST_CHECK_EQUAL(c3_final.control->last_irreversible_block_num(), 98); + + // copy c2 to c2_prime + push_blocks(c2, c2_prime); + + /// make c3 as prepared + push_blocks(c2, c3); + c3_pbft_controller.maybe_pbft_prepare(); + pbft_prepare c1_prepare; + c1_prepare_ = c1_pbft_controller.state_machine->get_prepares_cache(); + c1_prepare = c1_prepare_; +// check c1 prepare at 99 + BOOST_CHECK_EQUAL(c1_prepare_.block_info.block_num(), 99); + c3_pbft_controller.state_machine->on_prepare(std::make_shared>(c1_prepare_, c1_pbft_controller.pbft_db.get_chain_id())); + curr_state = c3_pbft_controller.state_machine->get_current()->get_name(); + BOOST_CHECK_EQUAL(curr_state, "{==== PREPARED ====}"); + + /// for set pbft commit cache to 99 + c2.produce_block(); + + c2_pbft_controller.maybe_pbft_prepare(); + c2_prepare_ = c2_pbft_controller.state_machine->get_prepares_cache(); + BOOST_CHECK_EQUAL(c2_prepare_.block_info.block_num(), 99); + c2_pbft_controller.maybe_pbft_commit(); + c2.produce_block(); + c2_pbft_controller.maybe_pbft_commit(); + + c2_commit_ = c2_pbft_controller.state_machine->get_commits_cache(); + BOOST_CHECK_EQUAL(c2_commit_.block_info.block_num(), 99); + BOOST_CHECK_EQUAL(c2.control->last_irreversible_block_num(), 99); + + push_blocks(c2, c1); + c1_pbft_controller.maybe_pbft_prepare(); + c2_prepare_ = c2_pbft_controller.state_machine->get_prepares_cache(); + c1_pbft_controller.state_machine->on_prepare(std::make_shared>(c2_prepare_, c2_pbft_controller.pbft_db.get_chain_id())); + c1_pbft_controller.maybe_pbft_commit(); + c2_commit_ = c2_pbft_controller.state_machine->get_commits_cache(); + c1_pbft_controller.state_machine->on_commit(std::make_shared>(c2_commit_, c2_pbft_controller.pbft_db.get_chain_id())); + c1.produce_block(); + c1_pbft_controller.maybe_pbft_commit(); + + c1_prepare_ = c1_pbft_controller.state_machine->get_prepares_cache(); + c1_commit_ = c1_pbft_controller.state_machine->get_commits_cache(); + BOOST_CHECK_EQUAL(c1_commit_.block_info.block_num(), 99); + BOOST_CHECK_EQUAL(c1.control->last_irreversible_block_num(), 99); + + /// make c3 as committed + c3_pbft_controller.maybe_pbft_commit(); + c1_commit_ = c1_pbft_controller.state_machine->get_commits_cache(); + c3_pbft_controller.state_machine->on_commit(std::make_shared>(c1_commit_, c1_pbft_controller.pbft_db.get_chain_id())); + c3.produce_block(); + c3_pbft_controller.maybe_pbft_commit(); + curr_state = c3_pbft_controller.state_machine->get_current()->get_name(); + BOOST_CHECK_EQUAL(curr_state, "{==== COMMITTED ====}"); + + BOOST_CHECK_EQUAL(c3.control->last_irreversible_block_num(), 99); + + + BOOST_CHECK_EQUAL(c2.control->head_block_num(), 101); + BOOST_CHECK_EQUAL(c3.control->head_block_num(), 100); + + c3.produce_block(); + c3_pbft_controller.maybe_pbft_prepare(); + c3_final_pbft_controller.maybe_pbft_prepare(); + c3.produce_block(); + + c3_final.produce_block(); + c3_final.produce_block(); + + // get c3 prepare and push to c1 + pbft_prepare c3_prepare = c3_pbft_controller.state_machine->get_prepares_cache(); + // check c3 prepare at 99 + BOOST_CHECK_EQUAL(c3_prepare.block_info.block_num(), 100); + BOOST_CHECK_EQUAL(c1_prepare.block_info.block_num(), 99); + + c3_final_fork.set_pbft_my_prepare(c3_prepare.block_info.block_id); + c3_final_pbft_controller.state_machine->on_prepare(std::make_shared>(c1_prepare, c1_pbft_controller.pbft_db.get_chain_id())); + + BOOST_CHECK_EQUAL(c3_final_fork.get_pbft_my_prepare(), c3_prepare.block_info.block_id); + + pbft_prepare c3_final_prepare = c3_final_pbft_controller.state_machine->get_prepares_cache(); + // check c3 prepare at 99 + BOOST_CHECK_EQUAL(c3_final_prepare.block_info.block_num(), 99); + curr_state = c3_final_pbft_controller.state_machine->get_current()->get_name(); + BOOST_CHECK_EQUAL(curr_state, "{==== PREPARED ====}"); + + + c3_final_pbft_controller.maybe_pbft_commit(); + + c2_prime.create_accounts({N(tester1)}); + c2_prime.produce_blocks(5); + + //push fork to c3 + for(int i = 100; i <= 104; i++) { + auto fb = c2_prime.control->fetch_block_by_number(i); + c3_final.push_block(fb); + } + + auto tmp_c2_prime_prepared_fork = c3_final.control->fork_db().get_block(c2_prime.control->get_block_id_for_num(100)); + auto tmp_c3_final_prepared_fork = c3_final.control->fork_db().get_block(c3_final.control->get_block_id_for_num(100)); + BOOST_CHECK_EQUAL(tmp_c3_final_prepared_fork->pbft_prepared, true); + BOOST_CHECK_EQUAL(tmp_c3_final_prepared_fork->pbft_my_prepare, true); + BOOST_CHECK_EQUAL(tmp_c2_prime_prepared_fork->pbft_prepared, true); + BOOST_CHECK_EQUAL(tmp_c2_prime_prepared_fork->pbft_my_prepare, true); + BOOST_CHECK_EQUAL(c3_final.control->last_irreversible_block_num(), 98); + + BOOST_CHECK_EQUAL(c3_final.control->head_block_num(), 104); + + pbft_commit c3_commit = c3_pbft_controller.state_machine->get_commits_cache(); + BOOST_CHECK_EQUAL(c3_commit.block_info.block_num(), 99); + c3_final_pbft_controller.maybe_pbft_commit(); + c3_final.produce_block(); +// c3_final_pbft_controller.maybe_pbft_commit(); + pbft_commit c3_final_commit = c3_final_pbft_controller.state_machine->get_commits_cache(); + c3_final_pbft_controller.state_machine->on_commit(std::make_shared>(c1_commit_, c1_pbft_controller.pbft_db.get_chain_id())); + // for sync + c3_final.produce_block(); + c3_final_pbft_controller.maybe_pbft_commit(); + curr_state = c3_final_pbft_controller.state_machine->get_current()->get_name(); + BOOST_CHECK_EQUAL(curr_state, "{==== COMMITTED ====}"); + BOOST_CHECK_EQUAL(c3_final.control->last_irreversible_block_num(), 99); + + c3_final_pbft_controller.maybe_pbft_prepare(); + c3_final_prepare = c3_final_pbft_controller.state_machine->get_prepares_cache(); + BOOST_CHECK_EQUAL(c3_final_prepare.block_info.block_num(), 100); + +} + + +BOOST_AUTO_TEST_CASE(fetch_branch_from_block_at_same_fork_return_at_least_common_ancestor) { + //create forks + tester c; + c.produce_block(); + c.produce_block(); + auto r = c.create_accounts( {N(dan),N(sam),N(pam)} ); + wdump((fc::json::to_pretty_string(r))); + c.produce_block(); + auto res = c.set_producers( {N(dan),N(sam),N(pam)} ); + vector sch = { {N(dan),get_public_key(N(dan), "active")}, + {N(sam),get_public_key(N(sam), "active")}, + {N(pam),get_public_key(N(pam), "active")}}; + wdump((fc::json::to_pretty_string(res))); + wlog("set producer schedule to [dan,sam,pam]"); + c.produce_blocks(98); + + BOOST_CHECK_EQUAL(c.control->head_block_num(), 102); + + // first is low block number + auto first = c.control->get_block_id_for_num(100); + auto second = c.control->get_block_id_for_num(102); + auto result = c.control->fork_db().fetch_branch_from(first, second); + + BOOST_CHECK_EQUAL(result.first.size(), 1); + BOOST_CHECK_EQUAL(result.second.size(), 3); + + + // first is high block number + first = c.control->get_block_id_for_num(102); + second = c.control->get_block_id_for_num(99); + result = c.control->fork_db().fetch_branch_from(first, second); + + BOOST_CHECK_EQUAL(result.first.size(), 4); + BOOST_CHECK_EQUAL(result.second.size(), 1); + + BOOST_CHECK_EQUAL(result.first[result.first.size() - 1]->id, result.second[result.second.size() - 1]->id); +} + + +BOOST_AUTO_TEST_CASE(fetch_branch_from_block_at_same_block_return_at_least_common_ancestor) { + //create forks + tester c; + c.produce_block(); + c.produce_block(); + auto r = c.create_accounts( {N(dan),N(sam),N(pam)} ); + wdump((fc::json::to_pretty_string(r))); + c.produce_block(); + auto res = c.set_producers( {N(dan),N(sam),N(pam)} ); + vector sch = { {N(dan),get_public_key(N(dan), "active")}, + {N(sam),get_public_key(N(sam), "active")}, + {N(pam),get_public_key(N(pam), "active")}}; + wdump((fc::json::to_pretty_string(res))); + wlog("set producer schedule to [dan,sam,pam]"); + c.produce_blocks(98); + + BOOST_CHECK_EQUAL(c.control->head_block_num(), 102); + + // same block + auto first = c.control->get_block_id_for_num(102); + auto second = c.control->get_block_id_for_num(102); + auto result = c.control->fork_db().fetch_branch_from(first, second); + + // result two branch will only include one common_ancestor + BOOST_CHECK_EQUAL(result.first.size(), 1); + BOOST_CHECK_EQUAL(result.second.size(), 1); + + BOOST_CHECK_EQUAL(result.first[result.first.size() - 1]->id == result.second[result.second.size() - 1]->id, true); +} + + +BOOST_AUTO_TEST_CASE(fetch_branch_from_block_at_diffent_fork_return_without_common_ancestor) { + //create forks + tester c; + c.produce_block(); + c.produce_block(); + auto r = c.create_accounts( {N(dan),N(sam),N(pam)} ); + wdump((fc::json::to_pretty_string(r))); + c.produce_block(); + auto res = c.set_producers( {N(dan),N(sam),N(pam)} ); + vector sch = { {N(dan),get_public_key(N(dan), "active")}, + {N(sam),get_public_key(N(sam), "active")}, + {N(pam),get_public_key(N(pam), "active")}}; + wdump((fc::json::to_pretty_string(res))); + wlog("set producer schedule to [dan,sam,pam]"); + c.produce_blocks(98); + + tester c2; + c2.produce_block(); + c2.produce_block(); + c2.create_accounts( {N(dan),N(sam),N(pam)} ); + c2.produce_block(); + c2.set_producers( {N(dan),N(sam),N(pam)} ); + wlog("set producer schedule to [dan,sam,pam]"); + c2.produce_blocks(98); + + //check c2 98 c98 equal + + c.create_accounts({N(tester1)}); + c.produce_blocks(10); + c2.create_accounts({N(tester2)}); + c2.produce_blocks(1); + + auto c2_previous_fork_head_id = c2.control->get_block_id_for_num(103); + auto c2_tmp_102 = c2.control->get_block_id_for_num(102); + BOOST_CHECK_EQUAL(c2.control->head_block_num(), 103); + + // push this fork to c2 + for (int i = 103; i <= 104; i++) { + auto fb = c.control->fetch_block_by_number(i); + c2.push_block(fb); + } + + BOOST_CHECK_EQUAL(c2.control->head_block_num(), 104); + + + auto first = c2.control->get_block_id_for_num(103); + BOOST_CHECK_EQUAL(first!= c2_previous_fork_head_id, true); + BOOST_CHECK_EQUAL(c2.control->get_block_id_for_num(102) == c2_tmp_102, true); + auto result = c2.control->fork_db().fetch_branch_from(first, c2_previous_fork_head_id); + + // if first and second in different fork, the result two branch do not include common ancestor + BOOST_CHECK_EQUAL(result.first.size(), 1); + BOOST_CHECK_EQUAL(result.second.size(), 1); + + BOOST_CHECK_EQUAL(result.first[result.first.size() - 1]->id != result.second[result.second.size() - 1]->id, true); + BOOST_CHECK_EQUAL(result.first[result.first.size() - 1]->block_num, 103); + BOOST_CHECK_EQUAL(result.second[result.second.size() - 1]->block_num, 103); +} BOOST_AUTO_TEST_SUITE_END() From 02093537df9dc2ceb3ce72573a7ed33d54a14f23 Mon Sep 17 00:00:00 2001 From: Frank-AFN Date: Tue, 16 Jul 2019 11:43:49 +0800 Subject: [PATCH 6/6] Refactor reserve prepare testcase and Add two times maybe switch forks testcase for issue 114 in boscore --- unittests/pbft_tests.cpp | 198 ++++++++++++++++++++++++--------------- 1 file changed, 120 insertions(+), 78 deletions(-) diff --git a/unittests/pbft_tests.cpp b/unittests/pbft_tests.cpp index ea0420c24a2..f2d75c5a6e8 100644 --- a/unittests/pbft_tests.cpp +++ b/unittests/pbft_tests.cpp @@ -349,6 +349,102 @@ BOOST_AUTO_TEST_CASE(switch_fork_when_accept_new_view_with_prepare_certificate_o BOOST_CHECK_EQUAL(ctrl_short_prepared_fork.last_irreversible_block_num(), 136); } +BOOST_AUTO_TEST_CASE(new_view_with_committed_cert_call_two_times_maybe_switch_forks) { + tester c1, new_view_generator; + controller &c1_ctrl = *c1.control.get(); + pbft_controller c1_pbft_controller{c1_ctrl}; + controller &ctrl_new_view_generator = *new_view_generator.control.get(); + pbft_controller pbft_new_view_generator{ctrl_new_view_generator}; + + auto msp = make_signature_provider(); + c1_ctrl.set_my_signature_providers(msp); + ctrl_new_view_generator.set_my_signature_providers(msp); + + c1_ctrl.set_upo(48); + ctrl_new_view_generator.set_upo(48); + + c1.create_accounts( {N(alice),N(bob),N(carol),N(deny)} ); + c1.set_producers({N(alice),N(bob),N(carol),N(deny)}); + c1.produce_blocks(100); + + new_view_generator.create_accounts( {N(alice),N(bob),N(carol),N(deny)} ); + new_view_generator.set_producers({N(alice),N(bob),N(carol),N(deny)}); + new_view_generator.produce_blocks(100); + + c1_pbft_controller.maybe_pbft_prepare(); + c1_pbft_controller.maybe_pbft_commit(); + c1.produce_blocks(1); + c1_pbft_controller.maybe_pbft_commit(); + c1.produce_blocks(25); + + pbft_new_view_generator.maybe_pbft_prepare(); + pbft_new_view_generator.maybe_pbft_commit(); + new_view_generator.produce_blocks(1); + pbft_new_view_generator.maybe_pbft_commit(); + new_view_generator.produce_blocks(25); + + BOOST_CHECK_EQUAL(ctrl_new_view_generator.head_block_num(), 127); + BOOST_CHECK_EQUAL(c1_ctrl.head_block_num(), 127); + BOOST_CHECK_EQUAL(ctrl_new_view_generator.last_irreversible_block_num(), 101); + BOOST_CHECK_EQUAL(c1_ctrl.last_irreversible_block_num(), 101); + + c1.create_accounts({N(shortname)}); + new_view_generator.create_accounts({N(longname)}); + c1.produce_blocks(6); + new_view_generator.produce_blocks(10); + + c1_pbft_controller.state_machine->set_prepares_cache(pbft_prepare()); + c1_ctrl.reset_pbft_my_prepare(); + c1_pbft_controller.maybe_pbft_prepare(); + c1.produce_block(); + + //merge short fork and long fork, make sure current head is short fork + for(int i=1;i<=10;i++){ + auto tmp = ctrl_new_view_generator.fetch_block_by_number(127+i); + c1.push_block(tmp); + } + BOOST_CHECK_EQUAL(c1_ctrl.head_block_num(), 134); + auto c1_my_prepare = c1_ctrl.get_pbft_my_prepare(); + auto c1_my_prepare_num = c1_ctrl.fork_db().get_block(c1_my_prepare)->block_num; + BOOST_CHECK_EQUAL(c1_my_prepare_num, 133); + + + //generate new view with long fork commit certificate + pbft_new_view_generator.state_machine->set_prepares_cache(pbft_prepare()); + BOOST_CHECK_EQUAL(pbft_new_view_generator.pbft_db.should_send_pbft_msg(), true); + ctrl_new_view_generator.reset_pbft_my_prepare(); + pbft_new_view_generator.maybe_pbft_prepare(); + + auto pbft_new_view_prepare = ctrl_new_view_generator.get_pbft_my_prepare(); + auto pbft_new_view_prepare_num = ctrl_new_view_generator.fork_db().get_block(pbft_new_view_prepare)->block_num; + BOOST_CHECK_EQUAL(pbft_new_view_prepare_num, 137); + + BOOST_CHECK_EQUAL(ctrl_new_view_generator.head_block_num(), 137); + pbft_new_view_generator.maybe_pbft_commit(); + new_view_generator.produce_block(); + BOOST_CHECK_EQUAL(ctrl_new_view_generator.last_irreversible_block_num(), 137); + + for(int i = 0; ido_send_view_change(); + auto new_view = pbft_new_view_generator.pbft_db.get_proposed_new_view_num(); + auto vcc = pbft_new_view_generator.pbft_db.generate_view_changed_certificate(new_view); + auto nv_msg = pbft_new_view_generator.pbft_db.send_pbft_new_view(vcc, new_view); + + //can switch fork after apply prepare certificate in new view + auto pmm = pbft_message_metadata(nv_msg, c1_pbft_controller.pbft_db.get_chain_id()); + + /// boscore issue https://github.com/boscore/bos/issues/114. + /// It will never throw exception block_validate_exception, "next block must be in the future" in the version 20e08dba + c1_pbft_controller.on_pbft_new_view(std::make_shared>(pmm)); + c1_pbft_controller.maybe_pbft_commit(); + c1.produce_blocks(2); + BOOST_CHECK_EQUAL(c1_ctrl.last_irreversible_block_num(), 137); + // make sure commited block same with new view generator lib block + BOOST_CHECK_EQUAL(c1_ctrl.fetch_block_by_number(137)->id(), ctrl_new_view_generator.fetch_block_by_number(137)->id()); +} + private_key_type get_private_key( name keyname, string role ) { return private_key_type::regenerate(fc::sha256::hash(string(keyname)+role)); @@ -360,24 +456,21 @@ public_key_type get_public_key( name keyname, string role ){ BOOST_AUTO_TEST_CASE(switch_fork_reserve_prepare) { const char* curr_state; - tester c1, c2, c2_prime, c3, c3_final; - controller &c1_fork = *c1.control.get(); - pbft_controller c1_pbft_controller{c1_fork}; - controller &c2_fork = *c2.control.get(); - pbft_controller c2_pbft_controller{c2_fork}; - controller &c2_fork_prime = c2_fork; - pbft_controller c2_prime_pbft_controller{c2_fork_prime}; - controller &c3_fork = *c3.control.get(); - pbft_controller c3_pbft_controller{c3_fork}; - controller &c3_final_fork = *c3_final.control.get(); - pbft_controller c3_final_pbft_controller{c3_final_fork}; - - - c1_fork.set_upo(48); - c2_fork.set_upo(48); - c2_fork_prime.set_upo(48); - c3_fork.set_upo(48); - c3_final_fork.set_upo(48); + tester c1, c2, c2_prime, c3_final; + controller &c1_ctrl = *c1.control.get(); /// only have signature Alice + pbft_controller c1_pbft_controller{c1_ctrl}; + controller &c2_ctrl = *c2.control.get(); /// have signature Alice and bob + pbft_controller c2_pbft_controller{c2_ctrl}; + controller &c2_ctrl_prime = c2_ctrl; /// for make fork + pbft_controller c2_prime_pbft_controller{c2_ctrl_prime}; + controller &c3_final_ctrl = *c3_final.control.get(); /// only have signature bob + pbft_controller c3_final_pbft_controller{c3_final_ctrl}; + + + c1_ctrl.set_upo(48); + c2_ctrl.set_upo(48); + c2_ctrl_prime.set_upo(48); + c3_final_ctrl.set_upo(48); /// c1 c1.produce_block(); @@ -392,7 +485,7 @@ BOOST_AUTO_TEST_CASE(switch_fork_reserve_prepare) { return priv_alice.sign(digest); }; msp_c1[pub_alice]=sp_alice; - c1_fork.set_my_signature_providers(msp_c1); + c1_ctrl.set_my_signature_providers(msp_c1); c1.set_producers( {N(alice), N(bob)} ); @@ -414,7 +507,7 @@ BOOST_AUTO_TEST_CASE(switch_fork_reserve_prepare) { return priv_bob.sign(digest); }; msp_c2[pub_bob]=sp_bob; - c2_fork.set_my_signature_providers(msp_c2); + c2_ctrl.set_my_signature_providers(msp_c2); c2.set_producers( {N(alice), N(bob)} ); @@ -428,32 +521,16 @@ BOOST_AUTO_TEST_CASE(switch_fork_reserve_prepare) { c2.produce_block(); BOOST_CHECK_EQUAL(c2.control->last_irreversible_block_num(), 98); - - /// c3 - c3.produce_block(); - c3.create_accounts( {N(alice), N(bob)} ); - c3.produce_block(); - - // make and get signature provider for c3 - std::map msp_c3; - msp_c3[pub_bob]=sp_bob; - - c3_fork.set_my_signature_providers(msp_c3); - - c3.set_producers( {N(alice), N(bob)} ); - - vector c3_sch = { {N(bob),get_public_key(N(bob), "active")} }; - /// c3 final c3_final.produce_block(); c3_final.create_accounts( {N(alice), N(bob)} ); c3_final.produce_block(); - // make and get signature provider for c3 + // make and get signature provider for c3 final std::map msp_c3_final; msp_c3_final[pub_bob]=sp_bob; - c3_final_fork.set_my_signature_providers(msp_c3_final); + c3_final_ctrl.set_my_signature_providers(msp_c3_final); c3_final.set_producers( {N(alice), N(bob)} ); @@ -463,10 +540,9 @@ BOOST_AUTO_TEST_CASE(switch_fork_reserve_prepare) { push_blocks(c2, c1); - /// make c1 lib 98 c3 lib 99 + /// make c1 lib 98 c1_pbft_controller.maybe_pbft_prepare(); pbft_prepare c2_prepare_ = c2_pbft_controller.state_machine->get_prepares_cache(); - // check c3 prepare at 63 BOOST_CHECK_EQUAL(c2_prepare_.block_info.block_num(), 98); c1_pbft_controller.state_machine->on_prepare(std::make_shared>(c2_prepare_, c2_pbft_controller.pbft_db.get_chain_id())); c1_pbft_controller.maybe_pbft_commit(); @@ -495,17 +571,9 @@ BOOST_AUTO_TEST_CASE(switch_fork_reserve_prepare) { // copy c2 to c2_prime push_blocks(c2, c2_prime); - /// make c3 as prepared - push_blocks(c2, c3); - c3_pbft_controller.maybe_pbft_prepare(); pbft_prepare c1_prepare; c1_prepare_ = c1_pbft_controller.state_machine->get_prepares_cache(); c1_prepare = c1_prepare_; -// check c1 prepare at 99 - BOOST_CHECK_EQUAL(c1_prepare_.block_info.block_num(), 99); - c3_pbft_controller.state_machine->on_prepare(std::make_shared>(c1_prepare_, c1_pbft_controller.pbft_db.get_chain_id())); - curr_state = c3_pbft_controller.state_machine->get_current()->get_name(); - BOOST_CHECK_EQUAL(curr_state, "{==== PREPARED ====}"); /// for set pbft commit cache to 99 c2.produce_block(); @@ -536,40 +604,16 @@ BOOST_AUTO_TEST_CASE(switch_fork_reserve_prepare) { BOOST_CHECK_EQUAL(c1_commit_.block_info.block_num(), 99); BOOST_CHECK_EQUAL(c1.control->last_irreversible_block_num(), 99); - /// make c3 as committed - c3_pbft_controller.maybe_pbft_commit(); - c1_commit_ = c1_pbft_controller.state_machine->get_commits_cache(); - c3_pbft_controller.state_machine->on_commit(std::make_shared>(c1_commit_, c1_pbft_controller.pbft_db.get_chain_id())); - c3.produce_block(); - c3_pbft_controller.maybe_pbft_commit(); - curr_state = c3_pbft_controller.state_machine->get_current()->get_name(); - BOOST_CHECK_EQUAL(curr_state, "{==== COMMITTED ====}"); - - BOOST_CHECK_EQUAL(c3.control->last_irreversible_block_num(), 99); - - - BOOST_CHECK_EQUAL(c2.control->head_block_num(), 101); - BOOST_CHECK_EQUAL(c3.control->head_block_num(), 100); - - c3.produce_block(); - c3_pbft_controller.maybe_pbft_prepare(); c3_final_pbft_controller.maybe_pbft_prepare(); - c3.produce_block(); c3_final.produce_block(); c3_final.produce_block(); - // get c3 prepare and push to c1 - pbft_prepare c3_prepare = c3_pbft_controller.state_machine->get_prepares_cache(); - // check c3 prepare at 99 - BOOST_CHECK_EQUAL(c3_prepare.block_info.block_num(), 100); BOOST_CHECK_EQUAL(c1_prepare.block_info.block_num(), 99); - - c3_final_fork.set_pbft_my_prepare(c3_prepare.block_info.block_id); + /// set c3 my preprare at 100 + c3_final_ctrl.set_pbft_my_prepare(c3_final_ctrl.get_block_id_for_num(100)); c3_final_pbft_controller.state_machine->on_prepare(std::make_shared>(c1_prepare, c1_pbft_controller.pbft_db.get_chain_id())); - BOOST_CHECK_EQUAL(c3_final_fork.get_pbft_my_prepare(), c3_prepare.block_info.block_id); - pbft_prepare c3_final_prepare = c3_final_pbft_controller.state_machine->get_prepares_cache(); // check c3 prepare at 99 BOOST_CHECK_EQUAL(c3_final_prepare.block_info.block_num(), 99); @@ -582,7 +626,7 @@ BOOST_AUTO_TEST_CASE(switch_fork_reserve_prepare) { c2_prime.create_accounts({N(tester1)}); c2_prime.produce_blocks(5); - //push fork to c3 + //push fork to c3_final for(int i = 100; i <= 104; i++) { auto fb = c2_prime.control->fetch_block_by_number(i); c3_final.push_block(fb); @@ -598,12 +642,10 @@ BOOST_AUTO_TEST_CASE(switch_fork_reserve_prepare) { BOOST_CHECK_EQUAL(c3_final.control->head_block_num(), 104); - pbft_commit c3_commit = c3_pbft_controller.state_machine->get_commits_cache(); - BOOST_CHECK_EQUAL(c3_commit.block_info.block_num(), 99); c3_final_pbft_controller.maybe_pbft_commit(); c3_final.produce_block(); -// c3_final_pbft_controller.maybe_pbft_commit(); pbft_commit c3_final_commit = c3_final_pbft_controller.state_machine->get_commits_cache(); + /// on commit will prepare next block immediately will trigger reserve prepare c3_final_pbft_controller.state_machine->on_commit(std::make_shared>(c1_commit_, c1_pbft_controller.pbft_db.get_chain_id())); // for sync c3_final.produce_block();