Skip to content

Commit

Permalink
feat(ethexe): dev mode, set blob via rpc (#4458)
Browse files Browse the repository at this point in the history
  • Loading branch information
osipov-mit authored Jan 23, 2025
1 parent 290c495 commit 7fce290
Show file tree
Hide file tree
Showing 12 changed files with 128 additions and 24 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

10 changes: 8 additions & 2 deletions ethexe/cli/src/params/ethereum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,16 @@ pub struct EthereumParams {
#[arg(long, alias = "eth-router")]
#[serde(rename = "router")]
pub ethereum_router: Option<String>,

/// Ethereum block time in seconds.
#[arg(long, alias = "eth-block-time")]
#[serde(rename = "block-time")]
pub block_time: Option<u64>,
}

impl EthereumParams {
/// Default block time in seconds.
pub const BLOCK_TIME: usize = 12;
pub const BLOCK_TIME: u64 = 12;

/// Default Ethereum RPC.
pub const DEFAULT_ETHEREUM_RPC: &str = "http://localhost:8545";
Expand All @@ -67,7 +72,7 @@ impl EthereumParams {
.ok_or_else(|| anyhow!("missing `ethereum-router`"))?
.parse()
.with_context(|| "invalid `ethereum-router`")?,
block_time: Duration::from_secs(Self::BLOCK_TIME as u64),
block_time: Duration::from_secs(self.block_time.unwrap_or(Self::BLOCK_TIME)),
})
}
}
Expand All @@ -78,6 +83,7 @@ impl MergeParams for EthereumParams {
ethereum_rpc: self.ethereum_rpc.or(with.ethereum_rpc),
ethereum_beacon_rpc: self.ethereum_beacon_rpc.or(with.ethereum_beacon_rpc),
ethereum_router: self.ethereum_router.or(with.ethereum_router),
block_time: self.block_time.or(with.block_time),
}
}
}
3 changes: 2 additions & 1 deletion ethexe/cli/src/params/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ impl Params {
pub fn into_config(self) -> Result<Config> {
let node = self.node.ok_or_else(|| anyhow!("missing node params"))?;
let net_dir = node.net_dir();
let dev = node.dev;

let ethereum = self
.ethereum
Expand All @@ -88,7 +89,7 @@ impl Params {
.network
.and_then(|p| p.into_config(net_dir).transpose())
.transpose()?,
rpc: self.rpc.and_then(|p| p.into_config()),
rpc: self.rpc.and_then(|p| p.into_config(dev)),
prometheus: self.prometheus.and_then(|p| p.into_config()),
})
}
Expand Down
10 changes: 8 additions & 2 deletions ethexe/cli/src/params/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ pub struct NodeParams {
#[serde(default)]
pub tmp: bool,

/// Flag to run node in development mode.
#[arg(long)]
#[serde(default)]
pub dev: bool,

/// Public key of the sequencer, if node should act as one.
#[arg(long)]
pub sequencer: Option<String>,
Expand Down Expand Up @@ -87,12 +92,13 @@ impl NodeParams {
.virtual_threads
.unwrap_or(Self::DEFAULT_VIRTUAL_THREADS)
.get() as usize,
dev: self.dev,
})
}

