diff --git a/Cargo.lock b/Cargo.lock index 91dd8340b..8ca119d6d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -979,6 +979,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" dependencies = [ "bindgen", + "cc", "pkg-config", "vcpkg", ] diff --git a/store/Cargo.toml b/store/Cargo.toml index a485300df..db5f8b0a3 100644 --- a/store/Cargo.toml +++ b/store/Cargo.toml @@ -30,7 +30,7 @@ miden-node-utils = { path = "../utils", version = "0.2" } miden-objects = { workspace = true } once_cell = { version = "1.18.0" } prost = { version = "0.12" } -rusqlite = { version = "0.30", features = ["array", "buildtime_bindgen"] } +rusqlite = { version = "0.30", features = ["array", "buildtime_bindgen", "bundled"] } rusqlite_migration = { version = "1.0" } serde = { version = "1.0", features = ["derive"] } thiserror = { workspace = true } diff --git a/store/src/db/migrations.rs b/store/src/db/migrations.rs index a4faa9a7e..3eec2bc0b 100644 --- a/store/src/db/migrations.rs +++ b/store/src/db/migrations.rs @@ -25,9 +25,9 @@ pub static MIGRATIONS: Lazy = Lazy::new(|| { merkle_path BLOB NOT NULL, PRIMARY KEY (block_num, note_index), + CONSTRAINT fk_block_num FOREIGN KEY (block_num) REFERENCES block_headers (block_num), CONSTRAINT notes_block_number_is_u32 CHECK (block_num >= 0 AND block_num < 4294967296), - CONSTRAINT notes_note_index_is_u32 CHECK (note_index >= 0 AND note_index < 4294967296), - FOREIGN KEY (block_num) REFERENCES block_headers (block_num) + CONSTRAINT notes_note_index_is_u32 CHECK (note_index >= 0 AND note_index < 4294967296) ) STRICT, WITHOUT ROWID; CREATE TABLE @@ -38,7 +38,7 @@ pub static MIGRATIONS: Lazy = Lazy::new(|| { block_num INTEGER NOT NULL, PRIMARY KEY (account_id), - FOREIGN KEY (block_num) REFERENCES block_headers (block_num), + CONSTRAINT fk_block_num FOREIGN KEY (block_num) REFERENCES block_headers (block_num), CONSTRAINT accounts_block_num_is_u32 CHECK (block_num >= 0 AND block_num < 4294967296) ) STRICT, WITHOUT ROWID; @@ -50,10 +50,10 @@ pub static MIGRATIONS: Lazy = Lazy::new(|| { block_number INTEGER NOT NULL, PRIMARY KEY (nullifier), + CONSTRAINT fk_block_num FOREIGN KEY (block_number) REFERENCES block_headers (block_num), CONSTRAINT nullifiers_nullifier_is_digest CHECK (length(nullifier) = 32), CONSTRAINT nullifiers_nullifier_prefix_is_u16 CHECK (nullifier_prefix >= 0 AND nullifier_prefix < 65536), - CONSTRAINT nullifiers_block_number_is_u32 CHECK (block_number >= 0 AND block_number < 4294967296), - FOREIGN KEY (block_number) REFERENCES block_headers (block_num) + CONSTRAINT nullifiers_block_number_is_u32 CHECK (block_number >= 0 AND block_number < 4294967296) ) STRICT, WITHOUT ROWID; ", )]) @@ -61,5 +61,5 @@ pub static MIGRATIONS: Lazy = Lazy::new(|| { #[test] fn migrations_test() { - assert!(MIGRATIONS.validate().is_ok()); + assert_eq!(MIGRATIONS.validate(), Ok(())); } diff --git a/store/src/db/tests.rs b/store/src/db/tests.rs index 7abcf5da9..57af54176 100644 --- a/store/src/db/tests.rs +++ b/store/src/db/tests.rs @@ -18,12 +18,36 @@ fn create_db() -> Connection { conn } +fn create_block( + conn: &mut Connection, + block_num: u32, +) { + let block_header = BlockHeader::new( + num_to_rpo_digest(1), + block_num, + num_to_rpo_digest(3), + num_to_rpo_digest(4), + num_to_rpo_digest(5), + num_to_rpo_digest(6), + num_to_rpo_digest(7), + num_to_rpo_digest(8), + 9_u8.into(), + 10_u8.into(), + ); + + let transaction = conn.transaction().unwrap(); + sql::insert_block_header(&transaction, &block_header).unwrap(); + transaction.commit().unwrap(); +} + #[test] fn test_sql_insert_nullifiers_for_block() { let mut conn = create_db(); let nullifiers = [num_to_nullifier(1 << 48)]; + let block_num = 1; + create_block(&mut conn, block_num); // Insert a new nullifier succeeds { @@ -66,12 +90,14 @@ fn test_sql_insert_nullifiers_for_block() { fn test_sql_select_nullifiers() { let mut conn = create_db(); + let block_num = 1; + create_block(&mut conn, block_num); + // test querying empty table let nullifiers = sql::select_nullifiers(&mut conn).unwrap(); assert!(nullifiers.is_empty()); // test multiple entries - let block_num = 1; let mut state = vec![]; for i in 0..10 { let nullifier = num_to_nullifier(i); @@ -90,12 +116,14 @@ fn test_sql_select_nullifiers() { fn test_sql_select_notes() { let mut conn = create_db(); + let block_num = 1; + create_block(&mut conn, block_num); + // test querying empty table let notes = sql::select_notes(&mut conn).unwrap(); assert!(notes.is_empty()); // test multiple entries - let block_num = 1; let mut state = vec![]; for i in 0..10 { let note = Note { @@ -123,12 +151,14 @@ fn test_sql_select_notes() { fn test_sql_select_accounts() { let mut conn = create_db(); + let block_num = 1; + create_block(&mut conn, block_num); + // test querying empty table let accounts = sql::select_accounts(&mut conn).unwrap(); assert!(accounts.is_empty()); // test multiple entries - let block_num = 1; let mut state = vec![]; for i in 0..10 { let account_id = i; @@ -159,6 +189,7 @@ fn test_sql_select_nullifiers_by_block_range() { // test single item let nullifier1 = num_to_nullifier(1 << 48); let block_number1 = 1; + create_block(&mut conn, block_number1); let transaction = conn.transaction().unwrap(); sql::insert_nullifiers_for_block(&transaction, &[nullifier1], block_number1).unwrap(); @@ -182,6 +213,7 @@ fn test_sql_select_nullifiers_by_block_range() { // test two elements let nullifier2 = num_to_nullifier(2 << 48); let block_number2 = 2; + create_block(&mut conn, block_number2); let transaction = conn.transaction().unwrap(); sql::insert_nullifiers_for_block(&transaction, &[nullifier2], block_number2).unwrap(); @@ -339,13 +371,15 @@ fn test_db_block_header() { fn test_db_account() { let mut conn = create_db(); + let block_num = 1; + create_block(&mut conn, block_num); + // test empty table let account_ids = vec![0, 1, 2, 3, 4, 5]; let res = sql::select_accounts_by_block_range(&mut conn, 0, u32::MAX, &account_ids).unwrap(); assert!(res.is_empty()); // test insertion - let block_num = 1; let account_id = 0; let account_hash = num_to_rpo_digest(0); @@ -382,6 +416,9 @@ fn test_db_account() { fn test_notes() { let mut conn = create_db(); + let block_num_1 = 1; + create_block(&mut conn, block_num_1); + // test empty table let res = sql::select_notes_since_block_by_tag_and_sender(&mut conn, &[], &[], 0).unwrap(); assert!(res.is_empty()); @@ -391,7 +428,6 @@ fn test_notes() { assert!(res.is_empty()); // test insertion - let block_num = 1; let note_index = 2u32; let tag = 5; let note_hash = num_to_rpo_digest(3); @@ -401,7 +437,7 @@ fn test_notes() { let merkle_path = MerklePath::new(notes_db.open(&idx).path.nodes().to_vec()); let note = Note { - block_num, + block_num: block_num_1, note_created: NoteCreated { note_index, note_id: num_to_rpo_digest(3), @@ -424,7 +460,7 @@ fn test_notes() { &mut conn, &[(tag >> 48) as u32], &[], - block_num, + block_num_1, ) .unwrap(); assert!(res.is_empty()); @@ -434,14 +470,17 @@ fn test_notes() { &mut conn, &[(tag >> 48) as u32], &[], - block_num - 1, + block_num_1 - 1, ) .unwrap(); assert_eq!(res, vec![note.clone()]); + let block_num_2 = note.block_num + 1; + create_block(&mut conn, block_num_2); + // insertion second note with same tag, but on higher block let note2 = Note { - block_num: note.block_num + 1, + block_num: block_num_2, note_created: NoteCreated { note_index: note.note_created.note_index, note_id: num_to_rpo_digest(3), @@ -460,7 +499,7 @@ fn test_notes() { &mut conn, &[(tag >> 48) as u32], &[], - block_num - 1, + block_num_1 - 1, ) .unwrap(); assert_eq!(res, vec![note.clone()]); @@ -470,7 +509,7 @@ fn test_notes() { &mut conn, &[(tag >> 48) as u32], &[], - block_num, + block_num_1, ) .unwrap(); assert_eq!(res, vec![note2.clone()]);