@@ -12,21 +12,72 @@ use subxt::{
12
12
SubstrateConfig ,
13
13
} ;
14
14
15
- use crate :: { api, sp_weights:: weight_v2:: Weight , BlockHash , Call , Client , KeyPair , TxStatus } ;
15
+ use crate :: {
16
+ api, sp_weights:: weight_v2:: Weight , AccountId , BlockHash , Call , KeyPair , SubxtClient , TxStatus ,
17
+ } ;
16
18
17
19
#[ derive( Clone ) ]
18
20
pub struct Connection {
19
- pub client : Client ,
21
+ client : SubxtClient ,
20
22
}
21
23
22
24
pub struct SignedConnection {
23
- pub connection : Connection ,
24
- pub signer : KeyPair ,
25
+ connection : Connection ,
26
+ signer : KeyPair ,
25
27
}
26
28
29
+ #[ derive( Clone ) ]
27
30
pub struct RootConnection {
28
- pub connection : Connection ,
29
- pub root : KeyPair ,
31
+ connection : SignedConnection ,
32
+ }
33
+
34
+ pub ( crate ) trait AsConnection {
35
+ fn as_connection ( & self ) -> & Connection ;
36
+ }
37
+
38
+ pub ( crate ) trait AsSigned {
39
+ fn as_signed ( & self ) -> & SignedConnection ;
40
+ }
41
+
42
+ #[ async_trait:: async_trait]
43
+ pub trait ConnectionApi : Sync {
44
+ async fn get_storage_entry < T : DecodeWithMetadata + Sync , Defaultable : Sync , Iterable : Sync > (
45
+ & self ,
46
+ addrs : & StaticStorageAddress < T , Yes , Defaultable , Iterable > ,
47
+ at : Option < BlockHash > ,
48
+ ) -> T :: Target ;
49
+
50
+ async fn get_storage_entry_maybe <
51
+ T : DecodeWithMetadata + Sync ,
52
+ Defaultable : Sync ,
53
+ Iterable : Sync ,
54
+ > (
55
+ & self ,
56
+ addrs : & StaticStorageAddress < T , Yes , Defaultable , Iterable > ,
57
+ at : Option < BlockHash > ,
58
+ ) -> Option < T :: Target > ;
59
+
60
+ async fn rpc_call < R : Decode > ( & self , func_name : String , params : RpcParams ) -> anyhow:: Result < R > ;
61
+ }
62
+
63
+ #[ async_trait:: async_trait]
64
+ pub trait SignedConnectionApi : ConnectionApi {
65
+ async fn send_tx < Call : TxPayload + Send + Sync > (
66
+ & self ,
67
+ tx : Call ,
68
+ status : TxStatus ,
69
+ ) -> anyhow:: Result < BlockHash > ;
70
+
71
+ async fn send_tx_with_params < Call : TxPayload + Send + Sync > (
72
+ & self ,
73
+ tx : Call ,
74
+ params : BaseExtrinsicParamsBuilder < SubstrateConfig , PlainTip > ,
75
+ status : TxStatus ,
76
+ ) -> anyhow:: Result < BlockHash > ;
77
+
78
+ fn account_id ( & self ) -> & AccountId ;
79
+ fn signer ( & self ) -> & KeyPair ;
80
+ async fn try_as_root ( & self ) -> anyhow:: Result < RootConnection > ;
30
81
}
31
82
32
83
#[ async_trait:: async_trait]
@@ -58,29 +109,42 @@ impl SudoCall for RootConnection {
58
109
}
59
110
}
60
111
61
- impl Connection {
62
- const DEFAULT_RETRIES : u32 = 10 ;
63
- const RETRY_WAIT_SECS : u64 = 1 ;
112
+ impl Clone for SignedConnection {
113
+ fn clone ( & self ) -> Self {
114
+ SignedConnection {
115
+ connection : self . connection . clone ( ) ,
116
+ signer : KeyPair :: new ( self . signer . signer ( ) . clone ( ) ) ,
117
+ }
118
+ }
119
+ }
64
120
65
- pub async fn new ( address : String ) -> Self {
66
- Self :: new_with_retries ( address, Self :: DEFAULT_RETRIES ) . await
121
+ impl AsConnection for Connection {
122
+ fn as_connection ( & self ) -> & Connection {
123
+ self
67
124
}
125
+ }
68
126
69
- pub async fn new_with_retries ( address : String , mut retries : u32 ) -> Self {
70
- loop {
71
- let client = Client :: from_url ( & address) . await ;
72
- match ( retries, client) {
73
- ( _, Ok ( client) ) => return Self { client } ,
74
- ( 0 , Err ( e) ) => panic ! ( "{:?}" , e) ,
75
- _ => {
76
- sleep ( Duration :: from_secs ( Self :: RETRY_WAIT_SECS ) ) ;
77
- retries -= 1 ;
78
- }
79
- }
80
- }
127
+ impl < S : AsSigned > AsConnection for S {
128
+ fn as_connection ( & self ) -> & Connection {
129
+ & self . as_signed ( ) . connection
81
130
}
131
+ }
132
+
133
+ impl AsSigned for SignedConnection {
134
+ fn as_signed ( & self ) -> & SignedConnection {
135
+ self
136
+ }
137
+ }
138
+
139
+ impl AsSigned for RootConnection {
140
+ fn as_signed ( & self ) -> & SignedConnection {
141
+ & self . connection
142
+ }
143
+ }
82
144
83
- pub async fn get_storage_entry < T : DecodeWithMetadata , Defaultable , Iterable > (
145
+ #[ async_trait:: async_trait]
146
+ impl < C : AsConnection + Sync > ConnectionApi for C {
147
+ async fn get_storage_entry < T : DecodeWithMetadata + Sync , Defaultable : Sync , Iterable : Sync > (
84
148
& self ,
85
149
addrs : & StaticStorageAddress < T , Yes , Defaultable , Iterable > ,
86
150
at : Option < BlockHash > ,
@@ -90,41 +154,40 @@ impl Connection {
90
154
. expect ( "There should be a value" )
91
155
}
92
156
93
- pub async fn get_storage_entry_maybe < T : DecodeWithMetadata , Defaultable , Iterable > (
157
+ async fn get_storage_entry_maybe <
158
+ T : DecodeWithMetadata + Sync ,
159
+ Defaultable : Sync ,
160
+ Iterable : Sync ,
161
+ > (
94
162
& self ,
95
163
addrs : & StaticStorageAddress < T , Yes , Defaultable , Iterable > ,
96
164
at : Option < BlockHash > ,
97
165
) -> Option < T :: Target > {
98
166
info ! ( target: "aleph-client" , "accessing storage at {}::{} at block {:?}" , addrs. pallet_name( ) , addrs. entry_name( ) , at) ;
99
- self . client
167
+ self . as_connection ( )
168
+ . as_client ( )
100
169
. storage ( )
101
170
. fetch ( addrs, at)
102
171
. await
103
172
. expect ( "Should access storage" )
104
173
}
105
174
106
- pub async fn rpc_call < R : Decode > (
107
- & self ,
108
- func_name : String ,
109
- params : RpcParams ,
110
- ) -> anyhow:: Result < R > {
175
+ async fn rpc_call < R : Decode > ( & self , func_name : String , params : RpcParams ) -> anyhow:: Result < R > {
111
176
info ! ( target: "aleph-client" , "submitting rpc call `{}`, with params {:?}" , func_name, params) ;
112
- let bytes: Bytes = self . client . rpc ( ) . request ( & func_name, params) . await ?;
177
+ let bytes: Bytes = self
178
+ . as_connection ( )
179
+ . as_client ( )
180
+ . rpc ( )
181
+ . request ( & func_name, params)
182
+ . await ?;
113
183
114
184
Ok ( R :: decode ( & mut bytes. as_ref ( ) ) ?)
115
185
}
116
186
}
117
187
118
- impl SignedConnection {
119
- pub async fn new ( address : String , signer : KeyPair ) -> Self {
120
- Self :: from_connection ( Connection :: new ( address) . await , signer)
121
- }
122
-
123
- pub fn from_connection ( connection : Connection , signer : KeyPair ) -> Self {
124
- Self { connection, signer }
125
- }
126
-
127
- pub async fn send_tx < Call : TxPayload > (
188
+ #[ async_trait:: async_trait]
189
+ impl < S : AsSigned + Sync > SignedConnectionApi for S {
190
+ async fn send_tx < Call : TxPayload + Send + Sync > (
128
191
& self ,
129
192
tx : Call ,
130
193
status : TxStatus ,
@@ -133,7 +196,7 @@ impl SignedConnection {
133
196
. await
134
197
}
135
198
136
- pub async fn send_tx_with_params < Call : TxPayload > (
199
+ async fn send_tx_with_params < Call : TxPayload + Send + Sync > (
137
200
& self ,
138
201
tx : Call ,
139
202
params : BaseExtrinsicParamsBuilder < SubstrateConfig , PlainTip > ,
@@ -144,10 +207,10 @@ impl SignedConnection {
144
207
}
145
208
146
209
let progress = self
147
- . connection
148
- . client
210
+ . as_connection ( )
211
+ . as_client ( )
149
212
. tx ( )
150
- . sign_and_submit_then_watch ( & tx, & self . signer , params)
213
+ . sign_and_submit_then_watch ( & tx, self . as_signed ( ) . signer ( ) , params)
151
214
. await
152
215
. map_err ( |e| anyhow ! ( "Failed to submit transaction: {:?}" , e) ) ?;
153
216
@@ -161,10 +224,60 @@ impl SignedConnection {
161
224
162
225
Ok ( hash)
163
226
}
227
+
228
+ fn account_id ( & self ) -> & AccountId {
229
+ self . as_signed ( ) . signer ( ) . account_id ( )
230
+ }
231
+
232
+ fn signer ( & self ) -> & KeyPair {
233
+ & self . as_signed ( ) . signer
234
+ }
235
+
236
+ async fn try_as_root ( & self ) -> anyhow:: Result < RootConnection > {
237
+ let temp = self . as_signed ( ) . clone ( ) ;
238
+ RootConnection :: try_from_connection ( temp. connection , temp. signer ) . await
239
+ }
240
+ }
241
+
242
+ impl Connection {
243
+ const DEFAULT_RETRIES : u32 = 10 ;
244
+ const RETRY_WAIT_SECS : u64 = 1 ;
245
+
246
+ pub async fn new ( address : & str ) -> Connection {
247
+ Self :: new_with_retries ( address, Self :: DEFAULT_RETRIES ) . await
248
+ }
249
+
250
+ async fn new_with_retries ( address : & str , mut retries : u32 ) -> Connection {
251
+ loop {
252
+ let client = SubxtClient :: from_url ( & address) . await ;
253
+ match ( retries, client) {
254
+ ( _, Ok ( client) ) => return Connection { client } ,
255
+ ( 0 , Err ( e) ) => panic ! ( "{:?}" , e) ,
256
+ _ => {
257
+ sleep ( Duration :: from_secs ( Self :: RETRY_WAIT_SECS ) ) ;
258
+ retries -= 1 ;
259
+ }
260
+ }
261
+ }
262
+ }
263
+
264
+ pub ( crate ) fn as_client ( & self ) -> & SubxtClient {
265
+ & self . client
266
+ }
267
+ }
268
+
269
+ impl SignedConnection {
270
+ pub async fn new ( address : & str , signer : KeyPair ) -> Self {
271
+ Self :: from_connection ( Connection :: new ( address) . await , signer)
272
+ }
273
+
274
+ pub fn from_connection ( connection : Connection , signer : KeyPair ) -> Self {
275
+ Self { connection, signer }
276
+ }
164
277
}
165
278
166
279
impl RootConnection {
167
- pub async fn new ( address : String , root : KeyPair ) -> anyhow:: Result < Self > {
280
+ pub async fn new ( address : & str , root : KeyPair ) -> anyhow:: Result < Self > {
168
281
RootConnection :: try_from_connection ( Connection :: new ( address) . await , root) . await
169
282
}
170
283
@@ -174,7 +287,12 @@ impl RootConnection {
174
287
) -> anyhow:: Result < Self > {
175
288
let root_address = api:: storage ( ) . sudo ( ) . key ( ) ;
176
289
177
- let root = match connection. client . storage ( ) . fetch ( & root_address, None ) . await {
290
+ let root = match connection
291
+ . as_client ( )
292
+ . storage ( )
293
+ . fetch ( & root_address, None )
294
+ . await
295
+ {
178
296
Ok ( Some ( account) ) => account,
179
297
_ => return Err ( anyhow ! ( "Could not read sudo key from chain" ) ) ,
180
298
} ;
@@ -188,15 +306,7 @@ impl RootConnection {
188
306
}
189
307
190
308
Ok ( Self {
191
- connection,
192
- root : signer,
309
+ connection : SignedConnection { connection, signer } ,
193
310
} )
194
311
}
195
-
196
- pub fn as_signed ( & self ) -> SignedConnection {
197
- SignedConnection {
198
- connection : self . connection . clone ( ) ,
199
- signer : KeyPair :: new ( self . root . signer ( ) . clone ( ) ) ,
200
- }
201
- }
202
312
}
0 commit comments