|
| 1 | +# Use Grevm with reth |
| 2 | + |
| 3 | +## Import |
| 4 | + |
| 5 | +Add the following line to your Cargo.toml |
| 6 | + |
| 7 | +```rust |
| 8 | +[dependencies] |
| 9 | +grevm = { git = "https://github.com/Galxe/grevm.git", branch = "main" } |
| 10 | +``` |
| 11 | + |
| 12 | +## Usage |
| 13 | + |
| 14 | +Using Grevm is straightforward and efficient. You just need to create a `GrevmScheduler` and then call `GrevmScheduler::parallel_execute` to get the results of parallel transaction execution. That’s all there is to it—simple and streamlined, making the process remarkably easy. |
| 15 | + |
| 16 | +```rust |
| 17 | +grevm::scheduler |
| 18 | +impl<DB> GrevmScheduler<DB> |
| 19 | +where |
| 20 | + DB: DatabaseRef + Send + Sync + 'static, |
| 21 | + DB::Error: Send + Sync, |
| 22 | +pub fn new(spec_id: SpecId, env: Env, db: DB, txs: Vec<TxEnv>) -> Self |
| 23 | + |
| 24 | +pub fn parallel_execute(mut self) -> Result<ExecuteOutput, GrevmError<DB::Error> |
| 25 | +``` |
| 26 | + |
| 27 | +In the code above, the generic constraint for `DB` is relatively relaxed; `DB` only needs to implement `DatabaseRef`, a read-only database trait provided by `revm` for Ethereum Virtual Machine interactions. Because this is a read-only interface, it naturally satisfies the `Send` and `Sync` traits. However, the `'static` constraint, which prevents `DB` from containing reference types (`&`), may not be met by all `DB` implementations. This `'static` requirement is introduced by `tokio` in Grevm, as `tokio` requires that objects have lifetimes independent of any references. |
| 28 | + |
| 29 | +Grevm addresses this limitation by ensuring that internal object lifetimes do not exceed its own, offering an `unsafe` alternative method, `new_grevm_scheduler`, for creating `GrevmScheduler`. This method allows developers to bypass the `'static` constraint if they are confident in managing lifetimes safely. |
| 30 | + |
| 31 | +```rust |
| 32 | +pub fn new_grevm_scheduler<DB>( |
| 33 | + spec_id: SpecId, |
| 34 | + env: Env, |
| 35 | + db: DB, |
| 36 | + txs: Vec<TxEnv>, |
| 37 | +) -> GrevmScheduler<DatabaseWrapper<DB::Error>> |
| 38 | +where |
| 39 | + DB: DatabaseRef + Send + Sync, |
| 40 | + DB::Error: Send + Sync, |
| 41 | +``` |
| 42 | + |
| 43 | +### Introduce Grevm to Reth |
| 44 | + |
| 45 | +Reth provides a `BlockExecutorProvider` to create an `Executor` for executing transactions. In theory, integrating Grevm should only require creating an `EthGrevmExecutor`. However, `BlockExecutorProvider` imposes a `DB` constraint that uses the `Database` trait, which is a mutable interface and doesn’t align with Grevm’s read-only requirements. In practice, the passed `DB` parameter does fulfill the `DatabaseRef` trait, which Grevm requires. Therefore, it’s necessary to add a `parallel_executor` to `BlockExecutorProvider` to introduce a `DatabaseRef` constraint. |
| 46 | + |
| 47 | +```rust |
| 48 | +pub trait ParallelDatabase: DatabaseRef<Error: Send + Sync> + Send + Sync {} |
| 49 | + |
| 50 | +impl<EvmConfig> BlockExecutorProvider for EthExecutorProvider<EvmConfig> |
| 51 | +where |
| 52 | + EvmConfig: ConfigureEvm, |
| 53 | +{ |
| 54 | + fn parallel_executor<DB>(&self, db: DB) -> Self::ParallelExecutor<DB> |
| 55 | + where |
| 56 | + DB: ParallelDatabase<Error: Into<ProviderError> + Display + Clone>, |
| 57 | + { |
| 58 | + EthGrevmExecutor::new(self.chain_spec.clone(), self.evm_config.clone(), db) |
| 59 | + } |
| 60 | +} |
| 61 | +``` |
| 62 | + |
| 63 | +The integration code for connecting Grevm to Reth is already complete. You can check it out here: [Introduce Grevm to Reth](https://github.com/Galxe/grevm-reth/commit/52472e6c6b125d5f038e93f6c5eddc57b230ba66) |
| 64 | + |
| 65 | +## Metrics |
| 66 | + |
| 67 | +To monitor and observe execution performance, Grevm uses the `metrics` crate from [crates.io](https://crates.io/crates/metrics). Users can integrate the [Prometheus exporter](https://crates.io/crates/metrics-exporter-prometheus) within their code to expose metrics data, which can then be configured in Grafana for real-time monitoring and visualization. Below is a table that provides the names and descriptions of various metric indicators: |
| 68 | + |
| 69 | +| Metric Name | Description | |
| 70 | +| --- | --- | |
| 71 | +| grevm.parallel_round_calls | Number of times parallel execution is called. | |
| 72 | +| grevm.sequential_execute_calls | Number of times sequential execution is called. | |
| 73 | +| grevm.total_tx_cnt | Total number of transactions. | |
| 74 | +| grevm.parallel_tx_cnt | Number of transactions executed in parallel. | |
| 75 | +| grevm.sequential_tx_cnt | Number of transactions executed sequentially. | |
| 76 | +| grevm.finality_tx_cnt | Number of transactions that encountered conflicts. | |
| 77 | +| grevm.conflict_tx_cnt | Number of transactions that reached finality. | |
| 78 | +| grevm.unconfirmed_tx_cnt | Number of transactions that are unconfirmed. | |
| 79 | +| grevm.reusable_tx_cnt | Number of reusable transactions. | |
| 80 | +| grevm.skip_validation_cnt | Number of transactions that skip validation | |
| 81 | +| grevm.concurrent_partition_num | Number of concurrent partitions. | |
| 82 | +| grevm.partition_execution_time_diff | Execution time difference between partitions(in nanoseconds). | |
| 83 | +| grevm.partition_num_tx_diff | Number of transactions difference between partitions. | |
| 84 | +| grevm.parse_hints_time | Time taken to parse execution hints(in nanoseconds). | |
| 85 | +| grevm.partition_tx_time | Time taken to partition transactions(in nanoseconds). | |
| 86 | +| grevm.parallel_execute_time | Time taken to validate transactions(in nanoseconds). | |
| 87 | +| grevm.validate_time | Time taken to execute(in nanoseconds). | |
| 88 | +| grevm.merge_write_set_time | Time taken to merge write set(in nanoseconds). | |
| 89 | +| grevm.commit_transition_time | Time taken to commit transition(in nanoseconds). | |
| 90 | +| grevm.build_output_time | Time taken to build output(in nanoseconds). | |
0 commit comments