@@ -36,7 +36,6 @@ lazy_static! {
36
36
static ref ADEXCORE_ABI : & ' static [ u8 ] =
37
37
include_bytes!( "../../lib/protocol-eth/abi/AdExCore.json" ) ;
38
38
static ref CHANNEL_STATE_ACTIVE : U256 = 1 . into( ) ;
39
- static ref PRIVILEGE_LEVEL_NONE : u8 = 0 ;
40
39
}
41
40
42
41
#[ derive( Debug , Clone ) ]
@@ -57,19 +56,18 @@ impl ChannelValidator for EthereumAdapter {}
57
56
58
57
impl EthereumAdapter {
59
58
pub fn init ( opts : KeystoreOptions , config : & Config ) -> AdapterResult < EthereumAdapter , Error > {
60
- let keystore_contents = fs :: read_to_string ( & opts . keystore_file )
61
- . map_err ( |err| Error :: Keystore ( KeystoreError :: ReadingFile ( err ) ) ) ?;
59
+ let keystore_contents =
60
+ fs :: read_to_string ( & opts . keystore_file ) . map_err ( KeystoreError :: ReadingFile ) ?;
62
61
63
- let keystore_json: Value = serde_json :: from_str ( & keystore_contents )
64
- . map_err ( |err| Error :: Keystore ( KeystoreError :: Deserialization ( err ) ) ) ?;
62
+ let keystore_json: Value =
63
+ serde_json :: from_str ( & keystore_contents ) . map_err ( KeystoreError :: Deserialization ) ?;
65
64
66
65
let address = keystore_json[ "address" ]
67
66
. as_str ( )
68
67
. map ( eth_checksum:: checksum)
69
- . ok_or_else ( || Error :: Keystore ( KeystoreError :: AddressMissing ) ) ?;
68
+ . ok_or_else ( || KeystoreError :: AddressMissing ) ?;
70
69
71
- let address = ValidatorId :: try_from ( & address)
72
- . map_err ( |err| Error :: Keystore ( KeystoreError :: AddressInvalid ( err) ) ) ?;
70
+ let address = ValidatorId :: try_from ( & address) . map_err ( KeystoreError :: AddressInvalid ) ?;
73
71
74
72
let ( eloop, transport) =
75
73
web3:: transports:: Http :: new ( & config. ethereum_network ) . map_err ( Error :: Web3 ) ?;
@@ -97,7 +95,7 @@ impl Adapter for EthereumAdapter {
97
95
fn unlock ( & mut self ) -> AdapterResult < ( ) , Self :: AdapterError > {
98
96
let account = SafeAccount :: from_file (
99
97
serde_json:: from_value ( self . keystore_json . clone ( ) )
100
- . map_err ( |err| Error :: Keystore ( KeystoreError :: Deserialization ( err ) ) ) ?,
98
+ . map_err ( KeystoreError :: Deserialization ) ?,
101
99
None ,
102
100
& Some ( self . keystore_pwd . clone ( ) ) ,
103
101
)
@@ -114,12 +112,12 @@ impl Adapter for EthereumAdapter {
114
112
115
113
fn sign ( & self , state_root : & str ) -> AdapterResult < String , Self :: AdapterError > {
116
114
if let Some ( wallet) = & self . wallet {
117
- let state_root = hex :: decode ( state_root )
118
- . map_err ( |_| AdapterError :: Signature ( "invalid state_root" . to_string ( ) ) ) ?;
115
+ let state_root =
116
+ hex :: decode ( state_root) . map_err ( StateRootError :: StateRootHexDecoding ) ?;
119
117
let message = Message :: from_slice ( & hash_message ( & state_root) ) ;
120
118
let wallet_sign = wallet
121
119
. sign ( & self . keystore_pwd , & message)
122
- . map_err ( |err| Error :: SignMessage ( EwtSigningError :: SigningMessage ( err ) ) ) ?;
120
+ . map_err ( EwtSigningError :: SigningMessage ) ?;
123
121
let signature: Signature = wallet_sign. into_electrum ( ) . into ( ) ;
124
122
125
123
Ok ( format ! ( "0x{}" , signature) )
@@ -135,17 +133,19 @@ impl Adapter for EthereumAdapter {
135
133
sig : & str ,
136
134
) -> AdapterResult < bool , Self :: AdapterError > {
137
135
if !sig. starts_with ( "0x" ) {
138
- return Err ( AdapterError :: Signature ( "not 0x prefixed hex" . to_string ( ) ) ) ;
136
+ return Err ( StateRootError :: SignatureNotPrefixed . into ( ) ) ;
139
137
}
140
- let decoded_signature = hex :: decode ( & sig [ 2 .. ] )
141
- . map_err ( |_| AdapterError :: Signature ( "invalid signature" . to_string ( ) ) ) ?;
138
+ let decoded_signature =
139
+ hex :: decode ( & sig [ 2 .. ] ) . map_err ( StateRootError :: SignatureHexDecoding ) ?;
142
140
let address = Address :: from_slice ( signer. inner ( ) ) ;
143
141
let signature = Signature :: from_electrum ( & decoded_signature) ;
144
- let state_root = hex:: decode ( state_root)
145
- . map_err ( |_| AdapterError :: Signature ( "invalid state_root" . to_string ( ) ) ) ?;
142
+ let state_root = hex:: decode ( state_root) . map_err ( StateRootError :: StateRootHexDecoding ) ?;
146
143
let message = Message :: from_slice ( & hash_message ( & state_root) ) ;
147
144
148
- verify_address ( & address, & signature, & message) . or_else ( |_| Ok ( false ) )
145
+ let verify_address = verify_address ( & address, & signature, & message)
146
+ . map_err ( StateRootError :: PublicKeyRecovery ) ?;
147
+
148
+ Ok ( verify_address)
149
149
}
150
150
151
151
fn validate_channel < ' a > (
@@ -173,19 +173,19 @@ impl Adapter for EthereumAdapter {
173
173
let contract_address: Address = self . config . ethereum_core_address . into ( ) ;
174
174
175
175
let contract = Contract :: from_json ( self . web3 . eth ( ) , contract_address, & ADEXCORE_ABI )
176
- . map_err ( |_| map_error ( "failed to init core contract" ) ) ?;
176
+ . map_err ( Error :: ContractInitialization ) ?;
177
177
178
178
let channel_status: U256 = contract
179
179
. query (
180
180
"states" ,
181
- ( Token :: FixedBytes ( channel. id . as_ref ( ) . to_vec ( ) ) , ) ,
181
+ Token :: FixedBytes ( channel. id . as_ref ( ) . to_vec ( ) ) ,
182
182
None ,
183
183
Options :: default ( ) ,
184
184
None ,
185
185
)
186
186
. compat ( )
187
187
. await
188
- . map_err ( |_| map_error ( "contract channel status query failed" ) ) ?;
188
+ . map_err ( Error :: ContractQuerying ) ?;
189
189
190
190
if channel_status != * CHANNEL_STATE_ACTIVE {
191
191
Err ( AdapterError :: Adapter ( Error :: ChannelInactive ( channel. id ) ) )
@@ -204,7 +204,9 @@ impl Adapter for EthereumAdapter {
204
204
) -> BoxFuture < ' a , AdapterResult < Session , Self :: AdapterError > > {
205
205
async move {
206
206
if token. len ( ) < 16 {
207
- return Err ( AdapterError :: Failed ( "invalid token id" . to_string ( ) ) ) ;
207
+ return Err ( AdapterError :: Authentication (
208
+ "Invalid token id length" . to_string ( ) ,
209
+ ) ) ;
208
210
}
209
211
210
212
let parts: Vec < & str > = token. split ( '.' ) . collect ( ) ;
@@ -214,18 +216,18 @@ impl Adapter for EthereumAdapter {
214
216
( header_encoded, payload_encoded, token_encoded)
215
217
}
216
218
_ => {
217
- return Err ( AdapterError :: Failed ( format ! (
219
+ return Err ( AdapterError :: Authentication ( format ! (
218
220
"{} token string is incorrect" ,
219
221
token
220
222
) ) )
221
223
}
222
224
} ;
223
225
224
226
let verified = ewt_verify ( header_encoded, payload_encoded, token_encoded)
225
- . map_err ( |err| AdapterError :: Adapter ( Error :: VerifyMessage ( err ) ) ) ?;
227
+ . map_err ( Error :: VerifyMessage ) ?;
226
228
227
229
if self . whoami ( ) . to_checksum ( ) != verified. payload . id {
228
- return Err ( AdapterError :: Configuration (
230
+ return Err ( AdapterError :: Authentication (
229
231
"token payload.id !== whoami(): token was not intended for us" . to_string ( ) ,
230
232
) ) ;
231
233
}
@@ -338,10 +340,6 @@ fn hash_message(message: &[u8]) -> [u8; 32] {
338
340
res
339
341
}
340
342
341
- fn map_error ( err : & str ) -> AdapterError < Error > {
342
- AdapterError :: Failed ( err. to_string ( ) )
343
- }
344
-
345
343
// Ethereum Web Tokens
346
344
#[ derive( Clone , Debug , Serialize , Deserialize ) ]
347
345
pub struct Payload {
@@ -434,49 +432,10 @@ pub fn ewt_verify(
434
432
}
435
433
436
434
mod error {
437
- use primitives:: adapter:: AdapterErrorKind ;
435
+ use primitives:: adapter:: { AdapterErrorKind , Error as AdapterError } ;
438
436
use primitives:: ChannelId ;
439
437
use std:: fmt;
440
438
441
- #[ derive( Debug ) ]
442
- pub enum KeystoreError {
443
- /// `address` key is missing from the keystore file
444
- AddressMissing ,
445
- /// The `address` key in the keystore file is not a valid `ValidatorId`
446
- AddressInvalid ( primitives:: DomainError ) ,
447
- /// reading the keystore file failed
448
- ReadingFile ( std:: io:: Error ) ,
449
- /// Deserializing the keystore file failed
450
- Deserialization ( serde_json:: Error ) ,
451
- }
452
-
453
- impl std:: error:: Error for KeystoreError {
454
- fn source ( & self ) -> Option < & ( dyn std:: error:: Error + ' static ) > {
455
- use KeystoreError :: * ;
456
- match self {
457
- AddressMissing => None ,
458
- AddressInvalid ( err) => Some ( err) ,
459
- ReadingFile ( err) => Some ( err) ,
460
- Deserialization ( err) => Some ( err) ,
461
- }
462
- }
463
- }
464
-
465
- impl fmt:: Display for KeystoreError {
466
- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
467
- use KeystoreError :: * ;
468
-
469
- match self {
470
- AddressMissing => write ! ( f, "\" address\" key missing in keystore file" ) ,
471
- AddressInvalid ( err) => write ! ( f, "\" address\" is invalid: {}" , err) ,
472
- ReadingFile ( err) => write ! ( f, "Reading the keystore file failed: {}" , err) ,
473
- Deserialization ( err) => {
474
- write ! ( f, "Deserializing the keystore file failed: {}" , err)
475
- }
476
- }
477
- }
478
- }
479
-
480
439
#[ derive( Debug ) ]
481
440
pub enum Error {
482
441
Keystore ( KeystoreError ) ,
@@ -493,6 +452,9 @@ mod error {
493
452
/// Signing of the message failed
494
453
SignMessage ( EwtSigningError ) ,
495
454
VerifyMessage ( EwtVerifyError ) ,
455
+ ContractInitialization ( ethabi:: Error ) ,
456
+ ContractQuerying ( web3:: contract:: Error ) ,
457
+ StateRoot ( StateRootError ) ,
496
458
}
497
459
498
460
impl std:: error:: Error for Error { }
@@ -512,10 +474,89 @@ mod error {
512
474
ChannelInactive ( channel_id) => write ! ( f, "Channel ({}) is not Active on the ethereum network" , channel_id) ,
513
475
SignMessage ( err) => write ! ( f, "Signing message - {}" , err) ,
514
476
VerifyMessage ( err) => write ! ( f, "Verifying message - {}" , err) ,
477
+ ContractInitialization ( err) => write ! ( f, "Contract initialization - {}" , err) ,
478
+ ContractQuerying ( err) => write ! ( f, "Contract querying - {}" , err) ,
479
+ StateRoot ( err) => write ! ( f, "State root - {}" , err)
480
+ }
481
+ }
482
+ }
483
+
484
+ #[ derive( Debug ) ]
485
+ pub enum StateRootError {
486
+ PublicKeyRecovery ( parity_crypto:: publickey:: Error ) ,
487
+ StateRootHexDecoding ( hex:: FromHexError ) ,
488
+ SignatureHexDecoding ( hex:: FromHexError ) ,
489
+ SignatureNotPrefixed ,
490
+ }
491
+
492
+ impl fmt:: Display for StateRootError {
493
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
494
+ use StateRootError :: * ;
495
+
496
+ match self {
497
+ PublicKeyRecovery ( err) => {
498
+ write ! ( f, "Recovering the public key from the signature - {}" , err)
499
+ }
500
+ StateRootHexDecoding ( err) => {
501
+ write ! ( f, "Decoding the hex of the state root - {}" , err)
502
+ }
503
+ SignatureHexDecoding ( err) => {
504
+ write ! ( f, "Decoding the hex of the signature - {}" , err)
505
+ }
506
+ SignatureNotPrefixed => write ! ( f, "Signature is not prefixed with `0x`" ) ,
515
507
}
516
508
}
517
509
}
518
510
511
+ impl From < StateRootError > for AdapterError < Error > {
512
+ fn from ( err : StateRootError ) -> Self {
513
+ AdapterError :: Adapter ( Error :: StateRoot ( err) )
514
+ }
515
+ }
516
+
517
+ #[ derive( Debug ) ]
518
+ pub enum KeystoreError {
519
+ /// `address` key is missing from the keystore file
520
+ AddressMissing ,
521
+ /// The `address` key in the keystore file is not a valid `ValidatorId`
522
+ AddressInvalid ( primitives:: DomainError ) ,
523
+ /// reading the keystore file failed
524
+ ReadingFile ( std:: io:: Error ) ,
525
+ /// Deserializing the keystore file failed
526
+ Deserialization ( serde_json:: Error ) ,
527
+ }
528
+
529
+ impl std:: error:: Error for KeystoreError {
530
+ fn source ( & self ) -> Option < & ( dyn std:: error:: Error + ' static ) > {
531
+ use KeystoreError :: * ;
532
+ match self {
533
+ AddressMissing => None ,
534
+ AddressInvalid ( err) => Some ( err) ,
535
+ ReadingFile ( err) => Some ( err) ,
536
+ Deserialization ( err) => Some ( err) ,
537
+ }
538
+ }
539
+ }
540
+
541
+ impl fmt:: Display for KeystoreError {
542
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
543
+ use KeystoreError :: * ;
544
+
545
+ match self {
546
+ AddressMissing => write ! ( f, "\" address\" key missing in keystore file" ) ,
547
+ AddressInvalid ( err) => write ! ( f, "\" address\" is invalid - {}" , err) ,
548
+ ReadingFile ( err) => write ! ( f, "Reading keystore file - {}" , err) ,
549
+ Deserialization ( err) => write ! ( f, "Deserializing keystore file - {}" , err) ,
550
+ }
551
+ }
552
+ }
553
+
554
+ impl From < KeystoreError > for AdapterError < Error > {
555
+ fn from ( err : KeystoreError ) -> Self {
556
+ AdapterError :: Adapter ( Error :: Keystore ( err) )
557
+ }
558
+ }
559
+
519
560
#[ derive( Debug ) ]
520
561
pub enum EwtSigningError {
521
562
HeaderSerialization ( serde_json:: Error ) ,
@@ -531,11 +572,16 @@ mod error {
531
572
match self {
532
573
HeaderSerialization ( err) => write ! ( f, "Header serialization - {}" , err) ,
533
574
PayloadSerialization ( err) => write ! ( f, "Payload serialization - {}" , err) ,
534
- SigningMessage ( err) => write ! ( f, "{}" , err) ,
575
+ SigningMessage ( err) => write ! ( f, "Signing message - {}" , err) ,
535
576
DecodingHexSignature ( err) => write ! ( f, "Decoding hex of Signature - {}" , err) ,
536
577
}
537
578
}
538
579
}
580
+ impl From < EwtSigningError > for AdapterError < Error > {
581
+ fn from ( err : EwtSigningError ) -> Self {
582
+ AdapterError :: Adapter ( Error :: SignMessage ( err) )
583
+ }
584
+ }
539
585
540
586
#[ derive( Debug ) ]
541
587
pub enum EwtVerifyError {
@@ -638,7 +684,8 @@ mod test {
638
684
)
639
685
. expect ( "Failed to verify signatures" ) ;
640
686
641
- assert ! ( verify, "invalid signature verification" ) ;
687
+ assert ! ( verify, "invalid signature 1 verification" ) ;
688
+ assert ! ( verify2, "invalid signature 2 verification" ) ;
642
689
}
643
690
644
691
#[ test]
@@ -689,9 +736,7 @@ mod test {
689
736
address : eth_adapter. whoami ( ) . to_checksum ( ) ,
690
737
} ;
691
738
692
- let token = ewt_sign ( & wallet. unwrap ( ) , & eth_adapter. keystore_pwd , & payload)
693
- . map_err ( |_| map_error ( "Failed to sign token" ) )
694
- . unwrap ( ) ;
739
+ let token = ewt_sign ( & wallet. unwrap ( ) , & eth_adapter. keystore_pwd , & payload) . unwrap ( ) ;
695
740
696
741
let session: Session = eth_adapter. session_from_token ( & token) . await . unwrap ( ) ;
697
742
0 commit comments