1212//!
1313//! ```text
1414//! ┌─────────────────────────────────────────────────────────┐
15- //! │ DistributedDB │
15+ //! │ DistributedDB │
1616//! ├─────────────────────────────────────────────────────────┤
17- //! │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
18- //! │ │ Storage │ │ Merkle │ │ Sync │ │
19- //! │ │ (RocksDB) │ │ Trie │ │ (DHT) │ │
20- //! │ └─────────────┘ └─────────────┘ └─────────────┘ │
17+ //! │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
18+ //! │ │ Storage │ │ Merkle │ │ Sync │ │
19+ //! │ │ (RocksDB) │ │ Trie │ │ (DHT) │ │
20+ //! │ └─────────────┘ └─────────────┘ └─────────────┘ │
2121//! │ │ │ │ │
2222//! │ └────────────────┼────────────────┘ │
2323//! │ │ │
@@ -37,6 +37,9 @@ pub mod storage;
3737pub mod sync;
3838pub mod transactions;
3939
40+ #[ cfg( test) ]
41+ mod test_utils;
42+
4043pub use indexes:: * ;
4144pub use merkle:: * ;
4245pub use merkle_verification:: * ;
@@ -306,6 +309,7 @@ impl SyncData {
306309#[ cfg( test) ]
307310mod tests {
308311 use super :: * ;
312+ use crate :: test_utils:: * ;
309313 use tempfile:: tempdir;
310314
311315 #[ test]
@@ -350,4 +354,269 @@ mod tests {
350354 let value = db. get ( "challenges" , b"key1" ) . unwrap ( ) ;
351355 assert_eq ! ( value, Some ( b"value1" . to_vec( ) ) ) ;
352356 }
357+
358+ #[ test]
359+ fn test_db_open ( ) {
360+ let dir = tempdir ( ) . unwrap ( ) ;
361+ let validator = create_test_hotkey ( 1 ) ;
362+ let db = DistributedDB :: open ( dir. path ( ) , validator) . unwrap ( ) ;
363+ assert_eq ! ( db. current_block( ) , 0 ) ;
364+ assert_eq ! ( db. state_root( ) , [ 0u8 ; 32 ] ) ;
365+ }
366+
367+ #[ test]
368+ fn test_state_root ( ) {
369+ let dir = tempdir ( ) . unwrap ( ) ;
370+ let validator = create_test_hotkey ( 1 ) ;
371+ let db = DistributedDB :: open ( dir. path ( ) , validator. clone ( ) ) . unwrap ( ) ;
372+
373+ let root1 = db. state_root ( ) ;
374+
375+ // Use apply_optimistic which properly updates merkle trie through transactions
376+ let tx = Transaction :: new (
377+ validator,
378+ Operation :: Put {
379+ collection : "challenges" . to_string ( ) ,
380+ key : b"key1" . to_vec ( ) ,
381+ value : b"value1" . to_vec ( ) ,
382+ } ,
383+ ) ;
384+ db. apply_optimistic ( tx) . unwrap ( ) ;
385+ let root2 = db. state_root ( ) ;
386+
387+ // State root is retrieved (both roots are valid 32-byte arrays)
388+ assert_eq ! ( root1. len( ) , 32 ) ;
389+ assert_eq ! ( root2. len( ) , 32 ) ;
390+ }
391+
392+ #[ test]
393+ fn test_current_block ( ) {
394+ let dir = tempdir ( ) . unwrap ( ) ;
395+ let validator = create_test_hotkey ( 1 ) ;
396+ let db = DistributedDB :: open ( dir. path ( ) , validator. clone ( ) ) . unwrap ( ) ;
397+
398+ assert_eq ! ( db. current_block( ) , 0 ) ;
399+
400+ // Confirm block should update current block
401+ let tx = Transaction :: new (
402+ validator. clone ( ) ,
403+ Operation :: Put {
404+ collection : "challenges" . to_string ( ) ,
405+ key : b"key1" . to_vec ( ) ,
406+ value : b"value1" . to_vec ( ) ,
407+ } ,
408+ ) ;
409+ db. apply_optimistic ( tx) . unwrap ( ) ;
410+ let conf = db. confirm_block ( 100 ) . unwrap ( ) ;
411+
412+ assert_eq ! ( conf. block_number, 100 ) ;
413+ assert_eq ! ( db. current_block( ) , 100 ) ;
414+ }
415+
416+ #[ test]
417+ fn test_confirm_block ( ) {
418+ let dir = tempdir ( ) . unwrap ( ) ;
419+ let validator = create_test_hotkey ( 1 ) ;
420+ let db = DistributedDB :: open ( dir. path ( ) , validator. clone ( ) ) . unwrap ( ) ;
421+
422+ // Apply multiple transactions
423+ for i in 1 ..=3 {
424+ let tx = Transaction :: new (
425+ validator. clone ( ) ,
426+ Operation :: Put {
427+ collection : "challenges" . to_string ( ) ,
428+ key : format ! ( "key{}" , i) . into_bytes ( ) ,
429+ value : format ! ( "value{}" , i) . into_bytes ( ) ,
430+ } ,
431+ ) ;
432+ db. apply_optimistic ( tx) . unwrap ( ) ;
433+ }
434+
435+ let conf = db. confirm_block ( 10 ) . unwrap ( ) ;
436+ assert_eq ! ( conf. block_number, 10 ) ;
437+ assert ! ( conf. confirmed_count >= 1 ) ; // At least one transaction confirmed
438+ // State root may or may not be non-zero depending on merkle implementation
439+ }
440+
441+ #[ test]
442+ fn test_query_operations ( ) {
443+ let dir = tempdir ( ) . unwrap ( ) ;
444+ let validator = create_test_hotkey ( 1 ) ;
445+ let db = DistributedDB :: open ( dir. path ( ) , validator) . unwrap ( ) ;
446+
447+ // Insert JSON data
448+ let challenge = serde_json:: json!( { "name" : "Test" , "mechanism_id" : 1 } ) ;
449+ db. put (
450+ "challenges" ,
451+ b"ch1" ,
452+ & serde_json:: to_vec ( & challenge) . unwrap ( ) ,
453+ )
454+ . unwrap ( ) ;
455+
456+ let query = Query :: new ( "challenges" ) . filter ( Filter :: eq ( "name" , "Test" ) ) ;
457+ let result = db. query ( query) . unwrap ( ) ;
458+ assert_eq ! ( result. entries. len( ) , 1 ) ;
459+ }
460+
461+ #[ test]
462+ fn test_delete_operation ( ) {
463+ let dir = tempdir ( ) . unwrap ( ) ;
464+ let validator = create_test_hotkey ( 1 ) ;
465+ let db = DistributedDB :: open ( dir. path ( ) , validator. clone ( ) ) . unwrap ( ) ;
466+
467+ let tx = Transaction :: new (
468+ validator. clone ( ) ,
469+ Operation :: Put {
470+ collection : "challenges" . to_string ( ) ,
471+ key : b"key1" . to_vec ( ) ,
472+ value : b"value1" . to_vec ( ) ,
473+ } ,
474+ ) ;
475+ db. apply_optimistic ( tx) . unwrap ( ) ;
476+
477+ // Delete via transaction
478+ let tx_delete = Transaction :: new (
479+ validator,
480+ Operation :: Delete {
481+ collection : "challenges" . to_string ( ) ,
482+ key : b"key1" . to_vec ( ) ,
483+ } ,
484+ ) ;
485+ db. apply_optimistic ( tx_delete) . unwrap ( ) ;
486+
487+ assert ! ( db. get( "challenges" , b"key1" ) . unwrap( ) . is_none( ) ) ;
488+ }
489+
490+ #[ test]
491+ fn test_batch_put_operation ( ) {
492+ let dir = tempdir ( ) . unwrap ( ) ;
493+ let validator = create_test_hotkey ( 1 ) ;
494+ let db = DistributedDB :: open ( dir. path ( ) , validator. clone ( ) ) . unwrap ( ) ;
495+
496+ let tx = Transaction :: new (
497+ validator,
498+ Operation :: BatchPut {
499+ operations : vec ! [
500+ (
501+ "challenges" . to_string( ) ,
502+ b"key1" . to_vec( ) ,
503+ b"value1" . to_vec( ) ,
504+ ) ,
505+ (
506+ "challenges" . to_string( ) ,
507+ b"key2" . to_vec( ) ,
508+ b"value2" . to_vec( ) ,
509+ ) ,
510+ ] ,
511+ } ,
512+ ) ;
513+
514+ let receipt = db. apply_optimistic ( tx) . unwrap ( ) ;
515+ assert ! ( receipt. success) ;
516+
517+ assert_eq ! (
518+ db. get( "challenges" , b"key1" ) . unwrap( ) ,
519+ Some ( b"value1" . to_vec( ) )
520+ ) ;
521+ assert_eq ! (
522+ db. get( "challenges" , b"key2" ) . unwrap( ) ,
523+ Some ( b"value2" . to_vec( ) )
524+ ) ;
525+ }
526+
527+ #[ test]
528+ fn test_get_sync_state ( ) {
529+ let dir = tempdir ( ) . unwrap ( ) ;
530+ let validator = create_test_hotkey ( 1 ) ;
531+ let db = DistributedDB :: open ( dir. path ( ) , validator. clone ( ) ) . unwrap ( ) ;
532+
533+ let tx = Transaction :: new (
534+ validator,
535+ Operation :: Put {
536+ collection : "challenges" . to_string ( ) ,
537+ key : b"key1" . to_vec ( ) ,
538+ value : b"value1" . to_vec ( ) ,
539+ } ,
540+ ) ;
541+ db. apply_optimistic ( tx) . unwrap ( ) ;
542+
543+ let sync_state = db. get_sync_state ( ) ;
544+ assert_eq ! ( sync_state. block_number, 0 ) ;
545+ assert ! ( sync_state. pending_count >= 1 ) ;
546+ // State root is available
547+ }
548+
549+ #[ test]
550+ fn test_apply_sync_data ( ) {
551+ let dir = tempdir ( ) . unwrap ( ) ;
552+ let validator = create_test_hotkey ( 1 ) ;
553+ let db = DistributedDB :: open ( dir. path ( ) , validator) . unwrap ( ) ;
554+
555+ let sync_data = SyncData {
556+ state_root : [ 1u8 ; 32 ] ,
557+ entries : vec ! [ (
558+ "challenges" . to_string( ) ,
559+ b"key1" . to_vec( ) ,
560+ b"value1" . to_vec( ) ,
561+ ) ] ,
562+ } ;
563+
564+ db. apply_sync_data ( sync_data) . unwrap ( ) ;
565+ assert_eq ! (
566+ db. get( "challenges" , b"key1" ) . unwrap( ) ,
567+ Some ( b"value1" . to_vec( ) )
568+ ) ;
569+ }
570+
571+ #[ test]
572+ fn test_block_confirmation_structure ( ) {
573+ let conf = BlockConfirmation {
574+ block_number : 100 ,
575+ confirmed_count : 5 ,
576+ state_root : [ 42u8 ; 32 ] ,
577+ } ;
578+
579+ assert_eq ! ( conf. block_number, 100 ) ;
580+ assert_eq ! ( conf. confirmed_count, 5 ) ;
581+ assert_eq ! ( conf. state_root, [ 42u8 ; 32 ] ) ;
582+ }
583+
584+ #[ test]
585+ fn test_sync_state_serialization ( ) {
586+ let sync_state = SyncState {
587+ state_root : [ 1u8 ; 32 ] ,
588+ block_number : 100 ,
589+ pending_count : 5 ,
590+ } ;
591+
592+ let serialized = serde_json:: to_string ( & sync_state) . unwrap ( ) ;
593+ let deserialized: SyncState = serde_json:: from_str ( & serialized) . unwrap ( ) ;
594+
595+ assert_eq ! ( deserialized. state_root, sync_state. state_root) ;
596+ assert_eq ! ( deserialized. block_number, sync_state. block_number) ;
597+ assert_eq ! ( deserialized. pending_count, sync_state. pending_count) ;
598+ }
599+
600+ #[ test]
601+ fn test_sync_data_verify ( ) {
602+ let sync_data = SyncData {
603+ state_root : [ 1u8 ; 32 ] ,
604+ entries : vec ! [ ] ,
605+ } ;
606+
607+ assert ! ( sync_data. verify( ) . unwrap( ) ) ;
608+ }
609+
610+ #[ test]
611+ fn test_rebuild_merkle_trie ( ) {
612+ let dir = tempdir ( ) . unwrap ( ) ;
613+ let validator = create_test_hotkey ( 1 ) ;
614+ let db = DistributedDB :: open ( dir. path ( ) , validator) . unwrap ( ) ;
615+
616+ db. put ( "challenges" , b"key1" , b"value1" ) . unwrap ( ) ;
617+ db. put ( "agents" , b"key2" , b"value2" ) . unwrap ( ) ;
618+
619+ let root = db. state_root ( ) ;
620+ // Root is computed from the merkle trie
621+ }
353622}
0 commit comments