Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into GH-54-contracts
Browse files Browse the repository at this point in the history
  • Loading branch information
heifner committed Jan 12, 2023
2 parents 4e1d593 + 9461180 commit b3a6e00
Show file tree
Hide file tree
Showing 44 changed files with 299 additions and 889 deletions.
1 change: 0 additions & 1 deletion docs/01_nodeos/03_plugins/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ For information on specific plugins, just select from the list below:
* [`test_control_api_plugin`](test_control_api_plugin/index.md)
* [`test_control_plugin`](test_control_plugin/index.md)
* [`trace_api_plugin`](trace_api_plugin/index.md)
* [`txn_test_gen_plugin`](txn_test_gen_plugin/index.md)

[[info | Nodeos is modular]]
| Plugins add incremental functionality to `nodeos`. Unlike runtime plugins, `nodeos` plugins are built at compile-time.
46 changes: 0 additions & 46 deletions docs/01_nodeos/03_plugins/txn_test_gen_plugin/index.md

This file was deleted.

3 changes: 3 additions & 0 deletions libraries/chain/include/eosio/chain/wasm_interface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ namespace eosio { namespace chain {
//Immediately exits currently running wasm. UB is called when no wasm running
void exit();

//Returns true if the code is cached
bool is_code_cached(const digest_type& code_hash, const uint8_t& vm_type, const uint8_t& vm_version) const;

// If substitute_apply is set, then apply calls it before doing anything else. If substitute_apply returns true,
// then apply returns immediately.
std::function<bool(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ namespace eosio { namespace chain {
});
}

bool is_code_cached(const digest_type& code_hash, const uint8_t& vm_type, const uint8_t& vm_version) const {
wasm_cache_index::iterator it = wasm_instantiation_cache.find( boost::make_tuple(code_hash, vm_type, vm_version) );
return it != wasm_instantiation_cache.end();
}

std::vector<uint8_t> parse_initial_memory(const Module& module) {
std::vector<uint8_t> mem_image;

Expand Down
4 changes: 4 additions & 0 deletions libraries/chain/wasm_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ namespace eosio { namespace chain {
my->runtime_interface->immediately_exit_currently_running_module();
}

bool wasm_interface::is_code_cached(const digest_type& code_hash, const uint8_t& vm_type, const uint8_t& vm_version) const {
return my->is_code_cached(code_hash, vm_type, vm_version);
}

wasm_instantiated_module_interface::~wasm_instantiated_module_interface() {}
wasm_runtime_interface::~wasm_runtime_interface() {}

Expand Down
2 changes: 2 additions & 0 deletions libraries/testing/include/eosio/testing/tester.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,8 @@ namespace eosio { namespace testing {
void set_code( account_name name, const vector<uint8_t> wasm, const private_key_type* signer = nullptr );
void set_abi( account_name name, const char* abi_json, const private_key_type* signer = nullptr );

bool is_code_cached( account_name name ) const;

bool chain_has_transaction( const transaction_id_type& txid ) const;
const transaction_receipt& get_transaction_receipt( const transaction_id_type& txid ) const;

Expand Down
7 changes: 7 additions & 0 deletions libraries/testing/tester.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -950,6 +950,13 @@ namespace eosio { namespace testing {
push_transaction( trx );
}

bool base_tester::is_code_cached( eosio::chain::account_name name ) const {
const auto& db = control->db();
const account_metadata_object* receiver_account = &db.template get<account_metadata_object,by_name>( name );
if ( receiver_account->code_hash == digest_type() ) return false;
return control->get_wasm_interface().is_code_cached( receiver_account->code_hash, receiver_account->vm_type, receiver_account->vm_version );
}


bool base_tester::chain_has_transaction( const transaction_id_type& txid ) const {
return chain_transactions.count(txid) != 0;
Expand Down
1 change: 0 additions & 1 deletion plugins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ add_subdirectory(resource_monitor_plugin)
add_subdirectory(signature_provider_plugin)
add_subdirectory(wallet_plugin)
add_subdirectory(wallet_api_plugin)
add_subdirectory(txn_test_gen_plugin)
add_subdirectory(db_size_api_plugin)
add_subdirectory(test_control_plugin)
add_subdirectory(test_control_api_plugin)
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class beast_http_listener : public std::enable_shared_from_this<beast_http_liste
typename protocol_type::acceptor acceptor_;
socket_type socket_;

boost::asio::deadline_timer accept_error_timer_;

public:
beast_http_listener() = default;
beast_http_listener(const beast_http_listener&) = delete;
Expand All @@ -36,7 +38,7 @@ class beast_http_listener : public std::enable_shared_from_this<beast_http_liste
beast_http_listener& operator=(const beast_http_listener&) = delete;
beast_http_listener& operator=(beast_http_listener&&) = delete;

beast_http_listener(std::shared_ptr<http_plugin_state> plugin_state) : is_listening_(false), plugin_state_(std::move(plugin_state)), acceptor_(plugin_state_->thread_pool->get_executor()), socket_(plugin_state_->thread_pool->get_executor()) {}
beast_http_listener(std::shared_ptr<http_plugin_state> plugin_state) : is_listening_(false), plugin_state_(std::move(plugin_state)), acceptor_(plugin_state_->thread_pool->get_executor()), socket_(plugin_state_->thread_pool->get_executor()), accept_error_timer_(plugin_state_->thread_pool->get_executor()) {}

virtual ~beast_http_listener() {
try {
Expand Down Expand Up @@ -106,19 +108,29 @@ class beast_http_listener : public std::enable_shared_from_this<beast_http_liste
void do_accept() {
auto self = this->shared_from_this();
acceptor_.async_accept(socket_, [self](beast::error_code ec) {
if(ec) {
fail(ec, "accept", self->plugin_state_->logger, "closing connection");
if(ec == boost::system::errc::too_many_files_open) {
// retry accept() after timeout to avoid cpu loop on accept
fail(ec, "accept", self->plugin_state_->logger, "too many files open - waiting 500ms");
self->accept_error_timer_.expires_from_now(boost::posix_time::milliseconds(500));
self->accept_error_timer_.async_wait([self = self->shared_from_this()](beast::error_code ec) {
if (!ec)
self->do_accept();
});
} else {
// Create the session object and run it
std::make_shared<session_type>(
if (ec) {
fail(ec, "accept", self->plugin_state_->logger, "closing connection");
} else {
// Create the session object and run it
std::make_shared<session_type>(
std::move(self->socket_),
self->plugin_state_)
->run_session();
}

// Accept another connection
self->do_accept();
}

// Accept another connection
self->do_accept();
});
}
};// end class beast_http_Listener
}// namespace eosio
}// namespace eosio
8 changes: 0 additions & 8 deletions plugins/net_plugin/net_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2341,14 +2341,6 @@ namespace eosio {

// called from connection strand
void connection::connect( const std::shared_ptr<tcp::resolver>& resolver, tcp::resolver::results_type endpoints ) {
switch ( no_retry ) {
case no_reason:
case wrong_version:
case benign_other:
break;
default:
return;
}
connecting = true;
pending_message_buffer.reset();
buffer_queue.clear_out_queue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,56 +15,47 @@

namespace eosio {

namespace bmi = boost::multi_index;
using chain::transaction_id_type;
using chain::account_name;
using chain::block_state_ptr;
using chain::packed_transaction;
namespace config = chain::config;

class subjective_billing {
private:

struct trx_cache_entry {
transaction_id_type trx_id;
account_name account;
int64_t subjective_cpu_bill;
fc::time_point expiry;
chain::transaction_id_type trx_id;
chain::account_name account;
int64_t subjective_cpu_bill = 0;
fc::time_point expiry;
};
struct by_id;
struct by_expiry;

using trx_cache_index = bmi::multi_index_container<
trx_cache_entry,
indexed_by<
bmi::hashed_unique<tag<by_id>, BOOST_MULTI_INDEX_MEMBER( trx_cache_entry, transaction_id_type, trx_id ) >,
bmi::hashed_unique<tag<by_id>, BOOST_MULTI_INDEX_MEMBER( trx_cache_entry, chain::transaction_id_type, trx_id ) >,
ordered_non_unique<tag<by_expiry>, BOOST_MULTI_INDEX_MEMBER( trx_cache_entry, fc::time_point, expiry ) >
>
>;

using decaying_accumulator = chain::resource_limits::impl::exponential_decay_accumulator<>;

struct subjective_billing_info {
uint64_t pending_cpu_us; // tracked cpu us for transactions that may still succeed in a block
uint64_t pending_cpu_us = 0; // tracked cpu us for transactions that may still succeed in a block
decaying_accumulator expired_accumulator; // accumulator used to account for transactions that have expired

bool empty(uint32_t time_ordinal, uint32_t expired_accumulator_average_window) {
bool empty(uint32_t time_ordinal, uint32_t expired_accumulator_average_window) const {
return pending_cpu_us == 0 && expired_accumulator.value_at(time_ordinal, expired_accumulator_average_window) == 0;
}
};

using account_subjective_bill_cache = std::map<account_name, subjective_billing_info>;
using block_subjective_bill_cache = std::map<account_name, uint64_t>;
using account_subjective_bill_cache = std::map<chain::account_name, subjective_billing_info>;

bool _disabled = false;
trx_cache_index _trx_cache_index;
account_subjective_bill_cache _account_subjective_bill_cache;
block_subjective_bill_cache _block_subjective_bill_cache;
std::set<chain::account_name> _disabled_accounts;
uint32_t _expired_accumulator_average_window = config::account_cpu_usage_average_window_ms / subjective_time_interval_ms;
uint32_t _expired_accumulator_average_window = chain::config::account_cpu_usage_average_window_ms / subjective_time_interval_ms;

private:
uint32_t time_ordinal_for( const fc::time_point& t ) const {
static uint32_t time_ordinal_for( const fc::time_point& t ) {
auto ordinal = t.time_since_epoch().count() / (1000U * (uint64_t)subjective_time_interval_ms);
EOS_ASSERT(ordinal <= std::numeric_limits<uint32_t>::max(), chain::tx_resource_exhaustion, "overflow of quantized time in subjective billing");
return ordinal;
Expand All @@ -88,11 +79,11 @@ class subjective_billing {
}
}

void remove_subjective_billing( const block_state_ptr& bsp, uint32_t time_ordinal ) {
void remove_subjective_billing( const chain::block_state_ptr& bsp, uint32_t time_ordinal ) {
if( !_trx_cache_index.empty() ) {
for( const auto& receipt : bsp->block->transactions ) {
if( std::holds_alternative<packed_transaction>(receipt.trx) ) {
const auto& pt = std::get<packed_transaction>(receipt.trx);
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 );
}
}
Expand All @@ -102,7 +93,7 @@ class subjective_billing {
public: // public for tests
static constexpr uint32_t subjective_time_interval_ms = 5'000;

void remove_subjective_billing( const transaction_id_type& trx_id, uint32_t time_ordinal ) {
void remove_subjective_billing( const chain::transaction_id_type& trx_id, uint32_t time_ordinal ) {
auto& idx = _trx_cache_index.get<by_id>();
auto itr = idx.find( trx_id );
if( itr != idx.end() ) {
Expand All @@ -114,11 +105,10 @@ class subjective_billing {
public:
void disable() { _disabled = true; }
void disable_account( chain::account_name a ) { _disabled_accounts.emplace( a ); }
bool is_account_disabled(const account_name& a ) const { return _disabled || _disabled_accounts.count( a ); }
bool is_account_disabled(const chain::account_name& a ) const { return _disabled || _disabled_accounts.count( a ); }

/// @param in_pending_block pass true if pt's bill time is accounted for in the pending block
void subjective_bill( const transaction_id_type& id, const fc::time_point& expire, const account_name& first_auth,
const fc::microseconds& elapsed, bool in_pending_block )
void subjective_bill( const chain::transaction_id_type& id, const fc::time_point& expire,
const chain::account_name& first_auth, const fc::microseconds& elapsed )
{
if( !_disabled && !_disabled_accounts.count( first_auth ) ) {
int64_t bill = std::max<int64_t>( 0, elapsed.count() );
Expand All @@ -129,14 +119,11 @@ class subjective_billing {
expire} );
if( p.second ) {
_account_subjective_bill_cache[first_auth].pending_cpu_us += bill;
if( in_pending_block ) {
_block_subjective_bill_cache[first_auth] += bill;
}
}
}
}

void subjective_bill_failure( const account_name& first_auth, const fc::microseconds& elapsed, const fc::time_point& now )
void subjective_bill_failure( const chain::account_name& first_auth, const fc::microseconds& elapsed, const fc::time_point& now )
{
if( !_disabled && !_disabled_accounts.count( first_auth ) ) {
int64_t bill = std::max<int64_t>( 0, elapsed.count() );
Expand All @@ -145,34 +132,27 @@ class subjective_billing {
}
}

int64_t get_subjective_bill( const account_name& first_auth, const fc::time_point& now ) const {
int64_t get_subjective_bill( const chain::account_name& first_auth, const fc::time_point& now ) const {
if( _disabled || _disabled_accounts.count( first_auth ) ) return 0;
const auto time_ordinal = time_ordinal_for(now);
const subjective_billing_info* sub_bill_info = nullptr;
auto aitr = _account_subjective_bill_cache.find( first_auth );
if( aitr != _account_subjective_bill_cache.end() ) {
sub_bill_info = &aitr->second;
}
uint64_t in_block_pending_cpu_us = 0;
auto bitr = _block_subjective_bill_cache.find( first_auth );
if( bitr != _block_subjective_bill_cache.end() ) {
in_block_pending_cpu_us = bitr->second;
}

if (sub_bill_info) {
EOS_ASSERT(sub_bill_info->pending_cpu_us >= in_block_pending_cpu_us, chain::tx_resource_exhaustion, "Logic error subjective billing ${a}", ("a", first_auth) );
int64_t sub_bill = sub_bill_info->pending_cpu_us - in_block_pending_cpu_us + sub_bill_info->expired_accumulator.value_at(time_ordinal, _expired_accumulator_average_window );
int64_t sub_bill = sub_bill_info->pending_cpu_us + sub_bill_info->expired_accumulator.value_at(time_ordinal, _expired_accumulator_average_window );
return sub_bill;
} else {
return 0;
}
}

void abort_block() {
_block_subjective_bill_cache.clear();
}

void on_block( fc::logger& log, const block_state_ptr& bsp, const fc::time_point& now ) {
void on_block( fc::logger& log, const chain::block_state_ptr& bsp, const fc::time_point& now ) {
if( bsp == nullptr || _disabled ) return;
const auto time_ordinal = time_ordinal_for(now);
const auto orig_count = _account_subjective_bill_cache.size();
Expand Down
14 changes: 5 additions & 9 deletions plugins/producer_plugin/producer_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1991,11 +1991,8 @@ producer_plugin_impl::push_transaction( const fc::time_point& block_deadline,
fc::microseconds max_trx_time = fc::milliseconds( _max_transaction_time_ms.load() );
if( max_trx_time.count() < 0 ) max_trx_time = fc::microseconds::maximum();

bool disable_subjective_billing = ( _pending_block_mode == pending_block_mode::producing )
|| disable_subjective_enforcement;

int64_t sub_bill = 0;
if( !disable_subjective_billing )
if( !disable_subjective_enforcement )
sub_bill = _subjective_billing.get_subjective_bill( first_auth, fc::time_point::now() );

auto prev_billed_cpu_time_us = trx->billed_cpu_time_us;
Expand Down Expand Up @@ -2027,7 +2024,7 @@ producer_plugin_impl::push_transaction( const fc::time_point& block_deadline,
if( failure_code != tx_duplicate::code_value ) {
fc_dlog( _trx_failed_trace_log, "Subjective bill for failed ${a}: ${b} elapsed ${t}us, time ${r}us",
("a",first_auth)("b",sub_bill)("t",trace->elapsed)("r", end - start));
if (!disable_subjective_billing)
if (!disable_subjective_enforcement) // subjectively bill failure when producing since not in objective cpu account billing
_subjective_billing.subjective_bill_failure( first_auth, trace->elapsed, fc::time_point::now() );

log_trx_results( trx, trace, start );
Expand All @@ -2052,10 +2049,9 @@ producer_plugin_impl::push_transaction( const fc::time_point& block_deadline,
("a",first_auth)("b",sub_bill)("t",trace->elapsed)("r", end - start));
_account_fails.add_success_time(end - start);
log_trx_results( trx, trace, start );
// if producing then trx is in the pending block and not immediately reverted
if (!disable_subjective_billing) {
_subjective_billing.subjective_bill( trx->id(), trx->packed_trx()->expiration(), first_auth, trace->elapsed,
_pending_block_mode == pending_block_mode::producing );
// if producing then trx is in objective cpu account billing
if (!disable_subjective_enforcement && _pending_block_mode != pending_block_mode::producing) {
_subjective_billing.subjective_bill( trx->id(), trx->packed_trx()->expiration(), first_auth, trace->elapsed );
}
if( next ) next( trace );
}
Expand Down
Loading

0 comments on commit b3a6e00

Please sign in to comment.