Skip to content

Commit 721e66d

Browse files
committed
Update success logging to be consistent with P2PLogger
1 parent 689c9b7 commit 721e66d

File tree

7 files changed

+120
-53
lines changed

7 files changed

+120
-53
lines changed

Diff for: ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/forkchoice/ForkChoice.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -760,7 +760,12 @@ private void reportInvalidBlock(final SignedBeaconBlock block, final BlockImport
760760
if (result.getFailureReason() == FailureReason.BLOCK_IS_FROM_FUTURE) {
761761
return;
762762
}
763-
debugDataDumper.saveInvalidBlockToFile(block.getSlot(), block.getRoot(), block.sszSerialize());
763+
debugDataDumper.saveInvalidBlockToFile(
764+
block.getSlot(),
765+
block.getRoot(),
766+
block.sszSerialize(),
767+
result.getFailureReason().name(),
768+
result.getFailureCause());
764769
P2P_LOG.onInvalidBlock(
765770
block.getSlot(),
766771
block.getRoot(),

Diff for: ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/util/DebugDataDumper.java

+47-25
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@ public DebugDataDumper(final Path directory, final boolean enabled) {
6060
}
6161

6262
public void saveGossipMessageDecodingError(
63-
final String topic, final Optional<UInt64> arrivalTimestamp, final Bytes originalMessage) {
63+
final String topic,
64+
final Optional<UInt64> arrivalTimestamp,
65+
final Bytes originalMessage,
66+
final Throwable error) {
6467
if (!enabled) {
6568
return;
6669
}
@@ -70,74 +73,93 @@ public void saveGossipMessageDecodingError(
7073
Path.of(GOSSIP_MESSAGES_DIR)
7174
.resolve(DECODING_ERROR_SUB_DIR)
7275
.resolve(topic.replaceAll("/", "_"));
73-
final String identifiers = String.format("on topic %s at %s", topic, formattedTimestamp);
74-
saveBytesToFile(
75-
"gossip message with decoding error",
76-
identifiers,
77-
topicPath.resolve(fileName),
78-
originalMessage);
76+
final boolean success =
77+
saveBytesToFile(
78+
"gossip message with decoding error", topicPath.resolve(fileName), originalMessage);
79+
if (success) {
80+
LOG.warn("Failed to decode gossip message on topic {}", topic, error);
81+
}
7982
}
8083

8184
public void saveGossipRejectedMessageToFile(
82-
final String topic, final Optional<UInt64> arrivalTimestamp, final Bytes decodedMessage) {
85+
final String topic,
86+
final Optional<UInt64> arrivalTimestamp,
87+
final Bytes decodedMessage,
88+
final Optional<String> reason) {
8389
if (!enabled) {
8490
return;
8591
}
8692
final String formattedTimestamp = formatOptionalTimestamp(arrivalTimestamp);
8793
final String fileName = String.format("%s.ssz", formattedTimestamp);
8894
final Path topicPath =
8995
Path.of(GOSSIP_MESSAGES_DIR).resolve(REJECTED_SUB_DIR).resolve(topic.replaceAll("/", "_"));
90-
final String identifiers = String.format("on topic %s at %s", topic, formattedTimestamp);
91-
saveBytesToFile(
92-
"rejected gossip message", identifiers, topicPath.resolve(fileName), decodedMessage);
96+
final boolean success =
97+
saveBytesToFile("rejected gossip message", topicPath.resolve(fileName), decodedMessage);
98+
if (success) {
99+
LOG.warn(
100+
"Rejecting gossip message on topic {}, reason: {}",
101+
topic,
102+
reason.orElse("failed validation"));
103+
}
93104
}
94105

95106
public void saveInvalidBlockToFile(
96-
final UInt64 slot, final Bytes32 blockRoot, final Bytes blockSsz) {
107+
final UInt64 slot,
108+
final Bytes32 blockRoot,
109+
final Bytes blockSsz,
110+
final String failureReason,
111+
final Optional<Throwable> failureCause) {
97112
if (!enabled) {
98113
return;
99114
}
100115
final String fileName = String.format("%s_%s.ssz", slot, blockRoot.toUnprefixedHexString());
101-
final String identifiers = String.format("at slot %s(%s)", slot, blockRoot);
102-
saveBytesToFile(
103-
"invalid block", identifiers, Path.of(INVALID_BLOCK_DIR).resolve(fileName), blockSsz);
116+
final boolean success =
117+
saveBytesToFile("invalid block", Path.of(INVALID_BLOCK_DIR).resolve(fileName), blockSsz);
118+
if (success) {
119+
LOG.warn(
120+
"Rejecting invalid block at slot {} with root {} because {}",
121+
slot,
122+
blockRoot,
123+
failureReason,
124+
failureCause.orElse(null));
125+
}
104126
}
105127

106128
@VisibleForTesting
107-
protected void saveBytesToFile(
108-
final String description,
109-
final String identifiers,
110-
final Path relativeFilePath,
111-
final Bytes bytes) {
129+
protected boolean saveBytesToFile(
130+
final String description, final Path relativeFilePath, final Bytes bytes) {
112131
final Path path = directory.resolve(relativeFilePath);
113132
try {
114133
Files.write(path, bytes.toArray());
115-
LOG.info("Saved {} {}", description, identifiers);
116134
} catch (NoSuchFileException e) {
117135
if (!path.getParent().toFile().mkdirs()) {
118136
LOG.error("Failed to save {} bytes to file.", description, e);
119-
return;
137+
return false;
120138
}
121-
saveAfterCreatingTopicDirectory(description, relativeFilePath, bytes);
139+
return saveAfterCreatingTopicDirectory(description, relativeFilePath, bytes);
122140
} catch (IOException e) {
123141
LOG.error("Failed to save {} bytes to file.", description, e);
142+
return false;
124143
}
144+
return true;
125145
}
126146

127-
private void saveAfterCreatingTopicDirectory(
147+
private boolean saveAfterCreatingTopicDirectory(
128148
final String description, final Path relativeFilePath, final Bytes bytes) {
129149
final Path path = directory.resolve(relativeFilePath);
130150
try {
131151
Files.write(path, bytes.toArray());
132-
LOG.info("Saved {} ", description);
133152
} catch (IOException e) {
134153
LOG.error("Failed to save {} bytes to file.", description, e);
135154
if (!path.getParent().toFile().exists()) {
155+
this.enabled = false;
136156
LOG.error(
137157
"{} directory does not exist. Disabling saving debug data to file.",
138158
relativeFilePath.getParent());
139159
}
160+
return false;
140161
}
162+
return true;
141163
}
142164

143165
private void createDirectory(

Diff for: ethereum/statetransition/src/main/java/tech/pegasys/teku/statetransition/util/noop/NoOpDebugDataDumper.java

+13-3
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,23 @@ public NoOpDebugDataDumper() {
2828

2929
@Override
3030
public void saveGossipMessageDecodingError(
31-
final String topic, final Optional<UInt64> arrivalTimestamp, final Bytes originalMessage) {}
31+
final String topic,
32+
final Optional<UInt64> arrivalTimestamp,
33+
final Bytes originalMessage,
34+
final Throwable error) {}
3235

3336
@Override
3437
public void saveGossipRejectedMessageToFile(
35-
final String topic, final Optional<UInt64> arrivalTimestamp, final Bytes decodedMessage) {}
38+
final String topic,
39+
final Optional<UInt64> arrivalTimestamp,
40+
final Bytes decodedMessage,
41+
final Optional<String> reason) {}
3642

3743
@Override
3844
public void saveInvalidBlockToFile(
39-
final UInt64 slot, final Bytes32 blockRoot, final Bytes blockSsz) {}
45+
final UInt64 slot,
46+
final Bytes32 blockRoot,
47+
final Bytes blockSsz,
48+
final String failureReason,
49+
final Optional<Throwable> failureCause) {}
4050
}

Diff for: ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/forkchoice/ForkChoiceTest.java

+18-5
Original file line numberDiff line numberDiff line change
@@ -307,16 +307,19 @@ void onBlock_consensusValidationShouldNotResolveWhenStateTransitionFails()
307307

308308
final BlockProcessor blockProcessor = mock(BlockProcessor.class);
309309
when(spec.getBlockProcessor(blockAndState.getSlot())).thenReturn(blockProcessor);
310+
final Exception blockException = new StateTransitionException("error!");
310311
when(blockProcessor.processAndValidateBlock(any(), any(), any(), any()))
311-
.thenThrow(new StateTransitionException("error!"));
312+
.thenThrow(blockException);
312313

313314
importBlockAndAssertFailure(blockAndState, FailureReason.FAILED_STATE_TRANSITION);
314315

315316
verify(debugDataDumper)
316317
.saveInvalidBlockToFile(
317318
eq(blockAndState.getSlot()),
318319
eq(blockAndState.getBlock().getRoot()),
319-
eq(blockAndState.getBlock().sszSerialize()));
320+
eq(blockAndState.getBlock().sszSerialize()),
321+
eq(FailureReason.FAILED_STATE_TRANSITION.toString()),
322+
eq(Optional.of(blockException)));
320323
verify(blockBroadcastValidator, never()).onConsensusValidationSucceeded();
321324
}
322325

@@ -347,7 +350,9 @@ void onBlock_consensusValidationShouldReturnRegardlessExecutionPayloadValidation
347350
// resolve with a failure
348351
payloadStatusSafeFuture.complete(PayloadStatus.invalid(Optional.empty(), Optional.empty()));
349352
assertBlockImportFailure(importResult, FailureReason.FAILED_STATE_TRANSITION);
350-
verify(debugDataDumper).saveInvalidBlockToFile(any(), any(), any());
353+
verify(debugDataDumper)
354+
.saveInvalidBlockToFile(
355+
any(), any(), any(), eq(FailureReason.FAILED_STATE_TRANSITION.toString()), any());
351356
}
352357

