Skip to content

Commit

Permalink
feat(genesis): allows external genesis file
Browse files Browse the repository at this point in the history
test(genesis): adds file loader tests

squashme: better catch handling
  • Loading branch information
jurajpiar authored and Vovchyk committed Apr 23, 2024
1 parent 6fab6d4 commit 1c396b9
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.ethereum.core.genesis;

public class GenesisLoaderException extends RuntimeException {
GenesisLoaderException(String message, Throwable error) {
super(message, error);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

Expand All @@ -54,6 +56,7 @@
* 4. Registers the genesis state root in the state root handler
*/
public class GenesisLoaderImpl implements GenesisLoader {

private static final byte[] EMPTY_LIST_HASH = HashUtil.keccak256(RLP.encodeList());

private static final Logger logger = LoggerFactory.getLogger(GenesisLoaderImpl.class);
Expand Down Expand Up @@ -81,7 +84,7 @@ public GenesisLoaderImpl(
activationConfig,
stateRootHandler,
trieStore,
GenesisLoaderImpl.class.getResourceAsStream("/genesis/" + genesisFile),
loadGenesisFile(genesisFile),
initialNonce,
isRsk,
useRskip92Encoding,
Expand Down Expand Up @@ -230,6 +233,21 @@ private void setupPrecompiledContractsStorage(Repository repository) {
}
}

static InputStream loadGenesisFile(String fileName) {
InputStream inputStream = GenesisLoaderImpl.class.getResourceAsStream("/genesis/" + fileName);
if (inputStream != null) {
return inputStream;
}

try {
return Files.newInputStream(Paths.get(fileName));
} catch (Exception e) {
logger.error("Cannot read genesis json file");

throw new GenesisLoaderException("Cannot open genesis block configuration file", e);
}
}

public static void loadGenesisInitalState(Repository repository, Genesis genesis) {
// first we need to create the accounts, which creates also the associated ContractDetails
for (RskAddress accounts : genesis.getAccounts().keySet()) {
Expand Down Expand Up @@ -259,7 +277,7 @@ private static GenesisJson readGenesisJson(InputStream inputStream) {
} catch (Exception e) {
logger.error("Cannot read genesis json file");

throw new RuntimeException("Genesis block configuration is corrupted or not found ./resources/genesis/...", e);
throw new GenesisLoaderException("Genesis block configuration is corrupted or not found", e);
} finally {
closeStream(inputStream);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package org.ethereum.core.genesis;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.util.Objects;

class GenesisLoaderImplTest {
private final String GENESIS_FILE_NAME = "temp_genesis.json";

private final String RESOURCES_GENESIS_FILE_PATH = Objects.requireNonNull(GenesisLoaderImpl.class.getResource("/genesis")).getPath() + "/" + GENESIS_FILE_NAME;

@SuppressWarnings("ResultOfMethodCallIgnored")
private boolean isStreamReadable(InputStream stream) {
try {
stream.read();
return true;
} catch (IOException e) {
return false;
}
}

@BeforeEach
public void createTempFiles() throws IOException {
boolean created = (new File(RESOURCES_GENESIS_FILE_PATH)).createNewFile();
Assertions.assertTrue(created);
}

@AfterEach
public void cleanUpFiles() {
boolean deleted = (new File(RESOURCES_GENESIS_FILE_PATH)).delete();
Assertions.assertTrue(deleted);
}

@Test
void loadGenesisFile_fromResourcesDir() {
InputStream genesisFileStream = GenesisLoaderImpl.loadGenesisFile(GENESIS_FILE_NAME);

Assertions.assertTrue(isStreamReadable(genesisFileStream));
}

@Test
void loadGenesisFile_missingFile_inResourcesDir() {
String genesisFilePath = new File("non-existent-file.json").getPath();

Exception e = Assertions.assertThrows(GenesisLoaderException.class, () -> GenesisLoaderImpl.loadGenesisFile(genesisFilePath));
Assertions.assertEquals("Cannot open genesis block configuration file", e.getMessage());
}

@Test
void loadGenesisFile_fromSystem(@TempDir Path tempGenesisDir) throws IOException {
File genesisFile = new File(tempGenesisDir + "/" + GENESIS_FILE_NAME);
Assertions.assertTrue(genesisFile.createNewFile());
InputStream genesisFileStream = GenesisLoaderImpl.loadGenesisFile(genesisFile.getPath());

Assertions.assertTrue(isStreamReadable(genesisFileStream));
}

@Test
void loadGenesisFile_missingFile_inSystem(@TempDir Path tempGenesisDir) {
String genesisFilePath = new File(tempGenesisDir + "/non-existent-file.json").getPath();

Exception e = Assertions.assertThrows(GenesisLoaderException.class, () -> GenesisLoaderImpl.loadGenesisFile(genesisFilePath));
Assertions.assertEquals("Cannot open genesis block configuration file", e.getMessage());
}
}

0 comments on commit 1c396b9

Please sign in to comment.