#![recursion_limit = "2048"]
#![cfg_attr(coverage_nightly, feature(coverage_attribute))]
use std::env;
use std::time::Instant;
pub use tasm_lib;
pub use tasm_lib::prelude::triton_vm;
pub use tasm_lib::prelude::twenty_first;
pub mod macros;
pub mod prelude;
#[derive(Debug, Clone)]
pub struct ScopeDurationLogger<'a> {
start: Instant,
description: &'a str,
log_slow_fn_threshold: Option<f64>,
location: &'static std::panic::Location<'static>,
}
impl<'a> ScopeDurationLogger<'a> {
#[track_caller]
pub fn new(description: &'a str, log_slow_fn_threshold: Option<f64>) -> Self {
Self {
start: Instant::now(),
description,
log_slow_fn_threshold,
location: std::panic::Location::caller(),
}
}
#[track_caller]
pub fn new_with_threshold(description: &'a str, log_slow_fn_threshold: f64) -> Self {
Self::new(description, Some(log_slow_fn_threshold))
}
#[track_caller]
pub fn new_default_threshold(description: &'a str) -> Self {
Self::new_with_threshold(
description,
match env::var("LOG_SLOW_SCOPE_THRESHOLD") {
Ok(t) => t.parse().unwrap(),
Err(_) => 0.001,
},
)
}
#[track_caller]
pub fn new_without_threshold(description: &'a str) -> Self {
Self::new(description, None)
}
}
impl Drop for ScopeDurationLogger<'_> {
fn drop(&mut self) {
let elapsed = self.start.elapsed();
let duration = elapsed.as_secs_f64();
if let Some(threshold) = self.log_slow_fn_threshold {
if duration >= threshold {
let msg = format!(
"executed {} in {} secs. exceeds slow fn threshold of {} secs. location: {}",
self.description, duration, threshold, self.location,
);
tracing::debug!("{}", msg);
}
} else {
let msg = format!(
"executed {} in {} secs. location: {}",
self.description, duration, self.location,
);
tracing::debug!("{}", msg);
}
}
}
pub mod block;
pub mod consensus_rule_set;
pub mod proof_abstractions;
pub mod transaction;
pub mod type_scripts;
#[cfg(test)]
#[cfg_attr(coverage_nightly, coverage(off))]
mod tests {
use itertools::Itertools;
use crate::block;
use crate::proof_abstractions::tasm::program::TritonProgram;
use crate::transaction;
use crate::type_scripts;
#[test]
fn print_all_validity_program_names() {
macro_rules! name_and_lib {
[$($t:expr),* $(,)?] => {[$({
let (library, _) = $t.library_and_code();
let snippet_names = library
.get_all_snippet_names()
.into_iter()
.map(annotate_with_sign_off_status)
.collect_vec();
(stringify!($t), snippet_names)
}),*]};
}
fn annotate_with_sign_off_status(name: String) -> String {
let Some(snippet) = tasm_lib::exported_snippets::name_to_snippet(&name) else {
return format!("⚠ {name}");
};
let sign_offs = snippet.sign_offs();
if sign_offs.is_empty() {
return format!("🅾 {name}");
}
format!("{} {name}", sign_offs.len())
}
let all_consensus_critical_imports = name_and_lib![
block::validity::block_program::BlockProgram,
transaction::validity::collect_lock_scripts::CollectLockScripts,
transaction::validity::collect_type_scripts::CollectTypeScripts,
transaction::validity::kernel_to_outputs::KernelToOutputs,
type_scripts::native_currency::NativeCurrency,
transaction::validity::removal_records_integrity::RemovalRecordsIntegrity,
transaction::validity::single_proof::SingleProof,
type_scripts::time_lock::TimeLock,
]
.into_iter()
.flat_map(|(name, snippet_names)| [vec![format!("\n{name}")], snippet_names].concat())
.unique()
.join("\n");
println!("{all_consensus_critical_imports}");
}
}