Skip to content

Commit 0480f57

Browse files
deuszxafck
andauthored
RPC messages work on ConfirmedBlockCertificates (#2976)
* RPC messages work on ConfirmedBlockCertificates * RM singular DownloadCertificate RPC query. * Ensure that we get correct number of certs in resposen. * Don't Box Vectors, * RM unnecessary conversion * Error contains CryptoHash type * Map ConfirmedBlockCertificate to Certificate before serializing * Obliterate CertificateValue for real this time (#2988) * Remove CertificateValue and change Certificate encoding. * Review part 1 * Update linera-chain/src/certificate/mod.rs Co-authored-by: Andreas Fackler <[email protected]> Signed-off-by: deuszx <[email protected]> --------- Signed-off-by: deuszx <[email protected]> Co-authored-by: Andreas Fackler <[email protected]> * Use ensure macro. * Update linera-rpc/src/grpc/client.rs Co-authored-by: Andreas Fackler <[email protected]> Signed-off-by: deuszx <[email protected]> * Import ensure --------- Signed-off-by: deuszx <[email protected]> Co-authored-by: Andreas Fackler <[email protected]>
1 parent 54a0e82 commit 0480f57

File tree

36 files changed

+509
-798
lines changed

36 files changed

+509
-798
lines changed

examples/hex-game/tests/hex_game.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ async fn hex_game() {
3131
})
3232
.await;
3333

34-
let executed_block = certificate.inner().executed_block().unwrap();
34+
let executed_block = certificate.inner().executed_block();
3535
let message_id = executed_block.message_id_for_operation(0, 0).unwrap();
3636
let description = ChainDescription::Child(message_id);
3737
let mut chain = ActiveChain::new(key_pair1.copy(), description, validator);
@@ -105,7 +105,7 @@ async fn hex_game_clock() {
105105
})
106106
.await;
107107

108-
let executed_block = certificate.inner().executed_block().unwrap();
108+
let executed_block = certificate.inner().executed_block();
109109
let message_id = executed_block.message_id_for_operation(0, 0).unwrap();
110110
let description = ChainDescription::Child(message_id);
111111
let mut chain = ActiveChain::new(key_pair1.copy(), description, validator.clone());

linera-chain/src/block.rs

Lines changed: 19 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,7 @@ use linera_execution::committee::Epoch;
1313
use serde::{Deserialize, Serialize};
1414
use thiserror::Error;
1515

16-
use crate::{
17-
data_types::ExecutedBlock,
18-
types::{CertificateValue, Hashed, HashedCertificateValue},
19-
ChainError,
20-
};
16+
use crate::{data_types::ExecutedBlock, types::Hashed, ChainError};
2117

2218
/// Wrapper around an `ExecutedBlock` that has been validated.
2319
#[derive(Debug, PartialEq, Eq, Hash, Clone, Deserialize, Serialize)]
@@ -32,7 +28,7 @@ impl ValidatedBlock {
3228
}
3329

