Compare commits

...

57 Commits

Author SHA1 Message Date
Lin Huang 95077ed429 Bump Leap to release/3.1.5 2023-07-12 09:25:47 -04:00
Lin Huang 05e6cc8c18 Update eos-vm to release/3.x 2023-07-12 09:25:10 -04:00
Lin Huang 5caf5833ad A companion Leap changes for fixing WASM memory exhaustion 2023-07-12 09:18:25 -04:00
Peter Oschwald ed854f2bbd Merge pull request #1291 from AntelopeIO/pinned-builds-workflow-in-ci
[3.1] Pinned Builds manual dispatch workflow in CI
2023-06-22 11:38:59 -05:00
Peter Oschwald e3976b8dc1 Merge pull request #1310 from AntelopeIO/pinned_build_install_prefix_knob
[3.1] `CMAKE_INSTALL_PREFIX=/usr` for pinned builds in CI
2023-06-22 10:59:43 -05:00
Peter Oschwald 02c43ca656 Use enf-x86-beefy-long runner 2023-06-22 09:30:09 -05:00
Peter Oschwald 1ec98976b1 Try newly added self hosted runner for pinned builds. 2023-06-16 14:42:43 -05:00
Peter Oschwald 93833b8e03 Simplify naming and path matching for artifact. 2023-06-16 14:14:55 -05:00
Matt Witherspoon d6cd2c9a7d LEAP_PINNED_INSTALL_PREFIX knob to set pinned_build.sh CMAKE_INSTALL_PREFIX 2023-06-15 22:37:09 -04:00
Peter Oschwald ae2679e164 Cleanup. 2023-06-15 16:13:03 -05:00
Peter Oschwald 0f25eaa33a Remove quotes from path for upload. 2023-06-15 14:13:06 -05:00
Peter Oschwald b7b4554a18 Fix spelling causing issue with GITHUB_ENV. And trying again to get artifact name correctly. 2023-06-15 12:35:43 -05:00
Peter Oschwald 20e59a92bc Not finding deb packages. check dir structure some more. 2023-06-15 10:49:04 -05:00
Peter Oschwald 31fd1361aa Something is not matching up with expected dir or file structure. 2023-06-15 08:00:00 -05:00
Peter Oschwald 449f37133b Skip wildcards in upload-artifact and capture artifact name with regex grep and store in env variable. 2023-06-14 16:44:42 -05:00
Peter Oschwald feeee5eb8f Say yes. 2023-06-14 15:37:38 -05:00
Peter Oschwald 32de87b185 Update package lists first. 2023-06-14 15:35:28 -05:00
Peter Oschwald 78dd785035 Need software-properties-common and a apt-get update to get add-apt-repository to work. 2023-06-14 15:34:06 -05:00
Peter Oschwald f4b39ea29e Use single quotes. 2023-06-14 15:30:35 -05:00
Peter Oschwald 20f45e5923 Add conditional step to add updated apt repository for git.
Ubuntu 18.04 installs  git 2.17.1, but need 2.18+ for git submodules to work.
2023-06-14 15:27:18 -05:00
Peter Oschwald fc2166a46d Merge branch 'init-pinned-builds-workflow-in-ci' into pinned-builds-workflow-in-ci 2023-06-14 13:58:18 -05:00
Peter Oschwald 39a5ba846a Have to have a job for github. Add temp job. 2023-06-14 13:57:00 -05:00
Peter Oschwald e4b28a7854 Remove empty jobs section. 2023-06-14 13:54:13 -05:00
Peter Oschwald e4819c35e1 Merge branch 'init-pinned-builds-workflow-in-ci' into pinned-builds-workflow-in-ci 2023-06-14 13:51:11 -05:00
Peter Oschwald 7b7027cbee Not using cached build environments so removing this job. 2023-06-14 13:49:33 -05:00
Peter Oschwald 74fb1615d8 Add pinned to artifact name and don't upload dev artifact by filtering out in regex. 2023-06-14 13:02:32 -05:00
Peter Oschwald 5523010cfd Fix syntax and forgotten run command. 2023-06-14 13:00:00 -05:00
Peter Oschwald 7c106605cc Not using cached build environments so removing this job. 2023-06-14 12:16:11 -05:00
Peter Oschwald 9047d1175b For now run on github runner. 2023-06-14 12:05:12 -05:00
Peter Oschwald da6a068639 Script already runs cpack, remove. Break artifact check into own step for easier removal in future. 2023-06-14 12:03:27 -05:00
Peter Oschwald a886743005 Initial work to run pinned_build script on base images.
Build package and upload artifacts.
2023-06-14 11:44:53 -05:00
Peter Oschwald 0dbfb1a6ed Creating a shell of the initial pinned_build.yaml workflow to be merged quickly allowing development of actual workflow in follow on branch.
Need to have workflow file merged before github will allow triggering it in a development branch.
2023-06-14 11:26:08 -05:00
Huang-Ming Huang 9d1ea27ed7 Merge pull request #777 from AntelopeIO/huangminghuang/strike-rule
[3.1] subjective-account-max-failures-window-size
2023-03-07 08:19:34 -06:00
Huang-Ming Huang 71548a6425 Merge branch 'release/3.1' into huangminghuang/strike-rule 2023-03-06 09:37:22 -06:00
Huang-Ming Huang 72c5d299fe add reset time until back 2023-03-06 09:12:30 -06:00
Huang-Ming Huang 5cf31c9929 address PR comment 2023-03-06 08:21:26 -06:00
Kevin Heifner 941b525093 Merge pull request #773 from AntelopeIO/GH-768-logging-3.1
[3.1] Move subjective bill log to `all` level of `producer_plugin` logger.
2023-03-04 13:42:53 -06:00
Kevin Heifner e377339f04 GH-768 Move subjective bill log to all level of producer_plugin logger. 2023-03-03 07:10:23 -06:00
Huang-Ming Huang fcbdb0ae98 subjective-account-max-failures-window-size 2023-03-01 06:13:02 -06:00
Gregory Popovitch ecc5c4ec11 Merge pull request #754 from AntelopeIO/gh-513_rel3.1
[3.1] keosd - Exit program if keosd fails to aquire wallet lock (GH #513)
2023-02-27 10:39:15 -05:00
greg7mdp caa01ca443 main() should return if appbase initialization fails. 2023-02-25 14:39:25 -05:00
Alexander Molchevsky 3e585d0f8a Merge pull request #747 from AntelopeIO/update_bios_boot_tutorial3.1
Backport to 3.1 of bootstrap new protocol features activation
2023-02-24 12:38:21 +02:00
Alexander Molchevsky 967ab869e0 Backport to 3.1 of bootstrap new protocol features activation 2023-02-24 00:42:48 +02:00
Kevin Heifner 0d977585ce Merge pull request #700 from AntelopeIO/GH-695-dirty-db-3.1
[3.1] Fix reporting of dirty db
2023-02-10 08:15:54 -06:00
Kevin Heifner a357765c73 GH-695 Report dirty-db correctly 2023-02-08 08:07:14 -06:00
766C6164 280d799958 Added comment on why non-propagating system_error 2023-02-08 08:03:43 -06:00
766C6164 f694588f9f Propagate all exceptions minus system_error 2023-02-08 08:03:38 -06:00
Kevin Heifner 26025d7382 Merge pull request #684 from AntelopeIO/GH-662-terminate-at-block-3.1
[3.1] Fix --terminate-at-block to stop at correct block
2023-02-04 15:17:10 -06:00
Kevin Heifner 517ef20396 GH-662 Fixes for terminate-scenarios-test 2023-02-03 16:01:08 -06:00
Kevin Heifner 6f16383453 GH-662 Fix terminate-at-block test 2023-02-03 14:10:57 -06:00
Kevin Heifner debba62dd8 GH-662 Fix terminate-at-block to terminate at correct block 2023-02-03 14:10:38 -06:00
Kevin Heifner 343596a0c1 Merge pull request #676 from AntelopeIO/GH-588-handshake-3.1
[3.1] net_plugin improve block latency calculation
2023-02-02 14:47:12 -06:00
Kevin Heifner ec27d3d1f3 GH-588 Round using lround instead of the original hardcoded +1 2023-02-01 15:10:23 -06:00
Kevin Heifner f347ab534e GH-588 Add additional logging that would be helpful for debugging 2023-02-01 13:42:13 -06:00
Kevin Heifner 3db765e0f1 GH-588 Remove +1 to number of blocks latency calculation. With it 0 latency indicates 1 block latency. 2023-01-31 07:44:20 -06:00
Kevin Heifner 0dbd5cf68c Merge pull request #667 from AntelopeIO/GH-631-fork-test-3.1
[3.1] Test fix: nodeos_forked_chain_lr_test
2023-01-27 13:30:03 -06:00
Kevin Heifner da2a1dc996 GH-631 Update preKill info since waiting for producer to change before continuing. 2023-01-26 13:29:19 -06:00
17 changed files with 214 additions and 122 deletions
+58
View File
@@ -0,0 +1,58 @@
name: "Pinned Build"
on:
workflow_dispatch:
permissions:
packages: read
contents: read
defaults:
run:
shell: bash
jobs:
Build:
name: Build
strategy:
fail-fast: false
matrix:
platform: [ubuntu18, ubuntu20, ubuntu22]
runs-on: ["self-hosted", "enf-x86-beefy-long"]
container: ${{ matrix.platform == 'ubuntu18' && 'ubuntu:bionic' || matrix.platform == 'ubuntu20' && 'ubuntu:focal' || 'ubuntu:jammy' }}
steps:
- name: Conditionally update git repo
if: ${{ matrix.platform == 'ubuntu18' }}
run: |
apt-get update
apt-get install -y software-properties-common
apt-get update
add-apt-repository ppa:git-core/ppa
- name: Update and Install git
run: |
apt-get update
apt-get install -y git
git --version
- name: Clone leap
uses: actions/checkout@v3
with:
submodules: recursive
- name: Install dependencies
run: |
# https://github.com/actions/runner/issues/2033
chown -R $(id -u):$(id -g) $PWD
./scripts/install_deps.sh
- name: Build Pinned Build
env:
LEAP_PINNED_INSTALL_PREFIX: /usr
run: |
./scripts/pinned_build.sh deps build "$(nproc)"
- name: Upload package
uses: actions/upload-artifact@v3
with:
name: leap-${{matrix.platform}}-pinned-amd64
path: build/leap-3*.deb
- name: Run Parallel Tests
run: |
cd build
ctest --output-on-failure -j $(nproc) -LE "(nonparallelizable_tests|long_running_tests)" --timeout 420
+1 -1
View File
@@ -15,7 +15,7 @@ set( CXX_STANDARD_REQUIRED ON)
set(VERSION_MAJOR 3)
set(VERSION_MINOR 1)
set(VERSION_PATCH 4)
set(VERSION_PATCH 5)
#set(VERSION_SUFFIX rc4)
if(VERSION_SUFFIX)
+10 -6
View File
@@ -2125,7 +2125,7 @@ struct controller_impl {
EOS_ASSERT( bsp, block_validate_exception, "null block" );
const auto& b = bsp->block;
if( conf.terminate_at_block > 0 && conf.terminate_at_block < self.head_block_num()) {
if( conf.terminate_at_block > 0 && conf.terminate_at_block <= self.head_block_num()) {
ilog("Reached configured maximum block ${num}; terminating", ("num", conf.terminate_at_block) );
shutdown();
return;
@@ -2160,7 +2160,7 @@ struct controller_impl {
EOS_ASSERT( (s == controller::block_status::irreversible || s == controller::block_status::validated),
block_validate_exception, "invalid block status for replay" );
if( conf.terminate_at_block > 0 && conf.terminate_at_block < self.head_block_num() ) {
if( conf.terminate_at_block > 0 && conf.terminate_at_block <= self.head_block_num() ) {
ilog("Reached configured maximum block ${num}; terminating", ("num", conf.terminate_at_block) );
shutdown();
return;
@@ -3494,10 +3494,14 @@ std::optional<chain_id_type> controller::extract_chain_id_from_db( const path& s
if( db.revision() < 1 ) return {};
return db.get<global_property_object>().chain_id;
} catch( const bad_database_version_exception& ) {
throw;
} catch( ... ) {
auto * gpo = db.find<global_property_object>();
if (gpo==nullptr) return {};
return gpo->chain_id;
} catch( const std::system_error& e ) {
// do not propagate db_error_code::not_found for absent db, so it will be created
if( e.code().value() != chainbase::db_error_code::not_found )
throw;
}
return {};
@@ -84,7 +84,7 @@ namespace eosio { namespace chain {
bool allow_ram_billing_in_notify = false;
uint32_t maximum_variable_signature_length = chain::config::default_max_variable_signature_length;
bool disable_all_subjective_mitigations = false; //< for developer & testing purposes, can be configured using `disable-all-subjective-mitigations` when `EOSIO_DEVELOPER` build option is provided
uint32_t terminate_at_block = 0; //< primarily for testing purposes
uint32_t terminate_at_block = 0;
wasm_interface::vm_type wasm_runtime = chain::config::default_wasm_runtime;
eosvmoc::config eosvmoc_config;
@@ -247,7 +247,7 @@ std::unique_ptr<wasm_instantiated_module_interface> eos_vm_runtime<Impl>::instan
wasm_code_ptr code((uint8_t*)code_bytes, code_size);
apply_options options = { .max_pages = 65536,
.max_call_depth = 0 };
std::unique_ptr<backend_t> bkend = std::make_unique<backend_t>(code, code_size, nullptr, options);
std::unique_ptr<backend_t> bkend = std::make_unique<backend_t>(code, code_size, nullptr, options, false); // uses 2-passes parsing
eos_vm_host_functions_t::resolve(bkend->get_module());
return std::make_unique<eos_vm_instantiated_module<Impl>>(this, std::move(bkend));
} catch(eosio::vm::exception& e) {
@@ -273,7 +273,7 @@ std::unique_ptr<wasm_instantiated_module_interface> eos_vm_profile_runtime::inst
wasm_code_ptr code((uint8_t*)code_bytes, code_size);
apply_options options = { .max_pages = 65536,
.max_call_depth = 0 };
std::unique_ptr<backend_t> bkend = std::make_unique<backend_t>(code, code_size, nullptr, options);
std::unique_ptr<backend_t> bkend = std::make_unique<backend_t>(code, code_size, nullptr, options, false); // uses 2-passes parsing
eos_vm_host_functions_t::resolve(bkend->get_module());
return std::make_unique<eos_vm_profiling_module>(std::move(bkend), code_bytes, code_size);
} catch(eosio::vm::exception& e) {
+20 -16
View File
@@ -26,6 +26,7 @@
#include <boost/asio/steady_timer.hpp>
#include <atomic>
#include <cmath>
#include <shared_mutex>
using namespace eosio::chain::plugin_interface;
@@ -1776,7 +1777,6 @@ namespace eosio {
if( c->is_transactions_only_connection() ) return;
uint32_t lib_num = 0;
uint32_t peer_lib = msg.last_irreversible_block_num;
uint32_t head = 0;
block_id_type head_id;
std::tie( lib_num, std::ignore, head,
@@ -1790,10 +1790,10 @@ namespace eosio {
peer_wlog(c, "Peer sent a handshake with a timestamp skewed by at least ${t}ms", ("t", network_latency_ns/1000000));
network_latency_ns = 0;
}
// number of blocks syncing node is behind from a peer node
uint32_t nblk_behind_by_net_latency = static_cast<uint32_t>(network_latency_ns / block_interval_ns);
// 2x for time it takes for message to reach back to peer node, +1 to compensate for integer division truncation
uint32_t nblk_combined_latency = 2 * nblk_behind_by_net_latency + 1;
// number of blocks syncing node is behind from a peer node, round up
uint32_t nblk_behind_by_net_latency = std::lround( static_cast<double>(network_latency_ns) / static_cast<double>(block_interval_ns) );
// 2x for time it takes for message to reach back to peer node
uint32_t nblk_combined_latency = 2 * nblk_behind_by_net_latency;
// message in the log below is used in p2p_high_latency_test.py test
peer_dlog(c, "Network latency is ${lat}ms, ${num} blocks discrepancy by network latency, ${tot_num} blocks discrepancy expected once message received",
("lat", network_latency_ns/1000000)("num", nblk_behind_by_net_latency)("tot_num", nblk_combined_latency));
@@ -1813,8 +1813,8 @@ namespace eosio {
//-----------------------------
if (head_id == msg.head_id) {
peer_ilog( c, "handshake lib ${lib}, head ${head}, head id ${id}.. sync 0",
("lib", msg.last_irreversible_block_num)("head", msg.head_num)("id", msg.head_id.str().substr(8,16)) );
peer_ilog( c, "handshake lib ${lib}, head ${head}, head id ${id}.. sync 0, lib ${l}",
("lib", msg.last_irreversible_block_num)("head", msg.head_num)("id", msg.head_id.str().substr(8,16))("l", lib_num) );
c->syncing = false;
notice_message note;
note.known_blocks.mode = none;
@@ -1823,9 +1823,10 @@ namespace eosio {
c->enqueue( note );
return;
}
if (head < peer_lib) {
peer_ilog( c, "handshake lib ${lib}, head ${head}, head id ${id}.. sync 1",
("lib", msg.last_irreversible_block_num)("head", msg.head_num)("id", msg.head_id.str().substr(8,16)) );
if (head < msg.last_irreversible_block_num) {
peer_ilog( c, "handshake lib ${lib}, head ${head}, head id ${id}.. sync 1, head ${h}, lib ${l}",
("lib", msg.last_irreversible_block_num)("head", msg.head_num)("id", msg.head_id.str().substr(8,16))
("h", head)("l", lib_num) );
c->syncing = false;
if (c->sent_handshake_count > 0) {
c->send_handshake();
@@ -1833,8 +1834,9 @@ namespace eosio {
return;
}
if (lib_num > msg.head_num + nblk_combined_latency) {
peer_ilog( c, "handshake lib ${lib}, head ${head}, head id ${id}.. sync 2",
("lib", msg.last_irreversible_block_num)("head", msg.head_num)("id", msg.head_id.str().substr(8,16)) );
peer_ilog( c, "handshake lib ${lib}, head ${head}, head id ${id}.. sync 2, head ${h}, lib ${l}",
("lib", msg.last_irreversible_block_num)("head", msg.head_num)("id", msg.head_id.str().substr(8,16))
("h", head)("l", lib_num) );
if (msg.generation > 1 || c->protocol_version > proto_base) {
notice_message note;
note.known_trx.pending = lib_num;
@@ -1848,14 +1850,16 @@ namespace eosio {
}
if (head + nblk_combined_latency < msg.head_num ) {
peer_ilog( c, "handshake lib ${lib}, head ${head}, head id ${id}.. sync 3",
("lib", msg.last_irreversible_block_num)("head", msg.head_num)("id", msg.head_id.str().substr(8,16)) );
peer_ilog( c, "handshake lib ${lib}, head ${head}, head id ${id}.. sync 3, head ${h}, lib ${l}",
("lib", msg.last_irreversible_block_num)("head", msg.head_num)("id", msg.head_id.str().substr(8,16))
("h", head)("l", lib_num) );
c->syncing = false;
verify_catchup(c, msg.head_num, msg.head_id);
return;
} else if(head >= msg.head_num + nblk_combined_latency) {
peer_ilog( c, "handshake lib ${lib}, head ${head}, head id ${id}.. sync 4",
("lib", msg.last_irreversible_block_num)("head", msg.head_num)("id", msg.head_id.str().substr(8,16)) );
peer_ilog( c, "handshake lib ${lib}, head ${head}, head id ${id}.. sync 4, head ${h}, lib ${l}",
("lib", msg.last_irreversible_block_num)("head", msg.head_num)("id", msg.head_id.str().substr(8,16))
("h", head)("l", lib_num) );
if (msg.generation > 1 || c->protocol_version > proto_base) {
notice_message note;
note.known_trx.mode = none;
+51 -26
View File
@@ -41,6 +41,13 @@ using std::vector;
using std::deque;
using boost::signals2::scoped_connection;
// in release/3.2+ move to fc logger.hpp
#define fc_tlog( LOGGER, FORMAT, ... ) \
FC_MULTILINE_MACRO_BEGIN \
if( (LOGGER).is_enabled( fc::log_level::all ) ) \
(LOGGER).log( FC_LOG_MESSAGE( all, FORMAT, __VA_ARGS__ ) ); \
FC_MULTILINE_MACRO_END
#undef FC_LOG_AND_DROP
#define LOG_AND_DROP() \
catch ( const guard_exception& e ) { \
@@ -197,8 +204,9 @@ public:
{
}
void set_max_failures_per_account( uint32_t max_failures ) {
max_failures_per_account = max_failures;
void set_max_failures_per_account( uint32_t max_failures, uint32_t size ) {
max_failures_per_account = max_failures;
reset_window_size_in_num_blocks = size;
}
void add( const account_name& n, int64_t exception_code ) {
@@ -218,10 +226,24 @@ public:
return false;
}
void report() const {
if( _log.is_enabled( fc::log_level::debug ) ) {
void report_and_clear(uint32_t block_num) {
if (last_reset_block_num != block_num && (block_num % reset_window_size_in_num_blocks == 0) ) {
report(block_num);
failed_accounts.clear();
last_reset_block_num = block_num;
}
}
fc::time_point next_reset_timepoint(uint32_t current_block_num, fc::time_point current_block_time) const {
auto num_blocks_to_reset = reset_window_size_in_num_blocks - (current_block_num % reset_window_size_in_num_blocks);
return current_block_time + fc::milliseconds(num_blocks_to_reset * eosio::chain::config::block_interval_ms);
}
private:
void report(uint32_t block_num) const {
if( _log.is_enabled(fc::log_level::debug)) {
auto now = fc::time_point::now();
for( const auto& e : failed_accounts ) {
for ( const auto& e : failed_accounts ) {
std::string reason;
if( e.second.is_deadline() ) reason += "deadline";
if( e.second.is_tx_cpu_usage() ) {
@@ -242,12 +264,6 @@ public:
}
}
}
void clear() {
failed_accounts.clear();
}
private:
struct account_failure {
enum class ex_fields : uint8_t {
ex_deadline_exception = 1,
@@ -282,6 +298,8 @@ private:
std::map<account_name, account_failure> failed_accounts;
uint32_t max_failures_per_account = 3;
uint32_t last_reset_block_num = 0;
uint32_t reset_window_size_in_num_blocks = 1;
const eosio::subjective_billing& subjective_billing;
};
@@ -675,8 +693,9 @@ class producer_plugin_impl : public std::enable_shared_from_this<producer_plugin
auto first_auth = trx->packed_trx()->get_transaction().first_authorizer();
if( _account_fails.failure_limit( first_auth ) ) {
send_response( std::static_pointer_cast<fc::exception>( std::make_shared<tx_cpu_usage_exceeded>(
FC_LOG_MESSAGE( error, "transaction ${id} exceeded failure limit for account ${a}",
("id", trx->id())("a", first_auth) ) ) ) );
FC_LOG_MESSAGE( error, "transaction ${id} exceeded failure limit for account ${a} until ${next_reset_time}",
("id", trx->id())("a", first_auth)
("next_reset_time", _account_fails.next_reset_timepoint(chain.head_block_num(),chain.head_block_time())) ) ) ) );
return true;
}
@@ -696,7 +715,7 @@ class producer_plugin_impl : public std::enable_shared_from_this<producer_plugin
auto prev_billed_cpu_time_us = trx->billed_cpu_time_us;
auto trace = chain.push_transaction( trx, block_deadline, max_trx_time, prev_billed_cpu_time_us, false, sub_bill );
fc_dlog( _trx_failed_trace_log, "Subjective bill for ${a}: ${b} elapsed ${t}us", ("a",first_auth)("b",sub_bill)("t",trace->elapsed));
fc_tlog( _log, "Subjective bill for ${a}: ${b} elapsed ${t}us", ("a",first_auth)("b",sub_bill)("t",trace->elapsed));
if( trace->except ) {
if( exception_is_exhausted( *trace->except ) ) {
_unapplied_transactions.add_incoming( trx, persist_until_expired, return_failure_traces, next );
@@ -879,7 +898,9 @@ void producer_plugin::set_program_options(
("subjective-cpu-leeway-us", boost::program_options::value<int32_t>()->default_value( config::default_subjective_cpu_leeway_us ),
"Time in microseconds allowed for a transaction that starts with insufficient CPU quota to complete and cover its CPU usage.")
("subjective-account-max-failures", boost::program_options::value<uint32_t>()->default_value(3),
"Sets the maximum amount of failures that are allowed for a given account per block.")
"Sets the maximum amount of failures that are allowed for a given account per window size.")
("subjective-account-max-failures-window-size", boost::program_options::value<uint32_t>()->default_value(1),
"Sets the window size in number of blocks for subjective-account-max-failures.")
("subjective-account-decay-time-minutes", bpo::value<uint32_t>()->default_value( config::account_cpu_usage_average_window_ms / 1000 / 60 ),
"Sets the time to return full subjective cpu for accounts")
("incoming-defer-ratio", bpo::value<double>()->default_value(1.0),
@@ -1029,7 +1050,13 @@ void producer_plugin::plugin_initialize(const boost::program_options::variables_
my->_keosd_provider_timeout_us = fc::milliseconds(options.at("keosd-provider-timeout").as<int32_t>());
my->_account_fails.set_max_failures_per_account( options.at("subjective-account-max-failures").as<uint32_t>() );
auto subjective_account_max_failures_window_size = options.at("subjective-account-max-failures-window-size").as<uint32_t>();
EOS_ASSERT( subjective_account_max_failures_window_size > 0, plugin_config_exception,
"subjective-account-max-failures-window-size ${s} must be greater than 0", ("s", subjective_account_max_failures_window_size) );
my->_account_fails.set_max_failures_per_account( options.at("subjective-account-max-failures").as<uint32_t>(),
subjective_account_max_failures_window_size );
my->_produce_time_offset_us = options.at("produce-time-offset-us").as<int32_t>();
EOS_ASSERT( my->_produce_time_offset_us <= 0 && my->_produce_time_offset_us >= -config::block_interval_us, plugin_config_exception,
@@ -1685,7 +1712,7 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() {
const auto& hbs = chain.head_block_state();
if( chain.get_terminate_at_block() > 0 && chain.get_terminate_at_block() < chain.head_block_num() ) {
if( chain.get_terminate_at_block() > 0 && chain.get_terminate_at_block() <= chain.head_block_num() ) {
ilog("Reached configured maximum block ${num}; terminating", ("num", chain.get_terminate_at_block()));
app().quit();
return start_block_result::failed;
@@ -1852,7 +1879,7 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() {
}
try {
_account_fails.clear();
_account_fails.report_and_clear(hbs->block_num);
if( !remove_expired_trxs( preprocess_deadline ) )
return start_block_result::exhausted;
@@ -2025,8 +2052,9 @@ bool producer_plugin_impl::process_unapplied_trxs( const fc::time_point& deadlin
++num_failed;
if( itr->next ) {
itr->next( std::make_shared<tx_cpu_usage_exceeded>(
FC_LOG_MESSAGE( error, "transaction ${id} exceeded failure limit for account ${a}",
("id", trx->id())("a", first_auth) ) ) );
FC_LOG_MESSAGE( error, "transaction ${id} exceeded failure limit for account ${a} until ${next_reset_time}",
("id", trx->id())("a", first_auth)
("next_reset_time", _account_fails.next_reset_timepoint(chain.head_block_num(),chain.head_block_time())) ) ) );
}
itr = _unapplied_transactions.erase( itr );
continue;
@@ -2049,7 +2077,7 @@ bool producer_plugin_impl::process_unapplied_trxs( const fc::time_point& deadlin
|| trx->read_only;
auto trace = chain.push_transaction( trx, deadline, max_trx_time, prev_billed_cpu_time_us, false, sub_bill );
fc_dlog( _trx_failed_trace_log, "Subjective unapplied bill for ${a}: ${b} prev ${t}us", ("a",first_auth)("b",prev_billed_cpu_time_us)("t",trace->elapsed));
fc_tlog( _log, "Subjective unapplied bill for ${a}: ${b} prev ${t}us", ("a",first_auth)("b",prev_billed_cpu_time_us)("t",trace->elapsed));
if( trace->except ) {
if( exception_is_exhausted( *trace->except ) ) {
if( block_is_exhausted() ) {
@@ -2058,7 +2086,7 @@ bool producer_plugin_impl::process_unapplied_trxs( const fc::time_point& deadlin
break;
}
} else {
fc_dlog( _trx_failed_trace_log, "Subjective unapplied bill for failed ${a}: ${b} prev ${t}us", ("a",first_auth)("b",prev_billed_cpu_time_us)("t",trace->elapsed));
fc_tlog( _log, "Subjective unapplied bill for failed ${a}: ${b} prev ${t}us", ("a",first_auth)("b",prev_billed_cpu_time_us)("t",trace->elapsed));
auto failure_code = trace->except->code();
if( failure_code != tx_duplicate::code_value ) {
// this failed our configured maximum transaction time, we don't want to replay it
@@ -2077,7 +2105,7 @@ bool producer_plugin_impl::process_unapplied_trxs( const fc::time_point& deadlin
continue;
}
} else {
fc_dlog( _trx_successful_trace_log, "Subjective unapplied bill for success ${a}: ${b} prev ${t}us", ("a",first_auth)("b",prev_billed_cpu_time_us)("t",trace->elapsed));
fc_tlog( _log, "Subjective unapplied bill for success ${a}: ${b} prev ${t}us", ("a",first_auth)("b",prev_billed_cpu_time_us)("t",trace->elapsed));
// if db_read_mode SPECULATIVE 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,
@@ -2439,9 +2467,6 @@ void producer_plugin_impl::produce_block() {
block_state_ptr new_bs = chain.head_block_state();
_account_fails.report();
_account_fails.clear();
ilog("Produced block ${id}... #${n} @ ${t} signed by ${p} [trxs: ${count}, lib: ${lib}, confirmed: ${confs}]",
("p",new_bs->header.producer)("id",new_bs->id.str().substr(8,16))
("n",new_bs->block_num)("t",new_bs->header.timestamp)
+12
View File
@@ -71,6 +71,17 @@ bfs::path determine_home_directory()
return home;
}
enum return_codes {
OTHER_FAIL = -2,
INITIALIZE_FAIL = -1,
SUCCESS = 0,
BAD_ALLOC = 1,
DATABASE_DIRTY = 2,
FIXED_REVERSIBLE = SUCCESS,
EXTRACTED_GENESIS = SUCCESS,
NODE_MANAGEMENT_SUCCESS = 5
};
int main(int argc, char** argv)
{
try {
@@ -90,6 +101,7 @@ int main(int argc, char** argv)
opts.count("print-default-config")) {
return 0;
}
return INITIALIZE_FAIL;
}
initialize_logging();
auto& http = app().get_plugin<http_plugin>();
+1 -1
View File
@@ -132,7 +132,7 @@ pushdir ${LEAP_DIR}
# build Leap
echo "Building Leap ${SCRIPT_DIR}"
try cmake -DCMAKE_TOOLCHAIN_FILE=${SCRIPT_DIR}/pinned_toolchain.cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=${LLVM_DIR}/lib/cmake -DCMAKE_PREFIX_PATH=${BOOST_DIR}/bin ${SCRIPT_DIR}/..
try cmake -DCMAKE_TOOLCHAIN_FILE=${SCRIPT_DIR}/pinned_toolchain.cmake -DCMAKE_INSTALL_PREFIX=${LEAP_PINNED_INSTALL_PREFIX:-/usr/local} -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=${LLVM_DIR}/lib/cmake -DCMAKE_PREFIX_PATH=${BOOST_DIR}/bin ${SCRIPT_DIR}/..
try make -j${JOBS}
try cpack
+3 -3
View File
@@ -120,11 +120,11 @@ add_test(NAME restart-scenarios-test-hard_replay COMMAND tests/restart-scenarios
set_property(TEST restart-scenarios-test-hard_replay PROPERTY LABELS nonparallelizable_tests)
add_test(NAME restart-scenarios-test-none COMMAND tests/restart-scenarios-test.py -c none --kill-sig term -p4 -v --clean-run --dump-error-details WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
set_property(TEST restart-scenarios-test-none PROPERTY LABELS nonparallelizable_tests)
add_test(NAME terminate-scenarios-test-resync COMMAND tests/terminate-scenarios-test.py -p 1 -c resync --kill-count 1 --terminate-at-block 10 --kill-sig term --dump-error-details WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
add_test(NAME terminate-scenarios-test-resync COMMAND tests/terminate-scenarios-test.py -c resync --terminate-at-block 10 --kill-sig term --dump-error-details WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
set_property(TEST terminate-scenarios-test-resync PROPERTY LABELS nonparallelizable_tests)
add_test(NAME terminate-scenarios-test-replay COMMAND tests/terminate-scenarios-test.py -p 1 -c replay --kill-count 1 --terminate-at-block 10 --kill-sig term --dump-error-details WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
add_test(NAME terminate-scenarios-test-replay COMMAND tests/terminate-scenarios-test.py -c replay --terminate-at-block 10 --kill-sig term --dump-error-details WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
set_property(TEST terminate-scenarios-test-replay PROPERTY LABELS nonparallelizable_tests)
add_test(NAME terminate-scenarios-test-hard_replay COMMAND tests/terminate-scenarios-test.py -p 1 -c hardReplay --kill-count 1 --terminate-at-block 10 --kill-sig term --dump-error-details WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
add_test(NAME terminate-scenarios-test-hard_replay COMMAND tests/terminate-scenarios-test.py -c hardReplay --terminate-at-block 10 --kill-sig term --dump-error-details WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
set_property(TEST terminate-scenarios-test-hard_replay PROPERTY LABELS nonparallelizable_tests)
add_test(NAME validate_dirty_db_test COMMAND tests/validate-dirty-db.py -v --clean-run --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
set_property(TEST validate_dirty_db_test PROPERTY LABELS nonparallelizable_tests)
+2 -2
View File
@@ -1430,14 +1430,14 @@ class Cluster(object):
time.sleep(1) # Give processes time to stand down
return True
def relaunchEosInstances(self, cachePopen=False, nodeArgs=""):
def relaunchEosInstances(self, cachePopen=False, nodeArgs="", waitForTerm=False):
chainArg=self.__chainSyncStrategy.arg + " " + nodeArgs
newChain= False if self.__chainSyncStrategy.name in [Utils.SyncHardReplayTag, Utils.SyncNoneTag] else True
for i in range(0, len(self.nodes)):
node=self.nodes[i]
if node.killed and not node.relaunch(chainArg, newChain=newChain, cachePopen=cachePopen):
if node.killed and not node.relaunch(chainArg, newChain=newChain, cachePopen=cachePopen, waitForTerm=waitForTerm):
return False
return True
+6 -5
View File
@@ -1210,7 +1210,7 @@ class Node(object):
# pylint: disable=too-many-locals
# If nodeosPath is equal to None, it will use the existing nodeos path
def relaunch(self, chainArg=None, newChain=False, skipGenesis=True, timeout=Utils.systemWaitTimeout, addSwapFlags=None, cachePopen=False, nodeosPath=None, waitForTerm=True):
def relaunch(self, chainArg=None, newChain=False, skipGenesis=True, timeout=Utils.systemWaitTimeout, addSwapFlags=None, cachePopen=False, nodeosPath=None, waitForTerm=False):
assert(self.pid is None)
assert(self.killed)
@@ -1265,15 +1265,16 @@ class Node(object):
except subprocess.TimeoutExpired:
return False
with open(popen.errfile.name, 'r') as f:
if "Reached configured maximum block 10; terminating" in f.read():
if "successfully exiting" in f.read():
return True
else:
return False
if "terminate-at-block" not in cmd or not waitForTerm:
isAlive=Utils.waitForBool(isNodeAlive, timeout, sleepTime=1)
else:
if waitForTerm:
isAlive=Utils.waitForBoolWithArg(didNodeExitGracefully, self.popenProc, timeout, sleepTime=1)
else:
isAlive=Utils.waitForBool(isNodeAlive, timeout, sleepTime=1)
if isAlive:
Utils.Print("Node relaunch was successful.")
else:
+2
View File
@@ -375,6 +375,8 @@ try:
if preKillBlockProducer == "defproducerj" or preKillBlockProducer == "defproducerk":
# wait for defproduceri so there is plenty of time to send kill before defproducerk
nonProdNode.waitForProducer("defproduceri")
preKillBlockNum=nonProdNode.getBlockNum()
preKillBlockProducer=nonProdNode.getBlockProducerByNum(preKillBlockNum)
Print("preKillBlockProducer = {}".format(preKillBlockProducer))
# kill at last block before defproducerl, since the block it is killed on will get propagated
killAtProducer="defproducerk"
+27 -47
View File
@@ -25,8 +25,6 @@ relaunchTimeout = 10
numOfProducers = 1
totalNodes = 4
termAtFutureBlockNum = 30
# Parse command line arguments
args = TestHelper.parse_args({
"-v",
@@ -47,7 +45,7 @@ keepLogs = args.keep_logs
# Wrapper function to execute test
# This wrapper function will resurrect the node to be tested, and shut
# it down by the end of the test
def executeTest(cluster, producerNode, testNodeId, testNodeArgs, resultMsgs):
def executeTest(cluster, testNodeId, testNodeArgs, resultMsgs):
testNode = None
testResult = False
resultDesc = "!!!BUG IS CONFIRMED ON TEST CASE #{} ({})".format(
@@ -63,17 +61,12 @@ def executeTest(cluster, producerNode, testNodeId, testNodeArgs, resultMsgs):
)
)
# Get current information from the producer.
producerNode.waitForHeadToAdvance()
# Launch the node with the terminate-at-block option specified
# in testNodeArgs. The option for each node has already
# been set via specificExtraNodeosArg in the cluster launch.
cluster.launchUnstarted(cachePopen=True)
testNode = cluster.getNode(testNodeId)
assert not testNode.verifyAlive() # resets pid so reluanch works
testNode.relaunch(addSwapFlags={"--terminate-at-block": "9999999"}, cachePopen=True)
# Wait for node to start up.
time.sleep(10)
time.sleep(3)
# Check the node stops at the correct block.
checkStatus(testNode, testNodeArgs)
@@ -107,8 +100,7 @@ def checkStatus(testNode, testNodeArgs):
"""Test --terminate-at-block stops at the correct block."""
Print(" ".join([
"The test node has begun receiving from the producing node and",
"is expected to stop at or little bigger than the block number",
"specified here: ",
"is expected to stop at the block number specified here: ",
testNodeArgs
]))
@@ -122,6 +114,12 @@ def checkStatus(testNode, testNodeArgs):
else:
checkHeadOrSpeculative(head, lib)
# Check for the terminate at block message.
match = re.search(r"--terminate-at-block (\d+)", testNodeArgs)
termAtBlock = int(match.group(1))
assert head == termAtBlock, f"head {head} termAtBlock {termAtBlock}"
def checkReplay(testNode, testNodeArgs):
"""Test --terminate-at-block with --replay-blockchain."""
@@ -135,20 +133,18 @@ def checkReplay(testNode, testNodeArgs):
testNodeArgs
]))
testNode.relaunch(chainArg="--replay-blockchain", cachePopen=True)
assert not testNode.verifyAlive()
testNode.relaunch(chainArg="--replay-blockchain", addSwapFlags={"--terminate-at-block": "9999999"}, cachePopen=True)
# Wait for node to finish up.
time.sleep(10)
time.sleep(3)
# Check for the terminate at block message.
match = re.search(r"--terminate-at-block=(\d+)", testNodeArgs)
match = re.search(r"--terminate-at-block (\d+)", testNodeArgs)
termAtBlock = int(match.group(1))
termMsg = "Reached configured maximum block {}; terminating".format(
termAtBlock
)
assert checkLog(testNode.popenProc.errfile.name, termMsg)
head, lib = getBlockNumInfo(testNode)
assert head == termAtBlock, f"head {head} termAtBlock {termAtBlock}"
def getBlockNumInfo(testNode):
@@ -159,11 +155,12 @@ def getBlockNumInfo(testNode):
info = testNode.getInfo()
if not info:
break
continue
try:
head = info["head_block_num"]
lib = info["last_irreversible_block_num"]
break
except KeyError:
pass
@@ -172,26 +169,6 @@ def getBlockNumInfo(testNode):
return head, lib
def checkLog(log, message, sleepDuration=1, maxAttempt=10):
attemptCnt = 0
found = False
while not found and attemptCnt < maxAttempt:
try:
with open(log, "r") as f:
found = message in f.read()
except OSError:
pass
if not found:
time.sleep(sleepDuration)
attemptCnt = attemptCnt + 1
return found
def checkIrreversible(head, lib):
assert head == lib, (
"Head ({}) should be equal to lib ({})".format(head, lib)
@@ -215,9 +192,9 @@ testSuccessful = False
try:
specificNodeosArgs = {
0 : "--enable-stale-production",
1 : "--read-mode irreversible --terminate-at-block=250",
2 : "--read-mode speculative --terminate-at-block=550",
3 : "--read-mode head --terminate-at-block=850",
1 : "--read-mode irreversible --terminate-at-block 75",
2 : "--read-mode speculative --terminate-at-block 100",
3 : "--read-mode head --terminate-at-block 125",
}
traceNodeosArgs = " --plugin eosio::trace_api_plugin --trace-no-abis "
@@ -229,7 +206,6 @@ try:
prodCount=numOfProducers,
totalProducers=numOfProducers,
totalNodes=totalNodes,
unstartedNodes=totalNodes - numOfProducers,
pnodes=1,
useBiosBootFile=False,
topo="mesh",
@@ -240,6 +216,11 @@ try:
producingNodeId = 0
producingNode = cluster.getNode(producingNodeId)
# wait for all to terminate, needs to be larger than largest terminate-at-block
producingNode.waitForBlock( 150, timeout=150 )
cluster.biosNode.kill(signal.SIGTERM)
producingNode.kill(signal.SIGTERM)
# Start executing test cases here
Utils.Print("Script Begin .............................")
@@ -250,7 +231,6 @@ try:
success = executeTest(
cluster,
producingNode,
nodeId,
nodeArgs,
testResultMsgs
+9 -9
View File
@@ -20,16 +20,15 @@ import random
Print=Utils.Print
errorExit=Utils.errorExit
args=TestHelper.parse_args({"-p","-d","-s","-c","--kill-sig","--kill-count","--keep-logs"
args=TestHelper.parse_args({"-d","-s","-c","--kill-sig","--keep-logs"
,"--dump-error-details","-v","--leave-running","--clean-run"
,"--terminate-at-block"})
pnodes=args.p
pnodes=1
topo=args.s
delay=args.d
chainSyncStrategyStr=args.c
debug=args.v
total_nodes = pnodes
killCount=args.kill_count if args.kill_count > 0 else 1
killSignal=args.kill_sig
killEosInstances= not args.leave_running
dumpErrorDetails=args.dump_error_details
@@ -70,19 +69,20 @@ try:
if not cluster.waitOnClusterBlockNumSync(3):
errorExit("Cluster never stabilized")
Print("Kill %d cluster node instances." % (killCount))
if cluster.killSomeEosInstances(killCount, killSignal) is False:
Print("Kill cluster node instance.")
if cluster.killSomeEosInstances(1, killSignal) is False:
errorExit("Failed to kill Eos instances")
assert not cluster.getNode(0).verifyAlive()
Print("nodeos instances killed.")
Print ("Relaunch dead cluster nodes instances.")
Print ("Relaunch dead cluster node instance.")
nodeArg = "--terminate-at-block %d" % terminate if terminate > 0 else ""
if nodeArg != "":
if chainSyncStrategyStr == "hardReplay":
nodeArg += " --truncate-at-block %d" % terminate
if cluster.relaunchEosInstances(cachePopen=True, nodeArgs=nodeArg) is False:
errorExit("Failed to relaunch Eos instances")
Print("nodeos instances relaunched.")
if cluster.relaunchEosInstances(cachePopen=True, nodeArgs=nodeArg, waitForTerm=(terminate > 0)) is False:
errorExit("Failed to relaunch Eos instance")
Print("nodeos instance relaunched.")
testSuccessful=True
finally:
@@ -332,9 +332,9 @@ def stepSetSystemContract():
retry(args.cleos + 'push action eosio activate \'["ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c43"]\' -p eosio@active')
# DISALLOW_EMPTY_PRODUCER_SCHEDULE
retry(args.cleos + 'push action eosio activate \'["68dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a297428"]\' -p eosio@active')
# FIX_LINKAUTH_RESTRICTION
# FIX_LINKAUTH_RESTRICTION
retry(args.cleos + 'push action eosio activate \'["e0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff526"]\' -p eosio@active')
# REPLACE_DEFERRED
# REPLACE_DEFERRED
retry(args.cleos + 'push action eosio activate \'["ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea99"]\' -p eosio@active')
# NO_DUPLICATE_DEFERRED_ID
retry(args.cleos + 'push action eosio activate \'["4a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0f"]\' -p eosio@active')
@@ -346,6 +346,12 @@ def stepSetSystemContract():
retry(args.cleos + 'push action eosio activate \'["4fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c2"]\' -p eosio@active')
# WTMSIG_BLOCK_SIGNATURES
retry(args.cleos + 'push action eosio activate \'["299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b4476707"]\' -p eosio@active')
# GET_CODE_HASH
retry(args.cleos + 'push action eosio activate \'["bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99"]\' -p eosio@active')
# GET_BLOCK_NUM
retry(args.cleos + 'push action eosio activate \'["35c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b"]\' -p eosio@active')
# CRYPTO_PRIMITIVES
retry(args.cleos + 'push action eosio activate \'["6bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc"]\' -p eosio@active')
sleep(1)
# install eosio.system latest version