11use crate :: { error:: Error , VaultIdManager } ;
22use bitcoin:: {
3- BitcoinCoreApi , Transaction , TransactionExt , TransactionMetadata , BLOCK_INTERVAL as BITCOIN_BLOCK_INTERVAL ,
3+ BitcoinCoreApi , Hash , TransactionExt , TransactionMetadata , Txid , BLOCK_INTERVAL as BITCOIN_BLOCK_INTERVAL ,
44} ;
55use futures:: {
66 stream:: { self , StreamExt } ,
@@ -11,7 +11,7 @@ use runtime::{
1111 InterBtcReplaceRequest , IssuePallet , RedeemPallet , RedeemRequestStatus , RefundPallet , ReplacePallet ,
1212 ReplaceRequestStatus , RequestRefundEvent , SecurityPallet , UtilFuncs , VaultId , VaultRegistryPallet , H256 ,
1313} ;
14- use std:: { collections:: HashMap , convert:: TryInto , time:: Duration } ;
14+ use std:: { collections:: HashMap , convert:: TryInto , sync :: Arc , time:: Duration } ;
1515use tokio:: time:: sleep;
1616
1717const ON_FORK_RETRY_DELAY : Duration = Duration :: from_secs ( 10 ) ;
@@ -180,6 +180,7 @@ impl Request {
180180 & self ,
181181 parachain_rpc : P ,
182182 btc_rpc : B ,
183+ rocksdb : Arc < rocksdb:: DB > ,
183184 num_confirmations : u32 ,
184185 ) -> Result < ( ) , Error > {
185186 // ensure the deadline has not expired yet
@@ -192,7 +193,13 @@ impl Request {
192193 }
193194
194195 let tx_metadata = self
195- . transfer_btc ( & parachain_rpc, btc_rpc, num_confirmations, self . vault_id . clone ( ) )
196+ . transfer_btc (
197+ & parachain_rpc,
198+ btc_rpc,
199+ rocksdb,
200+ num_confirmations,
201+ self . vault_id . clone ( ) ,
202+ )
196203 . await ?;
197204 self . execute ( parachain_rpc, tx_metadata) . await
198205 }
@@ -213,6 +220,7 @@ impl Request {
213220 & self ,
214221 parachain_rpc : & P ,
215222 btc_rpc : B ,
223+ rocksdb : Arc < rocksdb:: DB > ,
216224 num_confirmations : u32 ,
217225 vault_id : VaultId ,
218226 ) -> Result < TransactionMetadata , Error > {
@@ -244,6 +252,7 @@ impl Request {
244252 } ;
245253
246254 let txid = btc_rpc. send_transaction ( tx) . await ?;
255+ rocksdb. put ( self . hash , txid) . expect ( "could not write to db" ) ;
247256
248257 loop {
249258 let tx_metadata = btc_rpc. wait_for_transaction_metadata ( txid, num_confirmations) . await ?;
@@ -310,7 +319,7 @@ impl Request {
310319pub async fn execute_open_requests < B : BitcoinCoreApi + Clone + Send + Sync + ' static > (
311320 parachain_rpc : InterBtcParachain ,
312321 btc_rpc : VaultIdManager < B > ,
313- read_only_btc_rpc : B ,
322+ rocksdb : Arc < rocksdb :: DB > ,
314323 num_confirmations : u32 ,
315324 payment_margin : Duration ,
316325 process_refunds : bool ,
@@ -364,25 +373,19 @@ pub async fn execute_open_requests<B: BitcoinCoreApi + Clone + Send + Sync + 'st
364373 . map ( |x| ( x. hash , x) )
365374 . collect :: < HashMap < _ , _ > > ( ) ;
366375
367- // find the height of bitcoin chain corresponding to the earliest btc_height
368- let btc_start_height = match open_requests
369- . iter ( )
370- . map ( |( _, request) | request. btc_height . unwrap_or ( u32:: MAX ) )
371- . min ( )
372- {
373- Some ( x) => x,
374- None => return Ok ( ( ) ) , // the iterator is empty so we have nothing to do
375- } ;
376-
377- // iterate through transactions in reverse order, starting from those in the mempool
378- let mut transaction_stream = bitcoin:: reverse_stream_transactions ( & read_only_btc_rpc, btc_start_height) . await ?;
379- while let Some ( result) = transaction_stream. next ( ) . await {
380- let tx = result?;
381-
376+ for ( hash, request) in open_requests. clone ( ) . into_iter ( ) {
382377 // get the request this transaction corresponds to, if any
383- if let Some ( request ) = get_request_for_btc_tx ( & tx , & open_requests ) {
378+ if let Ok ( Some ( raw_txid ) ) = rocksdb . get ( & hash ) {
384379 // remove request from the hashmap
385- open_requests. retain ( |& key, _| key != request. hash ) ;
380+ open_requests. remove ( & request. hash ) ;
381+
382+ let txid = match Txid :: from_slice ( & raw_txid) {
383+ Ok ( txid) => txid,
384+ Err ( err) => {
385+ tracing:: error!( "Could not decode txid: {}" , err) ;
386+ continue ;
387+ }
388+ } ;
386389
387390 tracing:: info!(
388391 "{:?} request #{:?} has valid bitcoin payment - processing..." ,
@@ -409,7 +412,7 @@ pub async fn execute_open_requests<B: BitcoinCoreApi + Clone + Send + Sync + 'st
409412 // Payment has been made, but it might not have been confirmed enough times yet
410413 let tx_metadata = btc_rpc
411414 . clone ( )
412- . wait_for_transaction_metadata ( tx . txid ( ) , num_confirmations)
415+ . wait_for_transaction_metadata ( txid, num_confirmations)
413416 . await ;
414417
415418 match tx_metadata {
@@ -456,6 +459,7 @@ pub async fn execute_open_requests<B: BitcoinCoreApi + Clone + Send + Sync + 'st
456459 // make copies of the variables we move into the task
457460 let parachain_rpc = parachain_rpc. clone ( ) ;
458461 let btc_rpc = btc_rpc. clone ( ) ;
462+ let rocksdb = rocksdb. clone ( ) ;
459463 tokio:: spawn ( async move {
460464 let btc_rpc = match btc_rpc. get_bitcoin_rpc ( & request. vault_id ) . await {
461465 Some ( x) => x,
@@ -474,7 +478,10 @@ pub async fn execute_open_requests<B: BitcoinCoreApi + Clone + Send + Sync + 'st
474478 request. hash
475479 ) ;
476480
477- match request. pay_and_execute ( parachain_rpc, btc_rpc, num_confirmations) . await {
481+ match request
482+ . pay_and_execute ( parachain_rpc, btc_rpc, rocksdb, num_confirmations)
483+ . await
484+ {
478485 Ok ( _) => tracing:: info!(
479486 "{:?} request #{:?} successfully executed" ,
480487 request. request_type,
@@ -493,19 +500,6 @@ pub async fn execute_open_requests<B: BitcoinCoreApi + Clone + Send + Sync + 'st
493500 Ok ( ( ) )
494501}
495502
496- /// Get the Request from the hashmap that the given Transaction satisfies, based
497- /// on the OP_RETURN and the amount of btc that is transfered to the address
498- fn get_request_for_btc_tx ( tx : & Transaction , hash_map : & HashMap < H256 , Request > ) -> Option < Request > {
499- let hash = tx. get_op_return ( ) ?;
500- let request = hash_map. get ( & hash) ?;
501- let paid_amount = tx. get_payment_amount_to ( request. btc_address ) ?;
502- if paid_amount as u128 >= request. amount {
503- Some ( request. clone ( ) )
504- } else {
505- None
506- }
507- }
508-
509503#[ cfg( all( test, feature = "standalone-metadata" ) ) ]
510504mod tests {
511505 use super :: * ;
0 commit comments