Skip to content

Commit

Permalink
Merge branch 'main' into nish-fix-36-37-upstream
Browse files Browse the repository at this point in the history
  • Loading branch information
nbaztec committed Sep 19, 2023
2 parents 480f09e + 19b7cca commit 8aa061f
Show file tree
Hide file tree
Showing 12 changed files with 705 additions and 29 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "era_test_node"
version = "0.1.0"
version = "0.1.0-alpha.3"
edition = "2018"
authors = ["The Matter Labs Team <[email protected]>"]
homepage = "https://zksync.io/"
Expand Down
54 changes: 51 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<a href="https://era.zksync.io/docs/tools/testing/era-test-node.html">

![era-test-node](./.github/assets/era_test_node_banner_light.png#gh-light-mode-only)
![Webb Logo](./.github/assets/era_test_node_banner_dark.png#gh-dark-mode-only)
![era-test-node](./.github/assets/era_test_node_banner_dark.png#gh-dark-mode-only)
</a>

</div>
Expand All @@ -11,8 +11,7 @@

This crate provides an in-memory node that supports forking the state from other networks.

The goal of this crate is to offer a fast solution for integration testing, bootloader and system contract testing, and
prototyping.
The goal of this crate is to offer a fast solution for integration testing, bootloader and system contract testing, and prototyping.

🔗 For a detailed walkthrough, refer to the [official documentation](https://era.zksync.io/docs/tools/testing/era-test-node.html).

Expand Down Expand Up @@ -149,6 +148,26 @@ Call(Normal) 0x55362182242a4de20ea8a0ec055b2134bb24e23d executeTransac

```

You can use the following options to get more granular information during transaction processing:

- `--show-storage-logs <SHOW_STORAGE_LOGS>`: Show storage log information.
[default: none]
[possible values: none, read, write, all]

- `--show-vm-details <SHOW_VM_DETAILS>`: Show VM details information.
[default: none]
[possible values: none, all]

- `--show-gas-details <SHOW_GAS_DETAILS>`: Show Gas details information.
[default: none]
[possible values: none, all]

Example:

```bash
era_test_node --show-storage-logs=all --show-vm-details=all --show-gas-details=all run
```

## 💰 Using Rich Wallets

For testing and development purposes, the `era-test-node` comes pre-configured with a set of 'rich' wallets. These wallets are loaded with test funds, allowing you to simulate transactions and interactions without the need for real assets.
Expand All @@ -174,6 +193,35 @@ Feel free to use these wallets in your tests, but remember, they are for develop

See our list of [Supported APIs here](SUPPORTED_APIS.md).

## 🤖 CI/CD Testing with GitHub Actions

A GitHub Action is available for integrating `era-test-node` into your CI/CD environments. This action offers high configurability and streamlines the process of testing your applications in an automated way.

You can find this GitHub Action in the marketplace [here](https://github.com/marketplace/actions/era-test-node-action).

### 📝 Example Usage

Below is an example `yaml` configuration to use the `era-test-node` GitHub Action in your workflow:

```yml
name: Run Era Test Node Action

on:
push:
branches: [ main ]

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Run Era Test Node
uses: dutterbutter/era-test-node-action@latest
```
## 🤝 Contributing
We welcome contributions from the community! If you're interested in contributing to the zkSync Era In-Memory Node, please take a look at our [CONTRIBUTING.md](./.github/CONTRIBUTING.md) for guidelines and details on the process.
Expand Down
81 changes: 78 additions & 3 deletions SUPPORTED_APIS.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ The `status` options are:
| [`ETH`](#eth-namespace) | [`eth_chainId`](#eth_chainid) | `SUPPORTED` | Returns the currently configured chain id <br />_(default is `260`)_ |
| `ETH` | `eth_coinbase` | `NOT IMPLEMENTED` | Returns the client coinbase address |
| [`ETH`](#eth-namespace) | [`eth_estimateGas`](#eth_estimategas) | `SUPPORTED` | Generates and returns an estimate of how much gas is necessary for the transaction to complete |
| `ETH` | `eth_feeHistory` | `NOT IMPLEMENTED` | Returns a collection of historical block gas data |
| [`ETH`](#eth-namespace) | [`eth_feeHistory`](#eth_feehistory) | `SUPPORTED` | Returns a collection of historical block gas data <br />_(hardcoded with gas price of `250_000_000`)_ |
| [`ETH`](#eth-namespace) | [`eth_gasPrice`](#eth_gasprice) | `SUPPORTED` | Returns the current price per gas in wei <br />_(hardcoded to `250_000_000`)_ |
| [`ETH`](#eth-namespace) | [`eth_getBalance`](#eth_getbalance) | `SUPPORTED` | Returns the balance of the account of given address |
| [`ETH`](#eth-namespace) | [`eth_getBlockByHash`](#eth_getblockbyhash) | `SUPPORTED` | Returns information about a block by block hash |
Expand Down Expand Up @@ -75,7 +75,7 @@ The `status` options are:
| `ETH` | `eth_unsubscribe` | `NOT IMPLEMENTED` | Cancel a subscription to a particular event |
| `EVM` | `evm_addAccount` | `NOT IMPLEMENTED` | Adds any arbitrary account |
| [`EVM`](#evm-namespace) | [`evm_increaseTime`](#evm_increasetime) | `SUPPORTED` | Jump forward in time by the given amount of time, in seconds |
| `EVM` | `evm_mine` | `NOT IMPLEMENTED`<br />[GitHub Issue #67](https://github.com/matter-labs/era-test-node/issues/67) | Force a single block to be mined |
| [`EVM`](#evm-namespace) | [`evm_mine`](#evm_mine) | `SUPPORTED` | Force a single block to be mined |
| `EVM` | `evm_removeAccount` | `NOT IMPLEMENTED` | Removes an account |
| `EVM` | `evm_revert` | `NOT IMPLEMENTED`<br />[GitHub Issue #70](https://github.com/matter-labs/era-test-node/issues/70) | Revert the state of the blockchain to a previous snapshot |
| `EVM` | `evm_setAccountBalance` | `NOT IMPLEMENTED` | Sets the given account's balance to the specified WEI value |
Expand All @@ -93,7 +93,7 @@ The `status` options are:
| `HARDHAT` | `hardhat_impersonateAccount` | `NOT IMPLEMENTED`<br />[GitHub Issue #73](https://github.com/matter-labs/era-test-node/issues/73) | Impersonate an account |
| `HARDHAT` | `hardhat_getAutomine` | `NOT IMPLEMENTED` | Returns `true` if automatic mining is enabled, and `false` otherwise |
| `HARDHAT` | `hardhat_metadata` | `NOT IMPLEMENTED` | Returns the metadata of the current network |
| `HARDHAT` | `hardhat_mine` | `NOT IMPLEMENTED`<br />[GitHub Issue #75](https://github.com/matter-labs/era-test-node/issues/75) | Mine any number of blocks at once, in constant time |
| [`HARDHAT`](#hardhat-namespace) | [`hardhat_mine`](#hardhat_mine) | Mine any number of blocks at once, in constant time |
| `HARDHAT` | `hardhat_reset` | `NOT IMPLEMENTED` | Resets the state of the network |
| [`HARDHAT`](#hardhat-namespace) | [`hardhat_setBalance`](#hardhat_setbalance) | `SUPPORTED` | Modifies the balance of an account |
| `HARDHAT` | `hardhat_setCode` | `NOT IMPLEMENTED` | Sets the bytecode of a given account |
Expand Down Expand Up @@ -399,6 +399,31 @@ curl --request POST \
}'
```

### `eth_feeHistory`

[source](src/node.rs)

Returns the fee history for a given range of blocks

#### Arguments

+ `block_count: U64`
+ `newest_block: BlockNumber`
+ `reward_percentiles: Vec<f32>`

#### Status

`SUPPORTED`

#### Example

```bash
curl --request POST \
--url http://localhost:8011/ \
--header 'content-type: application/json' \
--data '{"jsonrpc": "2.0","id": "1","method": "eth_feeHistory","params": ["0x1", "latest", [25, 50 , 75]]}'
```

### `eth_gasPrice`

[source](src/node.rs)
Expand Down Expand Up @@ -1000,8 +1025,58 @@ curl --request POST \
}'
```

### `hardhat_mine`

[source](src/hardhat.rs)

Sometimes you may want to advance the latest block number of the network by a large number of blocks.
One way to do this would be to call the evm_mine RPC method multiple times, but this is too slow if you want to mine thousands of blocks.
The hardhat_mine method can mine any number of blocks at once, in constant time. (It exhibits the same performance no matter how many blocks are mined.)

#### Arguments

+ `num_blocks: U64` - The number of blocks to mine. (Optional: defaults to 1)
+ `interval: U646` - The interval between the timestamps of each block, in seconds. (Optional: defaults to 1)

#### Example

```bash
curl --request POST \
--url http://localhost:8011/ \
--header 'content-type: application/json' \
--data '{
"jsonrpc": "2.0",
"id": "2",
"method": "hardhat_mine",
"params": [
"0xaa",
"0x100"
]
}'
```

## `EVM NAMESPACE`

### `evm_mine`

[source](src/evm.rs)

Mines an empty block

#### Status

`SUPPORTED`

#### Example

```bash
curl --request POST \
--url http://localhost:8011/ \
--header 'content-type: application/json' \
--data '{"jsonrpc": "2.0","id": "1","method": "evm_mine","params": []
}'
```

### `evm_increaseTime`

[source](src/evm.rs)
Expand Down
61 changes: 60 additions & 1 deletion src/evm.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::sync::{Arc, RwLock};

use crate::{fork::ForkSource, node::InMemoryNodeInner};
use crate::{fork::ForkSource, node::InMemoryNodeInner, utils::mine_empty_blocks};
use jsonrpc_core::{BoxFuture, Result};
use jsonrpc_derive::rpc;
use zksync_core::api_server::web3::backend_jsonrpc::error::into_jsrpc_error;
Expand Down Expand Up @@ -30,6 +30,15 @@ pub trait EvmNamespaceT {
#[rpc(name = "evm_increaseTime")]
fn increase_time(&self, time_delta_seconds: u64) -> BoxFuture<Result<u64>>;

/// Force a single block to be mined.
///
/// Will mine an empty block (containing zero transactions)
///
/// # Returns
/// The string "0x0".
#[rpc(name = "evm_mine")]
fn evm_mine(&self) -> BoxFuture<Result<String>>;

/// Set the current timestamp for the node. The timestamp must be in future.
///
/// # Parameters
Expand Down Expand Up @@ -109,11 +118,26 @@ impl<S: Send + Sync + 'static + ForkSource + std::fmt::Debug> EvmNamespaceT
}
})
}

fn evm_mine(&self) -> BoxFuture<Result<String>> {
let inner = Arc::clone(&self.node);
Box::pin(async move {
match inner.write() {
Ok(mut inner) => {
mine_empty_blocks(&mut inner, 1, 1000);
log::info!("👷 Mined block #{}", inner.current_miniblock);
Ok("0x0".to_string())
}
Err(_) => Err(into_jsrpc_error(Web3Error::InternalError)),
}
})
}
}

#[cfg(test)]
mod tests {
use crate::{http_fork_source::HttpForkSource, node::InMemoryNode};
use zksync_core::api_server::web3::backend_jsonrpc::namespaces::eth::EthNamespaceT;

use super::*;

Expand Down Expand Up @@ -421,4 +445,39 @@ mod tests {
);
}
}

#[tokio::test]
async fn test_evm_mine() {
let node = InMemoryNode::<HttpForkSource>::default();
let evm = EvmNamespaceImpl::new(node.get_inner());

let start_block = node
.get_block_by_number(zksync_types::api::BlockNumber::Latest, false)
.await
.unwrap()
.expect("block exists");
let result = evm.evm_mine().await.expect("evm_mine");
assert_eq!(&result, "0x0");

let current_block = node
.get_block_by_number(zksync_types::api::BlockNumber::Latest, false)
.await
.unwrap()
.expect("block exists");

assert_eq!(start_block.number + 1, current_block.number);
assert_eq!(start_block.timestamp + 1000, current_block.timestamp);

let result = evm.evm_mine().await.expect("evm_mine");
assert_eq!(&result, "0x0");

let current_block = node
.get_block_by_number(zksync_types::api::BlockNumber::Latest, false)
.await
.unwrap()
.expect("block exists");

assert_eq!(start_block.number + 2, current_block.number);
assert_eq!(start_block.timestamp + 2000, current_block.timestamp);
}
}
Loading

0 comments on commit 8aa061f

Please sign in to comment.