Skip to content

Commit

Permalink
port(storage): use the cached block height from the database at the t…
Browse files Browse the repository at this point in the history
…ime of creation of the view
  • Loading branch information
rymnc committed Jan 29, 2025
1 parent 01c6cb0 commit 9b36c1f
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 69 deletions.
5 changes: 2 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Added
- [2635](https://github.com/FuelLabs/fuel-core/pull/2635): Add metrics to gas price service
- [2553](https://github.com/FuelLabs/fuel-core/pull/2553): Scaffold global merkle root storage crate.

### Changed
- [2387](https://github.com/FuelLabs/fuel-core/pull/2387): Update description `tx-max-depth` flag.
- [2630](https://github.com/FuelLabs/fuel-core/pull/2630): Removed some noisy `tracing::info!` logs

### Added
- [2553](https://github.com/FuelLabs/fuel-core/pull/2553): Scaffold global merkle root storage crate.

### Fixed
- [2632](https://github.com/FuelLabs/fuel-core/pull/2632): Improved performance of certain async trait impls in the gas price service.
- [2646](https://github.com/FuelLabs/fuel-core/pull/2646): Improved performance of fetching block height by caching it when the view is created.

## [Version 0.41.4]

Expand Down
89 changes: 63 additions & 26 deletions crates/fuel-core/src/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use crate::{
},
};
use fuel_core_chain_config::TableEntry;
pub use fuel_core_database::Error;
use fuel_core_gas_price_service::common::fuel_core_storage_adapter::storage::GasPriceMetadata;
use fuel_core_services::SharedMutex;
use fuel_core_storage::{
Expand Down Expand Up @@ -60,17 +61,12 @@ use itertools::Itertools;
use std::{
borrow::Cow,
fmt::Debug,
io::Empty,
sync::Arc,
};

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::{
gas_price::GasPriceDatabase,
indexation_availability,
};
#[cfg(feature = "rocksdb")]
use crate::state::{
historical_rocksdb::{
Expand All @@ -84,6 +80,13 @@ use crate::state::{
RocksDb,
},
};
use crate::{
database::database_description::{
gas_price::GasPriceDatabase,
indexation_availability,
},
state::HeightType,
};
#[cfg(feature = "rocksdb")]
use std::path::Path;

Expand Down Expand Up @@ -126,10 +129,13 @@ 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 RelayerIterableKeyValueView = IterableKeyValueView<ColumnType<Relayer>>;
GenericDatabase<DataSource<Description, Stage>, Empty>;
pub type OnChainIterableKeyValueView =
IterableKeyValueView<ColumnType<OnChain>, HeightType<OnChain>>;
pub type OffChainIterableKeyValueView =
IterableKeyValueView<ColumnType<OffChain>, HeightType<OffChain>>;
pub type RelayerIterableKeyValueView =
IterableKeyValueView<ColumnType<Relayer>, HeightType<Relayer>>;

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

Expand All @@ -141,7 +147,9 @@ impl OnChainIterableKeyValueView {
}

pub fn latest_height(&self) -> StorageResult<BlockHeight> {
self.maybe_latest_height()?.ok_or(not_found!("BlockHeight"))
self.metadata()
.cloned()
.ok_or_else(|| not_found!("Metadata"))
}

pub fn latest_block(&self) -> StorageResult<CompressedBlock> {
Expand Down Expand Up @@ -176,7 +184,10 @@ where
Description: DatabaseDescription,
{
pub fn new(data_source: DataSourceType<Description>) -> Self {
GenesisDatabase::from_storage(DataSource::new(data_source, GenesisStage))
GenesisDatabase::from_storage_and_metadata(
DataSource::new(data_source, GenesisStage),
None,
)
}
}

Expand All @@ -187,12 +198,15 @@ where
StorageInspect<MetadataTable<Description>, Error = StorageError>,
{
pub fn new(data_source: DataSourceType<Description>) -> Self {
let mut database = Self::from_storage(DataSource::new(
data_source,
RegularStage {
height: SharedMutex::new(None),
},
));
let mut database = Self::from_storage_and_metadata(
DataSource::new(
data_source,
RegularStage {
height: SharedMutex::new(None),
},
),
Some(Empty::default()),
);
let height = database
.latest_height_from_metadata()
.expect("Failed to get latest height during creation of the database");
Expand Down Expand Up @@ -235,14 +249,14 @@ where
) -> core::result::Result<GenesisDatabase<Description>, GenesisDatabase<Description>>
{
if !self.stage.height.lock().is_some() {
Ok(GenesisDatabase::new(self.into_inner().data))
Ok(GenesisDatabase::new(self.into_inner().0.data))
} else {
tracing::warn!(
"Converting regular database into genesis, \
while height is already set for `{}`",
Description::name()
);
Err(GenesisDatabase::new(self.into_inner().data))
Err(GenesisDatabase::new(self.into_inner().0.data))
}
}
}
Expand All @@ -254,7 +268,10 @@ where
{
pub fn in_memory() -> Self {
let data = Arc::<MemoryStore<Description>>::new(MemoryStore::default());
Self::from_storage(DataSource::new(data, Stage::default()))
Self::from_storage_and_metadata(
DataSource::new(data, Stage::default()),
Some(Empty::default()),
)
}

#[cfg(feature = "rocksdb")]
Expand Down Expand Up @@ -323,16 +340,30 @@ where

Ok(())
}

fn latest_view_with_height(
&self,
height: Option<Description::Height>,
) -> StorageResult<IterableKeyValueView<ColumnType<Description>, Description::Height>>
{
let view = self.inner_storage().data.latest_view()?;

let (view, _) = view.into_inner();
Ok(IterableKeyValueView::from_storage_and_metadata(
view, height,
))
}
}

impl<Description> AtomicView for Database<Description>
where
Description: DatabaseDescription,
{
type LatestView = IterableKeyValueView<ColumnType<Description>>;
type LatestView = IterableKeyValueView<ColumnType<Description>, Description::Height>;

fn latest_view(&self) -> StorageResult<Self::LatestView> {
self.inner_storage().data.latest_view()
let height = *self.inner_storage().stage.height.lock();
self.latest_view_with_height(height)
}
}

Expand All @@ -341,7 +372,7 @@ where
Description: DatabaseDescription,
{
type Height = Description::Height;
type ViewAtHeight = KeyValueView<ColumnType<Description>>;
type ViewAtHeight = KeyValueView<ColumnType<Description>, Description::Height>;

fn latest_height(&self) -> Option<Self::Height> {
*self.inner_storage().stage.height.lock()
Expand All @@ -351,9 +382,15 @@ where
let lock = self.inner_storage().stage.height.lock();

match *lock {
None => return self.latest_view().map(|view| view.into_key_value_view()),
None => {
return self
.latest_view_with_height(None)
.map(|view| view.into_key_value_view())
}
Some(current_height) if &current_height == height => {
return self.latest_view().map(|view| view.into_key_value_view())
return self
.latest_view_with_height(Some(current_height))
.map(|view| view.into_key_value_view())
}
_ => {}
};
Expand Down
6 changes: 3 additions & 3 deletions crates/fuel-core/src/database/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use fuel_core_storage::{
StorageWrite,
};

impl<Storage, M> StorageMutate<M> for GenericDatabase<Storage>
impl<Storage, M, Metadata> StorageMutate<M> for GenericDatabase<Storage, Metadata>
where
M: Mappable,
Self: Modifiable,
Expand Down Expand Up @@ -50,7 +50,7 @@ where
}
}

impl<Storage, M> StorageWrite<M> for GenericDatabase<Storage>
impl<Storage, M, Metadata> StorageWrite<M> for GenericDatabase<Storage, Metadata>
where
M: Mappable,
StructuredStorage<Storage>: StorageInspect<M, Error = StorageError>,
Expand Down Expand Up @@ -95,7 +95,7 @@ where
}
}

impl<Storage, M> StorageBatchMutate<M> for GenericDatabase<Storage>
impl<Storage, M, Metadata> StorageBatchMutate<M> for GenericDatabase<Storage, Metadata>
where
M: Mappable,
StructuredStorage<Storage>: StorageInspect<M, Error = StorageError>,
Expand Down
6 changes: 4 additions & 2 deletions crates/fuel-core/src/service/genesis/importer/import_task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -578,11 +578,13 @@ mod tests {
fn view_at_height(
&self,
_: &BlockHeight,
) -> StorageResult<KeyValueView<Self::Column>> {
) -> StorageResult<KeyValueView<Self::Column, BlockHeight>> {
Err(anyhow::anyhow!("I refuse to work!").into())
}

fn latest_view(&self) -> StorageResult<IterableKeyValueView<Self::Column>> {
fn latest_view(
&self,
) -> StorageResult<IterableKeyValueView<Self::Column, BlockHeight>> {
Err(anyhow::anyhow!("I refuse to work!").into())
}

Expand Down
28 changes: 16 additions & 12 deletions crates/fuel-core/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,25 @@ pub mod rocks_db;
pub mod rocks_db_key_iterator;

pub type ColumnType<Description> = <Description as DatabaseDescription>::Column;
pub type HeightType<Description> = <Description as DatabaseDescription>::Height;

/// A type extends the `KeyValueView`, allowing iteration over the storage.
pub type IterableKeyValueView<Column> =
GenericDatabase<IterableKeyValueViewWrapper<Column>>;
pub type IterableKeyValueView<Column, BlockHeight> =
GenericDatabase<IterableKeyValueViewWrapper<Column>, BlockHeight>;

/// The basic view available for the key value storage.
pub type KeyValueView<Column> = GenericDatabase<KeyValueViewWrapper<Column>>;
pub type KeyValueView<Column, BlockHeight> =
GenericDatabase<KeyValueViewWrapper<Column>, BlockHeight>;

impl<Column> IterableKeyValueView<Column>
impl<Column, Height> IterableKeyValueView<Column, Height>
where
Column: StorageColumn + 'static,
{
/// Downgrades the `IterableKeyValueView` into the `KeyValueView`.
pub fn into_key_value_view(self) -> KeyValueView<Column> {
let iterable = self.into_inner();
pub fn into_key_value_view(self) -> KeyValueView<Column, Height> {
let (iterable, metadata) = self.into_inner();
let storage = KeyValueViewWrapper::new(iterable);
KeyValueView::from_storage(storage)
KeyValueView::from_storage_and_metadata(storage, metadata)
}
}

Expand All @@ -61,9 +63,9 @@ pub trait TransactableStorage<Height>: IterableStore + Debug + Send + Sync {
fn view_at_height(
&self,
height: &Height,
) -> StorageResult<KeyValueView<Self::Column>>;
) -> StorageResult<KeyValueView<Self::Column, Height>>;

fn latest_view(&self) -> StorageResult<IterableKeyValueView<Self::Column>>;
fn latest_view(&self) -> StorageResult<IterableKeyValueView<Self::Column, Height>>;

fn rollback_block_to(&self, height: &Height) -> StorageResult<()>;
}
Expand All @@ -79,14 +81,16 @@ where
unimplemented!()
}

fn view_at_height(&self, _: &Height) -> StorageResult<KeyValueView<Self::Column>> {
fn view_at_height(
&self,
_: &Height,
) -> StorageResult<KeyValueView<Self::Column, Height>> {
unimplemented!()
}

fn latest_view(&self) -> StorageResult<IterableKeyValueView<Self::Column>> {
fn latest_view(&self) -> StorageResult<IterableKeyValueView<Self::Column, Height>> {
unimplemented!()
}

fn rollback_block_to(&self, _: &Height) -> StorageResult<()> {
unimplemented!()
}
Expand Down
Loading

0 comments on commit 9b36c1f

Please sign in to comment.