1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
use crate::Error as AdapterError;
use primitives::{
address::Error as AddressError, big_num::ParseBigIntError, ChainId, ChannelId, ValidatorId,
};
use thiserror::Error;
use super::ewt::Payload;
impl From<Error> for AdapterError {
fn from(error: Error) -> Self {
match error {
err @ Error::Keystore(..) => AdapterError::adapter(err),
Error::WalletUnlock(err) => AdapterError::wallet_unlock(err),
err @ Error::Web3(..) => AdapterError::adapter(err),
err @ Error::InvalidChannelId { .. } => AdapterError::adapter(err),
err @ Error::ChannelInactive(..) => AdapterError::adapter(err),
err @ Error::ChainNotWhitelisted(..) => AdapterError::adapter(err),
err @ Error::InvalidDepositAsset(..) => AdapterError::adapter(err),
err @ Error::BigNumParsing(..) => AdapterError::adapter(err),
err @ Error::SignMessage(..) => AdapterError::adapter(err),
err @ Error::VerifyMessage(..) => AdapterError::adapter(err),
err @ Error::ContractInitialization(..) => AdapterError::adapter(err),
err @ Error::ContractQuerying(..) => AdapterError::adapter(err),
err @ Error::VerifyAddress(..) => AdapterError::adapter(err),
err @ Error::AuthenticationTokenNotIntendedForUs { .. } => {
AdapterError::authentication(err)
}
err @ Error::InsufficientAuthorizationPrivilege { .. } => {
AdapterError::authorization(err)
}
}
}
}
#[derive(Debug, Error)]
pub enum Error {
#[error("Keystore: {0}")]
Keystore(#[from] KeystoreError),
#[error("Wallet unlocking: {0}")]
WalletUnlock(#[from] ethsign::Error),
#[error("Web3: {0}")]
Web3(#[from] web3::Error),
#[error("The hashed EthereumChannel.id ({expected}) is not the same as the Channel.id ({actual}) that was provided")]
InvalidChannelId {
expected: ChannelId,
actual: ChannelId,
},
#[error("Channel ({0}) is not Active on the ethereum network")]
ChannelInactive(ChannelId),
#[error("Signing message: {0}")]
SignMessage(#[from] EwtSigningError),
#[error("Verifying message: {0}")]
VerifyMessage(#[from] EwtVerifyError),
#[error("Contract initialization: {0}")]
ContractInitialization(web3::ethabi::Error),
#[error("Contract querying: {0}")]
ContractQuerying(web3::contract::Error),
#[error("Verifying address: {0}")]
VerifyAddress(#[from] VerifyError),
#[error("The intended {0:?} in the authentication token in not whitelisted")]
ChainNotWhitelisted(ChainId),
#[error("Deposit asset {0} is invalid")]
InvalidDepositAsset(#[from] AddressError),
#[error("Parsing BigNum: {0}")]
BigNumParsing(#[from] ParseBigIntError),
#[error("Token Payload.id({}) !== whoami({whoami}): token was not intended for us", .payload.id)]
AuthenticationTokenNotIntendedForUs {
payload: Payload,
whoami: ValidatorId,
},
#[error("Insufficient privilege")]
InsufficientAuthorizationPrivilege,
}
#[derive(Debug, Error)]
pub enum VerifyError {
#[error("Recovering the public key from the signature: {0}")]
PublicKeyRecovery(String),
#[error("Decoding state root: {0}")]
StateRootDecoding(#[source] hex::FromHexError),
#[error("Decoding signature: {0}")]
SignatureDecoding(#[source] hex::FromHexError),
#[error("Signature is not prefixed with `0x`")]
SignatureNotPrefixed,
#[error("Signature length or V component of the Signature was incorrect")]
SignatureInvalid,
}
#[derive(Debug, Error)]
pub enum KeystoreError {
#[error("\"address\" key missing in keystore file")]
AddressMissing,
#[error("\"address\" length should be 20 bytes")]
AddressLength,
#[error("Reading keystore file: {0}")]
ReadingFile(#[source] std::io::Error),
#[error("Deserializing keystore file: {0}")]
Deserialization(#[source] serde_json::Error),
}
#[derive(Debug, Error)]
pub enum EwtSigningError {
#[error("Header serialization: {0}")]
HeaderSerialization(#[source] serde_json::Error),
#[error("Payload serialization: {0}")]
PayloadSerialization(#[source] serde_json::Error),
#[error("Signing message: {0}")]
SigningMessage(String),
#[error("Decoding hex of Signature: {0}")]
DecodingHexSignature(#[from] hex::FromHexError),
}
#[derive(Debug, Error)]
pub enum EwtVerifyError {
#[error("The Ethereum Web Token header is invalid")]
InvalidHeader,
#[error("The token length should be at least 16 characters of length")]
InvalidTokenLength,
#[error("The token does not comply to the format of header.payload.signature")]
InvalidToken,
#[error("Address recovery: {0}")]
AddressRecovery(String),
#[error("Signature decoding: {0}")]
SignatureDecoding(#[source] base64::DecodeError),
#[error("Error when decoding token signature")]
InvalidSignature,
#[error("Payload decoding: {0}")]
PayloadDecoding(#[source] base64::DecodeError),
#[error("Payload deserialization: {0}")]
PayloadDeserialization(#[from] serde_json::Error),
#[error("Payload is not a valid UTF-8 string: {0}")]
PayloadUtf8(#[from] std::str::Utf8Error),
}
#[cfg(test)]
mod test {
use super::*;
fn assert_send<T: Send>() {}
fn assert_sync<T: Sync>() {}
#[test]
fn a_correct_error() {
assert_send::<Error>();
assert_sync::<Error>();
}
}