Skip to content

Commit

Permalink
Rework wait_for_block_commits to use the retry crate
Browse files Browse the repository at this point in the history
  • Loading branch information
romac committed Jun 16, 2021
1 parent 041c78a commit 92df6b5
Showing 1 changed file with 41 additions and 33 deletions.
74 changes: 41 additions & 33 deletions relayer/src/chain/cosmos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,18 @@ const DEFAULT_MAX_MSG_NUM: usize = 30;
const DEFAULT_MAX_TX_SIZE: usize = 2 * 1048576; // 2 MBytes
const DEFAULT_GAS_FEE_AMOUNT: u64 = 1000;

const MAX_RETRIES: usize = 30;

// default gas adjustment percentage
const DEFAULT_GAS_ADJUSTMENT: u64 = 10;

mod retry_strategy {
use crate::util::retry::Fixed;
use std::time::Duration;

pub fn wait_for_block_commits() -> impl Iterator<Item = Duration> {
Fixed::from_millis(300).take(10)
}
}

pub struct CosmosSdkChain {
config: ChainConfig,
rpc_client: HttpClient,
Expand Down Expand Up @@ -426,60 +433,59 @@ impl CosmosSdkChain {
/// with the transaction hashes to get the list of IbcEvents included in those transactions.
pub fn wait_for_block_commits(
&self,
tx_sync_results: &mut Vec<TxSyncResult>,
) -> Result<(), Error> {
// events_per_tx[i] collects the events generated by the transaction from tx_sync_results[i]
let mut counter = 0;

// TODO - exp backoff is not good here, if anything we want to speed up the retries towards the end range
while counter < MAX_RETRIES {
thread::sleep(Duration::from_millis(200));
mut tx_sync_results: Vec<TxSyncResult>,
) -> Result<Vec<TxSyncResult>, Error> {
use crate::util::retry::{retry_with_index, RetryResult};

counter += 1;
// Wait a little bit initially
thread::sleep(Duration::from_millis(200));

let result = retry_with_index(retry_strategy::wait_for_block_commits(), |index| {
if all_tx_results_found(&tx_sync_results) {
trace!(
"retrieved {} tx results after {} tries",
tx_sync_results.len(),
counter
index
);

// All transactions confirmed
return Ok(());
return RetryResult::Ok(());
}

for TxSyncResult { response, events } in tx_sync_results.iter_mut() {
// If this transaction was not committed yet, let's figure out
// whether it was because it failed or because it hasn't been committed yet.
if empty_event_present(&events) {
// try to resolve transaction hash
let events_per_tx = if response.code.value() != 0 {
vec![IbcEvent::ChainError(format!(
// If the transaction failed, replace the events with an error,
// so that we don't attempt to resolve the transaction later on.
if response.code.value() != 0 {
*events = vec![IbcEvent::ChainError(format!(
"code {:?}, log {}",
response.code, response.log
))]
))];

// Otherwise, try to resolve transaction hash to the corresponding events.
} else if let Ok(events_per_tx) =
self.query_txs(QueryTxRequest::Transaction(QueryTxHash(response.hash)))
{
if events_per_tx.is_empty() {
events.clone()
} else {
events_per_tx
// If we get events back, progress was made, so we replace the events
// with the new ones. in both cases we will check in the next iteration
// whether or not the transaction was fully committed.
if !events_per_tx.is_empty() {
*events = events_per_tx;
}
} else {
events.clone()
};

*events = events_per_tx;
}
}
}

thread::sleep(Duration::from_millis(300));
}
RetryResult::Retry(index)
});

if all_tx_results_found(&tx_sync_results) {
match result {
// All transactions confirmed
Ok(())
} else {
Err(Kind::TxNoConfirmation.into())
Ok(()) => Ok(tx_sync_results),
// Did not find confirmation
Err(_) => Err(Kind::TxNoConfirmation.into()),
}
}
}
Expand Down Expand Up @@ -608,12 +614,14 @@ impl Chain for CosmosSdkChain {
});
}

self.wait_for_block_commits(&mut tx_sync_results)?;
let tx_sync_results = self.wait_for_block_commits(tx_sync_results)?;

let events = tx_sync_results
.into_iter()
.map(|el| el.events)
.flatten()
.collect();

Ok(events)
}

Expand Down

0 comments on commit 92df6b5

Please sign in to comment.