Skip to content

Commit 1820109

Browse files
authored
Store network information in DB (#3755)
## Motivation We currently pass around a genesis configuration when deploying a validator but this is not really needed. This is the first step to simplify things. ## Proposal * Create a notion of network description to be persisted in DB * Use it in the proxy * Upgrade the RPC to return the full `NetworkInformation` while we're at it. Incidentally, we won't compute the genesis config hash over and over again. ## Test Plan CI ## Release Plan - Nothing to do / These changes follow the usual release cycle.
1 parent 5000163 commit 1820109

File tree

17 files changed

+240
-66
lines changed

17 files changed

+240
-66
lines changed

linera-client/src/config.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use linera_execution::{
2424
use linera_rpc::config::{
2525
ExporterServiceConfig, ValidatorInternalNetworkConfig, ValidatorPublicNetworkConfig,
2626
};
27-
use linera_storage::Storage;
27+
use linera_storage::{NetworkDescription, Storage};
2828
use serde::{Deserialize, Serialize};
2929

3030
#[derive(Debug, thiserror::Error)]
@@ -35,6 +35,8 @@ pub enum Error {
3535
Chain(#[from] linera_chain::ChainError),
3636
#[error("persistence error: {0}")]
3737
Persistence(Box<dyn std::error::Error + Send + Sync>),
38+
#[error("storage is already initialized: {0:?}")]
39+
StorageIsAlreadyInitialized(NetworkDescription),
3840
}
3941

4042
use crate::{
@@ -284,6 +286,13 @@ impl GenesisConfig {
284286
where
285287
S: Storage + Clone + Send + Sync + 'static,
286288
{
289+
if let Some(description) = storage
290+
.read_network_description()
291+
.await
292+
.map_err(linera_chain::ChainError::from)?
293+
{
294+
return Err(Error::StorageIsAlreadyInitialized(description));
295+
}
287296
let committee = self.create_committee();
288297
let committees: BTreeMap<_, _> = [(
289298
Epoch::ZERO,
@@ -308,6 +317,15 @@ impl GenesisConfig {
308317
let description = ChainDescription::new(origin, config, self.timestamp);
309318
storage.create_chain(description).await?;
310319
}
320+
let network_description = NetworkDescription {
321+
name: self.network_name.clone(),
322+
genesis_config_hash: CryptoHash::new(self),
323+
genesis_timestamp: self.timestamp,
324+
};
325+
storage
326+
.write_network_description(&network_description)
327+
.await
328+
.map_err(linera_chain::ChainError::from)?;
311329
Ok(())
312330
}
313331

linera-core/src/node.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use linera_chain::{
2121
ChainError,
2222
};
2323
use linera_execution::{committee::Committee, ExecutionError};
24+
use linera_storage::NetworkDescription;
2425
use linera_version::VersionInfo;
2526
use linera_views::views::ViewError;
2627
use serde::{Deserialize, Serialize};
@@ -92,8 +93,8 @@ pub trait ValidatorNode {
9293
/// Gets the version info for this validator node.
9394
async fn get_version_info(&self) -> Result<VersionInfo, NodeError>;
9495

95-
/// Gets the network's genesis config hash.
96-
async fn get_genesis_config_hash(&self) -> Result<CryptoHash, NodeError>;
96+
/// Gets the network's description.
97+
async fn get_network_description(&self) -> Result<NetworkDescription, NodeError>;
9798

9899
/// Subscribes to receiving notifications for a collection of chains.
99100
async fn subscribe(&self, chains: Vec<ChainId>) -> Result<Self::NotificationStream, NodeError>;

linera-core/src/unit_tests/test_utils.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use linera_chain::{
2929
},
3030
};
3131
use linera_execution::{committee::Committee, ResourceControlPolicy, WasmRuntime};
32-
use linera_storage::{DbStorage, Storage, TestClock};
32+
use linera_storage::{DbStorage, NetworkDescription, Storage, TestClock};
3333
#[cfg(all(not(target_arch = "wasm32"), feature = "storage-service"))]
3434
use linera_storage_service::client::ServiceStoreClient;
3535
use linera_version::VersionInfo;
@@ -173,8 +173,12 @@ where
173173
Ok(Default::default())
174174
}
175175

176-
async fn get_genesis_config_hash(&self) -> Result<CryptoHash, NodeError> {
177-
Ok(CryptoHash::test_hash("genesis config"))
176+
async fn get_network_description(&self) -> Result<NetworkDescription, NodeError> {
177+
Ok(NetworkDescription {
178+
name: "test network".to_string(),
179+
genesis_config_hash: CryptoHash::test_hash("genesis config"),
180+
genesis_timestamp: Timestamp::default(),
181+
})
178182
}
179183

180184
async fn upload_blob(&self, content: BlobContent) -> Result<BlobId, NodeError> {

linera-rpc/proto/rpc.proto

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ service ValidatorNode {
6464
// Request the node's version info.
6565
rpc GetVersionInfo(google.protobuf.Empty) returns (VersionInfo);
6666

67-
// Request the genesis configuration hash of the network this node is part of.
68-
rpc GetGenesisConfigHash(google.protobuf.Empty) returns (CryptoHash);
67+
// Request the network description seen by this node.
68+
rpc GetNetworkDescription(google.protobuf.Empty) returns (NetworkDescription);
6969

7070
// Download a blob.
7171
rpc DownloadBlob(BlobId) returns (BlobContent);
@@ -120,6 +120,12 @@ message VersionInfo {
120120
string wit_hash = 6;
121121
}
122122

123+
message NetworkDescription {
124+
string name = 1;
125+
CryptoHash genesis_config_hash = 2;
126+
uint64 genesis_timestamp = 3;
127+
}
128+
123129
// A request for client to subscribe to notifications for a given `ChainId`
124130
message SubscriptionRequest {
125131
repeated ChainId chain_ids = 1;

linera-rpc/src/client.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,12 +160,14 @@ impl ValidatorNode for Client {
160160
})
161161
}
162162

163-
async fn get_genesis_config_hash(&self) -> Result<CryptoHash, NodeError> {
163+
async fn get_network_description(
164+
&self,
165+
) -> Result<linera_storage::NetworkDescription, NodeError> {
164166
Ok(match self {
165-
Client::Grpc(grpc_client) => grpc_client.get_genesis_config_hash().await?,
167+
Client::Grpc(grpc_client) => grpc_client.get_network_description().await?,
166168

167169
#[cfg(with_simple_network)]
168-
Client::Simple(simple_client) => simple_client.get_genesis_config_hash().await?,
170+
Client::Simple(simple_client) => simple_client.get_network_description().await?,
169171
})
170172
}
171173

linera-rpc/src/grpc/client.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use linera_core::{
2323
node::{CrossChainMessageDelivery, NodeError, NotificationStream, ValidatorNode},
2424
worker::Notification,
2525
};
26+
use linera_storage::NetworkDescription;
2627
use linera_version::VersionInfo;
2728
use tonic::{Code, IntoRequest, Request, Status};
2829
use tracing::{debug, error, info, instrument, warn};
@@ -346,9 +347,9 @@ impl ValidatorNode for GrpcClient {
346347
}
347348

348349
#[instrument(target = "grpc_client", skip_all, err, fields(address = self.address))]
349-
async fn get_genesis_config_hash(&self) -> Result<CryptoHash, NodeError> {
350+
async fn get_network_description(&self) -> Result<NetworkDescription, NodeError> {
350351
let req = ();
351-
Ok(client_delegate!(self, get_genesis_config_hash, req)?.try_into()?)
352+
Ok(client_delegate!(self, get_network_description, req)?.try_into()?)
352353
}
353354

354355
#[instrument(target = "grpc_client", skip(self), err, fields(address = self.address))]

linera-rpc/src/grpc/conversions.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,40 @@ impl From<api::VersionInfo> for linera_version::VersionInfo {
142142
}
143143
}
144144

145+
impl From<linera_storage::NetworkDescription> for api::NetworkDescription {
146+
fn from(
147+
linera_storage::NetworkDescription {
148+
name,
149+
genesis_config_hash,
150+
genesis_timestamp,
151+
}: linera_storage::NetworkDescription,
152+
) -> Self {
153+
Self {
154+
name,
155+
genesis_config_hash: Some(genesis_config_hash.into()),
156+
genesis_timestamp: genesis_timestamp.micros(),
157+
}
158+
}
159+
}
160+
161+
impl TryFrom<api::NetworkDescription> for linera_storage::NetworkDescription {
162+
type Error = GrpcProtoConversionError;
163+
164+
fn try_from(
165+
api::NetworkDescription {
166+
name,
167+
genesis_config_hash,
168+
genesis_timestamp,
169+
}: api::NetworkDescription,
170+
) -> Result<Self, Self::Error> {
171+
Ok(Self {
172+
name,
173+
genesis_config_hash: try_proto_convert(genesis_config_hash)?,
174+
genesis_timestamp: genesis_timestamp.into(),
175+
})
176+
}
177+
}
178+
145179
impl TryFrom<Notification> for api::Notification {
146180
type Error = GrpcProtoConversionError;
147181

linera-rpc/src/message.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use linera_core::{
1515
data_types::{ChainInfoQuery, ChainInfoResponse, CrossChainRequest},
1616
node::NodeError,
1717
};
18+
use linera_storage::NetworkDescription;
1819
use linera_version::VersionInfo;
1920
use serde::{Deserialize, Serialize};
2021

@@ -42,14 +43,14 @@ pub enum RpcMessage {
4243
BlobLastUsedBy(Box<BlobId>),
4344
MissingBlobIds(Vec<BlobId>),
4445
VersionInfoQuery,
45-
GenesisConfigHashQuery,
46+
NetworkDescriptionQuery,
4647

4748
// Outbound
4849
Vote(Box<LiteVote>),
4950
ChainInfoResponse(Box<ChainInfoResponse>),
5051
Error(Box<NodeError>),
5152
VersionInfoResponse(Box<VersionInfo>),
52-
GenesisConfigHashResponse(Box<CryptoHash>),
53+
NetworkDescriptionResponse(Box<NetworkDescription>),
5354
UploadBlobResponse(Box<BlobId>),
5455
DownloadBlobResponse(Box<BlobContent>),
5556
DownloadPendingBlobResponse(Box<BlobContent>),
@@ -84,8 +85,8 @@ impl RpcMessage {
8485
| ChainInfoResponse(_)
8586
| VersionInfoQuery
8687
| VersionInfoResponse(_)
87-
| GenesisConfigHashQuery
88-
| GenesisConfigHashResponse(_)
88+
| NetworkDescriptionQuery
89+
| NetworkDescriptionResponse(_)
8990
| UploadBlob(_)
9091
| UploadBlobResponse(_)
9192
| DownloadBlob(_)
@@ -113,7 +114,7 @@ impl RpcMessage {
113114

114115
match self {
115116
VersionInfoQuery
116-
| GenesisConfigHashQuery
117+
| NetworkDescriptionQuery
117118
| UploadBlob(_)
118119
| DownloadBlob(_)
119120
| DownloadConfirmedBlock(_)
@@ -131,7 +132,7 @@ impl RpcMessage {
131132
| Error(_)
132133
| ChainInfoResponse(_)
133134
| VersionInfoResponse(_)
134-
| GenesisConfigHashResponse(_)
135+
| NetworkDescriptionResponse(_)
135136
| UploadBlobResponse(_)
136137
| DownloadPendingBlob(_)
137138
| DownloadPendingBlobResponse(_)
@@ -206,13 +207,22 @@ impl TryFrom<RpcMessage> for CryptoHash {
206207
fn try_from(message: RpcMessage) -> Result<Self, Self::Error> {
207208
match message {
208209
RpcMessage::BlobLastUsedByResponse(hash) => Ok(*hash),
209-
RpcMessage::GenesisConfigHashResponse(hash) => Ok(*hash),
210210
RpcMessage::Error(error) => Err(*error),
211211
_ => Err(NodeError::UnexpectedMessage),
212212
}
213213
}
214214
}
215215

216+
impl TryFrom<RpcMessage> for NetworkDescription {
217+
type Error = NodeError;
218+
fn try_from(message: RpcMessage) -> Result<Self, Self::Error> {
219+
match message {
220+
RpcMessage::NetworkDescriptionResponse(description) => Ok(*description),
221+
_ => Err(NodeError::UnexpectedMessage),
222+
}
223+
}
224+
}
225+
216226
impl TryFrom<RpcMessage> for Vec<BlobId> {
217227
type Error = NodeError;
218228
fn try_from(message: RpcMessage) -> Result<Self, Self::Error> {

linera-rpc/src/simple/client.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use linera_core::{
2121
data_types::{ChainInfoQuery, ChainInfoResponse},
2222
node::{CrossChainMessageDelivery, NodeError, NotificationStream, ValidatorNode},
2323
};
24+
use linera_storage::NetworkDescription;
2425
use linera_version::VersionInfo;
2526

2627
use super::{codec, transport::TransportProtocol};
@@ -156,8 +157,8 @@ impl ValidatorNode for SimpleClient {
156157
self.query(RpcMessage::VersionInfoQuery).await
157158
}
158159

159-
async fn get_genesis_config_hash(&self) -> Result<CryptoHash, NodeError> {
160-
self.query(RpcMessage::GenesisConfigHashQuery).await
160+
async fn get_network_description(&self) -> Result<NetworkDescription, NodeError> {
161+
self.query(RpcMessage::NetworkDescriptionQuery).await
161162
}
162163

163164
async fn upload_blob(&self, content: BlobContent) -> Result<BlobId, NodeError> {

linera-rpc/src/simple/server.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -391,8 +391,8 @@ where
391391
| RpcMessage::Error(_)
392392
| RpcMessage::ChainInfoResponse(_)
393393
| RpcMessage::VersionInfoResponse(_)
394-
| RpcMessage::GenesisConfigHashQuery
395-
| RpcMessage::GenesisConfigHashResponse(_)
394+
| RpcMessage::NetworkDescriptionQuery
395+
| RpcMessage::NetworkDescriptionResponse(_)
396396
| RpcMessage::DownloadBlob(_)
397397
| RpcMessage::DownloadBlobResponse(_)
398398
| RpcMessage::DownloadPendingBlobResponse(_)

0 commit comments

Comments
 (0)