@@ -2,6 +2,7 @@ use std::{
2
2
fs:: File ,
3
3
io:: { Error , ErrorKind , Result , Write } ,
4
4
path:: Path ,
5
+ sync:: Arc ,
5
6
} ;
6
7
7
8
use crate :: {
@@ -25,9 +26,14 @@ use jsonrpc_core::{Call, Id, MethodCall, Params, Value, Version};
25
26
use serde:: de;
26
27
27
28
pub use http:: Uri ;
29
+ use tokio:: sync:: RwLock ;
28
30
29
- /// HTTP client for interacting with the API, assumes single threaded use .
31
+ /// HTTP client for interacting with the API.
30
32
pub struct Client < C > {
33
+ inner : Arc < RwLock < ClientInner < C > > > ,
34
+ }
35
+
36
+ pub struct ClientInner < C > {
31
37
id : u64 ,
32
38
client : HyperClient < C > ,
33
39
endpoint : Uri ,
@@ -38,33 +44,37 @@ impl Client<HttpConnector> {
38
44
pub fn new ( endpoint : Uri ) -> Self {
39
45
let client = HyperClient :: new ( ) ;
40
46
Self {
41
- id : 0 ,
42
- client,
43
- endpoint,
44
- private_key : None ,
47
+ inner : Arc :: new ( RwLock :: new ( ClientInner {
48
+ id : 0 ,
49
+ client,
50
+ endpoint,
51
+ private_key : None ,
52
+ } ) ) ,
45
53
}
46
54
}
47
55
}
48
56
49
57
impl Client < HttpConnector > {
50
- fn next_id ( & mut self ) -> Id {
51
- let id = self . id ;
52
- self . id = id + 1 ;
58
+ async fn next_id ( & self ) -> Id {
59
+ let mut client = self . inner . write ( ) . await ;
60
+ let id = client. id ;
61
+ client. id = id + 1 ;
53
62
Id :: Num ( id)
54
63
}
55
64
56
- pub fn set_endpoint ( & mut self , endpoint : Uri ) {
57
- self . endpoint = endpoint;
65
+ pub async fn set_endpoint ( & self , endpoint : Uri ) {
66
+ let mut inner = self . inner . write ( ) . await ;
67
+ inner. endpoint = endpoint;
58
68
}
59
69
60
- pub fn set_private_key ( mut self , private_key : Key ) -> Self {
61
- self . private_key = Some ( private_key ) ;
62
- self
70
+ pub async fn set_private_key ( & self , private_key : Key ) {
71
+ let mut inner = self . inner . write ( ) . await ;
72
+ inner . private_key = Some ( private_key ) ;
63
73
}
64
74
65
75
/// Returns a serialized json request as string and the request id.
66
- pub fn raw_request ( & mut self , method : & str , params : & Params ) -> ( Id , String ) {
67
- let id = self . next_id ( ) ;
76
+ pub async fn raw_request ( & self , method : & str , params : & Params ) -> ( Id , String ) {
77
+ let id = self . next_id ( ) . await ;
68
78
let request = jsonrpc_core:: Request :: Single ( Call :: MethodCall ( MethodCall {
69
79
jsonrpc : Some ( Version :: V2 ) ,
70
80
method : method. to_owned ( ) ,
@@ -77,64 +87,73 @@ impl Client<HttpConnector> {
77
87
)
78
88
}
79
89
80
- /// Returns a recoverable signature from bytes.
81
- pub fn sign_digest ( & self , dh : & [ u8 ] ) -> Result < Sig > {
82
- if let Some ( pk) = & self . private_key {
90
+ /// Returns a recoverable signature from 32 byte SHA256 message.
91
+ pub async fn sign_digest ( & self , dh : & [ u8 ] ) -> Result < Sig > {
92
+ let inner = self . inner . read ( ) . await ;
93
+ if let Some ( pk) = & inner. private_key {
83
94
return pk. sign_digest ( dh) ;
84
95
}
85
96
Err ( Error :: new ( ErrorKind :: Other , "private key not set" ) )
86
97
}
87
98
88
99
/// Returns a PingResponse from client request.
89
- pub async fn ping ( & mut self ) -> Result < PingResponse > {
90
- let ( _id, json_request) = self . raw_request ( "ping" , & Params :: None ) ;
100
+ pub async fn ping ( & self ) -> Result < PingResponse > {
101
+ let ( _id, json_request) = self . raw_request ( "ping" , & Params :: None ) . await ;
91
102
let resp = self . post_de :: < PingResponse > ( & json_request) . await ?;
92
103
93
104
Ok ( resp)
94
105
}
95
106
96
107
/// Returns a DecodeTxResponse from client request.
97
- pub async fn decode_tx ( & mut self , tx_data : TransactionData ) -> Result < DecodeTxResponse > {
108
+ pub async fn decode_tx ( & self , tx_data : TransactionData ) -> Result < DecodeTxResponse > {
98
109
let arg_value = serde_json:: to_value ( & DecodeTxArgs { tx_data } ) ?;
99
- let ( _id, json_request) = self . raw_request ( "decodeTx" , & Params :: Array ( vec ! [ arg_value] ) ) ;
110
+ let ( _id, json_request) = self
111
+ . raw_request ( "decodeTx" , & Params :: Array ( vec ! [ arg_value] ) )
112
+ . await ;
100
113
let resp = self . post_de :: < DecodeTxResponse > ( & json_request) . await ?;
101
114
102
115
Ok ( resp)
103
116
}
104
117
105
118
/// Returns a IssueTxResponse from client request.
106
- pub async fn issue_tx ( & mut self , typed_data : & TypedData ) -> Result < IssueTxResponse > {
119
+ pub async fn issue_tx ( & self , typed_data : & TypedData ) -> Result < IssueTxResponse > {
107
120
let dh = decoder:: hash_structured_data ( typed_data) ?;
108
- let sig = self . sign_digest ( & dh. as_bytes ( ) ) ?. to_bytes ( ) . to_vec ( ) ;
121
+ let sig = self . sign_digest ( & dh. as_bytes ( ) ) . await ?. to_bytes ( ) . to_vec ( ) ;
109
122
log:: debug!( "signature: {:?}" , sig) ;
110
123
111
124
let arg_value = serde_json:: to_value ( & IssueTxArgs {
112
125
typed_data : typed_data. to_owned ( ) ,
113
126
signature : sig,
114
127
} ) ?;
115
- let ( _id, json_request) = self . raw_request ( "issueTx" , & Params :: Array ( vec ! [ arg_value] ) ) ;
128
+ let ( _id, json_request) = self
129
+ . raw_request ( "issueTx" , & Params :: Array ( vec ! [ arg_value] ) )
130
+ . await ;
116
131
let resp = self . post_de :: < IssueTxResponse > ( & json_request) . await ?;
117
132
118
133
Ok ( resp)
119
134
}
120
135
121
136
/// Returns a ResolveResponse from client request.
122
- pub async fn resolve ( & mut self , space : & str , key : & str ) -> Result < ResolveResponse > {
137
+ pub async fn resolve ( & self , space : & str , key : & str ) -> Result < ResolveResponse > {
123
138
let arg_value = serde_json:: to_value ( & ResolveArgs {
124
139
space : space. as_bytes ( ) . to_vec ( ) ,
125
140
key : key. as_bytes ( ) . to_vec ( ) ,
126
141
} ) ?;
127
- let ( _id, json_request) = self . raw_request ( "resolve" , & Params :: Array ( vec ! [ arg_value] ) ) ;
142
+ let ( _id, json_request) = self
143
+ . raw_request ( "resolve" , & Params :: Array ( vec ! [ arg_value] ) )
144
+ . await ;
128
145
let resp = self . post_de :: < ResolveResponse > ( & json_request) . await ?;
129
146
130
147
Ok ( resp)
131
148
}
132
149
133
150
/// Returns a deserialized response from client request.
134
151
pub async fn post_de < T : de:: DeserializeOwned > ( & self , json : & str ) -> Result < T > {
152
+ let inner = self . inner . read ( ) . await ;
153
+
135
154
let req = Request :: builder ( )
136
155
. method ( Method :: POST )
137
- . uri ( self . endpoint . to_string ( ) )
156
+ . uri ( inner . endpoint . to_string ( ) )
138
157
. header ( "content-type" , "application/json-rpc" )
139
158
. body ( Body :: from ( json. to_owned ( ) ) )
140
159
. map_err ( |e| {
@@ -144,7 +163,7 @@ impl Client<HttpConnector> {
144
163
)
145
164
} ) ?;
146
165
147
- let mut resp = self . client . request ( req) . await . map_err ( |e| {
166
+ let mut resp = inner . client . request ( req) . await . map_err ( |e| {
148
167
std:: io:: Error :: new (
149
168
std:: io:: ErrorKind :: Other ,
150
169
format ! ( "client post request failed: {}" , e) ,
@@ -219,12 +238,12 @@ pub fn get_or_create_pk(path: &str) -> Result<key::secp256k1::private_key::Key>
219
238
. map_err ( |e| std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , e. to_string ( ) ) )
220
239
}
221
240
222
- #[ test]
223
- fn test_raw_request ( ) {
224
- let mut cli = Client :: new ( Uri :: from_static ( "http://test.url" ) ) ;
225
- let ( id, _) = cli. raw_request ( "ping" , & Params :: None ) ;
241
+ #[ tokio :: test]
242
+ async fn test_raw_request ( ) {
243
+ let cli = Client :: new ( Uri :: from_static ( "http://test.url" ) ) ;
244
+ let ( id, _) = cli. raw_request ( "ping" , & Params :: None ) . await ;
226
245
assert_eq ! ( id, jsonrpc_core:: Id :: Num ( 0 ) ) ;
227
- let ( id, req) = cli. raw_request ( "ping" , & Params :: None ) ;
246
+ let ( id, req) = cli. raw_request ( "ping" , & Params :: None ) . await ;
228
247
assert_eq ! ( id, jsonrpc_core:: Id :: Num ( 1 ) ) ;
229
248
assert_eq ! (
230
249
req,
0 commit comments