Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 133 additions & 0 deletions scripts/solc-bin/bytecode_reports_for_modified_binaries.sh
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

"${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"
64 changes: 64 additions & 0 deletions scripts/solc-bin/compare_bytecode_reports.sh
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 < <(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mapfile... fancy stuff... never saw it before :-)...

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My feeling reading @cameel 's bash and python PRs

Copy link
Collaborator Author

Choose a reason for hiding this comment

The 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."