make accepted_blocks signal information only needed

This commit is contained in:
Lin Huang
2023-12-16 21:43:27 -05:00
parent 32448e2b3e
commit 360f3ba90e
35 changed files with 268 additions and 229 deletions
+1 -1
View File
@@ -1962,7 +1962,7 @@ struct controller_impl {
dm_logger->on_accepted_block(bsp);
}
emit( self.accepted_block, bsp );
emit( self.accepted_block, std::tie(bsp->block, bsp->id, bsp->header, bsp->block_num) );
if( s == controller::block_status::incomplete ) {
log_irreversible();
@@ -328,7 +328,7 @@ namespace eosio { namespace chain {
signal<void(uint32_t)> block_start;
signal<void(std::tuple<const signed_block_ptr&, const block_id_type&, const account_name&>)> accepted_block_header;
signal<void(const block_state_legacy_ptr&)> accepted_block;
signal<void(std::tuple<const signed_block_ptr&, const block_id_type&, const signed_block_header&, uint32_t>)> accepted_block;
signal<void(const block_state_legacy_ptr&)> irreversible_block;
signal<void(const transaction_metadata_ptr&)> accepted_transaction;
signal<void(std::tuple<const transaction_trace_ptr&, const packed_transaction_ptr&>)> applied_transaction;
@@ -2,7 +2,6 @@
#include <eosio/chain/types.hpp>
#include <eosio/chain/exceptions.hpp>
#include <eosio/chain/block_state_legacy.hpp>
#include <eosio/chain/transaction.hpp>
#include <eosio/chain/resource_limits.hpp>
#include <eosio/chain/resource_limits_private.hpp>
@@ -81,9 +80,9 @@ private:
}
}
void remove_subjective_billing( const chain::block_state_legacy_ptr& bsp, uint32_t time_ordinal ) {
void remove_subjective_billing( const chain::signed_block_ptr& block, uint32_t time_ordinal ) {
if( !_trx_cache_index.empty() ) {
for( const auto& receipt : bsp->block->transactions ) {
for( const auto& receipt : block->transactions ) {
if( std::holds_alternative<chain::packed_transaction>(receipt.trx) ) {
const auto& pt = std::get<chain::packed_transaction>(receipt.trx);
remove_subjective_billing( pt.id(), time_ordinal );
@@ -151,11 +150,11 @@ public:
}
}
void on_block( fc::logger& log, const chain::block_state_legacy_ptr& bsp, const fc::time_point& now ) {
if( bsp == nullptr || _disabled ) return;
void on_block( fc::logger& log, const chain::signed_block_ptr& block, const fc::time_point& now ) {
if( block == nullptr || _disabled ) return;
const auto time_ordinal = time_ordinal_for(now);
const auto orig_count = _account_subjective_bill_cache.size();
remove_subjective_billing( bsp, time_ordinal );
remove_subjective_billing( block, time_ordinal );
if (orig_count > 0) {
fc_dlog( log, "Subjective billed accounts ${n} removed ${r}",
("n", orig_count)("r", orig_count - _account_subjective_bill_cache.size()) );
@@ -114,10 +114,10 @@ public:
return true;
}
void clear_applied( const block_state_legacy_ptr& bs ) {
void clear_applied( const signed_block_ptr& block ) {
if( empty() ) return;
auto& idx = queue.get<by_trx_id>();
for( const auto& receipt : bs->block->transactions ) {
for( const auto& receipt : block->transactions ) {
if( std::holds_alternative<packed_transaction>(receipt.trx) ) {
const auto& pt = std::get<packed_transaction>(receipt.trx);
auto itr = idx.find( pt.id() );
@@ -1,6 +1,5 @@
#pragma once
#include <eosio/chain/block_state_legacy.hpp>
#include <eosio/state_history/types.hpp>
#include <boost/iostreams/filtering_streambuf.hpp>
@@ -15,7 +14,7 @@ struct trace_converter {
std::optional<augmented_transaction_trace> onblock_trace;
void add_transaction(const transaction_trace_ptr& trace, const chain::packed_transaction_ptr& transaction);
void pack(boost::iostreams::filtering_ostreambuf& ds, bool trace_debug_mode, const block_state_legacy_ptr& block_state_legacy);
void pack(boost::iostreams::filtering_ostreambuf& ds, bool trace_debug_mode, const chain::signed_block_ptr& block);
};
} // namespace state_history
+2 -2
View File
@@ -15,11 +15,11 @@ void trace_converter::add_transaction(const transaction_trace_ptr& trace, const
}
}
void trace_converter::pack(boost::iostreams::filtering_ostreambuf& obuf, bool trace_debug_mode, const block_state_legacy_ptr& block_state) {
void trace_converter::pack(boost::iostreams::filtering_ostreambuf& obuf, bool trace_debug_mode, const chain::signed_block_ptr& block) {
std::vector<augmented_transaction_trace> traces;
if (onblock_trace)
traces.push_back(*onblock_trace);
for (auto& r : block_state->block->transactions) {
for (auto& r : block->transactions) {
transaction_id_type id;
if (std::holds_alternative<transaction_id_type>(r.trx))
id = std::get<transaction_id_type>(r.trx);
+4 -3
View File
@@ -321,9 +321,10 @@ namespace eosio { namespace testing {
control->add_indices();
if (lambda) lambda();
chain_transactions.clear();
control->accepted_block.connect([this]( const block_state_legacy_ptr& block_state ){
FC_ASSERT( block_state->block );
for( auto receipt : block_state->block->transactions ) {
control->accepted_block.connect([this]( std::tuple<const signed_block_ptr&, const block_id_type&, const signed_block_header&, uint32_t> t ){
const auto& [ block, id, header, block_num ] = t;
FC_ASSERT( block );
for( auto receipt : block->transactions ) {
if( std::holds_alternative<packed_transaction>(receipt.trx) ) {
auto &pt = std::get<packed_transaction>(receipt.trx);
chain_transactions[pt.get_transaction().id()] = std::move(receipt);
@@ -16,7 +16,7 @@ namespace eosio::chain::plugin_interface {
namespace channels {
using rejected_block = channel_decl<struct rejected_block_tag, signed_block_ptr>;
using accepted_block_header = channel_decl<struct accepted_block_header_tag, std::tuple<signed_block_ptr, block_id_type, account_name>>;
using accepted_block = channel_decl<struct accepted_block_tag, block_state_legacy_ptr>;
using accepted_block = channel_decl<struct accepted_block_tag, std::tuple<signed_block_ptr, block_id_type, signed_block_header, uint32_t>>;
using irreversible_block = channel_decl<struct irreversible_block_tag, block_state_legacy_ptr>;
using applied_transaction = channel_decl<struct applied_transaction_tag, transaction_trace_ptr>;
}
+16 -16
View File
@@ -194,9 +194,9 @@ namespace eosio::chain_apis {
key_bimap.right.erase(key_range.first, key_range.second);
}
bool is_rollback_required( const chain::block_state_legacy_ptr& bsp ) const {
bool is_rollback_required( const chain::signed_block_ptr block ) const {
std::shared_lock read_lock(rw_mutex);
const auto bnum = bsp->block->block_num();
const auto bnum = block->block_num();
const auto& index = permission_info_index.get<by_last_updated_height>();
if (index.empty()) {
@@ -233,8 +233,8 @@ namespace eosio::chain_apis {
* at the HEAD state of the chain.
* @param bsp - the block to rollback before
*/
void rollback_to_before( const chain::block_state_legacy_ptr& bsp ) {
const auto bnum = bsp->block->block_num();
void rollback_to_before( const chain::signed_block_ptr block, const chain::signed_block_header& header, uint32_t block_num ) {
const auto bnum = block->block_num();
auto& index = permission_info_index.get<by_last_updated_height>();
const auto& permission_by_owner = controller.db().get_index<chain::permission_index>().indices().get<chain::by_owner>();
@@ -265,8 +265,8 @@ namespace eosio::chain_apis {
} else {
const auto& po = *itr;
uint32_t last_updated_height = chain::block_timestamp_type(po.last_updated) == bsp->header.timestamp ?
bsp->block_num : last_updated_time_to_height(po.last_updated);
uint32_t last_updated_height = chain::block_timestamp_type(po.last_updated) == header.timestamp ?
block_num : last_updated_time_to_height(po.last_updated);
index.modify(index.iterator_to(pi), [&po, last_updated_height](auto& mutable_pi) {
mutable_pi.last_updated_height = last_updated_height;
@@ -305,7 +305,7 @@ namespace eosio::chain_apis {
* the thread-safe data set
* @param bsp
*/
auto commit_block_prelock( const chain::block_state_legacy_ptr& bsp ) const {
auto commit_block_prelock( const chain::signed_block_ptr block ) const {
permission_set_t updated;
permission_set_t deleted;
@@ -338,7 +338,7 @@ namespace eosio::chain_apis {
if( onblock_trace )
process_trace(*onblock_trace);
for( const auto& r : bsp->block->transactions ) {
for( const auto& r : block->transactions ) {
chain::transaction_id_type id;
if( std::holds_alternative<chain::transaction_id_type>(r.trx)) {
id = std::get<chain::transaction_id_type>(r.trx);
@@ -352,7 +352,7 @@ namespace eosio::chain_apis {
}
}
return std::make_tuple(std::move(updated), std::move(deleted), is_rollback_required(bsp));
return std::make_tuple(std::move(updated), std::move(deleted), is_rollback_required(block));
}
/**
@@ -360,23 +360,23 @@ namespace eosio::chain_apis {
* transaction traces need to be in the cache prior to this call
* @param bsp
*/
void commit_block(const chain::block_state_legacy_ptr& bsp ) {
void commit_block(const chain::signed_block_ptr& block, const chain::signed_block_header& header, uint32_t block_num ) {
permission_set_t updated;
permission_set_t deleted;
bool rollback_required = false;
std::tie(updated, deleted, rollback_required) = commit_block_prelock(bsp);
std::tie(updated, deleted, rollback_required) = commit_block_prelock(block);
// optimistic skip of locking section if there is nothing to do
if (!updated.empty() || !deleted.empty() || rollback_required) {
std::unique_lock write_lock(rw_mutex);
rollback_to_before(bsp);
rollback_to_before(block, header, block_num);
// insert this blocks time into the time map
time_to_block_num.emplace(bsp->header.timestamp, bsp->block_num);
time_to_block_num.emplace(header.timestamp, block_num);
const auto bnum = bsp->block_num;
const auto bnum = block_num;
auto& index = permission_info_index.get<by_owner_name>();
const auto& permission_by_owner = controller.db().get_index<chain::permission_index>().indices().get<chain::by_owner>();
@@ -520,9 +520,9 @@ namespace eosio::chain_apis {
} FC_LOG_AND_DROP(("ACCOUNT DB cache_transaction_trace ERROR"));
}
void account_query_db::commit_block(const chain::block_state_legacy_ptr& block ) {
void account_query_db::commit_block( const chain::signed_block_ptr& block, const chain::signed_block_header& header, uint32_t block_num ) {
try {
_impl->commit_block(block);
_impl->commit_block(block, header, block_num);
} FC_LOG_AND_DROP(("ACCOUNT DB commit_block ERROR"));
}
+6 -5
View File
@@ -1018,20 +1018,21 @@ void chain_plugin_impl::plugin_initialize(const variables_map& options) {
accepted_block_header_channel.publish( priority::medium, t );
} );
accepted_block_connection = chain->accepted_block.connect( [this]( const block_state_legacy_ptr& blk ) {
accepted_block_connection = chain->accepted_block.connect( [this]( std::tuple<const signed_block_ptr&, const block_id_type&, const signed_block_header&, uint32_t> t ) {
const auto& [ block, id, header, block_num ] = t;
if (_account_query_db) {
_account_query_db->commit_block(blk);
_account_query_db->commit_block(block, header, block_num);
}
if (_trx_retry_db) {
_trx_retry_db->on_accepted_block(blk);
_trx_retry_db->on_accepted_block(block_num);
}
if (_trx_finality_status_processing) {
_trx_finality_status_processing->signal_accepted_block(blk);
_trx_finality_status_processing->signal_accepted_block(block, id);
}
accepted_block_channel.publish( priority::high, blk );
accepted_block_channel.publish( priority::high, t );
} );
irreversible_block_connection = chain->irreversible_block.connect( [this]( const block_state_legacy_ptr& blk ) {
@@ -40,7 +40,7 @@ namespace eosio::chain_apis {
* uncommitted traces.
* @param block
*/
void commit_block(const chain::block_state_legacy_ptr& block );
void commit_block( const chain::signed_block_ptr& block, const chain::signed_block_header& header, uint32_t block_num );
/**
* parameters for the get_accounts_by_authorizers RPC
@@ -42,7 +42,7 @@ namespace eosio::chain_apis {
void signal_applied_transaction( const chain::transaction_trace_ptr& trace, const chain::packed_transaction_ptr& ptrx );
void signal_accepted_block( const chain::block_state_legacy_ptr& bsp );
void signal_accepted_block( const chain::signed_block_ptr& block, const chain::block_id_type& id );
void signal_irreversible_block( const chain::block_state_legacy_ptr& bsp );
@@ -64,7 +64,7 @@ public:
/**
* Attach to chain accepted_block signal
*/
void on_accepted_block(const chain::block_state_legacy_ptr& block );
void on_accepted_block( uint32_t block_num );
/**
* Attach to chain irreversible_block signal
@@ -2,7 +2,6 @@
#include <eosio/chain/permission_object.hpp>
#include <eosio/testing/tester.hpp>
#include <eosio/chain/types.hpp>
#include <eosio/chain/block_state_legacy.hpp>
#include <eosio/chain_plugin/account_query_db.hpp>
#include <eosio/chain/thread_utils.hpp>
@@ -38,8 +37,9 @@ BOOST_FIXTURE_TEST_CASE(newaccount_test, validating_tester) { try {
auto aq_db = account_query_db(*control);
//link aq_db to the `accepted_block` signal on the controller
auto c2 = control->accepted_block.connect([&](const block_state_legacy_ptr& blk) {
aq_db.commit_block( blk);
auto c2 = control->accepted_block.connect([&](std::tuple<const signed_block_ptr&, const block_id_type&, const signed_block_header&, uint32_t> t) {
const auto& [ block, id, header, block_num ] = t;
aq_db.commit_block( block, header, block_num );
});
produce_blocks(10);
@@ -63,8 +63,9 @@ BOOST_FIXTURE_TEST_CASE(updateauth_test, validating_tester) { try {
auto aq_db = account_query_db(*control);
//link aq_db to the `accepted_block` signal on the controller
auto c = control->accepted_block.connect([&](const block_state_legacy_ptr& blk) {
aq_db.commit_block( blk);
auto c = control->accepted_block.connect([&](std::tuple<const signed_block_ptr&, const block_id_type&, const signed_block_header&, uint32_t> t) {
const auto& [ block, id, header, block_num ] = t;
aq_db.commit_block( block, header, block_num );
});
produce_blocks(10);
@@ -97,8 +98,9 @@ BOOST_FIXTURE_TEST_CASE(updateauth_test_multi_threaded, validating_tester) { try
auto aq_db = account_query_db(*control);
//link aq_db to the `accepted_block` signal on the controller
auto c = control->accepted_block.connect([&](const block_state_legacy_ptr& blk) {
aq_db.commit_block( blk);
auto c = control->accepted_block.connect([&](std::tuple<const signed_block_ptr&, const block_id_type&, const signed_block_header&, uint32_t> t) {
const auto& [ block, id, header, block_num ] = t;
aq_db.commit_block( block, header, block_num );
});
produce_blocks(10);
@@ -149,8 +151,9 @@ BOOST_AUTO_TEST_CASE(future_fork_test) { try {
auto aq_db = account_query_db(*node_a.control);
//link aq_db to the `accepted_block` signal on the controller
auto c = node_a.control->accepted_block.connect([&](const block_state_legacy_ptr& blk) {
aq_db.commit_block( blk);
auto c = node_a.control->accepted_block.connect([&](std::tuple<const signed_block_ptr&, const block_id_type&, const signed_block_header&, uint32_t> t) {
const auto& [ block, id, header, block_num ] = t;
aq_db.commit_block( block, header, block_num );
});
// create 10 blocks synced
@@ -196,8 +199,9 @@ BOOST_AUTO_TEST_CASE(fork_test) { try {
auto aq_db = account_query_db(*node_a.control);
//link aq_db to the `accepted_block` signal on the controller
auto c = node_a.control->accepted_block.connect([&](const block_state_legacy_ptr& blk) {
aq_db.commit_block( blk);
auto c = node_a.control->accepted_block.connect([&](std::tuple<const signed_block_ptr&, const block_id_type&, const signed_block_header&, uint32_t> t) {
const auto& [ block, id, header, block_num ] = t;
aq_db.commit_block( block, header, block_num );
});
// create 10 blocks synced
@@ -254,7 +254,7 @@ BOOST_AUTO_TEST_CASE(trx_finality_status_logic) { try {
const auto block_20_time = set_now("2022-04-04", "04:44:44.500");
add(trx_pairs_20, bs_20);
add(trx_pairs_20, bs_20);
status.signal_accepted_block(bs_20);
status.signal_accepted_block(bs_20->block, bs_20->id);
cs = status.get_chain_state();
@@ -321,7 +321,7 @@ BOOST_AUTO_TEST_CASE(trx_finality_status_logic) { try {
fc::logger::get(DEFAULT_LOGGER).set_log_level(fc::log_level::debug);
add(trx_pairs_21, bs_21);
status.signal_accepted_block(bs_21);
status.signal_accepted_block(bs_21->block, bs_21->id);
cs = status.get_chain_state();
BOOST_CHECK(cs.head_id == bs_21->id);
@@ -390,7 +390,7 @@ BOOST_AUTO_TEST_CASE(trx_finality_status_logic) { try {
status.signal_block_start(bn);
add(trx_pairs_22, bs_22);
status.signal_accepted_block(bs_22);
status.signal_accepted_block(bs_22->block, bs_22->id);
cs = status.get_chain_state();
BOOST_CHECK(cs.head_id == bs_22->id);
@@ -468,7 +468,7 @@ BOOST_AUTO_TEST_CASE(trx_finality_status_logic) { try {
status.signal_block_start(bn);
add(trx_pairs_22_alt, bs_22_alt);
status.signal_accepted_block(bs_22_alt);
status.signal_accepted_block(bs_22_alt->block, bs_22_alt->id);
cs = status.get_chain_state();
BOOST_CHECK(cs.head_id == bs_22_alt->id);
@@ -553,7 +553,7 @@ BOOST_AUTO_TEST_CASE(trx_finality_status_logic) { try {
status.signal_block_start(bn);
add(trx_pairs_19, bs_19);
status.signal_accepted_block(bs_19);
status.signal_accepted_block(bs_19->block, bs_19->id);
cs = status.get_chain_state();
BOOST_CHECK(cs.head_id == bs_19->id);
@@ -661,7 +661,7 @@ BOOST_AUTO_TEST_CASE(trx_finality_status_logic) { try {
status.signal_applied_transaction(trace, txn);
}
status.signal_accepted_block(bs_19_alt);
status.signal_accepted_block(bs_19_alt->block, bs_19_alt->id);
cs = status.get_chain_state();
BOOST_CHECK(cs.head_id == bs_19_alt->id);
@@ -898,7 +898,7 @@ namespace {
status.signal_applied_transaction(trace, txn);
}
status.signal_accepted_block(bs);
status.signal_accepted_block(bs->block, bs->id);
}
void send_spec_block() {
+25 -25
View File
@@ -276,7 +276,7 @@ BOOST_AUTO_TEST_CASE(trx_retry_logic) {
// signal block, nothing should be expired as now has not changed
auto bsp1 = make_block_state(1, {});
trx_retry.on_block_start(1);
trx_retry.on_accepted_block(bsp1);
trx_retry.on_accepted_block(bsp1->block_num);
trx_retry.on_irreversible_block(bsp1);
BOOST_CHECK(!trx_1_expired);
BOOST_CHECK(!trx_2_expired);
@@ -286,7 +286,7 @@ BOOST_AUTO_TEST_CASE(trx_retry_logic) {
// signal block, first transaction should expire
auto bsp2 = make_block_state(2, {});
trx_retry.on_block_start(2);
trx_retry.on_accepted_block(bsp2);
trx_retry.on_accepted_block(bsp2->block_num);
trx_retry.on_irreversible_block(bsp2);
BOOST_CHECK(trx_1_expired);
BOOST_CHECK(!trx_2_expired);
@@ -296,7 +296,7 @@ BOOST_AUTO_TEST_CASE(trx_retry_logic) {
// signal block, second transaction should expire
auto bsp3 = make_block_state(3, {});
trx_retry.on_block_start(3);
trx_retry.on_accepted_block(bsp3);
trx_retry.on_accepted_block(bsp3->block_num);
trx_retry.on_irreversible_block(bsp3);
BOOST_CHECK(trx_1_expired);
BOOST_CHECK(trx_2_expired);
@@ -328,7 +328,7 @@ BOOST_AUTO_TEST_CASE(trx_retry_logic) {
// signal block, transaction 3 should be sent
auto bsp4 = make_block_state(4, {});
trx_retry.on_block_start(4);
trx_retry.on_accepted_block(bsp4);
trx_retry.on_accepted_block(bsp4->block_num);
BOOST_CHECK( get_id(transactions_acked.pop().second) == 3 );
BOOST_CHECK_EQUAL( 0u, transactions_acked.size() );
// increase time by 1 seconds, so trx_4 is sent
@@ -337,7 +337,7 @@ BOOST_AUTO_TEST_CASE(trx_retry_logic) {
// signal block, transaction 4 should be sent
auto bsp5 = make_block_state(5, {});
trx_retry.on_block_start(5);
trx_retry.on_accepted_block(bsp5);
trx_retry.on_accepted_block(bsp5->block_num);
BOOST_CHECK( get_id(transactions_acked.pop().second) == 4 );
BOOST_CHECK_EQUAL( 0u, transactions_acked.size() );
BOOST_CHECK(!trx_3_expired);
@@ -347,7 +347,7 @@ BOOST_AUTO_TEST_CASE(trx_retry_logic) {
fc::mock_time_traits::set_now(pnow);
auto bsp6 = make_block_state(6, {});
trx_retry.on_block_start(6);
trx_retry.on_accepted_block(bsp6);
trx_retry.on_accepted_block(bsp6->block_num);
trx_retry.on_irreversible_block(bsp4);
trx_retry.on_irreversible_block(bsp5);
trx_retry.on_irreversible_block(bsp6);
@@ -378,7 +378,7 @@ BOOST_AUTO_TEST_CASE(trx_retry_logic) {
// not in block 7, so not returned to user
auto bsp7 = make_block_state(7, {});
trx_retry.on_block_start(7);
trx_retry.on_accepted_block(bsp7);
trx_retry.on_accepted_block(bsp7->block_num);
BOOST_CHECK(!trx_5_variant);
BOOST_CHECK(!trx_6_variant);
// 5,6 in block 8
@@ -390,7 +390,7 @@ BOOST_AUTO_TEST_CASE(trx_retry_logic) {
trx_retry.on_applied_transaction(trace_5, trx_5);
trx_retry.on_applied_transaction(trace_6, trx_6);
auto bsp8 = make_block_state(8, {trx_5, trx_6});
trx_retry.on_accepted_block(bsp8);
trx_retry.on_accepted_block(bsp8->block_num);
BOOST_CHECK(!trx_5_variant);
BOOST_CHECK(!trx_6_variant);
// need 2 blocks before 6 returned to user
@@ -398,14 +398,14 @@ BOOST_AUTO_TEST_CASE(trx_retry_logic) {
fc::mock_time_traits::set_now(pnow);
auto bsp9 = make_block_state(9, {});
trx_retry.on_block_start(9);
trx_retry.on_accepted_block(bsp9);
trx_retry.on_accepted_block(bsp9->block_num);
BOOST_CHECK(!trx_5_variant);
BOOST_CHECK(!trx_6_variant);
pnow += boost::posix_time::seconds(1); // new block, new time
fc::mock_time_traits::set_now(pnow);
auto bsp10 = make_block_state(10, {});
trx_retry.on_block_start(10);
trx_retry.on_accepted_block(bsp10);
trx_retry.on_accepted_block(bsp10->block_num);
BOOST_CHECK(!trx_5_variant);
BOOST_CHECK(trx_6_variant);
// now signal lib for trx_6
@@ -413,7 +413,7 @@ BOOST_AUTO_TEST_CASE(trx_retry_logic) {
fc::mock_time_traits::set_now(pnow);
auto bsp11 = make_block_state(11, {});
trx_retry.on_block_start(11);
trx_retry.on_accepted_block(bsp11);
trx_retry.on_accepted_block(bsp11->block_num);
BOOST_CHECK(!trx_5_variant);
BOOST_CHECK(trx_6_variant);
trx_retry.on_irreversible_block(bsp7);
@@ -456,7 +456,7 @@ BOOST_AUTO_TEST_CASE(trx_retry_logic) {
// not in block 12
auto bsp12 = make_block_state(12, {});
trx_retry.on_block_start(12);
trx_retry.on_accepted_block(bsp12);
trx_retry.on_accepted_block(bsp12->block_num);
BOOST_CHECK(!trx_7_variant);
BOOST_CHECK(!trx_8_variant);
BOOST_CHECK(!trx_9_expired);
@@ -471,7 +471,7 @@ BOOST_AUTO_TEST_CASE(trx_retry_logic) {
trx_retry.on_applied_transaction(trace_8, trx_8);
trx_retry.on_applied_transaction(trace_9, trx_9);
auto bsp13 = make_block_state(13, {trx_7, trx_8, trx_9});
trx_retry.on_accepted_block(bsp13);
trx_retry.on_accepted_block(bsp13->block_num);
BOOST_CHECK(!trx_7_variant);
BOOST_CHECK(!trx_8_variant);
BOOST_CHECK(!trx_9_expired);
@@ -480,7 +480,7 @@ BOOST_AUTO_TEST_CASE(trx_retry_logic) {
fc::mock_time_traits::set_now(pnow);
auto bsp14 = make_block_state(14, {});
trx_retry.on_block_start(14);
trx_retry.on_accepted_block(bsp14);
trx_retry.on_accepted_block(bsp14->block_num);
BOOST_CHECK(!trx_7_variant);
BOOST_CHECK(!trx_8_variant);
BOOST_CHECK(!trx_9_expired);
@@ -488,7 +488,7 @@ BOOST_AUTO_TEST_CASE(trx_retry_logic) {
fc::mock_time_traits::set_now(pnow);
auto bsp15 = make_block_state(15, {});
trx_retry.on_block_start(15);
trx_retry.on_accepted_block(bsp15);
trx_retry.on_accepted_block(bsp15->block_num);
BOOST_CHECK(!trx_7_variant);
BOOST_CHECK(!trx_8_variant);
BOOST_CHECK(!trx_9_expired);
@@ -500,14 +500,14 @@ BOOST_AUTO_TEST_CASE(trx_retry_logic) {
BOOST_CHECK_EQUAL(3u, trx_retry.size());
// now produce an empty 13
auto bsp13b = make_block_state(13, {}); // now 13 has no traces
trx_retry.on_accepted_block(bsp13b);
trx_retry.on_accepted_block(bsp13b->block_num);
// produced another empty block
pnow += boost::posix_time::seconds(1); // new block, new time
fc::mock_time_traits::set_now(pnow);
trx_retry.on_block_start(14);
// now produce an empty 14
auto bsp14b = make_block_state(14, {}); // empty
trx_retry.on_accepted_block(bsp14b);
trx_retry.on_accepted_block(bsp14b->block_num);
// produce block with 7,8
trx_retry.on_block_start(15);
auto trace_7b = make_transaction_trace( trx_7, 15);
@@ -515,13 +515,13 @@ BOOST_AUTO_TEST_CASE(trx_retry_logic) {
trx_retry.on_applied_transaction(trace_7b, trx_7);
trx_retry.on_applied_transaction(trace_8b, trx_8);
auto bsp15b = make_block_state(15, {trx_7, trx_8});
trx_retry.on_accepted_block(bsp15b);
trx_retry.on_accepted_block(bsp15b->block_num);
// need 3 blocks before 8 returned to user
pnow += boost::posix_time::seconds(1); // new block, new time
fc::mock_time_traits::set_now(pnow);
auto bsp16 = make_block_state(16, {});
trx_retry.on_block_start(16);
trx_retry.on_accepted_block(bsp16);
trx_retry.on_accepted_block(bsp16->block_num);
BOOST_CHECK(!trx_7_variant);
BOOST_CHECK(!trx_8_variant);
BOOST_CHECK(!trx_9_expired);
@@ -529,7 +529,7 @@ BOOST_AUTO_TEST_CASE(trx_retry_logic) {
fc::mock_time_traits::set_now(pnow);
auto bsp17 = make_block_state(17, {});
trx_retry.on_block_start(17);
trx_retry.on_accepted_block(bsp17);
trx_retry.on_accepted_block(bsp17->block_num);
BOOST_CHECK(!trx_7_variant);
BOOST_CHECK(!trx_8_variant);
BOOST_CHECK(!trx_9_expired);
@@ -537,7 +537,7 @@ BOOST_AUTO_TEST_CASE(trx_retry_logic) {
fc::mock_time_traits::set_now(pnow);
auto bsp18 = make_block_state(18, {});
trx_retry.on_block_start(18);
trx_retry.on_accepted_block(bsp18);
trx_retry.on_accepted_block(bsp18->block_num);
BOOST_CHECK(!trx_7_variant);
BOOST_CHECK(trx_8_variant);
BOOST_CHECK(!trx_9_expired);
@@ -559,7 +559,7 @@ BOOST_AUTO_TEST_CASE(trx_retry_logic) {
fc::mock_time_traits::set_now(pnow);
auto bsp19 = make_block_state(19, {});
trx_retry.on_block_start(19);
trx_retry.on_accepted_block(bsp19);
trx_retry.on_accepted_block(bsp19->block_num);
trx_retry.on_irreversible_block(bsp15);
trx_retry.on_irreversible_block(bsp16);
trx_retry.on_irreversible_block(bsp17);
@@ -572,7 +572,7 @@ BOOST_AUTO_TEST_CASE(trx_retry_logic) {
fc::mock_time_traits::set_now(pnow);
auto bsp20 = make_block_state(20, {});
trx_retry.on_block_start(20);
trx_retry.on_accepted_block(bsp20);
trx_retry.on_accepted_block(bsp20->block_num);
// waits for LIB
BOOST_CHECK(trx_7_variant);
BOOST_CHECK(trx_8_variant);
@@ -607,14 +607,14 @@ BOOST_AUTO_TEST_CASE(trx_retry_logic) {
trx_retry.on_applied_transaction(trace_10, trx_10);
trx_retry.on_applied_transaction(trace_11, trx_11);
auto bsp21 = make_block_state(21, {trx_10, trx_11});
trx_retry.on_accepted_block(bsp21);
trx_retry.on_accepted_block(bsp21->block_num);
BOOST_CHECK(trx_10_variant);
BOOST_CHECK(!trx_11_variant);
pnow += boost::posix_time::seconds(1); // new block, new time
fc::mock_time_traits::set_now(pnow);
auto bsp22 = make_block_state(22, {});
trx_retry.on_block_start(22);
trx_retry.on_accepted_block(bsp22);
trx_retry.on_accepted_block(bsp22->block_num);
BOOST_CHECK(trx_10_variant);
BOOST_CHECK(trx_11_variant);
BOOST_CHECK_EQUAL(0u, trx_retry.size());
@@ -15,7 +15,7 @@ namespace eosio::chain_apis {
void signal_applied_transaction( const chain::transaction_trace_ptr& trace, const chain::packed_transaction_ptr& ptrx );
void signal_accepted_block( const chain::block_state_legacy_ptr& bsp );
void signal_accepted_block( const chain::signed_block_ptr& block, const chain::block_id_type& id );
void handle_rollback();
@@ -67,9 +67,9 @@ namespace eosio::chain_apis {
} FC_LOG_AND_DROP(("Failed to signal applied transaction for finality status"));
}
void trx_finality_status_processing::signal_accepted_block( const chain::block_state_legacy_ptr& bsp ) {
void trx_finality_status_processing::signal_accepted_block( const chain::signed_block_ptr& block, const chain::block_id_type& id ) {
try {
_my->signal_accepted_block(bsp);
_my->signal_accepted_block(block, id);
} FC_LOG_AND_DROP(("Failed to signal accepted block for finality status"));
}
@@ -139,14 +139,14 @@ namespace eosio::chain_apis {
}
}
void trx_finality_status_processing_impl::signal_accepted_block( const chain::block_state_legacy_ptr& bsp ) {
void trx_finality_status_processing_impl::signal_accepted_block( const chain::signed_block_ptr& block, const chain::block_id_type& id ) {
// if this block had any transactions, then we have processed everything we need to already
if (bsp->id == _head_block_id) {
if (id == _head_block_id) {
return;
}
_head_block_id = bsp->id;
_head_block_timestamp = bsp->block->timestamp;
_head_block_id = id;
_head_block_timestamp = block->timestamp;
const auto head_block_num = chain::block_header::num_from_id(_head_block_id);
if (head_block_num <= _last_proc_block_num) {
+5 -5
View File
@@ -161,13 +161,13 @@ struct trx_retry_db_impl {
rollback_to( block_num );
}
void on_accepted_block(const chain::block_state_legacy_ptr& bsp ) {
void on_accepted_block( uint32_t block_num ) {
// good time to perform processing
ack_ready_trxs_by_block_num( bsp->block_num );
ack_ready_trxs_by_block_num( block_num );
retry_trxs();
}
void on_irreversible_block(const chain::block_state_legacy_ptr& bsp ) {
void on_irreversible_block( const chain::block_state_legacy_ptr& bsp ) {
ack_ready_trxs_by_lib( bsp->block_num );
clear_expired( bsp->block->timestamp );
}
@@ -321,9 +321,9 @@ void trx_retry_db::on_block_start( uint32_t block_num ) {
} FC_LOG_AND_DROP(("trx retry block_start ERROR"));
}
void trx_retry_db::on_accepted_block(const chain::block_state_legacy_ptr& block ) {
void trx_retry_db::on_accepted_block( uint32_t block_num ) {
try {
_impl->on_accepted_block(block);
_impl->on_accepted_block(block_num);
} FC_LOG_AND_DROP(("trx retry accepted_block ERROR"));
}
+4 -4
View File
@@ -529,7 +529,7 @@ namespace eosio {
uint32_t get_chain_head_num() const;
void on_accepted_block_header( const signed_block_ptr& block, const block_id_type& id );
void on_accepted_block( const block_state_legacy_ptr& bs );
void on_accepted_block();
void transaction_ack(const std::pair<fc::exception_ptr, packed_transaction_ptr>&);
void on_irreversible_block( const block_state_legacy_ptr& block );
@@ -3891,7 +3891,7 @@ namespace eosio {
});
}
void net_plugin_impl::on_accepted_block(const block_state_legacy_ptr& ) {
void net_plugin_impl::on_accepted_block() {
on_pending_schedule(chain_plug->chain().pending_producers());
on_active_schedule(chain_plug->chain().active_producers());
}
@@ -4288,8 +4288,8 @@ namespace eosio {
my->on_accepted_block_header( std::get<0>(t), std::get<1>(t) );
} );
cc.accepted_block.connect( [my = shared_from_this()]( const block_state_legacy_ptr& s ) {
my->on_accepted_block( s );
cc.accepted_block.connect( [my = shared_from_this()]( std::tuple<const signed_block_ptr&, const block_id_type&, const signed_block_header&, uint32_t> t ) {
my->on_accepted_block();
} );
cc.irreversible_block.connect( [my = shared_from_this()]( const block_state_legacy_ptr& s ) {
my->on_irreversible_block( s );
+7 -4
View File
@@ -620,11 +620,11 @@ public:
((_produce_block_cpu_effort.count() / 1000) * config::producer_repetitions) );
}
void on_block(const block_state_legacy_ptr& bsp) {
void on_block(const signed_block_ptr& block) {
auto& chain = chain_plug->chain();
auto before = _unapplied_transactions.size();
_unapplied_transactions.clear_applied(bsp);
chain.get_mutable_subjective_billing().on_block(_log, bsp, fc::time_point::now());
_unapplied_transactions.clear_applied(block);
chain.get_mutable_subjective_billing().on_block(_log, block, fc::time_point::now());
if (before > 0) {
fc_dlog(_log, "Removed applied transactions before: ${before}, after: ${after}", ("before", before)("after", _unapplied_transactions.size()));
}
@@ -1329,7 +1329,10 @@ void producer_plugin_impl::plugin_startup() {
EOS_ASSERT(_producers.empty() || chain_plug->accept_transactions(), plugin_config_exception,
"node cannot have any producer-name configured because no block production is possible with no [api|p2p]-accepted-transactions");
_accepted_block_connection.emplace(chain.accepted_block.connect([this](const auto& bsp) { on_block(bsp); }));
_accepted_block_connection.emplace(chain.accepted_block.connect([this](std::tuple<const signed_block_ptr&, const block_id_type&, const signed_block_header&, uint32_t> t) {
const auto& [ block, id, header, block_num ] = t;
on_block(block);
}));
_accepted_block_header_connection.emplace(chain.accepted_block_header.connect([this](std::tuple<const signed_block_ptr&, const block_id_type&, const account_name&> t) {
const auto& block = std::get<0>(t);
const auto& id = std::get<1>(t);
@@ -68,15 +68,15 @@ auto make_unique_trx( const chain_id_type& chain_id ) {
}
// verify all trxs are in blocks only once
bool verify_equal( const std::deque<packed_transaction_ptr>& trxs, const std::deque<block_state_legacy_ptr>& all_blocks) {
bool verify_equal( const std::deque<packed_transaction_ptr>& trxs, const std::deque<signed_block_ptr>& all_blocks) {
std::set<transaction_id_type> trxs_ids; // trx can appear more than once if they were aborted
std::set<transaction_id_type> blk_trxs_ids;
for( const auto& trx : trxs ) {
trxs_ids.emplace( trx->id() );
}
for( const auto& bs : all_blocks ) {
for( const auto& trx_receipt : bs->block->transactions ) {
for( const auto& block : all_blocks ) {
for( const auto& trx_receipt : block->transactions ) {
const auto& trx = std::get<packed_transaction>( trx_receipt.trx ).get_transaction();
blk_trxs_ids.emplace( trx.id() );
}
@@ -126,13 +126,14 @@ BOOST_AUTO_TEST_CASE(producer) {
auto[prod_plug, chain_plug] = plugin_fut.get();
auto chain_id = chain_plug->get_chain_id();
std::deque<block_state_legacy_ptr> all_blocks;
std::deque<signed_block_ptr> all_blocks;
std::promise<void> empty_blocks_promise;
std::future<void> empty_blocks_fut = empty_blocks_promise.get_future();
auto ab = chain_plug->chain().accepted_block.connect( [&](const block_state_legacy_ptr& bsp) {
auto ab = chain_plug->chain().accepted_block.connect( [&](std::tuple<const signed_block_ptr&, const block_id_type&, const signed_block_header&, uint32_t> t) {
const auto& [ block, id, header, block_num ] = t;
static int num_empty = std::numeric_limits<int>::max();
all_blocks.push_back( bsp );
if( bsp->block->transactions.empty() ) {
all_blocks.push_back( block );
if( block->transactions.empty() ) {
--num_empty;
if( num_empty == 0 ) empty_blocks_promise.set_value();
} else { // we want a few empty blocks after we have some non-empty blocks
@@ -26,7 +26,7 @@ struct send_queue_entry_base {
struct session_base {
virtual void send_update(bool changed) = 0;
virtual void send_update(const eosio::chain::block_state_legacy_ptr& block_state) = 0;
virtual void send_update(const chain::signed_block_ptr& block, const chain::block_id_type& id, uint32_t block_num) = 0;
virtual ~session_base() = default;
std::optional<state_history::get_blocks_request_v0> current_request;
@@ -35,15 +35,19 @@ struct session_base {
class send_update_send_queue_entry : public send_queue_entry_base {
std::shared_ptr<session_base> session;
const chain::block_state_legacy_ptr block_state;
const chain::signed_block_ptr block;
const chain::block_id_type id;
uint32_t block_num;
public:
send_update_send_queue_entry(std::shared_ptr<session_base> s, chain::block_state_legacy_ptr block_state)
send_update_send_queue_entry(std::shared_ptr<session_base> s, chain::signed_block_ptr block, chain::block_id_type id, uint32_t block_num)
: session(std::move(s))
, block_state(std::move(block_state)){}
, block(std::move(block))
, id(std::move(id))
, block_num(block_num){}
void send_entry() override {
if( block_state ) {
session->send_update(block_state);
if( block) {
session->send_update(block, id, block_num);
} else {
session->send_update(false);
}
@@ -118,14 +122,14 @@ public:
void send_updates() {
for( auto& s : session_set ) {
if (s->need_to_send_update ) {
add_send_queue(s, std::make_unique<send_update_send_queue_entry>(s, nullptr));
add_send_queue(s, std::make_unique<send_update_send_queue_entry>(s, nullptr, chain::block_id_type{}, 0));
}
}
}
void send_update(const chain::block_state_legacy_ptr& block_state) {
void send_update(const chain::signed_block_ptr& block, const chain::block_id_type& id, uint32_t block_num) {
for( auto& s : session_set ) {
add_send_queue(s, std::make_unique<send_update_send_queue_entry>(s, block_state));
add_send_queue(s, std::make_unique<send_update_send_queue_entry>(s, block, id, block_num));
}
}
@@ -481,7 +485,7 @@ private:
current_request = std::move(req);
}
void send_update(state_history::get_blocks_result_v0 result, const chain::block_state_legacy_ptr& block_state) {
void send_update(state_history::get_blocks_result_v0 result, const chain::signed_block_ptr& block, const chain::block_id_type& id, uint32_t block_num) {
need_to_send_update = true;
if (!current_request || !current_request->max_messages_in_flight) {
session_mgr.pop_entry(false);
@@ -502,7 +506,7 @@ private:
// not just an optimization, on accepted_block signal may not be able to find block_num in forkdb as it has not been validated
// until after the accepted_block signal
std::optional<chain::block_id_type> block_id =
(block_state && block_state->block_num == to_send_block_num) ? block_state->id : plugin.get_block_id(to_send_block_num);
(block_num == to_send_block_num) ? id : plugin.get_block_id(to_send_block_num);
if (block_id && position_it && (*position_it)->block_num == to_send_block_num) {
// This branch happens when the head block of nodeos is behind the head block of connecting client.
@@ -527,7 +531,7 @@ private:
if (prev_block_id)
result.prev_block = state_history::block_position{to_send_block_num - 1, *prev_block_id};
if (current_request->fetch_block)
plugin.get_block(to_send_block_num, block_state, result.block);
plugin.get_block(to_send_block_num, block_num, block, result.block);
if (current_request->fetch_traces && plugin.get_trace_log())
result.traces.emplace();
if (current_request->fetch_deltas && plugin.get_chain_state_log())
@@ -553,23 +557,23 @@ private:
std::make_shared<blocks_result_send_queue_entry<session>>(this->shared_from_this(), std::move(result))->send_entry();
}
void send_update(const chain::block_state_legacy_ptr& block_state) override {
void send_update(const chain::signed_block_ptr& block, const chain::block_id_type& id, uint32_t block_num) override {
if (!current_request || !current_request->max_messages_in_flight) {
session_mgr.pop_entry(false);
return;
}
state_history::get_blocks_result_v0 result;
result.head = {block_state->block_num, block_state->id};
to_send_block_num = std::min(block_state->block_num, to_send_block_num);
send_update(std::move(result), block_state);
result.head = {block_num, id};
to_send_block_num = std::min(block_num, to_send_block_num);
send_update(std::move(result), block, id, block_num);
}
void send_update(bool changed) override {
if (changed || need_to_send_update) {
state_history::get_blocks_result_v0 result;
result.head = plugin.get_block_head();
send_update(std::move(result), {});
send_update(std::move(result), nullptr, chain::block_id_type{}, 0);
} else {
session_mgr.pop_entry(false);
}
@@ -88,11 +88,11 @@ public:
boost::asio::io_context& get_ship_executor() { return thread_pool.get_executor(); }
// thread-safe
signed_block_ptr get_block(uint32_t block_num, const block_state_legacy_ptr& block_state) const {
signed_block_ptr get_block(uint32_t block_num, uint32_t block_state_block_num, const signed_block_ptr& block) const {
chain::signed_block_ptr p;
try {
if (block_state && block_num == block_state->block_num) {
p = block_state->block;
if (block_num == block_state_block_num) {
p = block;
} else {
p = chain_plug->chain().fetch_block_by_number(block_num);
}
@@ -107,8 +107,8 @@ public:
}
// thread-safe
void get_block(uint32_t block_num, const block_state_legacy_ptr& block_state, std::optional<bytes>& result) const {
auto p = get_block(block_num, block_state);
void get_block(uint32_t block_num, uint32_t block_state_block_num, const signed_block_ptr& block, std::optional<bytes>& result) const {
auto p = get_block(block_num, block_state_block_num, block);
if (p)
result = fc::raw::pack(*p);
}
@@ -201,12 +201,12 @@ public:
}
// called from main thread
void on_accepted_block(const block_state_legacy_ptr& block_state) {
void on_accepted_block(const signed_block_ptr& block, const block_id_type& id, const signed_block_header& block_header, uint32_t block_num) {
update_current();
try {
store_traces(block_state);
store_chain_state(block_state);
store_traces(block, id);
store_chain_state(id, block_header, block_num);
} catch (const fc::exception& e) {
fc_elog(_log, "fc::exception: ${details}", ("details", e.to_detail_string()));
// Both app().quit() and exception throwing are required. Without app().quit(),
@@ -224,8 +224,8 @@ public:
// this is safe as there are no clients connected until after replay is complete
// this method is called from the main thread and "plugin_started" is set on the main thread as well when plugin is started
if (plugin_started) {
boost::asio::post(get_ship_executor(), [self = this->shared_from_this(), block_state]() {
self->get_session_manager().send_update(block_state);
boost::asio::post(get_ship_executor(), [self = this->shared_from_this(), block, id, block_num]() {
self->get_session_manager().send_update(block, id, block_num);
});
}
@@ -243,29 +243,29 @@ public:
}
// called from main thread
void store_traces(const block_state_legacy_ptr& block_state) {
void store_traces(const signed_block_ptr& block, const block_id_type& id) {
if (!trace_log)
return;
state_history_log_header header{.magic = ship_magic(ship_current_version, 0),
.block_id = block_state->id,
.block_id = id,
.payload_size = 0};
trace_log->pack_and_write_entry(header, block_state->block->previous, [this, &block_state](auto&& buf) {
trace_converter.pack(buf, trace_debug_mode, block_state);
trace_log->pack_and_write_entry(header, block->previous, [this, &block](auto&& buf) {
trace_converter.pack(buf, trace_debug_mode, block);
});
}
// called from main thread
void store_chain_state(const block_state_legacy_ptr& block_state) {
void store_chain_state(const block_id_type& id, const signed_block_header& block_header, uint32_t block_num) {
if (!chain_state_log)
return;
bool fresh = chain_state_log->empty();
if (fresh)
fc_ilog(_log, "Placing initial state in block ${n}", ("n", block_state->block_num));
fc_ilog(_log, "Placing initial state in block ${n}", ("n", block_num));
state_history_log_header header{
.magic = ship_magic(ship_current_version, 0), .block_id = block_state->id, .payload_size = 0};
chain_state_log->pack_and_write_entry(header, block_state->header.previous, [this, fresh](auto&& buf) {
.magic = ship_magic(ship_current_version, 0), .block_id = id, .payload_size = 0};
chain_state_log->pack_and_write_entry(header, block_header.previous, [this, fresh](auto&& buf) {
pack_deltas(buf, chain_plug->chain().db(), fresh);
});
} // store_chain_state
@@ -329,7 +329,10 @@ void state_history_plugin_impl::plugin_initialize(const variables_map& options)
on_applied_transaction(std::get<0>(t), std::get<1>(t));
}));
accepted_block_connection.emplace(
chain.accepted_block.connect([&](const block_state_legacy_ptr& p) { on_accepted_block(p); }));
chain.accepted_block.connect([&](std::tuple<const signed_block_ptr&, const block_id_type&, const signed_block_header&, uint32_t> t) {
const auto& [ block, id, header, block_num ] = t;
on_accepted_block(block, id, header, block_num);
}));
block_start_connection.emplace(
chain.block_start.connect([&](uint32_t block_num) { on_block_start(block_num); }));
@@ -406,7 +409,7 @@ void state_history_plugin_impl::plugin_startup() {
auto bsp = chain.head_block_state();
if( bsp && chain_state_log && chain_state_log->empty() ) {
fc_ilog( _log, "Storing initial state on startup, this can take a considerable amount of time" );
store_chain_state( bsp );
store_chain_state( bsp->id, bsp->header, bsp->block_num );
fc_ilog( _log, "Done storing initial state on startup" );
}
first_available_block = chain.earliest_available_block_num();
@@ -123,7 +123,7 @@ struct mock_state_history_plugin {
fc::logger& get_logger() { return logger; }
void get_block(uint32_t block_num, const eosio::chain::block_state_legacy_ptr& block_state,
void get_block(uint32_t block_num, uint32_t block_state_block_num, const eosio::chain::signed_block_ptr& block,
std::optional<eosio::chain::bytes>& result) const {
result.emplace().resize(16);
}
@@ -15,9 +15,9 @@ public:
void kill_on_head(account_name prod, uint32_t where_in_seq);
private:
void accepted_block(const chain::block_state_legacy_ptr& bsp);
void accepted_block(const chain::block_id_type& id);
void applied_irreversible_block(const chain::block_state_legacy_ptr& bsp);
void process_next_block_state_legacy(const chain::block_state_legacy_ptr& bsp);
void process_next_block_state_legacy(const chain::block_id_type& id);
std::optional<boost::signals2::scoped_connection> _accepted_block_connection;
std::optional<boost::signals2::scoped_connection> _irreversible_block_connection;
@@ -36,8 +36,9 @@ void test_control_plugin_impl::connect() {
applied_irreversible_block( bs );
} ));
_accepted_block_connection =
_chain.accepted_block.connect( [&]( const chain::block_state_legacy_ptr& bs ) {
accepted_block( bs );
_chain.accepted_block.connect( [&]( std::tuple<const chain::signed_block_ptr&, const chain::block_id_type&, const chain::signed_block_header&, uint32_t> t ) {
const auto& [ block, id, header, block_num ] = t;
accepted_block( id );
} );
}
@@ -48,17 +49,19 @@ void test_control_plugin_impl::disconnect() {
void test_control_plugin_impl::applied_irreversible_block(const chain::block_state_legacy_ptr& bsp) {
if (_track_lib)
process_next_block_state_legacy(bsp);
process_next_block_state_legacy(bsp->id);
}
void test_control_plugin_impl::accepted_block(const chain::block_state_legacy_ptr& bsp) {
void test_control_plugin_impl::accepted_block(const chain::block_id_type& id) {
if (_track_head)
process_next_block_state_legacy(bsp);
process_next_block_state_legacy(id);
}
void test_control_plugin_impl::process_next_block_state_legacy(const chain::block_state_legacy_ptr& bsp) {
void test_control_plugin_impl::process_next_block_state_legacy(const chain::block_id_type& id) {
// Tests expect the shutdown only after signaling a producer shutdown and seeing a full production cycle
const auto block_time = _chain.head_block_time() + fc::microseconds(chain::config::block_interval_us);
// have to fetch bsp due to get_scheduled_producer call
const auto& bsp = _chain.fetch_block_state_by_id(id);
const auto& producer_authority = bsp->get_scheduled_producer(block_time);
const auto producer_name = producer_authority.producer_name;
const auto slot = bsp->block->timestamp.slot % chain::config::producer_repetitions;
@@ -31,8 +31,8 @@ public:
}
/// connect to chain controller accepted_block signal
void signal_accepted_block( const chain::block_state_legacy_ptr& bsp ) {
on_accepted_block( bsp );
void signal_accepted_block( const chain::signed_block_ptr& block, const chain::block_id_type& id, uint32_t block_num ) {
on_accepted_block( block, id, block_num );
}
/// connect to chain controller irreversible_block signal
@@ -63,8 +63,8 @@ private:
}
}
void on_accepted_block(const chain::block_state_legacy_ptr& block_state) {
store_block_trace( block_state );
void on_accepted_block(const chain::signed_block_ptr& block, const chain::block_id_type& id, uint32_t block_num) {
store_block_trace( block, id, block_num );
}
void on_irreversible_block( const chain::block_state_legacy_ptr& block_state ) {
@@ -80,18 +80,18 @@ private:
onblock_trace.reset();
}
void store_block_trace( const chain::block_state_legacy_ptr& block_state ) {
void store_block_trace( const chain::signed_block_ptr& block, const chain::block_id_type& id, uint32_t block_num) {
try {
using transaction_trace_t = transaction_trace_v3;
auto bt = create_block_trace( block_state );
auto bt = create_block_trace( block, id, block_num );
std::vector<transaction_trace_t> traces;
traces.reserve( block_state->block->transactions.size() + 1 );
traces.reserve( block->transactions.size() + 1 );
block_trxs_entry tt;
tt.ids.reserve(block_state->block->transactions.size() + 1);
tt.ids.reserve(block->transactions.size() + 1);
if( onblock_trace )
traces.emplace_back( to_transaction_trace<transaction_trace_t>( *onblock_trace ));
for( const auto& r : block_state->block->transactions ) {
for( const auto& r : block->transactions ) {
transaction_id_type id;
if( std::holds_alternative<transaction_id_type>(r.trx)) {
id = std::get<transaction_id_type>(r.trx);
@@ -63,16 +63,16 @@ inline TransactionTrace to_transaction_trace( const cache_trace& t ) {
return r;
}
inline block_trace_v2 create_block_trace( const chain::block_state_legacy_ptr& bsp ) {
inline block_trace_v2 create_block_trace( const chain::signed_block_ptr& block, const chain::block_id_type& id, uint32_t block_num ) {
block_trace_v2 r;
r.id = bsp->id;
r.number = bsp->block_num;
r.previous_id = bsp->block->previous;
r.timestamp = bsp->block->timestamp;
r.producer = bsp->block->producer;
r.schedule_version = bsp->block->schedule_version;
r.transaction_mroot = bsp->block->transaction_mroot;
r.action_mroot = bsp->block->action_mroot;
r.id = id;
r.number = block_num;
r.previous_id = block->previous;
r.timestamp = block->timestamp;
r.producer = block->producer;
r.schedule_version = block->schedule_version;
r.transaction_mroot = block->transaction_mroot;
r.action_mroot = block->action_mroot;
return r;
}
@@ -137,7 +137,7 @@ struct extraction_test_fixture {
}
void signal_accepted_block( const chain::block_state_legacy_ptr& bsp ) {
extraction_impl.signal_accepted_block(bsp);
extraction_impl.signal_accepted_block(bsp->block, bsp->id, bsp->block_num);
}
// fixture data and methods
@@ -377,9 +377,10 @@ struct trace_api_plugin_impl {
}));
accepted_block_connection.emplace(
chain.accepted_block.connect([this](const chain::block_state_legacy_ptr& p) {
chain.accepted_block.connect([this](std::tuple<const chain::signed_block_ptr&, const chain::block_id_type&, const chain::signed_block_header&, uint32_t> t) {
emit_killer([&](){
extraction->signal_accepted_block(p);
const auto& [ block, id, header, block_num ] = t;
extraction->signal_accepted_block(block, id, block_num);
});
}));
+5 -3
View File
@@ -1470,8 +1470,10 @@ void transaction_tests(T& chain) {
auto& t = std::get<0>(x);
if (t && t->receipt && t->receipt->status != transaction_receipt::executed) { trace = t; }
} );
block_state_legacy_ptr bsp;
auto c2 = chain.control->accepted_block.connect([&](const block_state_legacy_ptr& b) { bsp = b; });
signed_block_ptr block;
auto c2 = chain.control->accepted_block.connect([&](std::tuple<const signed_block_ptr&, const block_id_type&, const signed_block_header&, uint32_t> t) {
const auto& [ b, id, header, block_num ] = t;
block = b; });
// test error handling on deferred transaction failure
auto test_trace = CALL_TEST_FUNCTION(chain, "test_transaction", "send_transaction_trigger_error_handler", {});
@@ -1480,7 +1482,7 @@ void transaction_tests(T& chain) {
BOOST_CHECK_EQUAL(trace->receipt->status, transaction_receipt::soft_fail);
std::set<transaction_id_type> block_ids;
for( const auto& receipt : bsp->block->transactions ) {
for( const auto& receipt : block->transactions ) {
transaction_id_type id;
if( std::holds_alternative<packed_transaction>(receipt.trx) ) {
const auto& pt = std::get<packed_transaction>(receipt.trx);
+6 -4
View File
@@ -217,11 +217,13 @@ BOOST_AUTO_TEST_CASE(broadcasted_block_test)
signed_block_ptr bcasted_blk_by_prod_node;
signed_block_ptr bcasted_blk_by_recv_node;
producer_node.control->accepted_block.connect( [&](const block_state_legacy_ptr& bs) {
bcasted_blk_by_prod_node = bs->block;
producer_node.control->accepted_block.connect( [&](std::tuple<const signed_block_ptr&, const block_id_type&, const signed_block_header&, uint32_t> t) {
const auto& [ block, id, header, block_num ] = t;
bcasted_blk_by_prod_node = block;
});
receiving_node.control->accepted_block.connect( [&](const block_state_legacy_ptr& bs) {
bcasted_blk_by_recv_node = bs->block;
receiving_node.control->accepted_block.connect( [&](std::tuple<const signed_block_ptr&, const block_id_type&, const signed_block_header&, uint32_t> t) {
const auto& [ block, id, header, block_num ] = t;
bcasted_blk_by_recv_node = block;
});
auto b = producer_node.produce_block();
+38 -28
View File
@@ -149,41 +149,51 @@ BOOST_AUTO_TEST_CASE( signal_validated_blocks ) try {
tester chain;
tester validator;
block_state_legacy_ptr accepted_bsp;
auto c = chain.control->accepted_block.connect([&](const block_state_legacy_ptr& b) {
BOOST_CHECK(b);
BOOST_CHECK(chain.control->fetch_block_state_by_id(b->id) == b);
BOOST_CHECK(chain.control->fetch_block_state_by_number(b->block_num) == b); // verify it can be found (has to be validated)
BOOST_CHECK(chain.control->fetch_block_by_id(b->id) == b->block);
BOOST_CHECK(chain.control->fetch_block_by_number(b->block_num) == b->block);
BOOST_REQUIRE(chain.control->fetch_block_header_by_number(b->block_num));
BOOST_CHECK(chain.control->fetch_block_header_by_number(b->block_num)->calculate_id() == b->id);
BOOST_REQUIRE(chain.control->fetch_block_header_by_id(b->id));
BOOST_CHECK(chain.control->fetch_block_header_by_id(b->id)->calculate_id() == b->id);
accepted_bsp = b;
signed_block_ptr accepted_block;
block_id_type accepted_id;
auto c = chain.control->accepted_block.connect([&](std::tuple<const signed_block_ptr&, const block_id_type&, const signed_block_header&, uint32_t> t) {
const auto& [ block, id, header, block_num ] = t;
BOOST_CHECK(block);
const auto& bsp_by_id = chain.control->fetch_block_state_by_id(id);
BOOST_CHECK(bsp_by_id->block_num == block_num);
const auto& bsp_by_number = chain.control->fetch_block_state_by_number(block_num); // verify it can be found (has to be validated)
BOOST_CHECK(bsp_by_number->id == id);
BOOST_CHECK(chain.control->fetch_block_by_id(id) == block);
BOOST_CHECK(chain.control->fetch_block_by_number(block_num) == block);
BOOST_REQUIRE(chain.control->fetch_block_header_by_number(block_num));
BOOST_CHECK(chain.control->fetch_block_header_by_number(block_num)->calculate_id() == id);
BOOST_REQUIRE(chain.control->fetch_block_header_by_id(id));
BOOST_CHECK(chain.control->fetch_block_header_by_id(id)->calculate_id() == id);
accepted_block = block;
accepted_id = id;
});
block_state_legacy_ptr validated_bsp;
auto c2 = validator.control->accepted_block.connect([&](const block_state_legacy_ptr& b) {
BOOST_CHECK(b);
BOOST_CHECK(validator.control->fetch_block_state_by_id(b->id) == b);
BOOST_CHECK(validator.control->fetch_block_state_by_number(b->block_num) == b); // verify it can be found (has to be validated)
BOOST_CHECK(validator.control->fetch_block_by_id(b->id) == b->block);
BOOST_CHECK(validator.control->fetch_block_by_number(b->block_num) == b->block);
BOOST_REQUIRE(validator.control->fetch_block_header_by_number(b->block_num));
BOOST_CHECK(validator.control->fetch_block_header_by_number(b->block_num)->calculate_id() == b->id);
BOOST_REQUIRE(validator.control->fetch_block_header_by_id(b->id));
BOOST_CHECK(validator.control->fetch_block_header_by_id(b->id)->calculate_id() == b->id);
validated_bsp = b;
signed_block_ptr validated_block;
block_id_type validated_id;
auto c2 = validator.control->accepted_block.connect([&](std::tuple<const signed_block_ptr&, const block_id_type&, const signed_block_header&, uint32_t> t) {
const auto& [ block, id, header, block_num ] = t;
BOOST_CHECK(block);
const auto& bsp_by_id = validator.control->fetch_block_state_by_id(id);
BOOST_CHECK(bsp_by_id->block_num == block_num);
const auto& bsp_by_number = validator.control->fetch_block_state_by_number(block_num); // verify it can be found (has to be validated)
BOOST_CHECK(bsp_by_number->id == id);
BOOST_CHECK(validator.control->fetch_block_by_id(id) == block);
BOOST_CHECK(validator.control->fetch_block_by_number(block_num) == block);
BOOST_REQUIRE(validator.control->fetch_block_header_by_number(block_num));
BOOST_CHECK(validator.control->fetch_block_header_by_number(block_num)->calculate_id() == id);
BOOST_REQUIRE(validator.control->fetch_block_header_by_id(id));
BOOST_CHECK(validator.control->fetch_block_header_by_id(id)->calculate_id() == id);
validated_block = block;
validated_id = id;
});
chain.produce_blocks(1);
validator.push_block(accepted_bsp->block);
validator.push_block(accepted_block);
chain.create_account("hello"_n);
auto produced_block = chain.produce_block();
validator.push_block(accepted_bsp->block);
BOOST_CHECK(produced_block->calculate_id() == accepted_bsp->id);
BOOST_CHECK(accepted_bsp->id == validated_bsp->id);
validator.push_block(accepted_block);
BOOST_CHECK(produced_block->calculate_id() == accepted_id);
BOOST_CHECK(accepted_id == validated_id);
} FC_LOG_AND_RETHROW()
+13 -9
View File
@@ -351,10 +351,13 @@ BOOST_AUTO_TEST_CASE( validator_accepts_valid_blocks ) try {
auto id = n1.control->head_block_id();
block_state_legacy_ptr first_block;
signed_block_ptr first_block;
signed_block_header first_header;
auto c = n2.control->accepted_block.connect( [&]( const block_state_legacy_ptr& bsp) {
first_block = bsp;
auto c = n2.control->accepted_block.connect( [&]( std::tuple<const signed_block_ptr&, const block_id_type&, const signed_block_header&, uint32_t> t ) {
const auto& [ block, id, header, block_num ] = t;
first_block = block;
first_header = header;
} );
push_blocks( n1, n2 );
@@ -362,13 +365,13 @@ BOOST_AUTO_TEST_CASE( validator_accepts_valid_blocks ) try {
BOOST_CHECK_EQUAL( n2.control->head_block_id(), id );
BOOST_REQUIRE( first_block );
first_block->verify_signee();
BOOST_CHECK_EQUAL( first_block->header.calculate_id(), first_block->block->calculate_id() );
BOOST_CHECK( first_block->header.producer_signature == first_block->block->producer_signature );
// WARNING first_block->verify_signee();
BOOST_CHECK_EQUAL( first_header.calculate_id(), first_block->calculate_id() );
BOOST_CHECK( first_header.producer_signature == first_block->producer_signature );
c.disconnect();
n3.push_block( first_block->block );
n3.push_block( first_block );
BOOST_CHECK_EQUAL( n3.control->head_block_id(), id );
@@ -697,8 +700,9 @@ BOOST_AUTO_TEST_CASE( push_block_returns_forked_transactions ) try {
// test forked blocks signal accepted_block in order, required by trace_api_plugin
std::vector<signed_block_ptr> accepted_blocks;
auto conn = c.control->accepted_block.connect( [&]( const block_state_legacy_ptr& bsp) {
accepted_blocks.emplace_back( bsp->block );
auto conn = c.control->accepted_block.connect( [&]( std::tuple<const signed_block_ptr&, const block_id_type&, const signed_block_header&, uint32_t> t ) {
const auto& [ block, id, header, block_num ] = t;
accepted_blocks.emplace_back( block );
} );
// dan on chain 1 now gets all of the blocks from chain 2 which should cause fork switch
+6 -5
View File
@@ -631,16 +631,17 @@ struct state_history_tester : state_history_tester_logs, tester {
trace_converter.add_transaction(std::get<0>(t), std::get<1>(t));
});
control.accepted_block.connect([&](const block_state_legacy_ptr& block_state) {
control.accepted_block.connect([&](std::tuple<const signed_block_ptr&, const block_id_type&, const signed_block_header&, uint32_t> t) {
const auto& [ block, id, block_header, block_num ] = t;
eosio::state_history_log_header header{.magic = eosio::ship_magic(eosio::ship_current_version, 0),
.block_id = block_state->id,
.block_id = id,
.payload_size = 0};
traces_log.pack_and_write_entry(header, block_state->block->previous, [this, &block_state](auto&& buf) {
trace_converter.pack(buf, false, block_state);
traces_log.pack_and_write_entry(header, block->previous, [this, &block](auto&& buf) {
trace_converter.pack(buf, false, block);
});
chain_state_log.pack_and_write_entry(header, block_state->header.previous, [&control](auto&& buf) {
chain_state_log.pack_and_write_entry(header, block_header.previous, [&control](auto&& buf) {
eosio::state_history::pack_deltas(buf, control.db(), true);
});
});
@@ -124,7 +124,8 @@ BOOST_AUTO_TEST_CASE( unapplied_transaction_queue_test ) try {
// clear applied
q.add_aborted( { trx1, trx2, trx3 } );
q.clear_applied( create_test_block_state( { trx1, trx3, trx4 } ) );
auto bs0 = create_test_block_state( { trx1, trx3, trx4 } );
q.clear_applied( bs0->block );
BOOST_CHECK( q.size() == 1u );
BOOST_REQUIRE( next( q ) == trx2 );
BOOST_CHECK( q.size() == 0u );