未验证 提交 342f0488 编写于 作者: K Kevin Heifner 提交者: GitHub

Merge pull request #5031 from EOSIO/master

Merge 1.1.3 into develop
......@@ -27,7 +27,7 @@ set( CXX_STANDARD_REQUIRED ON)
set(VERSION_MAJOR 1)
set(VERSION_MINOR 1)
set(VERSION_PATCH 2)
set(VERSION_PATCH 3)
set( CLI_CLIENT_EXECUTABLE_NAME cleos )
set( GUI_CLIENT_EXECUTABLE_NAME eosio )
......
......@@ -20,10 +20,10 @@ cd eos/Docker
docker build . -t eosio/eos
```
The above will build off the most recent commit to the master branch by default. If you would like to target a specific branch/tag, you may use a build argument. For example, if you wished to generate a docker image based off of the v1.1.2 tag, you could do the following:
The above will build off the most recent commit to the master branch by default. If you would like to target a specific branch/tag, you may use a build argument. For example, if you wished to generate a docker image based off of the v1.1.3 tag, you could do the following:
```bash
docker build -t eosio/eos:v1.1.2 --build-arg branch=v1.1.2 .
docker build -t eosio/eos:v1.1.3 --build-arg branch=v1.1.3 .
```
By default, the symbol in eosio.system is set to SYS. You can override this using the symbol argument while building the docker image.
......
......@@ -468,7 +468,9 @@ struct controller_impl {
transaction_trace_ptr apply_onerror( const generated_transaction& gtrx,
fc::time_point deadline,
fc::time_point start,
uint32_t billed_cpu_time_us) {
uint32_t& cpu_time_to_bill_us, // only set on failure
uint32_t billed_cpu_time_us,
bool explicit_billed_cpu_time = false ) {
signed_transaction etrx;
// Deliver onerror action containing the failed deferred transaction directly back to the sender.
etrx.actions.emplace_back( vector<permission_level>{{gtrx.sender, config::active_name}},
......@@ -478,6 +480,7 @@ struct controller_impl {
transaction_context trx_context( self, etrx, etrx.id(), start );
trx_context.deadline = deadline;
trx_context.explicit_billed_cpu_time = explicit_billed_cpu_time;
trx_context.billed_cpu_time_us = billed_cpu_time_us;
transaction_trace_ptr trace = trx_context.trace;
try {
......@@ -498,6 +501,7 @@ struct controller_impl {
restore.cancel();
return trace;
} catch( const fc::exception& e ) {
cpu_time_to_bill_us = trx_context.update_billed_cpu_time( fc::time_point::now() );
trace->except = e;
trace->except_ptr = std::current_exception();
}
......@@ -530,14 +534,14 @@ struct controller_impl {
|| (code == key_blacklist_exception::code_value);
}
transaction_trace_ptr push_scheduled_transaction( const transaction_id_type& trxid, fc::time_point deadline, uint32_t billed_cpu_time_us ) {
transaction_trace_ptr push_scheduled_transaction( const transaction_id_type& trxid, fc::time_point deadline, uint32_t billed_cpu_time_us, bool explicit_billed_cpu_time = false ) {
const auto& idx = db.get_index<generated_transaction_multi_index,by_trx_id>();
auto itr = idx.find( trxid );
EOS_ASSERT( itr != idx.end(), unknown_transaction_exception, "unknown transaction" );
return push_scheduled_transaction( *itr, deadline, billed_cpu_time_us );
return push_scheduled_transaction( *itr, deadline, billed_cpu_time_us, explicit_billed_cpu_time );
}
transaction_trace_ptr push_scheduled_transaction( const generated_transaction_object& gto, fc::time_point deadline, uint32_t billed_cpu_time_us )
transaction_trace_ptr push_scheduled_transaction( const generated_transaction_object& gto, fc::time_point deadline, uint32_t billed_cpu_time_us, bool explicit_billed_cpu_time = false )
{ try {
auto undo_session = db.start_undo_session(true);
auto gtrx = generated_transaction(gto);
......@@ -573,15 +577,16 @@ struct controller_impl {
});
in_trx_requiring_checks = true;
uint32_t cpu_time_to_bill_us = billed_cpu_time_us;
transaction_context trx_context( self, dtrx, gtrx.trx_id );
trx_context.leeway = fc::microseconds(0); // avoid stealing cpu resource
trx_context.leeway = fc::microseconds(0); // avoid stealing cpu resource
trx_context.deadline = deadline;
trx_context.explicit_billed_cpu_time = explicit_billed_cpu_time;
trx_context.billed_cpu_time_us = billed_cpu_time_us;
transaction_trace_ptr trace = trx_context.trace;
flat_set<account_name> bill_to_accounts;
try {
trx_context.init_for_deferred_trx( gtrx.published );
bill_to_accounts = trx_context.bill_to_accounts;
trx_context.exec();
trx_context.finalize(); // Automatically rounds up network and CPU usage in trace and bills payers if successful
......@@ -601,35 +606,48 @@ struct controller_impl {
restore.cancel();
return trace;
} catch( const fc::exception& e ) {
cpu_time_to_bill_us = trx_context.update_billed_cpu_time( fc::time_point::now() );
trace->except = e;
trace->except_ptr = std::current_exception();
trace->elapsed = fc::time_point::now() - trx_context.start;
}
trx_context.undo_session.undo();
// Only soft or hard failure logic below:
// Only subjective OR soft OR hard failure logic below:
if( gtrx.sender != account_name() && !failure_is_subjective(*trace->except)) {
// Attempt error handling for the generated transaction.
dlog("${detail}", ("detail", trace->except->to_detail_string()));
auto error_trace = apply_onerror( gtrx, deadline, trx_context.start, trx_context.billed_cpu_time_us );
auto error_trace = apply_onerror( gtrx, deadline, trx_context.pseudo_start, cpu_time_to_bill_us, billed_cpu_time_us, explicit_billed_cpu_time );
error_trace->failed_dtrx_trace = trace;
trace = error_trace;
if( !trace->except_ptr ) {
undo_session.squash();
return trace;
}
trace->elapsed = fc::time_point::now() - trx_context.start;
}
// Only hard failure OR subjective failure logic below:
// Only subjective OR hard failure logic below:
trace->elapsed = fc::time_point::now() - trx_context.start;
if (!failure_is_subjective(*trace->except)) {
// hard failure logic
resource_limits.add_transaction_usage( bill_to_accounts, trx_context.billed_cpu_time_us, 0,
block_timestamp_type(self.pending_block_time()).slot ); // Should never fail
if( !explicit_billed_cpu_time ) {
auto& rl = self.get_mutable_resource_limits_manager();
rl.update_account_usage( trx_context.bill_to_accounts, block_timestamp_type(self.pending_block_time()).slot );
int64_t account_cpu_limit = 0;
std::tie( std::ignore, account_cpu_limit, std::ignore ) = trx_context.max_bandwidth_billed_accounts_can_pay( true );
if (!failure_is_subjective(*trace->except)) {
trace->receipt = push_receipt(gtrx.trx_id, transaction_receipt::hard_fail, trx_context.billed_cpu_time_us, 0);
cpu_time_to_bill_us = static_cast<uint32_t>( std::min( std::min( static_cast<int64_t>(cpu_time_to_bill_us),
account_cpu_limit ),
trx_context.initial_objective_duration_limit.count() ) );
}
resource_limits.add_transaction_usage( trx_context.bill_to_accounts, cpu_time_to_bill_us, 0,
block_timestamp_type(self.pending_block_time()).slot ); // Should never fail
trace->receipt = push_receipt(gtrx.trx_id, transaction_receipt::hard_fail, cpu_time_to_bill_us, 0);
emit( self.applied_transaction, trace );
undo_session.squash();
}
......@@ -662,7 +680,8 @@ struct controller_impl {
transaction_trace_ptr push_transaction( const transaction_metadata_ptr& trx,
fc::time_point deadline,
bool implicit,
uint32_t billed_cpu_time_us)
uint32_t billed_cpu_time_us,
bool explicit_billed_cpu_time = false )
{
EOS_ASSERT(deadline != fc::time_point(), transaction_exception, "deadline cannot be uninitialized");
......@@ -673,6 +692,7 @@ struct controller_impl {
trx_context.leeway = *subjective_cpu_leeway;
}
trx_context.deadline = deadline;
trx_context.explicit_billed_cpu_time = explicit_billed_cpu_time;
trx_context.billed_cpu_time_us = billed_cpu_time_us;
trace = trx_context.trace;
try {
......@@ -811,7 +831,7 @@ struct controller_impl {
in_trx_requiring_checks = old_value;
});
in_trx_requiring_checks = true;
push_transaction( onbtrx, fc::time_point::maximum(), true, self.get_global_properties().configuration.min_transaction_cpu_usage );
push_transaction( onbtrx, fc::time_point::maximum(), true, self.get_global_properties().configuration.min_transaction_cpu_usage, true );
} catch( const boost::interprocess::bad_alloc& e ) {
elog( "on block transaction failed due to a bad allocation" );
throw;
......@@ -850,9 +870,9 @@ struct controller_impl {
if( receipt.trx.contains<packed_transaction>() ) {
auto& pt = receipt.trx.get<packed_transaction>();
auto mtrx = std::make_shared<transaction_metadata>(pt);
trace = push_transaction( mtrx, fc::time_point::maximum(), false, receipt.cpu_usage_us);
trace = push_transaction( mtrx, fc::time_point::maximum(), false, receipt.cpu_usage_us, true );
} else if( receipt.trx.contains<transaction_id_type>() ) {
trace = push_scheduled_transaction( receipt.trx.get<transaction_id_type>(), fc::time_point::maximum(), receipt.cpu_usage_us );
trace = push_scheduled_transaction( receipt.trx.get<transaction_id_type>(), fc::time_point::maximum(), receipt.cpu_usage_us, true );
} else {
EOS_ASSERT( false, block_validate_exception, "encountered unexpected receipt type" );
}
......@@ -1312,13 +1332,13 @@ void controller::push_confirmation( const header_confirmation& c ) {
transaction_trace_ptr controller::push_transaction( const transaction_metadata_ptr& trx, fc::time_point deadline, uint32_t billed_cpu_time_us ) {
validate_db_available_size();
return my->push_transaction(trx, deadline, false, billed_cpu_time_us);
return my->push_transaction(trx, deadline, false, billed_cpu_time_us, billed_cpu_time_us > 0 );
}
transaction_trace_ptr controller::push_scheduled_transaction( const transaction_id_type& trxid, fc::time_point deadline, uint32_t billed_cpu_time_us )
{
validate_db_available_size();
return my->push_scheduled_transaction( trxid, deadline, billed_cpu_time_us );
return my->push_scheduled_transaction( trxid, deadline, billed_cpu_time_us, billed_cpu_time_us > 0 );
}
const flat_set<account_name>& controller::get_actor_whitelist() const {
......
......@@ -39,6 +39,10 @@ namespace eosio { namespace chain {
void add_ram_usage( account_name account, int64_t ram_delta );
uint32_t update_billed_cpu_time( fc::time_point now );
std::tuple<int64_t, int64_t, bool> max_bandwidth_billed_accounts_can_pay( bool force_elastic_limits = false )const;
private:
friend struct controller_impl;
......@@ -81,6 +85,7 @@ namespace eosio { namespace chain {
fc::time_point deadline = fc::time_point::maximum();
fc::microseconds leeway = fc::microseconds(3000);
int64_t billed_cpu_time_us = 0;
bool explicit_billed_cpu_time = false;
private:
bool is_initialized = false;
......@@ -92,6 +97,7 @@ namespace eosio { namespace chain {
uint64_t eager_net_limit = 0;
uint64_t& net_usage; /// reference to trace->net_usage
fc::microseconds initial_objective_duration_limit;
fc::microseconds objective_duration_limit;
fc::time_point _deadline = fc::time_point::maximum();
int64_t deadline_exception_code = block_cpu_usage_exceeded::code_value;
......
......@@ -70,7 +70,9 @@ namespace eosio { namespace chain {
}
}
if( billed_cpu_time_us > 0 )
initial_objective_duration_limit = objective_duration_limit;
if( billed_cpu_time_us > 0 ) // could also call on explicit_billed_cpu_time but it would be redundant
validate_cpu_usage_to_bill( billed_cpu_time_us, false ); // Fail early if the amount to be billed is too high
// Record accounts to be billed for network and CPU usage
......@@ -85,17 +87,11 @@ namespace eosio { namespace chain {
rl.update_account_usage( bill_to_accounts, block_timestamp_type(control.pending_block_time()).slot );
// Calculate the highest network usage and CPU time that all of the billed accounts can afford to be billed
int64_t account_net_limit = large_number_no_overflow;
int64_t account_cpu_limit = large_number_no_overflow;
for( const auto& a : bill_to_accounts ) {
bool elastic = !(control.is_producing_block() && control.is_resource_greylisted(a));
auto net_limit = rl.get_account_net_limit(a, elastic);
if( net_limit >= 0 )
account_net_limit = std::min( account_net_limit, net_limit );
auto cpu_limit = rl.get_account_cpu_limit(a, elastic);
if( cpu_limit >= 0 )
account_cpu_limit = std::min( account_cpu_limit, cpu_limit );
}
int64_t account_net_limit = 0;
int64_t account_cpu_limit = 0;
bool greylisted = false;
std::tie( account_net_limit, account_cpu_limit, greylisted ) = max_bandwidth_billed_accounts_can_pay();
net_limit_due_to_greylist |= greylisted;
eager_net_limit = net_limit;
......@@ -115,7 +111,7 @@ namespace eosio { namespace chain {
billing_timer_duration_limit = _deadline - start;
// Check if deadline is limited by caller-set deadline (only change deadline if billed_cpu_time_us is not set)
if( billed_cpu_time_us > 0 || deadline < _deadline ) {
if( explicit_billed_cpu_time || deadline < _deadline ) {
_deadline = deadline;
deadline_exception_code = deadline_exception::code_value;
} else {
......@@ -203,7 +199,6 @@ namespace eosio { namespace chain {
void transaction_context::finalize() {
EOS_ASSERT( is_initialized, transaction_exception, "must first initialize" );
const static int64_t large_number_no_overflow = std::numeric_limits<int64_t>::max()/2;
if( is_input ) {
auto& am = control.get_mutable_authorization_manager();
......@@ -220,19 +215,11 @@ namespace eosio { namespace chain {
}
// Calculate the new highest network usage and CPU time that all of the billed accounts can afford to be billed
int64_t account_net_limit = large_number_no_overflow;
int64_t account_cpu_limit = large_number_no_overflow;
for( const auto& a : bill_to_accounts ) {
bool elastic = !(control.is_producing_block() && control.is_resource_greylisted(a));
auto net_limit = rl.get_account_net_limit(a, elastic);
if( net_limit >= 0 ) {
account_net_limit = std::min( account_net_limit, net_limit );
if (!elastic) net_limit_due_to_greylist = true;
}
auto cpu_limit = rl.get_account_cpu_limit(a, elastic);
if( cpu_limit >= 0 )
account_cpu_limit = std::min( account_cpu_limit, cpu_limit );
}
int64_t account_net_limit = 0;
int64_t account_cpu_limit = 0;
bool greylisted = false;
std::tie( account_net_limit, account_cpu_limit, greylisted ) = max_bandwidth_billed_accounts_can_pay();
net_limit_due_to_greylist |= greylisted;
// Possibly lower net_limit to what the billed accounts can pay
if( static_cast<uint64_t>(account_net_limit) <= net_limit ) {
......@@ -254,10 +241,7 @@ namespace eosio { namespace chain {
auto now = fc::time_point::now();
trace->elapsed = now - start;
if( billed_cpu_time_us == 0 ) {
const auto& cfg = control.get_global_properties().configuration;
billed_cpu_time_us = std::max( (now - pseudo_start).count(), static_cast<int64_t>(cfg.min_transaction_cpu_usage) );
}
update_billed_cpu_time( now );
validate_cpu_usage_to_bill( billed_cpu_time_us );
......@@ -295,7 +279,7 @@ namespace eosio { namespace chain {
auto now = fc::time_point::now();
if( BOOST_UNLIKELY( now > _deadline ) ) {
// edump((now-start)(now-pseudo_start));
if( billed_cpu_time_us > 0 || deadline_exception_code == deadline_exception::code_value ) {
if( explicit_billed_cpu_time || deadline_exception_code == deadline_exception::code_value ) {
EOS_THROW( deadline_exception, "deadline exceeded", ("now", now)("deadline", _deadline)("start", start) );
} else if( deadline_exception_code == block_cpu_usage_exceeded::code_value ) {
EOS_THROW( block_cpu_usage_exceeded,
......@@ -316,7 +300,7 @@ namespace eosio { namespace chain {
}
void transaction_context::pause_billing_timer() {
if( billed_cpu_time_us > 0 || pseudo_start == fc::time_point() ) return; // either irrelevant or already paused
if( explicit_billed_cpu_time || pseudo_start == fc::time_point() ) return; // either irrelevant or already paused
auto now = fc::time_point::now();
billed_time = now - pseudo_start;
......@@ -325,7 +309,7 @@ namespace eosio { namespace chain {
}
void transaction_context::resume_billing_timer() {
if( billed_cpu_time_us > 0 || pseudo_start != fc::time_point() ) return; // either irrelevant or already running
if( explicit_billed_cpu_time || pseudo_start != fc::time_point() ) return; // either irrelevant or already running
auto now = fc::time_point::now();
pseudo_start = now - billed_time;
......@@ -370,6 +354,39 @@ namespace eosio { namespace chain {
}
}
uint32_t transaction_context::update_billed_cpu_time( fc::time_point now ) {
if( explicit_billed_cpu_time ) return static_cast<uint32_t>(billed_cpu_time_us);
const auto& cfg = control.get_global_properties().configuration;
billed_cpu_time_us = std::max( (now - pseudo_start).count(), static_cast<int64_t>(cfg.min_transaction_cpu_usage) );
return static_cast<uint32_t>(billed_cpu_time_us);
}
std::tuple<int64_t, int64_t, bool> transaction_context::max_bandwidth_billed_accounts_can_pay( bool force_elastic_limits )const {
// Assumes rl.update_account_usage( bill_to_accounts, block_timestamp_type(control.pending_block_time()).slot ) was already called prior
// Calculate the new highest network usage and CPU time that all of the billed accounts can afford to be billed
auto& rl = control.get_mutable_resource_limits_manager();
const static int64_t large_number_no_overflow = std::numeric_limits<int64_t>::max()/2;
int64_t account_net_limit = large_number_no_overflow;
int64_t account_cpu_limit = large_number_no_overflow;
bool greylisted = false;
for( const auto& a : bill_to_accounts ) {
bool elastic = force_elastic_limits || !(control.is_producing_block() && control.is_resource_greylisted(a));
auto net_limit = rl.get_account_net_limit(a, elastic);
if( net_limit >= 0 ) {
account_net_limit = std::min( account_net_limit, net_limit );
if (!elastic) greylisted = true;
}
auto cpu_limit = rl.get_account_cpu_limit(a, elastic);
if( cpu_limit >= 0 )
account_cpu_limit = std::min( account_cpu_limit, cpu_limit );
}
return std::make_tuple(account_net_limit, account_cpu_limit, greylisted);
}
void transaction_context::dispatch_action( action_trace& trace, const action& a, account_name receiver, bool context_free, uint32_t recurse_depth ) {
apply_context acontext( control, *this, a, recurse_depth );
acontext.context_free = context_free;
......
......@@ -216,7 +216,7 @@
done
fi
printf "\\tInstalling boost libraries.\\n"
if ! "${BREW}" install boost
if ! "${BREW}" install https://raw.githubusercontent.com/Homebrew/homebrew-core/f946d12e295c8a27519b73cc810d06593270a07f/Formula/boost.rb
then
printf "\\tUnable to install boost 1.67 libraries at this time. 0\\n"
printf "\\tExiting now.\\n\\n"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册