Skip to content

Commit

Permalink
feat: collect debug info for ckb tx pool on duplicate tx error
Browse files Browse the repository at this point in the history
  • Loading branch information
whfuyn committed May 19, 2023
1 parent 10785ee commit 47eafe1
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 30 deletions.
63 changes: 37 additions & 26 deletions crates/relayer/src/chain/ckb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,33 +232,44 @@ impl CkbChain {
.map_err(Error::key_base)?
.into_ckb_keypair(self.network()?);
let tx = signer::sign(tx, &inputs, vec![], key).map_err(Error::key_base)?;
let hash = self
.rt
.block_on(
self.rpc_client
.send_transaction(&tx.data().into(), Some(OutputsValidator::Passthrough)),
)
.map_err(|e| {
Error::send_tx(format!(
"{e}\n== transaction for debugging is below ==\n{}",
serde_json::to_string(&JsonTx::from(tx)).expect("jsonify ckb tx")
))
})?;

tracing::info!(
"ckb send_transaction success: {}, wait committed to block",
hex::encode(&hash)
);

self.rt.block_on(utils::wait_ckb_transaction_committed(
&self.rpc_client,
hash,
Duration::from_secs(3),
0,
Duration::from_secs(30),
))?;

Ok(())
let task = async {
let send_res = self
.rpc_client
.send_transaction(&tx.data().into(), Some(OutputsValidator::Passthrough))
.await;
let hash = match send_res {
Ok(hash) => Ok(hash),
Err(e) => {
let pool_log = utils::collect_ckb_tx_pool_info_on_duplicate_tx(
self.rpc_client.as_ref(),
&e,
)
.await
.unwrap_or_default();
let tx_info = format!(
"== transaction for debugging is below ==\n{}",
serde_json::to_string(&JsonTx::from(tx)).expect("jsonify ckb tx")
);
Err(Error::send_tx(format!("{e}\n{pool_log}\n{tx_info}\n")))
}
}?;

tracing::info!(
"ckb send_transaction success: {}, wait committed to block",
hex::encode(&hash)
);

utils::wait_ckb_transaction_committed(
&self.rpc_client,
hash,
Duration::from_secs(3),
0,
Duration::from_secs(30),
)
.await
};
self.rt.block_on(task)
}

pub fn network(&self) -> Result<NetworkType, Error> {
Expand Down
7 changes: 6 additions & 1 deletion crates/relayer/src/chain/ckb/communication.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use ckb_jsonrpc_types::{
BlockNumber, BlockView, CellWithStatus, ChainInfo, HeaderView, JsonBytes, OutPoint,
OutputsValidator, Transaction, TransactionWithStatusResponse,
OutputsValidator, RawTxPool, Transaction, TransactionWithStatusResponse, TxPoolInfo,
};
use ckb_sdk::rpc::ckb_indexer::{Cell, Pagination, SearchKey};
use ckb_types::H256;
Expand Down Expand Up @@ -34,6 +34,11 @@ pub trait CkbReader {
limit: u32,
cursor: Option<JsonBytes>,
) -> Response<Pagination<Cell>>;

// For debugging purposes.
fn get_raw_tx_pool(&self, verbose: bool) -> Response<RawTxPool>;

fn tx_pool_info(&self) -> Response<TxPoolInfo>;
}

pub trait CkbWriter {
Expand Down
12 changes: 10 additions & 2 deletions crates/relayer/src/chain/ckb/mock_rpc_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

use ckb_jsonrpc_types::{
BlockNumber, BlockView, CellWithStatus, ChainInfo, Header, HeaderView, JsonBytes, OutPoint,
OutputsValidator, ResponseFormat, Transaction, TransactionView, TransactionWithStatusResponse,
TxStatus,
OutputsValidator, RawTxPool, ResponseFormat, Transaction, TransactionView,
TransactionWithStatusResponse, TxPoolInfo, TxStatus,
};
use ckb_sdk::rpc::ckb_indexer::{Cell, Pagination, SearchKey};
use ckb_types::{packed, prelude::*, H256};
Expand Down Expand Up @@ -171,6 +171,14 @@ impl CkbReader for RpcClient {
};
Box::pin(async { Ok(resp) })
}

fn get_raw_tx_pool(&self, verbose: bool) -> Rpc<RawTxPool> {
todo!()
}

fn tx_pool_info(&self) -> Rpc<TxPoolInfo> {
todo!()
}
}

impl CkbWriter for RpcClient {
Expand Down
10 changes: 9 additions & 1 deletion crates/relayer/src/chain/ckb/rpc_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use ckb_jsonrpc_types::{
BlockNumber, BlockView, CellWithStatus, ChainInfo, HeaderView, JsonBytes, OutPoint,
OutputsValidator, Transaction, TransactionWithStatusResponse, Uint32,
OutputsValidator, RawTxPool, Transaction, TransactionWithStatusResponse, TxPoolInfo, Uint32,
};
use ckb_sdk::rpc::ckb_indexer::{Cell, Order, Pagination, SearchKey};
use ckb_types::H256;
Expand Down Expand Up @@ -162,6 +162,14 @@ impl CkbReader for RpcClient {
)
.boxed()
}

fn get_raw_tx_pool(&self, verbose: bool) -> Rpc<RawTxPool> {
jsonrpc!("get_raw_tx_pool", Target::CKB, self, RawTxPool, verbose).boxed()
}

fn tx_pool_info(&self) -> Rpc<TxPoolInfo> {
jsonrpc!("tx_pool_info", Target::CKB, self, TxPoolInfo).boxed()
}
}

impl CkbWriter for RpcClient {
Expand Down
38 changes: 38 additions & 0 deletions crates/relayer/src/chain/ckb/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,44 @@ pub async fn wait_ckb_transaction_committed(
Ok(())
}

pub async fn collect_ckb_tx_pool_info_on_duplicate_tx(
rpc: &impl CkbReader,
send_tx_err: &Error,
) -> Option<String> {
let err_msg = format!("{send_tx_err}");
// Collecting debug info for ckb tx pool on duplicate tx error.
// The error code is -1077.
// https://github.com/nervosnetwork/ckb/tree/develop/rpc#error-poolrejectedduplicatedtransaction
if err_msg.contains("PoolRejectedDuplicatedTransaction") || err_msg.contains("-1077") {
let mut pool_log = String::new();
match rpc.get_raw_tx_pool(true).await {
Ok(raw_tx_pool) => {
pool_log += &format!(
"== CKB raw tx pool ==\n{}\n",
serde_json::to_string(&raw_tx_pool).expect("jsonify ckb raw tx pool")
);
}
Err(e) => {
pool_log += &format!("== get ckb raw tx pool failed ==\n{e}");
}
}
match rpc.tx_pool_info().await {
Ok(tx_pool_info) => {
pool_log += &format!(
"== CKB tx pool info ==\n{}",
serde_json::to_string(&tx_pool_info).expect("jsonify ckb tx pool info")
);
}
Err(e) => {
pool_log += &format!("== get ckb tx pool info failed ==\n{e}");
}
}
Some(pool_log)
} else {
None
}
}

#[cfg(test)]
mod tests {
use std::path::Path;
Expand Down

0 comments on commit 47eafe1

Please sign in to comment.