diff --git a/.cicd/build-scripts.yml b/.cicd/build-scripts.yml new file mode 100644 index 00000000000..fb124275f88 --- /dev/null +++ b/.cicd/build-scripts.yml @@ -0,0 +1,137 @@ +steps: + + - label: ":aws: Amazon_Linux 2 - Build Pinned" + plugins: + - docker#v3.3.0: + image: "amazonlinux:2.0.20190508" + always-pull: true + agents: + queue: "automation-eks-eos-builder-fleet" + command: + - "./scripts/eosio_build.sh -P -y" + timeout: 180 + + - label: ":centos: CentOS 7.7 - Build Pinned" + plugins: + - docker#v3.3.0: + image: "centos:7.7.1908" + always-pull: true + agents: + queue: "automation-eks-eos-builder-fleet" + command: + - "./scripts/eosio_build.sh -P -y" + timeout: 180 + + - label: ":darwin: macOS 10.14 - Build Pinned" + env: + REPO: "git@github.com:EOSIO/eos.git" + TEMPLATE: "10.14.6_6C_14G_40G" + TEMPLATE_TAG: "clean::cicd::git-ssh::nas::brew::buildkite-agent" + agents: "queue=mac-anka-large-node-fleet" + command: + - "git clone git@github.com:EOSIO/eos.git eos && cd eos && git checkout -f $BUILDKITE_BRANCH && git submodule update --init --recursive" + - "cd eos && ./scripts/eosio_build.sh -P -y" + plugins: + - EOSIO/anka#v0.5.7: + debug: true + vm-name: "10.14.6_6C_14G_40G" + no-volume: true + modify-cpu: 12 + modify-ram: 24 + always-pull: true + wait-network: true + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent" + pre-execute-sleep: 10 + failover-registries: + - "registry_1" + - "registry_2" + inherit-environment-vars: true + - thedyrt/skip-checkout#v0.1.1: + cd: ~ + timeout: 180 + + - label: ":ubuntu: Ubuntu 16.04 - Build Pinned" + plugins: + - docker#v3.3.0: + image: "ubuntu:16.04" + always-pull: true + agents: + queue: "automation-eks-eos-builder-fleet" + command: + - "apt update && apt upgrade -y && apt install -y git" + - "./scripts/eosio_build.sh -P -y" + timeout: 180 + + - label: ":ubuntu: Ubuntu 18.04 - Build Pinned" + plugins: + - docker#v3.3.0: + image: "ubuntu:18.04" + always-pull: true + agents: + queue: "automation-eks-eos-builder-fleet" + command: + - "apt update && apt upgrade -y && apt install -y git" + - "./scripts/eosio_build.sh -P -y" + timeout: 180 + + - label: ":aws: Amazon_Linux 2 - Build UnPinned" + plugins: + - docker#v3.3.0: + image: "amazonlinux:2.0.20190508" + always-pull: true + agents: + queue: "automation-eks-eos-builder-fleet" + command: + - "./scripts/eosio_build.sh -y" + timeout: 180 + + - label: ":centos: CentOS 7.7 - Build UnPinned" + plugins: + - docker#v3.3.0: + image: "centos:7.7.1908" + always-pull: true + agents: + queue: "automation-eks-eos-builder-fleet" + command: + - "./scripts/eosio_build.sh -y" + timeout: 180 + + - label: ":darwin: macOS 10.14 - Build UnPinned" + env: + REPO: "git@github.com:EOSIO/eos.git" + TEMPLATE: "10.14.6_6C_14G_40G" + TEMPLATE_TAG: "clean::cicd::git-ssh::nas::brew::buildkite-agent" + agents: "queue=mac-anka-large-node-fleet" + command: + - "git clone git@github.com:EOSIO/eos.git eos && cd eos && git checkout -f $BUILDKITE_BRANCH && git submodule update --init --recursive" + - "cd eos && ./scripts/eosio_build.sh -y" + plugins: + - EOSIO/anka#v0.5.7: + debug: true + vm-name: "10.14.6_6C_14G_40G" + no-volume: true + modify-cpu: 12 + modify-ram: 24 + always-pull: true + wait-network: true + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent" + pre-execute-sleep: 10 + failover-registries: + - "registry_1" + - "registry_2" + inherit-environment-vars: true + - thedyrt/skip-checkout#v0.1.1: + cd: ~ + timeout: 180 + + - label: ":ubuntu: Ubuntu 18.04 - Build UnPinned" + plugins: + - docker#v3.3.0: + image: "ubuntu:18.04" + always-pull: true + agents: + queue: "automation-eks-eos-builder-fleet" + command: + - "apt update && apt upgrade -y && apt install -y git" + - "./scripts/eosio_build.sh -y" + timeout: 180 \ No newline at end of file diff --git a/.cicd/docker-tag.sh b/.cicd/docker-tag.sh index 18ef347a0a3..22da25dff95 100755 --- a/.cicd/docker-tag.sh +++ b/.cicd/docker-tag.sh @@ -3,7 +3,7 @@ set -eo pipefail echo '+++ :evergreen_tree: Configuring Environment' REPO='eosio/ci-contracts-builder' PREFIX='base-ubuntu-18.04' -IMAGE="$REPO:$PREFIX-$BUILDKITE_COMMIT" +IMAGE="$REPO:$PREFIX-$BUILDKITE_COMMIT-$PLATFORM_TYPE" SANITIZED_BRANCH=$(echo "$BUILDKITE_BRANCH" | tr '/' '_') SANITIZED_TAG=$(echo "$BUILDKITE_TAG" | tr '/' '_') echo '+++ :arrow_down: Pulling Container' diff --git a/.cicd/generate-pipeline.sh b/.cicd/generate-pipeline.sh index e2037c9f46b..3072f0d4b34 100755 --- a/.cicd/generate-pipeline.sh +++ b/.cicd/generate-pipeline.sh @@ -80,8 +80,8 @@ if [[ ! -z ${BUILDKITE_TRIGGERED_FROM_BUILD_ID} ]]; then fi export BUILD_SOURCE=${BUILD_SOURCE:---build \$BUILDKITE_BUILD_ID} # set trigger_job if master/release/develop branch and webhook -if [[ $BUILDKITE_BRANCH =~ ^release/[0-9]+\.[0-9]+\.x$ || $BUILDKITE_BRANCH =~ ^master$ || $BUILDKITE_BRANCH =~ ^develop$ ]]; then - [[ $BUILDKITE_SOURCE != 'scheduled' ]] && export TRIGGER_JOB=true +if [[ ! $BUILDKITE_PIPELINE_SLUG =~ 'lrt' ]] && [[ $BUILDKITE_BRANCH =~ ^release/[0-9]+\.[0-9]+\.x$ || $BUILDKITE_BRANCH =~ ^master$ || $BUILDKITE_BRANCH =~ ^develop$ ]]; then + [[ $BUILDKITE_SOURCE != 'schedule' ]] && export TRIGGER_JOB=true fi oIFS="$IFS" IFS=$'' @@ -438,6 +438,23 @@ EOF echo '' fi done +# Execute multiversion test +if ( [[ ! $PINNED == false ]] ); then + cat < "$PIPELINE_CONFIG" +if [[ -f "$PIPELINE_CONFIG" ]]; then + [[ "$DEBUG" == 'true' ]] && cat "$PIPELINE_CONFIG" | jq . + # export environment + if [[ "$(cat "$PIPELINE_CONFIG" | jq -r '.environment')" != 'null' ]]; then + for OBJECT in $(cat "$PIPELINE_CONFIG" | jq -r '.environment | to_entries | .[] | @base64'); do + KEY="$(echo $OBJECT | base64 --decode | jq -r .key)" + VALUE="$(echo $OBJECT | base64 --decode | jq -r .value)" + [[ ! -v $KEY ]] && export $KEY="$VALUE" + done + fi + # export multiversion.conf + echo '[eosio]' > multiversion.conf + for OBJECT in $(cat "$PIPELINE_CONFIG" | jq -r '.configuration | .[] | @base64'); do + echo "$(echo $OBJECT | base64 --decode)" >> multiversion.conf # outer echo adds '\n' + done + mv -f $GIT_ROOT/multiversion.conf $GIT_ROOT/tests +elif [[ "$DEBUG" == 'true' ]]; then + echo 'Pipeline configuration file not found!' + echo "PIPELINE_CONFIG = \"$PIPELINE_CONFIG\"" + echo "RAW_PIPELINE_CONFIG = \"$RAW_PIPELINE_CONFIG\"" + echo '$ pwd' + pwd + echo '$ ls' + ls + echo 'Skipping that step...' +fi +# multiversion +cd $GIT_ROOT/eos_multiversion_builder +echo 'Downloading other versions of nodeos...' +python2.7 $GIT_ROOT/.cicd/helpers/multi_eos_docker.py +cd $GIT_ROOT +cp $GIT_ROOT/tests/multiversion_paths.conf $GIT_ROOT/build/tests +cd $GIT_ROOT/build +# count tests +echo "+++ $([[ "$BUILDKITE" == 'true' ]] && echo ':microscope: ')Running Multiversion Test" +TEST_COUNT=$(ctest -N -L mixed_version_tests | grep -i 'Total Tests: ' | cut -d ':' -f 2 | awk '{print $1}') +if [[ $TEST_COUNT > 0 ]]; then + echo "$TEST_COUNT tests found." +else + echo "+++ $([[ "$BUILDKITE" == 'true' ]] && echo ':no_entry: ')ERROR: No tests registered with ctest! Exiting..." + exit 1 +fi +# run tests +set +e # defer ctest error handling to end +echo "$ ctest -L mixed_version_tests --output-on-failure -T Test" +ctest -L mixed_version_tests --output-on-failure -T Test +EXIT_STATUS=$? +echo 'Done running multiversion test.' +exit $EXIT_STATUS \ No newline at end of file diff --git a/.cicd/platforms/pinned/macos-10.14-pinned.sh b/.cicd/platforms/pinned/macos-10.14-pinned.sh index 477889d9124..99af86b61d0 100755 --- a/.cicd/platforms/pinned/macos-10.14-pinned.sh +++ b/.cicd/platforms/pinned/macos-10.14-pinned.sh @@ -49,7 +49,7 @@ sudo make install cd ../.. rm -rf clang8 # install boost from source -## Boost Fix: eosio/install/bin/../include/c++/v1/stdlib.h:94:15: fatal error: 'stdlib.h' file not found +# Boost Fix: eosio/install/bin/../include/c++/v1/stdlib.h:94:15: fatal error: 'stdlib.h' file not found export SDKROOT="$(xcrun --sdk macosx --show-sdk-path)" curl -LO https://dl.bintray.com/boostorg/release/1.71.0/source/boost_1_71_0.tar.bz2 tar -xjf boost_1_71_0.tar.bz2 diff --git a/.cicd/platforms/pinned/ubuntu-18.04-pinned.dockerfile b/.cicd/platforms/pinned/ubuntu-18.04-pinned.dockerfile index 7815e219c8f..2712342e28d 100644 --- a/.cicd/platforms/pinned/ubuntu-18.04-pinned.dockerfile +++ b/.cicd/platforms/pinned/ubuntu-18.04-pinned.dockerfile @@ -5,7 +5,8 @@ RUN apt-get update && \ apt-get upgrade -y && \ DEBIAN_FRONTEND=noninteractive apt-get install -y git make \ bzip2 automake libbz2-dev libssl-dev doxygen graphviz libgmp3-dev \ - autotools-dev libicu-dev python2.7 python2.7-dev python3 python3-dev \ + autotools-dev libicu-dev python2.7 python2.7-dev python3 \ + python3-dev python-configparser python-requests python-pip \ autoconf libtool g++ gcc curl zlib1g-dev sudo ruby libusb-1.0-0-dev \ libcurl4-gnutls-dev pkg-config patch ccache vim-common jq # build cmake. diff --git a/.cicd/test.sh b/.cicd/test.sh index 632e714d82e..88b09b8f28e 100755 --- a/.cicd/test.sh +++ b/.cicd/test.sh @@ -11,9 +11,9 @@ if [[ $(uname) == 'Darwin' ]]; then # macOS else # Linux COMMANDS="$MOUNTED_DIR/$@" . $HELPERS_DIR/file-hash.sh $CICD_DIR/platforms/$PLATFORM_TYPE/$IMAGE_TAG.dockerfile - echo "$ docker run --rm --init -v $(pwd):$MOUNTED_DIR $(buildkite-intrinsics) -e JOBS $FULL_TAG bash -c \"$COMMANDS\"" + echo "$ docker run --rm --init -v $(pwd):$MOUNTED_DIR $(buildkite-intrinsics) -e JOBS -e BUILDKITE_API_KEY $FULL_TAG bash -c \"$COMMANDS\"" set +e # defer error handling to end - eval docker run --rm --init -v $(pwd):$MOUNTED_DIR $(buildkite-intrinsics) -e JOBS $FULL_TAG bash -c \"$COMMANDS\" + eval docker run --rm --init -v $(pwd):$MOUNTED_DIR $(buildkite-intrinsics) -e JOBS -e BUILDKITE_API_KEY $FULL_TAG bash -c \"$COMMANDS\" EXIT_STATUS=$? fi # buildkite diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a490f97988..630e7670d49 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,7 +25,7 @@ set( CXX_STANDARD_REQUIRED ON) set(VERSION_MAJOR 2) set(VERSION_MINOR 0) -set(VERSION_PATCH 0) +set(VERSION_PATCH 1) #set(VERSION_SUFFIX rc3) if(VERSION_SUFFIX) diff --git a/README.md b/README.md index a3a858b5e2e..c1d9770d772 100644 --- a/README.md +++ b/README.md @@ -74,13 +74,13 @@ $ brew remove eosio #### Ubuntu 18.04 Package Install ```sh -$ wget https://github.com/eosio/eos/releases/download/v2.0.0/eosio_2.0.0-1-ubuntu-18.04_amd64.deb -$ sudo apt install ./eosio_2.0.0-1-ubuntu-18.04_amd64.deb +$ wget https://github.com/eosio/eos/releases/download/v2.0.1/eosio_2.0.1-1-ubuntu-18.04_amd64.deb +$ sudo apt install ./eosio_2.0.1-1-ubuntu-18.04_amd64.deb ``` #### Ubuntu 16.04 Package Install ```sh -$ wget https://github.com/eosio/eos/releases/download/v2.0.0/eosio_2.0.0-1-ubuntu-16.04_amd64.deb -$ sudo apt install ./eosio_2.0.0-1-ubuntu-16.04_amd64.deb +$ wget https://github.com/eosio/eos/releases/download/v2.0.1/eosio_2.0.1-1-ubuntu-16.04_amd64.deb +$ sudo apt install ./eosio_2.0.1-1-ubuntu-16.04_amd64.deb ``` #### Ubuntu Package Uninstall ```sh @@ -91,8 +91,8 @@ $ sudo apt remove eosio #### RPM Package Install ```sh -$ wget https://github.com/eosio/eos/releases/download/v2.0.0/eosio-2.0.0-1.el7.x86_64.rpm -$ sudo yum install ./eosio-2.0.0-1.el7.x86_64.rpm +$ wget https://github.com/eosio/eos/releases/download/v2.0.1/eosio-2.0.1-1.el7.x86_64.rpm +$ sudo yum install ./eosio-2.0.1-1.el7.x86_64.rpm ``` #### RPM Package Uninstall ```sh diff --git a/docs/00_install/00_install-prebuilt-binaries.md b/docs/00_install/00_install-prebuilt-binaries.md index d2c9beb9208..b5988fa7cbd 100644 --- a/docs/00_install/00_install-prebuilt-binaries.md +++ b/docs/00_install/00_install-prebuilt-binaries.md @@ -25,13 +25,13 @@ $ brew remove eosio #### Ubuntu 18.04 Package Install ```sh -$ wget https://github.com/eosio/eos/releases/download/v2.0.0/eosio_2.0.0-1-ubuntu-18.04_amd64.deb -$ sudo apt install ./eosio_2.0.0-1-ubuntu-18.04_amd64.deb +$ wget https://github.com/eosio/eos/releases/download/v2.0.1/eosio_2.0.1-1-ubuntu-18.04_amd64.deb +$ sudo apt install ./eosio_2.0.1-1-ubuntu-18.04_amd64.deb ``` #### Ubuntu 16.04 Package Install ```sh -$ wget https://github.com/eosio/eos/releases/download/v2.0.0/eosio_2.0.0-1-ubuntu-16.04_amd64.deb -$ sudo apt install ./eosio_2.0.0-1-ubuntu-16.04_amd64.deb +$ wget https://github.com/eosio/eos/releases/download/v2.0.1/eosio_2.0.1-1-ubuntu-16.04_amd64.deb +$ sudo apt install ./eosio_2.0.1-1-ubuntu-16.04_amd64.deb ``` #### Ubuntu Package Uninstall ```sh @@ -42,8 +42,8 @@ $ sudo apt remove eosio #### RPM Package Install ```sh -$ wget https://github.com/eosio/eos/releases/download/v2.0.0/eosio-2.0.0-1.el7.x86_64.rpm -$ sudo yum install ./eosio-2.0.0-1.el7.x86_64.rpm +$ wget https://github.com/eosio/eos/releases/download/v2.0.1/eosio-2.0.1-1.el7.x86_64.rpm +$ sudo yum install ./eosio-2.0.1-1.el7.x86_64.rpm ``` #### RPM Package Uninstall ```sh @@ -56,7 +56,7 @@ After installing the prebuilt packages, the actual EOSIO binaries will be locate * `/usr/opt/eosio//bin` (Linux-based); or * `/usr/local/Cellar/eosio//bin` (MacOS ) -where `version-string` is the EOSIO version that was installed; e.g. `2.0.0-rc2`. +where `version-string` is the EOSIO version that was installed; e.g. `2.0.1`. Also, soft links for each EOSIO program (`nodeos`, `cleos`, `keosd`, etc.) will be created under `usr/bin` or `usr/local/bin` to allow them to be executed from any directory. diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index 480ea01cbd1..9472a5a6775 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -123,6 +123,7 @@ struct building_block { vector _pending_trx_metas; vector _pending_trx_receipts; vector _actions; + optional _transaction_mroot; }; struct assembled_block { @@ -1308,7 +1309,7 @@ struct controller_impl { // Only subjective OR soft OR hard failure logic below: - if( gtrx.sender != account_name() && !failure_is_subjective(*trace->except)) { + if( gtrx.sender != account_name() && !(explicit_billed_cpu_time ? failure_is_subjective(*trace->except) : scheduled_failure_is_subjective(*trace->except))) { // Attempt error handling for the generated transaction. auto error_trace = apply_onerror( gtrx, deadline, trx_context.pseudo_start, @@ -1677,7 +1678,7 @@ struct controller_impl { // Create (unsigned) block: auto block_ptr = std::make_shared( pbhs.make_block_header( - calculate_trx_merkle(), + bb._transaction_mroot ? *bb._transaction_mroot : calculate_trx_merkle( bb._pending_trx_receipts ), calculate_action_merkle(), bb._new_pending_producer_schedule, std::move( bb._new_protocol_feature_activations ), @@ -1820,6 +1821,27 @@ struct controller_impl { } } + void report_block_header_diff( const block_header& b, const block_header& ab ) { + +#define EOS_REPORT(DESC,A,B) \ + if( A != B ) { \ + elog("${desc}: ${bv} != ${abv}", ("desc", DESC)("bv", A)("abv", B)); \ + } + + EOS_REPORT( "timestamp", b.timestamp, ab.timestamp ) + EOS_REPORT( "producer", b.producer, ab.producer ) + EOS_REPORT( "confirmed", b.confirmed, ab.confirmed ) + EOS_REPORT( "previous", b.previous, ab.previous ) + EOS_REPORT( "transaction_mroot", b.transaction_mroot, ab.transaction_mroot ) + EOS_REPORT( "action_mroot", b.action_mroot, ab.action_mroot ) + EOS_REPORT( "schedule_version", b.schedule_version, ab.schedule_version ) + EOS_REPORT( "new_producers", b.new_producers, ab.new_producers ) + EOS_REPORT( "header_extensions", b.header_extensions, ab.header_extensions ) + +#undef EOS_REPORT + } + + void apply_block( const block_state_ptr& bsp, controller::block_status s, const trx_meta_cache_lookup& trx_lookup ) { try { try { @@ -1898,13 +1920,20 @@ struct controller_impl { ("producer_receipt", receipt)("validator_receipt", trx_receipts.back()) ); } + // validated in create_block_state_future() + pending->_block_stage.get()._transaction_mroot = b->transaction_mroot; + finalize_block(); auto& ab = pending->_block_stage.get(); - // this implicitly asserts that all header fields (less the signature) are identical - EOS_ASSERT( producer_block_id == ab._id, block_validate_exception, "Block ID does not match", - ("producer_block_id",producer_block_id)("validator_block_id",ab._id) ); + if( producer_block_id != ab._id ) { + elog( "Validation block id does not match producer block id" ); + report_block_header_diff( *b, *ab._unsigned_block ); + // this implicitly asserts that all header fields (less the signature) are identical + EOS_ASSERT( producer_block_id == ab._id, block_validate_exception, "Block ID does not match", + ("producer_block_id", producer_block_id)("validator_block_id", ab._id) ); + } if( !use_bsp_cached ) { bsp->set_trxs_metas( std::move( ab._trx_metas ), !skip_auth_checks ); @@ -1936,6 +1965,11 @@ struct controller_impl { return async_thread_pool( thread_pool.get_executor(), [b, prev, control=this]() { const bool skip_validate_signee = false; + + auto trx_mroot = calculate_trx_merkle( b->transactions ); + EOS_ASSERT( b->transaction_mroot == trx_mroot, block_validate_exception, + "invalid block transaction merkle root ${b} != ${c}", ("b", b->transaction_mroot)("c", trx_mroot) ); + return std::make_shared( *prev, move( b ), @@ -2126,9 +2160,8 @@ struct controller_impl { return merkle( move(action_digests) ); } - checksum256_type calculate_trx_merkle() { + static checksum256_type calculate_trx_merkle( const vector& trxs ) { vector trx_digests; - const auto& trxs = pending->_block_stage.get()._pending_trx_receipts; trx_digests.reserve( trxs.size() ); for( const auto& a : trxs ) trx_digests.emplace_back( a.digest() ); diff --git a/libraries/fc b/libraries/fc index e95a03eed17..8d53b92f02b 160000 --- a/libraries/fc +++ b/libraries/fc @@ -1 +1 @@ -Subproject commit e95a03eed1796a3054e02e67f1171f8c9fdb57e5 +Subproject commit 8d53b92f02b0cb189a5c28b31a895401daf5dc0b diff --git a/plugins/chain_interface/include/eosio/chain/plugin_interface.hpp b/plugins/chain_interface/include/eosio/chain/plugin_interface.hpp index 44ef1860c60..9c1186d4eb7 100644 --- a/plugins/chain_interface/include/eosio/chain/plugin_interface.hpp +++ b/plugins/chain_interface/include/eosio/chain/plugin_interface.hpp @@ -44,7 +44,7 @@ namespace eosio { namespace chain { namespace plugin_interface { namespace methods { // synchronously push a block/trx to a single provider - using block_sync = method_decl; + using block_sync = method_decl&), first_provider_policy>; using transaction_async = method_decl), first_provider_policy>; } } diff --git a/plugins/chain_plugin/chain_plugin.cpp b/plugins/chain_plugin/chain_plugin.cpp index a854095fe3f..722dcee81e5 100644 --- a/plugins/chain_plugin/chain_plugin.cpp +++ b/plugins/chain_plugin/chain_plugin.cpp @@ -1133,8 +1133,8 @@ void chain_apis::read_write::validate() const { EOS_ASSERT( db.get_read_mode() != chain::db_read_mode::READ_ONLY, missing_chain_api_plugin_exception, "Not allowed, node in read-only mode" ); } -void chain_plugin::accept_block(const signed_block_ptr& block ) { - my->incoming_block_sync_method(block); +bool chain_plugin::accept_block(const signed_block_ptr& block, const block_id_type& id ) { + return my->incoming_block_sync_method(block, id); } void chain_plugin::accept_transaction(const chain::packed_transaction_ptr& trx, next_function next) { @@ -2066,7 +2066,7 @@ fc::variant read_only::get_block_header_state(const get_block_header_state_param void read_write::push_block(read_write::push_block_params&& params, next_function next) { try { - app().get_method()(std::make_shared(std::move(params))); + app().get_method()(std::make_shared(std::move(params)), {}); next(read_write::push_block_results{}); } catch ( boost::interprocess::bad_alloc& ) { chain_plugin::handle_db_exhaustion(); diff --git a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp index e00deb709e2..2b608c4e4a8 100644 --- a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp +++ b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp @@ -706,7 +706,7 @@ class chain_plugin : public plugin { chain_apis::read_only get_read_only_api() const { return chain_apis::read_only(chain(), get_abi_serializer_max_time()); } chain_apis::read_write get_read_write_api() { return chain_apis::read_write(chain(), get_abi_serializer_max_time()); } - void accept_block( const chain::signed_block_ptr& block ); + bool accept_block( const chain::signed_block_ptr& block, const chain::block_id_type& id ); void accept_transaction(const chain::packed_transaction_ptr& trx, chain::plugin_interface::next_function next); bool block_is_on_preferred_chain(const chain::block_id_type& block_id); diff --git a/plugins/http_plugin/http_plugin.cpp b/plugins/http_plugin/http_plugin.cpp index 7a720fa7564..887a2958c92 100644 --- a/plugins/http_plugin/http_plugin.cpp +++ b/plugins/http_plugin/http_plugin.cpp @@ -691,6 +691,8 @@ namespace eosio { if( my->thread_pool ) { my->thread_pool->stop(); } + + app().post( 0, [me = my](){} ); // keep my pointer alive until queue is drained } void http_plugin::add_handler(const string& url, const url_handler& handler) { diff --git a/plugins/http_plugin/include/eosio/http_plugin/http_plugin.hpp b/plugins/http_plugin/include/eosio/http_plugin/http_plugin.hpp index 5c81279fe62..29c31474fec 100644 --- a/plugins/http_plugin/include/eosio/http_plugin/http_plugin.hpp +++ b/plugins/http_plugin/include/eosio/http_plugin/http_plugin.hpp @@ -98,7 +98,7 @@ namespace eosio { get_supported_apis_result get_supported_apis()const; private: - std::unique_ptr my; + std::shared_ptr my; }; /** diff --git a/plugins/net_plugin/include/eosio/net_plugin/protocol.hpp b/plugins/net_plugin/include/eosio/net_plugin/protocol.hpp index a806486b50a..8ce781cefd5 100644 --- a/plugins/net_plugin/include/eosio/net_plugin/protocol.hpp +++ b/plugins/net_plugin/include/eosio/net_plugin/protocol.hpp @@ -17,6 +17,13 @@ namespace eosio { block_id_type head_id; }; + // Longest domain name is 253 characters according to wikipedia. + // Addresses include ":port" where max port is 65535, which adds 6 chars. + // We also add our own extentions of "[:trx|:blk] - xxxxxxx", which adds 14 chars, total= 273. + // Allow for future extentions as well, hence 384. + constexpr size_t max_p2p_address_length = 253 + 6; + constexpr size_t max_handshake_str_length = 384; + struct handshake_message { uint16_t network_version = 0; ///< incremental value above a computed base chain_id_type chain_id; ///< used to identify chain diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index d8c475dbc39..e58da153946 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -191,10 +191,8 @@ namespace eosio { void retry_fetch(const connection_ptr& conn); bool add_peer_block( const block_id_type& blkid, uint32_t connection_id ); - bool add_peer_block_id( const block_id_type& blkid, uint32_t connection_id ); bool peer_has_block(const block_id_type& blkid, uint32_t connection_id) const; bool have_block(const block_id_type& blkid) const; - size_t num_entries( uint32_t connection_id ) const; bool add_peer_txn( const node_transaction_state& nts ); void update_txns_block_num( const signed_block_ptr& sb ); @@ -384,7 +382,6 @@ namespace eosio { constexpr auto def_max_trx_in_progress_size = 100*1024*1024; // 100 MB constexpr auto def_max_consecutive_rejected_blocks = 3; // num of rejected blocks before disconnect constexpr auto def_max_consecutive_immediate_connection_close = 9; // back off if client keeps closing - constexpr auto def_max_peer_block_ids_per_connection = 100*1024; // if we reach this many then the connection is spaming us, disconnect constexpr auto def_max_clients = 25; // 0 for unlimited clients constexpr auto def_max_nodes_per_host = 1; constexpr auto def_conn_retry_wait = 30; @@ -416,9 +413,9 @@ namespace eosio { */ constexpr uint16_t proto_base = 0; constexpr uint16_t proto_explicit_sync = 1; - constexpr uint16_t block_id_notify = 2; + constexpr uint16_t block_id_notify = 2; // reserved. feature was removed. next net_version should be 3 - constexpr uint16_t net_version = block_id_notify; + constexpr uint16_t net_version = proto_explicit_sync; /** * Index by start_block_num @@ -622,7 +619,7 @@ namespace eosio { static void _close( connection* self, bool reconnect, bool shutdown ); // for easy capture public: - bool populate_handshake( handshake_message& hello ); + bool populate_handshake( handshake_message& hello, bool force ); bool resolve_and_connect(); void connect( const std::shared_ptr& resolver, tcp::resolver::results_type endpoints ); @@ -638,7 +635,7 @@ namespace eosio { */ bool process_next_message(uint32_t message_length); - void send_handshake(); + void send_handshake( bool force = false ); /** \name Peer Timestamps * Time message handling @@ -828,7 +825,7 @@ namespace eosio { last_handshake_recv(), last_handshake_sent() { - fc_ilog( logger, "accepted network connection" ); + fc_dlog( logger, "new connection object created" ); } void connection::update_endpoints() { @@ -855,13 +852,13 @@ namespace eosio { peer_add.substr( colon2 + 1 ) : peer_add.substr( colon2 + 1, end - (colon2 + 1) ); if( type.empty() ) { - fc_ilog( logger, "Setting connection type for: ${peer} to both transactions and blocks", ("peer", peer_add) ); + fc_dlog( logger, "Setting connection type for: ${peer} to both transactions and blocks", ("peer", peer_add) ); connection_type = both; } else if( type == "trx" ) { - fc_ilog( logger, "Setting connection type for: ${peer} to transactions only", ("peer", peer_add) ); + fc_dlog( logger, "Setting connection type for: ${peer} to transactions only", ("peer", peer_add) ); connection_type = transactions_only; } else if( type == "blk" ) { - fc_ilog( logger, "Setting connection type for: ${peer} to blocks only", ("peer", peer_add) ); + fc_dlog( logger, "Setting connection type for: ${peer} to blocks only", ("peer", peer_add) ); connection_type = blocks_only; } else { fc_wlog( logger, "Unknown connection type: ${t}", ("t", type) ); @@ -1044,10 +1041,10 @@ namespace eosio { syncing = false; } - void connection::send_handshake() { - strand.dispatch( [c = shared_from_this()]() { + void connection::send_handshake( bool force ) { + strand.dispatch( [force, c = shared_from_this()]() { std::unique_lock g_conn( c->conn_mtx ); - if( c->populate_handshake( c->last_handshake_sent ) ) { + if( c->populate_handshake( c->last_handshake_sent, force ) ) { static_assert( std::is_same_vsent_handshake_count ), int16_t>, "INT16_MAX based on int16_t" ); if( c->sent_handshake_count == INT16_MAX ) c->sent_handshake_count = 1; // do not wrap c->last_handshake_sent.generation = ++c->sent_handshake_count; @@ -1523,8 +1520,8 @@ namespace eosio { if( sync_state == in_sync ) { set_state( lib_catchup ); - sync_next_expected_num = std::max( lib_num + 1, sync_next_expected_num ); } + sync_next_expected_num = std::max( lib_num + 1, sync_next_expected_num ); fc_ilog( logger, "Catching up with chain, our last req is ${cc}, theirs is ${t} peer ${p}", ("cc", sync_last_requested_num)( "t", target )( "p", c->peer_name() ) ); @@ -1735,7 +1732,7 @@ namespace eosio { g.unlock(); c->close(); } else { - c->send_handshake(); + c->send_handshake( true ); } } @@ -1831,16 +1828,6 @@ namespace eosio { return added; } - bool dispatch_manager::add_peer_block_id( const block_id_type& blkid, uint32_t connection_id) { - std::lock_guard g( blk_state_mtx ); - auto bptr = blk_state.get().find( std::make_tuple( connection_id, std::ref( blkid ))); - bool added = (bptr == blk_state.end()); - if( added ) { - blk_state.insert( {blkid, block_header::num_from_id( blkid ), connection_id, false} ); - } - return added; - } - bool dispatch_manager::peer_has_block( const block_id_type& blkid, uint32_t connection_id ) const { std::lock_guard g(blk_state_mtx); const auto blk_itr = blk_state.get().find( std::make_tuple( connection_id, std::ref( blkid ))); @@ -1858,11 +1845,6 @@ namespace eosio { return false; } - size_t dispatch_manager::num_entries( uint32_t connection_id ) const { - std::lock_guard g(blk_state_mtx); - return blk_state.get().count( connection_id ); - } - bool dispatch_manager::add_peer_txn( const node_transaction_state& nts ) { std::lock_guard g( local_txns_mtx ); auto tptr = local_txns.get().find( std::make_tuple( std::ref( nts.id ), nts.connection_id ) ); @@ -1939,6 +1921,8 @@ namespace eosio { void dispatch_manager::bcast_block(const block_state_ptr& bs) { fc_dlog( logger, "bcast block ${b}", ("b", bs->block_num) ); + if( my_impl->sync_master->syncing_with_peer() ) return; + bool have_connection = false; for_each_block_connection( [&have_connection]( auto& cp ) { peer_dlog( cp, "socket_is_open ${s}, connecting ${c}, syncing ${ss}", @@ -1976,33 +1960,6 @@ namespace eosio { } ); } - void dispatch_manager::bcast_notice( const block_id_type& id ) { - if( my_impl->sync_master->syncing_with_peer() ) return; - - fc_dlog( logger, "bcast notice ${b}", ("b", block_header::num_from_id( id )) ); - notice_message note; - note.known_blocks.mode = normal; - note.known_blocks.pending = 1; // 1 indicates this is a block id notice - note.known_blocks.ids.emplace_back( id ); - - for_each_block_connection( [this, note]( auto& cp ) { - if( !cp->current() ) { - return true; - } - cp->strand.post( [this, cp, note]() { - // check protocol_version here since only accessed from strand - if( cp->protocol_version < block_id_notify ) return; - const block_id_type& id = note.known_blocks.ids.back(); - if( peer_has_block( id, cp->connection_id ) ) { - return; - } - fc_dlog( logger, "bcast block id ${b} to ${p}", ("b", block_header::num_from_id( id ))("p", cp->peer_name()) ); - cp->enqueue( note ); - } ); - return true; - } ); - } - // called from connection strand void dispatch_manager::recv_block(const connection_ptr& c, const block_id_type& id, uint32_t bnum) { std::unique_lock g( c->conn_mtx ); @@ -2069,18 +2026,7 @@ namespace eosio { if (msg.known_blocks.mode == normal) { // known_blocks.ids is never > 1 if( !msg.known_blocks.ids.empty() ) { - if( num_entries( c->connection_id ) > def_max_peer_block_ids_per_connection ) { - fc_elog( logger, "received too many notice_messages, disconnecting" ); - c->close( false ); - } - const block_id_type& blkid = msg.known_blocks.ids.back(); - if( have_block( blkid )) { - add_peer_block( blkid, c->connection_id ); - return; - } else { - add_peer_block_id( blkid, c->connection_id ); - } - if( msg.known_blocks.pending == 1 ) { // block id notify + if( msg.known_blocks.pending == 1 ) { // block id notify of 2.0.0, ignore return; } } @@ -2190,6 +2136,7 @@ namespace eosio { c->connect( resolver, endpoints ); } else { fc_elog( logger, "Unable to resolve ${add}: ${error}", ("add", c->peer_name())( "error", err.message() ) ); + c->connecting = false; ++c->consecutive_immediate_connection_close; } } ) ); @@ -2261,10 +2208,10 @@ namespace eosio { } else { if( from_addr >= max_nodes_per_host ) { - fc_elog( logger, "Number of connections (${n}) from ${ra} exceeds limit ${l}", + fc_dlog( logger, "Number of connections (${n}) from ${ra} exceeds limit ${l}", ("n", from_addr + 1)( "ra", paddr_str )( "l", max_nodes_per_host )); } else { - fc_elog( logger, "Error max_client_count ${m} exceeded", ("m", max_client_count)); + fc_dlog( logger, "max_client_count ${m} exceeded", ("m", max_client_count)); } // new_connection never added to connections and start_session not called, lifetime will end boost::system::error_code ec; @@ -2434,8 +2381,9 @@ namespace eosio { pending_message_buffer.advance_read_ptr( message_length ); return true; } - fc_dlog( logger, "${p} received block ${num}, id ${id}...", - ("p", peer_name())("num", bh.block_num())("id", blk_id.str().substr(8,16)) ); + fc_dlog( logger, "${p} received block ${num}, id ${id}..., latency: ${latency}", + ("p", peer_name())("num", bh.block_num())("id", blk_id.str().substr(8,16)) + ("latency", (fc::time_point::now() - bh.timestamp).count()/1000) ); if( !my_impl->sync_master->syncing_with_peer() ) { // guard against peer thinking it needs to send us old blocks uint32_t lib = 0; std::tie( lib, std::ignore, std::ignore, std::ignore, std::ignore, std::ignore ) = my_impl->get_chain_info(); @@ -2524,10 +2472,21 @@ namespace eosio { if (msg.p2p_address.empty()) { fc_wlog( logger, "Handshake message validation: p2p_address is null string" ); valid = false; + } else if( msg.p2p_address.length() > max_handshake_str_length ) { + // see max_handshake_str_length comment in protocol.hpp + fc_wlog( logger, "Handshake message validation: p2p_address to large: ${p}", ("p", msg.p2p_address.substr(0, max_handshake_str_length) + "...") ); + valid = false; } if (msg.os.empty()) { fc_wlog( logger, "Handshake message validation: os field is null string" ); valid = false; + } else if( msg.os.length() > max_handshake_str_length ) { + fc_wlog( logger, "Handshake message validation: os field to large: ${p}", ("p", msg.os.substr(0, max_handshake_str_length) + "...") ); + valid = false; + } + if( msg.agent.length() > max_handshake_str_length ) { + fc_wlog( logger, "Handshake message validation: agent field to large: ${p}", ("p", msg.agent.substr(0, max_handshake_str_length) + "...") ); + valid = false; } if ((msg.sig != chain::signature_type() || msg.token != sha256()) && (msg.token != fc::sha256::hash(msg.time))) { fc_wlog( logger, "Handshake message validation: token field invalid" ); @@ -2744,8 +2703,12 @@ namespace eosio { return; } if( msg.known_trx.mode != none ) { - fc_dlog( logger, "this is a ${m} notice with ${n} transactions", - ("m", modes_str( msg.known_trx.mode ))( "n", msg.known_trx.pending ) ); + if( logger.is_enabled( fc::log_level::debug ) ) { + const block_id_type& blkid = msg.known_blocks.ids.empty() ? block_id_type{} : msg.known_blocks.ids.back(); + fc_dlog( logger, "this is a ${m} notice with ${n} pending blocks: ${num} ${id}...", + ("m", modes_str( msg.known_blocks.mode ))("n", msg.known_blocks.pending) + ("num", block_header::num_from_id( blkid ))("id", blkid.str().substr( 8, 16 )) ); + } } switch (msg.known_trx.mode) { case none: @@ -2902,7 +2865,6 @@ namespace eosio { app().post(priority::high, [ptr{std::move(ptr)}, id, c = shared_from_this()]() mutable { c->process_signed_block( id, std::move( ptr ) ); }); - my_impl->dispatcher->bcast_notice( id ); } // called from application thread @@ -2936,8 +2898,9 @@ namespace eosio { go_away_reason reason = fatal_other; try { - my_impl->chain_plug->accept_block(msg); + bool accepted = my_impl->chain_plug->accept_block(msg, blk_id); my_impl->update_chain_info(); + if( !accepted ) return; reason = no_reason; } catch( const unlinkable_block_exception &ex) { peer_elog(c, "bad signed_block ${n} ${id}...: ${m}", ("n", blk_num)("id", blk_id.str().substr(8,16))("m",ex.what())); @@ -2959,6 +2922,7 @@ namespace eosio { if( reason == no_reason ) { boost::asio::post( my_impl->thread_pool->get_executor(), [dispatcher = my_impl->dispatcher.get(), cid=c->connection_id, blk_id, msg]() { + fc_dlog( logger, "accepted signed_block : #${n} ${id}...", ("n", msg->block_num())("id", blk_id.str().substr(8,16)) ); dispatcher->add_peer_block( blk_id, cid ); dispatcher->update_txns_block_num( msg ); }); @@ -3066,7 +3030,7 @@ namespace eosio { std::unique_lock g( connections_mtx ); auto it = (from ? connections.find(from) : connections.begin()); if (it == connections.end()) it = connections.begin(); - size_t num_rm = 0; + size_t num_rm = 0, num_clients = 0, num_peers = 0; while (it != connections.end()) { if (fc::time_point::now() >= max_time) { connection_wptr wit = *it; @@ -3077,13 +3041,16 @@ namespace eosio { } return; } + (*it)->peer_address().empty() ? ++num_clients : ++num_peers; if( !(*it)->socket_is_open() && !(*it)->connecting) { - if( (*it)->peer_address().length() > 0) { + if( !(*it)->peer_address().empty() ) { if( !(*it)->resolve_and_connect() ) { it = connections.erase(it); + --num_peers; ++num_rm; continue; } } else { + --num_clients; ++num_rm; it = connections.erase(it); continue; } @@ -3091,6 +3058,9 @@ namespace eosio { ++it; } g.unlock(); + if( num_clients > 0 || num_peers > 0 ) + fc_ilog( logger, "p2p client connections: ${num}/${max}, peer connections: ${pnum}/${pmax}", + ("num", num_clients)("max", max_client_count)("pnum", num_peers)("pmax", supplied_peers.size()) ); fc_dlog( logger, "connection monitor, removed ${n} connections", ("n", num_rm) ); if( reschedule ) { start_conn_timer( connector_period, std::weak_ptr()); @@ -3204,15 +3174,10 @@ namespace eosio { } // call from connection strand - bool connection::populate_handshake( handshake_message& hello ) { + bool connection::populate_handshake( handshake_message& hello, bool force ) { namespace sc = std::chrono; - bool send = false; - if( no_retry == wrong_version ) { - hello.network_version = net_version_base + proto_explicit_sync; // try previous version - send = true; - } else { - hello.network_version = net_version_base + net_version; - } + bool send = force; + hello.network_version = net_version_base + net_version; const auto prev_head_id = hello.head_id; uint32_t lib, head; std::tie( lib, std::ignore, head, @@ -3321,9 +3286,13 @@ namespace eosio { if( options.count( "p2p-listen-endpoint" ) && options.at("p2p-listen-endpoint").as().length()) { my->p2p_address = options.at( "p2p-listen-endpoint" ).as(); + EOS_ASSERT( my->p2p_address.length() <= max_p2p_address_length, chain::plugin_config_exception, + "p2p-listen-endpoint to long, must be less than ${m}", ("m", max_p2p_address_length) ); } if( options.count( "p2p-server-address" ) ) { my->p2p_server_address = options.at( "p2p-server-address" ).as(); + EOS_ASSERT( my->p2p_server_address.length() <= max_p2p_address_length, chain::plugin_config_exception, + "p2p_server_address to long, must be less than ${m}", ("m", max_p2p_address_length) ); } my->thread_pool_size = options.at( "net-threads" ).as(); @@ -3335,6 +3304,8 @@ namespace eosio { } if( options.count( "agent-name" )) { my->user_agent_name = options.at( "agent-name" ).as(); + EOS_ASSERT( my->user_agent_name.length() <= max_handshake_str_length, chain::plugin_config_exception, + "agent-name to long, must be less than ${m}", ("m", max_handshake_str_length) ); } if( options.count( "allowed-connection" )) { diff --git a/plugins/producer_plugin/producer_plugin.cpp b/plugins/producer_plugin/producer_plugin.cpp index 506050155a6..0ce8dfe10ea 100644 --- a/plugins/producer_plugin/producer_plugin.cpp +++ b/plugins/producer_plugin/producer_plugin.cpp @@ -332,8 +332,16 @@ class producer_plugin_impl : public std::enable_shared_from_thisid(); + bool on_incoming_block(const signed_block_ptr& block, const std::optional& block_id) { + auto& chain = chain_plug->chain(); + if ( chain.is_building_block() && _pending_block_mode == pending_block_mode::producing ) { + fc_wlog( _log, "dropped incoming block #${num} while producing #${pbn} for ${bt}, id: ${id}", + ("num", block->block_num())("pbn", chain.head_block_num() + 1) + ("bt", chain.pending_block_time())("id", block_id ? (*block_id).str() : "UNKNOWN") ); + return false; + } + + const auto& id = block_id ? *block_id : block->id(); auto blk_num = block->block_num(); fc_dlog(_log, "received incoming block ${n} ${id}", ("n", blk_num)("id", id)); @@ -341,11 +349,9 @@ class producer_plugin_impl : public std::enable_shared_from_thistimestamp < (fc::time_point::now() + fc::seconds( 7 )), block_from_the_future, "received a block from the future, ignoring it: ${id}", ("id", id) ); - chain::controller& chain = chain_plug->chain(); - /* de-dupe here... no point in aborting block if we already know the block */ auto existing = chain.fetch_block_by_id( id ); - if( existing ) { return; } + if( existing ) { return false; } // start processing of block auto bsf = chain.create_block_state_future( block ); @@ -367,7 +373,7 @@ class producer_plugin_impl : public std::enable_shared_from_this().publish( priority::medium, block ); @@ -395,6 +401,8 @@ class producer_plugin_impl : public std::enable_shared_from_thisblock->confirmed)("latency", (fc::time_point::now() - hbs->block->timestamp).count()/1000 ) ); } } + + return true; } class incoming_transaction_queue { @@ -651,7 +659,7 @@ void producer_plugin::set_program_options( "Limit (between 1 and 1000) on the multiple that CPU/NET virtual resources can extend during low usage (only enforced subjectively; use 1000 to not enforce any limit)") ("produce-time-offset-us", boost::program_options::value()->default_value(0), "offset of non last block producing time in microseconds. Negative number results in blocks to go out sooner, and positive number results in blocks to go out later") - ("last-block-time-offset-us", boost::program_options::value()->default_value(0), + ("last-block-time-offset-us", boost::program_options::value()->default_value(-200000), "offset of last block producing time in microseconds. Negative number results in blocks to go out sooner, and positive number results in blocks to go out later") ("max-scheduled-transaction-time-per-block-ms", boost::program_options::value()->default_value(100), "Maximum wall-clock time, in milliseconds, spent retiring scheduled transactions in any block before returning to normal transaction processing.") @@ -840,7 +848,7 @@ void producer_plugin::plugin_initialize(const boost::program_options::variables_ my->_incoming_block_subscription = app().get_channel().subscribe( [this](const signed_block_ptr& block) { try { - my->on_incoming_block(block); + my->on_incoming_block(block, {}); } LOG_AND_DROP(); }); @@ -852,8 +860,8 @@ void producer_plugin::plugin_initialize(const boost::program_options::variables_ }); my->_incoming_block_sync_provider = app().get_method().register_provider( - [this](const signed_block_ptr& block) { - my->on_incoming_block(block); + [this](const signed_block_ptr& block, const std::optional& block_id) { + return my->on_incoming_block(block, block_id); }); my->_incoming_transaction_async_provider = app().get_method().register_provider( diff --git a/scripts/helpers/eosio.sh b/scripts/helpers/eosio.sh index 5e92d19513f..a7ace5f53f9 100755 --- a/scripts/helpers/eosio.sh +++ b/scripts/helpers/eosio.sh @@ -291,7 +291,7 @@ function ensure-llvm() { elif [[ $NAME == "Amazon Linux" ]]; then execute unlink $LLVM_ROOT || true elif [[ $NAME == "CentOS Linux" ]]; then - execute ln -snf /opt/rh/llvm-toolset-7.0/root $LLVM_ROOT + export LOCAL_CMAKE_FLAGS="${LOCAL_CMAKE_FLAGS} -DLLVM_DIR='/opt/rh/llvm-toolset-7.0/root/usr/lib64/cmake/llvm'" fi } diff --git a/tests/Cluster.py b/tests/Cluster.py index 4102e3343f9..cb5d1d3ec2f 100644 --- a/tests/Cluster.py +++ b/tests/Cluster.py @@ -144,7 +144,7 @@ def setAlternateVersionLabels(self, file): # pylint: disable=too-many-branches # pylint: disable=too-many-statements def launch(self, pnodes=1, unstartedNodes=0, totalNodes=1, prodCount=1, topo="mesh", delay=1, onlyBios=False, dontBootstrap=False, - totalProducers=None, sharedProducers=0, extraNodeosArgs=None, useBiosBootFile=True, specificExtraNodeosArgs=None, onlySetProds=False, + totalProducers=None, sharedProducers=0, extraNodeosArgs=" --http-max-response-time-ms 990000 ", useBiosBootFile=True, specificExtraNodeosArgs=None, onlySetProds=False, pfSetupPolicy=PFSetupPolicy.FULL, alternateVersionLabelsFile=None, associatedNodeLabels=None, loadSystemContract=True): """Launch cluster. pnodes: producer nodes count @@ -220,7 +220,7 @@ def launch(self, pnodes=1, unstartedNodes=0, totalNodes=1, prodCount=1, topo="me if self.staging: cmdArr.append("--nogen") - nodeosArgs="--max-transaction-time -1 --http-max-response-time-ms 9999 --abi-serializer-max-time-ms 990000 --filter-on \"*\" --p2p-max-nodes-per-host %d" % (totalNodes) + nodeosArgs="--max-transaction-time -1 --abi-serializer-max-time-ms 990000 --filter-on \"*\" --p2p-max-nodes-per-host %d" % (totalNodes) if not self.walletd: nodeosArgs += " --plugin eosio::wallet_api_plugin" if self.enableMongo: diff --git a/tests/nodeos_multiple_version_protocol_feature_test.py b/tests/nodeos_multiple_version_protocol_feature_test.py index fdc0c3785bc..02c4bf11ea9 100755 --- a/tests/nodeos_multiple_version_protocol_feature_test.py +++ b/tests/nodeos_multiple_version_protocol_feature_test.py @@ -94,6 +94,10 @@ def hasBlockBecomeIrr(): assert cluster.launch(pnodes=4, totalNodes=4, prodCount=1, totalProducers=4, extraNodeosArgs=" --plugin eosio::producer_api_plugin ", useBiosBootFile=False, + specificExtraNodeosArgs={ + 0:"--http-max-response-time-ms 990000", + 1:"--http-max-response-time-ms 990000", + 2:"--http-max-response-time-ms 990000"}, onlySetProds=True, pfSetupPolicy=PFSetupPolicy.NONE, alternateVersionLabelsFile=alternateVersionLabelsFile, diff --git a/tests/nodeos_protocol_feature_test.py b/tests/nodeos_protocol_feature_test.py index 369068494ef..df416da1c29 100755 --- a/tests/nodeos_protocol_feature_test.py +++ b/tests/nodeos_protocol_feature_test.py @@ -45,7 +45,7 @@ def restartNode(node: Node, nodeId, chainArg=None, addSwapFlags=None): TestHelper.printSystemInfo("BEGIN") cluster.killall(allInstances=killAll) cluster.cleanup() - cluster.launch(extraNodeosArgs=" --plugin eosio::producer_api_plugin ", + cluster.launch(extraNodeosArgs=" --plugin eosio::producer_api_plugin --http-max-response-time-ms 990000 ", dontBootstrap=True, pfSetupPolicy=PFSetupPolicy.NONE) biosNode = cluster.biosNode diff --git a/tests/nodeos_under_min_avail_ram.py b/tests/nodeos_under_min_avail_ram.py index 6c9d6c7fc00..d48944344e4 100755 --- a/tests/nodeos_under_min_avail_ram.py +++ b/tests/nodeos_under_min_avail_ram.py @@ -88,7 +88,7 @@ def setName(self, num): minRAMValue=1002 maxRAMFlag="--chain-state-db-size-mb" maxRAMValue=1010 - extraNodeosArgs=" %s %d %s %d " % (minRAMFlag, minRAMValue, maxRAMFlag, maxRAMValue) + extraNodeosArgs=" %s %d %s %d --http-max-response-time-ms 990000 " % (minRAMFlag, minRAMValue, maxRAMFlag, maxRAMValue) if cluster.launch(onlyBios=False, pnodes=totalNodes, totalNodes=totalNodes, totalProducers=totalNodes, extraNodeosArgs=extraNodeosArgs, useBiosBootFile=False) is False: Utils.cmdError("launcher") errorExit("Failed to stand up eos cluster.") diff --git a/tests/prod_preactivation_test.py b/tests/prod_preactivation_test.py index dbc96c2c457..6543be1c288 100755 --- a/tests/prod_preactivation_test.py +++ b/tests/prod_preactivation_test.py @@ -68,7 +68,7 @@ Print("Stand up cluster") if cluster.launch(pnodes=prodCount, totalNodes=prodCount, prodCount=1, onlyBios=onlyBios, dontBootstrap=dontBootstrap, useBiosBootFile=False, - pfSetupPolicy=PFSetupPolicy.NONE, extraNodeosArgs=" --plugin eosio::producer_api_plugin") is False: + pfSetupPolicy=PFSetupPolicy.NONE, extraNodeosArgs=" --plugin eosio::producer_api_plugin --http-max-response-time-ms 990000 ") is False: cmdError("launcher") errorExit("Failed to stand up eos cluster.") diff --git a/unittests/block_tests.cpp b/unittests/block_tests.cpp index 023907ce3e6..3b98e4082d3 100644 --- a/unittests/block_tests.cpp +++ b/unittests/block_tests.cpp @@ -30,6 +30,13 @@ BOOST_AUTO_TEST_CASE(block_with_invalid_tx_test) auto invalid_packed_tx = packed_transaction(signed_tx); copy_b->transactions.back().trx = invalid_packed_tx; + // Re-calculate the transaction merkle + vector trx_digests; + const auto& trxs = copy_b->transactions; + for( const auto& a : trxs ) + trx_digests.emplace_back( a.digest() ); + copy_b->transaction_mroot = merkle( move(trx_digests) ); + // Re-sign the block auto header_bmroot = digest_type::hash( std::make_pair( copy_b->digest(), main.control->head_block_state()->blockroot_merkle.get_root() ) ); auto sig_digest = digest_type::hash( std::make_pair(header_bmroot, main.control->head_block_state()->pending_schedule.schedule_hash) ); diff --git a/unittests/forked_tests.cpp b/unittests/forked_tests.cpp index 7268a6d78c6..4ff7b07d350 100644 --- a/unittests/forked_tests.cpp +++ b/unittests/forked_tests.cpp @@ -265,7 +265,7 @@ BOOST_AUTO_TEST_CASE( forking ) try { wlog( "end push c2 blocks to c1" ); wlog( "now push dan's block to c1 but first corrupt it so it is a bad block" ); signed_block bad_block = std::move(*b); - bad_block.transaction_mroot = bad_block.previous; + bad_block.action_mroot = bad_block.previous; auto bad_block_bs = c.control->create_block_state_future( std::make_shared(std::move(bad_block)) ); c.control->abort_block(); BOOST_REQUIRE_EXCEPTION(c.control->push_block( bad_block_bs, forked_branch_callback{}, trx_meta_cache_lookup{} ), fc::exception,