Skip to content
Draft
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
import java.io.IOException;

/**
* Custom deserializer for {@link Transaction}s, which deserializes to a specific {@link Transaction} type
* based on the TransactionType JSON field.
* Custom deserializer for instances of {@link Transaction} that deserialize to a specific {@link Transaction} type
* based on the`TransactionType` JSON field.
*/
public class TransactionDeserializer extends StdDeserializer<Transaction> {

Expand All @@ -52,12 +52,12 @@ public Transaction deserialize(JsonParser jsonParser, DeserializationContext ctx
TransactionType transactionType = TransactionType.forValue(objectNode.get("TransactionType").asText());
final Class<? extends Transaction> transactionTypeClass = Transaction.typeMap.inverse().get(transactionType);

// Fixes #590 by removing the `Account` property from any incoming `UnlModify` JSON about to be deserialized.
// This fixes #590 because the JSON returned by the rippled/clio API v1 has a bug where the account value in
// `UnlModify` transactions is an empty string. When this value is deserialized, an exception is thrown because
// the empty string value is not a valid `Address`. By removing the property from incoming JSON, the Java value
// for the `Account` property is always set to ACCOUNT_ZERO via a default method. One other side effect of this
// fix is that `Account` property will not be errantly added to `unknownFields map of the ultimate Java object,
// Fixes #590 by removing the `Account` property from any incoming `UnlModify` JSON about to be deserialized.
// This fixes #590 because the JSON returned by the rippled/clio API v1 has a bug where the account value in
// `UnlModify` transactions is an empty string. When this value is deserialized, an exception is thrown because
// the empty string value is not a valid `Address`. By removing the property from incoming JSON, the Java value
// for the `Account` property is always set to ACCOUNT_ZERO via a default method. One other side effect of this
// fix is that `Account` property will not be errantly added to `unknownFields` map of the ultimate Java object,
// which is incorrect.
if (UnlModify.class.isAssignableFrom(transactionTypeClass)) {
objectNode.remove("Account");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,11 @@
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.xrpl.xrpl4j.codec.addresses.UnsignedByteArray;
import org.xrpl.xrpl4j.model.client.common.LedgerIndex;
import org.xrpl.xrpl4j.model.client.path.BookOffersOffer;
import org.xrpl.xrpl4j.model.client.serverinfo.ServerInfo;
import org.xrpl.xrpl4j.model.flags.Flags;
import org.xrpl.xrpl4j.model.transactions.CurrencyAmount;
import org.xrpl.xrpl4j.model.transactions.Transaction;
import org.xrpl.xrpl4j.model.transactions.metadata.AffectedNode;
import org.xrpl.xrpl4j.model.transactions.metadata.MetaLedgerEntryType;

/**
* Jackson module for the xrpl4j-model project.
Expand Down Expand Up @@ -63,7 +61,7 @@ public Xrpl4jModule() {
addDeserializer(Transaction.class, new TransactionDeserializer());

addDeserializer(ServerInfo.class, new ServerInfoDeserializer());

addSerializer(UnsignedByteArray.class, new UnsignedByteArraySerializer());
addDeserializer(UnsignedByteArray.class, new UnsignedByteArrayDeserializer());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -23,9 +23,9 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.base.Preconditions;
import com.google.common.primitives.UnsignedInteger;
import org.immutables.value.Value;
import org.immutables.value.Value.Derived;
import org.xrpl.xrpl4j.model.flags.TransactionFlags;

import java.util.Optional;
Expand Down Expand Up @@ -81,4 +81,14 @@ default TransactionFlags flags() {
@JsonProperty("DestinationTag")
Optional<UnsignedInteger> destinationTag();

/**
* Immutables Check to ensure property state after construction.
*/
@Value.Check
default AccountDelete normalize() {
Preconditions.checkState(!unknownFields().containsKey("TransactionType"));
Preconditions.checkState(!unknownFields().containsKey("Account"));
Preconditions.checkState(transactionType() == TransactionType.ACCOUNT_DELETE);
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -517,4 +517,15 @@ public int getValue() {
return value;
}
}

/**
* Immutables Check to ensure property state after construction.
*/
@Value.Check
default AccountSet normalize() {
Preconditions.checkState(!unknownFields().containsKey("TransactionType"));
Preconditions.checkState(!unknownFields().containsKey("Account"));
Preconditions.checkState(transactionType() == TransactionType.ACCOUNT_SET);
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.annotations.Beta;
import com.google.common.base.Preconditions;
import org.immutables.value.Value;
import org.xrpl.xrpl4j.model.flags.TransactionFlags;
import org.xrpl.xrpl4j.model.ledger.AuthAccountWrapper;
Expand Down Expand Up @@ -107,4 +108,14 @@ default TransactionFlags flags() {
@JsonProperty("AuthAccounts")
List<AuthAccountWrapper> authAccounts();

/**
* Immutables Check to ensure property state after construction.
*/
@Value.Check
default AmmBid normalize() {
Preconditions.checkState(!unknownFields().containsKey("TransactionType"));
Preconditions.checkState(!unknownFields().containsKey("Account"));
Preconditions.checkState(transactionType() == TransactionType.AMM_BID);
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.annotations.Beta;
import com.google.common.base.Preconditions;
import org.immutables.value.Value;
import org.xrpl.xrpl4j.model.flags.Flags;
import org.xrpl.xrpl4j.model.flags.TransactionFlags;

/**
Expand Down Expand Up @@ -68,4 +68,14 @@ default TransactionFlags flags() {
@JsonProperty("TradingFee")
TradingFee tradingFee();

/**
* Immutables Check to ensure property state after construction.
*/
@Value.Check
default AmmCreate normalize() {
Preconditions.checkState(!unknownFields().containsKey("TransactionType"));
Preconditions.checkState(!unknownFields().containsKey("Account"));
Preconditions.checkState(transactionType() == TransactionType.AMM_CREATE);
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.annotations.Beta;
import com.google.common.base.Preconditions;
import org.immutables.value.Value;
import org.immutables.value.Value.Immutable;
import org.xrpl.xrpl4j.model.flags.TransactionFlags;
Expand Down Expand Up @@ -58,4 +59,14 @@ default TransactionFlags flags() {
@JsonProperty("Asset2")
Issue asset2();

/**
* Immutables Check to ensure property state after construction.
*/
@Value.Check
default AmmDelete normalize() {
Preconditions.checkState(!unknownFields().containsKey("TransactionType"));
Preconditions.checkState(!unknownFields().containsKey("Account"));
Preconditions.checkState(transactionType() == TransactionType.AMM_DELETE);
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.annotations.Beta;
import com.google.common.base.Preconditions;
import org.immutables.value.Value;
import org.xrpl.xrpl4j.model.flags.AmmDepositFlags;
import org.xrpl.xrpl4j.model.ledger.Issue;
Expand Down Expand Up @@ -105,4 +106,15 @@ static ImmutableAmmDeposit.Builder builder() {
*/
@JsonProperty("TradingFee")
Optional<TradingFee> tradingFee();

/**
* Immutables Check to ensure property state after construction.
*/
@Value.Check
default AmmDeposit normalize() {
Preconditions.checkState(!unknownFields().containsKey("TransactionType"));
Preconditions.checkState(!unknownFields().containsKey("Account"));
Preconditions.checkState(transactionType() == TransactionType.AMM_DEPOSIT);
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.annotations.Beta;
import com.google.common.base.Preconditions;
import org.immutables.value.Value;
import org.xrpl.xrpl4j.model.flags.TransactionFlags;
import org.xrpl.xrpl4j.model.ledger.Issue;
Expand Down Expand Up @@ -68,5 +69,15 @@ default TransactionFlags flags() {
@JsonProperty("TradingFee")
TradingFee tradingFee();

/**
* Immutables Check to ensure property state after construction.
*/
@Value.Check
default AmmVote normalize() {
Preconditions.checkState(!unknownFields().containsKey("TransactionType"));
Preconditions.checkState(!unknownFields().containsKey("Account"));
Preconditions.checkState(transactionType() == TransactionType.AMM_VOTE);
return this;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,14 @@ static ImmutableAmmWithdraw.Builder builder() {
@JsonProperty("LPTokenIn")
Optional<CurrencyAmount> lpTokensIn();

/**
* Immutables Check to ensure property state after construction.
*/
@Value.Check
default AmmWithdraw normalize() {
Preconditions.checkState(!unknownFields().containsKey("TransactionType"));
Preconditions.checkState(!unknownFields().containsKey("Account"));
Preconditions.checkState(transactionType() == TransactionType.AMM_WITHDRAW);
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.base.Preconditions;
import org.immutables.value.Value;
import org.immutables.value.Value.Derived;
import org.xrpl.xrpl4j.model.flags.TransactionFlags;

/**
Expand Down Expand Up @@ -68,4 +68,15 @@ default TransactionFlags flags() {
*/
@JsonProperty("CheckID")
Hash256 checkId();

/**
* Immutables Check to ensure property state after construction.
*/
@Value.Check
default CheckCancel normalize() {
Preconditions.checkState(!unknownFields().containsKey("TransactionType"));
Preconditions.checkState(!unknownFields().containsKey("Account"));
Preconditions.checkState(transactionType() == TransactionType.CHECK_CANCEL);
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,15 @@ default void validateOnlyOneAmountSet() {
!(amount().isPresent() && deliverMin().isPresent()),
"The CheckCash transaction must include either amount or deliverMin, but not both.");
}

/**
* Immutables Check to ensure property state after construction.
*/
@Value.Check
default CheckCash normalize() {
Preconditions.checkState(!unknownFields().containsKey("TransactionType"));
Preconditions.checkState(!unknownFields().containsKey("Account"));
Preconditions.checkState(transactionType() == TransactionType.CHECK_CASH);
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -23,9 +23,9 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.base.Preconditions;
import com.google.common.primitives.UnsignedInteger;
import org.immutables.value.Value;
import org.immutables.value.Value.Derived;
import org.xrpl.xrpl4j.model.flags.TransactionFlags;

import java.util.Optional;
Expand Down Expand Up @@ -106,4 +106,14 @@ default TransactionFlags flags() {
@JsonProperty("InvoiceID")
Optional<Hash256> invoiceId();

/**
* Immutables Check to ensure property state after construction.
*/
@Value.Check
default CheckCreate normalize() {
Preconditions.checkState(!unknownFields().containsKey("TransactionType"));
Preconditions.checkState(!unknownFields().containsKey("Account"));
Preconditions.checkState(transactionType() == TransactionType.CHECK_CREATE);
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.annotations.Beta;
import com.google.common.base.Preconditions;
import org.immutables.value.Value;
import org.immutables.value.Value.Immutable;
import org.xrpl.xrpl4j.model.flags.TransactionFlags;
Expand Down Expand Up @@ -51,5 +52,15 @@ default TransactionFlags flags() {
@JsonProperty("Amount")
IssuedCurrencyAmount amount();

/**
* Immutables Check to ensure property state after construction.
*/
@Value.Check
default Clawback normalize() {
Preconditions.checkState(!unknownFields().containsKey("TransactionType"));
Preconditions.checkState(!unknownFields().containsKey("Account"));
Preconditions.checkState(transactionType() == TransactionType.CLAWBACK);
return this;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.base.Preconditions;
import org.immutables.value.Value;
import org.immutables.value.Value.Derived;
import org.xrpl.xrpl4j.model.flags.TransactionFlags;

import java.util.Optional;
Expand Down Expand Up @@ -93,4 +92,15 @@ default void validateFieldPresence() {
!(authorize().isPresent() && unauthorize().isPresent()),
"The DepositPreAuth transaction must include either Authorize or Unauthorize, but not both.");
}

/**
* Immutables Check to ensure property state after construction.
*/
@Value.Check
default DepositPreAuth normalize() {
Preconditions.checkState(!unknownFields().containsKey("TransactionType"));
Preconditions.checkState(!unknownFields().containsKey("Account"));
Preconditions.checkState(transactionType() == TransactionType.DEPOSIT_PRE_AUTH);
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.annotations.Beta;
import com.google.common.base.Preconditions;
import org.immutables.value.Value;
import org.immutables.value.Value.Immutable;
import org.xrpl.xrpl4j.model.flags.TransactionFlags;

import java.util.Optional;

/**
* Object mapping for the {@code DIDDelete} transaction.
*
Expand Down Expand Up @@ -46,5 +45,14 @@ default TransactionFlags flags() {
return TransactionFlags.EMPTY;
}


/**
* Immutables Check to ensure property state after construction.
*/
@Value.Check
default DidDelete normalize() {
Preconditions.checkState(!unknownFields().containsKey("TransactionType"));
Preconditions.checkState(!unknownFields().containsKey("Account"));
Preconditions.checkState(transactionType() == TransactionType.DID_DELETE);
return this;
}
}
Loading
Loading