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: fetch block numbers in store api + refactor: remove unwraps from libmdx impl of store #150

Merged
merged 22 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
95c651a
Impl RLPDecode for BlockHeader
fmoletta Jul 12, 2024
1e2a66c
Extend Store api to fetch blocks + start implementing Decode for Tran…
fmoletta Jul 12, 2024
ac5f04e
Encode and Decode transactions with type
fmoletta Jul 12, 2024
d397b34
Impl RLPDecode for Withdrawal
fmoletta Jul 12, 2024
6d6a0f8
Complete api for libmdx
fmoletta Jul 12, 2024
63f5d18
Implement getters and setters for block in store api
fmoletta Jul 12, 2024
da19600
Fixes + add test
fmoletta Jul 12, 2024
5e5f792
Clippy
fmoletta Jul 12, 2024
847782d
Add api skeleton for other db impls
fmoletta Jul 12, 2024
9e485c5
Move test to main module + fix api
fmoletta Jul 12, 2024
db86801
Merge branch 'main' into add-block-api-to-db
fmoletta Jul 15, 2024
7e98b8a
Add mapping between block hash & block number to store api
fmoletta Jul 15, 2024
23133aa
reafctor: Remove unwraps from libmdx impl of Store
fmoletta Jul 15, 2024
ffeccbf
Add methods to store
fmoletta Jul 15, 2024
2ab77f5
Add test
fmoletta Jul 15, 2024
fe7ba64
clippy
fmoletta Jul 15, 2024
682fa90
Add table to init
fmoletta Jul 15, 2024
5b3beee
Merge branch 'main' of https://github.com/lambdaclass/ethrex into add…
fmoletta Jul 16, 2024
2cca6ba
Merge branch 'main' of https://github.com/lambdaclass/ethrex into add…
fmoletta Jul 16, 2024
4de8f45
Remove from attribute from StoreError::Libmdx
fmoletta Jul 16, 2024
6e023e1
Collect store tests in test_store_suite
fmoletta Jul 16, 2024
4b16d64
Merge branch 'main' into add-block-number-table
fmoletta Jul 16, 2024
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 crates/core/src/types/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use std::cmp::{max, Ordering};
use super::Transaction;

pub type BlockNumber = u64;
pub type BlockHash = H256;

use lazy_static::lazy_static;

Expand Down
16 changes: 15 additions & 1 deletion crates/storage/src/in_memory.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use super::{Key, StoreEngine, Value};
use crate::error::StoreError;
use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHeader, BlockNumber};
use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHash, BlockHeader, BlockNumber};
use ethereum_types::Address;
use std::{collections::HashMap, fmt::Debug};

#[derive(Default)]
pub struct Store {
account_infos: HashMap<Address, AccountInfo>,
block_numbers: HashMap<BlockHash, BlockNumber>,
bodies: HashMap<BlockNumber, BlockBody>,
headers: HashMap<BlockNumber, BlockHeader>,
values: HashMap<Key, Value>,
Expand Down Expand Up @@ -66,6 +67,19 @@ impl StoreEngine for Store {
self.bodies.insert(block_number, block_body);
Ok(())
}

fn add_block_number(
&mut self,
block_hash: BlockHash,
block_number: BlockNumber,
) -> Result<(), StoreError> {
self.block_numbers.insert(block_hash, block_number);
Ok(())
}

fn get_block_number(&self, block_hash: BlockHash) -> Result<Option<BlockNumber>, StoreError> {
Ok(self.block_numbers.get(&block_hash).copied())
}
}