353358
@Test
@@ -747,7 +752,13 @@ void onBlock_shouldNotOptimisticallyImportInvalidExecutionPayload() {
747752
storageSystem.chainUpdater().setCurrentSlot(slotToImport.increment());
748753
importBlockAndAssertFailure(
749754
chainBuilder.generateNextBlock(), FailureReason.FAILED_STATE_TRANSITION);
750-
verify(debugDataDumper).saveInvalidBlockToFile(eq(slotToImport.increment()), any(), any());
755+
verify(debugDataDumper)
756+
.saveInvalidBlockToFile(
757+
eq(slotToImport.increment()),
758+
any(),
759+
any(),
760+
eq(FailureReason.FAILED_STATE_TRANSITION.toString()),
761+
any());
751762
}
752763

753764
@Test
@@ -788,7 +799,9 @@ void onBlock_shouldChangeForkChoiceForLatestValidHashOnInvalidExecutionPayload()
788799
.saveInvalidBlockToFile(
789800
eq(invalidBlock.getSlot()),
790801
eq(invalidBlock.getRoot()),
791-
eq(invalidBlock.getBlock().sszSerialize()));
802+
eq(invalidBlock.getBlock().sszSerialize()),
803+
eq(FailureReason.FAILED_STATE_TRANSITION.toString()),
804+
any());
792805
assertHeadIsOptimistic(maybeValidBlock);
793806
assertThat(forkChoiceStrategy.getChainHeads().get(0).getRoot())
794807
.isEqualTo(maybeValidBlock.getRoot());

