Skip to content

Commit

Permalink
Merge pull request #1856 from AleoHQ/feat/genesis-committee
Browse files Browse the repository at this point in the history
Removes `current_committee` from the Ledger struct
  • Loading branch information
howardwu authored Jul 31, 2023
2 parents 6121a7b + 59bde66 commit 06a44ca
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 51 deletions.
25 changes: 18 additions & 7 deletions ledger/src/check_next_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,22 +242,33 @@ impl<N: Network, C: ConsensusStorage<N>> Ledger<N, C> {

/* Authority */

// Ensure the block is signed by a validator in the committee.
let signer = block.authority().to_address();
if !self.current_committee.read().contains(&signer) {
bail!("Block {} ({}) is signed by an unauthorized account ({signer})", block.height(), block.hash());
}

// Verify the block authority.
match block.authority() {
Authority::Beacon(signature) => {
// Retrieve the signer.
let signer = signature.to_address();

// Ensure the block is signed by a validator in the committee.
if signer != self.genesis_block.authority().to_address() {
bail!(
"Block {} ({}) is signed by an unauthorized account ({signer})",
block.height(),
block.hash()
);
}
// Check the signature.
if !signature.verify(&signer, &[*block.hash()]) {
bail!("Invalid signature for block {} ({})", block.height(), block.hash());
}
}
// TODO: Check the certificates of the quorum.
Authority::Quorum(_certificates) => (),
Authority::Quorum(_certificates) => {
// // Ensure the block is signed by a validator in the committee.
// let signer = block.authority().to_address();
// if !self.current_committee.read().contains(&signer) {
// bail!("Block {} ({}) is signed by an unauthorized account ({signer})", block.height(), block.hash());
// }
}
}

/* Transactions */
Expand Down
3 changes: 2 additions & 1 deletion ledger/src/check_transaction_basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ impl<N: Network, C: ConsensusStorage<N>> Ledger<N, C> {
}
}

