wasm_host_simulator/
main.rs1extern crate core;
2
3mod data_provider;
4mod decoding;
5mod hashing;
6mod host_functions_wamr;
7mod mock_data;
8mod vm_wamr;
9
10use crate::mock_data::MockData;
11use clap::Parser;
12use env_logger::Builder;
13use log::LevelFilter;
14use log::{debug, error, info};
15use std::fs;
16use std::io::Write;
17use std::path::PathBuf;
18
19#[derive(Parser, Debug)]
21#[command(version, about, long_about = None)]
22struct Args {
23 #[arg(long)]
25 dir: Option<String>,
26
27 #[arg(short, long, default_value = "success")]
29 test_case: String,
30
31 #[arg(short, long)]
33 project: String,
34
35 #[arg(short, long)]
37 verbose: bool,
38
39 #[arg(long, default_value = "finish")]
41 function: String,
42
43 #[arg(long, default_value = "1000000")]
46 gas_cap: u32,
47}
48
49#[allow(clippy::type_complexity)]
50fn load_test_data(
51 dir: Option<String>,
52 project: &str,
53 test_case: &str,
54) -> Result<(String, String, String, String, String), Box<dyn std::error::Error>> {
55 let base_path = if let Some(dir) = dir {
57 PathBuf::from(dir).join("fixtures").join(test_case)
58 } else {
59 PathBuf::from(env!("CARGO_MANIFEST_DIR"))
60 .parent()
61 .unwrap()
62 .join("projects")
63 .join(project)
64 .join("fixtures")
65 .join(test_case)
66 };
67
68 if !base_path.exists() {
69 return Err(format!(
70 "Test case '{}' not found at expected location: {}",
71 test_case,
72 base_path.display()
73 )
74 .into());
75 }
76
77 let tx_path = base_path.join("tx.json");
78 let lo_path = base_path.join("ledger_object.json");
79 let lh_path = base_path.join("ledger_header.json");
80 let l_path = base_path.join("ledger.json");
81 let nfts_path = base_path.join("nfts.json");
82
83 let tx_json = fs::read_to_string(tx_path)?;
84 let lo_json = fs::read_to_string(lo_path)?;
85 let lh_json = fs::read_to_string(lh_path)?;
86 let l_json = fs::read_to_string(l_path)?;
87 let nft_json = fs::read_to_string(nfts_path)?;
88
89 Ok((tx_json, lo_json, lh_json, l_json, nft_json))
90}
91
92fn main() -> Result<(), Box<dyn std::error::Error>> {
93 let args = Args::parse();
94
95 let base_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
96 .parent()
97 .unwrap()
98 .join("projects");
99
100 if !base_path.exists() {
101 eprintln!(
102 "Error: Could not find projects directory at expected location: {}",
103 base_path.display()
104 );
105 std::process::exit(1);
106 }
107
108 let wasm_file = base_path
109 .join("target/wasm32v1-none/debug")
110 .join(format!("{}.wasm", args.project))
111 .to_string_lossy()
112 .to_string();
113
114 let log_level = if args.verbose {
116 LevelFilter::Debug
117 } else {
118 LevelFilter::Info
119 };
120
121 Builder::new()
122 .format(|buf, record| {
123 writeln!(
124 buf,
125 "[{} {}] {}",
126 record.level(),
127 record.target(),
128 record.args()
129 )
130 })
131 .filter(None, log_level)
132 .init();
133
134 info!("Starting Wasm host application {:?}", args);
135 info!("Target function: {} (default is 'finish')", args.function);
136 info!("Using test case: {}", args.test_case);
137 info!("Project: {}", args.project);
138 info!(
139 "Source Directory: {}",
140 args.dir.as_deref().unwrap_or("default")
141 );
142 info!("Loading test data from fixtures");
143 let (tx_json, lo_json, lh_json, l_json, nft_json) =
144 match load_test_data(args.dir, &args.project, &args.test_case) {
145 Ok((tx, lo, lh, l, nft)) => {
146 debug!("Test data loaded successfully");
147 (tx, lo, lh, l, nft)
148 }
149 Err(e) => {
150 error!("Failed to load test data: {}", e);
151 return Err(e);
152 }
153 };
154
155 let data_source = MockData::new(&tx_json, &lo_json, &lh_json, &l_json, &nft_json);
156 info!("Executing function: {}", args.function);
157 match vm_wamr::run_func(wasm_file, &args.function, Some(args.gas_cap), data_source) {
159 Ok(result) => {
160 if (result && args.test_case == "success") || (!result && args.test_case == "failure") {
161 println!("-------------------------------------------------");
162 println!("| WASM FUNCTION EXECUTION RESULT |");
163 println!("-------------------------------------------------");
164 println!("| Function: {:<33} |", args.function);
165 println!("| Test Case: {:<33} |", args.test_case);
166 println!("| Result: {:<33} |", result);
167 println!("-------------------------------------------------");
168 info!("Function completed with result: {}", result);
169 } else {
170 println!("-------------------------------------------------");
171 println!("| WASM FUNCTION EXECUTION RESULT |");
172 println!("-------------------------------------------------");
173 println!("| Function: {:<33} |", args.function);
174 println!("| Test Case: {:<33} |", args.test_case);
175 println!("| Result: {:<33} |", result);
176 println!("-------------------------------------------------");
177 info!("Function completed with result: {}", result);
178 return Err("Function result did not match expected outcome".into());
179 }
180 }
181 Err(e) => {
182 println!("-------------------------------------------------");
183 println!("| WASM FUNCTION EXECUTION ERROR |");
184 println!("-------------------------------------------------");
185 println!("| Function: {:<33} |", args.function);
186 println!("| Test Case: {:<33} |", args.test_case);
187 println!("| Error: {:<33} |", e);
188 println!("-------------------------------------------------");
189 error!("Function execution failed: {}", e);
190 return Err(Box::new(e));
191 }
192 }
193
194 info!("Wasm host application execution completed");
195 Ok(())
196}