2017-08-13 04:09:50 -07:00
|
|
|
#![allow(unknown_lints)]
|
|
|
|
|
|
|
|
use std::io;
|
2017-08-31 08:32:34 -07:00
|
|
|
use tokio_timer::{TimerError, TimeoutError};
|
2017-10-01 10:16:44 -07:00
|
|
|
use {web3, toml, ethabi, rustc_hex};
|
2018-04-25 03:12:39 -07:00
|
|
|
use ethcore::ethstore;
|
2018-04-26 17:38:39 -07:00
|
|
|
use ethcore::account_provider::{SignError, Error as AccountError};
|
2018-05-23 17:42:13 -07:00
|
|
|
use serde_json;
|
|
|
|
use hyper;
|
2017-06-25 04:21:13 -07:00
|
|
|
|
2017-08-02 03:45:15 -07:00
|
|
|
error_chain! {
|
|
|
|
types {
|
|
|
|
Error, ErrorKind, ResultExt, Result;
|
2017-06-25 04:21:13 -07:00
|
|
|
}
|
|
|
|
|
2017-08-02 03:45:15 -07:00
|
|
|
foreign_links {
|
|
|
|
Io(io::Error);
|
|
|
|
Toml(toml::de::Error);
|
2017-08-10 08:55:46 -07:00
|
|
|
Ethabi(ethabi::Error);
|
2017-08-12 01:55:18 -07:00
|
|
|
Timer(TimerError);
|
2017-10-01 10:16:44 -07:00
|
|
|
Hex(rustc_hex::FromHexError);
|
2018-05-23 17:42:13 -07:00
|
|
|
Json(serde_json::Error);
|
|
|
|
Hyper(hyper::Error);
|
2017-06-25 04:21:13 -07:00
|
|
|
}
|
2017-08-01 02:36:48 -07:00
|
|
|
|
2017-08-02 03:45:15 -07:00
|
|
|
errors {
|
2018-03-15 07:10:53 -07:00
|
|
|
ShutdownRequested
|
2018-04-03 23:42:16 -07:00
|
|
|
InsufficientFunds
|
2018-05-19 08:25:39 -07:00
|
|
|
NoRequiredSignaturesChanged {
|
|
|
|
description("No RequiredSignaturesChanged has been observed")
|
|
|
|
}
|
2017-08-31 08:32:34 -07:00
|
|
|
// api timeout
|
|
|
|
Timeout(request: &'static str) {
|
|
|
|
description("Request timeout"),
|
|
|
|
display("Request {} timed out", request),
|
|
|
|
}
|
2017-08-04 08:57:09 -07:00
|
|
|
// workaround for error_chain not allowing to check internal error kind
|
|
|
|
// https://github.com/rust-lang-nursery/error-chain/issues/206
|
|
|
|
MissingFile(filename: String) {
|
|
|
|
description("File not found"),
|
|
|
|
display("File {} not found", filename),
|
|
|
|
}
|
2017-08-02 03:45:15 -07:00
|
|
|
// workaround for lack of web3:Error Display and Error implementations
|
|
|
|
Web3(err: web3::Error) {
|
2017-08-04 08:57:09 -07:00
|
|
|
description("web3 error"),
|
|
|
|
display("{:?}", err),
|
2017-08-02 03:45:15 -07:00
|
|
|
}
|
2018-04-25 03:12:39 -07:00
|
|
|
KeyStore(err: ethstore::Error) {
|
|
|
|
description("keystore error"),
|
|
|
|
display("keystore error {:?}", err),
|
|
|
|
}
|
2018-04-26 17:38:39 -07:00
|
|
|
SignError(err: SignError) {
|
|
|
|
description("signing error")
|
|
|
|
display("signing error {:?}", err),
|
|
|
|
}
|
|
|
|
AccountError(err: AccountError) {
|
|
|
|
description("account error")
|
|
|
|
display("account error {:?}", err),
|
|
|
|
}
|
2018-05-07 16:34:03 -07:00
|
|
|
ContextualizedError(err: Box<Error>, context: &'static str) {
|
|
|
|
description("contextualized error")
|
|
|
|
display("{:?} in {}", err, context)
|
|
|
|
}
|
2018-05-28 10:00:39 -07:00
|
|
|
OtherError(error: String) {
|
|
|
|
description("other error")
|
|
|
|
display("{}", error)
|
2018-05-23 23:03:20 -07:00
|
|
|
}
|
|
|
|
ConfigError(err: String) {
|
|
|
|
description("config error")
|
|
|
|
display("{}", err)
|
2018-05-28 10:00:39 -07:00
|
|
|
}
|
2017-08-01 02:36:48 -07:00
|
|
|
}
|
|
|
|
}
|
2017-08-31 08:32:34 -07:00
|
|
|
|
Problem: nonce reuse
Unfortunately, bridge will still reuse nonce very often.
Specifically when trying to send more than one transaction at
a time, clearly a faulty behaviour.
Solution: chain retrieving a nonce with subsequent sending
of the transaction.
However, chaining these is not enough as it'll still fail.
This is happening because bridge module is polling all its components
(deposit_relay, withdraw_confirm, withdraw_relay) sequentially,
and some of them maybe waiting on their transactions to go through.
However, those transactions are also done as composed futures of nonce
retrieval and transaction sending. This means that it is very often
that first, these futures will go through the nonce acquisition process,
get the same values, and then submit transactions with the same nonce.
This patch makes NonceCheck future check if the transaction failed
with this specific issue of nonce reuse and effectively restarts from
the beginning in that case, repeating nonce acquisition process... until
it succeeeds.
2018-04-29 13:20:42 -07:00
|
|
|
impl<T> From<TimeoutError<T>> for Error {
|
|
|
|
fn from(err: TimeoutError<T>) -> Self {
|
2017-08-31 08:32:34 -07:00
|
|
|
match err {
|
Problem: nonce reuse
Unfortunately, bridge will still reuse nonce very often.
Specifically when trying to send more than one transaction at
a time, clearly a faulty behaviour.
Solution: chain retrieving a nonce with subsequent sending
of the transaction.
However, chaining these is not enough as it'll still fail.
This is happening because bridge module is polling all its components
(deposit_relay, withdraw_confirm, withdraw_relay) sequentially,
and some of them maybe waiting on their transactions to go through.
However, those transactions are also done as composed futures of nonce
retrieval and transaction sending. This means that it is very often
that first, these futures will go through the nonce acquisition process,
get the same values, and then submit transactions with the same nonce.
This patch makes NonceCheck future check if the transaction failed
with this specific issue of nonce reuse and effectively restarts from
the beginning in that case, repeating nonce acquisition process... until
it succeeeds.
2018-04-29 13:20:42 -07:00
|
|
|
TimeoutError::Timer(_call, _) | TimeoutError::TimedOut(_call) => {
|
|
|
|
ErrorKind::Timeout("communication timeout").into()
|
2017-08-31 08:32:34 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
Problem: nonce reuse
Unfortunately, bridge will still reuse nonce very often.
Specifically when trying to send more than one transaction at
a time, clearly a faulty behaviour.
Solution: chain retrieving a nonce with subsequent sending
of the transaction.
However, chaining these is not enough as it'll still fail.
This is happening because bridge module is polling all its components
(deposit_relay, withdraw_confirm, withdraw_relay) sequentially,
and some of them maybe waiting on their transactions to go through.
However, those transactions are also done as composed futures of nonce
retrieval and transaction sending. This means that it is very often
that first, these futures will go through the nonce acquisition process,
get the same values, and then submit transactions with the same nonce.
This patch makes NonceCheck future check if the transaction failed
with this specific issue of nonce reuse and effectively restarts from
the beginning in that case, repeating nonce acquisition process... until
it succeeeds.
2018-04-29 13:20:42 -07:00
|
|
|
|