From 5cbdf50b671d29efb3b7e7b9501286650b151e2b Mon Sep 17 00:00:00 2001 From: popcnt1 <142196625+popcnt1@users.noreply.github.com> Date: Wed, 12 Feb 2025 17:25:51 +0800 Subject: [PATCH 1/4] feat(rooch-db): add command to fetch transaction by order Introduce `GetTxByOrderCommand` to fetch a `LedgerTransaction` based on its order. Integrated the new command into the database commands module and CLI. --- .../commands/db/commands/get_tx_by_order.rs | 39 +++++++++++++++++++ crates/rooch/src/commands/db/commands/mod.rs | 1 + crates/rooch/src/commands/db/mod.rs | 5 +++ 3 files changed, 45 insertions(+) create mode 100644 crates/rooch/src/commands/db/commands/get_tx_by_order.rs diff --git a/crates/rooch/src/commands/db/commands/get_tx_by_order.rs b/crates/rooch/src/commands/db/commands/get_tx_by_order.rs new file mode 100644 index 0000000000..7fc3e204f1 --- /dev/null +++ b/crates/rooch/src/commands/db/commands/get_tx_by_order.rs @@ -0,0 +1,39 @@ +// Copyright (c) RoochNetwork +// SPDX-License-Identifier: Apache-2.0 + +use crate::commands::db::commands::init; +use clap::Parser; +use rooch_config::R_OPT_NET_HELP; +use rooch_types::error::RoochResult; +use rooch_types::rooch_network::RoochChainID; +use rooch_types::transaction::LedgerTransaction; +use std::path::PathBuf; + +/// Get LedgerTransaction by tx_order +#[derive(Debug, Parser)] +pub struct GetTxByOrderCommand { + /// Transaction's order + #[clap(long)] + pub order: u64, + + #[clap(long = "data-dir", short = 'd')] + /// Path to data dir, this dir is base dir, the final data_dir is base_dir/chain_network_name + pub base_data_dir: Option, + + /// If local chainid, start the service with a temporary data store. + /// All data will be deleted when the service is stopped. + #[clap(long, short = 'n', help = R_OPT_NET_HELP)] + pub chain_id: Option, +} + +impl GetTxByOrderCommand { + pub fn execute(self) -> RoochResult> { + let (_root, rooch_db, _start_time) = init(self.base_data_dir, self.chain_id); + let rooch_store = rooch_db.rooch_store.clone(); + + let tx_opt = rooch_store + .get_transaction_store() + .get_tx_by_order(self.order)?; + Ok(tx_opt) + } +} diff --git a/crates/rooch/src/commands/db/commands/mod.rs b/crates/rooch/src/commands/db/commands/mod.rs index e7e97939c0..94ad89c4eb 100644 --- a/crates/rooch/src/commands/db/commands/mod.rs +++ b/crates/rooch/src/commands/db/commands/mod.rs @@ -15,6 +15,7 @@ pub mod best_rollback; pub mod drop; pub mod get_changeset_by_order; pub mod get_execution_info_by_hash; +pub mod get_tx_by_order; pub mod repair; pub mod revert; pub mod rollback; diff --git a/crates/rooch/src/commands/db/mod.rs b/crates/rooch/src/commands/db/mod.rs index 1052301e48..17f9a7be2a 100644 --- a/crates/rooch/src/commands/db/mod.rs +++ b/crates/rooch/src/commands/db/mod.rs @@ -6,6 +6,7 @@ use crate::commands::db::commands::best_rollback::BestRollbackCommand; use crate::commands::db::commands::drop::DropCommand; use crate::commands::db::commands::get_changeset_by_order::GetChangesetByOrderCommand; use crate::commands::db::commands::get_execution_info_by_hash::GetExecutionInfoByHashCommand; +use crate::commands::db::commands::get_tx_by_order::GetTxByOrderCommand; use crate::commands::db::commands::repair::RepairCommand; use crate::commands::db::commands::revert::RevertCommand; use async_trait::async_trait; @@ -38,6 +39,9 @@ impl CommandAction for DB { DBCommand::Repair(repair) => repair.execute().await.map(|resp| { serde_json::to_string_pretty(&resp).expect("Failed to serialize response") }), + DBCommand::GetTxByOrder(get_tx_by_order) => get_tx_by_order.execute().map(|resp| { + serde_json::to_string_pretty(&resp).expect("Failed to serialize response") + }), DBCommand::GetChangesetByOrder(get_changeset_by_order) => { get_changeset_by_order.execute().await.map(|resp| { serde_json::to_string_pretty(&resp).expect("Failed to serialize response") @@ -62,6 +66,7 @@ pub enum DBCommand { Rollback(RollbackCommand), Drop(DropCommand), Repair(RepairCommand), + GetTxByOrder(GetTxByOrderCommand), GetChangesetByOrder(GetChangesetByOrderCommand), GetExecutionInfoByHash(GetExecutionInfoByHashCommand), BestRollback(BestRollbackCommand), From 425db183779efcc493b54edf41a729504cc85113 Mon Sep 17 00:00:00 2001 From: popcnt1 <142196625+popcnt1@users.noreply.github.com> Date: Wed, 12 Feb 2025 19:11:58 +0800 Subject: [PATCH 2/4] chore(rooch-db): simplify serialization and update exec mode Simplify JSON serialization in DB command responses to improve efficiency. Add "sync" as a valid execution mode option in the "exec" command for better flexibility. --- crates/rooch/src/commands/da/commands/exec.rs | 2 +- crates/rooch/src/commands/db/mod.rs | 21 +++++++++---------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/crates/rooch/src/commands/da/commands/exec.rs b/crates/rooch/src/commands/da/commands/exec.rs index 67d2e5b8ac..63d4c9a08e 100644 --- a/crates/rooch/src/commands/da/commands/exec.rs +++ b/crates/rooch/src/commands/da/commands/exec.rs @@ -58,7 +58,7 @@ pub struct ExecCommand { #[clap( long = "mode", default_value = "all", - help = "Execution mode: exec, seq, all. Default is all" + help = "Execution mode: exec, seq, all, sync. Default is all" )] pub mode: ExecMode, #[clap(long = "segment-dir")] diff --git a/crates/rooch/src/commands/db/mod.rs b/crates/rooch/src/commands/db/mod.rs index 17f9a7be2a..272d80ee59 100644 --- a/crates/rooch/src/commands/db/mod.rs +++ b/crates/rooch/src/commands/db/mod.rs @@ -39,18 +39,17 @@ impl CommandAction for DB { DBCommand::Repair(repair) => repair.execute().await.map(|resp| { serde_json::to_string_pretty(&resp).expect("Failed to serialize response") }), - DBCommand::GetTxByOrder(get_tx_by_order) => get_tx_by_order.execute().map(|resp| { - serde_json::to_string_pretty(&resp).expect("Failed to serialize response") - }), - DBCommand::GetChangesetByOrder(get_changeset_by_order) => { - get_changeset_by_order.execute().await.map(|resp| { - serde_json::to_string_pretty(&resp).expect("Failed to serialize response") - }) - } + DBCommand::GetTxByOrder(get_tx_by_order) => get_tx_by_order + .execute() + .map(|resp| serde_json::to_string(&resp).expect("Failed to serialize response")), + DBCommand::GetChangesetByOrder(get_changeset_by_order) => get_changeset_by_order + .execute() + .await + .map(|resp| serde_json::to_string(&resp).expect("Failed to serialize response")), DBCommand::GetExecutionInfoByHash(get_execution_info_by_hash) => { - get_execution_info_by_hash.execute().map(|resp| { - serde_json::to_string_pretty(&resp).expect("Failed to serialize response") - }) + get_execution_info_by_hash + .execute() + .map(|resp| serde_json::to_string(&resp).expect("Failed to serialize response")) } DBCommand::BestRollback(best_rollback) => best_rollback.execute().await.map(|resp| { serde_json::to_string_pretty(&resp).expect("Failed to serialize response") From bb8828ffdd69402c81b7bd0971b8e12c3d715014 Mon Sep 17 00:00:00 2001 From: popcnt1 <142196625+popcnt1@users.noreply.github.com> Date: Wed, 12 Feb 2025 19:12:36 +0800 Subject: [PATCH 3/4] fix(rooch-da): handle null state roots in transactions Fixes a bug where null state roots caused errors during parsing. Now null state roots are treated as H256::zero(), ensuring robust handling of input data. --- crates/rooch/src/commands/da/commands/mod.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/crates/rooch/src/commands/da/commands/mod.rs b/crates/rooch/src/commands/da/commands/mod.rs index c63b8a3b36..2fc17e9fb2 100644 --- a/crates/rooch/src/commands/da/commands/mod.rs +++ b/crates/rooch/src/commands/da/commands/mod.rs @@ -512,7 +512,12 @@ impl TxMetaStore { let line = line.unwrap(); let parts: Vec<&str> = line.split(':').collect(); let tx_order = parts[0].parse::()?; - let state_root = H256::from_str(parts[1])?; + let state_root_raw = parts[1]; + let state_root = if state_root_raw == "null" { + H256::zero() + } else { + H256::from_str(state_root_raw)? + }; let accumulator_root = H256::from_str(parts[2])?; exp_roots.insert(tx_order, (state_root, accumulator_root)); if tx_order > max_verified_tx_order { From ef901681c67857fb48461fba9dbfcf422fcaf032 Mon Sep 17 00:00:00 2001 From: popcnt1 <142196625+popcnt1@users.noreply.github.com> Date: Wed, 12 Feb 2025 19:12:53 +0800 Subject: [PATCH 4/4] docs(rooch-da): update README to reflect new state list script Update the README to indicate the use of `get_state_interval.sh` for generating `tx_order:state_root:accumulator_root` list files. Clarified instructions for scenarios without `--mode sync`. --- crates/rooch/src/commands/da/README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/crates/rooch/src/commands/da/README.md b/crates/rooch/src/commands/da/README.md index 5fbaee7d9d..a5c5c18474 100644 --- a/crates/rooch/src/commands/da/README.md +++ b/crates/rooch/src/commands/da/README.md @@ -62,14 +62,17 @@ Features include: 2. Compare state root with Rooch Network Mainnet/Testnet by tx_order:state_root list file 3. We could collect performance data in the execution process by tuning tools like `perf` if needed -#### Prepare tx_order:state_root list file +#### Prepare tx_order:state_root:accumulator_root list file -using [order_state.sh](https://github.com/popcnt1/roh/blob/main/scripts/order_state.sh) to generate tx_order:state_root: +If not run with `--mode sync`, you should prepare tx_order:state_root:accumulator_root list file by yourself. + +using [get_state_interval.sh](https://github.com/popcnt1/roh/blob/main/scripts/get_state_interval.sh) to generate +tx_order:state_root: accumulator_root list file: ```shell rooch env switch -n {network} -./order_state.sh {start_order} {end_order} {interval} +./get_state_interval.sh {start_order} {end_order} {interval} ``` #### Prepare genesis