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

Prepare the database to use different types than Database for atomic view #1991

Merged
merged 18 commits into from
Jun 28, 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- [#1992](https://github.com/FuelLabs/fuel-core/pull/1992): Parse multiple relayer contracts, `RELAYER-V2-LISTENING-CONTRACTS` env variable using a `,` delimiter.

#### Breaking
- [#1991](https://github.com/FuelLabs/fuel-core/pull/1991): Prepare the database to use different types than `Database` for atomic view.
- [#1989](https://github.com/FuelLabs/fuel-core/pull/1989): Extract `HistoricalView` trait from the `AtomicView`.

## [Version 0.30.0]
Expand Down
3 changes: 3 additions & 0 deletions benches/benches/transaction_throughput.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use criterion::{
};
use fuel_core::service::config::Trigger;
use fuel_core_benches::*;
use fuel_core_storage::transactional::AtomicView;
use fuel_core_types::{
fuel_asm::{
op,
Expand Down Expand Up @@ -116,6 +117,8 @@ where
.shared
.database
.on_chain()
.latest_view()
.unwrap()
.get_sealed_block_by_height(&1.into())
.unwrap()
.unwrap();
Expand Down
3 changes: 3 additions & 0 deletions bin/fuel-core/src/cli/snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ mod tests {
Messages,
Transactions,
},
transactional::AtomicView,
ContractsAssetKey,
ContractsStateKey,
StorageAsMut,
Expand Down Expand Up @@ -772,6 +773,8 @@ mod tests {
latest_block.blocks_root = db
.db
.on_chain()
.latest_view()
.unwrap()
.block_header_merkle_root(&latest_block.block_height)
.unwrap();
db.flush();
Expand Down
9 changes: 5 additions & 4 deletions crates/fuel-core/src/combined_database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ impl CombinedDatabase {
pub fn read_state_config(&self) -> StorageResult<StateConfig> {
use fuel_core_chain_config::AddTable;
use fuel_core_producer::ports::BlockProducerDatabase;
use fuel_core_storage::transactional::AtomicView;
use itertools::Itertools;
let mut builder = StateConfigBuilder::default();

Expand All @@ -180,10 +181,10 @@ impl CombinedDatabase {
ContractsLatestUtxo
);

let latest_block = self.on_chain().latest_block()?;
let blocks_root = self
.on_chain()
.block_header_merkle_root(latest_block.header().height())?;
let view = self.on_chain().latest_view()?;
let latest_block = view.latest_block()?;
let blocks_root =
view.block_header_merkle_root(latest_block.header().height())?;
let state_config =
builder.build(Some(fuel_core_chain_config::LastBlockConfig::from_header(
latest_block.header(),
Expand Down
161 changes: 62 additions & 99 deletions crates/fuel-core/src/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,51 +5,58 @@ use crate::{
on_chain::OnChain,
relayer::Relayer,
DatabaseDescription,
DatabaseHeight,
DatabaseMetadata,
},
metadata::MetadataTable,
Error as DatabaseError,
},
graphql_api::storage::blocks::FuelBlockIdsToHeights,
state::{
data_source::{
DataSource,
DataSourceType,
},
generic_database::GenericDatabase,
in_memory::memory_store::MemoryStore,
iterable_key_value_view::IterableKeyValueViewWrapper,
key_value_view::KeyValueViewWrapper,
ChangesIterator,
DataSource,
ColumnType,
IterableKeyValueView,
KeyValueView,
},
};
use fuel_core_chain_config::TableEntry;
use fuel_core_services::SharedMutex;
use fuel_core_storage::{
self,
blueprint::BlueprintInspect,
iter::{
BoxedIter,
IterDirection,
IterableStore,
IterableTable,
IteratorOverTable,
},
kv_store::{
KVItem,
KeyValueInspect,
Value,
},
not_found,
structured_storage::TableWithBlueprint,
tables::FuelBlocks,
transactional::{
AtomicView,
Changes,
ConflictPolicy,
HistoricalView,
Modifiable,
StorageTransaction,
},
Error as StorageError,
Mappable,
Result as StorageResult,
StorageAsMut,
StorageInspect,
StorageMutate,
};
use fuel_core_types::blockchain::block::CompressedBlock;
use fuel_core_types::{
blockchain::block::CompressedBlock,
fuel_types::BlockHeight,
};
use itertools::Itertools;
use std::{
fmt::Debug,
Expand All @@ -60,10 +67,8 @@ pub use fuel_core_database::Error;
pub type Result<T> = core::result::Result<T, Error>;

// TODO: Extract `Database` and all belongs into `fuel-core-database`.
use crate::database::database_description::DatabaseHeight;
#[cfg(feature = "rocksdb")]
use crate::state::rocks_db::RocksDb;
use fuel_core_storage::transactional::HistoricalView;
#[cfg(feature = "rocksdb")]
use std::path::Path;

Expand All @@ -78,6 +83,7 @@ pub mod message;
pub mod metadata;
pub mod sealed_block;
pub mod state;
#[cfg(feature = "test-helpers")]
pub mod storage;
pub mod transactions;

Expand All @@ -104,18 +110,22 @@ where
}
}

pub type Database<Description = OnChain, Stage = RegularStage<Description>> =
GenericDatabase<DataSource<Description, Stage>>;
pub type OnChainIterableKeyValueView = IterableKeyValueView<ColumnType<OnChain>>;
pub type OffChainIterableKeyValueView = IterableKeyValueView<ColumnType<OffChain>>;
pub type ReyalerIterableKeyValueView = IterableKeyValueView<ColumnType<Relayer>>;

pub type GenesisDatabase<Description = OnChain> = Database<Description, GenesisStage>;

#[derive(Clone, Debug)]
pub struct Database<Description = OnChain, Stage = RegularStage<Description>>
where
Description: DatabaseDescription,
{
data: DataSource<Description>,
stage: Stage,
}
impl OnChainIterableKeyValueView {
pub fn latest_height(&self) -> StorageResult<BlockHeight> {
self.iter_all::<FuelBlocks>(Some(IterDirection::Reverse))
.next()
.ok_or(not_found!("BlockHeight"))?
.map(|(height, _)| height)
}

impl Database<OnChain> {
pub fn latest_block(&self) -> StorageResult<CompressedBlock> {
self.iter_all::<FuelBlocks>(Some(IterDirection::Reverse))
.next()
Expand All @@ -135,8 +145,8 @@ where
direction: IterDirection,
) -> impl Iterator<Item = StorageResult<TableEntry<T>>> + 'a
where
T: TableWithBlueprint<Column = <DbDesc as DatabaseDescription>::Column> + 'a,
T::Blueprint: BlueprintInspect<T, Self>,
T: Mappable + 'a,
Self: IterableTable<T>,
{
self.iter_all_filtered::<T, _>(prefix, None, Some(direction))
.map_ok(|(key, value)| TableEntry { key, value })
Expand All @@ -147,11 +157,8 @@ impl<Description> GenesisDatabase<Description>
where
Description: DatabaseDescription,
{
pub fn new(data_source: DataSource<Description>) -> Self {
Self {
stage: GenesisStage,
data: data_source,
}
pub fn new(data_source: DataSourceType<Description>) -> Self {
GenesisDatabase::from_storage(DataSource::new(data_source, GenesisStage))
}
}

Expand All @@ -161,13 +168,13 @@ where
Database<Description>:
StorageInspect<MetadataTable<Description>, Error = StorageError>,
{
pub fn new(data_source: DataSource<Description>) -> Self {
let mut database = Self {
stage: RegularStage {
pub fn new(data_source: DataSourceType<Description>) -> Self {
let mut database = Self::from_storage(DataSource::new(
data_source,
RegularStage {
height: SharedMutex::new(None),
},
data: data_source,
};
));
let height = database
.latest_height()
.expect("Failed to get latest height during creation of the database");
Expand All @@ -193,7 +200,7 @@ where
"Height is already set for `{}`",
Description::name()
);
GenesisDatabase::new(self.data)
GenesisDatabase::new(self.into_inner().data)
}
}

Expand All @@ -204,69 +211,14 @@ where
{
pub fn in_memory() -> Self {
let data = Arc::<MemoryStore<Description>>::new(MemoryStore::default());
Self {
data,
stage: Stage::default(),
}
Self::from_storage(DataSource::new(data, Stage::default()))
}

#[cfg(feature = "rocksdb")]
pub fn rocksdb_temp() -> Self {
let data =
Arc::<RocksDb<Description>>::new(RocksDb::default_open_temp(None).unwrap());
Self {
data,
stage: Stage::default(),
}
}
}

impl<Description, Stage> KeyValueInspect for Database<Description, Stage>
where
Description: DatabaseDescription,
{
type Column = Description::Column;

fn exists(&self, key: &[u8], column: Self::Column) -> StorageResult<bool> {
self.data.as_ref().exists(key, column)
}

fn size_of_value(
&self,
key: &[u8],
column: Self::Column,
) -> StorageResult<Option<usize>> {
self.data.as_ref().size_of_value(key, column)
}

fn get(&self, key: &[u8], column: Self::Column) -> StorageResult<Option<Value>> {
self.data.as_ref().get(key, column)
}

fn read(
&self,
key: &[u8],
column: Self::Column,
buf: &mut [u8],
) -> StorageResult<Option<usize>> {
self.data.as_ref().read(key, column, buf)
}
}

impl<Description, Stage> IterableStore for Database<Description, Stage>
where
Description: DatabaseDescription,
{
fn iter_store(
&self,
column: Self::Column,
prefix: Option<&[u8]>,
start: Option<&[u8]>,
direction: IterDirection,
) -> BoxedIter<KVItem> {
self.data
.as_ref()
.iter_store(column, prefix, start, direction)
let db = RocksDb::<Description>::default_open_temp(None).unwrap();
let data = Arc::new(db);
Self::from_storage(DataSource::new(data, Stage::default()))
}
}

Expand Down Expand Up @@ -294,11 +246,13 @@ impl<Description> AtomicView for Database<Description>
where
Description: DatabaseDescription,
{
type LatestView = Self;
type LatestView = IterableKeyValueView<ColumnType<Description>>;

fn latest_view(&self) -> StorageResult<Self::LatestView> {
// TODO: https://github.com/FuelLabs/fuel-core/issues/1581
Ok(self.clone())
Ok(IterableKeyValueView::from_storage(
IterableKeyValueViewWrapper::new(self.clone()),
))
}
}

Expand All @@ -307,15 +261,24 @@ where
Description: DatabaseDescription,
{
type Height = Description::Height;
type ViewAtHeight = Self;
type ViewAtHeight = KeyValueView<ColumnType<Description>>;

fn latest_height(&self) -> Option<Self::Height> {
*self.stage.height.lock()
}

fn view_at(&self, _: &Self::Height) -> StorageResult<Self::ViewAtHeight> {
fn view_at(&self, height: &Self::Height) -> StorageResult<Self::ViewAtHeight> {
let lock = self.stage.height.lock();

if let Some(current_height) = *lock {
if &current_height == height {
return self.latest_view().map(|view| view.into_key_value_view());
}
}
// TODO: Unimplemented until of the https://github.com/FuelLabs/fuel-core/issues/451
Ok(self.clone())
Ok(KeyValueView::from_storage(KeyValueViewWrapper::new(
self.clone(),
)))
}
}

Expand Down
Loading
Loading