argotorg / argotorg/solidity

Emscripten binaries in solc npm package and in solc-bin are not identical

Open
#14,818 0 comments 0 reactions 0 assignees View on GitHub
bug :bug: build system :building_construction: medium effort medium impact solcbin solcjs
Dominant language
C++
Stars
25.7k
Forks
6.2k
Avg merge
1d 11h
Merged PRs (30d)
21

Description

The `soljson` binary that we include in the [`solc` npm package](https://www.npmjs.com/package/solc) differs from the one we include in the github releases and distribute in solc-bin.

This makes it hard to verify the binary, since the checksum won't match the ones we publish.

This seems to be caused by some automatic formatter that runs as a part of the TypeScript build process. This should be disabled so that the binary is published exactly as is.

After we fix it we should also add a CI check to compare the binary included in the package against solc-bin.

## Environment

- Compiler version: noticed around 0.8.23, but earlier versions are affected too.

## Steps to Reproduce

Download the binaries to compare:
```
wget https://registry.npmjs.org/solc/-/solc-0.8.24.tgz
wget https://binaries.soliditylang.org/emscripten-wasm32/solc-emscripten-wasm32-v0.8.24+commit.e11b9ed9.js
tar --extract --file solc-0.8.24.tgz package/soljson.js
```

The base64-encoded payload inside both files is exactly the same:
```
diff --unified \
<(sed -n 's|^"\(.*\)",$|\1|p' solc-emscripten-wasm32-v0.8.24+commit.e11b9ed9.js | fold --width 120) \
<(sed -n 's|^})("\(.*\)", 21944772);$|\1|p' package/soljson.js | fold --width 120)
```

The JS differs, possibly only in how it is formatted formatting:
```
diff --unified \
<(sed -e 's|^"\(.*\)",$||' solc-emscripten-wasm32-v0.8.24+commit.e11b9ed9.js | head -n 25) \
<(sed -e 's|^})("\(.*\)", 21944772);$||' package/soljson.js | head -n 25)
```

```diff
@@ -1,25 +1,25 @@
-var Module = Module || {}; Module["wasmBinary"] = (function(source, uncompressedSize) {function base64DecToArr (sBase64) {
-function b64ToUint6 (nChr) {
-
- return nChr > 64 && nChr < 91 ?
- nChr - 65
- : nChr > 96 && nChr < 123 ?
- nChr - 71
- : nChr > 47 && nChr < 58 ?
- nChr + 4
- : nChr === 43 ?
- 62
- : nChr === 47 ?
- 63
- :
- 0;
-
-}
-
- var
- nInLen = sBase64.length,
- nOutLen = nInLen * 3 + 1 >> 2, taBytes = new Uint8Array(nOutLen);
-
- for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) {
- nMod4 = nInIdx & 3;
- nUint24 |= b64ToUint6(sBase64.charCodeAt(nInIdx)) << 6 * (3 - nMod4);
+var Module = Module || {};
+Module["wasmBinary"] = (function (source, uncompressedSize) {
+ function base64DecToArr(sBase64) {
+ function b64ToUint6(nChr) {
+ return nChr > 64 && nChr < 91 ?
+ nChr - 65
+ : nChr > 96 && nChr < 123 ?
+ nChr - 71
+ : nChr > 47 && nChr < 58 ?
+ nChr + 4
+ : nChr === 43 ?
+ 62
+ : nChr === 47 ?
+ 63
+ :
+ 0;
+ }
+ var nInLen = sBase64.length, nOutLen = nInLen * 3 + 1 >> 2, taBytes = new Uint8Array(nOutLen);
+ for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) {
+ nMod4 = nInIdx & 3;
+ nUint24 |= b64ToUint6(sBase64.charCodeAt(nInIdx)) << 6 * (3 - nMod4);
+ if (nMod4 === 3 || nInLen - nInIdx === 1) {
+ for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) {
+ taBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255;
+ }
```

Contributor guide

Open the contributing guide

Research direction

Start by tracing the TypeScript build process that produces package/soljson.js, then compare it with the corresponding solc-bin Emscripten binary using the reproduction commands in the issue. The formatter should no longer alter the JavaScript wrapper, and CI should verify that the package binary matches solc-bin byte-for-byte.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, typescript, wasm
Domain
build-system, ci-cd, release
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.