Skip to content

Commit

Permalink
Store decompressed BLS keys for genesis block
Browse files Browse the repository at this point in the history
  • Loading branch information
hrxi committed Jan 23, 2025
1 parent eb922e6 commit 48e42ea
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 16 deletions.
36 changes: 20 additions & 16 deletions genesis-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
extern crate log;

use std::{
fs::{read_to_string, OpenOptions},
fs,
io::Error as IoError,
path::Path,
};
Expand Down Expand Up @@ -217,7 +217,7 @@ impl GenesisBuilder {
///
/// See `genesis/src/genesis/unit-albatross.toml` for an example.
pub fn from_config_file<P: AsRef<Path>>(path: P) -> Result<Self, GenesisBuilderError> {
Self::from_config(toml::from_str(&read_to_string(path)?)?)
Self::from_config(toml::from_str(&fs::read_to_string(path)?)?)
}

pub fn from_config(config: config::GenesisConfig) -> Result<Self, GenesisBuilderError> {
Expand Down Expand Up @@ -647,6 +647,8 @@ impl GenesisBuilder {
db: MdbxDatabase,
directory: P,
) -> Result<(Blake2bHash, bool), GenesisBuilderError> {
let directory = directory.as_ref();

let GenesisInfo {
block,
hash,
Expand All @@ -658,25 +660,27 @@ impl GenesisBuilder {
debug!("Accounts:");
debug!(?accounts);

let block_path = directory.as_ref().join("block.dat");
let block_path = directory.join("block.dat");
info!(path = %block_path.display(), "Writing block to");
let mut file = OpenOptions::new()
.create(true)
.truncate(true)
.write(true)
.open(&block_path)?;
block.serialize_to_writer(&mut file)?;
fs::write(block_path, block.serialize_to_vec())?;

let decompressed_path = directory.join("decompressed_keys.dat");
if let Block::Macro(MacroBlock { header: MacroHeader { validators: Some(validators), .. }, ..}) = &block {
let mut decompressed = Vec::new();
for key in validators.voting_keys() {
decompressed.extend_from_slice(&key.trusted_serialize());
}
fs::write(decompressed_path, decompressed)?;

} else {
unreachable!("genesis block must be an election block");
}

let have_accounts = accounts.is_some();
if let Some(accounts) = accounts {
let accounts_path = directory.as_ref().join("accounts.dat");
let accounts_path = directory.join("accounts.dat");
info!(path = %accounts_path.display(), "Writing accounts to");
let mut file = OpenOptions::new()
.create(true)
.truncate(true)
.write(true)
.open(&accounts_path)?;
accounts.serialize_to_writer(&mut file)?;
fs::write(accounts_path, accounts.serialize_to_vec())?;
}

Ok((hash, have_accounts))
Expand Down
1 change: 1 addition & 0 deletions genesis/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ fn write_genesis_rs(directory: &Path, name: &str, genesis_hash: &Blake2bHash, ha
let genesis_rs = format!(
r#"GenesisData {{
block: include_bytes!(concat!(env!("OUT_DIR"), "/genesis/{name}/block.dat")),
decompressed_keys: include_bytes!(concat!(env!("OUT_DIR"), "/genesis/{name}/decompressed_keys.dat")),
hash: Blake2bHash([{hash}]),
accounts: {accounts_expr},
}}"#,
Expand Down
23 changes: 23 additions & 0 deletions genesis/src/networks.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use std::env;
#[cfg(feature = "genesis-override")]
use std::path::Path;
use std::sync::OnceLock;

use nimiq_block::Block;
use nimiq_bls::{LazyPublicKey as BlsLazyPublicKey, PublicKey as BlsPublicKey};
#[cfg(feature = "genesis-override")]
use nimiq_database::mdbx::MdbxDatabase;
#[cfg(feature = "genesis-override")]
Expand All @@ -17,6 +19,7 @@ use nimiq_serde::Serialize;
#[derive(Clone, Debug)]
struct GenesisData {
block: &'static [u8],
decompressed_keys: &'static [u8],
hash: Blake2bHash,
accounts: Option<&'static [u8]>,
}
Expand Down Expand Up @@ -81,16 +84,36 @@ fn read_genesis_config(config: &Path) -> Result<GenesisData, GenesisBuilderError

Ok(GenesisData {
block: Box::leak(block.into_boxed_slice()),
decompressed_keys: &[],
hash,
accounts: accounts.map(|accounts| Box::leak(accounts.into_boxed_slice()) as &'static _),
})
}

static KEYS_DEV: OnceLock<Box<[BlsLazyPublicKey]>> = OnceLock::new();
static KEYS_TEST: OnceLock<Box<[BlsLazyPublicKey]>> = OnceLock::new();
static KEYS_UNIT: OnceLock<Box<[BlsLazyPublicKey]>> = OnceLock::new();
static KEYS_MAIN: OnceLock<Box<[BlsLazyPublicKey]>> = OnceLock::new();

fn network(network_id: NetworkId) -> Option<&'static NetworkInfo> {
let result = network_impl(network_id);
if let Some(info) = result {
assert_eq!(network_id, info.network_id);
assert_eq!(network_id, info.genesis_block().network());
let keys = match network_id {
NetworkId::DevAlbatross => &KEYS_DEV,
NetworkId::TestAlbatross => &KEYS_TEST,
NetworkId::UnitAlbatross => &KEYS_UNIT,
NetworkId::MainAlbatross => &KEYS_MAIN,
_ => unreachable!(),
};
keys.get_or_init(|| {
info.genesis.decompressed_keys.chunks(BlsPublicKey::TRUSTED_SERIALIZATION_SIZE)
.map(|chunk| {
BlsLazyPublicKey::from(BlsPublicKey::trusted_deserialize(&chunk.try_into().unwrap()))
})
.collect()
});
}
result
}
Expand Down

0 comments on commit 48e42ea

Please sign in to comment.