Compare commits

...

36 Commits

Author SHA1 Message Date
Cyrill Leutwiler 1a36630900 release resolc v0.3.0
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-06-28 12:16:23 +02:00
xermicus 75fc23c810 add the missing memset builtin (#353)
Closes  #350

- Add the missing `memset` builtin which was accidentally deleted in a
previous PR.
- Add a compilation test to ensure the `memset` builtin is present.

---------

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-06-28 12:01:34 +02:00
xermicus 486c9c28a1 new clippies (#352)
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-06-28 11:48:24 +02:00
PG Herveou 7656c6a8b4 js: Add stats and override options (#348)
- Add `RESOLC_BIN` env variable to force use a binary compiler instead
of the wasm
- Add `--diff-stats` options to print file path 

e.g

```
~/github/redstone-oracles-monorepo main*
❯ npx @parity/resolc@latest --diff-stats \
  --base-path . \
  --include-path node_modules \
  --bin packages/evm-connector/contracts/samples/SampleWithEvents.sol
┌─────────┬──────────────────────────────────────────────────────────────────────────┬───────────────────────────────┬────────────┬────────────┬───────────┐
│ (index) │ file                                                                     │ contract                      │ polkavm    │ bin        │ diff      │
├─────────┼──────────────────────────────────────────────────────────────────────────┼───────────────────────────────┼────────────┼────────────┼───────────┤
│ 0       │ 'packages/evm-connector/contracts/core/CalldataExtractor.sol'            │ 'CalldataExtractor'           │ '4.31 kB'  │ '2.53 kB'  │ '70.12%'  │
│ 1       │ 'packages/evm-connector/contracts/core/RedstoneConstants.sol'            │ 'RedstoneConstants'           │ '0.80 kB'  │ '0.17 kB'  │ '368.18%' │
│ 2       │ 'packages/evm-connector/contracts/core/RedstoneDefaultsLib.sol'          │ 'RedstoneDefaultsLib'         │ '0.90 kB'  │ '0.31 kB'  │ '189.06%' │
│ 3       │ 'packages/evm-connector/contracts/libs/BitmapLib.sol'                    │ 'BitmapLib'                   │ '0.90 kB'  │ '0.31 kB'  │ '189.06%' │
│ 4       │ 'packages/evm-connector/contracts/libs/NumericArrayLib.sol'              │ 'NumericArrayLib'             │ '0.90 kB'  │ '0.31 kB'  │ '189.06%' │
│ 5       │ 'packages/evm-connector/contracts/libs/SignatureLib.sol'                 │ 'SignatureLib'                │ '0.90 kB'  │ '0.31 kB'  │ '189.06%' │
│ 6       │ 'packages/evm-connector/contracts/mocks/RedstoneConsumerNumericMock.sol' │ 'RedstoneConsumerNumericMock' │ '13.62 kB' │ '10.17 kB' │ '33.96%'  │
│ 7       │ 'packages/evm-connector/contracts/samples/SampleWithEvents.sol'          │ 'SampleWithEvents'            │ '29.34 kB' │ '15.60 kB' │ '88.03%'  │
└─────────┴──────────────────────────────────────────────────────────────────────────┴───────────────────────────────┴────────────┴────────────┴───────────┘
```
2025-06-19 12:17:09 +02:00
xermicus 8754d802fa llvm-context: bugfix PHI values in SAR builtin translation (#345)
Closes #344

Signed-off-by: xermicus <cyrill@parity.io>
2025-06-14 15:12:03 +02:00
PG Herveou 63f0266fff @parity/resolc fix sol file resolutions (#343)
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
2025-06-05 10:05:53 +02:00
xermicus e94432eaa0 ci: the resolc version dictates binary releases (#341)
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-06-03 15:47:33 +02:00
xermicus 1fc3aa1554 release resolc v0.2.0 (#340)
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-06-03 15:36:54 +02:00
Chris a77ab501c8 fix: exclude EVM bytecode from production solc requests (#338)
This is to address issue #320

## Introduced changes
- Added new_required_for_tests() method that includes EVM bytecode flags
- Modified new_required() to exclude evm.bytecode and
evm.deployedBytecode
- Updated test utilities to explicitly request EVM bytecode when needed

Signed-off-by: 0xf333 <0x333@tuta.io>
2025-06-03 10:43:52 +02:00
xermicus 8a3c587bbe solc-json-interface: do not unconditionally skip serialization of custom keys (#337)
The data structure can be used to build the JSON input for `resolc` too.
In that case serializing of provided custom options should not be
dismissed.

Makes the memory settings struct more modular as a drive-by.

---------

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-06-03 08:17:54 +02:00
PG Herveou 45b6a57cae Fix npm package resolution (#339)
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'
2025-06-02 14:41:06 +02:00
xermicus 8a730f42cc update NPM package version (#336)
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-05-28 08:15:41 +02:00
xermicus 413819facd do not use wildcard dependency in resolc crate (#335)
Do not use wildcard dependency in resolc crate. No sure why the publish
dry-run doesn't catch this.

---------

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-05-27 14:19:24 +02:00
xermicus fa0ad68279 make resolc crate publishable (#334)
- Fetching the commit SHA must not panic if not executed in a git
repository.
- Remove the license printer.

---------

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-05-27 14:13:12 +02:00
xermicus 004c71d5d5 add description to revive-differential (#333)
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-05-27 13:26:05 +02:00
xermicus 4d659ac2a6 release resolc v0.1.0 (#332)
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-05-27 12:06:42 +02:00
xermicus ed9dc60417 bump dependencies (#331)
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-05-27 11:24:15 +02:00
xermicus 3b9144ef3b add installation instructions to the readme (#330)
Closes #294

---------

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-05-27 10:23:42 +02:00
xermicus bd4e108bb0 resolc crate (#328)
- Factor the YUL crate out of `revive-solidity`.
- `revive-solidity` is in reality not a Solidity implementation but the
revive solidity compiler driver (`resolc`). By renaming we not only get
this straight but also a binary with the same name as the crate which
should be less confusing.

---------

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-05-27 09:48:43 +02:00
xermicus 090e3ac13c bugfix an env var in the release workflow (#329)
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-05-27 09:29:25 +02:00
xermicus 3389865af7 solc-json-interface: make the input Cloneable (#323)
It helps external consumers working with the
`revive-solc-json-interface` crate.

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-05-21 10:03:32 +02:00
xermicus af39d506d9 update emsdk (#324)
Update Emscripten SDK to latest version `v4.0.9`.

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-05-21 07:01:41 +02:00
xermicus bb2f829361 expose custom PVM settings in the standard json interface (#318)
Exposes the following PolkaVM specific options via the standard json
interface:
- Heap size
- Stack size
- Whether to emit source level debug information

Additionally it is now forbidden to specify those as CLI option in
standard JSON mode. They are bytecode altering options and having
multiple ways to specify them creates unnecessary room for confusion:
The standard JSON input description should be sufficient and succint for
reproducible builds.

Closes #290

---------

Signed-off-by: xermicus <bigcyrill@hotmail.com>
2025-05-13 15:19:00 +02:00
xermicus 1b8fcc4649 Update the Rust version (#316)
- Update the Rust version to 1.85
- Update the package-lock.json
- Update the musl-cross docker image

---------

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-05-09 20:00:58 +02:00
Cyrill Leutwiler 0e9e405f21 remove any git dependencies
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-05-09 17:26:20 +02:00
xermicus 722dd86c27 remove STATUS.md (#315)
This information is provided in the docs.

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-05-09 12:21:25 +02:00
PG Herveou 0421869e4b Replace release 0.1.0-dev.15 with 0.1.0-dev.16 (#314)
add missing patch and rename release
2025-05-08 15:26:10 +02:00
xermicus 32f55b976c update changelog (#313)
somehow went wrong

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-05-08 14:16:46 +02:00
PG Herveou 459a786299 v0.1.0-dev.15 release (#311)
Co-authored-by: xermicus <cyrill@parity.io>
2025-05-08 14:09:55 +02:00
xermicus fbaa45f283 support solc v0.8.30 (#308)
- 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>
2025-05-08 13:29:13 +02:00
xermicus f2fac85dae add npm package information to release checklist (#312)
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-05-08 13:14:28 +02:00
PG Herveou b8f3073e29 Run lint:fix (#309) 2025-05-08 12:36:11 +02:00
xermicus 11d47d74ac apply size optimizations by default (#298)
So far if no optimization level was specified, optimizations for
execution time were applied. However, we currently are a bit limited on
code size. Add to that, this setting is not available in solc and people
generally ignore the docs, generating a lot of support requests.

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-05-07 15:35:48 +02:00
xermicus e3a9c95d32 llvm-builder: use the ninja generator for building the builtins on windows (#299)
The builtins build should use the Ninja generator (MSVC does not build a
valid archive).

Tested and verified here:
https://github.com/paritytech/revive-alex-workflowtest/releases/tag/untagged-f02d0f574bab8404fead

Closes #305

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-05-07 11:10:58 +02:00
PG Herveou a560b2d919 Fix npm-release job (#297)
follow up from #295
2025-04-30 21:48:11 +02:00
PG Herveou e07d0f0cb7 Move @parity/resolc from js-revive (#296)
- Move npm package from paritytech/js-revive 
- Rename package to `@parity/resolc`
2025-04-30 17:24:52 +02:00
205 changed files with 12672 additions and 3462 deletions
+2 -2
View File
@@ -10,8 +10,8 @@ rustflags = [
"-Clink-arg=-sWASM_ASYNC_COMPILATION=0", "-Clink-arg=-sWASM_ASYNC_COMPILATION=0",
"-Clink-arg=-sDYNAMIC_EXECUTION=0", "-Clink-arg=-sDYNAMIC_EXECUTION=0",
"-Clink-arg=-sALLOW_TABLE_GROWTH=1", "-Clink-arg=-sALLOW_TABLE_GROWTH=1",
"-Clink-arg=--js-library=js/embed/soljson_interface.js", "-Clink-arg=--js-library=js/emscripten/embed/soljson_interface.js",
"-Clink-arg=--pre-js=js/embed/pre.js", "-Clink-arg=--pre-js=js/emscripten/embed/pre.js",
"-Clink-arg=-sSTACK_SIZE=128kb", "-Clink-arg=-sSTACK_SIZE=128kb",
"-Clink-arg=-sNODEJS_CATCH_EXIT=0" "-Clink-arg=-sNODEJS_CATCH_EXIT=0"
] ]
+1 -1
View File
@@ -3,7 +3,7 @@ inputs:
version: version:
description: "" description: ""
required: false required: false
default: "3.1.64" default: "4.0.9"
runs: runs:
+1 -1
View File
@@ -19,7 +19,7 @@ runs:
shell: bash shell: bash
run: | run: |
mkdir -p solc mkdir -p solc
curl -sSL --output solc/solc https://github.com/ethereum/solidity/releases/download/v0.8.29/${SOLC_NAME} curl -sSL --output solc/solc https://github.com/ethereum/solidity/releases/download/v0.8.30/${SOLC_NAME}
- name: Make Solc Executable - name: Make Solc Executable
if: ${{ runner.os == 'Windows' }} if: ${{ runner.os == 'Windows' }}
+6 -1
View File
@@ -87,9 +87,14 @@ jobs:
run: | run: |
brew install ninja brew install ninja
- name: Install Dependencies
if: ${{ matrix.host == 'windows' }}
run: |
choco install ninja
- name: Install LLVM Builder - name: Install LLVM Builder
run: | run: |
cargo install --path crates/llvm-builder cargo install --locked --force --path crates/llvm-builder
- name: Clone LLVM - name: Clone LLVM
run: | run: |
+44 -4
View File
@@ -14,7 +14,7 @@ concurrency:
env: env:
CARGO_TERM_COLOR: always CARGO_TERM_COLOR: always
RUST_MUSL_CROSS_IMAGE: messense/rust-musl-cross@sha256:68b86bc7cb2867259e6b233415a665ff4469c28b57763e78c3bfea1c68091561 RUST_MUSL_CROSS_IMAGE: messense/rust-musl-cross@sha256:c0154e992adb791c3b848dd008939d19862549204f8cb26f5ca7a00f629e6067
jobs: jobs:
check-version-changed: check-version-changed:
@@ -44,7 +44,7 @@ jobs:
exit 0 exit 0
fi fi
export PKG_VER=v$(cat Cargo.toml | grep -A 5 package] | grep version | cut -d '=' -f 2 | tr -d '"' | tr -d " ") export PKG_VER=v$(cat crates/resolc/Cargo.toml | grep -A 5 package] | grep version | cut -d '=' -f 2 | tr -d '"' | tr -d " ")
echo "Current tag $CURRENT_TAG" echo "Current tag $CURRENT_TAG"
echo "Package version $PKG_VER" echo "Package version $PKG_VER"
# #
@@ -143,7 +143,7 @@ jobs:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
needs: [check-version-changed] needs: [check-version-changed]
env: env:
RELEASE_RESOLC_WASM_URI: https://github.com/paritytech/revive-workflow-test/releases/download/${{ github.ref_name }}/resolc.wasm RELEASE_RESOLC_WASM_URI: https://github.com/paritytech/revive/releases/download/${{ github.ref_name }}/resolc.wasm
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions-rust-lang/setup-rust-toolchain@v1 - uses: actions-rust-lang/setup-rust-toolchain@v1
@@ -181,7 +181,7 @@ jobs:
- name: Basic Sanity Check - name: Basic Sanity Check
run: | run: |
mkdir -p solc mkdir -p solc
curl -sSLo solc/soljson.js https://github.com/ethereum/solidity/releases/download/v0.8.29/soljson.js curl -sSLo solc/soljson.js https://github.com/ethereum/solidity/releases/download/v0.8.30/soljson.js
node -e " node -e "
const soljson = require('solc/soljson'); const soljson = require('solc/soljson');
const createRevive = require('./target/wasm32-unknown-emscripten/release/resolc.js'); const createRevive = require('./target/wasm32-unknown-emscripten/release/resolc.js');
@@ -286,3 +286,43 @@ jobs:
resolc.wasm resolc.wasm
resolc_web.js resolc_web.js
checksums.txt checksums.txt
npm-release:
needs: [create-release]
runs-on: macos-14
environment: tags
steps:
- uses: actions/checkout@v4
- name: Download Artifacts
uses: actions/download-artifact@v4
with:
merge-multiple: true
- name: Set Up Node.js
uses: actions/setup-node@v3
with:
node-version: "20"
- run: npm ci -w js/resolc
- name: Build
run: |
cp -f resolc.{wasm,js} js/resolc/src/resolc
npm -w js/resolc run build
- name: npm pack
run: npm -w js/resolc pack
- uses: actions/upload-artifact@v4
with:
name: npm_package
path: "parity-resolc-*.tgz"
- uses: octokit/request-action@bbedc70b1981e610d89f1f8de88311a1fc02fb83
with:
route: POST /repos/paritytech/npm_publish_automation/actions/workflows/publish.yml/dispatches
ref: main
inputs: '${{ format(''{{ "artifact_name": "npm_package", "repo": "{0}", "run_id": "{1}" }}'', github.repository, github.run_id) }}'
env:
GITHUB_TOKEN: ${{ secrets.NPM_PUBLISH_AUTOMATION_TOKEN }}
+12 -7
View File
@@ -86,13 +86,18 @@ jobs:
- name: Install Node Packages - name: Install Node Packages
run: npm install run: npm install
- name: Run Playwright tests - name: Test emscripten
run: |
cd js
npx playwright install --with-deps
npx playwright test
- name: Test revive
run: | run: |
echo "Running tests for ${{ matrix.os }}" echo "Running tests for ${{ matrix.os }}"
npm run test:wasm npm run test:wasm
- name: Test @parity/resolc
run: |
echo "Running tests for ${{ matrix.os }}"
npm run -w js/resolc test
- name: Run Playwright tests
run: |
cd js/emscripten
npx playwright install --with-deps
npx playwright test
+1 -1
View File
@@ -1,4 +1,5 @@
/target /target
/js/resolc/dist
target-llvm target-llvm
*.dot *.dot
.vscode/ .vscode/
@@ -11,7 +12,6 @@ target-llvm
node_modules node_modules
artifacts artifacts
tmp tmp
package-lock.json
/*.html /*.html
/build /build
soljson.js soljson.js
+6
View File
@@ -0,0 +1,6 @@
{
"trailingComma": "es5",
"tabWidth": 2,
"semi": false,
"singleQuote": true
}
+89 -3
View File
@@ -4,14 +4,74 @@
This is a development pre-release. This is a development pre-release.
Supported `polkadot-sdk` rev: `2503.0.1`
## v0.3.0
This is a development pre-release.
Supported `polkadot-sdk` rev: `2503.0.1`
### Fixed
- llvm-context: Bugfix the SAR YUL builtin translation.
- runtime-api: Add the missing `memset` builtin.
- npm package: Bugfix the exports field defined in the `package.json`.
## v0.2.0
This is a development pre-release.
Supported `polkadot-sdk` rev: `2503.0.1`
### Changed
- Removed the license printer from the `resolc` binary.
- EVM bytecode is no longer requested from solc (except in test utils) leading to less compilation work in the pipeline.
### Fixed
- solc-json-interface: Serializing of any custom key in the JSON input is only skipped if not provided.
- npm package resolution no longer fails with an 'ERR_PACKAGE_PATH_NOT_EXPORTED' error for packages defining exports fields in the `package.json`.
## v0.1.0
This is a development pre-release.
Supported `polkadot-sdk` rev: `2503.0.1`
### Added
- Add the PolkaVM heap size, stack size and debug info CLI compiler options to the standard JSON settings. This makes the standard JSON input succint for reproducible builds.
### Changed
- Supported `polkadot-sdk` version is now `2503.0.1`
- The `emsdk` version is now `4.0.9`
### Fixed
## v0.1.0-dev.16
This is a development pre-release.
Supported `polkadot-sdk` rev:`c29e72a8628835e34deb6aa7db9a78a2e4eabcee` Supported `polkadot-sdk` rev:`c29e72a8628835e34deb6aa7db9a78a2e4eabcee`
### Added ### Added
- Move the npm package from paritytech/js-revive, into this repo. The package `@parity/resolc` will be deployed to npm for each release.
- Support for solc v0.8.30
### Changed ### Changed
- By default, heavy size optimizations are applied.
### Fixed ### Fixed
- @parity/resolc: The solc dependency package is constrained to the latest supported version, preventing breaking the package ever time a new solc package was released.
- The resolc npm package no longer ignores the optimizer settings
## v0.1.0-dev.14 ## v0.1.0-dev.14
This is a development pre-release. This is a development pre-release.
@@ -19,13 +79,16 @@ This is a development pre-release.
Supported `polkadot-sdk` rev:`c29e72a8628835e34deb6aa7db9a78a2e4eabcee` Supported `polkadot-sdk` rev:`c29e72a8628835e34deb6aa7db9a78a2e4eabcee`
### Added ### Added
- The `revive-runner` helper utility binary which helps to run contracts locally without a blockchain node.
- The `revive-runner` helper utility binary which helps to run contracts locally without a blockchain node.
- Allow configuration of the EVM heap memory size and stack size via CLI flags and JSON input settings. - Allow configuration of the EVM heap memory size and stack size via CLI flags and JSON input settings.
### Changed ### Changed
- The default PVM stack memory size was increased from 16kb to 32kb. - The default PVM stack memory size was increased from 16kb to 32kb.
### Fixed ### Fixed
- Constructors avoid storing zero sized immutable data on exit. - Constructors avoid storing zero sized immutable data on exit.
## v0.1.0-dev.13 ## v0.1.0-dev.13
@@ -35,16 +98,19 @@ This is a development pre-release.
Supported `polkadot-sdk` rev:`c29e72a8628835e34deb6aa7db9a78a2e4eabcee` Supported `polkadot-sdk` rev:`c29e72a8628835e34deb6aa7db9a78a2e4eabcee`
### Added ### Added
- Support for solc v0.8.29 - Support for solc v0.8.29
- Decouples the solc JSON-input-output type definitions from the Solidity fronted and expose them via a dedicated crate. - Decouples the solc JSON-input-output type definitions from the Solidity fronted and expose them via a dedicated crate.
- `--supported-solc-versions` for `resolc` binary to return a `semver` range of supported `solc` versions. - `--supported-solc-versions` for `resolc` binary to return a `semver` range of supported `solc` versions.
- Support for passing LLVM command line options via the prcoess input or providing one or more `--llvm-arg='..'` resolc CLI flag. This allows more fine-grained control over the LLVM backend configuration. - Support for passing LLVM command line options via the prcoess input or providing one or more `--llvm-arg='..'` resolc CLI flag. This allows more fine-grained control over the LLVM backend configuration.
### Changed ### Changed
- Storage keys and values are big endian. This was a pre-mature optimization because for the contract itself it this is a no-op and thus not observable. However we should consider the storage layout as part of the contract ABI. The endianness of transient storage values are still kept as-is. - Storage keys and values are big endian. This was a pre-mature optimization because for the contract itself it this is a no-op and thus not observable. However we should consider the storage layout as part of the contract ABI. The endianness of transient storage values are still kept as-is.
- Running `resolc` using webkit is no longer supported. - Running `resolc` using webkit is no longer supported.
### Fixed ### Fixed
- A missing byte swap for the create2 salt value. - A missing byte swap for the create2 salt value.
## v0.1.0-dev.12 ## v0.1.0-dev.12
@@ -54,10 +120,12 @@ This is a development pre-release.
Supported `polkadot-sdk` rev: `21f6f0705e53c15aa2b8a5706b208200447774a9` Supported `polkadot-sdk` rev: `21f6f0705e53c15aa2b8a5706b208200447774a9`
### Added ### Added
- Per file output selection for `--standard-json` mode. - Per file output selection for `--standard-json` mode.
- The `ir` output selection option for `--standard-json` mode. - The `ir` output selection option for `--standard-json` mode.
### Changed ### Changed
- Improved code size: Large contracts compile to smaller code blobs when enabling aggressive size optimizations (`-Oz`). - Improved code size: Large contracts compile to smaller code blobs when enabling aggressive size optimizations (`-Oz`).
### Fixed ### Fixed
@@ -73,6 +141,7 @@ Supported `polkadot-sdk` rev: `274a781e8ca1a9432c7ec87593bd93214abbff50`
### Changed ### Changed
### Fixed ### Fixed
- A bug causing incorrect loads from the emulated EVM linear memory. - A bug causing incorrect loads from the emulated EVM linear memory.
- A missing integer truncate after switching to 64bit. - A missing integer truncate after switching to 64bit.
@@ -83,10 +152,12 @@ This is a development pre-release.
Supported `polkadot-sdk` rev: `274a781e8ca1a9432c7ec87593bd93214abbff50` Supported `polkadot-sdk` rev: `274a781e8ca1a9432c7ec87593bd93214abbff50`
### Added ### Added
- Support for the `coinbase` opcode. - Support for the `coinbase` opcode.
- The resolc web JS version. - The resolc web JS version.
### Changed ### Changed
- Missing the `--overwrite` flag emits an error instead of a warning. - Missing the `--overwrite` flag emits an error instead of a warning.
- The `resolc` executable prints the help by default. - The `resolc` executable prints the help by default.
- Removed support for legacy EVM assembly (EVMLA) translation. - Removed support for legacy EVM assembly (EVMLA) translation.
@@ -96,6 +167,7 @@ Supported `polkadot-sdk` rev: `274a781e8ca1a9432c7ec87593bd93214abbff50`
If detected, the re-entrant call flag is not set and 0 deposit limit is endowed. If detected, the re-entrant call flag is not set and 0 deposit limit is endowed.
### Fixed ### Fixed
- Solidity: Add the solc `--libraries` files to sources. - Solidity: Add the solc `--libraries` files to sources.
- A data race in tests. - A data race in tests.
- Fix `broken pipe` errors. - Fix `broken pipe` errors.
@@ -109,9 +181,11 @@ This is a development pre-release.
### Added ### Added
### Changed ### Changed
- Syscalls with more than 6 arguments now pack them into registers. - Syscalls with more than 6 arguments now pack them into registers.
### Fixed ### Fixed
- Remove reloading of the resolc.js file (fix issue with relative path in web worker) - Remove reloading of the resolc.js file (fix issue with relative path in web worker)
## v0.1.0-dev.8 ## v0.1.0-dev.8
@@ -119,15 +193,18 @@ This is a development pre-release.
This is a development pre-release. This is a development pre-release.
### Added ### Added
- The `revive-llvm-builder` crate with the `revive-llvm` helper utility for streamlined management of the LLVM framework dependency. - The `revive-llvm-builder` crate with the `revive-llvm` helper utility for streamlined management of the LLVM framework dependency.
- Initial support for running `resolc` in the browser. - Initial support for running `resolc` in the browser.
### Changed ### Changed
- Suported contracts runtime is polkadot-sdk git version `d62a90c8c729acd98c7e9a5cab9803b8b211ffc5`. - Suported contracts runtime is polkadot-sdk git version `d62a90c8c729acd98c7e9a5cab9803b8b211ffc5`.
- The minimum supported Rust version is `1.81.0`. - The minimum supported Rust version is `1.81.0`.
- Error out early instead of invoking `solc` with invalid base or include path flags. - Error out early instead of invoking `solc` with invalid base or include path flags.
### Fixed ### Fixed
- Decouple the LLVM target dependency from the LLVM host dependency. - Decouple the LLVM target dependency from the LLVM host dependency.
- Do not error out if no files and no errors were produced. This aligns resolc closer to solc. - Do not error out if no files and no errors were produced. This aligns resolc closer to solc.
- Fixes input normalization in the Wasm version. - Fixes input normalization in the Wasm version.
@@ -137,17 +214,20 @@ This is a development pre-release.
This is a development pre-release. This is a development pre-release.
### Added ### Added
- Implement the `GASPRICE` opcode. - Implement the `GASPRICE` opcode.
- Implement the `BASEFEE` opcode. - Implement the `BASEFEE` opcode.
- Implement the `GASLIMIT` opcode. - Implement the `GASLIMIT` opcode.
### Changed ### Changed
- The `GAS` opcode now returns the remaining `ref_time`. - The `GAS` opcode now returns the remaining `ref_time`.
- Contracts can now be supplied call data input of arbitrary size. - Contracts can now be supplied call data input of arbitrary size.
- Some syscalls now return the value in a register, slightly improving emitted contract code. - Some syscalls now return the value in a register, slightly improving emitted contract code.
- Calls forward maximum weight limits instead of 0, anticipating a change in polkadot-sdk where weight limits of 0 no longer interprets as uncapped limit. - Calls forward maximum weight limits instead of 0, anticipating a change in polkadot-sdk where weight limits of 0 no longer interprets as uncapped limit.
### Fixed ### Fixed
- A linker bug which was preventing certain contracts from linking with the PVM linker. - A linker bug which was preventing certain contracts from linking with the PVM linker.
- JS: Fix encoding conversion from JS string (UTF-16) to UTF-8. - JS: Fix encoding conversion from JS string (UTF-16) to UTF-8.
- The git commit hash slug is always displayed in the version string. - The git commit hash slug is always displayed in the version string.
@@ -157,6 +237,7 @@ This is a development pre-release.
This is a development pre-release. This is a development pre-release.
# Added # Added
- Implement the `BLOCKHASH` opcode. - Implement the `BLOCKHASH` opcode.
- Implement delegate calls. - Implement delegate calls.
- Implement the `GASPRICE` opcode. Currently hard-coded to return `1`. - Implement the `GASPRICE` opcode. Currently hard-coded to return `1`.
@@ -164,21 +245,24 @@ This is a development pre-release.
- Initial support for emitting debug info (opt in via the `-g` flag) - Initial support for emitting debug info (opt in via the `-g` flag)
# Changed # Changed
- resolc now emits 64bit PolkaVM blobs, reducing contract code size and execution time. - resolc now emits 64bit PolkaVM blobs, reducing contract code size and execution time.
- The RISC-V bit-manipulation target feature (`zbb`) is enabled. - The RISC-V bit-manipulation target feature (`zbb`) is enabled.
# Fixed # Fixed
- Compilation to Wasm (for usage in node and web browsers)
- Compilation to Wasm (for usage in node and web browsers)
## v0.1.0-dev.5 ## v0.1.0-dev.5
This is development pre-release. This is development pre-release.
# Added # Added
- Implement the `CODESIZE` and `EXTCODESIZE` opcodes. - Implement the `CODESIZE` and `EXTCODESIZE` opcodes.
# Changed # Changed
- Include the full revive version in the contract metadata. - Include the full revive version in the contract metadata.
# Fixed # Fixed
@@ -188,9 +272,11 @@ This is development pre-release.
This is development pre-release. This is development pre-release.
# Added # Added
- Support the `ORIGIN` opcode. - Support the `ORIGIN` opcode.
# Changed # Changed
- Update polkavm to `v0.14.0`. - Update polkavm to `v0.14.0`.
- Enable the `a`, `fast-unaligned-access` and `xtheadcondmov` LLVM target features, decreasing the code size for some contracts. - Enable the `a`, `fast-unaligned-access` and `xtheadcondmov` LLVM target features, decreasing the code size for some contracts.
Generated
+2072 -2230
View File
File diff suppressed because it is too large Load Diff
+41 -41
View File
@@ -3,7 +3,7 @@ resolver = "2"
members = ["crates/*"] members = ["crates/*"]
[workspace.package] [workspace.package]
version = "0.1.0-dev.14" version = "0.1.0"
authors = [ authors = [
"Cyrill Leutwiler <cyrill@parity.io>", "Cyrill Leutwiler <cyrill@parity.io>",
"Parity Technologies <admin@parity.io>", "Parity Technologies <admin@parity.io>",
@@ -11,59 +11,60 @@ authors = [
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
edition = "2021" edition = "2021"
repository = "https://github.com/paritytech/revive" repository = "https://github.com/paritytech/revive"
rust-version = "1.81.0" rust-version = "1.85.0"
[workspace.dependencies] [workspace.dependencies]
revive-benchmarks = { version = "0.1.0-dev.14", path = "crates/benchmarks" } resolc = { version = "0.3.0", path = "crates/resolc" }
revive-builtins = { version = "0.1.0-dev.14", path = "crates/builtins" } revive-benchmarks = { version = "0.1.0", path = "crates/benchmarks" }
revive-common = { version = "0.1.0-dev.14", path = "crates/common" } revive-builtins = { version = "0.1.0", path = "crates/builtins" }
revive-differential = { version = "0.1.0-dev.14", path = "crates/differential" } revive-common = { version = "0.1.0", path = "crates/common" }
revive-integration = { version = "0.1.0-dev.14", path = "crates/integration" } revive-differential = { version = "0.1.0", path = "crates/differential" }
revive-linker = { version = "0.1.0-dev.14", path = "crates/linker" } revive-integration = { version = "0.1.1", path = "crates/integration" }
lld-sys = { version = "0.1.0-dev.14", path = "crates/lld-sys" } revive-linker = { version = "0.1.0", path = "crates/linker" }
revive-llvm-context = { version = "0.1.0-dev.14", path = "crates/llvm-context" } lld-sys = { version = "0.1.0", path = "crates/lld-sys" }
revive-runtime-api = { version = "0.1.0-dev.14", path = "crates/runtime-api" } revive-llvm-context = { version = "0.3.0", path = "crates/llvm-context" }
revive-runner = { version = "0.1.0-dev.14", path = "crates/runner" } revive-runtime-api = { version = "0.2.0", path = "crates/runtime-api" }
revive-solc-json-interface = { version = "0.1.0-dev.14", path = "crates/solc-json-interface" } revive-runner = { version = "0.1.0", path = "crates/runner" }
revive-solidity = { version = "0.1.0-dev.14", path = "crates/solidity" } revive-solc-json-interface = { version = "0.2.0", path = "crates/solc-json-interface" }
revive-stdlib = { version = "0.1.0-dev.14", path = "crates/stdlib" } revive-stdlib = { version = "0.1.1", path = "crates/stdlib" }
revive-build-utils = { version = "0.1.0-dev.14", path = "crates/build-utils" } revive-build-utils = { version = "0.1.0", path = "crates/build-utils" }
revive-yul = { version = "0.2.1", path = "crates/yul" }
hex = "0.4.3" hex = "0.4.3"
cc = "1.2" cc = "1.2"
libc = "0.2.169" libc = "0.2.172"
tempfile = "3.17" tempfile = "3.20"
anyhow = "1.0" anyhow = "1.0"
semver = { version = "1.0", features = ["serde"] } semver = { version = "1.0", features = ["serde"] }
itertools = "0.14" itertools = "0.14"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0", features = ["arbitrary_precision"] } serde_json = { version = "1.0", features = ["arbitrary_precision"] }
regex = "1.10" regex = "1.11"
once_cell = "1.20" once_cell = "1.21"
num = "0.4.3" num = "0.4.3"
sha1 = "0.10" sha1 = "0.10"
sha3 = "0.10" sha3 = "0.10"
thiserror = "2.0" thiserror = "2.0"
which = "7.0" which = "7.0"
path-slash = "0.2" path-slash = "0.2"
rayon = "1.8" rayon = "1.10"
clap = { version = "4", default-features = false, features = ["derive"] } clap = { version = "4", default-features = false, features = ["derive"] }
polkavm-common = "0.21.0" polkavm-common = "0.24.0"
polkavm-linker = "0.21.0" polkavm-linker = "0.24.0"
polkavm-disassembler = "0.21.0" polkavm-disassembler = "0.24.0"
polkavm = "0.21.0" polkavm = "0.24.0"
alloy-primitives = { version = "0.8.21", features = ["serde"] } alloy-primitives = { version = "1.1", features = ["serde"] }
alloy-sol-types = "0.8.21" alloy-sol-types = "1.1"
alloy-genesis = "0.11.1" alloy-genesis = "1.0"
alloy-serde = "0.11.1" alloy-serde = "1.0"
env_logger = { version = "0.11.6", default-features = false } env_logger = { version = "0.11.8", default-features = false }
serde_stacker = "0.1.11" serde_stacker = "0.1.12"
criterion = { version = "0.5.1", features = ["html_reports"] } criterion = { version = "0.6", features = ["html_reports"] }
log = { version = "0.4.25" } log = { version = "0.4.27" }
git2 = { version = "0.20.0", default-features = false } git2 = { version = "0.20.2", default-features = false }
downloader = "0.2.8" downloader = "0.2.8"
flate2 = "1.0.35" flate2 = "1.1"
fs_extra = "1.3.0" fs_extra = "1.3"
num_cpus = "1" num_cpus = "1"
tar = "0.4" tar = "0.4"
toml = "0.8" toml = "0.8"
@@ -71,16 +72,15 @@ assert_cmd = "2.0"
assert_fs = "1.1" assert_fs = "1.1"
# polkadot-sdk and friends # polkadot-sdk and friends
codec = { version = "3.6.12", default-features = false, package = "parity-scale-codec" } codec = { version = "3.7.5", default-features = false, package = "parity-scale-codec" }
scale-info = { version = "2.11.6", default-features = false } scale-info = { version = "2.11.6", default-features = false }
polkadot-sdk = { git = "https://github.com/paritytech/polkadot-sdk", rev = "c29e72a8628835e34deb6aa7db9a78a2e4eabcee" } polkadot-sdk = { version = "2503.0.1" }
# llvm # llvm
[workspace.dependencies.inkwell] [workspace.dependencies.inkwell]
git = "https://github.com/TheDan64/inkwell.git" version = "0.6.0"
rev = "7b410298b6a93450adaa90b1841d5805a3038f12"
default-features = false default-features = false
features = ["serde", "llvm18-0", "no-libffi-linking", "target-riscv"] features = ["serde", "llvm18-1", "no-libffi-linking", "target-riscv"]
[profile.bench] [profile.bench]
inherits = "release" inherits = "release"
+2 -2
View File
@@ -1,4 +1,4 @@
FROM rust:1.84.0 AS llvm-builder FROM rust:1.85.0 AS llvm-builder
WORKDIR /opt/revive WORKDIR /opt/revive
RUN apt update && \ RUN apt update && \
@@ -11,7 +11,7 @@ RUN make install-llvm-builder
RUN revive-llvm --target-env musl clone RUN revive-llvm --target-env musl clone
RUN revive-llvm --target-env musl build --llvm-projects lld --llvm-projects clang RUN revive-llvm --target-env musl build --llvm-projects lld --llvm-projects clang
FROM messense/rust-musl-cross@sha256:68b86bc7cb2867259e6b233415a665ff4469c28b57763e78c3bfea1c68091561 AS resolc-builder FROM messense/rust-musl-cross@sha256:c0154e992adb791c3b848dd008939d19862549204f8cb26f5ca7a00f629e6067 AS resolc-builder
WORKDIR /opt/revive WORKDIR /opt/revive
RUN apt update && \ RUN apt update && \
+10 -13
View File
@@ -11,7 +11,7 @@
machete \ machete \
test \ test \
test-integration \ test-integration \
test-solidity \ test-resolc \
test-workspace \ test-workspace \
test-cli \ test-cli \
test-wasm \ test-wasm \
@@ -24,24 +24,24 @@
install: install-bin install-npm install: install-bin install-npm
install-bin: install-bin:
cargo install --locked --path crates/solidity cargo install --force --locked --path crates/resolc
install-npm: install-npm:
npm install && npm fund npm install && npm fund
install-wasm: install-npm install-wasm: install-npm
cargo build --target wasm32-unknown-emscripten -p revive-solidity --release --no-default-features cargo build --target wasm32-unknown-emscripten -p resolc --release --no-default-features
npm run build:package npm run build:package
install-llvm-builder: install-llvm-builder:
cargo install --path crates/llvm-builder cargo install --force --locked --path crates/llvm-builder
install-llvm: install-llvm-builder install-llvm: install-llvm-builder
revive-llvm clone revive-llvm clone
revive-llvm build --llvm-projects lld --llvm-projects clang revive-llvm build --llvm-projects lld --llvm-projects clang
install-revive-runner: install-revive-runner:
cargo install --path crates/runner --no-default-features --locked cargo install --locked --force --path crates/runner --no-default-features
format: format:
cargo fmt --all --check cargo fmt --all --check
@@ -58,8 +58,8 @@ test: format clippy machete test-cli test-workspace install-revive-runner
test-integration: install-bin test-integration: install-bin
cargo test --package revive-integration cargo test --package revive-integration
test-solidity: install test-resolc: install
cargo test --package revive-solidity cargo test --package resolc
test-workspace: install test-workspace: install
cargo test --workspace --exclude revive-llvm-builder cargo test --workspace --exclude revive-llvm-builder
@@ -90,9 +90,6 @@ clean:
cargo clean ; \ cargo clean ; \
revive-llvm clean ; \ revive-llvm clean ; \
rm -rf node_modules ; \ rm -rf node_modules ; \
rm -rf crates/solidity/src/tests/cli-tests/artifacts ; \ rm -rf crates/resolc/src/tests/cli-tests/artifacts ; \
cargo uninstall revive-solidity ; \ cargo uninstall resolc ; \
cargo uninstall revive-llvm-builder ; \ cargo uninstall revive-llvm-builder ;
rm -f package-lock.json ; \
rm -rf js/dist ; \
rm -f js/src/resolc.{wasm,js}
+38 -3
View File
@@ -14,7 +14,39 @@ This is experimental software in active development and not ready just yet for p
Discussion around the development is hosted on the [Polkadot Forum](https://forum.polkadot.network/t/contracts-update-solidity-on-polkavm/6949#a-new-solidity-compiler-1). Discussion around the development is hosted on the [Polkadot Forum](https://forum.polkadot.network/t/contracts-update-solidity-on-polkavm/6949#a-new-solidity-compiler-1).
## Installation ## Installation
Please consult [the documentation](https://contracts.polkadot.io/revive_compiler/installation) for installation instructions. Building Solidity contracts for PolkaVM requires installing the following two compilers:
- `resolc`: The revive Solidity compiler YUL frontend and PolkaVM code generator (provided by this repository).
- `solc`: The [Ethereum Solidity reference compiler](https://github.com/ethereum/solidity/) implemenation.`resolc` uses `solc` during the compilation process, please refer to the [Ethereum Solidity documentation](https://docs.soliditylang.org/en/latest/installing-solidity.html) for installation instructions.
### `resolc` binary releases
`resolc` is distributed as a standalone binary (with `solc` as the only external dependency). Please download one of our [binary releases](https://github.com/paritytech/revive/releases) for your target platform and mind the platform specific instructions below.
<details>
<summary>MacOS users</summary>
> **MacOS** users need to clear the `downloaded` attribute from the binary and set the executable flag.
> ```sh
> xattr -rc resolc-universal-apple-darwin
> chmod +x resolc-universal-apple-darwin
> ```
</details>
<details>
<summary>Linux users</summary>
> **Linux** users need to set the executable flag.
> ```sh
> chmod +x resolc-x86_64-unknown-linux-musl
> ```
</details>
### `resolc` NPM package
We distribute the revive compiler as [node.js module](https://www.npmjs.com/package/@parity/resolc) and [hardhat plugin](https://www.npmjs.com/package/@parity/hardhat-polkadot-resolc).
Note: The `solc` dependency is bundled via NPM packaging and defaults to the latest supported version.
## Building from source ## Building from source
@@ -99,8 +131,6 @@ Ensure that your branch passes `make test` locally when submitting a pull reques
### Design overview ### Design overview
See the [relevant section in our documentation](https://contracts.polkadot.io/revive_compiler/architecture) to learn more about how the compiler works. See the [relevant section in our documentation](https://contracts.polkadot.io/revive_compiler/architecture) to learn more about how the compiler works.
[Frontend](https://github.com/matter-labs/era-compiler-solidity) and [code generator](https://github.com/matter-labs/era-compiler-llvm-context) are based of ZKSync `zksolc` (the project started as a fork of the era compiler).
### Tests ### Tests
Before running the tests, ensure that Geth (Go Ethereum) is installed on your system. Follow the installation guide here: [Installing Geth](https://geth.ethereum.org/docs/getting-started/installing-geth). Before running the tests, ensure that Geth (Go Ethereum) is installed on your system. Follow the installation guide here: [Installing Geth](https://geth.ethereum.org/docs/getting-started/installing-geth).
@@ -109,3 +139,8 @@ Once Geth is installed, you can run the tests using the following command:
```sh ```sh
make test make test
``` ```
# Acknowledgements
The revive compiler project, after some early experiments with EVM bytecode translations, decided to fork the `era-compiler` framework.
[Frontend](https://github.com/matter-labs/era-compiler-solidity), [code generator](https://github.com/matter-labs/era-compiler-llvm-context) and some supporting libraries are based of ZKSync `zksolc`. I'd like to express my gratitude and thank the original authors for providing a useable code base under a generous license.
+11 -3
View File
@@ -4,15 +4,23 @@ Prior to the first stable release we neither have formal release processes nor d
To create a new pre-release: To create a new pre-release:
1. Create a release PR which updates the `-dev.X` versions in the workspace `Cargo.toml` and updates the `CHANGELOG.md` accordingly. 1. Create a release PR which, if necessary:
- Updates the versions in the workspace `Cargo.toml`
- Updates the version in each crate `Cargo.toml`
- Updates the version of the NPM package in `js/resolc/package.json`
- Updates the `CHANGELOG.md` to reflect all observable changes
2. If the CI passes, merge the release PR. 2. If the CI passes, merge the release PR.
3. Push a tag that has the same `-dev.X` version as in `Cargo.toml` 3. Push a `vX.Y.Z` tag that has the same version as in `Cargo.toml`
4. The release workflow will attempt to build and publish a new pre-release if the latest tag does match the cargo package version. 4. The release workflow will attempt to build and publish a new pre-release if the latest tag does match the cargo package version.
5. Wait for the `Release` workflow to finish. It should create the pre-release with the same `-dev.X` name. 5. Wait for the `Release` workflow to finish. It should create the pre-release with the same name.
6. Check that pre-release was created on the [Releases page](https://github.com/paritytech/revive/releases) with all artifacts. 6. Check that pre-release was created on the [Releases page](https://github.com/paritytech/revive/releases) with all artifacts.
7. After the release is published, another workflow should start automatically and update json files in https://github.com/paritytech/resolc-bin. Check the changes. 7. After the release is published, another workflow should start automatically and update json files in https://github.com/paritytech/resolc-bin. Check the changes.
8. Update the [contract-docs](https://github.com/paritytech/contract-docs/) accordingly 8. Update the [contract-docs](https://github.com/paritytech/contract-docs/) accordingly
# `resolc` NPM package release
Will happen automatically.
# LLVM release # LLVM release
To create a new LLVM release, run "Release LLVM" workflow. Use current LLVM version as parameter, e.g. `18.1.8`. To create a new LLVM release, run "Release LLVM" workflow. Use current LLVM version as parameter, e.g. `18.1.8`.
-30
View File
@@ -1,30 +0,0 @@
# Known issues
The following is known and we are either working on it or it is a hard limitation. Please do not open a new issue.
## Release
`0.1.0-dev-2`
## Missing features
- [Libraries with public functions are not supported](https://github.com/paritytech/revive/issues/91)
- [Automatic import resolution is not supported](https://github.com/paritytech/revive/issues/98)
- The emulated EVM linear contract memory is limited to 64kb in size. Will be fixed with support for metered dynamic memory.
- [The contract calldata is currently limited to 1kb in size](https://github.com/paritytech/revive/issues/57)
- [EIP-4844 opcodes are not supported](https://github.com/paritytech/revive/issues/64)
- [Delegate calls are not supported](https://github.com/paritytech/revive/issues/67)
- [The `blockhash` opcode is not supported](https://github.com/paritytech/revive/issues/61)
- [The `extcodesize` opcode is not supported](https://github.com/paritytech/revive/issues/58)
- [The `origin` opcode is not supported](https://github.com/paritytech/revive/issues/59)
- [Gas limits for contract calls are ignored](https://github.com/paritytech/revive/issues/60)
- [Gas related opcodes are not supported](https://github.com/paritytech/revive/issues/60)
- IPFS metadata hashes are not supported
- [Compiled contract artifacts can exceed the pallet static memory limit and fail to deploy](https://github.com/paritytech/revive/issues/96).
- [Transfers to inexistant accounts will fail if the transferred value lies below the ED.](https://github.com/paritytech/revive/issues/83) Will be fixed in the pallet to make the ED completely transparent for contracts.
## Wontfix
Please consult our documentation to learn more about Solidity and EVM features likely to remain unsupported (and why they will not be supported).
TODO: Insert link to the relevant documentation section.
+2 -1
View File
@@ -1,5 +1,6 @@
[package] [package]
name = "revive-differential" name = "revive-differential"
description = "utilities for differential testing the revive compiler against EVM"
version.workspace = true version.workspace = true
license.workspace = true license.workspace = true
edition.workspace = true edition.workspace = true
@@ -13,4 +14,4 @@ serde = { workspace = true }
serde_json = { workspace = true } serde_json = { workspace = true }
alloy-primitives = { workspace = true, features = ["serde"] } alloy-primitives = { workspace = true, features = ["serde"] }
alloy-genesis = { workspace = true } alloy-genesis = { workspace = true }
alloy-serde = { workspace = true } alloy-serde = { workspace = true }
+2 -2
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "revive-integration" name = "revive-integration"
version.workspace = true version = "0.1.1"
license.workspace = true license.workspace = true
edition.workspace = true edition.workspace = true
repository.workspace = true repository.workspace = true
@@ -13,7 +13,7 @@ alloy-sol-types = { workspace = true }
hex = { workspace = true } hex = { workspace = true }
serde_json = { workspace = true } serde_json = { workspace = true }
revive-solidity = { workspace = true } resolc = { workspace = true }
revive-runner = { workspace = true } revive-runner = { workspace = true }
revive-llvm-context = { workspace = true } revive-llvm-context = { workspace = true }
+49
View File
@@ -0,0 +1,49 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8;
/* runner.json
{
"differential": true,
"actions": [
{
"Instantiate": {
"code": {
"Solidity": {
"contract": "SAR"
}
}
}
}
]
}
*/
contract SAR {
constructor() payable {
assert(sar(0x03, 0x01) == 0x01);
assert(
sar(
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff,
0x01
) == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
);
assert(
sar(
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff,
0xff
) == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
);
assert(
sar(
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff,
0x100
) == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
);
}
function sar(uint256 a, uint256 b) public pure returns (uint256 c) {
assembly {
c := sar(b, a)
}
}
}
+1 -1
View File
@@ -1,8 +1,8 @@
use alloy_primitives::{Address, Bytes, I256, U256}; use alloy_primitives::{Address, Bytes, I256, U256};
use alloy_sol_types::{sol, SolCall, SolConstructor}; use alloy_sol_types::{sol, SolCall, SolConstructor};
use resolc::test_utils::*;
use revive_llvm_context::OptimizerSettings; use revive_llvm_context::OptimizerSettings;
use revive_solidity::test_utils::*;
#[derive(Clone)] #[derive(Clone)]
pub struct Contract { pub struct Contract {
+1
View File
@@ -60,6 +60,7 @@ test_spec!(mload, "MLoad", "MLoad.sol");
test_spec!(delegate_no_contract, "DelegateCaller", "DelegateCaller.sol"); test_spec!(delegate_no_contract, "DelegateCaller", "DelegateCaller.sol");
test_spec!(function_type, "FunctionType", "FunctionType.sol"); test_spec!(function_type, "FunctionType", "FunctionType.sol");
test_spec!(layout_at, "LayoutAt", "LayoutAt.sol"); test_spec!(layout_at, "LayoutAt", "LayoutAt.sol");
test_spec!(shift_arithmetic_right, "SAR", "SAR.sol");
fn instantiate(path: &str, contract: &str) -> Vec<SpecsAction> { fn instantiate(path: &str, contract: &str) -> Vec<SpecsAction> {
vec![Instantiate { vec![Instantiate {
+1 -1
View File
@@ -6,7 +6,7 @@ authors = [
"Anton Baliasnikov <aba@matterlabs.dev>", "Anton Baliasnikov <aba@matterlabs.dev>",
"Cyrill Leutwiler <cyrill@parity.io>", "Cyrill Leutwiler <cyrill@parity.io>",
] ]
version.workspace = true version = "0.2.0"
license.workspace = true license.workspace = true
edition.workspace = true edition.workspace = true
repository.workspace = true repository.workspace = true
+1 -1
View File
@@ -22,7 +22,7 @@ impl std::str::FromStr for BuildType {
"Release" => Ok(Self::Release), "Release" => Ok(Self::Release),
"RelWithDebInfo" => Ok(Self::RelWithDebInfo), "RelWithDebInfo" => Ok(Self::RelWithDebInfo),
"MinSizeRel" => Ok(Self::MinSizeRel), "MinSizeRel" => Ok(Self::MinSizeRel),
value => Err(format!("Unsupported build type: `{}`", value)), value => Err(format!("Unsupported build type: `{value}`")),
} }
} }
} }
+2 -8
View File
@@ -117,13 +117,7 @@ pub fn build(
log::info!("building compiler-rt for rv64emac"); log::info!("building compiler-rt for rv64emac");
crate::utils::check_presence("cmake")?; crate::utils::check_presence("cmake")?;
crate::utils::check_presence("ninja")?;
let generator = if cfg!(target_os = "windows") {
"Visual Studio 17 2022"
} else {
crate::utils::check_presence("ninja")?;
"Ninja"
};
let llvm_module_compiler_rt = crate::LLVMPath::llvm_module_compiler_rt()?; let llvm_module_compiler_rt = crate::LLVMPath::llvm_module_compiler_rt()?;
let llvm_compiler_rt_build = crate::LLVMPath::llvm_build_compiler_rt()?; let llvm_compiler_rt_build = crate::LLVMPath::llvm_build_compiler_rt()?;
@@ -136,7 +130,7 @@ pub fn build(
"-B", "-B",
llvm_compiler_rt_build.to_string_lossy().as_ref(), llvm_compiler_rt_build.to_string_lossy().as_ref(),
"-G", "-G",
generator, "Ninja",
]) ])
.args(CMAKE_STATIC_ARGS) .args(CMAKE_STATIC_ARGS)
.args(cmake_dynamic_args(build_type, target_env)?) .args(cmake_dynamic_args(build_type, target_env)?)
+1 -1
View File
@@ -16,7 +16,7 @@ impl std::str::FromStr for CcacheVariant {
match value { match value {
"ccache" => Ok(Self::Ccache), "ccache" => Ok(Self::Ccache),
"sccache" => Ok(Self::Sccache), "sccache" => Ok(Self::Sccache),
value => Err(format!("Unsupported ccache variant: `{}`", value)), value => Err(format!("Unsupported ccache variant: `{value}`")),
} }
} }
} }
+13 -14
View File
@@ -127,23 +127,22 @@ pub fn build(
sanitizer: Option<sanitizer::Sanitizer>, sanitizer: Option<sanitizer::Sanitizer>,
enable_valgrind: bool, enable_valgrind: bool,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
log::trace!("build type: {:?}", build_type); log::trace!("build type: {build_type:?}");
log::trace!("target env: {:?}", target_env); log::trace!("target env: {target_env:?}");
log::trace!("targets: {:?}", targets); log::trace!("targets: {targets:?}");
log::trace!("llvm projects: {:?}", llvm_projects); log::trace!("llvm projects: {llvm_projects:?}");
log::trace!("enable rtti: {:?}", enable_rtti); log::trace!("enable rtti: {enable_rtti:?}");
log::trace!("default target: {:?}", default_target); log::trace!("default target: {default_target:?}");
log::trace!("eneable tests: {:?}", enable_tests); log::trace!("eneable tests: {enable_tests:?}");
log::trace!("enable_coverage: {:?}", enable_coverage); log::trace!("enable_coverage: {enable_coverage:?}");
log::trace!("extra args: {:?}", extra_args); log::trace!("extra args: {extra_args:?}");
log::trace!("sanitzer: {:?}", sanitizer); log::trace!("sanitzer: {sanitizer:?}");
log::trace!("enable valgrind: {:?}", enable_valgrind); log::trace!("enable valgrind: {enable_valgrind:?}");
if !PathBuf::from(LLVMPath::DIRECTORY_LLVM_SOURCE).exists() { if !PathBuf::from(LLVMPath::DIRECTORY_LLVM_SOURCE).exists() {
log::error!( log::error!(
"LLVM project source directory {} does not exist (run `revive-llvm --target-env {} clone`)", "LLVM project source directory {} does not exist (run `revive-llvm --target-env {target_env} clone`)",
LLVMPath::DIRECTORY_LLVM_SOURCE, LLVMPath::DIRECTORY_LLVM_SOURCE
target_env
) )
} }
+1 -1
View File
@@ -22,7 +22,7 @@ impl std::str::FromStr for LLVMProject {
"lld" => Ok(Self::LLD), "lld" => Ok(Self::LLD),
"lldb" => Ok(Self::LLDB), "lldb" => Ok(Self::LLDB),
"mlir" => Ok(Self::MLIR), "mlir" => Ok(Self::MLIR),
value => Err(format!("Unsupported LLVM project to enable: `{}`", value)), value => Err(format!("Unsupported LLVM project to enable: `{value}`")),
} }
} }
} }
+1 -1
View File
@@ -30,7 +30,7 @@ impl TryFrom<&PathBuf> for Lock {
fn try_from(path: &PathBuf) -> Result<Self, Self::Error> { fn try_from(path: &PathBuf) -> Result<Self, Self::Error> {
let mut config_str = String::new(); let mut config_str = String::new();
let mut config_file = let mut config_file =
File::open(path).with_context(|| format!("Error opening {:?} file", path))?; File::open(path).with_context(|| format!("Error opening {path:?} file"))?;
config_file.read_to_string(&mut config_str)?; config_file.read_to_string(&mut config_str)?;
Ok(toml::from_str(&config_str)?) Ok(toml::from_str(&config_str)?)
} }
+1 -1
View File
@@ -29,7 +29,7 @@ impl FromStr for Platform {
fn from_str(value: &str) -> Result<Self, Self::Err> { fn from_str(value: &str) -> Result<Self, Self::Err> {
match value { match value {
"PolkaVM" => Ok(Self::PolkaVM), "PolkaVM" => Ok(Self::PolkaVM),
value => Err(format!("Unsupported platform: `{}`", value)), value => Err(format!("Unsupported platform: `{value}`")),
} }
} }
} }
+2 -2
View File
@@ -69,8 +69,8 @@ fn main_inner() -> anyhow::Result<()> {
}) })
.collect(); .collect();
log::debug!("extra_args: {:#?}", extra_args); log::debug!("extra_args: {extra_args:#?}");
log::debug!("extra_args_unescaped: {:#?}", extra_args_unescaped); log::debug!("extra_args_unescaped: {extra_args_unescaped:#?}");
if let Some(ccache_variant) = ccache_variant { if let Some(ccache_variant) = ccache_variant {
revive_llvm_builder::utils::check_presence(ccache_variant.to_string().as_str())?; revive_llvm_builder::utils::check_presence(ccache_variant.to_string().as_str())?;
+1 -1
View File
@@ -30,7 +30,7 @@ impl std::str::FromStr for Sanitizer {
"thread" => Ok(Self::Thread), "thread" => Ok(Self::Thread),
"dataflow" => Ok(Self::DataFlow), "dataflow" => Ok(Self::DataFlow),
"address;undefined" => Ok(Self::AddressUndefined), "address;undefined" => Ok(Self::AddressUndefined),
value => Err(format!("Unsupported sanitizer: `{}`", value)), value => Err(format!("Unsupported sanitizer: `{value}`")),
} }
} }
} }
+1 -1
View File
@@ -20,7 +20,7 @@ impl std::str::FromStr for TargetEnv {
"gnu" => Ok(Self::GNU), "gnu" => Ok(Self::GNU),
"musl" => Ok(Self::MUSL), "musl" => Ok(Self::MUSL),
"emscripten" => Ok(Self::Emscripten), "emscripten" => Ok(Self::Emscripten),
value => Err(format!("Unsupported target environment: `{}`", value)), value => Err(format!("Unsupported target environment: `{value}`")),
} }
} }
} }
+1 -1
View File
@@ -15,7 +15,7 @@ impl std::str::FromStr for TargetTriple {
fn from_str(value: &str) -> Result<Self, Self::Err> { fn from_str(value: &str) -> Result<Self, Self::Err> {
match value { match value {
"polkavm" => Ok(Self::PolkaVM), "polkavm" => Ok(Self::PolkaVM),
value => Err(format!("Unsupported target triple: `{}`", value)), value => Err(format!("Unsupported target triple: `{value}`")),
} }
} }
} }
+3 -3
View File
@@ -38,7 +38,7 @@ pub const MUSL_SNAPSHOTS_URL: &str = "https://git.musl-libc.org/cgit/musl/snapsh
pub const EMSDK_SOURCE_URL: &str = "https://github.com/emscripten-core/emsdk.git"; pub const EMSDK_SOURCE_URL: &str = "https://github.com/emscripten-core/emsdk.git";
/// The emscripten SDK version. /// The emscripten SDK version.
pub const EMSDK_VERSION: &str = "3.1.64"; pub const EMSDK_VERSION: &str = "4.0.9";
/// The subprocess runner. /// The subprocess runner.
/// ///
@@ -92,7 +92,7 @@ pub fn unpack_tar(filename: PathBuf, path: &str) -> anyhow::Result<()> {
pub fn download_musl(name: &str) -> anyhow::Result<()> { pub fn download_musl(name: &str) -> anyhow::Result<()> {
log::info!("downloading musl {name}"); log::info!("downloading musl {name}");
let tar_file_name = format!("{name}.tar.gz"); let tar_file_name = format!("{name}.tar.gz");
let url = format!("{}/{tar_file_name}", MUSL_SNAPSHOTS_URL); let url = format!("{MUSL_SNAPSHOTS_URL}/{tar_file_name}");
let target_path = crate::llvm_path::DIRECTORY_LLVM_TARGET let target_path = crate::llvm_path::DIRECTORY_LLVM_TARGET
.get() .get()
.unwrap() .unwrap()
@@ -223,6 +223,6 @@ pub fn install_emsdk() -> anyhow::Result<()> {
/// The LLVM target directory default path. /// The LLVM target directory default path.
pub fn directory_target_llvm(target_env: crate::target_env::TargetEnv) -> PathBuf { pub fn directory_target_llvm(target_env: crate::target_env::TargetEnv) -> PathBuf {
crate::llvm_path::DIRECTORY_LLVM_TARGET crate::llvm_path::DIRECTORY_LLVM_TARGET
.get_or_init(|| PathBuf::from(format!("./target-llvm/{}/", target_env))) .get_or_init(|| PathBuf::from(format!("./target-llvm/{target_env}/")))
.clone() .clone()
} }
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "revive-llvm-context" name = "revive-llvm-context"
version.workspace = true version = "0.3.0"
license.workspace = true license.workspace = true
edition.workspace = true edition.workspace = true
repository.workspace = true repository.workspace = true
-2
View File
@@ -5,7 +5,6 @@ use std::sync::OnceLock;
pub use self::debug_config::ir_type::IRType as DebugConfigIR; pub use self::debug_config::ir_type::IRType as DebugConfigIR;
pub use self::debug_config::DebugConfig; pub use self::debug_config::DebugConfig;
pub use self::memory::MemoryConfig;
pub use self::optimizer::settings::size_level::SizeLevel as OptimizerSettingsSizeLevel; pub use self::optimizer::settings::size_level::SizeLevel as OptimizerSettingsSizeLevel;
pub use self::optimizer::settings::Settings as OptimizerSettings; pub use self::optimizer::settings::Settings as OptimizerSettings;
pub use self::optimizer::Optimizer; pub use self::optimizer::Optimizer;
@@ -76,7 +75,6 @@ pub use self::target_machine::target::Target;
pub use self::target_machine::TargetMachine; pub use self::target_machine::TargetMachine;
pub(crate) mod debug_config; pub(crate) mod debug_config;
pub(crate) mod memory;
pub(crate) mod optimizer; pub(crate) mod optimizer;
pub(crate) mod polkavm; pub(crate) mod polkavm;
pub(crate) mod target_machine; pub(crate) mod target_machine;
-21
View File
@@ -1,21 +0,0 @@
//! The compile time PolkaVM memory configuration settings.
use serde::{Deserialize, Serialize};
/// The PolkaVM memory configuration.
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct MemoryConfig {
/// The emulated EVM linear heap memory size in bytes.
pub heap_size: u32,
/// The PVM stack size in bytes.
pub stack_size: u32,
}
impl Default for MemoryConfig {
fn default() -> Self {
Self {
heap_size: 64 * 1024,
stack_size: 32 * 1024,
}
}
}
@@ -234,7 +234,7 @@ impl TryFrom<&SolcStandardJsonInputSettingsOptimizer> for Settings {
fn try_from(value: &SolcStandardJsonInputSettingsOptimizer) -> Result<Self, Self::Error> { fn try_from(value: &SolcStandardJsonInputSettingsOptimizer) -> Result<Self, Self::Error> {
let mut result = match value.mode { let mut result = match value.mode {
Some(mode) => Self::try_from_cli(mode)?, Some(mode) => Self::try_from_cli(mode)?,
None => Self::cycles(), None => Self::size(),
}; };
if value.fallback_to_optimizing_for_size.unwrap_or_default() { if value.fallback_to_optimizing_for_size.unwrap_or_default() {
result.enable_fallback_to_size(); result.enable_fallback_to_size();
@@ -1,6 +1,7 @@
//! The entry function. //! The entry function.
use inkwell::types::BasicType; use inkwell::types::BasicType;
use revive_solc_json_interface::PolkaVMDefaultHeapMemorySize;
use crate::polkavm::context::address_space::AddressSpace; use crate::polkavm::context::address_space::AddressSpace;
use crate::polkavm::context::function::runtime; use crate::polkavm::context::function::runtime;
@@ -38,9 +39,12 @@ impl Entry {
context.xlen_type().const_zero(), context.xlen_type().const_zero(),
); );
let heap_memory_type = context let heap_memory_type = context.byte_type().array_type(
.byte_type() context
.array_type(context.memory_config.heap_size); .memory_config
.heap_size
.unwrap_or(PolkaVMDefaultHeapMemorySize),
);
context.set_global( context.set_global(
crate::polkavm::GLOBAL_HEAP_MEMORY, crate::polkavm::GLOBAL_HEAP_MEMORY,
heap_memory_type, heap_memory_type,
+18 -6
View File
@@ -25,8 +25,10 @@ use inkwell::debug_info::AsDIScope;
use inkwell::debug_info::DIScope; use inkwell::debug_info::DIScope;
use inkwell::types::BasicType; use inkwell::types::BasicType;
use inkwell::values::BasicValue; use inkwell::values::BasicValue;
use revive_solc_json_interface::PolkaVMDefaultHeapMemorySize;
use revive_solc_json_interface::PolkaVMDefaultStackMemorySize;
use revive_solc_json_interface::SolcStandardJsonInputSettingsPolkaVMMemory;
use crate::memory::MemoryConfig;
use crate::optimizer::settings::Settings as OptimizerSettings; use crate::optimizer::settings::Settings as OptimizerSettings;
use crate::optimizer::Optimizer; use crate::optimizer::Optimizer;
use crate::polkavm::DebugConfig; use crate::polkavm::DebugConfig;
@@ -88,7 +90,7 @@ where
/// The extra LLVM arguments that were used during target initialization. /// The extra LLVM arguments that were used during target initialization.
llvm_arguments: &'ctx [String], llvm_arguments: &'ctx [String],
/// The PVM memory configuration. /// The PVM memory configuration.
memory_config: MemoryConfig, memory_config: SolcStandardJsonInputSettingsPolkaVMMemory,
/// The project dependency manager. It can be any entity implementing the trait. /// The project dependency manager. It can be any entity implementing the trait.
/// The manager is used to get information about contracts and their dependencies during /// The manager is used to get information about contracts and their dependencies during
@@ -228,12 +230,18 @@ where
include_metadata_hash: bool, include_metadata_hash: bool,
debug_config: DebugConfig, debug_config: DebugConfig,
llvm_arguments: &'ctx [String], llvm_arguments: &'ctx [String],
memory_config: MemoryConfig, memory_config: SolcStandardJsonInputSettingsPolkaVMMemory,
) -> Self { ) -> Self {
Self::set_data_layout(llvm, &module); Self::set_data_layout(llvm, &module);
Self::link_stdlib_module(llvm, &module); Self::link_stdlib_module(llvm, &module);
Self::link_polkavm_imports(llvm, &module); Self::link_polkavm_imports(llvm, &module);
Self::set_polkavm_stack_size(llvm, &module, memory_config.stack_size); Self::set_polkavm_stack_size(
llvm,
&module,
memory_config
.stack_size
.unwrap_or(PolkaVMDefaultStackMemorySize),
);
Self::set_module_flags(llvm, &module); Self::set_module_flags(llvm, &module);
let intrinsics = Intrinsics::new(llvm, &module); let intrinsics = Intrinsics::new(llvm, &module);
@@ -1443,7 +1451,11 @@ where
} }
pub fn heap_size(&self) -> inkwell::values::IntValue<'ctx> { pub fn heap_size(&self) -> inkwell::values::IntValue<'ctx> {
self.xlen_type() self.xlen_type().const_int(
.const_int(self.memory_config.heap_size as u64, false) self.memory_config
.heap_size
.unwrap_or(PolkaVMDefaultHeapMemorySize) as u64,
false,
)
} }
} }
@@ -204,7 +204,7 @@ where
&context.word_type().const_all_ones(), &context.word_type().const_all_ones(),
overflow_negative_block, overflow_negative_block,
), ),
(&context.word_const(0), overflow_block), (&context.word_const(0), overflow_positive_block),
]); ]);
Ok(result.as_basic_value()) Ok(result.as_basic_value())
} }
+4 -4
View File
@@ -7,12 +7,12 @@ pub mod evm;
pub use self::r#const::*; pub use self::r#const::*;
use crate::debug_config::DebugConfig; use crate::debug_config::DebugConfig;
use crate::memory::MemoryConfig;
use crate::optimizer::settings::Settings as OptimizerSettings; use crate::optimizer::settings::Settings as OptimizerSettings;
use anyhow::Context as AnyhowContext; use anyhow::Context as AnyhowContext;
use polkavm_common::program::ProgramBlob; use polkavm_common::program::ProgramBlob;
use polkavm_disassembler::{Disassembler, DisassemblyFormat}; use polkavm_disassembler::{Disassembler, DisassemblyFormat};
use revive_solc_json_interface::SolcStandardJsonInputSettingsPolkaVMMemory;
use sha3::Digest; use sha3::Digest;
use self::context::build::Build; use self::context::build::Build;
@@ -37,7 +37,7 @@ pub fn build_assembly_text(
let mut disassembled_code = Vec::new(); let mut disassembled_code = Vec::new();
disassembler disassembler
.disassemble_into(&mut disassembled_code) .disassemble_into(&mut disassembled_code)
.with_context(|| format!("Failed to disassemble contract: {}", contract_path))?; .with_context(|| format!("Failed to disassemble contract: {contract_path}"))?;
let assembly_text = String::from_utf8(disassembled_code).with_context(|| { let assembly_text = String::from_utf8(disassembled_code).with_context(|| {
format!("Failed to convert disassembled code to string for contract: {contract_path}") format!("Failed to convert disassembled code to string for contract: {contract_path}")
@@ -91,7 +91,7 @@ pub trait Dependency {
include_metadata_hash: bool, include_metadata_hash: bool,
debug_config: DebugConfig, debug_config: DebugConfig,
llvm_arguments: &[String], llvm_arguments: &[String],
memory_config: MemoryConfig, memory_config: SolcStandardJsonInputSettingsPolkaVMMemory,
) -> anyhow::Result<String>; ) -> anyhow::Result<String>;
/// Resolves a full contract path. /// Resolves a full contract path.
@@ -113,7 +113,7 @@ impl Dependency for DummyDependency {
_include_metadata_hash: bool, _include_metadata_hash: bool,
_debug_config: DebugConfig, _debug_config: DebugConfig,
_llvm_arguments: &[String], _llvm_arguments: &[String],
_memory_config: MemoryConfig, _memory_config: SolcStandardJsonInputSettingsPolkaVMMemory,
) -> anyhow::Result<String> { ) -> anyhow::Result<String> {
Ok(String::new()) Ok(String::new())
} }
@@ -1,6 +1,6 @@
[package] [package]
name = "revive-solidity" name = "resolc"
version.workspace = true version = "0.3.0"
license.workspace = true license.workspace = true
edition.workspace = true edition.workspace = true
repository.workspace = true repository.workspace = true
@@ -18,33 +18,30 @@ path = "src/resolc/main.rs"
doctest = false doctest = false
[dependencies] [dependencies]
clap = { workspace = true }
thiserror = { workspace = true }
anyhow = { workspace = true } anyhow = { workspace = true }
which = { workspace = true } clap = { workspace = true }
hex = { workspace = true }
inkwell = { workspace = true }
once_cell = { workspace = true }
path-slash = { workspace = true } path-slash = { workspace = true }
rayon = { workspace = true, optional = true } rayon = { workspace = true, optional = true }
semver = { workspace = true }
serde = { workspace = true } serde = { workspace = true }
serde_json = { workspace = true } serde_json = { workspace = true }
semver = { workspace = true }
once_cell = { workspace = true }
regex = { workspace = true }
hex = { workspace = true }
num = { workspace = true }
sha3 = { workspace = true } sha3 = { workspace = true }
inkwell = { workspace = true } which = { workspace = true }
revive-common = { workspace = true } revive-common = { workspace = true }
revive-llvm-context = { workspace = true } revive-llvm-context = { workspace = true }
revive-solc-json-interface = { workspace = true, features = ["resolc"] } revive-solc-json-interface = { workspace = true, features = ["resolc"] }
revive-yul = { workspace = true }
[target.'cfg(target_env = "musl")'.dependencies] [target.'cfg(target_env = "musl")'.dependencies]
mimalloc = { version = "*", default-features = false } mimalloc = { version = "0.1.46", default-features = false }
[target.'cfg(target_os = "emscripten")'.dependencies] [target.'cfg(target_os = "emscripten")'.dependencies]
libc = { workspace = true } libc = { workspace = true }
inkwell = { workspace = true, features = ["target-riscv", "llvm18-0-no-llvm-linking"]} inkwell = { workspace = true, features = ["target-riscv", "llvm18-1-no-llvm-linking"]}
[build-dependencies] [build-dependencies]
git2 = { workspace = true, default-features = false } git2 = { workspace = true, default-features = false }
+11
View File
@@ -0,0 +1,11 @@
fn main() {
match git2::Repository::open("../..") {
Ok(repo) => {
let head = repo.head().expect("should have head");
let commit = head.peel_to_commit().expect("should have commit");
let id = &commit.id().to_string()[..7];
println!("cargo:rustc-env=GIT_COMMIT_HASH={id}");
}
Err(_) => println!("cargo:rustc-env=GIT_COMMIT_HASH=unknown"),
};
}
@@ -7,7 +7,6 @@ pub(crate) mod process;
pub(crate) mod project; pub(crate) mod project;
pub(crate) mod solc; pub(crate) mod solc;
pub(crate) mod version; pub(crate) mod version;
pub(crate) mod yul;
pub use self::build::contract::Contract as ContractBuild; pub use self::build::contract::Contract as ContractBuild;
pub use self::build::Build; pub use self::build::Build;
@@ -45,6 +44,8 @@ use revive_solc_json_interface::ResolcWarning;
use revive_solc_json_interface::SolcStandardJsonInput; use revive_solc_json_interface::SolcStandardJsonInput;
use revive_solc_json_interface::SolcStandardJsonInputLanguage; use revive_solc_json_interface::SolcStandardJsonInputLanguage;
use revive_solc_json_interface::SolcStandardJsonInputSettingsOptimizer; use revive_solc_json_interface::SolcStandardJsonInputSettingsOptimizer;
use revive_solc_json_interface::SolcStandardJsonInputSettingsPolkaVM;
use revive_solc_json_interface::SolcStandardJsonInputSettingsPolkaVMMemory;
use revive_solc_json_interface::SolcStandardJsonInputSettingsSelection; use revive_solc_json_interface::SolcStandardJsonInputSettingsSelection;
/// Runs the Yul mode. /// Runs the Yul mode.
@@ -55,7 +56,7 @@ pub fn yul<T: Compiler>(
include_metadata_hash: bool, include_metadata_hash: bool,
debug_config: revive_llvm_context::DebugConfig, debug_config: revive_llvm_context::DebugConfig,
llvm_arguments: &[String], llvm_arguments: &[String],
memory_config: revive_llvm_context::MemoryConfig, memory_config: SolcStandardJsonInputSettingsPolkaVMMemory,
) -> anyhow::Result<Build> { ) -> anyhow::Result<Build> {
let path = match input_files.len() { let path = match input_files.len() {
1 => input_files.first().expect("Always exists"), 1 => input_files.first().expect("Always exists"),
@@ -94,7 +95,7 @@ pub fn llvm_ir(
include_metadata_hash: bool, include_metadata_hash: bool,
debug_config: revive_llvm_context::DebugConfig, debug_config: revive_llvm_context::DebugConfig,
llvm_arguments: &[String], llvm_arguments: &[String],
memory_config: revive_llvm_context::MemoryConfig, memory_config: SolcStandardJsonInputSettingsPolkaVMMemory,
) -> anyhow::Result<Build> { ) -> anyhow::Result<Build> {
let path = match input_files.len() { let path = match input_files.len() {
1 => input_files.first().expect("Always exists"), 1 => input_files.first().expect("Always exists"),
@@ -135,7 +136,7 @@ pub fn standard_output<T: Compiler>(
suppressed_warnings: Option<Vec<ResolcWarning>>, suppressed_warnings: Option<Vec<ResolcWarning>>,
debug_config: revive_llvm_context::DebugConfig, debug_config: revive_llvm_context::DebugConfig,
llvm_arguments: &[String], llvm_arguments: &[String],
memory_config: revive_llvm_context::MemoryConfig, memory_config: SolcStandardJsonInputSettingsPolkaVMMemory,
) -> anyhow::Result<Build> { ) -> anyhow::Result<Build> {
let solc_version = solc.version()?; let solc_version = solc.version()?;
@@ -154,6 +155,10 @@ pub fn standard_output<T: Compiler>(
), ),
None, None,
suppressed_warnings, suppressed_warnings,
Some(SolcStandardJsonInputSettingsPolkaVM::new(
Some(memory_config),
debug_config.emit_debug_info,
)),
)?; )?;
let source_code_files = solc_input let source_code_files = solc_input
@@ -208,9 +213,8 @@ pub fn standard_json<T: Compiler>(
base_path: Option<String>, base_path: Option<String>,
include_paths: Vec<String>, include_paths: Vec<String>,
allow_paths: Option<String>, allow_paths: Option<String>,
debug_config: revive_llvm_context::DebugConfig, mut debug_config: revive_llvm_context::DebugConfig,
llvm_arguments: &[String], llvm_arguments: &[String],
memory_config: revive_llvm_context::MemoryConfig,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let solc_version = solc.version()?; let solc_version = solc.version()?;
@@ -224,6 +228,9 @@ pub fn standard_json<T: Compiler>(
let optimizer_settings = let optimizer_settings =
revive_llvm_context::OptimizerSettings::try_from(&solc_input.settings.optimizer)?; revive_llvm_context::OptimizerSettings::try_from(&solc_input.settings.optimizer)?;
let polkavm_settings = solc_input.settings.polkavm.unwrap_or_default();
debug_config.emit_debug_info = polkavm_settings.debug_information.unwrap_or_default();
let include_metadata_hash = match solc_input.settings.metadata { let include_metadata_hash = match solc_input.settings.metadata {
Some(ref metadata) => metadata.bytecode_hash != Some(MetadataHash::None), Some(ref metadata) => metadata.bytecode_hash != Some(MetadataHash::None),
None => true, None => true,
@@ -258,7 +265,9 @@ pub fn standard_json<T: Compiler>(
include_metadata_hash, include_metadata_hash,
debug_config, debug_config,
llvm_arguments, llvm_arguments,
memory_config, polkavm_settings
.memory_config
.unwrap_or_else(SolcStandardJsonInputSettingsPolkaVMMemory::default),
)?; )?;
build.write_to_standard_json(&mut solc_output, &solc_version)?; build.write_to_standard_json(&mut solc_output, &solc_version)?;
} }
@@ -286,7 +295,7 @@ pub fn combined_json<T: Compiler>(
output_directory: Option<PathBuf>, output_directory: Option<PathBuf>,
overwrite: bool, overwrite: bool,
llvm_arguments: &[String], llvm_arguments: &[String],
memory_config: revive_llvm_context::MemoryConfig, memory_config: SolcStandardJsonInputSettingsPolkaVMMemory,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let build = standard_output( let build = standard_output(
input_files, input_files,
@@ -1,6 +1,7 @@
//! Process for compiling a single compilation unit. //! Process for compiling a single compilation unit.
//! The input data. //! The input data.
use revive_solc_json_interface::SolcStandardJsonInputSettingsPolkaVMMemory;
use serde::Deserialize; use serde::Deserialize;
use serde::Serialize; use serde::Serialize;
@@ -23,7 +24,7 @@ pub struct Input {
/// The extra LLVM arguments give used for manual control. /// The extra LLVM arguments give used for manual control.
pub llvm_arguments: Vec<String>, pub llvm_arguments: Vec<String>,
/// The PVM memory configuration. /// The PVM memory configuration.
pub memory_config: revive_llvm_context::MemoryConfig, pub memory_config: SolcStandardJsonInputSettingsPolkaVMMemory,
} }
impl Input { impl Input {
@@ -35,7 +36,7 @@ impl Input {
optimizer_settings: revive_llvm_context::OptimizerSettings, optimizer_settings: revive_llvm_context::OptimizerSettings,
debug_config: revive_llvm_context::DebugConfig, debug_config: revive_llvm_context::DebugConfig,
llvm_arguments: Vec<String>, llvm_arguments: Vec<String>,
memory_config: revive_llvm_context::MemoryConfig, memory_config: SolcStandardJsonInputSettingsPolkaVMMemory,
) -> Self { ) -> Self {
Self { Self {
contract, contract,
@@ -8,7 +8,7 @@ use std::collections::HashSet;
use serde::Deserialize; use serde::Deserialize;
use serde::Serialize; use serde::Serialize;
use crate::yul::parser::statement::object::Object; use revive_yul::parser::statement::object::Object;
use self::llvm_ir::LLVMIR; use self::llvm_ir::LLVMIR;
use self::yul::Yul; use self::yul::Yul;
@@ -5,7 +5,7 @@ use std::collections::HashSet;
use serde::Deserialize; use serde::Deserialize;
use serde::Serialize; use serde::Serialize;
use crate::yul::parser::statement::object::Object; use revive_yul::parser::statement::object::Object;
/// The contract Yul source code. /// The contract Yul source code.
#[derive(Debug, Serialize, Deserialize, Clone)] #[derive(Debug, Serialize, Deserialize, Clone)]
@@ -5,6 +5,7 @@ pub mod metadata;
use std::collections::HashSet; use std::collections::HashSet;
use revive_solc_json_interface::SolcStandardJsonInputSettingsPolkaVMMemory;
use serde::Deserialize; use serde::Deserialize;
use serde::Serialize; use serde::Serialize;
use sha3::Digest; use sha3::Digest;
@@ -78,7 +79,7 @@ impl Contract {
include_metadata_hash: bool, include_metadata_hash: bool,
debug_config: revive_llvm_context::DebugConfig, debug_config: revive_llvm_context::DebugConfig,
llvm_arguments: &[String], llvm_arguments: &[String],
memory_config: revive_llvm_context::MemoryConfig, memory_config: SolcStandardJsonInputSettingsPolkaVMMemory,
) -> anyhow::Result<ContractBuild> { ) -> anyhow::Result<ContractBuild> {
let llvm = inkwell::context::Context::create(); let llvm = inkwell::context::Context::create();
let optimizer = revive_llvm_context::Optimizer::new(optimizer_settings); let optimizer = revive_llvm_context::Optimizer::new(optimizer_settings);
@@ -9,11 +9,14 @@ use std::path::Path;
#[cfg(feature = "parallel")] #[cfg(feature = "parallel")]
use rayon::iter::{IntoParallelIterator, ParallelIterator}; use rayon::iter::{IntoParallelIterator, ParallelIterator};
use revive_solc_json_interface::SolcStandardJsonOutput;
use serde::Deserialize; use serde::Deserialize;
use serde::Serialize; use serde::Serialize;
use sha3::Digest; use sha3::Digest;
use revive_solc_json_interface::SolcStandardJsonOutput;
use revive_yul::lexer::Lexer;
use revive_yul::parser::statement::object::Object;
use crate::build::contract::Contract as ContractBuild; use crate::build::contract::Contract as ContractBuild;
use crate::build::Build; use crate::build::Build;
use crate::missing_libraries::MissingLibraries; use crate::missing_libraries::MissingLibraries;
@@ -22,8 +25,6 @@ use crate::process::Process;
use crate::project::contract::ir::IR; use crate::project::contract::ir::IR;
use crate::solc::version::Version as SolcVersion; use crate::solc::version::Version as SolcVersion;
use crate::solc::Compiler; use crate::solc::Compiler;
use crate::yul::lexer::Lexer;
use crate::yul::parser::statement::object::Object;
use self::contract::Contract; use self::contract::Contract;
@@ -67,7 +68,7 @@ impl Project {
include_metadata_hash: bool, include_metadata_hash: bool,
debug_config: revive_llvm_context::DebugConfig, debug_config: revive_llvm_context::DebugConfig,
llvm_arguments: &[String], llvm_arguments: &[String],
memory_config: revive_llvm_context::MemoryConfig, memory_config: revive_solc_json_interface::SolcStandardJsonInputSettingsPolkaVMMemory,
) -> anyhow::Result<Build> { ) -> anyhow::Result<Build> {
let project = self.clone(); let project = self.clone();
#[cfg(feature = "parallel")] #[cfg(feature = "parallel")]
@@ -154,8 +155,8 @@ impl Project {
.iter() .iter()
.flat_map(|(file, names)| { .flat_map(|(file, names)| {
names names
.iter() .keys()
.map(|(name, _address)| format!("{file}:{name}")) .map(|name| format!("{file}:{name}"))
.collect::<HashSet<String>>() .collect::<HashSet<String>>()
}) })
.collect::<HashSet<String>>(); .collect::<HashSet<String>>();
@@ -321,7 +322,7 @@ impl revive_llvm_context::PolkaVMDependency for Project {
include_metadata_hash: bool, include_metadata_hash: bool,
debug_config: revive_llvm_context::DebugConfig, debug_config: revive_llvm_context::DebugConfig,
llvm_arguments: &[String], llvm_arguments: &[String],
memory_config: revive_llvm_context::MemoryConfig, memory_config: revive_solc_json_interface::SolcStandardJsonInputSettingsPolkaVMMemory,
) -> anyhow::Result<String> { ) -> anyhow::Result<String> {
let contract_path = project.resolve_path(identifier)?; let contract_path = project.resolve_path(identifier)?;
let contract = project let contract = project
@@ -23,10 +23,6 @@ pub struct Arguments {
#[arg(long = "supported-solc-versions")] #[arg(long = "supported-solc-versions")]
pub supported_solc_versions: bool, pub supported_solc_versions: bool,
/// Print the licence and exit.
#[arg(long = "license")]
pub license: bool,
/// Specify the input paths and remappings. /// Specify the input paths and remappings.
/// If an argument contains a '=', it is considered a remapping. /// If an argument contains a '=', it is considered a remapping.
/// Multiple Solidity files can be passed in the default Solidity mode. /// Multiple Solidity files can be passed in the default Solidity mode.
@@ -185,8 +181,8 @@ pub struct Arguments {
/// 1.Increasing the heap size will increase startup costs. /// 1.Increasing the heap size will increase startup costs.
/// 2.The heap size contributes to the total memory size a contract can use, /// 2.The heap size contributes to the total memory size a contract can use,
/// which includes the contracts code size /// which includes the contracts code size
#[arg(long = "heap-size", default_value = "65536")] #[arg(long = "heap-size")]
pub heap_size: u32, pub heap_size: Option<u32>,
/// The contracts total stack size in bytes. /// The contracts total stack size in bytes.
/// ///
@@ -200,8 +196,8 @@ pub struct Arguments {
/// 1.Increasing the heap size will increase startup costs. /// 1.Increasing the heap size will increase startup costs.
/// 2.The stack size contributes to the total memory size a contract can use, /// 2.The stack size contributes to the total memory size a contract can use,
/// which includes the contracts code size /// which includes the contracts code size
#[arg(long = "stack-size", default_value = "32768")] #[arg(long = "stack-size")]
pub stack_size: u32, pub stack_size: Option<u32>,
} }
impl Arguments { impl Arguments {
@@ -330,6 +326,22 @@ impl Arguments {
if self.metadata_hash.is_some() { if self.metadata_hash.is_some() {
anyhow::bail!("Metadata hash mode must specified in standard JSON input settings."); anyhow::bail!("Metadata hash mode must specified in standard JSON input settings.");
} }
if self.heap_size.is_some() {
anyhow::bail!(
"Heap size must be specified in standard JSON input polkavm memory settings."
);
}
if self.stack_size.is_some() {
anyhow::bail!(
"Stack size must be specified in standard JSON input polkavm memory settings."
);
}
if self.emit_source_debug_info {
anyhow::bail!(
"Debug info must be requested in standard JSON input polkavm settings."
);
}
} }
Ok(()) Ok(())
@@ -5,7 +5,7 @@ pub mod arguments;
use std::io::Write; use std::io::Write;
use std::str::FromStr; use std::str::FromStr;
use revive_solidity::Process; use resolc::Process;
use self::arguments::Arguments; use self::arguments::Arguments;
@@ -36,7 +36,7 @@ fn main_inner() -> anyhow::Result<()> {
std::io::stdout(), std::io::stdout(),
"{} version {}", "{} version {}",
env!("CARGO_PKG_DESCRIPTION"), env!("CARGO_PKG_DESCRIPTION"),
revive_solidity::ResolcVersion::default().long resolc::ResolcVersion::default().long
)?; )?;
return Ok(()); return Ok(());
} }
@@ -45,20 +45,12 @@ fn main_inner() -> anyhow::Result<()> {
writeln!( writeln!(
std::io::stdout(), std::io::stdout(),
">={},<={}", ">={},<={}",
revive_solidity::SolcFirstSupportedVersion, resolc::SolcFirstSupportedVersion,
revive_solidity::SolcLastSupportedVersion, resolc::SolcLastSupportedVersion,
)?; )?;
return Ok(()); return Ok(());
} }
if arguments.license {
let license_mit = include_str!("../../../../LICENSE-MIT");
let license_apache = include_str!("../../../../LICENSE-APACHE");
writeln!(std::io::stdout(), "{}\n{}\n", license_mit, license_apache)?;
return Ok(());
}
#[cfg(feature = "parallel")] #[cfg(feature = "parallel")]
rayon::ThreadPoolBuilder::new() rayon::ThreadPoolBuilder::new()
.stack_size(RAYON_WORKER_STACK_SIZE) .stack_size(RAYON_WORKER_STACK_SIZE)
@@ -71,20 +63,20 @@ fn main_inner() -> anyhow::Result<()> {
let mut infile = std::fs::File::open(fname)?; let mut infile = std::fs::File::open(fname)?;
#[cfg(target_os = "emscripten")] #[cfg(target_os = "emscripten")]
{ {
return revive_solidity::WorkerProcess::run(Some(&mut infile)); return resolc::WorkerProcess::run(Some(&mut infile));
} }
#[cfg(not(target_os = "emscripten"))] #[cfg(not(target_os = "emscripten"))]
{ {
return revive_solidity::NativeProcess::run(Some(&mut infile)); return resolc::NativeProcess::run(Some(&mut infile));
} }
} }
#[cfg(target_os = "emscripten")] #[cfg(target_os = "emscripten")]
{ {
return revive_solidity::WorkerProcess::run(None); return resolc::WorkerProcess::run(None);
} }
#[cfg(not(target_os = "emscripten"))] #[cfg(not(target_os = "emscripten"))]
{ {
return revive_solidity::NativeProcess::run(None); return resolc::NativeProcess::run(None);
} }
} }
@@ -111,14 +103,16 @@ fn main_inner() -> anyhow::Result<()> {
let mut solc = { let mut solc = {
#[cfg(target_os = "emscripten")] #[cfg(target_os = "emscripten")]
{ {
revive_solidity::SoljsonCompiler resolc::SoljsonCompiler
} }
#[cfg(not(target_os = "emscripten"))] #[cfg(not(target_os = "emscripten"))]
{ {
revive_solidity::SolcCompiler::new(arguments.solc.unwrap_or_else(|| { resolc::SolcCompiler::new(
revive_solidity::SolcCompiler::DEFAULT_EXECUTABLE_NAME.to_owned() arguments
}))? .solc
.unwrap_or_else(|| resolc::SolcCompiler::DEFAULT_EXECUTABLE_NAME.to_owned()),
)?
} }
}; };
@@ -129,7 +123,7 @@ fn main_inner() -> anyhow::Result<()> {
let mut optimizer_settings = match arguments.optimization { let mut optimizer_settings = match arguments.optimization {
Some(mode) => revive_llvm_context::OptimizerSettings::try_from_cli(mode)?, Some(mode) => revive_llvm_context::OptimizerSettings::try_from_cli(mode)?,
None => revive_llvm_context::OptimizerSettings::cycles(), None => revive_llvm_context::OptimizerSettings::size(),
}; };
if arguments.fallback_to_optimizing_for_size { if arguments.fallback_to_optimizing_for_size {
optimizer_settings.enable_fallback_to_size(); optimizer_settings.enable_fallback_to_size();
@@ -148,13 +142,13 @@ fn main_inner() -> anyhow::Result<()> {
None => true, None => true,
}; };
let memory_config = revive_llvm_context::MemoryConfig { let memory_config = revive_solc_json_interface::SolcStandardJsonInputSettingsPolkaVMMemory::new(
heap_size: arguments.heap_size, arguments.heap_size,
stack_size: arguments.stack_size, arguments.stack_size,
}; );
let build = if arguments.yul { let build = if arguments.yul {
revive_solidity::yul( resolc::yul(
input_files.as_slice(), input_files.as_slice(),
&mut solc, &mut solc,
optimizer_settings, optimizer_settings,
@@ -164,7 +158,7 @@ fn main_inner() -> anyhow::Result<()> {
memory_config, memory_config,
) )
} else if arguments.llvm_ir { } else if arguments.llvm_ir {
revive_solidity::llvm_ir( resolc::llvm_ir(
input_files.as_slice(), input_files.as_slice(),
optimizer_settings, optimizer_settings,
include_metadata_hash, include_metadata_hash,
@@ -173,7 +167,7 @@ fn main_inner() -> anyhow::Result<()> {
memory_config, memory_config,
) )
} else if arguments.standard_json { } else if arguments.standard_json {
revive_solidity::standard_json( resolc::standard_json(
&mut solc, &mut solc,
arguments.detect_missing_libraries, arguments.detect_missing_libraries,
arguments.base_path, arguments.base_path,
@@ -181,11 +175,10 @@ fn main_inner() -> anyhow::Result<()> {
arguments.allow_paths, arguments.allow_paths,
debug_config, debug_config,
&arguments.llvm_arguments, &arguments.llvm_arguments,
memory_config,
)?; )?;
return Ok(()); return Ok(());
} else if let Some(format) = arguments.combined_json { } else if let Some(format) = arguments.combined_json {
revive_solidity::combined_json( resolc::combined_json(
format, format,
input_files.as_slice(), input_files.as_slice(),
arguments.libraries, arguments.libraries,
@@ -207,7 +200,7 @@ fn main_inner() -> anyhow::Result<()> {
)?; )?;
return Ok(()); return Ok(());
} else { } else {
revive_solidity::standard_output( resolc::standard_output(
input_files.as_slice(), input_files.as_slice(),
arguments.libraries, arguments.libraries,
&mut solc, &mut solc,
@@ -247,9 +240,7 @@ fn main_inner() -> anyhow::Result<()> {
writeln!( writeln!(
std::io::stdout(), std::io::stdout(),
"Contract `{}` assembly:\n\n{}", "Contract `{path}` assembly:\n\n{assembly_text}"
path,
assembly_text
)?; )?;
} }
if arguments.output_binary { if arguments.output_binary {
@@ -19,7 +19,7 @@ use self::version::Version;
pub const FIRST_SUPPORTED_VERSION: semver::Version = semver::Version::new(0, 8, 0); pub const FIRST_SUPPORTED_VERSION: semver::Version = semver::Version::new(0, 8, 0);
/// The last supported version of `solc`. /// The last supported version of `solc`.
pub const LAST_SUPPORTED_VERSION: semver::Version = semver::Version::new(0, 8, 29); pub const LAST_SUPPORTED_VERSION: semver::Version = semver::Version::new(0, 8, 30);
/// `--include-path` was introduced in solc `0.8.8` <https://github.com/ethereum/solidity/releases/tag/v0.8.8> /// `--include-path` was introduced in solc `0.8.8` <https://github.com/ethereum/solidity/releases/tag/v0.8.8>
pub const FIRST_INCLUDE_PATH_VERSION: semver::Version = semver::Version::new(0, 8, 8); pub const FIRST_INCLUDE_PATH_VERSION: semver::Version = semver::Version::new(0, 8, 8);
@@ -89,7 +89,7 @@ pub fn build_solidity_with_options(
sources.clone(), sources.clone(),
libraries.clone(), libraries.clone(),
remappings, remappings,
SolcStandardJsonInputSettingsSelection::new_required(), SolcStandardJsonInputSettingsSelection::new_required_for_tests(),
SolcStandardJsonInputSettingsOptimizer::new( SolcStandardJsonInputSettingsOptimizer::new(
solc_optimizer_enabled, solc_optimizer_enabled,
optimizer_settings.middle_end_as_string().chars().last(), optimizer_settings.middle_end_as_string().chars().last(),
@@ -98,6 +98,7 @@ pub fn build_solidity_with_options(
), ),
None, None,
None, None,
None,
)?; )?;
let mut output = solc.standard_json(input, None, vec![], None)?; let mut output = solc.standard_json(input, None, vec![], None)?;
@@ -153,7 +154,7 @@ pub fn build_solidity_with_options_evm(
sources.clone(), sources.clone(),
libraries.clone(), libraries.clone(),
remappings, remappings,
SolcStandardJsonInputSettingsSelection::new_required(), SolcStandardJsonInputSettingsSelection::new_required_for_tests(),
SolcStandardJsonInputSettingsOptimizer::new( SolcStandardJsonInputSettingsOptimizer::new(
solc_optimizer_enabled, solc_optimizer_enabled,
None, None,
@@ -162,6 +163,7 @@ pub fn build_solidity_with_options_evm(
), ),
None, None,
None, None,
None,
)?; )?;
let mut output = solc.standard_json(input, None, vec![], None)?; let mut output = solc.standard_json(input, None, vec![], None)?;
@@ -209,10 +211,11 @@ pub fn build_solidity_and_detect_missing_libraries(
sources.clone(), sources.clone(),
libraries.clone(), libraries.clone(),
None, None,
SolcStandardJsonInputSettingsSelection::new_required(), SolcStandardJsonInputSettingsSelection::new_required_for_tests(),
SolcStandardJsonInputSettingsOptimizer::new(true, None, &solc_version.default, false), SolcStandardJsonInputSettingsOptimizer::new(true, None, &solc_version.default, false),
None, None,
None, None,
None,
)?; )?;
let mut output = solc.standard_json(input, None, vec![], None)?; let mut output = solc.standard_json(input, None, vec![], None)?;
@@ -282,10 +285,11 @@ pub fn check_solidity_warning(
sources.clone(), sources.clone(),
libraries, libraries,
None, None,
SolcStandardJsonInputSettingsSelection::new_required(), SolcStandardJsonInputSettingsSelection::new_required_for_tests(),
SolcStandardJsonInputSettingsOptimizer::new(true, None, &solc_version.default, false), SolcStandardJsonInputSettingsOptimizer::new(true, None, &solc_version.default, false),
None, None,
suppressed_warnings, suppressed_warnings,
None,
)?; )?;
let output = solc.standard_json(input, None, vec![], None)?; let output = solc.standard_json(input, None, vec![], None)?;
@@ -357,7 +361,7 @@ fn compile_evm(
.expect("source should compile"); .expect("source should compile");
let object = &contracts let object = &contracts
.get(contract_name) .get(contract_name)
.unwrap_or_else(|| panic!("contract '{}' didn't produce bin-runtime", contract_name)); .unwrap_or_else(|| panic!("contract '{contract_name}' didn't produce bin-runtime"));
let code = if runtime { let code = if runtime {
object.1.object.as_str() object.1.object.as_str()
} else { } else {
@@ -0,0 +1,22 @@
object "Test" {
code {
function allocate(size) -> ptr {
ptr := mload(0x40)
if iszero(ptr) { ptr := 0x60 }
mstore(0x40, add(ptr, size))
}
let size := datasize("Test_deployed")
let offset := allocate(size)
datacopy(offset, dataoffset("Test_deployed"), size)
return(offset, size)
}
object "Test_deployed" {
code {
{
let test:=0x5
mstore(2,signextend(0x8,0x0))
mstore(8,lt(0xc,test))
}
return(0, 65536)
}}}
@@ -0,0 +1,53 @@
import * as path from 'path'
const outputDir = 'artifacts'
const binExtension = ':C.pvm'
const asmExtension = ':C.pvmasm'
const llvmExtension = '.ll'
const contractSolFilename = 'contract.sol'
const contractYulFilename = 'contract.yul'
const contractOptimizedLLVMFilename = contractSolFilename + '.C.optimized'
const contractUnoptimizedLLVMFilename = contractSolFilename + '.C.unoptimized'
const pathToOutputDir = path.join(__dirname, '..', outputDir)
const pathToContracts = path.join(__dirname, '..', 'src', 'contracts')
const pathToBasicYulContract = path.join(
pathToContracts,
'yul',
contractYulFilename
)
const pathToMemsetYulContract = path.join(
pathToContracts,
'yul',
'memset.yul'
)
const pathToBasicSolContract = path.join(
pathToContracts,
'solidity',
contractSolFilename
)
const pathToSolBinOutputFile = path.join(
pathToOutputDir,
contractSolFilename + binExtension
)
const pathToSolAsmOutputFile = path.join(
pathToOutputDir,
contractSolFilename + asmExtension
)
export const paths = {
outputDir: outputDir,
binExtension: binExtension,
asmExtension: asmExtension,
llvmExtension: llvmExtension,
contractSolFilename: contractSolFilename,
contractYulFilename: contractYulFilename,
contractOptimizedLLVMFilename: contractOptimizedLLVMFilename,
contractUnoptimizedLLVMFilename: contractUnoptimizedLLVMFilename,
pathToOutputDir: pathToOutputDir,
pathToContracts: pathToContracts,
pathToBasicSolContract: pathToBasicSolContract,
pathToBasicYulContract: pathToBasicYulContract,
pathToMemsetYulContract: pathToMemsetYulContract,
pathToSolBinOutputFile: pathToSolBinOutputFile,
pathToSolAsmOutputFile: pathToSolAsmOutputFile,
}
@@ -0,0 +1,51 @@
import * as shell from 'shelljs'
import * as fs from 'fs'
import { spawnSync } from 'child_process'
interface CommandResult {
output: string
exitCode: number
}
export const executeCommand = (
command: string,
stdin?: string
): CommandResult => {
if (stdin) {
const process = spawnSync(command, [], {
input: stdin,
shell: true,
encoding: 'utf8',
maxBuffer: 30 * 1024 * 1024,
})
return {
exitCode: process.status || 0,
output: (process.stdout || process.stderr || '').toString(),
}
}
const result = shell.exec(command, { silent: true, async: false })
return {
exitCode: result.code,
output: result.stdout || result.stderr || '',
}
}
export const isFolderExist = (folder: string): boolean => {
return shell.test('-d', folder)
}
export const isFileExist = (
pathToFileDir: string,
fileName: string,
fileExtension: string
): boolean => {
return shell.ls(pathToFileDir).stdout.includes(fileName + fileExtension)
}
export const isFileEmpty = (file: string): boolean => {
if (fs.existsSync(file)) {
return fs.readFileSync(file).length === 0
}
}
@@ -0,0 +1,44 @@
import { executeCommand } from '../src/helper'
import { paths } from '../src/entities'
//id1746
describe('Run with --asm by default', () => {
const command = `resolc ${paths.pathToBasicSolContract} --asm`
const result = executeCommand(command)
const commandInvalid = 'resolc --asm'
const resultInvalid = executeCommand(commandInvalid)
it('Valid command exit code = 0', () => {
expect(result.exitCode).toBe(0)
})
it('--asm output is presented', () => {
const expectedPatterns = [/(deploy)/i, /(call)/i, /(seal_return)/i]
for (const pattern of expectedPatterns) {
expect(result.output).toMatch(pattern)
}
})
it('solc exit code == resolc exit code', () => {
const command = `solc ${paths.pathToBasicSolContract} --asm`
const solcResult = executeCommand(command)
expect(solcResult.exitCode).toBe(result.exitCode)
})
it('run invalid: resolc --asm', () => {
expect(resultInvalid.output).toMatch(
/(No input sources specified|Compilation aborted)/i
)
})
it('Invalid command exit code = 1', () => {
expect(resultInvalid.exitCode).toBe(1)
})
it('Invalid solc exit code == Invalid resolc exit code', () => {
const command = 'solc --asm'
const solcResult = executeCommand(command)
expect(solcResult.exitCode).toBe(resultInvalid.exitCode)
})
})
@@ -0,0 +1,241 @@
import {
executeCommand,
isFolderExist,
isFileExist,
isFileEmpty,
} from '../src/helper'
import { paths } from '../src/entities'
import * as shell from 'shelljs'
import * as path from 'path'
//id1762
describe('Run resolc without any options', () => {
const command = 'resolc'
const result = executeCommand(command)
it('Info with help is presented', () => {
expect(result.output).toMatch(/(Usage: resolc)/i)
})
it('Exit code = 1', () => {
expect(result.exitCode).toBe(1)
})
it('solc exit code == resolc exit code', () => {
const command = 'solc'
const solcResult = executeCommand(command)
expect(solcResult.exitCode).toBe(result.exitCode)
})
})
//#1713
describe('Default run a command from the help', () => {
const command = `resolc ${paths.pathToBasicSolContract} --overwrite -O3 --bin --output-dir "${paths.pathToOutputDir}"` // potential issue on resolc with full path on Windows cmd
const result = executeCommand(command)
it('Compiler run successful', () => {
expect(result.output).toMatch(/(Compiler run successful.)/i)
})
it('Exit code = 0', () => {
expect(result.exitCode).toBe(0)
})
it('Output dir is created', () => {
expect(isFolderExist(paths.pathToOutputDir)).toBe(true)
})
xit('Output file is created', () => {
// a bug on windows
expect(
isFileExist(
paths.pathToOutputDir,
paths.contractSolFilename,
paths.binExtension
)
).toBe(true)
})
it('the output file is not empty', () => {
expect(isFileEmpty(paths.pathToSolBinOutputFile)).toBe(false)
})
it("No 'Error'/'Warning'/'Fail' in the output", () => {
expect(result.output).not.toMatch(/([Ee]rror|[Ww]arning|[Ff]ail)/i)
})
})
//#1818
describe('Default run a command from the help', () => {
const command = `resolc ${paths.pathToBasicSolContract} --overwrite -O3 --bin --asm --output-dir "${paths.pathToOutputDir}"` // potential issue on resolc with full path on Windows cmd
const result = executeCommand(command)
it('Compiler run successful', () => {
expect(result.output).toMatch(/(Compiler run successful.)/i)
})
it('Exit code = 0', () => {
expect(result.exitCode).toBe(0)
})
it('Output dir is created', () => {
expect(isFolderExist(paths.pathToOutputDir)).toBe(true)
})
xit('Output files are created', () => {
// a bug on windows
expect(
isFileExist(
paths.pathToOutputDir,
paths.contractSolFilename,
paths.binExtension
)
).toBe(true)
expect(
isFileExist(
paths.pathToOutputDir,
paths.contractSolFilename,
paths.asmExtension
)
).toBe(true)
})
it('the output files are not empty', () => {
expect(isFileEmpty(paths.pathToSolBinOutputFile)).toBe(false)
expect(isFileEmpty(paths.pathToSolAsmOutputFile)).toBe(false)
})
it("No 'Error'/'Warning'/'Fail' in the output", () => {
expect(result.output).not.toMatch(/([Ee]rror|[Ww]arning|[Ff]ail)/i)
})
})
describe('Run resolc with source debug information', () => {
const commands = [
`resolc -g ${paths.pathToBasicSolContract} --overwrite --bin --asm --output-dir "${paths.pathToOutputDir}"`,
`resolc --disable-solc-optimizer -g ${paths.pathToBasicSolContract} --overwrite --bin --asm --output-dir "${paths.pathToOutputDir}"`,
] // potential issue on resolc with full path on Windows cmd`;
for (var idx in commands) {
const command = commands[idx]
const result = executeCommand(command)
it('Compiler run successful', () => {
expect(result.output).toMatch(/(Compiler run successful.)/i)
})
it('Exit code = 0', () => {
expect(result.exitCode).toBe(0)
})
it('Output dir is created', () => {
expect(isFolderExist(paths.pathToOutputDir)).toBe(true)
})
it('Output files are created', () => {
// a bug on windows
expect(
isFileExist(
paths.pathToOutputDir,
paths.contractSolFilename,
paths.binExtension
)
).toBe(true)
expect(
isFileExist(
paths.pathToOutputDir,
paths.contractSolFilename,
paths.asmExtension
)
).toBe(true)
})
it('the output files are not empty', () => {
expect(isFileEmpty(paths.pathToSolBinOutputFile)).toBe(false)
expect(isFileEmpty(paths.pathToSolAsmOutputFile)).toBe(false)
})
it("No 'Error'/'Fail' in the output", () => {
expect(result.output).not.toMatch(/([Ee]rror|[Ff]ail)/i)
})
}
})
describe('Run resolc with source debug information, check LLVM debug-info', () => {
const commands = [
`resolc -g ${paths.pathToBasicSolContract} --overwrite --debug-output-dir="${paths.pathToOutputDir}"`,
`resolc -g --disable-solc-optimizer ${paths.pathToBasicSolContract} --overwrite --debug-output-dir="${paths.pathToOutputDir}"`,
] // potential issue on resolc with full path on Windows cmd`;
for (var idx in commands) {
const command = commands[idx]
const result = executeCommand(command)
it('Compiler run successful', () => {
expect(result.output).toMatch(/(Compiler run successful.)/i)
})
it('Exit code = 0', () => {
expect(result.exitCode).toBe(0)
})
it('Output dir is created', () => {
expect(isFolderExist(paths.pathToOutputDir)).toBe(true)
})
it('Output files are created', () => {
// a bug on windows
expect(
isFileExist(
paths.pathToOutputDir,
paths.contractOptimizedLLVMFilename,
paths.llvmExtension
)
).toBe(true)
expect(
isFileExist(
paths.pathToOutputDir,
paths.contractUnoptimizedLLVMFilename,
paths.llvmExtension
)
).toBe(true)
})
it('the output files are not empty', () => {
expect(isFileEmpty(paths.pathToSolBinOutputFile)).toBe(false)
expect(isFileEmpty(paths.pathToSolAsmOutputFile)).toBe(false)
})
it("No 'Error'/'Fail' in the output", () => {
expect(result.output).not.toMatch(/([Ee]rror|[Ff]ail)/i)
})
}
})
describe('Standard JSON compilation with path options', () => {
const contractsDir = path.join(shell.tempdir(), 'contracts-test')
const inputFile = path.join(__dirname, '..', 'src/contracts/compiled/1.json')
beforeAll(() => {
shell.mkdir('-p', contractsDir)
const input = JSON.parse(shell.cat(inputFile).toString())
Object.entries(input.sources).forEach(
([sourcePath, source]: [string, any]) => {
const filePath = path.join(contractsDir, sourcePath)
shell.mkdir('-p', path.dirname(filePath))
shell.ShellString(source.content).to(filePath)
}
)
})
afterAll(() => {
shell.rm('-rf', contractsDir)
})
describe('Output with all path options', () => {
let result: { exitCode: number; output: string }
beforeAll(() => {
const tempInputFile = path.join(contractsDir, 'temp-input.json')
shell.cp(inputFile, tempInputFile)
const inputContent = shell.cat(inputFile).toString()
const command = `resolc --standard-json --base-path "${contractsDir}" --include-path "${contractsDir}" --allow-paths "${contractsDir}"`
result = executeCommand(command, inputContent)
shell.rm(tempInputFile)
})
it('Compiler run successful without emiting warnings', () => {
const parsedResults = JSON.parse(result.output)
expect(
parsedResults.errors.filter(
(error: { type: string }) => error.type != 'Warning'
)
).toEqual([])
})
})
})
@@ -0,0 +1,18 @@
import { executeCommand } from '../src/helper'
import { paths } from '../src/entities'
describe('tests for the memset builtin to be present', () => {
// -O3 is required to reproduce.
const command = `resolc ${paths.pathToMemsetYulContract} --yul -O3`
const result = executeCommand(command)
it('Valid command exit code = 0', () => {
expect(result.exitCode).toBe(0)
})
it('--yul output is presented', () => {
expect(result.output).toMatch(/(Compiler run successful)/i)
expect(result.output).toMatch(/(No output requested)/i)
})
})
@@ -0,0 +1,39 @@
import { executeCommand } from '../src/helper'
import { paths } from '../src/entities'
//id1743
describe('Run with --yul by default', () => {
const command = `resolc ${paths.pathToBasicYulContract} --yul`
const result = executeCommand(command)
const commandInvalid = 'resolc --yul'
const resultInvalid = executeCommand(commandInvalid)
it('Valid command exit code = 0', () => {
expect(result.exitCode).toBe(0)
})
it('--yul output is presented', () => {
expect(result.output).toMatch(/(Compiler run successful)/i)
expect(result.output).toMatch(/(No output requested)/i)
})
xit('solc exit code == resolc exit code', () => {
// unknown solc issue for datatype of the contract
const command = `solc ${paths.pathToBasicSolContract} --yul`
const solcResult = executeCommand(command)
expect(solcResult.exitCode).toBe(result.exitCode)
})
it('run invalid: resolc --yul', () => {
expect(resultInvalid.output).toMatch(/(The input file is missing)/i)
})
it('Invalid command exit code = 1', () => {
expect(resultInvalid.exitCode).toBe(1)
})
it('Invalid solc exit code == Invalid resolc exit code', () => {
const command = 'solc --yul'
const solcResult = executeCommand(command)
expect(solcResult.exitCode).toBe(resultInvalid.exitCode)
})
})
@@ -0,0 +1,188 @@
import { executeCommand } from '../src/helper'
import { paths } from '../src/entities'
describe('Set of --combined-json tests', () => {
const zksolcCommand = 'zksolc'
const solcCommand = 'solc'
const json_args: string[] = [
`abi`,
`hashes`,
`metadata`,
`devdoc`,
`userdoc`,
`storage-layout`,
`ast`,
`asm`,
`bin`,
`bin-runtime`,
]
//id1742:I
describe(`Run ${zksolcCommand} with just --combined-json`, () => {
const args = [`--combined-json`]
const result = executeCommand(zksolcCommand, args)
it('Valid command exit code = 1', () => {
expect(result.exitCode).toBe(1)
})
it('--combined-json error is presented', () => {
expect(result.output).toMatch(/(requires a value but none was supplied)/i)
})
it('solc exit code == zksolc exit code', () => {
const solcResult = executeCommand(solcCommand, args)
expect(solcResult.exitCode).toBe(result.exitCode)
})
})
//id1742:II
describe(`Run ${zksolcCommand} with Sol contract and --combined-json`, () => {
const args = [`${paths.pathToBasicSolContract}`, `--combined-json`]
const result = executeCommand(zksolcCommand, args)
it('Valid command exit code = 1', () => {
expect(result.exitCode).toBe(1)
})
it('--combined-json error is presented', () => {
expect(result.output).toMatch(/(requires a value but none was supplied)/i)
})
it('solc exit code == zksolc exit code', () => {
const solcResult = executeCommand(solcCommand, args)
expect(solcResult.exitCode).toBe(result.exitCode)
})
})
//id1742:III
for (let i = 0; i < json_args.length; i++) {
describe(`Run ${zksolcCommand} with Sol, --combined-json and ARG: ${json_args[i]}`, () => {
const args = [
`${paths.pathToBasicSolContract}`,
`--combined-json`,
`${json_args[i]}`,
]
const result = executeCommand(zksolcCommand, args)
it('Valid command exit code = 0', () => {
expect(result.exitCode).toBe(0)
})
it('--combined-json error is presented', () => {
expect(result.output).toMatch(/(contracts)/i)
})
it('solc exit code == zksolc exit code', () => {
const solcResult = executeCommand(solcCommand, args)
expect(solcResult.exitCode).toBe(result.exitCode)
})
})
}
//id1829:I
for (let i = 0; i < json_args.length; i++) {
describe(`Run ${zksolcCommand} with Sol, --combined-json and wrong ARG: --${json_args[i]}`, () => {
const args = [
`${paths.pathToBasicSolContract}`,
`--combined-json`,
`--${json_args[i]}`,
]
const result = executeCommand(zksolcCommand, args)
it('Valid command exit code = 1', () => {
expect(result.exitCode).toBe(1)
})
it('--combined-json error is presented', () => {
expect(result.output).toMatch(/(Invalid option|error)/i)
})
it('solc exit code == zksolc exit code', () => {
const solcResult = executeCommand(solcCommand, args)
expect(solcResult.exitCode).toBe(result.exitCode)
})
})
}
//id1829:II
for (let i = 0; i < json_args.length; i++) {
describe(`Run ${zksolcCommand} with Sol, --combined-json and multiple ARG: ${json_args[i]} ${json_args[i]}`, () => {
const args = [
`${paths.pathToBasicSolContract}`,
`--combined-json`,
`${json_args[i]}`,
`${json_args[i]}`,
]
const result = executeCommand(zksolcCommand, args)
xit('Valid command exit code = 1', () => {
expect(result.exitCode).toBe(1)
})
it('--combined-json error is presented', () => {
expect(result.output).toMatch(
/(No such file or directory|cannot find the file specified)/i
) // Hopefully we should have more precise message here!
})
xit('solc exit code == zksolc exit code', () => {
const solcResult = executeCommand(solcCommand, args)
expect(solcResult.exitCode).toBe(result.exitCode)
})
})
}
//id1829:III
for (let i = 0; i < json_args.length; i++) {
describe(`Run ${zksolcCommand} with Sol, and multiple (--combined-json ${json_args[i]})`, () => {
const args = [
`${paths.pathToBasicSolContract}`,
`--combined-json`,
`${json_args[i]}`,
`--combined-json`,
`${json_args[i]}`,
]
const result = executeCommand(zksolcCommand, args)
it('Valid command exit code = 1', () => {
expect(result.exitCode).toBe(1)
})
it('--combined-json error is presented', () => {
expect(result.output).toMatch(/(cannot be used multiple times)/i)
})
it('solc exit code == zksolc exit code', () => {
const solcResult = executeCommand(solcCommand, args)
expect(solcResult.exitCode).toBe(result.exitCode)
})
})
}
//id1830
for (let i = 0; i < json_args.length; i++) {
describe(`Run ${zksolcCommand} with Yul, and --combined-json ${json_args[i]}`, () => {
const args = [
`${paths.pathToBasicYulContract}`,
`--combined-json`,
`${json_args[i]}`,
]
const result = executeCommand(zksolcCommand, args)
it('Valid command exit code = 1', () => {
expect(result.exitCode).toBe(1)
})
it('--combined-json error is presented', () => {
expect(result.output).toMatch(/(ParserError: Expected identifier)/i)
})
asd
it('solc exit code == zksolc exit code', () => {
const solcResult = executeCommand(solcCommand, args)
expect(solcResult.exitCode).toBe(result.exitCode)
})
})
}
})
@@ -121,10 +121,10 @@ fn optimizer() {
assert!( assert!(
size_when_optimized_for_cycles < size_when_unoptimized, size_when_optimized_for_cycles < size_when_unoptimized,
"Expected the cycles-optimized bytecode to be smaller than the unoptimized. Optimized: {}B, Unoptimized: {}B", size_when_optimized_for_cycles, size_when_unoptimized, "Expected the cycles-optimized bytecode to be smaller than the unoptimized. Optimized: {size_when_optimized_for_cycles}B, Unoptimized: {size_when_unoptimized}B",
); );
assert!( assert!(
size_when_optimized_for_size < size_when_unoptimized, size_when_optimized_for_size < size_when_unoptimized,
"Expected the size-optimized bytecode to be smaller than the unoptimized. Optimized: {}B, Unoptimized: {}B", size_when_optimized_for_size, size_when_unoptimized, "Expected the size-optimized bytecode to be smaller than the unoptimized. Optimized: {size_when_optimized_for_size}B, Unoptimized: {size_when_unoptimized}B",
); );
} }
+2 -2
View File
@@ -17,7 +17,7 @@ path = "src/main.rs"
[features] [features]
std = ["polkadot-sdk/std"] std = ["polkadot-sdk/std"]
default = ["solidity"] default = ["solidity"]
solidity = ["revive-solidity", "revive-differential", "revive-llvm-context"] solidity = ["resolc", "revive-differential", "revive-llvm-context"]
[dependencies] [dependencies]
env_logger = { workspace = true } env_logger = { workspace = true }
@@ -39,6 +39,6 @@ polkadot-sdk.features = [
"pallet-timestamp" "pallet-timestamp"
] ]
revive-solidity = { workspace = true, optional = true } resolc = { workspace = true, optional = true }
revive-differential = { workspace = true, optional = true } revive-differential = { workspace = true, optional = true }
revive-llvm-context = { workspace = true, optional = true } revive-llvm-context = { workspace = true, optional = true }
+3 -3
View File
@@ -44,7 +44,7 @@ pub use crate::specs::*;
mod runtime; mod runtime;
mod specs; mod specs;
#[cfg(not(feature = "revive-solidity"))] #[cfg(not(feature = "resolc"))]
pub(crate) const NO_SOLIDITY_FRONTEND: &str = pub(crate) const NO_SOLIDITY_FRONTEND: &str =
"revive-runner was built without the solidity frontend; please enable the 'solidity' feature!"; "revive-runner was built without the solidity frontend; please enable the 'solidity' feature!";
@@ -234,7 +234,7 @@ impl CallResult {
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub enum Code { pub enum Code {
#[cfg(feature = "revive-solidity")] #[cfg(feature = "resolc")]
/// Compile a single solidity source and use the blob of `contract` /// Compile a single solidity source and use the blob of `contract`
Solidity { Solidity {
path: Option<std::path::PathBuf>, path: Option<std::path::PathBuf>,
@@ -270,7 +270,7 @@ impl From<Code> for pallet_revive::Code {
let Ok(source_code) = std::fs::read_to_string(&path) else { let Ok(source_code) = std::fs::read_to_string(&path) else {
panic!("Failed to reead source code from {}", path.display()); panic!("Failed to reead source code from {}", path.display());
}; };
pallet_revive::Code::Upload(revive_solidity::test_utils::compile_blob_with_options( pallet_revive::Code::Upload(resolc::test_utils::compile_blob_with_options(
&contract, &contract,
&source_code, &source_code,
solc_optimizer.unwrap_or(true), solc_optimizer.unwrap_or(true),
+7 -1
View File
@@ -94,6 +94,12 @@ impl FindAuthor<<Runtime as frame_system::Config>::AccountId> for Runtime {
where where
I: 'a + IntoIterator<Item = (frame_support::ConsensusEngineId, &'a [u8])>, I: 'a + IntoIterator<Item = (frame_support::ConsensusEngineId, &'a [u8])>,
{ {
Some([0xff; 32].into()) Some(
[[0xff; 20].as_slice(), [0xee; 12].as_slice()]
.concat()
.as_slice()
.try_into()
.unwrap(),
)
} }
} }
+7 -7
View File
@@ -4,12 +4,12 @@ use serde::{Deserialize, Serialize};
use crate::*; use crate::*;
use alloy_primitives::keccak256; use alloy_primitives::keccak256;
#[cfg(feature = "revive-solidity")] #[cfg(feature = "resolc")]
use alloy_primitives::Address; use alloy_primitives::Address;
#[cfg(feature = "revive-solidity")] #[cfg(feature = "resolc")]
use resolc::test_utils::*;
#[cfg(feature = "resolc")]
use revive_differential::{Evm, EvmLog}; use revive_differential::{Evm, EvmLog};
#[cfg(feature = "revive-solidity")]
use revive_solidity::test_utils::*;
const SPEC_MARKER_BEGIN: &str = "/* runner.json"; const SPEC_MARKER_BEGIN: &str = "/* runner.json";
const SPEC_MARKER_END: &str = "*/"; const SPEC_MARKER_END: &str = "*/";
@@ -256,7 +256,7 @@ impl Specs {
}; };
match code { match code {
#[cfg(feature = "revive-solidity")] #[cfg(feature = "resolc")]
Code::Bytes(bytes) if bytes.is_empty() => { Code::Bytes(bytes) if bytes.is_empty() => {
let contract_source = match std::fs::read_to_string(contract_path) { let contract_source = match std::fs::read_to_string(contract_path) {
Err(err) => panic!("unable to read {contract_path}: {err}"), Err(err) => panic!("unable to read {contract_path}: {err}"),
@@ -264,9 +264,9 @@ impl Specs {
}; };
*bytes = compile_blob(contract_name, &contract_source) *bytes = compile_blob(contract_name, &contract_source)
} }
#[cfg(not(feature = "revive-solidity"))] #[cfg(not(feature = "resolc"))]
Code::Bytes(_) => panic!("{NO_SOLIDITY_FRONTEND}"), Code::Bytes(_) => panic!("{NO_SOLIDITY_FRONTEND}"),
#[cfg(feature = "revive-solidity")] #[cfg(feature = "resolc")]
Code::Solidity { path, .. } if path.is_none() => *path = Some(contract_path.into()), Code::Solidity { path, .. } if path.is_none() => *path = Some(contract_path.into()),
_ => continue, _ => continue,
} }
+2 -2
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "revive-runtime-api" name = "revive-runtime-api"
version.workspace = true version = "0.2.0"
license.workspace = true license.workspace = true
edition.workspace = true edition.workspace = true
repository.workspace = true repository.workspace = true
@@ -9,7 +9,7 @@ description = "Implements the low level runtime API bindings with pallet contrac
[dependencies] [dependencies]
anyhow = { workspace = true } anyhow = { workspace = true }
inkwell = { workspace = true, features = ["target-riscv", "no-libffi-linking", "llvm18-0"] } inkwell = { workspace = true, features = ["target-riscv", "no-libffi-linking", "llvm18-1"] }
revive-common = { workspace = true } revive-common = { workspace = true }
+2 -3
View File
@@ -37,12 +37,11 @@ fn compile(source_path: &str, bitcode_path: &str) {
source_path, source_path,
]) ])
.output() .output()
.unwrap_or_else(|error| panic!("failed to execute clang: {}", error)); .unwrap_or_else(|error| panic!("failed to execute clang: {error}"));
assert!( assert!(
output.status.success(), output.status.success(),
"failed to compile the PolkaVM C API: {:?}", "failed to compile the PolkaVM C API: {output:?}"
output
); );
} }
+7
View File
@@ -30,6 +30,13 @@ void * memmove(void *dst, const void *src, size_t n) {
return dst; return dst;
} }
void * memset(void *b, int c, size_t len) {
uint8_t *dest = b;
uint8_t val = (uint8_t)c;
while (len-- > 0) *dest++ = val;
return b;
}
// Imports // Imports
POLKAVM_IMPORT(void, address, uint32_t) POLKAVM_IMPORT(void, address, uint32_t)

Some files were not shown because too many files have changed in this diff Show More