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

port(storage): use the cached block height from the database at the time of creation of the view #2646

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
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
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]

### Added

- [2648](https://github.com/FuelLabs/fuel-core/pull/2648): Add feature-flagged field to block header `fault_proving_header` that contains a commitment to all transaction ids.

### Fixed
- [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.6]

### Added
Expand All @@ -34,6 +36,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- [2617](https://github.com/FuelLabs/fuel-core/pull/2617): Add integration skeleton of parallel-executor.
- [2553](https://github.com/FuelLabs/fuel-core/pull/2553): Scaffold global merkle root storage crate.
- [2598](https://github.com/FuelLabs/fuel-core/pull/2598): Add initial test suite for global merkle root storage updates.

- [2635](https://github.com/FuelLabs/fuel-core/pull/2635): Add metrics to gas price service
- [2664](https://github.com/FuelLabs/fuel-core/pull/2664): Add print with all information when a transaction is refused because of a collision.

Expand Down
95 changes: 68 additions & 27 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 All @@ -267,7 +284,10 @@ where
)?;
let historical_db = HistoricalRocksDB::new(db, state_rewind_policy)?;
let data = Arc::new(historical_db);
Ok(Self::from_storage(DataSource::new(data, Stage::default())))
Ok(Self::from_storage_and_metadata(
DataSource::new(data, Stage::default()),
None,
))
}
}

Expand Down Expand Up @@ -323,16 +343,31 @@ 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 lock = self.inner_storage().stage.height.lock();
let view = self.latest_view_with_height(*lock)?;
Ok(view)
}
}

Expand All @@ -341,7 +376,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 +386,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
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
Loading