Files
archy/tests/apps/qortal/InitializedGenesis.java

70 lines
4.0 KiB
Java

import java.nio.file.Files;
import java.nio.file.Path;
import java.security.Provider;
import java.security.Security;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
/** Synthetic initialized-cache fixture, NEVER an installer/repair/migration. */
public final class InitializedGenesis {
private static final String URL = "jdbc:hsqldb:file:/qortal/db/blockchain;ifexists=true;hsqldb.full_log_replay=true";
private static void require(boolean condition) {
if (!condition) throw new IllegalStateException("Not the expected disposable empty-genesis fixture");
}
private static int scalar(Statement statement, String sql) throws Exception {
try (ResultSet rows = statement.executeQuery(sql)) {
require(rows.next());
return rows.getInt(1);
}
}
private static int inspect() throws Exception {
try (Connection db = DriverManager.getConnection(URL, "SA", ""); Statement s = db.createStatement()) {
int height = scalar(s, "SELECT MAX(height) FROM Blocks");
System.out.println("Synthetic repository height: " + height);
require(height == 0 || height == 1);
require(scalar(s, "SELECT COUNT(*) FROM ArbitraryTransactions") == 0);
require(scalar(s, "SELECT COUNT(*) FROM ArbitraryResourcesCache") == 0);
require(scalar(s, "SELECT version FROM DatabaseInfo") == 53);
s.execute("SHUTDOWN");
return height;
}
}
public static void main(String[] args) throws Exception {
require("1".equals(System.getenv("ARCHY_QORTAL_SYNTHETIC_FIXTURE")));
require(Files.readString(Path.of("/qortal/operator-sentinel")).equals("preserve operator data\n"));
Class.forName("org.hsqldb.jdbc.JDBCDriver");
if (inspect() == 0) {
// Failed startup may lose the uncheckpointed genesis block. Use the
// ACTUAL pinned Core's genesis processor, not invented chain rows.
// Reflection keeps host compilation standard-library-only; all Core
// code runs exclusively inside the network-none disposable fixture.
Security.addProvider((Provider) Class.forName("org.bouncycastle.jce.provider.BouncyCastleProvider").getConstructor().newInstance());
Class.forName("org.qortal.settings.Settings").getMethod("fileInstance", String.class).invoke(null, "/qortal/settings.json");
Class<?> manager = Class.forName("org.qortal.repository.RepositoryManager");
Class<?> factoryType = Class.forName("org.qortal.repository.RepositoryFactory");
Class<?> repositoryType = Class.forName("org.qortal.repository.Repository");
Object factory = Class.forName("org.qortal.repository.hsqldb.HSQLDBRepositoryFactory").getConstructor(String.class).newInstance(URL);
manager.getMethod("setRepositoryFactory", factoryType).invoke(null, factory);
Object repository = manager.getMethod("getRepository").invoke(null);
try {
Object genesis = Class.forName("org.qortal.block.GenesisBlock").getMethod("getInstance", repositoryType).invoke(null, repository);
genesis.getClass().getMethod("process").invoke(genesis);
repositoryType.getMethod("saveChanges").invoke(repository);
} finally {
repositoryType.getMethod("close").invoke(repository);
manager.getMethod("closeRepositoryFactory").invoke(null);
}
}
require(inspect() == 1);
try (Connection db = DriverManager.getConnection(URL, "SA", ""); Statement s = db.createStatement()) {
// Model an already initialized EMPTY cache. No QDN transaction,
// signature, wallet key or application record is invented.
require(s.executeUpdate("UPDATE DatabaseInfo SET latest_signature_populated = 1") == 1);
s.execute("SHUTDOWN");
}
System.out.println("FIXTURE ONLY: initialized empty cache; does NOT qualify fresh genesis/bootstrap");
}
}