Skip to content

Commit

Permalink
fix: unit tests in IssDetectorTests (#17128)
Browse files Browse the repository at this point in the history
Signed-off-by: Ivan Kavaldzhiev <ivankavaldzhiev@gmail.com>
  • Loading branch information
IvanKavaldzhiev authored Dec 19, 2024
1 parent 0bb55fe commit 1f6a473
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 75 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023-2024 Hedera Hashgraph, LLC
* Copyright (C) 2024 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -616,9 +616,6 @@ private void wire() {
final OutputWire<ReservedSignedState> hashedStateOutputWire =
hashedStateAndRoundOutputWire.buildAdvancedTransformer(
new StateAndRoundToStateReserver("postHasher_stateReserver"));
final OutputWire<ConsensusRound> hashedConsensusRoundOutput = stateHasherWiring
.getOutputWire()
.buildTransformer("postHasher_getConsensusRound", "stateAndRound", StateAndRound::round);

transactionHandlerWiring
.getOutputWire()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2024 Hedera Hashgraph, LLC
* Copyright (C) 2024 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -37,7 +37,7 @@
import com.swirlds.common.crypto.Hash;
import com.swirlds.common.platform.NodeId;
import com.swirlds.common.test.fixtures.Randotron;
import com.swirlds.platform.components.transaction.system.ScopedSystemTransaction;
import com.swirlds.platform.components.transaction.system.SystemTransactionExtractionUtils;
import com.swirlds.platform.consensus.ConsensusConfig;
import com.swirlds.platform.internal.ConsensusRound;
import com.swirlds.platform.internal.EventImpl;
Expand Down Expand Up @@ -203,14 +203,16 @@ void noIss() {
final List<EventImpl> eventsToInclude = selectRandomEvents(random, signatureEvents);
final ConsensusRound consensusRound = createRoundWithSignatureEvents(currentRound, eventsToInclude);

final var systemTransactions = getScopedSystemTransactions(currentRound, roundHash);
final var systemTransactions =
SystemTransactionExtractionUtils.extractFromRound(consensusRound, StateSignatureTransaction.class);
issDetectorTestHelper.handleStateAndRound(
new StateAndRound(mockState(currentRound, roundHash), consensusRound, systemTransactions));
}

// Add all remaining unsubmitted signature events
final ConsensusRound consensusRound = createRoundWithSignatureEvents(currentRound, signatureEvents);
final var systemTransactions = getScopedSystemTransactions(currentRound, randomHash(random));
final var systemTransactions =
SystemTransactionExtractionUtils.extractFromRound(consensusRound, StateSignatureTransaction.class);
issDetectorTestHelper.handleStateAndRound(
new StateAndRound(mockState(currentRound, randomHash(random)), consensusRound, systemTransactions));

Expand All @@ -227,22 +229,6 @@ void noIss() {
assertMarkerFile(IssType.OTHER_ISS.toString(), false);
}

private List<ScopedSystemTransaction<StateSignatureTransaction>> getScopedSystemTransactions(
long currentRound, Hash roundHash) {
final var semanticVersion = new SemanticVersion(1, 0, 0, null, null);
final var stateSignatureTransaction = StateSignatureTransaction.newBuilder()
.round(currentRound)
.signature(Bytes.EMPTY)
.hash(roundHash.getBytes())
.build();

final var scopedSystemTransaction =
new ScopedSystemTransaction(NodeId.of(1), semanticVersion, stateSignatureTransaction);
final var systemTransactions = new ArrayList<ScopedSystemTransaction<StateSignatureTransaction>>();
systemTransactions.add(scopedSystemTransaction);
return systemTransactions;
}

/**
* This test goes through a series of rounds, some of which experience ISSes. The test verifies that the expected
* number of ISSes are registered by the ISS detector.
Expand Down Expand Up @@ -340,16 +326,16 @@ void mixedOrderTest() {
final List<EventImpl> eventsToInclude = selectRandomEvents(random, signatureEvents);

final ConsensusRound consensusRound = createRoundWithSignatureEvents(currentRound, eventsToInclude);
final var systemTransactions = currentRound % 2 == 1
? getScopedSystemTransactions(currentRound, randomHash(random))
: new ArrayList<ScopedSystemTransaction<StateSignatureTransaction>>();
final var systemTransactions =
SystemTransactionExtractionUtils.extractFromRound(consensusRound, StateSignatureTransaction.class);
issDetectorTestHelper.handleStateAndRound(new StateAndRound(
mockState(currentRound, selfHashes.get((int) currentRound)), consensusRound, systemTransactions));
}

// Add all remaining signature events
final ConsensusRound consensusRound = createRoundWithSignatureEvents(roundsNonAncient, signatureEvents);
final var systemTransactions = getScopedSystemTransactions(currentRound, randomHash(random));
final var systemTransactions =
SystemTransactionExtractionUtils.extractFromRound(consensusRound, StateSignatureTransaction.class);
issDetectorTestHelper.handleStateAndRound(
new StateAndRound(mockState(roundsNonAncient, randomHash(random)), consensusRound, systemTransactions));

Expand Down Expand Up @@ -430,22 +416,22 @@ void decideForCatastrophicIss() {
generateEventsContainingSignatures(random, currentRound, catastrophicHashData);

// handle the catastrophic round, but don't submit any signatures yet, so it won't be detected
final var systemTransactions = getScopedSystemTransactions(currentRound, randomHash(random));
final var catastrophicRound = createRoundWithSignatureEvents(currentRound, List.of());
final var systemTransactionsForCatastrophicRound =
SystemTransactionExtractionUtils.extractFromRound(catastrophicRound, StateSignatureTransaction.class);
issDetectorTestHelper.handleStateAndRound(new StateAndRound(
mockState(currentRound, selfHashForCatastrophicRound),
createRoundWithSignatureEvents(currentRound, List.of()),
systemTransactions));
catastrophicRound,
systemTransactionsForCatastrophicRound));

// handle some more rounds on top of the catastrophic round
for (currentRound++; currentRound < 10; currentRound++) {
// don't include any signatures
final var systemTransactionsForNonCatastrophicRound = currentRound % 2 == 1
? getScopedSystemTransactions(currentRound, randomHash(random))
: new ArrayList<ScopedSystemTransaction<StateSignatureTransaction>>();
final var anotherRound = createRoundWithSignatureEvents(currentRound, List.of());
final var systemTransactionsForRoundWithoutSignatures =
SystemTransactionExtractionUtils.extractFromRound(anotherRound, StateSignatureTransaction.class);
issDetectorTestHelper.handleStateAndRound(new StateAndRound(
mockState(currentRound, randomHash()),
createRoundWithSignatureEvents(currentRound, List.of()),
systemTransactionsForNonCatastrophicRound));
mockState(currentRound, randomHash()), anotherRound, systemTransactionsForRoundWithoutSignatures));
}

// submit signatures on the ISS round that represent a minority of the weight
Expand All @@ -462,13 +448,11 @@ void decideForCatastrophicIss() {
signaturesToSubmit.add(signatureEvent);
}

final var moreSystemTransactions = currentRound % 2 == 1
? getScopedSystemTransactions(currentRound, randomHash(random))
: new ArrayList<ScopedSystemTransaction<StateSignatureTransaction>>();
final var roundWithMajority = createRoundWithSignatureEvents(currentRound, signaturesToSubmit);
final var systemTransactionsForRoundWithMajority =
SystemTransactionExtractionUtils.extractFromRound(roundWithMajority, StateSignatureTransaction.class);
issDetectorTestHelper.handleStateAndRound(new StateAndRound(
mockState(currentRound, randomHash()),
createRoundWithSignatureEvents(currentRound, signaturesToSubmit),
moreSystemTransactions));
mockState(currentRound, randomHash()), roundWithMajority, systemTransactionsForRoundWithMajority));
assertEquals(
0,
issDetectorTestHelper.getIssNotificationList().size(),
Expand All @@ -477,12 +461,12 @@ void decideForCatastrophicIss() {
currentRound++;

// submit the remaining signatures in the next round
final var remainingSystemTransactions = getScopedSystemTransactions(currentRound, randomHash(random));
final var remainingRound = createRoundWithSignatureEvents(currentRound, signaturesOnCatastrophicRound);
final var remainingSystemTransactions =
SystemTransactionExtractionUtils.extractFromRound(remainingRound, StateSignatureTransaction.class);

issDetectorTestHelper.handleStateAndRound(new StateAndRound(
mockState(currentRound, randomHash()),
createRoundWithSignatureEvents(currentRound, signaturesOnCatastrophicRound),
remainingSystemTransactions));
issDetectorTestHelper.handleStateAndRound(
new StateAndRound(mockState(currentRound, randomHash()), remainingRound, remainingSystemTransactions));

assertEquals(
1, issDetectorTestHelper.getCatastrophicIssCount(), "the catastrophic round should have caused an ISS");
Expand Down Expand Up @@ -577,24 +561,23 @@ void catastrophicShiftBeforeCompleteTest() {
}

// handle the catastrophic round, but it won't be decided yet, since there aren't enough signatures
final var catastrophicRound = createRoundWithSignatureEvents(currentRound, signaturesToSubmit);
final var systemTransactionsForCatastrophicRound =
getScopedSystemTransactions(currentRound, randomHash(random));
SystemTransactionExtractionUtils.extractFromRound(catastrophicRound, StateSignatureTransaction.class);

issDetectorTestHelper.handleStateAndRound(new StateAndRound(
mockState(currentRound, selfHashForCatastrophicRound),
createRoundWithSignatureEvents(currentRound, signaturesToSubmit),
catastrophicRound,
systemTransactionsForCatastrophicRound));

// shift through until the catastrophic round is almost ready to be cleaned up
for (currentRound++; currentRound < roundsNonAncient; currentRound++) {
final var systemTransactions = currentRound % 2 == 1
? getScopedSystemTransactions(currentRound, randomHash(random))
: new ArrayList<ScopedSystemTransaction<StateSignatureTransaction>>();
final var round = createRoundWithSignatureEvents(currentRound, List.of());
final var systemTransactions =
SystemTransactionExtractionUtils.extractFromRound(round, StateSignatureTransaction.class);

issDetectorTestHelper.handleStateAndRound(new StateAndRound(
mockState(currentRound, randomHash()),
createRoundWithSignatureEvents(currentRound, List.of()),
systemTransactions));
issDetectorTestHelper.handleStateAndRound(
new StateAndRound(mockState(currentRound, randomHash()), round, systemTransactions));
}

assertEquals(
Expand All @@ -604,12 +587,12 @@ void catastrophicShiftBeforeCompleteTest() {

// Shift the window. Even though we have not added enough data for a decision, we will have added enough to lead
// to a catastrophic ISS when the timeout is triggered.
final var systemTransactions = getScopedSystemTransactions(currentRound, randomHash(random));
final var remainingRound = createRoundWithSignatureEvents(currentRound, List.of());
final var systemTransactionsForRemainingRound =
SystemTransactionExtractionUtils.extractFromRound(remainingRound, StateSignatureTransaction.class);

issDetectorTestHelper.handleStateAndRound(new StateAndRound(
mockState(currentRound, randomHash()),
createRoundWithSignatureEvents(currentRound, List.of()),
systemTransactions));
mockState(currentRound, randomHash()), remainingRound, systemTransactionsForRemainingRound));

assertEquals(1, issDetectorTestHelper.getIssNotificationList().size(), "shifting should have caused an ISS");
assertEquals(
Expand Down Expand Up @@ -664,12 +647,14 @@ void bigShiftTest() {
random, currentRound, new RoundHashValidatorTests.HashGenerationData(catastrophicData, null));

// handle the catastrophic round, but don't submit any signatures yet, so it won't be detected
final var systemTransactions = getScopedSystemTransactions(currentRound, randomHash(random));
final var catastrophicRound = createRoundWithSignatureEvents(currentRound, List.of());
final var systemTransactionsForCatastrophicRound =
SystemTransactionExtractionUtils.extractFromRound(catastrophicRound, StateSignatureTransaction.class);

issDetectorTestHelper.handleStateAndRound(new StateAndRound(
mockState(currentRound, selfHashForCatastrophicRound),
createRoundWithSignatureEvents(currentRound, List.of()),
systemTransactions));
catastrophicRound,
systemTransactionsForCatastrophicRound));

long submittedWeight = 0;
final List<EventImpl> signaturesToSubmit = new ArrayList<>();
Expand All @@ -688,12 +673,14 @@ void bigShiftTest() {

currentRound++;
// submit the supermajority of signatures
final var roundWithSupermajority = createRoundWithSignatureEvents(currentRound, signaturesToSubmit);
final var systemTransactionsForRoundWithSupermajorityOfSignatures =
getScopedSystemTransactions(currentRound, randomHash(random));
SystemTransactionExtractionUtils.extractFromRound(
roundWithSupermajority, StateSignatureTransaction.class);

issDetectorTestHelper.handleStateAndRound(new StateAndRound(
mockState(currentRound, randomHash()),
createRoundWithSignatureEvents(currentRound, signaturesToSubmit),
roundWithSupermajority,
systemTransactionsForRoundWithSupermajorityOfSignatures));

// Shifting the window a great distance should not trigger the ISS.
Expand Down Expand Up @@ -743,21 +730,21 @@ void ignoredRoundTest() {

// handle the round and all signatures.
// The round has a catastrophic ISS, but should be ignored
final var systemTransactionsForISSRound = getScopedSystemTransactions(currentRound, randomHash(random));
final var catastrophicRound = createRoundWithSignatureEvents(currentRound, signaturesOnCatastrophicRound);
final var systemTransactionsForCatastrophicRound =
SystemTransactionExtractionUtils.extractFromRound(catastrophicRound, StateSignatureTransaction.class);

issDetectorTestHelper.handleStateAndRound(new StateAndRound(
mockState(currentRound, randomHash()),
createRoundWithSignatureEvents(currentRound, signaturesOnCatastrophicRound),
systemTransactionsForISSRound));
mockState(currentRound, randomHash()), catastrophicRound, systemTransactionsForCatastrophicRound));

// shift through some rounds, to make sure nothing unexpected happens
final var systemTransactions = getScopedSystemTransactions(currentRound, randomHash(random));

for (currentRound++; currentRound <= roundsNonAncient; currentRound++) {
final var anotherRound = createRoundWithSignatureEvents(currentRound, List.of());
final var systemTransactionsForAnotherRound =
SystemTransactionExtractionUtils.extractFromRound(anotherRound, StateSignatureTransaction.class);

issDetectorTestHelper.handleStateAndRound(new StateAndRound(
mockState(currentRound, randomHash()),
createRoundWithSignatureEvents(currentRound, List.of()),
systemTransactions));
mockState(currentRound, randomHash()), anotherRound, systemTransactionsForAnotherRound));
}

assertEquals(0, issDetectorTestHelper.getIssNotificationList().size(), "ISS should have been ignored");
Expand Down

0 comments on commit 1f6a473

Please sign in to comment.