44// license that can be found in the LICENSE file or at
55// https://opensource.org/licenses/MIT.
66
7+ use crate :: bus:: { HiddenServiceInfo , WrapOnionAddressV3 } ;
78use farcaster_core:: swap:: btcxmr:: Deal ;
89use farcaster_core:: swap:: SwapId ;
910use farcaster_core:: { blockchain:: Blockchain , role:: TradeRole } ;
11+ use internet2:: addr:: InetSocketAddr ;
1012use lmdb:: { Cursor , Transaction as LMDBTransaction } ;
13+ use std:: convert:: TryInto ;
1114use std:: io:: Cursor as IoCursor ;
1215use std:: path:: PathBuf ;
1316use strict_encoding:: { StrictDecode , StrictEncode } ;
17+ use torut:: onion:: { OnionAddressV3 , TorPublicKeyV3 } ;
1418
1519use crate :: bus:: {
1620 ctl:: { Checkpoint , CtlMsg } ,
@@ -212,6 +216,23 @@ impl Runtime {
212216 } ) ?;
213217 }
214218
219+ CtlMsg :: SetHiddenServiceInfo ( HiddenServiceInfo {
220+ onion_address,
221+ bind_address,
222+ } ) => {
223+ self . database
224+ . set_hidden_service_info ( & onion_address. 0 , & bind_address) ?;
225+ }
226+
227+ CtlMsg :: DeleteHiddenServiceInfo ( onion_address) => {
228+ if let Err ( err) = self . database . delete_hidden_service_info ( & onion_address. 0 ) {
229+ warn ! (
230+ "Did not delete hidden service info: {} due to {}" ,
231+ onion_address, err
232+ ) ;
233+ }
234+ }
235+
215236 _ => {
216237 error ! ( "BusMsg {} is not supported by the CTL interface" , request) ;
217238 }
@@ -255,6 +276,16 @@ impl Runtime {
255276 } ;
256277 }
257278
279+ InfoMsg :: GetAllHiddenServiceInfo => {
280+ let hidden_service_infos = self . database . get_all_hidden_service_info ( ) ?. into ( ) ;
281+ endpoints. send_to (
282+ ServiceBus :: Info ,
283+ self . identity ( ) ,
284+ source,
285+ BusMsg :: Info ( InfoMsg :: HiddenServiceInfoList ( hidden_service_infos) ) ,
286+ ) ?;
287+ }
288+
258289 InfoMsg :: GetCheckpointEntry ( swap_id) => {
259290 match self . database . get_checkpoint_info ( & swap_id) {
260291 Ok ( entry) => {
@@ -400,6 +431,7 @@ const LMDB_CHECKPOINT_INFOS: &str = "checkpoint_infos";
400431const LMDB_BITCOIN_ADDRESSES : & str = "bitcoin_addresses" ;
401432const LMDB_MONERO_ADDRESSES : & str = "monero_addresses" ;
402433const LMDB_DEAL_HISTORY : & str = "deal_history" ;
434+ const LMDB_HIDDEN_SERVICE_INFO : & str = "hidden_service_info" ;
403435
404436impl Database {
405437 fn new ( path : PathBuf ) -> Result < Database , lmdb:: Error > {
@@ -412,6 +444,7 @@ impl Database {
412444 env. create_db ( Some ( LMDB_BITCOIN_ADDRESSES ) , lmdb:: DatabaseFlags :: empty ( ) ) ?;
413445 env. create_db ( Some ( LMDB_DEAL_HISTORY ) , lmdb:: DatabaseFlags :: empty ( ) ) ?;
414446 env. create_db ( Some ( LMDB_MONERO_ADDRESSES ) , lmdb:: DatabaseFlags :: empty ( ) ) ?;
447+ env. create_db ( Some ( LMDB_HIDDEN_SERVICE_INFO ) , lmdb:: DatabaseFlags :: empty ( ) ) ?;
415448 Ok ( Database ( env) )
416449 }
417450
@@ -644,6 +677,52 @@ impl Database {
644677 res
645678 }
646679
680+ fn set_hidden_service_info (
681+ & mut self ,
682+ onion_address : & OnionAddressV3 ,
683+ socket_address : & InetSocketAddr ,
684+ ) -> Result < ( ) , Error > {
685+ let db = self . 0 . open_db ( Some ( LMDB_HIDDEN_SERVICE_INFO ) ) ?;
686+ let mut tx = self . 0 . begin_rw_txn ( ) ?;
687+ let key_bytes = onion_address. get_public_key ( ) . to_bytes ( ) ;
688+ if tx. get ( db, & key_bytes) . is_ok ( ) {
689+ tx. del ( db, & key_bytes, None ) ?;
690+ }
691+ let mut val = vec ! [ ] ;
692+ socket_address. strict_encode ( & mut val) ?;
693+ tx. put ( db, & key_bytes, & val, lmdb:: WriteFlags :: empty ( ) ) ?;
694+ tx. commit ( ) ?;
695+ Ok ( ( ) )
696+ }
697+
698+ fn get_all_hidden_service_info ( & mut self ) -> Result < Vec < HiddenServiceInfo > , Error > {
699+ let db = self . 0 . open_db ( Some ( LMDB_HIDDEN_SERVICE_INFO ) ) ?;
700+ let tx = self . 0 . begin_ro_txn ( ) ?;
701+ let mut cursor = tx. open_ro_cursor ( db) ?;
702+ let res = cursor
703+ . iter ( )
704+ . map ( |( key, value) | {
705+ Ok ( HiddenServiceInfo {
706+ onion_address : WrapOnionAddressV3 ( OnionAddressV3 :: from (
707+ & TorPublicKeyV3 :: from_bytes ( key. try_into ( ) . unwrap ( ) ) . unwrap ( ) ,
708+ ) ) ,
709+ bind_address : InetSocketAddr :: strict_decode ( std:: io:: Cursor :: new ( value) ) ?,
710+ } )
711+ } )
712+ . collect ( ) ;
713+ drop ( cursor) ;
714+ tx. abort ( ) ;
715+ res
716+ }
717+
718+ fn delete_hidden_service_info ( & mut self , key : & OnionAddressV3 ) -> Result < ( ) , lmdb:: Error > {
719+ let db = self . 0 . open_db ( Some ( LMDB_HIDDEN_SERVICE_INFO ) ) ?;
720+ let mut tx = self . 0 . begin_rw_txn ( ) ?;
721+ tx. del ( db, & key. get_public_key ( ) . as_bytes ( ) , None ) ?;
722+ tx. commit ( ) ?;
723+ Ok ( ( ) )
724+ }
725+
647726 fn get_checkpoint_state ( & mut self , checkpoint_key : & CheckpointKey ) -> Result < Vec < u8 > , Error > {
648727 let db = self . 0 . open_db ( Some ( LMDB_CHECKPOINTS ) ) ?;
649728 let tx = self . 0 . begin_ro_txn ( ) ?;
0 commit comments