mirror of
https://github.com/aljazceru/turso.git
synced 2025-12-25 20:14:21 +01:00
Merge 'Enable encryption option in Whopper ' from Avinash Sajjanshetty
If encryption is arg is passed, then we run whopper tests with encryptions. We randomly generate cipher and key, and run whopper. They are also printed for debugging and analysis. Also, updated the corresponding scripts. So now you can do: ```bash ./whopper/bin/run --enable-encryption or ./whopper/bin/explore --enable-encryption ``` Closes #3183
This commit is contained in:
@@ -248,7 +248,7 @@ Note that exploration uses the `chaos` mode so if you need to reproduce a run, u
|
||||
SEED=1234 ./whopper/bin/run --mode chaos
|
||||
```
|
||||
|
||||
Both `explore` and `run` accept `--enable-checksums` flag to enable per page checksums.
|
||||
Both `explore` and `run` accept the `--enable-checksums` and `--enable-encryption` flags for per page checksums and encryption respectively.
|
||||
|
||||
## Python Bindings
|
||||
|
||||
|
||||
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -4338,6 +4338,7 @@ version = "0.2.0-pre.3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
"hex",
|
||||
"memmap2",
|
||||
"rand 0.9.2",
|
||||
"rand_chacha 0.9.0",
|
||||
|
||||
@@ -40,7 +40,6 @@ pub mod numeric;
|
||||
mod numeric;
|
||||
|
||||
use crate::storage::checksum::CHECKSUM_REQUIRED_RESERVED_BYTES;
|
||||
use crate::storage::encryption::CipherMode;
|
||||
use crate::translate::pragma::TURSO_CDC_DEFAULT_TABLE_NAME;
|
||||
#[cfg(all(feature = "fs", feature = "conn_raw_api"))]
|
||||
use crate::types::{WalFrameInfo, WalState};
|
||||
@@ -79,7 +78,7 @@ use std::{
|
||||
#[cfg(feature = "fs")]
|
||||
use storage::database::DatabaseFile;
|
||||
pub use storage::database::IOContext;
|
||||
pub use storage::encryption::{EncryptionContext, EncryptionKey};
|
||||
pub use storage::encryption::{CipherMode, EncryptionContext, EncryptionKey};
|
||||
use storage::page_cache::PageCache;
|
||||
use storage::pager::{AtomicDbState, DbState};
|
||||
use storage::sqlite3_ondisk::PageSize;
|
||||
|
||||
@@ -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"]
|
||||
@@ -1,18 +1,34 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Usage: ./explore.sh [--enable-checksums|--enable-encryption] [other-args...]
|
||||
|
||||
set -e
|
||||
|
||||
# Check for special build time flags (e.g. `--enable-checksums`)
|
||||
# Check for special build time flags (e.g. `--enable-checksums`, `--enable-encryption`)
|
||||
FEATURES=""
|
||||
ARGS=()
|
||||
CHECKSUM_ENABLED=false
|
||||
ENCRYPTION_ENABLED=false
|
||||
|
||||
for arg in "$@"; do
|
||||
if [[ "$arg" == "--enable-checksums" ]]; then
|
||||
FEATURES="--features checksum"
|
||||
CHECKSUM_ENABLED=true
|
||||
elif [[ "$arg" == "--enable-encryption" ]]; then
|
||||
FEATURES="--features encryption"
|
||||
ENCRYPTION_ENABLED=true
|
||||
ARGS+=("$arg")
|
||||
else
|
||||
ARGS+=("$arg")
|
||||
fi
|
||||
done
|
||||
|
||||
# check for incompatible options
|
||||
if [[ "$CHECKSUM_ENABLED" == true && "$ENCRYPTION_ENABLED" == true ]]; then
|
||||
echo "Error: --enable-checksums and --enable-encryption are not compatible with each other"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cargo build $FEATURES -p turso_whopper
|
||||
|
||||
echo "Running Whopper in an infinite loop in 'chaos' mode..."
|
||||
|
||||
@@ -1,18 +1,34 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Usage: ./run.sh [--enable-checksums|--enable-encryption] [other-args...]
|
||||
|
||||
set -e
|
||||
|
||||
# Check for special build time flags (e.g. `--enable-checksums`)
|
||||
# Check for special build time flags (e.g. `--enable-checksums`, `--enable-encryption`)
|
||||
FEATURES=""
|
||||
ARGS=()
|
||||
CHECKSUM_ENABLED=false
|
||||
ENCRYPTION_ENABLED=false
|
||||
|
||||
for arg in "$@"; do
|
||||
if [[ "$arg" == "--enable-checksums" ]]; then
|
||||
FEATURES="--features checksum"
|
||||
CHECKSUM_ENABLED=true
|
||||
elif [[ "$arg" == "--enable-encryption" ]]; then
|
||||
FEATURES="--features encryption"
|
||||
ENCRYPTION_ENABLED=true
|
||||
ARGS+=("$arg")
|
||||
else
|
||||
ARGS+=("$arg")
|
||||
fi
|
||||
done
|
||||
|
||||
# check for incompatible options
|
||||
if [[ "$CHECKSUM_ENABLED" == true && "$ENCRYPTION_ENABLED" == true ]]; then
|
||||
echo "Error: --enable-checksums and --enable-encryption are not compatible with each other"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cargo build $FEATURES -p turso_whopper
|
||||
|
||||
time RUST_BACKTRACE=full ./target/debug/turso_whopper "${ARGS[@]}"
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user