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

Refactoring of the graphql-api service to use ports for Database #858

Merged
merged 26 commits into from
Jan 14, 2023
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
0f4a1c1
refactor coin query
ControlCplusControlV Dec 17, 2022
135f2b6
migrated chain singular queries
ControlCplusControlV Dec 17, 2022
353c12e
moved over block query
ControlCplusControlV Dec 17, 2022
deb15d3
Refactored all single queries
ControlCplusControlV Dec 17, 2022
ce662f4
moved traits out of schema
ControlCplusControlV Dec 19, 2022
b55d94e
moved traits out of schema
ControlCplusControlV Dec 19, 2022
30756fb
Update crates/fuel-core/src/query/block.rs
ControlCplusControlV Dec 20, 2022
1b0b321
fmt:
ControlCplusControlV Dec 20, 2022
34a256f
addressed pr comments
ControlCplusControlV Dec 21, 2022
6ad858a
Merge branch 'master' into controlc/gql_refactor
xgreenx Dec 23, 2022
a9a5a93
fixed issue
ControlCplusControlV Dec 23, 2022
7db5330
Merge branch 'master' into controlc/gql_refactor
ControlCplusControlV Dec 23, 2022
adf222d
fixed updates
ControlCplusControlV Dec 23, 2022
b93e77a
remove ci change
ControlCplusControlV Dec 23, 2022
8390684
remove ci change
ControlCplusControlV Dec 23, 2022
276dd49
fixed contract query
ControlCplusControlV Dec 23, 2022
5c6cc94
Merge branch 'master' into controlc/gql_refactor
ControlCplusControlV Dec 23, 2022
27c4e68
core
ControlCplusControlV Jan 5, 2023
4e0a983
`graphql-api` ports for database queries (#890)
xgreenx Jan 11, 2023
0d97e98
Merge branch 'master' into controlc/gql_refactor
ControlCplusControlV Jan 12, 2023
ade0a04
Leave `dap.rs` in the `fuel-core` level for now (#899)
xgreenx Jan 12, 2023
b506822
Merge branch 'master' into controlc/gql_refactor
xgreenx Jan 12, 2023
e36125b
Merge branch 'master' into controlc/gql_refactor
xgreenx Jan 13, 2023
af0aebd
Address comments in teh PR:
xgreenx Jan 13, 2023
68c8424
Forgot to remove `async_trait`
xgreenx Jan 13, 2023
6a28999
Merge branch 'master' into controlc/gql_refactor
xgreenx Jan 13, 2023
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
4 changes: 2 additions & 2 deletions crates/chain-config/src/config/coin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
use fuel_core_storage::MerkleRoot;
use fuel_core_types::{
blockchain::primitives::BlockHeight,
entities::coin::Coin,
entities::coin::CompressedCoin,
fuel_crypto::Hasher,
fuel_types::{
Address,
Expand Down Expand Up @@ -52,7 +52,7 @@ pub struct CoinConfig {
pub asset_id: AssetId,
}

impl GenesisCommitment for Coin {
impl GenesisCommitment for CompressedCoin {
fn root(&mut self) -> anyhow::Result<MerkleRoot> {
let coin_hash = *Hasher::default()
.chain(self.owner)
Expand Down
2 changes: 1 addition & 1 deletion crates/client/assets/schema.sdl
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,7 @@ enum ReceiptType {
}

"""
The schema analog of the [`crate::database::utils::Resource`].
The schema analog of the [`resource::Resource`].
"""
union Resource = Coin | Message

Expand Down
20 changes: 10 additions & 10 deletions crates/fuel-core/src/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ use fuel_core_storage::tables::{
use fuel_core_txpool::ports::TxPoolDb;
use fuel_core_types::{
entities::{
coin::Coin,
coin::CompressedCoin,
message::Message,
},
fuel_tx::UtxoId,
Expand Down Expand Up @@ -98,9 +98,9 @@ mod state;

pub mod balances;
pub mod metadata;
pub mod resource;
pub mod transaction;
// TODO: Rename in a separate PR into `transaction`
pub mod transactional;
pub mod transactions;
pub mod vm_database;

/// Database tables column ids.
Expand Down Expand Up @@ -135,7 +135,7 @@ pub enum Column {
Receipts = 11,
/// See [`FuelBlocks`](fuel_core_storage::tables::FuelBlocks)
FuelBlocks = 12,
/// Maps fuel block id to fuel block hash
/// Maps fuel block height to fuel block id
FuelBlockIds = 13,
/// See [`Messages`](fuel_core_storage::tables::Messages)
Messages = 14,
Expand Down Expand Up @@ -330,7 +330,7 @@ impl Default for Database {

impl BlockDb for Database {
fn block_height(&self) -> anyhow::Result<BlockHeight> {
Ok(self.get_block_height()?.unwrap_or_default())
Ok(self.latest_height()?.unwrap_or_default())
}

fn seal_block(
Expand All @@ -339,14 +339,14 @@ impl BlockDb for Database {
consensus: Consensus,
) -> anyhow::Result<()> {
self.storage::<SealedBlockConsensus>()
.insert(&block_id.into(), &consensus)
.insert(&block_id, &consensus)
.map(|_| ())
.map_err(Into::into)
}
}

impl TxPoolDb for Database {
fn utxo(&self, utxo_id: &UtxoId) -> StorageResult<Option<Coin>> {
fn utxo(&self, utxo_id: &UtxoId) -> StorageResult<Option<CompressedCoin>> {
self.storage::<Coins>()
.get(utxo_id)
.map(|t| t.map(|t| t.as_ref().clone()))
Expand All @@ -363,7 +363,7 @@ impl TxPoolDb for Database {
}

fn current_block_height(&self) -> StorageResult<BlockHeight> {
self.get_block_height()
self.latest_height()
.map(|h| h.unwrap_or_default())
.map_err(Into::into)
}
Expand All @@ -381,7 +381,7 @@ impl BlockProducerDatabase for Database {
}

fn current_block_height(&self) -> StorageResult<BlockHeight> {
self.get_block_height()
self.latest_height()
.map(|h| h.unwrap_or_default())
.map_err(Into::into)
}
Expand All @@ -403,6 +403,6 @@ impl ChainConfigDb for Database {
}

fn get_block_height(&self) -> StorageResult<Option<BlockHeight>> {
Self::get_block_height(self).map_err(Into::into)
Self::latest_height(self).map_err(Into::into)
}
}
110 changes: 61 additions & 49 deletions crates/fuel-core/src/database/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ use fuel_core_types::{
Block,
CompressedBlock,
},
primitives::BlockHeight,
primitives::{
BlockHeight,
BlockId,
},
},
fuel_tx::Bytes32,
tai64::Tai64,
Expand All @@ -42,19 +45,19 @@ use std::{
impl StorageInspect<FuelBlocks> for Database {
type Error = StorageError;

fn get(&self, key: &Bytes32) -> Result<Option<Cow<CompressedBlock>>, Self::Error> {
Database::get(self, key.as_ref(), Column::FuelBlocks).map_err(Into::into)
fn get(&self, key: &BlockId) -> Result<Option<Cow<CompressedBlock>>, Self::Error> {
Database::get(self, key.as_slice(), Column::FuelBlocks).map_err(Into::into)
}

fn contains_key(&self, key: &Bytes32) -> Result<bool, Self::Error> {
Database::exists(self, key.as_ref(), Column::FuelBlocks).map_err(Into::into)
fn contains_key(&self, key: &BlockId) -> Result<bool, Self::Error> {
Database::exists(self, key.as_slice(), Column::FuelBlocks).map_err(Into::into)
}
}

impl StorageMutate<FuelBlocks> for Database {
fn insert(
&mut self,
key: &Bytes32,
key: &BlockId,
value: &CompressedBlock,
) -> Result<Option<CompressedBlock>, Self::Error> {
let _: Option<BlockHeight> = Database::insert(
Expand All @@ -63,13 +66,13 @@ impl StorageMutate<FuelBlocks> for Database {
Column::FuelBlockIds,
*key,
)?;
Database::insert(self, key.as_ref(), Column::FuelBlocks, value)
Database::insert(self, key.as_slice(), Column::FuelBlocks, value)
.map_err(Into::into)
}

fn remove(&mut self, key: &Bytes32) -> Result<Option<CompressedBlock>, Self::Error> {
fn remove(&mut self, key: &BlockId) -> Result<Option<CompressedBlock>, Self::Error> {
let block: Option<CompressedBlock> =
Database::remove(self, key.as_ref(), Column::FuelBlocks)?;
Database::remove(self, key.as_slice(), Column::FuelBlocks)?;
if let Some(block) = &block {
let _: Option<Bytes32> = Database::remove(
self,
Expand All @@ -82,63 +85,64 @@ impl StorageMutate<FuelBlocks> for Database {
}

impl Database {
pub fn get_block_height(&self) -> DatabaseResult<Option<BlockHeight>> {
let block_entry = self.latest_block()?;
// get block height from most recently indexed block
let mut id = block_entry.map(|(height, _)| {
// safety: we know that all block heights are stored with the correct amount of bytes
let bytes = <[u8; 4]>::try_from(height.as_slice()).unwrap();
u32::from_be_bytes(bytes).into()
});
pub fn latest_height(&self) -> DatabaseResult<Option<BlockHeight>> {
let id = self.ids_of_latest_block()?;
// if no blocks, check if chain was configured with a base height
if id.is_none() {
id = self.get_starting_chain_height()?;
}
let id = match id {
Some((id, _)) => Some(id),
None => self.get_starting_chain_height()?,
};

Ok(id)
}

/// Get the current block at the head of the chain.
pub fn get_current_block(&self) -> StorageResult<Option<Cow<CompressedBlock>>> {
let block_entry = self.latest_block()?;
match block_entry {
let block_ids = self.ids_of_latest_block()?;
match block_ids {
Some((_, id)) => Ok(StorageAsRef::storage::<FuelBlocks>(self).get(&id)?),
None => Ok(None),
}
}

pub fn block_time(&self, height: u32) -> StorageResult<Tai64> {
let id = self.get_block_id(height.into())?.unwrap_or_default();
pub fn block_time(&self, height: BlockHeight) -> StorageResult<Tai64> {
let id = self.get_block_id(height)?.unwrap_or_default();
let block = self
.storage::<FuelBlocks>()
.get(&id)?
.ok_or(not_found!(FuelBlocks))?;
Ok(block.header().time().to_owned())
}

pub fn get_block_id(&self, height: BlockHeight) -> StorageResult<Option<Bytes32>> {
pub fn get_block_id(&self, height: BlockHeight) -> StorageResult<Option<BlockId>> {
Database::get(self, &height.to_bytes()[..], Column::FuelBlockIds)
.map_err(Into::into)
}

pub fn all_block_ids(
&self,
start: Option<BlockHeight>,
direction: Option<IterDirection>,
) -> impl Iterator<Item = DatabaseResult<(BlockHeight, Bytes32)>> + '_ {
direction: IterDirection,
) -> impl Iterator<Item = DatabaseResult<(BlockHeight, BlockId)>> + '_ {
let start = start.map(|b| b.to_bytes().to_vec());
self.iter_all::<Vec<u8>, Bytes32>(Column::FuelBlockIds, None, start, direction)
.map(|res| {
let (height, id) = res?;
Ok((
height
.try_into()
.expect("block height always has correct number of bytes"),
id,
))
})
self.iter_all::<Vec<u8>, BlockId>(
Column::FuelBlockIds,
None,
start,
Some(direction),
)
.map(|res| {
let (height, id) = res?;
Ok((
height
.try_into()
.expect("block height always has correct number of bytes"),
id,
))
})
}

pub fn genesis_block_ids(&self) -> DatabaseResult<(BlockHeight, Bytes32)> {
pub fn ids_of_genesis_block(&self) -> DatabaseResult<(BlockHeight, BlockId)> {
self.iter_all(
Column::FuelBlockIds,
None,
Expand All @@ -147,28 +151,36 @@ impl Database {
)
.next()
.ok_or(DatabaseError::ChainUninitialized)?
.map(|(height, id): (Vec<u8>, Bytes32)| {
.map(|(height, id): (Vec<u8>, BlockId)| {
let bytes = <[u8; 4]>::try_from(height.as_slice())
.expect("all block heights are stored with the correct amount of bytes");
(u32::from_be_bytes(bytes).into(), id)
})
}

fn latest_block(&self) -> DatabaseResult<Option<(Vec<u8>, Bytes32)>> {
self.iter_all(
Column::FuelBlockIds,
None,
None,
Some(IterDirection::Reverse),
)
.next()
.transpose()
pub fn ids_of_latest_block(&self) -> DatabaseResult<Option<(BlockHeight, BlockId)>> {
let ids = self
.iter_all::<Vec<u8>, BlockId>(
Column::FuelBlockIds,
None,
None,
Some(IterDirection::Reverse),
)
.next()
.transpose()?
.map(|(height, block)| {
// safety: we know that all block heights are stored with the correct amount of bytes
let bytes = <[u8; 4]>::try_from(height.as_slice()).unwrap();
(u32::from_be_bytes(bytes).into(), block)
});

Ok(ids)
}

/// Retrieve the full block and all associated transactions
pub(crate) fn get_full_block(
&self,
block_id: &Bytes32,
block_id: &BlockId,
) -> StorageResult<Option<Block>> {
let db_block = self.storage::<FuelBlocks>().get(block_id)?;
if let Some(block) = db_block {
Expand Down
14 changes: 7 additions & 7 deletions crates/fuel-core/src/database/coin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ use fuel_core_storage::{
};
use fuel_core_types::{
entities::coin::{
Coin,
CoinStatus,
CompressedCoin,
},
fuel_tx::{
Address,
Expand Down Expand Up @@ -49,7 +49,7 @@ fn utxo_id_to_bytes(utxo_id: &UtxoId) -> Vec<u8> {
impl StorageInspect<Coins> for Database {
type Error = StorageError;

fn get(&self, key: &UtxoId) -> Result<Option<Cow<Coin>>, Self::Error> {
fn get(&self, key: &UtxoId) -> Result<Option<Cow<CompressedCoin>>, Self::Error> {
Database::get(self, &utxo_id_to_bytes(key), Column::Coins).map_err(Into::into)
}

Expand All @@ -62,8 +62,8 @@ impl StorageMutate<Coins> for Database {
fn insert(
&mut self,
key: &UtxoId,
value: &Coin,
) -> Result<Option<Coin>, Self::Error> {
value: &CompressedCoin,
) -> Result<Option<CompressedCoin>, Self::Error> {
let coin_by_owner: Vec<u8> = owner_coin_id_key(&value.owner, key);
// insert primary record
let insert = Database::insert(self, utxo_id_to_bytes(key), Column::Coins, value)?;
Expand All @@ -73,8 +73,8 @@ impl StorageMutate<Coins> for Database {
Ok(insert)
}

fn remove(&mut self, key: &UtxoId) -> Result<Option<Coin>, Self::Error> {
let coin: Option<Coin> =
fn remove(&mut self, key: &UtxoId) -> Result<Option<CompressedCoin>, Self::Error> {
let coin: Option<CompressedCoin> =
Database::remove(self, &utxo_id_to_bytes(key), Column::Coins)?;

// cleanup secondary index
Expand Down Expand Up @@ -114,7 +114,7 @@ impl Database {

pub fn get_coin_config(&self) -> DatabaseResult<Option<Vec<CoinConfig>>> {
let configs = self
.iter_all::<Vec<u8>, Coin>(Column::Coins, None, None, None)
.iter_all::<Vec<u8>, CompressedCoin>(Column::Coins, None, None, None)
.filter_map(|coin| {
// Return only unspent coins
if let Ok(coin) = coin {
Expand Down
Loading