diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 62cf2c72e..78bc49fcc 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -155,4 +155,4 @@ jobs: key: ${{ env.cache-name }}-${{ hashFiles('pom.xml') }} restore-keys: ${{ env.cache-name }}- - name: Build - run: mvn dependency:go-offline install -Dmaven.javadoc.skip=true -DuseClioTestnet \ No newline at end of file + run: mvn dependency:go-offline install -Dmaven.javadoc.skip=true -DuseClioTestnet -DuseClioMainnet \ No newline at end of file diff --git a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/AccountTransactionsIT.java b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/AccountTransactionsIT.java index bc61fe9d9..6a17cc734 100644 --- a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/AccountTransactionsIT.java +++ b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/AccountTransactionsIT.java @@ -42,11 +42,8 @@ import org.xrpl.xrpl4j.model.client.ledger.LedgerResult; import org.xrpl.xrpl4j.model.transactions.Address; import org.xrpl.xrpl4j.model.transactions.Hash256; -import org.xrpl.xrpl4j.tests.environment.MainnetEnvironment; - -import java.util.HashSet; -import java.util.Optional; -import java.util.Set; +import org.xrpl.xrpl4j.tests.environment.ReportingMainnetEnvironment; +import org.xrpl.xrpl4j.tests.environment.XrplEnvironment; /** * An Integration Test to validate submission of Account transactions. @@ -58,7 +55,7 @@ public class AccountTransactionsIT { // an arbitrary address on xrpl mainnet that has a decent amount of transaction history public static final Address MAINNET_ADDRESS = Address.of("r9m6MwViR4GnUNqoGXGa8eroBrZ9FAPHFS"); - private final XrplClient mainnetClient = new MainnetEnvironment().getXrplClient(); + private final XrplClient mainnetClient = XrplEnvironment.getConfiguredMainnetEnvironment().getXrplClient(); @Test public void listTransactionsDefaultWithPagination() throws JsonRpcClientErrorException { @@ -69,6 +66,13 @@ public void listTransactionsDefaultWithPagination() throws JsonRpcClientErrorExc assertThat(results.marker()).isNotEmpty(); } + /** + * This test will fail if we hit a Clio node until CLIO-687 is deployed + * to mainnet. We expect 748 transactions across all pages of account_tx, however Clio duplicates the last + * transaction from each page in the next page, which results in more than 748 transactions returned. + * + * @throws JsonRpcClientErrorException If rippled/Clio returns an error or a request fails. + */ @Test @Timeout(30) public void listTransactionsPagination() throws JsonRpcClientErrorException { @@ -76,8 +80,6 @@ public void listTransactionsPagination() throws JsonRpcClientErrorException { // known ledger index range for this account that is known to have exactly 748 transactions LedgerIndexBound minLedger = LedgerIndexBound.of(61400000); LedgerIndexBound maxLedger = LedgerIndexBound.of(61487000); - Set transactionHashes = new HashSet<>(); - AccountTransactionsResult results = mainnetClient.accountTransactions( AccountTransactionsRequestParams.builder(minLedger, maxLedger) .account(MAINNET_ADDRESS) @@ -85,8 +87,8 @@ public void listTransactionsPagination() throws JsonRpcClientErrorException { ); assertThat(results.transactions()).isNotEmpty(); assertThat(results.marker()).isNotEmpty(); - results.transactions().forEach(transaction -> transactionHashes.add(transaction.resultTransaction().hash())); + int transactionsFound = results.transactions().size(); int pages = 0; while (results.marker().isPresent() && // Needed because clio is broken. See https://github.com/XRPLF/clio/issues/195#issuecomment-1247412892 @@ -94,19 +96,19 @@ public void listTransactionsPagination() throws JsonRpcClientErrorException { ) { results = mainnetClient.accountTransactions(AccountTransactionsRequestParams.builder(minLedger, maxLedger) .account(MAINNET_ADDRESS) - .limit(UnsignedInteger.valueOf(100L)) + .limit(UnsignedInteger.valueOf(200L)) .marker(results.marker().get()) .build()); - results.transactions().forEach(transaction -> transactionHashes.add(transaction.resultTransaction().hash())); + transactionsFound += results.transactions().size(); pages++; - logger.info("Retrieved {} transaction (marker={} page={})", - transactionHashes.size(), + logger.info("Retrieved {} ledgers (marker={} page={})", + transactionsFound, results.marker().map($ -> $.value()).orElseGet(() -> "n/a"), pages ); } - assertThat(transactionHashes.size()).isEqualTo(expectedTransactions); + assertThat(transactionsFound).isEqualTo(expectedTransactions); } @Test diff --git a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/environment/ClioMainnetEnvironment.java b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/environment/ClioMainnetEnvironment.java new file mode 100644 index 000000000..1404d1e92 --- /dev/null +++ b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/environment/ClioMainnetEnvironment.java @@ -0,0 +1,40 @@ +package org.xrpl.xrpl4j.tests.environment; + +/*- + * ========================LICENSE_START================================= + * xrpl4j :: integration-tests + * %% + * Copyright (C) 2020 - 2022 XRPL Foundation and its contributors + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ + +import okhttp3.HttpUrl; +import org.xrpl.xrpl4j.client.XrplClient; +import org.xrpl.xrpl4j.model.transactions.Address; + +/** + * XRPL mainnet environment that uses a Clio node. Integration tests can be run against a reporting mode mainnet + * node by using the {@link ReportingMainnetEnvironment}. + */ +public class ClioMainnetEnvironment extends MainnetEnvironment { + + private final XrplClient xrplClient = new XrplClient(HttpUrl.parse("https://s2-clio.ripple.com:51234")); + + @Override + public XrplClient getXrplClient() { + return xrplClient; + } + +} diff --git a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/environment/MainnetEnvironment.java b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/environment/MainnetEnvironment.java index 5650ac58e..58154f2b7 100644 --- a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/environment/MainnetEnvironment.java +++ b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/environment/MainnetEnvironment.java @@ -1,46 +1,12 @@ package org.xrpl.xrpl4j.tests.environment; -/*- - * ========================LICENSE_START================================= - * xrpl4j :: integration-tests - * %% - * Copyright (C) 2020 - 2022 XRPL Foundation and its contributors - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ - -import okhttp3.HttpUrl; import org.xrpl.xrpl4j.client.XrplClient; import org.xrpl.xrpl4j.model.transactions.Address; -/** - * XRPL mainnet environment. - */ -public class MainnetEnvironment implements XrplEnvironment { - - // FIXME: At the time of writing this, Clio is powering some traffic to s1 and s2. Clio behaves differently - // than reporting mode servers/rippled p2p servers in responses to account_tx RPC calls with - // "ledger_index" = "validated", which breaks AccountTransactionsIT. xrplcluster.com is not powered by Clio, so - // this client is pointed at xrplcluster.com. However, once this bug in Clio is resolved, we should revert back to - // using s1/s2 here. - // See this github issue: https://github.com/XRPLF/clio/pull/694 - private final XrplClient xrplClient = new XrplClient(HttpUrl.parse("https://xrplcluster.com")); +public abstract class MainnetEnvironment implements XrplEnvironment { @Override - public XrplClient getXrplClient() { - return xrplClient; - } + public abstract XrplClient getXrplClient(); @Override public void fundAccount(Address classicAddress) { diff --git a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/environment/ReportingMainnetEnvironment.java b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/environment/ReportingMainnetEnvironment.java new file mode 100644 index 000000000..3445b63bc --- /dev/null +++ b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/environment/ReportingMainnetEnvironment.java @@ -0,0 +1,40 @@ +package org.xrpl.xrpl4j.tests.environment; + +/*- + * ========================LICENSE_START================================= + * xrpl4j :: integration-tests + * %% + * Copyright (C) 2020 - 2022 XRPL Foundation and its contributors + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ + +import okhttp3.HttpUrl; +import org.xrpl.xrpl4j.client.XrplClient; +import org.xrpl.xrpl4j.model.transactions.Address; + +/** + * XRPL mainnet environment that uses a reporting mode only node. Integration tests can be run against a Clio mainnet + * node by using the {@link ClioMainnetEnvironment}. + */ +public class ReportingMainnetEnvironment extends MainnetEnvironment { + + private final XrplClient xrplClient = new XrplClient(HttpUrl.parse("https://s2-reporting.ripple.com:51234")); + + @Override + public XrplClient getXrplClient() { + return xrplClient; + } + +} diff --git a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/environment/XrplEnvironment.java b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/environment/XrplEnvironment.java index c5f9bb8c7..1c0521ad9 100644 --- a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/environment/XrplEnvironment.java +++ b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/environment/XrplEnvironment.java @@ -34,7 +34,14 @@ public interface XrplEnvironment { Logger logger = LoggerFactory.getLogger(XrplEnvironment.class); /** - * Gets the XRPL environment to use (based on existence of -DuseTestnet property). + * Gets the XRPL environment to use. + * + *

+ * Uses local rippled container by default. + * Set -DuseTestnet to run against reporting mode testnet node + * Set -DuseClioTestnet to run against Clio testnet node + * Set -DuseDevnet to run against devnet + *

* * @return XRPL environment of the correct type. */ @@ -64,6 +71,32 @@ static XrplEnvironment getConfiguredEnvironment() { } } + /** + * Gets the configured {@link MainnetEnvironment} for integration tests that run against mainnet, such as + * {@link org.xrpl.xrpl4j.tests.AccountTransactionsIT}. + * + *

The default environment is a Reporting Mode only environment. Tests can be run against a Clio node + * by setting the {@code -DuseClioMainnet} system property.

+ * + * @return A {@link MainnetEnvironment}. + */ + static MainnetEnvironment getConfiguredMainnetEnvironment() { + boolean isClioEnabled = System.getProperty("useClioMainnet") != null; + if (isClioEnabled) { + logger.info( + "System property 'useClioMainnet' detected; Using Clio mainnet node for integration tests that are run " + + "against mainnet." + ); + return new ClioMainnetEnvironment(); + } else { + logger.info( + "System property 'useClioMainnet' was not detected; Using Reporting Mode mainnet node for integration tests " + + "that are run against mainnet." + ); + return new ReportingMainnetEnvironment(); + } + } + XrplClient getXrplClient(); void fundAccount(Address classicAddress);