Skip to content

Commit 07b454d

Browse files
authored
Improve a few log messages: timeouts, validator addresses. (#4920)
## Motivation Some of our logs are less useful than they could be: * Many show a validator's public key instead of address. * One prints the `Debug` format of a `RoundTimeout`, with the time as a number of microseconds since the epoch. * We mix structured logging and printing values inline in the log message. ## Proposal * Print the validator address. * `impl Display for RoundTimeout`, and show the formatted date and time. * Prefer structured logging. ## Test Plan (Only minor logging changes.) ## Release Plan - These changes should be backported to `testnet_conway`, then - be released in a new SDK, (not urgent) - be released in a validator hotfix. (not urgent) ## Links - [reviewer checklist](https://github.com/linera-io/linera-protocol/blob/main/CONTRIBUTING.md#reviewer-checklist)
1 parent 8baaa9f commit 07b454d

File tree

5 files changed

+81
-50
lines changed

5 files changed

+81
-50
lines changed

linera-client/src/chain_listener.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -592,14 +592,16 @@ impl<C: ClientContext + 'static> ChainListener<C> {
592592
}
593593
Err(error) => warn!(%error, "Failed to process inbox."),
594594
Ok((certs, None)) => info!(
595-
"Done processing inbox of chain. {} blocks created on chain {chain_id}.",
596-
certs.len()
595+
%chain_id,
596+
created_block_count = %certs.len(),
597+
"done processing inbox",
597598
),
598599
Ok((certs, Some(new_timeout))) => {
599600
info!(
600-
"{} blocks created on chain {chain_id}. Will try processing the inbox later \
601-
based on the round timeout: {new_timeout:?}",
602-
certs.len(),
601+
%chain_id,
602+
created_block_count = %certs.len(),
603+
timeout = %new_timeout,
604+
"waiting for round timeout before continuing to process the inbox",
603605
);
604606
listening_client.timeout = new_timeout.timestamp;
605607
}

