rbpf-cli: support json output
This commit is contained in:
parent
197f42d346
commit
bf689303d4
|
@ -19,10 +19,11 @@ use {
|
||||||
transaction_context::TransactionContext,
|
transaction_context::TransactionContext,
|
||||||
},
|
},
|
||||||
std::{
|
std::{
|
||||||
|
fmt::{Debug, Formatter},
|
||||||
fs::File,
|
fs::File,
|
||||||
io::{Read, Seek, SeekFrom},
|
io::{Read, Seek, SeekFrom},
|
||||||
path::Path,
|
path::Path,
|
||||||
time::Instant,
|
time::{Duration, Instant},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -43,10 +44,10 @@ struct Input {
|
||||||
fn load_accounts(path: &Path) -> Result<Input> {
|
fn load_accounts(path: &Path) -> Result<Input> {
|
||||||
let file = File::open(path).unwrap();
|
let file = File::open(path).unwrap();
|
||||||
let input: Input = serde_json::from_reader(file)?;
|
let input: Input = serde_json::from_reader(file)?;
|
||||||
println!("Program input:");
|
eprintln!("Program input:");
|
||||||
println!("accounts {:?}", &input.accounts);
|
eprintln!("accounts {:?}", &input.accounts);
|
||||||
println!("instruction_data {:?}", &input.instruction_data);
|
eprintln!("instruction_data {:?}", &input.instruction_data);
|
||||||
println!("----------------------------------------");
|
eprintln!("----------------------------------------");
|
||||||
Ok(input)
|
Ok(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,6 +158,15 @@ native machine code before execting it in the virtual machine.",
|
||||||
.short('v')
|
.short('v')
|
||||||
.long("verify"),
|
.long("verify"),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("output_format")
|
||||||
|
.about("Return information in specified output format")
|
||||||
|
.long("output")
|
||||||
|
.value_name("FORMAT")
|
||||||
|
.global(true)
|
||||||
|
.takes_value(true)
|
||||||
|
.possible_values(&["json", "json-compact"]),
|
||||||
|
)
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
let config = Config {
|
let config = Config {
|
||||||
|
@ -286,7 +296,6 @@ native machine code before execting it in the virtual machine.",
|
||||||
&account_lengths,
|
&account_lengths,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
println!("Program output:");
|
|
||||||
let start_time = Instant::now();
|
let start_time = Instant::now();
|
||||||
let result = if matches.value_of("use").unwrap() == "interpreter" {
|
let result = if matches.value_of("use").unwrap() == "interpreter" {
|
||||||
vm.execute_program_interpreted(&mut instruction_meter)
|
vm.execute_program_interpreted(&mut instruction_meter)
|
||||||
|
@ -294,17 +303,33 @@ native machine code before execting it in the virtual machine.",
|
||||||
vm.execute_program_jit(&mut instruction_meter)
|
vm.execute_program_jit(&mut instruction_meter)
|
||||||
};
|
};
|
||||||
let duration = Instant::now() - start_time;
|
let duration = Instant::now() - start_time;
|
||||||
println!("Result: {:?}", result);
|
|
||||||
println!("Instruction Count: {}", vm.get_total_instruction_count());
|
let output = Output {
|
||||||
println!("Execution time: {} us", duration.as_micros());
|
result: format!("{:?}", result),
|
||||||
|
instruction_count: vm.get_total_instruction_count(),
|
||||||
|
execution_time: duration,
|
||||||
|
};
|
||||||
|
match matches.value_of("output_format") {
|
||||||
|
Some("json") => {
|
||||||
|
println!("{}", serde_json::to_string_pretty(&output).unwrap());
|
||||||
|
}
|
||||||
|
Some("json-compact") => {
|
||||||
|
println!("{}", serde_json::to_string(&output).unwrap());
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
println!("Program output:");
|
||||||
|
println!("{:?}", output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if matches.is_present("trace") {
|
if matches.is_present("trace") {
|
||||||
println!("Trace is saved in trace.out");
|
eprintln!("Trace is saved in trace.out");
|
||||||
let mut file = File::create("trace.out").unwrap();
|
let mut file = File::create("trace.out").unwrap();
|
||||||
let analysis = Analysis::from_executable(&executable);
|
let analysis = Analysis::from_executable(&executable);
|
||||||
vm.get_tracer().write(&mut file, &analysis).unwrap();
|
vm.get_tracer().write(&mut file, &analysis).unwrap();
|
||||||
}
|
}
|
||||||
if matches.is_present("profile") {
|
if matches.is_present("profile") {
|
||||||
println!("Profile is saved in profile.dot");
|
eprintln!("Profile is saved in profile.dot");
|
||||||
let tracer = &vm.get_tracer();
|
let tracer = &vm.get_tracer();
|
||||||
let dynamic_analysis = DynamicAnalysis::new(tracer, &analysis);
|
let dynamic_analysis = DynamicAnalysis::new(tracer, &analysis);
|
||||||
let mut file = File::create("profile.dot").unwrap();
|
let mut file = File::create("profile.dot").unwrap();
|
||||||
|
@ -313,3 +338,19 @@ native machine code before execting it in the virtual machine.",
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
struct Output {
|
||||||
|
result: String,
|
||||||
|
instruction_count: u64,
|
||||||
|
execution_time: Duration,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for Output {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
writeln!(f, "Result: {}", self.result)?;
|
||||||
|
writeln!(f, "Instruction Count: {}", self.instruction_count)?;
|
||||||
|
writeln!(f, "Execution time: {} us", self.execution_time.as_micros())?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue