Skip to content
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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ debug/
target/

# Cargo.lock has no effects on the consumers of a library crate
/Cargo.lock
Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk
Expand Down
13 changes: 13 additions & 0 deletions examples/insert/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "insert"
version = "0.1.0"
edition = "2024"

[dependencies]
alloy-primitives = "1.2.1"
alloy-trie = "0.8.1"
rand = "0.9.1"
triedb = { path = "../.." }

[profile.release]
debug = true
91 changes: 91 additions & 0 deletions examples/insert/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
use std::env;

use alloy_primitives::{Address, StorageKey, StorageValue, U256};
use alloy_trie::{EMPTY_ROOT_HASH, KECCAK_EMPTY};
use rand::prelude::*;
use triedb::{
Database,
account::Account,
path::{AddressPath, StoragePath},
transaction::TransactionError,
};

pub const DEFAULT_SETUP_DB_EOA_SIZE: usize = 1_000_000;
pub const DEFAULT_SETUP_DB_CONTRACT_SIZE: usize = 100_000;
pub const DEFAULT_SETUP_DB_STORAGE_PER_CONTRACT: usize = 10;
const SEED_EOA: u64 = 42; // EOA seeding value
const SEED_CONTRACT: u64 = 43; // contract account seeding value

pub fn generate_random_address(rng: &mut StdRng) -> AddressPath {
let addr = Address::random_with(rng);
AddressPath::for_address(addr)
}

pub fn setup_database(
db: &Database,
repeat: usize,
eoa_size: usize,
contract_size: usize,
storage_per_contract: usize,
) -> Result<(), TransactionError> {
// Populate database with initial accounts
let mut eoa_rng = StdRng::seed_from_u64(SEED_EOA);
let mut contract_rng = StdRng::seed_from_u64(SEED_CONTRACT);
for _i in 0..repeat {
let mut tx = db.begin_rw()?;
for i in 1..=eoa_size {
let address = generate_random_address(&mut eoa_rng);
let account =
Account::new(i as u64, U256::from(i as u64), EMPTY_ROOT_HASH, KECCAK_EMPTY);

tx.set_account(address, Some(account))?;
}

for i in 1..=contract_size {
let address = generate_random_address(&mut contract_rng);
let account =
Account::new(i as u64, U256::from(i as u64), EMPTY_ROOT_HASH, KECCAK_EMPTY);

tx.set_account(address.clone(), Some(account))?;

// add random storage to each account
for key in 1..=storage_per_contract {
let storage_key = StorageKey::from(U256::from(key));
let storage_path =
StoragePath::for_address_path_and_slot(address.clone(), storage_key);
let storage_value =
StorageValue::from_be_slice(storage_path.get_slot().pack().as_slice());

tx.set_storage_slot(storage_path, Some(storage_value))?;
}
}

tx.commit()?;
}
println!("root hash: {:?}", db.state_root());

Ok(())
}

fn main() {
let args: Vec<String> = env::args().collect();

let db_path = args.get(1).map(|s| s.to_owned()).unwrap_or_else(|| "test.db".to_string());
let repeat = args.get(2).and_then(|s| s.parse::<usize>().ok()).unwrap_or(1);
let eoa_size =
args.get(3).and_then(|s| s.parse::<usize>().ok()).unwrap_or(DEFAULT_SETUP_DB_EOA_SIZE);
let contract_size =
args.get(4).and_then(|s| s.parse::<usize>().ok()).unwrap_or(DEFAULT_SETUP_DB_CONTRACT_SIZE);
let storage_per_contract = args
.get(5)
.and_then(|s| s.parse::<usize>().ok())
.unwrap_or(DEFAULT_SETUP_DB_STORAGE_PER_CONTRACT);

let db = Database::options().create(true).wipe(true).open(db_path).unwrap();

println!("eoa size: {eoa_size}");
println!("repeat {repeat} times");
println!("contract size: {contract_size}, storage per contract: {storage_per_contract}");

setup_database(&db, repeat, eoa_size, contract_size, storage_per_contract).unwrap();
}