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 5c261ee
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 1 deletion.
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 = "read_view_get_coins"
156 changes: 156 additions & 0 deletions benches/benches/read_view_get_coins.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
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_concurrent(&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_concurrent(
&mut self,
utxo_ids: &[UtxoId],
) -> anyhow::Result<usize> {
let mut total = 0;
let mut handles = Vec::new();
for _ in 0..self.params.num_queries {
let on_chain_db = self.db.on_chain().clone();
let off_chain_db = self.db.off_chain().clone();
let utxo_ids = utxo_ids.to_vec();

let handle = tokio::spawn(async move {
let read_database =
ReadDatabase::new(0, BlockHeight::new(0), on_chain_db, off_chain_db);

let read_view = read_database.view().unwrap();
let res: Vec<_> = read_view.coins(utxo_ids).await.collect();
res.len()
});

handles.push(handle);
}

for handle in handles {
let res = handle.await.unwrap();
total += res;
}

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,
}
}
}
4 changes: 3 additions & 1 deletion crates/fuel-core/src/state/rocks_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ where
opener: F,
path: P,
columns: Vec<Description::Column>,
capacity: Option<usize>,
_capacity: Option<usize>,
max_fds: i32,
) -> DatabaseResult<Self>
where
Expand All @@ -252,6 +252,8 @@ where
// See https://github.com/facebook/rocksdb/blob/a1523efcdf2f0e8133b9a9f6e170a0dad49f928f/include/rocksdb/table.h#L246-L271 for details on what the format versions are/do.
block_opts.set_format_version(5);

let capacity = Some(100 * 1024 * 1024);

if let Some(capacity) = capacity {
// Set cache size 1/3 of the capacity as recommended by
// https://github.com/facebook/rocksdb/wiki/Setup-Options-and-Basic-Tuning#block-cache-size
Expand Down

0 comments on commit 5c261ee

Please sign in to comment.