diff --git a/libraries/chain/block_state.cpp b/libraries/chain/block_state.cpp index 369d090341..fd614a6118 100644 --- a/libraries/chain/block_state.cpp +++ b/libraries/chain/block_state.cpp @@ -88,7 +88,7 @@ namespace eosio { namespace chain { block_state::block_state( pending_block_header_state&& cur, signed_block_ptr&& b, - vector&& trx_metas, + deque&& trx_metas, const protocol_feature_set& pfs, const std::function&, diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index aa5c08c4c0..7586eb2cb5 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -121,16 +121,17 @@ struct building_block { std::optional _new_pending_producer_schedule; vector _new_protocol_feature_activations; size_t _num_new_protocol_features_that_have_activated = 0; - vector _pending_trx_metas; - vector _pending_trx_receipts; - vector _action_receipt_digests; + deque _pending_trx_metas; + deque _pending_trx_receipts; + deque _pending_trx_receipt_digests; + deque _action_receipt_digests; std::optional _transaction_mroot; }; struct assembled_block { block_id_type _id; pending_block_header_state _pending_block_header_state; - vector _trx_metas; + deque _trx_metas; signed_block_ptr _unsigned_block; // if the _unsigned_block pre-dates block-signing authorities this may be present. @@ -165,17 +166,7 @@ struct pending_state { return std::get(_block_stage)._pending_block_header_state; } - const vector& get_trx_receipts()const { - if( std::holds_alternative(_block_stage) ) - return std::get(_block_stage)._pending_trx_receipts; - - if( std::holds_alternative(_block_stage) ) - return std::get(_block_stage)._unsigned_block->transactions; - - return std::get(_block_stage)._block_state->block->transactions; - } - - vector extract_trx_metas() { + deque extract_trx_metas() { if( std::holds_alternative(_block_stage) ) return std::move( std::get(_block_stage)._pending_trx_metas ); @@ -1074,18 +1065,20 @@ struct controller_impl { // The returned scoped_exit should not exceed the lifetime of the pending which existed when make_block_restore_point was called. fc::scoped_exit> make_block_restore_point() { auto& bb = std::get(pending->_block_stage); - auto orig_block_transactions_size = bb._pending_trx_receipts.size(); - auto orig_state_transactions_size = bb._pending_trx_metas.size(); + auto orig_trx_receipts_size = bb._pending_trx_receipts.size(); + auto orig_trx_metas_size = bb._pending_trx_metas.size(); + auto orig_trx_receipt_digests_size = bb._pending_trx_receipt_digests.size(); auto orig_action_receipt_digests_size = bb._action_receipt_digests.size(); - std::function callback = [this, - orig_block_transactions_size, - orig_state_transactions_size, - orig_action_receipt_digests_size]() + orig_trx_receipts_size, + orig_trx_metas_size, + orig_trx_receipt_digests_size, + orig_action_receipt_digests_size]() { auto& bb = std::get(pending->_block_stage); - bb._pending_trx_receipts.resize(orig_block_transactions_size); - bb._pending_trx_metas.resize(orig_state_transactions_size); + bb._pending_trx_receipts.resize(orig_trx_receipts_size); + bb._pending_trx_metas.resize(orig_trx_metas_size); + bb._pending_trx_receipt_digests.resize(orig_trx_receipt_digests_size); bb._action_receipt_digests.resize(orig_action_receipt_digests_size); }; @@ -1437,6 +1430,7 @@ struct controller_impl { r.cpu_usage_us = cpu_usage_us; r.net_usage_words = net_usage_words; r.status = status; + std::get(pending->_block_stage)._pending_trx_receipt_digests.emplace_back( r.digest() ); return r; } @@ -1689,7 +1683,7 @@ struct controller_impl { }); } - const auto& gpo = db.get(); + const auto& gpo = self.get_global_properties(); if( gpo.proposed_schedule_block_num && // if there is a proposed schedule that was proposed in a block ... ( *gpo.proposed_schedule_block_num <= pbhs.dpos_irreversible_blocknum ) && // ... that has now become irreversible ... @@ -1724,7 +1718,7 @@ struct controller_impl { }); in_trx_requiring_checks = true; auto trace = push_transaction( onbtrx, fc::time_point::maximum(), fc::microseconds::maximum(), - self.get_global_properties().configuration.min_transaction_cpu_usage, true, 0 ); + gpo.configuration.min_transaction_cpu_usage, true, 0 ); if( trace->except ) { wlog("onblock ${block_num} is REJECTING: ${entire_trace}",("block_num", head->block_num + 1)("entire_trace", trace)); } @@ -1774,7 +1768,7 @@ struct controller_impl { // Create (unsigned) block: auto block_ptr = std::make_shared( pbhs.make_block_header( - bb._transaction_mroot ? *bb._transaction_mroot : calculate_trx_merkle( bb._pending_trx_receipts ), + merkle( std::move( std::get(pending->_block_stage)._pending_trx_receipt_digests ) ), merkle( std::move( std::get(pending->_block_stage)._action_receipt_digests ) ), bb._new_pending_producer_schedule, std::move( bb._new_protocol_feature_activations ), @@ -1978,8 +1972,8 @@ struct controller_impl { transaction_trace_ptr trace; size_t packed_idx = 0; + const auto& trx_receipts = std::get(pending->_block_stage)._pending_trx_receipts; for( const auto& receipt : b->transactions ) { - const auto& trx_receipts = std::get(pending->_block_stage)._pending_trx_receipts; auto num_pending_receipts = trx_receipts.size(); if( std::holds_alternative(receipt.trx) ) { const auto& trx_meta = ( use_bsp_cached ? bsp->trxs_metas().at( packed_idx ) @@ -2269,8 +2263,8 @@ struct controller_impl { } /// push_block - vector abort_block() { - vector applied_trxs; + deque abort_block() { + deque applied_trxs; if( pending ) { applied_trxs = pending->extract_trx_metas(); pending.reset(); @@ -2279,9 +2273,8 @@ struct controller_impl { return applied_trxs; } - static checksum256_type calculate_trx_merkle( const vector& trxs ) { - vector trx_digests; - trx_digests.reserve( trxs.size() ); + static checksum256_type calculate_trx_merkle( const deque& trxs ) { + deque trx_digests; for( const auto& a : trxs ) trx_digests.emplace_back( a.digest() ); @@ -2800,7 +2793,7 @@ void controller::commit_block() { my->commit_block(true); } -vector controller::abort_block() { +deque controller::abort_block() { return my->abort_block(); } @@ -2963,11 +2956,6 @@ std::optional controller::pending_producer_block_id()const { return my->pending->_producer_block_id; } -const vector& controller::get_pending_trx_receipts()const { - EOS_ASSERT( my->pending, block_validate_exception, "no pending block" ); - return my->pending->get_trx_receipts(); -} - uint32_t controller::last_irreversible_block_num() const { return my->fork_db.root()->block_num; } diff --git a/libraries/chain/include/eosio/chain/abi_serializer.hpp b/libraries/chain/include/eosio/chain/abi_serializer.hpp index 01551e9ff6..6b4a7ea542 100644 --- a/libraries/chain/include/eosio/chain/abi_serializer.hpp +++ b/libraries/chain/include/eosio/chain/abi_serializer.hpp @@ -366,6 +366,23 @@ namespace impl { mvo(name, std::move(array)); } + /** + * template which overloads add for deques of types which contain ABI information in their trees + * for these members we call ::add in order to trigger further processing + */ + template = 1> + static void add( mutable_variant_object &mvo, const char* name, const deque& v, Resolver resolver, abi_traverse_context& ctx ) + { + auto h = ctx.enter_scope(); + deque array; + + for (const auto& iter: v) { + mutable_variant_object elem_mvo; + add(elem_mvo, "_", iter, resolver, ctx); + array.emplace_back(std::move(elem_mvo["_"])); + } + mvo(name, std::move(array)); + } /** * template which overloads add for shared_ptr of types which contain ABI information in their trees * for these members we call ::add in order to trigger further processing @@ -730,6 +747,24 @@ namespace impl { } } + /** + * template which overloads extract for deque of types which contain ABI information in their trees + * for these members we call ::extract in order to trigger further processing + */ + template = 1> + static void extract( const fc::variant& v, deque& o, Resolver resolver, abi_traverse_context& ctx ) + { + auto h = ctx.enter_scope(); + const variants& array = v.get_array(); + o.clear(); + for( auto itr = array.begin(); itr != array.end(); ++itr ) { + M o_iter; + extract(*itr, o_iter, resolver, ctx); + o.emplace_back(std::move(o_iter)); + } + } + + /** * template which overloads extract for shared_ptr of types which contain ABI information in their trees * for these members we call ::extract in order to trigger further processing diff --git a/libraries/chain/include/eosio/chain/block.hpp b/libraries/chain/include/eosio/chain/block.hpp index b523f8af55..ab06da5d42 100644 --- a/libraries/chain/include/eosio/chain/block.hpp +++ b/libraries/chain/include/eosio/chain/block.hpp @@ -97,7 +97,7 @@ namespace eosio { namespace chain { signed_block& operator=(signed_block&&) = default; signed_block clone() const { return *this; } - vector transactions; /// new or generated transactions + deque transactions; /// new or generated transactions extensions_type block_extensions; flat_multimap validate_and_extract_extensions()const; diff --git a/libraries/chain/include/eosio/chain/block_state.hpp b/libraries/chain/include/eosio/chain/block_state.hpp index ad0a695a5a..4772094739 100644 --- a/libraries/chain/include/eosio/chain/block_state.hpp +++ b/libraries/chain/include/eosio/chain/block_state.hpp @@ -19,7 +19,7 @@ namespace eosio { namespace chain { block_state( pending_block_header_state&& cur, signed_block_ptr&& b, // unsigned block - vector&& trx_metas, + deque&& trx_metas, const protocol_feature_set& pfs, const std::function&, @@ -44,24 +44,24 @@ namespace eosio { namespace chain { bool is_valid()const { return validated; } bool is_pub_keys_recovered()const { return _pub_keys_recovered; } - vector extract_trxs_metas() { + deque extract_trxs_metas() { _pub_keys_recovered = false; auto result = std::move( _cached_trxs ); _cached_trxs.clear(); return result; } - void set_trxs_metas( vector&& trxs_metas, bool keys_recovered ) { + void set_trxs_metas( deque&& trxs_metas, bool keys_recovered ) { _pub_keys_recovered = keys_recovered; _cached_trxs = std::move( trxs_metas ); } - const vector& trxs_metas()const { return _cached_trxs; } + const deque& trxs_metas()const { return _cached_trxs; } bool validated = false; bool _pub_keys_recovered = false; /// this data is redundant with the data stored in block, but facilitates /// recapturing transactions when we pop a block - vector _cached_trxs; + deque _cached_trxs; }; using block_state_ptr = std::shared_ptr; diff --git a/libraries/chain/include/eosio/chain/controller.hpp b/libraries/chain/include/eosio/chain/controller.hpp index d3b4bf2735..6a2092618b 100644 --- a/libraries/chain/include/eosio/chain/controller.hpp +++ b/libraries/chain/include/eosio/chain/controller.hpp @@ -142,7 +142,7 @@ namespace eosio { namespace chain { /** * @return transactions applied in aborted block */ - vector abort_block(); + deque abort_block(); /** * @@ -227,8 +227,6 @@ namespace eosio { namespace chain { const block_signing_authority& pending_block_signing_authority()const; std::optional pending_producer_block_id()const; - const vector& get_pending_trx_receipts()const; - const producer_authority_schedule& active_producers()const; const producer_authority_schedule& pending_producers()const; std::optional proposed_producers()const; diff --git a/libraries/chain/include/eosio/chain/merkle.hpp b/libraries/chain/include/eosio/chain/merkle.hpp index 00eae073e0..b99d18c101 100644 --- a/libraries/chain/include/eosio/chain/merkle.hpp +++ b/libraries/chain/include/eosio/chain/merkle.hpp @@ -17,6 +17,6 @@ namespace eosio { namespace chain { /** * Calculates the merkle root of a set of digests, if ids is odd it will duplicate the last id. */ - digest_type merkle( vector ids ); + digest_type merkle( deque ids ); } } /// eosio::chain diff --git a/libraries/chain/include/eosio/chain/transaction_context.hpp b/libraries/chain/include/eosio/chain/transaction_context.hpp index 5c850c1436..778234fa2e 100644 --- a/libraries/chain/include/eosio/chain/transaction_context.hpp +++ b/libraries/chain/include/eosio/chain/transaction_context.hpp @@ -129,7 +129,7 @@ namespace eosio { namespace chain { fc::time_point published; - vector executed_action_receipt_digests; + deque executed_action_receipt_digests; flat_set bill_to_accounts; flat_set validate_ram_usage; diff --git a/libraries/chain/include/eosio/chain/types.hpp b/libraries/chain/include/eosio/chain/types.hpp index 6355cccae4..f875179049 100644 --- a/libraries/chain/include/eosio/chain/types.hpp +++ b/libraries/chain/include/eosio/chain/types.hpp @@ -17,6 +17,9 @@ #include #include +#include +#include + #include #include #include @@ -45,7 +48,6 @@ namespace eosio { namespace chain { using std::vector; using std::unordered_map; using std::string; - using std::deque; using std::shared_ptr; using std::weak_ptr; using std::unique_ptr; @@ -76,7 +78,15 @@ namespace eosio { namespace chain { using public_key_type = fc::crypto::public_key; using private_key_type = fc::crypto::private_key; using signature_type = fc::crypto::signature; - +#if BOOST_VERSION >= 107100 + // configurable boost deque performs much better than std::deque in our use cases + using block_1024_option_t = boost::container::deque_options< boost::container::block_size<1024u> >::type; + template + using deque = boost::container::deque< T, void, block_1024_option_t >; +#else + template + using deque = std::deque; +#endif struct void_t{}; using chainbase::allocator; diff --git a/libraries/chain/include/eosio/chain/unapplied_transaction_queue.hpp b/libraries/chain/include/eosio/chain/unapplied_transaction_queue.hpp index 3aab726739..4d83ab1b2a 100644 --- a/libraries/chain/include/eosio/chain/unapplied_transaction_queue.hpp +++ b/libraries/chain/include/eosio/chain/unapplied_transaction_queue.hpp @@ -153,7 +153,7 @@ class unapplied_transaction_queue { } } - void add_aborted( std::vector aborted_trxs ) { + void add_aborted( deque aborted_trxs ) { for( auto& trx : aborted_trxs ) { fc::time_point expiry = trx->packed_trx()->expiration(); auto insert_itr = queue.insert( { std::move( trx ), expiry, trx_enum_type::aborted } ); diff --git a/libraries/chain/merkle.cpp b/libraries/chain/merkle.cpp index 9c6ea42098..e4211f7bfd 100644 --- a/libraries/chain/merkle.cpp +++ b/libraries/chain/merkle.cpp @@ -32,7 +32,7 @@ bool is_canonical_right(const digest_type& val) { } -digest_type merkle(vector ids) { +digest_type merkle(deque ids) { if( 0 == ids.size() ) { return digest_type(); } while( ids.size() > 1 ) { diff --git a/plugins/chain_plugin/test/test_trx_finality_status_processing.cpp b/plugins/chain_plugin/test/test_trx_finality_status_processing.cpp index 308ee7bdaf..938c07d304 100644 --- a/plugins/chain_plugin/test/test_trx_finality_status_processing.cpp +++ b/plugins/chain_plugin/test/test_trx_finality_status_processing.cpp @@ -140,7 +140,7 @@ auto make_block_state( uint32_t block_num ) { auto bsp = std::make_shared( std::move( pbhs ), std::move( block ), - std::vector(), + deque(), chain::protocol_feature_set(), []( chain::block_timestamp_type timestamp, const fc::flat_set& cur_features, diff --git a/plugins/chain_plugin/test/test_trx_retry_db.cpp b/plugins/chain_plugin/test/test_trx_retry_db.cpp index 7512589f77..a5155e525a 100644 --- a/plugins/chain_plugin/test/test_trx_retry_db.cpp +++ b/plugins/chain_plugin/test/test_trx_retry_db.cpp @@ -180,7 +180,7 @@ auto make_block_state( uint32_t block_num, std::vector( std::move( pbhs ), std::move( block ), - std::vector(), + deque(), chain::protocol_feature_set(), []( chain::block_timestamp_type timestamp, const fc::flat_set& cur_features, diff --git a/plugins/producer_plugin/producer_plugin.cpp b/plugins/producer_plugin/producer_plugin.cpp index 8e4a7919cb..c2997b1cbb 100644 --- a/plugins/producer_plugin/producer_plugin.cpp +++ b/plugins/producer_plugin/producer_plugin.cpp @@ -38,7 +38,6 @@ using boost::multi_index_container; using std::string; using std::vector; -using std::deque; using boost::signals2::scoped_connection; #undef FC_LOG_AND_DROP diff --git a/plugins/trace_api_plugin/test/include/eosio/trace_api/test_common.hpp b/plugins/trace_api_plugin/test/include/eosio/trace_api/test_common.hpp index 70774d728f..39cff9c3f7 100644 --- a/plugins/trace_api_plugin/test/include/eosio/trace_api/test_common.hpp +++ b/plugins/trace_api_plugin/test/include/eosio/trace_api/test_common.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -94,7 +95,7 @@ namespace eosio::trace_api { auto bsp = std::make_shared( std::move( pbhs ), std::move( block ), - std::vector(), + eosio::chain::deque(), chain::protocol_feature_set(), []( chain::block_timestamp_type timestamp, const fc::flat_set& cur_features, diff --git a/unittests/block_tests.cpp b/unittests/block_tests.cpp index d837a13dd2..e4f8f15edc 100644 --- a/unittests/block_tests.cpp +++ b/unittests/block_tests.cpp @@ -31,7 +31,7 @@ BOOST_AUTO_TEST_CASE(block_with_invalid_tx_test) copy_b->transactions.back().trx = std::move(invalid_packed_tx); // Re-calculate the transaction merkle - vector trx_digests; + deque trx_digests; const auto& trxs = copy_b->transactions; for( const auto& a : trxs ) trx_digests.emplace_back( a.digest() ); @@ -109,9 +109,8 @@ std::pair corrupt_trx_in_block(validating_te copy_b->transactions.back().trx = std::move(invalid_packed_tx); // Re-calculate the transaction merkle - vector trx_digests; + deque trx_digests; const auto& trxs = copy_b->transactions; - trx_digests.reserve( trxs.size() ); for( const auto& a : trxs ) trx_digests.emplace_back( a.digest() ); copy_b->transaction_mroot = merkle( move(trx_digests) ); @@ -262,7 +261,7 @@ BOOST_FIXTURE_TEST_CASE( abort_block_transactions, validating_tester) { try { control->get_account( a ); // throws if it does not exist - vector unapplied_trxs = control->abort_block(); + deque unapplied_trxs = control->abort_block(); // verify transaction returned from abort_block() BOOST_REQUIRE_EQUAL( 1, unapplied_trxs.size() ); @@ -313,7 +312,7 @@ BOOST_FIXTURE_TEST_CASE( abort_block_transactions_tester, validating_tester) { t control->get_account( a ); // throws if it does not exist - vector unapplied_trxs = control->abort_block(); // should be empty now + deque unapplied_trxs = control->abort_block(); // should be empty now BOOST_REQUIRE_EQUAL( 0, unapplied_trxs.size() ); diff --git a/unittests/unapplied_transaction_queue_tests.cpp b/unittests/unapplied_transaction_queue_tests.cpp index 0de86e5e81..3b95218eff 100644 --- a/unittests/unapplied_transaction_queue_tests.cpp +++ b/unittests/unapplied_transaction_queue_tests.cpp @@ -32,7 +32,7 @@ auto next( unapplied_transaction_queue& q ) { return trx; } -auto create_test_block_state( std::vector trx_metas ) { +auto create_test_block_state( deque trx_metas ) { signed_block_ptr block = std::make_shared(); for( auto& trx_meta : trx_metas ) { block->transactions.emplace_back( *trx_meta->packed_trx() );