run whopper with encryption if arg is passed

This commit is contained in:
Avinash Sajjanshetty
2025-09-17 21:58:27 +05:30
parent f9a6cde79a
commit 10137ffaa4
3 changed files with 72 additions and 8 deletions

1
Cargo.lock generated
View File

@@ -4338,6 +4338,7 @@ version = "0.2.0-pre.3"
dependencies = [
"anyhow",
"clap",
"hex",
"memmap2",
"rand 0.9.2",
"rand_chacha 0.9.0",

View File

@@ -25,6 +25,8 @@ tracing = { workspace = true }
tracing-subscriber = { workspace = true, features = ["env-filter"] }
turso_core = { workspace = true, features = ["simulator"]}
turso_parser = { workspace = true }
hex = "0.4.3"
[features]
checksum = ["turso_core/checksum"]
checksum = ["turso_core/checksum"]
encryption = ["turso_core/encryption"]

View File

@@ -14,7 +14,9 @@ use std::cell::RefCell;
use std::sync::Arc;
use tracing::trace;
use tracing_subscriber::{EnvFilter, layer::SubscriberExt, util::SubscriberInitExt};
use turso_core::{Connection, Database, IO, Statement};
use turso_core::{
CipherMode, Connection, Database, DatabaseOpts, EncryptionOpts, IO, OpenFlags, Statement,
};
use turso_parser::ast::SortOrder;
mod io;
@@ -36,6 +38,9 @@ struct Args {
/// Enable MVCC (Multi-Version Concurrency Control)
#[arg(long)]
enable_mvcc: bool,
/// Enable database encryption
#[arg(long)]
enable_encryption: bool,
}
struct SimulatorConfig {
@@ -74,6 +79,17 @@ struct Stats {
integrity_checks: usize,
}
fn may_be_set_encryption(
conn: Arc<Connection>,
opts: &Option<EncryptionOpts>,
) -> anyhow::Result<Arc<Connection>> {
if let Some(opts) = opts {
conn.pragma_update("cipher", format!("'{}'", opts.cipher.clone()))?;
conn.pragma_update("hexkey", format!("'{}'", opts.hexkey.clone()))?;
}
Ok(conn)
}
fn main() -> anyhow::Result<()> {
init_logger();
@@ -109,14 +125,35 @@ fn main() -> anyhow::Result<()> {
let db_path = format!("whopper-{}-{}.db", seed, std::process::id());
let db = match Database::open_file(io.clone(), &db_path, args.enable_mvcc, true) {
Ok(db) => db,
Err(e) => {
return Err(anyhow::anyhow!("Database open failed: {}", e));
let encryption_opts = if args.enable_encryption {
let opts = random_encryption_config(&mut rng);
println!("cipher = {}, key = {}", opts.cipher, opts.hexkey);
Some(opts)
} else {
None
};
let db = {
let opts = DatabaseOpts::new()
.with_mvcc(args.enable_mvcc)
.with_indexes(true);
match Database::open_file_with_flags(
io.clone(),
&db_path,
OpenFlags::default(),
opts,
encryption_opts.clone(),
) {
Ok(db) => db,
Err(e) => {
return Err(anyhow::anyhow!("Database open failed: {}", e));
}
}
};
let boostrap_conn = match db.connect() {
Ok(conn) => conn,
Ok(conn) => may_be_set_encryption(conn, &encryption_opts)?,
Err(e) => {
return Err(anyhow::anyhow!("Connection failed: {}", e));
}
@@ -146,7 +183,7 @@ fn main() -> anyhow::Result<()> {
let mut fibers = Vec::new();
for i in 0..config.max_connections {
let conn = match db.connect() {
Ok(conn) => conn,
Ok(conn) => may_be_set_encryption(conn, &encryption_opts)?,
Err(e) => {
return Err(anyhow::anyhow!(
"Failed to create fiber connection {}: {}",
@@ -323,6 +360,30 @@ fn create_initial_schema(rng: &mut ChaCha8Rng) -> Vec<Create> {
schema
}
fn random_encryption_config(rng: &mut ChaCha8Rng) -> EncryptionOpts {
let cipher_modes = [
CipherMode::Aes128Gcm,
CipherMode::Aes256Gcm,
CipherMode::Aegis256,
CipherMode::Aegis128L,
CipherMode::Aegis128X2,
CipherMode::Aegis128X4,
CipherMode::Aegis256X2,
CipherMode::Aegis256X4,
];
let cipher_mode = cipher_modes[rng.random_range(0..cipher_modes.len())];
let key_size = cipher_mode.required_key_size();
let mut key = vec![0u8; key_size];
rng.fill_bytes(&mut key);
EncryptionOpts {
cipher: cipher_mode.to_string(),
hexkey: hex::encode(&key),
}
}
fn perform_work(
fiber_idx: usize,
rng: &mut ChaCha8Rng,