Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 29 additions & 12 deletions linera-core/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,18 +376,11 @@ impl<Env: Environment> Client<Env> {
let mut result = self.handle_certificate(certificate.clone()).await;

if let Err(LocalNodeError::BlobsNotFound(blob_ids)) = &result {
future::try_join_all(blob_ids.iter().map(|blob_id| async move {
let blob_certificate =
remote_node.download_certificate_for_blob(*blob_id).await?;
self.receive_sender_certificate(
blob_certificate,
ReceiveCertificateMode::NeedsCheck,
None,
)
.await?;
Result::<(), ChainClientError>::Ok(())
let blobs = future::join_all(blob_ids.iter().map(|blob_id| async move {
remote_node.try_download_blob(*blob_id).await.unwrap()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, b/c the blobs in blob_ids can only come from the certificate (otherwise it would have been the "unexpected blob" error)?

}))
.await?;
.await;
self.local_node.store_blobs(&blobs).await?;
result = self.handle_certificate(certificate.clone()).await;
}

Expand Down Expand Up @@ -930,11 +923,23 @@ impl<Env: Environment> Client<Env> {
async fn synchronize_chain_state(
&self,
chain_id: ChainId,
) -> Result<Box<ChainInfo>, ChainClientError> {
let (_, committee) = self.admin_committee().await?;
self.synchronize_chain_state_from_committee(chain_id, committee)
.await
}

/// Downloads and processes any certificates we are missing for the given chain, from the given
/// committee.
#[instrument(level = "trace", skip_all)]
pub async fn synchronize_chain_state_from_committee(
&self,
chain_id: ChainId,
committee: Committee,
) -> Result<Box<ChainInfo>, ChainClientError> {
#[cfg(with_metrics)]
let _latency = metrics::SYNCHRONIZE_CHAIN_STATE_LATENCY.measure_latency();

let (_, committee) = self.admin_committee().await?;
let validators = self.make_nodes(&committee)?;
Box::pin(self.fetch_chain_info(chain_id, &validators)).await?;
communicate_with_quorum(
Expand Down Expand Up @@ -2297,6 +2302,18 @@ impl<Env: Environment> ChainClient<Env> {
self.client.synchronize_chain_state(chain_id).await
}

/// Downloads and processes any certificates we are missing for this chain, from the given
/// committee.
#[instrument(level = "trace", skip_all)]
pub async fn synchronize_chain_state_from_committee(
&self,
committee: Committee,
) -> Result<Box<ChainInfo>, ChainClientError> {
self.client
.synchronize_chain_state_from_committee(self.chain_id, committee)
.await
}

/// Executes a list of operations.
#[instrument(level = "trace", skip(operations, blobs))]
pub async fn execute_operations(
Expand Down
2 changes: 1 addition & 1 deletion linera-core/src/remote_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ impl<N: ValidatorNode> RemoteNode<N> {
}

#[instrument(level = "trace")]
async fn try_download_blob(&self, blob_id: BlobId) -> Option<Blob> {
pub async fn try_download_blob(&self, blob_id: BlobId) -> Option<Blob> {
match self.node.download_blob(blob_id).await {
Ok(blob) => {
let blob = Blob::new(blob);
Expand Down
40 changes: 39 additions & 1 deletion linera-service/src/cli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use chrono::Utc;
use colored::Colorize;
use futures::{lock::Mutex, FutureExt as _, StreamExt};
use linera_base::{
crypto::{InMemorySigner, Signer},
crypto::{AccountPublicKey, InMemorySigner, Signer},
data_types::{ApplicationPermissions, Timestamp},
identifiers::{AccountOwner, ChainId},
listen_for_shutdown_signals,
Expand Down Expand Up @@ -1610,6 +1610,43 @@ impl Runnable for Job {
);
}

Wallet(WalletCommand::Init { faucet, .. }) => {
let Some(faucet_url) = faucet else {
return Ok(());
};
let Some(network_description) = storage.read_network_description().await? else {
anyhow::bail!("Missing network description");
};
let context = ClientContext::new(
storage,
options.context_options.clone(),
wallet,
signer.into_value(),
);
let faucet = cli_wrappers::Faucet::new(faucet_url);
let validators = faucet.current_validators().await?;
let chain_client = context.make_chain_client(network_description.admin_chain_id);
// TODO(#4434): This is a quick workaround with an equal-weight committee. Instead,
// the faucet should provide the full committee including weights.
let committee = Committee::new(
validators
.into_iter()
.map(|(pub_key, network_address)| {
let state = ValidatorState {
network_address,
votes: 100,
account_public_key: AccountPublicKey::from_slice(&[0; 33]).unwrap(),
};
(pub_key, state)
})
.collect(),
Default::default(), // unused
);
chain_client
.synchronize_chain_state_from_committee(committee)
.await?;
Comment on lines +1645 to +1647
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for the CLI only, what about other clients? Are they all supposed to do that manually?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, also on initialization.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(But this is still a hack; needs a proper solution, but I hope this can already unblock us.)

}

Wallet(WalletCommand::FollowChain {
chain_id,
sync: true,
Expand Down Expand Up @@ -2431,6 +2468,7 @@ Make sure to use a Linera client compatible with this network.
keystore.persist().await?;
options.create_wallet(genesis_config)?.persist().await?;
options.initialize_storage().boxed().await?;
options.run_with_storage(Job(options.clone())).await??;
info!(
"Wallet initialized in {} ms",
start_time.elapsed().as_millis()
Expand Down
13 changes: 13 additions & 0 deletions linera-service/tests/local_net_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,19 @@ async fn test_end_to_end_reconfiguration(config: LocalNetConfig) -> Result<()> {
);
}

if matches!(network, Network::Grpc) {
let client = net.make_client().await;
client.wallet_init(Some(&faucet)).await?;
let (chain_id, _owner) = client.request_chain(&faucet, true).await?;
let port = get_node_port().await;
let service = client
.run_node_service(port, ProcessInbox::Automatic)
.await?;
service
.publish_data_blob(&chain_id, b"blob bytes".to_vec())
.await?;
}

net.ensure_is_running().await?;
net.terminate().await?;

Expand Down
Loading