diff --git a/.cicd/build.sh b/.cicd/build.sh index e22658d57b6..4ace105301e 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -2,17 +2,11 @@ set -eo pipefail . ./.cicd/helpers/general.sh mkdir -p $BUILD_DIR -CMAKE_EXTRAS="-DCMAKE_BUILD_TYPE='Release' -DENABLE_MULTIVERSION_PROTOCOL_TEST=true" +CMAKE_EXTRAS="-DCMAKE_BUILD_TYPE='Release' -DENABLE_MULTIVERSION_PROTOCOL_TEST=true -DBUILD_MONGO_DB_PLUGIN=true" if [[ "$(uname)" == 'Darwin' ]]; then # You can't use chained commands in execute - if [[ "$TRAVIS" == 'true' ]]; then + if [[ "$GITHUB_ACTIONS" == 'true' ]]; then export PINNED=false - brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/1d91e94e8ecdf6877ad2c24a7cda1114e50f2a14/Formula/llvm@4.rb # Workaround for Travis cannot build LLVM4 from source. - brew reinstall openssl@1.1 # Fixes issue where builds in Travis cannot find libcrypto. - ccache -s - CMAKE_EXTRAS="$CMAKE_EXTRAS -DCMAKE_CXX_COMPILER_LAUNCHER=ccache" - else - CMAKE_EXTRAS="$CMAKE_EXTRAS -DBUILD_MONGO_DB_PLUGIN=true" fi [[ ! "$PINNED" == 'false' ]] && CMAKE_EXTRAS="$CMAKE_EXTRAS -DCMAKE_TOOLCHAIN_FILE=$HELPERS_DIR/clang.make" cd $BUILD_DIR @@ -21,27 +15,16 @@ if [[ "$(uname)" == 'Darwin' ]]; then echo "make -j$JOBS" make -j$JOBS else # Linux - CMAKE_EXTRAS="$CMAKE_EXTRAS -DBUILD_MONGO_DB_PLUGIN=true" ARGS=${ARGS:-"--rm --init -v $(pwd):$MOUNTED_DIR"} PRE_COMMANDS="cd $MOUNTED_DIR/build" # PRE_COMMANDS: Executed pre-cmake # CMAKE_EXTRAS: Executed within and right before the cmake path (cmake CMAKE_EXTRAS ..) - [[ ! "$IMAGE_TAG" =~ 'unpinned' ]] && CMAKE_EXTRAS="$CMAKE_EXTRAS -DCMAKE_TOOLCHAIN_FILE=$MOUNTED_DIR/.cicd/helpers/clang.make -DCMAKE_CXX_COMPILER_LAUNCHER=ccache" - if [[ "$IMAGE_TAG" == 'amazon_linux-2-pinned' ]]; then - PRE_COMMANDS="$PRE_COMMANDS && export PATH=/usr/lib64/ccache:\\\$PATH" - elif [[ "$IMAGE_TAG" == 'centos-7.7-pinned' ]]; then - PRE_COMMANDS="$PRE_COMMANDS && export PATH=/usr/lib64/ccache:\\\$PATH" - elif [[ "$IMAGE_TAG" == 'ubuntu-16.04-pinned' ]]; then - PRE_COMMANDS="$PRE_COMMANDS && export PATH=/usr/lib/ccache:\\\$PATH" - elif [[ "$IMAGE_TAG" == 'ubuntu-18.04-pinned' ]]; then - PRE_COMMANDS="$PRE_COMMANDS && export PATH=/usr/lib/ccache:\\\$PATH" - elif [[ "$IMAGE_TAG" == 'amazon_linux-2-unpinned' ]]; then - PRE_COMMANDS="$PRE_COMMANDS && export PATH=/usr/lib64/ccache:\\\$PATH" + [[ ! "$IMAGE_TAG" =~ 'unpinned' ]] && CMAKE_EXTRAS="$CMAKE_EXTRAS -DCMAKE_TOOLCHAIN_FILE=$MOUNTED_DIR/.cicd/helpers/clang.make" + if [[ "$IMAGE_TAG" == 'amazon_linux-2-unpinned' ]]; then CMAKE_EXTRAS="$CMAKE_EXTRAS -DCMAKE_CXX_COMPILER='clang++' -DCMAKE_C_COMPILER='clang'" elif [[ "$IMAGE_TAG" == 'centos-7.7-unpinned' ]]; then - PRE_COMMANDS="$PRE_COMMANDS && source /opt/rh/devtoolset-8/enable && source /opt/rh/rh-python36/enable && export PATH=/usr/lib64/ccache:\\\$PATH" + PRE_COMMANDS="$PRE_COMMANDS && source /opt/rh/devtoolset-8/enable && source /opt/rh/rh-python36/enable" elif [[ "$IMAGE_TAG" == 'ubuntu-18.04-unpinned' ]]; then - PRE_COMMANDS="$PRE_COMMANDS && export PATH=/usr/lib/ccache:\\\$PATH" CMAKE_EXTRAS="$CMAKE_EXTRAS -DCMAKE_CXX_COMPILER='clang++' -DCMAKE_C_COMPILER='clang'" fi BUILD_COMMANDS="cmake $CMAKE_EXTRAS .. && make -j$JOBS" @@ -52,9 +35,9 @@ else # Linux [[ "$ENABLE_INSTALL" == 'true' ]] && COMMANDS="cp -r $MOUNTED_DIR /root/eosio && cd /root/eosio/build &&" COMMANDS="$COMMANDS $BUILD_COMMANDS" [[ "$ENABLE_INSTALL" == 'true' ]] && COMMANDS="$COMMANDS && make install" - elif [[ "$TRAVIS" == 'true' ]]; then - ARGS="$ARGS -v /usr/lib/ccache -v $HOME/.ccache:/opt/.ccache -e JOBS -e TRAVIS -e CCACHE_DIR=/opt/.ccache" - COMMANDS="ccache -s && $BUILD_COMMANDS" + elif [[ "$GITHUB_ACTIONS" == 'true' ]]; then + ARGS="$ARGS -e JOBS" + COMMANDS="$BUILD_COMMANDS" fi . $HELPERS_DIR/file-hash.sh $CICD_DIR/platforms/$PLATFORM_TYPE/$IMAGE_TAG.dockerfile COMMANDS="$PRE_COMMANDS && $COMMANDS" 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 2ab222638c3..e84256cf3ef 100755 --- a/.cicd/generate-pipeline.sh +++ b/.cicd/generate-pipeline.sh @@ -76,8 +76,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=$'' @@ -111,7 +111,7 @@ EOF - "cd eos && ./.cicd/build.sh" - "cd eos && tar -pczf build.tar.gz build && buildkite-agent artifact upload build.tar.gz" plugins: - - chef/anka#v0.5.5: + - EOSIO/anka#v0.5.7: no-volume: true inherit-environment-vars: true vm-name: ${MOJAVE_ANKA_TEMPLATE_NAME} @@ -124,7 +124,7 @@ EOF failover-registries: - 'registry_1' - 'registry_2' - pre-execute-sleep: 10 + pre-execute-ping-sleep: "8.8.8.8" pre-commands: - "git clone git@github.com:EOSIO/mac-anka-fleet.git && cd mac-anka-fleet && . ./ensure-tag.bash -u 12 -r 25G -a '-n'" env: @@ -134,7 +134,7 @@ EOF TEMPLATE_TAG: $MOJAVE_ANKA_TAG_BASE IMAGE_TAG: $(echo "$PLATFORM_JSON" | jq -r .FILE_NAME) PLATFORM_TYPE: $PLATFORM_TYPE - TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eos && cd eos && $GIT_FETCH git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive && export IMAGE_TAG=$(echo "$PLATFORM_JSON" | jq -r .FILE_NAME) && export PLATFORM_TYPE=$PLATFORM_TYPE && . ./.cicd/platforms/$PLATFORM_TYPE/$(echo "$PLATFORM_JSON" | jq -r .FILE_NAME).sh && cd ~/eos && cd .. && rm -rf eos" + TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eos && cd eos && $GIT_FETCH git checkout -f \$BUILDKITE_COMMIT && git submodule update --init --recursive && export IMAGE_TAG=$(echo "$PLATFORM_JSON" | jq -r .FILE_NAME) && export PLATFORM_TYPE=$PLATFORM_TYPE && . ./.cicd/platforms/$PLATFORM_TYPE/$(echo "$PLATFORM_JSON" | jq -r .FILE_NAME).sh && cd ~/eos && cd .. && rm -rf eos" PROJECT_TAG: $(echo "$PLATFORM_JSON" | jq -r .HASHED_IMAGE_TAG) timeout: ${TIMEOUT:-180} agents: "queue=mac-anka-large-node-fleet" @@ -191,7 +191,7 @@ EOF - "cd eos && buildkite-agent artifact download build.tar.gz . --step '$(echo "$PLATFORM_JSON" | jq -r .ICON) $(echo "$PLATFORM_JSON" | jq -r .PLATFORM_NAME_FULL) - Build' && tar -xzf build.tar.gz" - "cd eos && ./.cicd/test.sh scripts/parallel-test.sh" plugins: - - chef/anka#v0.5.4: + - EOSIO/anka#v0.5.7: no-volume: true inherit-environment-vars: true vm-name: ${MOJAVE_ANKA_TEMPLATE_NAME} @@ -202,7 +202,7 @@ EOF failover-registries: - 'registry_1' - 'registry_2' - pre-execute-sleep: 10 + pre-execute-ping-sleep: "8.8.8.8" agents: "queue=mac-anka-node-fleet" retry: manual: @@ -245,7 +245,7 @@ EOF - "cd eos && buildkite-agent artifact download build.tar.gz . --step '$(echo "$PLATFORM_JSON" | jq -r .ICON) $(echo "$PLATFORM_JSON" | jq -r .PLATFORM_NAME_FULL) - Build' && tar -xzf build.tar.gz" - "cd eos && ./.cicd/test.sh scripts/serial-test.sh $TEST_NAME" plugins: - - chef/anka#v0.5.4: + - EOSIO/anka#v0.5.7: no-volume: true inherit-environment-vars: true vm-name: ${MOJAVE_ANKA_TEMPLATE_NAME} @@ -256,7 +256,7 @@ EOF failover-registries: - 'registry_1' - 'registry_2' - pre-execute-sleep: 10 + pre-execute-ping-sleep: "8.8.8.8" agents: "queue=mac-anka-node-fleet" retry: manual: @@ -301,7 +301,7 @@ EOF - "cd eos && buildkite-agent artifact download build.tar.gz . --step '$(echo "$PLATFORM_JSON" | jq -r .ICON) $(echo "$PLATFORM_JSON" | jq -r .PLATFORM_NAME_FULL) - Build' ${BUILD_SOURCE} && tar -xzf build.tar.gz" - "cd eos && ./.cicd/test.sh scripts/long-running-test.sh $TEST_NAME" plugins: - - chef/anka#v0.5.4: + - EOSIO/anka#v0.5.7: no-volume: true inherit-environment-vars: true vm-name: ${MOJAVE_ANKA_TEMPLATE_NAME} @@ -312,7 +312,7 @@ EOF failover-registries: - 'registry_1' - 'registry_2' - pre-execute-sleep: 10 + pre-execute-ping-sleep: "8.8.8.8" agents: "queue=mac-anka-node-fleet" retry: manual: @@ -331,6 +331,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/amazon_linux-2-pinned.dockerfile b/.cicd/platforms/pinned/amazon_linux-2-pinned.dockerfile index 60afc79a567..9abd0baf708 100644 --- a/.cicd/platforms/pinned/amazon_linux-2-pinned.dockerfile +++ b/.cicd/platforms/pinned/amazon_linux-2-pinned.dockerfile @@ -78,7 +78,4 @@ RUN curl -L https://github.com/mongodb/mongo-cxx-driver/archive/r3.4.0.tar.gz -o cd / && \ rm -rf mongo-cxx-driver-r3.4.0.tar.gz /mongo-cxx-driver-r3.4.0 # add mongodb to path -ENV PATH=${PATH}:/mongodb-linux-x86_64-amazon-3.6.3/bin -# install ccache -RUN curl -LO http://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/c/ccache-3.3.4-1.el7.x86_64.rpm && \ - yum install -y ccache-3.3.4-1.el7.x86_64.rpm \ No newline at end of file +ENV PATH=${PATH}:/mongodb-linux-x86_64-amazon-3.6.3/bin \ No newline at end of file diff --git a/.cicd/platforms/pinned/centos-7.7-pinned.dockerfile b/.cicd/platforms/pinned/centos-7.7-pinned.dockerfile index 52ef6fe8df9..bc94fd63415 100644 --- a/.cicd/platforms/pinned/centos-7.7-pinned.dockerfile +++ b/.cicd/platforms/pinned/centos-7.7-pinned.dockerfile @@ -87,10 +87,4 @@ RUN curl -L https://github.com/mongodb/mongo-cxx-driver/archive/r3.4.0.tar.gz -o cd / && \ rm -rf mongo-cxx-driver-r3.4.0.tar.gz /mongo-cxx-driver-r3.4.0 # add mongodb to path -ENV PATH=${PATH}:/mongodb-linux-x86_64-amazon-3.6.3/bin -# install ccache -RUN curl -LO http://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/c/ccache-3.3.4-1.el7.x86_64.rpm && \ - yum install -y ccache-3.3.4-1.el7.x86_64.rpm -# fix ccache for centos -RUN cd /usr/lib64/ccache && ln -s ../../bin/ccache c++ -ENV CCACHE_PATH="/opt/rh/devtoolset-8/root/usr/bin" \ No newline at end of file +ENV PATH=${PATH}:/mongodb-linux-x86_64-amazon-3.6.3/bin \ 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 06614de71aa..993e41eb271 100755 --- a/.cicd/platforms/pinned/macos-10.14-pinned.sh +++ b/.cicd/platforms/pinned/macos-10.14-pinned.sh @@ -2,7 +2,7 @@ set -eo pipefail VERSION=1 brew update -brew install git cmake python@2 python libtool libusb graphviz automake wget gmp pkgconfig doxygen openssl@1.1 jq || : +brew install git cmake python libtool libusb graphviz automake wget gmp pkgconfig doxygen openssl@1.1 jq || : # install clang from source git clone --single-branch --branch release_80 https://git.llvm.org/git/llvm.git clang8 cd clang8 @@ -59,11 +59,13 @@ sudo make install cd ../.. rm -rf llvm # install boost from source +## 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.70.0/source/boost_1_70_0.tar.bz2 tar -xjf boost_1_70_0.tar.bz2 cd boost_1_70_0 ./bootstrap.sh --prefix=/usr/local -sudo ./b2 --with-iostreams --with-date_time --with-filesystem --with-system --with-program_options --with-chrono --with-test -q -j$(getconf _NPROCESSORS_ONLN) install +sudo SDKROOT="$SDKROOT" ./b2 --with-iostreams --with-date_time --with-filesystem --with-system --with-program_options --with-chrono --with-test -q -j$(getconf _NPROCESSORS_ONLN) install cd .. sudo rm -rf boost_1_70_0.tar.bz2 boost_1_70_0 # install mongoDB diff --git a/.cicd/platforms/pinned/ubuntu-16.04-pinned.dockerfile b/.cicd/platforms/pinned/ubuntu-16.04-pinned.dockerfile index 8cdbe42e9ef..ad25acd5d36 100644 --- a/.cicd/platforms/pinned/ubuntu-16.04-pinned.dockerfile +++ b/.cicd/platforms/pinned/ubuntu-16.04-pinned.dockerfile @@ -79,13 +79,4 @@ RUN curl -L https://github.com/mongodb/mongo-cxx-driver/archive/r3.4.0.tar.gz -o cd / && \ rm -rf mongo-cxx-driver-r3.4.0.tar.gz /mongo-cxx-driver-r3.4.0 # add mongodb to path -ENV PATH=${PATH}:/mongodb-linux-x86_64-ubuntu1604-3.6.3/bin -# install ccache -RUN curl -LO https://github.com/ccache/ccache/releases/download/v3.4.1/ccache-3.4.1.tar.gz && \ - tar -xzf ccache-3.4.1.tar.gz && \ - cd ccache-3.4.1 && \ - ./configure && \ - make && \ - make install && \ - cd / && \ - rm -rf ccache-3.4.1.tar.gz /ccache-3.4.1 \ No newline at end of file +ENV PATH=${PATH}:/mongodb-linux-x86_64-ubuntu1604-3.6.3/bin \ No newline at end of file diff --git a/.cicd/platforms/pinned/ubuntu-18.04-pinned.dockerfile b/.cicd/platforms/pinned/ubuntu-18.04-pinned.dockerfile index 5448a23c04c..8d3a85fc50e 100644 --- a/.cicd/platforms/pinned/ubuntu-18.04-pinned.dockerfile +++ b/.cicd/platforms/pinned/ubuntu-18.04-pinned.dockerfile @@ -5,9 +5,10 @@ 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 + libcurl4-gnutls-dev pkg-config patch vim-common jq # build cmake. RUN curl -LO https://cmake.org/files/v3.13/cmake-3.13.2.tar.gz && \ tar -xzf cmake-3.13.2.tar.gz && \ diff --git a/.cicd/platforms/unpinned/amazon_linux-2-unpinned.dockerfile b/.cicd/platforms/unpinned/amazon_linux-2-unpinned.dockerfile index b2c086a6915..609c2fbe8c1 100644 --- a/.cicd/platforms/unpinned/amazon_linux-2-unpinned.dockerfile +++ b/.cicd/platforms/unpinned/amazon_linux-2-unpinned.dockerfile @@ -61,7 +61,4 @@ RUN curl -L https://github.com/mongodb/mongo-cxx-driver/archive/r3.4.0.tar.gz -o cd / && \ rm -rf mongo-cxx-driver-r3.4.0.tar.gz /mongo-cxx-driver-r3.4.0 # add mongodb to path -ENV PATH=${PATH}:/mongodb-linux-x86_64-amazon-3.6.3/bin -# install ccache -RUN curl -LO http://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/c/ccache-3.3.4-1.el7.x86_64.rpm && \ - yum install -y ccache-3.3.4-1.el7.x86_64.rpm \ No newline at end of file +ENV PATH=${PATH}:/mongodb-linux-x86_64-amazon-3.6.3/bin \ No newline at end of file diff --git a/.cicd/platforms/unpinned/centos-7.7-unpinned.dockerfile b/.cicd/platforms/unpinned/centos-7.7-unpinned.dockerfile index 4005a0a8dc6..83651700696 100644 --- a/.cicd/platforms/unpinned/centos-7.7-unpinned.dockerfile +++ b/.cicd/platforms/unpinned/centos-7.7-unpinned.dockerfile @@ -74,10 +74,4 @@ RUN curl -L https://github.com/mongodb/mongo-cxx-driver/archive/r3.4.0.tar.gz -o cd / && \ rm -rf mongo-cxx-driver-r3.4.0.tar.gz /mongo-cxx-driver-r3.4.0 # add mongodb to path -ENV PATH=${PATH}:/mongodb-linux-x86_64-amazon-3.6.3/bin -# install ccache -RUN curl -LO http://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/c/ccache-3.3.4-1.el7.x86_64.rpm && \ - yum install -y ccache-3.3.4-1.el7.x86_64.rpm -# fix ccache for centos -RUN cd /usr/lib64/ccache && ln -s ../../bin/ccache c++ -ENV CCACHE_PATH="/opt/rh/devtoolset-8/root/usr/bin" \ No newline at end of file +ENV PATH=${PATH}:/mongodb-linux-x86_64-amazon-3.6.3/bin \ No newline at end of file diff --git a/.cicd/platforms/unpinned/macos-10.14-unpinned.sh b/.cicd/platforms/unpinned/macos-10.14-unpinned.sh index 81f39f9eb28..2cb308ca0d7 100755 --- a/.cicd/platforms/unpinned/macos-10.14-unpinned.sh +++ b/.cicd/platforms/unpinned/macos-10.14-unpinned.sh @@ -1,8 +1,8 @@ #!/bin/bash set -eo pipefail -VERSION=1 +VERSION=2 brew update -brew install git cmake python@2 python libtool libusb graphviz automake wget gmp pkgconfig doxygen openssl@1.1 jq boost || : +brew install git cmake python libtool libusb graphviz automake wget gmp pkgconfig doxygen openssl@1.1 jq boost || : # install llvm 4 from source git clone --depth 1 --single-branch --branch release_40 https://github.com/llvm-mirror/llvm.git llvm cd llvm diff --git a/.cicd/platforms/unpinned/ubuntu-18.04-unpinned.dockerfile b/.cicd/platforms/unpinned/ubuntu-18.04-unpinned.dockerfile index 4e0feaa0180..467ad936c2f 100644 --- a/.cicd/platforms/unpinned/ubuntu-18.04-unpinned.dockerfile +++ b/.cicd/platforms/unpinned/ubuntu-18.04-unpinned.dockerfile @@ -7,7 +7,7 @@ RUN apt-get update && \ bzip2 automake libbz2-dev libssl-dev doxygen graphviz libgmp3-dev \ autotools-dev libicu-dev python2.7 python2.7-dev python3 python3-dev \ autoconf libtool g++ gcc curl zlib1g-dev sudo ruby libusb-1.0-0-dev \ - libcurl4-gnutls-dev pkg-config patch llvm-4.0 clang ccache vim-common jq + libcurl4-gnutls-dev pkg-config patch llvm-4.0 clang vim-common jq # build cmake. RUN curl -LO https://cmake.org/files/v3.13/cmake-3.13.2.tar.gz && \ tar -xzf cmake-3.13.2.tar.gz && \ diff --git a/.cicd/submodule-regression-check.sh b/.cicd/submodule-regression-check.sh index 47b4bcacc4b..80999067204 100755 --- a/.cicd/submodule-regression-check.sh +++ b/.cicd/submodule-regression-check.sh @@ -2,16 +2,15 @@ set -eo pipefail declare -A PR_MAP declare -A BASE_MAP -# Support Travis and BK -if ${TRAVIS:-false}; then - [[ -z $TRAVIS_PULL_REQUEST_BRANCH ]] && echo "Unable to find TRAVIS_PULL_REQUEST_BRANCH ENV. Skipping submodule regression check." && exit 0 - BASE_BRANCH=$TRAVIS_BRANCH - CURRENT_BRANCH=$TRAVIS_PULL_REQUEST_BRANCH - [[ ! -z $TRAVIS_PULL_REQUEST_SLUG ]] && CURRENT_BRANCH=$TRAVIS_COMMIT # When we're not running from a PR, the slug is not set. When we are, we need to use the TRAVIS_COMMIT to be sure we're supporting the Forked PR's merge/code that's in the EOS repo. This is needed for the git log below. -else + +if [[ $BUILDKITE == true ]]; then [[ -z $BUILDKITE_PULL_REQUEST_BASE_BRANCH ]] && echo "Unable to find BUILDKITE_PULL_REQUEST_BASE_BRANCH ENV. Skipping submodule regression check." && exit 0 BASE_BRANCH=$BUILDKITE_PULL_REQUEST_BASE_BRANCH CURRENT_BRANCH=$BUILDKITE_BRANCH +else + [[ -z $GITHUB_BASE_REF ]] && echo "Cannot find \$GITHUB_BASE_REF, so we have nothing to compare submodules to. Skipping submodule regression check." && exit 0 + BASE_BRANCH=$GITHUB_BASE_REF + CURRENT_BRANCH=$GITHUB_SHA fi echo "getting submodule info for $CURRENT_BRANCH" @@ -27,17 +26,15 @@ while read -r a b; do done < <(git submodule --quiet foreach --recursive 'echo $path `git log -1 --format=%ct`') # We need to switch back to the PR ref/head so we can git log properly -if [[ $TRAVIS == true && ! -z $TRAVIS_PULL_REQUEST_SLUG ]]; then - echo "git fetch origin +refs/pull/$TRAVIS_PULL_REQUEST/merge:" - git fetch origin +refs/pull/$TRAVIS_PULL_REQUEST/merge: 1> /dev/null - echo "switching back to $TRAVIS_COMMIT" - echo 'git checkout -qf FETCH_HEAD' - git checkout -qf FETCH_HEAD 1> /dev/null -elif [[ $BUILDKITE == true ]]; then - echo "switching back to $CURRENT_BRANCH" - git checkout -f $CURRENT_BRANCH 1> /dev/null +if [[ $BUILDKITE != true ]]; then + echo "git fetch origin +$GITHUB_REF:" + git fetch origin +${GITHUB_REF}: 1> /dev/null fi +echo "switching back to $CURRENT_BRANCH..." +echo "git checkout -qf $CURRENT_BRANCH" +git checkout -qf $CURRENT_BRANCH 1> /dev/null + for k in "${!BASE_MAP[@]}"; do base_ts=${BASE_MAP[$k]} pr_ts=${PR_MAP[$k]} 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/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000000..f3bb217d6f4 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,338 @@ +name: Pull Request +on: [pull_request] + +jobs: + start-job: + name: Start Job + runs-on: ubuntu-latest + steps: + - name: Start Job. + run: echo "PR created. Builds will be triggered here for forked PRs or Buildkite for internal PRs." + + + submodule_regression_check: + if: github.event.pull_request.base.repo.id != github.event.pull_request.head.repo.id + name: Submodule Regression Check + runs-on: ubuntu-latest + needs: start-job + steps: + - name: Checkout + uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e + with: + submodules: recursive + - name: Submodule Regression Check + run: ./.cicd/submodule-regression-check.sh + + + amazon_linux-2-build: + if: github.event.pull_request.base.repo.id != github.event.pull_request.head.repo.id + name: Amazon_Linux 2 | Build + runs-on: ubuntu-latest + needs: start-job + steps: + - name: Checkout + uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e + with: + submodules: recursive + - name: Build + run: | + ./.cicd/build.sh + tar -pczf build.tar.gz build + env: + IMAGE_TAG: amazon_linux-2-pinned + PLATFORM_TYPE: pinned + - name: Upload Build Artifact + uses: actions/upload-artifact@v1 + with: + name: amazon_linux-2-build + path: build.tar.gz + amazon_linux-2-parallel-test: + name: Amazon_Linux 2 | Parallel Test + runs-on: ubuntu-latest + needs: amazon_linux-2-build + steps: + - name: Checkout + uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e + with: + submodules: recursive + - name: Download Build Artifact + uses: actions/download-artifact@v1 + with: + name: amazon_linux-2-build + - name: Parallel Test + run: | + tar -xzf amazon_linux-2-build/build.tar.gz + ./.cicd/test.sh scripts/parallel-test.sh + env: + IMAGE_TAG: amazon_linux-2-pinned + PLATFORM_TYPE: pinned + amazon_linux-2-serial-test: + name: Amazon_Linux 2 | Serial Test + runs-on: ubuntu-latest + needs: amazon_linux-2-build + steps: + - name: Checkout + uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e + with: + submodules: recursive + - name: Download Build Artifact + uses: actions/download-artifact@v1 + with: + name: amazon_linux-2-build + - name: Serial Test + run: | + tar -xzf amazon_linux-2-build/build.tar.gz + ./.cicd/test.sh scripts/serial-test.sh + env: + IMAGE_TAG: amazon_linux-2-pinned + PLATFORM_TYPE: pinned + + + centos-77-build: + if: github.event.pull_request.base.repo.id != github.event.pull_request.head.repo.id + name: CentOS 7.7 | Build + runs-on: ubuntu-latest + needs: start-job + steps: + - name: Checkout + uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e + with: + submodules: recursive + - name: Build + run: | + ./.cicd/build.sh + tar -pczf build.tar.gz build + env: + IMAGE_TAG: centos-7.7-pinned + PLATFORM_TYPE: pinned + - name: Upload Build Artifact + uses: actions/upload-artifact@v1 + with: + name: centos-77-build + path: build.tar.gz + centos-77-parallel-test: + name: CentOS 7.7 | Parallel Test + runs-on: ubuntu-latest + needs: centos-77-build + steps: + - name: Checkout + uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e + with: + submodules: recursive + - name: Download Build Artifact + uses: actions/download-artifact@v1 + with: + name: centos-77-build + - name: Parallel Test + run: | + tar -xzf centos-77-build/build.tar.gz + ./.cicd/test.sh scripts/parallel-test.sh + env: + IMAGE_TAG: centos-7.7-pinned + PLATFORM_TYPE: pinned + centos-77-serial-test: + name: CentOS 7.7 | Serial Test + runs-on: ubuntu-latest + needs: centos-77-build + steps: + - name: Checkout + uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e + with: + submodules: recursive + - name: Download Build Artifact + uses: actions/download-artifact@v1 + with: + name: centos-77-build + - name: Serial Test + run: | + tar -xzf centos-77-build/build.tar.gz + ./.cicd/test.sh scripts/serial-test.sh + env: + IMAGE_TAG: centos-7.7-pinned + PLATFORM_TYPE: pinned + + + ubuntu-1604-build: + if: github.event.pull_request.base.repo.id != github.event.pull_request.head.repo.id + name: Ubuntu 16.04 | Build + runs-on: ubuntu-latest + needs: start-job + steps: + - name: Checkout + uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e + with: + submodules: recursive + - name: Build + run: | + ./.cicd/build.sh + tar -pczf build.tar.gz build + env: + IMAGE_TAG: ubuntu-16.04-pinned + PLATFORM_TYPE: pinned + - name: Upload Build Artifact + uses: actions/upload-artifact@v1 + with: + name: ubuntu-1604-build + path: build.tar.gz + ubuntu-1604-parallel-test: + name: Ubuntu 16.04 | Parallel Test + runs-on: ubuntu-latest + needs: ubuntu-1604-build + steps: + - name: Checkout + uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e + with: + submodules: recursive + - name: Download Build Artifact + uses: actions/download-artifact@v1 + with: + name: ubuntu-1604-build + - name: Parallel Test + run: | + tar -xzf ubuntu-1604-build/build.tar.gz + ./.cicd/test.sh scripts/parallel-test.sh + env: + IMAGE_TAG: ubuntu-16.04-pinned + PLATFORM_TYPE: pinned + ubuntu-1604-serial-test: + name: Ubuntu 16.04 | Serial Test + runs-on: ubuntu-latest + needs: ubuntu-1604-build + steps: + - name: Checkout + uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e + with: + submodules: recursive + - name: Download Build Artifact + uses: actions/download-artifact@v1 + with: + name: ubuntu-1604-build + - name: Serial Test + run: | + tar -xzf ubuntu-1604-build/build.tar.gz + ./.cicd/test.sh scripts/serial-test.sh + env: + IMAGE_TAG: ubuntu-16.04-pinned + PLATFORM_TYPE: pinned + + + ubuntu-1804-build: + if: github.event.pull_request.base.repo.id != github.event.pull_request.head.repo.id + name: Ubuntu 18.04 | Build + runs-on: ubuntu-latest + needs: start-job + steps: + - name: Checkout + uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e + with: + submodules: recursive + - name: Build + run: | + ./.cicd/build.sh + tar -pczf build.tar.gz build + env: + IMAGE_TAG: ubuntu-18.04-pinned + PLATFORM_TYPE: pinned + - name: Upload Build Artifact + uses: actions/upload-artifact@v1 + with: + name: ubuntu-1804-build + path: build.tar.gz + ubuntu-1804-parallel-test: + name: Ubuntu 18.04 | Parallel Test + runs-on: ubuntu-latest + needs: ubuntu-1804-build + steps: + - name: Checkout + uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e + with: + submodules: recursive + - name: Download Build Artifact + uses: actions/download-artifact@v1 + with: + name: ubuntu-1804-build + - name: Parallel Test + run: | + tar -xzf ubuntu-1804-build/build.tar.gz + ./.cicd/test.sh scripts/parallel-test.sh + env: + IMAGE_TAG: ubuntu-18.04-pinned + PLATFORM_TYPE: pinned + ubuntu-1804-serial-test: + name: Ubuntu 18.04 | Serial Test + runs-on: ubuntu-latest + needs: ubuntu-1804-build + steps: + - name: Checkout + uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e + with: + submodules: recursive + - name: Download Build Artifact + uses: actions/download-artifact@v1 + with: + name: ubuntu-1804-build + - name: Serial Test + run: | + tar -xzf ubuntu-1804-build/build.tar.gz + ./.cicd/test.sh scripts/serial-test.sh + env: + IMAGE_TAG: ubuntu-18.04-pinned + PLATFORM_TYPE: pinned + + + macos-1015-build: + if: github.event.pull_request.base.repo.id != github.event.pull_request.head.repo.id + name: MacOS 10.15 | Build + runs-on: macos-latest + needs: start-job + steps: + - name: Checkout + uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e + with: + submodules: recursive + - name: Build + run: | + ./.cicd/platforms/unpinned/macos-10.14-unpinned.sh + ./.cicd/build.sh + tar -pczf build.tar.gz build + - name: Upload Build Artifact + uses: actions/upload-artifact@v1 + with: + name: macos-1015-build + path: build.tar.gz + macos-1015-parallel-test: + name: MacOS 10.15 | Parallel Test + runs-on: macos-latest + needs: macos-1015-build + steps: + - name: Checkout + uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e + with: + submodules: recursive + - name: Download Build Artifact + uses: actions/download-artifact@v1 + with: + name: macos-1015-build + - name: Parallel Test + run: | + ./.cicd/platforms/unpinned/macos-10.14-unpinned.sh + tar -xzf macos-1015-build/build.tar.gz + ./.cicd/test.sh scripts/parallel-test.sh + macos-1015-serial-test: + name: MacOS 10.15 | Serial Test + runs-on: macos-latest + needs: macos-1015-build + steps: + - name: Checkout + uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e + with: + submodules: recursive + - name: Download Build Artifact + uses: actions/download-artifact@v1 + with: + name: macos-1015-build + - name: Serial Test + run: | + ./.cicd/platforms/unpinned/macos-10.14-unpinned.sh + tar -xzf macos-1015-build/build.tar.gz + ./.cicd/test.sh scripts/serial-test.sh \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index 80fe86f626d..e4fc1275311 100644 --- a/.gitmodules +++ b/.gitmodules @@ -18,3 +18,9 @@ [submodule "libraries/yubihsm"] path = libraries/yubihsm url = https://github.com/Yubico/yubihsm-shell +[submodule "plugins/uos_plugins"] + path = plugins/uos_plugins + url = https://github.com/UOSnetwork/uos.plugins +[submodule "libraries/singularity"] + path = libraries/singularity + url = https://github.com/UOSnetwork/singularity diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 1cf1daa32c8..00000000000 --- a/.travis.yml +++ /dev/null @@ -1,60 +0,0 @@ -language: cpp -git: - depth: false # prevent git describe failure when executing the appbase version.cmake.in -cache: - ccache: true - directories: - - $HOME/Library/Caches/Homebrew -if: fork = true OR type = api OR type = cron -matrix: - include: - - os: linux - dist: xenial - services: docker - env: - - PLATFORM_TYPE='pinned' - - IMAGE_TAG='ubuntu-18.04-pinned' - - os: linux - dist: xenial - services: docker - env: - - PLATFORM_TYPE='pinned' - - IMAGE_TAG='ubuntu-16.04-pinned' - - os: linux - dist: xenial - services: docker - env: - - PLATFORM_TYPE='pinned' - - IMAGE_TAG='amazon_linux-2-pinned' - - os: linux - dist: xenial - services: docker - env: - - PLATFORM_TYPE='pinned' - - IMAGE_TAG='centos-7.7-pinned' - - os: osx - osx_image: xcode10.2 - addons: - homebrew: - update: true - packages: - - ccache - - jq - - boost - - python@2 - - python - - libtool - - libusb - - graphviz - - automake - - wget - - gmp - - pkgconfig - - doxygen - - openssl@1.1 - env: - - PATH="/usr/local/opt/ccache/libexec:$PATH" -script: "ccache --max-size=1G && ./.cicd/build.sh && ./.cicd/test.sh scripts/parallel-test.sh && ./.cicd/test.sh scripts/serial-test.sh && if [[ $(uname) != 'Darwin' ]]; then ./.cicd/submodule-regression-check.sh; fi" -notifications: - webhooks: - secure: gmqODqoFAil2cR7v++ibqRNECBOSD/VJX+2qPa7XptkVWmVMzbII5CNgBQAscjFsp9arHPMXCCzkBi847PCSiHdsnYFQ4T273FLRWr3cDbLjfmR+BJ7dGKvQnlpSi2Ze2TtAPJyRl+iv+cxDj7cWE5zw2c4xbgh1a/cNO+/ayUfFkyMEIfVWRsHkdkra4gOLywou0XRLHr4CX1V60uU7uuqATnIMMi7gQYwiKKtZqjkbf8wcBvZirDhjQ6lDPN5tnZo6L4QHmqjtzNJg/UrD4h+zES53dLVI4uxlXRAwwpw+mJOFA3QE/3FT+bMQjLCffUz4gZaWcdgebPYzrwSWUbJoFdWAOwcTqivQY0FIQzcz/r6uGWcwWTavzkPEbg68BVM2BZId/0110J6feeTkpJ3MPV+UsIoGTvbg50vi/I06icftuZ/cLqDj3+Emifm7Jlr1sRTSdqtYAJj/2ImUfsb46cwgjAVhFOTvc+KuPgJQgvOXV7bZkxEr5qDWo8Al2sV8BWb83j1rMlZ4LfERokImDVqxu2kkcunchzvhtYFTesSpmwegVpwceCtOtO0rEUgATnfTEHzk2rm8nuz4UtidsQnluUKqmKD0QCqHXFfn+3ZRJsDqr+iCYdxv1BAeAVc9q1L7bgrKDMGiJgkxuhZ2v3J2SflWLvjZjFDduuc= diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b923b39783..a21b2aa1062 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required( VERSION 3.8 ) -project( EOSIO ) +project( UOS ) include(CTest) # suppresses DartConfiguration.tcl error enable_testing() @@ -28,7 +28,7 @@ set( CXX_STANDARD_REQUIRED ON) set(VERSION_MAJOR 1) set(VERSION_MINOR 8) -set(VERSION_PATCH 9) +set(VERSION_PATCH 12) #set(VERSION_SUFFIX develop) if(VERSION_SUFFIX) @@ -64,6 +64,7 @@ endif() set(CMAKE_EXPORT_COMPILE_COMMANDS "ON") set(BUILD_DOXYGEN FALSE CACHE BOOL "Build doxygen documentation on every make") set(BUILD_MONGO_DB_PLUGIN FALSE CACHE BOOL "Build mongo database plugin") +set(BUILD_UOS_BLOCKS_EXPORTER TRUE CACHE BOOL "Build UOS blocks exporter") set(ENABLE_MULTIVERSION_PROTOCOL_TEST FALSE CACHE BOOL "Enable nodeos multiversion protocol test") # add defaults for openssl @@ -110,7 +111,8 @@ find_package(Boost 1.67 REQUIRED COMPONENTS program_options chrono unit_test_framework - iostreams) + iostreams + thread) add_definitions(-DBOOST_ASIO_DISABLE_STD_EXPERIMENTAL_STRING_VIEW) diff --git a/CMakeModules/EosioTester.cmake.in b/CMakeModules/EosioTester.cmake.in index b22e638bb53..b3329427fb6 100644 --- a/CMakeModules/EosioTester.cmake.in +++ b/CMakeModules/EosioTester.cmake.in @@ -63,8 +63,10 @@ find_library(libplatform Platform @CMAKE_INSTALL_PREFIX@/lib64 @CMAKE_INSTALL_PR find_library(liblogging Logging @CMAKE_INSTALL_PREFIX@/lib64 @CMAKE_INSTALL_PREFIX@/lib NO_DEFAULT_PATH) find_library(libruntime Runtime @CMAKE_INSTALL_PREFIX@/lib64 @CMAKE_INSTALL_PREFIX@/lib NO_DEFAULT_PATH) find_library(libsoftfloat softfloat @CMAKE_INSTALL_PREFIX@/lib64 @CMAKE_INSTALL_PREFIX@/lib NO_DEFAULT_PATH) -find_library(liboscrypto crypto @OPENSSL_ROOT_DIR@/lib NO_DEFAULT_PATH) -find_library(libosssl ssl @OPENSSL_ROOT_DIR@/lib NO_DEFAULT_PATH) +get_filename_component(cryptodir @OPENSSL_CRYPTO_LIBRARY@ DIRECTORY) +find_library(liboscrypto crypto "${cryptodir}" NO_DEFAULT_PATH) +get_filename_component(ssldir @OPENSSL_SSL_LIBRARY@ DIRECTORY) +find_library(libosssl ssl "${ssldir}" NO_DEFAULT_PATH) find_library(libchainbase chainbase @CMAKE_INSTALL_PREFIX@/lib64 @CMAKE_INSTALL_PREFIX@/lib NO_DEFAULT_PATH) find_library(libbuiltins builtins @CMAKE_INSTALL_PREFIX@/lib64 @CMAKE_INSTALL_PREFIX@/lib NO_DEFAULT_PATH) find_library(GMP_LIBRARIES NAMES libgmp.a gmp.lib gmp libgmp-10 mpir diff --git a/CMakeModules/EosioTesterBuild.cmake.in b/CMakeModules/EosioTesterBuild.cmake.in index 4149ef5251d..d5d2c8a5962 100644 --- a/CMakeModules/EosioTesterBuild.cmake.in +++ b/CMakeModules/EosioTesterBuild.cmake.in @@ -62,8 +62,10 @@ find_library(libplatform Platform @CMAKE_BINARY_DIR@/libraries/wasm-jit/Source/P find_library(liblogging Logging @CMAKE_BINARY_DIR@/libraries/wasm-jit/Source/Logging NO_DEFAULT_PATH) find_library(libruntime Runtime @CMAKE_BINARY_DIR@/libraries/wasm-jit/Source/Runtime NO_DEFAULT_PATH) find_library(libsoftfloat softfloat @CMAKE_BINARY_DIR@/libraries/softfloat NO_DEFAULT_PATH) -find_library(liboscrypto crypto @OPENSSL_ROOT_DIR@/lib NO_DEFAULT_PATH) -find_library(libosssl ssl @OPENSSL_ROOT_DIR@/lib NO_DEFAULT_PATH) +get_filename_component(cryptodir @OPENSSL_CRYPTO_LIBRARY@ DIRECTORY) +find_library(liboscrypto crypto "${cryptodir}" NO_DEFAULT_PATH) +get_filename_component(ssldir @OPENSSL_SSL_LIBRARY@ DIRECTORY) +find_library(libosssl ssl "${ssldir}" NO_DEFAULT_PATH) find_library(libchainbase chainbase @CMAKE_BINARY_DIR@/libraries/chainbase NO_DEFAULT_PATH) find_library(libbuiltins builtins @CMAKE_BINARY_DIR@/libraries/builtins NO_DEFAULT_PATH) find_library(GMP_LIBRARIES NAMES libgmp.a gmp.lib gmp libgmp-10 mpir diff --git a/README.md b/README.md index 1723638aa15..7c97c61ad0a 100644 --- a/README.md +++ b/README.md @@ -1,99 +1,56 @@ +# UOS Overview +... -# EOSIO - The Most Powerful Infrastructure for Decentralized Applications -[![Build status](https://badge.buildkite.com/370fe5c79410f7d695e4e34c500b4e86e3ac021c6b1f739e20.svg?branch=master)](https://buildkite.com/EOSIO/eosio) +## Starting up the node -Welcome to the EOSIO source code repository! This software enables businesses to rapidly build and deploy high-performance and high-security blockchain-based applications. - -Some of the groundbreaking features of EOSIO include: - -1. Free Rate Limited Transactions -1. Low Latency Block confirmation (0.5 seconds) -1. Low-overhead Byzantine Fault Tolerant Finality -1. Designed for optional high-overhead, low-latency BFT finality -1. Smart contract platform powered by WebAssembly -1. Designed for Sparse Header Light Client Validation -1. Scheduled Recurring Transactions -1. Time Delay Security -1. Hierarchical Role Based Permissions -1. Support for Biometric Hardware Secured Keys (e.g. Apple Secure Enclave) -1. Designed for Parallel Execution of Context Free Validation Logic -1. Designed for Inter Blockchain Communication - -EOSIO is released under the open source MIT license and is offered “AS IS” without warranty of any kind, express or implied. Any security provided by the EOSIO software depends in part on how it is used, configured, and deployed. EOSIO is built upon many third-party libraries such as WABT (Apache License) and WAVM (BSD 3-clause) which are also provided “AS IS” without warranty of any kind. Without limiting the generality of the foregoing, Block.one makes no representation or guarantee that EOSIO or any third-party libraries will perform as intended or will be free of errors, bugs or faulty code. Both may fail in large or small ways that could completely or partially limit functionality or compromise computer systems. If you use or implement EOSIO, you do so at your own risk. In no event will Block.one be liable to any party for any damages whatsoever, even if it had been advised of the possibility of damage. - -Block.one is neither launching nor operating any initial public blockchains based upon the EOSIO software. This release refers only to version 1.0 of our open source software. We caution those who wish to use blockchains built on EOSIO to carefully vet the companies and organizations launching blockchains based on EOSIO before disclosing any private keys to their derivative software. - -There is no public testnet running currently. - ---- +Clone the code +``` +git clone https://github.com/UOSnetwork/uos +``` -**If you used our build scripts to install eosio, [please be sure to uninstall](#build-script-uninstall) before using our packages.** +Update the submodules +``` +cd uos +git submodule update --init --recursive +``` ---- +Install the additional libs: +``` +Debian/Ubuntu: apt -y install libboost-all-dev build-essential llvm-4.0-dev +CentOS7: yum -y install boost-devel +``` -#### Mac OS X Brew Install -```sh -$ brew tap eosio/eosio -$ brew install eosio +Compile: ``` -#### Mac OS X Brew Uninstall -```sh -$ brew remove eosio +./eosio_build.sh ``` -#### Ubuntu 18.04 Package Install -```sh -$ wget https://github.com/eosio/eos/releases/download/v1.8.9/eosio_1.8.9-1-ubuntu-18.04_amd64.deb -$ sudo apt install ./eosio_1.8.9-1-ubuntu-18.04_amd64.deb +Install: +``` +./eosio_install.sh ``` -#### Ubuntu 16.04 Package Install -```sh -$ wget https://github.com/eosio/eos/releases/download/v1.8.9/eosio_1.8.9-1-ubuntu-16.04_amd64.deb -$ sudo apt install ./eosio_1.8.9-1-ubuntu-16.04_amd64.deb + +Run and stop the node to generate the default config ``` -#### Ubuntu Package Uninstall -```sh -$ sudo apt remove eosio +nodeos +Ctrl+C ``` -#### Centos RPM Package Install -```sh -$ wget https://github.com/eosio/eos/releases/download/v1.8.9/eosio-1.8.9-1.el7.x86_64.rpm -$ sudo yum install ./eosio-1.8.9-1.el7.x86_64.rpm + +Add the seed nodes to the default config at ~/.local/share/eosio/nodeos/config/config.ini ``` -#### Centos RPM Package Uninstall -```sh -$ sudo yum remove eosio +p2p-peer-address = node-1.uos.network:9876 +p2p-peer-address = node-2.uos.network:9876 +p2p-peer-address = node-3.uos.network:9876 +p2p-peer-address = node-4.uos.network:9876 +p2p-peer-address = node-5.uos.network:9876 ``` -#### Build Script Uninstall - -If you have previously installed EOSIO using build scripts, you can execute `eosio_uninstall.sh` to uninstall. -- Passing `-y` will answer yes to all prompts (does not remove data directories) -- Passing `-f` will remove data directories (be very careful with this) -- Passing in `-i` allows you to specify where your eosio installation is located - -## Supported Operating Systems -EOSIO currently supports the following operating systems: -1. Amazon Linux 2 -2. CentOS 7 -3. Ubuntu 16.04 -4. Ubuntu 18.04 -5. MacOS 10.14 (Mojave) - -## Resources -1. [Website](https://eos.io) -1. [Blog](https://medium.com/eosio) -1. [Developer Portal](https://developers.eos.io) -1. [StackExchange for Q&A](https://eosio.stackexchange.com/) -1. [Community Telegram Group](https://t.me/EOSProject) -1. [Developer Telegram Group](https://t.me/joinchat/EaEnSUPktgfoI-XPfMYtcQ) -1. [White Paper](https://github.com/EOSIO/Documentation/blob/master/TechnicalWhitePaper.md) -1. [Roadmap](https://github.com/EOSIO/Documentation/blob/master/Roadmap.md) - - -## Getting Started -Instructions detailing the process of getting the software, building it, running a simple test network that produces blocks, account creation and uploading a sample contract to the blockchain can be found in [Getting Started](https://developers.eos.io/eosio-home/docs) on the [EOSIO Developer Portal](https://developers.eos.io). +See also: + +* [CONTRIBUTING](../../../uos.docs/blob/master/CONTRIBUTING.md) for detailed project information. +* [Spinning up a Node](../../../uos.docs/blob/master/uosBPubuntu.md) for a detailed node setup walkthrough on U°OS testnet. + ## Contributing diff --git a/libraries/CMakeLists.txt b/libraries/CMakeLists.txt index 54bb2f80e09..363c722cf40 100644 --- a/libraries/CMakeLists.txt +++ b/libraries/CMakeLists.txt @@ -6,6 +6,7 @@ add_subdirectory( wasm-jit ) add_subdirectory( appbase ) add_subdirectory( chain ) add_subdirectory( testing ) +add_subdirectory( singularity ) #turn tools&tests off; not needed for library build set(BUILD_TESTS OFF CACHE BOOL "Build GTest-based tests") diff --git a/libraries/chain/abi_serializer.cpp b/libraries/chain/abi_serializer.cpp index 91950de1f12..f3d473f25b5 100644 --- a/libraries/chain/abi_serializer.cpp +++ b/libraries/chain/abi_serializer.cpp @@ -118,7 +118,7 @@ namespace eosio { namespace chain { structs[st.name] = st; for( const auto& td : abi.types ) { - EOS_ASSERT(_is_type(td.type, ctx), invalid_type_inside_abi, "invalid type ${type}", ("type",td.type)); + EOS_ASSERT(!_is_type(td.new_type_name, ctx), duplicate_abi_type_def_exception, "type already exists", ("new_type_name",impl::limit_size(td.new_type_name))); typedefs[td.new_type_name] = td.type; diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index 5471739f69f..eda7b9e459e 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -118,6 +118,7 @@ struct building_block { vector _pending_trx_metas; vector _pending_trx_receipts; vector _actions; + optional _transaction_mroot; }; struct assembled_block { @@ -1168,7 +1169,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, @@ -1543,7 +1544,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(), std::move( bb._new_pending_producer_schedule ), std::move( bb._new_protocol_feature_activations ) @@ -1742,6 +1743,9 @@ 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(); @@ -1787,6 +1791,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 ), @@ -1974,9 +1983,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() ); @@ -2486,15 +2494,20 @@ void controller::push_block( std::future& block_state_future ) my->push_block( block_state_future ); } +bool controller::in_immutable_mode()const{ + return (db_mode_is_immutable(get_read_mode())); +} + 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(); - EOS_ASSERT( get_read_mode() != chain::db_read_mode::READ_ONLY, transaction_type_exception, "push transaction not allowed in read-only mode" ); + EOS_ASSERT( !in_immutable_mode(), transaction_type_exception, "push transaction not allowed in read-only mode" ); EOS_ASSERT( trx && !trx->implicit && !trx->scheduled, transaction_type_exception, "Implicit/Scheduled transaction not allowed" ); return my->push_transaction(trx, deadline, 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 ) { + EOS_ASSERT( !in_immutable_mode(), transaction_type_exception, "push scheduled transaction not allowed in read-only mode" ); validate_db_available_size(); return my->push_scheduled_transaction( trxid, deadline, billed_cpu_time_us, billed_cpu_time_us > 0 ); } diff --git a/libraries/chain/include/eosio/chain/config.hpp b/libraries/chain/include/eosio/chain/config.hpp index d6e1a8121f9..44c6ec9168b 100644 --- a/libraries/chain/include/eosio/chain/config.hpp +++ b/libraries/chain/include/eosio/chain/config.hpp @@ -82,6 +82,7 @@ const static uint32_t default_max_inline_action_size = 4 * 1024; // const static uint16_t default_max_inline_action_depth = 4; const static uint16_t default_max_auth_depth = 6; const static uint32_t default_sig_cpu_bill_pct = 50 * percent_1; // billable percentage of signature recovery +const static uint32_t default_block_cpu_effort_pct = 80 * percent_1; // percentage of block time used for producing block const static uint16_t default_controller_thread_pool_size = 2; const static uint32_t min_net_usage_delta_between_base_and_max_for_trx = 10*1024; diff --git a/libraries/chain/include/eosio/chain/controller.hpp b/libraries/chain/include/eosio/chain/controller.hpp index 1f9ff9bf871..6affc336021 100644 --- a/libraries/chain/include/eosio/chain/controller.hpp +++ b/libraries/chain/include/eosio/chain/controller.hpp @@ -47,6 +47,8 @@ namespace eosio { namespace chain { IRREVERSIBLE }; + inline bool db_mode_is_immutable(db_read_mode m) {return db_read_mode::READ_ONLY == m || db_read_mode::IRREVERSIBLE ==m;} + enum class validation_mode { FULL, LIGHT @@ -270,6 +272,7 @@ namespace eosio { namespace chain { db_read_mode get_read_mode()const; validation_mode get_validation_mode()const; + bool in_immutable_mode()const; void set_subjective_cpu_leeway(fc::microseconds leeway); fc::optional get_subjective_cpu_leeway() const; diff --git a/libraries/chain/transaction_context.cpp b/libraries/chain/transaction_context.cpp index 407cfb74c08..46aeedc9e64 100644 --- a/libraries/chain/transaction_context.cpp +++ b/libraries/chain/transaction_context.cpp @@ -745,7 +745,7 @@ namespace bacc = boost::accumulators; EOS_ASSERT( actor != nullptr, transaction_exception, "action's authorizing actor '${account}' does not exist", ("account", auth.actor) ); EOS_ASSERT( auth_manager.find_permission(auth) != nullptr, transaction_exception, - "action's authorizations include a non-existent permission: {permission}", + "action's authorizations include a non-existent permission: ${permission}", ("permission", auth) ); if( enforce_actor_whitelist_blacklist ) actors.insert( auth.actor ); diff --git a/libraries/fc b/libraries/fc index 25a24852325..2f39cd0086c 160000 --- a/libraries/fc +++ b/libraries/fc @@ -1 +1 @@ -Subproject commit 25a24852325f9f4c8510e671d351af007fae3713 +Subproject commit 2f39cd0086cc74f580ae2c7ff04139fb278ceaab diff --git a/libraries/singularity b/libraries/singularity new file mode 160000 index 00000000000..0e7719434e8 --- /dev/null +++ b/libraries/singularity @@ -0,0 +1 @@ +Subproject commit 0e7719434e81d51b0b3b59e7cb55692252fa9a3f diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index e07a10c5b8d..6be8b8d2525 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -16,6 +16,8 @@ add_subdirectory(txn_test_gen_plugin) add_subdirectory(db_size_api_plugin) #add_subdirectory(faucet_testnet_plugin) add_subdirectory(mongo_db_plugin) +add_subdirectory(uos_plugins/uos_rates) +add_subdirectory(uos_plugins/uos_blocks_exporter) add_subdirectory(login_plugin) add_subdirectory(test_control_plugin) add_subdirectory(test_control_api_plugin) diff --git a/plugins/chain_interface/include/eosio/chain/plugin_interface.hpp b/plugins/chain_interface/include/eosio/chain/plugin_interface.hpp index cdec12008ef..59bf597c1a8 100644 --- a/plugins/chain_interface/include/eosio/chain/plugin_interface.hpp +++ b/plugins/chain_interface/include/eosio/chain/plugin_interface.hpp @@ -48,7 +48,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 90c09b787f9..f1c56f52856 100644 --- a/plugins/chain_plugin/chain_plugin.cpp +++ b/plugins/chain_plugin/chain_plugin.cpp @@ -1007,11 +1007,11 @@ chain_apis::read_write::read_write(controller& db, const fc::microseconds& abi_s } 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" ); + EOS_ASSERT( !db.in_immutable_mode(), 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& trx, next_function next) { @@ -1887,7 +1887,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 544456afd6c..dfb43456bb5 100644 --- a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp +++ b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp @@ -686,7 +686,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& trx, chain::plugin_interface::next_function next); void accept_transaction(const chain::transaction_metadata_ptr& trx, chain::plugin_interface::next_function next); diff --git a/plugins/http_plugin/http_plugin.cpp b/plugins/http_plugin/http_plugin.cpp index ff7036f7d86..b9215733404 100644 --- a/plugins/http_plugin/http_plugin.cpp +++ b/plugins/http_plugin/http_plugin.cpp @@ -661,6 +661,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 eaa132ce0e4..9e7185d7bd0 100644 --- a/plugins/http_plugin/include/eosio/http_plugin/http_plugin.hpp +++ b/plugins/http_plugin/include/eosio/http_plugin/http_plugin.hpp @@ -101,7 +101,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 7170c1abd20..2f1032e2311 100644 --- a/plugins/net_plugin/include/eosio/net_plugin/protocol.hpp +++ b/plugins/net_plugin/include/eosio/net_plugin/protocol.hpp @@ -21,12 +21,19 @@ 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 fc::sha256 node_id; ///< used to identify peers and prevent self-connect chain::public_key_type key; ///< authentication key; may be a producer or peer key, or empty - tstamp time; + tstamp time{0}; fc::sha256 token; ///< digest of time to prove we own the private key of the key above chain::signature_type sig; ///< signature for the digest string p2p_address; @@ -36,7 +43,7 @@ namespace eosio { block_id_type head_id; string os; string agent; - int16_t generation; + int16_t generation{0}; }; @@ -74,16 +81,16 @@ namespace eosio { } struct go_away_message { - go_away_message (go_away_reason r = no_reason) : reason(r), node_id() {} - go_away_reason reason; + go_away_message(go_away_reason r = no_reason) : reason(r), node_id() {} + go_away_reason reason{no_reason}; fc::sha256 node_id; ///< for duplicate notification }; struct time_message { - tstamp org; //!< origin timestamp - tstamp rec; //!< receive timestamp - tstamp xmt; //!< transmit timestamp - mutable tstamp dst; //!< destination timestamp + tstamp org{0}; //!< origin timestamp + tstamp rec{0}; //!< receive timestamp + tstamp xmt{0}; //!< transmit timestamp + mutable tstamp dst{0}; //!< destination timestamp }; enum id_list_modes { @@ -105,9 +112,9 @@ namespace eosio { template struct select_ids { - select_ids () : mode(none),pending(0),ids() {} - id_list_modes mode; - uint32_t pending; + select_ids() : mode(none),pending(0),ids() {} + id_list_modes mode{none}; + uint32_t pending{0}; vector ids; bool empty () const { return (mode == none || ids.empty()); } }; @@ -116,20 +123,20 @@ namespace eosio { using ordered_blk_ids = select_ids; struct notice_message { - notice_message () : known_trx(), known_blocks() {} + notice_message() : known_trx(), known_blocks() {} ordered_txn_ids known_trx; ordered_blk_ids known_blocks; }; struct request_message { - request_message () : req_trx(), req_blocks() {} + request_message() : req_trx(), req_blocks() {} ordered_txn_ids req_trx; ordered_blk_ids req_blocks; }; struct sync_request_message { - uint32_t start_block; - uint32_t end_block; + uint32_t start_block{0}; + uint32_t end_block{0}; }; using net_message = static_variant connector_check; unique_ptr transaction_check; unique_ptr keepalive_timer; - boost::asio::steady_timer::duration connector_period; - boost::asio::steady_timer::duration txn_exp_period; - boost::asio::steady_timer::duration resp_expected_period; + boost::asio::steady_timer::duration connector_period{0}; + boost::asio::steady_timer::duration txn_exp_period{0}; + boost::asio::steady_timer::duration resp_expected_period{0}; boost::asio::steady_timer::duration keepalive_interval{std::chrono::seconds{32}}; int max_cleanup_time_ms = 0; @@ -289,6 +289,7 @@ namespace eosio { constexpr auto def_send_buffer_size = 1024*1024*def_send_buffer_size_mb; constexpr auto def_max_write_queue_size = def_send_buffer_size*10; constexpr auto def_max_trx_in_progress_size = 100*1024*1024; // 100 MB + constexpr auto def_max_consecutive_rejected_blocks = 13; // num of rejected blocks before 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; @@ -348,7 +349,7 @@ namespace eosio { */ struct peer_block_state { block_id_type id; - uint32_t block_num; + uint32_t block_num{0}; }; typedef multi_index_container< @@ -361,7 +362,7 @@ namespace eosio { struct update_block_num { - uint32_t new_bnum; + uint32_t new_bnum{0}; update_block_num(uint32_t bnum) : new_bnum(bnum) {} void operator() (node_transaction_state& nts) { nts.block_num = new_bnum; @@ -379,9 +380,9 @@ namespace eosio { :start_block( start ), end_block( end ), last( last_acted ), start_time(time_point::now()) {} - uint32_t start_block; - uint32_t end_block; - uint32_t last; ///< last sent or received + uint32_t start_block{0}; + uint32_t end_block{0}; + uint32_t last{0}; ///< last sent or received time_point start_time; ///< time request made or received }; @@ -498,6 +499,7 @@ namespace eosio { bool connecting = false; bool syncing = false; uint16_t protocol_version = 0; + uint16_t consecutive_rejected_blocks = 0; string peer_addr; unique_ptr response_expected; go_away_reason no_retry = no_reason; @@ -528,7 +530,7 @@ namespace eosio { double offset{0}; //!< peer offset static const size_t ts_buffer_size{32}; - char ts[ts_buffer_size]; //!< working buffer for making human readable timestamps + char ts[ts_buffer_size]{}; //!< working buffer for making human readable timestamps /** @} */ bool connected(); @@ -571,11 +573,11 @@ namespace eosio { void enqueue( const net_message &msg, bool trigger_send = true ); void enqueue_block( const signed_block_ptr& sb, bool trigger_send = true, bool to_sync_queue = false); void enqueue_buffer( const std::shared_ptr>& send_buffer, - bool trigger_send, int priority, go_away_reason close_after_send, + bool trigger_send, go_away_reason close_after_send, bool to_sync_queue = false); void cancel_sync(go_away_reason); void flush_queues(); - bool enqueue_sync_block(); + void enqueue_sync_block(); void request_sync_blocks(uint32_t start, uint32_t end); void cancel_wait(); @@ -586,10 +588,9 @@ namespace eosio { void queue_write(const std::shared_ptr>& buff, bool trigger_send, - int priority, std::function callback, bool to_sync_queue = false); - void do_queue_write(int priority); + void do_queue_write(); bool add_peer_block(const peer_block_state& pbs); bool peer_has_block(const block_id_type& blkid); @@ -660,12 +661,12 @@ namespace eosio { in_sync }; - uint32_t sync_known_lib_num; - uint32_t sync_last_requested_num; - uint32_t sync_next_expected_num; - uint32_t sync_req_span; + uint32_t sync_known_lib_num{0}; + uint32_t sync_last_requested_num{0}; + uint32_t sync_next_expected_num{0}; + uint32_t sync_req_span{0}; connection_ptr source; - stages state; + stages state{in_sync}; chain_plugin* chain_plug = nullptr; @@ -798,6 +799,7 @@ namespace eosio { flush_queues(); connecting = false; syncing = false; + consecutive_rejected_blocks = 0; if( last_req ) { my_impl->dispatcher->retry_fetch(shared_from_this()); } @@ -818,7 +820,7 @@ namespace eosio { for(auto tx = my_impl->local_txns.begin(); tx != my_impl->local_txns.end(); ++tx ){ const bool found = known_ids.find( tx->id ) != known_ids.cend(); if( !found ) { - queue_write( tx->serialized_txn, true, priority::low, []( boost::system::error_code ec, std::size_t ) {} ); + queue_write( tx->serialized_txn, true, []( boost::system::error_code ec, std::size_t ) {} ); } } } @@ -827,7 +829,7 @@ namespace eosio { for(const auto& t : ids) { auto tx = my_impl->local_txns.get().find(t); if( tx != my_impl->local_txns.end() ) { - queue_write( tx->serialized_txn, true, priority::low, []( boost::system::error_code ec, std::size_t ) {} ); + queue_write( tx->serialized_txn, true, []( boost::system::error_code ec, std::size_t ) {} ); } } } @@ -939,7 +941,6 @@ namespace eosio { void connection::queue_write(const std::shared_ptr>& buff, bool trigger_send, - int priority, std::function callback, bool to_sync_queue) { if( !buffer_queue.add_write_queue( buff, callback, to_sync_queue )) { @@ -949,11 +950,11 @@ namespace eosio { return; } if( buffer_queue.is_out_queue_empty() && trigger_send) { - do_queue_write( priority ); + do_queue_write(); } } - void connection::do_queue_write(int priority) { + void connection::do_queue_write() { if( !buffer_queue.ready_to_send() ) return; connection_wptr c(shared_from_this()); @@ -966,8 +967,8 @@ namespace eosio { buffer_queue.fill_out_buffer( bufs ); boost::asio::async_write(*socket, bufs, - boost::asio::bind_executor(strand, [c, socket=socket, priority]( boost::system::error_code ec, std::size_t w ) { - app().post(priority, [c, priority, ec, w]() { + boost::asio::bind_executor(strand, [c, socket=socket]( boost::system::error_code ec, std::size_t w ) { + app().post(priority::high, [c, ec, w]() { try { auto conn = c.lock(); if(!conn) @@ -988,7 +989,7 @@ namespace eosio { } conn->buffer_queue.clear_out_queue(); conn->enqueue_sync_block(); - conn->do_queue_write( priority ); + conn->do_queue_write(); } catch(const std::exception &ex) { auto conn = c.lock(); @@ -1027,26 +1028,28 @@ namespace eosio { } } - bool connection::enqueue_sync_block() { - if (!peer_requested) - return false; - uint32_t num = ++peer_requested->last; - bool trigger_send = num == peer_requested->start_block; - if(num == peer_requested->end_block) { - peer_requested.reset(); - fc_ilog( logger, "completing enqueue_sync_block ${num} to ${p}", ("num", num)("p", peer_name()) ); - } - try { - controller& cc = my_impl->chain_plug->chain(); - signed_block_ptr sb = cc.fetch_block_by_number(num); - if(sb) { - enqueue_block( sb, trigger_send, true); - return true; + void connection::enqueue_sync_block() { + connection_wptr c(shared_from_this()); + app().post( priority::low, [c]() { + auto conn = c.lock(); + if(!conn) return; + if( !conn->peer_requested ) + return; + uint32_t num = ++conn->peer_requested->last; + if( num == conn->peer_requested->end_block ) { + conn->peer_requested.reset(); + fc_ilog( logger, "completing enqueue_sync_block ${num} to ${p}", ("num", num)( "p", conn->peer_name() ) ); } - } catch ( ... ) { - fc_wlog( logger, "write loop exception" ); - } - return false; + try { + controller& cc = my_impl->chain_plug->chain(); + signed_block_ptr sb = cc.fetch_block_by_number( num ); + if( sb ) { + conn->enqueue_block( sb, true, true ); + } + } catch( ... ) { + fc_wlog( logger, "write loop exception" ); + } + } ); } void connection::enqueue( const net_message& m, bool trigger_send ) { @@ -1067,7 +1070,7 @@ namespace eosio { ds.write( header, header_size ); fc::raw::pack( ds, m ); - enqueue_buffer( send_buffer, trigger_send, priority::low, close_after_send ); + enqueue_buffer( send_buffer, trigger_send, close_after_send ); } template< typename T> @@ -1103,15 +1106,15 @@ namespace eosio { } void connection::enqueue_block( const signed_block_ptr& sb, bool trigger_send, bool to_sync_queue) { - enqueue_buffer( create_send_buffer( sb ), trigger_send, priority::low, no_reason, to_sync_queue); + enqueue_buffer( create_send_buffer( sb ), trigger_send, no_reason, to_sync_queue); } void connection::enqueue_buffer( const std::shared_ptr>& send_buffer, - bool trigger_send, int priority, go_away_reason close_after_send, + bool trigger_send, go_away_reason close_after_send, bool to_sync_queue) { connection_wptr weak_this = shared_from_this(); - queue_write(send_buffer,trigger_send, priority, + queue_write(send_buffer,trigger_send, [weak_this, close_after_send](boost::system::error_code ec, std::size_t ) { connection_ptr conn = weak_this.lock(); if (conn) { @@ -1588,7 +1591,7 @@ namespace eosio { } void sync_manager::rejected_block(const connection_ptr& c, uint32_t blk_num) { - if (state != in_sync ) { + if( ++c->consecutive_rejected_blocks > def_max_consecutive_rejected_blocks ) { fc_wlog( logger, "block ${bn} not accepted from ${p}, closing connection", ("bn",blk_num)("p",c->peer_name()) ); sync_last_requested_num = 0; source.reset(); @@ -1615,6 +1618,7 @@ namespace eosio { void sync_manager::recv_block(const connection_ptr& c, const block_id_type& blk_id, uint32_t blk_num, bool blk_applied) { fc_dlog(logger, "got block ${bn} from ${p}",("bn",blk_num)("p",c->peer_name())); + c->consecutive_rejected_blocks = 0; sync_update_expected(c, blk_id, blk_num, blk_applied); if (state == head_catchup) { fc_dlog(logger, "sync_manager in head_catchup state"); @@ -1683,7 +1687,7 @@ namespace eosio { send_buffer = create_send_buffer( bs->block ); } fc_dlog(logger, "bcast block ${b} to ${p}", ("b", bnum)("p", cp->peer_name())); - cp->enqueue_buffer( send_buffer, true, priority::high, no_reason ); + cp->enqueue_buffer( send_buffer, true, no_reason ); } } @@ -1918,6 +1922,7 @@ namespace eosio { } else { fc_elog( logger, "Unable to resolve ${peer_addr}: ${error}", ("peer_addr", c->peer_name())( "error", err.message()) ); + c->connecting = false; } } ); } ) ); @@ -2010,12 +2015,11 @@ namespace eosio { } else { if (from_addr >= max_nodes_per_host) { - fc_elog(logger, "Number of connections (${n}) from ${ra} exceeds limit", + fc_dlog(logger, "Number of connections (${n}) from ${ra} exceeds limit", ("n", from_addr+1)("ra",paddr.to_string())); } 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) ); } boost::system::error_code ec; socket->close( ec ); @@ -2242,7 +2246,7 @@ namespace eosio { void net_plugin_impl::send_transaction_to_all(const std::shared_ptr>& send_buffer, VerifierFunc verify) { for( auto &c : connections) { if( c->current() && verify( c )) { - c->enqueue_buffer( send_buffer, true, priority::low, no_reason ); + c->enqueue_buffer( send_buffer, true, no_reason ); } } } @@ -2260,10 +2264,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" ); @@ -2547,10 +2562,9 @@ namespace eosio { } void net_plugin_impl::handle_message(const connection_ptr& c, const packed_transaction_ptr& trx) { - fc_dlog(logger, "got a packed transaction, cancel wait"); - peer_ilog(c, "received packed_transaction"); + peer_dlog(c, "got a packed transaction, cancel wait"); controller& cc = my_impl->chain_plug->chain(); - if( cc.get_read_mode() == eosio::db_read_mode::READ_ONLY ) { + if( db_mode_is_immutable(cc.get_read_mode()) ) { fc_dlog(logger, "got a txn in read-only mode - dropping"); return; } @@ -2618,7 +2632,8 @@ namespace eosio { go_away_reason reason = fatal_other; try { - chain_plug->accept_block(msg); //, sync_master->is_active(c)); + bool accepted = chain_plug->accept_block(msg, blk_id); + 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())); @@ -2640,6 +2655,7 @@ namespace eosio { update_block_num ubn(blk_num); if( reason == no_reason ) { + fc_dlog( logger, "accepted signed_block : #${n} ${id}...", ("n", msg->block_num())("id", blk_id.str().substr(8,16)) ); for (const auto &recpt : msg->transactions) { auto id = (recpt.trx.which() == 0) ? recpt.trx.get() : recpt.trx.get().id(); auto ltx = local_txns.get().find(id); @@ -2754,23 +2770,30 @@ namespace eosio { auto from = from_connection.lock(); auto it = (from ? connections.find(from) : connections.begin()); if (it == connections.end()) it = connections.begin(); + size_t num_rm = 0, num_clients = 0, num_peers = 0; while (it != connections.end()) { if (fc::time_point::now() >= max_time) { start_conn_timer(std::chrono::milliseconds(1), *it); // avoid exhausting return; } + (*it)->peer_addr.empty() ? ++num_clients : ++num_peers; if( !(*it)->socket->is_open() && !(*it)->connecting) { - if( (*it)->peer_addr.length() > 0) { + if( !(*it)->peer_addr.empty() ) { connect(*it); } else { it = connections.erase(it); + --num_clients; ++num_rm; continue; } } ++it; } start_conn_timer(connector_period, std::weak_ptr()); + 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) ); } void net_plugin_impl::close(const connection_ptr& c) { @@ -2997,9 +3020,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(); @@ -3011,6 +3038,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" )) { @@ -3117,7 +3146,7 @@ namespace eosio { my->incoming_transaction_ack_subscription = app().get_channel().subscribe(boost::bind(&net_plugin_impl::transaction_ack, my.get(), _1)); - if( cc.get_read_mode() == chain::db_read_mode::READ_ONLY ) { + if( cc.in_immutable_mode() ) { my->max_nodes_per_host = 0; fc_ilog( logger, "node in read-only mode setting max_nodes_per_host to 0 to prevent connections" ); } diff --git a/plugins/producer_plugin/producer_plugin.cpp b/plugins/producer_plugin/producer_plugin.cpp index 4b36400534a..320feb7e6ff 100644 --- a/plugins/producer_plugin/producer_plugin.cpp +++ b/plugins/producer_plugin/producer_plugin.cpp @@ -217,8 +217,9 @@ class producer_plugin_impl : public std::enable_shared_from_this _signature_providers; std::set _producers; boost::asio::deadline_timer _timer; - std::map _producer_watermarks; - pending_block_mode _pending_block_mode; + using producer_watermark = std::pair; + std::map _producer_watermarks; + pending_block_mode _pending_block_mode = pending_block_mode::speculating; transaction_id_with_expiry_index _persistent_transactions; fc::optional _thread_pool; @@ -269,16 +270,17 @@ class producer_plugin_impl : public std::enable_shared_from_thissecond = std::max( itr->second, block_num ); + itr->second.first = std::max( itr->second.first, block_num ); + itr->second.second = std::max( itr->second.second, timestamp ); } else if( _producers.count( producer ) > 0 ) { - _producer_watermarks.emplace( producer, block_num ); + _producer_watermarks.emplace( producer, std::make_pair(block_num, timestamp) ); } } - std::optional get_watermark( account_name producer ) const { + std::optional get_watermark( account_name producer ) const { auto itr = _producer_watermarks.find( producer ); if( itr == _producer_watermarks.end() ) return {}; @@ -290,7 +292,7 @@ class producer_plugin_impl : public std::enable_shared_from_thisheader.producer, bsp->block_num ); + consider_new_watermark( bsp->header.producer, bsp->block_num, bsp->block->timestamp ); } void on_irreversible_block( const signed_block_ptr& lib ) { @@ -352,19 +354,26 @@ 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 ( _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 ${id}", ("id", id)); EOS_ASSERT( block->timestamp < (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 ); @@ -382,7 +391,7 @@ class producer_plugin_impl : public std::enable_shared_from_this().publish( priority::medium, block ); @@ -410,6 +419,8 @@ class producer_plugin_impl : public std::enable_shared_from_thisblock->confirmed)("latency", (fc::time_point::now() - hbs->block->timestamp).count()/1000 ) ); } } + + return true; } std::deque>> _pending_incoming_transactions; @@ -538,7 +549,8 @@ class producer_plugin_impl : public std::enable_shared_from_this& weak_this, const block_timestamp_type& current_block_time); + void schedule_delayed_production_loop(const std::weak_ptr& weak_this, optional wake_up_time); + optional calculate_producer_wake_up_time( const block_timestamp_type& ref_block_time ) const; + }; void new_chain_banner(const eosio::chain::controller& db) @@ -613,9 +627,13 @@ void producer_plugin::set_program_options( ("greylist-limit", boost::program_options::value()->default_value(1000), "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), - "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") + "Offset of non last block producing time in microseconds. Valid range 0 .. -block_time_interval.") + ("last-block-time-offset-us", boost::program_options::value()->default_value(-200000), + "Offset of last block producing time in microseconds. Valid range 0 .. -block_time_interval.") + ("cpu-effort-percent", bpo::value()->default_value(config::default_block_cpu_effort_pct / config::percent_1), + "Percentage of cpu block production time used to produce block. Whole number percentages, e.g. 80 for 80%") + ("last-block-cpu-effort-percent", bpo::value()->default_value(config::default_block_cpu_effort_pct / config::percent_1), + "Percentage of cpu block production time used to produce last block. Whole number percentages, e.g. 80 for 80%") ("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.") ("subjective-cpu-leeway-us", boost::program_options::value()->default_value( config::default_subjective_cpu_leeway_us ), @@ -749,8 +767,29 @@ void producer_plugin::plugin_initialize(const boost::program_options::variables_ my->_keosd_provider_timeout_us = fc::milliseconds(options.at("keosd-provider-timeout").as()); my->_produce_time_offset_us = options.at("produce-time-offset-us").as(); + EOS_ASSERT( my->_produce_time_offset_us <= 0 && my->_produce_time_offset_us >= -config::block_interval_us, plugin_config_exception, + "produce-time-offset-us ${o} must be 0 .. -${bi}", ("bi", config::block_interval_us)("o", my->_produce_time_offset_us) ); my->_last_block_time_offset_us = options.at("last-block-time-offset-us").as(); + EOS_ASSERT( my->_last_block_time_offset_us <= 0 && my->_last_block_time_offset_us >= -config::block_interval_us, plugin_config_exception, + "last-block-time-offset-us ${o} must be 0 .. -${bi}", ("bi", config::block_interval_us)("o", my->_last_block_time_offset_us) ); + + uint32_t cpu_effort_pct = options.at("cpu-effort-percent").as(); + EOS_ASSERT( cpu_effort_pct >= 0 && cpu_effort_pct <= 100, plugin_config_exception, + "cpu-effort-percent ${pct} must be 0 - 100", ("pct", cpu_effort_pct) ); + cpu_effort_pct *= config::percent_1; + int32_t cpu_effort_offset_us = + -EOS_PERCENT( config::block_interval_us, chain::config::percent_100 - cpu_effort_pct ); + + uint32_t last_block_cpu_effort_pct = options.at("last-block-cpu-effort-percent").as(); + EOS_ASSERT( last_block_cpu_effort_pct >= 0 && last_block_cpu_effort_pct <= 100, plugin_config_exception, + "last-block-cpu-effort-percent ${pct} must be 0 - 100", ("pct", last_block_cpu_effort_pct) ); + last_block_cpu_effort_pct *= config::percent_1; + int32_t last_block_cpu_effort_offset_us = + -EOS_PERCENT( config::block_interval_us, chain::config::percent_100 - last_block_cpu_effort_pct ); + + my->_produce_time_offset_us = std::min( my->_produce_time_offset_us, cpu_effort_offset_us ); + my->_last_block_time_offset_us = std::min( my->_last_block_time_offset_us, last_block_cpu_effort_offset_us ); my->_max_scheduled_transaction_time_per_block_ms = options.at("max-scheduled-transaction-time-per-block-ms").as(); @@ -786,7 +825,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(); }); @@ -796,8 +835,9 @@ void producer_plugin::plugin_initialize(const boost::program_options::variables_ } LOG_AND_DROP(); }); - my->_incoming_block_sync_provider = app().get_method().register_provider([this](const signed_block_ptr& block){ - my->on_incoming_block(block); + my->_incoming_block_sync_provider = app().get_method().register_provider( + [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([this](const transaction_metadata_ptr& trx, bool persist_until_expired, next_function next) -> void { @@ -1243,14 +1283,18 @@ optional producer_plugin_impl::calculate_next_block_time(const a // information then auto current_watermark = get_watermark(producer_name); if (current_watermark) { - auto watermark = *current_watermark; + const auto watermark = *current_watermark; auto block_num = chain.head_block_state()->block_num; if (chain.is_building_block()) { ++block_num; } - if (watermark > block_num) { - // if I have a watermark then I need to wait until after that watermark - minimum_offset = watermark - block_num + 1; + if (watermark.first > block_num) { + // if I have a watermark block number then I need to wait until after that watermark + minimum_offset = watermark.first - block_num + 1; + } + if (watermark.second > current_block_time) { + // if I have a watermark block timestamp then I need to wait until after that watermark timestamp + minimum_offset = std::max(minimum_offset, watermark.second.slot - current_block_time.slot + 1); } } @@ -1306,10 +1350,8 @@ enum class tx_category { producer_plugin_impl::start_block_result producer_plugin_impl::start_block() { chain::controller& chain = chain_plug->chain(); - if( chain.get_read_mode() == chain::db_read_mode::READ_ONLY ) - return start_block_result::waiting; - - fc_dlog(_log, "Starting block at ${time}", ("time", fc::time_point::now())); + if( chain.in_immutable_mode() ) + return start_block_result::waiting_for_block; const auto& hbs = chain.head_block_state(); @@ -1318,11 +1360,12 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() { const fc::time_point now = fc::time_point::now(); const fc::time_point block_time = calculate_pending_block_time(); + const pending_block_mode previous_pending_mode = _pending_block_mode; _pending_block_mode = pending_block_mode::producing; // Not our turn const auto& scheduled_producer = hbs->get_scheduled_producer(block_time); - auto current_watermark = get_watermark(scheduled_producer.producer_name); + const auto current_watermark = get_watermark(scheduled_producer.producer_name); auto signature_provider_itr = _signature_providers.find(scheduled_producer.block_signing_key); auto irreversible_block_age = get_irreversible_block_age(); @@ -1344,21 +1387,48 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() { if (_pending_block_mode == pending_block_mode::producing) { // determine if our watermark excludes us from producing at this point - if (current_watermark && *current_watermark >= hbs->block_num + 1) { - elog("Not producing block because \"${producer}\" signed a block at a higher block number (${watermark}) than the current fork's head (${head_block_num})", - ("producer", scheduled_producer.producer_name) - ("watermark", *current_watermark) - ("head_block_num", hbs->block_num)); - _pending_block_mode = pending_block_mode::speculating; + if (current_watermark) { + const block_timestamp_type block_timestamp{block_time}; + if (current_watermark->first > hbs->block_num) { + elog("Not producing block because \"${producer}\" signed a block at a higher block number (${watermark}) than the current fork's head (${head_block_num})", + ("producer", scheduled_producer.producer_name) + ("watermark", current_watermark->first) + ("head_block_num", hbs->block_num)); + _pending_block_mode = pending_block_mode::speculating; + } else if (current_watermark->second >= block_timestamp) { + elog("Not producing block because \"${producer}\" signed a block at the next block time or later (${watermark}) than the pending block time (${block_timestamp})", + ("producer", scheduled_producer.producer_name) + ("watermark", current_watermark->second) + ("block_timestamp", block_timestamp)); + _pending_block_mode = pending_block_mode::speculating; + } } } if (_pending_block_mode == pending_block_mode::speculating) { auto head_block_age = now - chain.head_block_time(); if (head_block_age > fc::seconds(5)) - return start_block_result::waiting; + return start_block_result::waiting_for_block; } + if (_pending_block_mode == pending_block_mode::producing) { + const auto start_block_time = block_time - fc::microseconds( config::block_interval_us ); + if( now < start_block_time ) { + fc_dlog(_log, "Not producing block waiting for production window ${n} ${bt}", ("n", hbs->block_num + 1)("bt", block_time) ); + // start_block_time instead of block_time because schedule_delayed_production_loop calculates next block time from given time + schedule_delayed_production_loop(weak_from_this(), calculate_producer_wake_up_time(start_block_time)); + return start_block_result::waiting_for_production; + } + } else if (previous_pending_mode == pending_block_mode::producing) { + // just produced our last block of our round + const auto start_block_time = block_time - fc::microseconds( config::block_interval_us ); + fc_dlog(_log, "Not starting speculative block until ${bt}", ("bt", start_block_time) ); + schedule_delayed_production_loop( weak_from_this(), start_block_time); + return start_block_result::waiting_for_production; + } + + fc_dlog(_log, "Starting block #${n} ${bt} at ${time}", ("n", hbs->block_num + 1)("bt", block_time)("time", now)); + try { uint16_t blocks_to_confirm = 0; @@ -1370,9 +1440,9 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() { // 3) if it is a producer on this node where this node knows the last block it produced, safely set it -UNLESS- // 4) the producer on this node's last watermark is higher (meaning on a different fork) if (current_watermark) { - auto watermark = *current_watermark; - if (watermark < hbs->block_num) { - blocks_to_confirm = (uint16_t)(std::min(std::numeric_limits::max(), (uint32_t)(hbs->block_num - watermark))); + auto watermark_bn = current_watermark->first; + if (watermark_bn < hbs->block_num) { + blocks_to_confirm = (uint16_t)(std::min(std::numeric_limits::max(), (uint32_t)(hbs->block_num - watermark_bn))); } } @@ -1750,6 +1820,12 @@ bool producer_plugin_impl::process_incoming_trxs( const fc::time_point& deadline return !exhausted; } +// Example: +// --> Start block A (block time x.500) at time x.000 +// -> start_block() +// --> deadline, produce block x.500 at time x.400 (assuming 80% cpu block effort) +// -> Idle +// --> Start block B (block time y.000) at time x.500 void producer_plugin_impl::schedule_production_loop() { chain::controller& chain = chain_plug->chain(); _timer.cancel(); @@ -1769,15 +1845,18 @@ void producer_plugin_impl::schedule_production_loop() { self->schedule_production_loop(); } } ) ); - } else if (result == start_block_result::waiting){ + } else if (result == start_block_result::waiting_for_block){ if (!_producers.empty() && !production_disabled_by_policy()) { fc_dlog(_log, "Waiting till another block is received and scheduling Speculative/Production Change"); - schedule_delayed_production_loop(weak_this, calculate_pending_block_time()); + schedule_delayed_production_loop(weak_this, calculate_producer_wake_up_time(calculate_pending_block_time())); } else { fc_dlog(_log, "Waiting till another block is received"); // nothing to do until more blocks arrive } + } else if (result == start_block_result::waiting_for_production) { + // scheduled in start_block() + } else if (_pending_block_mode == pending_block_mode::producing) { // we succeeded but block may be exhausted @@ -1819,28 +1898,37 @@ void producer_plugin_impl::schedule_production_loop() { } else if (_pending_block_mode == pending_block_mode::speculating && !_producers.empty() && !production_disabled_by_policy()){ fc_dlog(_log, "Speculative Block Created; Scheduling Speculative/Production Change"); EOS_ASSERT( chain.is_building_block(), missing_pending_block_state, "speculating without pending_block_state" ); - schedule_delayed_production_loop(weak_this, chain.pending_block_time()); + schedule_delayed_production_loop(weak_this, calculate_producer_wake_up_time(chain.pending_block_time())); } else { fc_dlog(_log, "Speculative Block Created"); } } -void producer_plugin_impl::schedule_delayed_production_loop(const std::weak_ptr& weak_this, const block_timestamp_type& current_block_time) { +optional producer_plugin_impl::calculate_producer_wake_up_time( const block_timestamp_type& ref_block_time ) const { // if we have any producers then we should at least set a timer for our next available slot optional wake_up_time; - for (const auto&p: _producers) { - auto next_producer_block_time = calculate_next_block_time(p, current_block_time); + for (const auto& p : _producers) { + auto next_producer_block_time = calculate_next_block_time(p, ref_block_time); if (next_producer_block_time) { auto producer_wake_up_time = *next_producer_block_time - fc::microseconds(config::block_interval_us); if (wake_up_time) { // wake up with a full block interval to the deadline - wake_up_time = std::min(*wake_up_time, producer_wake_up_time); + if( producer_wake_up_time < *wake_up_time ) { + wake_up_time = producer_wake_up_time; + } } else { wake_up_time = producer_wake_up_time; } } } + if( !wake_up_time ) { + fc_dlog(_log, "Not Scheduling Speculative/Production, no local producers had valid wake up times"); + } + + return wake_up_time; +} +void producer_plugin_impl::schedule_delayed_production_loop(const std::weak_ptr& weak_this, optional wake_up_time) { if (wake_up_time) { fc_dlog(_log, "Scheduling Speculative/Production Change at ${time}", ("time", wake_up_time)); static const boost::posix_time::ptime epoch(boost::gregorian::date(1970, 1, 1)); @@ -1852,8 +1940,6 @@ void producer_plugin_impl::schedule_delayed_production_loop(const std::weak_ptr< self->schedule_production_loop(); } } ) ); - } else { - fc_dlog(_log, "Not Scheduling Speculative/Production, no local producers had valid wake up times"); } } diff --git a/plugins/uos_plugins b/plugins/uos_plugins new file mode 160000 index 00000000000..c8de1c355c9 --- /dev/null +++ b/plugins/uos_plugins @@ -0,0 +1 @@ +Subproject commit c8de1c355c9dc386cd2c155f281ba36fa4b798de diff --git a/programs/cleos/main.cpp b/programs/cleos/main.cpp index 80f226c782e..9c532c9a0c5 100644 --- a/programs/cleos/main.cpp +++ b/programs/cleos/main.cpp @@ -1128,6 +1128,29 @@ struct vote_producers_subcommand { } }; +struct vote_calcs_subcommand { + string voter_str; + vector calc_names; + + vote_calcs_subcommand(CLI::App* actionRoot) { + auto vote_calcs = actionRoot->add_subcommand("calcs", localized("Vote for one or more calcs")); + vote_calcs->add_option("voter", voter_str, localized("The voting account"))->required(); + vote_calcs->add_option("calculators", calc_names, localized("The account(s) to vote for. All options from this position and following will be treated as the calc list."))->required(); + add_standard_transaction_options(vote_calcs, "voter@active"); + + vote_calcs->set_callback([this] { + + std::sort( calc_names.begin(), calc_names.end() ); + + fc::variant act_payload = fc::mutable_variant_object() + ("voter", voter_str) + ("calculators", calc_names); + auto accountPermissions = get_account_permissions(tx_permission, {voter_str,config::active_name}); + send_actions({create_action(accountPermissions, config::system_account_name, N(votecalc), act_payload)}); + }); + } +}; + struct approve_producer_subcommand { eosio::name voter; eosio::name producer_name; @@ -3878,6 +3901,11 @@ int main( int argc, char** argv ) { voteProducer->require_subcommand(); auto voteProxy = vote_producer_proxy_subcommand(voteProducer); auto voteProducers = vote_producers_subcommand(voteProducer); + + auto voteCalc = system->add_subcommand("votecalc", localized("Vote for a calculator")); + voteCalc->require_subcommand(); + auto voteCalcs = vote_calcs_subcommand(voteCalc); + auto approveProducer = approve_producer_subcommand(voteProducer); auto unapproveProducer = unapprove_producer_subcommand(voteProducer); diff --git a/programs/nodeos/CMakeLists.txt b/programs/nodeos/CMakeLists.txt index d5fe8273eb5..c4810b3c24d 100644 --- a/programs/nodeos/CMakeLists.txt +++ b/programs/nodeos/CMakeLists.txt @@ -62,14 +62,18 @@ target_link_libraries( ${NODE_EXECUTABLE_NAME} PRIVATE -Wl,${whole_archive_flag} producer_api_plugin -Wl,${no_whole_archive_flag} PRIVATE -Wl,${whole_archive_flag} test_control_plugin -Wl,${no_whole_archive_flag} PRIVATE -Wl,${whole_archive_flag} test_control_api_plugin -Wl,${no_whole_archive_flag} + PRIVATE -Wl,${whole_archive_flag} uos_rates -Wl,${no_whole_archive_flag} PRIVATE -Wl,${build_id_flag} PRIVATE chain_plugin http_plugin producer_plugin http_client_plugin PRIVATE eosio_chain fc ${CMAKE_DL_LIBS} ${PLATFORM_SPECIFIC_LIBS} ) if(BUILD_MONGO_DB_PLUGIN) target_link_libraries( ${NODE_EXECUTABLE_NAME} PRIVATE -Wl,${whole_archive_flag} mongo_db_plugin -Wl,${no_whole_archive_flag} ) +elseif(BUILD_UOS_BLOCKS_EXPORTER) + target_link_libraries (${NODE_EXECUTABLE_NAME} PRIVATE -Wl,${whole_archive_flag} uos_blocks_exporter -Wl,${no_whole_archive_flag}) endif() + include(additionalPlugins) copy_bin( ${NODE_EXECUTABLE_NAME} ) diff --git a/scripts/eosio_build.sh b/scripts/eosio_build.sh index 6353bfa4512..b3d2b55e07b 100755 --- a/scripts/eosio_build.sh +++ b/scripts/eosio_build.sh @@ -126,7 +126,7 @@ echo "User: ${CURRENT_USER}" # echo "git head id: %s" "$( cat .git/refs/heads/master )" echo "Current branch: $( execute git rev-parse --abbrev-ref HEAD 2>/dev/null )" -( [[ ! $NAME == "Ubuntu" ]] && [[ ! $ARCH == "Darwin" ]] ) && set -i # Ubuntu doesn't support interactive mode since it uses dash + Some folks are having this issue on Darwin; colors aren't supported yet anyway +( [[ ! $NAME == "Ubuntu" ]] && [[ ! $NAME == "Linux Mint" ]] && [[ ! $ARCH == "Darwin" ]] ) && set -i # Ubuntu doesn't support interactive mode since it uses dash + Some folks are having this issue on Darwin; colors aren't supported yet anyway # Ensure sudo is available (only if not using the root user) ensure-sudo @@ -177,6 +177,9 @@ if [[ $ARCH == "Linux" ]]; then "Ubuntu") FILE="${REPO_ROOT}/scripts/eosio_build_ubuntu.sh" ;; + "Linux Mint") + FILE="${REPO_ROOT}/scripts/eosio_build_ubuntu.sh" + ;; *) print_supported_linux_distros_and_exit;; esac CMAKE_PREFIX_PATHS="${EOSIO_INSTALL_DIR}" diff --git a/scripts/eosio_build_darwin_deps b/scripts/eosio_build_darwin_deps index d9a3bdb9e26..e8e5713464a 100755 --- a/scripts/eosio_build_darwin_deps +++ b/scripts/eosio_build_darwin_deps @@ -6,7 +6,6 @@ wget,/usr/local/bin/wget gmp,/usr/local/opt/gmp/include/gmpxx.h pkgconfig,/usr/local/bin/pkg-config python,/usr/local/opt/python3 -python@2,/usr/local/opt/python2 doxygen,/usr/local/bin/doxygen libusb,/usr/local/lib/libusb-1.0.0.dylib openssl@1.1,/usr/local/opt/openssl@1.1/lib/libssl.a \ No newline at end of file diff --git a/scripts/eosio_build_ubuntu.sh b/scripts/eosio_build_ubuntu.sh index 6912919cc1e..f91efa8bda4 100755 --- a/scripts/eosio_build_ubuntu.sh +++ b/scripts/eosio_build_ubuntu.sh @@ -5,7 +5,7 @@ echo "Physical Memory: ${MEM_GIG}G" echo "Disk space total: ${DISK_TOTAL}G" echo "Disk space available: ${DISK_AVAIL}G" -( [[ $NAME == "Ubuntu" ]] && ( [[ "$(echo ${VERSION_ID})" == "16.04" ]] || [[ "$(echo ${VERSION_ID})" == "18.04" ]] ) ) || ( echo " - You must be running 16.04.x or 18.04.x to install EOSIO." && exit 1 ) +( [[ $NAME == "Ubuntu" ]] && ( [[ "$(echo ${VERSION_ID})" == "16.04" ]] || [[ "$(echo ${VERSION_ID})" == "18.04" ]] ) || ( [[ $NAME == "Linux Mint" ]] && [[ "$(echo ${VERSION_ID})" == "19.1" ]] ) ) || ( echo " - You must be running 16.04.x or 18.04.x to install EOSIO." && exit 1 ) [[ $MEM_GIG -lt 7 ]] && echo "Your system must have 7 or more Gigabytes of physical memory installed." && exit 1 [[ "${DISK_AVAIL}" -lt "${DISK_MIN}" ]] && echo " - You must have at least ${DISK_MIN}GB of available storage to install EOSIO." && exit 1 diff --git a/scripts/helpers/eosio.sh b/scripts/helpers/eosio.sh index e700765827e..adc1598b180 100755 --- a/scripts/helpers/eosio.sh +++ b/scripts/helpers/eosio.sh @@ -246,7 +246,7 @@ function ensure-boost() { echo "${COLOR_CYAN}[Ensuring Boost $( echo $BOOST_VERSION | sed 's/_/./g' ) library installation]${COLOR_NC}" BOOSTVERSION=$( grep "#define BOOST_VERSION" "$BOOST_ROOT/include/boost/version.hpp" 2>/dev/null | tail -1 | tr -s ' ' | cut -d\ -f3 || true ) if [[ "${BOOSTVERSION}" != "${BOOST_VERSION_MAJOR}0${BOOST_VERSION_MINOR}0${BOOST_VERSION_PATCH}" ]]; then - B2_FLAGS="-q -j${JOBS} --with-iostreams --with-date_time --with-filesystem --with-system --with-program_options --with-chrono --with-test install" + B2_FLAGS="-q -j${JOBS} --with-iostreams --with-date_time --with-filesystem --with-system --with-program_options --with-chrono --with-test --with-thread --with-locale --with-serialization install" BOOTSTRAP_FLAGS="" if [[ $ARCH == "Linux" ]] && $PIN_COMPILER; then B2_FLAGS="toolset=clang cxxflags='-stdlib=libc++ -D__STRICT_ANSI__ -nostdinc++ -I${CLANG_ROOT}/include/c++/v1' linkflags='-stdlib=libc++' link=static threading=multi --with-iostreams --with-date_time --with-filesystem --with-system --with-program_options --with-chrono --with-test -q -j${JOBS} install" diff --git a/tests/Cluster.py b/tests/Cluster.py index 699858e355f..74b67612b1d 100644 --- a/tests/Cluster.py +++ b/tests/Cluster.py @@ -143,7 +143,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 @@ -219,7 +219,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 be3324f969e..9bbc5e056ed 100755 --- a/tests/nodeos_multiple_version_protocol_feature_test.py +++ b/tests/nodeos_multiple_version_protocol_feature_test.py @@ -87,6 +87,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 e42f934b2f4..9a548accf47 100755 --- a/tests/nodeos_protocol_feature_test.py +++ b/tests/nodeos_protocol_feature_test.py @@ -39,7 +39,7 @@ def restartNode(node: Node, nodeId, chainArg=None, addOrSwapFlags=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 70c7e428c9b..18d028a3262 100755 --- a/tests/nodeos_under_min_avail_ram.py +++ b/tests/nodeos_under_min_avail_ram.py @@ -84,7 +84,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 200477c7356..5335766107e 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/abi_tests.cpp b/unittests/abi_tests.cpp index dab7532b28c..a47cc3da581 100644 --- a/unittests/abi_tests.cpp +++ b/unittests/abi_tests.cpp @@ -1955,8 +1955,8 @@ BOOST_AUTO_TEST_CASE(abi_type_redefine) } )====="; - auto is_type_exception = [](fc::exception const & e) -> bool { return e.to_detail_string().find("invalid type") != std::string::npos; }; - BOOST_CHECK_EXCEPTION( abi_serializer abis(fc::json::from_string(repeat_abi).as(), max_serialization_time), invalid_type_inside_abi, is_type_exception ); + auto is_type_exception = [](fc::exception const & e) -> bool { return e.to_detail_string().find("Circular reference in type account_name") != std::string::npos; }; + BOOST_CHECK_EXCEPTION( abi_serializer abis(fc::json::from_string(repeat_abi).as(), max_serialization_time), abi_circular_def_exception, is_type_exception ); } FC_LOG_AND_RETHROW() } @@ -2304,6 +2304,57 @@ BOOST_AUTO_TEST_CASE(variants) } FC_LOG_AND_RETHROW() } +BOOST_AUTO_TEST_CASE(aliased_variants) +{ + using eosio::testing::fc_exception_message_starts_with; + + auto aliased_variant = R"({ + "version": "eosio::abi/1.1", + "types": [ + { "new_type_name": "foo", "type": "foo_variant" } + ], + "variants": [ + {"name": "foo_variant", "types": ["int8", "string"]} + ], + })"; + + try { + // round-trip abi through multiple formats + // json -> variant -> abi_def -> bin + auto bin = fc::raw::pack(fc::json::from_string(aliased_variant).as()); + // bin -> abi_def -> variant -> abi_def + abi_serializer abis(variant(fc::raw::unpack(bin)).as(), max_serialization_time ); + + verify_round_trip_conversion(abis, "foo", R"(["int8",21])", "0015"); + } FC_LOG_AND_RETHROW() +} + +BOOST_AUTO_TEST_CASE(variant_of_aliases) +{ + using eosio::testing::fc_exception_message_starts_with; + + auto aliased_variant = R"({ + "version": "eosio::abi/1.1", + "types": [ + { "new_type_name": "foo_0", "type": "int8" }, + { "new_type_name": "foo_1", "type": "string" } + ], + "variants": [ + {"name": "foo", "types": ["foo_0", "foo_1"]} + ], + })"; + + try { + // round-trip abi through multiple formats + // json -> variant -> abi_def -> bin + auto bin = fc::raw::pack(fc::json::from_string(aliased_variant).as()); + // bin -> abi_def -> variant -> abi_def + abi_serializer abis(variant(fc::raw::unpack(bin)).as(), max_serialization_time ); + + verify_round_trip_conversion(abis, "foo", R"(["foo_0",21])", "0015"); + } FC_LOG_AND_RETHROW() +} + BOOST_AUTO_TEST_CASE(extend) { using eosio::testing::fc_exception_message_starts_with; diff --git a/unittests/block_tests.cpp b/unittests/block_tests.cpp index fab79a306a1..cfed598e4c1 100644 --- a/unittests/block_tests.cpp +++ b/unittests/block_tests.cpp @@ -34,6 +34,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 920d759e951..42f59d19678 100644 --- a/unittests/forked_tests.cpp +++ b/unittests/forked_tests.cpp @@ -275,7 +275,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 ), fc::exception, @@ -405,7 +405,7 @@ BOOST_AUTO_TEST_CASE( read_modes ) try { BOOST_CHECK_EQUAL(head_block_num, read_only.control->fork_db_head_block_num()); BOOST_CHECK_EQUAL(head_block_num, read_only.control->head_block_num()); - tester irreversible(setup_policy::old_bios_only, db_read_mode::IRREVERSIBLE); + tester irreversible(setup_policy::none, db_read_mode::IRREVERSIBLE); push_blocks(c, irreversible); BOOST_CHECK_EQUAL(head_block_num, irreversible.control->fork_db_pending_head_block_num()); BOOST_CHECK_EQUAL(last_irreversible_block_num, irreversible.control->fork_db_head_block_num());