Skip to content

Commit 6beeefe

Browse files
authored
Stabilize scripts (#107)
* Use only private RPC URLs * Improve opcode support detection * Add CLZ opcode * Avoid sending parallel requests * Format * Fetch data * Upgrade setup-bun action and use latest bun version Also add a step to print the bun and node versions to make it easier to debug if there are issues in the future. * Update lockfile * Set LC_ALL=C to in prepare-chain-data.sh * Trigger CI
1 parent 8031468 commit 6beeefe

23 files changed

Lines changed: 147 additions & 86 deletions

.github/workflows/ci.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ jobs:
1212
runs-on: ubuntu-latest
1313
steps:
1414
- uses: actions/checkout@v4
15-
- uses: oven-sh/setup-bun@v1
15+
- uses: oven-sh/setup-bun@v2
16+
with:
17+
bun-version: latest
1618

1719
- name: Install dependencies
1820
run: bun install
@@ -24,7 +26,9 @@ jobs:
2426
runs-on: ubuntu-latest
2527
steps:
2628
- uses: actions/checkout@v4
27-
- uses: oven-sh/setup-bun@v1
29+
- uses: oven-sh/setup-bun@v2
30+
with:
31+
bun-version: latest
2832

2933
- name: Install dependencies
3034
run: bun install

.github/workflows/fetch-data.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,14 @@ jobs:
1313
ALCHEMY_API_KEY: ${{ secrets.ALCHEMY_API_KEY }}
1414
steps:
1515
- uses: actions/checkout@v4
16-
- uses: oven-sh/setup-bun@v1
16+
- uses: oven-sh/setup-bun@v2
17+
with:
18+
bun-version: latest
19+
20+
- name: Print versions
21+
run: |
22+
bun --version
23+
bun -p process.version
1724
1825
- name: Install dependencies
1926
run: bun install

bun.lockb

4.62 KB
Binary file not shown.

script/archive/precompile-check.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
// they are precompiles or predeploys, and prints the result.
55
// Example usage:
66
// bun script/precompile-check.ts optimism
7-
import { http, type Address, createPublicClient, getAddress } from 'viem';
7+
import { http, type Address, createPublicClient, getAddress, type GetBytecodeReturnType } from 'viem';
88
import { type Chain, arbitrum, optimism } from 'viem/chains';
99

1010
type ChainConfig = {
@@ -74,8 +74,11 @@ async function main() {
7474
const transport = http(rpcUrl, { batch: true });
7575
const client = createPublicClient({ chain, transport });
7676

77-
const promises = addresses.map((address) => client.getBytecode({ address }));
78-
const codes = await Promise.all(promises);
77+
const codes: GetBytecodeReturnType[] = []
78+
for (const address of addresses) {
79+
const code = await client.getBytecode({ address });
80+
codes.push(code);
81+
}
7982
const kinds = codes.map((code) =>
8083
code === '0x' || code === '0xfe' ? 'precompile' : 'predeploy',
8184
);

script/checks/deployed-contracts.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@ const NO_CODE_HASH = keccak256('0x');
55
export async function checkDeployedContracts(
66
client: PublicClient,
77
): Promise<{ name: string; address: Address; codeHash: Hex; hasCode: boolean }[]> {
8-
const result = deployedContracts.map(async ({ name, address }) => {
8+
const result = [];
9+
for (const { name, address } of deployedContracts) {
910
const code = await client.getBytecode({ address });
1011
const codeHash = (code && keccak256(code)) || NO_CODE_HASH;
11-
return { name, address, codeHash, hasCode: codeHash !== NO_CODE_HASH };
12-
});
13-
return await Promise.all(result);
12+
result.push({ name, address, codeHash, hasCode: codeHash !== NO_CODE_HASH });
13+
}
14+
return result;
1415
}
1516

1617
export const deployedContracts: { name: string; address: Address }[] = [

script/checks/evm-stack-addresses.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ export async function checkEvmStackAddresses(
2626

2727
for (const stack of Object.keys(evmStackAddresses)) {
2828
const stackPredploys = evmStackAddresses[stack as EVMStack];
29-
const res = stackPredploys.map(async ({ name, address, kind }) => {
29+
result[stack as EVMStack] = [];
30+
for (const { name, address, kind } of stackPredploys) {
3031
const code = await client.getBytecode({ address });
3132
const codeHash = (code && keccak256(code)) || NO_CODE_HASH;
3233
const exists = evmStackAddressExists(stack as EVMStack, codeHash);
33-
return { name, address, kind, codeHash, exists };
34-
});
35-
result[stack as EVMStack] = await Promise.all(res);
34+
result[stack as EVMStack].push({ name, address, kind, codeHash, exists });
35+
}
3636
}
3737

3838
return result;

script/checks/opcodes.ts

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import { type Hex, type PublicClient, toHex } from 'viem';
22

33
type Opcode = number;
4-
type CallError = { details: string };
54

65
export async function checkOpcodes(
76
client: PublicClient,
87
): Promise<{ number: Hex; name: string; supported: boolean | string }[]> {
98
const opcodes = Array.from(Array(0xff + 1).keys());
10-
const supported = await Promise.all(opcodes.map(async (opcode) => checkOpcode(opcode, client)));
9+
const supported: Array<boolean | 'unknown'> = [];
10+
for (const opcode of opcodes) {
11+
supported.push(await checkOpcode(opcode, client));
12+
}
1113

1214
const result: { number: Hex; name: string; supported: boolean | string }[] = [];
1315
opcodes.forEach((opcode, index) => {
@@ -29,15 +31,34 @@ async function checkOpcode(opcode: Opcode, client: PublicClient): Promise<boolea
2931
try {
3032
await client.call({ data: toHex(opcode, { size: 1 }) });
3133
return true; // Call succeeded so opcode is supported.
32-
} catch (e: unknown) {
33-
const err = e as CallError;
34+
} catch (err: unknown) {
35+
if (
36+
typeof err !== 'object' ||
37+
err === null ||
38+
!('details' in err) ||
39+
typeof err.details !== 'string'
40+
) {
41+
throw err;
42+
}
3443
const details = err.details.toLowerCase();
3544
// TODO These might be specific to the node implementation, can this be more robust?
36-
if (opcode === 0xfe && details.includes('invalid opcode: invalid')) return true; // Designated invalid opcode.
37-
if (details.includes('stack underflow')) return true; // Implies opcode is supported.
45+
if (
46+
opcode === 0xfe &&
47+
(details.includes('invalid opcode: invalid') || details.includes('invalidfeopcode'))
48+
)
49+
return true; // Designated invalid opcode.
50+
if (
51+
details.includes('stack underflow') ||
52+
details.includes('stackunderflow') ||
53+
details.includes('stackoverflow')
54+
) {
55+
return true; // Implies opcode is supported.
56+
}
3857
if (details.includes('not defined')) return false;
3958
if (details.includes('not supported')) return false;
59+
if (details.includes('notactivated')) return false;
4060
if (details.includes('invalid opcode')) return false;
61+
if (details.includes('opcodenotfound')) return false;
4162

4263
console.log(`\n======== Opcode ${opcode} ========`);
4364
console.log('err.details:', err.details);
@@ -73,6 +94,7 @@ export const knownOpcodes: Record<Opcode, string> = {
7394
0x1b: 'SHL',
7495
0x1c: 'SHR',
7596
0x1d: 'SAR',
97+
0x1e: 'CLZ',
7698
0x20: 'KECCAK256',
7799
0x30: 'ADDRESS',
78100
0x31: 'BALANCE',

script/checks/precompiles.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,19 @@ import type { Address, Hex, PublicClient } from 'viem';
33
export async function checkPrecompiles(
44
client: PublicClient,
55
): Promise<{ name: string; address: Address; implemented: boolean }[]> {
6-
const result = precompiles.map(async ({ name, address, testCalldata, expectedResponse }) => {
6+
const result = [];
7+
8+
for (const { name, address, testCalldata, expectedResponse } of precompiles) {
79
try {
810
const res = await client.call({ to: address, data: testCalldata });
911
const implemented = res.data === expectedResponse;
10-
return { name, address, implemented };
12+
result.push({ name, address, implemented });
1113
} catch (e) {
1214
// If the call fails, the precompile is not implemented.
13-
return { name, address, implemented: false };
15+
result.push({ name, address, implemented: false });
1416
}
15-
});
16-
return await Promise.all(result);
17+
}
18+
return result;
1719
}
1820

1921
// By default a call to an EOA succeeds and returns no data, therefore we cannot simply use a

script/data/chain/1.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
{ "number": "0x1b", "name": "SHL", "supported": true },
7878
{ "number": "0x1c", "name": "SHR", "supported": true },
7979
{ "number": "0x1d", "name": "SAR", "supported": true },
80+
{ "number": "0x1e", "name": "CLZ", "supported": true },
8081
{ "number": "0x20", "name": "KECCAK256", "supported": true },
8182
{ "number": "0x30", "name": "ADDRESS", "supported": true },
8283
{ "number": "0x31", "name": "BALANCE", "supported": true },
@@ -299,7 +300,7 @@
299300
{
300301
"name": "secp256r1",
301302
"address": "0x0000000000000000000000000000000000000100",
302-
"implemented": false
303+
"implemented": true
303304
}
304305
],
305306
"evmStackAddresses": {

script/data/chain/10.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
{ "number": "0x1b", "name": "SHL", "supported": true },
6464
{ "number": "0x1c", "name": "SHR", "supported": true },
6565
{ "number": "0x1d", "name": "SAR", "supported": true },
66+
{ "number": "0x1e", "name": "CLZ", "supported": false },
6667
{ "number": "0x20", "name": "KECCAK256", "supported": true },
6768
{ "number": "0x30", "name": "ADDRESS", "supported": true },
6869
{ "number": "0x31", "name": "BALANCE", "supported": true },

0 commit comments

Comments
 (0)