@@ -4,13 +4,16 @@ use revault_tx::{
44 bitcoin:: { secp256k1, util:: bip32, Amount , BlockHash , Network , OutPoint } ,
55 scripts:: { CpfpDescriptor , DepositDescriptor , UnvaultDescriptor } ,
66} ;
7- use schema:: { DbInstance , DbSignature , DbVault , SigTxType , SCHEMA } ;
7+ use schema:: { DbFeerate , DbInstance , DbSignature , DbVault , SigTxType , SCHEMA } ;
88
99use std:: { collections, convert:: TryInto , fs, io, os:: unix:: fs:: OpenOptionsExt , path, time} ;
1010
1111use rusqlite:: params;
1212
1313pub const DB_VERSION : u32 = 0 ;
14+ // FIXME: Use correct values
15+ pub const INIT_VAULT_RESERVE_FEERATE : u64 = 1000 ;
16+ pub const INIT_VAULT_RESERVE_HEIGHT : i32 = 680000 ;
1417
1518#[ derive( Debug ) ]
1619pub enum DatabaseError {
@@ -22,6 +25,8 @@ pub enum DatabaseError {
2225 DescriptorMismatch ( String , String ) ,
2326 /// An operation was requested on a vault that doesn't exist
2427 UnknownVault ( Box < dyn std:: fmt:: Debug > ) ,
28+ /// Vault reserve feerate not found
29+ VaultReserveFeerateNotFound ( String ) ,
2530}
2631
2732impl std:: fmt:: Display for DatabaseError {
@@ -43,6 +48,9 @@ impl std::fmt::Display for DatabaseError {
4348 "Operation requested on vault at '{:?}' but no such vault exist in database." ,
4449 * id
4550 ) ,
51+ Self :: VaultReserveFeerateNotFound ( ref e) => write ! (
52+ f,
53+ "Vault reserve feerate not found: {}" , e) ,
4654 }
4755 }
4856}
@@ -412,6 +420,36 @@ pub fn db_cancel_signatures(
412420 db_sigs_by_type ( db_path, vault_id, SigTxType :: Cancel )
413421}
414422
423+ pub fn db_update_vault_reserve_feerate (
424+ db_path : & path:: Path ,
425+ last_update : i32 ,
426+ vault_reserve_feerate : u64 ,
427+ ) -> Result < ( ) , DatabaseError > {
428+ db_exec ( db_path, |db_tx| {
429+ db_tx. execute (
430+ "UPDATE feerates
431+ SET last_update = (?1),
432+ vault_reserve_feerate = (?2)" ,
433+ params ! [ last_update, vault_reserve_feerate] ,
434+ ) ?;
435+ Ok ( ( ) )
436+ } )
437+ }
438+
439+
440+ pub fn db_vault_reserve_feerate ( db_path : & path:: Path ) -> Result < DbFeerate , DatabaseError > {
441+ let res: Option < DbFeerate > = db_query (
442+ db_path,
443+ "SELECT * FROM feerates ORDER BY last_update DESC LIMIT 1" ,
444+ [ ] , |row| row. try_into ( ) ) ?. pop ( ) ;
445+
446+ match res {
447+ Some ( db_feerate) => Ok ( db_feerate) ,
448+ None => return Err ( DatabaseError :: VaultReserveFeerateNotFound (
449+ String :: from ( "Feerates table not correctly initialised." ) ) )
450+ }
451+ }
452+
415453// Create the db file with RW permissions only for the user
416454fn create_db_file ( db_path : & path:: Path ) -> Result < ( ) , DatabaseError > {
417455 let mut options = fs:: OpenOptions :: new ( ) ;
@@ -460,7 +498,19 @@ fn create_db(
460498 vec![ 0u8 ; 32 ] ,
461499 ] ,
462500 ) ?;
463-
501+ if network == Network :: Bitcoin {
502+ tx. execute (
503+ "INSERT INTO feerates (last_update, vault_reserve_feerate)
504+ VALUES (?1,?2)" ,
505+ params ! [ INIT_VAULT_RESERVE_HEIGHT , INIT_VAULT_RESERVE_FEERATE ] ,
506+ ) ?;
507+ } else {
508+ tx. execute (
509+ "INSERT INTO feerates (last_update, vault_reserve_feerate)
510+ VALUES (?1,?2)" ,
511+ params ! [ 0 , INIT_VAULT_RESERVE_FEERATE ] ,
512+ ) ?;
513+ }
464514 Ok ( ( ) )
465515 } )
466516}
@@ -547,7 +597,7 @@ mod tests {
547597 use super :: * ;
548598
549599 // Create a dummy database and return its path (to be deleted by the caller)
550- fn get_db ( ) -> path:: PathBuf {
600+ fn get_db ( network : Network ) -> path:: PathBuf {
551601 let db_path: path:: PathBuf =
552602 format ! ( "scratch_test_{:?}.sqlite3" , thread:: current( ) . id( ) ) . into ( ) ;
553603 let deposit_desc = DepositDescriptor :: from_str ( "wsh(multi(2,xpub6AHA9hZDN11k2ijHMeS5QqHx2KP9aMBRhTDqANMnwVtdyw2TDYRmF8PjpvwUFcL1Et8Hj59S3gTSMcUQ5gAqTz3Wd8EsMTmF3DChhqPQBnU/*,xpub6AaffFGfH6WXfm6pwWzmUMuECQnoLeB3agMKaLyEBZ5ZVfwtnS5VJKqXBt8o5ooCWVy2H87GsZshp7DeKE25eWLyd1Ccuh2ZubQUkgpiVux/*))#n3cj9mhy" ) . unwrap ( ) ;
@@ -562,7 +612,7 @@ mod tests {
562612 & deposit_desc,
563613 & unvault_desc,
564614 & cpfp_desc,
565- Network :: Bitcoin ,
615+ network ,
566616 )
567617 . unwrap ( ) ;
568618
@@ -698,7 +748,7 @@ mod tests {
698748 // Sanity check we can create, delegate and delete a vault
699749 #[ test]
700750 fn db_vault_creation ( ) {
701- let db_path = get_db ( ) ;
751+ let db_path = get_db ( Network :: Bitcoin ) ;
702752 let outpoint_a = OutPoint :: from_str (
703753 "5bebdb97b54e2268b3fccd4aeea99419d87a92f88f27e906ceea5e863946a731:0" ,
704754 )
@@ -974,7 +1024,7 @@ mod tests {
9741024
9751025 #[ test]
9761026 fn db_tip_update ( ) {
977- let db_path = get_db ( ) ;
1027+ let db_path = get_db ( Network :: Bitcoin ) ;
9781028
9791029 let height = 21 ;
9801030 let hash =
@@ -997,4 +1047,29 @@ mod tests {
9971047 // Cleanup
9981048 fs:: remove_file ( & db_path) . unwrap ( ) ;
9991049 }
1050+
1051+ #[ test]
1052+ fn db_feerates_table ( ) {
1053+ let db_path = get_db ( Network :: Testnet ) ;
1054+ let vault_reserve_feerate = 1001 ;
1055+ let test_feerate = 1337 ;
1056+
1057+ let init_feerate = db_vault_reserve_feerate ( & db_path) . unwrap ( ) . vault_reserve_feerate ;
1058+ assert_eq ! ( init_feerate, INIT_VAULT_RESERVE_FEERATE ) ;
1059+
1060+ for last_update in 1 ..=10 {
1061+ if last_update < 10 {
1062+ db_update_vault_reserve_feerate ( & db_path, last_update, vault_reserve_feerate) . unwrap ( ) ;
1063+ } else {
1064+ db_update_vault_reserve_feerate ( & db_path, last_update, test_feerate) . unwrap ( ) ;
1065+ }
1066+ }
1067+
1068+ let row = db_vault_reserve_feerate ( & db_path) . unwrap ( ) ;
1069+
1070+ assert_eq ! ( row. last_update, 10 ) ;
1071+ assert_eq ! ( row. vault_reserve_feerate, test_feerate) ;
1072+
1073+ fs:: remove_file ( & db_path) . unwrap ( ) ;
1074+ }
10001075}
0 commit comments