Skip to content

Commit

Permalink
Use standalone structs in CertificateValue enum (#2868)
Browse files Browse the repository at this point in the history
* Use standalone structs in CertificateValue enum

* Update format.yaml

* Make ConfirmedBlock constructor available under benchmark feature

* cargo fmt part 2

* enable benchmark feature from linera-chain

* Format linera-service/Cargo.toml
  • Loading branch information
deuszx authored Nov 13, 2024
1 parent 65eb2f7 commit 8baa3d2
Show file tree
Hide file tree
Showing 12 changed files with 90 additions and 108 deletions.
1 change: 1 addition & 0 deletions linera-chain/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ version.workspace = true
test = ["tokio/macros", "linera-base/test", "linera-execution/test"]
metrics = ["prometheus", "linera-views/metrics", "linera-execution/metrics"]
web = ["linera-base/web", "linera-views/web", "linera-execution/web"]
benchmark = ["linera-base/test"]

[dependencies]
async-graphql.workspace = true
Expand Down
6 changes: 6 additions & 0 deletions linera-chain/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,16 @@ impl From<ConfirmedBlock> for HashedCertificateValue {
impl BcsHashable for ConfirmedBlock {}

impl ConfirmedBlock {
#[cfg(not(feature = "benchmark"))]
pub(super) fn new(executed_block: ExecutedBlock) -> Self {
Self { executed_block }
}

#[cfg(feature = "benchmark")]
pub fn new(executed_block: ExecutedBlock) -> Self {
Self { executed_block }
}

/// Creates a new `ConfirmedBlock` from a `ValidatedBlock`.
/// Note: There's no `new` method for `ConfirmedBlock` because it's
/// only created from a `ValidatedBlock`.
Expand Down
16 changes: 6 additions & 10 deletions linera-chain/src/certificate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,8 +346,8 @@ impl From<Certificate> for ValidatedBlockCertificate {
let signatures = cert.signatures().clone();
let hash = cert.value.hash();
match cert.value.into_inner() {
CertificateValue::ValidatedBlock { executed_block } => Self {
value: Hashed::unchecked_new(ValidatedBlock::new(executed_block), hash),
CertificateValue::ValidatedBlock(validated) => Self {
value: Hashed::unchecked_new(validated, hash),
round: cert.round,
signatures,
},
Expand Down Expand Up @@ -409,8 +409,8 @@ impl TryFrom<Certificate> for ConfirmedBlockCertificate {
let signatures = cert.signatures().clone();
let hash = cert.value.hash();
match cert.value.into_inner() {
CertificateValue::ConfirmedBlock { executed_block } => Ok(Self {
value: Hashed::unchecked_new(ConfirmedBlock::new(executed_block), hash),
CertificateValue::ConfirmedBlock(confirmed) => Ok(Self {
value: Hashed::unchecked_new(confirmed, hash),
round: cert.round,
signatures,
}),
Expand All @@ -424,12 +424,8 @@ impl From<Certificate> for TimeoutCertificate {
let signatures = cert.signatures().clone();
let hash = cert.value.hash();
match cert.value.into_inner() {
CertificateValue::Timeout {
chain_id,
epoch,
height,
} => Self {
value: Hashed::unchecked_new(Timeout::new(chain_id, height, epoch), hash),
CertificateValue::Timeout(timeout) => Self {
value: Hashed::unchecked_new(timeout, hash),
round: cert.round,
signatures,
},
Expand Down
62 changes: 23 additions & 39 deletions linera-chain/src/data_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use linera_execution::{
use serde::{de::Deserializer, Deserialize, Serialize};

use crate::{
block::{ConfirmedBlock, Timeout, ValidatedBlock},
types::{Hashed, ValidatedBlockCertificate},
ChainError,
};
Expand Down Expand Up @@ -396,17 +397,9 @@ pub struct EventRecord {
/// A statement to be certified by the validators.
#[derive(Debug, PartialEq, Eq, Hash, Clone, Deserialize, Serialize)]
pub enum CertificateValue {
ValidatedBlock {
executed_block: ExecutedBlock,
},
ConfirmedBlock {
executed_block: ExecutedBlock,
},
Timeout {
chain_id: ChainId,
height: BlockHeight,
epoch: Epoch,
},
ValidatedBlock(ValidatedBlock),
ConfirmedBlock(ConfirmedBlock),
Timeout(Timeout),
}

#[async_graphql::Object(cache_control(no_cache))]
Expand Down Expand Up @@ -692,29 +685,25 @@ impl From<HashedCertificateValue> for CertificateValue {
impl CertificateValue {
pub fn chain_id(&self) -> ChainId {
match self {
CertificateValue::ConfirmedBlock { executed_block, .. }
| CertificateValue::ValidatedBlock { executed_block, .. } => {
executed_block.block.chain_id
}
CertificateValue::Timeout { chain_id, .. } => *chain_id,
CertificateValue::ConfirmedBlock(confirmed) => confirmed.inner().block.chain_id,
CertificateValue::ValidatedBlock(validated) => validated.inner().block.chain_id,
CertificateValue::Timeout(Timeout { chain_id, .. }) => *chain_id,
}
}

pub fn height(&self) -> BlockHeight {
match self {
CertificateValue::ConfirmedBlock { executed_block, .. }
| CertificateValue::ValidatedBlock { executed_block, .. } => {
executed_block.block.height
}
CertificateValue::Timeout { height, .. } => *height,
CertificateValue::ConfirmedBlock(confirmed) => confirmed.inner().block.height,
CertificateValue::ValidatedBlock(validated) => validated.inner().block.height,
CertificateValue::Timeout(Timeout { height, .. }) => *height,
}
}

pub fn epoch(&self) -> Epoch {
match self {
CertificateValue::ConfirmedBlock { executed_block, .. }
| CertificateValue::ValidatedBlock { executed_block, .. } => executed_block.block.epoch,
CertificateValue::Timeout { epoch, .. } => *epoch,
CertificateValue::ConfirmedBlock(confirmed) => confirmed.inner().block.epoch,
CertificateValue::ValidatedBlock(validated) => validated.inner().block.epoch,
CertificateValue::Timeout(Timeout { epoch, .. }) => *epoch,
}
}

Expand Down Expand Up @@ -761,9 +750,9 @@ impl CertificateValue {

pub fn executed_block(&self) -> Option<&ExecutedBlock> {
match self {
CertificateValue::ConfirmedBlock { executed_block, .. }
| CertificateValue::ValidatedBlock { executed_block, .. } => Some(executed_block),
CertificateValue::Timeout { .. } => None,
CertificateValue::ConfirmedBlock(confirmed) => Some(confirmed.inner()),
CertificateValue::ValidatedBlock(validated) => Some(validated.inner()),
CertificateValue::Timeout(_) => None,
}
}

Expand Down Expand Up @@ -964,12 +953,12 @@ impl BlockExecutionOutcome {
impl HashedCertificateValue {
/// Creates a [`ConfirmedBlock`](CertificateValue::ConfirmedBlock) value.
pub fn new_confirmed(executed_block: ExecutedBlock) -> HashedCertificateValue {
CertificateValue::ConfirmedBlock { executed_block }.into()
CertificateValue::ConfirmedBlock(ConfirmedBlock::new(executed_block)).into()
}

/// Creates a [`ValidatedBlock`](CertificateValue::ValidatedBlock) value.
pub fn new_validated(executed_block: ExecutedBlock) -> HashedCertificateValue {
CertificateValue::ValidatedBlock { executed_block }.into()
CertificateValue::ValidatedBlock(ValidatedBlock::new(executed_block)).into()
}

/// Creates a [`Timeout`](CertificateValue::Timeout) value.
Expand All @@ -978,12 +967,7 @@ impl HashedCertificateValue {
height: BlockHeight,
epoch: Epoch,
) -> HashedCertificateValue {
CertificateValue::Timeout {
chain_id,
height,
epoch,
}
.into()
CertificateValue::Timeout(Timeout::new(chain_id, height, epoch)).into()
}

pub fn lite(&self) -> LiteValue {
Expand All @@ -996,10 +980,10 @@ impl HashedCertificateValue {
/// Returns the corresponding `ConfirmedBlock`, if this is a `ValidatedBlock`.
pub fn validated_to_confirmed(&self) -> Option<HashedCertificateValue> {
match self.inner() {
CertificateValue::ValidatedBlock { executed_block } => Some(
HashedCertificateValue::new_confirmed(executed_block.clone()),
),
CertificateValue::ConfirmedBlock { .. } | CertificateValue::Timeout { .. } => None,
CertificateValue::ValidatedBlock(validated) => {
Some(ConfirmedBlock::from_validated(validated.clone()).into())
}
CertificateValue::ConfirmedBlock(_) | CertificateValue::Timeout(_) => None,
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions linera-chain/src/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,15 +342,15 @@ impl ChainManager {
let new_round = certificate.round;
if let Some(Vote { value, round, .. }) = &self.pending {
match value.inner() {
CertificateValue::ConfirmedBlock { executed_block } => {
if &executed_block.block == new_block && *round == new_round {
CertificateValue::ConfirmedBlock(confirmed) => {
if &confirmed.inner().block == new_block && *round == new_round {
return Ok(Outcome::Skip); // We already voted to confirm this block.
}
}
CertificateValue::ValidatedBlock { .. } => {
CertificateValue::ValidatedBlock(_) => {
ensure!(new_round >= *round, ChainError::InsufficientRound(*round))
}
CertificateValue::Timeout { .. } => {
CertificateValue::Timeout(_) => {
// Unreachable: We only put validated or confirmed blocks in pending.
return Err(ChainError::InternalError(
"pending can only be validated or confirmed block".to_string(),
Expand Down
8 changes: 3 additions & 5 deletions linera-core/src/local_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,11 +205,9 @@ where

// Find the missing blobs locally and retry.
let required = match certificate.value() {
CertificateValue::ConfirmedBlock { executed_block, .. }
| CertificateValue::ValidatedBlock { executed_block, .. } => {
executed_block.required_blob_ids()
}
CertificateValue::Timeout { .. } => HashSet::new(),
CertificateValue::ConfirmedBlock(confirmed) => confirmed.inner().required_blob_ids(),
CertificateValue::ValidatedBlock(validated) => validated.inner().required_blob_ids(),
CertificateValue::Timeout(_) => HashSet::new(),
};
for blob_id in missing_blob_ids {
if !required.contains(blob_id) {
Expand Down
7 changes: 2 additions & 5 deletions linera-core/src/unit_tests/client_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use linera_base::{
};
use linera_chain::{
data_types::{CertificateValue, IncomingBundle, Medium, MessageBundle, Origin, PostedMessage},
types::Timeout,
ChainError, ChainExecutionContext,
};
use linera_execution::{
Expand Down Expand Up @@ -2012,11 +2013,7 @@ where
let certificate = client.request_leader_timeout().await.unwrap();
assert_eq!(
*certificate.value(),
CertificateValue::Timeout {
chain_id,
height: BlockHeight::from(1),
epoch: Epoch::ZERO
}
CertificateValue::Timeout(Timeout::new(chain_id, BlockHeight::from(1), Epoch::ZERO))
);
assert_eq!(certificate.round, Round::SingleLeader(0));

Expand Down
43 changes: 22 additions & 21 deletions linera-core/src/unit_tests/value_cache_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ use linera_base::{
data_types::{Blob, BlockHeight, Timestamp},
identifiers::{BlobId, ChainId},
};
use linera_chain::data_types::{
Block, BlockExecutionOutcome, CertificateValue, ExecutedBlock, HashedCertificateValue,
use linera_chain::{
data_types::{
Block, BlockExecutionOutcome, CertificateValue, ExecutedBlock, HashedCertificateValue,
},
types::{Timeout, ValidatedBlock},
};
use linera_execution::committee::Epoch;

Expand Down Expand Up @@ -518,11 +521,11 @@ fn create_dummy_blobs() -> Vec<Blob> {

/// Creates a new dummy [`HashedCertificateValue`] to use in the tests.
fn create_dummy_certificate_value(height: impl Into<BlockHeight>) -> HashedCertificateValue {
CertificateValue::Timeout {
chain_id: ChainId(CryptoHash::test_hash("Fake chain ID")),
height: height.into(),
epoch: Epoch(0),
}
CertificateValue::Timeout(Timeout::new(
ChainId(CryptoHash::test_hash("Fake chain ID")),
height.into(),
Epoch(0),
))
.into()
}

Expand All @@ -533,20 +536,18 @@ fn create_dummy_blob(id: usize) -> Blob {

/// Creates a dummy [`HashedCertificateValue::ValidatedBlock`] to use in the tests.
fn create_dummy_validated_block_value() -> HashedCertificateValue {
CertificateValue::ValidatedBlock {
executed_block: ExecutedBlock {
block: Block {
chain_id: ChainId(CryptoHash::test_hash("Fake chain ID")),
epoch: Epoch::ZERO,
incoming_bundles: vec![],
operations: vec![],
height: BlockHeight::ZERO,
timestamp: Timestamp::from(0),
authenticated_signer: None,
previous_block_hash: None,
},
outcome: BlockExecutionOutcome::default(),
CertificateValue::ValidatedBlock(ValidatedBlock::new(ExecutedBlock {
block: Block {
chain_id: ChainId(CryptoHash::test_hash("Fake chain ID")),
epoch: Epoch::ZERO,
incoming_bundles: vec![],
operations: vec![],
height: BlockHeight::ZERO,
timestamp: Timestamp::from(0),
authenticated_signer: None,
previous_block_hash: None,
},
}
outcome: BlockExecutionOutcome::default(),
}))
.into()
}
8 changes: 3 additions & 5 deletions linera-core/src/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -765,13 +765,11 @@ where
let (info, actions, _) = validation_outcomes;
(info, actions)
}
CertificateValue::ConfirmedBlock {
executed_block: _executed_block,
} => {
CertificateValue::ConfirmedBlock(_confirmed) => {
#[cfg(with_metrics)]
{
confirmed_transactions = (_executed_block.block.incoming_bundles.len()
+ _executed_block.block.operations.len())
confirmed_transactions = (_confirmed.inner().block.incoming_bundles.len()
+ _confirmed.inner().block.operations.len())
as u64;
}
let confirmed_block_certificate: ConfirmedBlockCertificate =
Expand Down
23 changes: 10 additions & 13 deletions linera-rpc/tests/snapshots/format__format.yaml.snap
Original file line number Diff line number Diff line change
Expand Up @@ -151,23 +151,16 @@ CertificateValue:
ENUM:
0:
ValidatedBlock:
STRUCT:
- executed_block:
TYPENAME: ExecutedBlock
NEWTYPE:
TYPENAME: ValidatedBlock
1:
ConfirmedBlock:
STRUCT:
- executed_block:
TYPENAME: ExecutedBlock
NEWTYPE:
TYPENAME: ConfirmedBlock
2:
Timeout:
STRUCT:
- chain_id:
TYPENAME: ChainId
- height:
TYPENAME: BlockHeight
- epoch:
TYPENAME: Epoch
NEWTYPE:
TYPENAME: Timeout
ChainAndHeight:
STRUCT:
- chain_id:
Expand Down Expand Up @@ -342,6 +335,10 @@ Committee:
CompressedBytecode:
STRUCT:
- compressed_bytes: BYTES
ConfirmedBlock:
STRUCT:
- executed_block:
TYPENAME: ExecutedBlock
CrateVersion:
STRUCT:
- major: U32
Expand Down
7 changes: 6 additions & 1 deletion linera-service/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ test = [
"linera-execution/test",
"dep:stdext",
]
benchmark = ["linera-base/test", "linera-client/benchmark", "dep:linera-sdk"]
benchmark = [
"linera-base/test",
"linera-client/benchmark",
"linera-chain/benchmark",
"dep:linera-sdk",
]
wasmer = ["linera-client/wasmer", "linera-execution/wasmer", "linera-storage/wasmer"]
wasmtime = [
"linera-client/wasmtime",
Expand Down
Loading

0 comments on commit 8baa3d2

Please sign in to comment.