3
3
//! This module contains the definition of the raw client that wraps the transport method
4
4
5
5
use std:: borrow:: Borrow ;
6
- use std:: collections:: { BTreeMap , BTreeSet , HashMap , VecDeque } ;
6
+ use std:: collections:: { BTreeMap , HashMap , VecDeque } ;
7
7
use std:: io:: { BufRead , BufReader , Read , Write } ;
8
8
use std:: mem:: drop;
9
9
use std:: net:: { TcpStream , ToSocketAddrs } ;
@@ -762,22 +762,23 @@ impl<T: Read + Write> ElectrumApi for RawClient<T> {
762
762
fn batch_call ( & self , batch : & Batch ) -> Result < Vec < serde_json:: Value > , Error > {
763
763
let mut raw = Vec :: new ( ) ;
764
764
765
- let mut missing_responses = BTreeSet :: new ( ) ;
765
+ let mut missing_responses = Vec :: new ( ) ;
766
766
let mut answers = BTreeMap :: new ( ) ;
767
767
768
- // Add our listener to the map before we send the request, Here we will clone the sender
769
- // for every request id, so that we only have to monitor one receiver.
770
- let ( sender, receiver) = channel ( ) ;
768
+ // Add our listener to the map before we send the request
771
769
772
770
for ( method, params) in batch. iter ( ) {
773
771
let req = Request :: new_id (
774
772
self . last_id . fetch_add ( 1 , Ordering :: SeqCst ) ,
775
773
method,
776
774
params. to_vec ( ) ,
777
775
) ;
778
- missing_responses. insert ( req. id ) ;
776
+ // Add distinct channel to each request so when we remove our request id (and sender) from the waiting_map
777
+ // we can be sure that the response gets sent to the correct channel in self.recv
778
+ let ( sender, receiver) = channel ( ) ;
779
+ missing_responses. push ( ( req. id , receiver) ) ;
779
780
780
- self . waiting_map . lock ( ) ?. insert ( req. id , sender. clone ( ) ) ;
781
+ self . waiting_map . lock ( ) ?. insert ( req. id , sender) ;
781
782
782
783
raw. append ( & mut serde_json:: to_vec ( & req) ?) ;
783
784
raw. extend_from_slice ( b"\n " ) ;
@@ -796,7 +797,7 @@ impl<T: Read + Write> ElectrumApi for RawClient<T> {
796
797
797
798
self . increment_calls ( ) ;
798
799
799
- for req_id in missing_responses. iter ( ) {
800
+ for ( req_id, receiver ) in missing_responses. iter ( ) {
800
801
match self . recv ( & receiver, * req_id) {
801
802
Ok ( mut resp) => answers. insert ( req_id, resp[ "result" ] . take ( ) ) ,
802
803
Err ( e) => {
@@ -805,7 +806,7 @@ impl<T: Read + Write> ElectrumApi for RawClient<T> {
805
806
warn ! ( "got error for req_id {}: {:?}" , req_id, e) ;
806
807
warn ! ( "removing all waiting req of this batch" ) ;
807
808
let mut guard = self . waiting_map . lock ( ) ?;
808
- for req_id in missing_responses. iter ( ) {
809
+ for ( req_id, _ ) in missing_responses. iter ( ) {
809
810
guard. remove ( req_id) ;
810
811
}
811
812
return Err ( e) ;
0 commit comments