diff --git a/apl-conf/pom.xml b/apl-conf/pom.xml index 000e0c6e06..0bc3fc1586 100644 --- a/apl-conf/pom.xml +++ b/apl-conf/pom.xml @@ -16,6 +16,16 @@ org.slf4j slf4j-api + + org.projectlombok + lombok + provided + + + com.apollocurrency + apl-utils + ${project.version} + org.junit.platform diff --git a/apl-conf/src/main/java/com/apollocurrency/aplwallet/apl/conf/ConfPlaceholder.java b/apl-conf/src/main/java/com/apollocurrency/aplwallet/apl/conf/ConfPlaceholder.java deleted file mode 100644 index 96099bb98a..0000000000 --- a/apl-conf/src/main/java/com/apollocurrency/aplwallet/apl/conf/ConfPlaceholder.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.apollocurrency.aplwallet.apl.conf; - -/** - * - * @author al - */ -public class ConfPlaceholder { - -} diff --git a/apl-conf/src/main/java/com/apollocurrency/aplwallet/apl/conf/ConfigRecord.java b/apl-conf/src/main/java/com/apollocurrency/aplwallet/apl/conf/ConfigRecord.java new file mode 100644 index 0000000000..fe182b199c --- /dev/null +++ b/apl-conf/src/main/java/com/apollocurrency/aplwallet/apl/conf/ConfigRecord.java @@ -0,0 +1,31 @@ +/* + * Copyright © 2018-2021 Apollo Foundation + */ +package com.apollocurrency.aplwallet.apl.conf; + +import com.apollocurrency.aplwallet.apl.util.Version; +import lombok.Builder; +import lombok.Builder.Default; + +/** + * + * @author Oleksiy Lukin alukin@gmail.com + */ +@Builder +public class ConfigRecord { + public String name; + @Default + public String defaultValue=""; + @Default + public String description=""; + @Default + public Version sinceRelease = new Version("1.0.0"); + @Default + public Version deprecatedSince = new Version("999.0.0"); + @Default + public String cmdLineOpt=""; + @Default + public String envVar=""; + @Default + public boolean isRequired = false; +} diff --git a/apl-conf/src/main/java/com/apollocurrency/aplwallet/apl/conf/ConfigVerifier.java b/apl-conf/src/main/java/com/apollocurrency/aplwallet/apl/conf/ConfigVerifier.java new file mode 100644 index 0000000000..b9db476c44 --- /dev/null +++ b/apl-conf/src/main/java/com/apollocurrency/aplwallet/apl/conf/ConfigVerifier.java @@ -0,0 +1,154 @@ +/* + * Copyright © 2018-2021 Apollo Foundation + */ +package com.apollocurrency.aplwallet.apl.conf; + + +import com.apollocurrency.aplwallet.apl.util.Version; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +/** + * Config Properies known by Apollo application + * @author Oleksiy Lukin alukin@gmail.com + */ +@Slf4j +public class ConfigVerifier { + private final static String FIRST_RELEASE = "1.0.0"; + private final static String DEX_RELEASE = "1.36.0"; + private final static String SHARDING_RELEASE = "1.35.0"; + private final static String MARIADB_RELEASE = "1.48.0"; + + private ConfigVerifier() { + } + + /** + * property name mapped to parameters + */ + @Getter + private Map knownProps; + + public boolean isSupported(String propName) { + return knownProps.containsKey(propName); + } + + public ConfigRecord get(String propName){ + ConfigRecord res = knownProps.get(propName); + return res; + } + + private ConfigRecord getOrAdd(String propName){ + ConfigRecord res = knownProps.get(propName); + if (res == null) { + res = ConfigRecord.builder() + .name(propName) + .build(); + knownProps.put(propName, res); + } + return res; + } + + public List listDeprecated(Version currVersion){ + List res = new ArrayList<>(); + knownProps.values().stream().filter(pr -> (pr.deprecatedSince.lessThan(currVersion))).forEachOrdered(pr -> { + res.add(pr); + }); + return res; + } + + public List listNewAfter(Version ver){ + List res = new ArrayList<>(); + knownProps.values().stream().filter(pr -> (pr.sinceRelease.greaterThan(ver))).forEachOrdered(pr -> { + res.add(pr); + }); + return res; + } + + /** + * Dumps all known properties with comment lines + * containing all available information about config property + * @param pos output stream where to dump + */ + public void dumpToProperties(OutputStream pos) throws IOException{ + Writer w = new OutputStreamWriter(pos); + for(ConfigRecord cr: knownProps.values()){ + w.write("# "+cr.description); + w.write("# Command line option: "+cr.cmdLineOpt+" Environment variable: "+cr.envVar); + w.write(cr.name+"="+cr.defaultValue); + } + } + + +/** + * Parse properties file comparing to known properties and filling undefined with defaults + * @param config Properties file from resource or disk. + * Unknown properties will be logged with WARN level; missing required properties will + * be filled with default and warning will be logged + * @param currentVersion + * @return ready to use properties + */ + public Properties parse(Properties config, Version currentVersion){ + //go through supplied config and check it, warn on deprecated and on unknown + for(Object key: config.keySet()){ + String name = (String)key; + String value = config.getProperty(name); + ConfigRecord cr = knownProps.get(name); + if (cr == null) { + log.warn("Unknown config property: '{}' with value: '{}'. It probably will be ignored", name, value); + } else if (currentVersion.greaterThan(cr.deprecatedSince)) { + log.warn("Config property: '{}' is deprecated since version '{}'", name, cr.deprecatedSince); + } + + } + //define required properties, warn on undefined + for(ConfigRecord pr: knownProps.values()){ + String val = config.getProperty(pr.name); + if (pr.isRequired && (val == null || val.isEmpty())) { + config.put(pr.name, pr.defaultValue); + log.warn("Required property: '{}' is not defined in config. Putting default value: '{}'", pr.name, pr.defaultValue); + } + } + return config; + } + + /** + * All known properties must be initiated in this method; All known properties are defined + * in resource file conf/apl-blockchain.properties or in files in corresponding testnet config + * directories.TODO: keywords for deprecation, command line options and env variables + * @param resourcePath path to properties file in resources + * @return created properties fully initiated with default values + */ + public static ConfigVerifier create( String resourcePath ) throws IOException { + ConfigVerifier kp = new ConfigVerifier(); + DefaultConfig dc = null; + if (resourcePath == null || resourcePath.isEmpty()) { + resourcePath="conf/apl-blockchain.properties"; + } + ClassLoader classloader = Thread.currentThread().getContextClassLoader(); + log.debug("Trying to load resource by path = '{}' ...", resourcePath); + try (InputStream is = classloader.getResourceAsStream(resourcePath)) { + dc = DefaultConfig.fromStream(is); + } + + kp.knownProps = dc.getKnownProperties(); + + //TODO: hardcode command line and env if so + + kp.getOrAdd("apl.customDbDir").sinceRelease = new Version(MARIADB_RELEASE); + + kp.getOrAdd("apl.customVaultKeystoreDir").sinceRelease = (new Version(DEX_RELEASE)); + + kp.getOrAdd("apl.customPidFile").sinceRelease = new Version(MARIADB_RELEASE); + + return kp; + } +} diff --git a/apl-conf/src/main/java/com/apollocurrency/aplwallet/apl/conf/DefaultConfig.java b/apl-conf/src/main/java/com/apollocurrency/aplwallet/apl/conf/DefaultConfig.java new file mode 100644 index 0000000000..aa83dcc9be --- /dev/null +++ b/apl-conf/src/main/java/com/apollocurrency/aplwallet/apl/conf/DefaultConfig.java @@ -0,0 +1,108 @@ +/* + * Copyright © 2018-2021 Apollo Foundation + */ +package com.apollocurrency.aplwallet.apl.conf; + +import com.apollocurrency.aplwallet.apl.util.Version; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +/** + * Parser of default config from resources. + * Default config must contain all properties known to the program with default values, + * description and keywords signaling corresponding command line options and + * environment variables. Keywords are prefixed + * @author Oleksiy Lukin alukin@gmail.com + */ +@Slf4j +public class DefaultConfig { + + public static final String KW_DEPRECATED = "DEPRECATED"; + public static final String KW_SINCE = "SINCE"; + public static final String KW_COMMAND_LINE = "CMDLINE"; + public static final String KW_ENV_VAR = "ENVVAR"; + + @Getter + final Map knownProperties = new HashMap<>(); + + static ConfigRecord createCr(String key, String value, List comments) { + Objects.requireNonNull(key, "key is NULL"); + Objects.requireNonNull(value, "value is NULL"); + Objects.requireNonNull(comments, "comments list is NULL"); + String comment = comments.stream().collect(Collectors.joining(" ")); + ConfigRecord cr = ConfigRecord.builder() + .name(key) + .defaultValue(value) + .description(comment) + .build(); + for (String line : comments) { + if (line.startsWith("!")) { + int end = line.indexOf(" ")>3 ? line.indexOf(" "): line.length()-1; + String cmd = line.substring(1,end).trim(); + String val = line.substring(end).trim(); + int val_end = val.indexOf(" ")>0 ? val.indexOf(" "): val.length(); + val = val.substring(0,val_end); + switch(cmd) { + case KW_DEPRECATED: + cr.deprecatedSince = new Version(val); + break; + case KW_SINCE: + cr.sinceRelease = new Version(val); + break; + case KW_COMMAND_LINE: + cr.cmdLineOpt=val; + break; + case KW_ENV_VAR: + cr.envVar = val; + break; + default: + log.warn("Unknown keyword in the property comments. Property: {} Keyword: {}", key, cmd); + } + } + } + + return cr; + } + + public static DefaultConfig fromStream(InputStream is) throws IOException { + Objects.requireNonNull(is, "Input Stream is NULL"); + DefaultConfig conf = new DefaultConfig(); + List commentBuf = new ArrayList<>(); + try ( BufferedReader br = new BufferedReader(new InputStreamReader(is))) { + String line; + while ((line = br.readLine()) != null) { + line = line.trim(); + if (line.startsWith("#")) { + commentBuf.add(line.substring(1)); + } else if (line.isBlank()) { + commentBuf.clear(); + } else { + String[] parts = line.split("="); + String key = parts[0]; + String value = ""; + if (parts.length > 1) { + value = parts[1]; + } + int idx = value.indexOf("#"); + if (idx >= 0) { + value = value.substring(idx); + } + + ConfigRecord cr = createCr(key, value, commentBuf); + conf.knownProperties.put(key, cr); + } + } + } + return conf; + } +} diff --git a/apl-conf/src/main/resources/conf/apl-blockchain.properties b/apl-conf/src/main/resources/conf/apl-blockchain.properties index 305cf7423b..714636dabd 100644 --- a/apl-conf/src/main/resources/conf/apl-blockchain.properties +++ b/apl-conf/src/main/resources/conf/apl-blockchain.properties @@ -23,10 +23,10 @@ # Set the socks proxy host. #socksProxyHost=localhost - +socksProxyHost= # Set the socks proxy port. #socksProxyPort=9050 - +socksProxyPort= #### PEER NETWORKING #### @@ -66,6 +66,7 @@ apl.myAddress= apl.myPlatform= # My hallmark, if available. +#!DEPRECATED 1.25.1 apl.myHallmark= # Maximum number of inbound connections. @@ -447,9 +448,13 @@ apl.batchCommitSize=100 apl.sharding.backupDb=false # if true, app will not import last shard, instead will start from genesis block +#!SINCE 1.35.0 +#!CMDLINE --no-shard-import apl.noshardimport=false # if true, app will not divide database for shards, will store large database files instead +#!SINCE 1.35.0 +#!CMDLINE --no-shard-import apl.noshardcreate=false # Minimal delay (in seconds) after reached shard height to wait before starting sharding process. diff --git a/apl-conf/src/test/java/com/apollocurrency/aplwallet/apl/conf/ConfigVerifierTest.java b/apl-conf/src/test/java/com/apollocurrency/aplwallet/apl/conf/ConfigVerifierTest.java new file mode 100644 index 0000000000..a7c757b4a5 --- /dev/null +++ b/apl-conf/src/test/java/com/apollocurrency/aplwallet/apl/conf/ConfigVerifierTest.java @@ -0,0 +1,110 @@ +package com.apollocurrency.aplwallet.apl.conf; + +import com.apollocurrency.aplwallet.apl.util.Constants; +import com.apollocurrency.aplwallet.apl.util.Version; +import com.apollocurrency.aplwallet.apl.util.env.config.PropertiesConfigLoader; +import lombok.SneakyThrows; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +import java.util.Collections; +import java.util.List; +import java.util.Properties; + +import static org.junit.jupiter.api.Assertions.*; + +class ConfigVerifierTest { + +// ConfigVerifier configVerifier; + + @AfterEach + void tearDown() { +// ConfigVerifier configVerifier = null; + } + + @SneakyThrows + @Test + void test_createEmpty() { + ConfigVerifier configVerifier = ConfigVerifier.create(null); + assertNotNull(configVerifier); + assertEquals(162, configVerifier.getKnownProps().size()); + } + + @SneakyThrows + @Test + void test_createNyKnownPath() { + ConfigVerifier configVerifier = ConfigVerifier.create("conf-tn2/apl-blockchain.properties"); + assertNotNull(configVerifier); + assertEquals(162, configVerifier.getKnownProps().size()); + } + + @SneakyThrows + @Test + void test_parse() { + ConfigVerifier configVerifier = ConfigVerifier.create("conf-tn2/apl-blockchain.properties"); + assertNotNull(configVerifier); + assertEquals(162, configVerifier.getKnownProps().size()); + + PropertiesConfigLoader propertiesLoader = new PropertiesConfigLoader( + null, + false, + null, + Constants.APPLICATION_DIR_NAME + ".properties", + Collections.emptyList()); + Properties applicationProperties = propertiesLoader.load(); + Properties properties = configVerifier.parse(applicationProperties, new Version(1, 25, 1)); + assertEquals(159, properties.size()); + } + + @SneakyThrows + @Test + void dumpToProperties() { + ConfigVerifier configVerifier = ConfigVerifier.create("conf-tn2/apl-blockchain.properties"); + assertNotNull(configVerifier); + assertEquals(162, configVerifier.getKnownProps().size()); + configVerifier.dumpToProperties(System.out); + } + + @SneakyThrows + @Test + void test_isSupported() { + ConfigVerifier configVerifier = ConfigVerifier.create("conf-tn1/apl-blockchain.properties"); + assertNotNull(configVerifier); + assertEquals(163, configVerifier.getKnownProps().size()); + assertTrue(configVerifier.isSupported("apl.myHallmark")); + } + + @SneakyThrows + @Test + void test_get() { + ConfigVerifier configVerifier = ConfigVerifier.create("conf-tn1/apl-blockchain.properties"); + assertNotNull(configVerifier); + assertEquals(163, configVerifier.getKnownProps().size()); + assertNotNull(configVerifier.get("apl.myHallmark")); + assertNull(configVerifier.get("apl.unknownPropertyName")); + } + + @SneakyThrows + @Test + void test_listDeprecated() { + ConfigVerifier configVerifier = ConfigVerifier.create("conf/apl-blockchain.properties"); + assertNotNull(configVerifier); + assertEquals(162, configVerifier.getKnownProps().size()); + List list = configVerifier.listDeprecated(new Version(1, 25, 3)); + assertNotNull(list); + assertEquals(1, list.size()); + assertEquals(new Version(1, 25, 1), list.get(0).deprecatedSince); + } + + @SneakyThrows + @Test + void test_listNewAfter() { + ConfigVerifier configVerifier = ConfigVerifier.create("conf/apl-blockchain.properties"); + assertNotNull(configVerifier); + assertEquals(162, configVerifier.getKnownProps().size()); + List list = configVerifier.listNewAfter(new Version(1, 35, 1)); + assertNotNull(list); + assertEquals(3, list.size()); + assertEquals(new Version(1, 48, 0), list.get(0).sinceRelease); + } +} \ No newline at end of file diff --git a/apl-conf/src/test/resources/logback-test.xml b/apl-conf/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..fed564207f --- /dev/null +++ b/apl-conf/src/test/resources/logback-test.xml @@ -0,0 +1,64 @@ + + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36}.%M\(%line\) - %msg%n + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apl-conf/src/test/resources/test-env.properties b/apl-conf/src/test/resources/test-env.properties new file mode 100644 index 0000000000..157a989aa1 --- /dev/null +++ b/apl-conf/src/test/resources/test-env.properties @@ -0,0 +1,6 @@ +# +# Copyright (c) 2018-2021. Apollo Foundation. +# +#comment out next property to increase the verbose level +apl-test.env=quiet +#apl-test.env=verbose diff --git a/apl-core/pom.xml b/apl-core/pom.xml index c301f8d93d..218e6215ac 100644 --- a/apl-core/pom.xml +++ b/apl-core/pom.xml @@ -276,7 +276,6 @@ org.testcontainers junit-jupiter - test diff --git a/apl-core/src/main/java/com/apollocurrency/aplwallet/apl/core/utils/LegacyDbUtil.java b/apl-core/src/main/java/com/apollocurrency/aplwallet/apl/core/utils/LegacyDbUtil.java deleted file mode 100644 index b412054d31..0000000000 --- a/apl-core/src/main/java/com/apollocurrency/aplwallet/apl/core/utils/LegacyDbUtil.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright © 2018-2021 Apollo Foundation - */ - -package com.apollocurrency.aplwallet.apl.core.utils; - -import com.apollocurrency.aplwallet.apl.util.env.RuntimeEnvironment; -import com.apollocurrency.aplwallet.apl.util.env.dirprovider.DirProvider; - -import java.nio.file.Path; -import java.nio.file.Paths; - -public class LegacyDbUtil { - public static Path getLegacyHomeDir() { - Path homeDirPath; - if (!RuntimeEnvironment.getInstance().isServiceMode()) { - if (RuntimeEnvironment.getInstance().isWindowsRuntime()) { - homeDirPath = Paths.get(System.getProperty("user.home"), "AppData", "Roaming", "APOLLO"); - } else { - homeDirPath = Paths.get(System.getProperty("user.home"), ".apollo"); - } - } else { - homeDirPath = DirProvider.getBinDir(); - } - return homeDirPath; - } -} diff --git a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/DBContainerRootTest.java b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/DbContainerRootUserTest.java similarity index 87% rename from apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/DBContainerRootTest.java rename to apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/DbContainerRootUserTest.java index fa6e52ad5c..1c6978c5f3 100644 --- a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/DBContainerRootTest.java +++ b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/DbContainerRootUserTest.java @@ -7,13 +7,13 @@ import org.testcontainers.junit.jupiter.Container; @Slf4j -public abstract class DBContainerRootTest { +public abstract class DbContainerRootUserTest { @Container public static final GenericContainer mariaDBContainer; static { - mariaDBContainer = new MariaDBContainer("mariadb:10.5") + mariaDBContainer = new MariaDBContainer(MariaDBConfigs.DOCKER_IMAGE_NAME_VERSION) .withDatabaseName("testdb") .withUsername("root") .withPassword("rootpass") diff --git a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/JdbcQueryExecutionHelperTest.java b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/JdbcQueryExecutionHelperTest.java index a738ab511d..024e14d2bd 100644 --- a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/JdbcQueryExecutionHelperTest.java +++ b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/JdbcQueryExecutionHelperTest.java @@ -20,7 +20,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @Tag("slow") -class JdbcQueryExecutionHelperTest extends DBContainerRootTest{ +class JdbcQueryExecutionHelperTest extends DbContainerRootUserTest { @RegisterExtension static DbExtension dbExtension = new DbExtension(mariaDBContainer); diff --git a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/MariaDBConfigs.java b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/MariaDBConfigs.java index f5fc74676d..b55941c7d3 100644 --- a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/MariaDBConfigs.java +++ b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/MariaDBConfigs.java @@ -2,6 +2,8 @@ public class MariaDBConfigs { + public static final String DOCKER_IMAGE_NAME_VERSION = "mariadb:10.11"; + private static String[] envs; static { diff --git a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/state/derived/ShardRecoveryDaoJdbcTest.java b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/state/derived/ShardRecoveryDaoJdbcTest.java index f2ddc0cfa0..0a0e819e45 100644 --- a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/state/derived/ShardRecoveryDaoJdbcTest.java +++ b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/state/derived/ShardRecoveryDaoJdbcTest.java @@ -4,11 +4,13 @@ package com.apollocurrency.aplwallet.apl.core.dao.state.derived; +import com.apollocurrency.aplwallet.apl.core.config.TimeConfig; import com.apollocurrency.aplwallet.apl.core.dao.DbContainerBaseTest; import com.apollocurrency.aplwallet.apl.core.dao.appdata.ShardRecoveryDaoJdbc; import com.apollocurrency.aplwallet.apl.core.dao.appdata.impl.ShardRecoveryDaoJdbcImpl; import com.apollocurrency.aplwallet.apl.core.db.DatabaseManager; import com.apollocurrency.aplwallet.apl.core.entity.appdata.ShardRecovery; +import com.apollocurrency.aplwallet.apl.core.service.appdata.TimeService; import com.apollocurrency.aplwallet.apl.core.service.appdata.impl.TimeServiceImpl; import com.apollocurrency.aplwallet.apl.core.shard.MigrateState; import com.apollocurrency.aplwallet.apl.extension.DbExtension; @@ -45,11 +47,16 @@ class ShardRecoveryDaoJdbcTest extends DbContainerBaseTest { @RegisterExtension static DbExtension extension = new DbExtension(mariaDBContainer); + TimeConfig config = new TimeConfig(false); + TimeService timeService = new TimeServiceImpl(config.timeSource()); + @WeldSetup public WeldInitiator weld = WeldInitiator.from( - PropertiesHolder.class, ShardRecoveryDaoJdbcImpl.class, TimeServiceImpl.class) + PropertiesHolder.class, ShardRecoveryDaoJdbcImpl.class) .addBeans(MockBean.of(extension.getDatabaseManager(), DatabaseManager.class)) .addBeans(MockBean.of(mock(NtpTime.class), NtpTime.class)) + .addBeans(MockBean.of(config, TimeConfig.class)) + .addBeans(MockBean.of(timeService, TimeService.class)) .build(); private Connection connection; diff --git a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/state/shuffling/ShufflingDataTableTest.java b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/state/shuffling/ShufflingDataTableTest.java index 2aa7e960e3..eec7beecee 100644 --- a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/state/shuffling/ShufflingDataTableTest.java +++ b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/state/shuffling/ShufflingDataTableTest.java @@ -5,7 +5,7 @@ package com.apollocurrency.aplwallet.apl.core.dao.state.shuffling; import com.apollocurrency.aplwallet.apl.core.chainid.BlockchainConfig; -import com.apollocurrency.aplwallet.apl.core.dao.DBContainerRootTest; +import com.apollocurrency.aplwallet.apl.core.dao.DbContainerRootUserTest; import com.apollocurrency.aplwallet.apl.core.dao.state.keyfactory.LongKey; import com.apollocurrency.aplwallet.apl.data.DbTestData; import com.apollocurrency.aplwallet.apl.data.ShufflingTestData; @@ -22,8 +22,9 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.mock; + @Tag("slow") -class ShufflingDataTableTest extends DBContainerRootTest { +class ShufflingDataTableTest extends DbContainerRootUserTest { @RegisterExtension static DbExtension extension = new DbExtension(mariaDBContainer, DbTestData.getInMemDbProps(), "db/shuffling.sql", null); diff --git a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/state/shuffling/ShufflingDbRepositoryTest.java b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/state/shuffling/ShufflingDbRepositoryTest.java index 1860f775fa..50afaf3b70 100644 --- a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/state/shuffling/ShufflingDbRepositoryTest.java +++ b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/state/shuffling/ShufflingDbRepositoryTest.java @@ -4,7 +4,7 @@ package com.apollocurrency.aplwallet.apl.core.dao.state.shuffling; -import com.apollocurrency.aplwallet.apl.core.dao.DBContainerRootTest; +import com.apollocurrency.aplwallet.apl.core.dao.DbContainerRootUserTest; import com.apollocurrency.aplwallet.apl.core.entity.state.shuffling.Shuffling; import com.apollocurrency.aplwallet.apl.core.entity.state.shuffling.ShufflingStage; import com.apollocurrency.aplwallet.apl.data.DbTestData; @@ -28,11 +28,11 @@ public class ShufflingDbRepositoryTest extends ShufflingRepositoryTest { @BeforeAll static void beforeAll() { - log.info("Connect to the db using {}", DBContainerRootTest.class); + log.info("Connect to the db using {}", DbContainerRootUserTest.class); } @RegisterExtension - static DbExtension extension = new DbExtension(DBContainerRootTest.mariaDBContainer, DbTestData.getInMemDbProps(), "db/shuffling.sql", null); + static DbExtension extension = new DbExtension(DbContainerRootUserTest.mariaDBContainer, DbTestData.getInMemDbProps(), "db/shuffling.sql", null); @Override public ShufflingTable createRepository() { diff --git a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/state/shuffling/ShufflingParticipantTableTest.java b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/state/shuffling/ShufflingParticipantTableTest.java index f2836bbb7b..434b6bbd76 100644 --- a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/state/shuffling/ShufflingParticipantTableTest.java +++ b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/state/shuffling/ShufflingParticipantTableTest.java @@ -4,7 +4,7 @@ package com.apollocurrency.aplwallet.apl.core.dao.state.shuffling; -import com.apollocurrency.aplwallet.apl.core.dao.DBContainerRootTest; +import com.apollocurrency.aplwallet.apl.core.dao.DbContainerRootUserTest; import com.apollocurrency.aplwallet.apl.core.dao.state.keyfactory.LinkKey; import com.apollocurrency.aplwallet.apl.core.entity.state.shuffling.ShufflingParticipant; import com.apollocurrency.aplwallet.apl.data.DbTestData; @@ -24,7 +24,7 @@ import static org.mockito.Mockito.mock; @Tag("slow") -public class ShufflingParticipantTableTest extends DBContainerRootTest { +public class ShufflingParticipantTableTest extends DbContainerRootUserTest { @RegisterExtension static DbExtension extension = new DbExtension(mariaDBContainer, DbTestData.getInMemDbProps(), "db/shuffling.sql", null); diff --git a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/state/smc/SmcContractEventLogTableTest.java b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/state/smc/SmcContractEventLogTableTest.java index b4ee5a4bb2..b2c15ce633 100644 --- a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/state/smc/SmcContractEventLogTableTest.java +++ b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/state/smc/SmcContractEventLogTableTest.java @@ -22,6 +22,7 @@ import lombok.extern.slf4j.Slf4j; import org.jboss.weld.junit.MockBean; import org.jboss.weld.junit5.EnableWeld; +import org.jboss.weld.junit5.ExplicitParamInjection; import org.jboss.weld.junit5.WeldInitiator; import org.jboss.weld.junit5.WeldSetup; import org.junit.jupiter.api.AfterEach; @@ -48,6 +49,7 @@ @Slf4j @Tag("slow") @EnableWeld +@ExplicitParamInjection class SmcContractEventLogTableTest extends DbContainerBaseTest { @RegisterExtension static TemporaryFolderExtension temporaryFolderExtension = new TemporaryFolderExtension(); @@ -122,11 +124,11 @@ void getEntries() { assertEquals(4, actual.size()); } - @CsvSource(delimiterString = ":", value = { - "Buy:0:-1:4", - "Transfer:0:-1:10", - "Transfer:100:-1:9", - "Transfer:100:10000:8" + @CsvSource(value = { + "Buy,0,-1,4", + "Transfer,0,-1,10", + "Transfer,100,-1,9", + "Transfer,100,10000,8" }) @ParameterizedTest void getEventsByFilter(String name, Integer heightFrom, Integer heightTo, Integer num) { diff --git a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/state/smc/SmcContractTableTest.java b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/state/smc/SmcContractTableTest.java index 92abcac779..7dbcbd24c7 100644 --- a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/state/smc/SmcContractTableTest.java +++ b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/state/smc/SmcContractTableTest.java @@ -32,6 +32,7 @@ import lombok.extern.slf4j.Slf4j; import org.jboss.weld.junit.MockBean; import org.jboss.weld.junit5.EnableWeld; +import org.jboss.weld.junit5.ExplicitParamInjection; import org.jboss.weld.junit5.WeldInitiator; import org.jboss.weld.junit5.WeldSetup; import org.junit.jupiter.api.AfterEach; @@ -64,6 +65,7 @@ @Slf4j @Tag("slow") @EnableWeld +@ExplicitParamInjection class SmcContractTableTest extends DbContainerBaseTest { @RegisterExtension diff --git a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/state/tagged/TaggedDataTimestampDaoTest.java b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/state/tagged/TaggedDataTimestampDaoTest.java index e1a4bc5db4..a521101180 100644 --- a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/state/tagged/TaggedDataTimestampDaoTest.java +++ b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/dao/state/tagged/TaggedDataTimestampDaoTest.java @@ -105,11 +105,10 @@ class TaggedDataTimestampDaoTest extends DbContainerBaseTest { .addBeans(MockBean.of(mock(AliasService.class), AliasService.class)) .addBeans(MockBean.of(propertiesHolder, PropertiesHolder.class)) .addBeans(MockBean.of(mock(PublicKeyDao.class), PublicKeyDao.class)) - .addBeans(MockBean.of(timeService, TimeConfig.class)) + .addBeans(MockBean.of(config, TimeConfig.class)) .addBeans(MockBean.of(timeService, TimeService.class)) .addBeans(MockBean.of(mock(PrunableLoadingService.class), PrunableLoadingService.class)) .addBeans(MockBean.of(ttd.getTransactionTypeFactory(), TransactionTypeFactory.class)) - .addBeans(MockBean.of(timeService, TimeService.class)) .addBeans(MockBean.of(mock(BlockchainConfig.class), BlockchainConfig.class)) .build(); diff --git a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/db/DatabaseManagerTest.java b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/db/DatabaseManagerTest.java index d0cd15382a..0283a180f3 100644 --- a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/db/DatabaseManagerTest.java +++ b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/db/DatabaseManagerTest.java @@ -4,7 +4,7 @@ package com.apollocurrency.aplwallet.apl.core.db; -import com.apollocurrency.aplwallet.apl.core.dao.DBContainerRootTest; +import com.apollocurrency.aplwallet.apl.core.dao.DbContainerRootUserTest; import com.apollocurrency.aplwallet.apl.core.shard.ShardManagement; import com.apollocurrency.aplwallet.apl.data.DbTestData; import com.apollocurrency.aplwallet.apl.db.updater.ShardAllScriptsDBUpdater; @@ -57,7 +57,7 @@ @Slf4j @Tag("slow") @ExtendWith(MockitoExtension.class) -class DatabaseManagerTest extends DBContainerRootTest { +class DatabaseManagerTest extends DbContainerRootUserTest { private static PropertiesHolder propertiesHolder = new PropertiesHolder(); private DbProperties baseDbProperties; private DatabaseManagerImpl databaseManager; diff --git a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/service/blockchain/BlockchainTest.java b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/service/blockchain/BlockchainTest.java index a766464f4a..32100f05bf 100644 --- a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/service/blockchain/BlockchainTest.java +++ b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/service/blockchain/BlockchainTest.java @@ -4,6 +4,7 @@ package com.apollocurrency.aplwallet.apl.core.service.blockchain; +import com.apollocurrency.aplwallet.apl.core.dao.DbContainerRootUserTest; import com.apollocurrency.aplwallet.apl.core.model.Block; import com.apollocurrency.aplwallet.apl.core.model.EcBlockData; import com.apollocurrency.aplwallet.apl.core.model.Sort; @@ -19,7 +20,6 @@ import com.apollocurrency.aplwallet.apl.core.converter.db.TransactionEntityToModelConverter; import com.apollocurrency.aplwallet.apl.core.converter.db.TransactionModelToEntityConverter; import com.apollocurrency.aplwallet.apl.core.converter.db.TxReceiptRowMapper; -import com.apollocurrency.aplwallet.apl.core.dao.DBContainerRootTest; import com.apollocurrency.aplwallet.apl.core.dao.appdata.TransactionIndexDao; import com.apollocurrency.aplwallet.apl.core.dao.blockchain.BlockDaoImpl; import com.apollocurrency.aplwallet.apl.core.dao.blockchain.TransactionDaoImpl; @@ -101,7 +101,7 @@ @Tag("slow") @EnableWeld @Slf4j -class BlockchainTest extends DBContainerRootTest { +class BlockchainTest extends DbContainerRootUserTest { static DbExtension extension;// init later in manual mode static DbPopulator shard1Populator; static DbPopulator shard2Populator; diff --git a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/service/state/DGSObserverTest.java b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/service/state/DGSObserverTest.java index 0b0a8f131c..95f8fa74f3 100644 --- a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/service/state/DGSObserverTest.java +++ b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/service/state/DGSObserverTest.java @@ -10,7 +10,9 @@ import com.apollocurrency.aplwallet.apl.core.app.observer.events.BlockEvent; import com.apollocurrency.aplwallet.apl.core.app.observer.events.BlockEventBinding; import com.apollocurrency.aplwallet.apl.core.app.observer.events.BlockEventType; +import com.apollocurrency.aplwallet.apl.core.config.TimeConfig; import com.apollocurrency.aplwallet.apl.core.model.Block; +import com.apollocurrency.aplwallet.apl.core.service.appdata.TimeService; import com.apollocurrency.aplwallet.apl.core.service.blockchain.TransactionBuilderFactory; import com.apollocurrency.aplwallet.apl.core.chainid.BlockchainConfig; import com.apollocurrency.aplwallet.apl.core.config.DaoConfig; @@ -90,6 +92,8 @@ public class DGSObserverTest extends DbContainerBaseTest { @RegisterExtension static DbExtension extension = new DbExtension(mariaDBContainer); Blockchain blockchain = mock(Blockchain.class); + TimeConfig config = new TimeConfig(false); + TimeService timeService = new TimeServiceImpl(config.timeSource()); private TransactionTestData td = new TransactionTestData(); @WeldSetup public WeldInitiator weld = WeldInitiator.from( @@ -106,7 +110,7 @@ public class DGSObserverTest extends DbContainerBaseTest { DGSServiceImpl.class, DGSObserver.class, DerivedDbTablesRegistryImpl.class, - TimeServiceImpl.class, BlockDaoImpl.class, + BlockDaoImpl.class, BlockEntityRowMapper.class, BlockEntityToModelConverter.class, BlockModelToEntityConverter.class, TransactionDaoImpl.class, BlockChainInfoServiceImpl.class, AccountServiceImpl.class, GenesisAccounts.class, JdbiHandleFactory.class, JdbiConfiguration.class) @@ -126,6 +130,8 @@ public class DGSObserverTest extends DbContainerBaseTest { .addBeans(MockBean.of(mock(PrunableLoadingService.class), PrunableLoadingService.class)) .addBeans(MockBean.of(td.getTransactionTypeFactory(), TransactionTypeFactory.class)) .addBeans(MockBean.of(mock(BlockchainConfig.class), BlockchainConfig.class)) + .addBeans(MockBean.of(config, TimeConfig.class)) + .addBeans(MockBean.of(timeService, TimeService.class)) .addBeans(MockBean.of(new AccountTable(extension.getDatabaseManager(), mock(Event.class)), AccountTableInterface.class)) .build(); @Inject diff --git a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/service/state/DGSServiceTest.java b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/service/state/DGSServiceTest.java index 021eabcd03..80fd813471 100644 --- a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/service/state/DGSServiceTest.java +++ b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/service/state/DGSServiceTest.java @@ -8,6 +8,7 @@ import com.apollocurrency.aplwallet.apl.core.app.GenesisAccounts; import com.apollocurrency.aplwallet.apl.core.chainid.BlockchainConfig; import com.apollocurrency.aplwallet.apl.core.config.JdbiConfiguration; +import com.apollocurrency.aplwallet.apl.core.config.TimeConfig; import com.apollocurrency.aplwallet.apl.core.dao.DbContainerBaseTest; import com.apollocurrency.aplwallet.apl.core.dao.state.account.AccountGuaranteedBalanceTable; import com.apollocurrency.aplwallet.apl.core.dao.state.account.AccountTable; @@ -27,6 +28,7 @@ import com.apollocurrency.aplwallet.apl.core.entity.state.dgs.DGSTag; import com.apollocurrency.aplwallet.apl.core.model.Block; import com.apollocurrency.aplwallet.apl.core.model.Transaction; +import com.apollocurrency.aplwallet.apl.core.service.appdata.TimeService; import com.apollocurrency.aplwallet.apl.core.service.appdata.impl.TimeServiceImpl; import com.apollocurrency.aplwallet.apl.core.service.blockchain.Blockchain; import com.apollocurrency.aplwallet.apl.core.service.blockchain.BlockchainProcessor; @@ -102,13 +104,14 @@ public class DGSServiceTest extends DbContainerBaseTest { @RegisterExtension DbExtension extension = new DbExtension(mariaDBContainer, DbTestData.getDbUrlProps(), "db/dgs-data.sql", "db/schema.sql"); + TimeConfig config = new TimeConfig(false); + TimeService timeService = new TimeServiceImpl(config.timeSource()); Blockchain blockchain = mock(Blockchain.class); AccountTable accountTable = new AccountTable(extension.getDatabaseManager(), mock(Event.class)); @WeldSetup public WeldInitiator weld = WeldInitiator.from( PropertiesHolder.class, - TimeServiceImpl.class, GlobalSyncImpl.class, FullTextConfigImpl.class, DGSPublicFeedbackTable.class, @@ -134,6 +137,8 @@ public class DGSServiceTest extends DbContainerBaseTest { .addBeans(MockBean.of(mock(AccountLedgerService.class), AccountLedgerService.class, AccountLedgerServiceImpl.class)) .addBeans(MockBean.of(mock(FullTextSearchUpdater.class), FullTextSearchUpdater.class, FullTextSearchUpdaterImpl.class)) .addBeans(MockBean.of(mock(BlockchainConfig.class), BlockchainConfig.class)) + .addBeans(MockBean.of(config, TimeConfig.class)) + .addBeans(MockBean.of(timeService, TimeService.class)) .build(); Block lastBlock = mock(Block.class); Block prevBlock = mock(Block.class); diff --git a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/service/state/PhasingPollServiceTest.java b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/service/state/PhasingPollServiceTest.java index 088fb1c848..4b8fe54f5d 100644 --- a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/service/state/PhasingPollServiceTest.java +++ b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/service/state/PhasingPollServiceTest.java @@ -164,7 +164,7 @@ public class PhasingPollServiceTest extends DbContainerBaseTest { .addBeans(MockBean.of(mock(AliasService.class), AliasService.class)) .addBeans(MockBean.of(blockDao, BlockDao.class)) .addBeans(MockBean.of(propertiesHolder, PropertiesHolder.class)) - .addBeans(MockBean.of(timeService, TimeConfig.class)) + .addBeans(MockBean.of(config, TimeConfig.class)) .addBeans(MockBean.of(timeService, TimeService.class)) .addBeans(MockBean.of(mock(PrunableLoadingService.class), PrunableLoadingService.class)) .addBeans(MockBean.of(ttd.getTransactionTypeFactory(), TransactionTypeFactory.class)) diff --git a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/service/state/ReferencedTransactionServiceTest.java b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/service/state/ReferencedTransactionServiceTest.java index da6903cc9d..eb562c8471 100644 --- a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/service/state/ReferencedTransactionServiceTest.java +++ b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/service/state/ReferencedTransactionServiceTest.java @@ -4,6 +4,8 @@ package com.apollocurrency.aplwallet.apl.core.service.state; +import com.apollocurrency.aplwallet.apl.core.config.TimeConfig; +import com.apollocurrency.aplwallet.apl.core.service.appdata.TimeService; import com.apollocurrency.aplwallet.apl.core.service.blockchain.TransactionBuilderFactory; import com.apollocurrency.aplwallet.apl.core.model.TransactionImpl; import com.apollocurrency.aplwallet.apl.core.chainid.BlockchainConfig; @@ -77,6 +79,8 @@ public class ReferencedTransactionServiceTest extends DbContainerBaseTest { static TemporaryFolderExtension temporaryFolderExtension = new TemporaryFolderExtension(); @RegisterExtension static DbExtension extension = new DbExtension(mariaDBContainer, DbTestData.getDbFileProperties(createPath("targetDb").toAbsolutePath().toString())); + TimeConfig config = new TimeConfig(false); + TimeService timeService = new TimeServiceImpl(config.timeSource()); BlockchainConfig blockchainConfig = Mockito.mock(BlockchainConfig.class); Chain chain = mock(Chain.class); @@ -99,7 +103,7 @@ public class ReferencedTransactionServiceTest extends DbContainerBaseTest { FullTextConfigImpl.class, GlobalSyncImpl.class, DerivedDbTablesRegistryImpl.class, - TimeServiceImpl.class, BlockDaoImpl.class, + BlockDaoImpl.class, BlockEntityRowMapper.class, BlockEntityToModelConverter.class, BlockModelToEntityConverter.class, TransactionDaoImpl.class, ReferencedTransactionService.class, JdbiHandleFactory.class, JdbiConfiguration.class) .addBeans(MockBean.of(extension.getDatabaseManager(), DatabaseManager.class)) @@ -113,8 +117,10 @@ public class ReferencedTransactionServiceTest extends DbContainerBaseTest { .addBeans(MockBean.of(mock(PrunableLoadingService.class), PrunableLoadingService.class)) .addBeans(MockBean.of(td.getTransactionTypeFactory(), TransactionTypeFactory.class)) .addBeans(MockBean.of(mock(PublicKeyDao.class), PublicKeyDao.class)) + .addBeans(MockBean.of(config, TimeConfig.class)) + .addBeans(MockBean.of(timeService, TimeService.class)) .build(); - HeightConfig config = Mockito.mock(HeightConfig.class); + HeightConfig heightConfig = Mockito.mock(HeightConfig.class); @Inject ReferencedTransactionService service; @@ -129,13 +135,13 @@ private static Path createPath(String fileName) { @BeforeEach void setUp() { - doReturn(config).when(blockchainConfig).getCurrentConfig(); + doReturn(heightConfig).when(blockchainConfig).getCurrentConfig(); } @Test void testHasAllReferencedTransaction() { TransactionTestData td = new TransactionTestData(); - doReturn(1000).when(config).getReferencedTransactionHeightSpan(); + doReturn(1000).when(heightConfig).getReferencedTransactionHeightSpan(); boolean hasAll = service.hasAllReferencedTransactions(td.TRANSACTION_0, 1000); assertTrue(hasAll); @@ -144,7 +150,7 @@ void testHasAllReferencedTransaction() { @Test void testHasNotAllReferencedTransactionsWhenHeightIsNotEnough() { TransactionTestData td = new TransactionTestData(); - doReturn(1000).when(config).getReferencedTransactionHeightSpan(); + doReturn(1000).when(heightConfig).getReferencedTransactionHeightSpan(); boolean hasAll = service.hasAllReferencedTransactions(td.TRANSACTION_5, td.TRANSACTION_5.getHeight()); assertFalse(hasAll); @@ -153,7 +159,7 @@ void testHasNotAllReferencedTransactionsWhenHeightIsNotEnough() { @Test void testHasNotAllReferencedTransactionsWhenTransactionHeightIsLessThanHeightOfReferencedTransactions() { TransactionTestData td = new TransactionTestData(); - doReturn(20_000).when(config).getReferencedTransactionHeightSpan(); + doReturn(20_000).when(heightConfig).getReferencedTransactionHeightSpan(); boolean hasAll = service.hasAllReferencedTransactions(td.TRANSACTION_11, td.TRANSACTION_11.getHeight()); assertFalse(hasAll); @@ -161,7 +167,7 @@ void testHasNotAllReferencedTransactionsWhenTransactionHeightIsLessThanHeightOfR @Test void testHasNotAllReferencedTransactionWhenMaximumNumberOfReferencedTransactionsReached() { - doReturn(20_000).when(config).getReferencedTransactionHeightSpan(); + doReturn(20_000).when(heightConfig).getReferencedTransactionHeightSpan(); TransactionTestData td = new TransactionTestData(); boolean hasAll = service.hasAllReferencedTransactions(td.TRANSACTION_9, td.TRANSACTION_9.getHeight()); diff --git a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/shard/ShardEngineTest.java b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/shard/ShardEngineTest.java index 259d22e688..9f6c54df23 100644 --- a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/shard/ShardEngineTest.java +++ b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/shard/ShardEngineTest.java @@ -18,7 +18,7 @@ import com.apollocurrency.aplwallet.apl.core.converter.db.TransactionEntityToModelConverter; import com.apollocurrency.aplwallet.apl.core.converter.db.TransactionModelToEntityConverter; import com.apollocurrency.aplwallet.apl.core.converter.db.TxReceiptRowMapper; -import com.apollocurrency.aplwallet.apl.core.dao.DBContainerRootTest; +import com.apollocurrency.aplwallet.apl.core.dao.DbContainerRootUserTest; import com.apollocurrency.aplwallet.apl.core.dao.appdata.BlockIndexDao; import com.apollocurrency.aplwallet.apl.core.dao.appdata.ReferencedTransactionDao; import com.apollocurrency.aplwallet.apl.core.dao.appdata.ShardDao; @@ -89,6 +89,7 @@ import com.apollocurrency.aplwallet.apl.extension.TemporaryFolderExtension; import com.apollocurrency.aplwallet.apl.testutil.DbPopulator; import com.apollocurrency.aplwallet.apl.testutil.DbUtils; +import com.apollocurrency.aplwallet.apl.util.Convert2; import com.apollocurrency.aplwallet.apl.util.FileUtils; import com.apollocurrency.aplwallet.apl.util.Zip; import com.apollocurrency.aplwallet.apl.util.ZipImpl; @@ -158,7 +159,7 @@ @Slf4j @Tag("slow") @EnableWeld -class ShardEngineTest extends DBContainerRootTest { +class ShardEngineTest extends DbContainerRootUserTest { static final String GOODS_TABLE_NAME = "goods"; static final String PHASING_POLL_TABLE_NAME = "phasing_poll"; static final String PRUNABLE_MESSAGE_TABLE_NAME = "prunable_message"; @@ -179,7 +180,11 @@ class ShardEngineTest extends DBContainerRootTest { createPath("targetDb").toAbsolutePath().toString()), "db/shard/shard-creation-data.sql"); private final Path dataExportDirPath = createPath("targetDb"); - private final Bean dataExportDir = MockBean.of(dataExportDirPath.toAbsolutePath(), Path.class); + private final Bean dataExportDir = MockBean. builder() + .beanClass(Path.class) + .addQualifier(new NamedLiteral("dataExportDir")) + .creating(dataExportDirPath.toAbsolutePath()) + .build(); private PropertiesHolder propertiesHolder = mock(PropertiesHolder.class); TimeConfig config = new TimeConfig(false); @@ -221,7 +226,6 @@ class ShardEngineTest extends DBContainerRootTest { ); // return the same dir for both CDI components // - dataExportDir.getQualifiers().add(new NamedLiteral("dataExportDir")); // for CsvExporter doReturn(dataExportDirPath).when(dirProvider).getDataExportDir(); // for Zip } @@ -238,21 +242,18 @@ class ShardEngineTest extends DBContainerRootTest { .addBeans(MockBean.of(td.getTransactionTypeFactory(), TransactionTypeFactory.class)) .addBeans(MockBean.of(zip, Zip.class)) .addBeans(dataExportDir) - .addBeans(MockBean.of(timeService, TimeService.class)) .addBeans(MockBean.of(mock(AccountPublicKeyService.class), AccountPublicKeyService.class, AccountPublicKeyServiceImpl.class)) .addBeans(MockBean.of(mock(BlockIndexService.class), BlockIndexService.class, BlockIndexServiceImpl.class)) .addBeans(MockBean.of(translator, CsvEscaperImpl.class)) -// .addBeans(MockBean.of(baseDbProperties, DbProperties.class)) // YL DO NOT REMOVE THAT PLEASE, it can be used for manual testing .addBeans(MockBean.of(mock(AliasService.class), AliasService.class)) .addBeans(MockBean.of(propertiesHolder, PropertiesHolder.class)) - .addBeans(MockBean.of(timeService, TimeConfig.class)) + .addBeans(MockBean.of(config, TimeConfig.class)) .addBeans(MockBean.of(timeService, TimeService.class)) .addBeans(MockBean.of(blockchainConfig, BlockchainConfig.class)) .addBeans(MockBean.of(publicKeyDao, PublicKeyDao.class)) .addBeans(MockBean.of(mock(InMemoryCacheManager.class), InMemoryCacheManager.class)) .addBeans(MockBean.of(mock(TaskDispatchManager.class), TaskDispatchManager.class)) .build(); - @Inject AccountCurrencyTable accountCurrencyTable; @Inject @@ -291,6 +292,7 @@ class ShardEngineTest extends DBContainerRootTest { @BeforeEach void setUp() { shardEngine.prepare(); + Convert2.init("APL", 0); } @AfterEach diff --git a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/shard/ShardMigrationExecutorTest.java b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/shard/ShardMigrationExecutorTest.java index 6903b2c446..17bdf97d17 100644 --- a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/shard/ShardMigrationExecutorTest.java +++ b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/shard/ShardMigrationExecutorTest.java @@ -20,7 +20,7 @@ import com.apollocurrency.aplwallet.apl.core.converter.db.TransactionEntityToModelConverter; import com.apollocurrency.aplwallet.apl.core.converter.db.TransactionModelToEntityConverter; import com.apollocurrency.aplwallet.apl.core.converter.db.TxReceiptRowMapper; -import com.apollocurrency.aplwallet.apl.core.dao.DBContainerRootTest; +import com.apollocurrency.aplwallet.apl.core.dao.DbContainerRootUserTest; import com.apollocurrency.aplwallet.apl.core.dao.appdata.BlockIndexDao; import com.apollocurrency.aplwallet.apl.core.dao.appdata.ReferencedTransactionDao; import com.apollocurrency.aplwallet.apl.core.dao.appdata.ShardDao; @@ -75,6 +75,7 @@ import com.apollocurrency.aplwallet.apl.core.shard.hash.ShardHashCalculatorImpl; import com.apollocurrency.aplwallet.apl.core.shard.helper.CsvExporter; import com.apollocurrency.aplwallet.apl.core.shard.helper.CsvExporterImpl; +import com.apollocurrency.aplwallet.apl.core.shard.helper.csv.CsvEscaper; import com.apollocurrency.aplwallet.apl.core.shard.helper.csv.CsvEscaperImpl; import com.apollocurrency.aplwallet.apl.core.shard.model.ExcludeInfo; import com.apollocurrency.aplwallet.apl.core.shard.model.PrevBlockData; @@ -98,6 +99,7 @@ import lombok.extern.slf4j.Slf4j; import org.jboss.weld.junit.MockBean; import org.jboss.weld.junit5.EnableWeld; +import org.jboss.weld.junit5.ExplicitParamInjection; import org.jboss.weld.junit5.WeldInitiator; import org.jboss.weld.junit5.WeldSetup; import org.jboss.weld.literal.NamedLiteral; @@ -107,6 +109,7 @@ import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.api.io.TempDir; import org.mockito.Mockito; import jakarta.enterprise.inject.spi.Bean; @@ -142,7 +145,8 @@ @Slf4j @Tag("slow") @EnableWeld -class ShardMigrationExecutorTest extends DBContainerRootTest { +@ExplicitParamInjection +class ShardMigrationExecutorTest extends DbContainerRootUserTest { private static final String SHA_512 = "SHA-512"; @RegisterExtension @@ -151,8 +155,12 @@ class ShardMigrationExecutorTest extends DBContainerRootTest { private static BlockchainConfig blockchainConfig = mock(BlockchainConfig.class); Chain chain = mock(Chain.class); private static HeightConfig heightConfig = mock(HeightConfig.class); - private final Path dataExportDirPath = createPath("targetDb"); - private final Bean dataExportDir = MockBean.of(dataExportDirPath.toAbsolutePath(), Path.class); + private final Path dataExportDirPath = createTempPath(); + private final Bean dataExportDir = MockBean. builder() + .beanClass(Path.class) + .addQualifier(new NamedLiteral("dataExportDir")) + .creating(dataExportDirPath.toAbsolutePath()) + .build(); @RegisterExtension static DbExtension extension = new DbExtension(mariaDBContainer); @@ -160,11 +168,13 @@ class ShardMigrationExecutorTest extends DBContainerRootTest { private TaskDispatchManager taskDispatchManager = mock(TaskDispatchManager.class); private DirProvider dirProvider = mock(DirProvider.class); - private Zip zip = new UtilComponentConfig().zip(); TimeConfig config = new TimeConfig(false); + private Zip zip = new UtilComponentConfig().zip(); + TimeConfig config = new TimeConfig(false); TimeService timeService = new TimeServiceImpl(config.timeSource()); private GeneratorService generatorService = mock(GeneratorService.class); private TransactionTestData td = new TransactionTestData(); - + CsvEscaper csvEscaper = new CsvEscaperImpl(); + CsvExporter csvExporter = new CsvExporterImpl(extension.getDatabaseManager(), dataExportDirPath, csvEscaper); @WeldSetup WeldInitiator weld = WeldInitiator.from( BlockchainImpl.class, DaoConfig.class, ReferencedTransactionDao.class, @@ -183,11 +193,11 @@ class ShardMigrationExecutorTest extends DBContainerRootTest { PhasingPollTable.class, FullTextConfigImpl.class, DerivedTablesRegistry.class, - ShardEngineImpl.class, CsvExporterImpl.class, AplAppStatus.class, + ShardEngineImpl.class, AplAppStatus.class, BlockDaoImpl.class, BlockEntityRowMapper.class, BlockEntityToModelConverter.class, BlockModelToEntityConverter.class, TransactionDaoImpl.class, ShardMigrationExecutor.class, - CsvEscaperImpl.class, JdbiHandleFactory.class, JdbiConfiguration.class) + JdbiHandleFactory.class, JdbiConfiguration.class) .addBeans(MockBean.of(blockchainConfig, BlockchainConfig.class)) .addBeans(MockBean.of(extension.getDatabaseManager(), DatabaseManager.class)) .addBeans(MockBean.of(mock(TransactionProcessor.class), TransactionProcessor.class)) @@ -204,13 +214,15 @@ class ShardMigrationExecutorTest extends DBContainerRootTest { .addBeans(MockBean.of(mock(PrunableMessageService.class), PrunableMessageService.class, PrunableMessageServiceImpl.class)) .addBeans(MockBean.of(mock(BlockIndexService.class), BlockIndexService.class, BlockIndexServiceImpl.class)) .addBeans(MockBean.of(mock(AliasService.class), AliasService.class)) - .addBeans(MockBean.of(timeService, TimeConfig.class)) + .addBeans(MockBean.of(config, TimeConfig.class)) .addBeans(MockBean.of(timeService, TimeService.class)) .addBeans(MockBean.of(zip, Zip.class)) .addBeans(MockBean.of(generatorService, GeneratorService.class)) .addBeans(MockBean.of(mock(PrunableLoadingService.class), PrunableLoadingService.class)) .addBeans(MockBean.of(td.getTransactionTypeFactory(), TransactionTypeFactory.class)) .addBeans(MockBean.of(mock(PublicKeyDao.class), PublicKeyDao.class)) + .addBeans(MockBean.of(csvEscaper, CsvEscaper.class)) + .addBeans(MockBean.of(csvExporter, CsvExporter.class)) .build(); @Inject private ShardEngine shardEngine; @@ -243,7 +255,6 @@ class ShardMigrationExecutorTest extends DBContainerRootTest { { // return the same dir for both CDI components - dataExportDir.getQualifiers().add(new NamedLiteral("dataExportDir")); // for CsvExporter doReturn(dataExportDirPath).when(dirProvider).getDataExportDir(); // for Zip doReturn(chain).when(blockchainConfig).getChain(); } @@ -270,8 +281,9 @@ void tearDown() { } @Test - void executeAllOperations() throws IOException { - doReturn(temporaryFolderExtension.newFolder("backup").toPath()).when(dirProvider).getDbDir(); + void executeAllOperations(@TempDir Path tempPath) { +// doReturn(tempPath.resolve("backup").toAbsolutePath()).when(dirProvider).getDbDir(); + doReturn(tempPath).when(dirProvider).getDbDir(); int snapshotBlockHeight = 8000; @@ -424,9 +436,9 @@ private static PropertiesHolder initPropertyHolder() { } - private Path createPath(String fileName) { + private Path createTempPath() { try { - return temporaryFolderExtension.newFolder().toPath().resolve(fileName); + return temporaryFolderExtension.newFolder().toPath(); } catch (IOException e) { throw new RuntimeException(e.toString(), e); } diff --git a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/shard/hash/ShardHashCalculatorImplTest.java b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/shard/hash/ShardHashCalculatorImplTest.java index 386b0c0268..5e0e783a44 100644 --- a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/shard/hash/ShardHashCalculatorImplTest.java +++ b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/shard/hash/ShardHashCalculatorImplTest.java @@ -4,8 +4,10 @@ package com.apollocurrency.aplwallet.apl.core.shard.hash; +import com.apollocurrency.aplwallet.apl.core.config.TimeConfig; import com.apollocurrency.aplwallet.apl.core.model.Block; import com.apollocurrency.aplwallet.apl.core.model.BlockImpl; +import com.apollocurrency.aplwallet.apl.core.service.appdata.TimeService; import com.apollocurrency.aplwallet.apl.core.service.blockchain.TransactionBuilderFactory; import com.apollocurrency.aplwallet.apl.core.chainid.BlockchainConfig; import com.apollocurrency.aplwallet.apl.core.chainid.HeightConfig; @@ -86,6 +88,8 @@ public class ShardHashCalculatorImplTest extends DbContainerBaseTest { @RegisterExtension static DbExtension dbExtension = new DbExtension(mariaDBContainer); BlockchainConfig blockchainConfig = mock(BlockchainConfig.class); + TimeConfig config = new TimeConfig(false); + TimeService timeService = new TimeServiceImpl(config.timeSource()); Chain chain = mock(Chain.class); PropertiesHolder propertiesHolder = mock(PropertiesHolder.class); HeightConfig heightConfig = mock(HeightConfig.class); @@ -101,7 +105,7 @@ public class ShardHashCalculatorImplTest extends DbContainerBaseTest { WeldInitiator weldInitiator = WeldInitiator.from(BlockchainImpl.class, ShardHashCalculatorImpl.class, BlockImpl.class, BlockDaoImpl.class, BlockEntityRowMapper.class, BlockEntityToModelConverter.class, BlockModelToEntityConverter.class, - DerivedDbTablesRegistryImpl.class, TimeServiceImpl.class, GlobalSyncImpl.class, TransactionDaoImpl.class, + DerivedDbTablesRegistryImpl.class, GlobalSyncImpl.class, TransactionDaoImpl.class, DaoConfig.class, TransactionServiceImpl.class, ShardDbExplorerImpl.class, TransactionEntityRowMapper.class, TransactionEntityRowMapper.class, TxReceiptRowMapper.class, PrunableTxRowMapper.class, @@ -122,6 +126,8 @@ public class ShardHashCalculatorImplTest extends DbContainerBaseTest { .addBeans(MockBean.of(mock(PrunableLoadingService.class), PrunableLoadingService.class)) .addBeans(MockBean.of(ttd.getTransactionTypeFactory(), TransactionTypeFactory.class)) .addBeans(MockBean.of(publicKeyDao, PublicKeyDao.class)) + .addBeans(MockBean.of(config, TimeConfig.class)) + .addBeans(MockBean.of(timeService, TimeService.class)) .build(); @Inject diff --git a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/shard/helper/CsvWriterReaderDerivedTablesTest.java b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/shard/helper/CsvWriterReaderDerivedTablesTest.java index 80128cd4f5..b89a742270 100644 --- a/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/shard/helper/CsvWriterReaderDerivedTablesTest.java +++ b/apl-core/src/test/java/com/apollocurrency/aplwallet/apl/core/shard/helper/CsvWriterReaderDerivedTablesTest.java @@ -236,8 +236,7 @@ class CsvWriterReaderDerivedTablesTest extends DbContainerBaseTest { .addBeans(MockBean.of(mock(BlockIndexService.class), BlockIndexService.class, BlockIndexServiceImpl.class)) .addBeans(MockBean.of(mock(AccountControlPhasingService.class), AccountControlPhasingService.class)) .addBeans(MockBean.of(propertiesHolder, PropertiesHolder.class)) - .addBeans(MockBean.of(timeService, TimeConfig.class)) - .addBeans(MockBean.of(timeService, TimeService.class)) + .addBeans(MockBean.of(config, TimeConfig.class)) .addBeans(MockBean.of(timeService, TimeService.class)) .addBeans(MockBean.of(peersService, PeersService.class)) .addBeans(MockBean.of(generatorService, GeneratorService.class)) diff --git a/apl-core/src/test/resources/db/phasing-poll-data.sql b/apl-core/src/test/resources/db/phasing-poll-data.sql index f173ce15a5..d0b33f1c4f 100644 --- a/apl-core/src/test/resources/db/phasing-poll-data.sql +++ b/apl-core/src/test/resources/db/phasing-poll-data.sql @@ -1,4 +1,7 @@ TRUNCATE TABLE transaction; +-- Clean txs metadata to not interfere with real transactions in this script from previosly launched tests +TRUNCATE TABLE transaction_shard_index; +TRUNCATE TABLE block_index; TRUNCATE TABLE block; TRUNCATE TABLE phasing_poll; TRUNCATE TABLE phasing_poll_result; @@ -6,6 +9,7 @@ TRUNCATE TABLE phasing_poll_voter; TRUNCATE TABLE phasing_vote; TRUNCATE TABLE phasing_poll_linked_transaction; TRUNCATE TABLE phasing_approval_tx; +TRUNCATE TABLE transaction_shard_index; INSERT INTO block (DB_ID, ID, HEIGHT, VERSION, `TIMESTAMP`, PREVIOUS_BLOCK_ID, TOTAL_AMOUNT, TOTAL_FEE, PAYLOAD_LENGTH, PREVIOUS_BLOCK_HASH, CUMULATIVE_DIFFICULTY, BASE_TARGET, NEXT_BLOCK_ID, GENERATION_SIGNATURE, BLOCK_SIGNATURE, PAYLOAD_HASH, GENERATOR_ID, TIMEOUT) VALUES diff --git a/apl-core/src/test/resources/db/shard/shard-creation-data.sql b/apl-core/src/test/resources/db/shard/shard-creation-data.sql index 902f2c9186..bf9dedb85d 100644 --- a/apl-core/src/test/resources/db/shard/shard-creation-data.sql +++ b/apl-core/src/test/resources/db/shard/shard-creation-data.sql @@ -465,17 +465,17 @@ INSERT into `trim` INSERT INTO prunable_message (db_id ,id ,sender_id , recipient_id ,message , encrypted_message ,message_is_text , encrypted_is_text , is_compressed, block_timestamp, transaction_timestamp, height) VALUES -(1000 ,10 ,-6004096130734886685 ,4882266200596627944 ,null ,X'b63f809f0df0b52f46225b702855c2704653e88ae96cd3dfe2c50cf2e30f747907cbb06267616241aa3aa55c2bf90457b1f275e9c96d42c7cc73cdb229a4fed055ad55245c89348c0d05c757e771996d8d597125aabb471bb25cd2d6e524f1bb9811c40f8259eff2cadf1f48df5c06f3' ,false , true , true , 128 , 120 , 10 ), -(1010 ,20 ,4882266200596627944 ,-6004096130734886685 ,X'48692c20416c69636521' ,X'7ac5c6571b768208df62ee48d3e9c8151abeb0f11858c66d01bdf0b8170b0741b596da28500094b25ed0bb981a41f4dfe489128c4013638d5c8eb143946b6af77b64da893560374409866b0db539ff456bbe56de583181db3ac90d67ee6f16bc0be3faa400e03ef25616b45789fde2ab' ,true , true , true , 140 , 130 , 12 ), -(1020 ,30 ,-6004096130734886685 ,4882266200596627944 ,X'476f6f646279652c20426f6221' ,X'dd39282b7262b9369773b68a851491bbecac1f9b7a6ec078381962b129872c2df5ee11b489ef1733e78c6c54fb6fbcf992071fdb83c4e40f501b8101af76dae9c61c3726d86490c43955644a64aa004d4fa45184e37060247a9a535acdc638ac' ,true , true , false ,158 , 155 , 14 ), -(1030 ,40 ,4882266200596627944 ,-6004096130734886685 ,X'ff3456236527fdab' ,X'dae6440045c8d5bf5c561d5ed9209898654038bb375875e5a50bf0d7bb44bdcaf4c074354638aa0fe97d70d4cb00a6d62c119703b75f63d40a29190feb85ba54d9e8e433e07bfcea5923e0ff59a0e8fd3c9bdd7bcd76a08eb5bcec871c65d06f' ,false , true , false ,160 , 157 , 15 ), -(1040 ,50 ,-6004096130734886685 ,-6004096130734886685 ,null ,X'7f39dde4494bdd8036799dc04d2e7967c3cc40af2fd3a0bd40e5113076713b9f2aa6895b6f848bfafce0fc085c991d0f0883ef75fe8b75e3bcf9308d4de27837958436fb572cf954a3dff1523908d4d09ff85558cb2bcd6ac2bba4967c4ae9c6fca25f4f8313b53b3aec308e02e3f758' ,false , true , true ,180 , 168 , 18 ), -(1050 ,60 ,-5872452783836294400 ,-6004096130734886685 ,X'54657374206d65737361676520746f20416c696365' ,null ,true , false , false ,185 , 178 , 19 ), -(1060 ,70 ,4882266200596627944 ,4882266200596627944 ,null ,X'a8d8a1784144872e909f5c5c0eb75ea01fc45a3a0aba2f04bbe8bc29414ab1d82c617d184baf26d4dab5f6e584326eb7a69649d70906cbae8a8633c59b5357b5f19ab6a1bcc94939b33723c192c734f62886a8ad860d8bcd23398545d04776d33401adbdf1f4b72d669388ade4cc759c' ,false , true , true ,211 , 214 , 22 ), -(1070 ,80 ,-5872452783836294400 ,-6004096130734886685 ,null ,X'11c48e4daac8e8582c9b83715366a0a0b4a7b7ae048d0ad115d22ae973c9c9e255fbb70f1b17168f6d15d877fa4dfd9017c8aedc9211e4576e434fb4b7102776777164f79368343936dd87f65dd58b24f61b075973c7b7c5947e5020bc835baf' ,false , true , false ,212 , 225 , 23 ), -(1080 ,90 ,-5872452783836294400 ,4882266200596627944 ,X'f3ab4384a18c2911' ,X'8de2b1bb43fc8f8ed866f551edae2f688494da7601b914fbc69f2c9c406f537845eab9a324a151d432d82a0e9d989467b1ff559a947fe8a5d0c9fe7bf0e6d0a44504273ff6b92b419abf752401b785157eb320f78e6ac13f75036a799ea47a4c' ,false , false , false ,232 , 230 , 25 ), -(1090 ,100 ,4882266200596627944 ,-5872452783836294400 ,null ,X'a1e59a83f92fe32e2e8bd4d840adca3af792e65499ae3d87068c793daf7f7d238c9c0820c951a9280d78e492eb27fb5961a974d98f63756728cb7a22d658dabbc0c6bf192eea4f41d950cff9f51c12f03f2f853cd9ead88f3c88ebbdb1ae0423dad64b3d2c0801fc1780b41c84fc330e' ,false , false , true ,247 , 242 , 28 ), -(1100 ,110 ,-6004096130734886685 ,-5872452783836294400 ,X'48656c6c6f20436875636b' ,null ,true , false , false ,259 , 254 , 30 ) +(1000 ,10 ,-6004096130734886685 ,4882266200596627944 ,null ,X'b63f809f0df0b52f46225b702855c2704653e88ae96cd3dfe2c50cf2e30f747907cbb06267616241aa3aa55c2bf90457b1f275e9c96d42c7cc73cdb229a4fed055ad55245c89348c0d05c757e771996d8d597125aabb471bb25cd2d6e524f1bb9811c40f8259eff2cadf1f48df5c06f3' ,false , true , true , 128 , UNIX_TIMESTAMP(), 541839 ), +(1010 ,20 ,4882266200596627944 ,-6004096130734886685 ,X'48692c20416c69636521' ,X'7ac5c6571b768208df62ee48d3e9c8151abeb0f11858c66d01bdf0b8170b0741b596da28500094b25ed0bb981a41f4dfe489128c4013638d5c8eb143946b6af77b64da893560374409866b0db539ff456bbe56de583181db3ac90d67ee6f16bc0be3faa400e03ef25616b45789fde2ab' ,true , true , true , 140 , UNIX_TIMESTAMP(), 541859 ), +(1020 ,30 ,-6004096130734886685 ,4882266200596627944 ,X'476f6f646279652c20426f6221' ,X'dd39282b7262b9369773b68a851491bbecac1f9b7a6ec078381962b129872c2df5ee11b489ef1733e78c6c54fb6fbcf992071fdb83c4e40f501b8101af76dae9c61c3726d86490c43955644a64aa004d4fa45184e37060247a9a535acdc638ac' ,true , true , false ,158 , UNIX_TIMESTAMP(), 541869 ), +(1030 ,40 ,4882266200596627944 ,-6004096130734886685 ,X'ff3456236527fdab' ,X'dae6440045c8d5bf5c561d5ed9209898654038bb375875e5a50bf0d7bb44bdcaf4c074354638aa0fe97d70d4cb00a6d62c119703b75f63d40a29190feb85ba54d9e8e433e07bfcea5923e0ff59a0e8fd3c9bdd7bcd76a08eb5bcec871c65d06f' ,false , true , false ,160 , UNIX_TIMESTAMP(), 541879 ), +(1040 ,50 ,-6004096130734886685 ,-6004096130734886685 ,null ,X'7f39dde4494bdd8036799dc04d2e7967c3cc40af2fd3a0bd40e5113076713b9f2aa6895b6f848bfafce0fc085c991d0f0883ef75fe8b75e3bcf9308d4de27837958436fb572cf954a3dff1523908d4d09ff85558cb2bcd6ac2bba4967c4ae9c6fca25f4f8313b53b3aec308e02e3f758' ,false , true , true ,180 , UNIX_TIMESTAMP(), 541889 ), +(1050 ,60 ,-5872452783836294400 ,-6004096130734886685 ,X'54657374206d65737361676520746f20416c696365' ,null ,true , false , false ,185 , UNIX_TIMESTAMP(), 541899 ), +(1060 ,70 ,4882266200596627944 ,4882266200596627944 ,null ,X'a8d8a1784144872e909f5c5c0eb75ea01fc45a3a0aba2f04bbe8bc29414ab1d82c617d184baf26d4dab5f6e584326eb7a69649d70906cbae8a8633c59b5357b5f19ab6a1bcc94939b33723c192c734f62886a8ad860d8bcd23398545d04776d33401adbdf1f4b72d669388ade4cc759c' ,false , true , true ,211 , UNIX_TIMESTAMP(), 541939 ), +(1070 ,80 ,-5872452783836294400 ,-6004096130734886685 ,null ,X'11c48e4daac8e8582c9b83715366a0a0b4a7b7ae048d0ad115d22ae973c9c9e255fbb70f1b17168f6d15d877fa4dfd9017c8aedc9211e4576e434fb4b7102776777164f79368343936dd87f65dd58b24f61b075973c7b7c5947e5020bc835baf' ,false , true , false ,212 , UNIX_TIMESTAMP(), 541949 ), +(1080 ,90 ,-5872452783836294400 ,4882266200596627944 ,X'f3ab4384a18c2911' ,X'8de2b1bb43fc8f8ed866f551edae2f688494da7601b914fbc69f2c9c406f537845eab9a324a151d432d82a0e9d989467b1ff559a947fe8a5d0c9fe7bf0e6d0a44504273ff6b92b419abf752401b785157eb320f78e6ac13f75036a799ea47a4c' ,false , false , false ,232 , UNIX_TIMESTAMP(), 541959 ), +(1090 ,100 ,4882266200596627944 ,-5872452783836294400 ,null ,X'a1e59a83f92fe32e2e8bd4d840adca3af792e65499ae3d87068c793daf7f7d238c9c0820c951a9280d78e492eb27fb5961a974d98f63756728cb7a22d658dabbc0c6bf192eea4f41d950cff9f51c12f03f2f853cd9ead88f3c88ebbdb1ae0423dad64b3d2c0801fc1780b41c84fc330e' ,false , false , true ,247 , UNIX_TIMESTAMP(), 541969 ), +(1100 ,110 ,-6004096130734886685 ,-5872452783836294400 ,X'48656c6c6f20436875636b' ,null ,true , false , false ,259 , UNIX_TIMESTAMP(), 541979 ) ; INSERT INTO phasing_approval_tx (db_id , phasing_tx, approved_tx, height ) VALUES diff --git a/apl-db-updater/pom.xml b/apl-db-updater/pom.xml index 0f9449eefa..b9e9309a50 100644 --- a/apl-db-updater/pom.xml +++ b/apl-db-updater/pom.xml @@ -23,6 +23,18 @@ + + org.flywaydb + flyway-mysql + + + com.h2database + h2 + + + org.mariadb.jdbc + mariadb-java-client + org.slf4j @@ -38,6 +50,16 @@ weld-junit5 test + + org.testcontainers + mariadb + test + + + org.testcontainers + junit-jupiter + test + diff --git a/apl-db-updater/src/main/resources/db/migration/mariadb/shard/V1_1__Add_constraints.sql b/apl-db-updater/src/main/resources/db/migration/mariadb/shard/V1_1__Add_constraints.sql index 5778f0a35a..45b27bbbca 100644 --- a/apl-db-updater/src/main/resources/db/migration/mariadb/shard/V1_1__Add_constraints.sql +++ b/apl-db-updater/src/main/resources/db/migration/mariadb/shard/V1_1__Add_constraints.sql @@ -5,7 +5,7 @@ ALTER TABLE `block` ADD CONSTRAINT primary_key_block_id PRIMARY KEY (`id`); ALTER TABLE `block` - ADD CONSTRAINT block_timestamp_idx unique (`TIMESTAMP` DESC); + ADD CONSTRAINT block_timestamp_idx unique (`TIMESTAMP`/* DESC*/); -- DESC is NOT permitted by RocksDb engine now ALTER TABLE `block` ADD CONSTRAINT block_height_idx unique (`height`); @@ -28,7 +28,7 @@ CREATE INDEX IF NOT EXISTS transaction_sender_id_idx ON `transaction` (`sender_i CREATE INDEX IF NOT EXISTS transaction_recipient_id_idx ON `transaction` (`recipient_id`); -CREATE INDEX IF NOT EXISTS transaction_block_timestamp_idx ON `transaction` (`block_timestamp` DESC); +CREATE INDEX IF NOT EXISTS transaction_block_timestamp_idx ON `transaction` (`block_timestamp`/* DESC*/); -- DESC is NOT permitted by RocksDb engine now ALTER TABLE `transaction` DROP CONSTRAINT IF EXISTS transaction_id_idx; diff --git a/apl-exec/src/main/java/com/apollocurrency/aplwallet/apl/exec/Apollo.java b/apl-exec/src/main/java/com/apollocurrency/aplwallet/apl/exec/Apollo.java index 9645f1cfec..d534cac448 100644 --- a/apl-exec/src/main/java/com/apollocurrency/aplwallet/apl/exec/Apollo.java +++ b/apl-exec/src/main/java/com/apollocurrency/aplwallet/apl/exec/Apollo.java @@ -5,12 +5,11 @@ import ch.qos.logback.classic.Level; import ch.qos.logback.classic.LoggerContext; -import com.apollocurrency.aplwallet.apl.conf.ConfPlaceholder; +import com.apollocurrency.aplwallet.apl.conf.ConfigVerifier; import com.apollocurrency.aplwallet.apl.core.app.AplCoreRuntime; import com.apollocurrency.aplwallet.apl.core.chainid.BlockchainConfig; import com.apollocurrency.aplwallet.apl.core.chainid.BlockchainConfigUpdater; import com.apollocurrency.aplwallet.apl.core.service.appdata.SecureStorageService; -import com.apollocurrency.aplwallet.apl.core.utils.LegacyDbUtil; import com.apollocurrency.aplwallet.apl.udpater.intfce.UpdaterCore; import com.apollocurrency.aplwallet.apl.updater.core.UpdaterCoreImpl; import com.apollocurrency.aplwallet.apl.util.Constants; @@ -40,6 +39,7 @@ import jakarta.enterprise.inject.spi.CDI; import java.io.File; import java.io.FileNotFoundException; +import java.io.IOException; import java.io.PrintWriter; import java.nio.file.Path; import java.nio.file.Paths; @@ -78,6 +78,8 @@ public class Apollo { private static AplContainer container; private static AplCoreRuntime aplCoreRuntime; + private static ConfigVerifier configVerifier; + private static void setLogLevel(int logLevel) { // let's SET LEVEL EXPLOCITLY only when it was passed via command line params String packageName = "com.apollocurrency.aplwallet.apl"; @@ -130,18 +132,50 @@ public static boolean saveStartParams(String[] argv, String pidPath, ConfigDirPr return res; } - public static PredefinedDirLocations merge(CmdLineArgs args, EnvironmentVariables vars, CustomDirLocations customDirLocations) { - return new PredefinedDirLocations( - customDirLocations.getDbDir().isEmpty() ? StringUtils.isBlank(args.dbDir) ? vars.dbDir : args.dbDir : customDirLocations.getDbDir().get(), - StringUtils.isBlank(args.logDir) ? vars.logDir : args.logDir, - customDirLocations.getKeystoreDir().isEmpty() ? StringUtils.isBlank(args.vaultKeystoreDir) ? vars.vaultKeystoreDir : args.vaultKeystoreDir : customDirLocations.getKeystoreDir().get(), - StringUtils.isBlank(args.pidFile) ? vars.pidFile : args.pidFile, - StringUtils.isBlank(args.twoFactorAuthDir) ? vars.twoFactorAuthDir : args.twoFactorAuthDir, - StringUtils.isBlank(args.dataExportDir) ? vars.dataExportDir : args.dataExportDir, - StringUtils.isBlank(args.dexKeystoreDir) ? vars.dexKeystoreDir : args.dexKeystoreDir - ); +/** + * Merge command line arguments environment variables and properties from config files + * into one set of properties. Precedence: command line, environment vars, configs. + * It means that command line can overwrite env vars and configs + * @param args parsed command line arguments + * @param vars parsed environment variables + * @param props parsed application config files + * @return properties, reqady to use in the application + */ + public static Properties merge(CmdLineArgs args, EnvironmentVariables vars, Properties props){ + + //{"--log-dir", "-l"} + String logDir = StringUtils.byPrecedence(args.logDir, vars.logDir, props.getProperty("apl.customLogDir")); + props.setProperty("apl.customLogDir",logDir); + //{"--db-dir"} + String dbDir = StringUtils.byPrecedence(args.dbDir, vars.dbDir, props.getProperty("apl.customDbDir")); + props.setProperty("apl.customDbDir", dbDir); + // {"--vault-key-dir"} + String vaultKeystoreDir = StringUtils.byPrecedence(args.vaultKeystoreDir, vars.vaultKeystoreDir, props.getProperty("apl.customVaultKeystoreDir")); + props.setProperty("apl.customVaultKeystoreDir", vaultKeystoreDir); + // {"--dex-key-dir"} + String dexKeystoreDir = StringUtils.byPrecedence(args.dexKeystoreDir, vars.dexKeystoreDir, props.getProperty("apl.customDexStorageDir")); + props.setProperty("apl.customDexStorageDir", dexKeystoreDir); + // {"--no-shard-import"} + String nsi = args.noShardImport ? "": String.valueOf(args.noShardImport); + String noShardImport = StringUtils.byPrecedence(nsi, props.getProperty("apl.noshardimport")); + props.setProperty("apl.noshardimport",noShardImport); + // {"--no-shard-create"} + String nsc = args.noShardCreate ? "": String.valueOf(args.noShardCreate); + String noShardCreate = StringUtils.byPrecedence(nsc, props.getProperty("apl.noshardcreate")); + props.setProperty("apl.noshardcreate",noShardCreate); + // {"--2fa-dir"} + String twoFactorAuthDir = StringUtils.byPrecedence(args.twoFactorAuthDir,vars.twoFactorAuthDir, props.getProperty("apl.dir2FA")); + props.setProperty("apl.dir2FA",twoFactorAuthDir); + // {"--dexp-dir"} + String dataExportDir = StringUtils.byPrecedence(args.dataExportDir, vars.dataExportDir, props.getProperty("apl.customDataExportDir")); + props.setProperty("apl.customDataExportDir",dataExportDir); + // {"--pid-file"} + String pidFile = StringUtils.byPrecedence(args.pidFile, vars.pidFile, props.getProperty("apl.customPidFile")); + props.getProperty("apl.customPidFile", pidFile); + return props; } + //TODO: check this piece of art public static void setSystemProperties(CmdLineArgs args){ System.setProperty("apl.runtime.mode", args.serviceMode ? "service" : "user"); System.setProperty("javax.net.ssl.trustStore", "cacerts"); @@ -149,17 +183,6 @@ public static void setSystemProperties(CmdLineArgs args){ System.setProperty("javax.net.ssl.trustStoreType", "JKS"); } - private static String getCustomDbPath(UUID chainId, Properties properties) { //maybe better to set dbUrl or add to dirProvider - String customDbDir = properties.getProperty(CustomDirLocations.DB_DIR_PROPERTY_NAME); - if (customDbDir != null) { - Path legacyHomeDir = LegacyDbUtil.getLegacyHomeDir(); - Path customDbPath = legacyHomeDir.resolve(customDbDir).resolve(chainId.toString().substring(0, 6)).normalize(); - System.out.println("Using custom db path " + customDbPath.toAbsolutePath().toString()); - return customDbPath.toAbsolutePath().toString(); - } - return null; - } - private void initUpdater(String attachmentFilePath, boolean debug, PropertiesHolder propertiesHolder) { if (!propertiesHolder.getBooleanProperty("apl.allowUpdates", false)) { return; @@ -204,8 +227,6 @@ public static void main(String[] argv) { RuntimeEnvironment.getInstance().setMain(Apollo.class); //set some important system properties setSystemProperties(args); -//cheat classloader to get access to "conf" package resources - ConfPlaceholder ph = new ConfPlaceholder(); //--------------- config locating section ------------------------------------- @@ -239,6 +260,15 @@ public static void main(String[] argv) { // is collected from configs, command line and environment variables Properties applicationProperties = propertiesLoader.load(); + try { + //verify and complete configuration + configVerifier = ConfigVerifier.create(configDirProvider.getConfigName() + File.separator + "apl-blockchain.properties"); + applicationProperties = configVerifier.parse(applicationProperties, Constants.VERSION); + } catch (IOException ex) { + System.err.println("WARNING! Can not verify config because can not read/parse default config from resources!"); + } + + ChainsConfigLoader chainsConfigLoader = new ChainsConfigLoader( configDirProvider, configDir, @@ -249,25 +279,12 @@ public static void main(String[] argv) { Map chains = chainsConfigLoader.load(); UUID chainId = ChainUtils.getActiveChain(chains).getChainId(); -//over-write config options from command line if set - - if (args.noShardImport) { - applicationProperties.setProperty("apl.noshardimport", "" + args.noShardImport); - } - if (args.noShardCreate) { - applicationProperties.setProperty("apl.noshardcreate", "" + args.noShardCreate); - } -//TODO: check this piece of art - CustomDirLocations customDirLocations = new CustomDirLocations( - getCustomDbPath(chainId, applicationProperties), - applicationProperties.getProperty(CustomDirLocations.KEYSTORE_DIR_PROPERTY_NAME) - ); + DirProviderFactory.setup( args.serviceMode, + chainId, + Constants.APPLICATION_DIR_NAME, + new PredefinedDirLocations(merge(args,envVars,applicationProperties)) + ); - DirProviderFactory.setup(args.serviceMode, - chainId, - Constants.APPLICATION_DIR_NAME, - merge(args, envVars, customDirLocations) - ); dirProvider = DirProviderFactory.getProvider(); RuntimeEnvironment.getInstance().setDirProvider(dirProvider); diff --git a/apl-exec/src/main/java/com/apollocurrency/aplwallet/apl/exec/CustomDirLocations.java b/apl-exec/src/main/java/com/apollocurrency/aplwallet/apl/exec/CustomDirLocations.java deleted file mode 100644 index 715a4a4203..0000000000 --- a/apl-exec/src/main/java/com/apollocurrency/aplwallet/apl/exec/CustomDirLocations.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright © 2018-2019 Apollo Foundation - */ - -package com.apollocurrency.aplwallet.apl.exec; - -import java.util.Objects; -import java.util.Optional; -import java.util.Properties; - -public class CustomDirLocations { - public static final String DB_DIR_PROPERTY_NAME = "apl.customDbDir"; - public static final String KEYSTORE_DIR_PROPERTY_NAME = "apl.customVaultKeystoreDir"; - private String dbDir; - private String keystoreDir; - - public CustomDirLocations(String dbDir, String keystoreDir) { - this.dbDir = dbDir; - this.keystoreDir = keystoreDir; - } - - public CustomDirLocations(Properties properties) { - Objects.requireNonNull(properties, "Properties should not be null"); - this.dbDir = properties.getProperty(DB_DIR_PROPERTY_NAME); - this.keystoreDir = properties.getProperty(KEYSTORE_DIR_PROPERTY_NAME); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof CustomDirLocations)) return false; - CustomDirLocations that = (CustomDirLocations) o; - return Objects.equals(dbDir, that.dbDir) && - Objects.equals(keystoreDir, that.keystoreDir); - } - - @Override - public int hashCode() { - return Objects.hash(dbDir, keystoreDir); - } - - public Optional getDbDir() { - return Optional.ofNullable(dbDir); - } - - public void setDbDir(String dbDir) { - this.dbDir = dbDir; - } - - public Optional getKeystoreDir() { - return Optional.ofNullable(keystoreDir); - } - - public void setKeystoreDir(String keystoreDir) { - this.keystoreDir = keystoreDir; - } -} diff --git a/apl-utils/src/main/java/com/apollocurrency/aplwallet/apl/util/StringUtils.java b/apl-utils/src/main/java/com/apollocurrency/aplwallet/apl/util/StringUtils.java index 757dcc06cb..9ff59d4323 100644 --- a/apl-utils/src/main/java/com/apollocurrency/aplwallet/apl/util/StringUtils.java +++ b/apl-utils/src/main/java/com/apollocurrency/aplwallet/apl/util/StringUtils.java @@ -32,4 +32,21 @@ public static boolean equalsIgnoreCase(String str, List l) { } return false; } + + /** + * Takes first not-empty value and ignores the rest of values + * @param values strings or nulls + * @return first not-empty value + */ + public static String byPrecedence(String ...values){ + String res =""; + String[] va = values; + for (int i = 0; iapl-db-updater apl-dex apl-vault-wallet - apl-smc + apl-smc @@ -163,9 +163,21 @@ maven-compiler-plugin ${compile-plugin.version} - ${java.version} - ${java.version} + ${maven.compiler.source} + ${maven.compiler.target} true + + + --add-exports + --add-opens + java.base/sun.security.x509=ALL-UNNAMED + java.base/sun.security.pkcs=ALL-UNNAMED + java.base/sun.security.provider=ALL-UNNAMED + java.base/sun.security.util=ALL-UNNAMED + java.base/jdk.internal.misc=ALL-UNNAMED + security.util=ALL-UNNAMED + + false @@ -221,6 +233,15 @@ org.apache.maven.plugins maven-compiler-plugin + + + + --add-exports + + + java.base/sun.security.x509=ALL-UNNAMED + + false