linera-core/src/client/mod.rs

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -437,9 +437,10 @@ impl<Env: Environment> Client<Env> {
437437
.download_certificates_from(&remote_node, chain_id, target_next_block_height)
438438
.await
439439
{
440-
Err(err) => info!(
441-
"Failed to download certificates from validator {:?}: {err}",
442-
remote_node.public_key
440+
Err(error) => info!(
441+
remote_node = remote_node.address(),
442+
%error,
443+
"failed to download certificates from validator",
443444
),
444445
Ok(Some(new_info)) => info = new_info,
445446
Ok(None) => {}
@@ -1027,7 +1028,7 @@ impl<Env: Environment> Client<Env> {
10271028
offset += received_entries as u64;
10281029
remote_log.extend(info.requested_received_log);
10291030
trace!(
1030-
?remote_node,
1031+
remote_node = remote_node.address(),
10311032
%received_entries,
10321033
"get_received_log_from_validator: received log batch",
10331034
);
@@ -1037,8 +1038,8 @@ impl<Env: Environment> Client<Env> {
10371038
}
10381039

10391040
trace!(
1040-
?remote_node,
1041-
num_entries = %remote_log.len(),
1041+
remote_node = remote_node.address(),
1042+
num_entries = remote_log.len(),
10421043
"get_received_log_from_validator: returning downloaded log",
10431044
);
10441045

@@ -1220,8 +1221,10 @@ impl<Env: Environment> Client<Env> {
12201221
// If we are at the same height as the remote node, we also update our chain manager.
12211222
if local_info.next_block_height != remote_info.next_block_height {
12221223
debug!(
1223-
"Synced from validator {}; but remote height is {} and local height is {}",
1224-
remote_node.public_key, remote_info.next_block_height, local_info.next_block_height
1224+
remote_node = remote_node.address(),
1225+
remote_height = %remote_info.next_block_height,
1226+
local_height = %local_info.next_block_height,
1227+
"synced from validator, but remote height and local height are different",
12251228
);
12261229
return Ok(());
12271230
};
@@ -1243,10 +1246,14 @@ impl<Env: Environment> Client<Env> {
12431246
}
12441247
LockingBlock::Regular(cert) => {
12451248
let hash = cert.hash();
1246-
if let Err(err) = self.try_process_locking_block_from(remote_node, cert).await {
1249+
if let Err(error) = self.try_process_locking_block_from(remote_node, cert).await
1250+
{
12471251
debug!(
1248-
"Skipping locked block {hash} from validator {} at height {}: {err}",
1249-
remote_node.public_key, local_info.next_block_height,
1252+
remote_node = remote_node.address(),
1253+
%hash,
1254+
height = %local_info.next_block_height,
1255+
%error,
1256+
"skipping locked block from validator",
12501257
);
12511258
}
12521259
}
@@ -1270,11 +1277,14 @@ impl<Env: Environment> Client<Env> {
12701277
.await
12711278
{
12721279
Ok(content) => content,
1273-
Err(err) => {
1280+
Err(error) => {
12741281
info!(
1275-
"Skipping proposal from {owner} and validator {} at \
1276-
height {}; failed to download {blob_id}: {err}",
1277-
remote_node.public_key, local_info.next_block_height
1282+
remote_node = remote_node.address(),
1283+
height = %local_info.next_block_height,
1284+
proposer = %owner,
1285+
%blob_id,
1286+
%error,
1287+
"skipping proposal from validator; failed to download blob",
12781288
);
12791289
continue 'proposal_loop;
12801290
}
@@ -1343,8 +1353,11 @@ impl<Env: Environment> Client<Env> {
13431353
}
13441354

13451355
debug!(
1346-
"Skipping proposal from {owner} and validator {} at height {}: {err}",
1347-
remote_node.public_key, local_info.next_block_height
1356+
remote_node = remote_node.address(),
1357+
proposer = %owner,
1358+
height = %local_info.next_block_height,
1359+
error = %err,
1360+
"skipping proposal from validator",
13481361
);
13491362
}
13501363
}

linera-core/src/data_types.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Copyright (c) Zefchain Labs, Inc.
33
// SPDX-License-Identifier: Apache-2.0
44

5-
use std::{collections::BTreeMap, ops::Not};
5+
use std::{collections::BTreeMap, fmt, ops::Not};
66

77
use custom_debug_derive::Debug;
88
use linera_base::{
@@ -364,12 +364,22 @@ pub struct RoundTimeout {
364364
pub next_block_height: BlockHeight,
365365
}
366366

367+
impl fmt::Display for RoundTimeout {
368+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
369+
write!(
370+
f,
371+
"{} at height {} times out at {}",
372+
self.current_round, self.next_block_height, self.timestamp
373+
)
374+
}
375+
}
376+
367377
impl<T> ClientOutcome<T> {
368378
#[cfg(with_testing)]
369379
pub fn unwrap(self) -> T {
370380
match self {
371381
ClientOutcome::Committed(t) => t,
372-
ClientOutcome::WaitForTimeout(timeout) => panic!("Unexpected timeout: {timeout:?}"),
382+
ClientOutcome::WaitForTimeout(timeout) => panic!("unexpected timeout: {timeout}"),
373383
}
374384
}
375385

linera-core/src/remote_node.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,11 @@ impl<N: ValidatorNode> RemoteNode<N> {
286286
}
287287
Ok(())
288288
}
289+
290+
/// Returns the validator's URL.
291+
pub fn address(&self) -> String {
292+
self.node.address()
293+
}
289294
}
290295

291296
impl<N: ValidatorNode> PartialEq for RemoteNode<N> {

linera-core/src/updater.rs

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -345,12 +345,12 @@ where
345345
height: BlockHeight,
346346
error: &NodeError,
347347
) -> Result<(), chain_client::Error> {
348-
let validator = &self.remote_node.public_key;
348+
let validator = &self.remote_node.address();
349349
match error {
350350
NodeError::WrongRound(validator_round) if *validator_round > round => {
351351
tracing::debug!(
352-
?validator, %chain_id, %validator_round, %round,
353-
"Validator is at a higher round; synchronizing.",
352+
validator, %chain_id, %validator_round, %round,
353+
"validator is at a higher round; synchronizing",
354354
);
355355
self.client
356356
.synchronize_chain_state_from(&self.remote_node, chain_id)
@@ -361,20 +361,20 @@ where
361361
found_block_height,
362362
} if expected_block_height > found_block_height => {
363363
tracing::debug!(
364-
?validator,
364+
validator,
365365
%chain_id,
366366
%expected_block_height,
367367
%found_block_height,
368-
"Validator is at a higher height; synchronizing.",
368+
"validator is at a higher height; synchronizing",
369369
);
370370
self.client
371371
.synchronize_chain_state_from(&self.remote_node, chain_id)
372372
.await?;
373373
}
374374
NodeError::WrongRound(validator_round) if *validator_round < round => {
375375
tracing::debug!(
376-
?validator, %chain_id, %validator_round, %round,
377-
"Validator is at a lower round; sending chain info.",
376+
validator, %chain_id, %validator_round, %round,
377+
"validator is at a lower round; sending chain info",
378378
);
379379
self.send_chain_information(
380380
chain_id,
@@ -438,8 +438,9 @@ where
438438
// The proposal is for a different round, so we need to update the validator.
439439
// TODO: this should probably be more specific as to which rounds are retried.
440440
tracing::debug!(
441-
"Wrong round; sending chain {chain_id} to validator {}.",
442-
self.remote_node.public_key
441+
remote_node = self.remote_node.address(),
442+
%chain_id,
443+
"wrong round; sending chain to validator",
443444
);
444445
self.send_chain_information(
445446
chain_id,
@@ -455,8 +456,9 @@ where
455456
&& found_block_height == proposal.content.block.height =>
456457
{
457458
tracing::debug!(
458-
"Wrong height; sending chain {chain_id} to validator {}.",
459-
self.remote_node.public_key
459+
remote_node = self.remote_node.address(),
460+
%chain_id,
461+
"wrong height; sending chain to validator",
460462
);
461463
// The proposal is for a later block height, so we need to update the validator.
462464
self.send_chain_information(
@@ -476,8 +478,9 @@ where
476478
.is_none_or(|h| *h < height) =>
477479
{
478480
tracing::debug!(
479-
"Missing cross-chain update; sending chain {origin} to validator {}.",
480-
self.remote_node.public_key
481+
remote_node = %self.remote_node.address(),
482+
chain_id = %origin,
483+
"Missing cross-chain update; sending chain to validator.",
481484
);
482485
sent_cross_chain_updates.insert(origin, height);
483486
// Some received certificates may be missing for this validator
@@ -492,20 +495,18 @@ where
492495
}
493496
Err(NodeError::EventsNotFound(event_ids)) => {
494497
let mut publisher_heights = BTreeMap::new();
495-
let new_chain_ids = event_ids
498+
let chain_ids = event_ids
496499
.iter()
497500
.map(|event_id| event_id.chain_id)
498501
.filter(|chain_id| !publisher_chain_ids_sent.contains(chain_id))
499502
.collect::<BTreeSet<_>>();
500503
tracing::debug!(
501-
"Missing events; sending chains {new_chain_ids:?} to validator {}",
502-
self.remote_node.public_key
503-
);
504-
ensure!(
505-
!new_chain_ids.is_empty(),
506-
NodeError::EventsNotFound(event_ids)
504+
remote_node = self.remote_node.address(),
505+
?chain_ids,
506+
"missing events; sending chains to validator",
507507
);
508-
for chain_id in new_chain_ids {
508+
ensure!(!chain_ids.is_empty(), NodeError::EventsNotFound(event_ids));
509+
for chain_id in chain_ids {
509510
let height = self
510511
.client
511512
.local_node
@@ -711,32 +712,32 @@ where
711712
.chain(manager.requested_signed_proposal)
712713
{
713714
if proposal.content.round == manager.current_round {
714-
if let Err(err) = self.remote_node.handle_block_proposal(proposal).await {
715-
tracing::info!("Failed to send block proposal: {err}");
715+
if let Err(error) = self.remote_node.handle_block_proposal(proposal).await {
716+
tracing::info!(%error, "failed to send block proposal");
716717
} else {
717718
return Ok(());
718719
}
719720
}
720721
}
721722
if let Some(LockingBlock::Regular(validated)) = manager.requested_locking.map(|b| *b) {
722723
if validated.round == manager.current_round {
723-
if let Err(err) = self
724+
if let Err(error) = self
724725
.remote_node
725726
.handle_optimized_validated_certificate(
726727
&validated,
727728
CrossChainMessageDelivery::NonBlocking,
728729
)
729730
.await
730731
{
731-
tracing::info!("Failed to send locking block: {err}");
732+
tracing::info!(%error, "failed to send locking block");
732733
} else {
733734
return Ok(());
734735
}
735736
}
736737
}
737738
if let Some(cert) = manager.timeout {
738739
if cert.round >= remote_round {
739-
tracing::debug!("Sending timeout for {}", cert.round);
740+
tracing::debug!(round = %cert.round, "sending timeout");
740741
self.remote_node.handle_timeout_certificate(*cert).await?;
741742
}
742743
}

0 commit comments

Comments
 (0)