Change wallet retry strategy (and address stratum panic) (#1004)

* remove complex retry from wallet client

* remove complex retry from wallet client

* move retry code to stratum
This commit is contained in:
Yeastplume 2018-04-25 16:48:19 +01:00 committed by GitHub
parent 8227ce941a
commit 820d55a532
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 14 additions and 31 deletions

View file

@ -86,6 +86,7 @@ pub fn get_block(
max_tx: u32, max_tx: u32,
wallet_listener_url: Option<String>, wallet_listener_url: Option<String>,
) -> (core::Block, BlockFees) { ) -> (core::Block, BlockFees) {
let wallet_retry_interval = 5;
// get the latest chain state and build a block on top of it // get the latest chain state and build a block on top of it
let mut result = build_block( let mut result = build_block(
chain, chain,
@ -102,6 +103,14 @@ pub fn get_block(
"Duplicate commit for potential coinbase detected. Trying next derivation." "Duplicate commit for potential coinbase detected. Trying next derivation."
); );
} }
self::Error::Wallet(_) => {
error!(
LOGGER,
"Stratum server: Can't connect to wallet listener at {:?}; will retry",
wallet_listener_url.as_ref().unwrap()
);
thread::sleep(Duration::from_secs(wallet_retry_interval));
}
ae => { ae => {
warn!(LOGGER, "Error building new block: {:?}. Retrying.", ae); warn!(LOGGER, "Error building new block: {:?}. Retrying.", ae);
} }
@ -227,7 +236,6 @@ fn get_coinbase(
let url = format!("{}/v1/receive/coinbase", wallet_listener_url.as_str()); let url = format!("{}/v1/receive/coinbase", wallet_listener_url.as_str());
let res = wallet::client::create_coinbase(&url, &block_fees)?; let res = wallet::client::create_coinbase(&url, &block_fees)?;
let out_bin = util::from_hex(res.output).unwrap(); let out_bin = util::from_hex(res.output).unwrap();
let kern_bin = util::from_hex(res.kernel).unwrap(); let kern_bin = util::from_hex(res.kernel).unwrap();
let key_id_bin = util::from_hex(res.key_id).unwrap(); let key_id_bin = util::from_hex(res.key_id).unwrap();

View file

@ -12,17 +12,12 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
use std::time;
use std::ops::FnMut;
use futures::{Future, Stream}; use futures::{Future, Stream};
use failure::ResultExt; use failure::ResultExt;
use hyper; use hyper;
use hyper::{Method, Request}; use hyper::{Method, Request};
use hyper::header::ContentType; use hyper::header::ContentType;
use tokio_core::reactor; use tokio_core::reactor;
use tokio_retry::Retry;
use tokio_retry::strategy::FibonacciBackoff;
use serde_json; use serde_json;
use types::*; use types::*;
@ -32,36 +27,16 @@ use std::io;
/// Call the wallet API to create a coinbase output for the given block_fees. /// Call the wallet API to create a coinbase output for the given block_fees.
/// Will retry based on default "retry forever with backoff" behavior. /// Will retry based on default "retry forever with backoff" behavior.
pub fn create_coinbase(url: &str, block_fees: &BlockFees) -> Result<CbData, Error> { pub fn create_coinbase(url: &str, block_fees: &BlockFees) -> Result<CbData, Error> {
let mut has_error = false; match single_create_coinbase(&url, &block_fees) {
Err(e) => {
retry_backoff_forever(|| {
let res = single_create_coinbase(&url, &block_fees);
if let Err(_) = res {
has_error = true;
error!( error!(
LOGGER, LOGGER,
"Failed to get coinbase from {}. Run grin wallet listen", url "Failed to get coinbase from {}. Run grin wallet listen", url
); );
Err(e)
} }
if has_error { Ok(res) => Ok(res),
error!(LOGGER, "Successfully received coinbase from {}", url);
} }
res
})
}
/// Runs the specified function wrapped in some basic retry logic.
fn retry_backoff_forever<F, R>(f: F) -> Result<R, Error>
where
F: FnMut() -> Result<R, Error>,
{
let mut core =
reactor::Core::new().context(ErrorKind::GenericError("Could not create reactor"))?;
let retry_strategy =
FibonacciBackoff::from_millis(100).max_delay(time::Duration::from_secs(10));
let retry_future = Retry::spawn(core.handle(), retry_strategy, f);
let res = core.run(retry_future).unwrap();
Ok(res)
} }
pub fn send_partial_tx(url: &str, partial_tx: &PartialTx, fluff: bool) -> Result<PartialTx, Error> { pub fn send_partial_tx(url: &str, partial_tx: &PartialTx, fluff: bool) -> Result<PartialTx, Error> {