@@ -52,6 +52,15 @@ use std::thread;
52
52
use std:: thread:: JoinHandle ;
53
53
use std:: time:: Duration ;
54
54
55
+ lazy_static ! {
56
+ // Flag that send call is in the progress. init_send_tx is not atomic because we don't want
57
+ // wallet to be blocked during send attempt that can take up to 2 minutes is we are using mwcmqs and other wallet is offline.
58
+ // Also we don't wantot to lock outputs before send and cancel on failure.
59
+ // That is we are introducing a simple flag for the send. Only one instance will be ready to go through
60
+ // send workflow with owner API. Ownser API ans command can act together, in worst case it will throw lock error
61
+ pub static ref INIT_SEND_TX_LOCK : Arc <Mutex <u32 >> = Arc :: new( Mutex :: new( 0 ) ) ;
62
+ }
63
+
55
64
/// Main interface into all wallet API functions.
56
65
/// Wallet APIs are split into two seperate blocks of functionality
57
66
/// called the ['Owner'](struct.Owner.html) and ['Foreign'](struct.Foreign.html) APIs
@@ -705,8 +714,6 @@ where
705
714
) -> Result < Slate , Error > {
706
715
let address = args. address . clone ( ) ;
707
716
708
- wallet_lock ! ( self . wallet_inst, w) ;
709
- owner:: update_wallet_state ( & mut * * w, keychain_mask, & None ) ?;
710
717
let send_args = args. send_args . clone ( ) ;
711
718
//minimum_confirmations cannot be zero.
712
719
let minimum_confirmations = args. minimum_confirmations . clone ( ) ;
@@ -766,23 +773,32 @@ where
766
773
None
767
774
} ;
768
775
769
- let mut slate =
770
- { owner:: init_send_tx ( & mut * * w, keychain_mask, & args, self . doctest_mode , routputs) ? } ;
776
+ // Using it as a global lock for the API
777
+ // Without usage it still works until the end of the block
778
+ let mut _send_lock = INIT_SEND_TX_LOCK . lock ( ) ;
779
+
780
+ let ( mut slate, slatepack_secret, height, secp) = {
781
+ wallet_lock ! ( self . wallet_inst, w) ;
782
+ owner:: update_wallet_state ( & mut * * w, keychain_mask, & None ) ?;
783
+
784
+ let slate = {
785
+ owner:: init_send_tx ( & mut * * w, keychain_mask, & args, self . doctest_mode , routputs) ?
786
+ } ;
787
+
788
+ let keychain = w. keychain ( keychain_mask) ?;
789
+ let ( height, _, _) = w. w2n_client ( ) . get_chain_tip ( ) ?;
790
+ let slatepack_secret =
791
+ proofaddress:: payment_proof_address_dalek_secret ( & keychain, None ) ?;
771
792
772
- match send_args {
793
+ ( slate, slatepack_secret, height, keychain. secp ( ) . clone ( ) )
794
+ } ;
795
+
796
+ let res = match send_args {
773
797
Some ( sa) => {
774
798
let original_slate = slate. clone ( ) ;
775
799
776
800
match sender_info {
777
801
Some ( ( sender, other_wallet_info) ) => {
778
- let ( slatepack_secret, height, secp) = {
779
- let keychain = w. keychain ( keychain_mask) ?;
780
- let ( height, _, _) = w. w2n_client ( ) . get_chain_tip ( ) ?;
781
- let slatepack_secret =
782
- proofaddress:: payment_proof_address_dalek_secret ( & keychain, None ) ?;
783
- ( slatepack_secret, height, keychain. secp ( ) . clone ( ) )
784
- } ;
785
-
786
802
slate = sender
787
803
. send_tx (
788
804
true ,
@@ -822,35 +838,41 @@ where
822
838
e
823
839
} ) ?;
824
840
825
- owner:: tx_lock_outputs (
826
- & mut * * w,
827
- keychain_mask,
828
- & slate,
829
- address,
830
- 0 ,
831
- self . doctest_mode ,
832
- ) ?;
833
-
834
- slate = match sa. finalize {
835
- true => {
836
- let ( slate_res, _context) = owner:: finalize_tx (
837
- & mut * * w,
838
- keychain_mask,
839
- & slate,
840
- true ,
841
- self . doctest_mode ,
842
- ) ?;
843
- slate_res
844
- }
845
- false => slate,
841
+ let w2n_client = {
842
+ wallet_lock ! ( self . wallet_inst, w) ;
843
+
844
+ owner:: tx_lock_outputs (
845
+ & mut * * w,
846
+ keychain_mask,
847
+ & slate,
848
+ address,
849
+ 0 ,
850
+ self . doctest_mode ,
851
+ ) ?;
852
+
853
+ slate = match sa. finalize {
854
+ true => {
855
+ let ( slate_res, _context) = owner:: finalize_tx (
856
+ & mut * * w,
857
+ keychain_mask,
858
+ & slate,
859
+ true ,
860
+ self . doctest_mode ,
861
+ ) ?;
862
+ slate_res
863
+ }
864
+ false => slate,
865
+ } ;
866
+ println ! (
867
+ "slate [{}] finalized successfully in owner_api" ,
868
+ slate. id. to_string( )
869
+ ) ;
870
+
871
+ w. w2n_client ( ) . clone ( )
846
872
} ;
847
- println ! (
848
- "slate [{}] finalized successfully in owner_api" ,
849
- slate. id. to_string( )
850
- ) ;
851
873
852
874
if sa. post_tx {
853
- owner:: post_tx ( w . w2n_client ( ) , slate. tx_or_err ( ) ?, sa. fluff ) ?;
875
+ owner:: post_tx ( & w2n_client, slate. tx_or_err ( ) ?, sa. fluff ) ?;
854
876
}
855
877
println ! (
856
878
"slate [{}] posted successfully in owner_api" ,
@@ -859,7 +881,9 @@ where
859
881
Ok ( slate)
860
882
}
861
883
None => Ok ( slate) ,
862
- }
884
+ } ;
885
+
886
+ res
863
887
}
864
888
865
889
/// Issues a new invoice transaction slate, essentially a `request for payment`.
0 commit comments