Skip to content

Commit 8f45acd

Browse files
committed
fix tests
1 parent 4370dae commit 8f45acd

File tree

5 files changed

+207
-81
lines changed

5 files changed

+207
-81
lines changed

xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/LedgerHeader.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ static ImmutableLedgerHeader.Builder builder() {
9595
* @return A {@link ZonedDateTime} representing the {@link #closeTime()} in human-readable format.
9696
*/
9797
@JsonProperty("close_time_human")
98-
@JsonFormat(pattern = "yyyy-MMM-dd HH:mm:ss[.SSSSSSSSS][.SSSSSS][.SSS] z", locale = "en_US")
98+
@JsonFormat(pattern = "yyyy-MMM-dd HH:mm:ss.SSSSSSSSS z", locale = "en_US")
9999
Optional<ZonedDateTime> closeTimeHuman();
100100

101101
/**

xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/client/ledger/LedgerResultJsonTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public void testJson() throws JsonProcessingException, JSONException {
6464
" \"ledger\": {\n" +
6565
" \"account_hash\": \"B258A8BB4743FB74CBBD6E9F67E4A56C4432EA09E5805E4CC2DA26F2DBE8F3D1\",\n" +
6666
" \"close_time\": 638329271,\n" +
67-
" \"close_time_human\": \"2020-Mar-24 01:41:11.000000000.000000.000 UTC\",\n" +
67+
" \"close_time_human\": \"2020-Mar-24 01:41:11.000000000 UTC\",\n" +
6868
" \"close_time_resolution\": 10,\n" +
6969
" \"closed\": true,\n" +
7070
" \"ledger_hash\": \"3652D7FD0576BC452C0D2E9B747BDD733075971D1A9A1D98125055DEF428721A\",\n" +

xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/ledger/LedgerHeaderJsonTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ public void deserializeLedgerHeaderWithTransactions() throws JsonProcessingExcep
112112
" \"ledger_hash\" : \"3652D7FD0576BC452C0D2E9B747BDD733075971D1A9A1D98125055DEF428721A\",\n" +
113113
" \"account_hash\" : \"B258A8BB4743FB74CBBD6E9F67E4A56C4432EA09E5805E4CC2DA26F2DBE8F3D1\",\n" +
114114
" \"close_time\" : 638329271,\n" +
115-
" \"close_time_human\" : \"2020-Mar-24 01:41:11.000000000.000000.000 UTC\",\n" +
115+
" \"close_time_human\" : \"2020-Mar-24 01:41:11.000000000 UTC\",\n" +
116116
" \"closed\" : true,\n" +
117117
" \"parent_hash\" : \"AE996778246BC81F85D5AF051241DAA577C23BCA04C034A7074F93700194520D\",\n" +
118118
" \"parent_close_time\" : 638329270,\n" +

xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/environment/LocalRippledEnvironment.java

Lines changed: 11 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -24,22 +24,16 @@
2424
import static org.slf4j.LoggerFactory.getLogger;
2525

2626
import com.fasterxml.jackson.core.JsonProcessingException;
27-
import com.google.common.base.Preconditions;
28-
import okhttp3.HttpUrl;
2927
import org.slf4j.Logger;
3028
import org.xrpl.xrpl4j.client.JsonRpcClientErrorException;
31-
import org.xrpl.xrpl4j.client.XrplAdminClient;
3229
import org.xrpl.xrpl4j.client.XrplClient;
33-
import org.xrpl.xrpl4j.crypto.keys.Base58EncodedSecret;
3430
import org.xrpl.xrpl4j.crypto.keys.KeyPair;
3531
import org.xrpl.xrpl4j.crypto.keys.PrivateKey;
36-
import org.xrpl.xrpl4j.crypto.keys.Seed;
3732
import org.xrpl.xrpl4j.crypto.signing.SignatureService;
3833
import org.xrpl.xrpl4j.crypto.signing.SingleSignedTransaction;
3934
import org.xrpl.xrpl4j.crypto.signing.bc.BcSignatureService;
4035
import org.xrpl.xrpl4j.model.client.accounts.AccountInfoRequestParams;
4136
import org.xrpl.xrpl4j.model.client.accounts.AccountInfoResult;
42-
import org.xrpl.xrpl4j.model.client.admin.AcceptLedgerResult;
4337
import org.xrpl.xrpl4j.model.client.fees.FeeResult;
4438
import org.xrpl.xrpl4j.model.client.fees.FeeUtils;
4539
import org.xrpl.xrpl4j.model.client.transactions.SubmitResult;
@@ -51,63 +45,29 @@
5145
import java.math.BigDecimal;
5246
import java.time.Duration;
5347
import java.util.Objects;
54-
import java.util.concurrent.Executors;
55-
import java.util.concurrent.ScheduledExecutorService;
56-
import java.util.concurrent.TimeUnit;
5748

5849
/**
59-
* Environment that connects to a locally running rippled node in standalone mode.
50+
* Environment that runs a local rippled inside docker in standalone mode.
6051
*/
6152
public class LocalRippledEnvironment implements XrplEnvironment {
6253

6354
private static final Logger LOGGER = getLogger(LocalRippledEnvironment.class);
6455

65-
/**
66-
* The URL of the locally running rippled node.
67-
*/
68-
private static final HttpUrl LOCAL_RIPPLED_URL = HttpUrl.parse("http://127.0.0.1:51234/");
69-
70-
/**
71-
* Seed for the Master/Root wallet in the rippled standalone mode.
72-
*/
73-
private static final String MASTER_WALLET_SEED = "snoPBrXtMeMyMHUVTgbuqAfg1SUTb";
56+
private static final RippledContainer rippledContainer = new RippledContainer().start();
7457

75-
private static ScheduledExecutorService ledgerAcceptor;
76-
77-
private final XrplClient xrplClient;
78-
private final XrplAdminClient xrplAdminClient;
7958
private final SignatureService<PrivateKey> signatureService = new BcSignatureService();
8059

81-
/**
82-
* No-args constructor that initializes the connection to the local rippled node.
83-
*/
84-
public LocalRippledEnvironment() {
85-
this.xrplClient = new XrplClient(LOCAL_RIPPLED_URL);
86-
this.xrplAdminClient = new XrplAdminClient(LOCAL_RIPPLED_URL);
87-
// Start the ledger acceptor with a default interval
88-
this.startLedgerAcceptor(Duration.ofMillis(1000));
89-
}
90-
91-
/**
92-
* Get the {@link KeyPair} of the master account.
93-
*
94-
* @return The {@link KeyPair} of the master account.
95-
*/
96-
public static KeyPair getMasterKeyPair() {
97-
return Seed.fromBase58EncodedSecret(Base58EncodedSecret.of(MASTER_WALLET_SEED)).deriveKeyPair();
98-
}
99-
10060
@Override
10161
public XrplClient getXrplClient() {
102-
return xrplClient;
62+
return rippledContainer.getXrplClient();
10363
}
10464

10565
@Override
10666
public void fundAccount(Address classicAddress) {
107-
// accounts are funded from the genesis account that holds all XRP when the ledger starts.
67+
// accounts are funded from the genesis account that holds all XRP when the ledger container starts.
10868
try {
10969
sendPayment(
110-
getMasterKeyPair(),
70+
RippledContainer.getMasterKeyPair(),
11171
classicAddress,
11272
XrpCurrencyAmount.ofXrp(BigDecimal.valueOf(1000))
11373
);
@@ -141,53 +101,26 @@ protected void sendPayment(KeyPair sourceKeyPair, Address destinationAddress, Xr
141101
SingleSignedTransaction<Payment> signedPayment = signatureService.sign(sourceKeyPair.privateKey(), payment);
142102
SubmitResult<Payment> result = getXrplClient().submit(signedPayment);
143103
assertThat(result.engineResult()).isEqualTo(TransactionResultCodes.TES_SUCCESS);
144-
LOGGER.info("Payment successful: " + LOCAL_RIPPLED_URL +
104+
LOGGER.info("Payment successful: " + rippledContainer.getBaseUri().toString() +
145105
result.transactionResult().transaction());
146106
}
147107

148108
/**
149-
* Method to accept next ledger ad hoc.
109+
* Method to accept next ledger ad hoc, only available in RippledContainer.java implementation.
150110
*/
151111
@Override
152112
public void acceptLedger() {
153-
try {
154-
AcceptLedgerResult status = xrplAdminClient.acceptLedger();
155-
LOGGER.info("Accepted ledger status: {}", status);
156-
} catch (RuntimeException | JsonRpcClientErrorException e) {
157-
LOGGER.warn("Ledger accept failed", e);
158-
}
113+
rippledContainer.acceptLedger();
159114
}
160115

161116
@Override
162117
public void startLedgerAcceptor(Duration acceptIntervalMillis) {
163-
Objects.requireNonNull(acceptIntervalMillis, "acceptIntervalMillis must not be null");
164-
Preconditions.checkArgument(acceptIntervalMillis.toMillis() > 0, "acceptIntervalMillis must be greater than 0");
165-
166-
// Stop any existing ledger acceptor
167-
if (ledgerAcceptor != null && !ledgerAcceptor.isShutdown()) {
168-
stopLedgerAcceptor();
169-
}
170-
171-
// rippled is run in standalone mode which means that ledgers won't automatically close. You have to manually
172-
// advance the ledger using the "ledger_accept" method on the admin API. To mimic the behavior of a networked
173-
// rippled, run a scheduled task to trigger the "ledger_accept" method.
174-
ledgerAcceptor = Executors.newScheduledThreadPool(1);
175-
ledgerAcceptor.scheduleAtFixedRate(this::acceptLedger,
176-
acceptIntervalMillis.toMillis(),
177-
acceptIntervalMillis.toMillis(),
178-
TimeUnit.MILLISECONDS
179-
);
118+
Objects.requireNonNull(acceptIntervalMillis);
119+
rippledContainer.startLedgerAcceptor(acceptIntervalMillis);
180120
}
181121

182122
@Override
183123
public void stopLedgerAcceptor() {
184-
if (ledgerAcceptor != null) {
185-
try {
186-
ledgerAcceptor.shutdown();
187-
ledgerAcceptor.awaitTermination(5, TimeUnit.SECONDS);
188-
} catch (InterruptedException e) {
189-
throw new RuntimeException("Unable to stop ledger acceptor", e);
190-
}
191-
}
124+
rippledContainer.stopLedgerAcceptor();
192125
}
193126
}
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
package org.xrpl.xrpl4j.tests.environment;
2+
3+
/*-
4+
* ========================LICENSE_START=================================
5+
* xrpl4j :: integration-tests
6+
* %%
7+
* Copyright (C) 2020 - 2022 XRPL Foundation and its contributors
8+
* %%
9+
* Licensed under the Apache License, Version 2.0 (the "License");
10+
* you may not use this file except in compliance with the License.
11+
* You may obtain a copy of the License at
12+
*
13+
* http://www.apache.org/licenses/LICENSE-2.0
14+
*
15+
* Unless required by applicable law or agreed to in writing, software
16+
* distributed under the License is distributed on an "AS IS" BASIS,
17+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
* See the License for the specific language governing permissions and
19+
* limitations under the License.
20+
* =========================LICENSE_END==================================
21+
*/
22+
23+
import static org.assertj.core.api.Assertions.assertThat;
24+
import static org.slf4j.LoggerFactory.getLogger;
25+
26+
import com.fasterxml.jackson.core.JsonProcessingException;
27+
import com.google.common.base.Preconditions;
28+
import okhttp3.HttpUrl;
29+
import org.slf4j.Logger;
30+
import org.xrpl.xrpl4j.client.JsonRpcClientErrorException;
31+
import org.xrpl.xrpl4j.client.XrplAdminClient;
32+
import org.xrpl.xrpl4j.client.XrplClient;
33+
import org.xrpl.xrpl4j.crypto.keys.Base58EncodedSecret;
34+
import org.xrpl.xrpl4j.crypto.keys.KeyPair;
35+
import org.xrpl.xrpl4j.crypto.keys.PrivateKey;
36+
import org.xrpl.xrpl4j.crypto.keys.Seed;
37+
import org.xrpl.xrpl4j.crypto.signing.SignatureService;
38+
import org.xrpl.xrpl4j.crypto.signing.SingleSignedTransaction;
39+
import org.xrpl.xrpl4j.crypto.signing.bc.BcSignatureService;
40+
import org.xrpl.xrpl4j.model.client.accounts.AccountInfoRequestParams;
41+
import org.xrpl.xrpl4j.model.client.accounts.AccountInfoResult;
42+
import org.xrpl.xrpl4j.model.client.admin.AcceptLedgerResult;
43+
import org.xrpl.xrpl4j.model.client.fees.FeeResult;
44+
import org.xrpl.xrpl4j.model.client.fees.FeeUtils;
45+
import org.xrpl.xrpl4j.model.client.transactions.SubmitResult;
46+
import org.xrpl.xrpl4j.model.transactions.Address;
47+
import org.xrpl.xrpl4j.model.transactions.Payment;
48+
import org.xrpl.xrpl4j.model.transactions.TransactionResultCodes;
49+
import org.xrpl.xrpl4j.model.transactions.XrpCurrencyAmount;
50+
51+
import java.math.BigDecimal;
52+
import java.time.Duration;
53+
import java.util.Objects;
54+
import java.util.concurrent.Executors;
55+
import java.util.concurrent.ScheduledExecutorService;
56+
import java.util.concurrent.TimeUnit;
57+
58+
/**
59+
* Environment that connects to a locally running rippled node in standalone mode.
60+
*/
61+
public class LocalRippledEnvironmentForConfidentialMPT implements XrplEnvironment {
62+
63+
private static final Logger LOGGER = getLogger(LocalRippledEnvironmentForConfidentialMPT.class);
64+
65+
/**
66+
* The URL of the locally running rippled node.
67+
*/
68+
private static final HttpUrl LOCAL_RIPPLED_URL = HttpUrl.parse("http://127.0.0.1:51234/");
69+
70+
/**
71+
* Seed for the Master/Root wallet in the rippled standalone mode.
72+
*/
73+
private static final String MASTER_WALLET_SEED = "snoPBrXtMeMyMHUVTgbuqAfg1SUTb";
74+
75+
private static ScheduledExecutorService ledgerAcceptor;
76+
77+
private final XrplClient xrplClient;
78+
private final XrplAdminClient xrplAdminClient;
79+
private final SignatureService<PrivateKey> signatureService = new BcSignatureService();
80+
81+
/**
82+
* No-args constructor that initializes the connection to the local rippled node.
83+
*/
84+
public LocalRippledEnvironmentForConfidentialMPT() {
85+
this.xrplClient = new XrplClient(LOCAL_RIPPLED_URL);
86+
this.xrplAdminClient = new XrplAdminClient(LOCAL_RIPPLED_URL);
87+
// Start the ledger acceptor with a default interval
88+
this.startLedgerAcceptor(Duration.ofMillis(1000));
89+
}
90+
91+
/**
92+
* Get the {@link KeyPair} of the master account.
93+
*
94+
* @return The {@link KeyPair} of the master account.
95+
*/
96+
public static KeyPair getMasterKeyPair() {
97+
return Seed.fromBase58EncodedSecret(Base58EncodedSecret.of(MASTER_WALLET_SEED)).deriveKeyPair();
98+
}
99+
100+
@Override
101+
public XrplClient getXrplClient() {
102+
return xrplClient;
103+
}
104+
105+
@Override
106+
public void fundAccount(Address classicAddress) {
107+
// accounts are funded from the genesis account that holds all XRP when the ledger starts.
108+
try {
109+
sendPayment(
110+
getMasterKeyPair(),
111+
classicAddress,
112+
XrpCurrencyAmount.ofXrp(BigDecimal.valueOf(1000))
113+
);
114+
} catch (JsonRpcClientErrorException | JsonProcessingException e) {
115+
throw new RuntimeException("could not fund account", e);
116+
}
117+
}
118+
119+
protected AccountInfoResult getCurrentAccountInfo(Address classicAddress) {
120+
try {
121+
AccountInfoRequestParams params = AccountInfoRequestParams.of(classicAddress);
122+
return getXrplClient().accountInfo(params);
123+
} catch (Exception e) {
124+
throw new RuntimeException(e.getMessage(), e);
125+
}
126+
}
127+
128+
protected void sendPayment(KeyPair sourceKeyPair, Address destinationAddress, XrpCurrencyAmount paymentAmount)
129+
throws JsonRpcClientErrorException, JsonProcessingException {
130+
FeeResult feeResult = getXrplClient().fee();
131+
AccountInfoResult accountInfo = this.getCurrentAccountInfo(sourceKeyPair.publicKey().deriveAddress());
132+
Payment payment = Payment.builder()
133+
.account(sourceKeyPair.publicKey().deriveAddress())
134+
.fee(FeeUtils.computeNetworkFees(feeResult).recommendedFee())
135+
.sequence(accountInfo.accountData().sequence())
136+
.destination(destinationAddress)
137+
.amount(paymentAmount)
138+
.signingPublicKey(sourceKeyPair.publicKey())
139+
.build();
140+
141+
SingleSignedTransaction<Payment> signedPayment = signatureService.sign(sourceKeyPair.privateKey(), payment);
142+
SubmitResult<Payment> result = getXrplClient().submit(signedPayment);
143+
assertThat(result.engineResult()).isEqualTo(TransactionResultCodes.TES_SUCCESS);
144+
LOGGER.info("Payment successful: " + LOCAL_RIPPLED_URL +
145+
result.transactionResult().transaction());
146+
}
147+
148+
/**
149+
* Method to accept next ledger ad hoc.
150+
*/
151+
@Override
152+
public void acceptLedger() {
153+
try {
154+
AcceptLedgerResult status = xrplAdminClient.acceptLedger();
155+
LOGGER.info("Accepted ledger status: {}", status);
156+
} catch (RuntimeException | JsonRpcClientErrorException e) {
157+
LOGGER.warn("Ledger accept failed", e);
158+
}
159+
}
160+
161+
@Override
162+
public void startLedgerAcceptor(Duration acceptIntervalMillis) {
163+
Objects.requireNonNull(acceptIntervalMillis, "acceptIntervalMillis must not be null");
164+
Preconditions.checkArgument(acceptIntervalMillis.toMillis() > 0, "acceptIntervalMillis must be greater than 0");
165+
166+
// Stop any existing ledger acceptor
167+
if (ledgerAcceptor != null && !ledgerAcceptor.isShutdown()) {
168+
stopLedgerAcceptor();
169+
}
170+
171+
// rippled is run in standalone mode which means that ledgers won't automatically close. You have to manually
172+
// advance the ledger using the "ledger_accept" method on the admin API. To mimic the behavior of a networked
173+
// rippled, run a scheduled task to trigger the "ledger_accept" method.
174+
ledgerAcceptor = Executors.newScheduledThreadPool(1);
175+
ledgerAcceptor.scheduleAtFixedRate(this::acceptLedger,
176+
acceptIntervalMillis.toMillis(),
177+
acceptIntervalMillis.toMillis(),
178+
TimeUnit.MILLISECONDS
179+
);
180+
}
181+
182+
@Override
183+
public void stopLedgerAcceptor() {
184+
if (ledgerAcceptor != null) {
185+
try {
186+
ledgerAcceptor.shutdown();
187+
ledgerAcceptor.awaitTermination(5, TimeUnit.SECONDS);
188+
} catch (InterruptedException e) {
189+
throw new RuntimeException("Unable to stop ledger acceptor", e);
190+
}
191+
}
192+
}
193+
}

0 commit comments

Comments
 (0)