mds1 / evm-diff

Diff EVM-compatible chains in a friendly format
https://evmdiff.com
MIT License
278 stars 27 forks source link

feat: define `opcode` type definition and add a few opcodes for each chain #12

Closed leovct closed 1 year ago

leovct commented 1 year ago

Description

First PR of the Opcode diffs issue (Resolves #6)

The Opcode type is quite similar to the one suggested in the issue. The only changes I made were to add two new fields. One called examples, which is quite similar to the example field of evm.codes and a playgroundLink field which redirects to the evm.codes/playground link of evm.codes. I also created a Variable type instead of the OpcodeParam type suggested in order to re-use this type in the context of gas computation.

For the gas computation, I chose to represent it as simple as possible with a name, a description, an algebraic expression and some variables. I took inspiration from this good old repository.

type Variable = {
  name: string;
  description: string;
  expression?: string;
}

type GasComputation = {
  name: string;
  description: string;
  expression: string;
  variables: Variable[];
}

type Memory = {
  before: string;
  after: string;
}

type Example = {
  input: (string | string[]);
  output?: string;
  memory?: Memory;
}

export type Opcode = {
  // same fields as those defined in the issue
  gasComputation?: GasComputation;
  examples: Example[];
  playgroundLink?: string;
}

To keep this PR simple, I only added a few opcodes such as add, blockhash, number and mstore. You might ask why these specific opcodes and that's a great question. First, the add opcode is simple and doesn't require a dynamic computation as opposed to the mstore opcode. Second, the number opcode has a different meaning on the mainnet chain and L2 chains such as arbitrum or optimism while the blockhash opcode is the same on all chains (just like add and mstore opcodes). I went with these opcodes because they cover different configuration cases which shows the possibilities of the type system I've used here.

Each opcode is defined in its own file to separate things clearly between each opcode. These opcodes live in group folders, matching the Ethereum execution-specs folder names. To better illustrate, here is the structure of the src/chains/mainnet/vm folder.

$ tree src/chains/mainnet/vm
src/chains/mainnet/vm
├── opcodes
│   ├── arithmetic
│   │   ├── add.ts
│   │   └── index.ts
│   ├── block
│   │   ├── blockhash.ts
│   │   ├── index.ts
│   │   └── number.ts
│   ├── index.ts
│   └── memory
│       ├── index.ts
│       └── mstore.ts
└── precompiles.ts

5 directories, 9 files

Some opcodes are exactly the same on L1 and L2 chains so to prevent us from copy-pasting opcode configurations, I defined the mainnet opcodes under src/chains/mainnet/vm/opcodes and reused these opcodes to define arbitrum and optimism opcodes. It means that we only need to write the configuration of the opcodes that are different such as number (as well as mainnet opcodes of course), e.g. src/chains/arbitrum/vm/opcodes/block/number.ts.

Test

$ pnpm fmt:check
> evm-diff@0.1.0 fmt:check /Users/leovct/Documents/opensource/evm-diff
> prettier --check .

Checking formatting...
All matched files use Prettier code style!

$ pnpm build
> evm-diff@0.1.0 build /Users/leovct/Documents/opensource/evm-diff
> next build

info  - Linting and checking validity of types  
info  - Creating an optimized production build  
info  - Compiled successfully
info  - Collecting page data  
info  - Generating static pages (4/4)
info  - Finalizing page optimization  

Route (pages)                              Size     First Load JS
┌ ○ /                                      558 B          99.7 kB
├   /_app                                  0 B            83.3 kB
├ ○ /404                                   182 B          83.4 kB
└ ○ /diff                                  21.1 kB         120 kB
+ First Load JS shared by all              88.1 kB
  ├ chunks/framework-cda45640750da278.js   45.2 kB
  ├ chunks/main-1e0620acb78b93fb.js        26.8 kB
  ├ chunks/pages/_app-47443414f282c22a.js  9.57 kB
  ├ chunks/webpack-52a83b85e685af40.js     1.61 kB
  └ css/a7410964315e4c62.css               4.88 kB

○  (Static)  automatically rendered as static HTML (uses no initial props)
vercel[bot] commented 1 year ago

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
evm-diff ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jun 14, 2023 2:14am
leovct commented 1 year ago

It should be in a pretty good state now @mds1 :)