use serde::Serialize;
use crate::{Result, compile_source};
#[derive(Debug, Clone, Serialize, PartialEq, Eq)]
pub struct CostReport {
pub validators: Vec<ValidatorCost>,
pub total_bytes: usize,
pub total_nodes: usize,
pub total_budget_units: usize,
}
#[derive(Debug, Clone, Serialize, PartialEq, Eq)]
pub struct ValidatorCost {
pub title: String,
pub script_purpose: String,
pub bytes: usize,
pub nodes: usize,
pub budget_units: usize,
}
pub fn estimate_source(file: &str, source: &str) -> Result<CostReport> {
let output = compile_source(file, source)?;
let validators = output
.blueprint
.validators
.iter()
.map(|validator| {
let bytes = validator.compiled_code.len();
let nodes = validator.compiled_code.matches('(').count();
ValidatorCost {
title: validator.title.clone(),
script_purpose: validator.script_purpose.clone(),
bytes,
nodes,
budget_units: budget_units(bytes, nodes),
}
})
.collect::<Vec<_>>();
Ok(report(validators))
}
pub fn report(validators: Vec<ValidatorCost>) -> CostReport {
CostReport {
total_bytes: validators.iter().map(|cost| cost.bytes).sum(),
total_nodes: validators.iter().map(|cost| cost.nodes).sum(),
total_budget_units: validators.iter().map(|cost| cost.budget_units).sum(),
validators,
}
}
pub fn budget_units(bytes: usize, nodes: usize) -> usize {
bytes.saturating_mul(2) + nodes.saturating_mul(100)
}