use clvmr::Allocator;
use clvmr::serde::node_to_bytes;
use dig_protocol::Bytes32;
use crate::SLASH_APPEAL_REMARK_MAGIC_V1;
use crate::appeal::envelope::SlashAppeal;
use crate::error::SlashingError;
pub fn encode_slash_appeal_remark_payload_v1(ap: &SlashAppeal) -> serde_json::Result<Vec<u8>> {
let body = serde_json::to_vec(ap)?;
let mut out = Vec::with_capacity(SLASH_APPEAL_REMARK_MAGIC_V1.len() + body.len());
out.extend_from_slice(SLASH_APPEAL_REMARK_MAGIC_V1);
out.extend_from_slice(&body);
Ok(out)
}
pub fn parse_slash_appeals_from_conditions<P>(payloads: &[P]) -> Vec<SlashAppeal>
where
P: AsRef<[u8]>,
{
let magic = SLASH_APPEAL_REMARK_MAGIC_V1;
let mut out = Vec::new();
for payload in payloads {
let bytes = payload.as_ref();
let Some(body) = bytes.strip_prefix(magic) else {
continue;
};
if let Ok(ap) = serde_json::from_slice::<SlashAppeal>(body) {
out.push(ap);
}
}
out
}
pub fn slash_appeal_remark_puzzle_reveal_v1(ap: &SlashAppeal) -> Result<Vec<u8>, SlashingError> {
let wire = encode_slash_appeal_remark_payload_v1(ap)
.map_err(|e| SlashingError::InvalidSlashingEvidence(format!("encode: {e}")))?;
let mut allocator = Allocator::new();
let payload_atom = allocator
.new_atom(&wire)
.map_err(|e| SlashingError::InvalidSlashingEvidence(format!("new_atom: {e}")))?;
let nil = allocator.nil();
let tail = allocator
.new_pair(payload_atom, nil)
.map_err(|e| SlashingError::InvalidSlashingEvidence(format!("new_pair tail: {e}")))?;
let opcode = allocator
.new_small_number(1)
.map_err(|e| SlashingError::InvalidSlashingEvidence(format!("new_small_number: {e}")))?;
let condition = allocator
.new_pair(opcode, tail)
.map_err(|e| SlashingError::InvalidSlashingEvidence(format!("new_pair cond: {e}")))?;
let condition_list = allocator
.new_pair(condition, nil)
.map_err(|e| SlashingError::InvalidSlashingEvidence(format!("new_pair list: {e}")))?;
let puzzle = allocator
.new_pair(opcode, condition_list)
.map_err(|e| SlashingError::InvalidSlashingEvidence(format!("new_pair puzzle: {e}")))?;
node_to_bytes(&allocator, puzzle)
.map_err(|e| SlashingError::InvalidSlashingEvidence(format!("node_to_bytes: {e}")))
}
pub fn slash_appeal_remark_puzzle_hash_v1(ap: &SlashAppeal) -> Result<Bytes32, SlashingError> {
let reveal = slash_appeal_remark_puzzle_reveal_v1(ap)?;
let hash = clvm_utils::tree_hash_from_bytes(&reveal)
.map_err(|e| SlashingError::InvalidSlashingEvidence(format!("tree_hash: {e}")))?;
Ok(hash.into())
}