3430
/// Returns a reference to the `ExecutedBlock` contained in this `ValidatedBlock`.
35-
pub fn inner(&self) -> &ExecutedBlock {
31+
pub fn executed_block(&self) -> &ExecutedBlock {
3632
&self.executed_block
3733
}
3834

@@ -48,20 +44,6 @@ impl ValidatedBlock {
4844

4945
impl BcsHashable for ValidatedBlock {}
5046

51-
impl TryFrom<HashedCertificateValue> for Hashed<ValidatedBlock> {
52-
type Error = ConversionError;
53-
54-
fn try_from(value: HashedCertificateValue) -> Result<Self, Self::Error> {
55-
let hash = value.hash();
56-
match value.into_inner() {
57-
CertificateValue::ValidatedBlock(validated) => {
58-
Ok(Hashed::unchecked_new(validated, hash))
59-
}
60-
_ => Err(ConversionError::ValidatedBlock),
61-
}
62-
}
63-
}
64-
6547
/// Wrapper around an `ExecutedBlock` that has been confirmed.
6648
#[derive(Debug, PartialEq, Eq, Hash, Clone, Deserialize, Serialize)]
6749
pub struct ConfirmedBlock {
@@ -94,29 +76,9 @@ impl Hashed<ConfirmedBlock> {
9476
}
9577
}
9678

97-
impl TryFrom<HashedCertificateValue> for Hashed<ConfirmedBlock> {
98-
type Error = ConversionError;
99-
100-
fn try_from(value: HashedCertificateValue) -> Result<Self, Self::Error> {
101-
let hash = value.hash();
102-
match value.into_inner() {
103-
CertificateValue::ConfirmedBlock(confirmed) => {
104-
Ok(Hashed::unchecked_new(confirmed, hash))
105-
}
106-
_ => Err(ConversionError::ConfirmedBlock),
107-
}
108-
}
109-
}
110-
11179
impl BcsHashable for ConfirmedBlock {}
11280

11381
impl ConfirmedBlock {
114-
#[cfg(not(feature = "benchmark"))]
115-
pub(super) fn new(executed_block: ExecutedBlock) -> Self {
116-
Self { executed_block }
117-
}
118-
119-
#[cfg(feature = "benchmark")]
12082
pub fn new(executed_block: ExecutedBlock) -> Self {
12183
Self { executed_block }
12284
}
@@ -140,6 +102,14 @@ impl ConfirmedBlock {
140102
self.executed_block
141103
}
142104

105+
pub fn chain_id(&self) -> ChainId {
106+
self.executed_block.block.chain_id
107+
}
108+
109+
pub fn height(&self) -> BlockHeight {
110+
self.executed_block.block.height
111+
}
112+
143113
pub fn to_log_str(&self) -> &'static str {
144114
"confirmed_block"
145115
}
@@ -189,27 +159,20 @@ impl Timeout {
189159
}
190160
}
191161

192-
impl TryFrom<HashedCertificateValue> for Hashed<Timeout> {
193-
type Error = &'static str;
194-
fn try_from(value: HashedCertificateValue) -> Result<Hashed<Timeout>, Self::Error> {
195-
let hash = value.hash();
196-
match value.into_inner() {
197-
CertificateValue::Timeout(timeout) => Ok(Hashed::unchecked_new(timeout, hash)),
198-
_ => Err("Expected a Timeout value"),
199-
}
200-
}
201-
}
202-
203162
impl BcsHashable for Timeout {}
204163

205-
/// Failure to convert a [`HashedCertificateValue`] into one of the block types.
164+
/// Failure to convert a `Certificate` into one of the expected certificate types.
206165
#[derive(Clone, Copy, Debug, Error)]
207166
pub enum ConversionError {
208-
/// Failure to convert to [`ConfirmedBlock`].
209-
#[error("Expected a `ConfirmedBlock` value")]
167+
/// Failure to convert to [`ConfirmedBlock`] certificate.
168+
#[error("Expected a `ConfirmedBlockCertificate` value")]
210169
ConfirmedBlock,
211170

212-
/// Failure to convert to [`ValidatedBlock`].
213-
#[error("Expected a `ValidatedBlock` value")]
171+
/// Failure to convert to [`ValidatedBlock`] certificate.
172+
#[error("Expected a `ValidatedBlockCertificate` value")]
214173
ValidatedBlock,
174+
175+
/// Failure to convert to [`Timeout`] certificate.
176+
#[error("Expected a `TimeoutCertificate` value")]
177+
Timeout,
215178
}

linera-chain/src/certificate/confirmed.rs

Lines changed: 52 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,21 @@
22
// Copyright (c) Zefchain Labs, Inc.
33
// SPDX-License-Identifier: Apache-2.0
44

5-
use linera_base::identifiers::{BlobId, ChainId, MessageId};
6-
use linera_execution::committee::Epoch;
7-
8-
use super::{
9-
generic::GenericCertificate, hashed::Hashed, Certificate, CertificateValue,
10-
HashedCertificateValue,
5+
use linera_base::{
6+
crypto::Signature,
7+
data_types::Round,
8+
identifiers::{BlobId, ChainId, MessageId},
119
};
10+
use linera_execution::committee::{Epoch, ValidatorName};
11+
use serde::{ser::SerializeStruct, Deserialize, Deserializer, Serialize};
12+
13+
use super::{generic::GenericCertificate, hashed::Hashed, Certificate};
1214
use crate::{
13-
block::{ConfirmedBlock, ConversionError, ValidatedBlock},
15+
block::{ConfirmedBlock, ConversionError},
1416
data_types::{ExecutedBlock, Medium, MessageBundle},
1517
};
1618

1719
impl GenericCertificate<ConfirmedBlock> {
18-
/// Creates a new `ConfirmedBlockCertificate` from a `ValidatedBlockCertificate`.
19-
pub fn from_validated(validated: GenericCertificate<ValidatedBlock>) -> Self {
20-
let round = validated.round;
21-
let validated_block = validated.into_inner();
22-
// To keep the signature checks passing, we need to obtain a hash over the old type.
23-
let old_confirmed = HashedCertificateValue::new_confirmed(validated_block.inner().clone());
24-
let confirmed = ConfirmedBlock::from_validated(validated_block);
25-
let hashed = Hashed::unchecked_new(confirmed, old_confirmed.hash());
26-
27-
Self::new(hashed, round, vec![])
28-
}
29-
3020
/// Returns reference to the `ExecutedBlock` contained in this certificate.
3121
pub fn executed_block(&self) -> &ExecutedBlock {
3222
self.inner().executed_block()
@@ -54,31 +44,61 @@ impl GenericCertificate<ConfirmedBlock> {
5444
pub fn requires_blob(&self, blob_id: &BlobId) -> bool {
5545
self.executed_block().requires_blob(blob_id)
5646
}
47+
48+
#[cfg(with_testing)]
49+
pub fn outgoing_message_count(&self) -> usize {
50+
self.executed_block().messages().iter().map(Vec::len).sum()
51+
}
5752
}
5853

5954
impl TryFrom<Certificate> for GenericCertificate<ConfirmedBlock> {
6055
type Error = ConversionError;
6156

6257
fn try_from(cert: Certificate) -> Result<Self, Self::Error> {
63-
let hash = cert.hash();
64-
let (value, round, signatures) = cert.destructure();
65-
match value.into_inner() {
66-
CertificateValue::ConfirmedBlock(confirmed) => Ok(Self::new(
67-
Hashed::unchecked_new(confirmed, hash),
68-
round,
69-
signatures,
70-
)),
58+
match cert {
59+
Certificate::Confirmed(confirmed) => Ok(confirmed),
7160
_ => Err(ConversionError::ConfirmedBlock),
7261
}
7362
}
7463
}
7564

7665
impl From<GenericCertificate<ConfirmedBlock>> for Certificate {
7766
fn from(cert: GenericCertificate<ConfirmedBlock>) -> Certificate {
78-
let (value, round, signatures) = cert.destructure();
79-
let hash = value.hash();
80-
let value =
81-
Hashed::unchecked_new(CertificateValue::ConfirmedBlock(value.into_inner()), hash);
82-
Certificate::new(value, round, signatures)
67+
Certificate::Confirmed(cert)
68+
}
69+
}
70+
71+
impl Serialize for GenericCertificate<ConfirmedBlock> {
72+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
73+
where
74+
S: serde::Serializer,
75+
{
76+
let mut state = serializer.serialize_struct("ConfirmedBlockCertificate", 3)?;
77+
state.serialize_field("value", self.inner())?;
78+
state.serialize_field("round", &self.round)?;
79+
state.serialize_field("signatures", self.signatures())?;
80+
state.end()
81+
}
82+
}
83+
84+
impl<'de> Deserialize<'de> for GenericCertificate<ConfirmedBlock> {
85+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
86+
where
87+
D: Deserializer<'de>,
88+
{
89+
#[derive(Debug, Deserialize)]
90+
#[serde(rename = "ConfirmedBlockCertificate")]
91+
struct Helper {
92+
value: Hashed<ConfirmedBlock>,
93+
round: Round,
94+
signatures: Vec<(ValidatorName, Signature)>,
95+
}
96+
97+
let helper = Helper::deserialize(deserializer)?;
98+
if !crate::data_types::is_strictly_ordered(&helper.signatures) {
99+
Err(serde::de::Error::custom("Vector is not strictly sorted"))
100+
} else {
101+
Ok(Self::new(helper.value, helper.round, helper.signatures))
102+
}
83103
}
84104
}

0 commit comments

Comments
 (0)