Skip to content

Commit e2cad30

Browse files
Implement the syncing with all validators functionality. (#4558)
## Motivation In operations, it is useful to be able to sync with all validators in one single operation. Fixes #4488 ## Proposal The implementation is straightforward. ## Test Plan The CI. I did test with README.md kind of files and added a `linera sync-all-validators` function. And it does access to the validators without error. I did not test that the syncing does happen, though. I created issue #4535 that shows some idea for improving the syncing with validators. ## Release Plan Fully compatible with existing DevNet / TestNet. ## Links None.
1 parent 5c29952 commit e2cad30

File tree

3 files changed

+72
-0
lines changed

3 files changed

+72
-0
lines changed

CLI.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ This document contains the help content for the `linera` command-line program.
2020
* [`linera query-validator`](#linera-query-validator)
2121
* [`linera query-validators`](#linera-query-validators)
2222
* [`linera sync-validator`](#linera-sync-validator)
23+
* [`linera sync-all-validators`](#linera-sync-all-validators)
2324
* [`linera set-validator`](#linera-set-validator)
2425
* [`linera remove-validator`](#linera-remove-validator)
2526
* [`linera revoke-epochs`](#linera-revoke-epochs)
@@ -87,6 +88,7 @@ Client implementation and command-line tool for the Linera blockchain
8788
* `query-validator` — Show the version and genesis config hash of a new validator, and print a warning if it is incompatible. Also print some information about the given chain while we are at it
8889
* `query-validators` — Show the current set of validators for a chain. Also print some information about the given chain while we are at it
8990
* `sync-validator` — Synchronizes a validator with the local state of chains
91+
* `sync-all-validators` — Synchronizes all validators with the local state of chains
9092
* `set-validator` — Add or modify a validator (admin only)
9193
* `remove-validator` — Remove a validator (admin only)
9294
* `revoke-epochs` — Deprecates all committees up to and including the specified one
@@ -440,6 +442,18 @@ Synchronizes a validator with the local state of chains
440442

441443

442444

445+
## `linera sync-all-validators`
446+
447+
Synchronizes all validators with the local state of chains
448+
449+
**Usage:** `linera sync-all-validators [OPTIONS]`
450+
451+
###### **Options:**
452+
453+
* `--chains <CHAINS>` — The chains to synchronize, or the default chain if empty
454+
455+
456+
443457
## `linera set-validator`
444458

445459
Add or modify a validator (admin only)

linera-service/src/cli/command.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,13 @@ pub enum ClientCommand {
352352
chains: Vec<ChainId>,
353353
},
354354

355+
/// Synchronizes all validators with the local state of chains.
356+
SyncAllValidators {
357+
/// The chains to synchronize, or the default chain if empty.
358+
#[arg(long, num_args = 0..)]
359+
chains: Vec<ChainId>,
360+
},
361+
355362
/// Add or modify a validator (admin only)
356363
SetValidator {
357364
/// The public key of the validator.
@@ -969,6 +976,7 @@ impl ClientCommand {
969976
| ClientCommand::QueryValidator { .. }
970977
| ClientCommand::QueryValidators { .. }
971978
| ClientCommand::SyncValidator { .. }
979+
| ClientCommand::SyncAllValidators { .. }
972980
| ClientCommand::SetValidator { .. }
973981
| ClientCommand::RemoveValidator { .. }
974982
| ClientCommand::ResourceControlPolicy { .. }

linera-service/src/cli/main.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,7 @@ impl Runnable for Job {
544544
address,
545545
mut chains,
546546
} => {
547+
let time_start = Instant::now();
547548
let context = ClientContext::new(
548549
storage,
549550
options.context_options.clone(),
@@ -562,6 +563,55 @@ impl Runnable for Job {
562563

563564
Box::pin(chain.sync_validator(validator.clone())).await?;
564565
}
566+
let time_total = time_start.elapsed();
567+
info!(
568+
"Syncing with validator {address} in {} ms",
569+
time_total.as_millis()
570+
);
571+
}
572+
573+
SyncAllValidators { mut chains } => {
574+
let time_start = Instant::now();
575+
let context = Arc::new(ClientContext::new(
576+
storage,
577+
options.context_options.clone(),
578+
wallet,
579+
signer.into_value(),
580+
));
581+
582+
if chains.is_empty() {
583+
chains.push(context.default_chain());
584+
}
585+
586+
let committee = context.wallet().genesis_config().committee.clone();
587+
588+
// Parallelize the validator loop - sync all validators concurrently
589+
let tasks = committee
590+
.validator_addresses()
591+
.map(|(_validator_name, network_address)| {
592+
let context = context.clone();
593+
let chains = chains.clone();
594+
async move {
595+
let validator =
596+
context.make_node_provider().make_node(network_address)?;
597+
// For each validator, sync all chains sequentially
598+
for chain_id in &chains {
599+
let chain = context.make_chain_client(*chain_id);
600+
Box::pin(chain.sync_validator(validator.clone())).await?;
601+
}
602+
anyhow::Result::<()>::Ok(())
603+
}
604+
})
605+
.collect::<Vec<_>>();
606+
607+
// Wait for all validator sync tasks to complete
608+
futures::future::try_join_all(tasks).await?;
609+
610+
let time_total = time_start.elapsed();
611+
info!(
612+
"Syncing with all validators in {} ms",
613+
time_total.as_millis()
614+
);
565615
}
566616

567617
command @ (SetValidator { .. }

0 commit comments

Comments
 (0)