Skip to content

Commit

Permalink
Update to new design
Browse files Browse the repository at this point in the history
  • Loading branch information
courtneyeh committed Apr 11, 2024
1 parent c33baf2 commit f1ddf82
Show file tree
Hide file tree
Showing 16 changed files with 143 additions and 133 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -760,13 +760,11 @@ private void reportInvalidBlock(final SignedBeaconBlock block, final BlockImport
if (result.getFailureReason() == FailureReason.BLOCK_IS_FROM_FUTURE) {
return;
}
final String savedFile =
p2pDumpManager.saveInvalidBlockToFile(
block.getSlot(), block.getRoot(), block.sszSerialize());
p2pDumpManager.saveInvalidBlockToFile(block.getSlot(), block.getRoot(), block.sszSerialize());
P2P_LOG.onInvalidBlock(
block.getSlot(),
block.getRoot(),
savedFile,
block.sszSerialize(),
result.getFailureReason().name(),
result.getFailureCause());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@

package tech.pegasys.teku.statetransition.util;

import com.google.common.annotations.VisibleForTesting;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
import tech.pegasys.teku.infrastructure.logging.LoggingConfigurator;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;

public class P2PDumpManager {
Expand All @@ -30,12 +30,16 @@ public class P2PDumpManager {
private static final String GOSSIP_REJECTED_DIR = "rejected_gossip_messages";
private static final String INVALID_BLOCK_DIR = "invalid_blocks";

private final boolean isIncludeP2pWarnings = LoggingConfigurator.isIncludeP2pWarnings();

private final boolean enabled;
private final Path directory;

public P2PDumpManager(final Path directory) {
public P2PDumpManager(final Path directory, final boolean enabled) {
this.enabled = enabled; // TODO fix directory structure
this.directory = directory;
if (!enabled) {
return;
}

if (this.directory.resolve(GOSSIP_DECODING_ERROR_DIR).toFile().mkdirs()) {
LOG.info(
String.format(
Expand All @@ -55,58 +59,62 @@ public P2PDumpManager(final Path directory) {
}
}

public String saveGossipMessageDecodingError(
public void saveGossipMessageDecodingError(
final String topic, final String arrivalTimestamp, final Bytes originalMessage) {
if (!isIncludeP2pWarnings) {
return "";
if (!enabled) {
return;
}
final String fileName = String.format("%s_%s.ssz", arrivalTimestamp, topic);
final String identifiers = String.format("Topic: %s", topic);
return saveBytesToFile(
saveBytesToFile(
"gossip message with decoding error",
GOSSIP_DECODING_ERROR_DIR,
fileName,
identifiers,
originalMessage);
}

public String saveGossipRejectedMessageToFile(
public void saveGossipRejectedMessageToFile(
final String topic, final String arrivalTimestamp, final Bytes decodedMessage) {
if (!isIncludeP2pWarnings) {
return "";
if (!enabled) {
return;
}
final String fileName = String.format("%s_%s.ssz", arrivalTimestamp, topic);
final String identifiers = String.format("Topic: %s", topic);
return saveBytesToFile(
saveBytesToFile(
"rejected gossip message", GOSSIP_REJECTED_DIR, fileName, identifiers, decodedMessage);
}

public String saveInvalidBlockToFile(
public void saveInvalidBlockToFile(
final UInt64 slot, final Bytes32 blockRoot, final Bytes blockSsz) {
if (!isIncludeP2pWarnings) {
return "";
if (!enabled) {
return;
}
final String fileName =
String.format("slot%s_root%s.ssz", slot, blockRoot.toUnprefixedHexString());
final String identifiers = String.format("Slot: %s, Block Root: %s", slot, blockRoot);
return saveBytesToFile("invalid block", INVALID_BLOCK_DIR, fileName, identifiers, blockSsz);
saveBytesToFile("invalid block", INVALID_BLOCK_DIR, fileName, identifiers, blockSsz);
}

private String saveBytesToFile(
private void saveBytesToFile(
final String object,
final String errorDirectory,
final String fileName,
final String identifiers,
final Bytes bytes) {
final Path path = directory.resolve(errorDirectory).resolve(fileName);
try {
return Files.write(path, bytes.toArray()).toString();

final String file =
Files.write(path, bytes.toArray())
.toString(); // todo change to not be printing the whole path
LOG.info("Saved {} bytes to file. {}. Location: {}", object, identifiers, file);
} catch (IOException e) {
final String errorMessage =
String.format("Failed to save %s bytes to file. %s", object, identifiers);
LOG.error(errorMessage, e);
return String.format("Error saving to %s", path);
LOG.error("Failed to save {}} bytes to file. {}", object, identifiers, e);
}
}

@VisibleForTesting
protected boolean isEnabled() {
return enabled;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,11 @@

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import org.apache.tuweni.bytes.Bytes;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import tech.pegasys.teku.infrastructure.logging.LoggingConfig;
import tech.pegasys.teku.infrastructure.logging.LoggingConfigurator;
import tech.pegasys.teku.infrastructure.time.StubTimeProvider;
import tech.pegasys.teku.spec.TestSpecFactory;
import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock;
Expand All @@ -36,79 +35,79 @@ class P2PDumpManagerTest {

@Test
void saveGossipMessageDecodingError_shouldSaveToFile(@TempDir Path tempDir) {
final P2PDumpManager manager = new P2PDumpManager(tempDir);
final P2PDumpManager manager = new P2PDumpManager(tempDir, true);
final Bytes messageBytes = dataStructureUtil.stateBuilderPhase0().build().sszSerialize();
final String arrivalTimestamp = timeProvider.getTimeInMillis().toString();
final String file =
manager.saveGossipMessageDecodingError("test_topic", arrivalTimestamp, messageBytes);
manager.saveGossipMessageDecodingError("test_topic", arrivalTimestamp, messageBytes);

final String fileName = String.format("%s_%s.ssz", arrivalTimestamp, "test_topic");
final Path expectedFile = tempDir.resolve("gossip_decoding_error_messages").resolve(fileName);
assertThat(file).isEqualTo(expectedFile.toString());
checkBytesSavedToFile(expectedFile, messageBytes);
}

@Test
void saveGossipMessageDecodingError_shouldNotSaveToFileWhenWarningsDisabled(
@TempDir Path tempDir) {
disableP2pWarnings();
final P2PDumpManager manager = new P2PDumpManager(tempDir);
void saveGossipMessageDecodingError_shouldNotSaveToFileWhenDisabled(@TempDir Path tempDir) {
final P2PDumpManager manager = new P2PDumpManager(tempDir, false);
final Bytes messageBytes = dataStructureUtil.stateBuilderPhase0().build().sszSerialize();
final String arrivalTimestamp = timeProvider.getTimeInMillis().toString();
final String file =
manager.saveGossipMessageDecodingError("test_topic", arrivalTimestamp, messageBytes);
assertThat(file).isEqualTo("");
manager.saveGossipMessageDecodingError("test_topic", arrivalTimestamp, messageBytes);
assertThat(manager.isEnabled()).isFalse();

final String fileName = String.format("%s_%s.ssz", arrivalTimestamp, "test_topic");
final Path expectedFile = tempDir.resolve("gossip_decoding_error_messages").resolve(fileName);
checkFileNotExist(expectedFile);
}

@Test
void saveGossipRejectedMessageToFile_shouldSaveToFile(@TempDir Path tempDir) {
final P2PDumpManager manager = new P2PDumpManager(tempDir);
final P2PDumpManager manager = new P2PDumpManager(tempDir, true);
final Bytes messageBytes = dataStructureUtil.stateBuilderPhase0().build().sszSerialize();
final String arrivalTimestamp = timeProvider.getTimeInMillis().toString();
final String file =
manager.saveGossipRejectedMessageToFile("test_topic", arrivalTimestamp, messageBytes);
manager.saveGossipRejectedMessageToFile("test_topic", arrivalTimestamp, messageBytes);

final String fileName = String.format("%s_%s.ssz", arrivalTimestamp, "test_topic");
final Path expectedFile = tempDir.resolve("rejected_gossip_messages").resolve(fileName);
assertThat(file).isEqualTo(expectedFile.toString());
checkBytesSavedToFile(expectedFile, messageBytes);
}

@Test
void saveGossipRejectedMessageToFile_shouldNotSaveToFileWhenWarningsDisabled(
@TempDir Path tempDir) {
disableP2pWarnings();
final P2PDumpManager manager = new P2PDumpManager(tempDir);
void saveGossipRejectedMessageToFile_shouldNotSaveToFileWhenDisabled(@TempDir Path tempDir) {
final P2PDumpManager manager = new P2PDumpManager(tempDir, false);
final Bytes messageBytes = dataStructureUtil.stateBuilderPhase0().build().sszSerialize();
final String arrivalTimestamp = timeProvider.getTimeInMillis().toString();
final String file =
manager.saveGossipRejectedMessageToFile("test_topic", arrivalTimestamp, messageBytes);
assertThat(file).isEqualTo("");
manager.saveGossipRejectedMessageToFile("test_topic", arrivalTimestamp, messageBytes);
assertThat(manager.isEnabled()).isFalse();

final String fileName = String.format("%s_%s.ssz", arrivalTimestamp, "test_topic");
final Path expectedFile = tempDir.resolve("rejected_gossip_messages").resolve(fileName);
checkFileNotExist(expectedFile);
}

@Test
void saveInvalidBlockToFile_shouldSaveToFile(@TempDir Path tempDir) {
final P2PDumpManager manager = new P2PDumpManager(tempDir);
final P2PDumpManager manager = new P2PDumpManager(tempDir, true);
final SignedBeaconBlock block = dataStructureUtil.randomSignedBeaconBlock();
final String file =
manager.saveInvalidBlockToFile(block.getSlot(), block.getRoot(), block.sszSerialize());
manager.saveInvalidBlockToFile(block.getSlot(), block.getRoot(), block.sszSerialize());

final String fileName =
String.format(
"slot%s_root%s.ssz", block.getSlot(), block.getRoot().toUnprefixedHexString());
final Path expectedFile = tempDir.resolve("invalid_blocks").resolve(fileName);
assertThat(file).isEqualTo(expectedFile.toString());
checkBytesSavedToFile(expectedFile, block.sszSerialize());
}

@Test
void saveInvalidBlockToFile_shouldNotSaveToFileWhenWarningsDisabled(@TempDir Path tempDir) {
disableP2pWarnings();
final P2PDumpManager manager = new P2PDumpManager(tempDir);
void saveInvalidBlockToFile_shouldNotSaveToFileWhenDisabled(@TempDir Path tempDir) {
final P2PDumpManager manager = new P2PDumpManager(tempDir, false);
final SignedBeaconBlock block = dataStructureUtil.randomSignedBeaconBlock();
final String file =
manager.saveInvalidBlockToFile(block.getSlot(), block.getRoot(), block.sszSerialize());
assertThat(file).isEqualTo("");
manager.saveInvalidBlockToFile(block.getSlot(), block.getRoot(), block.sszSerialize());
assertThat(manager.isEnabled()).isFalse();

final String fileName =
String.format(
"slot%s_root%s.ssz", block.getSlot(), block.getRoot().toUnprefixedHexString());
final Path expectedFile = tempDir.resolve("invalid_blocks").resolve(fileName);
checkFileNotExist(expectedFile);
}

private void checkBytesSavedToFile(final Path path, final Bytes expectedBytes) {
Expand All @@ -120,12 +119,14 @@ private void checkBytesSavedToFile(final Path path, final Bytes expectedBytes) {
}
}

private void disableP2pWarnings() {
LoggingConfigurator.update(
LoggingConfig.builder()
.logDirectory(".")
.logFileNamePrefix("prefix")
.includeP2pWarningsEnabled(false)
.build());
private void checkFileNotExist(final Path path) {
try {
Bytes.wrap(Files.readAllBytes(path));
} catch (IOException e) {
if (e instanceof NoSuchFileException) {
return;
}
}
fail("File was found and bytes read");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import java.util.Optional;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;

Expand All @@ -32,40 +33,40 @@ public P2PLogger(final String name) {
}

public void onGossipMessageDecodingError(
final String topic, final String savedFile, final Throwable error) {
final String topic, final Bytes originalMessage, final Throwable error) {
if (isIncludeP2pWarnings) {
log.warn(
"Failed to decode gossip message on topic {}, raw message location: {}",
"Failed to decode gossip message on topic {}, raw message: {}",
topic,
savedFile,
originalMessage,
error);
}
}

public void onGossipRejected(
final String topic, final String savedFile, final Optional<String> description) {
final String topic, final Bytes decodedMessage, final Optional<String> description) {
if (isIncludeP2pWarnings) {
log.warn(
"Rejecting gossip message on topic {}, reason: {}, decoded message location: {}",
"Rejecting gossip message on topic {}, reason: {}, decoded message: {}",
topic,
description.orElse("failed validation"),
savedFile);
decodedMessage);
}
}

public void onInvalidBlock(
final UInt64 slot,
final Bytes32 blockRoot,
final String savedFile,
final Bytes blockSsz,
final String failureReason,
final Optional<Throwable> failureCause) {
if (isIncludeP2pWarnings) {
log.warn(
"Rejecting invalid block at slot {} with root {} because {}. Full block data location: {}",
"Rejecting invalid block at slot {} with root {} because {}. Full block data: {}",
slot,
blockRoot,
failureReason,
savedFile,
blockSsz,
failureCause.orElse(null));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,14 @@ public static Path defaultDataPath() {
private final Path dataBasePath;
private final Optional<Path> beaconDataPath;
private final Optional<Path> validatorDataPath;
private final Optional<Path> p2pDumpsDataPath;

private DataConfig(
final Path dataBasePath,
final Optional<Path> beaconDataPath,
final Optional<Path> validatorDataPath,
final Optional<Path> p2pDumpsDataPath) {
final Optional<Path> validatorDataPath) {
this.dataBasePath = dataBasePath;
this.beaconDataPath = beaconDataPath;
this.validatorDataPath = validatorDataPath;
this.p2pDumpsDataPath = p2pDumpsDataPath;
}

public static DataConfig.Builder builder() {
Expand All @@ -56,16 +53,11 @@ public Optional<Path> getValidatorDataPath() {
return validatorDataPath;
}

public Optional<Path> getP2pDumpsDataPath() {
return p2pDumpsDataPath;
}

public static final class Builder {

private Path dataBasePath = defaultDataPath();
private Optional<Path> beaconDataPath = Optional.empty();
private Optional<Path> validatorDataPath = Optional.empty();
private Optional<Path> p2pDumpsDataPath = Optional.empty();

private Builder() {}

Expand All @@ -84,16 +76,11 @@ public Builder validatorDataPath(Path validatorDataPath) {
return this;
}

public Builder p2pDumpsDataPath(Path p2pDumpsDataPath) {
this.p2pDumpsDataPath = Optional.ofNullable(p2pDumpsDataPath);
return this;
}

public DataConfig build() {
if (dataBasePath == null) {
throw new InvalidConfigurationException("data-base-path must be specified");
}
return new DataConfig(dataBasePath, beaconDataPath, validatorDataPath, p2pDumpsDataPath);
return new DataConfig(dataBasePath, beaconDataPath, validatorDataPath);
}
}
}
Loading

0 comments on commit f1ddf82

Please sign in to comment.