|
@@ -4,17 +4,19 @@
|
|
|
//! implementation
|
|
//! implementation
|
|
|
use std::str::FromStr;
|
|
use std::str::FromStr;
|
|
|
|
|
|
|
|
|
|
+// For derivation path parsing
|
|
|
|
|
+use bitcoin::bip32::DerivationPath;
|
|
|
use cashu::secret::Secret;
|
|
use cashu::secret::Secret;
|
|
|
use cashu::{Amount, CurrencyUnit, SecretKey};
|
|
use cashu::{Amount, CurrencyUnit, SecretKey};
|
|
|
|
|
|
|
|
use super::*;
|
|
use super::*;
|
|
|
-use crate::database;
|
|
|
|
|
|
|
+use crate::database::MintKVStoreDatabase;
|
|
|
use crate::mint::MintKeySetInfo;
|
|
use crate::mint::MintKeySetInfo;
|
|
|
|
|
|
|
|
#[inline]
|
|
#[inline]
|
|
|
async fn setup_keyset<DB>(db: &DB) -> Id
|
|
async fn setup_keyset<DB>(db: &DB) -> Id
|
|
|
where
|
|
where
|
|
|
- DB: KeysDatabase<Err = database::Error>,
|
|
|
|
|
|
|
+ DB: KeysDatabase<Err = crate::database::Error>,
|
|
|
{
|
|
{
|
|
|
let keyset_id = Id::from_str("00916bbf7ef91a36").unwrap();
|
|
let keyset_id = Id::from_str("00916bbf7ef91a36").unwrap();
|
|
|
let keyset_info = MintKeySetInfo {
|
|
let keyset_info = MintKeySetInfo {
|
|
@@ -23,7 +25,7 @@ where
|
|
|
active: true,
|
|
active: true,
|
|
|
valid_from: 0,
|
|
valid_from: 0,
|
|
|
final_expiry: None,
|
|
final_expiry: None,
|
|
|
- derivation_path: bitcoin::bip32::DerivationPath::from_str("m/0'/0'/0'").unwrap(),
|
|
|
|
|
|
|
+ derivation_path: DerivationPath::from_str("m/0'/0'/0'").unwrap(),
|
|
|
derivation_path_index: Some(0),
|
|
derivation_path_index: Some(0),
|
|
|
max_order: 32,
|
|
max_order: 32,
|
|
|
input_fee_ppk: 0,
|
|
input_fee_ppk: 0,
|
|
@@ -37,7 +39,7 @@ where
|
|
|
/// State transition test
|
|
/// State transition test
|
|
|
pub async fn state_transition<DB>(db: DB)
|
|
pub async fn state_transition<DB>(db: DB)
|
|
|
where
|
|
where
|
|
|
- DB: Database<database::Error> + KeysDatabase<Err = database::Error>,
|
|
|
|
|
|
|
+ DB: Database<crate::database::Error> + KeysDatabase<Err = crate::database::Error>,
|
|
|
{
|
|
{
|
|
|
let keyset_id = setup_keyset(&db).await;
|
|
let keyset_id = setup_keyset(&db).await;
|
|
|
|
|
|
|
@@ -83,7 +85,7 @@ where
|
|
|
/// other tests
|
|
/// other tests
|
|
|
pub async fn add_and_find_proofs<DB>(db: DB)
|
|
pub async fn add_and_find_proofs<DB>(db: DB)
|
|
|
where
|
|
where
|
|
|
- DB: Database<database::Error> + KeysDatabase<Err = database::Error>,
|
|
|
|
|
|
|
+ DB: Database<crate::database::Error> + KeysDatabase<Err = crate::database::Error>,
|
|
|
{
|
|
{
|
|
|
let keyset_id = setup_keyset(&db).await;
|
|
let keyset_id = setup_keyset(&db).await;
|
|
|
|
|
|
|
@@ -122,12 +124,99 @@ where
|
|
|
assert_eq!(proofs_from_db.unwrap().len(), 2);
|
|
assert_eq!(proofs_from_db.unwrap().len(), 2);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/// Test KV store functionality including write, read, list, update, and remove operations
|
|
|
|
|
+pub async fn kvstore_functionality<DB>(db: DB)
|
|
|
|
|
+where
|
|
|
|
|
+ DB: Database<crate::database::Error> + MintKVStoreDatabase<Err = crate::database::Error>,
|
|
|
|
|
+{
|
|
|
|
|
+ // Test basic read/write operations in transaction
|
|
|
|
|
+ {
|
|
|
|
|
+ let mut tx = Database::begin_transaction(&db).await.unwrap();
|
|
|
|
|
+
|
|
|
|
|
+ // Write some test data
|
|
|
|
|
+ tx.kv_write("test_namespace", "sub_namespace", "key1", b"value1")
|
|
|
|
|
+ .await
|
|
|
|
|
+ .unwrap();
|
|
|
|
|
+ tx.kv_write("test_namespace", "sub_namespace", "key2", b"value2")
|
|
|
|
|
+ .await
|
|
|
|
|
+ .unwrap();
|
|
|
|
|
+ tx.kv_write("test_namespace", "other_sub", "key3", b"value3")
|
|
|
|
|
+ .await
|
|
|
|
|
+ .unwrap();
|
|
|
|
|
+
|
|
|
|
|
+ // Read back the data in the transaction
|
|
|
|
|
+ let value1 = tx
|
|
|
|
|
+ .kv_read("test_namespace", "sub_namespace", "key1")
|
|
|
|
|
+ .await
|
|
|
|
|
+ .unwrap();
|
|
|
|
|
+ assert_eq!(value1, Some(b"value1".to_vec()));
|
|
|
|
|
+
|
|
|
|
|
+ // List keys in namespace
|
|
|
|
|
+ let keys = tx.kv_list("test_namespace", "sub_namespace").await.unwrap();
|
|
|
|
|
+ assert_eq!(keys, vec!["key1", "key2"]);
|
|
|
|
|
+
|
|
|
|
|
+ // Commit transaction
|
|
|
|
|
+ tx.commit().await.unwrap();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Test read operations after commit
|
|
|
|
|
+ {
|
|
|
|
|
+ let value1 = db
|
|
|
|
|
+ .kv_read("test_namespace", "sub_namespace", "key1")
|
|
|
|
|
+ .await
|
|
|
|
|
+ .unwrap();
|
|
|
|
|
+ assert_eq!(value1, Some(b"value1".to_vec()));
|
|
|
|
|
+
|
|
|
|
|
+ let keys = db.kv_list("test_namespace", "sub_namespace").await.unwrap();
|
|
|
|
|
+ assert_eq!(keys, vec!["key1", "key2"]);
|
|
|
|
|
+
|
|
|
|
|
+ let other_keys = db.kv_list("test_namespace", "other_sub").await.unwrap();
|
|
|
|
|
+ assert_eq!(other_keys, vec!["key3"]);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Test update and remove operations
|
|
|
|
|
+ {
|
|
|
|
|
+ let mut tx = Database::begin_transaction(&db).await.unwrap();
|
|
|
|
|
+
|
|
|
|
|
+ // Update existing key
|
|
|
|
|
+ tx.kv_write("test_namespace", "sub_namespace", "key1", b"updated_value1")
|
|
|
|
|
+ .await
|
|
|
|
|
+ .unwrap();
|
|
|
|
|
+
|
|
|
|
|
+ // Remove a key
|
|
|
|
|
+ tx.kv_remove("test_namespace", "sub_namespace", "key2")
|
|
|
|
|
+ .await
|
|
|
|
|
+ .unwrap();
|
|
|
|
|
+
|
|
|
|
|
+ tx.commit().await.unwrap();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Verify updates
|
|
|
|
|
+ {
|
|
|
|
|
+ let value1 = db
|
|
|
|
|
+ .kv_read("test_namespace", "sub_namespace", "key1")
|
|
|
|
|
+ .await
|
|
|
|
|
+ .unwrap();
|
|
|
|
|
+ assert_eq!(value1, Some(b"updated_value1".to_vec()));
|
|
|
|
|
+
|
|
|
|
|
+ let value2 = db
|
|
|
|
|
+ .kv_read("test_namespace", "sub_namespace", "key2")
|
|
|
|
|
+ .await
|
|
|
|
|
+ .unwrap();
|
|
|
|
|
+ assert_eq!(value2, None);
|
|
|
|
|
+
|
|
|
|
|
+ let keys = db.kv_list("test_namespace", "sub_namespace").await.unwrap();
|
|
|
|
|
+ assert_eq!(keys, vec!["key1"]);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
/// Unit test that is expected to be passed for a correct database implementation
|
|
/// Unit test that is expected to be passed for a correct database implementation
|
|
|
#[macro_export]
|
|
#[macro_export]
|
|
|
macro_rules! mint_db_test {
|
|
macro_rules! mint_db_test {
|
|
|
($make_db_fn:ident) => {
|
|
($make_db_fn:ident) => {
|
|
|
mint_db_test!(state_transition, $make_db_fn);
|
|
mint_db_test!(state_transition, $make_db_fn);
|
|
|
mint_db_test!(add_and_find_proofs, $make_db_fn);
|
|
mint_db_test!(add_and_find_proofs, $make_db_fn);
|
|
|
|
|
+ mint_db_test!(kvstore_functionality, $make_db_fn);
|
|
|
};
|
|
};
|
|
|
($name:ident, $make_db_fn:ident) => {
|
|
($name:ident, $make_db_fn:ident) => {
|
|
|
#[tokio::test]
|
|
#[tokio::test]
|