From 3631e26c9f00be9f9ff04fae5a98387b060f028e Mon Sep 17 00:00:00 2001 From: Chris Gundlach Date: Fri, 4 Dec 2020 16:07:59 -0800 Subject: [PATCH 1/7] added app method to producer plugin for bv sync --- .../include/eosio/chain/plugin_interface.hpp | 1 + plugins/chain_plugin/chain_plugin.cpp | 2 + .../chain_plugin/blockvault_sync_strategy.hpp | 7 ++- .../test/test_blockvault_sync_strategy.cpp | 4 +- plugins/producer_plugin/producer_plugin.cpp | 55 ++++++++++++++++++- 5 files changed, 64 insertions(+), 5 deletions(-) diff --git a/plugins/chain_interface/include/eosio/chain/plugin_interface.hpp b/plugins/chain_interface/include/eosio/chain/plugin_interface.hpp index 5463dd55e0a..f0f3de8e288 100644 --- a/plugins/chain_interface/include/eosio/chain/plugin_interface.hpp +++ b/plugins/chain_interface/include/eosio/chain/plugin_interface.hpp @@ -45,6 +45,7 @@ namespace eosio { namespace chain { namespace plugin_interface { namespace methods { // synchronously push a block/trx to a single provider using block_sync = method_decl&), first_provider_policy>; + using blockvault_sync = method_decl; using transaction_async = method_decl), first_provider_policy>; } } diff --git a/plugins/chain_plugin/chain_plugin.cpp b/plugins/chain_plugin/chain_plugin.cpp index ea41700801f..6ce28410375 100644 --- a/plugins/chain_plugin/chain_plugin.cpp +++ b/plugins/chain_plugin/chain_plugin.cpp @@ -177,6 +177,7 @@ class chain_plugin_impl { ,applied_transaction_channel(app().get_channel()) ,incoming_block_channel(app().get_channel()) ,incoming_block_sync_method(app().get_method()) + ,incoming_blockvault_sync_method(app().get_method()) ,incoming_transaction_async_method(app().get_method()) {} @@ -208,6 +209,7 @@ class chain_plugin_impl { // retained references to methods for easy calling incoming::methods::block_sync::method_type& incoming_block_sync_method; + incoming::methods::blockvault_sync::method_type& incoming_blockvault_sync_method; incoming::methods::transaction_async::method_type& incoming_transaction_async_method; // method provider handles diff --git a/plugins/chain_plugin/include/eosio/chain_plugin/blockvault_sync_strategy.hpp b/plugins/chain_plugin/include/eosio/chain_plugin/blockvault_sync_strategy.hpp index c12c5ac7153..b3f9397d493 100644 --- a/plugins/chain_plugin/include/eosio/chain_plugin/blockvault_sync_strategy.hpp +++ b/plugins/chain_plugin/include/eosio/chain_plugin/blockvault_sync_strategy.hpp @@ -45,6 +45,10 @@ struct blockvault_sync_strategy : public sync_callback { ilog("Received no data from blockvault."); run_startup(); } + + ilog("Sync from blockvault completed. ${snap}. ${blks} blocks received. ${ulnk} blocks unlinkable", + ("snap", _received_snapshot ? "Got snapshot" : "No snapshot") + ("blks", _num_blocks_received)("ulnk", _num_unlinkable_blocks)); } void on_snapshot(const char* snapshot_filename) override final { @@ -66,6 +70,7 @@ struct blockvault_sync_strategy : public sync_callback { } void on_block(eosio::chain::signed_block_ptr block) override final { + ilog("Received block number ${bn}", ("bn", block->block_num())); if (_check_shutdown()) { _shutdown(); } @@ -76,7 +81,7 @@ struct blockvault_sync_strategy : public sync_callback { try { ++_num_blocks_received; - _blockchain_provider.incoming_block_sync_method(block, block->calculate_id()); + _blockchain_provider.incoming_blockvault_sync_method(block); } catch (unlinkable_block_exception& e) { if (block->block_num() == 2) { elog("Received unlinkable block 2. Please double check if --genesis-json and --genesis-timestamp are " diff --git a/plugins/chain_plugin/test/test_blockvault_sync_strategy.cpp b/plugins/chain_plugin/test/test_blockvault_sync_strategy.cpp index 167ed59d28f..d88338e6bbb 100644 --- a/plugins/chain_plugin/test/test_blockvault_sync_strategy.cpp +++ b/plugins/chain_plugin/test/test_blockvault_sync_strategy.cpp @@ -70,9 +70,8 @@ struct mock_chain_plugin_t { chain = std::make_unique(); } - bool incoming_block_sync_method(const chain::signed_block_ptr& block, const chain::block_id_type& id) { + bool incoming_blockvault_sync_method(const chain::signed_block_ptr& block) { _block = block; - _id = id; return _accept_block_rc; } @@ -147,7 +146,6 @@ BOOST_FIXTURE_TEST_CASE(on_block_no_snapshot, TESTER) { BOOST_TEST(plugin._startup_non_snapshot_called); BOOST_TEST(!plugin.chain->_startup_reader_called); BOOST_TEST(plugin._block->calculate_id() == b->calculate_id()); - BOOST_TEST(plugin._block->calculate_id() == plugin._id); } FC_LOG_AND_RETHROW() } diff --git a/plugins/producer_plugin/producer_plugin.cpp b/plugins/producer_plugin/producer_plugin.cpp index 2e2de5f16c4..e70603ef155 100644 --- a/plugins/producer_plugin/producer_plugin.cpp +++ b/plugins/producer_plugin/producer_plugin.cpp @@ -176,6 +176,7 @@ class producer_plugin_impl : public std::enable_shared_from_thischain(); + + const auto& id = block->calculate_id(); + auto blk_num = block->block_num(); + + fc_dlog(_log, "syncing blockvault block ${n} ${id}", ("n", blk_num)("id", id)); + + // start processing of block + auto bsf = chain.create_block_state_future( id, block ); + + // abort the pending block + _unapplied_transactions.add_aborted( chain.abort_block() ); + + // push the new block + auto handle_error = [&](const auto& e) + { + elog((e.to_detail_string())); + app().get_channel().publish( priority::medium, block ); + throw; + }; + + try { + block_state_ptr blk_state = chain.push_block( bsf, [this]( const branch_type& forked_branch ) { + _unapplied_transactions.add_forked( forked_branch ); + }, [this]( const transaction_id_type& id ) { + return _unapplied_transactions.get_trx( id ); + } ); + if ( blockvault != nullptr ) { + blockvault->async_append_external_block(blk_state->dpos_irreversible_blocknum, blk_state->block, [](bool){}); + } + } catch ( const guard_exception& e ) { + chain_plugin::handle_guard_exception(e); + return false; + } catch ( const std::bad_alloc& ) { + chain_plugin::handle_bad_alloc(); + } catch ( boost::interprocess::bad_alloc& ) { + chain_plugin::handle_db_exhaustion(); + } catch( const fc::exception& e ) { + handle_error(e); + } catch (const std::exception& e) { + handle_error(fc::std_exception_wrapper::from_current_exception(e)); + } + + return true; + } + bool on_incoming_block(const signed_block_ptr& block, const std::optional& block_id) { auto& chain = chain_plug->chain(); - if ( _pending_block_mode == pending_block_mode::producing ) { + if ( _pending_block_mode == pending_block_mode::producing) { fc_wlog( _log, "dropped incoming block #${num} id: ${id}", ("num", block->block_num())("id", block_id ? (*block_id).str() : "UNKNOWN") ); return false; @@ -813,6 +861,11 @@ void producer_plugin::plugin_initialize(const boost::program_options::variables_ return my->on_incoming_block(block, block_id); }); + my->_incoming_blockvault_sync_provider = app().get_method().register_provider( + [this](const signed_block_ptr& block) { + return my->on_sync_block(block); + }); + my->_incoming_transaction_async_provider = app().get_method().register_provider( [this](const packed_transaction_ptr& trx, bool persist_until_expired, next_function next) -> void { return my->on_incoming_transaction_async(trx, persist_until_expired, next ); From 5b284441bf43d88d436c01a67ee0a23fc6672f80 Mon Sep 17 00:00:00 2001 From: Chris Gundlach Date: Fri, 4 Dec 2020 17:11:11 -0800 Subject: [PATCH 2/7] address review comments --- .../include/eosio/chain_plugin/blockvault_sync_strategy.hpp | 6 ++++-- plugins/producer_plugin/producer_plugin.cpp | 4 ---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/plugins/chain_plugin/include/eosio/chain_plugin/blockvault_sync_strategy.hpp b/plugins/chain_plugin/include/eosio/chain_plugin/blockvault_sync_strategy.hpp index b3f9397d493..8276a3dce49 100644 --- a/plugins/chain_plugin/include/eosio/chain_plugin/blockvault_sync_strategy.hpp +++ b/plugins/chain_plugin/include/eosio/chain_plugin/blockvault_sync_strategy.hpp @@ -53,7 +53,7 @@ struct blockvault_sync_strategy : public sync_callback { void on_snapshot(const char* snapshot_filename) override final { ilog("Received snapshot from blockvault ${fn}", ("fn", snapshot_filename)); - EOS_ASSERT(!_received_snapshot, plugin_exception, "Received multiple snapshots from blockvault.", ); + EOS_ASSERT(!_received_snapshot, plugin_exception, "Received multiple snapshots from blockvault." ); _received_snapshot = true; if (_check_shutdown()) { @@ -81,7 +81,9 @@ struct blockvault_sync_strategy : public sync_callback { try { ++_num_blocks_received; - _blockchain_provider.incoming_blockvault_sync_method(block); + EOS_ASSERT(_blockchain_provider.incoming_blockvault_sync_method(block), plugin_exception, + "Unable to sync block from blockvault, block num=${bnum}, block id=${bid}", + ("bnum", block->block_num())("bid", block->calculate_id())); } catch (unlinkable_block_exception& e) { if (block->block_num() == 2) { elog("Received unlinkable block 2. Please double check if --genesis-json and --genesis-timestamp are " diff --git a/plugins/producer_plugin/producer_plugin.cpp b/plugins/producer_plugin/producer_plugin.cpp index e70603ef155..af80c6d4512 100644 --- a/plugins/producer_plugin/producer_plugin.cpp +++ b/plugins/producer_plugin/producer_plugin.cpp @@ -311,7 +311,6 @@ class producer_plugin_impl : public std::enable_shared_from_this().publish( priority::medium, block ); throw; }; @@ -321,9 +320,6 @@ class producer_plugin_impl : public std::enable_shared_from_thisasync_append_external_block(blk_state->dpos_irreversible_blocknum, blk_state->block, [](bool){}); - } } catch ( const guard_exception& e ) { chain_plugin::handle_guard_exception(e); return false; From a0e9f035cae7a894a55581a818f147f03aefd887 Mon Sep 17 00:00:00 2001 From: Chris Gundlach Date: Sat, 5 Dec 2020 09:47:46 -0800 Subject: [PATCH 3/7] throttled block sync logging --- .../include/eosio/chain_plugin/blockvault_sync_strategy.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/chain_plugin/include/eosio/chain_plugin/blockvault_sync_strategy.hpp b/plugins/chain_plugin/include/eosio/chain_plugin/blockvault_sync_strategy.hpp index 8276a3dce49..78862e4bacb 100644 --- a/plugins/chain_plugin/include/eosio/chain_plugin/blockvault_sync_strategy.hpp +++ b/plugins/chain_plugin/include/eosio/chain_plugin/blockvault_sync_strategy.hpp @@ -70,7 +70,10 @@ struct blockvault_sync_strategy : public sync_callback { } void on_block(eosio::chain::signed_block_ptr block) override final { - ilog("Received block number ${bn}", ("bn", block->block_num())); + if (0 == (_num_blocks_received % 100)) { + ilog("Received block number ${bn}", ("bn", block->block_num())); + } + if (_check_shutdown()) { _shutdown(); } From 5788c11e1039d873e8a52c82b801d0260a35d3a8 Mon Sep 17 00:00:00 2001 From: Chris Gundlach Date: Sat, 5 Dec 2020 09:56:09 -0800 Subject: [PATCH 4/7] changed sync logging to dlog --- .../include/eosio/chain_plugin/blockvault_sync_strategy.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/chain_plugin/include/eosio/chain_plugin/blockvault_sync_strategy.hpp b/plugins/chain_plugin/include/eosio/chain_plugin/blockvault_sync_strategy.hpp index 78862e4bacb..9b0b96315b4 100644 --- a/plugins/chain_plugin/include/eosio/chain_plugin/blockvault_sync_strategy.hpp +++ b/plugins/chain_plugin/include/eosio/chain_plugin/blockvault_sync_strategy.hpp @@ -71,9 +71,9 @@ struct blockvault_sync_strategy : public sync_callback { void on_block(eosio::chain::signed_block_ptr block) override final { if (0 == (_num_blocks_received % 100)) { - ilog("Received block number ${bn}", ("bn", block->block_num())); + dlog("Received block number ${bn}", ("bn", block->block_num())); } - + if (_check_shutdown()) { _shutdown(); } From bf3854bbbe80447e04b1ac0c704bedfb1896b9d8 Mon Sep 17 00:00:00 2001 From: Chris Gundlach Date: Sat, 5 Dec 2020 12:12:46 -0800 Subject: [PATCH 5/7] added connectivity check to bv sync --- .../include/eosio/chain/plugin_interface.hpp | 2 +- .../chain_plugin/blockvault_sync_strategy.hpp | 2 +- .../test/test_blockvault_sync_strategy.cpp | 2 +- plugins/producer_plugin/producer_plugin.cpp | 15 ++++++++++++--- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/plugins/chain_interface/include/eosio/chain/plugin_interface.hpp b/plugins/chain_interface/include/eosio/chain/plugin_interface.hpp index f0f3de8e288..bd5d950172b 100644 --- a/plugins/chain_interface/include/eosio/chain/plugin_interface.hpp +++ b/plugins/chain_interface/include/eosio/chain/plugin_interface.hpp @@ -45,7 +45,7 @@ namespace eosio { namespace chain { namespace plugin_interface { namespace methods { // synchronously push a block/trx to a single provider using block_sync = method_decl&), first_provider_policy>; - using blockvault_sync = method_decl; + using blockvault_sync = method_decl; using transaction_async = method_decl), first_provider_policy>; } } diff --git a/plugins/chain_plugin/include/eosio/chain_plugin/blockvault_sync_strategy.hpp b/plugins/chain_plugin/include/eosio/chain_plugin/blockvault_sync_strategy.hpp index 9b0b96315b4..8a69904d1a8 100644 --- a/plugins/chain_plugin/include/eosio/chain_plugin/blockvault_sync_strategy.hpp +++ b/plugins/chain_plugin/include/eosio/chain_plugin/blockvault_sync_strategy.hpp @@ -84,7 +84,7 @@ struct blockvault_sync_strategy : public sync_callback { try { ++_num_blocks_received; - EOS_ASSERT(_blockchain_provider.incoming_blockvault_sync_method(block), plugin_exception, + EOS_ASSERT(_blockchain_provider.incoming_blockvault_sync_method(block, (1 != _num_blocks_received)), plugin_exception, "Unable to sync block from blockvault, block num=${bnum}, block id=${bid}", ("bnum", block->block_num())("bid", block->calculate_id())); } catch (unlinkable_block_exception& e) { diff --git a/plugins/chain_plugin/test/test_blockvault_sync_strategy.cpp b/plugins/chain_plugin/test/test_blockvault_sync_strategy.cpp index d88338e6bbb..b0929fbb183 100644 --- a/plugins/chain_plugin/test/test_blockvault_sync_strategy.cpp +++ b/plugins/chain_plugin/test/test_blockvault_sync_strategy.cpp @@ -70,7 +70,7 @@ struct mock_chain_plugin_t { chain = std::make_unique(); } - bool incoming_blockvault_sync_method(const chain::signed_block_ptr& block) { + bool incoming_blockvault_sync_method(const chain::signed_block_ptr& block, bool check_connectivity) { _block = block; return _accept_block_rc; } diff --git a/plugins/producer_plugin/producer_plugin.cpp b/plugins/producer_plugin/producer_plugin.cpp index af80c6d4512..bb57e6b9429 100644 --- a/plugins/producer_plugin/producer_plugin.cpp +++ b/plugins/producer_plugin/producer_plugin.cpp @@ -293,7 +293,7 @@ class producer_plugin_impl : public std::enable_shared_from_thischain(); const auto& id = block->calculate_id(); @@ -301,6 +301,15 @@ class producer_plugin_impl : public std::enable_shared_from_thisprevious); + if (!previous) { + dlog("Don't have previous block for block number ${bn}, looking for block id ${pbi}", + ("bn", block->block_num())("pbi", block->previous)); + return true; + } + } + // start processing of block auto bsf = chain.create_block_state_future( id, block ); @@ -858,8 +867,8 @@ void producer_plugin::plugin_initialize(const boost::program_options::variables_ }); my->_incoming_blockvault_sync_provider = app().get_method().register_provider( - [this](const signed_block_ptr& block) { - return my->on_sync_block(block); + [this](const signed_block_ptr& block, bool check_connectivity) { + return my->on_sync_block(block, check_connectivity); }); my->_incoming_transaction_async_provider = app().get_method().register_provider( From 9b3775547533f50e27ed843e4e40a2160d8babc3 Mon Sep 17 00:00:00 2001 From: Chris Gundlach Date: Sat, 5 Dec 2020 13:02:20 -0800 Subject: [PATCH 6/7] changed logic on when to check connectivity --- .../eosio/chain_plugin/blockvault_sync_strategy.hpp | 9 ++++++++- .../chain_plugin/test/test_blockvault_sync_strategy.cpp | 3 +++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/plugins/chain_plugin/include/eosio/chain_plugin/blockvault_sync_strategy.hpp b/plugins/chain_plugin/include/eosio/chain_plugin/blockvault_sync_strategy.hpp index 8a69904d1a8..491658bbfc5 100644 --- a/plugins/chain_plugin/include/eosio/chain_plugin/blockvault_sync_strategy.hpp +++ b/plugins/chain_plugin/include/eosio/chain_plugin/blockvault_sync_strategy.hpp @@ -67,6 +67,8 @@ struct blockvault_sync_strategy : public sync_callback { _startup_run = true; infile.close(); + + _snapshot_height = _blockchain_provider.chain->head_block_num(); } void on_block(eosio::chain::signed_block_ptr block) override final { @@ -83,8 +85,12 @@ struct blockvault_sync_strategy : public sync_callback { } try { + ++_num_blocks_received; - EOS_ASSERT(_blockchain_provider.incoming_blockvault_sync_method(block, (1 != _num_blocks_received)), plugin_exception, + auto rc = _blockchain_provider.incoming_blockvault_sync_method(block, + (!_received_snapshot || (block->block_num() != _snapshot_height +1))); + + EOS_ASSERT(rc, plugin_exception, "Unable to sync block from blockvault, block num=${bnum}, block id=${bid}", ("bnum", block->block_num())("bid", block->calculate_id())); } catch (unlinkable_block_exception& e) { @@ -106,6 +112,7 @@ struct blockvault_sync_strategy : public sync_callback { bool _received_snapshot; uint32_t _num_unlinkable_blocks = 0; uint32_t _num_blocks_received = 0; + uint32_t _snapshot_height = 0; }; } // namespace blockvault diff --git a/plugins/chain_plugin/test/test_blockvault_sync_strategy.cpp b/plugins/chain_plugin/test/test_blockvault_sync_strategy.cpp index b0929fbb183..a82fa14eddd 100644 --- a/plugins/chain_plugin/test/test_blockvault_sync_strategy.cpp +++ b/plugins/chain_plugin/test/test_blockvault_sync_strategy.cpp @@ -43,6 +43,9 @@ struct mock_chain_t { std::shared_ptr _reader; bool _startup_reader_called; + + uint32_t _head_block_num = 0; + uint32_t head_block_num() {return _head_block_num;} }; struct mock_blockvault_t : public block_vault_interface { From 00af1877f1770055a293e2c5af4f65ceefebbe53 Mon Sep 17 00:00:00 2001 From: Chris Gundlach Date: Sat, 5 Dec 2020 13:17:40 -0800 Subject: [PATCH 7/7] cleaned up logical expression --- .../include/eosio/chain_plugin/blockvault_sync_strategy.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/chain_plugin/include/eosio/chain_plugin/blockvault_sync_strategy.hpp b/plugins/chain_plugin/include/eosio/chain_plugin/blockvault_sync_strategy.hpp index 491658bbfc5..b5268063665 100644 --- a/plugins/chain_plugin/include/eosio/chain_plugin/blockvault_sync_strategy.hpp +++ b/plugins/chain_plugin/include/eosio/chain_plugin/blockvault_sync_strategy.hpp @@ -88,7 +88,7 @@ struct blockvault_sync_strategy : public sync_callback { ++_num_blocks_received; auto rc = _blockchain_provider.incoming_blockvault_sync_method(block, - (!_received_snapshot || (block->block_num() != _snapshot_height +1))); + !(_received_snapshot && block->block_num() == _snapshot_height +1)); EOS_ASSERT(rc, plugin_exception, "Unable to sync block from blockvault, block num=${bnum}, block id=${bid}",