@@ -3,6 +3,8 @@ use chrono::Utc;
3
3
use ethabi:: token:: Token ;
4
4
use ethkey:: Password ;
5
5
use ethstore:: SafeAccount ;
6
+ use futures:: compat:: Future01CompatExt ;
7
+ use futures:: future:: BoxFuture ;
6
8
use lazy_static:: lazy_static;
7
9
use parity_crypto:: publickey:: {
8
10
public_to_address, recover, verify_address, Address , Message , Signature ,
@@ -24,8 +26,6 @@ use web3::{
24
26
contract:: { Contract , Options } ,
25
27
types:: U256 ,
26
28
} ;
27
- use futures:: future:: { BoxFuture } ;
28
- use futures:: compat:: Future01CompatExt ;
29
29
30
30
lazy_static ! {
31
31
static ref ADEXCORE_ABI : & ' static [ u8 ] =
@@ -124,132 +124,129 @@ impl Adapter for EthereumAdapter {
124
124
}
125
125
126
126
fn validate_channel < ' a > ( & ' a self , channel : & ' a Channel ) -> BoxFuture < ' a , AdapterResult < bool > > {
127
- Box :: pin (
128
- async move {
129
- // check if channel is valid
130
- if let Err ( e) = EthereumAdapter :: is_channel_valid ( & self . config , self . whoami ( ) , channel) {
131
- return Err ( AdapterError :: InvalidChannel ( e. to_string ( ) ) ) ;
132
- }
133
-
134
- let eth_channel = EthereumChannel :: try_from ( channel)
135
- . map_err ( |e| AdapterError :: InvalidChannel ( e. to_string ( ) ) ) ?;
127
+ Box :: pin ( async move {
128
+ // check if channel is valid
129
+ if let Err ( e) = EthereumAdapter :: is_channel_valid ( & self . config , self . whoami ( ) , channel)
130
+ {
131
+ return Err ( AdapterError :: InvalidChannel ( e. to_string ( ) ) ) ;
132
+ }
136
133
137
- let channel_id = eth_channel
138
- . hash_hex ( & self . config . ethereum_core_address )
139
- . map_err ( |_| map_error ( "Failed to hash the channel id" ) ) ?;
134
+ let eth_channel = EthereumChannel :: try_from ( channel)
135
+ . map_err ( |e| AdapterError :: InvalidChannel ( e. to_string ( ) ) ) ?;
140
136
141
- let our_channel_id = format ! ( "0x{}" , hex:: encode( channel. id) ) ;
142
- if channel_id != our_channel_id {
143
- return Err ( AdapterError :: Configuration (
144
- "channel.id is not valid" . to_string ( ) ,
145
- ) ) ;
146
- }
137
+ let channel_id = eth_channel
138
+ . hash_hex ( & self . config . ethereum_core_address )
139
+ . map_err ( |_| map_error ( "Failed to hash the channel id" ) ) ?;
147
140
148
- let contract_address = Address :: from_slice ( & self . config . ethereum_core_address ) ;
149
-
150
- let ( _eloop, transport) = web3:: transports:: Http :: new ( & self . config . ethereum_network )
151
- . map_err ( |_| map_error ( "failed to init http transport" ) ) ?;
152
- let web3 = web3:: Web3 :: new ( transport) ;
153
-
154
- let contract = Contract :: from_json ( web3. eth ( ) , contract_address, & ADEXCORE_ABI )
155
- . map_err ( |_| map_error ( "failed to init core contract" ) ) ?;
156
-
157
- let channel_status: U256 = contract
158
- . query (
159
- "states" ,
160
- ( Token :: FixedBytes ( channel. id . as_ref ( ) . to_vec ( ) ) , ) ,
161
- None ,
162
- Options :: default ( ) ,
163
- None ,
164
- )
165
- . compat ( )
166
- . await
167
- . map_err ( |_| map_error ( "contract channel status query failed" ) ) ?;
168
-
169
- if channel_status != * CHANNEL_STATE_ACTIVE {
170
- return Err ( AdapterError :: Configuration (
171
- "channel is not Active on the ethereum network" . to_string ( ) ,
172
- ) ) ;
173
- }
141
+ let our_channel_id = format ! ( "0x{}" , hex:: encode( channel. id) ) ;
142
+ if channel_id != our_channel_id {
143
+ return Err ( AdapterError :: Configuration (
144
+ "channel.id is not valid" . to_string ( ) ,
145
+ ) ) ;
146
+ }
174
147
175
- Ok ( true )
148
+ let contract_address = Address :: from_slice ( & self . config . ethereum_core_address ) ;
149
+
150
+ let ( _eloop, transport) = web3:: transports:: Http :: new ( & self . config . ethereum_network )
151
+ . map_err ( |_| map_error ( "failed to init http transport" ) ) ?;
152
+ let web3 = web3:: Web3 :: new ( transport) ;
153
+
154
+ let contract = Contract :: from_json ( web3. eth ( ) , contract_address, & ADEXCORE_ABI )
155
+ . map_err ( |_| map_error ( "failed to init core contract" ) ) ?;
156
+
157
+ let channel_status: U256 = contract
158
+ . query (
159
+ "states" ,
160
+ ( Token :: FixedBytes ( channel. id . as_ref ( ) . to_vec ( ) ) , ) ,
161
+ None ,
162
+ Options :: default ( ) ,
163
+ None ,
164
+ )
165
+ . compat ( )
166
+ . await
167
+ . map_err ( |_| map_error ( "contract channel status query failed" ) ) ?;
168
+
169
+ if channel_status != * CHANNEL_STATE_ACTIVE {
170
+ return Err ( AdapterError :: Configuration (
171
+ "channel is not Active on the ethereum network" . to_string ( ) ,
172
+ ) ) ;
176
173
}
177
- )
174
+
175
+ Ok ( true )
176
+ } )
178
177
}
179
178
180
179
/// Creates a `Session` from a provided Token by calling the Contract.
181
180
/// Does **not** cache the (`Token`, `Session`) pair.
182
181
fn session_from_token < ' a > ( & ' a self , token : & ' a str ) -> BoxFuture < ' a , AdapterResult < Session > > {
183
- Box :: pin (
184
- async move {
185
- if token. len ( ) < 16 {
186
- return Err ( AdapterError :: Failed ( "invalid token id" . to_string ( ) ) ) ;
187
- }
188
-
189
- let parts: Vec < & str > = token. split ( '.' ) . collect ( ) ;
190
- let ( header_encoded, payload_encoded, token_encoded) =
191
- match ( parts. get ( 0 ) , parts. get ( 1 ) , parts. get ( 2 ) ) {
192
- ( Some ( header_encoded) , Some ( payload_encoded) , Some ( token_encoded) ) => {
193
- ( header_encoded, payload_encoded, token_encoded)
194
- }
195
- _ => {
196
- return Err ( AdapterError :: Failed ( format ! (
197
- "{} token string is incorrect" ,
198
- token
199
- ) ) )
200
- }
201
- } ;
202
-
203
- let verified = ewt_verify ( header_encoded, payload_encoded, token_encoded)
204
- . map_err ( |e| map_error ( & e. to_string ( ) ) ) ?;
205
-
206
- if self . whoami ( ) . to_hex_checksummed_string ( ) != verified. payload . id {
207
- return Err ( AdapterError :: Configuration (
208
- "token payload.id !== whoami(): token was not intended for us" . to_string ( ) ,
209
- ) ) ;
210
- }
211
-
212
- let sess = match & verified. payload . identity {
213
- Some ( identity) => {
214
- let contract_address = Address :: from_slice ( identity) ;
215
- let ( _eloop, transport) =
216
- web3:: transports:: Http :: new ( & self . config . ethereum_network )
217
- . map_err ( |_| map_error ( "failed to init http transport" ) ) ?;
218
- let web3 = web3:: Web3 :: new ( transport) ;
219
- let contract = Contract :: from_json ( web3. eth ( ) , contract_address, & IDENTITY_ABI )
220
- . map_err ( |_| map_error ( "failed to init identity contract" ) ) ?;
221
-
222
- let privilege_level: U256 = contract
223
- . query (
224
- "privileges" ,
225
- ( Token :: Address ( Address :: from_slice ( verified. from . inner ( ) ) ) , ) ,
226
- None ,
227
- Options :: default ( ) ,
228
- None ,
229
- )
230
- . compat ( )
231
- . await
232
- . map_err ( |_| map_error ( "failed query priviledge level on contract" ) ) ?;
233
-
234
- if privilege_level == * PRIVILEGE_LEVEL_NONE {
235
- return Err ( AdapterError :: Authorization (
236
- "insufficient privilege" . to_string ( ) ,
237
- ) ) ;
238
- }
239
- Session {
240
- era : verified. payload . era ,
241
- uid : identity. into ( ) ,
242
- }
182
+ Box :: pin ( async move {
183
+ if token. len ( ) < 16 {
184
+ return Err ( AdapterError :: Failed ( "invalid token id" . to_string ( ) ) ) ;
185
+ }
186
+
187
+ let parts: Vec < & str > = token. split ( '.' ) . collect ( ) ;
188
+ let ( header_encoded, payload_encoded, token_encoded) =
189
+ match ( parts. get ( 0 ) , parts. get ( 1 ) , parts. get ( 2 ) ) {
190
+ ( Some ( header_encoded) , Some ( payload_encoded) , Some ( token_encoded) ) => {
191
+ ( header_encoded, payload_encoded, token_encoded)
192
+ }
193
+ _ => {
194
+ return Err ( AdapterError :: Failed ( format ! (
195
+ "{} token string is incorrect" ,
196
+ token
197
+ ) ) )
243
198
}
244
- None => Session {
245
- era : verified. payload . era ,
246
- uid : verified. from ,
247
- } ,
248
199
} ;
249
-
250
- Ok ( sess)
200
+
201
+ let verified = ewt_verify ( header_encoded, payload_encoded, token_encoded)
202
+ . map_err ( |e| map_error ( & e. to_string ( ) ) ) ?;
203
+
204
+ if self . whoami ( ) . to_hex_checksummed_string ( ) != verified. payload . id {
205
+ return Err ( AdapterError :: Configuration (
206
+ "token payload.id !== whoami(): token was not intended for us" . to_string ( ) ,
207
+ ) ) ;
251
208
}
252
- )
209
+
210
+ let sess = match & verified. payload . identity {
211
+ Some ( identity) => {
212
+ let contract_address = Address :: from_slice ( identity) ;
213
+ let ( _eloop, transport) =
214
+ web3:: transports:: Http :: new ( & self . config . ethereum_network )
215
+ . map_err ( |_| map_error ( "failed to init http transport" ) ) ?;
216
+ let web3 = web3:: Web3 :: new ( transport) ;
217
+ let contract = Contract :: from_json ( web3. eth ( ) , contract_address, & IDENTITY_ABI )
218
+ . map_err ( |_| map_error ( "failed to init identity contract" ) ) ?;
219
+
220
+ let privilege_level: U256 = contract
221
+ . query (
222
+ "privileges" ,
223
+ ( Token :: Address ( Address :: from_slice ( verified. from . inner ( ) ) ) , ) ,
224
+ None ,
225
+ Options :: default ( ) ,
226
+ None ,
227
+ )
228
+ . compat ( )
229
+ . await
230
+ . map_err ( |_| map_error ( "failed query priviledge level on contract" ) ) ?;
231
+
232
+ if privilege_level == * PRIVILEGE_LEVEL_NONE {
233
+ return Err ( AdapterError :: Authorization (
234
+ "insufficient privilege" . to_string ( ) ,
235
+ ) ) ;
236
+ }
237
+ Session {
238
+ era : verified. payload . era ,
239
+ uid : identity. into ( ) ,
240
+ }
241
+ }
242
+ None => Session {
243
+ era : verified. payload . era ,
244
+ uid : verified. from ,
245
+ } ,
246
+ } ;
247
+
248
+ Ok ( sess)
249
+ } )
253
250
}
254
251
255
252
fn get_auth ( & self , validator : & ValidatorId ) -> AdapterResult < String > {
0 commit comments