Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/maven/jackson.version-2.15.2
Browse files Browse the repository at this point in the history
  • Loading branch information
sappenin authored Dec 6, 2023
2 parents 2c8cb95 + 3c4a076 commit d9f02f7
Show file tree
Hide file tree
Showing 97 changed files with 9,858 additions and 1,403 deletions.
5 changes: 3 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,11 @@
<artifactId>jackson-datatype-cryptoconditions</artifactId>
<version>${cryptoconditions.version}</version>
</dependency>
<!-- This is the highest version we can use if we want to support Java 8. See https://logback.qos.ch/download.html -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.11</version>
<version>1.3.8</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
Expand Down Expand Up @@ -291,7 +292,7 @@
<cryptoconditions.version>1.0.4</cryptoconditions.version>
<jackson.version>2.15.2</jackson.version>
<feign.version>12.3</feign.version>
<slf4j.version>1.7.36</slf4j.version>
<slf4j.version>2.0.7</slf4j.version>
<junit-jupiter.version>5.10.0</junit-jupiter.version>
<guava.version>32.1.1-jre</guava.version>
</properties>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.primitives.UnsignedLong;
import org.xrpl.xrpl4j.codec.addresses.ByteUtils;
import org.xrpl.xrpl4j.codec.addresses.UnsignedByte;
import org.xrpl.xrpl4j.codec.addresses.UnsignedByteArray;
Expand Down Expand Up @@ -140,8 +141,14 @@ public AmountType fromParser(BinaryParser parser) {
public AmountType fromJson(JsonNode value) throws JsonProcessingException {
if (value.isValueNode()) {
assertXrpIsValid(value.asText());
UInt64Type number = new UInt64Type().fromJson(value.asText());
byte[] rawBytes = number.toBytes();

UnsignedByteArray number = UnsignedByteArray.fromHex(
ByteUtils.padded(
UnsignedLong.valueOf(value.asText()).toString(16),
64 / 4
)
);
byte[] rawBytes = number.toByteArray();
rawBytes[0] |= 0x40;
return new AmountType(UnsignedByteArray.of(rawBytes));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public abstract class SerializedType<T extends SerializedType<T>> {
.put("UInt64", () -> new UInt64Type())
.put("Vector256", () -> new Vector256Type())
.put("Issue", () -> new IssueType())
.put("XChainBridge", () -> new XChainBridgeType())
.build();
private final UnsignedByteArray bytes;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*/

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.TextNode;
import com.google.common.primitives.UnsignedLong;
import org.xrpl.xrpl4j.codec.binary.serdes.BinaryParser;

Expand All @@ -44,7 +45,12 @@ public UInt64Type fromParser(BinaryParser parser) {

@Override
public UInt64Type fromJson(JsonNode value) {
return new UInt64Type(UnsignedLong.valueOf(value.asText()));
// STUInt64s are represented as hex-encoded Strings in JSON.
return new UInt64Type(UnsignedLong.valueOf(value.asText(), 16));
}

@Override
public JsonNode toJson() {
return new TextNode(UnsignedLong.valueOf(toHex(), 16).toString(16));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package org.xrpl.xrpl4j.codec.binary.types;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.annotations.Beta;
import org.immutables.value.Value.Immutable;

/**
* JSON mapping object for the XChainBridge serialized type.
*/
@Beta
@Immutable
@JsonSerialize(as = ImmutableXChainBridge.class)
@JsonDeserialize(as = ImmutableXChainBridge.class)
public interface XChainBridge {

/**
* Construct a {@code XChainBridge} builder.
*
* @return An {@link ImmutableXChainBridge.Builder}.
*/
static ImmutableXChainBridge.Builder builder() {
return ImmutableXChainBridge.builder();
}

/**
* The door account on the issuing chain. For an XRP-XRP bridge, this must be the genesis account (the account that is
* created when the network is first started, which contains all of the XRP).
*
* @return The address of the door account as a {@link JsonNode}.
*/
@JsonProperty("IssuingChainDoor")
JsonNode issuingChainDoor();

/**
* The asset that is minted and burned on the issuing chain. For an IOU-IOU bridge, the issuer of the asset must be
* the door account on the issuing chain, to avoid supply issues.
*
* @return An {@link Issue}.
*/
@JsonProperty("IssuingChainIssue")
JsonNode issuingChainIssue();

/**
* The door account on the locking chain.
*
* @return The address of the door account as a {@link JsonNode}.
*/
@JsonProperty("LockingChainDoor")
JsonNode lockingChainDoor();

/**
* The asset that is locked and unlocked on the locking chain.
*
* @return An {@link Issue}.
*/
@JsonProperty("LockingChainIssue")
JsonNode lockingChainIssue();


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package org.xrpl.xrpl4j.codec.binary.types;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.xrpl.xrpl4j.codec.addresses.UnsignedByte;
import org.xrpl.xrpl4j.codec.addresses.UnsignedByteArray;
import org.xrpl.xrpl4j.codec.binary.BinaryCodecObjectMapperFactory;
import org.xrpl.xrpl4j.codec.binary.serdes.BinaryParser;

public class XChainBridgeType extends SerializedType<XChainBridgeType> {

private static final ObjectMapper objectMapper = BinaryCodecObjectMapperFactory.getObjectMapper();

/**
* XChainBridge typed fields are serialized by serializing the LockingChainDoor, LockingChainIssue, IssuingChainDoor
* IssuingChainIssue fields in order without type or field codes. LockingChainDoor and IssuingChainDoor are an
* {@link AccountIdType}, and LockingChainIssue and IssuingChainIssue are {@link IssueType}s.
*
* <p>The "empty" or "zero"
* XChainBridge type has LockingChainDoor and IssuingChainDoor = ACCOUNT_ZERO, and LockingChainIssue and
* IssuingChainIssue = XRP. AccountIDs are serialized with a length prefix, which is always {@code 0x14}. The XRP
* issue is serialized as 160 zero bits. Therefore, the "zero" XChainBridge is {@code 0x14} followed by 20 zero bytes
* for the LockingChainDoor, followed by 20 zero bytes for LockingChainIssue, followed by {@code 0x14} and 20 zero
* bytes for the IssuingChainDoor and 20 zero bytes for IssuingChainIssue.</p>
*/
private static final byte[] ZERO_XCHAIN_BRIDGE = new byte[82];

static {
ZERO_XCHAIN_BRIDGE[0] = 0x14;
ZERO_XCHAIN_BRIDGE[41] = 0x14;
}

public XChainBridgeType() {
this(UnsignedByteArray.of(ZERO_XCHAIN_BRIDGE));
}

public XChainBridgeType(UnsignedByteArray bytes) {
super(bytes);
}


@Override
public XChainBridgeType fromJson(JsonNode node) throws JsonProcessingException {
if (!node.isObject()) {
throw new IllegalArgumentException("node is not an object");
}
XChainBridge bridge = objectMapper.treeToValue(node, XChainBridge.class);

// AccountIDs have a VL prefix that is always 20 (except for ACCOUNT_ZERO). Usually this length prefix is
// added in BinarySerializer.writeFieldAndValue because STAccounts are VL encoded according to definitions.json.
// However, because STXChainBridges are not VL encoded, we need to manually add the length prefix to the two
// STAccount types here.
UnsignedByteArray byteArray = UnsignedByteArray.of(UnsignedByte.of(20));
byteArray.append(new AccountIdType().fromJson(bridge.lockingChainDoor()).value());
byteArray.append(new IssueType().fromJson(bridge.lockingChainIssue()).value());

// Need to add length prefix for issuing chain door account.
byteArray.append(UnsignedByte.of(20));
byteArray.append(new AccountIdType().fromJson(bridge.issuingChainDoor()).value());
byteArray.append(new IssueType().fromJson(bridge.issuingChainIssue()).value());

return new XChainBridgeType(byteArray);
}

@Override
public XChainBridgeType fromParser(BinaryParser parser) {
parser.skip(1);
AccountIdType lockingChainDoor = new AccountIdType().fromParser(parser);
IssueType lockingChainIssue = new IssueType().fromParser(parser);
parser.skip(1);
AccountIdType issuingChainDoor = new AccountIdType().fromParser(parser);
IssueType issuingChainIssue = new IssueType().fromParser(parser);

return new XChainBridgeType(
UnsignedByteArray.of(UnsignedByte.of(20))
.append(lockingChainDoor.value())
.append(lockingChainIssue.value())
.append(UnsignedByte.of(20))
.append(issuingChainDoor.value())
.append(issuingChainIssue.value())
);
}

@Override
public JsonNode toJson() {
BinaryParser parser = new BinaryParser(this.toHex());
parser.skip(1);
AccountIdType lockingChainDoor = new AccountIdType().fromParser(parser);
IssueType lockingChainIssue = new IssueType().fromParser(parser);
parser.skip(1);
AccountIdType issuingChainDoor = new AccountIdType().fromParser(parser);
IssueType issuingChainIssue = new IssueType().fromParser(parser);

XChainBridge bridge = XChainBridge.builder()
.lockingChainDoor(lockingChainDoor.toJson())
.lockingChainIssue(lockingChainIssue.toJson())
.issuingChainDoor(issuingChainDoor.toJson())
.issuingChainIssue(issuingChainIssue.toJson())
.build();

return objectMapper.valueToTree(bridge);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.xrpl.xrpl4j.crypto.keys.PrivateKeyable;
import org.xrpl.xrpl4j.crypto.keys.PublicKey;
import org.xrpl.xrpl4j.model.client.channels.UnsignedClaim;
import org.xrpl.xrpl4j.model.ledger.Attestation;
import org.xrpl.xrpl4j.model.transactions.Signer;
import org.xrpl.xrpl4j.model.transactions.Transaction;

Expand Down Expand Up @@ -101,6 +102,11 @@ public Signature sign(final P privateKeyable, final UnsignedClaim unsignedClaim)
return this.abstractTransactionSigner.sign(privateKeyable, unsignedClaim);
}

@Override
public Signature sign(P privateKeyable, Attestation attestation) {
return this.abstractTransactionSigner.sign(privateKeyable, attestation);
}

@Override
public <T extends Transaction> Signature multiSign(final P privateKeyable, final T transaction) {
return abstractTransactionSigner.multiSign(privateKeyable, transaction);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.xrpl.xrpl4j.crypto.keys.PrivateKeyable;
import org.xrpl.xrpl4j.crypto.keys.PublicKey;
import org.xrpl.xrpl4j.model.client.channels.UnsignedClaim;
import org.xrpl.xrpl4j.model.ledger.Attestation;
import org.xrpl.xrpl4j.model.transactions.Address;
import org.xrpl.xrpl4j.model.transactions.Transaction;

Expand Down Expand Up @@ -67,6 +68,15 @@ public Signature sign(final P privateKeyable, final UnsignedClaim unsignedClaim)
return this.signingHelper(privateKeyable, signableBytes);
}

@Override
public Signature sign(P privateKeyable, Attestation attestation) {
Objects.requireNonNull(privateKeyable);
Objects.requireNonNull(attestation);

final UnsignedByteArray signableBytes = this.signatureUtils.toSignableBytes(attestation);
return this.signingHelper(privateKeyable, signableBytes);
}

@Override
public <T extends Transaction> Signature multiSign(final P privateKeyable, final T transaction) {
Objects.requireNonNull(privateKeyable);
Expand Down
Loading

0 comments on commit d9f02f7

Please sign in to comment.