Skip to content

Commit

Permalink
feat: simple bench target for measuring coin batch lookup times
Browse files Browse the repository at this point in the history
  • Loading branch information
netrome committed Nov 15, 2024
1 parent 676ca8f commit 4e7d3b3
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions benches/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ fuel-core = { path = "../crates/fuel-core", default-features = false, features =
"rocksdb-production",
] }
fuel-core-chain-config = { workspace = true }
fuel-core-client = { path = "./../crates/client" }
fuel-core-database = { path = "./../crates/database" }
fuel-core-services = { path = "./../crates/services" }
fuel-core-storage = { path = "./../crates/storage", features = ["smt"] }
Expand Down Expand Up @@ -76,3 +77,7 @@ name = "transaction_throughput"
[[bench]]
harness = false
name = "db_lookup_times"

[[bench]]
harness = false
name = "end_to_end_query_times"
145 changes: 145 additions & 0 deletions benches/benches/end_to_end_query_times.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
use fuel_core::{
combined_database::CombinedDatabase,
fuel_core_graphql_api::database::ReadDatabase,
};

use fuel_core_chain_config::Randomize;
use fuel_core_storage::{
tables::{
Coins,
FuelBlocks,
},
transactional::WriteTransaction,
StorageAsMut,
};
use fuel_core_types::{
blockchain::block::CompressedBlock,
entities::coins::coin::CompressedCoin,
fuel_tx::{
Address,
AssetId,
UtxoId,
},
fuel_types::BlockHeight,
};
use rand::{
rngs::StdRng,
SeedableRng,
};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
println!("Setting up bench harness.");
let mut harness = Harness::new(StdRng::seed_from_u64(2322)).await?;

println!("Populating storage with transactions.");
let utxo_ids = harness.populate_database().await?;

println!("Querying transactions from storage.");
let total = harness.query_database_many_times(&utxo_ids).await?;

println!("Queried a total of {total} coins");

Ok(())
}

struct Harness<Rng> {
rng: Rng,
params: Parameters,
db: CombinedDatabase,
}

impl<Rng: rand::RngCore + rand::CryptoRng + Send> Harness<Rng> {
async fn new(rng: Rng) -> anyhow::Result<Self> {
let params = Parameters::hard_coded();
let db = CombinedDatabase::default();

Ok(Self { rng, params, db })
}

async fn populate_database(&mut self) -> anyhow::Result<Vec<UtxoId>> {
let mut utxo_ids = Vec::new();

let mut coins: Vec<_> = (0..(self.params.utxo_count_per_block
* self.params.num_blocks))
.map(|_| self.generate_random_coin())
.collect();

for block_height in 0..self.params.num_blocks {
let block_height = BlockHeight::from(block_height as u32);
let mut compressed_block = CompressedBlock::default();
compressed_block.header_mut().set_block_height(block_height);

let mut transaction = self.db.on_chain_mut().write_transaction();

transaction
.storage::<FuelBlocks>()
.insert(&block_height, &compressed_block)
.unwrap();

for _ in 0..self.params.utxo_count_per_block {
let (utxo_id, coin) = coins.pop().unwrap(); // TODO: Cleanup

transaction
.storage::<Coins>()
.insert(&utxo_id, &coin)
.unwrap();

utxo_ids.push(utxo_id);
}

transaction.commit().unwrap();
}

Ok(utxo_ids)
}

async fn query_database_many_times(
&mut self,
utxo_ids: &[UtxoId],
) -> anyhow::Result<usize> {
let read_database = ReadDatabase::new(
0,
BlockHeight::new(0),
self.db.on_chain().clone(),
self.db.off_chain().clone(),
);

let read_view = read_database.view()?;

let mut total = 0;
for _ in 0..self.params.num_queries {
let res: Vec<_> = read_view.coins(utxo_ids.to_vec()).await.collect();
total += res.len();
}

Ok(total)
}

fn generate_random_coin(&mut self) -> (UtxoId, CompressedCoin) {
let utxo_id = UtxoId::randomize(&mut self.rng);

let mut coin = CompressedCoin::default();
coin.set_amount(self.rng.next_u64());
coin.set_asset_id(AssetId::randomize(&mut self.rng));
coin.set_owner(Address::randomize(&mut self.rng));

(utxo_id, coin)
}
}

struct Parameters {
num_queries: usize,
num_blocks: usize,
utxo_count_per_block: usize,
}

impl Parameters {
fn hard_coded() -> Self {
Self {
num_queries: 100,
num_blocks: 100,
utxo_count_per_block: 1000,
}
}
}

0 comments on commit 4e7d3b3

Please sign in to comment.