molpha-verifier 0.1.0

Solana program library for verifying Molpha threshold-signed oracle updates
Documentation
//! Deterministic selection-bitmap derivation for a `(feed_id, registry_version, timestamp)` round.

use solana_keccak_hasher::hashv;

use crate::bitmap::{derive_group_bitmap, effective_selection_size};
use crate::error::DataUpdateError;

/// `bytes32(keccak256("MOLPHA_SELECTION_V1"))` — EVM `Validator` selection seed prefix.
///
/// Value: `keccak256(bytes("MOLPHA_SELECTION_V1"))`, verified by the unit test below.
pub const SELECTION_SEED_PREFIX: [u8; 32] = [
    0x1d, 0xef, 0x81, 0x59, 0xcb, 0xcf, 0xcd, 0xfd, 0x72, 0x8d, 0x41, 0x97, 0x51, 0x9a, 0x57, 0xc0,
    0x6e, 0x24, 0x3f, 0x0d, 0x94, 0x68, 0xb4, 0xc1, 0xe5, 0xc4, 0xa2, 0x33, 0xfc, 0x56, 0x53, 0xc3,
];

/// Derive the deterministic selection bitmap for a round.
///
/// `seed = keccak(SELECTION_SEED_PREFIX, feed_id, registry_version_be, canonical_timestamp_be)`,
/// then `derive_group_bitmap(seed, node_count, effective_selection_size(...))`.
pub fn derive_selection_bitmap(
    feed_id: &[u8; 32],
    registry_version: u32,
    canonical_timestamp: i64,
    node_count: u32,
    signatures_required: u8,
    redundancy_buffer: u8,
) -> Result<[u8; 32], DataUpdateError> {
    let canonical_timestamp_bytes = (canonical_timestamp as u64).to_be_bytes();
    let selection_seed = hashv(&[
        SELECTION_SEED_PREFIX.as_slice(),
        feed_id.as_ref(),
        registry_version.to_be_bytes().as_ref(),
        canonical_timestamp_bytes.as_ref(),
    ])
    .to_bytes();
    let selection_size =
        effective_selection_size(signatures_required, redundancy_buffer, node_count);
    derive_group_bitmap(&selection_seed, node_count, selection_size)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn selection_seed_prefix_is_keccak_of_domain() {
        let expected = hashv(&[b"MOLPHA_SELECTION_V1"]).to_bytes();
        assert_eq!(SELECTION_SEED_PREFIX, expected);
    }
}