Skip to content

Commit

Permalink
fix: address book jrs test failing (#10928)
Browse files Browse the repository at this point in the history
Signed-off-by: Edward Wertz <[email protected]>
  • Loading branch information
edward-swirldslabs authored Jan 12, 2024
1 parent f179127 commit 30ab9fb
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ public class AddressBookInitializer {
private final int maxNumFiles;
/** Indicate that the unmodified config address book must be used. */
private final boolean useConfigAddressBook;
/** Indicates that the address book has changed */
private boolean addressBookChanged = false;
/** Indicates that one of the address books has changed */
private boolean addressBookChange = false;

/**
* Constructs an AddressBookInitializer to initialize an address book from config.txt, the saved state from disk, or
Expand Down Expand Up @@ -127,7 +127,12 @@ public AddressBookInitializer(
final AddressBookConfig addressBookConfig =
platformContext.getConfiguration().getConfigData(AddressBookConfig.class);
this.initialState = Objects.requireNonNull(initialState, "The initialState must not be null.");
this.stateAddressBook = initialState.isGenesisState() ? null : initialState.getAddressBook();

this.stateAddressBook = initialState.getState().getPlatformState().getAddressBook();
if (stateAddressBook == null && !initialState.isGenesisState()) {
throw new IllegalStateException("Only genesis states can have null address books.");
}

this.pathToAddressBookDirectory = Path.of(addressBookConfig.addressBookDirectory());
try {
Files.createDirectories(pathToAddressBookDirectory);
Expand Down Expand Up @@ -172,7 +177,7 @@ public AddressBook getPreviousAddressBook() {
* @return true if the address book has changed on initialization
*/
public boolean hasAddressBookChanged() {
return addressBookChanged;
return addressBookChange;
}

/**
Expand All @@ -195,13 +200,11 @@ private InitializedAddressBooks initialize() {
"Overriding the address book in the state with the address book from config.txt");
candidateAddressBook = configAddressBook;
previousAddressBook = stateAddressBook;
addressBookChanged = !Objects.equals(configAddressBook, stateAddressBook);
} else if (initialState.isGenesisState()) {
// If this is a genesis state, the state's address book and previous address book will be null.
// Adopt the config.txt address book.
logger.info(STARTUP.getMarker(), "Starting from genesis: using the config address book.");
candidateAddressBook = configAddressBook;
addressBookChanged = true;
checkCandidateAddressBookValidity(candidateAddressBook);
previousAddressBook = null;
} else if (!softwareUpgrade) {
Expand All @@ -210,7 +213,6 @@ private InitializedAddressBooks initialize() {
candidateAddressBook = stateAddressBook;
// since state address book was checked for validity prior to adoption, no check needed here.
previousAddressBook = null;
addressBookChanged = false;
} else {
// Loaded State from Disk, Non-Genesis, There is a software version upgrade
logger.info(
Expand All @@ -222,12 +224,21 @@ private InitializedAddressBooks initialize() {
.copy();
candidateAddressBook = checkCandidateAddressBookValidity(candidateAddressBook);
previousAddressBook = stateAddressBook;
addressBookChanged = !Objects.equals(configAddressBook, stateAddressBook);
}
// This flag indicates the state needs to be updated with the changes to the address books.
addressBookChange = hasAddressBookChanged(initialState, candidateAddressBook, previousAddressBook);
recordAddressBooks(candidateAddressBook);
return new InitializedAddressBooks(candidateAddressBook, previousAddressBook);
}

private boolean hasAddressBookChanged(
@NonNull final SignedState state,
@Nullable final AddressBook currentAddressBook,
@Nullable final AddressBook previousAddressBook) {
return !Objects.equals(state.getState().getPlatformState().getAddressBook(), currentAddressBook)
|| !Objects.equals(state.getState().getPlatformState().getPreviousAddressBook(), previousAddressBook);
}

/**
* Checks if the candidateAddressBook is valid and returns it, otherwise returns the configAddressBook if it has
* non-zero weight. If the candidateAddressBook's addresses are out of sync with the configAddressBook or both
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import static com.swirlds.platform.state.address.AddressBookInitializer.STATE_ADDRESS_BOOK_USED;
import static com.swirlds.platform.state.address.AddressBookInitializer.USED_ADDRESS_BOOK_HEADER;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
Expand All @@ -46,6 +47,7 @@
import com.swirlds.test.framework.config.TestConfigBuilder;
import com.swirlds.test.framework.context.TestPlatformContextBuilder;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
Expand Down Expand Up @@ -89,14 +91,16 @@ void forceUseOfConfigAddressBook() throws IOException {
"The previous address book must equal the state address book.");
assertAddressBookFileContent(
initializer, configAddressBook, signedState.getAddressBook(), inititializedAddressBook);
assertTrue(initializer.hasAddressBookChanged());
}

@Test
@DisplayName("Genesis. Config.txt Initializes Address Book.")
void noStateLoadedFromDisk() throws IOException {
clearTestDirectory();
final AddressBook configAddressBook = getRandomAddressBook();
final SignedState signedState = getMockSignedState(10, configAddressBook, true);
// initial state has no address books set.
final SignedState signedState = getMockSignedState(10, null, null, true);
final AddressBookInitializer initializer = new AddressBookInitializer(
new NodeId(0),
getMockSoftwareVersion(2),
Expand All @@ -113,14 +117,16 @@ void noStateLoadedFromDisk() throws IOException {
assertNull(initializer.getPreviousAddressBook(), "The previous address book should be null.");
assertAddressBookFileContent(
initializer, configAddressBook, signedState.getAddressBook(), inititializedAddressBook);
assertTrue(initializer.hasAddressBookChanged());
}

@Test
@DisplayName("No state loaded from disk. Genesis State set 0 weight.")
void noStateLoadedFromDiskGenesisStateSetZeroWeight() throws IOException {
clearTestDirectory();
final AddressBook configAddressBook = getRandomAddressBook();
final SignedState signedState = getMockSignedState(10, configAddressBook, true);
// initial state has currentAddressBook set to configAddressBook
final SignedState signedState = getMockSignedState(10, configAddressBook, null, true);
final AddressBookInitializer initializer = new AddressBookInitializer(
new NodeId(0),
getMockSoftwareVersion(2),
Expand All @@ -137,14 +143,16 @@ void noStateLoadedFromDiskGenesisStateSetZeroWeight() throws IOException {
assertNull(initializer.getPreviousAddressBook(), "The previous address book should be null.");
assertAddressBookFileContent(
initializer, configAddressBook, signedState.getAddressBook(), inititializedAddressBook);
assertFalse(initializer.hasAddressBookChanged());
}

@Test
@DisplayName("No state loaded from disk. Genesis State modifies address book entries.")
void noStateLoadedFromDiskGenesisStateChangedAddressBook() throws IOException {
clearTestDirectory();
final AddressBook configAddressBook = getRandomAddressBook();
final SignedState signedState = getMockSignedState(7, configAddressBook, true);
// initial state has currentAddressBook set to configAddressBook
final SignedState signedState = getMockSignedState(7, configAddressBook, null, true);
final AddressBookInitializer initializer = new AddressBookInitializer(
new NodeId(0),
getMockSoftwareVersion(2),
Expand All @@ -161,13 +169,15 @@ void noStateLoadedFromDiskGenesisStateChangedAddressBook() throws IOException {
assertNull(initializer.getPreviousAddressBook(), "The previous address book should be null.");
assertAddressBookFileContent(
initializer, configAddressBook, signedState.getAddressBook(), inititializedAddressBook);
assertFalse(initializer.hasAddressBookChanged());
}

@Test
@DisplayName("Current software version is equal to state software version.")
void currentVersionEqualsStateVersion() throws IOException {
clearTestDirectory();
final SignedState signedState = getMockSignedState(2, getRandomAddressBook(), false);
// start state with previous address book
final SignedState signedState = getMockSignedState(2, getRandomAddressBook(), getRandomAddressBook(), false);
final AddressBook configAddressBook = copyWithWeightChanges(signedState.getAddressBook(), 10);
final AddressBookInitializer initializer = new AddressBookInitializer(
new NodeId(0),
Expand All @@ -188,13 +198,15 @@ void currentVersionEqualsStateVersion() throws IOException {
"When there is no upgrade, the address book should not change");
assertAddressBookFileContent(
initializer, configAddressBook, signedState.getAddressBook(), inititializedAddressBook);
// Initializer nullifies the previous address book when there is no software upgrade.
assertTrue(initializer.hasAddressBookChanged());
}

@Test
@DisplayName("Version upgrade, SwirldState set 0 weight.")
void versionUpgradeSwirldStateZeroWeight() throws IOException {
clearTestDirectory();
final SignedState signedState = getMockSignedState(0, getRandomAddressBook(), false);
final SignedState signedState = getMockSignedState(0, getRandomAddressBook(), getRandomAddressBook(), false);
final AddressBook configAddressBook = copyWithWeightChanges(signedState.getAddressBook(), 10);
final AddressBookInitializer initializer = new AddressBookInitializer(
new NodeId(0),
Expand All @@ -215,13 +227,14 @@ void versionUpgradeSwirldStateZeroWeight() throws IOException {
"The previous address book must equal the state address book.");
assertAddressBookFileContent(
initializer, configAddressBook, signedState.getAddressBook(), inititializedAddressBook);
assertTrue(initializer.hasAddressBookChanged());
}

@Test
@DisplayName("Version upgrade, Swirld State modified the address book.")
void versionUpgradeSwirldStateModifiedAddressBook() throws IOException {
clearTestDirectory();
final SignedState signedState = getMockSignedState(2, getRandomAddressBook(), false);
final SignedState signedState = getMockSignedState(2, getRandomAddressBook(), getRandomAddressBook(), false);
final AddressBook configAddressBook = copyWithWeightChanges(signedState.getAddressBook(), 3);
final AddressBookInitializer initializer = new AddressBookInitializer(
new NodeId(0),
Expand All @@ -242,6 +255,7 @@ void versionUpgradeSwirldStateModifiedAddressBook() throws IOException {
"The previous address book must equal the state address book.");
assertAddressBookFileContent(
initializer, configAddressBook, signedState.getAddressBook(), inititializedAddressBook);
assertTrue(initializer.hasAddressBookChanged());
}

@Test
Expand Down Expand Up @@ -273,6 +287,7 @@ void versionUpgradeSwirldStateWeightUpdateWorks() throws IOException {
"The previous address book must equal the state address book.");
assertAddressBookFileContent(
initializer, configAddressBook, signedState.getAddressBook(), inititializedAddressBook);
assertTrue(initializer.hasAddressBookChanged());
}

/**
Expand Down Expand Up @@ -321,35 +336,39 @@ private SoftwareVersion getMockSoftwareVersion(int version) {
* @return The mock SignedState.
*/
private SignedState getMockSignedState7WeightRandomAddressBook() {
return getMockSignedState(7, getRandomAddressBook(), false);
return getMockSignedState(7, getRandomAddressBook(), getRandomAddressBook(), false);
}

/**
* Creates a mock signed state and a SwirldState that sets all addresses to the given weightValue.
*
* @param weightValue The weight value that the SwirldState should set all addresses to in its updateWeight
* method.
* @param stateAddressBook The address book that the SignedState should return in its getAddressBook method.
* @param fromGenesis Whether the state should be from genesis or not.
* @param weightValue The weight value that the SwirldState should set all addresses to in its updateWeight
* method.
* @param currentAddressBook The address book that should be returned by {@link SignedState#getAddressBook()} and
* {@link PlatformState#getAddressBook()}
* @param previousAddressBook The address book that should be returned by
* {@link PlatformState#getPreviousAddressBook()}
* @param fromGenesis Whether the state should be from genesis or not.
* @return The mock SignedState and SwirldState configured to set all addresses with given weightValue.
*/
private SignedState getMockSignedState(
final int weightValue, @NonNull final AddressBook stateAddressBook, boolean fromGenesis) {
final int weightValue,
@Nullable final AddressBook currentAddressBook,
@Nullable final AddressBook previousAddressBook,
boolean fromGenesis) {
final SignedState signedState = mock(SignedState.class);
final SoftwareVersion softwareVersion = getMockSoftwareVersion(2);
final SwirldState swirldState = getMockSwirldStateSupplier(weightValue).get();
if (fromGenesis) {
when(signedState.getAddressBook()).thenReturn(null);
} else {
when(signedState.getAddressBook()).thenReturn(stateAddressBook);
}
when(signedState.getSwirldState()).thenReturn(swirldState);
final PlatformState platformState = mock(PlatformState.class);
when(platformState.getCreationSoftwareVersion()).thenReturn(softwareVersion);
when(platformState.getAddressBook()).thenReturn(currentAddressBook);
when(platformState.getPreviousAddressBook()).thenReturn(previousAddressBook);
final State state = mock(State.class);
when(state.getPlatformState()).thenReturn(platformState);
when(signedState.getState()).thenReturn(state);
when(signedState.isGenesisState()).thenReturn(fromGenesis);
when(signedState.getAddressBook()).thenReturn(currentAddressBook);
return signedState;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ private static GossipEvent createGossipEvent(
.thenReturn(new EventDescriptor(eventHash, eventCreator, eventGeneration, eventBirthRound));
when(event.getGeneration()).thenReturn(eventGeneration);
when(event.getSenderId()).thenReturn(eventCreator);
when(event.getAncientIndicator(any()))
.thenAnswer(args -> args.getArguments()[0] == AncientMode.BIRTH_ROUND_THRESHOLD
? eventBirthRound
: eventGeneration);

return event;
}
Expand Down

0 comments on commit 30ab9fb

Please sign in to comment.