/// Get path to the database directory.
pub fn db_dir(&self) -> PathBuf {
if self.tmp {
if self.tmp || self.dev {
Self::tmp_db()
} else {
self.base().join("db")
Expand Down Expand Up @@ -144,7 +150,7 @@ impl MergeParams for NodeParams {
Self {
base: self.base.or(with.base),
tmp: self.tmp || with.tmp,

dev: self.dev || with.dev,
sequencer: self.sequencer.or(with.sequencer),
validator: self.validator.or(with.validator),

Expand Down
8 changes: 6 additions & 2 deletions ethexe/cli/src/params/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ impl RpcParams {
pub const DEFAULT_RPC_PORT: u16 = 9944;

/// Convert self into a proper `RpcConfig` object, if RPC service is enabled.
pub fn into_config(self) -> Option<RpcConfig> {
pub fn into_config(self, dev: bool) -> Option<RpcConfig> {
if self.no_rpc {
return None;
}
Expand Down Expand Up @@ -83,7 +83,11 @@ impl RpcParams {
})
.into();

Some(RpcConfig { listen_addr, cors })
Some(RpcConfig {
listen_addr,
cors,
dev,
})
}
}

Expand Down
1 change: 1 addition & 0 deletions ethexe/rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ ethexe-runtime-common = { workspace = true, features = ["std"] }
sp-core = { workspace = true, features = ["serde"] }
gear-core = { workspace = true, features = ["std"] }
serde = { workspace = true, features = ["std"] }
ethexe-observer.workspace = true
57 changes: 57 additions & 0 deletions ethexe/rpc/src/apis/dev.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// This file is part of Gear.
//
// Copyright (C) 2024 Gear Technologies Inc.
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use std::sync::Arc;

use ethexe_observer::MockBlobReader;
use gear_core::ids::prelude::CodeIdExt;
use gprimitives::{CodeId, H256};
use jsonrpsee::{
core::{async_trait, RpcResult},
proc_macros::rpc,
};
use sp_core::Bytes;

#[rpc(server)]
pub trait Dev {
#[method(name = "dev_setBlob")]
async fn set_blob(&self, blob: Bytes) -> RpcResult<(H256, CodeId)>;
}

#[derive(Clone)]
pub struct DevApi {
blob_reader: Arc<MockBlobReader>,
}

impl DevApi {
pub fn new(blob_reader: Arc<MockBlobReader>) -> Self {
Self { blob_reader }
}
}

#[async_trait]
impl DevServer for DevApi {
async fn set_blob(&self, blob: Bytes) -> RpcResult<(H256, CodeId)> {
let code_id = CodeId::generate(&blob);
let blob_tx = H256::random();

self.blob_reader.add_blob_transaction(blob_tx, blob.0).await;

Ok((blob_tx, code_id))
}
}
2 changes: 2 additions & 0 deletions ethexe/rpc/src/apis/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.

mod block;
mod dev;
mod program;

pub use block::{BlockApi, BlockServer};
pub use dev::{DevApi, DevServer};
pub use program::{ProgramApi, ProgramServer};
22 changes: 18 additions & 4 deletions ethexe/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use anyhow::{anyhow, Result};
use apis::{BlockApi, BlockServer, ProgramApi, ProgramServer};
use apis::{BlockApi, BlockServer, DevApi, DevServer, ProgramApi, ProgramServer};
use ethexe_db::Database;
use ethexe_observer::MockBlobReader;
use futures::FutureExt;
use jsonrpsee::{
server::{
Expand All @@ -27,7 +28,7 @@ use jsonrpsee::{
},
Methods, RpcModule as JsonrpcModule,
};
use std::net::SocketAddr;
use std::{net::SocketAddr, sync::Arc};
use tokio::net::TcpListener;
use tower::Service;

Expand All @@ -51,16 +52,23 @@ pub struct RpcConfig {
pub listen_addr: SocketAddr,
/// CORS.
pub cors: Option<Vec<String>>,
/// Dev mode.
pub dev: bool,
}

pub struct RpcService {
config: RpcConfig,
db: Database,
blob_reader: Option<Arc<MockBlobReader>>,
}

impl RpcService {
pub fn new(config: RpcConfig, db: Database) -> Self {
Self { config, db }
pub fn new(config: RpcConfig, db: Database, blob_reader: Option<Arc<MockBlobReader>>) -> Self {
Self {
config,
db,
blob_reader,
}
}

pub const fn port(&self) -> u16 {
Expand All @@ -82,6 +90,12 @@ impl RpcService {
module.merge(ProgramServer::into_rpc(ProgramApi::new(self.db.clone())))?;
module.merge(BlockServer::into_rpc(BlockApi::new(self.db.clone())))?;

if self.config.dev {
module.merge(DevServer::into_rpc(DevApi::new(
self.blob_reader.unwrap().clone(),
)))?;
}

let (stop_handle, server_handle) = stop_channel();

let cfg = PerConnection {
Expand Down
1 change: 1 addition & 0 deletions ethexe/service/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ pub struct NodeConfig {
pub max_commitment_depth: u32,
pub worker_threads_override: Option<usize>,
pub virtual_threads: usize,
pub dev: bool,
}

#[derive(Debug)]
Expand Down
35 changes: 22 additions & 13 deletions ethexe/service/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use ethexe_common::{
use ethexe_db::{BlockMetaStorage, CodesStorage, Database};
use ethexe_ethereum::{primitives::U256, router::RouterQuery};
use ethexe_network::{db_sync, NetworkReceiverEvent};
use ethexe_observer::{RequestBlockData, RequestEvent};
use ethexe_observer::{MockBlobReader, RequestBlockData, RequestEvent};
use ethexe_processor::{LocalOutcome, ProcessorConfig};
use ethexe_prometheus::MetricsService;
use ethexe_sequencer::agro::AggregatedCommitments;
Expand Down Expand Up @@ -84,15 +84,25 @@ pub enum NetworkMessage {

impl Service {
pub async fn new(config: &Config) -> Result<Self> {
let blob_reader = Arc::new(
ethexe_observer::ConsensusLayerBlobReader::new(
&config.ethereum.rpc,
&config.ethereum.beacon_rpc,
config.ethereum.block_time,
let mock_blob_reader: Option<Arc<MockBlobReader>> = if config.node.dev {
Some(Arc::new(MockBlobReader::new(config.ethereum.block_time)))
} else {
None
};

let blob_reader: Arc<dyn ethexe_observer::BlobReader> = if config.node.dev {
mock_blob_reader.clone().unwrap()
} else {
Arc::new(
ethexe_observer::ConsensusLayerBlobReader::new(
&config.ethereum.rpc,
&config.ethereum.beacon_rpc,
config.ethereum.block_time,
)
.await
.with_context(|| "failed to create blob reader")?,
)
.await
.with_context(|| "failed to create blob reader")?,
);
};

let rocks_db = ethexe_db::RocksDatabase::open(config.node.database_path.clone())
.with_context(|| "failed to open database")?;
Expand Down Expand Up @@ -227,10 +237,9 @@ impl Service {
None
};

let rpc = config
.rpc
.as_ref()
.map(|config| ethexe_rpc::RpcService::new(config.clone(), db.clone()));
let rpc = config.rpc.as_ref().map(|config| {
ethexe_rpc::RpcService::new(config.clone(), db.clone(), mock_blob_reader.clone())
});

Ok(Self {
db,
Expand Down
2 changes: 2 additions & 0 deletions ethexe/service/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ async fn basics() {
max_commitment_depth: 1_000,
worker_threads_override: None,
virtual_threads: 16,
dev: true,
};

let eth_cfg = crate::config::EthereumConfig {
Expand Down Expand Up @@ -106,6 +107,7 @@ async fn basics() {
config.rpc = Some(RpcConfig {
listen_addr: SocketAddr::new(Ipv4Addr::LOCALHOST.into(), 9944),
cors: None,
dev: true,
});

config.prometheus = Some(PrometheusConfig::new_with_default_registry(
Expand Down

0 comments on commit 7fce290

Please sign in to comment.