Skip to main content

tempo_chainspec/
network_identity.rs

1//! Compiled network identities.
2
3use alloy_primitives::hex;
4use commonware_codec::ReadExt as _;
5use commonware_cryptography::bls12381::primitives::variant::{MinSig, Variant};
6use eyre::Context;
7use tempo_dkg_onchain_artifacts::OnchainDkgOutcome;
8
9const TESTNET_NETWORK_IDENTITY_EPOCH: u64 = 51;
10const TESTNET_NETWORK_IDENTITY: [u8; 96] = hex!(
11    "0x84591ad702a9ee67c0c64add2ff166c19a4666a1dc636cc530a810052957d34c"
12    "185bb1d2c7f5569983485a5af49baed70166ba17ae782bc8c75701099c704747"
13    "98ccc181d03b0c12054f1d01c7817b27b425bae4bfcf936218c0d097cccf3242"
14);
15
16const MAINNET_NETWORK_IDENTITY_EPOCH: u64 = 0;
17const MAINNET_NETWORK_IDENTITY: [u8; 96] = hex!(
18    "0xa217bb85001d4dcf8e5c50136f77af88cb2cab1857279b91c6240f41cca95c4f"
19    "43f6dcab3e0dfb87dafb3ecbeb6251e90a5df2e6c47432482821cd8b84665ee4"
20    "642589d2d9628a92b03e2bbfb00e006d038cd98def76d2a41b7c228c05f5a193"
21);
22
23/// This holds the key that is known to be active. The genesis-derived
24/// value must be updated with a newer identity after a full DKG rotation.
25#[derive(Debug, Clone, PartialEq, Eq)]
26pub struct NetworkIdentity {
27    /// First epoch for which `identity` is expected to verify finalizations.
28    pub from_epoch: u64,
29    /// BLS threshold public key.
30    pub identity: <MinSig as Variant>::Public,
31}
32
33impl NetworkIdentity {
34    pub(crate) fn mainnet() -> Self {
35        let identity = <MinSig as Variant>::Public::read(&mut MAINNET_NETWORK_IDENTITY.as_ref())
36            .expect("valid network identity");
37
38        Self {
39            identity,
40            from_epoch: MAINNET_NETWORK_IDENTITY_EPOCH,
41        }
42    }
43
44    pub(crate) fn testnet() -> Self {
45        let identity = <MinSig as Variant>::Public::read(&mut TESTNET_NETWORK_IDENTITY.as_ref())
46            .expect("valid network identity");
47
48        Self {
49            identity,
50            from_epoch: TESTNET_NETWORK_IDENTITY_EPOCH,
51        }
52    }
53
54    pub(crate) fn from_extra_data(extra_data: &[u8]) -> eyre::Result<Self> {
55        let mut extra_data = extra_data;
56        let outcome =
57            OnchainDkgOutcome::read(&mut extra_data).wrap_err("unable to parse dkg outcome")?;
58
59        Ok(Self {
60            from_epoch: outcome.epoch.get(),
61            identity: *outcome.network_identity(),
62        })
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69    use commonware_codec::Encode as _;
70
71    #[test]
72    fn compiled_identity_decodes() {
73        let identity = NetworkIdentity::testnet();
74
75        assert_eq!(identity.from_epoch, TESTNET_NETWORK_IDENTITY_EPOCH);
76        assert_eq!(
77            identity.identity.encode().as_ref(),
78            TESTNET_NETWORK_IDENTITY.as_ref()
79        );
80
81        let identity = NetworkIdentity::mainnet();
82
83        assert_eq!(identity.from_epoch, MAINNET_NETWORK_IDENTITY_EPOCH);
84        assert_eq!(
85            identity.identity.encode().as_ref(),
86            MAINNET_NETWORK_IDENTITY.as_ref()
87        );
88    }
89}