Skip to content

Commit

Permalink
GRPC entrypoint to download a certificate
Browse files Browse the repository at this point in the history
  • Loading branch information
ndr-ds committed May 31, 2024
1 parent cf27151 commit 7a20c90
Show file tree
Hide file tree
Showing 12 changed files with 295 additions and 23 deletions.
12 changes: 10 additions & 2 deletions linera-core/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@

use futures::stream::{BoxStream, LocalBoxStream, Stream};
use linera_base::{
crypto::CryptoError,
crypto::{CryptoError, CryptoHash},
data_types::{ArithmeticError, Blob, BlockHeight, HashedBlob},
identifiers::{BlobId, ChainId},
};
use linera_chain::{
data_types::{BlockProposal, Certificate, HashedCertificateValue, LiteCertificate, Origin},
data_types::{
BlockProposal, Certificate, CertificateValue, HashedCertificateValue, LiteCertificate,
Origin,
},
ChainError,
};
use linera_execution::{
Expand Down Expand Up @@ -82,6 +85,11 @@ pub trait LocalValidatorNode {
) -> Result<Self::NotificationStream, NodeError>;

async fn download_blob(&mut self, blob_id: BlobId) -> Result<Blob, NodeError>;

async fn download_certificate_value(
&mut self,
hash: CryptoHash,
) -> Result<CertificateValue, NodeError>;
}

/// Turn an address into a validator node.
Expand Down
28 changes: 27 additions & 1 deletion linera-core/src/unit_tests/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use linera_base::{
identifiers::{BlobId, ChainDescription, ChainId},
};
use linera_chain::data_types::{
BlockProposal, Certificate, HashedCertificateValue, LiteCertificate,
BlockProposal, Certificate, CertificateValue, HashedCertificateValue, LiteCertificate,
};
use linera_execution::{
committee::{Committee, ValidatorName},
Expand Down Expand Up @@ -163,6 +163,16 @@ where
self.spawn_and_receive(move |validator, sender| validator.do_download_blob(blob_id, sender))
.await
}

async fn download_certificate_value(
&mut self,
hash: CryptoHash,
) -> Result<CertificateValue, NodeError> {
self.spawn_and_receive(move |validator, sender| {
validator.do_download_certificate_value(hash, sender)
})
.await
}
}

impl<S> LocalValidatorClient<S>
Expand Down Expand Up @@ -344,6 +354,22 @@ where
.map_err(Into::into);
sender.send(hashed_blob.map(|hashed_blob| hashed_blob.blob().clone()))
}

async fn do_download_certificate_value(
self,
hash: CryptoHash,
sender: oneshot::Sender<Result<CertificateValue, NodeError>>,
) -> Result<(), Result<CertificateValue, NodeError>> {
let validator = self.client.lock().await;
let certificate = validator
.state
.storage_client()
.read_hashed_certificate_value(hash)
.await
.map(Into::into)
.map_err(Into::into);
sender.send(certificate)
}
}

#[derive(Clone)]
Expand Down
33 changes: 33 additions & 0 deletions linera-rpc/proto/rpc.proto
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ service ValidatorNode {

// Downloads a blob.
rpc DownloadBlob(BlobId) returns (Blob);

// Downloads a certificate value.
rpc DownloadCertificateValue(CryptoHash) returns (CertificateValue);
}

// Information about the Linera crate version the validator is running
Expand Down Expand Up @@ -224,6 +227,28 @@ message Certificate {
bytes blobs = 7;
}

message CertificateValue {
oneof inner {
ValidatedBlock validated_block = 1;
ConfirmedBlock confirmed_block = 2;
Timeout timeout = 3;
}
}

message ValidatedBlock {
bytes executed_block = 1;
}

message ConfirmedBlock {
bytes executed_block = 1;
}

message Timeout {
ChainId chain_id = 1;
BlockHeight height = 2;
Epoch epoch = 3;
}

message ChainId {
bytes bytes = 1;
}
Expand All @@ -232,6 +257,10 @@ message PublicKey {
bytes bytes = 1;
}

message CryptoHash {
bytes bytes = 1;
}

message Owner {
bytes bytes = 1;
}
Expand Down Expand Up @@ -262,3 +291,7 @@ message ChainInfoResponse {
message BlockHeight {
uint64 height = 1;
}

message Epoch {
uint32 epoch = 1;
}
15 changes: 14 additions & 1 deletion linera-rpc/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
// SPDX-License-Identifier: Apache-2.0

use linera_base::{
crypto::CryptoHash,
data_types::{Blob, HashedBlob},
identifiers::{BlobId, ChainId},
};
use linera_chain::data_types::{
BlockProposal, Certificate, HashedCertificateValue, LiteCertificate,
BlockProposal, Certificate, CertificateValue, HashedCertificateValue, LiteCertificate,
};
#[cfg(web)]
use linera_core::node::{
Expand Down Expand Up @@ -153,4 +154,16 @@ impl ValidatorNode for Client {
Client::Simple(simple_client) => simple_client.download_blob(blob_id).await?,
})
}

async fn download_certificate_value(
&mut self,
hash: CryptoHash,
) -> Result<CertificateValue, NodeError> {
Ok(match self {
Client::Grpc(grpc_client) => grpc_client.download_certificate_value(hash).await?,

#[cfg(with_simple_network)]
Client::Simple(simple_client) => simple_client.download_certificate_value(hash).await?,
})
}
}
16 changes: 15 additions & 1 deletion linera-rpc/src/grpc/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ use std::{iter, time::Duration};

