Skip to content

Commit b7514c1

Browse files
feat: change query tx status loop (#2034)
1 parent 536b30b commit b7514c1

File tree

7 files changed

+71
-17
lines changed

7 files changed

+71
-17
lines changed

apps/namadillo/src/App/Common/Toast.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,9 @@ const Toast = ({ notification, onClose }: ToastProps): JSX.Element => {
129129
)}
130130
{notification.details &&
131131
(viewDetails || notification.type === "error") && (
132-
<div className="w-full text-xs text-white block">
132+
<div className="w-full text-xs text-white block whitespace-pre-wrap">
133+
{/* We "prefix" the error message with a line break to make it more visible */}
134+
{notification.type === "error" && <br />}
133135
{notification.details}
134136
</div>
135137
)}

apps/namadillo/src/utils/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,10 @@ export const toErrorDetail = (
141141
// TODO: Over time we may expand this to format errors for more result codes
142142
switch (code) {
143143
case ResultCode.TxGasLimit:
144-
return `${error.toString()} ${toGasMsg(args.gasLimit)}`;
144+
return `${error.toString()}.\n${toGasMsg(args.gasLimit)}`;
145145
case ResultCode.WasmRuntimeError:
146146
// We can only check error type by reading the error message
147-
return error.toString() + ` ${textToErrorDetail(info, tx[0])}`;
147+
return `${error.toString()}.\n${textToErrorDetail(info, tx[0])}`;
148148

149149
default:
150150
return error.toString() + ` ${info}`;

packages/shared/lib/src/sdk/io.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,9 @@ fn read(question: Option<&str>) -> std::io::Result<String> {
99
.prompt_with_message(question)
1010
.expect("Prompt to be defined");
1111

12-
input.ok_or(std::io::Error::new(
13-
std::io::ErrorKind::Other,
14-
"Input is null",
15-
))
12+
input.ok_or(std::io::Error::other("Input is null"))
1613
}
17-
None => Err(std::io::Error::new(std::io::ErrorKind::Other, "No window")),
14+
None => Err(std::io::Error::other("No window")),
1815
}
1916
}
2017

packages/shared/lib/src/sdk/masp/masp_web.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ impl WebShieldedUtils {
7777
}
7878

7979
fn to_io_err(e: Error) -> std::io::Error {
80-
std::io::Error::new(std::io::ErrorKind::Other, e.to_string())
80+
std::io::Error::other(e.to_string())
8181
}
8282

8383
pub async fn build_database(chain_id: &str) -> Result<Rexie, Error> {

packages/shared/lib/src/sdk/mod.rs

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use namada_sdk::masp::ShieldedContext;
3434
use namada_sdk::masp_primitives::sapling::ViewingKey;
3535
use namada_sdk::masp_primitives::transaction::components::amount::I128Sum;
3636
use namada_sdk::masp_primitives::zip32::{ExtendedFullViewingKey, ExtendedKey};
37-
use namada_sdk::rpc::{self, query_denom, query_epoch, InnerTxResult, TxResponse};
37+
use namada_sdk::rpc::{self, query_denom, query_epoch, InnerTxResult, TxAppliedEvents, TxResponse};
3838
use namada_sdk::signing::SigningTxData;
3939
use namada_sdk::string_encoding::Format;
4040
use namada_sdk::tendermint_rpc::Url;
@@ -337,6 +337,48 @@ impl Sdk {
337337
to_js_result(borsh::to_vec(&namada_tx)?)
338338
}
339339

340+
// We query tx evcents in loop here as control flow in namada_sdk does not seem to work well in
341+
// browsers
342+
async fn query_tx_result(
343+
&self,
344+
deadline: u64,
345+
tx_hash: &str,
346+
) -> Result<TxAppliedEvents, JsValue> {
347+
let mut backoff = 0;
348+
let deadline = time::Instant::now() + time::Duration::from_secs(deadline);
349+
let tx_query = rpc::TxEventQuery::Applied(tx_hash);
350+
351+
let event = loop {
352+
// We do linear backoff here to avoid hammering the RPC server
353+
backoff += 1000;
354+
355+
if time::Instant::now() >= deadline {
356+
break Err(JsValue::from("Timed out waiting for tx to be applied"));
357+
}
358+
let res = rpc::query_tx_events(self.namada.client(), tx_query).await;
359+
360+
let maybe_response = match res {
361+
Ok(response) => response,
362+
Err(_) => {
363+
crate::utils::sleep(backoff).await;
364+
continue;
365+
}
366+
};
367+
368+
match maybe_response {
369+
Some(res) => {
370+
break Ok(res);
371+
}
372+
None => {
373+
crate::utils::sleep(backoff).await;
374+
continue;
375+
}
376+
}
377+
}?;
378+
379+
Ok(event)
380+
}
381+
340382
pub async fn broadcast_tx(&self, tx_bytes: &[u8], deadline: u64) -> Result<JsValue, JsValue> {
341383
#[derive(serde::Serialize)]
342384
struct TxErrResponse {
@@ -363,11 +405,7 @@ impl Sdk {
363405
));
364406
}
365407

366-
let deadline = time::Instant::now() + time::Duration::from_secs(deadline);
367-
let tx_query = rpc::TxEventQuery::Applied(tx_hash.as_str());
368-
let event = rpc::query_tx_status(&self.namada, tx_query, deadline)
369-
.await
370-
.map_err(|e| JsValue::from_str(&e.to_string()))?;
408+
let event = self.query_tx_result(deadline, &tx_hash).await?;
371409
let tx_response = TxResponse::from_events(event);
372410

373411
let mut batch_tx_results: Vec<tx::BatchTxResult> = vec![];

packages/shared/lib/src/sdk/tx.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,11 @@ pub struct BatchTxResult {
450450

451451
impl BatchTxResult {
452452
pub fn new(hash: String, is_applied: bool, error: Option<String>) -> BatchTxResult {
453-
BatchTxResult { hash, is_applied, error }
453+
BatchTxResult {
454+
hash,
455+
is_applied,
456+
error,
457+
}
454458
}
455459
}
456460

packages/shared/lib/src/utils.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use gloo_utils::format::JsValueSerdeExt;
2-
use js_sys::Uint8Array;
2+
use js_sys::{Promise, Uint8Array};
33
use serde::Serialize;
44
use std::fmt::Debug;
55
use wasm_bindgen::prelude::*;
6+
use wasm_bindgen_futures::JsFuture;
67

78
#[wasm_bindgen]
89
extern "C" {
@@ -44,3 +45,15 @@ pub fn set_panic_hook() {
4445
web_sys::console::log_1(&"Set panic hook".into());
4546
console_error_panic_hook::set_once();
4647
}
48+
49+
/// Sleep function using setTimeout wrapped in a JS Promise
50+
pub async fn sleep(ms: i32) {
51+
let promise = Promise::new(&mut |resolve, _reject| {
52+
web_sys::window()
53+
.unwrap()
54+
.set_timeout_with_callback_and_timeout_and_arguments_0(&resolve, ms)
55+
.unwrap();
56+
});
57+
58+
let _ = JsFuture::from(promise).await;
59+
}

0 commit comments

Comments
 (0)