ckb_debugger/
mock_tx_embed.rs1use ckb_chain_spec::consensus::TYPE_ID_CODE_HASH;
2use ckb_hash::blake2b_256;
3use ckb_types::core::ScriptHashType;
4use ckb_types::packed::Script;
5use ckb_types::prelude::{Builder, Entity, Pack};
6use ckb_vm::Bytes;
7use regex::{Captures, Regex};
8use std::collections::HashMap;
9use std::path::{Path, PathBuf};
10
11pub fn mock_tx_embed(path: PathBuf, data: &str) -> String {
14 let mut embed = MockTxEmbed::new(path, data.to_string());
15 embed.replace_all()
16}
17
18pub struct MockTxEmbed {
20 pub data: String,
21 pub path: PathBuf,
22 pub type_id_dict: HashMap<String, String>,
23}
24
25impl MockTxEmbed {
26 pub fn new(path: PathBuf, data: String) -> Self {
27 Self { data, path, type_id_dict: HashMap::new() }
28 }
29
30 pub fn replace_data(&mut self) -> &mut Self {
32 let regex = Regex::new(r"\{\{ ?data (.+?) ?\}\}").unwrap();
33 self.data = regex
34 .replace_all(&self.data, |caps: &Captures| -> String {
35 let cap1 = &caps[1];
36 let path = if !Path::new(cap1).is_absolute() {
37 let root = self.path.parent().unwrap();
38 root.join(cap1)
39 } else {
40 Path::new(cap1).to_path_buf()
41 };
42 let data = std::fs::read(&path);
43 if data.is_err() {
44 panic!("Read {:?} failed : {:?}", path, data);
45 }
46 let data = data.unwrap();
47 hex::encode(data)
48 })
49 .to_string();
50 self
51 }
52
53 pub fn replace_hash(&mut self) -> &mut Self {
55 let regex = Regex::new(r"\{\{ ?hash (.+?) ?\}\}").unwrap();
56 self.data = regex
57 .replace_all(&self.data, |caps: &Captures| -> String {
58 let cap1 = &caps[1];
59 let path = if !Path::new(cap1).is_absolute() {
60 let root = self.path.parent().unwrap();
61 root.join(cap1)
62 } else {
63 Path::new(cap1).to_path_buf()
64 };
65 let data = std::fs::read(path).unwrap();
66 hex::encode(blake2b_256(data))
67 })
68 .to_string();
69 self
70 }
71
72 pub fn prelude_type_id(&mut self) -> &mut Self {
74 let rule = Regex::new(r"\{\{ ?def_type (.+?) ?\}\}").unwrap();
75 for caps in rule.captures_iter(&self.data) {
76 let type_id_name = &caps[1];
77 assert!(!self.type_id_dict.contains_key(type_id_name));
78 let type_id_script = Script::new_builder()
79 .args(Bytes::from(type_id_name.to_string()).pack())
80 .code_hash(TYPE_ID_CODE_HASH.pack())
81 .hash_type(ScriptHashType::Type)
82 .build();
83 let type_id_script_hash = type_id_script.calc_script_hash();
84 let type_id_script_hash = format!("{:x}", type_id_script_hash);
85 self.type_id_dict.insert(type_id_name.to_string(), type_id_script_hash);
86 }
87 self
88 }
89
90 pub fn replace_def_type(&mut self) -> &mut Self {
92 let regex = Regex::new(r#""?\{\{ ?def_type (.+?) ?\}\}"?"#).unwrap();
93 self.data = regex
94 .replace_all(&self.data, |caps: &Captures| -> String {
95 let cap1 = &caps[1];
96 let type_id_script_json = ckb_jsonrpc_types::Script {
97 code_hash: TYPE_ID_CODE_HASH,
98 hash_type: ckb_jsonrpc_types::ScriptHashType::Type,
99 args: ckb_jsonrpc_types::JsonBytes::from_vec(cap1.as_bytes().to_vec()),
100 };
101 return serde_json::to_string_pretty(&type_id_script_json).unwrap();
102 })
103 .to_string();
104 self
105 }
106
107 pub fn replace_ref_type(&mut self) -> &mut Self {
109 let regex = Regex::new(r"\{\{ ?ref_type (.+?) ?\}\}").unwrap();
110 self.data = regex
111 .replace_all(&self.data, |caps: &Captures| -> String {
112 let cap1 = &caps[1];
113 return self.type_id_dict[&cap1.to_string()].clone();
114 })
115 .to_string();
116 self
117 }
118
119 pub fn replace_all(&mut self) -> String {
121 self.replace_data().replace_hash().prelude_type_id().replace_def_type().replace_ref_type();
122 self.data.clone()
123 }
124}