sov_zk_cycle_macros/
lib.rs1#![deny(missing_docs)]
2#![doc = include_str!("../README.md")]
3extern crate proc_macro;
4
5use proc_macro::TokenStream;
6use quote::quote;
7use syn::{parse_macro_input, ItemFn};
8
9#[proc_macro_attribute]
22pub fn cycle_tracker(_attr: TokenStream, item: TokenStream) -> TokenStream {
23 let input = parse_macro_input!(item as ItemFn);
24
25 match wrap_function(input) {
26 Ok(ok) => ok,
27 Err(err) => err.to_compile_error().into(),
28 }
29}
30
31fn wrap_function(input: ItemFn) -> Result<TokenStream, syn::Error> {
32 let visibility = &input.vis;
33 let name = &input.sig.ident;
34 let inputs = &input.sig.inputs;
35 let output = &input.sig.output;
36 let block = &input.block;
37 let generics = &input.sig.generics;
38 let where_clause = &input.sig.generics.where_clause;
39 let risc0_zkvm = syn::Ident::new("risc0_zkvm", proc_macro2::Span::call_site());
40 let risc0_zkvm_platform =
41 syn::Ident::new("risc0_zkvm_platform", proc_macro2::Span::call_site());
42
43 let result = quote! {
44 #visibility fn #name #generics (#inputs) #output #where_clause {
45 let before = #risc0_zkvm::guest::env::get_cycle_count();
46 let result = (|| #block)();
47 let after = #risc0_zkvm::guest::env::get_cycle_count();
48
49 let tuple = (stringify!(#name).to_string(), (after - before) as u64);
51 let mut serialized = Vec::new();
52 serialized.extend(tuple.0.as_bytes());
53 serialized.push(0);
54 let size_bytes = tuple.1.to_ne_bytes();
55 serialized.extend(&size_bytes);
56
57 let cycle_string = String::from("cycle_metrics\0");
59 let metrics_syscall_name = unsafe {
60 #risc0_zkvm_platform::syscall::SyscallName::from_bytes_with_nul(cycle_string.as_ptr())
61 };
62
63 #risc0_zkvm::guest::env::send_recv_slice::<u8,u8>(metrics_syscall_name, &serialized);
64 result
65 }
66 };
67 Ok(result.into())
68}