@@ -5,6 +5,7 @@ use ethkey::Password;
5
5
use ethstore:: SafeAccount ;
6
6
use futures:: compat:: Future01CompatExt ;
7
7
use futures:: future:: { BoxFuture , FutureExt } ;
8
+ use futures:: TryFutureExt ;
8
9
use lazy_static:: lazy_static;
9
10
use parity_crypto:: publickey:: {
10
11
public_to_address, recover, verify_address, Address , Message , Signature ,
@@ -15,8 +16,8 @@ use primitives::{
15
16
config:: Config ,
16
17
Channel , ToETHChecksum , ValidatorId ,
17
18
} ;
19
+ use reqwest:: Client ;
18
20
use serde:: { Deserialize , Serialize } ;
19
- use serde_hex:: { SerHexOpt , StrictPfx } ;
20
21
use serde_json:: Value ;
21
22
use std:: convert:: TryFrom ;
22
23
use std:: error:: Error ;
@@ -34,10 +35,8 @@ use web3::{
34
35
lazy_static ! {
35
36
static ref ADEXCORE_ABI : & ' static [ u8 ] =
36
37
include_bytes!( "../../lib/protocol-eth/abi/AdExCore.json" ) ;
37
- static ref IDENTITY_ABI : & ' static [ u8 ] =
38
- include_bytes!( "../../lib/protocol-eth/abi/Identity.json" ) ;
39
38
static ref CHANNEL_STATE_ACTIVE : U256 = 1 . into( ) ;
40
- static ref PRIVILEGE_LEVEL_NONE : U256 = 0 . into ( ) ;
39
+ static ref PRIVILEGE_LEVEL_NONE : u8 = 0 ;
41
40
}
42
41
43
42
#[ derive( Debug , Clone ) ]
@@ -49,6 +48,7 @@ pub struct EthereumAdapter {
49
48
wallet : Option < SafeAccount > ,
50
49
event_loop : Arc < EventLoopHandle > ,
51
50
web3 : Web3 < Http > ,
51
+ relayer : RelayerClient ,
52
52
}
53
53
54
54
// Enables EthereumAdapter to be able to
@@ -78,6 +78,8 @@ impl EthereumAdapter {
78
78
. map_err ( |_| map_error ( "failed to init http transport" ) ) ?;
79
79
let event_loop = Arc :: new ( eloop) ;
80
80
let web3 = web3:: Web3 :: new ( transport) ;
81
+ let relayer = RelayerClient :: new ( & config. ethereum_adapter_relayer )
82
+ . map_err ( |_| map_error ( "Client for Relayer couldn't be built" ) ) ?;
81
83
82
84
Ok ( Self {
83
85
address,
@@ -87,6 +89,7 @@ impl EthereumAdapter {
87
89
config : config. to_owned ( ) ,
88
90
event_loop,
89
91
web3,
92
+ relayer,
90
93
} )
91
94
}
92
95
}
@@ -219,32 +222,20 @@ impl Adapter for EthereumAdapter {
219
222
220
223
let sess = match & verified. payload . identity {
221
224
Some ( identity) => {
222
- let contract_address: Address = identity. into ( ) ;
223
- let contract =
224
- Contract :: from_json ( self . web3 . eth ( ) , contract_address, & IDENTITY_ABI )
225
- . map_err ( |_| map_error ( "failed to init identity contract" ) ) ?;
226
-
227
- let privilege_level: U256 = contract
228
- . query (
229
- "privileges" ,
230
- ( Token :: Address ( Address :: from_slice ( verified. from . inner ( ) ) ) , ) ,
231
- None ,
232
- Options :: default ( ) ,
233
- None ,
234
- )
235
- . compat ( )
236
- . await
237
- . map_err ( |_| map_error ( "failed query priviledge level on contract" ) ) ?;
238
-
239
- if privilege_level == * PRIVILEGE_LEVEL_NONE {
225
+ if self
226
+ . relayer
227
+ . has_privileges ( & verified. from , identity)
228
+ . await ?
229
+ {
230
+ Session {
231
+ era : verified. payload . era ,
232
+ uid : identity. to_owned ( ) ,
233
+ }
234
+ } else {
240
235
return Err ( AdapterError :: Authorization (
241
236
"insufficient privilege" . to_string ( ) ,
242
237
) ) ;
243
238
}
244
- Session {
245
- era : verified. payload . era ,
246
- uid : identity. into ( ) ,
247
- }
248
239
}
249
240
None => Session {
250
241
era : verified. payload . era ,
@@ -276,6 +267,53 @@ impl Adapter for EthereumAdapter {
276
267
}
277
268
}
278
269
270
+ #[ derive( Debug , Clone ) ]
271
+ struct RelayerClient {
272
+ client : Client ,
273
+ relayer_url : String ,
274
+ }
275
+
276
+ impl RelayerClient {
277
+ pub fn new ( relayer_url : & str ) -> Result < Self , reqwest:: Error > {
278
+ let client = Client :: builder ( ) . build ( ) ?;
279
+
280
+ Ok ( Self {
281
+ relayer_url : relayer_url. to_string ( ) ,
282
+ client,
283
+ } )
284
+ }
285
+
286
+ /// Checks whether there are any privileges (i.e. > 0)
287
+ pub async fn has_privileges (
288
+ & self ,
289
+ from : & ValidatorId ,
290
+ identity : & ValidatorId ,
291
+ ) -> Result < bool , AdapterError > {
292
+ use reqwest:: Response ;
293
+ use std:: collections:: HashMap ;
294
+
295
+ let relay_url = format ! (
296
+ "{}/identity/by-owner/{}" ,
297
+ self . relayer_url,
298
+ from. to_checksum( )
299
+ ) ;
300
+
301
+ let identities_owned: HashMap < ValidatorId , u8 > = self
302
+ . client
303
+ . get ( & relay_url)
304
+ . send ( )
305
+ . and_then ( |res : Response | res. json ( ) )
306
+ . await
307
+ . map_err ( |_| map_error ( "Fetching privileges failed" ) ) ?;
308
+
309
+ let has_privileges = identities_owned
310
+ . get ( identity)
311
+ . map_or ( false , |privileges| * privileges > 0 ) ;
312
+
313
+ Ok ( has_privileges)
314
+ }
315
+ }
316
+
279
317
fn hash_message ( message : & str ) -> [ u8 ; 32 ] {
280
318
let eth = "\x19 Ethereum Signed Message:\n " ;
281
319
let message_length = message. len ( ) ;
@@ -301,12 +339,8 @@ pub struct Payload {
301
339
pub id : String ,
302
340
pub era : i64 ,
303
341
pub address : String ,
304
- #[ serde(
305
- default ,
306
- skip_serializing_if = "Option::is_none" ,
307
- with = "SerHexOpt::<StrictPfx>"
308
- ) ]
309
- pub identity : Option < [ u8 ; 20 ] > ,
342
+ #[ serde( default , skip_serializing_if = "Option::is_none" ) ]
343
+ pub identity : Option < ValidatorId > ,
310
344
}
311
345
312
346
#[ derive( Clone , Debug ) ]
@@ -377,7 +411,7 @@ pub fn ewt_verify(
377
411
let payload: Payload = serde_json:: from_str ( & payload_string) ?;
378
412
379
413
let verified_payload = VerifyPayload {
380
- from : ValidatorId :: try_from ( & format ! ( "{:?}" , address) ) ? ,
414
+ from : ValidatorId :: from ( address. as_fixed_bytes ( ) ) ,
381
415
payload,
382
416
} ;
383
417
@@ -482,6 +516,33 @@ mod test {
482
516
) ;
483
517
}
484
518
519
+ #[ tokio:: test]
520
+ #[ ignore]
521
+ async fn test_session_from_token ( ) {
522
+ use primitives:: ToETHChecksum ;
523
+ let identity = ValidatorId :: try_from ( "0x5B04DBc513F90CaAFAa09307Ad5e3C65EB4b26F0" ) . unwrap ( ) ;
524
+
525
+ let mut eth_adapter = setup_eth_adapter ( None ) ;
526
+ eth_adapter. unlock ( ) . expect ( "should unlock eth adapter" ) ;
527
+ let wallet = eth_adapter. wallet . clone ( ) ;
528
+
529
+ let era = Utc :: now ( ) . timestamp_millis ( ) as f64 / 60000.0 ;
530
+ let payload = Payload {
531
+ id : eth_adapter. whoami ( ) . to_checksum ( ) ,
532
+ era : era. floor ( ) as i64 ,
533
+ identity : Some ( identity. clone ( ) ) ,
534
+ address : eth_adapter. whoami ( ) . to_checksum ( ) ,
535
+ } ;
536
+
537
+ let token = ewt_sign ( & wallet. unwrap ( ) , & eth_adapter. keystore_pwd , & payload)
538
+ . map_err ( |_| map_error ( "Failed to sign token" ) )
539
+ . unwrap ( ) ;
540
+
541
+ let session: Session = eth_adapter. session_from_token ( & token) . await . unwrap ( ) ;
542
+
543
+ assert_eq ! ( session. uid, identity) ;
544
+ }
545
+
485
546
#[ tokio:: test]
486
547
async fn should_validate_valid_channel_properly ( ) {
487
548
let ( _eloop, http) =
@@ -604,13 +665,10 @@ mod test {
604
665
. await
605
666
. expect ( "open channel" ) ;
606
667
607
- let contract_addr = <[ u8 ; 20 ] >:: from_hex ( & format ! ( "{:?}" , adex_contract. address( ) ) [ 2 ..] )
608
- . expect ( "failed to deserialize contract addr" ) ;
609
-
668
+ let contract_addr = adex_contract. address ( ) . to_fixed_bytes ( ) ;
610
669
let channel_id = eth_channel. hash ( & contract_addr) . expect ( "hash hex" ) ;
611
670
// set id to proper id
612
- valid_channel. id = ChannelId :: from_hex ( hex:: encode ( channel_id) )
613
- . expect ( "prep_db: failed to deserialize channel id" ) ;
671
+ valid_channel. id = ChannelId :: from ( channel_id) ;
614
672
615
673
// eth adapter
616
674
let mut eth_adapter = setup_eth_adapter ( Some ( contract_addr) ) ;
@@ -623,68 +681,4 @@ mod test {
623
681
624
682
assert_eq ! ( result, true , "should validate valid channel correctly" ) ;
625
683
}
626
-
627
- #[ tokio:: test]
628
- async fn should_generate_session_from_token_with_identity ( ) {
629
- // setup test payload
630
- let mut eth_adapter = setup_eth_adapter ( None ) ;
631
- eth_adapter. unlock ( ) . expect ( "should unlock eth adapter" ) ;
632
-
633
- // part of address used in initializing ganache-cli
634
- let leader_account: Address = "Df08F82De32B8d460adbE8D72043E3a7e25A3B39"
635
- . parse ( )
636
- . expect ( "failed to parse leader account" ) ;
637
-
638
- let eth_adapter_address: Address = eth_adapter
639
- . whoami ( )
640
- . to_hex_non_prefix_string ( )
641
- . parse ( )
642
- . expect ( "failed to parse eth adapter address" ) ;
643
-
644
- let identity_bytecode = include_str ! ( "../test/resources/identitybytecode.json" ) ;
645
-
646
- // deploy identity contract
647
- let identity_contract = Contract :: deploy ( eth_adapter. web3 . eth ( ) , & IDENTITY_ABI )
648
- . expect ( "invalid token token contract" )
649
- . confirmations ( 0 )
650
- . options ( Options :: with ( |opt| {
651
- opt. gas_price = Some ( 1 . into ( ) ) ;
652
- opt. gas = Some ( 6_721_975 . into ( ) ) ;
653
- } ) )
654
- . execute (
655
- identity_bytecode,
656
- (
657
- Token :: Array ( vec ! [ Token :: Address ( eth_adapter_address) ] ) ,
658
- Token :: Array ( vec ! [ Token :: Uint ( 1 . into( ) ) ] ) ,
659
- ) ,
660
- leader_account,
661
- )
662
- . expect ( "Correct parameters are passed to the constructor." )
663
- . compat ( )
664
- . await
665
- . expect ( "failed to initialize identity contract" ) ;
666
-
667
- // identity contract address
668
- let identity = <[ u8 ; 20 ] >:: from_hex ( & format ! ( "{:?}" , identity_contract. address( ) ) [ 2 ..] )
669
- . expect ( "failed to deserialize address" ) ;
670
-
671
- let payload = Payload {
672
- id : eth_adapter. whoami ( ) . to_checksum ( ) ,
673
- era : 100_000 ,
674
- address : format ! ( "{:?}" , leader_account) ,
675
- identity : Some ( identity) ,
676
- } ;
677
-
678
- let wallet = eth_adapter. wallet . clone ( ) ;
679
- let response = ewt_sign ( & wallet. unwrap ( ) , & eth_adapter. keystore_pwd , & payload)
680
- . expect ( "failed to generate ewt signature" ) ;
681
-
682
- // verify since its with identity
683
- let session = eth_adapter
684
- . session_from_token ( & response)
685
- . await
686
- . expect ( "failed generate session" ) ;
687
-
688
- assert_eq ! ( session. uid. inner( ) , & identity) ;
689
- }
690
684
}
0 commit comments