Skip to content

Commit 4f55037

Browse files
committed
Update delete graffiti in manager to delete file
1 parent 6134bdb commit 4f55037

File tree

2 files changed

+45
-32
lines changed

2 files changed

+45
-32
lines changed

validator/api/src/main/java/tech/pegasys/teku/validator/api/GraffitiManager.java

+24-22
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import java.io.IOException;
1717
import java.nio.charset.StandardCharsets;
1818
import java.nio.file.Files;
19+
import java.nio.file.NoSuchFileException;
1920
import java.nio.file.Path;
2021
import java.util.Optional;
2122
import org.apache.logging.log4j.LogManager;
@@ -34,14 +35,6 @@ public GraffitiManager(final DataDirLayout dataDirLayout) {
3435
this.graffitiPath = createManagementDirectory(dataDirLayout);
3536
}
3637

37-
public Optional<String> setGraffiti(final BLSPublicKey publicKey, final String graffiti) {
38-
return updateGraffiti(publicKey, graffiti.strip());
39-
}
40-
41-
public Optional<String> deleteGraffiti(final BLSPublicKey publicKey) {
42-
return updateGraffiti(publicKey);
43-
}
44-
4538
private Path createManagementDirectory(final DataDirLayout dataDirLayout) {
4639
final Path graffitiDirectory = dataDirLayout.getValidatorDataDirectory().resolve(GRAFFITI_DIR);
4740
if (!graffitiDirectory.toFile().exists() && !graffitiDirectory.toFile().mkdirs()) {
@@ -51,22 +44,19 @@ private Path createManagementDirectory(final DataDirLayout dataDirLayout) {
5144
return graffitiDirectory;
5245
}
5346

54-
private Optional<String> updateGraffiti(final BLSPublicKey publicKey) {
55-
return updateGraffiti(publicKey, "");
56-
}
57-
58-
private Optional<String> updateGraffiti(final BLSPublicKey publicKey, final String graffiti) {
59-
final int graffitiSize = graffiti.getBytes(StandardCharsets.UTF_8).length;
47+
public Optional<String> setGraffiti(final BLSPublicKey publicKey, final String graffiti) {
48+
final String strippedGraffiti = graffiti.strip();
49+
final int graffitiSize = strippedGraffiti.getBytes(StandardCharsets.UTF_8).length;
6050
if (graffitiSize > 32) {
6151
throw new IllegalArgumentException(
6252
String.format(
6353
"'%s' converts to %s bytes. Input must be 32 bytes or less.",
64-
graffiti, graffitiSize));
54+
strippedGraffiti, graffitiSize));
6555
}
6656

6757
try {
6858
final Path file = graffitiPath.resolve(resolveFileName(publicKey));
69-
Files.writeString(file, graffiti);
59+
Files.writeString(file, strippedGraffiti);
7060
} catch (IOException e) {
7161
final String errorMessage =
7262
String.format("Unable to update graffiti for validator %s", publicKey);
@@ -76,25 +66,37 @@ private Optional<String> updateGraffiti(final BLSPublicKey publicKey, final Stri
7666
return Optional.empty();
7767
}
7868

69+
public Optional<String> deleteGraffiti(final BLSPublicKey publicKey) {
70+
final Path file = graffitiPath.resolve(resolveFileName(publicKey));
71+
72+
try {
73+
Files.delete(file);
74+
return Optional.empty();
75+
} catch (NoSuchFileException e) {
76+
throw new IllegalArgumentException(
77+
"Saved graffiti does not exist for validator " + publicKey);
78+
} catch (IOException e) {
79+
final String errorMessage =
80+
String.format("Unable to delete graffiti for validator %s", publicKey);
81+
LOG.error(errorMessage, e);
82+
return Optional.of(errorMessage);
83+
}
84+
}
85+
7986
public Optional<Bytes32> getGraffiti(final BLSPublicKey publicKey) {
8087
final Path filePath = graffitiPath.resolve(resolveFileName(publicKey));
8188
if (!filePath.toFile().exists()) {
8289
return Optional.empty();
8390
}
8491

8592
try {
86-
return Optional.of(GraffitiParser.loadFromFile(filePath)).filter(this::graffitiNotEmpty);
93+
return Optional.of(GraffitiParser.loadFromFile(filePath));
8794
} catch (GraffitiLoaderException | IllegalArgumentException e) {
8895
LOG.error("Unable to read graffiti from storage.", e);
8996
return Optional.empty();
9097
}
9198
}
9299

93-
private boolean graffitiNotEmpty(final Bytes32 graffiti) {
94-
final Bytes32 emptyBytesParsed = Bytes32Parser.toBytes32(new byte[0]);
95-
return !graffiti.equals(emptyBytesParsed);
96-
}
97-
98100
private String resolveFileName(final BLSPublicKey publicKey) {
99101
return publicKey.toSSZBytes().toUnprefixedHexString() + ".txt";
100102
}

validator/api/src/test/java/tech/pegasys/teku/validator/api/GraffitiManagerTest.java

+21-10
Original file line numberDiff line numberDiff line change
@@ -104,38 +104,43 @@ void setGraffiti_shouldThrowExceptionWhenGraffitiTooBig(@TempDir final Path temp
104104
}
105105

106106
@Test
107-
void deleteGraffiti_shouldSetGraffitiWhenFileNotExist(@TempDir final Path tempDir) {
107+
void deleteGraffiti_shouldThrowIllegalArgumentWhenNoGraffitiToDelete(
108+
@TempDir final Path tempDir) {
108109
dataDirLayout = new SimpleDataDirLayout(tempDir);
109110
manager = new GraffitiManager(dataDirLayout);
110111
assertThat(getGraffitiManagementDir().toFile().exists()).isTrue();
111-
assertThat(manager.deleteGraffiti(publicKey)).isEmpty();
112-
checkStoredGraffitiFile(publicKey, "");
112+
assertThatThrownBy(() -> manager.deleteGraffiti(publicKey))
113+
.isInstanceOf(IllegalArgumentException.class)
114+
.hasMessage("Saved graffiti does not exist for validator " + publicKey);
115+
checkNoGraffitiFile(publicKey);
113116
}
114117

115118
@Test
116-
void deleteGraffiti_shouldSetGraffitiWhenFileExist(@TempDir final Path tempDir)
119+
void deleteGraffiti_shouldDeleteGraffitiWhenFileExist(@TempDir final Path tempDir)
117120
throws IOException {
118121
dataDirLayout = new SimpleDataDirLayout(tempDir);
119122
manager = new GraffitiManager(dataDirLayout);
120123
assertThat(getGraffitiManagementDir().resolve(getFileName(publicKey)).toFile().createNewFile())
121124
.isTrue();
122125

123126
assertThat(manager.deleteGraffiti(publicKey)).isEmpty();
124-
checkStoredGraffitiFile(publicKey, "");
127+
checkNoGraffitiFile(publicKey);
125128
}
126129

127130
@Test
131+
@DisabledOnOs(OS.WINDOWS) // Can't set permissions on Windows
128132
void deleteGraffiti_shouldReturnErrorMessageWhenUnableToWriteFile(@TempDir final Path tempDir)
129133
throws IOException {
130134
dataDirLayout = new SimpleDataDirLayout(tempDir);
131135
manager = new GraffitiManager(dataDirLayout);
132136

133137
final File file = getGraffitiManagementDir().resolve(getFileName(publicKey)).toFile();
134138
assertThat(file.createNewFile()).isTrue();
135-
assertThat(file.setWritable(false)).isTrue();
139+
assertThat(file.getParentFile().setWritable(false)).isTrue();
136140

137141
assertThat(manager.deleteGraffiti(publicKey))
138-
.hasValue("Unable to update graffiti for validator " + publicKey);
142+
.hasValue("Unable to delete graffiti for validator " + publicKey);
143+
assertThat(file.exists()).isTrue();
139144
}
140145

141146
@Test
@@ -149,7 +154,7 @@ void shouldSetAndDeleteGraffitiWhenManagementPreexisting(@TempDir final Path tem
149154
checkStoredGraffitiFile(publicKey, graffiti);
150155

151156
assertThat(manager.deleteGraffiti(publicKey)).isEmpty();
152-
checkStoredGraffitiFile(publicKey, "");
157+
checkNoGraffitiFile(publicKey);
153158
}
154159

155160
private void checkStoredGraffitiFile(final BLSPublicKey publicKey, final String graffiti) {
@@ -162,6 +167,11 @@ private void checkStoredGraffitiFile(final BLSPublicKey publicKey, final String
162167
}
163168
}
164169

170+
private void checkNoGraffitiFile(final BLSPublicKey publicKey) {
171+
final Path filePath = getGraffitiManagementDir().resolve(getFileName(publicKey));
172+
assertThat(filePath.toFile().exists()).isFalse();
173+
}
174+
165175
@Test
166176
void getGraffiti_shouldGetGraffitiFromStorage(@TempDir final Path tempDir) throws IOException {
167177
dataDirLayout = new SimpleDataDirLayout(tempDir);
@@ -207,13 +217,14 @@ void getGraffiti_shouldReturnEmptyWhenNotReadableFile(@TempDir final Path tempDi
207217
}
208218

209219
@Test
210-
void getGraffiti_shouldReturnEmptyWhenFileEmpty(@TempDir final Path tempDir) throws IOException {
220+
void getGraffiti_shouldReturnEmptyBytesWhenFileEmpty(@TempDir final Path tempDir)
221+
throws IOException {
211222
dataDirLayout = new SimpleDataDirLayout(tempDir);
212223
manager = new GraffitiManager(dataDirLayout);
213224
final Path filePath = getGraffitiManagementDir().resolve(getFileName(publicKey));
214225
assertThat(filePath.toFile().createNewFile()).isTrue();
215226

216-
assertThat(manager.getGraffiti(publicKey)).isEmpty();
227+
assertThat(manager.getGraffiti(publicKey)).hasValue(Bytes32Parser.toBytes32(new byte[0]));
217228
}
218229

219230
private Path getGraffitiManagementDir() {

0 commit comments

Comments
 (0)