Skip to content

Commit

Permalink
feat: PCES can use either birth round or generation (#10808)
Browse files Browse the repository at this point in the history
Signed-off-by: Austin Littley <[email protected]>
Signed-off-by: Cody Littley <[email protected]>
Co-authored-by: Austin Littley <[email protected]>
  • Loading branch information
cody-littley and Austin Littley authored Jan 11, 2024
1 parent a1d62b6 commit 688f3d5
Show file tree
Hide file tree
Showing 29 changed files with 1,709 additions and 1,236 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@
import com.swirlds.merkle.map.test.pta.MapKey;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

@Disabled("flaky")
class AccountTransactionFactoryTests {

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
import com.swirlds.platform.dispatch.DispatchConfiguration;
import com.swirlds.platform.dispatch.triggers.flow.DiskStateLoadedTrigger;
import com.swirlds.platform.dispatch.triggers.flow.ReconnectStateLoadedTrigger;
import com.swirlds.platform.event.AncientMode;
import com.swirlds.platform.event.EventCounter;
import com.swirlds.platform.event.GossipEvent;
import com.swirlds.platform.event.creation.EventCreationManager;
Expand Down Expand Up @@ -440,15 +441,25 @@ public class SwirldsPlatform implements Platform {
try {
final Path databaseDirectory = getDatabaseDirectory(platformContext, selfId);

// When we perform the migration to using birth round bounding, we will need to read
// the old type and start writing the new type.
final AncientMode currentFileType = platformContext
.getConfiguration()
.getConfigData(EventConfig.class)
.useBirthRoundAncientThreshold()
? AncientMode.BIRTH_ROUND_THRESHOLD
: AncientMode.GENERATION_THRESHOLD;

initialPcesFiles = PcesFileReader.readFilesFromDisk(
platformContext,
recycleBin,
databaseDirectory,
initialState.getRound(),
preconsensusEventStreamConfig.permitGaps());
preconsensusEventStreamConfig.permitGaps(),
currentFileType);

preconsensusEventFileManager = new PcesFileManager(
platformContext, Time.getCurrent(), initialPcesFiles, selfId, initialState.getRound());
preconsensusEventFileManager =
new PcesFileManager(platformContext, initialPcesFiles, selfId, initialState.getRound());
} catch (final IOException e) {
throw new UncheckedIOException(e);
}
Expand Down Expand Up @@ -791,7 +802,6 @@ public class SwirldsPlatform implements Platform {

platformWiring.updateNonAncientEventWindow(NonAncientEventWindow.createUsingPlatformContext(
initialState.getRound(), initialMinimumGenerationNonAncient, platformContext));
platformWiring.updateMinimumGenerationNonAncient(initialState.getMinRoundGeneration());

// We don't want to invoke these callbacks until after we are starting up.
final long round = initialState.getRound();
Expand Down Expand Up @@ -977,7 +987,6 @@ private void loadReconnectState(final SignedState signedState) {
signedState.getState().getPlatformState().getAddressBook()));
platformWiring.updateNonAncientEventWindow(NonAncientEventWindow.createUsingPlatformContext(
signedState.getRound(), signedState.getMinRoundGeneration(), platformContext));
platformWiring.updateMinimumGenerationNonAncient(signedState.getMinRoundGeneration());

consensusRoundHandler.loadDataFromSignedState(signedState, true);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ public void buildDescriptor() {
this.descriptor = hashedData.createEventDescriptor();
}

/**
* {@inheritDoc}
*/
@Override
public long getGeneration() {
return hashedData.getGeneration();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,18 @@ private BestEffortPcesFileCopy() {}
* fail as a result. This method retries several times if a failure is encountered. Success is not guaranteed, but
* success or failure is atomic and will not throw an exception.
*
* @param platformContext the platform context
* @param selfId the id of this node
* @param destinationDirectory the directory where the state is being written
* @param minimumGenerationNonAncient the minimum generation of events that are not ancient, with respect to the
* state that is being written
* @param round the round of the state that is being written
* @param platformContext the platform context
* @param selfId the id of this node
* @param destinationDirectory the directory where the state is being written
* @param lowerBound the lower bound of events that are not ancient, with respect to the state that is
* being written
* @param round the round of the state that is being written
*/
public static void copyPcesFilesRetryOnFailure(
@NonNull final PlatformContext platformContext,
@NonNull final NodeId selfId,
@NonNull final Path destinationDirectory,
final long minimumGenerationNonAncient,
final long lowerBound,
final long round) {

final boolean copyPreconsensusStream = platformContext
Expand All @@ -89,8 +89,7 @@ public static void copyPcesFilesRetryOnFailure(
try {
executeAndRename(
pcesDestination,
temporaryDirectory -> copyPcesFiles(
platformContext, selfId, temporaryDirectory, minimumGenerationNonAncient));
temporaryDirectory -> copyPcesFiles(platformContext, selfId, temporaryDirectory, lowerBound));

return;
} catch (final IOException | UncheckedIOException e) {
Expand Down Expand Up @@ -122,17 +121,17 @@ public static void copyPcesFilesRetryOnFailure(
* real production states and streams, in the short term. In the longer term we should consider alternate and
* cleaner strategies.
*
* @param platformContext the platform context
* @param selfId the id of this node
* @param destinationDirectory the directory where the PCES files should be written
* @param minimumGenerationNonAncient the minimum generation of events that are not ancient, with respect to the
* state that is being written
* @param platformContext the platform context
* @param selfId the id of this node
* @param destinationDirectory the directory where the PCES files should be written
* @param lowerBound the lower bound of events that are not ancient, with respect to the state that is
* being written
*/
private static void copyPcesFiles(
@NonNull final PlatformContext platformContext,
@NonNull final NodeId selfId,
@NonNull final Path destinationDirectory,
final long minimumGenerationNonAncient)
final long lowerBound)
throws IOException {

final List<PcesFile> allFiles = gatherPcesFilesOnDisk(selfId, platformContext);
Expand All @@ -144,7 +143,7 @@ private static void copyPcesFiles(
Collections.sort(allFiles);

// Discard all files that either have an incorrect origin or that do not contain non-ancient events.
final List<PcesFile> filesToCopy = getRequiredPcesFiles(allFiles, minimumGenerationNonAncient);
final List<PcesFile> filesToCopy = getRequiredPcesFiles(allFiles, lowerBound);
if (filesToCopy.isEmpty()) {
return;
}
Expand All @@ -156,51 +155,48 @@ private static void copyPcesFiles(
* Get the preconsensus files that we need to copy to a state. We need any file that has a matching origin and that
* contains non-ancient events (w.r.t. the state).
*
* @param allFiles all PCES files on disk
* @param minimumGenerationNonAncient the minimum generation of events that are not ancient, with respect to the
* state that is being written
* @param allFiles all PCES files on disk
* @param lowerBound the lower bound of events that are not ancient, with respect to the state that is being
* written
* @return the list of files to copy
*/
@NonNull
private static List<PcesFile> getRequiredPcesFiles(
@NonNull final List<PcesFile> allFiles, final long minimumGenerationNonAncient) {
private static List<PcesFile> getRequiredPcesFiles(@NonNull final List<PcesFile> allFiles, final long lowerBound) {

final List<PcesFile> filesToCopy = new ArrayList<>();
final PcesFile lastFile = allFiles.get(allFiles.size() - 1);
for (final PcesFile file : allFiles) {
if (file.getOrigin() == lastFile.getOrigin()
&& file.getMaximumGeneration() >= minimumGenerationNonAncient) {
if (file.getOrigin() == lastFile.getOrigin() && file.getUpperBound() >= lowerBound) {
filesToCopy.add(file);
}
}

if (filesToCopy.isEmpty()) {
logger.warn(
STATE_TO_DISK.getMarker(),
"No preconsensus event files meeting specified criteria found to copy. "
+ "Minimum generation non-ancient: {}",
minimumGenerationNonAncient);
"No preconsensus event files meeting specified criteria found to copy. Lower bound: {}",
lowerBound);
} else if (filesToCopy.size() == 1) {
logger.info(
STATE_TO_DISK.getMarker(),
"""
Found 1 preconsensus event file meeting specified criteria to copy.
Minimum generation non-ancient: {}
Lower bound: {}
File: {}
""",
minimumGenerationNonAncient,
lowerBound,
filesToCopy.get(0).getPath());
} else {
logger.info(
STATE_TO_DISK.getMarker(),
"""
Found {} preconsensus event files meeting specified criteria to copy.
Minimum generation non-ancient: {}
Lower bound: {}
First file to copy: {}
Last file to copy: {}
""",
filesToCopy.size(),
minimumGenerationNonAncient,
lowerBound,
filesToCopy.get(0).getPath(),
filesToCopy.get(filesToCopy.size() - 1).getPath());
}
Expand Down
Loading

0 comments on commit 688f3d5

Please sign in to comment.