Skip to content

Commit

Permalink
Merge pull request #434 from TheWaWaR/dump-by-tx-subcommand-json-file
Browse files Browse the repository at this point in the history
feat: support dump mock json file for debugger by `ckb-cli tx` json file
  • Loading branch information
TheWaWaR authored Oct 24, 2022
2 parents 09d6d4d + de064eb commit 6868f2a
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 40 deletions.
90 changes: 52 additions & 38 deletions src/subcommands/mock_tx.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::convert::TryFrom;
use std::fs;
use std::io::{Read, Write};
use std::path::PathBuf;
Expand All @@ -20,7 +21,7 @@ use ckb_types::{
};
use clap::{App, Arg, ArgMatches};

use super::{CliSubCommand, Output};
use super::{tx::ReprTxHelper, CliSubCommand, Output};
use crate::plugin::PluginManager;
use crate::utils::{
arg::lock_arg,
Expand All @@ -29,6 +30,7 @@ use crate::utils::{
mock_tx_helper::MockTransactionHelper,
other::{get_genesis_info, get_signer},
rpc::HttpRpcClient,
tx_helper::TxHelper,
};

pub struct MockTxSubCommand<'a> {
Expand Down Expand Up @@ -93,7 +95,7 @@ impl<'a> MockTxSubCommand<'a> {
.clone()
.required_unless("tx-hash")
.conflicts_with("tx-hash")
.about("CKB transaction data file (format: json)"),
.about("CKB transaction data file or `ckb-cli tx` subcommand json file (format: json)"),
)
.arg(
arg_output_file
Expand Down Expand Up @@ -266,7 +268,19 @@ impl<'a> CliSubCommand for MockTxSubCommand<'a> {
let mut file = fs::File::open(path).map_err(|err| err.to_string())?;
file.read_to_string(&mut content)
.map_err(|err| err.to_string())?;
serde_json::from_str(content.as_str()).map_err(|err| err.to_string())?
let repr_result: Result<ReprTxHelper, String> =
serde_json::from_str(content.as_str()).map_err(|err| err.to_string());
if let Ok(repr) = repr_result {
let helper = TxHelper::try_from(repr)?;
let mut get_live_cell = |out_point: OutPoint, _with_data: bool| {
load_output_and_data(self.rpc_client, out_point.into())
.map(|(output, _data, _)| output.into())
};
let tx = helper.build_tx(&mut get_live_cell, true)?;
tx.data().into()
} else {
serde_json::from_str(content.as_str()).map_err(|err| err.to_string())?
}
} else if let Some(tx_hash) = tx_hash_opt {
self.rpc_client
.get_transaction(tx_hash.clone())?
Expand All @@ -279,41 +293,6 @@ impl<'a> CliSubCommand for MockTxSubCommand<'a> {
} else {
return Err(String::from("<tx-hash> or <tx-file> is required"));
};
fn load_output_and_data(
rpc_client: &mut HttpRpcClient,
out_point: json_types::OutPoint,
) -> Result<(json_types::CellOutput, json_types::JsonBytes, H256), String>
{
let tx_hash = out_point.tx_hash;
let index = out_point.index.value() as usize;
let (tx, block_hash) = rpc_client
.get_transaction(tx_hash.clone())?
.filter(|tx_with_status| tx_with_status.tx_status.block_hash.is_some())
.filter(|tx_with_status| tx_with_status.transaction.is_some())
.map(|tx_with_status| {
let tx = json_types::Transaction::from(packed::Transaction::from(
tx_with_status.transaction.unwrap().inner,
));
let block_hash = tx_with_status
.tx_status
.block_hash
.expect("block_hash exists");
(tx, block_hash)
})
.ok_or_else(|| {
format!("transaction not exists or not mined: {:x}", tx_hash)
})?;
let output = tx.outputs.get(index).cloned().ok_or_else(|| {
format!(
"can not found output tx-hash={:x}, index={}",
tx_hash, index
)
})?;
let data = tx.outputs_data.get(index).cloned().ok_or_else(|| {
format!("can not found data tx-hash={:x}, index={}", tx_hash, index)
})?;
Ok((output, data, block_hash))
}
let mock_inputs = src_tx
.inputs
.iter()
Expand Down Expand Up @@ -425,6 +404,41 @@ impl<'a> CliSubCommand for MockTxSubCommand<'a> {
}
}

fn load_output_and_data(
rpc_client: &mut HttpRpcClient,
out_point: json_types::OutPoint,
) -> Result<(json_types::CellOutput, json_types::JsonBytes, H256), String> {
let tx_hash = out_point.tx_hash;
let index = out_point.index.value() as usize;
let (tx, block_hash) = rpc_client
.get_transaction(tx_hash.clone())?
.filter(|tx_with_status| tx_with_status.tx_status.block_hash.is_some())
.filter(|tx_with_status| tx_with_status.transaction.is_some())
.map(|tx_with_status| {
let tx = json_types::Transaction::from(packed::Transaction::from(
tx_with_status.transaction.unwrap().inner,
));
let block_hash = tx_with_status
.tx_status
.block_hash
.expect("block_hash exists");
(tx, block_hash)
})
.ok_or_else(|| format!("transaction not exists or not mined: {:x}", tx_hash))?;
let output = tx.outputs.get(index).cloned().ok_or_else(|| {
format!(
"can not found output tx-hash={:x}, index={}",
tx_hash, index
)
})?;
let data = tx
.outputs_data
.get(index)
.cloned()
.ok_or_else(|| format!("can not found data tx-hash={:x}, index={}", tx_hash, index))?;
Ok((output, data, block_hash))
}

struct Loader<'a> {
rpc_client: &'a mut HttpRpcClient,
}
Expand Down
4 changes: 2 additions & 2 deletions src/subcommands/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@ fn modify_tx_file<T, F: FnOnce(&mut TxHelper) -> Result<T, String>>(

#[derive(Clone, Default, Serialize, Deserialize, PartialEq, Eq, Debug)]
#[serde(deny_unknown_fields)]
struct ReprTxHelper {
pub(crate) struct ReprTxHelper {
transaction: json_types::Transaction,
multisig_configs: HashMap<H160, ReprMultisigConfig>,
signatures: HashMap<JsonBytes, Vec<JsonBytes>>,
Expand Down Expand Up @@ -780,7 +780,7 @@ impl TryFrom<ReprTxHelper> for TxHelper {

#[derive(Clone, Default, Serialize, Deserialize, PartialEq, Eq, Debug)]
#[serde(deny_unknown_fields)]
struct ReprMultisigConfig {
pub(crate) struct ReprMultisigConfig {
sighash_addresses: Vec<String>,
require_first_n: u8,
threshold: u8,
Expand Down

0 comments on commit 6868f2a

Please sign in to comment.