use futures::{future, stream, StreamExt};
use linera_base::{
crypto::CryptoHash,
data_types::{Blob, HashedBlob},
identifiers::{BlobId, ChainId},
};
use linera_chain::data_types;
use linera_chain::data_types::{self, CertificateValue};
#[cfg(web)]
use linera_core::node::{
LocalNotificationStream as NotificationStream, LocalValidatorNode as ValidatorNode,
Expand Down Expand Up @@ -274,6 +275,19 @@ impl ValidatorNode for GrpcClient {
.into_inner()
.into())
}

#[instrument(target = "grpc_client", skip_all, err, fields(address = self.address))]
async fn download_certificate_value(
&mut self,
hash: CryptoHash,
) -> Result<CertificateValue, NodeError> {
Ok(self
.client
.download_certificate_value(<CryptoHash as Into<api::CryptoHash>>::into(hash))
.await?
.into_inner()
.try_into()?)
}
}

#[cfg(not(web))]
Expand Down
116 changes: 114 additions & 2 deletions linera-rpc/src/grpc/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ use linera_base::{
identifiers::{BlobId, ChainId, Owner},
};
use linera_chain::data_types::{
BlockAndRound, BlockProposal, Certificate, HashedCertificateValue, LiteCertificate, LiteValue,
BlockAndRound, BlockProposal, Certificate, CertificateValue, HashedCertificateValue,
LiteCertificate, LiteValue,
};
use linera_core::{
data_types::{ChainInfoQuery, ChainInfoResponse, CrossChainRequest},
node::NodeError,
worker::Notification,
};
use linera_execution::committee::ValidatorName;
use linera_execution::committee::{Epoch, ValidatorName};
use thiserror::Error;
use tonic::{Code, Status};

Expand Down Expand Up @@ -50,6 +51,14 @@ impl From<GrpcProtoConversionError> for Status {
}
}

impl From<GrpcProtoConversionError> for NodeError {
fn from(error: GrpcProtoConversionError) -> Self {
NodeError::GrpcError {
error: error.to_string(),
}
}
}

impl From<linera_version::CrateVersion> for api::CrateVersion {
fn from(
linera_version::CrateVersion {
Expand Down Expand Up @@ -514,6 +523,18 @@ impl From<api::BlockHeight> for BlockHeight {
}
}

impl From<api::Epoch> for Epoch {
fn from(epoch: api::Epoch) -> Self {
Self(epoch.epoch)
}
}

impl From<Epoch> for api::Epoch {
fn from(epoch: Epoch) -> Self {
Self { epoch: epoch.0 }
}
}

impl From<Owner> for api::Owner {
fn from(owner: Owner) -> Self {
Self {
Expand Down Expand Up @@ -546,6 +567,14 @@ impl From<BlobId> for api::BlobId {
}
}

impl TryFrom<api::CryptoHash> for CryptoHash {
type Error = GrpcProtoConversionError;

fn try_from(hash: api::CryptoHash) -> Result<Self, Self::Error> {
Ok(CryptoHash::try_from(hash.bytes.as_slice())?)
}
}

impl From<Blob> for api::Blob {
fn from(blob: Blob) -> Self {
Self { bytes: blob.bytes }
Expand All @@ -558,6 +587,89 @@ impl From<api::Blob> for Blob {
}
}

impl TryFrom<api::CertificateValue> for CertificateValue {
type Error = GrpcProtoConversionError;

fn try_from(certificate: api::CertificateValue) -> Result<Self, Self::Error> {
use api::certificate_value::Inner;

Ok(
match certificate
.inner
.ok_or(GrpcProtoConversionError::MissingField)?
{
Inner::ConfirmedBlock(api::ConfirmedBlock { executed_block }) => {
CertificateValue::ConfirmedBlock {
executed_block: bincode::deserialize(&executed_block)?,
}
}
Inner::ValidatedBlock(api::ValidatedBlock { executed_block }) => {
CertificateValue::ValidatedBlock {
executed_block: bincode::deserialize(&executed_block)?,
}
}
Inner::Timeout(api::Timeout {
chain_id,
height,
epoch,
}) => CertificateValue::Timeout {
chain_id: try_proto_convert(chain_id)?,
height: height.ok_or(GrpcProtoConversionError::MissingField)?.into(),
epoch: epoch.ok_or(GrpcProtoConversionError::MissingField)?.into(),
},
},
)
}
}

impl TryFrom<CertificateValue> for api::CertificateValue {
type Error = GrpcProtoConversionError;

fn try_from(certificate: CertificateValue) -> Result<Self, Self::Error> {
use api::certificate_value::Inner;

let inner = match certificate {
CertificateValue::ConfirmedBlock { executed_block } => {
Inner::ConfirmedBlock(api::ConfirmedBlock {
executed_block: bincode::serialize(&executed_block)?,
})
}
CertificateValue::ValidatedBlock { executed_block } => {
Inner::ValidatedBlock(api::ValidatedBlock {
executed_block: bincode::serialize(&executed_block)?,
})
}
CertificateValue::Timeout {
chain_id,
height,
epoch,
} => Inner::Timeout(api::Timeout {
chain_id: Some(chain_id.into()),
height: Some(height.into()),
epoch: Some(epoch.into()),
}),
};

Ok(Self { inner: Some(inner) })
}
}

impl TryFrom<HashedCertificateValue> for api::CertificateValue {
type Error = GrpcProtoConversionError;

fn try_from(hv: HashedCertificateValue) -> Result<Self, Self::Error> {
<HashedCertificateValue as Into<CertificateValue>>::into(hv).try_into()
}
}

impl From<CryptoHash> for api::CryptoHash {
fn from(hash: CryptoHash) -> Self {
Self {
bytes: hash.as_bytes().to_vec(),
}
}
}

#[cfg(test)]
pub mod tests {
use std::{borrow::Cow, fmt::Debug};
Expand Down
Loading

0 comments on commit 7a20c90

Please sign in to comment.