-
Notifications
You must be signed in to change notification settings - Fork 6.3k
Bytecode comparison PR scripts for solc-bin #10838
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,133 @@ | ||
| #!/usr/bin/env bash | ||
|
|
||
| # ------------------------------------------------------------------------------ | ||
| # Determines versions of all release binaries from solc-bin repo modified in the | ||
| # specified commit range, finds all release binaries from one, selected platform | ||
| # that match these versions and uses them to produce bytecode reports. | ||
| # | ||
| # The script is meant to be backwards-compatible with older versions of the | ||
| # compiler. Reports are generated via the CLI interface (rather than Standard | ||
| # JSON) in case of native binaries because the JSON interface was not available | ||
| # in very old versions. | ||
| # | ||
| # The script creates one report per binary and file names follow the pattern | ||
| # 'report-<binary name>.txt'. | ||
| # | ||
| # Usage: | ||
| # <script name>.sh <PLATFORM> <BASE_REF> <TOP_REF> <SOLC_BIN_DIR> <SOLIDITY_DIR> | ||
| # | ||
| # PLATFORM: Platform name, corresponding the one of the top-level directories | ||
| # in solc-bin. | ||
| # BASE_REF..TOP_REF: Commit range in the solc-bin repository to search for | ||
| # modified binaries. | ||
| # SOLC_BIN_DIR: Directory containing a checkout of the ethereum/solc-bin | ||
| # repository with full history. Must be an absolute path. | ||
| # SOLIDITY_DIR: Directory containing a checkout of the ethereum/solidity | ||
| # repository with full history. Bytecode report will be generated using | ||
| # scripts from the currently checked out revision. Must be an absolute path. | ||
| # | ||
| # Example: | ||
| # <script name>.sh linux-amd64 gh-pages pr-branch "$PWD/solc-bin" "$PWD/solidity" | ||
| # ------------------------------------------------------------------------------ | ||
| # 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 <http://www.gnu.org/licenses/> | ||
| # | ||
| # (c) 2020 solidity contributors. | ||
| #------------------------------------------------------------------------------ | ||
|
|
||
| # FIXME: Can't use set -u because the old Bash on macOS treats empty arrays as unbound variables | ||
| set -eo pipefail | ||
|
|
||
| (( $# == 5 )) || { echo "ERROR: Not enough arguments."; exit 1; } | ||
|
|
||
| platform="$1" | ||
| base_ref="$2" | ||
| top_ref="$3" | ||
| solc_bin_dir="$4" | ||
| solidity_dir="$5" | ||
|
|
||
| report_dir="$PWD" | ||
| tmp_dir=$(mktemp -d -t bytecode-reports-XXXXXX) | ||
| solcjs_dir="$tmp_dir/solcjs" | ||
| script_dir="$solidity_dir/scripts" | ||
|
|
||
| cd "$tmp_dir" | ||
|
|
||
| git clone https://github.com/ethereum/solc-js.git "$solcjs_dir" | ||
| cd "$solcjs_dir" | ||
| npm install | ||
| rm soljson.js | ||
|
|
||
| cd "${solc_bin_dir}/${platform}/" | ||
| echo "Commit range: ${base_ref}..${top_ref}" | ||
|
|
||
| modified_release_versions=$( | ||
| git diff --name-only "${base_ref}" | | ||
| sed -n -E 's/^[^\/]+\/(solc|soljson)-[0-9a-zA-Z-]+-v([0-9.]+)\+commit\.[0-9a-f]+(.[^.]+)?$/\2/p' | | ||
| sort -V | | ||
| uniq | ||
| ) | ||
| echo "Release versions modified in the commit range:" | ||
| echo "$modified_release_versions" | ||
|
|
||
| # NOTE: We want perform the check when the soljson-* files in bin/ and wasm/ are modified too | ||
| # because in that case the symlinks in emscripten-wasm32/ and emscripten-asmjs/ might remain | ||
| # unchanged but were're assuming that these directories are never directly used as a platform name. | ||
| [[ $platform != bin && $platform != wasm ]] || { echo "Invalid platform name."; exit 1; } | ||
|
|
||
| platform_binaries="$(git ls-files "solc-${platform}-v*+commit.*" | sort -V)" | ||
|
|
||
| for binary_name in $platform_binaries; do | ||
| solidity_version=$(echo "$binary_name" | sed -n -E 's/^solc-'"${platform}"'-v([0-9.]+)\+commit.+$/\1/p') | ||
|
|
||
| if echo "$modified_release_versions" | grep -x "$solidity_version"; then | ||
| echo "Binary ${binary_name} (version ${solidity_version}) matches one of the modified versions." | ||
|
|
||
| work_dir="${tmp_dir}/${binary_name}" | ||
| mkdir "$work_dir" | ||
| cd "$work_dir" | ||
|
|
||
| # While bytecode scripts come from the latest compiler, the test files should come from | ||
| # the Solidity version we're running them against to avoid errors due to breaking syntax changes. | ||
| git clone --branch "v${solidity_version}" "$solidity_dir" "${work_dir}/solidity/" | ||
| "${script_dir}/isolate_tests.py" "${work_dir}/solidity/test/" | ||
|
|
||
| if [[ $platform == emscripten-wasm32 ]] || [[ $platform == emscripten-asmjs ]]; then | ||
| ln -sf "${solc_bin_dir}/${platform}/${binary_name}" "${solcjs_dir}/soljson.js" | ||
| ln -s "${solcjs_dir}" solc-js | ||
| cp "${script_dir}/bytecodecompare/prepare_report.js" prepare_report.js | ||
|
|
||
| # shellcheck disable=SC2035 | ||
| ./prepare_report.js --strip-smt-pragmas *.sol > "${report_dir}/report-${binary_name}.txt" | ||
| else | ||
| yul_optimizer_flags=() | ||
| if [[ $solidity_version == 0.6.0 ]] || [[ $solidity_version == 0.6.1 ]]; then | ||
| yul_optimizer_flags+=(--force-no-optimize-yul) | ||
| fi | ||
ekpyron marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| "${script_dir}/bytecodecompare/prepare_report.py" "${solc_bin_dir}/${platform}/${binary_name}" \ | ||
| --interface cli \ | ||
| --smt-use strip-pragmas \ | ||
| --report-file "${report_dir}/report-${binary_name}.txt" \ | ||
| "${yul_optimizer_flags[@]}" | ||
| fi | ||
|
|
||
| rm -r "${work_dir}/solidity/" | ||
| else | ||
| echo "Binary ${binary_name} (version ${solidity_version}) does not match any modified version. Skipping." | ||
| fi | ||
| done | ||
|
|
||
| rm -r "$tmp_dir" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| #!/usr/bin/env bash | ||
|
|
||
| # ------------------------------------------------------------------------------ | ||
| # Compares bytecode reports from multiple compiler versions and platforms to | ||
| # determine if there are any differences. | ||
| # | ||
| # The script does not accept any arguments. | ||
| # | ||
| # The reports should be placed in subdirectories of the current working | ||
| # directory and their names should follow one of the following patterns: | ||
| # | ||
| # report-solc-<platform>-v<solidity version>+commit.<commit hash>.txt | ||
| # report-soljson-<platform>-v<solidity version>+commit.<commit hash>.js.txt | ||
| # | ||
| # Reports corresponding to the same version and commit hash are grouped together | ||
| # and the script succeeds only if the files within each group are identical. | ||
| # ------------------------------------------------------------------------------ | ||
| # 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 <http://www.gnu.org/licenses/> | ||
| # | ||
| # (c) 2020 solidity contributors. | ||
| #------------------------------------------------------------------------------ | ||
|
|
||
| set -euo pipefail | ||
|
|
||
| report_files="$(find . -type f -name 'report-*.txt')" | ||
| [[ $report_files != "" ]] || { echo "No reports found in the working directory."; exit 0; } | ||
|
|
||
| echo "Available reports:" | ||
| echo "$report_files" | ||
|
|
||
| versions_in_report_names=$( | ||
| echo "$report_files" | | ||
| sed -n -E 's/^\.\/[^\/]+\/report-(solc|soljson)-[0-9a-zA-Z-]+-v([0-9.]+\+commit\.[0-9a-f]+)(.[^.]+)?\.txt$/\2/p' | | ||
| sort -V | | ||
| uniq | ||
| ) | ||
|
|
||
| num_failed_comparisons=0 | ||
| for solidity_version_and_commit in $versions_in_report_names; do | ||
| echo "Comparing reports for Solidity ${solidity_version_and_commit}:" | ||
| mapfile -t report_files_for_version < <( | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My feeling reading @cameel 's bash and python PRs
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's just the bad influence of shellcheck dragging me to the dark side :) See SC2207. I could get away with simpler stuff while this was sitting in the github action file but now that I moved it to the main repo I had to obey :) |
||
| echo "$report_files" | | ||
| sed -n -E '/^\.\/[^\/]+\/report-(solc|soljson)-[0-9a-zA-Z-]+-v'"${solidity_version_and_commit//\+/\\+}"'+(.[^.]+)?\.txt$/p' | ||
| ) | ||
|
|
||
| diff --report-identical-files --brief --from-file "${report_files_for_version[@]}" || ((++num_failed_comparisons)) | ||
| echo | ||
| done | ||
|
|
||
| (( num_failed_comparisons == 0 )) || { echo "Found bytecode differences in ${num_failed_comparisons} versions"; exit 1; } | ||
| echo "No bytecode differences found." | ||
Uh oh!
There was an error while loading. Please reload this page.