Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use DaService in sov-ethereum. #668

Merged
merged 7 commits into from
Aug 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/demo-rollup/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ prettytable-rs = "^0.10"
criterion = "0.5.1"

[features]
default = []
experimental = ["sov-ethereum/experimental"]

[[bench]]
Expand Down
2 changes: 1 addition & 1 deletion examples/demo-rollup/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ async fn main() -> Result<(), anyhow::Error> {
register_ledger(ledger_db.clone(), &mut methods)?;
register_sequencer(da_service.clone(), &mut app, &mut methods)?;
#[cfg(feature = "experimental")]
register_ethereum(rollup_config.da.clone(), &mut methods)?;
register_ethereum(da_service.clone(), &mut methods)?;
}

let storage = app.get_storage();
Expand Down
9 changes: 4 additions & 5 deletions examples/demo-rollup/src/register_rpc.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//! Full-Node specific RPC methods.
use std::sync::Arc;

use anyhow::Context;
use demo_stf::app::App;
Expand All @@ -24,7 +23,7 @@ where
DA: DaService<Error = anyhow::Error> + Send + Sync + 'static,
{
let batch_builder = demo_runner.batch_builder.take().unwrap();
let sequencer_rpc = get_sequencer_rpc(batch_builder, Arc::new(da_service));
let sequencer_rpc = get_sequencer_rpc(batch_builder, da_service);
methods
.merge(sequencer_rpc)
.context("Failed to merge Txs RPC modules")
Expand All @@ -43,8 +42,8 @@ pub fn register_ledger(

#[cfg(feature = "experimental")]
/// register ethereum methods.
pub fn register_ethereum(
da_config: jupiter::da_service::DaServiceConfig,
pub fn register_ethereum<DA: DaService>(
da_service: DA,
methods: &mut jsonrpsee::RpcModule<()>,
) -> Result<(), anyhow::Error> {
use std::fs;
Expand All @@ -60,7 +59,7 @@ pub fn register_ethereum(
)
.unwrap();

let ethereum_rpc = sov_ethereum::get_ethereum_rpc(da_config, tx_signer_private_key);
let ethereum_rpc = sov_ethereum::get_ethereum_rpc(da_service, tx_signer_private_key);
methods
.merge(ethereum_rpc)
.context("Failed to merge Ethereum RPC modules")
Expand Down
1 change: 1 addition & 0 deletions full-node/sov-ethereum/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ resolver = "2"

[dependencies]
jsonrpsee = { workspace = true, features = ["http-client", "server"] }
sov-rollup-interface = { path = "../../rollup-interface" }

sov-evm = { path = "../../module-system/module-implementations/sov-evm", default-features = false }
demo-stf = { path = "../../examples/demo-stf", features = ["native"] }
Expand Down
74 changes: 17 additions & 57 deletions full-node/sov-ethereum/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,47 +7,42 @@ pub mod experimental {
use std::sync::Mutex;

use borsh::ser::BorshSerialize;
use const_rollup_config::ROLLUP_NAMESPACE_RAW;
use demo_stf::app::DefaultPrivateKey;
use demo_stf::runtime::{DefaultContext, Runtime};
use ethers::types::{Bytes, H256};
use jsonrpsee::core::client::ClientT;
use jsonrpsee::core::params::ArrayParams;
use jsonrpsee::http_client::{HeaderMap, HttpClient};
use jsonrpsee::types::ErrorObjectOwned;
use jsonrpsee::RpcModule;
use jupiter::da_service::DaServiceConfig;
use reth_primitives::TransactionSignedNoHash as RethTransactionSignedNoHash;
use reth_rpc::eth::error::EthApiError;
use sov_evm::call::CallMessage;
use sov_evm::evm::{EthAddress, RawEvmTransaction};
use sov_modules_api::transaction::Transaction;
use sov_modules_api::utils::to_jsonrpsee_error_object;
use sov_modules_api::EncodeCall;
use sov_rollup_interface::services::da::DaService;

const GAS_PER_BYTE: usize = 120;
const ETH_RPC_ERROR: &str = "ETH_RPC_ERROR";

pub fn get_ethereum_rpc(
config: DaServiceConfig,
pub fn get_ethereum_rpc<DA: DaService>(
da_service: DA,
tx_signer_prov_key: DefaultPrivateKey,
) -> RpcModule<Ethereum> {
) -> RpcModule<Ethereum<DA>> {
let mut rpc = RpcModule::new(Ethereum {
config,
nonces: Default::default(),
tx_signer_prov_key,
da_service,
});
register_rpc_methods(&mut rpc).expect("Failed to register sequencer RPC methods");
rpc
}

pub struct Ethereum {
config: DaServiceConfig,
pub struct Ethereum<DA: DaService> {
nonces: Mutex<HashMap<EthAddress, u64>>,
tx_signer_prov_key: DefaultPrivateKey,
da_service: DA,
}

impl Ethereum {
impl<DA: DaService> Ethereum<DA> {
fn make_raw_tx(
&self,
raw_tx: RawEvmTransaction,
Expand Down Expand Up @@ -81,45 +76,9 @@ pub mod experimental {
}
}

impl Ethereum {
fn make_client(&self) -> HttpClient {
let mut headers = HeaderMap::new();
headers.insert(
"Authorization",
format!("Bearer {}", self.config.celestia_rpc_auth_token.clone())
.parse()
.unwrap(),
);

jsonrpsee::http_client::HttpClientBuilder::default()
.set_headers(headers)
.max_request_size(default_max_response_size())
.build(self.config.celestia_rpc_address.clone())
.expect("Client initialization is valid")
}

async fn send_tx_to_da(
&self,
raw: Vec<u8>,
) -> Result<serde_json::Value, jsonrpsee::core::Error> {
let blob = vec![raw].try_to_vec()?;
let client = self.make_client();
let fee: u64 = 2000;
let namespace = ROLLUP_NAMESPACE_RAW.to_vec();
let gas_limit = (blob.len() + 512) * GAS_PER_BYTE + 1060;

let mut params = ArrayParams::new();
params.insert(namespace)?;
params.insert(blob)?;
params.insert(fee.to_string())?;
params.insert(gas_limit)?;
client
.request::<serde_json::Value, _>("state.SubmitPayForBlob", params)
.await
}
}

fn register_rpc_methods(rpc: &mut RpcModule<Ethereum>) -> Result<(), jsonrpsee::core::Error> {
fn register_rpc_methods<DA: DaService>(
rpc: &mut RpcModule<Ethereum<DA>>,
) -> Result<(), jsonrpsee::core::Error> {
rpc.register_async_method(
"eth_sendRawTransaction",
|parameters, ethereum| async move {
Expand All @@ -130,8 +89,13 @@ pub mod experimental {
.make_raw_tx(raw_evm_tx)
.map_err(|e| to_jsonrpsee_error_object(e, ETH_RPC_ERROR))?;

let blob = vec![raw_tx]
.try_to_vec()
.map_err(|e| to_jsonrpsee_error_object(e, ETH_RPC_ERROR))?;

ethereum
.send_tx_to_da(raw_tx)
.da_service
.send_transaction(&blob)
.await
.map_err(|e| to_jsonrpsee_error_object(e, ETH_RPC_ERROR))?;

Expand All @@ -141,8 +105,4 @@ pub mod experimental {

Ok(())
}

fn default_max_response_size() -> u32 {
1024 * 1024 * 100 // 100 MB
}
}
19 changes: 9 additions & 10 deletions full-node/sov-sequencer/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::sync::{Arc, Mutex};
use std::sync::Mutex;

use anyhow::anyhow;
use jsonrpsee::types::ErrorObjectOwned;
Expand All @@ -12,12 +12,12 @@ const SEQUENCER_RPC_ERROR: &str = "SEQUENCER_RPC_ERROR";
/// Single data structure that manages mempool and batch producing.
pub struct Sequencer<B: BatchBuilder, T: DaService> {
batch_builder: Mutex<B>,
da_service: Arc<T>,
da_service: T,
}

impl<B: BatchBuilder + Send + Sync, T: DaService + Send + Sync> Sequencer<B, T> {
/// Creates new Sequencer from BatchBuilder and DaService
pub fn new(batch_builder: B, da_service: Arc<T>) -> Self {
pub fn new(batch_builder: B, da_service: T) -> Self {
Self {
batch_builder: Mutex::new(batch_builder),
da_service,
Expand Down Expand Up @@ -59,7 +59,7 @@ fn register_txs_rpc_methods<B, D>(
) -> Result<(), jsonrpsee::core::Error>
where
B: BatchBuilder + Send + Sync + 'static,
D: DaService + Send + Sync + 'static,
D: DaService,
{
rpc.register_async_method("sequencer_publishBatch", |_, batch_builder| async move {
batch_builder
Expand All @@ -79,10 +79,10 @@ where
Ok(())
}

pub fn get_sequencer_rpc<B, D>(batch_builder: B, da_service: Arc<D>) -> RpcModule<Sequencer<B, D>>
pub fn get_sequencer_rpc<B, D>(batch_builder: B, da_service: D) -> RpcModule<Sequencer<B, D>>
where
B: BatchBuilder + Send + Sync + 'static,
D: DaService + Send + Sync + 'static,
D: DaService,
{
let sequencer = Sequencer::new(batch_builder, da_service);
let mut rpc = RpcModule::new(sequencer);
Expand All @@ -109,7 +109,6 @@ pub enum SubmitTransactionResponse {

#[cfg(test)]
mod tests {
use std::sync::Arc;

use sov_rollup_interface::mocks::{MockBatchBuilder, MockDaService};

Expand All @@ -118,7 +117,7 @@ mod tests {
#[tokio::test]
async fn test_submit_on_empty_mempool() {
let batch_builder = MockBatchBuilder { mempool: vec![] };
let da_service = Arc::new(MockDaService::default());
let da_service = MockDaService::default();
assert!(da_service.is_empty());
let rpc = get_sequencer_rpc(batch_builder, da_service.clone());

Expand All @@ -140,7 +139,7 @@ mod tests {
let batch_builder = MockBatchBuilder {
mempool: vec![tx1.clone(), tx2.clone()],
};
let da_service = Arc::new(MockDaService::default());
let da_service = MockDaService::default();
assert!(da_service.is_empty());
let rpc = get_sequencer_rpc(batch_builder, da_service.clone());

Expand All @@ -159,7 +158,7 @@ mod tests {
#[tokio::test]
async fn test_accept_tx() {
let batch_builder = MockBatchBuilder { mempool: vec![] };
let da_service = Arc::new(MockDaService::default());
let da_service = MockDaService::default();

let rpc = get_sequencer_rpc(batch_builder, da_service.clone());
assert!(da_service.is_empty());
Expand Down
6 changes: 3 additions & 3 deletions rollup-interface/src/node/services/da.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! The da module defines traits used by the full node to interact with the DA layer.
use std::fmt;
use std::fmt::{self, Display};

use async_trait::async_trait;
use serde::de::DeserializeOwned;
Expand All @@ -14,7 +14,7 @@ use crate::zk::ValidityCondition;
/// The DaService has two responsibilities - fetching data from the DA layer, transforming the
/// data into a representation that can be efficiently verified in circuit.
#[async_trait]
pub trait DaService {
pub trait DaService: Send + Sync + 'static {
/// A handle to the types used by the DA layer.
type RuntimeConfig: DeserializeOwned;

Expand All @@ -28,7 +28,7 @@ pub trait DaService {
>;

/// The error type for fallible methods.
type Error: fmt::Debug + Send + Sync;
type Error: fmt::Debug + Send + Sync + Display;

/// Create a new instance of the DaService
async fn new(
Expand Down