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

feat: impl operator #6

Merged
merged 5 commits into from
Apr 23, 2024
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
358 changes: 357 additions & 1 deletion Cargo.lock

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ reth-libmdbx = { git = "https://github.com/0xEigenLabs/reth", package = "reth-li
#reth-node-core = { path = "../reth/crates/node-core" }
#reth-node-api = { path = "../reth/crates/node-api" }
#reth-rpc-types = { path = "../reth/crates/rpc/rpc-types" }
ethers-providers = { version = "2.0.14", features = ["ws"] }
ethers-core = { version = "2.0.14", default-features = false }


# Async
Expand Down Expand Up @@ -85,4 +87,4 @@ pretty_assertions = "1.4.0"


[build-dependencies]
tonic-build = "0.8.0"
tonic-build = "0.8.0"
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ rm -rf /tmp/chain
reth init --datadir /tmp/chain --chain testdata/chain.json
RUST_LOG="debug,evm=trace,consensus::auto=trace,consensus::engine=trace,rpc::eth=trace" reth node -d --chain testdata/chain.json --datadir /tmp/chain --auto-mine --http --http.port 8546 --http.api debug,eth,net,trace,web3,rpc

RUST_LOG="rpc::eth=trace" RETH_DB_PATH=/tmp/chain cargo run -r
RUST_LOG="rpc::eth=trace" ZETH_DB_PATH=/tmp/chain ZETH_OPERATOR_DB=/tmp/operator PROVER_ADDR=localhost:50061 ZETH_L2_ADDR=http://localhost:8546 HOST=0.0.0.0:8182 cargo run -r
```


Expand Down
1 change: 0 additions & 1 deletion src/db/db_utils/libmdbx.rs

This file was deleted.

32 changes: 0 additions & 32 deletions src/db/db_utils/mod.rs

This file was deleted.

226 changes: 226 additions & 0 deletions src/db/lfs/libmdbx.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
// TODO: Fix me
#![allow(dead_code)]
#![allow(unused_imports)]

use crate::db::lfs::libmdbx;
use crate::db::Database as EigenDB;
use reth_libmdbx::*;
use std::fs;

pub struct Db(MdbxDB);

impl Db {
pub fn new(env: Environment, default_db: Database) -> Self {
Db(MdbxDB { env, default_db })
}
}

pub struct MdbxDB {
env: Environment,
default_db: Database,
}

pub fn open_mdbx_db(path: &str, max_dbs: usize) -> std::result::Result<Box<dyn EigenDB>, ()> {
// create the directory if it does not exist
// TODO: catch errors
fs::create_dir_all(path).unwrap();

let env = match Environment::builder()
.set_max_dbs(max_dbs)
.open(std::path::Path::new(path))
{
Ok(env) => env,
Err(e) => {
println!("Error opening the environment: {:?}", e);
return Err(());
}
};

let txn_open_default_db = env.begin_rw_txn().unwrap();
let default_db = match txn_open_default_db.create_db(None, reth_libmdbx::DatabaseFlags::empty())
{
Ok(db) => db,
Err(e) => {
println!("Error creating the default database: {:?}", e);
return Err(());
}
};

// TODO: catch errors
txn_open_default_db.commit().unwrap();

Ok(Box::new(libmdbx::Db::new(env, default_db)))
}

impl EigenDB for Db {
fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
let txn = self.0.env.begin_ro_txn().unwrap();
let value: Option<Vec<u8>> = txn.get(self.0.default_db.dbi(), key).unwrap();
value
}

fn put(&mut self, key: Vec<u8>, value: Vec<u8>) {
let txn = self.0.env.begin_rw_txn().unwrap();
txn.put(self.0.default_db.dbi(), key, value, WriteFlags::empty())
.unwrap();
txn.commit().unwrap();
}

fn del(&mut self, key: Vec<u8>) -> Option<Vec<u8>> {
let txn = self.0.env.begin_rw_txn().unwrap();
let value: Option<Vec<u8>> = txn.get(self.0.default_db.dbi(), &key).unwrap();
let success = txn.del(self.0.default_db.dbi(), &key, None).unwrap();
// TODO: catch errors
txn.commit().unwrap();
if !success {
return None;
}
value
}
}

#[cfg(test)]
mod tests {
use super::*;
use std::{fs, string};

#[test]
fn test_open_mdbx_db() {
let path = "tmp/test_open_mdbx_db";
let max_dbs = 20;
let _ = open_mdbx_db(path, max_dbs).unwrap();
fs::remove_dir_all(path).unwrap();
}

#[test]
fn test_eigen_mdbx() {
let path = "tmp/test_eigen_mdbx_dn";
let max_dbs = 20;
let mut db = open_mdbx_db(path, max_dbs).unwrap();

let key = b"key";
// let key = string::String::from("value").into_bytes();
let value = string::String::from(
"value-11111111111111111111111111111111111111111111111111111111111111111111111111",
)
.into_bytes();

// get a key-value pair from the default database
// will return None because the key does not exist
let get_val = db.get(key);
assert_eq!(None, get_val);

// put a key-value pair in the default database
// get a key-value pair from the default database again
// and check if the value is the same as the one we put
db.put(key.to_vec(), value.clone());
let get_val = db.get(key);
assert_eq!(Some(value.clone()), get_val);

// del a key-value pair from the default database
// get a key-value pair from the default database again
// will return None because the key was deleted
db.del(key.to_vec());
let get_val = db.get(key);
assert_eq!(None, get_val);

// remove test directory
fs::remove_dir_all(path).unwrap();
}

#[test]
fn test_reth_libmdbx() {
use reth_libmdbx::{EnvironmentBuilder, WriteFlags};

// path to the database
let path = "tmp/test_mdbx";
// create the directory if it does not exist
fs::create_dir_all(path).unwrap();

// initialize the environment
let env = match Environment::builder()
.set_max_dbs(20)
.open(std::path::Path::new(path))
{
Ok(env) => env,
Err(e) => {
println!("Error opening the environment: {:?}", e);
return;
}
};

let txn_prepare = env.begin_rw_txn().unwrap();

// use the default database
let default_db = match txn_prepare.create_db(None, DatabaseFlags::empty()) {
Ok(db) => db,
Err(e) => {
println!("Error creating the default database: {:?}", e);
return;
}
};

// create and use a new database
let db1 = match txn_prepare.create_db(Some("my_database_1"), DatabaseFlags::empty()) {
Ok(db) => db,
Err(e) => {
println!("Error creating the database: {:?}", e);
return;
}
};

txn_prepare.commit().unwrap();

let key = b"key";
// let key = string::String::from("value").into_bytes();
let value = string::String::from(
"value-11111111111111111111111111111111111111111111111111111111111111111111111111",
)
.into_bytes();

// put and get a key-value pair from following databases: default, my_database_1
let txn = env.begin_rw_txn().unwrap();

// put and get a key-value pair in the default database
txn.put(default_db.dbi(), key, value.clone(), WriteFlags::empty())
.unwrap();
let fetched_value_1: Option<Vec<u8>> = txn.get(default_db.dbi(), key).unwrap();
assert_eq!(
Some(
b"value-11111111111111111111111111111111111111111111111111111111111111111111111111"
.to_vec()
),
fetched_value_1
);

// put and get a key-value pair in the new database
txn.put(db1.dbi(), key, value.clone(), WriteFlags::empty())
.unwrap();
let fetched_value_2: Option<Vec<u8>> = txn.get(db1.dbi(), key).unwrap();
assert_eq!(
Some(
b"value-11111111111111111111111111111111111111111111111111111111111111111111111111"
.to_vec()
),
fetched_value_2
);

txn.commit().unwrap();

// del and get a key-value pair from the following databases: default, my_database_1
let txn2 = env.begin_rw_txn().unwrap();

txn2.del(default_db.dbi(), key, None).unwrap();
let fetched_value_1_when_del: Option<Vec<u8>> = txn2.get(default_db.dbi(), key).unwrap();
assert_eq!(None, fetched_value_1_when_del);

txn2.del(db1.dbi(), key, None).unwrap();
let fetched_value_2_when_del: Option<Vec<u8>> = txn2.get(db1.dbi(), key).unwrap();
assert_eq!(None, fetched_value_2_when_del);

txn2.commit().unwrap();

// remove test directory
fs::remove_dir_all(path).unwrap();
}
}
5 changes: 5 additions & 0 deletions src/db/db_utils/mem.rs → src/db/lfs/mem.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::db::lfs::mem;
use crate::db::Database as EigenDB;
use std::collections::HashMap;

Expand All @@ -17,3 +18,7 @@ impl EigenDB for Db {
self.0.remove(&key)
}
}

pub fn open_memory_db() -> Result<Box<dyn EigenDB>, ()> {
Ok(Box::new(mem::Db::default()))
}
27 changes: 27 additions & 0 deletions src/db/lfs/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// TODO: Fix me
#![allow(dead_code)]

mod libmdbx;
mod mem;

use crate::db::Database as EigenDB;

pub(crate) enum DBConfig {
/// memory kv-database
Memory,
/// libmdbx database
Mdbx {
/// Path to the mdbx database
// path: PathBuf,
path: String,
/// Maximum number of databases
max_dbs: usize,
},
}

pub(crate) fn open_db(config: DBConfig) -> Result<Box<dyn EigenDB>, ()> {
match config {
DBConfig::Memory => mem::open_memory_db(),
DBConfig::Mdbx { path, max_dbs } => libmdbx::open_mdbx_db(&path, max_dbs),
}
}
16 changes: 15 additions & 1 deletion src/db/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#![allow(dead_code)]

mod data_availability_db;
mod db_utils;
pub(crate) mod lfs;

/// TODO: we need a trait to abstract the database operations in order to support multiple databases

Expand All @@ -11,3 +11,17 @@ pub trait Database {
fn put(&mut self, key: Vec<u8>, value: Vec<u8>);
fn del(&mut self, key: Vec<u8>) -> Option<Vec<u8>>;
}

/// Used to represent different tables or columns or databases
/// Which is more appropriate to use among tables, columns, and databases to represent our data?
pub(crate) mod columns {
/// The number of columns in the DB
pub const TOTAL_COLUMNS: usize = 2;

/// The column for DEFAULT
pub const DEFAULT: usize = 0;

// TODO: others
/// The column for DATA_AVAILABILITY
pub const DATA_AVAILABILITY: usize = 1;
}
Loading
Loading