Skip to content

Commit

Permalink
Endpoint to download a Certificate
Browse files Browse the repository at this point in the history
  • Loading branch information
ndr-ds committed Jun 18, 2024
1 parent 26ffd08 commit 3c4df8a
Show file tree
Hide file tree
Showing 12 changed files with 129 additions and 17 deletions.
2 changes: 2 additions & 0 deletions linera-core/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ pub trait LocalValidatorNode {
&mut self,
hash: CryptoHash,
) -> Result<HashedCertificateValue, NodeError>;

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

/// Turn an address into a validator node.
Expand Down
24 changes: 24 additions & 0 deletions linera-core/src/unit_tests/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,13 @@ where
})
.await
}

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

impl<S> LocalValidatorClient<S>
Expand Down Expand Up @@ -364,6 +371,23 @@ where
.map_err(Into::into);
sender.send(certificate_value)
}

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

sender.send(certificate)
}
}

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

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

// Downloads a certificate.
rpc DownloadCertificate(CryptoHash) returns (Certificate);
}

// Information about the Linera crate version the validator is running
Expand Down
9 changes: 9 additions & 0 deletions linera-rpc/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,4 +166,13 @@ impl ValidatorNode for Client {
Client::Simple(simple_client) => simple_client.download_certificate_value(hash).await?,
})
}

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

