{"id":21526898,"url":"https://github.com/lambdaclass/starknet-replay","last_synced_at":"2025-08-25T08:17:06.509Z","repository":{"id":242551368,"uuid":"809855417","full_name":"lambdaclass/starknet-replay","owner":"lambdaclass","description":"Provides a way of reading a real Starknet State, so you can re-execute an existing transaction in any of the Starknet networks in an easy way","archived":false,"fork":false,"pushed_at":"2025-08-22T23:32:22.000Z","size":126220,"stargazers_count":9,"open_issues_count":21,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-23T00:39:38.535Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lambdaclass.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-06-03T15:20:17.000Z","updated_at":"2025-08-22T23:32:26.000Z","dependencies_parsed_at":"2024-08-26T16:11:12.399Z","dependency_job_id":"2a8b496b-0061-4eae-9a45-c41fc778cd18","html_url":"https://github.com/lambdaclass/starknet-replay","commit_stats":null,"previous_names":["lambdaclass/starknet-replay"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/lambdaclass/starknet-replay","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lambdaclass%2Fstarknet-replay","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lambdaclass%2Fstarknet-replay/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lambdaclass%2Fstarknet-replay/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lambdaclass%2Fstarknet-replay/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lambdaclass","download_url":"https://codeload.github.com/lambdaclass/starknet-replay/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lambdaclass%2Fstarknet-replay/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272031413,"owners_count":24861687,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-25T02:00:12.092Z","response_time":1107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-24T01:47:03.279Z","updated_at":"2025-08-25T08:17:06.487Z","avatar_url":"https://github.com/lambdaclass.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# starknet-replay\nProvides a way of reading a real Starknet State, so you can re-execute an existing transaction in any of the Starknet networks in an easy way\n\n## Getting Started\n\n### Prerequisites\n\n- Linux or macOS (aarch64 included) only for now\n- LLVM 19 with MLIR\n- Rust 1.78.0 or later, since cairo-native makes use of the u128 abi change.\n- Git\n\n### Setup\n\nRun the following make target to install dependencies:\n```bash\nmake deps\n```\nIt will automatically install LLVM 19 with MLIR on macos, if you are using linux you must do it manually. On debian, you can use `apt.llvm.org`, or build it from source.\n\nThis project is integrated with Cairo Native, see [Cairo Native Setup](#cairo-native-setup) to set it up correctly\n\nSome environment variable are needed, you can automatically set them by sourcing `env.sh`. If the script doesn't adjust to your specific environment you can `cp` it into `.env` or `.envrc` and modify it.\n```bash\n# Cairo Native\nexport LLVM_SYS_191_PREFIX=/path/to/llvm-19\nexport MLIR_SYS_190_PREFIX=/path/to/llvm-19\nexport TABLEGEN_190_PREFIX=/path/to/llvm-19\n# RPC\nexport RPC_ENDPOINT_MAINNET=rpc.endpoint.mainnet.com\nexport RPC_ENDPOINT_TESTNET=rpc.endpoint.testnet.com\n```\n\nOn macos, you may also need to set the following to avoid linking errors:\n\n```bash\nexport LIBRARY_PATH=/opt/homebrew/lib\n```\n\nOnce you have installed dependencies and set the needed environment variables, you can build the project and run the tests:\n```bash\nmake build\nmake test\n```\n\n### Cairo Native Setup\n\nStarknet Replay is currenlty integrated with [Cairo Native](https://github.com/lambdaclass/cairo_native), which makes the execution of sierra programs possible through native machine code. To use it, the following needs to be setup:\n\n- On mac with brew, running `make deps` should have installed LLVM 19 with MLIR, otherwise, you must install it manually. On Debian, you can use `apt.llvm.org`, or build it from source.\n\n- The `LLVM_SYS_191_PREFIX`, `MLIR_SYS_190_PREFIX` and `TABLEGEN_190_PREFIX` environment variable needs to point to said installation. In macOS, run:\n  ```\n  export LLVM_SYS_190_PREFIX=/opt/homebrew/opt/llvm@19\n  export MLIR_SYS_191_PREFIX=/opt/homebrew/opt/llvm@19\n  export TABLEGEN_190_PREFIX=/opt/homebrew/opt/llvm@19\n  ```\n  and you're set.\n\nAfterwards, compiling with the feature flag `cairo-native` will enable native execution. You can check out some example test code that uses it under `tests/cairo_native.rs`.\n\n#### Using ahead of time compilation with Native.\n\n## replay\nYou can use the replay crate to execute transactions or blocks via the CLI. For example:\n\n```bash\n* cargo run tx 0x04ba569a40a866fd1cbb2f3d3ba37ef68fb91267a4931a377d6acc6e5a854f9a mainnet 648461\n* cargo run block mainnet 648655\n* cargo run block-range 90000 90002 mainnet\n* cargo run block-txs mainnet 633538 0x021c594980fc2503b2e62a1bb9ce811e7ae22c1478fb0602146745edc9d03bb6 0x13e148692edfbbb4de5d983c6875780e2397e34a432a7355bf2172435ecec0e\n```\n\n\u003e [!IMPORTANT]\n\u003e Compiled contracts are cached to disk at `./cache/native/` directory. This saves time when reexecuting transactions, but can also cause errors if you try to run a contract that was compiled with a different Cairo Native version.\n\u003e\n\u003e Make sure to remove the directory every time you update the Cairo Native version. Running `make clean` will automatically remove it.\n\n### RPC Timeout\nThe RPC time out is handled in two different ways:\n\n- RPC request timeout (in seconds): How many seconds to wait before generating a timeout. By default, the RPC timeout is set to 90 seconds. However, using the env var `RPC_TIMEOUT` this value can be customized.\n- RPC request retry: How many times the request is re-sent before failing due to timeout. By default, every RPC request is retried 10 times. However, this limit can be customized by setting the `RPC_RETRY_LIMIT` env var.\n\nBy setting both env vars, if any RPC request fails with a timeout, starknet-replay will retry sending the request with a limit of `RPC_RETRY_LIMIT` times awaiting `RPC_TIMEOUT` seconds for the response before generating another timeout.\n\nAn exponential-backoff algorithm distributes the retries in time, reducing the amount of simultaneous RPC requests to avoid new timeouts. If the limit of retries is reached, a new request timeout will cease the retrail process and return an timeout error.\n\n### Benchmarks\n\nTo run benchmarks with the replay crate, you can use either `bench-block-range` or `bench-tx` commands. These make sure to cache all needed information (including cairo native compilation) before the actual execution. To use it you must compile the binary under the benchmark flag.\n\n```bash\n* cargo run --features benchmark bench-tx 0x04ba569a40a866fd1cbb2f3d3ba37ef68fb91267a4931a377d6acc6e5a854f9a mainnet 648461 1\n* cargo run --features benchmark bench-block-range 90000 90002 mainnet 1\n```\n\nThese commands are like `tx` and `block-range` commands, but with the number of runs to execute as their last argument.\n\n### Logging\n\nThis projects uses tracing with env-filter, so logging can be modified by the RUST_LOG environment variable. By default, only info events from the replay crate are shown.\n\nAs an example, to show only error messages from the replay crate, run:\n```bash\nRUST_LOG=replay=error cargo run block mainnet 648461\n```\n\n### Comparing with VM\n\nTo compare Native execution with the VM, you can use the `state_dump` feature. It will save to disk the execution info and state diff of every contract executed.\n- If executing Native, the dumps will be saved at: `state_dumps/native/block{block_number}/{tx_hash}.json`\n- If paired with `only_cairo_vm` feature, the dumps will be saved at: `state_dumps/vm/block{block_number}/{tx_hash}.json`\n\nTo compare the outputs, you can use the following scripts. Some of them required `delta` (modern diff).\n- `cmp_state_dumps.py`. Prints which transactions match with the VM and which differ.\n   ```bash\n   \u003e python3 ./scripts/cmp_state_dumps.py\n   Starting comparison with 16 workers\n   DIFF 1478358 0xde8db1dc28c7ab48192d9aad1d5c8b08e732738f12b9945f591caa48e4dfa0\n   Finished comparison\n\n   MATCH 9\n   DIFF 1\n   ```\n- `delta_state_dumps.sh`. It opens delta to review the differences between VM and Native with each transaction.\n   ```bash\n   \u003e ./scripts/delta_state_dumps.sh\n   ```\n\n### Replaying isolated calls\n\nThe replay crate supports executing isolated calls inside of a transaction, although it probably won't work in every scenario.\n\nFirst, obtain the full state dump of a transaction:\n\n```bash\ncargo run --features state_dump -- tx \\\n   0x01368e23fc6ba5eaf064b9e64f5cddda0c6d565b6f64cb8f036e0d1928a99c79 mainnet 1000000\n```\n\nThen, extract the desired call (by its call index). In this case, I will try to re-execute starting from the third call (that is, with index 2).\n\n```bash\n./scripts/extract_call.py \\\n   state_dumps/native/block1000000/0x01368e23fc6ba5eaf064b9e64f5cddda0c6d565b6f64cb8f036e0d1928a99c79.json \\\n   2 \u003e call.json \n```\n\nFinally, re-execute it with the `call` command.\n\n```bash\ncargo run -- call call.json \\\n   0x01368e23fc6ba5eaf064b9e64f5cddda0c6d565b6f64cb8f036e0d1928a99c79 1000000 mainnet\n```\n\nThe `state_dump` feature can be used to save the execution result to either\n- `call_state_dumps/native/{tx_hash}.json`\n- `call_state_dumps/vm/{tx_hash}.json`\n\n### Benchmarking\n\nFirst, build the benchmarking binaries.\n\n```bash\nmake deps-bench\n```\n\nThen, you can benchmark a single transaction by running:\n```bash\n./scripts/benchmark_tx.sh \u003ctx\u003e \u003cnet\u003e \u003cblock\u003e \u003claps\u003e\n```\n\nIf you want to benchmark a full block, you could run:\n```bash\n./scripts/benchmark_block.sh \u003cblock-start\u003e \u003cblock-end\u003e \u003cnet\u003e \u003claps\u003e\n```\n\nIf you just want to benchmarks a few different sample transactions, run:\n```bash\n./scripts/benchmark_txs.sh\n```\n\nThis generates the following files in the `bench_data` directory:\n- `{native,vm}-data-*.json` - execution time of each contract call.\n- `{native,vm}-logs-*.json` - stdout from running the benchmark.\n\nAt the end of the run, you can generate a report by executing:\n\n``` bash\npython plotting/plot_execution_time.py native-data vm-data --output-dir \u003coutput-dir\u003e --no-display\n```\n\nThe report will be generated to `\u003coutput-dir\u003e/report.html`\n\n### Benchmarking Compilation\n\nYou can benchmark the compilation of a block range by running:\n```bash\n./scripts/benchmark_compilation.sh \u003cblock-start\u003e \u003cblock-end\u003e \u003cnet\u003e\n```\nThis will save compilation data to `./bench_data/compilation-\u003cblock-start\u003e-\u003cblock-end\u003e-\u003cnet\u003e.json`.\n\nAt the end of the run, you can generate a report by running:\n``` bash\npython plotting/plot_compilation_stats.py \u003ccompilation-data\u003e --output-dir \u003coutput-dir\u003e --no-display\n```\n\nThe report will be generated to `\u003coutput-dir\u003e/report.html`\n\n## Block Composition\nYou can check the average of txs, swaps, transfers (the last two in %) inside an average block, separeted by the day of execution. The results\nwill be saved in a json file inside the floder `block_composition` as a vector of block execution where each of the is entrypoint call tree.\n\nTo generate the need information run this command:\n`cargo run --release -F block-composition block-compose \u003cblock_start\u003e \u003cblock_end\u003e \u003cchain\u003e`\n\n## Libfunc Profiling\nYou can gather information about each libfunc execution in a transaction. To do so, run this command:\n`cargo run --release -F with-libfunc-profiling block-range \u003cblock_start\u003e \u003cblock_end\u003e \u003cchain\u003e`\n\nThis will create a `libfunc_profiles/block\u003cnumber\u003e/\u003ctx_hash\u003e.json` for every transaction executed, containing a list of entrypoints executed. Every entrypoint of that list contains a `profile_summary`, which contains information about the execution of every libfunc. An example of a profile would be:\n\n```json\n{\n   \"block_number\": 641561,\n   \"tx\": \"0x2e0abd9a260095622f71ff8869aaee0267af1199be78ad5ad91a3c83df0ad08\",\n   \"entrypoints\": [\n      {\n         \"class_hash\": \"0x36078334509b514626504edc9fb252328d1a240e4e948bef8d0c08dff45927f\",\n         \"selector\": \"0x162da33a4585851fe8d3af3c2a9c60b557814e221e0d4f30ff0b2189d9c7775\",\n         \"profile_summary\": [\n            {\n               \"libfunc_name\": \"struct_construct\",\n               \"samples\": 1,\n               \"total_time\": 1,\n               \"average_time\": 1.0,\n               \"std_deviation\": 0.0,\n               \"quartiles\": [\n                  1,\n                  1,\n                  1,\n                  1,\n                  1\n               ]\n            },\n            ...\n         ]\n      },\n      ...\n   ]\n}\n```\n\n## Plotting\n\nIn the `plotting` directory, you can find python scripts to plot relevant information.\n\nTo run them, you must first execute the benchmarks to obtain both the execution data and the execution logs.\n\n- `python ./plotting/plot_execution_time.py native-data vm-data`: Plots the benchmark data of Native and VM.\n- `python ./plotting/plot_compilation_logs.py native-logs`: Plots the compilation logs for Native and VM.\n- `python ./plotting/plot_compilation_stats.py *.json`: Plots the compilation stats for Native.\n- `python ./plotting/plot_block_composition.py native-logs`: Average of txs, swaps, transfers inside an average block, separeted by the day of execution.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flambdaclass%2Fstarknet-replay","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flambdaclass%2Fstarknet-replay","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flambdaclass%2Fstarknet-replay/lists"}