impl Debug for Store {
Expand Down
67 changes: 55 additions & 12 deletions crates/storage/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use self::libmdbx::Store as LibmdbxStore;
use self::rocksdb::Store as RocksDbStore;
#[cfg(feature = "sled")]
use self::sled::Store as SledStore;
use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHeader, BlockNumber};
use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHash, BlockHeader, BlockNumber};
use ethereum_types::Address;
use std::fmt::Debug;
use std::sync::{Arc, Mutex};
Expand Down Expand Up @@ -67,6 +67,16 @@ pub trait StoreEngine: Debug + Send {
/// Obtain block body
fn get_block_body(&self, block_number: BlockNumber) -> Result<Option<BlockBody>, StoreError>;

/// Add block body
fn add_block_number(
&mut self,
block_hash: BlockHash,
block_number: BlockNumber,
) -> Result<(), StoreError>;

/// Obtain block number
fn get_block_number(&self, block_hash: BlockHash) -> Result<Option<BlockNumber>, StoreError>;

/// Set an arbitrary value (used for eventual persistent values: eg. current_block_height)
fn set_value(&mut self, key: Key, value: Value) -> Result<(), StoreError>;

Expand Down Expand Up @@ -179,6 +189,29 @@ impl Store {
.unwrap()
.get_block_body(block_number)
}

pub fn add_block_number(
&self,
block_hash: BlockHash,
block_number: BlockNumber,
) -> Result<(), StoreError> {
self.engine
.clone()
.lock()
.unwrap()
.add_block_number(block_hash, block_number)
}

pub fn get_block_number(
&self,
block_hash: BlockHash,
) -> Result<Option<BlockNumber>, StoreError> {
self.engine
.clone()
.lock()
.unwrap()
.get_block_number(block_hash)
}
}