#[cfg(with_simple_network)]
Client::Simple(simple_client) => simple_client.download_certificate(hash).await?,
})
}
}
14 changes: 12 additions & 2 deletions linera-rpc/src/grpc/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use linera_base::{
data_types::{Blob, HashedBlob},
identifiers::{BlobId, ChainId},
};
use linera_chain::data_types::{self, CertificateValue, HashedCertificateValue};
use linera_chain::data_types::{self, Certificate, CertificateValue, HashedCertificateValue};
#[cfg(web)]
use linera_core::node::{
LocalNotificationStream as NotificationStream, LocalValidatorNode as ValidatorNode,
Expand Down Expand Up @@ -165,7 +165,7 @@ impl ValidatorNode for GrpcClient {
#[instrument(target = "grpc_client", skip_all, err, fields(address = self.address))]
async fn handle_certificate(
&mut self,
certificate: data_types::Certificate,
certificate: Certificate,
hashed_certificate_values: Vec<data_types::HashedCertificateValue>,
hashed_blobs: Vec<HashedBlob>,
delivery: CrossChainMessageDelivery,
Expand Down Expand Up @@ -289,6 +289,16 @@ impl ValidatorNode for GrpcClient {
.try_into()?;
Ok(certificate_value.with_hash_checked(hash)?)
}

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

#[cfg(not(web))]
Expand Down
34 changes: 30 additions & 4 deletions linera-rpc/src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use linera_base::{
data_types::Blob,
identifiers::{BlobId, ChainId},
};
use linera_chain::data_types::{BlockProposal, CertificateValue, LiteVote};
use linera_chain::data_types::{BlockProposal, Certificate, CertificateValue, LiteVote};
use linera_core::{
data_types::{ChainInfoQuery, ChainInfoResponse, CrossChainRequest},
node::NodeError,
Expand All @@ -27,6 +27,7 @@ pub enum RpcMessage {
ChainInfoQuery(Box<ChainInfoQuery>),
DownloadBlob(Box<BlobId>),
DownloadCertificateValue(Box<CryptoHash>),
DownloadCertificate(Box<CryptoHash>),
VersionInfoQuery,

// Outbound
Expand All @@ -36,6 +37,7 @@ pub enum RpcMessage {
VersionInfoResponse(Box<VersionInfo>),
DownloadBlobResponse(Box<Blob>),
DownloadCertificateValueResponse(Box<CertificateValue>),
DownloadCertificateResponse(Box<Certificate>),

// Internal to a validator
CrossChainRequest(Box<CrossChainRequest>),
Expand All @@ -62,7 +64,9 @@ impl RpcMessage {
| DownloadBlob(_)
| DownloadBlobResponse(_)
| DownloadCertificateValue(_)
| DownloadCertificateValueResponse(_) => {
| DownloadCertificateValueResponse(_)
| DownloadCertificate(_)
| DownloadCertificateResponse(_) => {
return None;
}
};
Expand All @@ -76,7 +80,10 @@ impl RpcMessage {
use RpcMessage::*;

match self {
VersionInfoQuery | DownloadBlob(_) | DownloadCertificateValue(_) => true,
VersionInfoQuery
| DownloadBlob(_)
| DownloadCertificateValue(_)
| DownloadCertificate(_) => true,
BlockProposal(_)
| LiteCertificate(_)
| Certificate(_)
Expand All @@ -87,7 +94,8 @@ impl RpcMessage {
| ChainInfoResponse(_)
| VersionInfoResponse(_)
| DownloadBlobResponse(_)
| DownloadCertificateValueResponse(_) => false,
| DownloadCertificateValueResponse(_)
| DownloadCertificateResponse(_) => false,
}
}
}
Expand Down Expand Up @@ -140,6 +148,18 @@ impl TryFrom<RpcMessage> for CertificateValue {
}
}

impl TryFrom<RpcMessage> for Certificate {
type Error = NodeError;
fn try_from(message: RpcMessage) -> Result<Self, Self::Error> {
use RpcMessage::*;
match message {
DownloadCertificateResponse(certificate) => Ok(*certificate),
Error(error) => Err(*error),
_ => Err(NodeError::UnexpectedMessage),
}
}
}

impl From<BlockProposal> for RpcMessage {
fn from(block_proposal: BlockProposal) -> Self {
RpcMessage::BlockProposal(Box::new(block_proposal))
Expand Down Expand Up @@ -205,3 +225,9 @@ impl From<CertificateValue> for RpcMessage {
RpcMessage::DownloadCertificateValueResponse(Box::new(certificate))
}
}

impl From<Certificate> for RpcMessage {
fn from(certificate: Certificate) -> Self {
RpcMessage::DownloadCertificateResponse(Box::new(certificate))
}
}
5 changes: 5 additions & 0 deletions linera-rpc/src/simple/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,11 @@ impl ValidatorNode for SimpleClient {
.await?;
Ok(certificate_value.with_hash_checked(hash)?)
}

async fn download_certificate(&mut self, hash: CryptoHash) -> Result<Certificate, NodeError> {
self.query(RpcMessage::DownloadCertificate(Box::new(hash)))
.await
}
}

#[derive(Clone)]
Expand Down
4 changes: 3 additions & 1 deletion linera-rpc/src/simple/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,9 @@ where
| RpcMessage::DownloadBlob(_)
| RpcMessage::DownloadBlobResponse(_)
| RpcMessage::DownloadCertificateValue(_)
| RpcMessage::DownloadCertificateValueResponse(_) => Err(NodeError::UnexpectedMessage),
| RpcMessage::DownloadCertificateValueResponse(_)
| RpcMessage::DownloadCertificate(_)
| RpcMessage::DownloadCertificateResponse(_) => Err(NodeError::UnexpectedMessage),
};

self.server.packets_processed += 1;
Expand Down
22 changes: 15 additions & 7 deletions linera-rpc/tests/snapshots/format__format.yaml.snap
Original file line number Diff line number Diff line change
Expand Up @@ -766,32 +766,40 @@ RpcMessage:
NEWTYPE:
TYPENAME: CryptoHash
6:
VersionInfoQuery: UNIT
DownloadCertificate:
NEWTYPE:
TYPENAME: CryptoHash
7:
VersionInfoQuery: UNIT
8:
Vote:
NEWTYPE:
TYPENAME: LiteVote
8:
9:
ChainInfoResponse:
NEWTYPE:
TYPENAME: ChainInfoResponse
9:
10:
Error:
NEWTYPE:
TYPENAME: NodeError
10:
11:
VersionInfoResponse:
NEWTYPE:
TYPENAME: VersionInfo
11:
12:
DownloadBlobResponse:
NEWTYPE:
TYPENAME: Blob
12:
13:
DownloadCertificateValueResponse:
NEWTYPE:
TYPENAME: CertificateValue
13:
14:
DownloadCertificateResponse:
NEWTYPE:
TYPENAME: Certificate
15:
CrossChainRequest:
NEWTYPE:
TYPENAME: CrossChainRequest
Expand Down
19 changes: 17 additions & 2 deletions linera-service/src/grpc_proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ use linera_rpc::{
notifier_service_server::{NotifierService, NotifierServiceServer},
validator_node_server::{ValidatorNode, ValidatorNodeServer},
validator_worker_client::ValidatorWorkerClient,
Blob, BlobId, BlockProposal, CertificateValue, ChainInfoQuery, ChainInfoResult,
CryptoHash, HandleCertificateRequest, LiteCertificate, Notification,
Blob, BlobId, BlockProposal, Certificate, CertificateValue, ChainInfoQuery,
ChainInfoResult, CryptoHash, HandleCertificateRequest, LiteCertificate, Notification,
SubscriptionRequest, VersionInfo,
},
pool::GrpcConnectionPool,
Expand Down Expand Up @@ -426,6 +426,21 @@ where
.map_err(|err| Status::from_error(Box::new(err)))?;
Ok(Response::new(certificate.try_into()?))
}

#[instrument(skip_all, err(Display))]
async fn download_certificate(
&self,
request: Request<CryptoHash>,
) -> Result<Response<Certificate>, Status> {
let hash = request.into_inner().try_into()?;
let certificate = self
.0
.storage
.read_certificate(hash)
.await
.map_err(|err| Status::from_error(Box::new(err)))?;
Ok(Response::new(certificate.try_into()?))
}
}

#[async_trait]
Expand Down
6 changes: 5 additions & 1 deletion linera-service/src/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,9 @@ where
.into_inner()
.into(),
)),
DownloadCertificate(hash) => {
Ok(Some(self.storage.read_certificate(*hash).await?.into()))
}
BlockProposal(_)
| LiteCertificate(_)
| Certificate(_)
Expand All @@ -311,7 +314,8 @@ where
| ChainInfoResponse(_)
| VersionInfoResponse(_)
| DownloadBlobResponse(_)
| DownloadCertificateValueResponse(_) => {
| DownloadCertificateValueResponse(_)
| DownloadCertificateResponse(_) => {
Err(anyhow::Error::from(NodeError::UnexpectedMessage))
}
}
Expand Down
4 changes: 4 additions & 0 deletions linera-service/src/schema_export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ impl ValidatorNode for DummyValidatorNode {
) -> Result<HashedCertificateValue, NodeError> {
Err(NodeError::UnexpectedMessage)
}

async fn download_certificate(&mut self, _: CryptoHash) -> Result<Certificate, NodeError> {
Err(NodeError::UnexpectedMessage)
}
}

struct DummyValidatorNodeProvider;
Expand Down

0 comments on commit 3c4df8a

Please sign in to comment.