Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a analyzer to analyze bad tx-file and give detailed reasons #154

Merged
merged 4 commits into from
Feb 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions ckb-debugger/examples/exec.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@
},
"type": null
},
"data": "0x",
"header": null
"data": "0x"
}
],
"cell_deps": [
Expand All @@ -40,8 +39,7 @@
},
"type": null
},
"data": "0x{{ data exec_caller }}",
"header": null
"data": "0x{{ data exec_caller }}"
},
{
"cell_dep": {
Expand All @@ -60,8 +58,7 @@
},
"type": null
},
"data": "0x{{ data exec_callee }}",
"header": null
"data": "0x{{ data exec_callee }}"
}
],
"header_deps": []
Expand Down
9 changes: 3 additions & 6 deletions ckb-debugger/examples/spawn.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@
},
"type": null
},
"data": "0x",
"header": null
"data": "0x"
}
],
"cell_deps": [
Expand All @@ -40,8 +39,7 @@
},
"type": null
},
"data": "0x{{ data spawn_caller_strcat }}",
"header": null
"data": "0x{{ data spawn_caller_strcat }}"
},
{
"cell_dep": {
Expand All @@ -60,8 +58,7 @@
},
"type": null
},
"data": "0x{{ data spawn_callee_strcat }}",
"header": null
"data": "0x{{ data spawn_callee_strcat }}"
}
],
"header_deps": []
Expand Down
393 changes: 393 additions & 0 deletions ckb-debugger/src/analyzer.rs

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion ckb-debugger/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod analyzer;
mod api;
mod machine_analyzer;
mod machine_assign;
Expand All @@ -8,11 +9,12 @@ mod syscall_elf_dumper;
#[cfg(target_family = "unix")]
mod syscall_stdio;

pub use analyzer::analyze;
pub use api::{run, run_json};
pub use machine_analyzer::{MachineAnalyzer, MachineOverlap, MachineProfile, MachineStepLog};
pub use machine_assign::MachineAssign;
pub use machine_gdb::{GdbStubHandler, GdbStubHandlerEventLoop};
pub use misc::{get_script_hash_by_index, pre_check, DummyResourceLoader, Embed, HumanReadableCycles};
pub use misc::{get_script_hash_by_index, DummyResourceLoader, Embed, HumanReadableCycles};
pub use syscall_all::{FileOperation, FileStream, Random, TimeNow};
pub use syscall_elf_dumper::ElfDumper;
#[cfg(target_family = "unix")]
Expand Down
10 changes: 3 additions & 7 deletions ckb-debugger/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use ckb_chain_spec::consensus::{ConsensusBuilder, TYPE_ID_CODE_HASH};
#[cfg(target_family = "unix")]
use ckb_debugger::Stdio;
use ckb_debugger::{
get_script_hash_by_index, pre_check, ElfDumper, FileOperation, FileStream, HumanReadableCycles, MachineAnalyzer,
analyze, get_script_hash_by_index, ElfDumper, FileOperation, FileStream, HumanReadableCycles, MachineAnalyzer,
MachineAssign, MachineOverlap, MachineProfile, MachineStepLog, Random, TimeNow,
};
use ckb_debugger::{Embed, GdbStubHandler, GdbStubHandlerEventLoop};
Expand Down Expand Up @@ -214,20 +214,16 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
Some("-") => {
let mut buf = String::new();
std::io::stdin().read_to_string(&mut buf)?;
analyze(&buf)?;
let repr_mock_tx: ReprMockTransaction = serde_json::from_str(&buf)?;
if let Err(msg) = pre_check(&repr_mock_tx) {
println!("Potential format error found: {}", msg);
}
repr_mock_tx.into()
}
Some(doc) => {
let buf = std::fs::read_to_string(doc)?;
let mut mock_tx_embed = Embed::new(PathBuf::from(doc.to_string()), buf.clone());
let buf = mock_tx_embed.replace_all();
analyze(&buf)?;
let repr_mock_tx: ReprMockTransaction = serde_json::from_str(&buf)?;
if let Err(msg) = pre_check(&repr_mock_tx) {
println!("Potential format error found: {}", msg);
}
repr_mock_tx.into()
}
None => {
Expand Down
42 changes: 2 additions & 40 deletions ckb-debugger/src/misc.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use ckb_chain_spec::consensus::TYPE_ID_CODE_HASH;
use ckb_hash::blake2b_256;
use ckb_mock_tx_types::{MockResourceLoader, MockTransaction, ReprMockTransaction};
use ckb_mock_tx_types::{MockResourceLoader, MockTransaction};
use ckb_script::ScriptGroupType;
use ckb_types::core::{HeaderView, ScriptHashType};
use ckb_types::packed::{Byte32, CellOutput, OutPoint, OutPointVec, Script};
use ckb_types::packed::{Byte32, CellOutput, OutPoint, Script};
use ckb_types::prelude::{Builder, Entity, Pack};
use ckb_types::H256;
use ckb_vm::Bytes;
Expand Down Expand Up @@ -168,41 +168,3 @@ pub fn get_script_hash_by_index(
_ => panic!("Invalid specified script: {:?} {} {}", script_group_type, cell_type, cell_index),
}
}

