## Description
Improves overall time spent for our CI checks to complete. For cache
hits, total time decreases from ~70min to ~29min.
## Overview
```mermaid
gantt
title CI on a PR — BEFORE ~70m vs NOW ~29m
dateFormat HH:mm
axisFormat %M
section BEFORE ~70m
[release] build-wasm 20m :r1, 00:00, 20m
[release] build-x86_64-apple-darwin 17m :r2, 00:00, 17m
[release] build-x86_64-pc-windows-msvc 11m :r3, 00:00, 11m
[release] build-x86_64-unknown-linux-musl 10m :r4, 00:00, 10m
[release] build-aarch64-apple-darwin 8m :r5, 00:00, 8m
[release] create-macos-universal 14s :r6, 00:17, 1m
[test-wasm] own duplicate wasm build 19m :w1, 00:00, 19m
[test-wasm] test matrix 3m :w2, 00:19, 3m
[test] required 12m :crit, t1, 00:00, 12m
[differential-tests] build matrix waits 8m for release :crit, t2, 00:12, 8m
[differential-tests] macos-x86_64 compile and hash 44m :crit, t3, 00:20, 44m
[differential-tests] windows-x86_64 compile and hash 26m :t4, 00:20, 26m
[differential-tests] linux-x86_64 compile and hash 20m :t5, 00:20, 20m
[differential-tests] macos-arm64 compile and hash 15m :t6, 00:20, 15m
[differential-tests] run-e2e-tests parallel 43m :t7, 00:22, 43m
[differential-tests] compare-hashes 5m :crit, t8, 01:04, 5m
[hardhat] use-hardhat chained 1m :crit, t9, 01:09, 1m
section NOW ~29m
[release] build-windows 3m :nr1, 00:00, 3m
[release] build-x86_64-apple-darwin 7m :nr2, 00:00, 7m
[release] build-linux 2m :nr3, 00:00, 2m
[release] build-aarch64-apple-darwin 2m :nr4, 00:00, 2m
[release] create-macos-universal 23s :nr5, 00:07, 1m
[release] build-wasm cache hit ~11s :nr6, 00:15, 1m
[test-wasm] shared wasm build 15m :nw1, 00:00, 15m
[test-wasm] test matrix 3m :nw2, 00:15, 3m
[test] required 6m :crit, nt1, 00:00, 6m
[test] check-changes 2s parallel :nt2, 00:00, 1m
[differential-tests] per-target cache hits ~1m 30s :crit, nt3, 00:06, 2m
[differential-tests] windows-x86_64 compile and hash 19m :crit, nt4, 00:08, 19m
[differential-tests] linux-x86_64 compile and hash 16m :nt5, 00:08, 16m
[differential-tests] macos-arm64 compile and hash 13m :nt6, 00:08, 13m
[differential-tests] run-e2e-tests 16m :nt7, 00:08, 16m
[differential-tests] compare-hashes 2m :crit, nt8, 00:27, 2m
[hardhat] use-hardhat parallel 1m :nt9, 00:07, 1m
```
## Measurements
| Metric | Before | Now | Improvement |
|---|---|---|---|
| **PR CI wall-clock** | 70m 15s | 28m 47s | **−41m 28s (−59%)** |
| `test` job (required check) | 12m 10s | 6m 17s | −5m 53s (faster LLVM
download) |
| `compile-and-hash` build phase | ~7m 30s (waiting on release builds) |
~30s (builds already available) to ~1m 30s (if waiting for macos) |
−6-7m (per-target build split + faster LLVM download) |
| `run-e2e-tests` build phase | ~7m 30s (waiting on release builds) |
~30s (`linux-x86_64` already available) | −7m (per-target build split) |
| Longest `compile-and-hash` job | 44m 05s (`macos-x86_64`) | 19m 08s
(`windows-x86_64`) | −24m 57s (`macos-x86_64` excluded on PRs) |
| `compile-and-hash` matrix start time | 20m 13s | 7m 54s | −12m 19s
(per-target build split + faster LLVM download) |
| `run-e2e-tests` start time | 21m 50s | 7m 36s | −14m 14s (per-target
build split + faster LLVM download) |
| `run-e2e-tests` duration | 43m 28s | 16m 22s | −27m 06s (concurrency
bump + flakiness fix) |
## Changes
| Change | Before | Now |
|---|---|---|
| **Per-target build sub-workflows** | <ul><li>Getting a reusable build
depended on all builds completing.</li><li>Even if e.g. a macOS build is
cached, the waiting workflow with macOS runners could be queued for a
long time just to get the status and cache of the other workflow, since
macOS runners are more scarce than e.g. Ubuntu.</li></ul> |
<ul><li>Split umbrella `reusable-build.yml` into
`reusable-build-{linux,macos,windows,wasm}.yml`.</li><li>Consumers can
wait on a specific target and start earlier instead of blocking on the
whole matrix.</li><li>E.g. E2E and the compile-and-hash matrix start
earlier (gate only on the targets needed).</li></ul> |
| **Bottleneck macOS Intel only running on `main`** | macOS Intel
runners are 2-3× slower than macOS ARM for the contract compilation
tests. Ran on each PR, being the bottleneck. | This build is now
excluded from the matrix for PR runs, and only included for pushes to
`main`. |
| **E2E tests use higher concurrency** | `run-e2e-tests` duration:
~43min.</li></ul> | <ul><li>Uses higher number of concurrent tasks, made
possible by retester flakiness fix.</li><li>`run-e2e-tests` duration:
~16min.</li></ul> |
| **Faster LLVM downloads** | Building resolc took ~8-13min (~16 min on
macOS intel). | `get-llvm/action.yml` uses more efficient version
detection. Building resolc now takes ~2min (~4-7 min on macOS intel). |
| **Wasm tests use cached artifacts** | `test-wasm.yml` ran its own
duplicate build. | `test-wasm.yml` uses the reusable Wasm build. |
| **Skip unnecessary polkadot-sdk package** | For E2E tests,
`polkadot-omni-node` was unconditionally downloaded (~3-4min). | Only
`pallet-revive-eth-rpc` and `revive-dev-node` are downloaded from the
cache. |
| **Cache `report-processor`** | Only `retester` was cached. |
`report-processor` is cached for the compilations and export hashes
jobs. |
| **Hardhat unblocked from differential tests** | Started after the
differential tests succeeded in order to reuse the Linux build. | Starts
as soon as the required `test` job succeeds, using the reusable Linux
build. |
| **Conditionally skip workflows** | <ul><li>Some workflows
conditionally skipped for md-only changes.</li><li>Tooling-only changes
also ran e.g. `test-wasm.yml` and `differential-tests.yml`.</ul></li> |
<ul><li>Most workflows are skipped for doc-only
updates.</li><li>Tooling-only updates trigger only the respective
tooling test (Hardhat), apart from the required `test`
job.</li><li>Differential tests are skipped for js-only
updates.</li></ul> |
| **Miscellaneous** | <ul><li>Used actions running on soon-deprecated
Node 20.</li><li>Difficult to debug Playwright `test-wasm`
failures.</li></ul> | <ul><li>Upgraded actions that used Node
20.</li><li>Added Playwright debug traces uploaded on `test-wasm`
failures.</li></ul> |
## Resolved Issues
Closes#533
Bumps `@playwright/test` from ^1.59.1 to ^1.60.0 in an attempt to fix
the flaky install-step hang in test-wasm.yml.
Co-authored-by: xermicus <cyrill@parity.io>
- Support solc v0.8.35
- The new `erc7201` is comptime (already translated to a constant in
Yul)
Didn't spot any relevant breakage or addition in the release notes so
should be no-brainer.
---------
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
Emscripten 4.0.12 introduced breaking change by changing module factory
to always return promise even if `WASM_ASYNC_COMPILATION=0`. To overcome this, build emscripten compiler without MODULARIZE with custom export of `createRevive`.
As a drive-by fix, the get-llvm action now ignores LLVM releases marked
as pre-release.
---------
Signed-off-by: xermicus <bigcyrill@hotmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
The `--bin` CLI flag was not producing bytecode because the
`outputSelection` was not updated to explicitly requested it.
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
This marks a milestone: Smart contracts on Polkadot Asset Hub are live
and we release the first compiler version!
Signed-off-by: xermicus <bigcyrill@hotmail.com>
# Description
Compilation times for resolc were significantly slower than solc when:
* Multiple files were included in the JSON input file via
`--standard-json`
* And none of the files requested code generation
* (If only a subset of files requested code generation, both resolc and
solc were very slow)
Reason:
* Resolc unconditionally generated bytecode for all contracts, even if
not requested.
* When compiling to PolkaVM bytecode, we need to pass additional flags
(e.g. `irOptimized`) to solc. If these flags were not explicitly
requested, resolc also added these to the requested output since PolkaVM
bytecode was always generated.
## Breaking Changes
The following changes are breaking, but fix the semantics to match its
intended behavior:
* Compiling with `--standard-json` now compiles to PolkaVM bytecode
***only*** for the contracts explicitly requested in the
`outputSelection`.
* Compiling with `--standard-json` now outputs ***only*** the explicitly
requested output (e.g. `evm.assembly`, `evm.bytecode`, `ast`, etc.).
```jsonc
// Example:
{
"settings": {
// ...
"outputSelection": {
"src/common/GasService.sol": {
// Contracts in this file will generate bytecode.
// Only these fields of the JSON output selection will be in the `contracts` output.
"*": ["abi", "evm.methodIdentifiers", "metadata", "evm.bytecode"],
// Only this field of the JSON output selection will be in the `sources` output.
"": ["ast"]
},
"src/common/Gateway.sol": {
// No contracts in this file will generate bytecode.
"*": ["abi", "evm.methodIdentifiers", "metadata"],
// No `ast` will be in the `sources` output (only the automatically added `id`,
// similar to solc as this is not a configurable output selection).
"": []
},
}
}
}
```
## Performance Improvements
When e.g. the standard JSON input file includes multiple files and
requests output for every contract as per this setting:
```jsonc
{
"settings": {
// ...
"optimizer": { "enabled": true, "runs": 1 },
"viaIR": true,
"outputSelection": {
"src/common/GasService.sol": {
"*": ["abi", "evm.methodIdentifiers", "metadata", "evm.bytecode"],
},
// Rest of files..
}
}
}
```
The differences in compilation times depending on whether `evm.bytecode`
is selected in every file, one file, or no files can be seen below:
| Solc Optimizer (runs=1) | ViaIR | Request `abi`,
`evm.methodIdentifiers`, `metadata` | Request `evm.bytecode` | resolc
before | resolc after | solc v0.8.33 |
|:-----------------------:|:-----:|:---------:|:---------:|:-------------:|:------------:|:----------:|
| ✅ | ✅ | All files | All files | `~14.5s` | `~14.5s` | `~13.5s` |
| ✅ | ✅ | All files | One file | `~14.5s` | `~450ms` | `~13.5s` |
| ✅ | ✅ | All files | No files | `~14.5s` | `~390ms` | `~350ms` |
**Observations:**
* `resolc before` is roughly the same no matter the request
* This is due to unconditionally generating bytecode
* When not requesting bytecode for any contracts:
* `resolc after` now compiles in ~390ms (vs ~14.5s), similar to `solc`
* Neither `solc` nor `resolc after` generates bytecode when none of the
contracts request it
* When requesting bytecode for all contracts in _only one_ file:
* `resolc after` now compiles in ~450ms (vs ~14.5s)
* `solc` still compiles in the same time as when requesting bytecode for
all contracts in all files
* This is something they have tried to improve (see
[Solidity#15373](https://github.com/argotorg/solidity/issues/15373) and
[Solidity#15615](https://github.com/argotorg/solidity/issues/15615)),
and the intended behavior seems to now be that bytecode should only be
generated when explicitly requested for each contract.
* Even though PRs have merged to try to fix it, their issue seems to
persist as of v0.8.33.
# Open Questions
* Foundry:
* [x] Pruning of the AST:
* Just saw [this past
commit](https://github.com/paritytech/revive/pull/385) to not prune the
AST for Foundry compatibility.
* Can Foundry not explicitly request `"": "ast"`?
* **Answer:**
* Pruning the AST when not requested should be fine, as long as Foundry
explicitly requests it when needed.
* Will be tested by Foundry maintainer.
# Review Notes
Changes in `docs/` (~25 files) can be skipped as they are automatically
updated after adding content to `book/` and rebuilding it.
# Resolved Issues
Closes#326
---------
Co-authored-by: xermicus <cyrill@parity.io>
Ran into this today, my env was set and pointing to an old version
so it's a breaking change, but I think we are better off not hardcoding
the env here, the user can do whatever they want when they invoke
compile
Separate between compilation and linker phases to allow deploy time
linking and back-porting era compiler changes to fix#91. Unlinked
contract binaries (caused by missing libraries or missing factory
dependencies in turn) are emitted as raw ELF object.
Few drive by fixes:
- #98
- A compiler panic on missing libraries definitions.
- Fixes some incosistent type forwarding in JSON output (empty string
vs. null object).
- Remove the unused fallback for size optimization setting.
- Remove the broken `--lvm-ir` mode.
- CI workflow fixes.
---------
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
Signed-off-by: xermicus <bigcyrill@hotmail.com>
Signed-off-by: xermicus <cyrill@parity.io>
second take on #339
turns out that the resolve-pkg npm package was also failing to properly
resolve package with an exports field define in the package.json.
This fixes it and add a test case with such a package
Current approach fails with an 'ERR_PACKAGE_PATH_NOT_EXPORTED' error for
npm package that defines an exports field in the package.json
e.g:
> require.resolve('@redstone-finance/evm-connector/package.json')
will fail with
Uncaught:
Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './package.json'
is not defined by "exports" in
/home/pg/github/evm-test-suite/eth-rpc/node_modules/@redstone-finance/evm-connector/package.json
code: 'ERR_PACKAGE_PATH_NOT_EXPORTED'
- Add support for solc `v0.8.30`. No changes in YUL or the binary
interface.
- Fix a semver bug in the NPM packages to correctly align their solc
dependencies with our last supported version.
---------
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
This pull request adds changes described in **this comment**:
- `.github/scripts/json_generator.py` - a small script that generates
several json files for different platforms.
-
[generate_versions.yml](https://github.com/paritytech/revive/compare/as-release-json?expand=1#diff-2aee05b96020ac60943e6dfcb30597e53898f31542aeb570468b970d9a13a5a6)
- the workflow that runs when release is published, creates info.json
files and pushes them into resolc-bin repo
- `js/build.js` is adjusted in order to set `RESOLC_WASM_URI` from env
variable
- ⚠️ Release workflow is changed:
- In PRs and main branch it'll only build artifacts
- Release will happen automatically only on the `v*` tag push. This is
needed for revive_web.js to have the necessary `RESOLC_WASM_URI`
- workflow will check that version in Cargo.toml is the same as the tag
when the new tag is pushed
cc https://github.com/paritytech/revive/issues/162
cc https://github.com/paritytech/devops/issues/3890
No observable changes w.r.t. YUL compilation.
- Mark solc v0.8.29 as the latest supported version
- Add integration test for solc v0.8.29 specific feature
- Use the latest version on CI
- Drive-by fix linter complaints and a two types in the CI yaml files
---------
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
Signed-off-by: xermicus <cyrill@parity.io>