diff --git a/.circleci/compare_bytecode_reports.sh b/.circleci/compare_bytecode_reports.sh new file mode 100755 index 000000000..adff761b6 --- /dev/null +++ b/.circleci/compare_bytecode_reports.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash +set -euo pipefail + +#------------------------------------------------------------------------------ +# Compares bytecode reports generated by prepare_report.py/.js. +# +# ------------------------------------------------------------------------------ +# This file is part of solidity. +# +# solidity is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# solidity is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with solidity. If not, see +# +# (c) 2023 solidity contributors. +#------------------------------------------------------------------------------ + +no_cli_platforms=( + emscripten +) +native_platforms=( + ubuntu2004-static + ubuntu + osx + windows +) +interfaces=( + cli + standard-json +) + +report_files=() +for platform in "${no_cli_platforms[@]}"; do + report_files+=("bytecode-report-${platform}.txt") +done +for platform in "${native_platforms[@]}"; do + for interface in "${interfaces[@]}"; do + report_files+=("bytecode-report-${platform}-${interface}.txt") + done +done + +echo "Reports to compare:" +printf -- "- %s\n" "${report_files[@]}" + +if ! diff --brief --report-identical-files --from-file "${report_files[@]}"; then + diff --unified=0 --report-identical-files --from-file "${report_files[@]}" | head --lines 50 + zip "all-bytecode-reports.zip" "${report_files[@]}" + exit 1 +fi diff --git a/.circleci/config.yml b/.circleci/config.yml index 7e568f9d1..b618d1574 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -76,34 +76,31 @@ commands: parameters: label: type: string + binary_type: + type: enum + enum: + - solcjs + - native binary_path: type: string steps: - - run: mkdir test-cases/ - run: - name: Prepare input files + name: Generate bytecode reports for the selected preset command: | - cd test-cases/ - python3 ../scripts/isolate_tests.py ../test/ - - run: - name: Generate bytecode report - command: | - cd test-cases/ - interface=$(echo -e "standard-json\ncli" | circleci tests split) - echo "Selected interface: ${interface}" - - python3 ../scripts/bytecodecompare/prepare_report.py \ - << parameters.binary_path >> \ - --interface "$interface" \ - --report-file "../bytecode-report-<< parameters.label >>-${interface}.txt" + .circleci/parallel_bytecode_report.sh \ + "<< parameters.label >>" \ + "<< parameters.binary_type >>" \ + "${PWD}/<< parameters.binary_path >>" - store_artifacts: path: bytecode-report-<< parameters.label >>-standard-json.txt - store_artifacts: path: bytecode-report-<< parameters.label >>-cli.txt + - store_artifacts: + path: bytecode-report-<< parameters.label >>.txt - persist_to_workspace: root: . paths: - - bytecode-report-<< parameters.label >>-*.txt + - bytecode-report-<< parameters.label >>*.txt - matrix_notify_failure_unless_pr install_python3: @@ -1485,10 +1482,6 @@ jobs: # It can be safely removed once we move both to the same Ubuntu version. b_bytecode_ubu_static: <<: *base_ubuntu2004_small - environment: - TERM: xterm - MAKEFLAGS: -j 2 - LC_ALL: C parallelism: 2 # For prepare_bytecode_report steps: - checkout @@ -1496,14 +1489,11 @@ jobs: at: build - prepare_bytecode_report: label: "ubuntu2004-static" - binary_path: "../build/solc/solc-static-linux" + binary_type: native + binary_path: "build/solc/solc-static-linux" b_bytecode_ubu: <<: *base_ubuntu2204_small - environment: - TERM: xterm - MAKEFLAGS: -j 2 - LC_ALL: C parallelism: 2 # For prepare_bytecode_report steps: - checkout @@ -1511,14 +1501,11 @@ jobs: at: build - prepare_bytecode_report: label: "ubuntu" - binary_path: "../build/solc/solc" + binary_type: native + binary_path: "build/solc/solc" b_bytecode_osx: <<: *base_osx - environment: - TERM: xterm - MAKEFLAGS: -j 5 - LC_ALL: C parallelism: 2 # For prepare_bytecode_report steps: - checkout @@ -1526,12 +1513,11 @@ jobs: at: . - prepare_bytecode_report: label: "osx" - binary_path: "../build/solc/solc" + binary_type: native + binary_path: "build/solc/solc" b_bytecode_win: <<: *base_win - environment: - LC_ALL: C parallelism: 2 # For prepare_bytecode_report steps: # NOTE: For bytecode generation we need the input files to be byte-for-byte identical on all @@ -1544,53 +1530,27 @@ jobs: at: build - prepare_bytecode_report: label: "windows" - binary_path: "../build/solc/Release/solc.exe" + binary_type: native + binary_path: "build/solc/Release/solc.exe" b_bytecode_ems: <<: *base_node_small - environment: - SOLC_EMSCRIPTEN: "On" - LC_ALL: C steps: - checkout - attach_workspace: at: emscripten_build/libsolc - - run: scripts/bytecodecompare/storebytecode.sh && mv -v report.txt bytecode-report-emscripten.txt - - store_artifacts: - path: bytecode-report-emscripten.txt - - persist_to_workspace: - root: . - paths: - - bytecode-report-emscripten.txt - - matrix_notify_failure_unless_pr + - prepare_bytecode_report: + label: "emscripten" + binary_type: solcjs + binary_path: "emscripten_build/libsolc/soljson.js" t_bytecode_compare: <<: *base_ubuntu2204_small - environment: - REPORT_FILES: | - bytecode-report-emscripten.txt - bytecode-report-ubuntu2004-static-standard-json.txt - bytecode-report-ubuntu2004-static-cli.txt - bytecode-report-ubuntu-standard-json.txt - bytecode-report-ubuntu-cli.txt - bytecode-report-osx-standard-json.txt - bytecode-report-osx-cli.txt - bytecode-report-windows-standard-json.txt - bytecode-report-windows-cli.txt steps: + - checkout - attach_workspace: at: . - - run: - name: Compare reports - command: diff --brief --report-identical-files --from-file $REPORT_FILES - - run: - name: Print diff - when: on_fail - command: diff --unified=0 --report-identical-files --from-file $REPORT_FILES | head --lines 50 - - run: - name: Bundle reports into a single package - when: on_fail - command: zip all-bytecode-reports.zip $REPORT_FILES + - run: .circleci/compare_bytecode_reports.sh - store_artifacts: # NOTE: store_artifacts does not support the 'when' attribute. # Fortunately when the artifact does not exist it just says "No artifact files found" and ignores it. @@ -1743,27 +1703,27 @@ workflows: # Bytecode comparison: - b_bytecode_ubu_static: - <<: *requires_nothing + <<: *on_all_tags_and_branches requires: - b_ubu_static - b_bytecode_ubu: - <<: *requires_nothing + <<: *on_all_tags_and_branches requires: - b_ubu - b_bytecode_win: - <<: *requires_nothing + <<: *on_all_tags_and_branches requires: - b_win - b_bytecode_osx: - <<: *requires_nothing + <<: *on_all_tags_and_branches requires: - b_osx - b_bytecode_ems: - <<: *requires_nothing + <<: *on_all_tags_and_branches requires: - b_ems - t_bytecode_compare: - <<: *requires_nothing + <<: *on_all_tags_and_branches requires: - b_bytecode_ubu_static - b_bytecode_ubu diff --git a/.circleci/parallel_bytecode_report.sh b/.circleci/parallel_bytecode_report.sh new file mode 100755 index 000000000..fd435bf61 --- /dev/null +++ b/.circleci/parallel_bytecode_report.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +set -euo pipefail + +#------------------------------------------------------------------------------ +# Splits all test source code into multiple files, generates bytecode and metadata +# for each file and combines it into a single report.txt file. +# +# The script is meant to be executed in CI on all supported platforms. All generated +# reports must be identical for a given compiler version. +# +# ------------------------------------------------------------------------------ +# This file is part of solidity. +# +# solidity is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# solidity is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with solidity. If not, see +# +# (c) 2023 solidity contributors. +#------------------------------------------------------------------------------ + +(( $# == 3 )) || { >&2 echo "Wrong number of arguments."; exit 1; } +label="$1" +binary_type="$2" +binary_path="$3" # This path must be absolute + +[[ $binary_type == native || $binary_type == solcjs ]] || { >&2 echo "Invalid binary type: ${binary_type}"; exit 1; } + +# NOTE: Locale affects the order of the globbed files. +export LC_ALL=C + +mkdir test-cases/ +cd test-cases/ + +echo "Preparing input files" +python3 ../scripts/isolate_tests.py ../test/ + +if [[ $binary_type == native ]]; then + interface=$(echo -e "standard-json\ncli" | circleci tests split) + echo "Selected interface: ${interface}" + + echo "Generating bytecode reports" + python3 ../scripts/bytecodecompare/prepare_report.py \ + "$binary_path" \ + --interface "$interface" \ + --report-file "../bytecode-report-${label}-${interface}.txt" +else + echo "Installing solc-js" + git clone --depth 1 https://github.com/ethereum/solc-js.git solc-js + cp "$binary_path" solc-js/soljson.js + + cd solc-js/ + npm install + npm run build + + cd .. + npm install ./solc-js/dist + + cp ../scripts/bytecodecompare/prepare_report.js . + + echo "Generating bytecode reports" + # shellcheck disable=SC2035 + ./prepare_report.js \ + *.sol > "../bytecode-report-${label}.txt" +fi diff --git a/scripts/bytecodecompare/storebytecode.sh b/scripts/bytecodecompare/storebytecode.sh deleted file mode 100755 index beeb79d09..000000000 --- a/scripts/bytecodecompare/storebytecode.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env bash - -#------------------------------------------------------------------------------ -# Script used for cross-platform comparison of the bytecode generated by the compiler. -# Splits all test source code into multiple files, generates bytecode and metadata -# for each file and combines it into a single report.txt file. -# -# The script is meant to be executed in CI on all supported platforms. All generated -# reports must be identical for a given compiler version. -# -# ------------------------------------------------------------------------------ -# This file is part of solidity. -# -# solidity is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# solidity is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with solidity. If not, see -# -# (c) 2017 solidity contributors. -#------------------------------------------------------------------------------ - -set -e - -REPO_ROOT="$(dirname "$0")"/../.. -cd "$REPO_ROOT" -REPO_ROOT=$(pwd) # make it absolute - -BUILD_DIR="${1:-${REPO_ROOT}/build}" - -# Set locale to C to prevent it from affecting glob sort order. -export LC_ALL=C - -echo "Compiling all test contracts into bytecode..." -TMPDIR=$(mktemp -d) -( - cd "$TMPDIR" - - "$REPO_ROOT"/scripts/isolate_tests.py "$REPO_ROOT"/test/ - - if [[ "$SOLC_EMSCRIPTEN" = "On" ]] - then - echo "Installing solc-js..." - # npm install solc - git clone --depth 1 https://github.com/ethereum/solc-js.git solc-js - cp "$REPO_ROOT/emscripten_build/libsolc/soljson.js" solc-js/ - pushd solc-js/ - npm install - npm run build - popd - - cp "$REPO_ROOT/scripts/bytecodecompare/prepare_report.js" . - npm install ./solc-js/dist - - echo "Running the compiler..." - # shellcheck disable=SC2035 - ./prepare_report.js *.sol > report.txt - echo "Finished running the compiler." - else - "$REPO_ROOT/scripts/bytecodecompare/prepare_report.py" "$BUILD_DIR/solc/solc" - fi - - cp report.txt "$REPO_ROOT" -) -rm -rf "$TMPDIR" -echo "Storebytecode finished."