builder() {
diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/BaseFeeDropsDeserializer.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/BaseFeeDropsDeserializer.java
new file mode 100644
index 000000000..e7d282fe0
--- /dev/null
+++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/BaseFeeDropsDeserializer.java
@@ -0,0 +1,61 @@
+package org.xrpl.xrpl4j.model.jackson.modules;
+
+/*-
+ * ========================LICENSE_START=================================
+ * xrpl4j :: model
+ * %%
+ * 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 com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
+import com.google.common.primitives.UnsignedLong;
+import org.xrpl.xrpl4j.model.transactions.SetFee;
+import org.xrpl.xrpl4j.model.transactions.XrpCurrencyAmount;
+
+import java.io.IOException;
+
+/**
+ * Custom Jackson deserializer for {@link XrpCurrencyAmount} instances found in {@link SetFee}.
+ *
+ * Before the XRPFees amendment, a {@link SetFee}
+ * transaction serializes its `BaseFee` to a hex string. After the
+ * XRPFees amendment, a {@link SetFee} transaction
+ * serializes its `BaseFee` to a decimal string.
+ *
+ * @see "https://xrpl.org/resources/known-amendments/#xrpfees"
+ */
+public class BaseFeeDropsDeserializer extends StdDeserializer {
+
+ /**
+ * No-args constructor.
+ */
+ public BaseFeeDropsDeserializer() {
+ super(XrpCurrencyAmount.class);
+ }
+
+ @Override
+ public XrpCurrencyAmount deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException {
+ // Pre-XRPFees, SetFee transactions serialize `BaseFee` to a hex string. Post XRPFees SetFee transactions
+ // have a `BaseFeeDrops` field which is a decimal string.
+ if (jsonParser.currentName().equals("BaseFee")) {
+ return XrpCurrencyAmount.of(UnsignedLong.valueOf(jsonParser.getText(), 16));
+ } else {
+ return XrpCurrencyAmount.ofDrops(jsonParser.getValueAsLong());
+ }
+ }
+}
diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/EscrowFinish.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/EscrowFinish.java
index 9aa5d8464..a1a7e7a5b 100644
--- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/EscrowFinish.java
+++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/EscrowFinish.java
@@ -228,9 +228,19 @@ default EscrowFinish normalizeCondition() {
// In this case, we should try to read conditionRawValue to a Condition. If that fails, condition()
// will remain empty, otherwise we will set condition().
try {
- Condition condition = CryptoConditionReader.readCondition(
- BaseEncoding.base16().decode(conditionRawValue().get().toUpperCase(Locale.US))
- );
+ byte[] conditionRawValueBytes = BaseEncoding.base16()
+ .decode(conditionRawValue().get().toUpperCase(Locale.US));
+ Condition condition = CryptoConditionReader.readCondition(conditionRawValueBytes);
+
+ // CryptoConditionReader.readCondition can succeed if the first part of the condition raw value
+ // is a valid condition, but the raw value has extra bytes afterward. Here, we check that the parsed
+ // condition is equivalent to the raw value when re-written.
+ if (!Arrays.equals(CryptoConditionWriter.writeCondition(condition), conditionRawValueBytes)) {
+ logger.warn("EscrowFinish Condition was malformed: mismatch between raw value and parsed condition. " +
+ "conditionRawValue() will contain the condition value, but condition() will be empty.");
+ return this;
+ }
+
return EscrowFinish.builder().from(this)
.condition(condition)
.build();
@@ -300,9 +310,19 @@ default EscrowFinish normalizeFulfillment() {
// In this case, we should try to read fulfillmentRawValue to a Condition. If that fails, fulfillment()
// will remain empty, otherwise we will set fulfillment().
try {
- Fulfillment> fulfillment = CryptoConditionReader.readFulfillment(
- BaseEncoding.base16().decode(fulfillmentRawValue().get().toUpperCase(Locale.US))
- );
+ byte[] fulfillmentRawValueBytes = BaseEncoding.base16()
+ .decode(fulfillmentRawValue().get().toUpperCase(Locale.US));
+ Fulfillment> fulfillment = CryptoConditionReader.readFulfillment(fulfillmentRawValueBytes);
+
+ // CryptoConditionReader.readFulfillment can succeed if the first part of the fulfillment raw value
+ // is a valid fulfillment, but the raw value has extra bytes afterward. Here, we check that the parsed
+ // fulfillment is equivalent to the raw value when re-written.
+ if (!Arrays.equals(CryptoConditionWriter.writeFulfillment(fulfillment), fulfillmentRawValueBytes)) {
+ logger.warn("EscrowFinish Fulfillment was malformed: mismatch between raw value and parsed fulfillment. " +
+ "fulfillmentRawValue() will contain the fulfillment value, but fulfillment() will be empty.");
+ return this;
+ }
+
return EscrowFinish.builder().from(this)
.fulfillment(fulfillment)
.build();
@@ -318,7 +338,7 @@ default EscrowFinish normalizeFulfillment() {
}
} catch (DerEncodingException e) {
- // This should never happen. CryptoconditionWriter.writeCondition errantly declares that it can throw
+ // This should never happen. CryptoconditionWriter.writeFulfillment errantly declares that it can throw
// a DerEncodingException, but nowhere in its implementation does it throw.
throw new RuntimeException(e);
}
diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/SetFee.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/SetFee.java
index 65178f352..8b7ee2412 100644
--- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/SetFee.java
+++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/SetFee.java
@@ -9,9 +9,9 @@
* 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.
@@ -20,12 +20,15 @@
* =========================LICENSE_END==================================
*/
+import com.fasterxml.jackson.annotation.JsonAlias;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.primitives.UnsignedInteger;
import org.immutables.value.Value;
import org.xrpl.xrpl4j.model.client.common.LedgerIndex;
+import org.xrpl.xrpl4j.model.jackson.modules.BaseFeeDropsDeserializer;
import java.util.Optional;
@@ -53,34 +56,92 @@ static ImmutableSetFee.Builder builder() {
* The charge, in drops of XRP, for the reference transaction, as hex. (This is the transaction cost before scaling
* for load.)
*
- * @return A hex {@link String} basefee value.
+ * This method only exists for historical purposes. When deserialized from a {@link SetFee} transaction from
+ * ledgers prior to the {@code XRPFees} amendment, this field will still be set based on {@link #baseFeeDrops()}.
+ *
+ * @return A hex {@link String} baseFee value.
+ */
+ @Value.Derived
+ @JsonIgnore
+ default String baseFee() {
+ return baseFeeDrops().value().toString(16);
+ }
+
+ /**
+ * The charge, in drops of XRP, for the reference transaction (This is the transaction cost before scaling for load).
+ *
+ *
This field will also be populated with the {@code BaseFee} value from any {@link SetFee} transactions
+ * that occurred before the XRPFees amendment took effect.
+ *
+ * @return An {@link XrpCurrencyAmount}.
*/
- @JsonProperty("BaseFee")
- String baseFee();
+ @JsonProperty("BaseFeeDrops")
+ @JsonAlias("BaseFee")
+ @JsonDeserialize(using = BaseFeeDropsDeserializer.class)
+ XrpCurrencyAmount baseFeeDrops();
/**
- * The cost, in fee units, of the reference transaction.
+ * The cost, in fee units, of the reference transaction. {@link SetFee} transactions deserialized from ledgers prior
+ * to the {@code XRPFees} amendment will always have this field, but transactions deserialized from ledgers post
+ * {@code XRPFees} activation will never have this field.
*
* @return An {@link UnsignedInteger} cost of ref transaction.
*/
@JsonProperty("ReferenceFeeUnits")
- UnsignedInteger referenceFeeUnits();
+ Optional referenceFeeUnits();
/**
* The base reserve, in drops.
*
- * @return An {@link UnsignedInteger} base reverse value in {@link org.xrpl.xrpl4j.model.client.fees.FeeDrops}.
+ * This method only exists for historical purposes. When deserialized from a {@link SetFee} transaction from
+ * ledgers prior to the {@code XRPFees} amendment, this field will still be set based on {@link #reserveBaseDrops()}}.
+ *
+ * @return An {@link UnsignedInteger} base reserve value in {@link org.xrpl.xrpl4j.model.client.fees.FeeDrops}.
*/
- @JsonProperty("ReserveBase")
- UnsignedInteger reserveBase();
+ @Value.Derived
+ @JsonIgnore
+ default UnsignedInteger reserveBase() {
+ return UnsignedInteger.valueOf(reserveBaseDrops().value().longValue());
+ }
+
+ /**
+ * The base reserve, as an {@link XrpCurrencyAmount}.
+ *
+ *
This field will also be populated with the {@code ReserveBase} value from any {@link SetFee} transactions
+ * that occurred before the XRPFees amendment took effect.
+ *
+ * @return An {@link XrpCurrencyAmount}.
+ */
+ @JsonProperty("ReserveBaseDrops")
+ @JsonAlias("ReserveBase")
+ XrpCurrencyAmount reserveBaseDrops();
/**
* The incremental reserve, in drops.
*
+ * This method only exists for historical purposes. When deserialized from a {@link SetFee} transaction from
+ * ledgers prior to the {@code XRPFees} amendment, this field will still be set based on
+ * {@link #reserveIncrementDrops()}.
+ *
* @return An {@link UnsignedInteger} incremental reserve in {@link org.xrpl.xrpl4j.model.client.fees.FeeDrops}.
*/
- @JsonProperty("ReserveIncrement")
- UnsignedInteger reserveIncrement();
+ @Value.Derived
+ @JsonIgnore
+ default UnsignedInteger reserveIncrement() {
+ return UnsignedInteger.valueOf(reserveIncrementDrops().value().longValue());
+ }
+
+ /**
+ * The incremental reserve, as an {@link XrpCurrencyAmount}.
+ *
+ *
This field will also be populated with the {@code ReserveIncrement} value from any {@link SetFee} transactions
+ * that occurred before the XRPFees amendment took effect.
+ *
+ * @return An {@link XrpCurrencyAmount}.
+ */
+ @JsonProperty("ReserveIncrementDrops")
+ @JsonAlias("ReserveIncrement")
+ XrpCurrencyAmount reserveIncrementDrops();
/**
* The index of the ledger version where this pseudo-transaction appears. This distinguishes the pseudo-transaction
diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/EscrowFinishTest.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/EscrowFinishTest.java
index 232bf6b6b..15358b4c6 100644
--- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/EscrowFinishTest.java
+++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/EscrowFinishTest.java
@@ -28,6 +28,7 @@
import com.google.common.primitives.UnsignedInteger;
import com.ripple.cryptoconditions.Condition;
import com.ripple.cryptoconditions.CryptoConditionReader;
+import com.ripple.cryptoconditions.CryptoConditionWriter;
import com.ripple.cryptoconditions.Fulfillment;
import com.ripple.cryptoconditions.PreimageSha256Condition;
import com.ripple.cryptoconditions.PreimageSha256Fulfillment;
@@ -176,6 +177,29 @@ void normalizeWithNoConditionAndRawValueForMalformedCondition() {
assertThat(actual.conditionRawValue()).isNotEmpty().get().isEqualTo("1234");
}
+ /**
+ * This tests the case where conditionRawValue is present and is parseable to a Condition but when the
+ * parsed Condition is written to a byte array, the value differs from the conditionRawValue bytes. This
+ * can occur if the condition raw value contains a valid condition in the first 32 bytes, but also includes
+ * extra bytes afterward.
+ */
+ @Test
+ void normalizeConditionWithRawValueThatIsParseableButNotValid() {
+ EscrowFinish actual = EscrowFinish.builder()
+ .fee(XrpCurrencyAmount.ofDrops(1))
+ .account(Address.of("rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59Ba"))
+ .sequence(UnsignedInteger.ONE)
+ .owner(Address.of("rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH"))
+ .offerSequence(UnsignedInteger.ZERO)
+ .conditionRawValue(GOOD_CONDITION_STR + GOOD_CONDITION_STR)
+ .build();
+
+ assertThat(actual.condition()).isEmpty();
+ assertThat(actual.conditionRawValue()).isNotEmpty().get().isEqualTo(
+ GOOD_CONDITION_STR + GOOD_CONDITION_STR
+ );
+ }
+
@Test
void normalizeWithNoConditionAndRawValueForBadHexLengthCondition() {
EscrowFinish actual = EscrowFinish.builder()
@@ -284,6 +308,29 @@ void normalizeWithNoFulfillmentAndRawValueForMalformedFulfillment() {
assertThat(actual.fulfillmentRawValue()).isNotEmpty().get().isEqualTo("1234");
}
+ /**
+ * This tests the case where fulfillmentRawValue is present and is parseable to a Fulfillment> but when the
+ * parsed Fulfillment is written to a byte array, the value differs from the fulfillmentRawValue bytes. This
+ * can occur if the fulfillment raw value contains a valid fulfillment in the first 32 bytes, but also includes
+ * extra bytes afterward, such as in transaction 138543329687544CDAFCD3AB0DCBFE9C4F8E710397747BA7155F19426F493C8D.
+ */
+ @Test
+ void normalizeFulfillmentWithRawValueThatIsParseableButNotValid() {
+ EscrowFinish actual = EscrowFinish.builder()
+ .fee(XrpCurrencyAmount.ofDrops(1))
+ .account(Address.of("rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59Ba"))
+ .sequence(UnsignedInteger.ONE)
+ .owner(Address.of("rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH"))
+ .offerSequence(UnsignedInteger.ZERO)
+ .fulfillmentRawValue(GOOD_FULFILLMENT_STR + GOOD_FULFILLMENT_STR)
+ .build();
+
+ assertThat(actual.fulfillment()).isEmpty();
+ assertThat(actual.fulfillmentRawValue()).isNotEmpty().get().isEqualTo(
+ GOOD_FULFILLMENT_STR + GOOD_FULFILLMENT_STR
+ );
+ }
+
@Test
void normalizeWithNoFulfillmentAndRawValueForBadHexLengthFulfillment() {
EscrowFinish actual = EscrowFinish.builder()
diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/SetFeeTest.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/SetFeeTest.java
index dbf5c3118..42018706f 100644
--- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/SetFeeTest.java
+++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/SetFeeTest.java
@@ -22,25 +22,57 @@
import static org.assertj.core.api.Assertions.assertThat;
+import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.common.primitives.UnsignedInteger;
import com.google.common.primitives.UnsignedLong;
+import org.json.JSONException;
import org.junit.jupiter.api.Test;
+import org.xrpl.xrpl4j.model.AbstractJsonTest;
import org.xrpl.xrpl4j.model.client.common.LedgerIndex;
import java.util.Optional;
-public class SetFeeTest {
+/**
+ * Unit tests for {@link SetFee}.
+ */
+public class SetFeeTest extends AbstractJsonTest {
+
+ @Test
+ public void testConstructWithNoFeeUnits() {
+ SetFee setFee = SetFee.builder()
+ .account(Address.of("rrrrrrrrrrrrrrrrrrrrrhoLvTp"))
+ .fee(XrpCurrencyAmount.ofDrops(12))
+ .sequence(UnsignedInteger.valueOf(2470665))
+ .baseFeeDrops(XrpCurrencyAmount.ofDrops(10))
+ .reserveBaseDrops(XrpCurrencyAmount.ofDrops(20000000))
+ .reserveIncrementDrops(XrpCurrencyAmount.ofDrops(5000000))
+ .ledgerSequence(Optional.of(LedgerIndex.of(UnsignedInteger.valueOf(67850752))))
+ .build();
+
+ assertThat(setFee.transactionType()).isEqualTo(TransactionType.SET_FEE);
+ assertThat(setFee.account()).isEqualTo(Address.of("rrrrrrrrrrrrrrrrrrrrrhoLvTp"));
+ assertThat(setFee.fee().value()).isEqualTo(UnsignedLong.valueOf(12));
+ assertThat(setFee.sequence()).isEqualTo(UnsignedInteger.valueOf(2470665));
+ assertThat(setFee.ledgerSequence()).isNotEmpty().get().isEqualTo(LedgerIndex.of(UnsignedInteger.valueOf(67850752)));
+ assertThat(setFee.baseFee()).isEqualTo("a");
+ assertThat(setFee.baseFeeDrops()).isEqualTo(XrpCurrencyAmount.ofDrops(10));
+ assertThat(setFee.referenceFeeUnits()).isEmpty();
+ assertThat(setFee.reserveIncrement()).isEqualTo(UnsignedInteger.valueOf(5000000));
+ assertThat(setFee.reserveIncrementDrops()).isEqualTo(XrpCurrencyAmount.ofDrops(5000000));
+ assertThat(setFee.reserveBase()).isEqualTo(UnsignedInteger.valueOf(20000000));
+ assertThat(setFee.reserveBaseDrops()).isEqualTo(XrpCurrencyAmount.ofDrops(20000000));
+ }
@Test
- public void testBuilder() {
+ public void testConstructWithFeeUnits() {
SetFee setFee = SetFee.builder()
.account(Address.of("rrrrrrrrrrrrrrrrrrrrrhoLvTp"))
.fee(XrpCurrencyAmount.ofDrops(12))
.sequence(UnsignedInteger.valueOf(2470665))
- .baseFee("000000000000000A")
+ .baseFeeDrops(XrpCurrencyAmount.ofDrops(10))
+ .reserveBaseDrops(XrpCurrencyAmount.ofDrops(20000000))
+ .reserveIncrementDrops(XrpCurrencyAmount.ofDrops(5000000))
.referenceFeeUnits(UnsignedInteger.valueOf(10))
- .reserveBase(UnsignedInteger.valueOf(20000000))
- .reserveIncrement(UnsignedInteger.valueOf(5000000))
.ledgerSequence(Optional.of(LedgerIndex.of(UnsignedInteger.valueOf(67850752))))
.build();
@@ -49,8 +81,78 @@ public void testBuilder() {
assertThat(setFee.fee().value()).isEqualTo(UnsignedLong.valueOf(12));
assertThat(setFee.sequence()).isEqualTo(UnsignedInteger.valueOf(2470665));
assertThat(setFee.ledgerSequence()).isNotEmpty().get().isEqualTo(LedgerIndex.of(UnsignedInteger.valueOf(67850752)));
- assertThat(setFee.referenceFeeUnits()).isEqualTo(UnsignedInteger.valueOf(10));
+ assertThat(setFee.baseFee()).isEqualTo("a");
+ assertThat(setFee.baseFeeDrops()).isEqualTo(XrpCurrencyAmount.ofDrops(10));
+ assertThat(setFee.referenceFeeUnits()).isNotEmpty().get().isEqualTo(UnsignedInteger.valueOf(10));
assertThat(setFee.reserveIncrement()).isEqualTo(UnsignedInteger.valueOf(5000000));
+ assertThat(setFee.reserveIncrementDrops()).isEqualTo(XrpCurrencyAmount.ofDrops(5000000));
assertThat(setFee.reserveBase()).isEqualTo(UnsignedInteger.valueOf(20000000));
+ assertThat(setFee.reserveBaseDrops()).isEqualTo(XrpCurrencyAmount.ofDrops(20000000));
+ }
+
+ @Test
+ public void testDeserializePreXrpFeesTransaction() throws JsonProcessingException {
+ SetFee expected = SetFee.builder()
+ .account(Address.of("rrrrrrrrrrrrrrrrrrrrrhoLvTp"))
+ .fee(XrpCurrencyAmount.ofDrops(12))
+ .sequence(UnsignedInteger.valueOf(2470665))
+ .baseFeeDrops(XrpCurrencyAmount.ofDrops(10))
+ .referenceFeeUnits(UnsignedInteger.valueOf(10))
+ .reserveBaseDrops(XrpCurrencyAmount.ofDrops(20000000))
+ .reserveIncrementDrops(XrpCurrencyAmount.ofDrops(5000000))
+ .ledgerSequence(Optional.of(LedgerIndex.of(UnsignedInteger.valueOf(67850752))))
+ .build();
+
+ String json = "{" +
+ "\"Account\":\"rrrrrrrrrrrrrrrrrrrrrhoLvTp\"," +
+ "\"Fee\":\"12\"," +
+ "\"LedgerSequence\":67850752," +
+ "\"Sequence\":2470665," +
+ "\"SigningPubKey\":\"\"," +
+ "\"TransactionType\":\"SetFee\"," +
+ "\"ReserveIncrement\":5000000," +
+ "\"ReserveBase\":20000000," +
+ "\"ReferenceFeeUnits\":10," +
+ "\"BaseFee\":\"a\"}";
+
+ Transaction actual = objectMapper.readValue(json, Transaction.class);
+ assertThat(actual).isEqualTo(expected);
+
+ String reserialized = objectMapper.writeValueAsString(actual);
+ Transaction redeserialized = objectMapper.readValue(reserialized, Transaction.class);
+
+ assertThat(redeserialized).isEqualTo(expected);
+ }
+
+ @Test
+ public void testDeserializePostXrpFeesTransaction() throws JsonProcessingException {
+ SetFee expected = SetFee.builder()
+ .account(Address.of("rrrrrrrrrrrrrrrrrrrrrhoLvTp"))
+ .fee(XrpCurrencyAmount.ofDrops(0))
+ .sequence(UnsignedInteger.valueOf(0))
+ .baseFeeDrops(XrpCurrencyAmount.ofDrops(10))
+ .reserveBaseDrops(XrpCurrencyAmount.ofDrops(10000000))
+ .reserveIncrementDrops(XrpCurrencyAmount.ofDrops(2000000))
+ .ledgerSequence(Optional.of(LedgerIndex.of(UnsignedInteger.valueOf(66462465))))
+ .build();
+
+ String json = "{\n" +
+ " \"Account\": \"rrrrrrrrrrrrrrrrrrrrrhoLvTp\",\n" +
+ " \"BaseFeeDrops\": \"10\",\n" +
+ " \"Fee\": \"0\",\n" +
+ " \"LedgerSequence\": 66462465,\n" +
+ " \"ReserveBaseDrops\": \"10000000\",\n" +
+ " \"ReserveIncrementDrops\": \"2000000\",\n" +
+ " \"Sequence\": 0,\n" +
+ " \"SigningPubKey\": \"\",\n" +
+ " \"TransactionType\": \"SetFee\"}";
+
+ Transaction actual = objectMapper.readValue(json, Transaction.class);
+ assertThat(actual).isEqualTo(expected);
+
+ String reserialized = objectMapper.writeValueAsString(actual);
+ Transaction redeserialized = objectMapper.readValue(reserialized, Transaction.class);
+
+ assertThat(redeserialized).isEqualTo(expected);
}
}
diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/json/SetFeeJsonTests.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/json/SetFeeJsonTests.java
deleted file mode 100644
index 05e0fa594..000000000
--- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/json/SetFeeJsonTests.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package org.xrpl.xrpl4j.model.transactions.json;
-
-/*-
- * ========================LICENSE_START=================================
- * xrpl4j :: core
- * %%
- * Copyright (C) 2020 - 2023 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 com.fasterxml.jackson.core.JsonProcessingException;
-import com.google.common.primitives.UnsignedInteger;
-import org.json.JSONException;
-import org.junit.jupiter.api.Test;
-import org.xrpl.xrpl4j.model.AbstractJsonTest;
-import org.xrpl.xrpl4j.model.client.common.LedgerIndex;
-import org.xrpl.xrpl4j.model.transactions.Address;
-import org.xrpl.xrpl4j.model.transactions.SetFee;
-import org.xrpl.xrpl4j.model.transactions.XrpCurrencyAmount;
-
-import java.util.Optional;
-
-public class SetFeeJsonTests extends AbstractJsonTest {
-
- @Test
- public void testJson() throws JsonProcessingException, JSONException {
- SetFee setFee = SetFee.builder()
- .account(Address.of("rrrrrrrrrrrrrrrrrrrrrhoLvTp"))
- .fee(XrpCurrencyAmount.ofDrops(12))
- .sequence(UnsignedInteger.valueOf(2470665))
- .baseFee("000000000000000A")
- .referenceFeeUnits(UnsignedInteger.valueOf(10))
- .reserveBase(UnsignedInteger.valueOf(20000000))
- .reserveIncrement(UnsignedInteger.valueOf(5000000))
- .ledgerSequence(Optional.of(LedgerIndex.of(UnsignedInteger.valueOf(67850752))))
- .build();
-
- String json = "{" +
- "\"Account\":\"rrrrrrrrrrrrrrrrrrrrrhoLvTp\"," +
- "\"Fee\":\"12\"," +
- "\"LedgerSequence\":67850752," +
- "\"Sequence\":2470665," +
- "\"SigningPubKey\":\"\"," +
- "\"TransactionType\":\"SetFee\"," +
- "\"ReserveIncrement\":5000000," +
- "\"ReserveBase\":20000000," +
- "\"ReferenceFeeUnits\":10," +
- "\"BaseFee\":\"000000000000000A\"}";
-
- assertCanSerializeAndDeserialize(setFee, json);
- }
-}