Skip to content

Commit 36717ed

Browse files
authored
[testnet] Improve a few log messages: timeouts, validator addresses. (#4920) (#4924)
Backport of #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 released in a new SDK, (not urgent) - be released in a validator hotfix. (not urgent) ## Links - PR to main: #4920 - [reviewer checklist](https://github.com/linera-io/linera-protocol/blob/main/CONTRIBUTING.md#reviewer-checklist)
1 parent 1fcaeec commit 36717ed

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
@@ -512,14 +512,16 @@ impl<C: ClientContext + 'static> ChainListener<C> {
512512
}
513513
Err(error) => warn!(%error, "Failed to process inbox."),
514514
Ok((certs, None)) => info!(
515-
"Done processing inbox of chain. {} blocks created on chain {chain_id}.",
516-
certs.len()
515+
%chain_id,
516+
created_block_count = %certs.len(),
517+
"done processing inbox",
517518
),
518519
Ok((certs, Some(new_timeout))) => {
519520
info!(
520-
"{} blocks created on chain {chain_id}. Will try processing the inbox later \
521-
based on the round timeout: {new_timeout:?}",
522-
certs.len(),
521+
%chain_id,
522+
created_block_count = %certs.len(),
523+
timeout = %new_timeout,
524+
"waiting for round timeout before continuing to process the inbox",
523525
);
524526
listening_client.timeout = new_timeout.timestamp;
525527
}

linera-core/src/client/mod.rs

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -300,9 +300,10 @@ impl<Env: Environment> Client<Env> {
300300
.download_certificates_from(&remote_node, chain_id, target_next_block_height)
301301
.await
302302
{
303-
Err(err) => info!(
304-
"Failed to download certificates from validator {:?}: {err}",
305-
remote_node.public_key
303+
Err(error) => info!(
304+
remote_node = remote_node.address(),
305+
%error,
306+
"failed to download certificates from validator",
306307
),
307308
Ok(Some(new_info)) => info = new_info,
308309
Ok(None) => {}
@@ -888,7 +889,7 @@ impl<Env: Environment> Client<Env> {
888889
offset += received_entries as u64;
889890
remote_log.extend(info.requested_received_log);
890891
trace!(
891-
?remote_node,
892+
remote_node = remote_node.address(),
892893
%received_entries,
893894
"get_received_log_from_validator: received log batch",
894895
);
@@ -898,8 +899,8 @@ impl<Env: Environment> Client<Env> {
898899
}
899900

900901
trace!(
901-
?remote_node,
902-
num_entries = %remote_log.len(),
902+
remote_node = remote_node.address(),
903+
num_entries = remote_log.len(),
903904
"get_received_log_from_validator: returning downloaded log",
904905
);
905906

@@ -1080,8 +1081,10 @@ impl<Env: Environment> Client<Env> {
10801081
// If we are at the same height as the remote node, we also update our chain manager.
10811082
if local_info.next_block_height != remote_info.next_block_height {
10821083
debug!(
1083-
"Synced from validator {}; but remote height is {} and local height is {}",
1084-
remote_node.public_key, remote_info.next_block_height, local_info.next_block_height
1084+
remote_node = remote_node.address(),
1085+
remote_height = %remote_info.next_block_height,
1086+
local_height = %local_info.next_block_height,
1087+
"synced from validator, but remote height and local height are different",
10851088
);
10861089
return Ok(());
10871090
};
@@ -1103,10 +1106,14 @@ impl<Env: Environment> Client<Env> {
11031106
}
11041107
LockingBlock::Regular(cert) => {
11051108
let hash = cert.hash();
1106-
if let Err(err) = self.try_process_locking_block_from(remote_node, cert).await {
1109+
if let Err(error) = self.try_process_locking_block_from(remote_node, cert).await
1110+
{
11071111
debug!(
1108-
"Skipping locked block {hash} from validator {} at height {}: {err}",
1109-
remote_node.public_key, local_info.next_block_height,
1112+
remote_node = remote_node.address(),
1113+
%hash,
1114+
height = %local_info.next_block_height,
1115+
%error,
1116+
"skipping locked block from validator",
11101117
);
11111118
}
11121119
}
@@ -1128,11 +1135,14 @@ impl<Env: Environment> Client<Env> {
11281135
.await
11291136
{
11301137
Ok(content) => content,
1131-
Err(err) => {
1138+
Err(error) => {
11321139
info!(
1133-
"Skipping proposal from {owner} and validator {} at \
1134-
height {}; failed to download {blob_id}: {err}",
1135-
remote_node.public_key, local_info.next_block_height
1140+
remote_node = remote_node.address(),
1141+
height = %local_info.next_block_height,
1142+
proposer = %owner,
1143+
%blob_id,
1144+
%error,
1145+
"skipping proposal from validator; failed to download blob",
11361146
);
11371147
continue 'proposal_loop;
11381148
}
@@ -1195,8 +1205,11 @@ impl<Env: Environment> Client<Env> {
11951205
}
11961206

11971207
debug!(
1198-
"Skipping proposal from {owner} and validator {} at height {}: {err}",
1199-
remote_node.public_key, local_info.next_block_height
1208+
remote_node = remote_node.address(),
1209+
proposer = %owner,
1210+
height = %local_info.next_block_height,
1211+
error = %err,
1212+
"skipping proposal from validator",
12001213
);
12011214
}
12021215
}

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::{
@@ -354,12 +354,22 @@ pub struct RoundTimeout {
354354
pub next_block_height: BlockHeight,
355355
}
356356

357+
impl fmt::Display for RoundTimeout {
358+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
359+
write!(
360+
f,
361+
"{} at height {} times out at {}",
362+
self.current_round, self.next_block_height, self.timestamp
363+
)
364+
}
365+
}
366+
357367
impl<T> ClientOutcome<T> {
358368
#[cfg(with_testing)]
359369
pub fn unwrap(self) -> T {
360370
match self {
361371
ClientOutcome::Committed(t) => t,
362-
ClientOutcome::WaitForTimeout(timeout) => panic!("Unexpected timeout: {timeout:?}"),
372+
ClientOutcome::WaitForTimeout(timeout) => panic!("unexpected timeout: {timeout}"),
363373
}
364374
}
365375

linera-core/src/remote_node.rs

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

290295
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<(), ChainClientError> {
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)