helios/consensus/src/utils.rs

97 lines
2.5 KiB
Rust

use blst::{
min_pk::{PublicKey, Signature},
BLST_ERROR,
};
use common::{types::Bytes32, utils::bytes32_to_node};
use eyre::Result;
use ssz_rs::prelude::*;
use crate::types::{Header, SignatureBytes};
pub fn calc_sync_period(slot: u64) -> u64 {
let epoch = slot / 32; // 32 slots per epoch
epoch / 256 // 256 epochs per sync committee
}
pub fn is_aggregate_valid(sig_bytes: &SignatureBytes, msg: &[u8], pks: &[&PublicKey]) -> bool {
let dst: &[u8] = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_";
let sig_res = Signature::from_bytes(sig_bytes);
match sig_res {
Ok(sig) => sig.fast_aggregate_verify(true, msg, dst, pks) == BLST_ERROR::BLST_SUCCESS,
Err(_) => false,
}
}
pub fn is_proof_valid<L: Merkleized>(
attested_header: &Header,
leaf_object: &mut L,
branch: &[Bytes32],
depth: usize,
index: usize,
) -> bool {
let res: Result<bool> = (move || {
let leaf_hash = leaf_object.hash_tree_root()?;
let state_root = bytes32_to_node(&attested_header.state_root)?;
let branch = branch_to_nodes(branch.to_vec())?;
let is_valid = is_valid_merkle_branch(&leaf_hash, branch.iter(), depth, index, &state_root);
Ok(is_valid)
})();
if let Ok(is_valid) = res {
is_valid
} else {
false
}
}
#[derive(SimpleSerialize, Default, Debug)]
struct SigningData {
object_root: Bytes32,
domain: Bytes32,
}
#[derive(SimpleSerialize, Default, Debug)]
struct ForkData {
current_version: Vector<u8, 4>,
genesis_validator_root: Bytes32,
}
pub fn compute_signing_root(object_root: Bytes32, domain: Bytes32) -> Result<Node> {
let mut data = SigningData {
object_root,
domain,
};
Ok(data.hash_tree_root()?)
}
pub fn compute_domain(
domain_type: &[u8],
fork_version: Vector<u8, 4>,
genesis_root: Bytes32,
) -> Result<Bytes32> {
let fork_data_root = compute_fork_data_root(fork_version, genesis_root)?;
let start = domain_type;
let end = &fork_data_root.as_bytes()[..28];
let d = [start, end].concat();
Ok(d.to_vec().try_into().unwrap())
}
fn compute_fork_data_root(
current_version: Vector<u8, 4>,
genesis_validator_root: Bytes32,
) -> Result<Node> {
let mut fork_data = ForkData {
current_version,
genesis_validator_root,
};
Ok(fork_data.hash_tree_root()?)
}
pub fn branch_to_nodes(branch: Vec<Bytes32>) -> Result<Vec<Node>> {
branch
.iter()
.map(bytes32_to_node)
.collect::<Result<Vec<Node>>>()
}