use crate::ast::*;
use serde::Serialize;
use truthlinked_axiom_sdk::hashing::namespace;
#[derive(Debug, Serialize)]
pub struct StorageKeySpec {
pub offset: usize,
pub len: usize,
}
#[derive(Debug, Serialize)]
pub struct Manifest {
pub declared_reads: Vec<String>,
pub declared_writes: Vec<String>,
pub commutative_keys: Vec<String>,
pub storage_key_specs: Vec<StorageKeySpec>,
}
pub fn generate(cell: &CellDef) -> Manifest {
let mut reads: Vec<[u8; 32]> = Vec::new();
let mut writes: Vec<[u8; 32]> = Vec::new();
let mut commutative: Vec<[u8; 32]> = Vec::new();
for slot in &cell.storage {
let key = namespace(&slot.name);
reads.push(key);
writes.push(key);
if slot.commutative {
commutative.push(key);
}
}
reads.sort();
reads.dedup();
writes.sort();
writes.dedup();
commutative.sort();
commutative.dedup();
let mut specs: Vec<StorageKeySpec> = Vec::new();
for f in cell.fns.iter().filter(|f| f.public) {
for (i, param) in f.params.iter().enumerate() {
if matches!(param.ty, Type::Address | Type::U256) {
specs.push(StorageKeySpec {
offset: 4 + i * 32,
len: 32,
});
}
}
}
specs.sort_by_key(|s| s.offset);
specs.dedup_by_key(|s| s.offset);
Manifest {
declared_reads: reads.iter().map(hex::encode).collect(),
declared_writes: writes.iter().map(hex::encode).collect(),
commutative_keys: commutative.iter().map(hex::encode).collect(),
storage_key_specs: specs,
}
}