#[cfg(test)]
Expand All @@ -199,8 +232,7 @@ mod tests {
#[test]
fn test_in_memory_store() {
let store = Store::new("test", EngineType::InMemory).unwrap();
test_store_account(store.clone());
test_store_block(store.clone());
test_store_suite(store);
}

#[cfg(feature = "libmdbx")]
Expand All @@ -209,9 +241,7 @@ mod tests {
// Removing preexistent DBs in case of a failed previous test
remove_test_dbs("test.mdbx");
let store = Store::new("test.mdbx", EngineType::Libmdbx).unwrap();
test_store_account(store.clone());
test_store_block(store.clone());

test_store_suite(store);
remove_test_dbs("test.mdbx");
}

Expand All @@ -221,9 +251,7 @@ mod tests {
// Removing preexistent DBs in case of a failed previous test
remove_test_dbs("test.sled");
let store = Store::new("test.sled", EngineType::Sled).unwrap();
test_store_account(store.clone());
// test_store_block(store.clone()); Unimplemented

test_store_suite(store);
remove_test_dbs("test.sled");
}

Expand All @@ -233,12 +261,16 @@ mod tests {
// Removing preexistent DBs in case of a failed previous test
remove_test_dbs("test.rocksdb");
let store = Store::new("test.rocksdb", EngineType::Sled).unwrap();
test_store_account(store.clone());
// test_store_block(store.clone()); Unimplemented

test_store_suite(store);
remove_test_dbs("test.rocksdb");
}

fn test_store_suite(store: Store) {
test_store_account(store.clone());
test_store_block(store.clone());
test_store_block_number(store.clone());
}

fn test_store_account(mut store: Store) {
let address = Address::random();
let code = Bytes::new();
Expand Down Expand Up @@ -347,4 +379,15 @@ mod tests {
};
(block_header, block_body)
}

fn test_store_block_number(store: Store) {
let block_hash = H256::random();
let block_number = 6;

store.add_block_number(block_hash, block_number).unwrap();

let stored_number = store.get_block_number(block_hash).unwrap().unwrap();

assert_eq!(stored_number, block_number);
}
}
120 changes: 70 additions & 50 deletions crates/storage/src/libmdbx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ use super::{Key, StoreEngine, Value};
use crate::error::StoreError;
use crate::rlp::{
AccountCodeHashRLP, AccountCodeRLP, AccountInfoRLP, AccountStorageKeyRLP,
AccountStorageValueRLP, AddressRLP, BlockBodyRLP, BlockHeaderRLP, ReceiptRLP,
AccountStorageValueRLP, AddressRLP, BlockBodyRLP, BlockHashRLP, BlockHeaderRLP, ReceiptRLP,
};
use anyhow::Result;
use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHeader};
use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHash, BlockHeader};
use ethereum_rust_core::types::{BlockNumber, Index};
use ethereum_types::Address;
use libmdbx::{
Expand Down Expand Up @@ -35,26 +35,22 @@ impl StoreEngine for Store {
account_info: AccountInfo,
) -> Result<(), StoreError> {
// Write account to mdbx
{
let txn = self.db.begin_readwrite().unwrap();
match txn.upsert::<AccountInfos>(address.into(), account_info.into()) {
Ok(_) => txn.commit().unwrap(),
Err(err) => return Err(StoreError::LibmdbxError(err)),
}
}
Ok(())
let txn = self
.db
.begin_readwrite()
.map_err(StoreError::LibmdbxError)?;
txn.upsert::<AccountInfos>(address.into(), account_info.into())
.map_err(StoreError::LibmdbxError)?;
txn.commit().map_err(StoreError::LibmdbxError)
}

fn get_account_info(&self, address: Address) -> Result<Option<AccountInfo>, StoreError> {
// Read account from mdbx
let read_value = {
let txn = self.db.begin_read().unwrap();
txn.get::<AccountInfos>(address.into())
};
match read_value {
Ok(value) => Ok(value.map(|a| a.to())),
Err(err) => Err(StoreError::LibmdbxError(err)),
}
let txn = self.db.begin_read().map_err(StoreError::LibmdbxError)?;
Ok(txn
.get::<AccountInfos>(address.into())
.map_err(StoreError::LibmdbxError)?
.map(|a| a.to()))
}

fn add_block_header(
Expand All @@ -63,29 +59,25 @@ impl StoreEngine for Store {
block_header: BlockHeader,
) -> std::result::Result<(), StoreError> {
// Write block header to mdbx
{
let txn = self.db.begin_readwrite().unwrap();
match txn.upsert::<Headers>(block_number, block_header.into()) {
Ok(_) => txn.commit().unwrap(),
Err(err) => return Err(StoreError::LibmdbxError(err)),
}
}
Ok(())
let txn = self
.db
.begin_readwrite()
.map_err(StoreError::LibmdbxError)?;
txn.upsert::<Headers>(block_number, block_header.into())
.map_err(StoreError::LibmdbxError)?;
txn.commit().map_err(StoreError::LibmdbxError)
}

fn get_block_header(
&self,
block_number: BlockNumber,
) -> std::result::Result<Option<BlockHeader>, StoreError> {
// Read block header from mdbx
let read_value = {
let txn = self.db.begin_read().unwrap();
txn.get::<Headers>(block_number)
};
match read_value {
Ok(value) => Ok(value.map(|a| a.to())),
Err(err) => Err(StoreError::LibmdbxError(err)),
}
let txn = self.db.begin_read().map_err(StoreError::LibmdbxError)?;
Ok(txn
.get::<Headers>(block_number)
.map_err(StoreError::LibmdbxError)?
.map(|h| h.to()))
}

fn add_block_body(
Expand All @@ -94,29 +86,50 @@ impl StoreEngine for Store {
block_body: BlockBody,
) -> std::result::Result<(), StoreError> {
// Write block body to mdbx
{
let txn = self.db.begin_readwrite().unwrap();
match txn.upsert::<Bodies>(block_number, block_body.into()) {
Ok(_) => txn.commit().unwrap(),
Err(err) => return Err(StoreError::LibmdbxError(err)),
}
}
Ok(())
let txn = self
.db
.begin_readwrite()
.map_err(StoreError::LibmdbxError)?;
txn.upsert::<Bodies>(block_number, block_body.into())
.map_err(StoreError::LibmdbxError)?;
txn.commit().map_err(StoreError::LibmdbxError)
}

fn get_block_body(
&self,
block_number: BlockNumber,
) -> std::result::Result<Option<BlockBody>, StoreError> {
// Read block body from mdbx
let read_value = {
let txn = self.db.begin_read().unwrap();
txn.get::<Bodies>(block_number)
};
match read_value {
Ok(value) => Ok(value.map(|a| a.to())),
Err(err) => Err(StoreError::LibmdbxError(err)),
}
let txn = self.db.begin_read().map_err(StoreError::LibmdbxError)?;
Ok(txn
.get::<Bodies>(block_number)
.map_err(StoreError::LibmdbxError)?
.map(|b| b.to()))
}

fn add_block_number(
&mut self,
block_hash: BlockHash,
block_number: BlockNumber,
) -> std::result::Result<(), StoreError> {
// Write block number to mdbx
let txn = self
.db
.begin_readwrite()
.map_err(StoreError::LibmdbxError)?;
txn.upsert::<BlockNumbers>(block_hash.into(), block_number)
.map_err(StoreError::LibmdbxError)?;
txn.commit().map_err(StoreError::LibmdbxError)
}

fn get_block_number(
&self,
block_hash: BlockHash,
) -> std::result::Result<Option<BlockNumber>, StoreError> {
// Read block number from mdbx
let txn = self.db.begin_read().map_err(StoreError::LibmdbxError)?;
txn.get::<BlockNumbers>(block_hash.into())
.map_err(StoreError::LibmdbxError)
}

fn set_value(&mut self, _key: Key, _value: Value) -> Result<(), StoreError> {
Expand All @@ -135,6 +148,12 @@ impl Debug for Store {
}

// Define tables

table!(
/// Block hash to number table.
( BlockNumbers ) BlockHashRLP => BlockNumber
);

table!(
/// Block headers table.
( Headers ) BlockNumber => BlockHeaderRLP
Expand Down Expand Up @@ -164,6 +183,7 @@ dupsort!(
/// will be temporary.
pub fn init_db(path: Option<impl AsRef<Path>>) -> Database {
let tables = [
table_info!(BlockNumbers),
table_info!(Headers),
table_info!(Bodies),
table_info!(AccountInfos),
Expand Down
3 changes: 2 additions & 1 deletion crates/storage/src/rlp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::marker::PhantomData;

use ethereum_rust_core::{
rlp::{decode::RLPDecode, encode::RLPEncode},
types::{AccountInfo, BlockBody, BlockHeader, Receipt},
types::{AccountInfo, BlockBody, BlockHash, BlockHeader, Receipt},
Address,
};
use libmdbx::orm::{Decodable, Encodable};
Expand All @@ -19,6 +19,7 @@ pub struct AccountStorageKeyRLP(pub [u8; 32]);
pub struct AccountStorageValueRLP(pub [u8; 32]);

// Block types
pub type BlockHashRLP = Rlp<BlockHash>;
pub type BlockHeaderRLP = Rlp<BlockHeader>;
pub type BlockBodyRLP = Rlp<BlockBody>;

Expand Down
14 changes: 13 additions & 1 deletion crates/storage/src/rocksdb.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::{Key, StoreEngine, Value};
use crate::error::StoreError;
use crate::rlp::{AccountInfoRLP, AddressRLP};
use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHeader, BlockNumber};
use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHash, BlockHeader, BlockNumber};
use ethereum_types::Address;
use libmdbx::orm::{Decodable, Encodable};
use std::fmt::Debug;
Expand Down Expand Up @@ -133,6 +133,18 @@ impl StoreEngine for Store {
todo!()
}

fn add_block_number(
&mut self,
_block_hash: BlockHash,
_block_number: BlockNumber,
) -> Result<(), StoreError> {
todo!()
}

fn get_block_number(&self, _block_hash: BlockHash) -> Result<Option<BlockNumber>, StoreError> {
todo!()
}

fn set_value(&mut self, key: Key, value: Value) -> Result<(), StoreError> {
let (reply_sender, reply_receiver) = sync_channel(0);
self.command_sender.send(StoreCommand::Put(
Expand Down
Loading
Loading