// TODO (howardwu): DEPRECATE THIS - Remove support for `mint` altogether.
// Ensure the mint transaction is attributed to a validator in the committee.
if transaction.is_mint() {
// Retrieve the execution.
Expand All @@ -42,7 +43,7 @@ impl<N: Network, C: ConsensusStorage<N>> Ledger<N, C> {
// Retrieve the address that minted.
let address = mint_address(transition)?;
// Check if the address is in the current committee.
if !self.current_committee.read().contains(address) {
if *address != self.genesis_block.authority().to_address() {
bail!("Mint transaction ({transaction_id}) is from an unauthorized account ({address})")
}
}
Expand Down
22 changes: 16 additions & 6 deletions ledger/src/get.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@
use super::*;

impl<N: Network, C: ConsensusStorage<N>> Ledger<N, C> {
/// Returns the committee for the given `block height`.
pub fn get_committee(&self, block_height: u32) -> Result<Option<Committee<N>>> {
self.vm.committee_store().get_committee(block_height)
}

/// Returns the committee for the given `round`.
pub fn get_committee_for_round(&self, round: u64) -> Result<Option<Committee<N>>> {
self.vm.committee_store().get_committee_for_round(round)
}

/// Returns the state root that contains the given `block height`.
pub fn get_state_root(&self, block_height: u32) -> Result<Option<N::StateRoot>> {
self.vm.block_store().get_state_root(block_height)
Expand All @@ -41,7 +51,7 @@ impl<N: Network, C: ConsensusStorage<N>> Ledger<N, C> {
pub fn get_block(&self, height: u32) -> Result<Block<N>> {
// If the height is 0, return the genesis block.
if height == 0 {
return Ok(self.genesis.clone());
return Ok(self.genesis_block.clone());
}
// Retrieve the block hash.
let block_hash = match self.vm.block_store().get_block_hash(height)? {
Expand Down Expand Up @@ -82,7 +92,7 @@ impl<N: Network, C: ConsensusStorage<N>> Ledger<N, C> {
pub fn get_hash(&self, height: u32) -> Result<N::BlockHash> {
// If the height is 0, return the genesis block hash.
if height == 0 {
return Ok(self.genesis.hash());
return Ok(self.genesis_block.hash());
}
match self.vm.block_store().get_block_hash(height)? {
Some(block_hash) => Ok(block_hash),
Expand All @@ -106,7 +116,7 @@ impl<N: Network, C: ConsensusStorage<N>> Ledger<N, C> {
pub fn get_header(&self, height: u32) -> Result<Header<N>> {
// If the height is 0, return the genesis block header.
if height == 0 {
return Ok(*self.genesis.header());
return Ok(*self.genesis_block.header());
}
// Retrieve the block hash.
let block_hash = match self.vm.block_store().get_block_hash(height)? {
Expand All @@ -124,7 +134,7 @@ impl<N: Network, C: ConsensusStorage<N>> Ledger<N, C> {
pub fn get_transactions(&self, height: u32) -> Result<Transactions<N>> {
// If the height is 0, return the genesis block transactions.
if height == 0 {
return Ok(self.genesis.transactions().clone());
return Ok(self.genesis_block.transactions().clone());
}
// Retrieve the block hash.
let block_hash = match self.vm.block_store().get_block_hash(height)? {
Expand Down Expand Up @@ -168,7 +178,7 @@ impl<N: Network, C: ConsensusStorage<N>> Ledger<N, C> {
pub fn get_coinbase(&self, height: u32) -> Result<Option<CoinbaseSolution<N>>> {
// If the height is 0, return the genesis block solutions.
if height == 0 {
return Ok(self.genesis.coinbase().cloned());
return Ok(self.genesis_block.coinbase().cloned());
}
// Retrieve the block hash.
let block_hash = match self.vm.block_store().get_block_hash(height)? {
Expand All @@ -183,7 +193,7 @@ impl<N: Network, C: ConsensusStorage<N>> Ledger<N, C> {
pub fn get_authority(&self, height: u32) -> Result<Authority<N>> {
// If the height is 0, return the genesis block authority.
if height == 0 {
return Ok(self.genesis.authority().clone());
return Ok(self.genesis_block.authority().clone());
}
// Retrieve the block hash.
let block_hash = match self.vm.block_store().get_block_hash(height)? {
Expand Down
65 changes: 28 additions & 37 deletions ledger/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ extern crate tracing;
pub use ledger_authority as authority;
pub use ledger_block as block;
pub use ledger_coinbase as coinbase;
pub use ledger_committee as committee;
pub use ledger_narwhal as narwhal;
pub use ledger_query as query;
pub use ledger_store as store;
Expand Down Expand Up @@ -61,6 +62,7 @@ use console::{
use ledger_authority::Authority;
use ledger_block::{Block, ConfirmedTransaction, Header, Metadata, Ratify, Transaction, Transactions};
use ledger_coinbase::{CoinbasePuzzle, CoinbaseSolution, EpochChallenge, ProverSolution, PuzzleCommitment};
use ledger_committee::Committee;
use ledger_narwhal::{Subdag, Transmission, TransmissionID};
use ledger_query::Query;
use ledger_store::{ConsensusStorage, ConsensusStore};
Expand All @@ -72,7 +74,7 @@ use synthesizer::{
use aleo_std::prelude::{finish, lap, timer};
use anyhow::Result;
use core::ops::Range;
use indexmap::{IndexMap, IndexSet};
use indexmap::IndexMap;
use parking_lot::RwLock;
use rand::{prelude::IteratorRandom, rngs::OsRng};
use std::{borrow::Cow, sync::Arc};
Expand Down Expand Up @@ -102,26 +104,24 @@ pub struct Ledger<N: Network, C: ConsensusStorage<N>> {
/// The VM state.
vm: VM<N, C>,
/// The genesis block.
genesis: Block<N>,
genesis_block: Block<N>,
/// The coinbase puzzle.
coinbase_puzzle: CoinbasePuzzle<N>,
/// The current block.
current_block: Arc<RwLock<Block<N>>>,
/// The current epoch challenge.
current_epoch_challenge: Arc<RwLock<Option<EpochChallenge<N>>>>,
/// The current committee.
current_committee: Arc<RwLock<IndexSet<Address<N>>>>,
/// The current block.
current_block: Arc<RwLock<Block<N>>>,
}

impl<N: Network, C: ConsensusStorage<N>> Ledger<N, C> {
/// Loads the ledger from storage.
pub fn load(genesis: Block<N>, dev: Option<u16>) -> Result<Self> {
pub fn load(genesis_block: Block<N>, dev: Option<u16>) -> Result<Self> {
let timer = timer!("Ledger::load");

// Retrieve the genesis hash.
let genesis_hash = genesis.hash();
let genesis_hash = genesis_block.hash();
// Initialize the ledger.
let ledger = Self::load_unchecked(genesis, dev)?;
let ledger = Self::load_unchecked(genesis_block, dev)?;

// Ensure the ledger contains the correct genesis block.
if !ledger.contains_block_hash(&genesis_hash)? {
Expand All @@ -147,7 +147,7 @@ impl<N: Network, C: ConsensusStorage<N>> Ledger<N, C> {
}

/// Loads the ledger from storage, without performing integrity checks.
pub fn load_unchecked(genesis: Block<N>, dev: Option<u16>) -> Result<Self> {
pub fn load_unchecked(genesis_block: Block<N>, dev: Option<u16>) -> Result<Self> {
let timer = timer!("Ledger::load_unchecked");

// Initialize the consensus store.
Expand All @@ -164,20 +164,16 @@ impl<N: Network, C: ConsensusStorage<N>> Ledger<N, C> {
// Initialize the ledger.
let mut ledger = Self {
vm,
genesis: genesis.clone(),
genesis_block: genesis_block.clone(),
coinbase_puzzle: CoinbasePuzzle::<N>::load()?,
current_block: Arc::new(RwLock::new(genesis.clone())),
current_epoch_challenge: Default::default(),
current_committee: Default::default(),
current_block: Arc::new(RwLock::new(genesis_block.clone())),
};

// Add the genesis validator to the committee.
ledger.current_committee.write().insert(genesis.authority().to_address());

// If the block store is empty, initialize the genesis block.
if ledger.vm.block_store().heights().max().is_none() {
// Add the genesis block.
ledger.advance_to_next_block(&genesis)?;
ledger.advance_to_next_block(&genesis_block)?;
}
lap!(timer, "Initialize genesis");

Expand All @@ -199,11 +195,6 @@ impl<N: Network, C: ConsensusStorage<N>> Ledger<N, C> {
Ok(ledger)
}

/// TODO: Delete this after testing for snarkOS team.
pub fn insert_committee_member(&self, address: Address<N>) {
self.current_committee.write().insert(address);
}

/// Returns the VM.
pub const fn vm(&self) -> &VM<N, C> {
&self.vm
Expand All @@ -215,15 +206,28 @@ impl<N: Network, C: ConsensusStorage<N>> Ledger<N, C> {
}

/// Returns the latest committee.
pub fn latest_committee(&self) -> IndexSet<Address<N>> {
self.current_committee.read().clone()
pub fn latest_committee(&self) -> Result<Committee<N>> {
self.vm.committee_store().current_committee()
}

/// Returns the latest state root.
pub fn latest_state_root(&self) -> N::StateRoot {
self.vm.block_store().current_state_root()
}

/// Returns the latest epoch number.
pub fn latest_epoch_number(&self) -> u32 {
self.current_block.read().height() / N::NUM_BLOCKS_PER_EPOCH
}

/// Returns the latest epoch challenge.
pub fn latest_epoch_challenge(&self) -> Result<EpochChallenge<N>> {
match self.current_epoch_challenge.read().as_ref() {
Some(challenge) => Ok(challenge.clone()),
None => self.get_epoch_challenge(self.latest_height()),
}
}

/// Returns the latest block.
pub fn latest_block(&self) -> Block<N> {
self.current_block.read().clone()
Expand Down Expand Up @@ -298,19 +302,6 @@ impl<N: Network, C: ConsensusStorage<N>> Ledger<N, C> {
pub fn latest_transactions(&self) -> Transactions<N> {
self.current_block.read().transactions().clone()
}

/// Returns the latest epoch number.
pub fn latest_epoch_number(&self) -> u32 {
self.current_block.read().height() / N::NUM_BLOCKS_PER_EPOCH
}

/// Returns the latest epoch challenge.
pub fn latest_epoch_challenge(&self) -> Result<EpochChallenge<N>> {
match self.current_epoch_challenge.read().as_ref() {
Some(challenge) => Ok(challenge.clone()),
None => self.get_epoch_challenge(self.latest_height()),
}
}
}

impl<N: Network, C: ConsensusStorage<N>> Ledger<N, C> {
Expand Down
7 changes: 7 additions & 0 deletions synthesizer/src/vm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ use ledger_query::Query;
use ledger_store::{
atomic_finalize,
BlockStore,
CommitteeStore,
ConsensusStorage,
ConsensusStore,
FinalizeMode,
Expand Down Expand Up @@ -145,6 +146,12 @@ impl<N: Network, C: ConsensusStorage<N>> VM<N, C> {
}

impl<N: Network, C: ConsensusStorage<N>> VM<N, C> {
/// Returns the committee store.
#[inline]
pub fn committee_store(&self) -> &CommitteeStore<N, C::CommitteeStorage> {
self.store.committee_store()
}

/// Returns the finalize store.
#[inline]
pub fn finalize_store(&self) -> &FinalizeStore<N, C::FinalizeStorage> {
Expand Down

1 comment on commit 06a44ca

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'snarkVM Benchmarks'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.50.

Benchmark suite Current: 06a44ca Previous: 6121a7b Ratio
bls12_377: fq2_add_assign 48 ns/iter (± 0) 22 ns/iter (± 0) 2.18

This comment was automatically generated by workflow using github-action-benchmark.

CC: @raychu86

Please sign in to comment.