@@ -15,10 +15,11 @@ use std::collections::HashSet;
1515use std:: fmt:: Debug ;
1616use std:: str:: FromStr ;
1717use std:: time:: SystemTime ;
18- use web3:: types:: H256 ;
18+ use web3:: types:: { Address , H256 } ;
19+ use crate :: blockchain:: blockchain_interface:: blockchain_interface_web3:: lower_level_interface_web3:: TxStatus ;
1920
2021#[ derive( Debug , PartialEq , Eq ) ]
21- pub enum PendingPayableDaoError {
22+ pub enum SentPayableDaoError {
2223 InsertionFailed ( String ) ,
2324 UpdateFailed ( String ) ,
2425 SignConversionError ( u64 ) ,
@@ -28,27 +29,43 @@ pub enum PendingPayableDaoError {
2829}
2930
3031#[ derive( Debug ) ]
31- pub struct TransactionHashes {
32+ pub struct TxIdentifiers {
3233 pub rowid_results : Vec < ( u64 , H256 ) > ,
3334 pub no_rowid_results : Vec < H256 > ,
3435}
3536
36- pub trait PendingPayableDao {
37+ struct TransactionRecord {
38+ tx : Tx ,
39+ status : TxStatus ,
40+ }
41+
42+ struct Tx {
43+ // GH-608: Perhaps TxReceipt could be a similar structure to be used
44+ receiver_address : Address ,
45+ amount : u128 ,
46+ tx_hash : String ,
47+ timestamp : SystemTime ,
48+ gas_price_wei : u64 ,
49+ nonce : u32 ,
50+ }
51+
52+ struct StatusChange {
53+ new_status : TxStatus ,
54+ }
55+
56+ pub trait SentPayableDao {
3757 // Note that the order of the returned results is not guaranteed
38- fn fingerprints_rowids ( & self , hashes : & [ H256 ] ) -> TransactionHashes ;
39- fn return_all_errorless_fingerprints ( & self ) -> Vec < PendingPayableFingerprint > ;
40- fn insert_new_fingerprints (
41- & self ,
42- hashes_and_amounts : & [ HashAndAmount ] ,
43- batch_wide_timestamp : SystemTime ,
44- ) -> Result < ( ) , PendingPayableDaoError > ;
45- fn delete_fingerprints ( & self , ids : & [ u64 ] ) -> Result < ( ) , PendingPayableDaoError > ;
46- fn increment_scan_attempts ( & self , ids : & [ u64 ] ) -> Result < ( ) , PendingPayableDaoError > ;
47- fn mark_failures ( & self , ids : & [ u64 ] ) -> Result < ( ) , PendingPayableDaoError > ;
58+ fn get_tx_identifiers ( & self , hashes : & [ H256 ] ) -> TxIdentifiers ;
59+ fn retrieve_pending_txs ( & self ) -> Vec < Tx > ;
60+
61+ fn retrieve_txs_to_retry ( & self ) -> Vec < Tx > ;
62+ fn insert_new_records ( & self , txs : Vec < Tx > ) -> Result < ( ) , SentPayableDaoError > ;
63+ fn delete_records ( & self , ids : & [ u64 ] ) -> Result < ( ) , SentPayableDaoError > ;
64+ fn change_statuses ( & self , ids : & [ StatusChange ] ) -> Result < ( ) , SentPayableDaoError > ;
4865}
4966
50- impl PendingPayableDao for PendingPayableDaoReal < ' _ > {
51- fn fingerprints_rowids ( & self , hashes : & [ H256 ] ) -> TransactionHashes {
67+ impl SentPayableDao for SentPayableDaoReal < ' _ > {
68+ fn transaction_rowids ( & self , hashes : & [ H256 ] ) -> TxIdentifiers {
5269 //Vec<(Option<u64>, H256)> {
5370 fn hash_and_rowid_in_single_row ( row : & Row ) -> rusqlite:: Result < ( u64 , H256 ) > {
5471 let hash_str: String = row. get ( 0 ) . expectv ( "hash" ) ;
@@ -81,7 +98,7 @@ impl PendingPayableDao for PendingPayableDaoReal<'_> {
8198 . cloned ( )
8299 . collect ( ) ;
83100
84- TransactionHashes {
101+ TxIdentifiers {
85102 rowid_results : all_found_records,
86103 no_rowid_results : hashes_of_missing_rowids,
87104 }
@@ -128,7 +145,7 @@ impl PendingPayableDao for PendingPayableDaoReal<'_> {
128145 & self ,
129146 hashes_and_amounts : & [ HashAndAmount ] ,
130147 batch_wide_timestamp : SystemTime ,
131- ) -> Result < ( ) , PendingPayableDaoError > {
148+ ) -> Result < ( ) , SentPayableDaoError > {
132149 fn values_clause_for_fingerprints_to_insert (
133150 hashes_and_amounts : & [ HashAndAmount ] ,
134151 batch_wide_timestamp : SystemTime ,
@@ -162,11 +179,11 @@ impl PendingPayableDao for PendingPayableDaoReal<'_> {
162179 hashes_and_amounts. len( ) ,
163180 x
164181 ) ,
165- Err ( e) => Err ( PendingPayableDaoError :: InsertionFailed ( e. to_string ( ) ) ) ,
182+ Err ( e) => Err ( SentPayableDaoError :: InsertionFailed ( e. to_string ( ) ) ) ,
166183 }
167184 }
168185
169- fn delete_fingerprints ( & self , ids : & [ u64 ] ) -> Result < ( ) , PendingPayableDaoError > {
186+ fn delete_fingerprints ( & self , ids : & [ u64 ] ) -> Result < ( ) , SentPayableDaoError > {
170187 let sql = format ! (
171188 "delete from pending_payable where rowid in ({})" ,
172189 Self :: serialize_ids( ids)
@@ -183,11 +200,11 @@ impl PendingPayableDao for PendingPayableDaoReal<'_> {
183200 ids. len( ) ,
184201 num
185202 ) ,
186- Err ( e) => Err ( PendingPayableDaoError :: RecordDeletion ( e. to_string ( ) ) ) ,
203+ Err ( e) => Err ( SentPayableDaoError :: RecordDeletion ( e. to_string ( ) ) ) ,
187204 }
188205 }
189206
190- fn increment_scan_attempts ( & self , ids : & [ u64 ] ) -> Result < ( ) , PendingPayableDaoError > {
207+ fn increment_scan_attempts ( & self , ids : & [ u64 ] ) -> Result < ( ) , SentPayableDaoError > {
191208 let sql = format ! (
192209 "update pending_payable set attempt = attempt + 1 where rowid in ({})" ,
193210 Self :: serialize_ids( ids)
@@ -199,11 +216,11 @@ impl PendingPayableDao for PendingPayableDaoReal<'_> {
199216 ids. len( ) ,
200217 num
201218 ) ,
202- Err ( e) => Err ( PendingPayableDaoError :: UpdateFailed ( e. to_string ( ) ) ) ,
219+ Err ( e) => Err ( SentPayableDaoError :: UpdateFailed ( e. to_string ( ) ) ) ,
203220 }
204221 }
205222
206- fn mark_failures ( & self , ids : & [ u64 ] ) -> Result < ( ) , PendingPayableDaoError > {
223+ fn mark_failures ( & self , ids : & [ u64 ] ) -> Result < ( ) , SentPayableDaoError > {
207224 let sql = format ! (
208225 "update pending_payable set process_error = 'ERROR' where rowid in ({})" ,
209226 Self :: serialize_ids( ids)
@@ -220,7 +237,7 @@ impl PendingPayableDao for PendingPayableDaoReal<'_> {
220237 ids. len( ) , num
221238 )
222239 ,
223- Err ( e) => Err ( PendingPayableDaoError :: ErrorMarkFailed ( e. to_string ( ) ) ) ,
240+ Err ( e) => Err ( SentPayableDaoError :: ErrorMarkFailed ( e. to_string ( ) ) ) ,
224241 }
225242 }
226243}
@@ -241,11 +258,11 @@ impl PendingPayable {
241258}
242259
243260#[ derive( Debug ) ]
244- pub struct PendingPayableDaoReal < ' a > {
261+ pub struct SentPayableDaoReal < ' a > {
245262 conn : Box < dyn ConnectionWrapper + ' a > ,
246263}
247264
248- impl < ' a > PendingPayableDaoReal < ' a > {
265+ impl < ' a > SentPayableDaoReal < ' a > {
249266 pub fn new ( conn : Box < dyn ConnectionWrapper + ' a > ) -> Self {
250267 Self { conn }
251268 }
@@ -260,20 +277,20 @@ impl<'a> PendingPayableDaoReal<'a> {
260277}
261278
262279pub trait PendingPayableDaoFactory {
263- fn make ( & self ) -> Box < dyn PendingPayableDao > ;
280+ fn make ( & self ) -> Box < dyn SentPayableDao > ;
264281}
265282
266283impl PendingPayableDaoFactory for DaoFactoryReal {
267- fn make ( & self ) -> Box < dyn PendingPayableDao > {
268- Box :: new ( PendingPayableDaoReal :: new ( self . make_connection ( ) ) )
284+ fn make ( & self ) -> Box < dyn SentPayableDao > {
285+ Box :: new ( SentPayableDaoReal :: new ( self . make_connection ( ) ) )
269286 }
270287}
271288
272289#[ cfg( test) ]
273290mod tests {
274291 use crate :: accountant:: checked_conversion;
275292 use crate :: accountant:: db_access_objects:: pending_payable_dao:: {
276- PendingPayableDao , PendingPayableDaoError , PendingPayableDaoReal ,
293+ SentPayableDao , SentPayableDaoError , SentPayableDaoReal ,
277294 } ;
278295 use crate :: accountant:: db_access_objects:: utils:: from_time_t;
279296 use crate :: accountant:: db_big_integer:: big_int_divider:: BigIntDivider ;
@@ -305,7 +322,7 @@ mod tests {
305322 let hash_2 = make_tx_hash ( 6789 ) ;
306323 let amount_2 = 44445 ;
307324 let batch_wide_timestamp = from_time_t ( 200_000_000 ) ;
308- let subject = PendingPayableDaoReal :: new ( wrapped_conn) ;
325+ let subject = SentPayableDaoReal :: new ( wrapped_conn) ;
309326 let hash_and_amount_1 = HashAndAmount {
310327 hash : hash_1,
311328 amount : amount_1,
@@ -366,14 +383,14 @@ mod tests {
366383 let hash = make_tx_hash ( 45466 ) ;
367384 let amount = 55556 ;
368385 let timestamp = from_time_t ( 200_000_000 ) ;
369- let subject = PendingPayableDaoReal :: new ( Box :: new ( wrapped_conn) ) ;
386+ let subject = SentPayableDaoReal :: new ( Box :: new ( wrapped_conn) ) ;
370387 let hash_and_amount = HashAndAmount { hash, amount } ;
371388
372389 let result = subject. insert_new_fingerprints ( & [ hash_and_amount] , timestamp) ;
373390
374391 assert_eq ! (
375392 result,
376- Err ( PendingPayableDaoError :: InsertionFailed (
393+ Err ( SentPayableDaoError :: InsertionFailed (
377394 "attempt to write a readonly database" . to_string( )
378395 ) )
379396 )
@@ -395,7 +412,7 @@ mod tests {
395412 let hash_1 = make_tx_hash ( 4546 ) ;
396413 let amount_1 = 55556 ;
397414 let batch_wide_timestamp = from_time_t ( 200_000_000 ) ;
398- let subject = PendingPayableDaoReal :: new ( Box :: new ( wrapped_conn) ) ;
415+ let subject = SentPayableDaoReal :: new ( Box :: new ( wrapped_conn) ) ;
399416 let hash_and_amount = HashAndAmount {
400417 hash : hash_1,
401418 amount : amount_1,
@@ -413,7 +430,7 @@ mod tests {
413430 let wrapped_conn = DbInitializerReal :: default ( )
414431 . initialize ( & home_dir, DbInitializationConfig :: test_default ( ) )
415432 . unwrap ( ) ;
416- let subject = PendingPayableDaoReal :: new ( wrapped_conn) ;
433+ let subject = SentPayableDaoReal :: new ( wrapped_conn) ;
417434 let timestamp = from_time_t ( 195_000_000 ) ;
418435 // use full range tx hashes because SqLite has tendencies to see the value as a hex and convert it to an integer,
419436 // then complain about its excessive size if supplied in unquoted strings
@@ -438,7 +455,7 @@ mod tests {
438455 . unwrap ( ) ;
439456 }
440457
441- let result = subject. fingerprints_rowids ( & [ hash_1, hash_2] ) ;
458+ let result = subject. transaction_rowids ( & [ hash_1, hash_2] ) ;
442459
443460 let first_expected_pair = & ( 1 , hash_1) ;
444461 assert ! (
@@ -466,7 +483,7 @@ mod tests {
466483 let wrapped_conn = DbInitializerReal :: default ( )
467484 . initialize ( & home_dir, DbInitializationConfig :: test_default ( ) )
468485 . unwrap ( ) ;
469- let subject = PendingPayableDaoReal :: new ( wrapped_conn) ;
486+ let subject = SentPayableDaoReal :: new ( wrapped_conn) ;
470487 let hash_1 = make_tx_hash ( 11119 ) ;
471488 let hash_2 = make_tx_hash ( 22229 ) ;
472489 let hash_3 = make_tx_hash ( 33339 ) ;
@@ -494,7 +511,7 @@ mod tests {
494511 . unwrap ( ) ;
495512 subject. delete_fingerprints ( & [ 1 ] ) . unwrap ( ) ;
496513
497- let result = subject. fingerprints_rowids ( & [ hash_1, hash_2, hash_3, hash_4] ) ;
514+ let result = subject. transaction_rowids ( & [ hash_1, hash_2, hash_3, hash_4] ) ;
498515
499516 assert_eq ! ( result. rowid_results, vec![ ( 2 , hash_3) , ] ) ;
500517 assert_eq ! ( result. no_rowid_results, vec![ hash_1, hash_2, hash_4] ) ;
@@ -509,7 +526,7 @@ mod tests {
509526 let wrapped_conn = DbInitializerReal :: default ( )
510527 . initialize ( & home_dir, DbInitializationConfig :: test_default ( ) )
511528 . unwrap ( ) ;
512- let subject = PendingPayableDaoReal :: new ( wrapped_conn) ;
529+ let subject = SentPayableDaoReal :: new ( wrapped_conn) ;
513530 let batch_wide_timestamp = from_time_t ( 195_000_000 ) ;
514531 let hash_1 = make_tx_hash ( 11119 ) ;
515532 let amount_1 = 787 ;
@@ -567,7 +584,7 @@ mod tests {
567584 let wrapped_conn = DbInitializerReal :: default ( )
568585 . initialize ( & home_dir, DbInitializationConfig :: test_default ( ) )
569586 . unwrap ( ) ;
570- let subject = PendingPayableDaoReal :: new ( wrapped_conn) ;
587+ let subject = SentPayableDaoReal :: new ( wrapped_conn) ;
571588 let timestamp = from_time_t ( 198_000_000 ) ;
572589 let hash = make_tx_hash ( 10000 ) ;
573590 let amount = 333 ;
@@ -619,7 +636,7 @@ mod tests {
619636 . execute ( [ ] )
620637 . unwrap ( ) ;
621638 }
622- let subject = PendingPayableDaoReal :: new ( wrapped_conn) ;
639+ let subject = SentPayableDaoReal :: new ( wrapped_conn) ;
623640
624641 let _ = subject. return_all_errorless_fingerprints ( ) ;
625642 }
@@ -633,7 +650,7 @@ mod tests {
633650 let conn = DbInitializerReal :: default ( )
634651 . initialize ( & home_dir, DbInitializationConfig :: test_default ( ) )
635652 . unwrap ( ) ;
636- let subject = PendingPayableDaoReal :: new ( conn) ;
653+ let subject = SentPayableDaoReal :: new ( conn) ;
637654 {
638655 subject
639656 . insert_new_fingerprints (
@@ -684,13 +701,13 @@ mod tests {
684701 . unwrap ( ) ;
685702 let wrapped_conn = ConnectionWrapperReal :: new ( conn_read_only) ;
686703 let rowid = 45 ;
687- let subject = PendingPayableDaoReal :: new ( Box :: new ( wrapped_conn) ) ;
704+ let subject = SentPayableDaoReal :: new ( Box :: new ( wrapped_conn) ) ;
688705
689706 let result = subject. delete_fingerprints ( & [ rowid] ) ;
690707
691708 assert_eq ! (
692709 result,
693- Err ( PendingPayableDaoError :: RecordDeletion (
710+ Err ( SentPayableDaoError :: RecordDeletion (
694711 "attempt to write a readonly database" . to_string( )
695712 ) )
696713 )
@@ -710,7 +727,7 @@ mod tests {
710727 . unwrap ( ) ;
711728 let rowid_1 = 1 ;
712729 let rowid_2 = 2 ;
713- let subject = PendingPayableDaoReal :: new ( conn) ;
730+ let subject = SentPayableDaoReal :: new ( conn) ;
714731 {
715732 subject
716733 . insert_new_fingerprints (
@@ -751,7 +768,7 @@ mod tests {
751768 amount : 3344 ,
752769 } ;
753770 let timestamp = from_time_t ( 190_000_000 ) ;
754- let subject = PendingPayableDaoReal :: new ( conn) ;
771+ let subject = SentPayableDaoReal :: new ( conn) ;
755772 {
756773 subject
757774 . insert_new_fingerprints (
@@ -794,13 +811,13 @@ mod tests {
794811 )
795812 . unwrap ( ) ;
796813 let wrapped_conn = ConnectionWrapperReal :: new ( conn_read_only) ;
797- let subject = PendingPayableDaoReal :: new ( Box :: new ( wrapped_conn) ) ;
814+ let subject = SentPayableDaoReal :: new ( Box :: new ( wrapped_conn) ) ;
798815
799816 let result = subject. increment_scan_attempts ( & [ 1 ] ) ;
800817
801818 assert_eq ! (
802819 result,
803- Err ( PendingPayableDaoError :: UpdateFailed (
820+ Err ( SentPayableDaoError :: UpdateFailed (
804821 "attempt to write a readonly database" . to_string( )
805822 ) )
806823 )
@@ -818,7 +835,7 @@ mod tests {
818835 let conn = DbInitializerReal :: default ( )
819836 . initialize ( & home_dir, DbInitializationConfig :: test_default ( ) )
820837 . unwrap ( ) ;
821- let subject = PendingPayableDaoReal :: new ( conn) ;
838+ let subject = SentPayableDaoReal :: new ( conn) ;
822839
823840 let _ = subject. increment_scan_attempts ( & [ 1 , 2 ] ) ;
824841 }
@@ -843,7 +860,7 @@ mod tests {
843860 amount : amount_2,
844861 } ;
845862 let timestamp = from_time_t ( 190_000_000 ) ;
846- let subject = PendingPayableDaoReal :: new ( conn) ;
863+ let subject = SentPayableDaoReal :: new ( conn) ;
847864 {
848865 subject
849866 . insert_new_fingerprints ( & [ hash_and_amount_1, hash_and_amount_2] , timestamp)
@@ -919,13 +936,13 @@ mod tests {
919936 )
920937 . unwrap ( ) ;
921938 let wrapped_conn = ConnectionWrapperReal :: new ( conn_read_only) ;
922- let subject = PendingPayableDaoReal :: new ( Box :: new ( wrapped_conn) ) ;
939+ let subject = SentPayableDaoReal :: new ( Box :: new ( wrapped_conn) ) ;
923940
924941 let result = subject. mark_failures ( & [ 1 ] ) ;
925942
926943 assert_eq ! (
927944 result,
928- Err ( PendingPayableDaoError :: ErrorMarkFailed (
945+ Err ( SentPayableDaoError :: ErrorMarkFailed (
929946 "attempt to write a readonly database" . to_string( )
930947 ) )
931948 )
@@ -943,7 +960,7 @@ mod tests {
943960 let conn = DbInitializerReal :: default ( )
944961 . initialize ( & home_dir, DbInitializationConfig :: test_default ( ) )
945962 . unwrap ( ) ;
946- let subject = PendingPayableDaoReal :: new ( conn) ;
963+ let subject = SentPayableDaoReal :: new ( conn) ;
947964
948965 let _ = subject. mark_failures ( & [ 10 , 20 ] ) ;
949966 }
0 commit comments