From 8e831379b71a0532f671decb73edb60fb4788f4e Mon Sep 17 00:00:00 2001 From: nkramer44 Date: Thu, 17 Oct 2024 15:38:34 -0400 Subject: [PATCH 01/11] checkpoint --- .../xrpl4j/codec/binary/XrplBinaryCodec.java | 2 +- .../codec/binary/serdes/BinaryParser.java | 2 +- .../codec/binary/serdes/BinarySerializer.java | 4 +- .../xrpl4j/codec/binary/types/AmountType.java | 83 +- .../codec/binary/types/Hash192Type.java | 31 + .../xrpl4j/codec/binary/types/MptAmount.java | 59 + .../codec/binary/types/SerializedType.java | 61 +- .../xrpl4j/codec/binary/types/UInt64Type.java | 15 +- .../src/main/resources/definitions.json | 1904 ++++------------- .../codec/binary/types/AmountTypeTest.java | 39 + .../codec/binary/types/HashTypeTest.java | 3 + .../binary/types/UInt64TypeUnitTest.java | 59 +- .../bc/BcDerivedKeySignatureServiceTest.java | 31 +- .../src/test/resources/data-driven-tests.json | 131 ++ 14 files changed, 893 insertions(+), 1531 deletions(-) create mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/Hash192Type.java create mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/MptAmount.java diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/XrplBinaryCodec.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/XrplBinaryCodec.java index e3dfc2a33..faa272554 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/XrplBinaryCodec.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/XrplBinaryCodec.java @@ -146,7 +146,7 @@ public String encodeForSigningClaim(String json) throws JsonProcessingException } UnsignedByteArray channel = UnsignedByteArray.fromHex(node.get(CHANNEL_FIELD_NAME).asText()); UnsignedByteArray amount = UnsignedByteArray.of( - new UInt64Type(UnsignedLong.valueOf(node.get(AMOUNT_FIELD_NAME).asText())).toBytes() + new UInt64Type(UnsignedLong.valueOf(node.get(AMOUNT_FIELD_NAME).asText()), 16).toBytes() ); UnsignedByteArray byteArray = UnsignedByteArray.empty(); diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/serdes/BinaryParser.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/serdes/BinaryParser.java index 16b8cb998..2293c9540 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/serdes/BinaryParser.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/serdes/BinaryParser.java @@ -195,7 +195,7 @@ public > T readType(Class type) { * @return The type associated with the given field. */ public SerializedType typeForField(FieldInstance field) { - return SerializedType.getTypeByName(field.type()); + return SerializedType.getTypeByName(field.type(), field.name()); } /** diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/serdes/BinarySerializer.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/serdes/BinarySerializer.java index 2ef048ba2..05a31df73 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/serdes/BinarySerializer.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/serdes/BinarySerializer.java @@ -109,9 +109,9 @@ public void writeFieldAndValue(final FieldInstance field, final JsonNode value) Objects.requireNonNull(value); SerializedType typedValue; if (field.name().equals("BaseFee")) { - typedValue = SerializedType.getTypeByName(field.type()).fromHex(value.asText()); + typedValue = SerializedType.getTypeByName(field.type(), field.name()).fromHex(value.asText()); } else { - typedValue = SerializedType.getTypeByName(field.type()).fromJson(value); + typedValue = SerializedType.getTypeByName(field.type(), field.name()).fromJson(value); } writeFieldAndValue(field, typedValue); } diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/AmountType.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/AmountType.java index a186dc568..1a81c8509 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/AmountType.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/AmountType.java @@ -24,6 +24,8 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.TextNode; +import com.google.common.base.Preconditions; +import com.google.common.io.BaseEncoding; import com.google.common.primitives.UnsignedLong; import org.xrpl.xrpl4j.codec.addresses.ByteUtils; import org.xrpl.xrpl4j.codec.addresses.UnsignedByte; @@ -50,6 +52,7 @@ class AmountType extends SerializedType { public static final String ZERO_CURRENCY_AMOUNT_HEX = "8000000000000000"; public static final int NATIVE_AMOUNT_BYTE_LENGTH = 8; public static final int CURRENCY_AMOUNT_BYTE_LENGTH = 48; + public static final int MPT_AMOUNT_BYTE_LENGTH = 33; private static final int MAX_IOU_PRECISION = 16; /** @@ -142,14 +145,21 @@ private static void verifyNoDecimal(BigDecimal decimal) { @Override public AmountType fromParser(BinaryParser parser) { - boolean isXrp = !parser.peek().isNthBitSet(1); - int numBytes = isXrp ? NATIVE_AMOUNT_BYTE_LENGTH : CURRENCY_AMOUNT_BYTE_LENGTH; + UnsignedByte nextByte = parser.peek(); + Preconditions.checkArgument( + !(nextByte.isNthBitSet(1) && nextByte.isNthBitSet(3)), + "Invalid STAmount: First and third leading bits are set, which indicates the amount is both an IOU and an MPT." + ); + boolean isXrpOrMpt = !nextByte.isNthBitSet(1); + boolean isXrp = !nextByte.isNthBitSet(3); + int numBytes = isXrpOrMpt ? (isXrp ? NATIVE_AMOUNT_BYTE_LENGTH : MPT_AMOUNT_BYTE_LENGTH) : CURRENCY_AMOUNT_BYTE_LENGTH; return new AmountType(parser.read(numBytes)); } @Override public AmountType fromJson(JsonNode value) throws JsonProcessingException { if (value.isValueNode()) { + // XRP Amount assertXrpIsValid(value.asText()); final boolean isValueNegative = value.asText().startsWith("-"); @@ -166,22 +176,45 @@ public AmountType fromJson(JsonNode value) throws JsonProcessingException { rawBytes[0] |= 0x40; } return new AmountType(UnsignedByteArray.of(rawBytes)); - } + } else if (!value.has("mpt_issuance_id")) { + // IOU Amount + Amount amount = objectMapper.treeToValue(value, Amount.class); + BigDecimal number = new BigDecimal(amount.value()); + + UnsignedByteArray result = number.unscaledValue().equals(BigInteger.ZERO) ? + UnsignedByteArray.fromHex(ZERO_CURRENCY_AMOUNT_HEX) : + getAmountBytes(number); + + UnsignedByteArray currency = new CurrencyType().fromJson(value.get("currency")).value(); + UnsignedByteArray issuer = new AccountIdType().fromJson(value.get("issuer")).value(); + + result.append(currency); + result.append(issuer); - Amount amount = objectMapper.treeToValue(value, Amount.class); - BigDecimal number = new BigDecimal(amount.value()); + return new AmountType(result); + } else { + // MPT Amount + MptAmount amount = objectMapper.treeToValue(value, MptAmount.class); - UnsignedByteArray result = number.unscaledValue().equals(BigInteger.ZERO) ? - UnsignedByteArray.fromHex(ZERO_CURRENCY_AMOUNT_HEX) : - getAmountBytes(number); + if (FluentCompareTo.is(amount.unsignedLongValue()).greaterThan(UnsignedLong.valueOf(Long.MAX_VALUE))) { + throw new IllegalArgumentException("Invalid MPT amount: given value requires 64 bits, only 63 allowed."); + } - UnsignedByteArray currency = new CurrencyType().fromJson(value.get("currency")).value(); - UnsignedByteArray issuer = new AccountIdType().fromJson(value.get("issuer")).value(); + UnsignedByteArray amountBytes = UnsignedByteArray.fromHex( + ByteUtils.padded( + amount.unsignedLongValue().toString(16), + 16 // <-- 64 / 4 + ) + ); + UnsignedByteArray issuanceIdBytes = new Hash192Type().fromJson(new TextNode(amount.mptIssuanceId())).value(); - result.append(currency); - result.append(issuer); + // MPT Amounts always have 0110000 as its first byte. + UnsignedByteArray result = UnsignedByteArray.of(UnsignedByte.of(0x60)); + result.append(amountBytes); + result.append(issuanceIdBytes); - return new AmountType(result); + return new AmountType(result); + } } private UnsignedByteArray getAmountBytes(BigDecimal number) { @@ -213,7 +246,21 @@ public JsonNode toJson() { value = value.negate(); } return new TextNode(value.toString()); + } else if (this.isMpt()) { + BinaryParser parser = new BinaryParser(this.toHex()); + // We know the first byte already based on this.isMpt() + parser.skip(1); + UnsignedLong amount = parser.readUInt64(); + UnsignedByteArray issuanceId = new Hash192Type().fromParser(parser).value(); + + MptAmount mptAmount = MptAmount.builder() + .value(amount.toString(10)) + .mptIssuanceId(issuanceId.hexValue()) + .build(); + + return objectMapper.valueToTree(mptAmount); } else { + // Must be IOU if it's not XRP or MPT BinaryParser parser = new BinaryParser(this.toHex()); UnsignedByteArray mantissa = parser.read(8); final SerializedType currency = new CurrencyType().fromParser(parser); @@ -251,8 +298,14 @@ public JsonNode toJson() { * @return {@code true} if this AmountType is native; {@code false} otherwise. */ private boolean isNative() { - // 1st bit in 1st byte is set to 0 for native XRP - return (toBytes()[0] & 0x80) == 0; + // 1st bit in 1st byte is set to 0 for native XRP, 3rd bit is also 0. + // 0xA0 is 1010 0000 + return (toBytes()[0] & 0xA0) == 0; + } + + private boolean isMpt() { + // 1st bit in 1st byte is 0, 2nd bit is 1, and 3rd bit is 1 + return (toBytes()[0] & 0xA0) == 0x20; } /** diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/Hash192Type.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/Hash192Type.java new file mode 100644 index 000000000..c0056f4c9 --- /dev/null +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/Hash192Type.java @@ -0,0 +1,31 @@ +package org.xrpl.xrpl4j.codec.binary.types; + +import com.fasterxml.jackson.databind.JsonNode; +import org.xrpl.xrpl4j.codec.addresses.UnsignedByteArray; +import org.xrpl.xrpl4j.codec.binary.serdes.BinaryParser; + +/** + * Codec for XRPL Hash192 type. + */ +public class Hash192Type extends HashType { + + public static final int WIDTH = 24; + + public Hash192Type() { + this(UnsignedByteArray.ofSize(WIDTH)); + } + + public Hash192Type(UnsignedByteArray list) { + super(list, WIDTH); + } + + @Override + public Hash192Type fromParser(BinaryParser parser) { + return new Hash192Type(parser.read(WIDTH)); + } + + @Override + public Hash192Type fromJson(JsonNode node) { + return new Hash192Type(UnsignedByteArray.fromHex(node.asText())); + } +} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/MptAmount.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/MptAmount.java new file mode 100644 index 000000000..68e7e0458 --- /dev/null +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/MptAmount.java @@ -0,0 +1,59 @@ +package org.xrpl.xrpl4j.codec.binary.types; + +/*- + * ========================LICENSE_START================================= + * xrpl4j :: binary-codec + * %% + * 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.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.UnsignedLong; +import org.immutables.value.Value; +import org.immutables.value.Value.Immutable; + +/** + * Model for XRPL MPT Amount JSON. + */ +@Immutable +@JsonSerialize(as = ImmutableMptAmount.class) +@JsonDeserialize(as = ImmutableMptAmount.class) +interface MptAmount { + + /** + * Construct a {@code MptAmount} builder. + * + * @return An {@link ImmutableMptAmount.Builder}. + */ + static ImmutableMptAmount.Builder builder() { + return ImmutableMptAmount.builder(); + } + + String value(); + + @JsonIgnore + @Value.Derived + default UnsignedLong unsignedLongValue() { + return UnsignedLong.valueOf(value()); + } + + @JsonProperty("mpt_issuance_id") + String mptIssuanceId(); + +} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java index 42ad767d9..a685c7c7b 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java @@ -24,13 +24,15 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.TextNode; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Sets; import org.xrpl.xrpl4j.codec.addresses.UnsignedByteArray; import org.xrpl.xrpl4j.codec.binary.BinaryCodecObjectMapperFactory; import org.xrpl.xrpl4j.codec.binary.serdes.BinaryParser; import java.util.Map; import java.util.Objects; -import java.util.function.Supplier; +import java.util.Set; +import java.util.function.Function; /** * Defines an abstract type serialization parent-class for all XRPL serialized type definitions. @@ -39,26 +41,34 @@ */ public abstract class SerializedType> { + private static final Set BASE_10_UINT64_FIELD_NAMES = Sets.newHashSet("MaximumAmount", "OutstandingAmount", "MPTAmount"); @SuppressWarnings("all") - private static final Map>> typeMap = - new ImmutableMap.Builder>>() - .put("AccountID", () -> new AccountIdType()) - .put("Amount", () -> new AmountType()) - .put("Blob", () -> new BlobType()) - .put("Currency", () -> new CurrencyType()) - .put("Hash128", () -> new Hash128Type()) - .put("Hash160", () -> new Hash160Type()) - .put("Hash256", () -> new Hash256Type()) - .put("PathSet", () -> new PathSetType()) - .put("STArray", () -> new STArrayType()) - .put("STObject", () -> new STObjectType()) - .put("UInt8", () -> new UInt8Type()) - .put("UInt16", () -> new UInt16Type()) - .put("UInt32", () -> new UInt32Type()) - .put("UInt64", () -> new UInt64Type()) - .put("Vector256", () -> new Vector256Type()) - .put("Issue", () -> new IssueType()) - .put("XChainBridge", () -> new XChainBridgeType()) + private static final Map>> typeMap = + new ImmutableMap.Builder>>() + .put("AccountID", fieldName -> new AccountIdType()) + .put("Amount", fieldName -> new AmountType()) + .put("Blob", fieldName -> new BlobType()) + .put("Currency", fieldName -> new CurrencyType()) + .put("Hash128", fieldName -> new Hash128Type()) + .put("Hash160", fieldName -> new Hash160Type()) + .put("Hash192", fieldName -> new Hash192Type()) + .put("Hash256", fieldName -> new Hash256Type()) + .put("PathSet", fieldName -> new PathSetType()) + .put("STArray", fieldName -> new STArrayType()) + .put("STObject", fieldName -> new STObjectType()) + .put("UInt8", fieldName -> new UInt8Type()) + .put("UInt16", fieldName -> new UInt16Type()) + .put("UInt32", fieldName -> new UInt32Type()) + .put("UInt64", fieldName -> { + if (BASE_10_UINT64_FIELD_NAMES.contains(fieldName)) { + return new UInt64Type(10); + } else { + return new UInt64Type(16); + } + }) + .put("Vector256", fieldName -> new Vector256Type()) + .put("Issue", fieldName -> new IssueType()) + .put("XChainBridge", fieldName -> new XChainBridgeType()) .build(); private final UnsignedByteArray bytes; @@ -69,12 +79,13 @@ public SerializedType(UnsignedByteArray bytes) { /** * Get the {@link SerializedType} for the supplied {@code name}. * - * @param name A {@link String} representing the name of a {@link SerializedType}. + * @param name A {@link String} representing the name of a {@link SerializedType}. + * @param fieldName The name of the field that is being serialized. * * @return A {@link SerializedType} for the supplied {@code name}. */ - public static SerializedType getTypeByName(String name) { - return typeMap.get(name).get(); + public static SerializedType getTypeByName(String name, String fieldName) { + return typeMap.get(name).apply(fieldName); } /** @@ -87,7 +98,9 @@ public static SerializedType getTypeByName(String name) { public static String getNameByType(SerializedType type) { return typeMap.entrySet() .stream() - .filter(entry -> entry.getValue().get().getClass().equals(type.getClass())) + // We only care about the class name, and the String passed to .apply is only used to figure + // out the radix of the JSON string for UInt64Types. Plus this method is only used in a test. + .filter(entry -> entry.getValue().apply("").getClass().equals(type.getClass())) .map(Map.Entry::getKey) .findAny() .orElse(null); diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UInt64Type.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UInt64Type.java index a08dfc05f..018561adb 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UInt64Type.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UInt64Type.java @@ -30,27 +30,30 @@ */ public class UInt64Type extends UIntType { - public UInt64Type() { - this(UnsignedLong.ZERO); + private final int radix; + + public UInt64Type(int radix) { + this(UnsignedLong.ZERO, radix); } - public UInt64Type(UnsignedLong value) { + public UInt64Type(UnsignedLong value, int radix) { super(value, 64); + this.radix = radix; } @Override public UInt64Type fromParser(BinaryParser parser) { - return new UInt64Type(parser.readUInt64()); + return new UInt64Type(parser.readUInt64(), radix); } @Override public UInt64Type fromJson(JsonNode value) { // STUInt64s are represented as hex-encoded Strings in JSON. - return new UInt64Type(UnsignedLong.valueOf(value.asText(), 16)); + return new UInt64Type(UnsignedLong.valueOf(value.asText(), radix), radix); } @Override public JsonNode toJson() { - return new TextNode(UnsignedLong.valueOf(toHex(), 16).toString(16)); + return new TextNode(UnsignedLong.valueOf(toHex(), 16).toString(radix).toUpperCase()); } } diff --git a/xrpl4j-core/src/main/resources/definitions.json b/xrpl4j-core/src/main/resources/definitions.json index 797be9ce2..6a82327a8 100644 --- a/xrpl4j-core/src/main/resources/definitions.json +++ b/xrpl4j-core/src/main/resources/definitions.json @@ -1,35 +1,29 @@ { "TYPES": { + "Validation": 10003, "Done": -1, - "Unknown": -2, - "NotPresent": 0, - "UInt16": 1, - "UInt32": 2, - "UInt64": 3, "Hash128": 4, - "Hash256": 5, - "Amount": 6, "Blob": 7, "AccountID": 8, - "STObject": 14, - "STArray": 15, + "Amount": 6, + "Hash256": 5, "UInt8": 16, - "Hash160": 17, - "PathSet": 18, "Vector256": 19, - "UInt96": 20, - "UInt192": 21, - "UInt384": 22, - "UInt512": 23, - "Issue": 24, - "XChainBridge": 25, - "Currency": 26, + "STObject": 14, + "Unknown": -2, "Transaction": 10001, + "Hash160": 17, + "PathSet": 18, "LedgerEntry": 10002, - "Validation": 10003, - "Metadata": 10004 + "UInt16": 1, + "NotPresent": 0, + "UInt64": 3, + "UInt32": 2, + "STArray": 15 }, "LEDGER_ENTRY_TYPES": { + "Any": -3, + "Child": -2, "Invalid": -1, "AccountRoot": 97, "DirectoryNode": 100, @@ -37,27 +31,18 @@ "Ticket": 84, "SignerList": 83, "Offer": 111, - "Bridge": 105, "LedgerHashes": 104, "Amendments": 102, - "XChainOwnedClaimID": 113, - "XChainOwnedCreateAccountClaimID": 116, "FeeSettings": 115, "Escrow": 117, "PayChannel": 120, - "Check": 67, "DepositPreauth": 112, - "NegativeUNL": 78, - "NFTokenPage": 80, - "NFTokenOffer": 55, - "AMM": 121, - "DID": 73, - "Oracle": 128, - "Any": -3, - "Child": -2, + "Check": 67, "Nickname": 110, "Contract": 99, - "GeneratorMap": 103 + "NFTokenPage": 80, + "NFTokenOffer": 55, + "NegativeUNL": 78 }, "FIELDS": [ [ @@ -81,309 +66,209 @@ } ], [ - "ObjectEndMarker", + "LedgerEntryType", { "nth": 1, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "UInt16" } ], [ - "ArrayEndMarker", + "TransactionType", { - "nth": 1, + "nth": 2, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" - } - ], - [ - "hash", - { - "nth": 257, - "isVLEncoded": false, - "isSerialized": false, - "isSigningField": false, - "type": "Hash256" - } - ], - [ - "index", - { - "nth": 258, - "isVLEncoded": false, - "isSerialized": false, - "isSigningField": false, - "type": "Hash256" - } - ], - [ - "taker_gets_funded", - { - "nth": 258, - "isVLEncoded": false, - "isSerialized": false, - "isSigningField": false, - "type": "Amount" - } - ], - [ - "taker_pays_funded", - { - "nth": 259, - "isVLEncoded": false, - "isSerialized": false, - "isSigningField": false, - "type": "Amount" - } - ], - [ - "LedgerEntry", - { - "nth": 257, - "isVLEncoded": false, - "isSerialized": false, - "isSigningField": false, - "type": "LedgerEntry" - } - ], - [ - "Transaction", - { - "nth": 257, - "isVLEncoded": false, - "isSerialized": false, - "isSigningField": false, - "type": "Transaction" - } - ], - [ - "Validation", - { - "nth": 257, - "isVLEncoded": false, - "isSerialized": false, - "isSigningField": false, - "type": "Validation" + "type": "UInt16" } ], [ - "Metadata", + "SignerWeight", { - "nth": 257, + "nth": 3, "isVLEncoded": false, - "isSerialized": false, - "isSigningField": false, - "type": "Metadata" + "isSerialized": true, + "isSigningField": true, + "type": "UInt16" } ], [ - "CloseResolution", + "TransferFee", { - "nth": 1, + "nth": 4, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt8" + "type": "UInt16" } ], [ - "Method", + "Flags", { "nth": 2, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt8" + "type": "UInt32" } ], [ - "TransactionResult", + "SourceTag", { "nth": 3, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt8" + "type": "UInt32" } ], [ - "Scale", + "Sequence", { "nth": 4, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt8" + "type": "UInt32" } ], [ - "TickSize", + "PreviousTxnLgrSeq", { - "nth": 16, + "nth": 5, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt8" + "type": "UInt32" } ], [ - "UNLModifyDisabling", + "LedgerSequence", { - "nth": 17, + "nth": 6, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt8" + "type": "UInt32" } ], [ - "HookResult", + "CloseTime", { - "nth": 18, + "nth": 7, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt8" + "type": "UInt32" } ], [ - "WasLockingChainSend", + "ParentCloseTime", { - "nth": 19, + "nth": 8, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt8" + "type": "UInt32" } ], [ - "LedgerEntryType", + "SigningTime", { - "nth": 1, + "nth": 9, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt16" + "type": "UInt32" } ], [ - "TransactionType", + "Expiration", { - "nth": 2, + "nth": 10, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt16" + "type": "UInt32" } ], [ - "SignerWeight", + "TransferRate", { - "nth": 3, + "nth": 11, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt16" + "type": "UInt32" } ], [ - "TransferFee", + "WalletSize", { - "nth": 4, + "nth": 12, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt16" + "type": "UInt32" } ], [ - "TradingFee", + "OwnerCount", { - "nth": 5, + "nth": 13, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt16" + "type": "UInt32" } ], [ - "DiscountedFee", + "DestinationTag", { - "nth": 6, + "nth": 14, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt16" + "type": "UInt32" } ], [ - "Version", + "HighQualityIn", { "nth": 16, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt16" + "type": "UInt32" } ], [ - "HookStateChangeCount", + "HighQualityOut", { "nth": 17, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt16" + "type": "UInt32" } ], [ - "HookEmitCount", + "LowQualityIn", { "nth": 18, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt16" - } - ], - [ - "HookExecutionIndex", - { - "nth": 19, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt16" - } - ], - [ - "HookApiVersion", - { - "nth": 20, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt16" - } - ], - [ - "NetworkID", - { - "nth": 1, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, "type": "UInt32" } ], [ - "Flags", + "LowQualityOut", { - "nth": 2, + "nth": 19, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -391,9 +276,9 @@ } ], [ - "SourceTag", + "QualityIn", { - "nth": 3, + "nth": 20, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -401,9 +286,9 @@ } ], [ - "Sequence", + "QualityOut", { - "nth": 4, + "nth": 21, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -411,9 +296,9 @@ } ], [ - "PreviousTxnLgrSeq", + "StampEscrow", { - "nth": 5, + "nth": 22, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -421,9 +306,9 @@ } ], [ - "LedgerSequence", + "BondAmount", { - "nth": 6, + "nth": 23, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -431,939 +316,239 @@ } ], [ - "CloseTime", + "LoadFee", { - "nth": 7, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "ParentCloseTime", - { - "nth": 8, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "SigningTime", - { - "nth": 9, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "Expiration", - { - "nth": 10, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "TransferRate", - { - "nth": 11, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "WalletSize", - { - "nth": 12, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "OwnerCount", - { - "nth": 13, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "DestinationTag", - { - "nth": 14, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "LastUpdateTime", - { - "nth": 15, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "HighQualityIn", - { - "nth": 16, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "HighQualityOut", - { - "nth": 17, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "LowQualityIn", - { - "nth": 18, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "LowQualityOut", - { - "nth": 19, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "QualityIn", - { - "nth": 20, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "QualityOut", - { - "nth": 21, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "StampEscrow", - { - "nth": 22, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "BondAmount", - { - "nth": 23, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "LoadFee", - { - "nth": 24, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "OfferSequence", - { - "nth": 25, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "FirstLedgerSequence", - { - "nth": 26, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "LastLedgerSequence", - { - "nth": 27, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "TransactionIndex", - { - "nth": 28, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "OperationLimit", - { - "nth": 29, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "ReferenceFeeUnits", - { - "nth": 30, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "ReserveBase", - { - "nth": 31, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "ReserveIncrement", - { - "nth": 32, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "SetFlag", - { - "nth": 33, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "ClearFlag", - { - "nth": 34, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "SignerQuorum", - { - "nth": 35, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "CancelAfter", - { - "nth": 36, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "FinishAfter", - { - "nth": 37, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "SignerListID", - { - "nth": 38, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "SettleDelay", - { - "nth": 39, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "TicketCount", - { - "nth": 40, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "TicketSequence", - { - "nth": 41, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "NFTokenTaxon", - { - "nth": 42, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "MintedNFTokens", - { - "nth": 43, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "BurnedNFTokens", - { - "nth": 44, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "HookStateCount", - { - "nth": 45, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "EmitGeneration", - { - "nth": 46, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "VoteWeight", - { - "nth": 48, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "FirstNFTokenSequence", - { - "nth": 50, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "OracleDocumentID", - { - "nth": 51, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "IndexNext", - { - "nth": 1, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "IndexPrevious", - { - "nth": 2, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "BookNode", - { - "nth": 3, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "OwnerNode", - { - "nth": 4, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "BaseFee", - { - "nth": 5, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "ExchangeRate", - { - "nth": 6, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "LowNode", - { - "nth": 7, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "HighNode", - { - "nth": 8, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "DestinationNode", - { - "nth": 9, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "Cookie", - { - "nth": 10, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "ServerVersion", - { - "nth": 11, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "NFTokenOfferNode", - { - "nth": 12, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "EmitBurden", - { - "nth": 13, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "HookOn", - { - "nth": 16, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "HookInstructionCount", - { - "nth": 17, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "HookReturnCode", - { - "nth": 18, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "ReferenceCount", - { - "nth": 19, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "XChainClaimID", - { - "nth": 20, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "XChainAccountCreateCount", - { - "nth": 21, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "XChainAccountClaimCount", - { - "nth": 22, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "AssetPrice", - { - "nth": 23, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "EmailHash", - { - "nth": 1, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Hash128" - } - ], - [ - "TakerPaysCurrency", - { - "nth": 1, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Hash160" - } - ], - [ - "TakerPaysIssuer", - { - "nth": 2, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Hash160" - } - ], - [ - "TakerGetsCurrency", - { - "nth": 3, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Hash160" - } - ], - [ - "TakerGetsIssuer", - { - "nth": 4, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Hash160" - } - ], - [ - "LedgerHash", - { - "nth": 1, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Hash256" - } - ], - [ - "ParentHash", - { - "nth": 2, + "nth": 24, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "UInt32" } ], [ - "TransactionHash", + "OfferSequence", { - "nth": 3, + "nth": 25, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "UInt32" } ], [ - "AccountHash", + "FirstLedgerSequence", { - "nth": 4, + "nth": 26, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "UInt32" } ], [ - "PreviousTxnID", + "LastLedgerSequence", { - "nth": 5, + "nth": 27, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "UInt32" } ], [ - "LedgerIndex", + "TransactionIndex", { - "nth": 6, + "nth": 28, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "UInt32" } ], [ - "WalletLocator", + "OperationLimit", { - "nth": 7, + "nth": 29, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "UInt32" } ], [ - "RootIndex", + "ReferenceFeeUnits", { - "nth": 8, + "nth": 30, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "UInt32" } ], [ - "AccountTxnID", + "ReserveBase", { - "nth": 9, + "nth": 31, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "UInt32" } ], [ - "NFTokenID", + "ReserveIncrement", { - "nth": 10, + "nth": 32, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "UInt32" } ], [ - "EmitParentTxnID", + "SetFlag", { - "nth": 11, + "nth": 33, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "UInt32" } ], [ - "EmitNonce", + "ClearFlag", { - "nth": 12, + "nth": 34, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "UInt32" } ], [ - "EmitHookHash", + "SignerQuorum", { - "nth": 13, + "nth": 35, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "UInt32" } ], [ - "AMMID", + "CancelAfter", { - "nth": 14, + "nth": 36, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "UInt32" } ], [ - "BookDirectory", + "FinishAfter", { - "nth": 16, + "nth": 37, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "UInt32" } ], [ - "InvoiceID", + "IndexNext", { - "nth": 17, + "nth": 1, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "UInt64" } ], [ - "Nickname", + "IndexPrevious", { - "nth": 18, + "nth": 2, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "UInt64" } ], [ - "Amendment", + "BookNode", { - "nth": 19, + "nth": 3, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "UInt64" } ], [ - "Digest", + "OwnerNode", { - "nth": 21, + "nth": 4, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "UInt64" } ], [ - "Channel", + "BaseFee", { - "nth": 22, + "nth": 5, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "UInt64" } ], [ - "ConsensusHash", + "ExchangeRate", { - "nth": 23, + "nth": 6, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "UInt64" } ], [ - "CheckID", + "LowNode", { - "nth": 24, + "nth": 7, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "UInt64" } ], [ - "ValidatedHash", + "HighNode", { - "nth": 25, + "nth": 8, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "UInt64" } ], [ - "PreviousPageMin", + "EmailHash", { - "nth": 26, + "nth": 1, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "Hash128" } ], [ - "NextPageMin", + "LedgerHash", { - "nth": 27, + "nth": 1, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1371,9 +556,9 @@ } ], [ - "NFTokenBuyOffer", + "ParentHash", { - "nth": 28, + "nth": 2, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1381,9 +566,9 @@ } ], [ - "NFTokenSellOffer", + "TransactionHash", { - "nth": 29, + "nth": 3, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1391,9 +576,9 @@ } ], [ - "HookStateKey", + "AccountHash", { - "nth": 30, + "nth": 4, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1401,9 +586,9 @@ } ], [ - "HookHash", + "PreviousTxnID", { - "nth": 31, + "nth": 5, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1411,9 +596,9 @@ } ], [ - "HookNamespace", + "LedgerIndex", { - "nth": 32, + "nth": 6, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1421,9 +606,9 @@ } ], [ - "HookSetTxnID", + "WalletLocator", { - "nth": 33, + "nth": 7, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1431,119 +616,119 @@ } ], [ - "Amount", + "RootIndex", { - "nth": 1, + "nth": 8, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Amount" + "type": "Hash256" } ], [ - "Balance", + "AccountTxnID", { - "nth": 2, + "nth": 9, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Amount" + "type": "Hash256" } ], [ - "LimitAmount", + "NFTokenID", { - "nth": 3, + "nth": 10, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Amount" + "type": "Hash256" } ], [ - "TakerPays", + "BookDirectory", { - "nth": 4, + "nth": 16, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Amount" + "type": "Hash256" } ], [ - "TakerGets", + "InvoiceID", { - "nth": 5, + "nth": 17, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Amount" + "type": "Hash256" } ], [ - "LowLimit", + "Nickname", { - "nth": 6, + "nth": 18, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Amount" + "type": "Hash256" } ], [ - "HighLimit", + "Amendment", { - "nth": 7, + "nth": 19, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Amount" + "type": "Hash256" } ], [ - "Fee", + "TicketID", { - "nth": 8, + "nth": 20, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Amount" + "type": "Hash256" } ], [ - "SendMax", + "Digest", { - "nth": 9, + "nth": 21, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Amount" + "type": "Hash256" } ], [ - "DeliverMin", + "hash", { - "nth": 10, + "nth": 257, "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Amount" + "isSerialized": false, + "isSigningField": false, + "type": "Hash256" } ], [ - "Amount2", + "index", { - "nth": 11, + "nth": 258, "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Amount" + "isSerialized": false, + "isSigningField": false, + "type": "Hash256" } ], [ - "BidMin", + "Amount", { - "nth": 12, + "nth": 1, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1551,9 +736,9 @@ } ], [ - "BidMax", + "Balance", { - "nth": 13, + "nth": 2, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1561,9 +746,9 @@ } ], [ - "MinimumOffer", + "LimitAmount", { - "nth": 16, + "nth": 3, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1571,9 +756,9 @@ } ], [ - "RippleEscrow", + "TakerPays", { - "nth": 17, + "nth": 4, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1581,9 +766,9 @@ } ], [ - "DeliveredAmount", + "TakerGets", { - "nth": 18, + "nth": 5, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1591,9 +776,9 @@ } ], [ - "NFTokenBrokerFee", + "LowLimit", { - "nth": 19, + "nth": 6, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1601,9 +786,9 @@ } ], [ - "BaseFeeDrops", + "HighLimit", { - "nth": 22, + "nth": 7, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1611,9 +796,9 @@ } ], [ - "ReserveBaseDrops", + "Fee", { - "nth": 23, + "nth": 8, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1621,9 +806,9 @@ } ], [ - "ReserveIncrementDrops", + "SendMax", { - "nth": 24, + "nth": 9, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1631,9 +816,9 @@ } ], [ - "LPTokenOut", + "DeliverMin", { - "nth": 25, + "nth": 10, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1641,9 +826,9 @@ } ], [ - "LPTokenIn", + "MinimumOffer", { - "nth": 26, + "nth": 16, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1651,9 +836,9 @@ } ], [ - "EPrice", + "RippleEscrow", { - "nth": 27, + "nth": 17, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1661,9 +846,9 @@ } ], [ - "Price", + "DeliveredAmount", { - "nth": 28, + "nth": 18, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1671,9 +856,9 @@ } ], [ - "SignatureReward", + "NFTokenBrokerFee", { - "nth": 29, + "nth": 19, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1681,22 +866,22 @@ } ], [ - "MinAccountCreateAmount", + "taker_gets_funded", { - "nth": 30, + "nth": 258, "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, + "isSerialized": false, + "isSigningField": false, "type": "Amount" } ], [ - "LPTokenBalance", + "taker_pays_funded", { - "nth": 31, + "nth": 259, "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, + "isSerialized": false, + "isSigningField": false, "type": "Amount" } ], @@ -1900,86 +1085,6 @@ "type": "Blob" } ], - [ - "HookStateData", - { - "nth": 22, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "Blob" - } - ], - [ - "HookReturnString", - { - "nth": 23, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "Blob" - } - ], - [ - "HookParameterName", - { - "nth": 24, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "Blob" - } - ], - [ - "HookParameterValue", - { - "nth": 25, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "Blob" - } - ], - [ - "DIDDocument", - { - "nth": 26, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "Blob" - } - ], - [ - "Data", - { - "nth": 27, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "Blob" - } - ], - [ - "AssetClass", - { - "nth": 28, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "Blob" - } - ], - [ - "Provider", - { - "nth": 29, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "Blob" - } - ], [ "Account", { @@ -2041,49 +1146,9 @@ } ], [ - "RegularKey", - { - "nth": 8, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "AccountID" - } - ], - [ - "NFTokenMinter", - { - "nth": 9, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "AccountID" - } - ], - [ - "EmitCallback", - { - "nth": 10, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "AccountID" - } - ], - [ - "HookAccount", - { - "nth": 16, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "AccountID" - } - ], - [ - "OtherChainSource", + "Target", { - "nth": 18, + "nth": 7, "isVLEncoded": true, "isSerialized": true, "isSigningField": true, @@ -2091,9 +1156,9 @@ } ], [ - "OtherChainDestination", + "RegularKey", { - "nth": 19, + "nth": 8, "isVLEncoded": true, "isSerialized": true, "isSigningField": true, @@ -2101,9 +1166,9 @@ } ], [ - "AttestationSignerAccount", + "NFTokenMinter", { - "nth": 20, + "nth": 9, "isVLEncoded": true, "isSerialized": true, "isSigningField": true, @@ -2111,633 +1176,623 @@ } ], [ - "AttestationRewardAccount", + "ObjectEndMarker", { - "nth": 21, - "isVLEncoded": true, + "nth": 1, + "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "AccountID" + "type": "STObject" } ], [ - "LockingChainDoor", + "TransactionMetaData", { - "nth": 22, - "isVLEncoded": true, + "nth": 2, + "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "AccountID" + "type": "STObject" } ], [ - "IssuingChainDoor", + "CreatedNode", { - "nth": 23, - "isVLEncoded": true, + "nth": 3, + "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "AccountID" + "type": "STObject" } ], [ - "Indexes", + "DeletedNode", { - "nth": 1, - "isVLEncoded": true, + "nth": 4, + "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Vector256" + "type": "STObject" } ], [ - "Hashes", + "ModifiedNode", { - "nth": 2, - "isVLEncoded": true, + "nth": 5, + "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Vector256" + "type": "STObject" } ], [ - "Amendments", + "PreviousFields", { - "nth": 3, - "isVLEncoded": true, + "nth": 6, + "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Vector256" + "type": "STObject" } ], [ - "NFTokenOffers", + "FinalFields", { - "nth": 4, - "isVLEncoded": true, + "nth": 7, + "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Vector256" + "type": "STObject" } ], [ - "Paths", + "NewFields", { - "nth": 1, + "nth": 8, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "PathSet" + "type": "STObject" } ], [ - "BaseAsset", + "TemplateEntry", { - "nth": 1, + "nth": 9, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Currency" + "type": "STObject" } ], [ - "QuoteAsset", + "Memo", { - "nth": 2, + "nth": 10, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Currency" + "type": "STObject" } ], [ - "LockingChainIssue", + "SignerEntry", { - "nth": 1, + "nth": 11, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Issue" + "type": "STObject" } ], [ - "IssuingChainIssue", + "NFToken", { - "nth": 2, + "nth": 12, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Issue" + "type": "STObject" } ], [ - "Asset", + "Signer", { - "nth": 3, + "nth": 16, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Issue" + "type": "STObject" } ], [ - "Asset2", + "Majority", { - "nth": 4, + "nth": 18, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Issue" + "type": "STObject" } ], [ - "XChainBridge", + "DisabledValidator", { - "nth": 1, + "nth": 19, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "XChainBridge" + "type": "STObject" } ], [ - "TransactionMetaData", + "ArrayEndMarker", { - "nth": 2, + "nth": 1, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "STArray" } ], [ - "CreatedNode", + "Signers", { "nth": 3, "isVLEncoded": false, "isSerialized": true, - "isSigningField": true, - "type": "STObject" + "isSigningField": false, + "type": "STArray" } ], [ - "DeletedNode", + "SignerEntries", { "nth": 4, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "STArray" } ], [ - "ModifiedNode", + "Template", { "nth": 5, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "STArray" } ], [ - "PreviousFields", + "Necessary", { "nth": 6, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "STArray" } ], [ - "FinalFields", + "Sufficient", { "nth": 7, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "STArray" } ], [ - "NewFields", + "AffectedNodes", { "nth": 8, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "STArray" } ], [ - "TemplateEntry", + "Memos", { "nth": 9, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "STArray" } ], [ - "Memo", + "NFTokens", { "nth": 10, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "STArray" } ], [ - "SignerEntry", + "Majorities", { - "nth": 11, + "nth": 16, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "STArray" } ], [ - "NFToken", + "DisabledValidators", { - "nth": 12, + "nth": 17, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "STArray" } ], [ - "EmitDetails", + "CloseResolution", { - "nth": 13, + "nth": 1, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "UInt8" } ], [ - "Hook", + "Method", { - "nth": 14, + "nth": 2, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "UInt8" } ], [ - "Signer", + "TransactionResult", { - "nth": 16, + "nth": 3, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "UInt8" } ], [ - "Majority", + "TakerPaysCurrency", { - "nth": 18, + "nth": 1, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "Hash160" } ], [ - "DisabledValidator", + "TakerPaysIssuer", { - "nth": 19, + "nth": 2, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "Hash160" } ], [ - "EmittedTxn", + "TakerGetsCurrency", { - "nth": 20, + "nth": 3, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "Hash160" } ], [ - "HookExecution", + "TakerGetsIssuer", { - "nth": 21, + "nth": 4, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "Hash160" } ], [ - "HookDefinition", + "Paths", { - "nth": 22, + "nth": 1, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "PathSet" } ], [ - "HookParameter", + "Indexes", { - "nth": 23, - "isVLEncoded": false, + "nth": 1, + "isVLEncoded": true, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "Vector256" } ], [ - "HookGrant", + "Hashes", { - "nth": 24, - "isVLEncoded": false, + "nth": 2, + "isVLEncoded": true, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "Vector256" } ], [ - "VoteEntry", + "Amendments", { - "nth": 25, - "isVLEncoded": false, + "nth": 3, + "isVLEncoded": true, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "Vector256" } ], [ - "AuctionSlot", + "NFTokenOffers", { - "nth": 26, - "isVLEncoded": false, + "nth": 4, + "isVLEncoded": true, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "Vector256" } ], [ - "AuthAccount", + "Transaction", { - "nth": 27, + "nth": 1, "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STObject" + "isSerialized": false, + "isSigningField": false, + "type": "Transaction" } ], [ - "XChainClaimProofSig", + "LedgerEntry", { - "nth": 28, + "nth": 1, "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STObject" + "isSerialized": false, + "isSigningField": false, + "type": "LedgerEntry" } ], [ - "XChainCreateAccountProofSig", + "Validation", { - "nth": 29, + "nth": 1, "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STObject" + "isSerialized": false, + "isSigningField": false, + "type": "Validation" } ], [ - "XChainClaimAttestationCollectionElement", + "SignerListID", { - "nth": 30, + "nth": 38, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "UInt32" } ], [ - "XChainCreateAccountAttestationCollectionElement", + "SettleDelay", { - "nth": 31, + "nth": 39, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "UInt32" } ], [ - "PriceData", + "TicketCount", { - "nth": 32, + "nth": 40, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" - } - ], - [ - "Signers", - { - "nth": 3, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": false, - "type": "STArray" + "type": "UInt32" } ], [ - "SignerEntries", + "TicketSequence", { - "nth": 4, + "nth": 41, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" + "type": "UInt32" } ], [ - "Template", + "NFTokenTaxon", { - "nth": 5, + "nth": 42, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" + "type": "UInt32" } ], [ - "Necessary", + "MintedNFTokens", { - "nth": 6, + "nth": 43, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" + "type": "UInt32" } ], [ - "Sufficient", + "BurnedNFTokens", { - "nth": 7, + "nth": 44, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" + "type": "UInt32" } ], [ - "AffectedNodes", + "Channel", { - "nth": 8, + "nth": 22, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" + "type": "Hash256" } ], [ - "Memos", + "ConsensusHash", { - "nth": 9, + "nth": 23, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" + "type": "Hash256" } ], [ - "NFTokens", + "CheckID", { - "nth": 10, + "nth": 24, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" + "type": "Hash256" } ], [ - "Hooks", + "ValidatedHash", { - "nth": 11, + "nth": 25, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" + "type": "Hash256" } ], [ - "VoteSlots", + "PreviousPageMin", { - "nth": 12, + "nth": 26, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" + "type": "Hash256" } ], [ - "Majorities", + "NextPageMin", { - "nth": 16, + "nth": 27, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" + "type": "Hash256" } ], [ - "DisabledValidators", + "NFTokenBuyOffer", { - "nth": 17, + "nth": 28, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" + "type": "Hash256" } ], [ - "HookExecutions", + "NFTokenSellOffer", { - "nth": 18, + "nth": 29, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" + "type": "Hash256" } ], [ - "HookParameters", + "TickSize", { - "nth": 19, + "nth": 16, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" + "type": "UInt8" } ], [ - "HookGrants", + "UNLModifyDisabling", { - "nth": 20, + "nth": 17, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" + "type": "UInt8" } ], [ - "XChainClaimAttestations", + "DestinationNode", { - "nth": 21, + "nth": 9, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" + "type": "UInt64" } ], [ - "XChainCreateAccountAttestations", + "Cookie", { - "nth": 22, + "nth": 10, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" + "type": "UInt64" } ], [ - "PriceDataSeries", + "ServerVersion", { - "nth": 24, + "nth": 11, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" + "type": "UInt64" } ], [ - "AuthAccounts", + "NFTokenOfferNode", { - "nth": 25, + "nth": 12, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" + "type": "UInt64" } ] ], @@ -2755,10 +1810,6 @@ "telCAN_NOT_QUEUE_BLOCKED": -389, "telCAN_NOT_QUEUE_FEE": -388, "telCAN_NOT_QUEUE_FULL": -387, - "telWRONG_NETWORK": -386, - "telREQUIRES_NETWORK_ID": -385, - "telNETWORK_ID_MAKES_TX_NON_CANONICAL": -384, - "telENV_RPC_FAILED": -383, "temMALFORMED": -299, "temBAD_AMOUNT": -298, @@ -2793,21 +1844,10 @@ "temBAD_TICK_SIZE": -269, "temINVALID_ACCOUNT_ID": -268, "temCANNOT_PREAUTH_SELF": -267, - "temINVALID_COUNT": -266, - "temUNCERTAIN": -265, - "temUNKNOWN": -264, - "temSEQ_AND_TICKET": -263, - "temBAD_NFTOKEN_TRANSFER_FEE": -262, - "temBAD_AMM_TOKENS": -261, - "temXCHAIN_EQUAL_DOOR_ACCOUNTS": -260, - "temXCHAIN_BAD_PROOF": -259, - "temXCHAIN_BRIDGE_BAD_ISSUES": -258, - "temXCHAIN_BRIDGE_NONDOOR_OWNER": -257, - "temXCHAIN_BRIDGE_BAD_MIN_ACCOUNT_CREATE_AMOUNT": -256, - "temXCHAIN_BRIDGE_BAD_REWARD_AMOUNT": -255, - "temEMPTY_DID": -254, - "temARRAY_EMPTY": -253, - "temARRAY_TOO_LARGE": -252, + "temUNCERTAIN": -266, + "temUNKNOWN": -265, + "temSEQ_AND_TICKET": -264, + "temBAD_NFTOKEN_TRANSFER_FEE": -263, "tefFAILURE": -199, "tefALREADY": -198, @@ -2843,7 +1883,6 @@ "terNO_RIPPLE": -90, "terQUEUED": -89, "terPRE_TICKET": -88, - "terNO_AMM": -87, "tesSUCCESS": 0, @@ -2885,7 +1924,7 @@ "tecKILLED": 150, "tecHAS_OBLIGATIONS": 151, "tecTOO_SOON": 152, - "tecHOOK_REJECTED": 153, + "tecMAX_SEQUENCE_REACHED": 154, "tecNO_SUITABLE_NFTOKEN_PAGE": 155, "tecNFTOKEN_BUY_SELL_MISMATCH": 156, @@ -2894,39 +1933,12 @@ "tecINSUFFICIENT_FUNDS": 159, "tecOBJECT_NOT_FOUND": 160, "tecINSUFFICIENT_PAYMENT": 161, - "tecUNFUNDED_AMM": 162, - "tecAMM_BALANCE": 163, - "tecAMM_FAILED": 164, - "tecAMM_INVALID_TOKENS": 165, - "tecAMM_EMPTY": 166, - "tecAMM_NOT_EMPTY": 167, - "tecAMM_ACCOUNT": 168, - "tecINCOMPLETE": 169, - "tecXCHAIN_BAD_TRANSFER_ISSUE": 170, - "tecXCHAIN_NO_CLAIM_ID": 171, - "tecXCHAIN_BAD_CLAIM_ID": 172, - "tecXCHAIN_CLAIM_NO_QUORUM": 173, - "tecXCHAIN_PROOF_UNKNOWN_KEY": 174, - "tecXCHAIN_CREATE_ACCOUNT_NONXRP_ISSUE": 175, - "tecXCHAIN_WRONG_CHAIN": 176, - "tecXCHAIN_REWARD_MISMATCH": 177, - "tecXCHAIN_NO_SIGNERS_LIST": 178, - "tecXCHAIN_SENDING_ACCOUNT_MISMATCH": 179, - "tecXCHAIN_INSUFF_CREATE_AMOUNT": 180, - "tecXCHAIN_ACCOUNT_CREATE_PAST": 181, - "tecXCHAIN_ACCOUNT_CREATE_TOO_MANY": 182, - "tecXCHAIN_PAYMENT_FAILED": 183, - "tecXCHAIN_SELF_COMMIT": 184, - "tecXCHAIN_BAD_PUBLIC_KEY_ACCOUNT_PAIR": 185, - "tecXCHAIN_CREATE_ACCOUNT_DISABLED": 186, - "tecEMPTY_DID": 187, - "tecINVALID_UPDATE_TIME": 188, - "tecTOKEN_PAIR_NOT_FOUND": 189, - "tecARRAY_EMPTY": 190, - "tecARRAY_TOO_LARGE": 191 + "tecINCORRECT_ASSET": 162, + "tecTOO_MANY": 163 }, "TRANSACTION_TYPES": { "Invalid": -1, + "Payment": 0, "EscrowCreate": 1, "EscrowFinish": 2, @@ -2949,31 +1961,11 @@ "DepositPreauth": 19, "TrustSet": 20, "AccountDelete": 21, - "SetHook": 22, "NFTokenMint": 25, "NFTokenBurn": 26, "NFTokenCreateOffer": 27, "NFTokenCancelOffer": 28, "NFTokenAcceptOffer": 29, - "Clawback": 30, - "AMMCreate": 35, - "AMMDeposit": 36, - "AMMWithdraw": 37, - "AMMVote": 38, - "AMMBid": 39, - "AMMDelete": 40, - "XChainCreateClaimID": 41, - "XChainCommit": 42, - "XChainClaim": 43, - "XChainAccountCreateCommit": 44, - "XChainAddClaimAttestation": 45, - "XChainAddAccountCreateAttestation": 46, - "XChainModifyBridge": 47, - "XChainCreateBridge": 48, - "DIDSet": 49, - "DIDDelete": 50, - "OracleSet": 51, - "OracleDelete": 52, "EnableAmendment": 100, "SetFee": 101, "UNLModify": 102 diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/AmountTypeTest.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/AmountTypeTest.java index ccdcbca1d..6d3a476ac 100644 --- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/AmountTypeTest.java +++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/AmountTypeTest.java @@ -21,11 +21,14 @@ */ import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertThrows; import com.fasterxml.jackson.core.JsonProcessingException; +import com.google.common.primitives.UnsignedLong; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.provider.Arguments; +import org.xrpl.xrpl4j.codec.binary.serdes.BinaryParser; import java.io.IOException; import java.util.stream.Stream; @@ -217,4 +220,40 @@ void encodeLargeNegativeCurrencyAmount() { assertThat(codec.fromJson(json).toHex()).isEqualTo(hex); } + @Test + void encodeDecodeMptAmount() { + String json = "{\"value\":\"100\",\"mpt_issuance_id\":\"00002403C84A0A28E0190E208E982C352BBD5006600555CF\"}"; + AmountType fromJson = codec.fromJson(json); + assertThat(fromJson.toHex()) + .isEqualTo("60000000000000006400002403C84A0A28E0190E208E982C352BBD5006600555CF"); + assertThat(fromJson.toJson().toString()).isEqualTo(json); + } + + @Test + void encodeDecodeLargestAmount() { + String json = "{\"value\":\"9223372036854775807\"," + + "\"mpt_issuance_id\":\"00002403C84A0A28E0190E208E982C352BBD5006600555CF\"}"; + AmountType fromJson = codec.fromJson(json); + assertThat(fromJson.toHex()) + .isEqualTo("607FFFFFFFFFFFFFFF00002403C84A0A28E0190E208E982C352BBD5006600555CF"); + assertThat(fromJson.toJson().toString()).isEqualTo(json); + } + + @Test + void encodeMptAmountWithMoreThan63BitAmountThrows() { + UnsignedLong maxLongPlusOne = UnsignedLong.valueOf(Long.MAX_VALUE).plus(UnsignedLong.ONE); + String json = "{\"value\":\"" + maxLongPlusOne + "\"," + + "\"mpt_issuance_id\":\"00002403C84A0A28E0190E208E982C352BBD5006600555CF\"}"; + assertThatThrownBy(() -> codec.fromJson(json)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("Invalid MPT amount: given value requires 64 bits, only 63 allowed."); + } + + @Test + void decodeMptAmountWithIouAndMptBitsSet() { + String badHex = "A0000000000000006400002403C84A0A28E0190E208E982C352BBD5006600555CF"; + assertThatThrownBy(() -> codec.fromParser(new BinaryParser(badHex))) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("Invalid STAmount: First and third leading bits are set, " + + "which indicates the amount is both an IOU and an MPT."); + } } diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/HashTypeTest.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/HashTypeTest.java index 1a02414cd..34884b251 100644 --- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/HashTypeTest.java +++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/HashTypeTest.java @@ -32,12 +32,14 @@ class HashTypeTest { public static final char DOUBLE_QUOTE = '"'; private final Hash128Type codec128 = new Hash128Type(); private final Hash160Type codec160 = new Hash160Type(); + private final Hash192Type codec192 = new Hash192Type(); private final Hash256Type codec256 = new Hash256Type(); @Test void decode() { assertThat(codec128.fromHex(bytes(16)).toHex()).isEqualTo(bytes(16)); assertThat(codec160.fromHex(bytes(20)).toHex()).isEqualTo(bytes(20)); + assertThat(codec192.fromHex(bytes(24)).toHex()).isEqualTo(bytes(24)); assertThat(codec256.fromHex(bytes(32)).toHex()).isEqualTo(bytes(32)); } @@ -45,6 +47,7 @@ void decode() { void encode() { assertThat(codec128.fromJson(DOUBLE_QUOTE + bytes(16) + DOUBLE_QUOTE).toHex()).isEqualTo(bytes(16)); assertThat(codec160.fromJson(DOUBLE_QUOTE + bytes(20) + DOUBLE_QUOTE).toHex()).isEqualTo(bytes(20)); + assertThat(codec192.fromJson(DOUBLE_QUOTE + bytes(24) + DOUBLE_QUOTE).toHex()).isEqualTo(bytes(24)); assertThat(codec256.fromJson(DOUBLE_QUOTE + bytes(32) + DOUBLE_QUOTE).toHex()).isEqualTo(bytes(32)); } diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/UInt64TypeUnitTest.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/UInt64TypeUnitTest.java index e162389b0..295e3e57d 100644 --- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/UInt64TypeUnitTest.java +++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/UInt64TypeUnitTest.java @@ -24,32 +24,63 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import com.google.common.primitives.UnsignedLong; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; public class UInt64TypeUnitTest { - private final UInt64Type codec = new UInt64Type(); + private final UInt64Type base16Type = new UInt64Type(16); + private final UInt64Type base10Type = new UInt64Type(10); private static UnsignedLong maxUint64 = UnsignedLong.valueOf("FFFFFFFFFFFFFFFF", 16); @Test - void decode() { - assertThat(codec.fromHex("0000000000000000").valueOf()).isEqualTo(UnsignedLong.valueOf(0)); - assertThat(codec.fromHex("000000000000000F").valueOf()).isEqualTo(UnsignedLong.valueOf(15)); - assertThat(codec.fromHex("00000000FFFFFFFF").valueOf()).isEqualTo(UnsignedLong.valueOf(4294967295L)); - assertThat(codec.fromHex("FFFFFFFFFFFFFFFF").valueOf()).isEqualTo(maxUint64); + void decodeBase16() { + assertThat(base16Type.fromHex("0000000000000000").valueOf()).isEqualTo(UnsignedLong.valueOf(0)); + assertThat(base16Type.fromHex("000000000000000F").valueOf()).isEqualTo(UnsignedLong.valueOf(15)); + assertThat(base16Type.fromHex("00000000FFFFFFFF").valueOf()).isEqualTo(UnsignedLong.valueOf(4294967295L)); + assertThat(base16Type.fromHex("FFFFFFFFFFFFFFFF").valueOf()).isEqualTo(maxUint64); } @Test - void encode() { - assertThat(codec.fromJson("\"0\"").toHex()).isEqualTo("0000000000000000"); - assertThat(codec.fromJson("\"F\"").toHex()).isEqualTo("000000000000000F"); - assertThat(codec.fromJson("\"FFFF\"").toHex()).isEqualTo("000000000000FFFF"); - assertThat(codec.fromJson("\"FFFFFFFF\"").toHex()).isEqualTo("00000000FFFFFFFF"); - assertThat(codec.fromJson("\"FFFFFFFFFFFFFFFF\"").toHex()).isEqualTo("FFFFFFFFFFFFFFFF"); + void encodeBase16() { + assertThat(base16Type.fromJson("\"0\"").toHex()).isEqualTo("0000000000000000"); + assertThat(base16Type.fromJson("\"F\"").toHex()).isEqualTo("000000000000000F"); + assertThat(base16Type.fromJson("\"FFFF\"").toHex()).isEqualTo("000000000000FFFF"); + assertThat(base16Type.fromJson("\"FFFFFFFF\"").toHex()).isEqualTo("00000000FFFFFFFF"); + assertThat(base16Type.fromJson("\"FFFFFFFFFFFFFFFF\"").toHex()).isEqualTo("FFFFFFFFFFFFFFFF"); + } + + @Test + void decodeBase10() { + assertThat(base10Type.fromHex("0000000000000000").valueOf()).isEqualTo(UnsignedLong.valueOf(0)); + assertThat(base10Type.fromHex("000000000000000F").valueOf()).isEqualTo(UnsignedLong.valueOf(15)); + assertThat(base10Type.fromHex("00000000FFFFFFFF").valueOf()).isEqualTo(UnsignedLong.valueOf(4294967295L)); + assertThat(base10Type.fromHex("FFFFFFFFFFFFFFFF").valueOf()).isEqualTo(maxUint64); + } + + @Test + void encodeBase10() { + assertThat(base10Type.fromJson("\"0\"").toHex()).isEqualTo("0000000000000000"); + assertThat(base10Type.fromJson("\"15\"").toHex()).isEqualTo("000000000000000F"); + assertThat(base10Type.fromJson("\"65535\"").toHex()).isEqualTo("000000000000FFFF"); + assertThat(base10Type.fromJson("\"4294967295\"").toHex()).isEqualTo("00000000FFFFFFFF"); + assertThat(base10Type.fromJson("\"18446744073709551615\"").toHex()).isEqualTo("FFFFFFFFFFFFFFFF"); + } + + @ParameterizedTest + @ValueSource(strings = {"\"0\"", "\"15\"", "\"65535\"", "\"4294967295\"", "\"18446744073709551615\""}) + void toFromJsonBase10(String json) { + assertThat(base10Type.fromJson(json).toJson().toString()).isEqualTo(json); + } + + @ParameterizedTest + @ValueSource(strings = {"\"0\"", "\"F\"", "\"FFFF\"", "\"FFFFFFFF\"", "\"FFFFFFFFFFFFFFFF\""}) + void toFromJsonBase16(String json) { + assertThat(base16Type.fromJson(json).toJson().toString()).isEqualTo(json); } @Test void encodeOutOfBounds() { - assertThrows(IllegalArgumentException.class, () -> codec.fromJson("18446744073709551616")); + assertThrows(IllegalArgumentException.class, () -> base16Type.fromJson("18446744073709551616")); } } diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/crypto/signing/bc/BcDerivedKeySignatureServiceTest.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/crypto/signing/bc/BcDerivedKeySignatureServiceTest.java index e407ae1c2..bc2c9c73a 100644 --- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/crypto/signing/bc/BcDerivedKeySignatureServiceTest.java +++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/crypto/signing/bc/BcDerivedKeySignatureServiceTest.java @@ -593,18 +593,25 @@ void signAttestationClaimEc() { .destination(AddressConstants.GENESIS_ACCOUNT) .build(); - final ExecutorService pool = Executors.newFixedThreadPool(5); - final Callable signedTxCallable = () -> { - Signature signature = this.derivedKeySignatureService.sign(privateKeyReference, unsignedAttestation); - assertThat(signature).isNotNull(); - assertThat(signature.base16Value()).isEqualTo( - "30440220078E2379E68E59D60DFF4054FE0F988A95595E7A0DB2DB7215A3B7C03232CC7C022021BDB527050084BD9" + - "533BD21FAC0ABB63FD21754AC87C5F580AC583DDF1A9740" - ); - return true; - }; + Signature signature = this.derivedKeySignatureService.sign(privateKeyReference, unsignedAttestation); + assertThat(signature).isNotNull(); + assertThat(signature.base16Value()).isEqualTo( + "30440220078E2379E68E59D60DFF4054FE0F988A95595E7A0DB2DB7215A3B7C03232CC7C022021BDB527050084BD9" + + "533BD21FAC0ABB63FD21754AC87C5F580AC583DDF1A9740" + ); - final List> futureSeeds = new ArrayList<>(); +// final ExecutorService pool = Executors.newFixedThreadPool(5); +// final Callable signedTxCallable = () -> { +// Signature signature = this.derivedKeySignatureService.sign(privateKeyReference, unsignedAttestation); +// assertThat(signature).isNotNull(); +// assertThat(signature.base16Value()).isEqualTo( +// "30440220078E2379E68E59D60DFF4054FE0F988A95595E7A0DB2DB7215A3B7C03232CC7C022021BDB527050084BD9" + +// "533BD21FAC0ABB63FD21754AC87C5F580AC583DDF1A9740" +// ); +// return true; +// }; + + /*final List> futureSeeds = new ArrayList<>(); for (int i = 0; i < 500; i++) { futureSeeds.add(pool.submit(signedTxCallable)); } @@ -617,7 +624,7 @@ void signAttestationClaimEc() { throw new RuntimeException(e.getMessage(), e); } }) - .forEach(validSig -> assertThat(validSig).isTrue()); + .forEach(validSig -> assertThat(validSig).isTrue());*/ } @Test diff --git a/xrpl4j-core/src/test/resources/data-driven-tests.json b/xrpl4j-core/src/test/resources/data-driven-tests.json index 5e82b5a00..58c4367e4 100644 --- a/xrpl4j-core/src/test/resources/data-driven-tests.json +++ b/xrpl4j-core/src/test/resources/data-driven-tests.json @@ -3679,6 +3679,137 @@ "type_specialisation_field": "TransactionResult", "type": "UInt8", "expected_hex": "8D" + }, + { + "test_json": { + "mpt_issuance_id": "00002403C84A0A28E0190E208E982C352BBD5006600555CF", + "value": "9223372036854775808" + }, + "type": "Amount", + "error": "Value is too large" + }, + { + "test_json": { + "mpt_issuance_id": "00002403C84A0A28E0190E208E982C352BBD5006600555CF", + "value": "18446744073709551615" + }, + "type": "Amount", + "error": "Value is too large" + }, + { + "test_json": { + "mpt_issuance_id": "00002403C84A0A28E0190E208E982C352BBD5006600555CF", + "value": "-1" + }, + "type": "Amount", + "error": "Value is negative" + }, + { + "test_json": { + "mpt_issuance_id": "00002403C84A0A28E0190E208E982C352BBD5006600555CF", + "value": "10.1" + }, + "type": "Amount", + "error": "Value has decimal point" + }, + { + "test_json": { + "mpt_issuance_id": "10", + "value": "10" + }, + "type": "Amount", + "error": "mpt_issuance_id has invalid hash length" + }, + { + "test_json": { + "mpt_issuance_id": "00002403C84A0A28E0190E208E982C352BBD5006600555CF", + "value": "10", + "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji" + }, + "type": "Amount", + "error": "Issuer not valid for MPT" + }, + { + "test_json": { + "mpt_issuance_id": "00002403C84A0A28E0190E208E982C352BBD5006600555CF", + "value": "10", + "currency": "USD" + }, + "type": "Amount", + "error": "Currency not valid for MPT" + }, + { + "test_json": { + "mpt_issuance_id": "00002403C84A0A28E0190E208E982C352BBD5006600555CF", + "value": "a" + }, + "type": "Amount", + "error": "Value has incorrect hex format" + }, + { + "test_json": { + "mpt_issuance_id": "00002403C84A0A28E0190E208E982C352BBD5006600555CF", + "value": "0xy" + }, + "type": "Amount", + "error": "Value has bad hex character" + }, + { + "test_json": { + "mpt_issuance_id": "00002403C84A0A28E0190E208E982C352BBD5006600555CF", + "value": "/" + }, + "type": "Amount", + "error": "Value has bad character" + }, + { + "test_json": { + "mpt_issuance_id": "00002403C84A0A28E0190E208E982C352BBD5006600555CF", + "value": "0x8000000000000000" + }, + "type": "Amount", + "error": "Hex value out of range" + }, + { + "test_json": { + "mpt_issuance_id": "00002403C84A0A28E0190E208E982C352BBD5006600555CF", + "value": "0xFFFFFFFFFFFFFFFF" + }, + "type": "Amount", + "error": "Hex value out of range" + }, + { + "test_json": { + "mpt_issuance_id":"00002403C84A0A28E0190E208E982C352BBD5006600555CF", + "value": "9223372036854775807" + }, + "type_id": 6, + "is_native": false, + "type": "Amount", + "expected_hex": "607FFFFFFFFFFFFFFF00002403C84A0A28E0190E208E982C352BBD5006600555CF", + "is_negative": false + }, + { + "test_json": { + "mpt_issuance_id":"00002403C84A0A28E0190E208E982C352BBD5006600555CF", + "value": "0" + }, + "type_id": 6, + "is_native": false, + "type": "Amount", + "expected_hex": "60000000000000000000002403C84A0A28E0190E208E982C352BBD5006600555CF", + "is_negative": false + }, + { + "test_json": { + "mpt_issuance_id":"00002403C84A0A28E0190E208E982C352BBD5006600555CF", + "value": "100" + }, + "type_id": 6, + "is_native": false, + "type": "Amount", + "expected_hex": "60000000000000006400002403C84A0A28E0190E208E982C352BBD5006600555CF", + "is_negative": false } ] } From 21783ffffeb98541af033eef4c18c75cc4e9455e Mon Sep 17 00:00:00 2001 From: nkramer44 Date: Thu, 17 Oct 2024 16:17:19 -0400 Subject: [PATCH 02/11] fix definitions and AmountType.fromParser --- .../xrpl4j/codec/binary/types/AmountType.java | 16 +- .../src/main/resources/definitions.json | 1898 +++++++++++++---- .../codec/binary/types/AmountTypeTest.java | 9 - 3 files changed, 1507 insertions(+), 416 deletions(-) diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/AmountType.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/AmountType.java index 1a81c8509..8c0a39a03 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/AmountType.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/AmountType.java @@ -146,13 +146,15 @@ private static void verifyNoDecimal(BigDecimal decimal) { @Override public AmountType fromParser(BinaryParser parser) { UnsignedByte nextByte = parser.peek(); - Preconditions.checkArgument( - !(nextByte.isNthBitSet(1) && nextByte.isNthBitSet(3)), - "Invalid STAmount: First and third leading bits are set, which indicates the amount is both an IOU and an MPT." - ); - boolean isXrpOrMpt = !nextByte.isNthBitSet(1); - boolean isXrp = !nextByte.isNthBitSet(3); - int numBytes = isXrpOrMpt ? (isXrp ? NATIVE_AMOUNT_BYTE_LENGTH : MPT_AMOUNT_BYTE_LENGTH) : CURRENCY_AMOUNT_BYTE_LENGTH; + int numBytes; + if (nextByte.isNthBitSet(1)) { + numBytes = CURRENCY_AMOUNT_BYTE_LENGTH; + } else { + boolean isMpt = nextByte.isNthBitSet(3); + + numBytes = isMpt ? MPT_AMOUNT_BYTE_LENGTH : NATIVE_AMOUNT_BYTE_LENGTH; + } + return new AmountType(parser.read(numBytes)); } diff --git a/xrpl4j-core/src/main/resources/definitions.json b/xrpl4j-core/src/main/resources/definitions.json index 6a82327a8..f874d7c00 100644 --- a/xrpl4j-core/src/main/resources/definitions.json +++ b/xrpl4j-core/src/main/resources/definitions.json @@ -1,29 +1,35 @@ { "TYPES": { - "Validation": 10003, "Done": -1, + "Unknown": -2, + "NotPresent": 0, + "UInt16": 1, + "UInt32": 2, + "UInt64": 3, "Hash128": 4, + "Hash256": 5, + "Amount": 6, "Blob": 7, "AccountID": 8, - "Amount": 6, - "Hash256": 5, - "UInt8": 16, - "Vector256": 19, "STObject": 14, - "Unknown": -2, - "Transaction": 10001, + "STArray": 15, + "UInt8": 16, "Hash160": 17, "PathSet": 18, + "Vector256": 19, + "UInt96": 20, + "Hash192": 21, + "UInt384": 22, + "UInt512": 23, + "Issue": 24, + "XChainBridge": 25, + "Currency": 26, + "Transaction": 10001, "LedgerEntry": 10002, - "UInt16": 1, - "NotPresent": 0, - "UInt64": 3, - "UInt32": 2, - "STArray": 15 + "Validation": 10003, + "Metadata": 10004 }, "LEDGER_ENTRY_TYPES": { - "Any": -3, - "Child": -2, "Invalid": -1, "AccountRoot": 97, "DirectoryNode": 100, @@ -31,18 +37,29 @@ "Ticket": 84, "SignerList": 83, "Offer": 111, + "Bridge": 105, "LedgerHashes": 104, "Amendments": 102, + "XChainOwnedClaimID": 113, + "XChainOwnedCreateAccountClaimID": 116, "FeeSettings": 115, "Escrow": 117, "PayChannel": 120, - "DepositPreauth": 112, "Check": 67, - "Nickname": 110, - "Contract": 99, + "DepositPreauth": 112, + "NegativeUNL": 78, "NFTokenPage": 80, "NFTokenOffer": 55, - "NegativeUNL": 78 + "AMM": 121, + "DID": 73, + "Oracle": 128, + "MPTokenIssuance": 126, + "MPToken": 127, + "Any": -3, + "Child": -2, + "Nickname": 110, + "Contract": 99, + "GeneratorMap": 103 }, "FIELDS": [ [ @@ -66,239 +83,319 @@ } ], [ - "LedgerEntryType", + "ObjectEndMarker", { "nth": 1, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt16" + "type": "STObject" } ], [ - "TransactionType", + "ArrayEndMarker", { - "nth": 2, + "nth": 1, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt16" + "type": "STArray" } ], [ - "SignerWeight", + "hash", { - "nth": 3, + "nth": 257, "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt16" + "isSerialized": false, + "isSigningField": false, + "type": "Hash256" } ], [ - "TransferFee", + "index", { - "nth": 4, + "nth": 258, + "isVLEncoded": false, + "isSerialized": false, + "isSigningField": false, + "type": "Hash256" + } + ], + [ + "taker_gets_funded", + { + "nth": 258, + "isVLEncoded": false, + "isSerialized": false, + "isSigningField": false, + "type": "Amount" + } + ], + [ + "taker_pays_funded", + { + "nth": 259, + "isVLEncoded": false, + "isSerialized": false, + "isSigningField": false, + "type": "Amount" + } + ], + [ + "LedgerEntry", + { + "nth": 257, + "isVLEncoded": false, + "isSerialized": false, + "isSigningField": false, + "type": "LedgerEntry" + } + ], + [ + "Transaction", + { + "nth": 257, + "isVLEncoded": false, + "isSerialized": false, + "isSigningField": false, + "type": "Transaction" + } + ], + [ + "Validation", + { + "nth": 257, + "isVLEncoded": false, + "isSerialized": false, + "isSigningField": false, + "type": "Validation" + } + ], + [ + "Metadata", + { + "nth": 257, + "isVLEncoded": false, + "isSerialized": false, + "isSigningField": false, + "type": "Metadata" + } + ], + [ + "CloseResolution", + { + "nth": 1, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt16" + "type": "UInt8" } ], [ - "Flags", + "Method", { "nth": 2, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "UInt8" } ], [ - "SourceTag", + "TransactionResult", { "nth": 3, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "UInt8" } ], [ - "Sequence", + "Scale", { "nth": 4, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "UInt8" } ], [ - "PreviousTxnLgrSeq", + "TickSize", { - "nth": 5, + "nth": 16, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "UInt8" } ], [ - "LedgerSequence", + "UNLModifyDisabling", { - "nth": 6, + "nth": 17, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "UInt8" } ], [ - "CloseTime", + "HookResult", { - "nth": 7, + "nth": 18, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "UInt8" } ], [ - "ParentCloseTime", + "WasLockingChainSend", { - "nth": 8, + "nth": 19, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "UInt8" } ], [ - "SigningTime", + "AssetScale", { - "nth": 9, + "nth": 20, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "UInt8" } ], [ - "Expiration", + "LedgerEntryType", { - "nth": 10, + "nth": 1, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "UInt16" } ], [ - "TransferRate", + "TransactionType", { - "nth": 11, + "nth": 2, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "UInt16" } ], [ - "WalletSize", + "SignerWeight", { - "nth": 12, + "nth": 3, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "UInt16" } ], [ - "OwnerCount", + "TransferFee", { - "nth": 13, + "nth": 4, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "UInt16" } ], [ - "DestinationTag", + "TradingFee", { - "nth": 14, + "nth": 5, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "UInt16" } ], [ - "HighQualityIn", + "DiscountedFee", + { + "nth": 6, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt16" + } + ], + [ + "Version", { "nth": 16, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "UInt16" } ], [ - "HighQualityOut", + "HookStateChangeCount", { "nth": 17, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "UInt16" } ], [ - "LowQualityIn", + "HookEmitCount", { "nth": 18, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "UInt16" } ], [ - "LowQualityOut", + "HookExecutionIndex", { "nth": 19, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "UInt16" } ], [ - "QualityIn", + "HookApiVersion", { "nth": 20, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "UInt16" } ], [ - "QualityOut", + "LedgerFixType", { "nth": 21, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "UInt16" } ], [ - "StampEscrow", + "NetworkID", { - "nth": 22, + "nth": 1, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -306,9 +403,9 @@ } ], [ - "BondAmount", + "Flags", { - "nth": 23, + "nth": 2, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -316,9 +413,9 @@ } ], [ - "LoadFee", + "SourceTag", { - "nth": 24, + "nth": 3, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -326,9 +423,9 @@ } ], [ - "OfferSequence", + "Sequence", { - "nth": 25, + "nth": 4, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -336,9 +433,9 @@ } ], [ - "FirstLedgerSequence", + "PreviousTxnLgrSeq", { - "nth": 26, + "nth": 5, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -346,9 +443,9 @@ } ], [ - "LastLedgerSequence", + "LedgerSequence", { - "nth": 27, + "nth": 6, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -356,9 +453,9 @@ } ], [ - "TransactionIndex", + "CloseTime", { - "nth": 28, + "nth": 7, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -366,9 +463,9 @@ } ], [ - "OperationLimit", + "ParentCloseTime", { - "nth": 29, + "nth": 8, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -376,9 +473,9 @@ } ], [ - "ReferenceFeeUnits", + "SigningTime", { - "nth": 30, + "nth": 9, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -386,7 +483,217 @@ } ], [ - "ReserveBase", + "Expiration", + { + "nth": 10, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "TransferRate", + { + "nth": 11, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "WalletSize", + { + "nth": 12, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "OwnerCount", + { + "nth": 13, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "DestinationTag", + { + "nth": 14, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "LastUpdateTime", + { + "nth": 15, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "HighQualityIn", + { + "nth": 16, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "HighQualityOut", + { + "nth": 17, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "LowQualityIn", + { + "nth": 18, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "LowQualityOut", + { + "nth": 19, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "QualityIn", + { + "nth": 20, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "QualityOut", + { + "nth": 21, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "StampEscrow", + { + "nth": 22, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "BondAmount", + { + "nth": 23, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "LoadFee", + { + "nth": 24, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "OfferSequence", + { + "nth": 25, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "FirstLedgerSequence", + { + "nth": 26, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "LastLedgerSequence", + { + "nth": 27, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "TransactionIndex", + { + "nth": 28, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "OperationLimit", + { + "nth": 29, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "ReferenceFeeUnits", + { + "nth": 30, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "ReserveBase", { "nth": 31, "isVLEncoded": false, @@ -402,153 +709,613 @@ "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "UInt32" + } + ], + [ + "SetFlag", + { + "nth": 33, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "ClearFlag", + { + "nth": 34, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "SignerQuorum", + { + "nth": 35, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "CancelAfter", + { + "nth": 36, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "FinishAfter", + { + "nth": 37, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "SignerListID", + { + "nth": 38, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "SettleDelay", + { + "nth": 39, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "TicketCount", + { + "nth": 40, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "TicketSequence", + { + "nth": 41, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "NFTokenTaxon", + { + "nth": 42, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "MintedNFTokens", + { + "nth": 43, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "BurnedNFTokens", + { + "nth": 44, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "HookStateCount", + { + "nth": 45, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "EmitGeneration", + { + "nth": 46, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "VoteWeight", + { + "nth": 48, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "FirstNFTokenSequence", + { + "nth": 50, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "OracleDocumentID", + { + "nth": 51, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "IndexNext", + { + "nth": 1, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt64" + } + ], + [ + "IndexPrevious", + { + "nth": 2, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt64" + } + ], + [ + "BookNode", + { + "nth": 3, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt64" + } + ], + [ + "OwnerNode", + { + "nth": 4, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt64" + } + ], + [ + "BaseFee", + { + "nth": 5, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt64" + } + ], + [ + "ExchangeRate", + { + "nth": 6, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt64" + } + ], + [ + "LowNode", + { + "nth": 7, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt64" + } + ], + [ + "HighNode", + { + "nth": 8, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt64" + } + ], + [ + "DestinationNode", + { + "nth": 9, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt64" + } + ], + [ + "Cookie", + { + "nth": 10, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt64" + } + ], + [ + "ServerVersion", + { + "nth": 11, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt64" + } + ], + [ + "NFTokenOfferNode", + { + "nth": 12, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt64" + } + ], + [ + "EmitBurden", + { + "nth": 13, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt64" + } + ], + [ + "HookOn", + { + "nth": 16, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt64" + } + ], + [ + "HookInstructionCount", + { + "nth": 17, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt64" + } + ], + [ + "HookReturnCode", + { + "nth": 18, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt64" + } + ], + [ + "ReferenceCount", + { + "nth": 19, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt64" + } + ], + [ + "XChainClaimID", + { + "nth": 20, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt64" + } + ], + [ + "XChainAccountCreateCount", + { + "nth": 21, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt64" + } + ], + [ + "XChainAccountClaimCount", + { + "nth": 22, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt64" + } + ], + [ + "AssetPrice", + { + "nth": 23, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt64" + } + ], + [ + "MaximumAmount", + { + "nth": 24, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt64" + } + ], + [ + "OutstandingAmount", + { + "nth": 25, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt64" + } + ], + [ + "MPTAmount", + { + "nth": 26, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt64" + } + ], + [ + "EmailHash", + { + "nth": 1, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Hash128" + } + ], + [ + "TakerPaysCurrency", + { + "nth": 1, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Hash160" + } + ], + [ + "TakerPaysIssuer", + { + "nth": 2, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Hash160" + } + ], + [ + "TakerGetsCurrency", + { + "nth": 3, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Hash160" + } + ], + [ + "TakerGetsIssuer", + { + "nth": 4, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Hash160" } ], [ - "SetFlag", + "MPTokenIssuanceID", { - "nth": 33, + "nth": 1, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "Hash192" } ], [ - "ClearFlag", + "LedgerHash", { - "nth": 34, + "nth": 1, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "Hash256" } ], [ - "SignerQuorum", + "ParentHash", { - "nth": 35, + "nth": 2, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "Hash256" } ], [ - "CancelAfter", + "TransactionHash", { - "nth": 36, + "nth": 3, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "Hash256" } ], [ - "FinishAfter", + "AccountHash", { - "nth": 37, + "nth": 4, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "Hash256" } ], [ - "IndexNext", + "PreviousTxnID", { - "nth": 1, + "nth": 5, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt64" + "type": "Hash256" } ], [ - "IndexPrevious", + "LedgerIndex", { - "nth": 2, + "nth": 6, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt64" + "type": "Hash256" } ], [ - "BookNode", + "WalletLocator", { - "nth": 3, + "nth": 7, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt64" + "type": "Hash256" } ], [ - "OwnerNode", + "RootIndex", { - "nth": 4, + "nth": 8, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt64" + "type": "Hash256" } ], [ - "BaseFee", + "AccountTxnID", { - "nth": 5, + "nth": 9, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt64" + "type": "Hash256" } ], [ - "ExchangeRate", + "NFTokenID", { - "nth": 6, + "nth": 10, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt64" + "type": "Hash256" } ], [ - "LowNode", + "EmitParentTxnID", { - "nth": 7, + "nth": 11, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt64" + "type": "Hash256" } ], [ - "HighNode", + "EmitNonce", { - "nth": 8, + "nth": 12, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt64" + "type": "Hash256" } ], [ - "EmailHash", + "EmitHookHash", { - "nth": 1, + "nth": 13, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash128" + "type": "Hash256" } ], [ - "LedgerHash", + "AMMID", { - "nth": 1, + "nth": 14, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -556,9 +1323,9 @@ } ], [ - "ParentHash", + "BookDirectory", { - "nth": 2, + "nth": 16, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -566,9 +1333,9 @@ } ], [ - "TransactionHash", + "InvoiceID", { - "nth": 3, + "nth": 17, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -576,9 +1343,9 @@ } ], [ - "AccountHash", + "Nickname", { - "nth": 4, + "nth": 18, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -586,9 +1353,9 @@ } ], [ - "PreviousTxnID", + "Amendment", { - "nth": 5, + "nth": 19, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -596,9 +1363,9 @@ } ], [ - "LedgerIndex", + "Digest", { - "nth": 6, + "nth": 21, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -606,9 +1373,9 @@ } ], [ - "WalletLocator", + "Channel", { - "nth": 7, + "nth": 22, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -616,9 +1383,9 @@ } ], [ - "RootIndex", + "ConsensusHash", { - "nth": 8, + "nth": 23, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -626,9 +1393,9 @@ } ], [ - "AccountTxnID", + "CheckID", { - "nth": 9, + "nth": 24, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -636,9 +1403,9 @@ } ], [ - "NFTokenID", + "ValidatedHash", { - "nth": 10, + "nth": 25, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -646,9 +1413,9 @@ } ], [ - "BookDirectory", + "PreviousPageMin", { - "nth": 16, + "nth": 26, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -656,9 +1423,9 @@ } ], [ - "InvoiceID", + "NextPageMin", { - "nth": 17, + "nth": 27, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -666,9 +1433,9 @@ } ], [ - "Nickname", + "NFTokenBuyOffer", { - "nth": 18, + "nth": 28, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -676,9 +1443,9 @@ } ], [ - "Amendment", + "NFTokenSellOffer", { - "nth": 19, + "nth": 29, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -686,9 +1453,9 @@ } ], [ - "TicketID", + "HookStateKey", { - "nth": 20, + "nth": 30, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -696,9 +1463,9 @@ } ], [ - "Digest", + "HookHash", { - "nth": 21, + "nth": 31, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -706,22 +1473,22 @@ } ], [ - "hash", + "HookNamespace", { - "nth": 257, + "nth": 32, "isVLEncoded": false, - "isSerialized": false, - "isSigningField": false, + "isSerialized": true, + "isSigningField": true, "type": "Hash256" } ], [ - "index", + "HookSetTxnID", { - "nth": 258, + "nth": 33, "isVLEncoded": false, - "isSerialized": false, - "isSigningField": false, + "isSerialized": true, + "isSigningField": true, "type": "Hash256" } ], @@ -825,6 +1592,36 @@ "type": "Amount" } ], + [ + "Amount2", + { + "nth": 11, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "BidMin", + { + "nth": 12, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "BidMax", + { + "nth": 13, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], [ "MinimumOffer", { @@ -866,22 +1663,102 @@ } ], [ - "taker_gets_funded", + "BaseFeeDrops", + { + "nth": 22, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "ReserveBaseDrops", + { + "nth": 23, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "ReserveIncrementDrops", + { + "nth": 24, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "LPTokenOut", + { + "nth": 25, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "LPTokenIn", + { + "nth": 26, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "EPrice", + { + "nth": 27, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "Price", + { + "nth": 28, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "SignatureReward", + { + "nth": 29, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "MinAccountCreateAmount", { - "nth": 258, + "nth": 30, "isVLEncoded": false, - "isSerialized": false, - "isSigningField": false, + "isSerialized": true, + "isSigningField": true, "type": "Amount" } ], [ - "taker_pays_funded", + "LPTokenBalance", { - "nth": 259, + "nth": 31, "isVLEncoded": false, - "isSerialized": false, - "isSigningField": false, + "isSerialized": true, + "isSigningField": true, "type": "Amount" } ], @@ -1085,6 +1962,96 @@ "type": "Blob" } ], + [ + "HookStateData", + { + "nth": 22, + "isVLEncoded": true, + "isSerialized": true, + "isSigningField": true, + "type": "Blob" + } + ], + [ + "HookReturnString", + { + "nth": 23, + "isVLEncoded": true, + "isSerialized": true, + "isSigningField": true, + "type": "Blob" + } + ], + [ + "HookParameterName", + { + "nth": 24, + "isVLEncoded": true, + "isSerialized": true, + "isSigningField": true, + "type": "Blob" + } + ], + [ + "HookParameterValue", + { + "nth": 25, + "isVLEncoded": true, + "isSerialized": true, + "isSigningField": true, + "type": "Blob" + } + ], + [ + "DIDDocument", + { + "nth": 26, + "isVLEncoded": true, + "isSerialized": true, + "isSigningField": true, + "type": "Blob" + } + ], + [ + "Data", + { + "nth": 27, + "isVLEncoded": true, + "isSerialized": true, + "isSigningField": true, + "type": "Blob" + } + ], + [ + "AssetClass", + { + "nth": 28, + "isVLEncoded": true, + "isSerialized": true, + "isSigningField": true, + "type": "Blob" + } + ], + [ + "Provider", + { + "nth": 29, + "isVLEncoded": true, + "isSerialized": true, + "isSigningField": true, + "type": "Blob" + } + ], + [ + "MPTokenMetadata", + { + "nth": 30, + "isVLEncoded": true, + "isSerialized": true, + "isSigningField": true, + "type": "Blob" + } + ], [ "Account", { @@ -1146,9 +2113,9 @@ } ], [ - "Target", + "RegularKey", { - "nth": 7, + "nth": 8, "isVLEncoded": true, "isSerialized": true, "isSigningField": true, @@ -1156,9 +2123,9 @@ } ], [ - "RegularKey", + "NFTokenMinter", { - "nth": 8, + "nth": 9, "isVLEncoded": true, "isSerialized": true, "isSigningField": true, @@ -1166,9 +2133,9 @@ } ], [ - "NFTokenMinter", + "EmitCallback", { - "nth": 9, + "nth": 10, "isVLEncoded": true, "isSerialized": true, "isSigningField": true, @@ -1176,623 +2143,683 @@ } ], [ - "ObjectEndMarker", + "MPTokenHolder", { - "nth": 1, - "isVLEncoded": false, + "nth": 11, + "isVLEncoded": true, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "AccountID" } ], [ - "TransactionMetaData", + "HookAccount", { - "nth": 2, - "isVLEncoded": false, + "nth": 16, + "isVLEncoded": true, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "AccountID" } ], [ - "CreatedNode", + "OtherChainSource", { - "nth": 3, - "isVLEncoded": false, + "nth": 18, + "isVLEncoded": true, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "AccountID" } ], [ - "DeletedNode", + "OtherChainDestination", { - "nth": 4, - "isVLEncoded": false, + "nth": 19, + "isVLEncoded": true, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "AccountID" } ], [ - "ModifiedNode", + "AttestationSignerAccount", { - "nth": 5, - "isVLEncoded": false, + "nth": 20, + "isVLEncoded": true, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "AccountID" } ], [ - "PreviousFields", + "AttestationRewardAccount", { - "nth": 6, - "isVLEncoded": false, + "nth": 21, + "isVLEncoded": true, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "AccountID" } ], [ - "FinalFields", + "LockingChainDoor", { - "nth": 7, - "isVLEncoded": false, + "nth": 22, + "isVLEncoded": true, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "AccountID" } ], [ - "NewFields", + "IssuingChainDoor", { - "nth": 8, - "isVLEncoded": false, + "nth": 23, + "isVLEncoded": true, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "AccountID" } ], [ - "TemplateEntry", + "Indexes", { - "nth": 9, + "nth": 1, + "isVLEncoded": true, + "isSerialized": true, + "isSigningField": true, + "type": "Vector256" + } + ], + [ + "Hashes", + { + "nth": 2, + "isVLEncoded": true, + "isSerialized": true, + "isSigningField": true, + "type": "Vector256" + } + ], + [ + "Amendments", + { + "nth": 3, + "isVLEncoded": true, + "isSerialized": true, + "isSigningField": true, + "type": "Vector256" + } + ], + [ + "NFTokenOffers", + { + "nth": 4, + "isVLEncoded": true, + "isSerialized": true, + "isSigningField": true, + "type": "Vector256" + } + ], + [ + "Paths", + { + "nth": 1, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "PathSet" } ], [ - "Memo", + "BaseAsset", { - "nth": 10, + "nth": 1, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "Currency" } ], [ - "SignerEntry", + "QuoteAsset", { - "nth": 11, + "nth": 2, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "Currency" } ], [ - "NFToken", + "LockingChainIssue", { - "nth": 12, + "nth": 1, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "Issue" } ], [ - "Signer", + "IssuingChainIssue", { - "nth": 16, + "nth": 2, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "Issue" } ], [ - "Majority", + "Asset", { - "nth": 18, + "nth": 3, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "Issue" } ], [ - "DisabledValidator", + "Asset2", { - "nth": 19, + "nth": 4, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STObject" + "type": "Issue" } ], [ - "ArrayEndMarker", + "XChainBridge", { "nth": 1, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" + "type": "XChainBridge" } ], [ - "Signers", + "TransactionMetaData", + { + "nth": 2, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "STObject" + } + ], + [ + "CreatedNode", { "nth": 3, "isVLEncoded": false, "isSerialized": true, - "isSigningField": false, - "type": "STArray" + "isSigningField": true, + "type": "STObject" } ], [ - "SignerEntries", + "DeletedNode", { "nth": 4, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" + "type": "STObject" } ], [ - "Template", + "ModifiedNode", { "nth": 5, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" + "type": "STObject" } ], [ - "Necessary", + "PreviousFields", { "nth": 6, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" + "type": "STObject" } ], [ - "Sufficient", + "FinalFields", { "nth": 7, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" + "type": "STObject" } ], [ - "AffectedNodes", + "NewFields", { "nth": 8, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" + "type": "STObject" } ], [ - "Memos", + "TemplateEntry", { "nth": 9, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" + "type": "STObject" } ], [ - "NFTokens", + "Memo", { "nth": 10, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" + "type": "STObject" } ], [ - "Majorities", + "SignerEntry", { - "nth": 16, + "nth": 11, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" + "type": "STObject" } ], [ - "DisabledValidators", + "NFToken", { - "nth": 17, + "nth": 12, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" + "type": "STObject" } ], [ - "CloseResolution", + "EmitDetails", { - "nth": 1, + "nth": 13, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt8" + "type": "STObject" } ], [ - "Method", + "Hook", { - "nth": 2, + "nth": 14, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt8" + "type": "STObject" } ], [ - "TransactionResult", + "Signer", { - "nth": 3, + "nth": 16, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt8" + "type": "STObject" } ], [ - "TakerPaysCurrency", + "Majority", { - "nth": 1, + "nth": 18, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash160" + "type": "STObject" } ], [ - "TakerPaysIssuer", + "DisabledValidator", { - "nth": 2, + "nth": 19, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash160" + "type": "STObject" } ], [ - "TakerGetsCurrency", + "EmittedTxn", { - "nth": 3, + "nth": 20, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash160" + "type": "STObject" } ], [ - "TakerGetsIssuer", + "HookExecution", { - "nth": 4, + "nth": 21, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash160" + "type": "STObject" } ], [ - "Paths", + "HookDefinition", { - "nth": 1, + "nth": 22, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "PathSet" + "type": "STObject" } ], [ - "Indexes", + "HookParameter", { - "nth": 1, - "isVLEncoded": true, + "nth": 23, + "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Vector256" + "type": "STObject" } ], [ - "Hashes", + "HookGrant", { - "nth": 2, - "isVLEncoded": true, + "nth": 24, + "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Vector256" + "type": "STObject" } ], [ - "Amendments", + "VoteEntry", { - "nth": 3, - "isVLEncoded": true, + "nth": 25, + "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Vector256" + "type": "STObject" } ], [ - "NFTokenOffers", + "AuctionSlot", { - "nth": 4, - "isVLEncoded": true, + "nth": 26, + "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Vector256" + "type": "STObject" } ], [ - "Transaction", + "AuthAccount", { - "nth": 1, + "nth": 27, "isVLEncoded": false, - "isSerialized": false, - "isSigningField": false, - "type": "Transaction" + "isSerialized": true, + "isSigningField": true, + "type": "STObject" } ], [ - "LedgerEntry", + "XChainClaimProofSig", { - "nth": 1, + "nth": 28, "isVLEncoded": false, - "isSerialized": false, - "isSigningField": false, - "type": "LedgerEntry" + "isSerialized": true, + "isSigningField": true, + "type": "STObject" } ], [ - "Validation", + "XChainCreateAccountProofSig", { - "nth": 1, + "nth": 29, "isVLEncoded": false, - "isSerialized": false, - "isSigningField": false, - "type": "Validation" + "isSerialized": true, + "isSigningField": true, + "type": "STObject" } ], [ - "SignerListID", + "XChainClaimAttestationCollectionElement", { - "nth": 38, + "nth": 30, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "STObject" } ], [ - "SettleDelay", + "XChainCreateAccountAttestationCollectionElement", { - "nth": 39, + "nth": 31, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "STObject" } ], [ - "TicketCount", + "PriceData", { - "nth": 40, + "nth": 32, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "STObject" } ], [ - "TicketSequence", + "Signers", { - "nth": 41, + "nth": 3, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": false, + "type": "STArray" + } + ], + [ + "SignerEntries", + { + "nth": 4, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "STArray" } ], [ - "NFTokenTaxon", + "Template", { - "nth": 42, + "nth": 5, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "STArray" } ], [ - "MintedNFTokens", + "Necessary", { - "nth": 43, + "nth": 6, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "STArray" } ], [ - "BurnedNFTokens", + "Sufficient", { - "nth": 44, + "nth": 7, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "STArray" } ], [ - "Channel", + "AffectedNodes", { - "nth": 22, + "nth": 8, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "STArray" } ], [ - "ConsensusHash", + "Memos", { - "nth": 23, + "nth": 9, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "STArray" } ], [ - "CheckID", + "NFTokens", { - "nth": 24, + "nth": 10, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "STArray" } ], [ - "ValidatedHash", + "Hooks", { - "nth": 25, + "nth": 11, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "STArray" } ], [ - "PreviousPageMin", + "VoteSlots", { - "nth": 26, + "nth": 12, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "STArray" } ], [ - "NextPageMin", + "Majorities", { - "nth": 27, + "nth": 16, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "STArray" } ], [ - "NFTokenBuyOffer", + "DisabledValidators", { - "nth": 28, + "nth": 17, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "STArray" } ], [ - "NFTokenSellOffer", + "HookExecutions", { - "nth": 29, + "nth": 18, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash256" + "type": "STArray" } ], [ - "TickSize", + "HookParameters", { - "nth": 16, + "nth": 19, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt8" + "type": "STArray" } ], [ - "UNLModifyDisabling", + "HookGrants", { - "nth": 17, + "nth": 20, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt8" + "type": "STArray" } ], [ - "DestinationNode", + "XChainClaimAttestations", { - "nth": 9, + "nth": 21, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt64" + "type": "STArray" } ], [ - "Cookie", + "XChainCreateAccountAttestations", { - "nth": 10, + "nth": 22, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt64" + "type": "STArray" } ], [ - "ServerVersion", + "PriceDataSeries", { - "nth": 11, + "nth": 24, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt64" + "type": "STArray" } ], [ - "NFTokenOfferNode", + "AuthAccounts", { - "nth": 12, + "nth": 25, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt64" + "type": "STArray" } ] ], @@ -1810,6 +2837,10 @@ "telCAN_NOT_QUEUE_BLOCKED": -389, "telCAN_NOT_QUEUE_FEE": -388, "telCAN_NOT_QUEUE_FULL": -387, + "telWRONG_NETWORK": -386, + "telREQUIRES_NETWORK_ID": -385, + "telNETWORK_ID_MAKES_TX_NON_CANONICAL": -384, + "telENV_RPC_FAILED": -383, "temMALFORMED": -299, "temBAD_AMOUNT": -298, @@ -1844,10 +2875,22 @@ "temBAD_TICK_SIZE": -269, "temINVALID_ACCOUNT_ID": -268, "temCANNOT_PREAUTH_SELF": -267, - "temUNCERTAIN": -266, - "temUNKNOWN": -265, - "temSEQ_AND_TICKET": -264, - "temBAD_NFTOKEN_TRANSFER_FEE": -263, + "temINVALID_COUNT": -266, + "temUNCERTAIN": -265, + "temUNKNOWN": -264, + "temSEQ_AND_TICKET": -263, + "temBAD_NFTOKEN_TRANSFER_FEE": -262, + "temBAD_AMM_TOKENS": -261, + "temXCHAIN_EQUAL_DOOR_ACCOUNTS": -260, + "temXCHAIN_BAD_PROOF": -259, + "temXCHAIN_BRIDGE_BAD_ISSUES": -258, + "temXCHAIN_BRIDGE_NONDOOR_OWNER": -257, + "temXCHAIN_BRIDGE_BAD_MIN_ACCOUNT_CREATE_AMOUNT": -256, + "temXCHAIN_BRIDGE_BAD_REWARD_AMOUNT": -255, + "temEMPTY_DID": -254, + "temARRAY_EMPTY": -253, + "temARRAY_TOO_LARGE": -252, + "temBAD_TRANSFER_FEE": -251, "tefFAILURE": -199, "tefALREADY": -198, @@ -1870,6 +2913,7 @@ "tefTOO_BIG": -181, "tefNO_TICKET": -180, "tefNFTOKEN_IS_NOT_TRANSFERABLE": -179, + "tefINVALID_LEDGER_FIX_TYPE": -178, "terRETRY": -99, "terFUNDS_SPENT": -98, @@ -1883,6 +2927,7 @@ "terNO_RIPPLE": -90, "terQUEUED": -89, "terPRE_TICKET": -88, + "terNO_AMM": -87, "tesSUCCESS": 0, @@ -1924,7 +2969,7 @@ "tecKILLED": 150, "tecHAS_OBLIGATIONS": 151, "tecTOO_SOON": 152, - + "tecHOOK_REJECTED": 153, "tecMAX_SEQUENCE_REACHED": 154, "tecNO_SUITABLE_NFTOKEN_PAGE": 155, "tecNFTOKEN_BUY_SELL_MISMATCH": 156, @@ -1933,12 +2978,40 @@ "tecINSUFFICIENT_FUNDS": 159, "tecOBJECT_NOT_FOUND": 160, "tecINSUFFICIENT_PAYMENT": 161, - "tecINCORRECT_ASSET": 162, - "tecTOO_MANY": 163 + "tecUNFUNDED_AMM": 162, + "tecAMM_BALANCE": 163, + "tecAMM_FAILED": 164, + "tecAMM_INVALID_TOKENS": 165, + "tecAMM_EMPTY": 166, + "tecAMM_NOT_EMPTY": 167, + "tecAMM_ACCOUNT": 168, + "tecINCOMPLETE": 169, + "tecXCHAIN_BAD_TRANSFER_ISSUE": 170, + "tecXCHAIN_NO_CLAIM_ID": 171, + "tecXCHAIN_BAD_CLAIM_ID": 172, + "tecXCHAIN_CLAIM_NO_QUORUM": 173, + "tecXCHAIN_PROOF_UNKNOWN_KEY": 174, + "tecXCHAIN_CREATE_ACCOUNT_NONXRP_ISSUE": 175, + "tecXCHAIN_WRONG_CHAIN": 176, + "tecXCHAIN_REWARD_MISMATCH": 177, + "tecXCHAIN_NO_SIGNERS_LIST": 178, + "tecXCHAIN_SENDING_ACCOUNT_MISMATCH": 179, + "tecXCHAIN_INSUFF_CREATE_AMOUNT": 180, + "tecXCHAIN_ACCOUNT_CREATE_PAST": 181, + "tecXCHAIN_ACCOUNT_CREATE_TOO_MANY": 182, + "tecXCHAIN_PAYMENT_FAILED": 183, + "tecXCHAIN_SELF_COMMIT": 184, + "tecXCHAIN_BAD_PUBLIC_KEY_ACCOUNT_PAIR": 185, + "tecXCHAIN_CREATE_ACCOUNT_DISABLED": 186, + "tecEMPTY_DID": 187, + "tecINVALID_UPDATE_TIME": 188, + "tecTOKEN_PAIR_NOT_FOUND": 189, + "tecARRAY_EMPTY": 190, + "tecARRAY_TOO_LARGE": 191, + "tecLOCKED": 192 }, "TRANSACTION_TYPES": { "Invalid": -1, - "Payment": 0, "EscrowCreate": 1, "EscrowFinish": 2, @@ -1961,13 +3034,38 @@ "DepositPreauth": 19, "TrustSet": 20, "AccountDelete": 21, + "SetHook": 22, "NFTokenMint": 25, "NFTokenBurn": 26, "NFTokenCreateOffer": 27, "NFTokenCancelOffer": 28, "NFTokenAcceptOffer": 29, + "Clawback": 30, + "AMMCreate": 35, + "AMMDeposit": 36, + "AMMWithdraw": 37, + "AMMVote": 38, + "AMMBid": 39, + "AMMDelete": 40, + "XChainCreateClaimID": 41, + "XChainCommit": 42, + "XChainClaim": 43, + "XChainAccountCreateCommit": 44, + "XChainAddClaimAttestation": 45, + "XChainAddAccountCreateAttestation": 46, + "XChainModifyBridge": 47, + "XChainCreateBridge": 48, + "DIDSet": 49, + "DIDDelete": 50, + "OracleSet": 51, + "OracleDelete": 52, + "LedgerStateFix": 53, + "MPTokenIssuanceCreate": 54, + "MPTokenIssuanceDestroy": 55, + "MPTokenAuthorize": 56, + "MPTokenIssuanceSet": 57, "EnableAmendment": 100, "SetFee": 101, "UNLModify": 102 } -} +} \ No newline at end of file diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/AmountTypeTest.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/AmountTypeTest.java index 6d3a476ac..d803fe7eb 100644 --- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/AmountTypeTest.java +++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/AmountTypeTest.java @@ -247,13 +247,4 @@ void encodeMptAmountWithMoreThan63BitAmountThrows() { assertThatThrownBy(() -> codec.fromJson(json)).isInstanceOf(IllegalArgumentException.class) .hasMessage("Invalid MPT amount: given value requires 64 bits, only 63 allowed."); } - - @Test - void decodeMptAmountWithIouAndMptBitsSet() { - String badHex = "A0000000000000006400002403C84A0A28E0190E208E982C352BBD5006600555CF"; - assertThatThrownBy(() -> codec.fromParser(new BinaryParser(badHex))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Invalid STAmount: First and third leading bits are set, " + - "which indicates the amount is both an IOU and an MPT."); - } } From 787cea845d2e30f673637c3f5f4cb96c60019e6e Mon Sep 17 00:00:00 2001 From: nkramer44 Date: Thu, 17 Oct 2024 16:18:58 -0400 Subject: [PATCH 03/11] checkstyle --- .../codec/binary/types/SerializedType.java | 4 ++- .../bc/BcDerivedKeySignatureServiceTest.java | 31 +++++++------------ 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java index a685c7c7b..6dd101a45 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java @@ -41,7 +41,9 @@ */ public abstract class SerializedType> { - private static final Set BASE_10_UINT64_FIELD_NAMES = Sets.newHashSet("MaximumAmount", "OutstandingAmount", "MPTAmount"); + private static final Set BASE_10_UINT64_FIELD_NAMES = Sets.newHashSet( + "MaximumAmount", "OutstandingAmount", "MPTAmount" + ); @SuppressWarnings("all") private static final Map>> typeMap = new ImmutableMap.Builder>>() diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/crypto/signing/bc/BcDerivedKeySignatureServiceTest.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/crypto/signing/bc/BcDerivedKeySignatureServiceTest.java index bc2c9c73a..e407ae1c2 100644 --- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/crypto/signing/bc/BcDerivedKeySignatureServiceTest.java +++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/crypto/signing/bc/BcDerivedKeySignatureServiceTest.java @@ -593,25 +593,18 @@ void signAttestationClaimEc() { .destination(AddressConstants.GENESIS_ACCOUNT) .build(); - Signature signature = this.derivedKeySignatureService.sign(privateKeyReference, unsignedAttestation); - assertThat(signature).isNotNull(); - assertThat(signature.base16Value()).isEqualTo( - "30440220078E2379E68E59D60DFF4054FE0F988A95595E7A0DB2DB7215A3B7C03232CC7C022021BDB527050084BD9" + - "533BD21FAC0ABB63FD21754AC87C5F580AC583DDF1A9740" - ); + final ExecutorService pool = Executors.newFixedThreadPool(5); + final Callable signedTxCallable = () -> { + Signature signature = this.derivedKeySignatureService.sign(privateKeyReference, unsignedAttestation); + assertThat(signature).isNotNull(); + assertThat(signature.base16Value()).isEqualTo( + "30440220078E2379E68E59D60DFF4054FE0F988A95595E7A0DB2DB7215A3B7C03232CC7C022021BDB527050084BD9" + + "533BD21FAC0ABB63FD21754AC87C5F580AC583DDF1A9740" + ); + return true; + }; -// final ExecutorService pool = Executors.newFixedThreadPool(5); -// final Callable signedTxCallable = () -> { -// Signature signature = this.derivedKeySignatureService.sign(privateKeyReference, unsignedAttestation); -// assertThat(signature).isNotNull(); -// assertThat(signature.base16Value()).isEqualTo( -// "30440220078E2379E68E59D60DFF4054FE0F988A95595E7A0DB2DB7215A3B7C03232CC7C022021BDB527050084BD9" + -// "533BD21FAC0ABB63FD21754AC87C5F580AC583DDF1A9740" -// ); -// return true; -// }; - - /*final List> futureSeeds = new ArrayList<>(); + final List> futureSeeds = new ArrayList<>(); for (int i = 0; i < 500; i++) { futureSeeds.add(pool.submit(signedTxCallable)); } @@ -624,7 +617,7 @@ void signAttestationClaimEc() { throw new RuntimeException(e.getMessage(), e); } }) - .forEach(validSig -> assertThat(validSig).isTrue());*/ + .forEach(validSig -> assertThat(validSig).isTrue()); } @Test From 9f967891b305cd17be9868b502d7629bb04d36fa Mon Sep 17 00:00:00 2001 From: nkramer44 Date: Fri, 18 Oct 2024 10:09:07 -0400 Subject: [PATCH 04/11] refactor --- .../xrpl4j/codec/binary/XrplBinaryCodec.java | 2 +- .../codec/binary/serdes/BinaryParser.java | 2 +- .../codec/binary/serdes/BinarySerializer.java | 8 +-- .../codec/binary/types/SerializedType.java | 71 +++++++++---------- .../xrpl4j/codec/binary/types/UInt64Type.java | 43 ++++++++--- .../xrpl4j/codec/binary/types/UIntType.java | 2 + .../binary/types/UInt64TypeUnitTest.java | 25 +------ 7 files changed, 77 insertions(+), 76 deletions(-) diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/XrplBinaryCodec.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/XrplBinaryCodec.java index faa272554..e3dfc2a33 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/XrplBinaryCodec.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/XrplBinaryCodec.java @@ -146,7 +146,7 @@ public String encodeForSigningClaim(String json) throws JsonProcessingException } UnsignedByteArray channel = UnsignedByteArray.fromHex(node.get(CHANNEL_FIELD_NAME).asText()); UnsignedByteArray amount = UnsignedByteArray.of( - new UInt64Type(UnsignedLong.valueOf(node.get(AMOUNT_FIELD_NAME).asText()), 16).toBytes() + new UInt64Type(UnsignedLong.valueOf(node.get(AMOUNT_FIELD_NAME).asText())).toBytes() ); UnsignedByteArray byteArray = UnsignedByteArray.empty(); diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/serdes/BinaryParser.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/serdes/BinaryParser.java index 2293c9540..16b8cb998 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/serdes/BinaryParser.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/serdes/BinaryParser.java @@ -195,7 +195,7 @@ public > T readType(Class type) { * @return The type associated with the given field. */ public SerializedType typeForField(FieldInstance field) { - return SerializedType.getTypeByName(field.type(), field.name()); + return SerializedType.getTypeByName(field.type()); } /** diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/serdes/BinarySerializer.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/serdes/BinarySerializer.java index 05a31df73..8a53d50b3 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/serdes/BinarySerializer.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/serdes/BinarySerializer.java @@ -107,12 +107,8 @@ public void writeFieldAndValue(final FieldInstance field, final SerializedType v public void writeFieldAndValue(final FieldInstance field, final JsonNode value) throws JsonProcessingException { Objects.requireNonNull(field); Objects.requireNonNull(value); - SerializedType typedValue; - if (field.name().equals("BaseFee")) { - typedValue = SerializedType.getTypeByName(field.type(), field.name()).fromHex(value.asText()); - } else { - typedValue = SerializedType.getTypeByName(field.type(), field.name()).fromJson(value); - } + SerializedType typedValue = SerializedType.getTypeByName(field.type()).fromJson(value, field); + writeFieldAndValue(field, typedValue); } diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java index 6dd101a45..ebcc7dc46 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java @@ -24,15 +24,15 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.TextNode; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Sets; import org.xrpl.xrpl4j.codec.addresses.UnsignedByteArray; import org.xrpl.xrpl4j.codec.binary.BinaryCodecObjectMapperFactory; +import org.xrpl.xrpl4j.codec.binary.definitions.FieldInstance; import org.xrpl.xrpl4j.codec.binary.serdes.BinaryParser; import java.util.Map; import java.util.Objects; -import java.util.Set; import java.util.function.Function; +import java.util.function.Supplier; /** * Defines an abstract type serialization parent-class for all XRPL serialized type definitions. @@ -41,36 +41,28 @@ */ public abstract class SerializedType> { - private static final Set BASE_10_UINT64_FIELD_NAMES = Sets.newHashSet( - "MaximumAmount", "OutstandingAmount", "MPTAmount" - ); + @SuppressWarnings("all") - private static final Map>> typeMap = - new ImmutableMap.Builder>>() - .put("AccountID", fieldName -> new AccountIdType()) - .put("Amount", fieldName -> new AmountType()) - .put("Blob", fieldName -> new BlobType()) - .put("Currency", fieldName -> new CurrencyType()) - .put("Hash128", fieldName -> new Hash128Type()) - .put("Hash160", fieldName -> new Hash160Type()) - .put("Hash192", fieldName -> new Hash192Type()) - .put("Hash256", fieldName -> new Hash256Type()) - .put("PathSet", fieldName -> new PathSetType()) - .put("STArray", fieldName -> new STArrayType()) - .put("STObject", fieldName -> new STObjectType()) - .put("UInt8", fieldName -> new UInt8Type()) - .put("UInt16", fieldName -> new UInt16Type()) - .put("UInt32", fieldName -> new UInt32Type()) - .put("UInt64", fieldName -> { - if (BASE_10_UINT64_FIELD_NAMES.contains(fieldName)) { - return new UInt64Type(10); - } else { - return new UInt64Type(16); - } - }) - .put("Vector256", fieldName -> new Vector256Type()) - .put("Issue", fieldName -> new IssueType()) - .put("XChainBridge", fieldName -> new XChainBridgeType()) + private static final Map>> typeMap = + new ImmutableMap.Builder>>() + .put("AccountID", () -> new AccountIdType()) + .put("Amount", () -> new AmountType()) + .put("Blob", () -> new BlobType()) + .put("Currency", () -> new CurrencyType()) + .put("Hash128", () -> new Hash128Type()) + .put("Hash160", () -> new Hash160Type()) + .put("Hash192", () -> new Hash192Type()) + .put("Hash256", () -> new Hash256Type()) + .put("PathSet", () -> new PathSetType()) + .put("STArray", () -> new STArrayType()) + .put("STObject", () -> new STObjectType()) + .put("UInt8", () -> new UInt8Type()) + .put("UInt16", () -> new UInt16Type()) + .put("UInt32", () -> new UInt32Type()) + .put("UInt64", () -> new UInt64Type()) + .put("Vector256", () -> new Vector256Type()) + .put("Issue", () -> new IssueType()) + .put("XChainBridge", () -> new XChainBridgeType()) .build(); private final UnsignedByteArray bytes; @@ -81,13 +73,12 @@ public SerializedType(UnsignedByteArray bytes) { /** * Get the {@link SerializedType} for the supplied {@code name}. * - * @param name A {@link String} representing the name of a {@link SerializedType}. - * @param fieldName The name of the field that is being serialized. + * @param name A {@link String} representing the name of a {@link SerializedType}. * * @return A {@link SerializedType} for the supplied {@code name}. */ - public static SerializedType getTypeByName(String name, String fieldName) { - return typeMap.get(name).apply(fieldName); + public static SerializedType getTypeByName(String name) { + return typeMap.get(name).get(); } /** @@ -102,7 +93,7 @@ public static String getNameByType(SerializedType type) { .stream() // We only care about the class name, and the String passed to .apply is only used to figure // out the radix of the JSON string for UInt64Types. Plus this method is only used in a test. - .filter(entry -> entry.getValue().apply("").getClass().equals(type.getClass())) + .filter(entry -> entry.getValue().get().getClass().equals(type.getClass())) .map(Map.Entry::getKey) .findAny() .orElse(null); @@ -141,6 +132,10 @@ public T fromParser(BinaryParser parser, int lengthHint) { */ public abstract T fromJson(JsonNode node) throws JsonProcessingException; + public T fromJson(JsonNode node, FieldInstance fieldInstance) throws JsonProcessingException { + return fromJson(node); + } + /** * Construct a concrete instance of {@link SerializedType} from the supplied {@code json}. * @@ -212,6 +207,10 @@ public JsonNode toJson() { return new TextNode(toHex()); } + public JsonNode toJson(FieldInstance fieldInstance) { + return toJson(); + } + /** * Convert this {@link SerializedType} to a hex-encoded {@link String}. * diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UInt64Type.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UInt64Type.java index 018561adb..b5957fe06 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UInt64Type.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UInt64Type.java @@ -22,38 +22,65 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.TextNode; +import com.google.common.collect.Sets; import com.google.common.primitives.UnsignedLong; +import org.xrpl.xrpl4j.codec.binary.definitions.FieldInstance; import org.xrpl.xrpl4j.codec.binary.serdes.BinaryParser; +import java.util.Set; + /** * Codec for XRPL UInt64 type. */ public class UInt64Type extends UIntType { - private final int radix; + private static final Set BASE_10_UINT64_FIELD_NAMES = Sets.newHashSet( + "MaximumAmount", "OutstandingAmount", "MPTAmount" + ); - public UInt64Type(int radix) { - this(UnsignedLong.ZERO, radix); + public UInt64Type() { + this(UnsignedLong.ZERO); } - public UInt64Type(UnsignedLong value, int radix) { + public UInt64Type(UnsignedLong value) { super(value, 64); - this.radix = radix; } @Override public UInt64Type fromParser(BinaryParser parser) { - return new UInt64Type(parser.readUInt64(), radix); + return new UInt64Type(parser.readUInt64()); } @Override public UInt64Type fromJson(JsonNode value) { - // STUInt64s are represented as hex-encoded Strings in JSON. - return new UInt64Type(UnsignedLong.valueOf(value.asText(), radix), radix); + throw new UnsupportedOperationException("Cannot construct UInt64Type from JSON without a FieldInstance. Call " + + "the overload of this method that accepts a FieldInstance instead."); } @Override public JsonNode toJson() { + throw new UnsupportedOperationException("Cannot convert UInt64Type to JSON without a FieldInstance. Call " + + "the overload of this method that accepts a FieldInstance instead."); + } + + @Override + public UInt64Type fromJson(JsonNode value, FieldInstance fieldInstance) { + int radix = getRadix(fieldInstance); + // STUInt64s are represented as hex-encoded Strings in JSON. + return new UInt64Type(UnsignedLong.valueOf(value.asText(), radix)); + } + + @Override + public JsonNode toJson(FieldInstance fieldInstance) { + int radix = getRadix(fieldInstance); return new TextNode(UnsignedLong.valueOf(toHex(), 16).toString(radix).toUpperCase()); } + + private static int getRadix(FieldInstance fieldInstance) { + int radix = 16; + if (BASE_10_UINT64_FIELD_NAMES.contains(fieldInstance.name())) { + radix = 10; + } + return radix; + } } diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UIntType.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UIntType.java index 915dcc678..99ba88722 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UIntType.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UIntType.java @@ -25,6 +25,7 @@ import com.google.common.primitives.UnsignedLong; import org.xrpl.xrpl4j.codec.addresses.ByteUtils; import org.xrpl.xrpl4j.codec.addresses.UnsignedByteArray; +import org.xrpl.xrpl4j.codec.binary.definitions.FieldInstance; /** * Base codec for XRPL UInt types. @@ -50,4 +51,5 @@ UnsignedLong valueOf() { public JsonNode toJson() { return new TextNode(UnsignedLong.valueOf(toHex(), 16).toString()); } + } diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/UInt64TypeUnitTest.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/UInt64TypeUnitTest.java index 295e3e57d..590b35089 100644 --- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/UInt64TypeUnitTest.java +++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/UInt64TypeUnitTest.java @@ -29,8 +29,7 @@ import org.junit.jupiter.params.provider.ValueSource; public class UInt64TypeUnitTest { - private final UInt64Type base16Type = new UInt64Type(16); - private final UInt64Type base10Type = new UInt64Type(10); + private final UInt64Type base16Type = new UInt64Type(); private static UnsignedLong maxUint64 = UnsignedLong.valueOf("FFFFFFFFFFFFFFFF", 16); @Test @@ -50,28 +49,6 @@ void encodeBase16() { assertThat(base16Type.fromJson("\"FFFFFFFFFFFFFFFF\"").toHex()).isEqualTo("FFFFFFFFFFFFFFFF"); } - @Test - void decodeBase10() { - assertThat(base10Type.fromHex("0000000000000000").valueOf()).isEqualTo(UnsignedLong.valueOf(0)); - assertThat(base10Type.fromHex("000000000000000F").valueOf()).isEqualTo(UnsignedLong.valueOf(15)); - assertThat(base10Type.fromHex("00000000FFFFFFFF").valueOf()).isEqualTo(UnsignedLong.valueOf(4294967295L)); - assertThat(base10Type.fromHex("FFFFFFFFFFFFFFFF").valueOf()).isEqualTo(maxUint64); - } - - @Test - void encodeBase10() { - assertThat(base10Type.fromJson("\"0\"").toHex()).isEqualTo("0000000000000000"); - assertThat(base10Type.fromJson("\"15\"").toHex()).isEqualTo("000000000000000F"); - assertThat(base10Type.fromJson("\"65535\"").toHex()).isEqualTo("000000000000FFFF"); - assertThat(base10Type.fromJson("\"4294967295\"").toHex()).isEqualTo("00000000FFFFFFFF"); - assertThat(base10Type.fromJson("\"18446744073709551615\"").toHex()).isEqualTo("FFFFFFFFFFFFFFFF"); - } - - @ParameterizedTest - @ValueSource(strings = {"\"0\"", "\"15\"", "\"65535\"", "\"4294967295\"", "\"18446744073709551615\""}) - void toFromJsonBase10(String json) { - assertThat(base10Type.fromJson(json).toJson().toString()).isEqualTo(json); - } @ParameterizedTest @ValueSource(strings = {"\"0\"", "\"F\"", "\"FFFF\"", "\"FFFFFFFF\"", "\"FFFFFFFFFFFFFFFF\""}) From 1ec7628a478d5bfee132ba2aac1375944093a2d5 Mon Sep 17 00:00:00 2001 From: nkramer44 Date: Fri, 18 Oct 2024 10:58:24 -0400 Subject: [PATCH 05/11] fix tests and checkstyle --- .../codec/binary/types/STObjectType.java | 2 +- .../codec/binary/types/SerializedType.java | 22 +++++ .../xrpl4j/codec/binary/types/UInt64Type.java | 18 ++-- .../binary/types/UInt64TypeUnitTest.java | 88 +++++++++++++++---- 4 files changed, 105 insertions(+), 25 deletions(-) diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/STObjectType.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/STObjectType.java index e1f3f4927..85d04a1d6 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/STObjectType.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/STObjectType.java @@ -181,7 +181,7 @@ public JsonNode toJson() { if (field.name().equals(OBJECT_END_MARKER)) { break; } - JsonNode value = parser.readFieldValue(field).toJson(); + JsonNode value = parser.readFieldValue(field).toJson(field); JsonNode mapped = definitionsService.mapFieldRawValueToSpecialization(field.name(), value.asText()) .map(TextNode::new) .map(JsonNode.class::cast) diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java index ebcc7dc46..514ada287 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java @@ -128,10 +128,23 @@ public T fromParser(BinaryParser parser, int lengthHint) { * @param node A {@link JsonNode} to use. * * @return A {@link T} based upon the information found in {@code node}. + * * @throws JsonProcessingException if {@code node} is not well-formed JSON. */ public abstract T fromJson(JsonNode node) throws JsonProcessingException; + /** + * Obtain a {@link T} using the supplied {@link JsonNode} as well as a {@link FieldInstance}. Prefer using this method + * where possible over {@link #fromJson(JsonNode)}, as some {@link SerializedType}s require a {@link FieldInstance} to + * accurately serialize and deserialize. + * + * @param node A {@link JsonNode} to serialize to binary. + * @param fieldInstance The {@link FieldInstance} describing the field being serialized. + * + * @return A {@link T}. + * + * @throws JsonProcessingException If {@code node} is not well-formed JSON. + */ public T fromJson(JsonNode node, FieldInstance fieldInstance) throws JsonProcessingException { return fromJson(node); } @@ -207,6 +220,15 @@ public JsonNode toJson() { return new TextNode(toHex()); } + /** + * Convert this {@link SerializedType} to a {@link JsonNode} based on the supplied {@link FieldInstance}. Prefer using + * this method where possible over {@link #fromJson(JsonNode)}, as some {@link SerializedType}s require a + * {@link FieldInstance} to accurately serialize and deserialize. + * + * @param fieldInstance A {@link FieldInstance} describing the field being deserialized. + * + * @return A {@link JsonNode}. + */ public JsonNode toJson(FieldInstance fieldInstance) { return toJson(); } diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UInt64Type.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UInt64Type.java index b5957fe06..6bb3497ec 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UInt64Type.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UInt64Type.java @@ -34,7 +34,11 @@ */ public class UInt64Type extends UIntType { - private static final Set BASE_10_UINT64_FIELD_NAMES = Sets.newHashSet( + /** + * These fields are represented as base 10 Strings in JSON, whereas all other STUInt64s are represented + * in base16. + */ + protected static final Set BASE_10_UINT64_FIELD_NAMES = Sets.newHashSet( "MaximumAmount", "OutstandingAmount", "MPTAmount" ); @@ -57,12 +61,6 @@ public UInt64Type fromJson(JsonNode value) { "the overload of this method that accepts a FieldInstance instead."); } - @Override - public JsonNode toJson() { - throw new UnsupportedOperationException("Cannot convert UInt64Type to JSON without a FieldInstance. Call " + - "the overload of this method that accepts a FieldInstance instead."); - } - @Override public UInt64Type fromJson(JsonNode value, FieldInstance fieldInstance) { int radix = getRadix(fieldInstance); @@ -70,6 +68,12 @@ public UInt64Type fromJson(JsonNode value, FieldInstance fieldInstance) { return new UInt64Type(UnsignedLong.valueOf(value.asText(), radix)); } + @Override + public JsonNode toJson() { + throw new UnsupportedOperationException("Cannot convert UInt64Type to JSON without a FieldInstance. Call " + + "the overload of this method that accepts a FieldInstance instead."); + } + @Override public JsonNode toJson(FieldInstance fieldInstance) { int radix = getRadix(fieldInstance); diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/UInt64TypeUnitTest.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/UInt64TypeUnitTest.java index 590b35089..66b78074f 100644 --- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/UInt64TypeUnitTest.java +++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/UInt64TypeUnitTest.java @@ -21,43 +21,97 @@ */ import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import com.fasterxml.jackson.databind.node.TextNode; +import com.google.common.base.Strings; +import com.google.common.io.BaseEncoding; +import com.google.common.primitives.UnsignedInteger; import com.google.common.primitives.UnsignedLong; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.ValueSource; +import org.xrpl.xrpl4j.codec.binary.definitions.FieldInstance; + +import java.util.stream.Stream; public class UInt64TypeUnitTest { - private final UInt64Type base16Type = new UInt64Type(); + private final UInt64Type type = new UInt64Type(); private static UnsignedLong maxUint64 = UnsignedLong.valueOf("FFFFFFFFFFFFFFFF", 16); @Test - void decodeBase16() { - assertThat(base16Type.fromHex("0000000000000000").valueOf()).isEqualTo(UnsignedLong.valueOf(0)); - assertThat(base16Type.fromHex("000000000000000F").valueOf()).isEqualTo(UnsignedLong.valueOf(15)); - assertThat(base16Type.fromHex("00000000FFFFFFFF").valueOf()).isEqualTo(UnsignedLong.valueOf(4294967295L)); - assertThat(base16Type.fromHex("FFFFFFFFFFFFFFFF").valueOf()).isEqualTo(maxUint64); + void testFromHex() { + assertThat(type.fromHex("0000000000000000").valueOf()).isEqualTo(UnsignedLong.valueOf(0)); + assertThat(type.fromHex("000000000000000F").valueOf()).isEqualTo(UnsignedLong.valueOf(15)); + assertThat(type.fromHex("00000000FFFFFFFF").valueOf()).isEqualTo(UnsignedLong.valueOf(4294967295L)); + assertThat(type.fromHex("FFFFFFFFFFFFFFFF").valueOf()).isEqualTo(maxUint64); + } + + @ParameterizedTest + @MethodSource(value = "base16JsonArguments") + void testFromJsonBase16(TextNode json) { + FieldInstance base16FieldInstance = mock(FieldInstance.class); + when(base16FieldInstance.name()).thenReturn("Base16Field"); + assertThat(type.fromJson(json, base16FieldInstance).toHex()) + .isEqualTo(Strings.padStart(json.asText(), 16, '0')); + assertThat(type.fromJson(json, base16FieldInstance).toJson(base16FieldInstance)).isEqualTo(json); + } + + @ParameterizedTest + @MethodSource(value = "base10JsonArguments") + void testFromJsonBase10(TextNode json) { + UInt64Type.BASE_10_UINT64_FIELD_NAMES.forEach( + b10FieldName -> { + FieldInstance base10FieldInstance = mock(FieldInstance.class); + when(base10FieldInstance.name()).thenReturn(b10FieldName); + String expectedHex = Strings.padStart(UnsignedLong.valueOf(json.asText()).toString(16).toUpperCase(), 16, '0'); + assertThat(type.fromJson(json, base10FieldInstance).toHex()) + .isEqualTo(expectedHex); + assertThat(type.fromJson(json, base10FieldInstance).toJson(base10FieldInstance)).isEqualTo(json); + } + ); + } + + @Test + void fromJsonThrowsWithoutFieldInstance() { + assertThatThrownBy(() -> type.fromJson(new TextNode("0"))) + .isInstanceOf(UnsupportedOperationException.class); } @Test - void encodeBase16() { - assertThat(base16Type.fromJson("\"0\"").toHex()).isEqualTo("0000000000000000"); - assertThat(base16Type.fromJson("\"F\"").toHex()).isEqualTo("000000000000000F"); - assertThat(base16Type.fromJson("\"FFFF\"").toHex()).isEqualTo("000000000000FFFF"); - assertThat(base16Type.fromJson("\"FFFFFFFF\"").toHex()).isEqualTo("00000000FFFFFFFF"); - assertThat(base16Type.fromJson("\"FFFFFFFFFFFFFFFF\"").toHex()).isEqualTo("FFFFFFFFFFFFFFFF"); + void toJsonThrowsWithoutFieldInstance() { + assertThatThrownBy(type::toJson) + .isInstanceOf(UnsupportedOperationException.class); } + private static Stream base16JsonArguments() { + return Stream.of( + new TextNode("0"), + new TextNode("F"), + new TextNode("FFFF"), + new TextNode("FFFFFFFF"), + new TextNode("FFFFFFFFFFFFFFFF") + ); + } - @ParameterizedTest - @ValueSource(strings = {"\"0\"", "\"F\"", "\"FFFF\"", "\"FFFFFFFF\"", "\"FFFFFFFFFFFFFFFF\""}) - void toFromJsonBase16(String json) { - assertThat(base16Type.fromJson(json).toJson().toString()).isEqualTo(json); + private static Stream base10JsonArguments() { + return Stream.of( + new TextNode("0"), + new TextNode("15"), + new TextNode("65535"), + new TextNode("4294967295"), + new TextNode("18446744073709551615") + ); } @Test void encodeOutOfBounds() { - assertThrows(IllegalArgumentException.class, () -> base16Type.fromJson("18446744073709551616")); + FieldInstance field = mock(FieldInstance.class); + when(field.name()).thenReturn("Field"); + assertThrows(IllegalArgumentException.class, () -> type.fromJson(new TextNode("18446744073709551616"), field)); } } From 8828d84add698d1b37997ae929e5f112b8d59e71 Mon Sep 17 00:00:00 2001 From: nkramer44 Date: Fri, 18 Oct 2024 11:02:00 -0400 Subject: [PATCH 06/11] cleanup --- .../codec/binary/types/SerializedType.java | 2 -- .../xrpl4j/codec/binary/types/UInt64Type.java | 16 +++++++++++----- .../xrpl/xrpl4j/codec/binary/types/UIntType.java | 2 -- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java index 514ada287..999c14c03 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java @@ -91,8 +91,6 @@ public static SerializedType getTypeByName(String name) { public static String getNameByType(SerializedType type) { return typeMap.entrySet() .stream() - // We only care about the class name, and the String passed to .apply is only used to figure - // out the radix of the JSON string for UInt64Types. Plus this method is only used in a test. .filter(entry -> entry.getValue().get().getClass().equals(type.getClass())) .map(Map.Entry::getKey) .findAny() diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UInt64Type.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UInt64Type.java index 6bb3497ec..d58843e93 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UInt64Type.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UInt64Type.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. @@ -35,8 +35,7 @@ public class UInt64Type extends UIntType { /** - * These fields are represented as base 10 Strings in JSON, whereas all other STUInt64s are represented - * in base16. + * These fields are represented as base 10 Strings in JSON, whereas all other STUInt64s are represented in base16. */ protected static final Set BASE_10_UINT64_FIELD_NAMES = Sets.newHashSet( "MaximumAmount", "OutstandingAmount", "MPTAmount" @@ -64,7 +63,6 @@ public UInt64Type fromJson(JsonNode value) { @Override public UInt64Type fromJson(JsonNode value, FieldInstance fieldInstance) { int radix = getRadix(fieldInstance); - // STUInt64s are represented as hex-encoded Strings in JSON. return new UInt64Type(UnsignedLong.valueOf(value.asText(), radix)); } @@ -80,6 +78,14 @@ public JsonNode toJson(FieldInstance fieldInstance) { return new TextNode(UnsignedLong.valueOf(toHex(), 16).toString(radix).toUpperCase()); } + /** + * Most UInt64s are represented as hex Strings in JSON. However, some MPT related fields are represented in base 10 in + * JSON. This method determines the radix of the field based on the supplied {@link FieldInstance}'s name. + * + * @param fieldInstance A {@link FieldInstance}. + * + * @return An int representing the radix. + */ private static int getRadix(FieldInstance fieldInstance) { int radix = 16; if (BASE_10_UINT64_FIELD_NAMES.contains(fieldInstance.name())) { diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UIntType.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UIntType.java index 99ba88722..915dcc678 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UIntType.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UIntType.java @@ -25,7 +25,6 @@ import com.google.common.primitives.UnsignedLong; import org.xrpl.xrpl4j.codec.addresses.ByteUtils; import org.xrpl.xrpl4j.codec.addresses.UnsignedByteArray; -import org.xrpl.xrpl4j.codec.binary.definitions.FieldInstance; /** * Base codec for XRPL UInt types. @@ -51,5 +50,4 @@ UnsignedLong valueOf() { public JsonNode toJson() { return new TextNode(UnsignedLong.valueOf(toHex(), 16).toString()); } - } From 73e282ed78fa791fd33d801ca76174b65eae42bf Mon Sep 17 00:00:00 2001 From: nkramer44 Date: Sat, 19 Oct 2024 10:17:31 -0400 Subject: [PATCH 07/11] negative MPT amounts, other formatting feedback --- .../xrpl4j/codec/binary/types/AmountType.java | 22 +++++++------- .../xrpl4j/codec/binary/types/MptAmount.java | 17 +++++++---- .../codec/binary/types/SerializedType.java | 2 -- .../codec/binary/types/AmountTypeTest.java | 30 ++++++++++++++++++- .../src/test/resources/data-driven-tests.json | 15 +++++++++- 5 files changed, 67 insertions(+), 19 deletions(-) diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/AmountType.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/AmountType.java index 8c0a39a03..d5edde1fd 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/AmountType.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/AmountType.java @@ -24,8 +24,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.TextNode; -import com.google.common.base.Preconditions; -import com.google.common.io.BaseEncoding; import com.google.common.primitives.UnsignedLong; import org.xrpl.xrpl4j.codec.addresses.ByteUtils; import org.xrpl.xrpl4j.codec.addresses.UnsignedByte; @@ -199,7 +197,7 @@ public AmountType fromJson(JsonNode value) throws JsonProcessingException { MptAmount amount = objectMapper.treeToValue(value, MptAmount.class); if (FluentCompareTo.is(amount.unsignedLongValue()).greaterThan(UnsignedLong.valueOf(Long.MAX_VALUE))) { - throw new IllegalArgumentException("Invalid MPT amount: given value requires 64 bits, only 63 allowed."); + throw new IllegalArgumentException("Invalid MPT amount. Maximum MPT value is (2^63 - 1)"); } UnsignedByteArray amountBytes = UnsignedByteArray.fromHex( @@ -211,7 +209,8 @@ public AmountType fromJson(JsonNode value) throws JsonProcessingException { UnsignedByteArray issuanceIdBytes = new Hash192Type().fromJson(new TextNode(amount.mptIssuanceId())).value(); // MPT Amounts always have 0110000 as its first byte. - UnsignedByteArray result = UnsignedByteArray.of(UnsignedByte.of(0x60)); + int leadingByte = amount.isNegative() ? 0x20 : 0x60; + UnsignedByteArray result = UnsignedByteArray.of(UnsignedByte.of(leadingByte)); result.append(amountBytes); result.append(issuanceIdBytes); @@ -251,12 +250,14 @@ public JsonNode toJson() { } else if (this.isMpt()) { BinaryParser parser = new BinaryParser(this.toHex()); // We know the first byte already based on this.isMpt() - parser.skip(1); + UnsignedByte leadingByte = parser.read(1).get(0); + boolean isNegative = !leadingByte.isNthBitSet(2); UnsignedLong amount = parser.readUInt64(); UnsignedByteArray issuanceId = new Hash192Type().fromParser(parser).value(); + String amountBase10 = amount.toString(10); MptAmount mptAmount = MptAmount.builder() - .value(amount.toString(10)) + .value(isNegative ? "-" + amountBase10 : amountBase10) .mptIssuanceId(issuanceId.hexValue()) .build(); @@ -301,13 +302,14 @@ public JsonNode toJson() { */ private boolean isNative() { // 1st bit in 1st byte is set to 0 for native XRP, 3rd bit is also 0. - // 0xA0 is 1010 0000 - return (toBytes()[0] & 0xA0) == 0; + byte leadingByte = toBytes()[0]; + return (leadingByte & 0x80) == 0 && (leadingByte & 0x20) == 0; } private boolean isMpt() { - // 1st bit in 1st byte is 0, 2nd bit is 1, and 3rd bit is 1 - return (toBytes()[0] & 0xA0) == 0x20; + // 1st bit in 1st byte is 0, and 3rd bit is 1 + byte leadingByte = toBytes()[0]; + return (leadingByte & 0x80) == 0 && (leadingByte & 0x20) != 0; } /** diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/MptAmount.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/MptAmount.java index 68e7e0458..fbbaffe6f 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/MptAmount.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/MptAmount.java @@ -47,13 +47,20 @@ static ImmutableMptAmount.Builder builder() { String value(); + @JsonProperty("mpt_issuance_id") + String mptIssuanceId(); + + @Value.Derived @JsonIgnore + default boolean isNegative() { + return value().startsWith("-"); + } + @Value.Derived + @JsonIgnore default UnsignedLong unsignedLongValue() { - return UnsignedLong.valueOf(value()); + return isNegative() ? + UnsignedLong.valueOf(value().substring(1)) : + UnsignedLong.valueOf(value()); } - - @JsonProperty("mpt_issuance_id") - String mptIssuanceId(); - } diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java index 999c14c03..3bf4d05e7 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java @@ -31,7 +31,6 @@ import java.util.Map; import java.util.Objects; -import java.util.function.Function; import java.util.function.Supplier; /** @@ -41,7 +40,6 @@ */ public abstract class SerializedType> { - @SuppressWarnings("all") private static final Map>> typeMap = new ImmutableMap.Builder>>() diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/AmountTypeTest.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/AmountTypeTest.java index d803fe7eb..b51cf4b52 100644 --- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/AmountTypeTest.java +++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/AmountTypeTest.java @@ -229,6 +229,15 @@ void encodeDecodeMptAmount() { assertThat(fromJson.toJson().toString()).isEqualTo(json); } + @Test + void encodeDecodeMptAmountNegative() { + String json = "{\"value\":\"-100\",\"mpt_issuance_id\":\"00002403C84A0A28E0190E208E982C352BBD5006600555CF\"}"; + AmountType fromJson = codec.fromJson(json); + assertThat(fromJson.toHex()) + .isEqualTo("20000000000000006400002403C84A0A28E0190E208E982C352BBD5006600555CF"); + assertThat(fromJson.toJson().toString()).isEqualTo(json); + } + @Test void encodeDecodeLargestAmount() { String json = "{\"value\":\"9223372036854775807\"," + @@ -239,12 +248,31 @@ void encodeDecodeLargestAmount() { assertThat(fromJson.toJson().toString()).isEqualTo(json); } + @Test + void encodeDecodeLargestAmountNegative() { + String json = "{\"value\":\"-9223372036854775807\"," + + "\"mpt_issuance_id\":\"00002403C84A0A28E0190E208E982C352BBD5006600555CF\"}"; + AmountType fromJson = codec.fromJson(json); + assertThat(fromJson.toHex()) + .isEqualTo("207FFFFFFFFFFFFFFF00002403C84A0A28E0190E208E982C352BBD5006600555CF"); + assertThat(fromJson.toJson().toString()).isEqualTo(json); + } + @Test void encodeMptAmountWithMoreThan63BitAmountThrows() { UnsignedLong maxLongPlusOne = UnsignedLong.valueOf(Long.MAX_VALUE).plus(UnsignedLong.ONE); String json = "{\"value\":\"" + maxLongPlusOne + "\"," + "\"mpt_issuance_id\":\"00002403C84A0A28E0190E208E982C352BBD5006600555CF\"}"; assertThatThrownBy(() -> codec.fromJson(json)).isInstanceOf(IllegalArgumentException.class) - .hasMessage("Invalid MPT amount: given value requires 64 bits, only 63 allowed."); + .hasMessage("Invalid MPT amount. Maximum MPT value is (2^63 - 1)"); + } + + @Test + void encodeMptAmountWithMoreThan63BitAmountThrowsNegative() { + UnsignedLong maxLongPlusOne = UnsignedLong.valueOf(Long.MAX_VALUE).plus(UnsignedLong.ONE); + String json = "{\"value\":\"-" + maxLongPlusOne + "\"," + + "\"mpt_issuance_id\":\"00002403C84A0A28E0190E208E982C352BBD5006600555CF\"}"; + assertThatThrownBy(() -> codec.fromJson(json)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("Invalid MPT amount. Maximum MPT value is (2^63 - 1)"); } } diff --git a/xrpl4j-core/src/test/resources/data-driven-tests.json b/xrpl4j-core/src/test/resources/data-driven-tests.json index 58c4367e4..b704887d6 100644 --- a/xrpl4j-core/src/test/resources/data-driven-tests.json +++ b/xrpl4j-core/src/test/resources/data-driven-tests.json @@ -3701,8 +3701,10 @@ "mpt_issuance_id": "00002403C84A0A28E0190E208E982C352BBD5006600555CF", "value": "-1" }, + "is_native": false, "type": "Amount", - "error": "Value is negative" + "expected_hex": "20000000000000000100002403C84A0A28E0190E208E982C352BBD5006600555CF", + "is_negative": false }, { "test_json": { @@ -3800,6 +3802,17 @@ "expected_hex": "60000000000000000000002403C84A0A28E0190E208E982C352BBD5006600555CF", "is_negative": false }, + { + "test_json": { + "mpt_issuance_id":"00002403C84A0A28E0190E208E982C352BBD5006600555CF", + "value": "-0" + }, + "type_id": 6, + "is_native": false, + "type": "Amount", + "expected_hex": "20000000000000000000002403C84A0A28E0190E208E982C352BBD5006600555CF", + "is_negative": false + }, { "test_json": { "mpt_issuance_id":"00002403C84A0A28E0190E208E982C352BBD5006600555CF", From f10521fb9d00dc39a18b22bbf473022d0bcfe0b8 Mon Sep 17 00:00:00 2001 From: nkramer44 Date: Sat, 19 Oct 2024 11:36:01 -0400 Subject: [PATCH 08/11] make Hash192 a UInt and rename --- .../xrpl4j/codec/binary/types/AmountType.java | 4 +-- .../codec/binary/types/Hash192Type.java | 31 ------------------- .../codec/binary/types/SerializedType.java | 2 +- .../codec/binary/types/UInt192Type.java | 31 +++++++++++++++++++ .../xrpl4j/codec/binary/types/UIntType.java | 16 +++++----- .../src/main/resources/definitions.json | 4 +-- .../codec/binary/types/HashTypeTest.java | 3 +- .../binary/types/UInt16TypeUnitTest.java | 6 ++-- .../binary/types/UInt32TypeUnitTest.java | 6 ++-- .../binary/types/UInt64TypeUnitTest.java | 10 +++--- 10 files changed, 57 insertions(+), 56 deletions(-) delete mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/Hash192Type.java create mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UInt192Type.java diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/AmountType.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/AmountType.java index d5edde1fd..d6386ac1f 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/AmountType.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/AmountType.java @@ -206,7 +206,7 @@ public AmountType fromJson(JsonNode value) throws JsonProcessingException { 16 // <-- 64 / 4 ) ); - UnsignedByteArray issuanceIdBytes = new Hash192Type().fromJson(new TextNode(amount.mptIssuanceId())).value(); + UnsignedByteArray issuanceIdBytes = new UInt192Type().fromJson(new TextNode(amount.mptIssuanceId())).value(); // MPT Amounts always have 0110000 as its first byte. int leadingByte = amount.isNegative() ? 0x20 : 0x60; @@ -253,7 +253,7 @@ public JsonNode toJson() { UnsignedByte leadingByte = parser.read(1).get(0); boolean isNegative = !leadingByte.isNthBitSet(2); UnsignedLong amount = parser.readUInt64(); - UnsignedByteArray issuanceId = new Hash192Type().fromParser(parser).value(); + UnsignedByteArray issuanceId = new UInt192Type().fromParser(parser).value(); String amountBase10 = amount.toString(10); MptAmount mptAmount = MptAmount.builder() diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/Hash192Type.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/Hash192Type.java deleted file mode 100644 index c0056f4c9..000000000 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/Hash192Type.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.xrpl.xrpl4j.codec.binary.types; - -import com.fasterxml.jackson.databind.JsonNode; -import org.xrpl.xrpl4j.codec.addresses.UnsignedByteArray; -import org.xrpl.xrpl4j.codec.binary.serdes.BinaryParser; - -/** - * Codec for XRPL Hash192 type. - */ -public class Hash192Type extends HashType { - - public static final int WIDTH = 24; - - public Hash192Type() { - this(UnsignedByteArray.ofSize(WIDTH)); - } - - public Hash192Type(UnsignedByteArray list) { - super(list, WIDTH); - } - - @Override - public Hash192Type fromParser(BinaryParser parser) { - return new Hash192Type(parser.read(WIDTH)); - } - - @Override - public Hash192Type fromJson(JsonNode node) { - return new Hash192Type(UnsignedByteArray.fromHex(node.asText())); - } -} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java index 3bf4d05e7..4a2358234 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java @@ -49,7 +49,7 @@ public abstract class SerializedType> { .put("Currency", () -> new CurrencyType()) .put("Hash128", () -> new Hash128Type()) .put("Hash160", () -> new Hash160Type()) - .put("Hash192", () -> new Hash192Type()) + .put("UInt192", () -> new UInt192Type()) .put("Hash256", () -> new Hash256Type()) .put("PathSet", () -> new PathSetType()) .put("STArray", () -> new STArrayType()) diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UInt192Type.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UInt192Type.java new file mode 100644 index 000000000..5fcdd276d --- /dev/null +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UInt192Type.java @@ -0,0 +1,31 @@ +package org.xrpl.xrpl4j.codec.binary.types; + +import com.fasterxml.jackson.databind.JsonNode; +import org.xrpl.xrpl4j.codec.addresses.UnsignedByteArray; +import org.xrpl.xrpl4j.codec.binary.serdes.BinaryParser; + +/** + * Codec for XRPL UInt192 type. + */ +public class UInt192Type extends UIntType { + + public static final int WIDTH_BYTES = 24; + + public UInt192Type() { + this(UnsignedByteArray.ofSize(WIDTH_BYTES)); + } + + public UInt192Type(UnsignedByteArray list) { + super(list, WIDTH_BYTES * 8); + } + + @Override + public UInt192Type fromParser(BinaryParser parser) { + return new UInt192Type(parser.read(WIDTH_BYTES)); + } + + @Override + public UInt192Type fromJson(JsonNode node) { + return new UInt192Type(UnsignedByteArray.fromHex(node.asText())); + } +} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UIntType.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UIntType.java index 915dcc678..c9a5c9f6a 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UIntType.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/UIntType.java @@ -22,6 +22,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.TextNode; +import com.google.common.base.Preconditions; import com.google.common.primitives.UnsignedLong; import org.xrpl.xrpl4j.codec.addresses.ByteUtils; import org.xrpl.xrpl4j.codec.addresses.UnsignedByteArray; @@ -31,19 +32,20 @@ */ abstract class UIntType> extends SerializedType { - private final UnsignedLong value; - public UIntType(UnsignedLong value, int bitSize) { super(UnsignedByteArray.fromHex(ByteUtils.padded(value.toString(16), bitSizeToHexLength(bitSize)))); - this.value = value; } - private static int bitSizeToHexLength(int bitSize) { - return bitSize / 4; + public UIntType(UnsignedByteArray value, int bitSize) { + super(UnsignedByteArray.fromHex(ByteUtils.padded(value.hexValue(), bitSizeToHexLength(bitSize)))); + Preconditions.checkArgument( + value.length() == bitSize / 8, + String.format("Invalid %s length: %s", this.getClass().getSimpleName(), value.length()) + ); } - UnsignedLong valueOf() { - return value; + private static int bitSizeToHexLength(int bitSize) { + return bitSize / 4; } @Override diff --git a/xrpl4j-core/src/main/resources/definitions.json b/xrpl4j-core/src/main/resources/definitions.json index f874d7c00..9ba4b5897 100644 --- a/xrpl4j-core/src/main/resources/definitions.json +++ b/xrpl4j-core/src/main/resources/definitions.json @@ -18,7 +18,7 @@ "PathSet": 18, "Vector256": 19, "UInt96": 20, - "Hash192": 21, + "UInt192": 21, "UInt384": 22, "UInt512": 23, "Issue": 24, @@ -1179,7 +1179,7 @@ "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash192" + "type": "UInt192" } ], [ diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/HashTypeTest.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/HashTypeTest.java index 34884b251..96cb30ad3 100644 --- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/HashTypeTest.java +++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/HashTypeTest.java @@ -24,7 +24,6 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import com.google.common.base.Strings; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; class HashTypeTest { @@ -32,7 +31,7 @@ class HashTypeTest { public static final char DOUBLE_QUOTE = '"'; private final Hash128Type codec128 = new Hash128Type(); private final Hash160Type codec160 = new Hash160Type(); - private final Hash192Type codec192 = new Hash192Type(); + private final UInt192Type codec192 = new UInt192Type(); private final Hash256Type codec256 = new Hash256Type(); @Test diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/UInt16TypeUnitTest.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/UInt16TypeUnitTest.java index ab35eb038..10149b65f 100644 --- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/UInt16TypeUnitTest.java +++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/UInt16TypeUnitTest.java @@ -33,9 +33,9 @@ class UInt16TypeUnitTest { @Test void decode() { - assertThat(codec.fromHex("0000").valueOf()).isEqualTo(UnsignedLong.valueOf(0)); - assertThat(codec.fromHex("000F").valueOf()).isEqualTo(UnsignedLong.valueOf(15)); - assertThat(codec.fromHex("FFFF").valueOf()).isEqualTo(UnsignedLong.valueOf(65535)); + assertThat(codec.fromHex("0000").toHex()).isEqualTo("0000"); + assertThat(codec.fromHex("000F").toHex()).isEqualTo("000F"); + assertThat(codec.fromHex("FFFF").toHex()).isEqualTo("FFFF"); } @Test diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/UInt32TypeUnitTest.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/UInt32TypeUnitTest.java index b550d2bda..80813cd96 100644 --- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/UInt32TypeUnitTest.java +++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/UInt32TypeUnitTest.java @@ -33,9 +33,9 @@ public class UInt32TypeUnitTest { @Test void decode() { - assertThat(codec.fromHex("00000000").valueOf()).isEqualTo(UnsignedLong.valueOf(0)); - assertThat(codec.fromHex("0000000F").valueOf()).isEqualTo(UnsignedLong.valueOf(15)); - assertThat(codec.fromHex("FFFFFFFF").valueOf()).isEqualTo(UnsignedLong.valueOf(4294967295L)); + assertThat(codec.fromHex("00000000").toHex()).isEqualTo("00000000"); + assertThat(codec.fromHex("0000000F").toHex()).isEqualTo("0000000F"); + assertThat(codec.fromHex("FFFFFFFF").toHex()).isEqualTo("FFFFFFFF"); } @Test diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/UInt64TypeUnitTest.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/UInt64TypeUnitTest.java index 66b78074f..48608198f 100644 --- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/UInt64TypeUnitTest.java +++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/UInt64TypeUnitTest.java @@ -35,20 +35,20 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.ValueSource; +import org.xrpl.xrpl4j.codec.addresses.UnsignedByteArray; import org.xrpl.xrpl4j.codec.binary.definitions.FieldInstance; import java.util.stream.Stream; public class UInt64TypeUnitTest { private final UInt64Type type = new UInt64Type(); - private static UnsignedLong maxUint64 = UnsignedLong.valueOf("FFFFFFFFFFFFFFFF", 16); @Test void testFromHex() { - assertThat(type.fromHex("0000000000000000").valueOf()).isEqualTo(UnsignedLong.valueOf(0)); - assertThat(type.fromHex("000000000000000F").valueOf()).isEqualTo(UnsignedLong.valueOf(15)); - assertThat(type.fromHex("00000000FFFFFFFF").valueOf()).isEqualTo(UnsignedLong.valueOf(4294967295L)); - assertThat(type.fromHex("FFFFFFFFFFFFFFFF").valueOf()).isEqualTo(maxUint64); + assertThat(type.fromHex("0000000000000000").toHex()).isEqualTo("0000000000000000"); + assertThat(type.fromHex("000000000000000F").toHex()).isEqualTo("000000000000000F"); + assertThat(type.fromHex("00000000FFFFFFFF").toHex()).isEqualTo("00000000FFFFFFFF"); + assertThat(type.fromHex("FFFFFFFFFFFFFFFF").toHex()).isEqualTo("FFFFFFFFFFFFFFFF"); } @ParameterizedTest From 25d1e1d792f6a504558fb141b31653045eafbae1 Mon Sep 17 00:00:00 2001 From: nkramer44 Date: Sat, 19 Oct 2024 16:45:22 -0400 Subject: [PATCH 09/11] correct definitions.json --- .../src/main/resources/definitions.json | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/xrpl4j-core/src/main/resources/definitions.json b/xrpl4j-core/src/main/resources/definitions.json index 9ba4b5897..daa6bb1fc 100644 --- a/xrpl4j-core/src/main/resources/definitions.json +++ b/xrpl4j-core/src/main/resources/definitions.json @@ -223,9 +223,9 @@ } ], [ - "TickSize", + "AssetScale", { - "nth": 16, + "nth": 5, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -233,9 +233,9 @@ } ], [ - "UNLModifyDisabling", + "TickSize", { - "nth": 17, + "nth": 16, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -243,9 +243,9 @@ } ], [ - "HookResult", + "UNLModifyDisabling", { - "nth": 18, + "nth": 17, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -253,9 +253,9 @@ } ], [ - "WasLockingChainSend", + "HookResult", { - "nth": 19, + "nth": 18, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -263,9 +263,9 @@ } ], [ - "AssetScale", + "WasLockingChainSend", { - "nth": 20, + "nth": 19, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -3062,8 +3062,8 @@ "LedgerStateFix": 53, "MPTokenIssuanceCreate": 54, "MPTokenIssuanceDestroy": 55, - "MPTokenAuthorize": 56, - "MPTokenIssuanceSet": 57, + "MPTokenIssuanceSet": 56, + "MPTokenAuthorize": 57, "EnableAmendment": 100, "SetFee": 101, "UNLModify": 102 From ae996c6fe9f09e43b8a708cf39412754c7c669d4 Mon Sep 17 00:00:00 2001 From: nkramer44 Date: Tue, 29 Oct 2024 11:59:32 -0400 Subject: [PATCH 10/11] pr feedback --- .../org/xrpl/xrpl4j/codec/binary/types/AmountType.java | 8 ++++---- .../xrpl/xrpl4j/codec/binary/types/SerializedType.java | 8 ++++++-- .../codec/binary/types/BaseSerializerTypeTest.java | 9 +++++++-- xrpl4j-core/src/test/resources/data-driven-tests.json | 4 ++-- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/AmountType.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/AmountType.java index d6386ac1f..29fc61968 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/AmountType.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/AmountType.java @@ -300,13 +300,13 @@ public JsonNode toJson() { * * @return {@code true} if this AmountType is native; {@code false} otherwise. */ - private boolean isNative() { + public boolean isNative() { // 1st bit in 1st byte is set to 0 for native XRP, 3rd bit is also 0. byte leadingByte = toBytes()[0]; return (leadingByte & 0x80) == 0 && (leadingByte & 0x20) == 0; } - private boolean isMpt() { + public boolean isMpt() { // 1st bit in 1st byte is 0, and 3rd bit is 1 byte leadingByte = toBytes()[0]; return (leadingByte & 0x80) == 0 && (leadingByte & 0x20) != 0; @@ -317,9 +317,9 @@ private boolean isMpt() { * * @return {@code true} if this AmountType is positive; {@code false} otherwise. */ - private boolean isPositive() { + public boolean isPositive() { // 2nd bit in 1st byte is set to 1 for positive amounts - return (toBytes()[0] & 0x40) > 0; + return toHex().startsWith("00000000000000", 2) || (toBytes()[0] & 0x40) > 0; } } diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java index 4a2358234..0d86b9a76 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/SerializedType.java @@ -119,7 +119,9 @@ public T fromParser(BinaryParser parser, int lengthHint) { } /** - * Obtain a {@link T} using the supplied {@code node}. + * Obtain a {@link T} using the supplied {@code node}. Prefer using {@link #fromJson(JsonNode, FieldInstance)} over + * this method, as some {@link SerializedType}s require a {@link FieldInstance} to accurately serialize and + * deserialize. * * @param node A {@link JsonNode} to use. * @@ -208,7 +210,9 @@ public byte[] toBytes() { } /** - * Convert this {@link SerializedType} to a {@link JsonNode}. + * Convert this {@link SerializedType} to a {@link JsonNode}. Prefer using {@link #toJson(FieldInstance)} over this + * method where possible, as some {@link SerializedType}s require a {@link FieldInstance} to accurately serialize and + * deserialize. * * @return A {@link JsonNode}. */ diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/BaseSerializerTypeTest.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/BaseSerializerTypeTest.java index 12386ba06..6ce484063 100644 --- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/BaseSerializerTypeTest.java +++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/BaseSerializerTypeTest.java @@ -50,12 +50,17 @@ protected static Stream dataDrivenFixturesForType(SerializedType seri @ParameterizedTest @MethodSource("dataDrivenFixtures") void fixtureTests(ValueTest fixture) throws IOException { - SerializedType serializedType = getType(); + SerializedType serializedType = getType(); JsonNode value = getValue(fixture); if (fixture.error() != null) { assertThrows(Exception.class, () -> serializedType.fromJson(value)); } else { - assertThat(serializedType.fromJson(value).toHex()).isEqualTo(fixture.expectedHex()); + SerializedType serialized = serializedType.fromJson(value); + if (fixture.type().equals("Amount")) { + assertThat(((AmountType) serialized).isPositive()).isEqualTo(!fixture.isNegative()); + assertThat(((AmountType) serialized).isNative()).isEqualTo(fixture.isNative()); + } + assertThat(serialized.toHex()).isEqualTo(fixture.expectedHex()); } } diff --git a/xrpl4j-core/src/test/resources/data-driven-tests.json b/xrpl4j-core/src/test/resources/data-driven-tests.json index b704887d6..99260f8e5 100644 --- a/xrpl4j-core/src/test/resources/data-driven-tests.json +++ b/xrpl4j-core/src/test/resources/data-driven-tests.json @@ -3704,7 +3704,7 @@ "is_native": false, "type": "Amount", "expected_hex": "20000000000000000100002403C84A0A28E0190E208E982C352BBD5006600555CF", - "is_negative": false + "is_negative": true }, { "test_json": { @@ -3811,7 +3811,7 @@ "is_native": false, "type": "Amount", "expected_hex": "20000000000000000000002403C84A0A28E0190E208E982C352BBD5006600555CF", - "is_negative": false + "is_negative": true }, { "test_json": { From b34cd1eeee5af73c33ca1639eab64365dede4ef9 Mon Sep 17 00:00:00 2001 From: nkramer44 Date: Sat, 9 Nov 2024 10:23:04 -0500 Subject: [PATCH 11/11] rename MPTokenHolder to Holder --- .../xrpl4j/codec/binary/types/AmountType.java | 3 +- .../src/main/resources/definitions.json | 2 +- .../binary/types/BaseSerializerTypeTest.java | 5 ++-- .../src/test/resources/data-driven-tests.json | 30 ------------------- 4 files changed, 6 insertions(+), 34 deletions(-) diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/AmountType.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/AmountType.java index 29fc61968..75d44533e 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/AmountType.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/AmountType.java @@ -24,6 +24,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.TextNode; +import com.google.common.base.Strings; import com.google.common.primitives.UnsignedLong; import org.xrpl.xrpl4j.codec.addresses.ByteUtils; import org.xrpl.xrpl4j.codec.addresses.UnsignedByte; @@ -319,7 +320,7 @@ public boolean isMpt() { */ public boolean isPositive() { // 2nd bit in 1st byte is set to 1 for positive amounts - return toHex().startsWith("00000000000000", 2) || (toBytes()[0] & 0x40) > 0; + return (toBytes()[0] & 0x40) > 0; } } diff --git a/xrpl4j-core/src/main/resources/definitions.json b/xrpl4j-core/src/main/resources/definitions.json index daa6bb1fc..6e2257e8d 100644 --- a/xrpl4j-core/src/main/resources/definitions.json +++ b/xrpl4j-core/src/main/resources/definitions.json @@ -2143,7 +2143,7 @@ } ], [ - "MPTokenHolder", + "Holder", { "nth": 11, "isVLEncoded": true, diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/BaseSerializerTypeTest.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/BaseSerializerTypeTest.java index 6ce484063..6416aa979 100644 --- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/BaseSerializerTypeTest.java +++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/types/BaseSerializerTypeTest.java @@ -57,8 +57,9 @@ void fixtureTests(ValueTest fixture) throws IOException { } else { SerializedType serialized = serializedType.fromJson(value); if (fixture.type().equals("Amount")) { - assertThat(((AmountType) serialized).isPositive()).isEqualTo(!fixture.isNegative()); - assertThat(((AmountType) serialized).isNative()).isEqualTo(fixture.isNative()); + AmountType amountType = (AmountType) serialized; + assertThat(amountType.isPositive()).isEqualTo(!fixture.isNegative()); + assertThat(amountType.isNative()).isEqualTo(fixture.isNative()); } assertThat(serialized.toHex()).isEqualTo(fixture.expectedHex()); } diff --git a/xrpl4j-core/src/test/resources/data-driven-tests.json b/xrpl4j-core/src/test/resources/data-driven-tests.json index 99260f8e5..745eb7a28 100644 --- a/xrpl4j-core/src/test/resources/data-driven-tests.json +++ b/xrpl4j-core/src/test/resources/data-driven-tests.json @@ -2524,21 +2524,6 @@ "is_negative": false, "exponent": -15 }, - { - "test_json": { - "currency": "USD", - "value": "0", - "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji" - }, - "significant_digits": 1, - "type_id": 6, - "is_native": false, - "mantissa": "0000000000000000", - "type": "Amount", - "expected_hex": "800000000000000000000000000000000000000055534400000000000000000000000000000000000000000000000001", - "is_negative": false, - "exponent": -15 - }, { "test_json": { "currency": "USD", @@ -2569,21 +2554,6 @@ "is_negative": false, "exponent": -15 }, - { - "test_json": { - "currency": "USD", - "value": "0.0", - "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji" - }, - "significant_digits": 1, - "type_id": 6, - "is_native": false, - "mantissa": "0000000000000000", - "type": "Amount", - "expected_hex": "800000000000000000000000000000000000000055534400000000000000000000000000000000000000000000000001", - "is_negative": false, - "exponent": -15 - }, { "test_json": { "currency": "USD",