Skip to content

Commit 83cd9dc

Browse files
committed
prepare_report.py: Don't use --metadata option with compiler versions that do not support it
- Before 0.4.3 the option was unavailable but ignored. - Between 0.4.3 and 0.4.6 an attempt to use that option causes an error.
1 parent debc0af commit 83cd9dc

File tree

2 files changed

+55
-1
lines changed

2 files changed

+55
-1
lines changed

scripts/bytecodecompare/prepare_report.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ def prepare_compiler_input( # pylint: disable=too-many-arguments
146146
force_no_optimize_yul: bool,
147147
interface: CompilerInterface,
148148
smt_use: SMTUse,
149+
metadata_option_supported: bool,
149150
) -> Tuple[List[str], str]:
150151

151152
if interface == CompilerInterface.STANDARD_JSON:
@@ -168,7 +169,9 @@ def prepare_compiler_input( # pylint: disable=too-many-arguments
168169
else:
169170
assert interface == CompilerInterface.CLI
170171

171-
compiler_options = [str(source_file_name), '--bin', '--metadata']
172+
compiler_options = [str(source_file_name), '--bin']
173+
if metadata_option_supported:
174+
compiler_options.append('--metadata')
172175
if optimize:
173176
compiler_options.append('--optimize')
174177
elif force_no_optimize_yul:
@@ -182,13 +185,37 @@ def prepare_compiler_input( # pylint: disable=too-many-arguments
182185
return (command_line, compiler_input)
183186

184187

188+
def detect_metadata_cli_option_support(compiler_path: Path):
189+
process = subprocess.run(
190+
[str(compiler_path), '--metadata', '-'],
191+
input="contract C {}",
192+
encoding='utf8',
193+
capture_output=True,
194+
check=False,
195+
)
196+
197+
negative_response = "unrecognised option '--metadata'".strip()
198+
if (process.returncode == 0) != (process.stderr != negative_response):
199+
# If the error is other than expected or there's an error message but no error, don't try
200+
# to guess. Just fail.
201+
print(
202+
f"Compiler exit code: {process.returncode}\n"
203+
f"Compiler output:\n{process.stderr}\n",
204+
file=sys.stderr
205+
)
206+
raise Exception("Failed to determine if the compiler supports the --metadata option.")
207+
208+
return process.returncode == 0
209+
210+
185211
def run_compiler( # pylint: disable=too-many-arguments
186212
compiler_path: Path,
187213
source_file_name: Path,
188214
optimize: bool,
189215
force_no_optimize_yul: bool,
190216
interface: CompilerInterface,
191217
smt_use: SMTUse,
218+
metadata_option_supported: bool,
192219
tmp_dir: Path,
193220
) -> FileReport:
194221

@@ -200,6 +227,7 @@ def run_compiler( # pylint: disable=too-many-arguments
200227
force_no_optimize_yul,
201228
interface,
202229
smt_use,
230+
metadata_option_supported,
203231
)
204232

205233
process = subprocess.run(
@@ -222,6 +250,7 @@ def run_compiler( # pylint: disable=too-many-arguments
222250
force_no_optimize_yul,
223251
interface,
224252
smt_use,
253+
metadata_option_supported,
225254
)
226255

227256
# Create a copy that we can use directly with the CLI interface
@@ -249,6 +278,8 @@ def generate_report(
249278
smt_use: SMTUse,
250279
force_no_optimize_yul: bool
251280
):
281+
metadata_option_supported = detect_metadata_cli_option_support(compiler_path)
282+
252283
with open('report.txt', mode='w', encoding='utf8', newline='\n') as report_file:
253284
for optimize in [False, True]:
254285
with TemporaryDirectory(prefix='prepare_report-') as tmp_dir:
@@ -261,6 +292,7 @@ def generate_report(
261292
force_no_optimize_yul,
262293
interface,
263294
smt_use,
295+
metadata_option_supported,
264296
Path(tmp_dir),
265297
)
266298
report_file.write(report.format_report())

test/scripts/test_bytecodecompare_prepare_report.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ def test_prepare_compiler_input_should_work_with_standard_json_interface(self):
176176
force_no_optimize_yul=False,
177177
interface=CompilerInterface.STANDARD_JSON,
178178
smt_use=SMTUse.DISABLE,
179+
metadata_option_supported=True,
179180
)
180181

181182
self.assertEqual(command_line, ['solc', '--standard-json'])
@@ -189,6 +190,7 @@ def test_prepare_compiler_input_should_work_with_cli_interface(self):
189190
force_no_optimize_yul=False,
190191
interface=CompilerInterface.CLI,
191192
smt_use=SMTUse.DISABLE,
193+
metadata_option_supported=True,
192194
)
193195

194196
self.assertEqual(
@@ -223,6 +225,7 @@ def test_prepare_compiler_input_for_json_preserves_newlines(self):
223225
force_no_optimize_yul=False,
224226
interface=CompilerInterface.STANDARD_JSON,
225227
smt_use=SMTUse.DISABLE,
228+
metadata_option_supported=True,
226229
)
227230

228231
self.assertEqual(command_line, ['solc', '--standard-json'])
@@ -236,6 +239,7 @@ def test_prepare_compiler_input_for_cli_preserves_newlines(self):
236239
force_no_optimize_yul=True,
237240
interface=CompilerInterface.CLI,
238241
smt_use=SMTUse.DISABLE,
242+
metadata_option_supported=True,
239243
)
240244

241245
self.assertEqual(compiler_input, SMT_CONTRACT_WITH_MIXED_NEWLINES_SOL_CODE)
@@ -248,6 +252,7 @@ def test_prepare_compiler_input_for_cli_should_handle_force_no_optimize_yul_flag
248252
force_no_optimize_yul=True,
249253
interface=CompilerInterface.CLI,
250254
smt_use=SMTUse.DISABLE,
255+
metadata_option_supported=True,
251256
)
252257

253258
self.assertEqual(
@@ -256,6 +261,23 @@ def test_prepare_compiler_input_for_cli_should_handle_force_no_optimize_yul_flag
256261
)
257262
self.assertEqual(compiler_input, SMT_SMOKE_TEST_SOL_CODE)
258263

264+
def test_prepare_compiler_input_for_cli_should_not_use_metadata_option_if_not_supported(self):
265+
(command_line, compiler_input) = prepare_compiler_input(
266+
Path('solc'),
267+
SMT_SMOKE_TEST_SOL_PATH,
268+
optimize=True,
269+
force_no_optimize_yul=False,
270+
interface=CompilerInterface.CLI,
271+
smt_use=SMTUse.PRESERVE,
272+
metadata_option_supported=False,
273+
)
274+
275+
self.assertEqual(
276+
command_line,
277+
['solc', str(SMT_SMOKE_TEST_SOL_PATH), '--bin', '--optimize'],
278+
)
279+
self.assertEqual(compiler_input, SMT_SMOKE_TEST_SOL_CODE)
280+
259281

260282
class TestParseStandardJSONOutput(PrepareReportTestBase):
261283
def test_parse_standard_json_output(self):

0 commit comments

Comments
 (0)