Skip to content

Commit

Permalink
feat: Implement eth_getBlockByHash and eth_getBlockByNumber with corr…
Browse files Browse the repository at this point in the history
…ect behavior (#102)

* returns blocks via hashes

* add fork getBlockByHash fallback

* add support for eth_getBlockByHash and eth_getBlockByNumber

* insert genesis block when using run mode

* use actual current block number for block generation
  • Loading branch information
nbaztec committed Sep 13, 2023
1 parent 0cac26b commit f263687
Show file tree
Hide file tree
Showing 10 changed files with 1,046 additions and 114 deletions.
44 changes: 39 additions & 5 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,6 @@ ethabi = "16.0.0"
itertools = "0.10.5"
log = "0.4.20"
simplelog = "0.12.1"

[dev-dependencies]
httptest = "0.15.4"
36 changes: 33 additions & 3 deletions SUPPORTED_APIS.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ The `status` options are:
| `ETH` | `eth_feeHistory` | `NOT IMPLEMENTED` | Returns a collection of historical block gas data |
| [`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_getBlockByHash` | `NOT IMPLEMENTED`<br />[GitHub Issue #25](https://github.com/matter-labs/era-test-node/issues/25) | Returns information about a block by block hash |
| [`ETH`](#eth-namespace) | [`eth_getBlockByNumber`](#eth_getblockbynumber) | `PARTIALLY`<br />[GitHub Issue #71](https://github.com/matter-labs/era-test-node/issues/71) | Returns information about a block by block number<br /> ⚠️ _Support not available for `earliest`, `pending`, or block numbers other than the current block number_ |
| [`ETH`](#eth-namespace) | `eth_getBlockByHash`(#eth_getblockbyhash) | `SUPPORTED` | Returns information about a block by block hash |
| [`ETH`](#eth-namespace) | [`eth_getBlockByNumber`](#eth_getblockbynumber) | `SUPPORTED` | Returns information about a block by block number |
| `ETH` | `eth_getBlockTransactionCountByHash` | `NOT IMPLEMENTED`<br />[GitHub Issue #44](https://github.com/matter-labs/era-test-node/issues/44) | Number of transactions in a block from a block matching the given block hash |
| `ETH` | `eth_getBlockTransactionCountByNumber` | `NOT IMPLEMENTED`<br />[GitHub Issue #43](https://github.com/matter-labs/era-test-node/issues/43) | Number of transactions in a block from a block matching the given block number |
| `ETH` | `eth_getCompilers` | `NOT IMPLEMENTED` | Returns a list of available compilers |
Expand Down Expand Up @@ -452,6 +452,36 @@ curl --request POST \
}'
```

### `eth_getBlockByHash`

[source](src/node.rs)

Returns information about a block by block hash

#### Arguments

+ `hash: H256`

+ `full: boolean`

#### Status

`SUPPORTED`

#### Example

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

### `eth_getBlockByNumber`

[source](src/node.rs)
Expand All @@ -466,7 +496,7 @@ Returns information about a block by block number

#### Status

`PARTIALLY`
`SUPPORTED`

#### Example

Expand Down
36 changes: 35 additions & 1 deletion src/fork.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use tokio::runtime::Builder;
use zksync_basic_types::{Address, L1BatchNumber, L2ChainId, MiniblockNumber, H256, U256, U64};

use zksync_types::{
api::{BlockIdVariant, BlockNumber, Transaction},
api::{Block, BlockIdVariant, BlockNumber, Transaction, TransactionVariant},
l2::L2Tx,
StorageKey,
};
Expand Down Expand Up @@ -208,6 +208,20 @@ pub trait ForkSource {
&self,
block_number: MiniblockNumber,
) -> eyre::Result<Vec<zksync_types::Transaction>>;

/// Returns the block for a given hash.
fn get_block_by_hash(
&self,
hash: H256,
full_transactions: bool,
) -> eyre::Result<Option<Block<TransactionVariant>>>;

/// Returns the block for a given number.
fn get_block_by_number(
&self,
block_number: zksync_types::api::BlockNumber,
full_transactions: bool,
) -> eyre::Result<Option<zksync_types::api::Block<zksync_types::api::TransactionVariant>>>;
}

/// Holds the information about the original chain.
Expand All @@ -218,7 +232,10 @@ pub struct ForkDetails<S> {
pub fork_source: S,
// Block number at which we forked (the next block to create is l1_block + 1)
pub l1_block: L1BatchNumber,
// The actual L2 block
pub l2_block: zksync_types::api::Block<zksync_types::api::TransactionVariant>,
pub l2_miniblock: u64,
pub l2_miniblock_hash: H256,
pub block_timestamp: u64,
pub overwrite_chain_id: Option<L2ChainId>,
pub l1_gas_price: u64,
Expand All @@ -237,6 +254,21 @@ impl ForkDetails<HttpForkSource> {
.unwrap()
.unwrap_or_else(|| panic!("Could not find block {:?} in {:?}", miniblock, url));

let root_hash = block_details
.base
.root_hash
.unwrap_or_else(|| panic!("fork block #{} missing root hash", miniblock));
let block = client
.get_block_by_hash(root_hash, true)
.await
.ok()
.flatten()
.unwrap_or_else(|| {
panic!(
"Could not find block #{:?} ({:#x}) in {:?}",
miniblock, root_hash, url
)
});
let l1_batch_number = block_details.l1_batch_number;

log::info!(
Expand All @@ -249,8 +281,10 @@ impl ForkDetails<HttpForkSource> {
fork_url: url.to_owned(),
},
l1_block: l1_batch_number,
l2_block: block,
block_timestamp: block_details.base.timestamp,
l2_miniblock: miniblock,
l2_miniblock_hash: root_hash,
overwrite_chain_id: chain_id,
l1_gas_price: block_details.base.l1_gas_price,
}
Expand Down
24 changes: 24 additions & 0 deletions src/http_fork_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,28 @@ impl ForkSource for HttpForkSource {
block_on(async move { client.get_raw_block_transactions(block_number).await })
.wrap_err("fork http client failed")
}

fn get_block_by_hash(
&self,
hash: zksync_basic_types::H256,
full_transactions: bool,
) -> eyre::Result<Option<zksync_types::api::Block<zksync_types::api::TransactionVariant>>> {
let client = self.create_client();
block_on(async move { client.get_block_by_hash(hash, full_transactions).await })
.wrap_err("fork http client failed")
}

fn get_block_by_number(
&self,
block_number: zksync_types::api::BlockNumber,
full_transactions: bool,
) -> eyre::Result<Option<zksync_types::api::Block<zksync_types::api::TransactionVariant>>> {
let client = self.create_client();
block_on(async move {
client
.get_block_by_number(block_number, full_transactions)
.await
})
.wrap_err("fork http client failed")
}
}
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,5 @@ pub mod resolver;
pub mod system_contracts;
pub mod utils;
pub mod zks;

mod testing;
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ mod http_fork_source;
mod node;
mod resolver;
mod system_contracts;
mod testing;
mod utils;
mod zks;

Expand Down
Loading

0 comments on commit f263687

Please sign in to comment.