// Check transactions before executing them to avoid obvious mistakes.
pub fn pre_check(tx: &ReprMockTransaction) -> Result<(), String> {
let mut mock_cell_deps: Vec<_> = tx.mock_info.cell_deps.iter().map(|c| c.cell_dep.clone()).collect();
let mut real_cell_deps: Vec<_> = tx.tx.cell_deps.iter().map(|c| c.clone()).collect();
for dep in &tx.mock_info.cell_deps {
if dep.cell_dep.dep_type == ckb_jsonrpc_types::DepType::DepGroup {
let outpoints = OutPointVec::from_slice(dep.data.as_bytes()).unwrap();
let outpoints: Vec<OutPoint> = outpoints.into_iter().collect();
let resolved_cell_deps: Vec<_> = outpoints
.into_iter()
.map(|o| ckb_jsonrpc_types::CellDep { out_point: o.into(), dep_type: ckb_jsonrpc_types::DepType::Code })
.collect();
real_cell_deps.extend(resolved_cell_deps);
}
}
let compare = |a: &ckb_jsonrpc_types::CellDep, b: &ckb_jsonrpc_types::CellDep| {
let l = serde_json::to_string(a).unwrap();
let r = serde_json::to_string(b).unwrap();
l.cmp(&r)
};
mock_cell_deps.sort_by(compare);
real_cell_deps.sort_by(compare);
if mock_cell_deps != real_cell_deps {
return Err(String::from("Precheck: celldeps is mismatched"));
}
let mock_inputs: Vec<_> = tx.mock_info.inputs.iter().map(|i| i.input.clone()).collect();
let real_inputs: Vec<_> = tx.tx.inputs.clone();
if mock_inputs != real_inputs {
return Err(String::from("Precheck: inputs is mismatched"));
}
let mock_header_deps: Vec<_> = tx.mock_info.header_deps.iter().map(|h| h.hash.clone()).collect();
let read_header_deps: Vec<_> = tx.tx.header_deps.clone();
if mock_header_deps != read_header_deps {
return Err(String::from("Precheck: header deps is mismatched"));
}
Ok(())
}
14 changes: 4 additions & 10 deletions ckb-vm-signal-profiler/src/frames.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,16 +110,10 @@ impl Report {
};
samples.push(sample);
}
let samples_value = protos::ValueType {
type_: strings[SAMPLES] as i64,
unit: strings[COUNT] as i64,
..Default::default()
};
let time_value = protos::ValueType {
type_: strings[CPU] as i64,
unit: strings[NANOSECONDS] as i64,
..Default::default()
};
let samples_value =
protos::ValueType { type_: strings[SAMPLES] as i64, unit: strings[COUNT] as i64, ..Default::default() };
let time_value =
protos::ValueType { type_: strings[CPU] as i64, unit: strings[NANOSECONDS] as i64, ..Default::default() };
let profile = protos::Profile {
sample_type: vec![samples_value, time_value.clone()].into(),
sample: samples.into(),
Expand Down