Skip to content

Commit

Permalink
Merge pull request AntelopeIO#484 from eosnetworkfoundation/backport_…
Browse files Browse the repository at this point in the history
…optimize_push_transaction

Backport push_transaction optimizations.
  • Loading branch information
ndcgundlach authored Jun 23, 2022
2 parents fdd3f43 + 28e59d6 commit be93354
Show file tree
Hide file tree
Showing 17 changed files with 94 additions and 64 deletions.
2 changes: 1 addition & 1 deletion libraries/chain/block_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ namespace eosio { namespace chain {

block_state::block_state( pending_block_header_state&& cur,
signed_block_ptr&& b,
vector<transaction_metadata_ptr>&& trx_metas,
deque<transaction_metadata_ptr>&& trx_metas,
const protocol_feature_set& pfs,
const std::function<void( block_timestamp_type,
const flat_set<digest_type>&,
Expand Down
64 changes: 26 additions & 38 deletions libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,16 +121,17 @@ struct building_block {
std::optional<producer_authority_schedule> _new_pending_producer_schedule;
vector<digest_type> _new_protocol_feature_activations;
size_t _num_new_protocol_features_that_have_activated = 0;
vector<transaction_metadata_ptr> _pending_trx_metas;
vector<transaction_receipt> _pending_trx_receipts;
vector<digest_type> _action_receipt_digests;
deque<transaction_metadata_ptr> _pending_trx_metas;
deque<transaction_receipt> _pending_trx_receipts;
deque<digest_type> _pending_trx_receipt_digests;
deque<digest_type> _action_receipt_digests;
std::optional<checksum256_type> _transaction_mroot;
};

struct assembled_block {
block_id_type _id;
pending_block_header_state _pending_block_header_state;
vector<transaction_metadata_ptr> _trx_metas;
deque<transaction_metadata_ptr> _trx_metas;
signed_block_ptr _unsigned_block;

// if the _unsigned_block pre-dates block-signing authorities this may be present.
Expand Down Expand Up @@ -165,17 +166,7 @@ struct pending_state {
return std::get<assembled_block>(_block_stage)._pending_block_header_state;
}

const vector<transaction_receipt>& get_trx_receipts()const {
if( std::holds_alternative<building_block>(_block_stage) )
return std::get<building_block>(_block_stage)._pending_trx_receipts;

if( std::holds_alternative<assembled_block>(_block_stage) )
return std::get<assembled_block>(_block_stage)._unsigned_block->transactions;

return std::get<completed_block>(_block_stage)._block_state->block->transactions;
}

vector<transaction_metadata_ptr> extract_trx_metas() {
deque<transaction_metadata_ptr> extract_trx_metas() {
if( std::holds_alternative<building_block>(_block_stage) )
return std::move( std::get<building_block>(_block_stage)._pending_trx_metas );

Expand Down Expand Up @@ -1082,18 +1073,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<std::function<void()>> make_block_restore_point() {
auto& bb = std::get<building_block>(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<void()> 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<building_block>(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);
};

Expand Down Expand Up @@ -1445,6 +1438,7 @@ struct controller_impl {
r.cpu_usage_us = cpu_usage_us;
r.net_usage_words = net_usage_words;
r.status = status;
std::get<building_block>(pending->_block_stage)._pending_trx_receipt_digests.emplace_back( r.digest() );
return r;
}

Expand Down Expand Up @@ -1697,7 +1691,7 @@ struct controller_impl {
});
}

const auto& gpo = db.get<global_property_object>();
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 ...
Expand Down Expand Up @@ -1732,7 +1726,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));
}
Expand Down Expand Up @@ -1782,7 +1776,7 @@ struct controller_impl {

// Create (unsigned) block:
auto block_ptr = std::make_shared<signed_block>( pbhs.make_block_header(
bb._transaction_mroot ? *bb._transaction_mroot : calculate_trx_merkle( bb._pending_trx_receipts ),
merkle( std::move( std::get<building_block>(pending->_block_stage)._pending_trx_receipt_digests ) ),
merkle( std::move( std::get<building_block>(pending->_block_stage)._action_receipt_digests ) ),
bb._new_pending_producer_schedule,
std::move( bb._new_protocol_feature_activations ),
Expand Down Expand Up @@ -1986,8 +1980,8 @@ struct controller_impl {
transaction_trace_ptr trace;

size_t packed_idx = 0;
const auto& trx_receipts = std::get<building_block>(pending->_block_stage)._pending_trx_receipts;
for( const auto& receipt : b->transactions ) {
const auto& trx_receipts = std::get<building_block>(pending->_block_stage)._pending_trx_receipts;
auto num_pending_receipts = trx_receipts.size();
if( std::holds_alternative<packed_transaction>(receipt.trx) ) {
const auto& trx_meta = ( use_bsp_cached ? bsp->trxs_metas().at( packed_idx )
Expand Down Expand Up @@ -2277,8 +2271,8 @@ struct controller_impl {

} /// push_block

vector<transaction_metadata_ptr> abort_block() {
vector<transaction_metadata_ptr> applied_trxs;
deque<transaction_metadata_ptr> abort_block() {
deque<transaction_metadata_ptr> applied_trxs;
if( pending ) {
applied_trxs = pending->extract_trx_metas();
pending.reset();
Expand All @@ -2287,9 +2281,8 @@ struct controller_impl {
return applied_trxs;
}

static checksum256_type calculate_trx_merkle( const vector<transaction_receipt>& trxs ) {
vector<digest_type> trx_digests;
trx_digests.reserve( trxs.size() );
static checksum256_type calculate_trx_merkle( const deque<transaction_receipt>& trxs ) {
deque<digest_type> trx_digests;
for( const auto& a : trxs )
trx_digests.emplace_back( a.digest() );

Expand Down Expand Up @@ -2808,7 +2801,7 @@ void controller::commit_block() {
my->commit_block(true);
}

vector<transaction_metadata_ptr> controller::abort_block() {
deque<transaction_metadata_ptr> controller::abort_block() {
return my->abort_block();
}

Expand Down Expand Up @@ -2980,11 +2973,6 @@ std::optional<block_id_type> controller::pending_producer_block_id()const {
return my->pending->_producer_block_id;
}

const vector<transaction_receipt>& 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;
}
Expand Down
35 changes: 35 additions & 0 deletions libraries/chain/include/eosio/chain/abi_serializer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<typename M, typename Resolver, require_abi_t<M> = 1>
static void add( mutable_variant_object &mvo, const char* name, const deque<M>& v, Resolver resolver, abi_traverse_context& ctx )
{
auto h = ctx.enter_scope();
deque<fc::variant> 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
Expand Down Expand Up @@ -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<typename M, typename Resolver, require_abi_t<M> = 1>
static void extract( const fc::variant& v, deque<M>& 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
Expand Down
2 changes: 1 addition & 1 deletion libraries/chain/include/eosio/chain/block.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ namespace eosio { namespace chain {
signed_block& operator=(signed_block&&) = default;
signed_block clone() const { return *this; }

vector<transaction_receipt> transactions; /// new or generated transactions
deque<transaction_receipt> transactions; /// new or generated transactions
extensions_type block_extensions;

flat_multimap<uint16_t, block_extension> validate_and_extract_extensions()const;
Expand Down
10 changes: 5 additions & 5 deletions libraries/chain/include/eosio/chain/block_state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace eosio { namespace chain {

block_state( pending_block_header_state&& cur,
signed_block_ptr&& b, // unsigned block
vector<transaction_metadata_ptr>&& trx_metas,
deque<transaction_metadata_ptr>&& trx_metas,
const protocol_feature_set& pfs,
const std::function<void( block_timestamp_type,
const flat_set<digest_type>&,
Expand All @@ -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<transaction_metadata_ptr> extract_trxs_metas() {
deque<transaction_metadata_ptr> extract_trxs_metas() {
_pub_keys_recovered = false;
auto result = std::move( _cached_trxs );
_cached_trxs.clear();
return result;
}
void set_trxs_metas( vector<transaction_metadata_ptr>&& trxs_metas, bool keys_recovered ) {
void set_trxs_metas( deque<transaction_metadata_ptr>&& trxs_metas, bool keys_recovered ) {
_pub_keys_recovered = keys_recovered;
_cached_trxs = std::move( trxs_metas );
}
const vector<transaction_metadata_ptr>& trxs_metas()const { return _cached_trxs; }
const deque<transaction_metadata_ptr>& 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<transaction_metadata_ptr> _cached_trxs;
deque<transaction_metadata_ptr> _cached_trxs;
};

using block_state_ptr = std::shared_ptr<block_state>;
Expand Down
4 changes: 1 addition & 3 deletions libraries/chain/include/eosio/chain/controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ namespace eosio { namespace chain {
/**
* @return transactions applied in aborted block
*/
vector<transaction_metadata_ptr> abort_block();
deque<transaction_metadata_ptr> abort_block();

/**
*
Expand Down Expand Up @@ -232,8 +232,6 @@ namespace eosio { namespace chain {
std::optional<block_id_type> pending_producer_block_id()const;
uint32_t pending_block_num()const;

const vector<transaction_receipt>& get_pending_trx_receipts()const;

const producer_authority_schedule& active_producers()const;
const producer_authority_schedule& pending_producers()const;
std::optional<producer_authority_schedule> proposed_producers()const;
Expand Down
2 changes: 1 addition & 1 deletion libraries/chain/include/eosio/chain/merkle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<digest_type> ids );
digest_type merkle( deque<digest_type> ids );

} } /// eosio::chain
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ namespace eosio { namespace chain {
fc::time_point published;


vector<digest_type> executed_action_receipt_digests;
deque<digest_type> executed_action_receipt_digests;
flat_set<account_name> bill_to_accounts;
flat_set<account_name> validate_ram_usage;

Expand Down
14 changes: 12 additions & 2 deletions libraries/chain/include/eosio/chain/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
#include <fc/fixed_string.hpp>
#include <fc/crypto/private_key.hpp>

#include <boost/version.hpp>
#include <boost/container/deque.hpp>

#include <memory>
#include <vector>
#include <deque>
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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<typename T>
using deque = boost::container::deque< T, void, block_1024_option_t >;
#else
template<typename T>
using deque = std::deque<T>;
#endif
struct void_t{};

using chainbase::allocator;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ class unapplied_transaction_queue {
}
}

void add_aborted( std::vector<transaction_metadata_ptr> aborted_trxs ) {
void add_aborted( deque<transaction_metadata_ptr> 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 } );
Expand Down
2 changes: 1 addition & 1 deletion libraries/chain/merkle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ bool is_canonical_right(const digest_type& val) {
}


digest_type merkle(vector<digest_type> ids) {
digest_type merkle(deque<digest_type> ids) {
if( 0 == ids.size() ) { return digest_type(); }

while( ids.size() > 1 ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ auto make_block_state( uint32_t block_num ) {
auto bsp = std::make_shared<chain::block_state>(
std::move( pbhs ),
std::move( block ),
std::vector<chain::transaction_metadata_ptr>(),
deque<chain::transaction_metadata_ptr>(),
chain::protocol_feature_set(),
[]( chain::block_timestamp_type timestamp,
const fc::flat_set<chain::digest_type>& cur_features,
Expand Down
2 changes: 1 addition & 1 deletion plugins/chain_plugin/test/test_trx_retry_db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ auto make_block_state( uint32_t block_num, std::vector<chain::packed_transaction
auto bsp = std::make_shared<chain::block_state>(
std::move( pbhs ),
std::move( block ),
std::vector<chain::transaction_metadata_ptr>(),
deque<chain::transaction_metadata_ptr>(),
chain::protocol_feature_set(),
[]( chain::block_timestamp_type timestamp,
const fc::flat_set<chain::digest_type>& cur_features,
Expand Down
1 change: 0 additions & 1 deletion plugins/producer_plugin/producer_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <eosio/chain/block.hpp>
#include <eosio/chain/block_state.hpp>
#include <eosio/chain/name.hpp>
#include <eosio/chain/types.hpp>

#include <eosio/trace_api/data_log.hpp>
#include <eosio/trace_api/metadata_log.hpp>
Expand Down Expand Up @@ -94,7 +95,7 @@ namespace eosio::trace_api {
auto bsp = std::make_shared<chain::block_state>(
std::move( pbhs ),
std::move( block ),
std::vector<chain::transaction_metadata_ptr>(),
eosio::chain::deque<chain::transaction_metadata_ptr>(),
chain::protocol_feature_set(),
[]( chain::block_timestamp_type timestamp,
const fc::flat_set<chain::digest_type>& cur_features,
Expand Down
Loading

0 comments on commit be93354

Please sign in to comment.