Skip to content

Commit

Permalink
feat(ledgers): When dumping and loading the genesis ledgers, include …
Browse files Browse the repository at this point in the history
…the hashes matrix to speed up the process
  • Loading branch information
tizoc committed Mar 25, 2024
1 parent 5fee51b commit 7c220e2
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 2 deletions.
11 changes: 11 additions & 0 deletions ledger/src/mask/mask.rs
Expand Up @@ -268,6 +268,17 @@ impl Mask {
self.with(|this| this.validate_inner_hashes())
}

/// Returns a vector of tuples of (index, hash) of all the hashes contained
/// in this mask.
pub fn get_raw_inner_hashes(&self) -> Vec<(u64, Fp)> {
self.with(|this| this.get_raw_inner_hashes())
}

/// Sets the contents of this mask's hash matrix using raw data.
pub fn set_raw_inner_hashes(&self, hashes: Vec<(u64, Fp)>) {
self.with(|this| this.set_raw_inner_hashes(hashes))
}

/// For tests only, check if the address is in the mask, without checking parent
#[cfg(test)]
fn test_is_in_mask(&self, addr: &Address) -> bool {
Expand Down
20 changes: 20 additions & 0 deletions ledger/src/mask/mask_impl.rs
Expand Up @@ -972,6 +972,26 @@ impl MaskImpl {
Ok(())
}

pub fn get_raw_inner_hashes(&self) -> Vec<(u64, Fp)> {
match self {
Root { database, .. } => {
database.with(|this| this.hashes_matrix.get_raw_inner_hashes())
}
Attached { hashes, .. } => hashes.clone().get_raw_inner_hashes(),
Unattached { hashes, .. } => hashes.clone().get_raw_inner_hashes(),
}
}

pub fn set_raw_inner_hashes(&self, raw_hashes: Vec<(u64, Fp)>) {
match self {
Root { database, .. } => {
database.with(|this| this.hashes_matrix.set_raw_inner_hashes(raw_hashes))
}
Attached { hashes, .. } => hashes.clone().set_raw_inner_hashes(raw_hashes),
Unattached { hashes, .. } => hashes.clone().set_raw_inner_hashes(raw_hashes),
}
}

/// For tests only, check if the address is in the mask, without checking parent
#[cfg(test)]
pub fn test_is_in_mask(&self, addr: &Address) -> bool {
Expand Down
18 changes: 18 additions & 0 deletions ledger/src/tree.rs
Expand Up @@ -106,6 +106,14 @@ impl HashesMatrix {
self.nhashes += 1;
}

/// Do not use directly. Used to forcefully reconstructing the hashes
/// matrix from raw data.
pub fn set_raw_index(&mut self, idx: u64, hash: Fp) {
let old = self.matrix.insert(idx, hash);
assert!(old.is_none());
self.nhashes += 1;
}

pub fn remove(&mut self, addr: &Address) {
let linear = addr.to_linear_index();
self.remove_at_index(linear);
Expand Down Expand Up @@ -194,6 +202,16 @@ impl HashesMatrix {
nhashes: *nhashes,
}
}

pub fn get_raw_inner_hashes(&self) -> Vec<(u64, Fp)> {
self.matrix.clone().into_iter().collect()
}

pub fn set_raw_inner_hashes(&mut self, hashes: Vec<(u64, Fp)>) {
for (idx, hash) in hashes {
self.set_raw_index(idx, hash);
}
}
}

static HASH_EMPTIES: Lazy<Mutex<Vec<Fp>>> = Lazy::new(|| {
Expand Down
@@ -1,6 +1,7 @@
use std::borrow::Cow;

use ledger::{scan_state::currency::Balance, BaseLedger};
use mina_hasher::Fp;
use mina_p2p_messages::{binprot::BinProtRead, v2};
use openmina_core::constants::CONSTRAINT_CONSTANTS;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -100,9 +101,14 @@ impl GenesisConfig {
Self::AccountsBinProt { bytes, constants } => {
let mut bytes = bytes.as_ref();
let expected_hash = Option::<v2::LedgerHash>::binprot_read(&mut bytes)?;
let hashes = Vec::<(u64, v2::LedgerHash)>::binprot_read(&mut bytes)?
.into_iter()
.map(|(idx, hash)| (idx, hash.0.to_field()))
.collect();
let accounts = Vec::<ledger::Account>::binprot_read(&mut bytes)?;

let (mut mask, total_currency) = Self::build_ledger_from_accounts(accounts);
let (mut mask, total_currency) =
Self::build_ledger_from_accounts_and_hashes(accounts, hashes);
let ledger_hash = ledger_hash(&mut mask);
if let Some(expected_hash) = expected_hash.filter(|h| h != &ledger_hash) {
anyhow::bail!("ledger hash mismatch after building the mask! expected: '{expected_hash}', got '{ledger_hash}'");
Expand Down Expand Up @@ -169,8 +175,22 @@ impl GenesisConfig {
mask.get_or_create_account(account_id, account).unwrap();
(mask, total_currency)
});

(mask, v2::CurrencyAmountStableV1(total_currency.into()))
}

fn build_ledger_from_accounts_and_hashes(
accounts: impl IntoIterator<Item = ledger::Account>,
hashes: Vec<(u64, Fp)>,
) -> (ledger::Mask, v2::CurrencyAmountStableV1) {
let (mask, total_currency) = Self::build_ledger_from_accounts(accounts);

// Must happen after the accounts have been set to avoid
// cache invalidations.
mask.set_raw_inner_hashes(hashes);

(mask, total_currency)
}
}

fn ledger_hash(mask: &mut ledger::Mask) -> v2::LedgerHash {
Expand Down
10 changes: 9 additions & 1 deletion tools/ledger-tool/src/main.rs
Expand Up @@ -154,11 +154,19 @@ fn main() -> anyhow::Result<()> {
}

let root = mask.merkle_root();
let top_hash = v2::LedgerHash::from(v2::MinaBaseLedgerHash0StableV1(root.into()));
let top_hash = v2::LedgerHash::from_fp(root);
println!("{top_hash}");

let mut hashes = vec![];

for (idx, hash) in mask.get_raw_inner_hashes() {
let hash = v2::LedgerHash::from_fp(hash);
hashes.push((idx, hash));
}

let mut output = File::create(&output)?;
Some(top_hash).binprot_write(&mut output)?;
hashes.binprot_write(&mut output)?;
accounts.binprot_write(&mut output)?;

Ok(())
Expand Down

0 comments on commit 7c220e2

Please sign in to comment.