Skip to content

Commit

Permalink
Remove genesis temp tables (#1737)
Browse files Browse the repository at this point in the history
Closes #1734

Removes the temporary tables for calculating genesis block roots.
  • Loading branch information
MujkicA committed Mar 6, 2024
1 parent 36e3363 commit a7eec76
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 236 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Added

- [#1737](https://github.com/FuelLabs/fuel-core/pull/1737): Remove temporary tables for calculating roots during genesis.
- [#1731](https://github.com/FuelLabs/fuel-core/pull/1731): Expose `schema.sdl` from `fuel-core-client`.

### Changed
Expand Down
165 changes: 35 additions & 130 deletions crates/fuel-core/src/database/genesis_progress.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,23 @@
use crate::state::DataSource;

use super::Database;
use fuel_core_chain_config::GenesisCommitment;
use fuel_core_executor::refs::ContractRef;
use fuel_core_storage::{
blueprint::{
plain::Plain,
Blueprint,
},
codec::{
postcard::Postcard,
raw::Raw,
},
blueprint::plain::Plain,
codec::postcard::Postcard,
column::Column,
structured_storage::TableWithBlueprint,
tables::ContractsLatestUtxo,
tables::{
Coins,
ContractsLatestUtxo,
Messages,
},
Mappable,
MerkleRoot,
Result,
StorageAsMut,
StorageInspect,
StorageMutate,
};
use fuel_core_types::{
fuel_merkle::sparse::{
in_memory::MerkleTree,
MerkleTreeKey,
},
fuel_types::ContractId,
};
use itertools::{
process_results,
Itertools,
};
use fuel_core_types::fuel_merkle::binary::root_calculator::MerkleRootCalculator;
use serde::{
Deserialize,
Serialize,
Expand Down Expand Up @@ -63,62 +50,6 @@ impl TableWithBlueprint for GenesisMetadata {
}
}

// TODO: Remove as part of the https://github.com/FuelLabs/fuel-core/issues/1734
pub struct GenesisCoinRoots;

impl Mappable for GenesisCoinRoots {
type Key = Self::OwnedKey;
type OwnedKey = MerkleRoot;
type Value = Self::OwnedValue;
type OwnedValue = ();
}

impl TableWithBlueprint for GenesisCoinRoots {
type Blueprint = Plain<Raw, Postcard>;
type Column = Column;
fn column() -> Self::Column {
Column::GenesisCoinRoots
}
}

// TODO: Remove as part of the https://github.com/FuelLabs/fuel-core/issues/1734
pub struct GenesisMessageRoots;

impl Mappable for GenesisMessageRoots {
type Key = Self::OwnedKey;
type OwnedKey = MerkleRoot;
type Value = Self::OwnedValue;
type OwnedValue = ();
}

impl TableWithBlueprint for GenesisMessageRoots {
type Blueprint = Plain<Raw, Postcard>;
type Column = Column;
fn column() -> Self::Column {
Column::GenesisMessageRoots
}
}

// TODO: Remove as part of the https://github.com/FuelLabs/fuel-core/issues/1734
pub struct GenesisContractRoots;

impl Mappable for GenesisContractRoots {
type Key = Self::OwnedKey;
type OwnedKey = MerkleRoot;
type Value = Self::OwnedValue;
type OwnedValue = ();
}

impl TableWithBlueprint for GenesisContractRoots {
type Blueprint = Plain<Raw, Postcard>;
type Column = Column;
fn column() -> Self::Column {
Column::GenesisContractRoots
}
}

pub type GenesisImportedContractId = ContractId;

impl Database {
pub fn genesis_progress(&self, key: &GenesisResource) -> Option<usize> {
Some(
Expand All @@ -139,66 +70,40 @@ impl Database {
Ok(())
}

pub fn add_coin_root(&mut self, root: MerkleRoot) -> Result<()> {
StorageMutate::<GenesisCoinRoots>::insert(self, &root, &())?;
Ok(())
}

pub fn add_message_root(&mut self, root: MerkleRoot) -> Result<()> {
StorageMutate::<GenesisMessageRoots>::insert(self, &root, &())?;
Ok(())
}
pub fn genesis_coins_root(&self) -> Result<MerkleRoot> {
let coins = self.iter_all::<Coins>(None);

pub fn add_contract_root(&mut self, root: MerkleRoot) -> Result<()> {
StorageMutate::<GenesisContractRoots>::insert(self, &root, &())?;
Ok(())
}
let mut root_calculator = MerkleRootCalculator::new();
for coin in coins {
let (_, coin) = coin?;
root_calculator.push(coin.root()?.as_slice());
}

pub(crate) fn genesis_roots<M>(
&self,
) -> Result<impl Iterator<Item = (MerkleTreeKey, [u8; 32])>>
where
M: Mappable<OwnedKey = [u8; 32]> + TableWithBlueprint<Column = Column>,
M::Blueprint: Blueprint<M, DataSource>,
{
let roots_iter = self.iter_all::<M>(None);

let roots = process_results(roots_iter, |roots| {
roots.map(|(root, _)| root).collect::<Vec<MerkleRoot>>()
})?
.into_iter()
.enumerate()
.map(|(idx, root)| (MerkleTreeKey::new(idx.to_be_bytes()), root));

Ok(roots)
Ok(root_calculator.root())
}

fn compute_genesis_root<M>(&self) -> Result<MerkleRoot>
where
M: Mappable<OwnedKey = [u8; 32]> + TableWithBlueprint<Column = Column>,
M::Blueprint: Blueprint<M, DataSource>,
{
let roots = self.genesis_roots::<M>()?;
Ok(MerkleTree::root_from_set(roots.into_iter()))
}
pub fn genesis_messages_root(&self) -> Result<MerkleRoot> {
let messages = self.iter_all::<Messages>(None);

pub fn genesis_coin_root(&self) -> Result<MerkleRoot> {
self.compute_genesis_root::<GenesisCoinRoots>()
}
let mut root_calculator = MerkleRootCalculator::new();
for message in messages {
let (_, message) = message?;
root_calculator.push(message.root()?.as_slice());
}

pub fn genesis_messages_root(&self) -> Result<MerkleRoot> {
self.compute_genesis_root::<GenesisMessageRoots>()
Ok(root_calculator.root())
}

pub fn genesis_contracts_root(&self) -> Result<MerkleRoot> {
self.compute_genesis_root::<GenesisContractRoots>()
}
let contracts = self.iter_all::<ContractsLatestUtxo>(None);

let mut root_calculator = MerkleRootCalculator::new();
for contract in contracts {
let (contract_id, _) = contract?;
let root = ContractRef::new(self, contract_id).root()?;
root_calculator.push(root.as_slice());
}

pub fn genesis_loaded_contracts(
&self,
) -> impl Iterator<Item = Result<GenesisImportedContractId>> + '_ {
self.iter_all::<ContractsLatestUtxo>(None)
.map_ok(|(contract_id, _)| contract_id)
.map(|res| res.map_err(Into::into))
Ok(root_calculator.root())
}
}
12 changes: 2 additions & 10 deletions crates/fuel-core/src/database/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,7 @@ use fuel_core_storage::{
};
use std::borrow::Cow;

use super::genesis_progress::{
GenesisCoinRoots,
GenesisContractRoots,
GenesisMessageRoots,
GenesisMetadata,
};
use super::genesis_progress::GenesisMetadata;

/// The trait allows selectively inheriting the implementation of storage traits from `StructuredStorage`
/// for the `Database`. Not all default implementations of the `StructuredStorage` are suitable
Expand Down Expand Up @@ -106,10 +101,7 @@ use_structured_implementation!(
FuelBlockIdsToHeights,
FuelBlockMerkleData,
FuelBlockMerkleMetadata,
GenesisMetadata,
GenesisCoinRoots,
GenesisMessageRoots,
GenesisContractRoots
GenesisMetadata
);

#[cfg(feature = "relayer")]
Expand Down
51 changes: 10 additions & 41 deletions crates/fuel-core/src/service/genesis.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
use self::workers::GenesisWorkers;
use crate::{
database::{
genesis_progress::{
GenesisCoinRoots,
GenesisContractRoots,
GenesisMessageRoots,
GenesisMetadata,
},
genesis_progress::GenesisMetadata,
Database,
},
service::config::Config,
Expand All @@ -31,7 +26,6 @@ use fuel_core_storage::{
StorageTransaction,
Transactional,
},
MerkleRoot,
StorageAsMut,
};
use fuel_core_types::{
Expand Down Expand Up @@ -94,7 +88,7 @@ pub async fn execute_genesis_block(

let genesis = Genesis {
chain_config_hash: config.chain_config.root()?.into(),
coins_root: original_database.genesis_coin_root()?.into(),
coins_root: original_database.genesis_coins_root()?.into(),
messages_root: original_database.genesis_messages_root()?.into(),
contracts_root: original_database.genesis_contracts_root()?.into(),
};
Expand Down Expand Up @@ -130,18 +124,13 @@ async fn import_chain_state(workers: GenesisWorkers) -> anyhow::Result<()> {
return Err(e);
}

workers.compute_contracts_root().await?;

Ok(())
}

fn cleanup_genesis_progress(database: &mut Database) -> anyhow::Result<()> {
database.delete_all(GenesisMetadata::column())?;
database.delete_all(GenesisCoinRoots::column())?;
database.delete_all(GenesisMessageRoots::column())?;
database.delete_all(GenesisContractRoots::column())?;

Ok(())
database
.delete_all(GenesisMetadata::column())
.map_err(|e| e.into())
}

pub fn create_genesis_block(config: &Config) -> Block {
Expand Down Expand Up @@ -206,7 +195,7 @@ fn init_coin(
coin: &CoinConfig,
output_index: u64,
height: BlockHeight,
) -> anyhow::Result<MerkleRoot> {
) -> anyhow::Result<()> {
// TODO: Store merkle sum tree root over coins with unspecified utxo ids.
let utxo_id = coin.utxo_id().unwrap_or(generated_utxo_id(output_index));

Expand Down Expand Up @@ -235,7 +224,7 @@ fn init_coin(
return Err(anyhow!("Coin should not exist"));
}

compressed_coin.root()
Ok(())
}

fn init_contract(
Expand Down Expand Up @@ -290,7 +279,7 @@ fn init_contract(
Ok(())
}

fn init_da_message(db: &mut Database, msg: MessageConfig) -> anyhow::Result<MerkleRoot> {
fn init_da_message(db: &mut Database, msg: MessageConfig) -> anyhow::Result<()> {
let message: Message = msg.into();

if db
Expand All @@ -301,7 +290,7 @@ fn init_da_message(db: &mut Database, msg: MessageConfig) -> anyhow::Result<Merk
return Err(anyhow!("Message should not exist"));
}

message.root()
Ok(())
}

#[cfg(test)]
Expand All @@ -310,12 +299,7 @@ mod tests {

use crate::{
combined_database::CombinedDatabase,
database::genesis_progress::{
GenesisCoinRoots,
GenesisContractRoots,
GenesisMessageRoots,
GenesisResource,
},
database::genesis_progress::GenesisResource,
service::{
config::Config,
FuelService,
Expand Down Expand Up @@ -454,21 +438,6 @@ mod tests {
for key in GenesisResource::iter() {
assert!(db.genesis_progress(&key).is_none());
}
assert!(db
.genesis_roots::<GenesisCoinRoots>()
.unwrap()
.next()
.is_none());
assert!(db
.genesis_roots::<GenesisMessageRoots>()
.unwrap()
.next()
.is_none());
assert!(db
.genesis_roots::<GenesisContractRoots>()
.unwrap()
.next()
.is_none());
}

#[tokio::test]
Expand Down
Loading

0 comments on commit a7eec76

Please sign in to comment.