diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index fe4b38dae..299b5f007 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -15,6 +15,7 @@ - [ ] No spelling errors - `./scripts/check_spelling.sh` - [ ] Performed code self-review - [ ] Rebased to the latest commit of the target branch (or merged it into my branch) + - Once you make the PR reviewable, please prefer merging over rebasing - [ ] Updated the docs if needed - `./website/README.md` - [ ] Linked the [issues](https://github.com/0xSpaceShard/starknet-devnet-rs/issues) resolvable by this PR - [linking info](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword) -- [ ] Updated the tests if needed; all passing - [execution info](https://github.com/0xSpaceShard/starknet-devnet-rs/?tab=readme-ov-file#test-execution) +- [ ] Updated the tests if needed; all passing - [execution info](https://github.com/0xSpaceShard/starknet-devnet-rs/blob/main/.github/CONTRIBUTING.md#test-execution) diff --git a/Cargo.lock b/Cargo.lock index 668409f19..f47aa5cb5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5577,7 +5577,7 @@ dependencies = [ [[package]] name = "starknet-devnet" -version = "0.1.1" +version = "0.1.2" dependencies = [ "anyhow", "async-trait", @@ -5609,7 +5609,7 @@ dependencies = [ [[package]] name = "starknet-devnet-core" -version = "0.1.1" +version = "0.1.2" dependencies = [ "blockifier", "cairo-lang-starknet-classes", @@ -5638,7 +5638,7 @@ dependencies = [ [[package]] name = "starknet-devnet-server" -version = "0.1.1" +version = "0.1.2" dependencies = [ "anyhow", "async-trait", @@ -5663,7 +5663,7 @@ dependencies = [ [[package]] name = "starknet-devnet-types" -version = "0.1.1" +version = "0.1.2" dependencies = [ "base64 0.22.1", "blockifier", diff --git a/Cargo.toml b/Cargo.toml index 4f9b946b3..689c73b17 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -93,9 +93,9 @@ cairo-lang-syntax = "=2.6.0" cairo-lang-utils = "=2.6.0" # Inner dependencies -starknet-types = { version = "0.1.1", path = "crates/starknet-devnet-types", package = "starknet-devnet-types" } -starknet-core = { version = "0.1.1", path = "crates/starknet-devnet-core", package = "starknet-devnet-core" } -server = { version = "0.1.1", path = "crates/starknet-devnet-server", package = "starknet-devnet-server" } +starknet-types = { version = "0.1.2", path = "crates/starknet-devnet-types", package = "starknet-devnet-types" } +starknet-core = { version = "0.1.2", path = "crates/starknet-devnet-core", package = "starknet-devnet-core" } +server = { version = "0.1.2", path = "crates/starknet-devnet-server", package = "starknet-devnet-server" } # Dependabot alerts zerocopy = "0.7.31" diff --git a/crates/starknet-devnet-core/Cargo.toml b/crates/starknet-devnet-core/Cargo.toml index f8972a09e..9463c1cb7 100644 --- a/crates/starknet-devnet-core/Cargo.toml +++ b/crates/starknet-devnet-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "starknet-devnet-core" -version = "0.1.1" +version = "0.1.2" edition.workspace = true repository.workspace = true license-file.workspace = true diff --git a/crates/starknet-devnet-server/Cargo.toml b/crates/starknet-devnet-server/Cargo.toml index ce1c73e7e..a307f8de7 100644 --- a/crates/starknet-devnet-server/Cargo.toml +++ b/crates/starknet-devnet-server/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "starknet-devnet-server" -version = "0.1.1" +version = "0.1.2" edition = "2021" repository.workspace = true license-file.workspace = true diff --git a/crates/starknet-devnet-types/Cargo.toml b/crates/starknet-devnet-types/Cargo.toml index 2a7647e0f..1618c7036 100644 --- a/crates/starknet-devnet-types/Cargo.toml +++ b/crates/starknet-devnet-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "starknet-devnet-types" -version = "0.1.1" +version = "0.1.2" edition = "2021" description = "Starknet types for the devnet" repository.workspace = true diff --git a/crates/starknet-devnet/Cargo.toml b/crates/starknet-devnet/Cargo.toml index f8764dcce..46b09976a 100644 --- a/crates/starknet-devnet/Cargo.toml +++ b/crates/starknet-devnet/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "starknet-devnet" -version = "0.1.1" +version = "0.1.2" edition = "2021" repository.workspace = true license-file.workspace = true diff --git a/website/docs/predeployed.md b/website/docs/predeployed.md index 4a390e752..6f3c143d9 100644 --- a/website/docs/predeployed.md +++ b/website/docs/predeployed.md @@ -24,8 +24,23 @@ If you want to deploy an instance of an account contract class not predeclared o ## How to get predeployment info? -The predeployment information is logged on Devnet startup. Predeployed accounts can be retrieved in JSON format by sending a `GET` request to `/predeployed_accounts` of your Devnet or `JSON-RPC` request with method name `devnet_getPredeployedAccounts`. With additional query string `with_balance=true` WEI and FRI balances at the pending state will be provided. +The information on predeployed contracts is logged on Devnet startup. Predeployed accounts can be retrieved in JSON format by sending a `GET` request to `/predeployed_accounts`. With the additional query parameter `with_balance=true`, WEI and FRI balances at the pending state will be provided: ``` -GET /predeployed_accounts?with_balance=true +GET /predeployed_accounts?[with_balance=true] +``` + +Alternatively, send a JSON-RPC request: + +``` +JSON-RPC +{ + "jsonrpc": "2.0", + "id": "1", + "method": "devnet_getPredeployedAccounts", + "params": { + // optional; defaults to false + "with_balance": true | false + } +} ``` diff --git a/website/versioned_docs/version-0.1.2/account-impersonation.md b/website/versioned_docs/version-0.1.2/account-impersonation.md new file mode 100644 index 000000000..ff295925d --- /dev/null +++ b/website/versioned_docs/version-0.1.2/account-impersonation.md @@ -0,0 +1,85 @@ +# Account impersonation + +:::info + +This page is about account impersonation. To read about account class selection and deployment, click [here](./predeployed). + +::: + +## Introduction + +Devnet allows you to use impersonated account from mainnet/testnet. This means that a transaction sent from an impersonated account will not fail with an invalid signature error. In the general case, a transaction sent with an account that is not in the local state fails with the aforementioned error. For impersonation to work, Devnet needs to be run in [forking mode](./forking.md). + +:::warning Caveat + +- Only `INVOKE` and `DECLARE` transactions are supported. `DEPLOY_ACCOUNT` transaction is not supported, but you can create an `INVOKE` transaction to UDC. +- Overall fee, for transactions sent with an impersonated account, will be lower compared to normal transactions. The reason is that validation part is skipped. +- The most common way of sending a transaction is via starknet-rs/starknet.js or starkli. Trying to send with an account that **does not** exist even in the origin network will return an error: + - In transaction construction, if account nonce is not hardcoded, Devnet is queried and returns `ContractNotFound`. + - Otherwise the nonce fetching part is skipped and `InsufficientAccountBalance` is returned. + +::: + +## Disabling impersonation + +Users can disable account impersonation by starting Devnet with CLI flag `--disable-account-impersonation` or by setting environment variable `DISABLE_ACCOUNT_IMPERSONATION`. Every subsequent JSON-RPC impersonation request will return an error. This feature can be used in CTFs to prevent participants from easily solving the task. + +## API + +Account impersonation follows JSON-RPC method specification. Each method returns an empty response: + +### devnet_impersonateAccount + +Impersonates a specific account address nonexistent in the local state. + +```js +{ + "jsonrpc": "2.0", + "id": "1", + "method": "devnet_impersonateAccount", + "params": { + "account_address": "0x49D36570D4E46F48E99674BD3FCC84644DDD6B96F7C741B1562B82F9E004DC7" + } +} +``` + +### devnet_stopImpersonateAccount + +Stops the impersonation of an account previously marked for impersonation. + +```js +{ + "jsonrpc": "2.0", + "id": "1", + "method": "devnet_stopImpersonateAccount", + "params": { + "account_address": "0x49D36570D4E46F48E99674BD3FCC84644DDD6B96F7C741B1562B82F9E004DC7" + } +} +``` + +### devnet_autoImpersonate + +Enables automatic account impersonation. Every account that does not exist in the local state will be impersonated. + +```js +{ + "jsonrpc": "2.0", + "id": "1", + "method": "devnet_autoImpersonate", + "params": {} +} +``` + +### devnet_stopAutoImpersonate + +Stops the effect of [automatic impersonation](#devnet_autoimpersonate). + +```js +{ + "jsonrpc": "2.0", + "id": "1", + "method": "devnet_stopAutoImpersonate", + "params": {} +} +``` diff --git a/website/versioned_docs/version-0.1.2/api.md b/website/versioned_docs/version-0.1.2/api.md new file mode 100644 index 000000000..be8d48e74 --- /dev/null +++ b/website/versioned_docs/version-0.1.2/api.md @@ -0,0 +1,53 @@ +# API + +## JSON-RPC API + +Both Starknet's and Devnet's JSON-RPC API are reachable at `/rpc` and `/`. E.g. if spawning Devnet with default settings, these URLs are functionally equivalent: `http://127.0.0.1:5050/rpc` and `http://127.0.0.1:5050/`. The difference between these two groups of methods is their prefix: `starknet_` (e.g. `starknet_getNonce`) and `devnet_` (e.g. `devnet_mint`). + +### Starknet API + +Unlike Pythonic Devnet, which also supported Starknet's gateway and feeder gateway API, Devnet in Rust supports [Starknet's JSON-RPC API](https://github.com/starkware-libs/starknet-specs/tree/master/api). Since JSON-RPC v0.6.0, to find out which JSON-RPC version is supported by which Devnet version, check out the [releases page](https://github.com/0xspaceshard/starknet-devnet-rs/releases). + +### Devnet API + +Devnet has many additional features which are available via their own endpoints and JSON-RPC, which are all mentioned throughout the documentation. + +## Interacting with Devnet in JavaScript and TypeScript + +To interact with Devnet using the [Devnet API](#devnet-api), you can use [`starknet-devnet-js`](https://github.com/0xSpaceShard/starknet-devnet-js/). This can be especially useful in achieving [L1-L2 communication](./postman.md#l1-l2-interaction-via-postman). + +To interact with Devnet usings the [Starknet API](#starknet-api), use [starknet.js](https://www.starknetjs.com/). + +## Config API + +To retrieve the current configuration of Devnet, send a `GET` request to `/config` or `JSON-RPC` request with method name `devnet_getConfig`. Example response is attached below. It can be interpreted as a JSON mapping of CLI input parameters, both specified and default ones, with some irrelevant parameters omitted. So use `starknet-devnet --help` to better understand the meaning of each value, though keep in mind that some of the parameters have slightly modified names. + +```json +{ + "seed": 4063802897, + "total_accounts": 10, + "account_contract_class_hash": "0x61dac032f228abef9c6626f995015233097ae253a7f72d68552db02f2971b8f", + "predeployed_accounts_initial_balance": "1000000000000000000000", + "start_time": null, + "gas_price_wei": 100000000000, + "gas_price_strk": 100000000000, + "data_gas_price_wei": 100000000000, + "data_gas_price_strk": 100000000000, + "chain_id": "SN_SEPOLIA", + "dump_on": "exit", + "dump_path": "dump_path.json", + "state_archive": "none", + "fork_config": { + "url": "http://rpc.pathfinder.equilibrium.co/integration-sepolia/rpc/v0_7", + "block_number": 26429 + }, + "server_config": { + "host": "127.0.0.1", + "port": 5050, + "timeout": 120, + "request_body_size_limit": 2000000 + }, + "block_generation": null, + "lite_mode": false +} +``` diff --git a/website/versioned_docs/version-0.1.2/balance.md b/website/versioned_docs/version-0.1.2/balance.md new file mode 100644 index 000000000..ce9df1dc7 --- /dev/null +++ b/website/versioned_docs/version-0.1.2/balance.md @@ -0,0 +1,69 @@ +# Account balance + +Other than using prefunded predeployed accounts, you can also add funds to an account that you deployed yourself. + +Separate tokens use separate ERC20 contracts for minting and charging fees. These are the token contracts predeployed by Devnet and the addresses where they are located: + +- ETH: `0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7` +- STRK: `0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d` + +## Mint token - Local faucet + +By sending a `POST` request to `/mint` or `JSON-RPC` request with method name `devnet_mint` for a token, you initiate a transaction on that token's ERC20 contract. The response contains the hash of this transaction, as well as the new balance after minting. The token is specified by providing the unit, and defaults to `WEI`. + +The value of `amount` is in WEI and needs to be an integer (or a float whose fractional part is 0, e.g. `1000.0` or `1e21`) + +``` +POST /mint +{ + "address": "0x6e3205f...", + "amount": 500000, + "unit": "WEI" | "FRI" +} +``` + +``` +JSON-RPC +{ + "jsonrpc": "2.0", + "id": "1", + "method": "devnet_mint", + "params": { + "address": "0x6e3205f...", + "amount": 500000, + "unit": "WEI" | "FRI" + } +} +``` + +Response: + +``` +{ + "new_balance": 500000, + "unit": "WEI" | "FRI", + "tx_hash": "0xa24f23..." +} +``` + +## Check balance + +Check the balance of an address by sending a `GET` request to `/account_balance`. The address should be a 0x-prefixed hex string; `unit` defaults to `WEI` and `block_tag` to `latest`. + +``` +GET /account_balance?address=
[&unit=][&block_tag=] +``` + +``` +JSON-RPC +{ + "jsonrpc": "2.0", + "id": "1", + "method": "devnet_getAccountBalance", + "params": { + "address": "0x6e3205f...", + "unit": "WEI" | "FRI", + "block_tag": "latest" | "pending" + } +} +``` diff --git a/website/versioned_docs/version-0.1.2/blocks.md b/website/versioned_docs/version-0.1.2/blocks.md new file mode 100644 index 000000000..43c1a1e64 --- /dev/null +++ b/website/versioned_docs/version-0.1.2/blocks.md @@ -0,0 +1,136 @@ +# Blocks + +By default, Devnet starts with a genesis block labelled with number zero. In [forking mode](./forking), the genesis block number is equal to the forked block number plus one. + +## Creating blocks on transaction + +If you start Devnet with `--block-generation-on transaction`, a new block is generated with each new transaction. This is the default block generation regime. This mode also supports [empty block creation](#request-new-block-creation). + +## Creating blocks on demand + +If you start Devnet with the `--block-generation-on demand` CLI option, you will enable the possibility to store more than one transaction in the pending block (targetable via block tag `"pending"`). + +Once you've added the desired transactions into the pending block, you can [request new block creation](#request-new-block-creation). This will convert the pending block to the latest block (targetable via block tag `"latest"`), giving it a block hash and a block number. All subsequent transactions will be stored in a new pending block. + +In case of demanding block creation with no pending transactions, a new empty block will be generated. + +The creation of the genesis block is not affected by this feature. + +``` +POST /create_block +``` + +``` +JSON-RPC +{ + "jsonrpc": "2.0", + "id": "1", + "method": "devnet_createBlock" +} +``` + +Response: + +``` +{'block_hash': '0x115e1b390cafa7942b6ab141ab85040defe7dee9bef3bc31d8b5b3d01cc9c67'} +``` + +## Automatic periodic block creation + +If started with the `--block-generation-on ` CLI option, Devnet will behave as in [`demand` mode](#creating-blocks-on-demand), but new blocks will be mined automatically every `` seconds. Consider this example of spawning Devnet at moment `t`: + +```bash +# t +$ starknet-devnet --block-generation-on 10 + +# t + 1s +# user: send tx1 + +# t + 4s +# user: send tx2 + +# t + 10s +# Devnet: block automatically generated, contains tx1 and tx2 + +# t + 12s +# user: send tx3 + +# t + 14s +# user: invoke empty block creation +# Devnet: generated block contains tx3 + +# t + 20s +# Devnet: block automatically generated, contains no txs (manual creation did not restart the counter) +``` + +## Request new block creation + +To request the creation of a new block, `POST` a request with no body to `/create_block` or send: + +``` +JSON-RPC +{ + "jsonrpc": "2.0", + "id": "1", + "method": "devnet_createBlock" +} +``` + +Response: + +``` +{"block_hash": "0x115e1b390cafa7942b6ab141ab85040defe7dee9bef3bc31d8b5b3d01cc9c67"} +``` + +The newly created block will contain all pending transactions, if any, since the last block creation. + +## Abort blocks + +This functionality allows simulating block abortion that can occur on mainnet. It is supported in the `--state-archive-capacity full` mode. + +You can abort blocks and revert transactions from the specified block to the currently latest block. Newly created blocks after the abortion will have accepted status and will continue with numbering where the last accepted block left off. + +The state of Devnet will be reverted to the state of the last accepted block. + +### Example + +Assume there are 3 accepted blocks numbered 1, 2 and 3. Upon receiving a request to abort blocks starting with block 2, the blocks numbered 2 and 3 are aborted and their transactions reverted. The state of network will be as it was in block 1. Once a new block is mined, it will be accepted and it will have number 2. + +### Limitations + +Aborted blocks can only be queried by block hash. Devnet does not support the abortion of: + +- blocks in the forking origin (i.e. blocks mined before the forked block) +- already aborted blocks +- Devnet's genesis block + +### Request and response + +To abort, send one of the following: + +``` +POST /abort_blocks +{ + "starting_block_hash": BLOCK_HASH +} +``` + +``` +JSON-RPC +{ + "jsonrpc": "2.0", + "id": "1", + "method": "devnet_abortBlocks", + "params": { + "starting_block_hash": BLOCK_HASH + } +} +``` + +Response: + +``` +{ + "aborted": [BLOCK_HASH_0, BLOCK_HASH_1, ...] +} +``` diff --git a/website/versioned_docs/version-0.1.2/dump-load-restart.md b/website/versioned_docs/version-0.1.2/dump-load-restart.md new file mode 100644 index 000000000..640439daf --- /dev/null +++ b/website/versioned_docs/version-0.1.2/dump-load-restart.md @@ -0,0 +1,106 @@ +# Dump, load, restart + +## Dumping + +To preserve your Devnet instance for future use, these are the options: + +- Dumping on exit (handles Ctrl+C, i.e. SIGINT; doesn't handle SIGKILL): + +``` +$ starknet-devnet --dump-on exit --dump-path +``` + +- Dumping after each block: + +``` +$ starknet-devnet --dump-on block --dump-path +``` + +- Dumping on request requires providing --dump-on mode on the startup. Example usage in `exit` mode (replace ``, `` and `` with your own): + +``` +$ starknet-devnet --dump-on exit --dump-path +$ curl -X POST http://:/dump -d '{ "path": }' -H "Content-Type: application/json" +``` + +``` +JSON-RPC +{ + "jsonrpc": "2.0", + "id": "1", + "method": "devnet_dump", + "params": { + "path": PATH + } +} +``` + +## Loading + +To load a preserved Devnet instance, the options are: + +- Loading on startup (note the argument name is not `--load-path` as it was in Devnet-py): + +``` +$ starknet-devnet --dump-path +``` + +- Loading on request: + +``` +curl -X POST http://:/load -d '{ "path": }' -H "Content-Type: application/json" +``` + +``` +JSON-RPC +{ + "jsonrpc": "2.0", + "id": "1", + "method": "devnet_load", + "params": { + "path": PATH + } +} +``` + +Currently, dumping produces a list of received transactions that is stored on disk. Conversely, loading is implemented as the re-execution of transactions from a dump. This means that timestamps of `StarknetBlock` will be different on each load. + +### Loading disclaimer + +Dumping and loading are not guaranteed to work across versions. I.e. if you dumped one version of Devnet, do not expect it to be loadable with a different version. + +If you dumped a Devnet utilizing one class for account predeployment (e.g. `--account-class cairo0`), you should use the same option when loading. The same applies for dumping a Devnet in `--block-generation-on demand` mode. + +## Restarting + +Devnet can be restarted by making a `POST /restart` request (no body required) or `JSON-RPC` request with method name `devnet_restart`. All of the deployed contracts (including predeployed), blocks and storage updates will be restarted to the original state, without the transactions and requests that may have been loaded from a dump file on startup. + +## Docker + +To enable dumping and loading with dockerized Devnet, you must bind the container path to the path on your host machine. + +This example: + +- Relies on [Docker bind mount](https://docs.docker.com/storage/bind-mounts/); try [Docker volume](https://docs.docker.com/storage/volumes/) instead. +- Assumes that `/path/to/dumpdir` exists. If unsure, use absolute paths. +- Assumes you are listening on `127.0.0.1:5050`. + +If there is `mydump` inside `/path/to/dumpdir`, you can load it with: + +``` +docker run \ + -p 127.0.0.1:5050:5050 \ + --mount type=bind,source=/path/to/dumpdir,target=/path/to/dumpdir \ + shardlabs/starknet-devnet-rs \ + --dump-path /path/to/dumpdir/mydump +``` + +To dump to `/path/to/dumpdir/mydump` on Devnet shutdown, run: + +``` +docker run \ + -p 127.0.0.1:5050:5050 \ + --mount type=bind,source=/path/to/dumpdir,target=/path/to/dumpdir \ + shardlabs/starknet-devnet-rs \ + --dump-on exit --dump-path /path/to/dumpdir/mydump +``` diff --git a/website/versioned_docs/version-0.1.2/forking.md b/website/versioned_docs/version-0.1.2/forking.md new file mode 100644 index 000000000..d9413aadf --- /dev/null +++ b/website/versioned_docs/version-0.1.2/forking.md @@ -0,0 +1,17 @@ +# Forking + +To interact with contracts deployed on mainnet or testnet, you can use forking. Simulate the origin and experiment with it locally, making no changes to the origin itself. + +``` +$ starknet-devnet --fork-network [--fork-block ] +``` + +The value passed to `--fork-network` should be the URL to a Starknet JSON-RPC API provider. Specifying a `--fork-block` is optional; it defaults to the `"latest"` block at the time of Devnet's start-up. All calls will first try Devnet's state and then fall back to the forking block. + +## Account impersonation + +[Here](./account-impersonation) you can read more about acting as an account deployed on the origin. + +## Deploying an undeclared account + +[Here](./predeployed#deploying-an-undeclared-account) you can read about deploying an account not declared on Devnet. diff --git a/website/versioned_docs/version-0.1.2/historic-state.md b/website/versioned_docs/version-0.1.2/historic-state.md new file mode 100644 index 000000000..f2358c680 --- /dev/null +++ b/website/versioned_docs/version-0.1.2/historic-state.md @@ -0,0 +1,9 @@ +# Historic state support + +With state archive capacity set to `full`, Devnet will store full state history, enabling its querying by block hash or number. The default mode is `none`, where no old states are stored and only the latest is available for querying. + +``` +$ starknet-devnet --state-archive-capacity +``` + +All RPC endpoints that support querying the state at an old (non-latest) block only work with state archive capacity set to `full`. diff --git a/website/versioned_docs/version-0.1.2/intro.md b/website/versioned_docs/version-0.1.2/intro.md new file mode 100644 index 000000000..55dc7a5f5 --- /dev/null +++ b/website/versioned_docs/version-0.1.2/intro.md @@ -0,0 +1,21 @@ +--- +sidebar_position: 1 +--- + +# Intro + +:::danger Difference disclaimer + +- Devnet should not be used as a replacement for official testnets. After testing on Devnet, be sure to test on a testnet (alpha-sepolia)! +- The semantics of `REJECTED` and `REVERTED` status of a transaction is not the same as on the official testnet: + +| Tx status | Official testnet | Devnet | +| ---------- | ----------------------------------------------------------- | ---------------------------------------------------------- | +| `REJECTED` | validation failed; not included in a block | not used | +| `REVERTED` | validation passed but execution failed; included in a block | validation or execution failed; not included in a block`*` | + +`*`: dummy zeroes (0) in tx info for block number and tx index + +::: + +You may now proceed with [running Devnet](./running/install) and checking out the many features listed in the sidebar on the left. diff --git a/website/versioned_docs/version-0.1.2/lite.md b/website/versioned_docs/version-0.1.2/lite.md new file mode 100644 index 000000000..500fbe71e --- /dev/null +++ b/website/versioned_docs/version-0.1.2/lite.md @@ -0,0 +1,15 @@ +# Lite mode + +To run Devnet in a minimal lite mode, provide the flag: + +``` +$ starknet-devnet --lite-mode +``` + +Steps skipped in lite mode: + +- calculating block hash + +This is useful if your use-case doesn't need the functionalities above. + +The extent of what is affected by lite mode may be expanded in the future. diff --git a/website/versioned_docs/version-0.1.2/postman.md b/website/versioned_docs/version-0.1.2/postman.md new file mode 100644 index 000000000..39acbc739 --- /dev/null +++ b/website/versioned_docs/version-0.1.2/postman.md @@ -0,0 +1,193 @@ +# L1-L2 interaction via Postman + +Postman is a Starknet utility that allows testing L1-L2 interaction. Ensure you have an L1 node and a Devnet (L2 node) running, [load](#load) a messaging contract, and [flush](#flush) the queue when needed. You can use [**`starknet-devnet-js`**](https://github.com/0xSpaceShard/starknet-devnet-js) to perform these actions, as witnessed in [**this example**](https://github.com/0xSpaceShard/starknet-devnet-js/blob/master/test/postman.test.ts), or directly send requests to the endpoints specified below. + +## Load + +``` +POST /postman/load_l1_messaging_contract +``` + +```json +{ + "networkUrl": "http://localhost:8545", + "address": "0x123...def" +} +``` + +``` +JSON-RPC +{ + "jsonrpc": "2.0", + "id": "1", + "method": "devnet_postmanLoad", + "params": { + "networkUrl": "http://localhost:8545", + "address": "0x123...def" + } +} +``` + +Loads a `MockStarknetMessaging` contract. The `address` parameter is optional; if provided, the `MockStarknetMessaging` contract will be fetched from that address, otherwise a new one will be deployed. + +`networkUrl` is the URL of the JSON-RPC API of the L1 node you've run locally or that already exists; possibilities include, and are not limited to: + +- [**Anvil**](https://github.com/foundry-rs/foundry/tree/master/crates/anvil) +- [**Sepolia testnet**](https://sepolia.etherscan.io/) +- [**Ganache**](https://www.npmjs.com/package/ganache) +- [**Geth**](https://github.com/ethereum/go-ethereum#docker-quick-start) +- [**Hardhat node**](https://hardhat.org/hardhat-network/#running-stand-alone-in-order-to-support-wallets-and-other-software) + +## Flush + +``` +POST /postman/flush +``` + +``` +JSON-RPC +{ + "jsonrpc": "2.0", + "id": "1", + "method": "devnet_postmanFlush" +} +``` + +Goes through the newly enqueued messages, sending them from L1 to L2 and from L2 to L1. Requires no body. Optionally, set the `dry_run` specifier to just see the result of flushing, without actually triggering it: + +``` +POST /postman/flush +``` + +```js +{ "dry_run": true } +``` + +``` +JSON-RPC +{ + "jsonrpc": "2.0", + "id": "1", + "method": "devnet_postmanFlush", + "params": { + "dry_run": true + } +} +``` + +A running L1 node is required if `dry_run` is not set. + +## Disclaimer + +This method of L1-L2 communication testing differs from how Starknet mainnet and testnets work. Taking [**L1L2Example.sol**](https://github.com/MikeSpa/starknet-test/blob/6a68d033cd7ddb5df937154f860f1c06174e6860/L1L2Example.sol#L46) (originally from Starknet documentation, no longer available there): + +```solidity +constructor(IStarknetCore starknetCore_) public { + starknetCore = starknetCore_; +} +``` + +The constructor takes an `IStarknetCore` contract as argument, however for Devnet's L1-L2 communication testing, this has to be replaced with the logic in [**MockStarknetMessaging.sol**](https://github.com/starkware-libs/cairo-lang/blob/master/src/starkware/starknet/testing/MockStarknetMessaging.sol): + +```solidity +constructor(MockStarknetMessaging mockStarknetMessaging_) public { + starknetCore = mockStarknetMessaging_; +} +``` + +## Mock transactions + +### L1->L2 + +Sending mock transactions from L1 to L2 without the need for running L1. Deployed L2 contract address `l2_contract_address` and `entry_point_selector` must be valid otherwise new block will not be created. + +Normally `nonce` is calculated by L1 StarknetContract and it's used in L1 and L2. In this case, we need to provide it manually. + +A running L1 node is **not** required for this operation. + +``` +POST /postman/send_message_to_l2 +``` + +Request: + +```js +{ + "l2_contract_address": "0x00285ddb7e5c777b310d806b9b2a0f7c7ba0a41f12b420219209d97a3b7f25b2", + "entry_point_selector": "0xC73F681176FC7B3F9693986FD7B14581E8D540519E27400E88B8713932BE01", + "l1_contract_address": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", + "payload": [ + "0x1", + "0x2" + ], + "paid_fee_on_l1": "0x123456abcdef" + "nonce":"0x0" +} +``` + +``` +JSON-RPC +{ + "jsonrpc": "2.0", + "id": "1", + "method": "devnet_postmanSendMessageToL2", + "params": { + "l2_contract_address": "0x00285ddb7e5c777b310d806b9b2a0f7c7ba0a41f12b420219209d97a3b7f25b2", + "entry_point_selector": "0xC73F681176FC7B3F9693986FD7B14581E8D540519E27400E88B8713932BE01", + "l1_contract_address": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", + "payload": [ + "0x1", + "0x2" + ], + "paid_fee_on_l1": "0x123456abcdef" + "nonce":"0x0" + } +} +``` + +Response: + +```js +{ "transaction_hash": "0x0548c761a9fd5512782998b2da6f44c42bf78fb88c3794eea330a91c9abb10bb" } +``` + +### L2->L1 + +Sending mock transactions from L2 to L1. +Deployed L2 contract address `l2_contract_address` and `l1_contract_address` must be valid. + +A running L1 node is required for this operation. + +``` +POST /postman/consume_message_from_l2 +``` + +Request: + +```js +{ + "l2_contract_address": "0x00285ddb7e5c777b310d806b9b2a0f7c7ba0a41f12b420219209d97a3b7f25b2", + "l1_contract_address": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", + "payload": ["0x0", "0x1", "0x3e8"], +} +``` + +``` +JSON-RPC +{ + "jsonrpc": "2.0", + "id": "1", + "method": "devnet_postmanConsumeMessageFromL2", + "params": { + "l2_contract_address": "0x00285ddb7e5c777b310d806b9b2a0f7c7ba0a41f12b420219209d97a3b7f25b2", + "l1_contract_address": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", + "payload": ["0x0", "0x1", "0x3e8"], + } +} +``` + +Response: + +```js +{"message_hash": "0xae14f241131b524ac8d043d9cb4934253ac5c5589afef19f0d761816a9c7e26d"} +``` diff --git a/website/versioned_docs/version-0.1.2/predeployed.md b/website/versioned_docs/version-0.1.2/predeployed.md new file mode 100644 index 000000000..6f3c143d9 --- /dev/null +++ b/website/versioned_docs/version-0.1.2/predeployed.md @@ -0,0 +1,46 @@ +# Predeployed contracts + +Devnet predeploys a [UDC](https://docs.openzeppelin.com/contracts-cairo/0.6.1/udc), an [ERC20 (fee token)](https://docs.openzeppelin.com/contracts-cairo/0.8.1/erc20) contract and a set of predeployed funded accounts. + +The set of accounts can be controlled via [CLI options](./running/cli): `--accounts `, `--initial-balance `, `--seed `. + +## Account class selection + +Choose between predeploying Cairo 0 (OpenZeppelin 0.5.1) or Cairo 1 (default; OpenZeppelin 0.8.1) accounts by using: + +``` +--account-class [cairo0 | cairo1] +``` + +Alternatively, provide a path to the [Sierra artifact](https://github.com/starkware-libs/cairo#compiling-and-running-cairo-files) of your custom account using: + +``` +--account-class-custom +``` + +## Deploying an undeclared account + +If you want to deploy an instance of an account contract class not predeclared on Devnet, you can use [forking](./forking). Just fork an origin network which has the needed class already declared, e.g. the Sepolia testnet. Why? Because new versions of wallets like ArgentX and Braavos tend to be declared on testnet/mainnet soon after release. + +## How to get predeployment info? + +The information on predeployed contracts is logged on Devnet startup. Predeployed accounts can be retrieved in JSON format by sending a `GET` request to `/predeployed_accounts`. With the additional query parameter `with_balance=true`, WEI and FRI balances at the pending state will be provided: + +``` +GET /predeployed_accounts?[with_balance=true] +``` + +Alternatively, send a JSON-RPC request: + +``` +JSON-RPC +{ + "jsonrpc": "2.0", + "id": "1", + "method": "devnet_getPredeployedAccounts", + "params": { + // optional; defaults to false + "with_balance": true | false + } +} +``` diff --git a/website/versioned_docs/version-0.1.2/running/_category_.json b/website/versioned_docs/version-0.1.2/running/_category_.json new file mode 100644 index 000000000..17c529a24 --- /dev/null +++ b/website/versioned_docs/version-0.1.2/running/_category_.json @@ -0,0 +1,7 @@ +{ + "label": "Running", + "position": 2, + "link": { + "type": "generated-index" + } +} diff --git a/website/versioned_docs/version-0.1.2/running/cli.md b/website/versioned_docs/version-0.1.2/running/cli.md new file mode 100644 index 000000000..f9e914bd9 --- /dev/null +++ b/website/versioned_docs/version-0.1.2/running/cli.md @@ -0,0 +1,89 @@ +--- +sidebar_position: 2.3 +--- + +# CLI options + +Configure your Devnet instance by specifying CLI parameters on startup. + +## Help + +Check out all the options with: + +``` +$ starknet-devnet --help +``` + +Or if using dockerized Devnet: + +``` +$ docker run --rm shardlabs/starknet-devnet-rs --help +``` + +## Environment variables + +Every CLI option can also be specified via an environment variable: + +``` +$ = = starknet-devnet +``` + +To see the exact variable names, use [`--help`](#help). + +### Precedence + +If both a CLI argument and an environment variable are passed for a parameter, the CLI argument takes precedence. If none are provided, the default value is used. E.g. if running Devnet with the following command, seed value 42 will be used: + +``` +$ SEED=10 starknet-devnet --seed 42 +``` + +### Docker + +If using dockerized Devnet, specify the variables like this: + +``` +$ docker run \ + -e = \ + -e = \ + ... \ + shardlabs/starknet-devnet-rs +``` + +## Load configuration from a file + +If providing many configuration parameters in a single command becomes cumbersome, consider loading them from a file. By relying on [environment variables](#environment-variables), prepare your configuration in a file like this: + +```bash +export SEED=42 +export ACCOUNTS=3 +... +``` + +Assuming the file is called `.my-env-file`, then run: + +```bash +$ source .my-env-file && starknet-devnet +``` + +To run in a subshell and prevent environment pollution (i.e. to unset the variables after Devnet exits), use parentheses: + +```bash +$ ( source .my-env-file && starknet-devnet ) +``` + +### Docker + +To load environment variables from `.my-env-file` with Docker, remove the `export` part in each line to have the file look like this: + +``` +SEED=42 +ACCOUNTS=3 +... +``` + +Then run: + +``` +$ docker run --env-file .my-env-file shardlabs/starknet-devnet-rs +``` diff --git a/website/versioned_docs/version-0.1.2/running/docker.md b/website/versioned_docs/version-0.1.2/running/docker.md new file mode 100644 index 000000000..2aca5a682 --- /dev/null +++ b/website/versioned_docs/version-0.1.2/running/docker.md @@ -0,0 +1,85 @@ +--- +sidebar_position: 2.2 +--- + +# Run with Docker + +Devnet is available as a Docker image ([Docker Hub link](https://hub.docker.com/r/shardlabs/starknet-devnet-rs/)). To download the `latest` image, run: + +```text +$ docker pull shardlabs/starknet-devnet-rs +``` + +Supported platforms: linux/amd64 and linux/arm64 (also executable on darwin/arm64). + +Running a container is done like this (see [port publishing](#container-port-publishing) for more info): + +```text +$ docker run -p [HOST:]:5050 shardlabs/starknet-devnet-rs [OPTIONS] +``` + +### Docker image tags + +All of the versions published on crates.io for starknet-devnet are available as docker images, which can be used via: + +``` +$ docker pull shardlabs/starknet-devnet-rs: +``` + +:::note + +The `latest` docker image tag corresponds to the last published version on crates.io. + +::: + +Commits to the `main` branch of this repository are mostly available as images tagged with their commit hash (the full 40-lowercase-hex-digits SHA1 digest): + +``` +$ docker pull shardlabs/starknet-devnet-rs: +``` + +By appending the `-seed0` suffix, you can use images which [predeploy funded accounts](../predeployed) with `--seed 0`, thus always predeploying the same set of accounts: + +``` +$ docker pull shardlabs/starknet-devnet-rs:-seed0 +$ docker pull shardlabs/starknet-devnet-rs:latest-seed0 +``` + +### Container port publishing + +#### Linux + +If on a Linux host machine, you can use [`--network host`](https://docs.docker.com/network/host/). This way, the port used internally by the container is also available on your host machine. The `--port` option can be used (as well as other CLI options). + +```text +$ docker run --network host shardlabs/starknet-devnet-rs [--port ] +``` + +#### Mac and Windows + +If not on Linux, you need to publish the container's internally used port to a desired `` on your host machine. The internal port is `5050` by default (probably not your concern, but can be overridden with `--port`). + +```text +$ docker run -p [HOST:]:5050 shardlabs/starknet-devnet-rs +``` + +E.g. if you want to use your host machine's `127.0.0.1:5050`, you need to run: + +```text +$ docker run -p 127.0.0.1:5050:5050 shardlabs/starknet-devnet-rs +``` + +You may ignore any address-related output logged on container startup (e.g. `Starknet Devnet listening on 0.0.0.0:5050`). What you will use is what you specified with the `-p` argument. + +If you don't specify the `HOST` part, the server will indeed be available on all of your host machine's addresses (localhost, local network IP, etc.), which may present a security issue if you don't want anyone from the local network to access your Devnet instance. + +### Development note + +Due to internal needs, images with arch suffix are built and pushed to Docker Hub, but this is not mentioned in the user docs as users should NOT be needing it. + +This is what happens under the hood on `main`: + +- build `shardlabs/starknet-devnet-rs--amd` +- build `shardlabs/starknet-devnet-rs--arm` +- create and push joint docker manifest called `shardlabs/starknet-devnet-rs-` + - same for `latest` diff --git a/website/versioned_docs/version-0.1.2/running/install.md b/website/versioned_docs/version-0.1.2/running/install.md new file mode 100644 index 000000000..caaf5107c --- /dev/null +++ b/website/versioned_docs/version-0.1.2/running/install.md @@ -0,0 +1,71 @@ +--- +sidebar_position: 2.1 +--- + +# Install and run + +## Requirements + +Any of the approaches below that mention `cargo` require you to have [installed Rust](https://www.rust-lang.org/tools/install). You might also need to install `pkg-config` and `make`. + +The required Rust version is specified in `rust-toolchain.toml` in the project root and handled automatically by `cargo`. + +## Install an executable binary + +Installing an executable binary is achievable with `cargo install` via [crates.io](https://crates.io/) or [github.com](https://github.com). This approach downloads the crate, builds it in release mode and copies it to `~/.cargo/bin/`. To avoid needing to compile and wait, check the [pre-compiled binary section](#fetch-a-pre-compiled-binary-executable). + +### Remove Pythonic Devnet + +If in the past you installed [Pythonic Devnet](https://github.com/0xSpaceShard/starknet-devnet), be sure to remove it to avoid name collision of the old and the new executable - if by no other means, then by `rm $(which starknet-devnet)`. + +### Install from crates.io + +``` +$ cargo install starknet-devnet +``` + +### Install from GitHub + +- Use the `--locked` flag to ensure using the dependencies listed in `Cargo.lock` in the project root. +- Preferably familiarize yourself with the `cargo install` command ([docs](https://doc.rust-lang.org/cargo/commands/cargo-install.html#dealing-with-the-lockfile)). + +``` +$ cargo install --git https://github.com/0xSpaceShard/starknet-devnet-rs.git --locked +``` + +### Run the installed executable + +When `cargo install` finishes, follow the output in your terminal. If properly configured, you should be able to run Devnet with: + +``` +$ starknet-devnet +``` + +## Fetch a pre-compiled binary executable + +If you want to save time and skip project compilation on installation, since Devnet v0.0.5, the Assets section of each [GitHub release](https://github.com/0xSpaceShard/starknet-devnet-rs/releases) contains a set of platform-specific pre-compiled binary executables. Extract and run with: + +``` +$ curl https://github.com/0xSpaceShard/starknet-devnet-rs/releases/download// | tar -xvzf -C +$ /starknet-devnet +``` + +## Run from source + +To install the project from source, after [git-cloning](https://github.com/git-guides/git-clone) the [Devnet repository](https://github.com/0xSpaceShard/starknet-devnet-rs), running the following command will install, build and start Devnet: + +``` +$ cargo run +``` + +Specify optional CLI params like this: + +``` +$ cargo run -- [ARGS] +``` + +For a more optimized performance (though with a longer compilation time), run: + +``` +$ cargo run --release +``` diff --git a/website/versioned_docs/version-0.1.2/server-config.md b/website/versioned_docs/version-0.1.2/server-config.md new file mode 100644 index 000000000..9198a6522 --- /dev/null +++ b/website/versioned_docs/version-0.1.2/server-config.md @@ -0,0 +1,77 @@ +# Server config + +To read generally about ways to configure your Devnet instance, check out the [CLI section](./running/cli.md). + +## Host and port + +Specify the host and the port used by the server with `--host
` and `--port ` CLI arguments. If running with Docker, check out the [port publishing docs](./running/docker#container-port-publishing). + +## Logging + +By default, the logging level is `INFO`, but this can be changed via the `RUST_LOG` environment variable. + +All logging levels: `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR` + +To specify the logging level and run Devnet on the same line: + +``` +$ RUST_LOG= starknet-devnet +``` + +or if using dockerized Devnet: + +``` +$ docker run -e RUST_LOG= shardlabs/starknet-devnet-rs +``` + +By default, logging of request and response data is turned off. +To see the request and/or response body, additional levels can be specified via the `RUST_LOG` environment variable: `REQUEST` for request body, `RESPONSE` for response body. + +:::note + +Logging request and response requires at least logging level `INFO`. + +For example, the following two commands will log request and response data with log level `INFO`. + +``` +$ RUST_LOG="REQUEST,RESPONSE" starknet-devnet +``` + +``` +$ RUST_LOG="REQUEST,RESPONSE,INFO" starknet-devnet +``` + +::: + +## Timeout + +Specify the maximum amount of time an HTTP request can be served. This makes it possible to deploy and manage large contracts that take longer to execute. + +``` +$ starknet-devnet --timeout +``` + +## Request body size limit + +Specify the maximum size of an incoming HTTP request body. This makes it possible to deploy and manage large contracts that take up more space. + +``` +$ starknet-devnet --request-body-size-limit +``` + +## API + +Retrieve the server config by sending a `GET` request to `/config` or `JSON-RPC` request with method name `devnet_getConfig` and extracting its `server_config` property. + +``` +$ curl localhost:5050/config | jq .server_config +``` + +``` +JSON-RPC +{ + "jsonrpc": "2.0", + "id": "1", + "method": "devnet_getConfig" +} +``` diff --git a/website/versioned_docs/version-0.1.2/starknet-time.md b/website/versioned_docs/version-0.1.2/starknet-time.md new file mode 100644 index 000000000..39748a884 --- /dev/null +++ b/website/versioned_docs/version-0.1.2/starknet-time.md @@ -0,0 +1,84 @@ +# Starknet time + +Block and state timestamp can be manipulated by setting the exact time or setting the time offset. By default, timestamp methods `/set_time`, `/increase_time` and `JSON-RPC` methods `devnet_setTime`, `devnet_increaseTime` generate a new block. This can be changed for `/set_time` (`devnet_setTime`) by setting the optional parameter `generate_block` to `false`. This skips immediate new block generation, but will use the specified timestamp whenever the next block is supposed to be generated. + +All values should be set in [Unix time seconds](https://en.wikipedia.org/wiki/Unix_time). + +## Set time + +Sets the exact time and generates a new block. + +``` +POST /set_time +{ + "time": TIME_IN_SECONDS +} +``` + +``` +JSON-RPC +{ + "jsonrpc": "2.0", + "id": "1", + "method": "devnet_setTime", + "params": { + "time": TIME_IN_SECONDS + } +} +``` + +Doesn't generate a new block, but sets the exact time for the next generated block. + +``` +POST /set_time +{ + "time": TIME_IN_SECONDS, + "generate_block": false +} +``` + +``` +JSON-RPC +{ + "jsonrpc": "2.0", + "id": "1", + "method": "devnet_setTime", + "params": { + "time": TIME_IN_SECONDS, + "generate_block": false + } +} +``` + +Warning: block time can be set in the past which might lead to unexpected behavior! + +## Increase time + +Increases the block timestamp by the provided amount and generates a new block. All subsequent blocks will keep this increment. + +``` +POST /increase_time +{ + "time": TIME_IN_SECONDS +} +``` + +``` +JSON-RPC +{ + "jsonrpc": "2.0", + "id": "1", + "method": "devnet_increaseTime", + "params": { + "time": TIME_IN_SECONDS + } +} +``` + +## Start time argument + +Devnet can be started with `--start-time` CLI argument, where `START_TIME_IN_SECONDS` should be greater than 0. + +``` +$ starknet-devnet --start-time +``` diff --git a/website/versioned_sidebars/version-0.1.2-sidebars.json b/website/versioned_sidebars/version-0.1.2-sidebars.json new file mode 100644 index 000000000..145418b2d --- /dev/null +++ b/website/versioned_sidebars/version-0.1.2-sidebars.json @@ -0,0 +1,8 @@ +{ + "docSidebar": [ + { + "type": "autogenerated", + "dirName": "." + } + ] +} diff --git a/website/versions.json b/website/versions.json index bea0a0f20..2eff7b212 100644 --- a/website/versions.json +++ b/website/versions.json @@ -1,4 +1,5 @@ [ + "0.1.2", "0.1.1", "0.0.7", "0.0.6"