Diff for: ethereum/statetransition/src/test/java/tech/pegasys/teku/statetransition/util/DebugDataDumperTest.java

+28-12
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ void saveGossipMessageDecodingError_shouldSaveToFile(@TempDir Path tempDir) {
4747
final DebugDataDumper manager = new DebugDataDumper(tempDir, true);
4848
final Bytes messageBytes = dataStructureUtil.stateBuilderPhase0().build().sszSerialize();
4949
final Optional<UInt64> arrivalTimestamp = Optional.of(timeProvider.getTimeInMillis());
50-
manager.saveGossipMessageDecodingError("/eth/test/topic", arrivalTimestamp, messageBytes);
50+
manager.saveGossipMessageDecodingError(
51+
"/eth/test/topic", arrivalTimestamp, messageBytes, new Throwable());
5152

5253
final String fileName =
5354
String.format("%s.ssz", manager.formatTimestamp(timeProvider.getTimeInMillis()));
@@ -65,7 +66,8 @@ void saveGossipMessageDecodingError_shouldNotSaveToFileWhenDisabled(@TempDir Pat
6566
final DebugDataDumper manager = new DebugDataDumper(tempDir, false);
6667
final Bytes messageBytes = dataStructureUtil.stateBuilderPhase0().build().sszSerialize();
6768
final Optional<UInt64> arrivalTimestamp = Optional.of(timeProvider.getTimeInMillis());
68-
manager.saveGossipMessageDecodingError("/eth/test/topic", arrivalTimestamp, messageBytes);
69+
manager.saveGossipMessageDecodingError(
70+
"/eth/test/topic", arrivalTimestamp, messageBytes, new Throwable());
6971
assertThat(manager.isEnabled()).isFalse();
7072

7173
final String fileName =
@@ -84,7 +86,8 @@ void saveGossipRejectedMessageToFile_shouldSaveToFile(@TempDir Path tempDir) {
8486
final DebugDataDumper manager = new DebugDataDumper(tempDir, true);
8587
final Bytes messageBytes = dataStructureUtil.stateBuilderPhase0().build().sszSerialize();
8688
final Optional<UInt64> arrivalTimestamp = Optional.of(timeProvider.getTimeInMillis());
87-
manager.saveGossipRejectedMessageToFile("/eth/test/topic", arrivalTimestamp, messageBytes);
89+
manager.saveGossipRejectedMessageToFile(
90+
"/eth/test/topic", arrivalTimestamp, messageBytes, Optional.of("reason"));
8891

8992
final String fileName =
9093
String.format("%s.ssz", manager.formatTimestamp(timeProvider.getTimeInMillis()));
@@ -102,7 +105,8 @@ void saveGossipRejectedMessageToFile_shouldNotSaveToFileWhenDisabled(@TempDir Pa
102105
final DebugDataDumper manager = new DebugDataDumper(tempDir, false);
103106
final Bytes messageBytes = dataStructureUtil.stateBuilderPhase0().build().sszSerialize();
104107
final Optional<UInt64> arrivalTimestamp = Optional.of(timeProvider.getTimeInMillis());
105-
manager.saveGossipRejectedMessageToFile("/eth/test/topic", arrivalTimestamp, messageBytes);
108+
manager.saveGossipRejectedMessageToFile(
109+
"/eth/test/topic", arrivalTimestamp, messageBytes, Optional.of("reason"));
106110
assertThat(manager.isEnabled()).isFalse();
107111

108112
final String fileName = String.format("%s.ssz", arrivalTimestamp);
@@ -119,7 +123,12 @@ void saveGossipRejectedMessageToFile_shouldNotSaveToFileWhenDisabled(@TempDir Pa
119123
void saveInvalidBlockToFile_shouldSaveToFile(@TempDir Path tempDir) {
120124
final DebugDataDumper manager = new DebugDataDumper(tempDir, true);
121125
final SignedBeaconBlock block = dataStructureUtil.randomSignedBeaconBlock();
122-
manager.saveInvalidBlockToFile(block.getSlot(), block.getRoot(), block.sszSerialize());
126+
manager.saveInvalidBlockToFile(
127+
block.getSlot(),
128+
block.getRoot(),
129+
block.sszSerialize(),
130+
"reason",
131+
Optional.of(new Throwable()));
123132

124133
final String fileName =
125134
String.format("%s_%s.ssz", block.getSlot(), block.getRoot().toUnprefixedHexString());
@@ -131,7 +140,8 @@ void saveInvalidBlockToFile_shouldSaveToFile(@TempDir Path tempDir) {
131140
void saveInvalidBlockToFile_shouldNotSaveToFileWhenDisabled(@TempDir Path tempDir) {
132141
final DebugDataDumper manager = new DebugDataDumper(tempDir, false);
133142
final SignedBeaconBlock block = dataStructureUtil.randomSignedBeaconBlock();
134-
manager.saveInvalidBlockToFile(block.getSlot(), block.getRoot(), block.sszSerialize());
143+
manager.saveInvalidBlockToFile(
144+
block.getSlot(), block.getRoot(), block.sszSerialize(), "reason", Optional.empty());
135145
assertThat(manager.isEnabled()).isFalse();
136146

137147
final String fileName =
@@ -144,9 +154,12 @@ void saveInvalidBlockToFile_shouldNotSaveToFileWhenDisabled(@TempDir Path tempDi
144154
void saveBytesToFile_shouldNotThrowExceptionWhenNoDirectory(@TempDir Path tempDir) {
145155
final DebugDataDumper manager = new DebugDataDumper(tempDir, true);
146156
assertDoesNotThrow(
147-
() ->
148-
manager.saveBytesToFile(
149-
"object", "at slot 1", Path.of("invalid").resolve("file.ssz"), Bytes.EMPTY));
157+
() -> {
158+
final boolean success =
159+
manager.saveBytesToFile(
160+
"object", Path.of("invalid").resolve("file.ssz"), Bytes.EMPTY);
161+
assertThat(success).isTrue(); // creates directory
162+
});
150163
}
151164

152165
@Test
@@ -157,9 +170,12 @@ void saveBytesToFile_shouldNotEscalateWhenIOException(@TempDir Path tempDir) {
157170
assertThat(invalidPath.mkdirs()).isTrue();
158171
assertThat(invalidPath.setWritable(false)).isTrue();
159172
assertDoesNotThrow(
160-
() ->
161-
manager.saveBytesToFile(
162-
"object", "at slot 1", Path.of("invalid").resolve("file.ssz"), Bytes.EMPTY));
173+
() -> {
174+
final boolean success =
175+
manager.saveBytesToFile(
176+
"object", Path.of("invalid").resolve("file.ssz"), Bytes.EMPTY);
177+
assertThat(success).isFalse();
178+
});
163179
}
164180

165181
@Test

Diff for: networking/eth2/src/main/java/tech/pegasys/teku/networking/eth2/gossip/topics/topichandlers/Eth2TopicHandler.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,8 @@ private void processMessage(
138138
debugDataDumper.saveGossipRejectedMessageToFile(
139139
getTopic(),
140140
message.getArrivalTimestamp(),
141-
message.getDecodedMessage().getDecodedMessage().orElse(Bytes.EMPTY));
141+
message.getDecodedMessage().getDecodedMessage().orElse(Bytes.EMPTY),
142+
internalValidationResult.getDescription());
142143
P2P_LOG.onGossipRejected(
143144
getTopic(),
144145
message.getDecodedMessage().getDecodedMessage().orElse(Bytes.EMPTY),
@@ -172,7 +173,7 @@ protected ValidationResult handleMessageProcessingError(
172173
if (ExceptionUtil.hasCause(err, DecodingException.class)) {
173174

174175
debugDataDumper.saveGossipMessageDecodingError(
175-
getTopic(), message.getArrivalTimestamp(), message.getOriginalMessage());
176+
getTopic(), message.getArrivalTimestamp(), message.getOriginalMessage(), err);
176177
P2P_LOG.onGossipMessageDecodingError(getTopic(), message.getOriginalMessage(), err);
177178
response = ValidationResult.Invalid;
178179
} else if (ExceptionUtil.hasCause(err, RejectedExecutionException.class)) {

Diff for: networking/eth2/src/test/java/tech/pegasys/teku/networking/eth2/gossip/topics/Eth2TopicHandlerTest.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public void handleMessage_invalid() {
9292
topicHandler.handleMessage(topicHandler.prepareMessage(blockBytes, Optional.empty()));
9393
asyncRunner.executeQueuedActions();
9494
verify(debugDataDumper)
95-
.saveGossipRejectedMessageToFile(eq(topicHandler.getTopic()), any(), any());
95+
.saveGossipRejectedMessageToFile(eq(topicHandler.getTopic()), any(), any(), any());
9696
assertThatSafeFuture(result).isCompletedWithValue(ValidationResult.Invalid);
9797
}
9898

@@ -125,7 +125,7 @@ public void handleMessage_invalidBytes() {
125125
final SafeFuture<ValidationResult> result =
126126
topicHandler.handleMessage(topicHandler.prepareMessage(invalidBytes, Optional.empty()));
127127
verify(debugDataDumper)
128-
.saveGossipMessageDecodingError(eq(topicHandler.getTopic()), any(), any());
128+
.saveGossipMessageDecodingError(eq(topicHandler.getTopic()), any(), any(), any());
129129
asyncRunner.executeQueuedActions();
130130

131131
assertThatSafeFuture(result).isCompletedWithValue(ValidationResult.Invalid);
@@ -148,7 +148,7 @@ public void handleMessage_errorWhileProcessing_decodingException() {
148148
final SafeFuture<ValidationResult> result =
149149
topicHandler.handleMessage(topicHandler.prepareMessage(blockBytes, Optional.empty()));
150150
verify(debugDataDumper)
151-
.saveGossipMessageDecodingError(eq(topicHandler.getTopic()), any(), any());
151+
.saveGossipMessageDecodingError(eq(topicHandler.getTopic()), any(), any(), any());
152152
asyncRunner.executeQueuedActions();
153153

154154
assertThatSafeFuture(result).isCompletedWithValue(ValidationResult.Invalid);
@@ -171,7 +171,7 @@ public void handleMessage_errorWhileProcessing_wrappedDecodingException() {
171171
final SafeFuture<ValidationResult> result =
172172
topicHandler.handleMessage(topicHandler.prepareMessage(blockBytes, Optional.empty()));
173173
verify(debugDataDumper)
174-
.saveGossipMessageDecodingError(eq(topicHandler.getTopic()), any(), any());
174+
.saveGossipMessageDecodingError(eq(topicHandler.getTopic()), any(), any(), any());
175175
asyncRunner.executeQueuedActions();
176176

177177
assertThatSafeFuture(result).isCompletedWithValue(ValidationResult.Invalid);
@@ -194,7 +194,7 @@ public void handleMessage_errorWhileProcessing_decodingExceptionWithCause() {
194194
final SafeFuture<ValidationResult> result =
195195
topicHandler.handleMessage(topicHandler.prepareMessage(blockBytes, Optional.empty()));
196196
verify(debugDataDumper)
197-
.saveGossipMessageDecodingError(eq(topicHandler.getTopic()), any(), any());
197+
.saveGossipMessageDecodingError(eq(topicHandler.getTopic()), any(), any(), any());
198198
asyncRunner.executeQueuedActions();
199199

200200
assertThatSafeFuture(result).isCompletedWithValue(ValidationResult.Invalid);

0 commit comments

Comments
 (0)