Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.2] Backport push_transaction optimizations. #484

Merged
merged 3 commits into from
Jun 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -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<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 @@ -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<building_block>(pending->_block_stage)._pending_trx_receipt_digests.emplace_back( r.digest() );
return r;
}

Expand Down Expand Up @@ -1689,7 +1683,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 @@ -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));
}
Expand Down Expand Up @@ -1774,7 +1768,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 @@ -1978,8 +1972,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 @@ -2269,8 +2263,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 @@ -2279,9 +2273,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 @@ -2800,7 +2793,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 @@ -2963,11 +2956,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 @@ -142,7 +142,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 @@ -227,8 +227,6 @@ namespace eosio { namespace chain {
const block_signing_authority& pending_block_signing_authority()const;
std::optional<block_id_type> pending_producer_block_id()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