From 90f3ad5b583ebd1abf8d378a19bdbbe201a483fe Mon Sep 17 00:00:00 2001 From: Shawn Reuland Date: Sun, 20 Mar 2022 20:29:25 -0700 Subject: [PATCH 1/7] #410: updated xdr definitions for Protocol 19, add SignedPayload Signer from CAP40 into StrKey encoding/decoding. --- CHANGELOG.md | 6 + readme.md | 6 + src/main/java/org/stellar/sdk/Predicate.java | 19 +- .../org/stellar/sdk/SignedPayloadSigner.java | 45 +++ src/main/java/org/stellar/sdk/Signer.java | 24 ++ src/main/java/org/stellar/sdk/StrKey.java | 73 +++- .../java/org/stellar/sdk/Transaction.java | 29 +- .../sdk/xdr/AccountEntryExtensionV2.java | 30 +- .../sdk/xdr/AccountEntryExtensionV3.java | 107 ++++++ .../stellar/sdk/xdr/AllowTrustResultCode.java | 2 +- src/main/java/org/stellar/sdk/xdr/Asset.java | 61 ++-- .../org/stellar/sdk/xdr/ClaimPredicate.java | 38 +- .../stellar/sdk/xdr/ClaimableBalanceID.java | 30 +- .../sdk/xdr/ClaimableBalanceIDType.java | 5 +- .../org/stellar/sdk/xdr/CryptoKeyType.java | 3 + .../java/org/stellar/sdk/xdr/Duration.java | 60 ++++ .../org/stellar/sdk/xdr/ExtensionPoint.java | 79 +++++ .../org/stellar/sdk/xdr/HashIDPreimage.java | 327 ++++++++++++++++++ .../org/stellar/sdk/xdr/LedgerBounds.java | 84 +++++ .../sdk/xdr/LedgerHeaderExtensionV1.java | 6 +- .../stellar/sdk/xdr/LedgerHeaderFlags.java | 3 +- .../org/stellar/sdk/xdr/OfferEntryFlags.java | 2 +- .../org/stellar/sdk/xdr/PreconditionType.java | 52 +++ .../org/stellar/sdk/xdr/Preconditions.java | 123 +++++++ .../org/stellar/sdk/xdr/PreconditionsV2.java | 206 +++++++++++ .../java/org/stellar/sdk/xdr/SignerKey.java | 107 +++++- .../org/stellar/sdk/xdr/SignerKeyType.java | 5 +- .../org/stellar/sdk/xdr/StellarValue.java | 6 +- .../java/org/stellar/sdk/xdr/Transaction.java | 42 +-- .../org/stellar/sdk/xdr/TrustLineEntry.java | 12 +- .../stellar/sdk/SetOptionsOperationTest.java | 43 +++ src/test/java/org/stellar/sdk/SignerTest.java | 45 +++ src/test/java/org/stellar/sdk/StrKeyTest.java | 63 +++- .../java/org/stellar/sdk/TransactionTest.java | 13 +- .../sdk/xdr/AccountEntryDecodeTest.java | 50 +++ xdr/Stellar-ledger-entries.x | 39 ++- xdr/Stellar-ledger.x | 12 +- xdr/Stellar-transaction.x | 67 +++- xdr/Stellar-types.x | 21 +- 39 files changed, 1757 insertions(+), 188 deletions(-) create mode 100644 src/main/java/org/stellar/sdk/SignedPayloadSigner.java create mode 100644 src/main/java/org/stellar/sdk/xdr/AccountEntryExtensionV3.java create mode 100644 src/main/java/org/stellar/sdk/xdr/Duration.java create mode 100644 src/main/java/org/stellar/sdk/xdr/ExtensionPoint.java create mode 100644 src/main/java/org/stellar/sdk/xdr/HashIDPreimage.java create mode 100644 src/main/java/org/stellar/sdk/xdr/LedgerBounds.java create mode 100644 src/main/java/org/stellar/sdk/xdr/PreconditionType.java create mode 100644 src/main/java/org/stellar/sdk/xdr/Preconditions.java create mode 100644 src/main/java/org/stellar/sdk/xdr/PreconditionsV2.java create mode 100644 src/test/java/org/stellar/sdk/SetOptionsOperationTest.java create mode 100644 src/test/java/org/stellar/sdk/SignerTest.java create mode 100644 src/test/java/org/stellar/sdk/xdr/AccountEntryDecodeTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index b745eb23b..aa6114035 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ As this project is pre 1.0, breaking changes may happen for minor version bumps. A breaking change will get clearly notified in this log. +## 0.32.0 (Pending) + +* Update XDR definitions and auto-generated classes to support upcoming protocol 19 release ([#276](https://github.com/stellar/java-stellar-sdk/pull/276)). +* Extend StrKey implementation to handle [CAP 40 Payload Signer](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0040.md) ([#276](https://github.com/stellar/java-stellar-sdk/pull/276)). + + ## 0.31.0 * Fixed NPE on TrustlineCreatedEffectResponse.getAsset() for liquidity pool asset type. diff --git a/readme.md b/readme.md index 2cb0a606b..a1a2c1202 100644 --- a/readme.md +++ b/readme.md @@ -38,3 +38,9 @@ For information on how to contribute, please refer to our [contribution guide](h ## License java-stellar-sdk is licensed under an Apache-2.0 license. See the [LICENSE](https://github.com/stellar/java-stellar-sdk/blob/master/LICENSE) file for details. + +## xdr to jave code generation +All the java source files in org.stellar.sdk.xdr package are generated using the `xdrgen` command from the [stellar/xdrgen](https://github.com/stellar/xdrgen) +``` +xdrgen -o ./src/main/java/org/stellar/sdk/xdr -l java -n org.stellar.sdk.xdr ./xdr/Stellar-types.x ./xdr/Stellar-SCP.x ./xdr/Stellar-overlay.x ./xdr/Stellar-ledger-entries.x ./xdr/Stellar-ledger.x ./xdr/Stellar-transaction.x +``` \ No newline at end of file diff --git a/src/main/java/org/stellar/sdk/Predicate.java b/src/main/java/org/stellar/sdk/Predicate.java index 045fc1eec..35d7c7617 100644 --- a/src/main/java/org/stellar/sdk/Predicate.java +++ b/src/main/java/org/stellar/sdk/Predicate.java @@ -4,7 +4,10 @@ import com.google.common.collect.Lists; import org.stellar.sdk.xdr.ClaimPredicate; import org.stellar.sdk.xdr.ClaimPredicateType; +import org.stellar.sdk.xdr.Duration; import org.stellar.sdk.xdr.Int64; +import org.stellar.sdk.xdr.TimePoint; +import org.stellar.sdk.xdr.Uint64; import org.threeten.bp.Instant; import java.util.List; @@ -34,9 +37,9 @@ public static Predicate fromXdr(org.stellar.sdk.xdr.ClaimPredicate xdr) { case CLAIM_PREDICATE_NOT: return new Not(fromXdr(xdr.getNotPredicate())); case CLAIM_PREDICATE_BEFORE_RELATIVE_TIME: - return new RelBefore(xdr.getRelBefore().getInt64()); + return new RelBefore(xdr.getRelBefore().getDuration().getInt64()); case CLAIM_PREDICATE_BEFORE_ABSOLUTE_TIME: - return new AbsBefore(xdr.getAbsBefore().getInt64()); + return new AbsBefore(xdr.getAbsBefore().getTimePoint().getUint64()); default: throw new IllegalArgumentException("Unknown asset type " + xdr.getDiscriminant()); } @@ -209,9 +212,11 @@ public int hashCode() { public ClaimPredicate toXdr() { org.stellar.sdk.xdr.ClaimPredicate xdr = new org.stellar.sdk.xdr.ClaimPredicate(); xdr.setDiscriminant(ClaimPredicateType.CLAIM_PREDICATE_BEFORE_ABSOLUTE_TIME); - Int64 t = new Int64(); - t.setInt64(epochSeconds); - xdr.setAbsBefore(t); + Uint64 t = new Uint64(); + t.setUint64(epochSeconds); + TimePoint beforeTime = new TimePoint(); + beforeTime.setTimePoint(t); + xdr.setAbsBefore(beforeTime); return xdr; } } @@ -246,7 +251,9 @@ public ClaimPredicate toXdr() { xdr.setDiscriminant(ClaimPredicateType.CLAIM_PREDICATE_BEFORE_RELATIVE_TIME); Int64 t = new Int64(); t.setInt64(secondsSinceClose); - xdr.setRelBefore(t); + Duration beforeTime = new Duration(); + beforeTime.setDuration(t); + xdr.setRelBefore(beforeTime); return xdr; } } diff --git a/src/main/java/org/stellar/sdk/SignedPayloadSigner.java b/src/main/java/org/stellar/sdk/SignedPayloadSigner.java new file mode 100644 index 000000000..06e573a5c --- /dev/null +++ b/src/main/java/org/stellar/sdk/SignedPayloadSigner.java @@ -0,0 +1,45 @@ +package org.stellar.sdk; + +/** + * Data model for the signed payload signer + */ +public class SignedPayloadSigner { + private String accountId; + private byte[] payload; + + /** + * constructor + * + * @param accountId - the StrKey format of a stellar AccountId + * @param payload - the raw payload for a signed payload + */ + public SignedPayloadSigner(String accountId, byte[] payload) { + this.accountId = accountId; + this.payload = payload; + } + + /** + * get the StrKey encoded representation of a stellar account id + * @return stellar account id in StrKey encoding + */ + public String getEncodedAccountId() { + return accountId; + } + + /** + * get the binary format of a stellar account id, a Ed25519 public key + * @return stellar account id in binary format + */ + public byte[] getDecodedAccountId() { + return StrKey.decodeStellarAccountId(accountId); + } + + /** + * get the payload that signatures are produced from. + * @see + * @return + */ + public byte[] getPayload() { + return payload; + } +} diff --git a/src/main/java/org/stellar/sdk/Signer.java b/src/main/java/org/stellar/sdk/Signer.java index 8f1e91ecf..cbf356af0 100644 --- a/src/main/java/org/stellar/sdk/Signer.java +++ b/src/main/java/org/stellar/sdk/Signer.java @@ -4,12 +4,15 @@ import org.stellar.sdk.xdr.SignerKeyType; import org.stellar.sdk.xdr.Uint256; +import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; /** * Signer is a helper class that creates {@link org.stellar.sdk.xdr.SignerKey} objects. */ public class Signer { + public static final int SIGNED_PAYLOAD_MAX_PAYLOAD_LENGTH = 64; + /** * Create ed25519PublicKey {@link org.stellar.sdk.xdr.SignerKey} from * a {@link org.stellar.sdk.KeyPair} @@ -72,6 +75,27 @@ public static SignerKey preAuthTx(byte[] hash) { return signerKey; } + /** + * Create SignerKey {@link org.stellar.sdk.xdr.SignerKey} from {@link org.stellar.sdk.SignedPayloadSigner} + * + * @param signedPayloadSigner - signed payload values + * @return org.stellar.sdk.xdr.SignerKey + */ + public static SignerKey signedPayload(SignedPayloadSigner signedPayloadSigner) { + checkNotNull(signedPayloadSigner.getEncodedAccountId(), "accountId cannot be null"); + checkArgument(signedPayloadSigner.getPayload().length <= SIGNED_PAYLOAD_MAX_PAYLOAD_LENGTH ); + + SignerKey signerKey = new SignerKey(); + SignerKey.SignerKeyEd25519SignedPayload payloadSigner = new SignerKey.SignerKeyEd25519SignedPayload(); + payloadSigner.setPayload(signedPayloadSigner.getPayload()); + payloadSigner.setEd25519(createUint256(signedPayloadSigner.getDecodedAccountId())); + + signerKey.setDiscriminant(SignerKeyType.SIGNER_KEY_TYPE_ED25519_SIGNED_PAYLOAD); + signerKey.setEd25519SignedPayload(payloadSigner); + + return signerKey; + } + private static Uint256 createUint256(byte[] hash) { if (hash.length != 32) { throw new RuntimeException("hash must be 32 bytes long"); diff --git a/src/main/java/org/stellar/sdk/StrKey.java b/src/main/java/org/stellar/sdk/StrKey.java index 438814718..7a0b787b9 100644 --- a/src/main/java/org/stellar/sdk/StrKey.java +++ b/src/main/java/org/stellar/sdk/StrKey.java @@ -1,14 +1,29 @@ package org.stellar.sdk; -import com.google.common.io.BaseEncoding; import com.google.common.base.Optional; +import com.google.common.io.BaseEncoding; import com.google.common.primitives.Bytes; import com.google.common.primitives.Longs; -import org.stellar.sdk.xdr.*; - -import java.io.*; +import org.stellar.sdk.xdr.AccountID; +import org.stellar.sdk.xdr.CryptoKeyType; +import org.stellar.sdk.xdr.MuxedAccount; +import org.stellar.sdk.xdr.PublicKey; +import org.stellar.sdk.xdr.PublicKeyType; +import org.stellar.sdk.xdr.Uint256; +import org.stellar.sdk.xdr.Uint64; +import org.stellar.sdk.xdr.XdrDataInputStream; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.CharArrayWriter; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.OutputStream; import java.util.Arrays; +import static org.stellar.sdk.Signer.SIGNED_PAYLOAD_MAX_PAYLOAD_LENGTH; + class StrKey { public static final int ACCOUNT_ID_ADDRESS_LENGTH = 56; @@ -18,7 +33,8 @@ public enum VersionByte { MUXED((byte)(12 << 3)), // M SEED((byte)(18 << 3)), // S PRE_AUTH_TX((byte)(19 << 3)), // T - SHA256_HASH((byte)(23 << 3)); // X + SHA256_HASH((byte)(23 << 3)), // X + SIGNED_PAYLOAD((byte)(15 << 3)); // P private final byte value; VersionByte(byte value) { this.value = value; @@ -49,6 +65,25 @@ public static String encodeStellarAccountId(AccountID accountID) { return String.valueOf(encoded); } + public static String encodeSignedPayload(SignedPayloadSigner signedPayloadSigner) { + if (signedPayloadSigner.getPayload().length > SIGNED_PAYLOAD_MAX_PAYLOAD_LENGTH) { + throw new FormatException("invalid payload length, must be less than " + SIGNED_PAYLOAD_MAX_PAYLOAD_LENGTH); + } + try { + ByteArrayOutputStream record = new ByteArrayOutputStream(); + DataOutputStream dataStream = new DataOutputStream(record); + dataStream.write(signedPayloadSigner.getDecodedAccountId()); + dataStream.writeInt(signedPayloadSigner.getPayload().length); + dataStream.write(signedPayloadSigner.getPayload()); + int padding = signedPayloadSigner.getPayload().length % 4 > 0 ? 4 - signedPayloadSigner.getPayload().length % 4 : 0; + dataStream.write(new byte[padding]); + char[] encoded = encodeCheck(VersionByte.SIGNED_PAYLOAD, record.toByteArray()); + return String.valueOf(encoded); + } catch (Exception ex) { + throw new FormatException(ex.getMessage()); + } + } + public static String encodeStellarMuxedAccount(MuxedAccount muxedAccount) { switch (muxedAccount.getDiscriminant()) { case KEY_TYPE_MUXED_ED25519: @@ -154,6 +189,22 @@ public static byte[] decodeStellarSecretSeed(char[] data) { return decodeCheck(VersionByte.SEED, data); } + public static SignedPayloadSigner decodeSignedPayload(char[] data) { + try { + byte[] signedPayloadRaw = decodeCheck(VersionByte.SIGNED_PAYLOAD, data); + DataInputStream dataStream = new DataInputStream(new ByteArrayInputStream(signedPayloadRaw)); + byte[] binaryAccountId = new byte[32]; + dataStream.read(binaryAccountId); + int payloadLength = dataStream.readInt(); + byte[] payload = new byte[payloadLength]; + dataStream.read(payload); + + return new SignedPayloadSigner(encodeStellarAccountId(binaryAccountId), payload ); + } catch (Exception ex) { + throw new FormatException(ex.getMessage()); + } + } + public static String encodePreAuthTx(byte[] data) { char[] encoded = encodeCheck(VersionByte.PRE_AUTH_TX, data); return String.valueOf(encoded); @@ -177,20 +228,20 @@ protected static char[] encodeCheck(VersionByte versionByte, byte[] data) { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); outputStream.write(versionByte.getValue()); outputStream.write(data); - byte payload[] = outputStream.toByteArray(); - byte checksum[] = StrKey.calculateChecksum(payload); + byte[] payload = outputStream.toByteArray(); + byte[] checksum = StrKey.calculateChecksum(payload); outputStream.write(checksum); - byte unencoded[] = outputStream.toByteArray(); + byte[] unencoded = outputStream.toByteArray(); if (VersionByte.SEED != versionByte) { - return StrKey.base32Encoding.encode(unencoded).toCharArray(); + return base32Encoding.encode(unencoded).toCharArray(); } // Why not use base32Encoding.encode here? // We don't want secret seed to be stored as String in memory because of security reasons. It's impossible // to erase it from memory when we want it to be erased (ASAP). CharArrayWriter charArrayWriter = new CharArrayWriter(unencoded.length); - OutputStream charOutputStream = StrKey.base32Encoding.encodingStream(charArrayWriter); + OutputStream charOutputStream = base32Encoding.encodingStream(charArrayWriter); charOutputStream.write(unencoded); char[] charsEncoded = charArrayWriter.toCharArray(); @@ -242,7 +293,7 @@ protected static byte[] decodeCheck(VersionByte versionByte, char[] encoded) { } } - byte[] decoded = StrKey.base32Encoding.decode(java.nio.CharBuffer.wrap(encoded)); + byte[] decoded = base32Encoding.decode(java.nio.CharBuffer.wrap(encoded)); byte decodedVersionByte = decoded[0]; byte[] payload = Arrays.copyOfRange(decoded, 0, decoded.length-2); byte[] data = Arrays.copyOfRange(payload, 1, payload.length); diff --git a/src/main/java/org/stellar/sdk/Transaction.java b/src/main/java/org/stellar/sdk/Transaction.java index fc90f502f..082d41d20 100644 --- a/src/main/java/org/stellar/sdk/Transaction.java +++ b/src/main/java/org/stellar/sdk/Transaction.java @@ -1,7 +1,23 @@ package org.stellar.sdk; import com.google.common.base.Objects; -import org.stellar.sdk.xdr.*; +import org.stellar.sdk.xdr.ClaimableBalanceID; +import org.stellar.sdk.xdr.ClaimableBalanceIDType; +import org.stellar.sdk.xdr.DecoratedSignature; +import org.stellar.sdk.xdr.EnvelopeType; +import org.stellar.sdk.xdr.Hash; +import org.stellar.sdk.xdr.Int64; +import org.stellar.sdk.xdr.OperationID; +import org.stellar.sdk.xdr.PreconditionType; +import org.stellar.sdk.xdr.Preconditions; +import org.stellar.sdk.xdr.SequenceNumber; +import org.stellar.sdk.xdr.TransactionEnvelope; +import org.stellar.sdk.xdr.TransactionSignaturePayload; +import org.stellar.sdk.xdr.TransactionV0; +import org.stellar.sdk.xdr.TransactionV0Envelope; +import org.stellar.sdk.xdr.TransactionV1Envelope; +import org.stellar.sdk.xdr.Uint32; +import org.stellar.sdk.xdr.XdrDataOutputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -188,7 +204,11 @@ private org.stellar.sdk.xdr.Transaction toV1Xdr(AccountConverter accountConverte v1Tx.setSourceAccount(accountConverter.encode(mSourceAccount)); v1Tx.setOperations(operations); v1Tx.setMemo(mMemo.toXdr()); - v1Tx.setTimeBounds(mTimeBounds == null ? null : mTimeBounds.toXdr()); + Preconditions.Builder preconditions = new Preconditions.Builder().discriminant(PreconditionType.PRECOND_NONE); + if (mTimeBounds != null) { + preconditions.discriminant(PreconditionType.PRECOND_TIME).timeBounds(mTimeBounds.toXdr()); + } + v1Tx.setCond(preconditions.build()); v1Tx.setExt(ext); return v1Tx; @@ -228,9 +248,12 @@ public static Transaction fromV0EnvelopeXdr(TransactionV0Envelope envelope, Netw public static Transaction fromV1EnvelopeXdr(AccountConverter accountConverter, TransactionV1Envelope envelope, Network network) { int mFee = envelope.getTx().getFee().getUint32(); + TimeBounds mTimeBounds = null; Long mSequenceNumber = envelope.getTx().getSeqNum().getSequenceNumber().getInt64(); Memo mMemo = Memo.fromXdr(envelope.getTx().getMemo()); - TimeBounds mTimeBounds = TimeBounds.fromXdr(envelope.getTx().getTimeBounds()); + if (envelope.getTx().getCond().getDiscriminant().equals(PreconditionType.PRECOND_TIME)) { + mTimeBounds = TimeBounds.fromXdr(envelope.getTx().getCond().getTimeBounds()); + } Operation[] mOperations = new Operation[envelope.getTx().getOperations().length]; for (int i = 0; i < envelope.getTx().getOperations().length; i++) { diff --git a/src/main/java/org/stellar/sdk/xdr/AccountEntryExtensionV2.java b/src/main/java/org/stellar/sdk/xdr/AccountEntryExtensionV2.java index d92131ea2..1911d96f5 100644 --- a/src/main/java/org/stellar/sdk/xdr/AccountEntryExtensionV2.java +++ b/src/main/java/org/stellar/sdk/xdr/AccountEntryExtensionV2.java @@ -4,9 +4,9 @@ package org.stellar.sdk.xdr; -import java.io.IOException; - import com.google.common.base.Objects; + +import java.io.IOException; import java.util.Arrays; // === xdr source ============================================================ @@ -21,6 +21,8 @@ // { // case 0: // void; +// case 3: +// AccountEntryExtensionV3 v3; // } // ext; // }; @@ -140,18 +142,32 @@ public Integer getDiscriminant() { public void setDiscriminant(Integer value) { this.v = value; } + private AccountEntryExtensionV3 v3; + public AccountEntryExtensionV3 getV3() { + return this.v3; + } + public void setV3(AccountEntryExtensionV3 value) { + this.v3 = value; + } public static final class Builder { private Integer discriminant; + private AccountEntryExtensionV3 v3; public Builder discriminant(Integer discriminant) { this.discriminant = discriminant; return this; } + public Builder v3(AccountEntryExtensionV3 v3) { + this.v3 = v3; + return this; + } + public AccountEntryExtensionV2Ext build() { AccountEntryExtensionV2Ext val = new AccountEntryExtensionV2Ext(); val.setDiscriminant(discriminant); + val.setV3(v3); return val; } } @@ -163,6 +179,9 @@ public static void encode(XdrDataOutputStream stream, AccountEntryExtensionV2Ext switch (encodedAccountEntryExtensionV2Ext.getDiscriminant()) { case 0: break; + case 3: + AccountEntryExtensionV3.encode(stream, encodedAccountEntryExtensionV2Ext.v3); + break; } } public void encode(XdrDataOutputStream stream) throws IOException { @@ -175,12 +194,15 @@ public static AccountEntryExtensionV2Ext decode(XdrDataInputStream stream) throw switch (decodedAccountEntryExtensionV2Ext.getDiscriminant()) { case 0: break; + case 3: + decodedAccountEntryExtensionV2Ext.v3 = AccountEntryExtensionV3.decode(stream); + break; } return decodedAccountEntryExtensionV2Ext; } @Override public int hashCode() { - return Objects.hashCode(this.v); + return Objects.hashCode(this.v3, this.v); } @Override public boolean equals(Object object) { @@ -189,7 +211,7 @@ public boolean equals(Object object) { } AccountEntryExtensionV2Ext other = (AccountEntryExtensionV2Ext) object; - return Objects.equal(this.v, other.v); + return Objects.equal(this.v3, other.v3) && Objects.equal(this.v, other.v); } } diff --git a/src/main/java/org/stellar/sdk/xdr/AccountEntryExtensionV3.java b/src/main/java/org/stellar/sdk/xdr/AccountEntryExtensionV3.java new file mode 100644 index 000000000..a63b1dee5 --- /dev/null +++ b/src/main/java/org/stellar/sdk/xdr/AccountEntryExtensionV3.java @@ -0,0 +1,107 @@ +// Automatically generated by xdrgen +// DO NOT EDIT or your changes may be overwritten + +package org.stellar.sdk.xdr; + + +import com.google.common.base.Objects; + +import java.io.IOException; + +// === xdr source ============================================================ + +// struct AccountEntryExtensionV3 +// { +// // We can use this to add more fields, or because it is first, to +// // change AccountEntryExtensionV3 into a union. +// ExtensionPoint ext; +// +// // Ledger number at which `seqNum` took on its present value. +// uint32 seqLedger; +// +// // Time at which `seqNum` took on its present value. +// TimePoint seqTime; +// }; + +// =========================================================================== +public class AccountEntryExtensionV3 implements XdrElement { + public AccountEntryExtensionV3 () {} + private ExtensionPoint ext; + public ExtensionPoint getExt() { + return this.ext; + } + public void setExt(ExtensionPoint value) { + this.ext = value; + } + private Uint32 seqLedger; + public Uint32 getSeqLedger() { + return this.seqLedger; + } + public void setSeqLedger(Uint32 value) { + this.seqLedger = value; + } + private TimePoint seqTime; + public TimePoint getSeqTime() { + return this.seqTime; + } + public void setSeqTime(TimePoint value) { + this.seqTime = value; + } + public static void encode(XdrDataOutputStream stream, AccountEntryExtensionV3 encodedAccountEntryExtensionV3) throws IOException{ + ExtensionPoint.encode(stream, encodedAccountEntryExtensionV3.ext); + Uint32.encode(stream, encodedAccountEntryExtensionV3.seqLedger); + TimePoint.encode(stream, encodedAccountEntryExtensionV3.seqTime); + } + public void encode(XdrDataOutputStream stream) throws IOException { + encode(stream, this); + } + public static AccountEntryExtensionV3 decode(XdrDataInputStream stream) throws IOException { + AccountEntryExtensionV3 decodedAccountEntryExtensionV3 = new AccountEntryExtensionV3(); + decodedAccountEntryExtensionV3.ext = ExtensionPoint.decode(stream); + decodedAccountEntryExtensionV3.seqLedger = Uint32.decode(stream); + decodedAccountEntryExtensionV3.seqTime = TimePoint.decode(stream); + return decodedAccountEntryExtensionV3; + } + @Override + public int hashCode() { + return Objects.hashCode(this.ext, this.seqLedger, this.seqTime); + } + @Override + public boolean equals(Object object) { + if (!(object instanceof AccountEntryExtensionV3)) { + return false; + } + + AccountEntryExtensionV3 other = (AccountEntryExtensionV3) object; + return Objects.equal(this.ext, other.ext) && Objects.equal(this.seqLedger, other.seqLedger) && Objects.equal(this.seqTime, other.seqTime); + } + + public static final class Builder { + private ExtensionPoint ext; + private Uint32 seqLedger; + private TimePoint seqTime; + + public Builder ext(ExtensionPoint ext) { + this.ext = ext; + return this; + } + + public Builder seqLedger(Uint32 seqLedger) { + this.seqLedger = seqLedger; + return this; + } + + public Builder seqTime(TimePoint seqTime) { + this.seqTime = seqTime; + return this; + } + + public AccountEntryExtensionV3 build() { + AccountEntryExtensionV3 val = new AccountEntryExtensionV3(); + val.setExt(ext); + val.setSeqLedger(seqLedger); + val.setSeqTime(seqTime); + return val; + } + } +} diff --git a/src/main/java/org/stellar/sdk/xdr/AllowTrustResultCode.java b/src/main/java/org/stellar/sdk/xdr/AllowTrustResultCode.java index b51667c2d..45447edc0 100644 --- a/src/main/java/org/stellar/sdk/xdr/AllowTrustResultCode.java +++ b/src/main/java/org/stellar/sdk/xdr/AllowTrustResultCode.java @@ -21,7 +21,7 @@ // ALLOW_TRUST_CANT_REVOKE = -4, // source account can't revoke trust, // ALLOW_TRUST_SELF_NOT_ALLOWED = -5, // trusting self is not allowed // ALLOW_TRUST_LOW_RESERVE = -6 // claimable balances can't be created -// // on revoke due to low reserves +// // on revoke due to low reserves // }; // =========================================================================== diff --git a/src/main/java/org/stellar/sdk/xdr/Asset.java b/src/main/java/org/stellar/sdk/xdr/Asset.java index 3093903bf..0e9ccc672 100644 --- a/src/main/java/org/stellar/sdk/xdr/Asset.java +++ b/src/main/java/org/stellar/sdk/xdr/Asset.java @@ -4,10 +4,10 @@ package org.stellar.sdk.xdr; -import java.io.IOException; - import com.google.common.base.Objects; +import java.io.IOException; + // === xdr source ============================================================ // union Asset switch (AssetType type) @@ -79,44 +79,39 @@ public Asset build() { } public static void encode(XdrDataOutputStream stream, Asset encodedAsset) throws IOException { - //Xdrgen::AST::Identifier - //AssetType - stream.writeInt(encodedAsset.getDiscriminant().getValue()); - switch (encodedAsset.getDiscriminant()) { - case ASSET_TYPE_NATIVE: - break; - case ASSET_TYPE_CREDIT_ALPHANUM4: - AlphaNum4.encode(stream, encodedAsset.alphaNum4); - break; - case ASSET_TYPE_CREDIT_ALPHANUM12: - AlphaNum12.encode(stream, encodedAsset.alphaNum12); - break; - case ASSET_TYPE_POOL_SHARE: - throw new RuntimeException("Invalid asset type"); - } + //Xdrgen::AST::Identifier + //AssetType + stream.writeInt(encodedAsset.getDiscriminant().getValue()); + switch (encodedAsset.getDiscriminant()) { + case ASSET_TYPE_NATIVE: + break; + case ASSET_TYPE_CREDIT_ALPHANUM4: + AlphaNum4.encode(stream, encodedAsset.alphaNum4); + break; + case ASSET_TYPE_CREDIT_ALPHANUM12: + AlphaNum12.encode(stream, encodedAsset.alphaNum12); + break; + } } public void encode(XdrDataOutputStream stream) throws IOException { encode(stream, this); } public static Asset decode(XdrDataInputStream stream) throws IOException { - Asset decodedAsset = new Asset(); - AssetType discriminant = AssetType.decode(stream); - decodedAsset.setDiscriminant(discriminant); - switch (decodedAsset.getDiscriminant()) { - case ASSET_TYPE_NATIVE: - break; - case ASSET_TYPE_CREDIT_ALPHANUM4: - decodedAsset.alphaNum4 = AlphaNum4.decode(stream); - break; - case ASSET_TYPE_CREDIT_ALPHANUM12: - decodedAsset.alphaNum12 = AlphaNum12.decode(stream); - break; - case ASSET_TYPE_POOL_SHARE: - throw new RuntimeException("Invalid asset type"); - } + Asset decodedAsset = new Asset(); + AssetType discriminant = AssetType.decode(stream); + decodedAsset.setDiscriminant(discriminant); + switch (decodedAsset.getDiscriminant()) { + case ASSET_TYPE_NATIVE: + break; + case ASSET_TYPE_CREDIT_ALPHANUM4: + decodedAsset.alphaNum4 = AlphaNum4.decode(stream); + break; + case ASSET_TYPE_CREDIT_ALPHANUM12: + decodedAsset.alphaNum12 = AlphaNum12.decode(stream); + break; + } return decodedAsset; } - @Override public int hashCode() { return Objects.hashCode(this.alphaNum4, this.alphaNum12, this.type); diff --git a/src/main/java/org/stellar/sdk/xdr/ClaimPredicate.java b/src/main/java/org/stellar/sdk/xdr/ClaimPredicate.java index b87de7dd7..404b6282d 100644 --- a/src/main/java/org/stellar/sdk/xdr/ClaimPredicate.java +++ b/src/main/java/org/stellar/sdk/xdr/ClaimPredicate.java @@ -4,9 +4,9 @@ package org.stellar.sdk.xdr; -import java.io.IOException; - import com.google.common.base.Objects; + +import java.io.IOException; import java.util.Arrays; // === xdr source ============================================================ @@ -22,10 +22,10 @@ // case CLAIM_PREDICATE_NOT: // ClaimPredicate* notPredicate; // case CLAIM_PREDICATE_BEFORE_ABSOLUTE_TIME: -// int64 absBefore; // Predicate will be true if closeTime < absBefore +// TimePoint absBefore; // Predicate will be true if closeTime < absBefore // case CLAIM_PREDICATE_BEFORE_RELATIVE_TIME: -// int64 relBefore; // Seconds since closeTime of the ledger in which the -// // ClaimableBalanceEntry was created +// Duration relBefore; // Seconds since closeTime of the ledger in which the +// // ClaimableBalanceEntry was created // }; // =========================================================================== @@ -59,18 +59,18 @@ public ClaimPredicate getNotPredicate() { public void setNotPredicate(ClaimPredicate value) { this.notPredicate = value; } - private Int64 absBefore; - public Int64 getAbsBefore() { + private TimePoint absBefore; + public TimePoint getAbsBefore() { return this.absBefore; } - public void setAbsBefore(Int64 value) { + public void setAbsBefore(TimePoint value) { this.absBefore = value; } - private Int64 relBefore; - public Int64 getRelBefore() { + private Duration relBefore; + public Duration getRelBefore() { return this.relBefore; } - public void setRelBefore(Int64 value) { + public void setRelBefore(Duration value) { this.relBefore = value; } @@ -79,8 +79,8 @@ public static final class Builder { private ClaimPredicate[] andPredicates; private ClaimPredicate[] orPredicates; private ClaimPredicate notPredicate; - private Int64 absBefore; - private Int64 relBefore; + private TimePoint absBefore; + private Duration relBefore; public Builder discriminant(ClaimPredicateType discriminant) { this.discriminant = discriminant; @@ -102,12 +102,12 @@ public Builder notPredicate(ClaimPredicate notPredicate) { return this; } - public Builder absBefore(Int64 absBefore) { + public Builder absBefore(TimePoint absBefore) { this.absBefore = absBefore; return this; } - public Builder relBefore(Int64 relBefore) { + public Builder relBefore(Duration relBefore) { this.relBefore = relBefore; return this; } @@ -154,10 +154,10 @@ public static void encode(XdrDataOutputStream stream, ClaimPredicate encodedClai } break; case CLAIM_PREDICATE_BEFORE_ABSOLUTE_TIME: - Int64.encode(stream, encodedClaimPredicate.absBefore); + TimePoint.encode(stream, encodedClaimPredicate.absBefore); break; case CLAIM_PREDICATE_BEFORE_RELATIVE_TIME: - Int64.encode(stream, encodedClaimPredicate.relBefore); + Duration.encode(stream, encodedClaimPredicate.relBefore); break; } } @@ -192,10 +192,10 @@ public static ClaimPredicate decode(XdrDataInputStream stream) throws IOExceptio } break; case CLAIM_PREDICATE_BEFORE_ABSOLUTE_TIME: - decodedClaimPredicate.absBefore = Int64.decode(stream); + decodedClaimPredicate.absBefore = TimePoint.decode(stream); break; case CLAIM_PREDICATE_BEFORE_RELATIVE_TIME: - decodedClaimPredicate.relBefore = Int64.decode(stream); + decodedClaimPredicate.relBefore = Duration.decode(stream); break; } return decodedClaimPredicate; diff --git a/src/main/java/org/stellar/sdk/xdr/ClaimableBalanceID.java b/src/main/java/org/stellar/sdk/xdr/ClaimableBalanceID.java index d57036769..c75a39d1e 100644 --- a/src/main/java/org/stellar/sdk/xdr/ClaimableBalanceID.java +++ b/src/main/java/org/stellar/sdk/xdr/ClaimableBalanceID.java @@ -4,18 +4,16 @@ package org.stellar.sdk.xdr; -import java.io.IOException; - import com.google.common.base.Objects; +import java.io.IOException; + // === xdr source ============================================================ // union ClaimableBalanceID switch (ClaimableBalanceIDType type) // { // case CLAIMABLE_BALANCE_ID_TYPE_V0: // Hash v0; -// case CLAIMABLE_BALANCE_ID_TYPE_FROM_POOL_REVOKE: -// Hash fromPoolRevoke; // }; // =========================================================================== @@ -35,18 +33,10 @@ public Hash getV0() { public void setV0(Hash value) { this.v0 = value; } - private Hash fromPoolRevoke; - public Hash getFromPoolRevoke() { - return this.fromPoolRevoke; - } - public void setFromPoolRevoke(Hash value) { - this.fromPoolRevoke = value; - } public static final class Builder { private ClaimableBalanceIDType discriminant; private Hash v0; - private Hash fromPoolRevoke; public Builder discriminant(ClaimableBalanceIDType discriminant) { this.discriminant = discriminant; @@ -58,16 +48,10 @@ public Builder v0(Hash v0) { return this; } - public Builder fromPoolRevoke(Hash fromPoolRevoke) { - this.fromPoolRevoke = fromPoolRevoke; - return this; - } - public ClaimableBalanceID build() { ClaimableBalanceID val = new ClaimableBalanceID(); val.setDiscriminant(discriminant); val.setV0(v0); - val.setFromPoolRevoke(fromPoolRevoke); return val; } } @@ -80,9 +64,6 @@ public static void encode(XdrDataOutputStream stream, ClaimableBalanceID encoded case CLAIMABLE_BALANCE_ID_TYPE_V0: Hash.encode(stream, encodedClaimableBalanceID.v0); break; - case CLAIMABLE_BALANCE_ID_TYPE_FROM_POOL_REVOKE: - Hash.encode(stream, encodedClaimableBalanceID.fromPoolRevoke); - break; } } public void encode(XdrDataOutputStream stream) throws IOException { @@ -96,15 +77,12 @@ public static ClaimableBalanceID decode(XdrDataInputStream stream) throws IOExce case CLAIMABLE_BALANCE_ID_TYPE_V0: decodedClaimableBalanceID.v0 = Hash.decode(stream); break; - case CLAIMABLE_BALANCE_ID_TYPE_FROM_POOL_REVOKE: - decodedClaimableBalanceID.fromPoolRevoke = Hash.decode(stream); - break; } return decodedClaimableBalanceID; } @Override public int hashCode() { - return Objects.hashCode(this.v0, this.fromPoolRevoke, this.type); + return Objects.hashCode(this.v0, this.type); } @Override public boolean equals(Object object) { @@ -113,6 +91,6 @@ public boolean equals(Object object) { } ClaimableBalanceID other = (ClaimableBalanceID) object; - return Objects.equal(this.v0, other.v0) && Objects.equal(this.fromPoolRevoke, other.fromPoolRevoke) && Objects.equal(this.type, other.type); + return Objects.equal(this.v0, other.v0) && Objects.equal(this.type, other.type); } } diff --git a/src/main/java/org/stellar/sdk/xdr/ClaimableBalanceIDType.java b/src/main/java/org/stellar/sdk/xdr/ClaimableBalanceIDType.java index 63c44220c..308ad5c89 100644 --- a/src/main/java/org/stellar/sdk/xdr/ClaimableBalanceIDType.java +++ b/src/main/java/org/stellar/sdk/xdr/ClaimableBalanceIDType.java @@ -11,14 +11,12 @@ // enum ClaimableBalanceIDType // { -// CLAIMABLE_BALANCE_ID_TYPE_V0 = 0, -// CLAIMABLE_BALANCE_ID_TYPE_FROM_POOL_REVOKE = 1 +// CLAIMABLE_BALANCE_ID_TYPE_V0 = 0 // }; // =========================================================================== public enum ClaimableBalanceIDType implements XdrElement { CLAIMABLE_BALANCE_ID_TYPE_V0(0), - CLAIMABLE_BALANCE_ID_TYPE_FROM_POOL_REVOKE(1), ; private int mValue; @@ -34,7 +32,6 @@ public static ClaimableBalanceIDType decode(XdrDataInputStream stream) throws IO int value = stream.readInt(); switch (value) { case 0: return CLAIMABLE_BALANCE_ID_TYPE_V0; - case 1: return CLAIMABLE_BALANCE_ID_TYPE_FROM_POOL_REVOKE; default: throw new RuntimeException("Unknown enum value: " + value); } diff --git a/src/main/java/org/stellar/sdk/xdr/CryptoKeyType.java b/src/main/java/org/stellar/sdk/xdr/CryptoKeyType.java index bfaf14e5c..72d7e81a8 100644 --- a/src/main/java/org/stellar/sdk/xdr/CryptoKeyType.java +++ b/src/main/java/org/stellar/sdk/xdr/CryptoKeyType.java @@ -14,6 +14,7 @@ // KEY_TYPE_ED25519 = 0, // KEY_TYPE_PRE_AUTH_TX = 1, // KEY_TYPE_HASH_X = 2, +// KEY_TYPE_ED25519_SIGNED_PAYLOAD = 3, // // MUXED enum values for supported type are derived from the enum values // // above by ORing them with 0x100 // KEY_TYPE_MUXED_ED25519 = 0x100 @@ -24,6 +25,7 @@ public enum CryptoKeyType implements XdrElement { KEY_TYPE_ED25519(0), KEY_TYPE_PRE_AUTH_TX(1), KEY_TYPE_HASH_X(2), + KEY_TYPE_ED25519_SIGNED_PAYLOAD(3), KEY_TYPE_MUXED_ED25519(256), ; private int mValue; @@ -42,6 +44,7 @@ public static CryptoKeyType decode(XdrDataInputStream stream) throws IOException case 0: return KEY_TYPE_ED25519; case 1: return KEY_TYPE_PRE_AUTH_TX; case 2: return KEY_TYPE_HASH_X; + case 3: return KEY_TYPE_ED25519_SIGNED_PAYLOAD; case 256: return KEY_TYPE_MUXED_ED25519; default: throw new RuntimeException("Unknown enum value: " + value); diff --git a/src/main/java/org/stellar/sdk/xdr/Duration.java b/src/main/java/org/stellar/sdk/xdr/Duration.java new file mode 100644 index 000000000..56507997c --- /dev/null +++ b/src/main/java/org/stellar/sdk/xdr/Duration.java @@ -0,0 +1,60 @@ +// Automatically generated by xdrgen +// DO NOT EDIT or your changes may be overwritten + +package org.stellar.sdk.xdr; + + +import com.google.common.base.Objects; + +import java.io.IOException; + +// === xdr source ============================================================ + +// typedef int64 Duration; + +// =========================================================================== +public class Duration implements XdrElement { + private Int64 Duration; + + public Duration() {} + + public Duration(Int64 Duration) { + this.Duration = Duration; + } + + public Int64 getDuration() { + return this.Duration; + } + + public void setDuration(Int64 value) { + this.Duration = value; + } + + public static void encode(XdrDataOutputStream stream, Duration encodedDuration) throws IOException { + Int64.encode(stream, encodedDuration.Duration); + } + + public void encode(XdrDataOutputStream stream) throws IOException { + encode(stream, this); + } + public static Duration decode(XdrDataInputStream stream) throws IOException { + Duration decodedDuration = new Duration(); + decodedDuration.Duration = Int64.decode(stream); + return decodedDuration; + } + + @Override + public int hashCode() { + return Objects.hashCode(this.Duration); + } + + @Override + public boolean equals(Object object) { + if (!(object instanceof Duration)) { + return false; + } + + Duration other = (Duration) object; + return Objects.equal(this.Duration, other.Duration); + } +} diff --git a/src/main/java/org/stellar/sdk/xdr/ExtensionPoint.java b/src/main/java/org/stellar/sdk/xdr/ExtensionPoint.java new file mode 100644 index 000000000..fb785dc66 --- /dev/null +++ b/src/main/java/org/stellar/sdk/xdr/ExtensionPoint.java @@ -0,0 +1,79 @@ +// Automatically generated by xdrgen +// DO NOT EDIT or your changes may be overwritten + +package org.stellar.sdk.xdr; + + +import com.google.common.base.Objects; + +import java.io.IOException; + +// === xdr source ============================================================ + +// union ExtensionPoint switch (int v) { +// case 0: +// void; +// }; + +// =========================================================================== +public class ExtensionPoint implements XdrElement { + public ExtensionPoint () {} + Integer v; + public Integer getDiscriminant() { + return this.v; + } + public void setDiscriminant(Integer value) { + this.v = value; + } + + public static final class Builder { + private Integer discriminant; + + public Builder discriminant(Integer discriminant) { + this.discriminant = discriminant; + return this; + } + + public ExtensionPoint build() { + ExtensionPoint val = new ExtensionPoint(); + val.setDiscriminant(discriminant); + return val; + } + } + + public static void encode(XdrDataOutputStream stream, ExtensionPoint encodedExtensionPoint) throws IOException { + //Xdrgen::AST::Typespecs::Int + //Integer + stream.writeInt(encodedExtensionPoint.getDiscriminant().intValue()); + switch (encodedExtensionPoint.getDiscriminant()) { + case 0: + break; + } + } + public void encode(XdrDataOutputStream stream) throws IOException { + encode(stream, this); + } + public static ExtensionPoint decode(XdrDataInputStream stream) throws IOException { + ExtensionPoint decodedExtensionPoint = new ExtensionPoint(); + Integer discriminant = stream.readInt(); + decodedExtensionPoint.setDiscriminant(discriminant); + switch (decodedExtensionPoint.getDiscriminant()) { + case 0: + break; + } + return decodedExtensionPoint; + } + @Override + public int hashCode() { + return Objects.hashCode(this.v); + } + @Override + public boolean equals(Object object) { + if (!(object instanceof ExtensionPoint)) { + return false; + } + + ExtensionPoint other = (ExtensionPoint) object; + return Objects.equal(this.v, other.v); + } +} diff --git a/src/main/java/org/stellar/sdk/xdr/HashIDPreimage.java b/src/main/java/org/stellar/sdk/xdr/HashIDPreimage.java new file mode 100644 index 000000000..559d9a584 --- /dev/null +++ b/src/main/java/org/stellar/sdk/xdr/HashIDPreimage.java @@ -0,0 +1,327 @@ +// Automatically generated by xdrgen +// DO NOT EDIT or your changes may be overwritten + +package org.stellar.sdk.xdr; + + +import com.google.common.base.Objects; + +import java.io.IOException; + +// === xdr source ============================================================ + +// union HashIDPreimage switch (EnvelopeType type) +// { +// case ENVELOPE_TYPE_OP_ID: +// struct +// { +// AccountID sourceAccount; +// SequenceNumber seqNum; +// uint32 opNum; +// } operationID; +// case ENVELOPE_TYPE_POOL_REVOKE_OP_ID: +// struct +// { +// AccountID sourceAccount; +// SequenceNumber seqNum; +// uint32 opNum; +// PoolID liquidityPoolID; +// Asset asset; +// } revokeID; +// }; + +// =========================================================================== +public class HashIDPreimage implements XdrElement { + public HashIDPreimage () {} + EnvelopeType type; + public EnvelopeType getDiscriminant() { + return this.type; + } + public void setDiscriminant(EnvelopeType value) { + this.type = value; + } + private HashIDPreimageOperationID operationID; + public HashIDPreimageOperationID getOperationID() { + return this.operationID; + } + public void setOperationID(HashIDPreimageOperationID value) { + this.operationID = value; + } + private HashIDPreimageRevokeID revokeID; + public HashIDPreimageRevokeID getRevokeID() { + return this.revokeID; + } + public void setRevokeID(HashIDPreimageRevokeID value) { + this.revokeID = value; + } + + public static final class Builder { + private EnvelopeType discriminant; + private HashIDPreimageOperationID operationID; + private HashIDPreimageRevokeID revokeID; + + public Builder discriminant(EnvelopeType discriminant) { + this.discriminant = discriminant; + return this; + } + + public Builder operationID(HashIDPreimageOperationID operationID) { + this.operationID = operationID; + return this; + } + + public Builder revokeID(HashIDPreimageRevokeID revokeID) { + this.revokeID = revokeID; + return this; + } + + public HashIDPreimage build() { + HashIDPreimage val = new HashIDPreimage(); + val.setDiscriminant(discriminant); + val.setOperationID(operationID); + val.setRevokeID(revokeID); + return val; + } + } + + public static void encode(XdrDataOutputStream stream, HashIDPreimage encodedHashIDPreimage) throws IOException { + //Xdrgen::AST::Identifier + //EnvelopeType + stream.writeInt(encodedHashIDPreimage.getDiscriminant().getValue()); + switch (encodedHashIDPreimage.getDiscriminant()) { + case ENVELOPE_TYPE_OP_ID: + HashIDPreimageOperationID.encode(stream, encodedHashIDPreimage.operationID); + break; + case ENVELOPE_TYPE_POOL_REVOKE_OP_ID: + HashIDPreimageRevokeID.encode(stream, encodedHashIDPreimage.revokeID); + break; + } + } + public void encode(XdrDataOutputStream stream) throws IOException { + encode(stream, this); + } + public static HashIDPreimage decode(XdrDataInputStream stream) throws IOException { + HashIDPreimage decodedHashIDPreimage = new HashIDPreimage(); + EnvelopeType discriminant = EnvelopeType.decode(stream); + decodedHashIDPreimage.setDiscriminant(discriminant); + switch (decodedHashIDPreimage.getDiscriminant()) { + case ENVELOPE_TYPE_OP_ID: + decodedHashIDPreimage.operationID = HashIDPreimageOperationID.decode(stream); + break; + case ENVELOPE_TYPE_POOL_REVOKE_OP_ID: + decodedHashIDPreimage.revokeID = HashIDPreimageRevokeID.decode(stream); + break; + } + return decodedHashIDPreimage; + } + @Override + public int hashCode() { + return Objects.hashCode(this.operationID, this.revokeID, this.type); + } + @Override + public boolean equals(Object object) { + if (!(object instanceof HashIDPreimage)) { + return false; + } + + HashIDPreimage other = (HashIDPreimage) object; + return Objects.equal(this.operationID, other.operationID) && Objects.equal(this.revokeID, other.revokeID) && Objects.equal(this.type, other.type); + } + + public static class HashIDPreimageOperationID { + public HashIDPreimageOperationID () {} + private AccountID sourceAccount; + public AccountID getSourceAccount() { + return this.sourceAccount; + } + public void setSourceAccount(AccountID value) { + this.sourceAccount = value; + } + private SequenceNumber seqNum; + public SequenceNumber getSeqNum() { + return this.seqNum; + } + public void setSeqNum(SequenceNumber value) { + this.seqNum = value; + } + private Uint32 opNum; + public Uint32 getOpNum() { + return this.opNum; + } + public void setOpNum(Uint32 value) { + this.opNum = value; + } + public static void encode(XdrDataOutputStream stream, HashIDPreimageOperationID encodedHashIDPreimageOperationID) throws IOException{ + AccountID.encode(stream, encodedHashIDPreimageOperationID.sourceAccount); + SequenceNumber.encode(stream, encodedHashIDPreimageOperationID.seqNum); + Uint32.encode(stream, encodedHashIDPreimageOperationID.opNum); + } + public void encode(XdrDataOutputStream stream) throws IOException { + encode(stream, this); + } + public static HashIDPreimageOperationID decode(XdrDataInputStream stream) throws IOException { + HashIDPreimageOperationID decodedHashIDPreimageOperationID = new HashIDPreimageOperationID(); + decodedHashIDPreimageOperationID.sourceAccount = AccountID.decode(stream); + decodedHashIDPreimageOperationID.seqNum = SequenceNumber.decode(stream); + decodedHashIDPreimageOperationID.opNum = Uint32.decode(stream); + return decodedHashIDPreimageOperationID; + } + @Override + public int hashCode() { + return Objects.hashCode(this.sourceAccount, this.seqNum, this.opNum); + } + @Override + public boolean equals(Object object) { + if (!(object instanceof HashIDPreimageOperationID)) { + return false; + } + + HashIDPreimageOperationID other = (HashIDPreimageOperationID) object; + return Objects.equal(this.sourceAccount, other.sourceAccount) && Objects.equal(this.seqNum, other.seqNum) && Objects.equal(this.opNum, other.opNum); + } + + public static final class Builder { + private AccountID sourceAccount; + private SequenceNumber seqNum; + private Uint32 opNum; + + public Builder sourceAccount(AccountID sourceAccount) { + this.sourceAccount = sourceAccount; + return this; + } + + public Builder seqNum(SequenceNumber seqNum) { + this.seqNum = seqNum; + return this; + } + + public Builder opNum(Uint32 opNum) { + this.opNum = opNum; + return this; + } + + public HashIDPreimageOperationID build() { + HashIDPreimageOperationID val = new HashIDPreimageOperationID(); + val.setSourceAccount(sourceAccount); + val.setSeqNum(seqNum); + val.setOpNum(opNum); + return val; + } + } + + } + public static class HashIDPreimageRevokeID { + public HashIDPreimageRevokeID () {} + private AccountID sourceAccount; + public AccountID getSourceAccount() { + return this.sourceAccount; + } + public void setSourceAccount(AccountID value) { + this.sourceAccount = value; + } + private SequenceNumber seqNum; + public SequenceNumber getSeqNum() { + return this.seqNum; + } + public void setSeqNum(SequenceNumber value) { + this.seqNum = value; + } + private Uint32 opNum; + public Uint32 getOpNum() { + return this.opNum; + } + public void setOpNum(Uint32 value) { + this.opNum = value; + } + private PoolID liquidityPoolID; + public PoolID getLiquidityPoolID() { + return this.liquidityPoolID; + } + public void setLiquidityPoolID(PoolID value) { + this.liquidityPoolID = value; + } + private Asset asset; + public Asset getAsset() { + return this.asset; + } + public void setAsset(Asset value) { + this.asset = value; + } + public static void encode(XdrDataOutputStream stream, HashIDPreimageRevokeID encodedHashIDPreimageRevokeID) throws IOException{ + AccountID.encode(stream, encodedHashIDPreimageRevokeID.sourceAccount); + SequenceNumber.encode(stream, encodedHashIDPreimageRevokeID.seqNum); + Uint32.encode(stream, encodedHashIDPreimageRevokeID.opNum); + PoolID.encode(stream, encodedHashIDPreimageRevokeID.liquidityPoolID); + Asset.encode(stream, encodedHashIDPreimageRevokeID.asset); + } + public void encode(XdrDataOutputStream stream) throws IOException { + encode(stream, this); + } + public static HashIDPreimageRevokeID decode(XdrDataInputStream stream) throws IOException { + HashIDPreimageRevokeID decodedHashIDPreimageRevokeID = new HashIDPreimageRevokeID(); + decodedHashIDPreimageRevokeID.sourceAccount = AccountID.decode(stream); + decodedHashIDPreimageRevokeID.seqNum = SequenceNumber.decode(stream); + decodedHashIDPreimageRevokeID.opNum = Uint32.decode(stream); + decodedHashIDPreimageRevokeID.liquidityPoolID = PoolID.decode(stream); + decodedHashIDPreimageRevokeID.asset = Asset.decode(stream); + return decodedHashIDPreimageRevokeID; + } + @Override + public int hashCode() { + return Objects.hashCode(this.sourceAccount, this.seqNum, this.opNum, this.liquidityPoolID, this.asset); + } + @Override + public boolean equals(Object object) { + if (!(object instanceof HashIDPreimageRevokeID)) { + return false; + } + + HashIDPreimageRevokeID other = (HashIDPreimageRevokeID) object; + return Objects.equal(this.sourceAccount, other.sourceAccount) && Objects.equal(this.seqNum, other.seqNum) && Objects.equal(this.opNum, other.opNum) && Objects.equal(this.liquidityPoolID, other.liquidityPoolID) && Objects.equal(this.asset, other.asset); + } + + public static final class Builder { + private AccountID sourceAccount; + private SequenceNumber seqNum; + private Uint32 opNum; + private PoolID liquidityPoolID; + private Asset asset; + + public Builder sourceAccount(AccountID sourceAccount) { + this.sourceAccount = sourceAccount; + return this; + } + + public Builder seqNum(SequenceNumber seqNum) { + this.seqNum = seqNum; + return this; + } + + public Builder opNum(Uint32 opNum) { + this.opNum = opNum; + return this; + } + + public Builder liquidityPoolID(PoolID liquidityPoolID) { + this.liquidityPoolID = liquidityPoolID; + return this; + } + + public Builder asset(Asset asset) { + this.asset = asset; + return this; + } + + public HashIDPreimageRevokeID build() { + HashIDPreimageRevokeID val = new HashIDPreimageRevokeID(); + val.setSourceAccount(sourceAccount); + val.setSeqNum(seqNum); + val.setOpNum(opNum); + val.setLiquidityPoolID(liquidityPoolID); + val.setAsset(asset); + return val; + } + } + + } +} diff --git a/src/main/java/org/stellar/sdk/xdr/LedgerBounds.java b/src/main/java/org/stellar/sdk/xdr/LedgerBounds.java new file mode 100644 index 000000000..c55bb91ad --- /dev/null +++ b/src/main/java/org/stellar/sdk/xdr/LedgerBounds.java @@ -0,0 +1,84 @@ +// Automatically generated by xdrgen +// DO NOT EDIT or your changes may be overwritten + +package org.stellar.sdk.xdr; + + +import com.google.common.base.Objects; + +import java.io.IOException; + +// === xdr source ============================================================ + +// struct LedgerBounds +// { +// uint32 minLedger; +// uint32 maxLedger; +// }; + +// =========================================================================== +public class LedgerBounds implements XdrElement { + public LedgerBounds () {} + private Uint32 minLedger; + public Uint32 getMinLedger() { + return this.minLedger; + } + public void setMinLedger(Uint32 value) { + this.minLedger = value; + } + private Uint32 maxLedger; + public Uint32 getMaxLedger() { + return this.maxLedger; + } + public void setMaxLedger(Uint32 value) { + this.maxLedger = value; + } + public static void encode(XdrDataOutputStream stream, LedgerBounds encodedLedgerBounds) throws IOException{ + Uint32.encode(stream, encodedLedgerBounds.minLedger); + Uint32.encode(stream, encodedLedgerBounds.maxLedger); + } + public void encode(XdrDataOutputStream stream) throws IOException { + encode(stream, this); + } + public static LedgerBounds decode(XdrDataInputStream stream) throws IOException { + LedgerBounds decodedLedgerBounds = new LedgerBounds(); + decodedLedgerBounds.minLedger = Uint32.decode(stream); + decodedLedgerBounds.maxLedger = Uint32.decode(stream); + return decodedLedgerBounds; + } + @Override + public int hashCode() { + return Objects.hashCode(this.minLedger, this.maxLedger); + } + @Override + public boolean equals(Object object) { + if (!(object instanceof LedgerBounds)) { + return false; + } + + LedgerBounds other = (LedgerBounds) object; + return Objects.equal(this.minLedger, other.minLedger) && Objects.equal(this.maxLedger, other.maxLedger); + } + + public static final class Builder { + private Uint32 minLedger; + private Uint32 maxLedger; + + public Builder minLedger(Uint32 minLedger) { + this.minLedger = minLedger; + return this; + } + + public Builder maxLedger(Uint32 maxLedger) { + this.maxLedger = maxLedger; + return this; + } + + public LedgerBounds build() { + LedgerBounds val = new LedgerBounds(); + val.setMinLedger(minLedger); + val.setMaxLedger(maxLedger); + return val; + } + } +} diff --git a/src/main/java/org/stellar/sdk/xdr/LedgerHeaderExtensionV1.java b/src/main/java/org/stellar/sdk/xdr/LedgerHeaderExtensionV1.java index a78303c1d..6be2aaa41 100644 --- a/src/main/java/org/stellar/sdk/xdr/LedgerHeaderExtensionV1.java +++ b/src/main/java/org/stellar/sdk/xdr/LedgerHeaderExtensionV1.java @@ -4,15 +4,15 @@ package org.stellar.sdk.xdr; -import java.io.IOException; - import com.google.common.base.Objects; +import java.io.IOException; + // === xdr source ============================================================ // struct LedgerHeaderExtensionV1 // { -// uint32 flags; // UpgradeFlags +// uint32 flags; // LedgerHeaderFlags // // union switch (int v) // { diff --git a/src/main/java/org/stellar/sdk/xdr/LedgerHeaderFlags.java b/src/main/java/org/stellar/sdk/xdr/LedgerHeaderFlags.java index 4c898b73d..99d3c02f7 100644 --- a/src/main/java/org/stellar/sdk/xdr/LedgerHeaderFlags.java +++ b/src/main/java/org/stellar/sdk/xdr/LedgerHeaderFlags.java @@ -10,8 +10,7 @@ // === xdr source ============================================================ // enum LedgerHeaderFlags -// { // masks for each flag -// +// { // DISABLE_LIQUIDITY_POOL_TRADING_FLAG = 0x1, // DISABLE_LIQUIDITY_POOL_DEPOSIT_FLAG = 0x2, // DISABLE_LIQUIDITY_POOL_WITHDRAWAL_FLAG = 0x4 diff --git a/src/main/java/org/stellar/sdk/xdr/OfferEntryFlags.java b/src/main/java/org/stellar/sdk/xdr/OfferEntryFlags.java index 3aa9758f6..32bd84157 100644 --- a/src/main/java/org/stellar/sdk/xdr/OfferEntryFlags.java +++ b/src/main/java/org/stellar/sdk/xdr/OfferEntryFlags.java @@ -11,7 +11,7 @@ // enum OfferEntryFlags // { -// // issuer has authorized account to perform transactions with its credit +// // an offer with this flag will not act on and take a reverse offer of equal price // PASSIVE_FLAG = 1 // }; diff --git a/src/main/java/org/stellar/sdk/xdr/PreconditionType.java b/src/main/java/org/stellar/sdk/xdr/PreconditionType.java new file mode 100644 index 000000000..6636f2560 --- /dev/null +++ b/src/main/java/org/stellar/sdk/xdr/PreconditionType.java @@ -0,0 +1,52 @@ +// Automatically generated by xdrgen +// DO NOT EDIT or your changes may be overwritten + +package org.stellar.sdk.xdr; + + +import java.io.IOException; + + +// === xdr source ============================================================ + +// enum PreconditionType { +// PRECOND_NONE = 0, +// PRECOND_TIME = 1, +// PRECOND_V2 = 2 +// }; + +// =========================================================================== +public enum PreconditionType implements XdrElement { + PRECOND_NONE(0), + PRECOND_TIME(1), + PRECOND_V2(2), + ; + private int mValue; + + PreconditionType(int value) { + mValue = value; + } + + public int getValue() { + return mValue; + } + + public static PreconditionType decode(XdrDataInputStream stream) throws IOException { + int value = stream.readInt(); + switch (value) { + case 0: return PRECOND_NONE; + case 1: return PRECOND_TIME; + case 2: return PRECOND_V2; + default: + throw new RuntimeException("Unknown enum value: " + value); + } + } + + public static void encode(XdrDataOutputStream stream, PreconditionType value) throws IOException { + stream.writeInt(value.getValue()); + } + + public void encode(XdrDataOutputStream stream) throws IOException { + encode(stream, this); + } +} diff --git a/src/main/java/org/stellar/sdk/xdr/Preconditions.java b/src/main/java/org/stellar/sdk/xdr/Preconditions.java new file mode 100644 index 000000000..7eb39c140 --- /dev/null +++ b/src/main/java/org/stellar/sdk/xdr/Preconditions.java @@ -0,0 +1,123 @@ +// Automatically generated by xdrgen +// DO NOT EDIT or your changes may be overwritten + +package org.stellar.sdk.xdr; + + +import com.google.common.base.Objects; + +import java.io.IOException; + +// === xdr source ============================================================ + +// union Preconditions switch (PreconditionType type) { +// case PRECOND_NONE: +// void; +// case PRECOND_TIME: +// TimeBounds timeBounds; +// case PRECOND_V2: +// PreconditionsV2 v2; +// }; + +// =========================================================================== +public class Preconditions implements XdrElement { + public Preconditions () {} + PreconditionType type; + public PreconditionType getDiscriminant() { + return this.type; + } + public void setDiscriminant(PreconditionType value) { + this.type = value; + } + private TimeBounds timeBounds; + public TimeBounds getTimeBounds() { + return this.timeBounds; + } + public void setTimeBounds(TimeBounds value) { + this.timeBounds = value; + } + private PreconditionsV2 v2; + public PreconditionsV2 getV2() { + return this.v2; + } + public void setV2(PreconditionsV2 value) { + this.v2 = value; + } + + public static final class Builder { + private PreconditionType discriminant; + private TimeBounds timeBounds; + private PreconditionsV2 v2; + + public Builder discriminant(PreconditionType discriminant) { + this.discriminant = discriminant; + return this; + } + + public Builder timeBounds(TimeBounds timeBounds) { + this.timeBounds = timeBounds; + return this; + } + + public Builder v2(PreconditionsV2 v2) { + this.v2 = v2; + return this; + } + + public Preconditions build() { + Preconditions val = new Preconditions(); + val.setDiscriminant(discriminant); + val.setTimeBounds(timeBounds); + val.setV2(v2); + return val; + } + } + + public static void encode(XdrDataOutputStream stream, Preconditions encodedPreconditions) throws IOException { + //Xdrgen::AST::Identifier + //PreconditionType + stream.writeInt(encodedPreconditions.getDiscriminant().getValue()); + switch (encodedPreconditions.getDiscriminant()) { + case PRECOND_NONE: + break; + case PRECOND_TIME: + TimeBounds.encode(stream, encodedPreconditions.timeBounds); + break; + case PRECOND_V2: + PreconditionsV2.encode(stream, encodedPreconditions.v2); + break; + } + } + public void encode(XdrDataOutputStream stream) throws IOException { + encode(stream, this); + } + public static Preconditions decode(XdrDataInputStream stream) throws IOException { + Preconditions decodedPreconditions = new Preconditions(); + PreconditionType discriminant = PreconditionType.decode(stream); + decodedPreconditions.setDiscriminant(discriminant); + switch (decodedPreconditions.getDiscriminant()) { + case PRECOND_NONE: + break; + case PRECOND_TIME: + decodedPreconditions.timeBounds = TimeBounds.decode(stream); + break; + case PRECOND_V2: + decodedPreconditions.v2 = PreconditionsV2.decode(stream); + break; + } + return decodedPreconditions; + } + @Override + public int hashCode() { + return Objects.hashCode(this.timeBounds, this.v2, this.type); + } + @Override + public boolean equals(Object object) { + if (!(object instanceof Preconditions)) { + return false; + } + + Preconditions other = (Preconditions) object; + return Objects.equal(this.timeBounds, other.timeBounds) && Objects.equal(this.v2, other.v2) && Objects.equal(this.type, other.type); + } +} diff --git a/src/main/java/org/stellar/sdk/xdr/PreconditionsV2.java b/src/main/java/org/stellar/sdk/xdr/PreconditionsV2.java new file mode 100644 index 000000000..dc098c1d4 --- /dev/null +++ b/src/main/java/org/stellar/sdk/xdr/PreconditionsV2.java @@ -0,0 +1,206 @@ +// Automatically generated by xdrgen +// DO NOT EDIT or your changes may be overwritten + +package org.stellar.sdk.xdr; + + +import com.google.common.base.Objects; + +import java.io.IOException; +import java.util.Arrays; + +// === xdr source ============================================================ + +// struct PreconditionsV2 { +// TimeBounds *timeBounds; +// +// // Transaciton only valid for ledger numbers n such that +// // minLedger <= n < maxLedger +// LedgerBounds *ledgerBounds; +// +// // If NULL, only valid when sourceAccount's sequence number +// // is seqNum - 1. Otherwise, valid when sourceAccount's +// // sequence number n satisfies minSeqNum <= n < tx.seqNum. +// // Note that after execution the account's sequence number +// // is always raised to tx.seqNum, and a transaction is not +// // valid if tx.seqNum is too high to ensure replay protection. +// SequenceNumber *minSeqNum; +// +// // For the transaction to be valid, the current ledger time must +// // be at least minSeqAge greater than sourceAccount's seqTime. +// Duration minSeqAge; +// +// // For the transaction to be valid, the current ledger number +// // must be at least minSeqLedgerGap greater than sourceAccount's +// // seqLedger. +// uint32 minSeqLedgerGap; +// +// // For the transaction to be valid, there must be a signature +// // corresponding to every Signer in this array, even if the +// // signature is not otherwise required by the sourceAccount or +// // operations. +// SignerKey extraSigners<2>; +// }; + +// =========================================================================== +public class PreconditionsV2 implements XdrElement { + public PreconditionsV2 () {} + private TimeBounds timeBounds; + public TimeBounds getTimeBounds() { + return this.timeBounds; + } + public void setTimeBounds(TimeBounds value) { + this.timeBounds = value; + } + private LedgerBounds ledgerBounds; + public LedgerBounds getLedgerBounds() { + return this.ledgerBounds; + } + public void setLedgerBounds(LedgerBounds value) { + this.ledgerBounds = value; + } + private SequenceNumber minSeqNum; + public SequenceNumber getMinSeqNum() { + return this.minSeqNum; + } + public void setMinSeqNum(SequenceNumber value) { + this.minSeqNum = value; + } + private Duration minSeqAge; + public Duration getMinSeqAge() { + return this.minSeqAge; + } + public void setMinSeqAge(Duration value) { + this.minSeqAge = value; + } + private Uint32 minSeqLedgerGap; + public Uint32 getMinSeqLedgerGap() { + return this.minSeqLedgerGap; + } + public void setMinSeqLedgerGap(Uint32 value) { + this.minSeqLedgerGap = value; + } + private SignerKey[] extraSigners; + public SignerKey[] getExtraSigners() { + return this.extraSigners; + } + public void setExtraSigners(SignerKey[] value) { + this.extraSigners = value; + } + public static void encode(XdrDataOutputStream stream, PreconditionsV2 encodedPreconditionsV2) throws IOException{ + if (encodedPreconditionsV2.timeBounds != null) { + stream.writeInt(1); + TimeBounds.encode(stream, encodedPreconditionsV2.timeBounds); + } else { + stream.writeInt(0); + } + if (encodedPreconditionsV2.ledgerBounds != null) { + stream.writeInt(1); + LedgerBounds.encode(stream, encodedPreconditionsV2.ledgerBounds); + } else { + stream.writeInt(0); + } + if (encodedPreconditionsV2.minSeqNum != null) { + stream.writeInt(1); + SequenceNumber.encode(stream, encodedPreconditionsV2.minSeqNum); + } else { + stream.writeInt(0); + } + Duration.encode(stream, encodedPreconditionsV2.minSeqAge); + Uint32.encode(stream, encodedPreconditionsV2.minSeqLedgerGap); + int extraSignerssize = encodedPreconditionsV2.getExtraSigners().length; + stream.writeInt(extraSignerssize); + for (int i = 0; i < extraSignerssize; i++) { + SignerKey.encode(stream, encodedPreconditionsV2.extraSigners[i]); + } + } + public void encode(XdrDataOutputStream stream) throws IOException { + encode(stream, this); + } + public static PreconditionsV2 decode(XdrDataInputStream stream) throws IOException { + PreconditionsV2 decodedPreconditionsV2 = new PreconditionsV2(); + int timeBoundsPresent = stream.readInt(); + if (timeBoundsPresent != 0) { + decodedPreconditionsV2.timeBounds = TimeBounds.decode(stream); + } + int ledgerBoundsPresent = stream.readInt(); + if (ledgerBoundsPresent != 0) { + decodedPreconditionsV2.ledgerBounds = LedgerBounds.decode(stream); + } + int minSeqNumPresent = stream.readInt(); + if (minSeqNumPresent != 0) { + decodedPreconditionsV2.minSeqNum = SequenceNumber.decode(stream); + } + decodedPreconditionsV2.minSeqAge = Duration.decode(stream); + decodedPreconditionsV2.minSeqLedgerGap = Uint32.decode(stream); + int extraSignerssize = stream.readInt(); + decodedPreconditionsV2.extraSigners = new SignerKey[extraSignerssize]; + for (int i = 0; i < extraSignerssize; i++) { + decodedPreconditionsV2.extraSigners[i] = SignerKey.decode(stream); + } + return decodedPreconditionsV2; + } + @Override + public int hashCode() { + return Objects.hashCode(this.timeBounds, this.ledgerBounds, this.minSeqNum, this.minSeqAge, this.minSeqLedgerGap, Arrays.hashCode(this.extraSigners)); + } + @Override + public boolean equals(Object object) { + if (!(object instanceof PreconditionsV2)) { + return false; + } + + PreconditionsV2 other = (PreconditionsV2) object; + return Objects.equal(this.timeBounds, other.timeBounds) && Objects.equal(this.ledgerBounds, other.ledgerBounds) && Objects.equal(this.minSeqNum, other.minSeqNum) && Objects.equal(this.minSeqAge, other.minSeqAge) && Objects.equal(this.minSeqLedgerGap, other.minSeqLedgerGap) && Arrays.equals(this.extraSigners, other.extraSigners); + } + + public static final class Builder { + private TimeBounds timeBounds; + private LedgerBounds ledgerBounds; + private SequenceNumber minSeqNum; + private Duration minSeqAge; + private Uint32 minSeqLedgerGap; + private SignerKey[] extraSigners; + + public Builder timeBounds(TimeBounds timeBounds) { + this.timeBounds = timeBounds; + return this; + } + + public Builder ledgerBounds(LedgerBounds ledgerBounds) { + this.ledgerBounds = ledgerBounds; + return this; + } + + public Builder minSeqNum(SequenceNumber minSeqNum) { + this.minSeqNum = minSeqNum; + return this; + } + + public Builder minSeqAge(Duration minSeqAge) { + this.minSeqAge = minSeqAge; + return this; + } + + public Builder minSeqLedgerGap(Uint32 minSeqLedgerGap) { + this.minSeqLedgerGap = minSeqLedgerGap; + return this; + } + + public Builder extraSigners(SignerKey[] extraSigners) { + this.extraSigners = extraSigners; + return this; + } + + public PreconditionsV2 build() { + PreconditionsV2 val = new PreconditionsV2(); + val.setTimeBounds(timeBounds); + val.setLedgerBounds(ledgerBounds); + val.setMinSeqNum(minSeqNum); + val.setMinSeqAge(minSeqAge); + val.setMinSeqLedgerGap(minSeqLedgerGap); + val.setExtraSigners(extraSigners); + return val; + } + } +} diff --git a/src/main/java/org/stellar/sdk/xdr/SignerKey.java b/src/main/java/org/stellar/sdk/xdr/SignerKey.java index 98a9d64bd..303c661ae 100644 --- a/src/main/java/org/stellar/sdk/xdr/SignerKey.java +++ b/src/main/java/org/stellar/sdk/xdr/SignerKey.java @@ -4,10 +4,11 @@ package org.stellar.sdk.xdr; -import java.io.IOException; - import com.google.common.base.Objects; +import java.io.IOException; +import java.util.Arrays; + // === xdr source ============================================================ // union SignerKey switch (SignerKeyType type) @@ -20,6 +21,13 @@ // case SIGNER_KEY_TYPE_HASH_X: // /* Hash of random 256 bit preimage X */ // uint256 hashX; +// case SIGNER_KEY_TYPE_ED25519_SIGNED_PAYLOAD: +// struct { +// /* Public key that must sign the payload. */ +// uint256 ed25519; +// /* Payload to be raw signed by ed25519. */ +// opaque payload<64>; +// } ed25519SignedPayload; // }; // =========================================================================== @@ -53,12 +61,20 @@ public Uint256 getHashX() { public void setHashX(Uint256 value) { this.hashX = value; } + private SignerKeyEd25519SignedPayload ed25519SignedPayload; + public SignerKeyEd25519SignedPayload getEd25519SignedPayload() { + return this.ed25519SignedPayload; + } + public void setEd25519SignedPayload(SignerKeyEd25519SignedPayload value) { + this.ed25519SignedPayload = value; + } public static final class Builder { private SignerKeyType discriminant; private Uint256 ed25519; private Uint256 preAuthTx; private Uint256 hashX; + private SignerKeyEd25519SignedPayload ed25519SignedPayload; public Builder discriminant(SignerKeyType discriminant) { this.discriminant = discriminant; @@ -80,12 +96,18 @@ public Builder hashX(Uint256 hashX) { return this; } + public Builder ed25519SignedPayload(SignerKeyEd25519SignedPayload ed25519SignedPayload) { + this.ed25519SignedPayload = ed25519SignedPayload; + return this; + } + public SignerKey build() { SignerKey val = new SignerKey(); val.setDiscriminant(discriminant); val.setEd25519(ed25519); val.setPreAuthTx(preAuthTx); val.setHashX(hashX); + val.setEd25519SignedPayload(ed25519SignedPayload); return val; } } @@ -104,6 +126,9 @@ public static void encode(XdrDataOutputStream stream, SignerKey encodedSignerKey case SIGNER_KEY_TYPE_HASH_X: Uint256.encode(stream, encodedSignerKey.hashX); break; + case SIGNER_KEY_TYPE_ED25519_SIGNED_PAYLOAD: + SignerKeyEd25519SignedPayload.encode(stream, encodedSignerKey.ed25519SignedPayload); + break; } } public void encode(XdrDataOutputStream stream) throws IOException { @@ -123,12 +148,15 @@ public static SignerKey decode(XdrDataInputStream stream) throws IOException { case SIGNER_KEY_TYPE_HASH_X: decodedSignerKey.hashX = Uint256.decode(stream); break; + case SIGNER_KEY_TYPE_ED25519_SIGNED_PAYLOAD: + decodedSignerKey.ed25519SignedPayload = SignerKeyEd25519SignedPayload.decode(stream); + break; } return decodedSignerKey; } @Override public int hashCode() { - return Objects.hashCode(this.ed25519, this.preAuthTx, this.hashX, this.type); + return Objects.hashCode(this.ed25519, this.preAuthTx, this.hashX, this.ed25519SignedPayload, this.type); } @Override public boolean equals(Object object) { @@ -137,6 +165,77 @@ public boolean equals(Object object) { } SignerKey other = (SignerKey) object; - return Objects.equal(this.ed25519, other.ed25519) && Objects.equal(this.preAuthTx, other.preAuthTx) && Objects.equal(this.hashX, other.hashX) && Objects.equal(this.type, other.type); + return Objects.equal(this.ed25519, other.ed25519) && Objects.equal(this.preAuthTx, other.preAuthTx) && Objects.equal(this.hashX, other.hashX) && Objects.equal(this.ed25519SignedPayload, other.ed25519SignedPayload) && Objects.equal(this.type, other.type); + } + + public static class SignerKeyEd25519SignedPayload { + public SignerKeyEd25519SignedPayload () {} + private Uint256 ed25519; + public Uint256 getEd25519() { + return this.ed25519; + } + public void setEd25519(Uint256 value) { + this.ed25519 = value; + } + private byte[] payload; + public byte[] getPayload() { + return this.payload; + } + public void setPayload(byte[] value) { + this.payload = value; + } + public static void encode(XdrDataOutputStream stream, SignerKeyEd25519SignedPayload encodedSignerKeyEd25519SignedPayload) throws IOException{ + Uint256.encode(stream, encodedSignerKeyEd25519SignedPayload.ed25519); + int payloadsize = encodedSignerKeyEd25519SignedPayload.payload.length; + stream.writeInt(payloadsize); + stream.write(encodedSignerKeyEd25519SignedPayload.getPayload(), 0, payloadsize); + } + public void encode(XdrDataOutputStream stream) throws IOException { + encode(stream, this); + } + public static SignerKeyEd25519SignedPayload decode(XdrDataInputStream stream) throws IOException { + SignerKeyEd25519SignedPayload decodedSignerKeyEd25519SignedPayload = new SignerKeyEd25519SignedPayload(); + decodedSignerKeyEd25519SignedPayload.ed25519 = Uint256.decode(stream); + int payloadsize = stream.readInt(); + decodedSignerKeyEd25519SignedPayload.payload = new byte[payloadsize]; + stream.read(decodedSignerKeyEd25519SignedPayload.payload, 0, payloadsize); + return decodedSignerKeyEd25519SignedPayload; + } + @Override + public int hashCode() { + return Objects.hashCode(this.ed25519, Arrays.hashCode(this.payload)); + } + @Override + public boolean equals(Object object) { + if (!(object instanceof SignerKeyEd25519SignedPayload)) { + return false; + } + + SignerKeyEd25519SignedPayload other = (SignerKeyEd25519SignedPayload) object; + return Objects.equal(this.ed25519, other.ed25519) && Arrays.equals(this.payload, other.payload); + } + + public static final class Builder { + private Uint256 ed25519; + private byte[] payload; + + public Builder ed25519(Uint256 ed25519) { + this.ed25519 = ed25519; + return this; + } + + public Builder payload(byte[] payload) { + this.payload = payload; + return this; + } + + public SignerKeyEd25519SignedPayload build() { + SignerKeyEd25519SignedPayload val = new SignerKeyEd25519SignedPayload(); + val.setEd25519(ed25519); + val.setPayload(payload); + return val; + } + } + } } diff --git a/src/main/java/org/stellar/sdk/xdr/SignerKeyType.java b/src/main/java/org/stellar/sdk/xdr/SignerKeyType.java index d5e610028..4000eaf2e 100644 --- a/src/main/java/org/stellar/sdk/xdr/SignerKeyType.java +++ b/src/main/java/org/stellar/sdk/xdr/SignerKeyType.java @@ -13,7 +13,8 @@ // { // SIGNER_KEY_TYPE_ED25519 = KEY_TYPE_ED25519, // SIGNER_KEY_TYPE_PRE_AUTH_TX = KEY_TYPE_PRE_AUTH_TX, -// SIGNER_KEY_TYPE_HASH_X = KEY_TYPE_HASH_X +// SIGNER_KEY_TYPE_HASH_X = KEY_TYPE_HASH_X, +// SIGNER_KEY_TYPE_ED25519_SIGNED_PAYLOAD = KEY_TYPE_ED25519_SIGNED_PAYLOAD // }; // =========================================================================== @@ -21,6 +22,7 @@ public enum SignerKeyType implements XdrElement { SIGNER_KEY_TYPE_ED25519(0), SIGNER_KEY_TYPE_PRE_AUTH_TX(1), SIGNER_KEY_TYPE_HASH_X(2), + SIGNER_KEY_TYPE_ED25519_SIGNED_PAYLOAD(3), ; private int mValue; @@ -38,6 +40,7 @@ public static SignerKeyType decode(XdrDataInputStream stream) throws IOException case 0: return SIGNER_KEY_TYPE_ED25519; case 1: return SIGNER_KEY_TYPE_PRE_AUTH_TX; case 2: return SIGNER_KEY_TYPE_HASH_X; + case 3: return SIGNER_KEY_TYPE_ED25519_SIGNED_PAYLOAD; default: throw new RuntimeException("Unknown enum value: " + value); } diff --git a/src/main/java/org/stellar/sdk/xdr/StellarValue.java b/src/main/java/org/stellar/sdk/xdr/StellarValue.java index 6954c7e9c..c841d5903 100644 --- a/src/main/java/org/stellar/sdk/xdr/StellarValue.java +++ b/src/main/java/org/stellar/sdk/xdr/StellarValue.java @@ -4,9 +4,9 @@ package org.stellar.sdk.xdr; -import java.io.IOException; - import com.google.common.base.Objects; + +import java.io.IOException; import java.util.Arrays; // === xdr source ============================================================ @@ -20,7 +20,7 @@ // // this is a vector of encoded 'LedgerUpgrade' so that nodes can drop // // unknown steps during consensus if needed. // // see notes below on 'LedgerUpgrade' for more detail -// // max size is dictated by number of upgrade types ( room for future) +// // max size is dictated by number of upgrade types (+ room for future) // UpgradeType upgrades<6>; // // // reserved for future use diff --git a/src/main/java/org/stellar/sdk/xdr/Transaction.java b/src/main/java/org/stellar/sdk/xdr/Transaction.java index acb2290c9..728be1b57 100644 --- a/src/main/java/org/stellar/sdk/xdr/Transaction.java +++ b/src/main/java/org/stellar/sdk/xdr/Transaction.java @@ -4,9 +4,9 @@ package org.stellar.sdk.xdr; -import java.io.IOException; - import com.google.common.base.Objects; + +import java.io.IOException; import java.util.Arrays; // === xdr source ============================================================ @@ -22,8 +22,8 @@ // // sequence number to consume in the account // SequenceNumber seqNum; // -// // validity range (inclusive) for the last ledger close time -// TimeBounds* timeBounds; +// // validity conditions +// Preconditions cond; // // Memo memo; // @@ -62,12 +62,12 @@ public SequenceNumber getSeqNum() { public void setSeqNum(SequenceNumber value) { this.seqNum = value; } - private TimeBounds timeBounds; - public TimeBounds getTimeBounds() { - return this.timeBounds; + private Preconditions cond; + public Preconditions getCond() { + return this.cond; } - public void setTimeBounds(TimeBounds value) { - this.timeBounds = value; + public void setCond(Preconditions value) { + this.cond = value; } private Memo memo; public Memo getMemo() { @@ -94,12 +94,7 @@ public static void encode(XdrDataOutputStream stream, Transaction encodedTransac MuxedAccount.encode(stream, encodedTransaction.sourceAccount); Uint32.encode(stream, encodedTransaction.fee); SequenceNumber.encode(stream, encodedTransaction.seqNum); - if (encodedTransaction.timeBounds != null) { - stream.writeInt(1); - TimeBounds.encode(stream, encodedTransaction.timeBounds); - } else { - stream.writeInt(0); - } + Preconditions.encode(stream, encodedTransaction.cond); Memo.encode(stream, encodedTransaction.memo); int operationssize = encodedTransaction.getOperations().length; stream.writeInt(operationssize); @@ -116,10 +111,7 @@ public static Transaction decode(XdrDataInputStream stream) throws IOException { decodedTransaction.sourceAccount = MuxedAccount.decode(stream); decodedTransaction.fee = Uint32.decode(stream); decodedTransaction.seqNum = SequenceNumber.decode(stream); - int timeBoundsPresent = stream.readInt(); - if (timeBoundsPresent != 0) { - decodedTransaction.timeBounds = TimeBounds.decode(stream); - } + decodedTransaction.cond = Preconditions.decode(stream); decodedTransaction.memo = Memo.decode(stream); int operationssize = stream.readInt(); decodedTransaction.operations = new Operation[operationssize]; @@ -131,7 +123,7 @@ public static Transaction decode(XdrDataInputStream stream) throws IOException { } @Override public int hashCode() { - return Objects.hashCode(this.sourceAccount, this.fee, this.seqNum, this.timeBounds, this.memo, Arrays.hashCode(this.operations), this.ext); + return Objects.hashCode(this.sourceAccount, this.fee, this.seqNum, this.cond, this.memo, Arrays.hashCode(this.operations), this.ext); } @Override public boolean equals(Object object) { @@ -140,14 +132,14 @@ public boolean equals(Object object) { } Transaction other = (Transaction) object; - return Objects.equal(this.sourceAccount, other.sourceAccount) && Objects.equal(this.fee, other.fee) && Objects.equal(this.seqNum, other.seqNum) && Objects.equal(this.timeBounds, other.timeBounds) && Objects.equal(this.memo, other.memo) && Arrays.equals(this.operations, other.operations) && Objects.equal(this.ext, other.ext); + return Objects.equal(this.sourceAccount, other.sourceAccount) && Objects.equal(this.fee, other.fee) && Objects.equal(this.seqNum, other.seqNum) && Objects.equal(this.cond, other.cond) && Objects.equal(this.memo, other.memo) && Arrays.equals(this.operations, other.operations) && Objects.equal(this.ext, other.ext); } public static final class Builder { private MuxedAccount sourceAccount; private Uint32 fee; private SequenceNumber seqNum; - private TimeBounds timeBounds; + private Preconditions cond; private Memo memo; private Operation[] operations; private TransactionExt ext; @@ -167,8 +159,8 @@ public Builder seqNum(SequenceNumber seqNum) { return this; } - public Builder timeBounds(TimeBounds timeBounds) { - this.timeBounds = timeBounds; + public Builder cond(Preconditions cond) { + this.cond = cond; return this; } @@ -192,7 +184,7 @@ public Transaction build() { val.setSourceAccount(sourceAccount); val.setFee(fee); val.setSeqNum(seqNum); - val.setTimeBounds(timeBounds); + val.setCond(cond); val.setMemo(memo); val.setOperations(operations); val.setExt(ext); diff --git a/src/main/java/org/stellar/sdk/xdr/TrustLineEntry.java b/src/main/java/org/stellar/sdk/xdr/TrustLineEntry.java index 668c07d37..1a0417c29 100644 --- a/src/main/java/org/stellar/sdk/xdr/TrustLineEntry.java +++ b/src/main/java/org/stellar/sdk/xdr/TrustLineEntry.java @@ -4,18 +4,18 @@ package org.stellar.sdk.xdr; -import java.io.IOException; - import com.google.common.base.Objects; +import java.io.IOException; + // === xdr source ============================================================ // struct TrustLineEntry // { -// AccountID accountID; // account this trustline belongs to -// TrustLineAsset asset; // type of asset (with issuer) -// int64 balance; // how much of this asset the user has. -// // Asset defines the unit for this; +// AccountID accountID; // account this trustline belongs to +// TrustLineAsset asset; // type of asset (with issuer) +// int64 balance; // how much of this asset the user has. +// // Asset defines the unit for this; // // int64 limit; // balance cannot be above this // uint32 flags; // see TrustLineFlags diff --git a/src/test/java/org/stellar/sdk/SetOptionsOperationTest.java b/src/test/java/org/stellar/sdk/SetOptionsOperationTest.java new file mode 100644 index 000000000..ece16d1aa --- /dev/null +++ b/src/test/java/org/stellar/sdk/SetOptionsOperationTest.java @@ -0,0 +1,43 @@ +package org.stellar.sdk; + +import com.google.common.io.BaseEncoding; +import org.junit.Test; +import org.stellar.sdk.xdr.SignerKey; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +public class SetOptionsOperationTest { + KeyPair source = KeyPair.fromSecretSeed("SC4CGETADVYTCR5HEAVZRB3DZQY5Y4J7RFNJTRA6ESMHIPEZUSTE2QDK"); + + @Test + public void testPaylodSignerKey() { + SetOptionsOperation.Builder builder = new SetOptionsOperation.Builder(); + String payloadSignerStrKey = "GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ"; + + byte[] payload = BaseEncoding.base16().decode("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20".toUpperCase()); + SignedPayloadSigner signedPayloadSigner = new SignedPayloadSigner(payloadSignerStrKey, payload); + SignerKey signerKey = Signer.signedPayload(signedPayloadSigner); + + builder.setSigner(signerKey, 1); + builder.setSourceAccount(source.getAccountId()); + + SetOptionsOperation operation = builder.build(); + + org.stellar.sdk.xdr.Operation xdr = operation.toXdr(AccountConverter.enableMuxed()); + SetOptionsOperation parsedOperation = (SetOptionsOperation) Operation.fromXdr(AccountConverter.enableMuxed(), xdr); + + // verify round trip between xdr and pojo + assertEquals(source.getAccountId(), parsedOperation.getSourceAccount()); + assertArrayEquals(signedPayloadSigner.getDecodedAccountId(), parsedOperation.getSigner().getEd25519SignedPayload().getEd25519().getUint256()); + assertArrayEquals(signedPayloadSigner.getPayload(), parsedOperation.getSigner().getEd25519SignedPayload().getPayload()); + + // verify serialized xdr emitted with signed payload + assertEquals( + "AAAAAQAAAAC7JAuE3XvquOnbsgv2SRztjuk4RoBVefQ0rlrFMMQvfAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAEAAAADPww0v5OtDZlx0EzMkPcFURyDiq2XNKSi+w16A/x/6JoAAAAgAQIDBAUGBwgJCgsMDQ4PEBES" + + "ExQVFhcYGRobHB0eHyAAAAAB", + operation.toXdrBase64(AccountConverter.enableMuxed())); + } + +} diff --git a/src/test/java/org/stellar/sdk/SignerTest.java b/src/test/java/org/stellar/sdk/SignerTest.java new file mode 100644 index 000000000..8b6a81cec --- /dev/null +++ b/src/test/java/org/stellar/sdk/SignerTest.java @@ -0,0 +1,45 @@ +package org.stellar.sdk; + +import com.google.common.io.BaseEncoding; +import org.junit.Test; +import org.stellar.sdk.xdr.SignerKey; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.fail; + +public class SignerTest { + + @Test + public void itCreatesSignedPayloadSigner() { + String accountStrKey = "GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ"; + + byte[] payload = BaseEncoding.base16().decode("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20".toUpperCase()); + SignedPayloadSigner signedPayloadSigner = new SignedPayloadSigner(accountStrKey, payload); + SignerKey signerKey = Signer.signedPayload(signedPayloadSigner); + + assertArrayEquals(signerKey.getEd25519SignedPayload().getPayload(), payload); + assertArrayEquals(signerKey.getEd25519SignedPayload().getEd25519().getUint256(),signedPayloadSigner.getDecodedAccountId()); + } + + @Test + public void itFailsWhenInvalidParameters() { + String accountStrKey = "GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTnotgood"; + byte[] payload = BaseEncoding.base16().decode("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20".toUpperCase()); + SignedPayloadSigner signedPayloadSigner = new SignedPayloadSigner(accountStrKey, payload); + + try { + SignerKey signerKey = Signer.signedPayload(signedPayloadSigner); + fail("should not create a payload signer if invalid account"); + } catch (IllegalArgumentException ignored) {} + + accountStrKey = "GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ"; + payload = BaseEncoding.base16().decode("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f200102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2001".toUpperCase()); + signedPayloadSigner = new SignedPayloadSigner(accountStrKey, payload); + try { + SignerKey signerKey = Signer.signedPayload(signedPayloadSigner); + fail("should not create a payload signer if payload > max length"); + } catch (IllegalArgumentException ignored) {} + + } + +} diff --git a/src/test/java/org/stellar/sdk/StrKeyTest.java b/src/test/java/org/stellar/sdk/StrKeyTest.java index 689ba0a52..e0dc89a0e 100644 --- a/src/test/java/org/stellar/sdk/StrKeyTest.java +++ b/src/test/java/org/stellar/sdk/StrKeyTest.java @@ -1,5 +1,6 @@ package org.stellar.sdk; +import com.google.common.io.BaseEncoding; import org.junit.Test; import org.stellar.sdk.xdr.AccountID; import org.stellar.sdk.xdr.CryptoKeyType; @@ -7,7 +8,10 @@ import java.io.IOException; -import static org.junit.Assert.*; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + public class StrKeyTest { @Test @@ -45,6 +49,7 @@ public void testDecodedVersionByte() { assertEquals(StrKey.decodeVersionByte("MA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVAAAAAAAAAAAAAJLK"), StrKey.VersionByte.MUXED); assertEquals(StrKey.decodeVersionByte("TAQCSRX2RIDJNHFIFHWD63X7D7D6TRT5Y2S6E3TEMXTG5W3OECHZ2OG4"), StrKey.VersionByte.PRE_AUTH_TX); assertEquals(StrKey.decodeVersionByte("XDRPF6NZRR7EEVO7ESIWUDXHAOMM2QSKIQQBJK6I2FB7YKDZES5UCLWD"), StrKey.VersionByte.SHA256_HASH); + assertEquals(StrKey.decodeVersionByte("PDPYP7E6NEYZSVOTV6M23OFM2XRIMPDUJABHGHHH2Y67X7JL25GW6AAAAAAAAAAAAAAJEVA"), StrKey.VersionByte.SIGNED_PAYLOAD); } @Test() @@ -129,6 +134,62 @@ public void testRoundTripHashXFromBytes() { assertArrayEquals(data, StrKey.decodeCheck(StrKey.VersionByte.SHA256_HASH, hashX.toCharArray())); } + @Test + public void testValidSignedPayloadEncode() { + // Valid signed payload with an ed25519 public key and a 32-byte payload. + byte[] payload = BaseEncoding.base16().decode("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20".toUpperCase()); + SignedPayloadSigner signedPayloadSigner = new SignedPayloadSigner("GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ", payload); + String encoded = StrKey.encodeSignedPayload(signedPayloadSigner); + assertEquals(encoded, "PA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAQACAQDAQCQMBYIBEFAWDANBYHRAEISCMKBKFQXDAMRUGY4DUPB6IBZGM"); + + // Valid signed payload with an ed25519 public key and a 29-byte payload. + payload = BaseEncoding.base16().decode("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d".toUpperCase()); + signedPayloadSigner = new SignedPayloadSigner("GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ", payload); + encoded = StrKey.encodeSignedPayload(signedPayloadSigner); + assertEquals(encoded, "PA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAOQCAQDAQCQMBYIBEFAWDANBYHRAEISCMKBKFQXDAMRUGY4DUAAAAFGBU"); + } + + @Test + public void testInvalidSignedPayloadEncode() { + byte[] payload = BaseEncoding.base16().decode("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f200102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2001".toUpperCase()); + SignedPayloadSigner signedPayloadSigner = new SignedPayloadSigner("GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ", payload); + try { + StrKey.encodeSignedPayload(signedPayloadSigner); + fail("should not encode signed payloads > 64"); + } catch (FormatException ignored){} + + payload = BaseEncoding.base16().decode("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f200102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20".toUpperCase()); + signedPayloadSigner = new SignedPayloadSigner("GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KV_notgood", payload); + try { + StrKey.encodeSignedPayload(signedPayloadSigner); + fail("should not encode when accountid is not valid strkey"); + } catch (FormatException ignored){} + } + + @Test + public void testRoundTripSignedPayloadVersionByte() { + byte[] data = rawBytes( + // ed25519 + 0x36, 0x3e, 0xaa, 0x38, 0x67, 0x84, 0x1f, 0xba, + 0xd0, 0xf4, 0xed, 0x88, 0xc7, 0x79, 0xe4, 0xfe, + 0x66, 0xe5, 0x6a, 0x24, 0x70, 0xdc, 0x98, 0xc0, + 0xec, 0x9c, 0x07, 0x3d, 0x05, 0xc7, 0xb1, 0x03, + // payload length + 0x00, 0x00, 0x00, 0x09, + // payload + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, + // padding + 0x00, 0x00, 0x00); + + String hashX = "PA3D5KRYM6CB7OWQ6TWYRR3Z4T7GNZLKERYNZGGA5SOAOPIFY6YQGAAAAAEQAAAAAAAAAAAAAAAAAABBXA"; + assertEquals( + hashX, + String.valueOf(StrKey.encodeCheck(StrKey.VersionByte.SIGNED_PAYLOAD, data)) + ); + assertArrayEquals(data, StrKey.decodeCheck(StrKey.VersionByte.SIGNED_PAYLOAD, hashX.toCharArray())); + } + @Test public void testDecodeEmpty() { try { diff --git a/src/test/java/org/stellar/sdk/TransactionTest.java b/src/test/java/org/stellar/sdk/TransactionTest.java index 681d18d2b..74bba77f8 100644 --- a/src/test/java/org/stellar/sdk/TransactionTest.java +++ b/src/test/java/org/stellar/sdk/TransactionTest.java @@ -9,7 +9,10 @@ import java.security.SecureRandom; import java.util.Arrays; -import static org.junit.Assert.*; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; public class TransactionTest { @@ -121,8 +124,8 @@ public void testBuilderTimeBounds() throws FormatException, IOException { ); org.stellar.sdk.xdr.TransactionEnvelope decodedTransaction = org.stellar.sdk.xdr.TransactionEnvelope.decode(is); - assertEquals(decodedTransaction.getV1().getTx().getTimeBounds().getMinTime().getTimePoint().getUint64().longValue(), 42); - assertEquals(decodedTransaction.getV1().getTx().getTimeBounds().getMaxTime().getTimePoint().getUint64().longValue(), 1337); + assertEquals(decodedTransaction.getV1().getTx().getCond().getTimeBounds().getMinTime().getTimePoint().getUint64().longValue(), 42); + assertEquals(decodedTransaction.getV1().getTx().getCond().getTimeBounds().getMaxTime().getTimePoint().getUint64().longValue(), 1337); Transaction transaction2 = (Transaction)Transaction.fromEnvelopeXdr(AccountConverter.enableMuxed(), transaction.toEnvelopeXdr(), Network.TESTNET); @@ -299,8 +302,8 @@ public void testBuilderTimeBoundsNoMaxTime() throws FormatException, IOException ); org.stellar.sdk.xdr.TransactionEnvelope decodedTransaction = org.stellar.sdk.xdr.TransactionEnvelope.decode(is); - assertEquals(decodedTransaction.getV1().getTx().getTimeBounds().getMinTime().getTimePoint().getUint64().longValue(), 42); - assertEquals(decodedTransaction.getV1().getTx().getTimeBounds().getMaxTime().getTimePoint().getUint64().longValue(), 0); + assertEquals(decodedTransaction.getV1().getTx().getCond().getTimeBounds().getMinTime().getTimePoint().getUint64().longValue(), 42); + assertEquals(decodedTransaction.getV1().getTx().getCond().getTimeBounds().getMaxTime().getTimePoint().getUint64().longValue(), 0); } @Test diff --git a/src/test/java/org/stellar/sdk/xdr/AccountEntryDecodeTest.java b/src/test/java/org/stellar/sdk/xdr/AccountEntryDecodeTest.java new file mode 100644 index 000000000..0163f5b7d --- /dev/null +++ b/src/test/java/org/stellar/sdk/xdr/AccountEntryDecodeTest.java @@ -0,0 +1,50 @@ +package org.stellar.sdk.xdr; + +import com.google.common.io.BaseEncoding; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import static org.junit.Assert.assertArrayEquals; + +public class AccountEntryDecodeTest { + + BaseEncoding base64Encoding = BaseEncoding.base64(); + + @Test + public void testDecodeSignerPayload() throws IOException { + AccountEntry.Builder bldr = new AccountEntry.Builder(); + Signer signer = new Signer(); + SignerKey signerKey = new SignerKey(); + signerKey.setDiscriminant(SignerKeyType.SIGNER_KEY_TYPE_ED25519_SIGNED_PAYLOAD); + signerKey.setEd25519SignedPayload(new SignerKey.SignerKeyEd25519SignedPayload()); + signerKey.getEd25519SignedPayload().setPayload(new byte[]{1,2,3,4}); + signerKey.getEd25519SignedPayload().setEd25519(new Uint256(new byte[32])); + signer.setKey(signerKey); + signer.setWeight(new Uint32(1)); + bldr.signers(new Signer[]{signer}); + bldr.accountID(new AccountID(new PublicKey.Builder().discriminant(PublicKeyType.PUBLIC_KEY_TYPE_ED25519).ed25519(new Uint256(new byte[32])).build())); + bldr.seqNum(new SequenceNumber(new Int64(1L))); + bldr.balance(new Int64(0L)); + bldr.numSubEntries(new Uint32(0)); + bldr.flags(new Uint32(0)); + bldr.homeDomain(new String32(new XdrString(""))); + bldr.thresholds(new Thresholds(new byte[3])); + bldr.ext(new AccountEntry.AccountEntryExt.Builder().discriminant(0).build()); + + AccountEntry xdr = bldr.build(); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + XdrDataOutputStream outputStream = new XdrDataOutputStream(baos); + AccountEntry.encode(outputStream, xdr); + String encodedXdr = base64Encoding.encode(baos.toByteArray()); + + byte[] decodedbBytes = base64Encoding.decode(encodedXdr); + + AccountEntry accountEntry = AccountEntry.decode(new XdrDataInputStream(new ByteArrayInputStream(decodedbBytes))); + assertArrayEquals(new byte[32], accountEntry.getSigners()[0].getKey().getEd25519SignedPayload().getEd25519().getUint256()); + assertArrayEquals(new byte[]{1,2,3,4}, accountEntry.getSigners()[0].getKey().getEd25519SignedPayload().getPayload()); + } +} diff --git a/xdr/Stellar-ledger-entries.x b/xdr/Stellar-ledger-entries.x index 198e93dd8..a1bb8e726 100644 --- a/xdr/Stellar-ledger-entries.x +++ b/xdr/Stellar-ledger-entries.x @@ -13,6 +13,7 @@ typedef string string32<32>; typedef string string64<64>; typedef int64 SequenceNumber; typedef uint64 TimePoint; +typedef int64 Duration; typedef opaque DataValue<64>; typedef Hash PoolID; // SHA256(LiquidityPoolParameters) @@ -133,6 +134,19 @@ const MAX_SIGNERS = 20; typedef AccountID* SponsorshipDescriptor; +struct AccountEntryExtensionV3 +{ + // We can use this to add more fields, or because it is first, to + // change AccountEntryExtensionV3 into a union. + ExtensionPoint ext; + + // Ledger number at which `seqNum` took on its present value. + uint32 seqLedger; + + // Time at which `seqNum` took on its present value. + TimePoint seqTime; +}; + struct AccountEntryExtensionV2 { uint32 numSponsored; @@ -143,6 +157,8 @@ struct AccountEntryExtensionV2 { case 0: void; + case 3: + AccountEntryExtensionV3 v3; } ext; }; @@ -257,10 +273,10 @@ struct TrustLineEntryExtensionV2 struct TrustLineEntry { - AccountID accountID; // account this trustline belongs to - TrustLineAsset asset; // type of asset (with issuer) - int64 balance; // how much of this asset the user has. - // Asset defines the unit for this; + AccountID accountID; // account this trustline belongs to + TrustLineAsset asset; // type of asset (with issuer) + int64 balance; // how much of this asset the user has. + // Asset defines the unit for this; int64 limit; // balance cannot be above this uint32 flags; // see TrustLineFlags @@ -290,7 +306,7 @@ struct TrustLineEntry enum OfferEntryFlags { - // issuer has authorized account to perform transactions with its credit + // an offer with this flag will not act on and take a reverse offer of equal price PASSIVE_FLAG = 1 }; @@ -368,10 +384,10 @@ case CLAIM_PREDICATE_OR: case CLAIM_PREDICATE_NOT: ClaimPredicate* notPredicate; case CLAIM_PREDICATE_BEFORE_ABSOLUTE_TIME: - int64 absBefore; // Predicate will be true if closeTime < absBefore + TimePoint absBefore; // Predicate will be true if closeTime < absBefore case CLAIM_PREDICATE_BEFORE_RELATIVE_TIME: - int64 relBefore; // Seconds since closeTime of the ledger in which the - // ClaimableBalanceEntry was created + Duration relBefore; // Seconds since closeTime of the ledger in which the + // ClaimableBalanceEntry was created }; enum ClaimantType @@ -391,16 +407,13 @@ case CLAIMANT_TYPE_V0: enum ClaimableBalanceIDType { - CLAIMABLE_BALANCE_ID_TYPE_V0 = 0, - CLAIMABLE_BALANCE_ID_TYPE_FROM_POOL_REVOKE = 1 + CLAIMABLE_BALANCE_ID_TYPE_V0 = 0 }; union ClaimableBalanceID switch (ClaimableBalanceIDType type) { case CLAIMABLE_BALANCE_ID_TYPE_V0: Hash v0; -case CLAIMABLE_BALANCE_ID_TYPE_FROM_POOL_REVOKE: - Hash fromPoolRevoke; }; enum ClaimableBalanceFlags @@ -576,4 +589,4 @@ enum EnvelopeType ENVELOPE_TYPE_OP_ID = 6, ENVELOPE_TYPE_POOL_REVOKE_OP_ID = 7 }; -} +} \ No newline at end of file diff --git a/xdr/Stellar-ledger.x b/xdr/Stellar-ledger.x index 8a45985c8..b33e85a57 100644 --- a/xdr/Stellar-ledger.x +++ b/xdr/Stellar-ledger.x @@ -33,7 +33,7 @@ struct StellarValue // this is a vector of encoded 'LedgerUpgrade' so that nodes can drop // unknown steps during consensus if needed. // see notes below on 'LedgerUpgrade' for more detail - // max size is dictated by number of upgrade types ( room for future) + // max size is dictated by number of upgrade types (+ room for future) UpgradeType upgrades<6>; // reserved for future use @@ -47,11 +47,10 @@ struct StellarValue ext; }; -const MASK_LEDGERHEADER_FLAGS = 0x7; +const MASK_LEDGER_HEADER_FLAGS = 0x7; enum LedgerHeaderFlags -{ // masks for each flag - +{ DISABLE_LIQUIDITY_POOL_TRADING_FLAG = 0x1, DISABLE_LIQUIDITY_POOL_DEPOSIT_FLAG = 0x2, DISABLE_LIQUIDITY_POOL_WITHDRAWAL_FLAG = 0x4 @@ -59,7 +58,7 @@ enum LedgerHeaderFlags struct LedgerHeaderExtensionV1 { - uint32 flags; // UpgradeFlags + uint32 flags; // LedgerHeaderFlags union switch (int v) { @@ -69,7 +68,6 @@ struct LedgerHeaderExtensionV1 ext; }; - /* The LedgerHeader is the highest level structure representing the * state of a ledger, cryptographically linked to previous ledgers. */ @@ -365,4 +363,4 @@ union LedgerCloseMeta switch (int v) case 0: LedgerCloseMetaV0 v0; }; -} +} \ No newline at end of file diff --git a/xdr/Stellar-transaction.x b/xdr/Stellar-transaction.x index 19d0240d0..cd31b3a33 100644 --- a/xdr/Stellar-transaction.x +++ b/xdr/Stellar-transaction.x @@ -527,7 +527,7 @@ struct Operation body; }; -union OperationID switch (EnvelopeType type) +union HashIDPreimage switch (EnvelopeType type) { case ENVELOPE_TYPE_OP_ID: struct @@ -535,7 +535,7 @@ case ENVELOPE_TYPE_OP_ID: AccountID sourceAccount; SequenceNumber seqNum; uint32 opNum; - } id; + } operationID; case ENVELOPE_TYPE_POOL_REVOKE_OP_ID: struct { @@ -544,7 +544,7 @@ case ENVELOPE_TYPE_POOL_REVOKE_OP_ID: uint32 opNum; PoolID liquidityPoolID; Asset asset; - } revokeId; + } revokeID; }; enum MemoType @@ -576,6 +576,58 @@ struct TimeBounds TimePoint maxTime; // 0 here means no maxTime }; +struct LedgerBounds +{ + uint32 minLedger; + uint32 maxLedger; +}; + +struct PreconditionsV2 { + TimeBounds *timeBounds; + + // Transaciton only valid for ledger numbers n such that + // minLedger <= n < maxLedger + LedgerBounds *ledgerBounds; + + // If NULL, only valid when sourceAccount's sequence number + // is seqNum - 1. Otherwise, valid when sourceAccount's + // sequence number n satisfies minSeqNum <= n < tx.seqNum. + // Note that after execution the account's sequence number + // is always raised to tx.seqNum, and a transaction is not + // valid if tx.seqNum is too high to ensure replay protection. + SequenceNumber *minSeqNum; + + // For the transaction to be valid, the current ledger time must + // be at least minSeqAge greater than sourceAccount's seqTime. + Duration minSeqAge; + + // For the transaction to be valid, the current ledger number + // must be at least minSeqLedgerGap greater than sourceAccount's + // seqLedger. + uint32 minSeqLedgerGap; + + // For the transaction to be valid, there must be a signature + // corresponding to every Signer in this array, even if the + // signature is not otherwise required by the sourceAccount or + // operations. + SignerKey extraSigners<2>; +}; + +enum PreconditionType { + PRECOND_NONE = 0, + PRECOND_TIME = 1, + PRECOND_V2 = 2 +}; + +union Preconditions switch (PreconditionType type) { + case PRECOND_NONE: + void; + case PRECOND_TIME: + TimeBounds timeBounds; + case PRECOND_V2: + PreconditionsV2 v2; +}; + // maximum number of operations per transaction const MAX_OPS_PER_TX = 100; @@ -627,8 +679,8 @@ struct Transaction // sequence number to consume in the account SequenceNumber seqNum; - // validity range (inclusive) for the last ledger close time - TimeBounds* timeBounds; + // validity conditions + Preconditions cond; Memo memo; @@ -1082,7 +1134,7 @@ enum AllowTrustResultCode ALLOW_TRUST_CANT_REVOKE = -4, // source account can't revoke trust, ALLOW_TRUST_SELF_NOT_ALLOWED = -5, // trusting self is not allowed ALLOW_TRUST_LOW_RESERVE = -6 // claimable balances can't be created - // on revoke due to low reserves + // on revoke due to low reserves }; union AllowTrustResult switch (AllowTrustResultCode code) @@ -1415,7 +1467,6 @@ default: void; }; - /* High level Operation Result */ enum OperationResultCode { @@ -1582,4 +1633,4 @@ struct TransactionResult } ext; }; -} +} \ No newline at end of file diff --git a/xdr/Stellar-types.x b/xdr/Stellar-types.x index 8f7d5c206..7d5a1467c 100644 --- a/xdr/Stellar-types.x +++ b/xdr/Stellar-types.x @@ -14,11 +14,20 @@ typedef int int32; typedef unsigned hyper uint64; typedef hyper int64; +// An ExtensionPoint is always marshaled as a 32-bit 0 value. At a +// later point, it can be replaced by a different union so as to +// extend a structure. +union ExtensionPoint switch (int v) { +case 0: + void; +}; + enum CryptoKeyType { KEY_TYPE_ED25519 = 0, KEY_TYPE_PRE_AUTH_TX = 1, KEY_TYPE_HASH_X = 2, + KEY_TYPE_ED25519_SIGNED_PAYLOAD = 3, // MUXED enum values for supported type are derived from the enum values // above by ORing them with 0x100 KEY_TYPE_MUXED_ED25519 = 0x100 @@ -33,7 +42,8 @@ enum SignerKeyType { SIGNER_KEY_TYPE_ED25519 = KEY_TYPE_ED25519, SIGNER_KEY_TYPE_PRE_AUTH_TX = KEY_TYPE_PRE_AUTH_TX, - SIGNER_KEY_TYPE_HASH_X = KEY_TYPE_HASH_X + SIGNER_KEY_TYPE_HASH_X = KEY_TYPE_HASH_X, + SIGNER_KEY_TYPE_ED25519_SIGNED_PAYLOAD = KEY_TYPE_ED25519_SIGNED_PAYLOAD }; union PublicKey switch (PublicKeyType type) @@ -52,6 +62,13 @@ case SIGNER_KEY_TYPE_PRE_AUTH_TX: case SIGNER_KEY_TYPE_HASH_X: /* Hash of random 256 bit preimage X */ uint256 hashX; +case SIGNER_KEY_TYPE_ED25519_SIGNED_PAYLOAD: + struct { + /* Public key that must sign the payload. */ + uint256 ed25519; + /* Payload to be raw signed by ed25519. */ + opaque payload<64>; + } ed25519SignedPayload; }; // variable size as the size depends on the signature scheme used @@ -80,4 +97,4 @@ struct HmacSha256Mac { opaque mac[32]; }; -} +} \ No newline at end of file From 5bf518bfd24895520b5e4f391ad71470eda584af Mon Sep 17 00:00:00 2001 From: Shawn Reuland Date: Mon, 21 Mar 2022 15:20:21 -0700 Subject: [PATCH 2/7] #410: use xdr data types for predicate time dimensions, incorporate some pr feedback --- CHANGELOG.md | 8 ++++ src/main/java/org/stellar/sdk/Predicate.java | 46 ++++++++----------- .../org/stellar/sdk/SignedPayloadSigner.java | 2 +- .../sdk/responses/PredicateDeserializer.java | 11 +++-- .../ClaimableBalancePageDeserializerTest.java | 2 +- .../sdk/responses/EffectDeserializerTest.java | 4 +- .../responses/OperationDeserializerTest.java | 2 +- 7 files changed, 39 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa6114035..2b62f7446 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,14 @@ As this project is pre 1.0, breaking changes may happen for minor version bumps. * Update XDR definitions and auto-generated classes to support upcoming protocol 19 release ([#276](https://github.com/stellar/java-stellar-sdk/pull/276)). * Extend StrKey implementation to handle [CAP 40 Payload Signer](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0040.md) ([#276](https://github.com/stellar/java-stellar-sdk/pull/276)). +### Breaking changes + +* Predicate.AbsBefore + * `Predicate.AbsBefore(org.stellar.sdk.xdr.TimePoint)` + * `org.stellar.sdk.xdr.TimePoint Predicate.AbsBefore.getTimestampSeconds()` +* Predicate.RelBefore + * `Predicate.RelBefore(org.stellar.sdk.xdr.Duration)` + * `org.stellar.sdk.xdr.Duration Predicate.RelBefore.getSecondsSinceClose()` ## 0.31.0 diff --git a/src/main/java/org/stellar/sdk/Predicate.java b/src/main/java/org/stellar/sdk/Predicate.java index 35d7c7617..d2cea4591 100644 --- a/src/main/java/org/stellar/sdk/Predicate.java +++ b/src/main/java/org/stellar/sdk/Predicate.java @@ -37,9 +37,9 @@ public static Predicate fromXdr(org.stellar.sdk.xdr.ClaimPredicate xdr) { case CLAIM_PREDICATE_NOT: return new Not(fromXdr(xdr.getNotPredicate())); case CLAIM_PREDICATE_BEFORE_RELATIVE_TIME: - return new RelBefore(xdr.getRelBefore().getDuration().getInt64()); + return new RelBefore(xdr.getRelBefore()); case CLAIM_PREDICATE_BEFORE_ABSOLUTE_TIME: - return new AbsBefore(xdr.getAbsBefore().getTimePoint().getUint64()); + return new AbsBefore(xdr.getAbsBefore()); default: throw new IllegalArgumentException("Unknown asset type " + xdr.getDiscriminant()); } @@ -181,18 +181,18 @@ public ClaimPredicate toXdr() { } public static class AbsBefore extends Predicate { - private final long epochSeconds; + private final TimePoint timePoint; - public AbsBefore(long epochSeconds) { - this.epochSeconds = epochSeconds; + public AbsBefore(TimePoint timePoint) { + this.timePoint = timePoint; } - public long getTimestampSeconds() { - return epochSeconds; + public TimePoint getTimestampSeconds() { + return timePoint; } public Instant getDate() { - return Instant.ofEpochSecond(epochSeconds); + return Instant.ofEpochSecond(timePoint.getTimePoint().getUint64()); } @Override @@ -200,36 +200,32 @@ public boolean equals(Object o) { if (this == o) { return true; } - return (getClass() == o.getClass()) && Objects.equal(epochSeconds, ((AbsBefore)o).epochSeconds); + return (getClass() == o.getClass()) && Objects.equal(timePoint, ((AbsBefore)o).timePoint); } @Override public int hashCode() { - return Objects.hashCode(epochSeconds); + return Objects.hashCode(timePoint); } @Override public ClaimPredicate toXdr() { org.stellar.sdk.xdr.ClaimPredicate xdr = new org.stellar.sdk.xdr.ClaimPredicate(); xdr.setDiscriminant(ClaimPredicateType.CLAIM_PREDICATE_BEFORE_ABSOLUTE_TIME); - Uint64 t = new Uint64(); - t.setUint64(epochSeconds); - TimePoint beforeTime = new TimePoint(); - beforeTime.setTimePoint(t); - xdr.setAbsBefore(beforeTime); + xdr.setAbsBefore(timePoint); return xdr; } } public static class RelBefore extends Predicate { - private final long secondsSinceClose; + private final Duration duration; - public RelBefore(long secondsSinceClose) { - this.secondsSinceClose = secondsSinceClose; + public RelBefore(Duration secondsSinceClose) { + this.duration = secondsSinceClose; } - public long getSecondsSinceClose() { - return secondsSinceClose; + public Duration getSecondsSinceClose() { + return duration; } @Override @@ -237,23 +233,19 @@ public boolean equals(Object o) { if (this == o) { return true; } - return (getClass() == o.getClass()) && Objects.equal(secondsSinceClose, ((RelBefore)o).secondsSinceClose); + return (getClass() == o.getClass()) && Objects.equal(duration, ((RelBefore)o).duration); } @Override public int hashCode() { - return Objects.hashCode(secondsSinceClose); + return Objects.hashCode(duration); } @Override public ClaimPredicate toXdr() { org.stellar.sdk.xdr.ClaimPredicate xdr = new org.stellar.sdk.xdr.ClaimPredicate(); xdr.setDiscriminant(ClaimPredicateType.CLAIM_PREDICATE_BEFORE_RELATIVE_TIME); - Int64 t = new Int64(); - t.setInt64(secondsSinceClose); - Duration beforeTime = new Duration(); - beforeTime.setDuration(t); - xdr.setRelBefore(beforeTime); + xdr.setRelBefore(duration); return xdr; } } diff --git a/src/main/java/org/stellar/sdk/SignedPayloadSigner.java b/src/main/java/org/stellar/sdk/SignedPayloadSigner.java index 06e573a5c..70b60d763 100644 --- a/src/main/java/org/stellar/sdk/SignedPayloadSigner.java +++ b/src/main/java/org/stellar/sdk/SignedPayloadSigner.java @@ -19,7 +19,7 @@ public SignedPayloadSigner(String accountId, byte[] payload) { } /** - * get the StrKey encoded representation of a stellar account id + * get the StrKey encoded representation of a signed payload signer * @return stellar account id in StrKey encoding */ public String getEncodedAccountId() { diff --git a/src/main/java/org/stellar/sdk/responses/PredicateDeserializer.java b/src/main/java/org/stellar/sdk/responses/PredicateDeserializer.java index 6c129750f..1a51824e0 100644 --- a/src/main/java/org/stellar/sdk/responses/PredicateDeserializer.java +++ b/src/main/java/org/stellar/sdk/responses/PredicateDeserializer.java @@ -3,6 +3,10 @@ import com.google.common.collect.Lists; import com.google.gson.*; import org.stellar.sdk.Predicate; +import org.stellar.sdk.xdr.Duration; +import org.stellar.sdk.xdr.Int64; +import org.stellar.sdk.xdr.TimePoint; +import org.stellar.sdk.xdr.Uint64; import org.threeten.bp.Instant; import java.lang.reflect.Type; @@ -39,15 +43,14 @@ public Predicate deserialize(JsonElement json, Type typeOfT, JsonDeserialization // backwards compatible for abs before, uses the newer abs_before_epoch if available from server // otherwise if abs_before_epoch is absent, it will fall back to original attempt to parse abs_before date string if (obj.has("abs_before_epoch")) { - return new Predicate.AbsBefore(obj.get("abs_before_epoch").getAsLong()); + return new Predicate.AbsBefore(new TimePoint(new Uint64(obj.get("abs_before_epoch").getAsLong()))); } else if (obj.has("abs_before")) { String formattedDate = obj.get("abs_before").getAsString(); - return new Predicate.AbsBefore(Instant.parse(formattedDate).getEpochSecond()); + return new Predicate.AbsBefore(new TimePoint(new Uint64(Instant.parse(formattedDate).getEpochSecond()))); } if (obj.has("rel_before")) { - Long relBefore = obj.get("rel_before").getAsLong(); - return new Predicate.RelBefore(relBefore); + return new Predicate.RelBefore(new Duration(new Int64(obj.get("rel_before").getAsLong()))); } throw new IllegalArgumentException("Unsupported predicate: "+json.toString()); diff --git a/src/test/java/org/stellar/sdk/responses/ClaimableBalancePageDeserializerTest.java b/src/test/java/org/stellar/sdk/responses/ClaimableBalancePageDeserializerTest.java index b53516305..01bd459ed 100644 --- a/src/test/java/org/stellar/sdk/responses/ClaimableBalancePageDeserializerTest.java +++ b/src/test/java/org/stellar/sdk/responses/ClaimableBalancePageDeserializerTest.java @@ -34,7 +34,7 @@ public void testDeserialize() { Predicate.AbsBefore absBefore = (Predicate.AbsBefore)or.getInner().get(0); Predicate.RelBefore relBefore = (Predicate.RelBefore)or.getInner().get(1); assertEquals(absBefore.getDate().toString(), "2020-09-28T17:57:04Z"); - assertEquals(relBefore.getSecondsSinceClose(), 12); + assertEquals(relBefore.getSecondsSinceClose().getDuration().getInt64().longValue(), 12L); assertEquals(claimableBalancePage.getRecords().get(1).getId(), "00000000ae76f49e8513d0922b6bcbc8a3f5c4c0a5161871f27924e08724646acab56cd3"); assertEquals(claimableBalancePage.getRecords().get(1).getAsset(), Asset.create("native")); diff --git a/src/test/java/org/stellar/sdk/responses/EffectDeserializerTest.java b/src/test/java/org/stellar/sdk/responses/EffectDeserializerTest.java index 431c8e89e..28db4fceb 100644 --- a/src/test/java/org/stellar/sdk/responses/EffectDeserializerTest.java +++ b/src/test/java/org/stellar/sdk/responses/EffectDeserializerTest.java @@ -284,7 +284,7 @@ public void testDeserializeClaimableBalanceClaimantCreatedEffect() { assertEquals(effect.getBalanceId(), "0000000071d3336fa6b6cf81fcbeda85a503ccfabc786ab1066594716f3f9551ea4b89ca"); assertEquals(effect.getType(), "claimable_balance_claimant_created"); assertSame(effect.getPredicate().getClass(), Predicate.AbsBefore.class); - assertEquals(((Predicate.AbsBefore)effect.getPredicate()).getTimestampSeconds(), 1234567890982222222L); + assertEquals(((Predicate.AbsBefore)effect.getPredicate()).getTimestampSeconds().getTimePoint().getUint64().longValue(), 1234567890982222222L); } @Test @@ -322,7 +322,7 @@ public void testBackwardsCompatAbsBeforeEpoch() { assertEquals(effect.getBalanceId(), "0000000071d3336fa6b6cf81fcbeda85a503ccfabc786ab1066594716f3f9551ea4b89ca"); assertEquals(effect.getType(), "claimable_balance_claimant_created"); assertSame(effect.getPredicate().getClass(), Predicate.AbsBefore.class); - assertEquals(((Predicate.AbsBefore)effect.getPredicate()).getTimestampSeconds(), 1637479450L); + assertEquals(((Predicate.AbsBefore)effect.getPredicate()).getTimestampSeconds().getTimePoint().getUint64().longValue(), 1637479450L); } @Test diff --git a/src/test/java/org/stellar/sdk/responses/OperationDeserializerTest.java b/src/test/java/org/stellar/sdk/responses/OperationDeserializerTest.java index 19bde0c35..25a8bece7 100644 --- a/src/test/java/org/stellar/sdk/responses/OperationDeserializerTest.java +++ b/src/test/java/org/stellar/sdk/responses/OperationDeserializerTest.java @@ -1567,7 +1567,7 @@ public void testDeserializeCreateClaimableBalanceOperation() { assertEquals(operation.getClaimants().size(), 2); assertEquals(operation.getClaimants().get(0).getDestination(), "GBQECQVAS2FJ7DLCUXDASZAJQLWPXNTCR2DGBPKQDO3QS66TJXLRHFIK"); assertSame(operation.getClaimants().get(0).getPredicate().getClass(), Predicate.AbsBefore.class); - assertEquals(((Predicate.AbsBefore)operation.getClaimants().get(0).getPredicate()).getTimestampSeconds(), 1234567890982222222L); + assertEquals(((Predicate.AbsBefore)operation.getClaimants().get(0).getPredicate()).getTimestampSeconds().getTimePoint().getUint64().longValue(), 1234567890982222222L); assertEquals(operation.getClaimants().get(1).getDestination(), "GAKFBRS24U3PEN6XDMEX4JEV5NGBARS2ZFF5O4CF3JL464SQSD4MDCPF"); assertSame(operation.getClaimants().get(1).getPredicate().getClass(), Predicate.Unconditional.class); assertEquals(operation.getType(), "create_claimable_balance"); From c44b1de9fbe6eb0b5bd98fe22b7771082b185384 Mon Sep 17 00:00:00 2001 From: Shawn Reuland Date: Mon, 21 Mar 2022 22:01:36 -0700 Subject: [PATCH 3/7] #410: use xdr encoding/decoding for signed payload (de)ser, use AccountID for signed payload pojo to check discriminant on public key types --- .../org/stellar/sdk/SignedPayloadSigner.java | 39 ++++++++++++------- src/main/java/org/stellar/sdk/Signer.java | 4 +- src/main/java/org/stellar/sdk/StrKey.java | 33 ++++++++-------- .../stellar/sdk/SetOptionsOperationTest.java | 4 +- .../stellar/sdk/SignedPayloadSignerTest.java | 18 +++++++++ src/test/java/org/stellar/sdk/SignerTest.java | 20 +++------- src/test/java/org/stellar/sdk/StrKeyTest.java | 13 ++----- 7 files changed, 74 insertions(+), 57 deletions(-) create mode 100644 src/test/java/org/stellar/sdk/SignedPayloadSignerTest.java diff --git a/src/main/java/org/stellar/sdk/SignedPayloadSigner.java b/src/main/java/org/stellar/sdk/SignedPayloadSigner.java index 70b60d763..1564fe9e6 100644 --- a/src/main/java/org/stellar/sdk/SignedPayloadSigner.java +++ b/src/main/java/org/stellar/sdk/SignedPayloadSigner.java @@ -1,37 +1,50 @@ package org.stellar.sdk; +import org.stellar.sdk.xdr.AccountID; +import org.stellar.sdk.xdr.PublicKey; +import org.stellar.sdk.xdr.PublicKeyType; +import org.stellar.sdk.xdr.Uint256; + +import static com.google.common.base.Preconditions.checkNotNull; + + /** * Data model for the signed payload signer */ public class SignedPayloadSigner { - private String accountId; + private AccountID accountId; private byte[] payload; /** * constructor * - * @param accountId - the StrKey format of a stellar AccountId + * @param accountId - the xdr AccountID * @param payload - the raw payload for a signed payload */ - public SignedPayloadSigner(String accountId, byte[] payload) { - this.accountId = accountId; - this.payload = payload; + public SignedPayloadSigner(AccountID accountId, byte[] payload) { + this.accountId = checkNotNull(accountId); + this.payload = checkNotNull(payload); } /** - * get the StrKey encoded representation of a signed payload signer - * @return stellar account id in StrKey encoding + * construcxtor + * + * @param ed25519PublicKey raw bytes of a ED25519 public key + * @param payload the raw payload for a signed payload */ - public String getEncodedAccountId() { - return accountId; + public SignedPayloadSigner(byte[] ed25519PublicKey, byte[] payload ) { + this(new AccountID( + new PublicKey.Builder() + .discriminant(PublicKeyType.PUBLIC_KEY_TYPE_ED25519) + .ed25519(new Uint256(ed25519PublicKey)).build()), payload); } /** - * get the binary format of a stellar account id, a Ed25519 public key - * @return stellar account id in binary format + * get the account that represents the signed payload signer + * @return stellar account */ - public byte[] getDecodedAccountId() { - return StrKey.decodeStellarAccountId(accountId); + public AccountID getAccountId() { + return accountId; } /** diff --git a/src/main/java/org/stellar/sdk/Signer.java b/src/main/java/org/stellar/sdk/Signer.java index cbf356af0..50b1501e7 100644 --- a/src/main/java/org/stellar/sdk/Signer.java +++ b/src/main/java/org/stellar/sdk/Signer.java @@ -82,13 +82,13 @@ public static SignerKey preAuthTx(byte[] hash) { * @return org.stellar.sdk.xdr.SignerKey */ public static SignerKey signedPayload(SignedPayloadSigner signedPayloadSigner) { - checkNotNull(signedPayloadSigner.getEncodedAccountId(), "accountId cannot be null"); + checkNotNull(signedPayloadSigner.getAccountId(), "accountId cannot be null"); checkArgument(signedPayloadSigner.getPayload().length <= SIGNED_PAYLOAD_MAX_PAYLOAD_LENGTH ); SignerKey signerKey = new SignerKey(); SignerKey.SignerKeyEd25519SignedPayload payloadSigner = new SignerKey.SignerKeyEd25519SignedPayload(); payloadSigner.setPayload(signedPayloadSigner.getPayload()); - payloadSigner.setEd25519(createUint256(signedPayloadSigner.getDecodedAccountId())); + payloadSigner.setEd25519(signedPayloadSigner.getAccountId().getAccountID().getEd25519()); signerKey.setDiscriminant(SignerKeyType.SIGNER_KEY_TYPE_ED25519_SIGNED_PAYLOAD); signerKey.setEd25519SignedPayload(payloadSigner); diff --git a/src/main/java/org/stellar/sdk/StrKey.java b/src/main/java/org/stellar/sdk/StrKey.java index 7a0b787b9..298909f4d 100644 --- a/src/main/java/org/stellar/sdk/StrKey.java +++ b/src/main/java/org/stellar/sdk/StrKey.java @@ -9,15 +9,15 @@ import org.stellar.sdk.xdr.MuxedAccount; import org.stellar.sdk.xdr.PublicKey; import org.stellar.sdk.xdr.PublicKeyType; +import org.stellar.sdk.xdr.SignerKey; import org.stellar.sdk.xdr.Uint256; import org.stellar.sdk.xdr.Uint64; import org.stellar.sdk.xdr.XdrDataInputStream; +import org.stellar.sdk.xdr.XdrDataOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.CharArrayWriter; -import java.io.DataInputStream; -import java.io.DataOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Arrays; @@ -69,14 +69,17 @@ public static String encodeSignedPayload(SignedPayloadSigner signedPayloadSigner if (signedPayloadSigner.getPayload().length > SIGNED_PAYLOAD_MAX_PAYLOAD_LENGTH) { throw new FormatException("invalid payload length, must be less than " + SIGNED_PAYLOAD_MAX_PAYLOAD_LENGTH); } + if (!signedPayloadSigner.getAccountId().getAccountID().getDiscriminant().equals(PublicKeyType.PUBLIC_KEY_TYPE_ED25519)) { + throw new FormatException("invalid payload signer, only ED25519 public key accounts are supported currently"); + } try { + SignerKey.SignerKeyEd25519SignedPayload xdrPayloadSigner = new SignerKey.SignerKeyEd25519SignedPayload(); + xdrPayloadSigner.setPayload(signedPayloadSigner.getPayload()); + xdrPayloadSigner.setEd25519(signedPayloadSigner.getAccountId().getAccountID().getEd25519()); + ByteArrayOutputStream record = new ByteArrayOutputStream(); - DataOutputStream dataStream = new DataOutputStream(record); - dataStream.write(signedPayloadSigner.getDecodedAccountId()); - dataStream.writeInt(signedPayloadSigner.getPayload().length); - dataStream.write(signedPayloadSigner.getPayload()); - int padding = signedPayloadSigner.getPayload().length % 4 > 0 ? 4 - signedPayloadSigner.getPayload().length % 4 : 0; - dataStream.write(new byte[padding]); + xdrPayloadSigner.encode(new XdrDataOutputStream(record)); + char[] encoded = encodeCheck(VersionByte.SIGNED_PAYLOAD, record.toByteArray()); return String.valueOf(encoded); } catch (Exception ex) { @@ -192,14 +195,12 @@ public static byte[] decodeStellarSecretSeed(char[] data) { public static SignedPayloadSigner decodeSignedPayload(char[] data) { try { byte[] signedPayloadRaw = decodeCheck(VersionByte.SIGNED_PAYLOAD, data); - DataInputStream dataStream = new DataInputStream(new ByteArrayInputStream(signedPayloadRaw)); - byte[] binaryAccountId = new byte[32]; - dataStream.read(binaryAccountId); - int payloadLength = dataStream.readInt(); - byte[] payload = new byte[payloadLength]; - dataStream.read(payload); - - return new SignedPayloadSigner(encodeStellarAccountId(binaryAccountId), payload ); + + SignerKey.SignerKeyEd25519SignedPayload xdrPayloadSigner = SignerKey.SignerKeyEd25519SignedPayload.decode( + new XdrDataInputStream(new ByteArrayInputStream(signedPayloadRaw)) + ); + + return new SignedPayloadSigner( xdrPayloadSigner.getEd25519().getUint256(), xdrPayloadSigner.getPayload()); } catch (Exception ex) { throw new FormatException(ex.getMessage()); } diff --git a/src/test/java/org/stellar/sdk/SetOptionsOperationTest.java b/src/test/java/org/stellar/sdk/SetOptionsOperationTest.java index ece16d1aa..23c072316 100644 --- a/src/test/java/org/stellar/sdk/SetOptionsOperationTest.java +++ b/src/test/java/org/stellar/sdk/SetOptionsOperationTest.java @@ -16,7 +16,7 @@ public void testPaylodSignerKey() { String payloadSignerStrKey = "GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ"; byte[] payload = BaseEncoding.base16().decode("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20".toUpperCase()); - SignedPayloadSigner signedPayloadSigner = new SignedPayloadSigner(payloadSignerStrKey, payload); + SignedPayloadSigner signedPayloadSigner = new SignedPayloadSigner(StrKey.decodeStellarAccountId(payloadSignerStrKey), payload); SignerKey signerKey = Signer.signedPayload(signedPayloadSigner); builder.setSigner(signerKey, 1); @@ -29,7 +29,7 @@ public void testPaylodSignerKey() { // verify round trip between xdr and pojo assertEquals(source.getAccountId(), parsedOperation.getSourceAccount()); - assertArrayEquals(signedPayloadSigner.getDecodedAccountId(), parsedOperation.getSigner().getEd25519SignedPayload().getEd25519().getUint256()); + assertEquals(signedPayloadSigner.getAccountId().getAccountID().getEd25519(), parsedOperation.getSigner().getEd25519SignedPayload().getEd25519()); assertArrayEquals(signedPayloadSigner.getPayload(), parsedOperation.getSigner().getEd25519SignedPayload().getPayload()); // verify serialized xdr emitted with signed payload diff --git a/src/test/java/org/stellar/sdk/SignedPayloadSignerTest.java b/src/test/java/org/stellar/sdk/SignedPayloadSignerTest.java new file mode 100644 index 000000000..9869b3298 --- /dev/null +++ b/src/test/java/org/stellar/sdk/SignedPayloadSignerTest.java @@ -0,0 +1,18 @@ +package org.stellar.sdk; + +import org.junit.Test; +import org.stellar.sdk.xdr.AccountID; + +import static org.junit.Assert.fail; + +public class SignedPayloadSignerTest { + @Test + public void itFailsWhenAccoutIDIsNull() { + try { + new SignedPayloadSigner( + (AccountID)null, + new byte[]{}); + fail("should not create when accountid is null"); + } catch (NullPointerException ignored){} + } +} diff --git a/src/test/java/org/stellar/sdk/SignerTest.java b/src/test/java/org/stellar/sdk/SignerTest.java index 8b6a81cec..e0d755091 100644 --- a/src/test/java/org/stellar/sdk/SignerTest.java +++ b/src/test/java/org/stellar/sdk/SignerTest.java @@ -5,6 +5,7 @@ import org.stellar.sdk.xdr.SignerKey; import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; public class SignerTest { @@ -14,27 +15,18 @@ public void itCreatesSignedPayloadSigner() { String accountStrKey = "GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ"; byte[] payload = BaseEncoding.base16().decode("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20".toUpperCase()); - SignedPayloadSigner signedPayloadSigner = new SignedPayloadSigner(accountStrKey, payload); + SignedPayloadSigner signedPayloadSigner = new SignedPayloadSigner(StrKey.decodeStellarAccountId(accountStrKey), payload); SignerKey signerKey = Signer.signedPayload(signedPayloadSigner); assertArrayEquals(signerKey.getEd25519SignedPayload().getPayload(), payload); - assertArrayEquals(signerKey.getEd25519SignedPayload().getEd25519().getUint256(),signedPayloadSigner.getDecodedAccountId()); + assertEquals(signerKey.getEd25519SignedPayload().getEd25519(),signedPayloadSigner.getAccountId().getAccountID().getEd25519()); } @Test public void itFailsWhenInvalidParameters() { - String accountStrKey = "GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTnotgood"; - byte[] payload = BaseEncoding.base16().decode("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20".toUpperCase()); - SignedPayloadSigner signedPayloadSigner = new SignedPayloadSigner(accountStrKey, payload); - - try { - SignerKey signerKey = Signer.signedPayload(signedPayloadSigner); - fail("should not create a payload signer if invalid account"); - } catch (IllegalArgumentException ignored) {} - - accountStrKey = "GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ"; - payload = BaseEncoding.base16().decode("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f200102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2001".toUpperCase()); - signedPayloadSigner = new SignedPayloadSigner(accountStrKey, payload); + String accountStrKey = "GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ"; + byte[] payload = BaseEncoding.base16().decode("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f200102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2001".toUpperCase()); + SignedPayloadSigner signedPayloadSigner = new SignedPayloadSigner(StrKey.decodeStellarAccountId(accountStrKey), payload); try { SignerKey signerKey = Signer.signedPayload(signedPayloadSigner); fail("should not create a payload signer if payload > max length"); diff --git a/src/test/java/org/stellar/sdk/StrKeyTest.java b/src/test/java/org/stellar/sdk/StrKeyTest.java index e0dc89a0e..c6a43e352 100644 --- a/src/test/java/org/stellar/sdk/StrKeyTest.java +++ b/src/test/java/org/stellar/sdk/StrKeyTest.java @@ -138,13 +138,13 @@ public void testRoundTripHashXFromBytes() { public void testValidSignedPayloadEncode() { // Valid signed payload with an ed25519 public key and a 32-byte payload. byte[] payload = BaseEncoding.base16().decode("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20".toUpperCase()); - SignedPayloadSigner signedPayloadSigner = new SignedPayloadSigner("GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ", payload); + SignedPayloadSigner signedPayloadSigner = new SignedPayloadSigner(StrKey.decodeStellarAccountId("GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ"), payload); String encoded = StrKey.encodeSignedPayload(signedPayloadSigner); assertEquals(encoded, "PA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAQACAQDAQCQMBYIBEFAWDANBYHRAEISCMKBKFQXDAMRUGY4DUPB6IBZGM"); // Valid signed payload with an ed25519 public key and a 29-byte payload. payload = BaseEncoding.base16().decode("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d".toUpperCase()); - signedPayloadSigner = new SignedPayloadSigner("GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ", payload); + signedPayloadSigner = new SignedPayloadSigner(StrKey.decodeStellarAccountId("GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ"), payload); encoded = StrKey.encodeSignedPayload(signedPayloadSigner); assertEquals(encoded, "PA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAOQCAQDAQCQMBYIBEFAWDANBYHRAEISCMKBKFQXDAMRUGY4DUAAAAFGBU"); } @@ -152,18 +152,11 @@ public void testValidSignedPayloadEncode() { @Test public void testInvalidSignedPayloadEncode() { byte[] payload = BaseEncoding.base16().decode("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f200102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2001".toUpperCase()); - SignedPayloadSigner signedPayloadSigner = new SignedPayloadSigner("GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ", payload); + SignedPayloadSigner signedPayloadSigner = new SignedPayloadSigner(StrKey.decodeStellarAccountId("GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ"), payload); try { StrKey.encodeSignedPayload(signedPayloadSigner); fail("should not encode signed payloads > 64"); } catch (FormatException ignored){} - - payload = BaseEncoding.base16().decode("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f200102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20".toUpperCase()); - signedPayloadSigner = new SignedPayloadSigner("GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KV_notgood", payload); - try { - StrKey.encodeSignedPayload(signedPayloadSigner); - fail("should not encode when accountid is not valid strkey"); - } catch (FormatException ignored){} } @Test From 163b582c5d7c1ba9cb11ff69ca626c517af7c1be Mon Sep 17 00:00:00 2001 From: Shawn Reuland Date: Tue, 22 Mar 2022 11:39:08 -0700 Subject: [PATCH 4/7] #410: maintain backwards compliant Predicate --- src/main/java/org/stellar/sdk/Predicate.java | 21 +++++++++--- .../org/stellar/sdk/SignedPayloadSigner.java | 2 +- .../ClaimableBalancePageDeserializerTest.java | 2 +- .../sdk/responses/EffectDeserializerTest.java | 34 ++++++++++++++++--- .../responses/OperationDeserializerTest.java | 32 +++++++++++++++-- 5 files changed, 77 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/stellar/sdk/Predicate.java b/src/main/java/org/stellar/sdk/Predicate.java index d2cea4591..fe908b4d0 100644 --- a/src/main/java/org/stellar/sdk/Predicate.java +++ b/src/main/java/org/stellar/sdk/Predicate.java @@ -180,6 +180,9 @@ public ClaimPredicate toXdr() { } } + /** + * Represents a predicate based on a maximum date and time. + */ public static class AbsBefore extends Predicate { private final TimePoint timePoint; @@ -187,8 +190,11 @@ public AbsBefore(TimePoint timePoint) { this.timePoint = timePoint; } - public TimePoint getTimestampSeconds() { - return timePoint; + public AbsBefore(long epochSeconds) { + this(new TimePoint(new Uint64(epochSeconds))); + } + public long getTimestampSeconds() { + return timePoint.getTimePoint().getUint64(); } public Instant getDate() { @@ -217,6 +223,9 @@ public ClaimPredicate toXdr() { } } + /** + * Represents predicate based on maximum length of time + */ public static class RelBefore extends Predicate { private final Duration duration; @@ -224,8 +233,12 @@ public RelBefore(Duration secondsSinceClose) { this.duration = secondsSinceClose; } - public Duration getSecondsSinceClose() { - return duration; + public RelBefore(long secondsSinceClose) { + this(new Duration(new Int64(secondsSinceClose))); + } + + public long getSecondsSinceClose() { + return duration.getDuration().getInt64(); } @Override diff --git a/src/main/java/org/stellar/sdk/SignedPayloadSigner.java b/src/main/java/org/stellar/sdk/SignedPayloadSigner.java index 1564fe9e6..ea23dd173 100644 --- a/src/main/java/org/stellar/sdk/SignedPayloadSigner.java +++ b/src/main/java/org/stellar/sdk/SignedPayloadSigner.java @@ -27,7 +27,7 @@ public SignedPayloadSigner(AccountID accountId, byte[] payload) { } /** - * construcxtor + * constructor * * @param ed25519PublicKey raw bytes of a ED25519 public key * @param payload the raw payload for a signed payload diff --git a/src/test/java/org/stellar/sdk/responses/ClaimableBalancePageDeserializerTest.java b/src/test/java/org/stellar/sdk/responses/ClaimableBalancePageDeserializerTest.java index 01bd459ed..b7b054ae8 100644 --- a/src/test/java/org/stellar/sdk/responses/ClaimableBalancePageDeserializerTest.java +++ b/src/test/java/org/stellar/sdk/responses/ClaimableBalancePageDeserializerTest.java @@ -34,7 +34,7 @@ public void testDeserialize() { Predicate.AbsBefore absBefore = (Predicate.AbsBefore)or.getInner().get(0); Predicate.RelBefore relBefore = (Predicate.RelBefore)or.getInner().get(1); assertEquals(absBefore.getDate().toString(), "2020-09-28T17:57:04Z"); - assertEquals(relBefore.getSecondsSinceClose().getDuration().getInt64().longValue(), 12L); + assertEquals(relBefore.getSecondsSinceClose(), 12L); assertEquals(claimableBalancePage.getRecords().get(1).getId(), "00000000ae76f49e8513d0922b6bcbc8a3f5c4c0a5161871f27924e08724646acab56cd3"); assertEquals(claimableBalancePage.getRecords().get(1).getAsset(), Asset.create("native")); diff --git a/src/test/java/org/stellar/sdk/responses/EffectDeserializerTest.java b/src/test/java/org/stellar/sdk/responses/EffectDeserializerTest.java index 28db4fceb..c9bc17c76 100644 --- a/src/test/java/org/stellar/sdk/responses/EffectDeserializerTest.java +++ b/src/test/java/org/stellar/sdk/responses/EffectDeserializerTest.java @@ -1,13 +1,37 @@ package org.stellar.sdk.responses; import junit.framework.TestCase; - import org.junit.Test; -import org.stellar.sdk.Asset; import org.stellar.sdk.AssetAmount; import org.stellar.sdk.AssetTypeNative; import org.stellar.sdk.Predicate; -import org.stellar.sdk.responses.effects.*; +import org.stellar.sdk.responses.effects.AccountCreatedEffectResponse; +import org.stellar.sdk.responses.effects.AccountCreditedEffectResponse; +import org.stellar.sdk.responses.effects.AccountDebitedEffectResponse; +import org.stellar.sdk.responses.effects.AccountFlagsUpdatedEffectResponse; +import org.stellar.sdk.responses.effects.AccountHomeDomainUpdatedEffectResponse; +import org.stellar.sdk.responses.effects.AccountInflationDestinationUpdatedEffectResponse; +import org.stellar.sdk.responses.effects.AccountRemovedEffectResponse; +import org.stellar.sdk.responses.effects.AccountThresholdsUpdatedEffectResponse; +import org.stellar.sdk.responses.effects.ClaimableBalanceClaimantCreatedEffectResponse; +import org.stellar.sdk.responses.effects.ClaimableBalanceClawedBackEffectResponse; +import org.stellar.sdk.responses.effects.DataCreatedEffectResponse; +import org.stellar.sdk.responses.effects.DataRemovedEffectResponse; +import org.stellar.sdk.responses.effects.DataUpdatedEffectResponse; +import org.stellar.sdk.responses.effects.EffectResponse; +import org.stellar.sdk.responses.effects.LiquidityPoolTradeEffectResponse; +import org.stellar.sdk.responses.effects.SequenceBumpedEffectResponse; +import org.stellar.sdk.responses.effects.SignerCreatedEffectResponse; +import org.stellar.sdk.responses.effects.SignerRemovedEffectResponse; +import org.stellar.sdk.responses.effects.SignerUpdatedEffectResponse; +import org.stellar.sdk.responses.effects.TradeEffectResponse; +import org.stellar.sdk.responses.effects.TrustlineAuthorizedEffectResponse; +import org.stellar.sdk.responses.effects.TrustlineAuthorizedToMaintainLiabilitiesEffectResponse; +import org.stellar.sdk.responses.effects.TrustlineCreatedEffectResponse; +import org.stellar.sdk.responses.effects.TrustlineDeauthorizedEffectResponse; +import org.stellar.sdk.responses.effects.TrustlineFlagsUpdatedEffectResponse; +import org.stellar.sdk.responses.effects.TrustlineRemovedEffectResponse; +import org.stellar.sdk.responses.effects.TrustlineUpdatedEffectResponse; import org.stellar.sdk.xdr.LiquidityPoolType; import java.util.Arrays; @@ -284,7 +308,7 @@ public void testDeserializeClaimableBalanceClaimantCreatedEffect() { assertEquals(effect.getBalanceId(), "0000000071d3336fa6b6cf81fcbeda85a503ccfabc786ab1066594716f3f9551ea4b89ca"); assertEquals(effect.getType(), "claimable_balance_claimant_created"); assertSame(effect.getPredicate().getClass(), Predicate.AbsBefore.class); - assertEquals(((Predicate.AbsBefore)effect.getPredicate()).getTimestampSeconds().getTimePoint().getUint64().longValue(), 1234567890982222222L); + assertEquals(((Predicate.AbsBefore)effect.getPredicate()).getTimestampSeconds(), 1234567890982222222L); } @Test @@ -322,7 +346,7 @@ public void testBackwardsCompatAbsBeforeEpoch() { assertEquals(effect.getBalanceId(), "0000000071d3336fa6b6cf81fcbeda85a503ccfabc786ab1066594716f3f9551ea4b89ca"); assertEquals(effect.getType(), "claimable_balance_claimant_created"); assertSame(effect.getPredicate().getClass(), Predicate.AbsBefore.class); - assertEquals(((Predicate.AbsBefore)effect.getPredicate()).getTimestampSeconds().getTimePoint().getUint64().longValue(), 1637479450L); + assertEquals(((Predicate.AbsBefore)effect.getPredicate()).getTimestampSeconds(), 1637479450L); } @Test diff --git a/src/test/java/org/stellar/sdk/responses/OperationDeserializerTest.java b/src/test/java/org/stellar/sdk/responses/OperationDeserializerTest.java index 25a8bece7..9ee801760 100644 --- a/src/test/java/org/stellar/sdk/responses/OperationDeserializerTest.java +++ b/src/test/java/org/stellar/sdk/responses/OperationDeserializerTest.java @@ -4,8 +4,34 @@ import com.google.common.collect.Lists; import junit.framework.TestCase; import org.junit.Test; -import org.stellar.sdk.*; -import org.stellar.sdk.responses.operations.*; +import org.stellar.sdk.Asset; +import org.stellar.sdk.AssetAmount; +import org.stellar.sdk.AssetTypeNative; +import org.stellar.sdk.AssetTypePoolShare; +import org.stellar.sdk.FormatException; +import org.stellar.sdk.Predicate; +import org.stellar.sdk.Price; +import org.stellar.sdk.responses.operations.AccountMergeOperationResponse; +import org.stellar.sdk.responses.operations.AllowTrustOperationResponse; +import org.stellar.sdk.responses.operations.BumpSequenceOperationResponse; +import org.stellar.sdk.responses.operations.ChangeTrustOperationResponse; +import org.stellar.sdk.responses.operations.ClaimClaimableBalanceOperationResponse; +import org.stellar.sdk.responses.operations.ClawbackClaimableBalanceOperationResponse; +import org.stellar.sdk.responses.operations.ClawbackOperationResponse; +import org.stellar.sdk.responses.operations.CreateAccountOperationResponse; +import org.stellar.sdk.responses.operations.CreateClaimableBalanceOperationResponse; +import org.stellar.sdk.responses.operations.EndSponsoringFutureReservesOperationResponse; +import org.stellar.sdk.responses.operations.InflationOperationResponse; +import org.stellar.sdk.responses.operations.LiquidityPoolDepositOperationResponse; +import org.stellar.sdk.responses.operations.LiquidityPoolWithdrawOperationResponse; +import org.stellar.sdk.responses.operations.ManageBuyOfferOperationResponse; +import org.stellar.sdk.responses.operations.ManageDataOperationResponse; +import org.stellar.sdk.responses.operations.OperationResponse; +import org.stellar.sdk.responses.operations.PathPaymentStrictReceiveOperationResponse; +import org.stellar.sdk.responses.operations.PathPaymentStrictSendOperationResponse; +import org.stellar.sdk.responses.operations.PaymentOperationResponse; +import org.stellar.sdk.responses.operations.SetOptionsOperationResponse; +import org.stellar.sdk.responses.operations.SetTrustLineFlagsOperationResponse; import java.math.BigInteger; import java.util.Arrays; @@ -1567,7 +1593,7 @@ public void testDeserializeCreateClaimableBalanceOperation() { assertEquals(operation.getClaimants().size(), 2); assertEquals(operation.getClaimants().get(0).getDestination(), "GBQECQVAS2FJ7DLCUXDASZAJQLWPXNTCR2DGBPKQDO3QS66TJXLRHFIK"); assertSame(operation.getClaimants().get(0).getPredicate().getClass(), Predicate.AbsBefore.class); - assertEquals(((Predicate.AbsBefore)operation.getClaimants().get(0).getPredicate()).getTimestampSeconds().getTimePoint().getUint64().longValue(), 1234567890982222222L); + assertEquals(((Predicate.AbsBefore)operation.getClaimants().get(0).getPredicate()).getTimestampSeconds(), 1234567890982222222L); assertEquals(operation.getClaimants().get(1).getDestination(), "GAKFBRS24U3PEN6XDMEX4JEV5NGBARS2ZFF5O4CF3JL464SQSD4MDCPF"); assertSame(operation.getClaimants().get(1).getPredicate().getClass(), Predicate.Unconditional.class); assertEquals(operation.getType(), "create_claimable_balance"); From 1717767a293a462658c29f5f006d9511523ef3d3 Mon Sep 17 00:00:00 2001 From: Shawn Reuland Date: Wed, 23 Mar 2022 10:42:57 -0700 Subject: [PATCH 5/7] #410: renamed parameter to 'signer' per feedback on pr --- .../org/stellar/sdk/SignedPayloadSigner.java | 18 +++++++++--------- src/main/java/org/stellar/sdk/Signer.java | 4 ++-- src/main/java/org/stellar/sdk/StrKey.java | 4 ++-- .../stellar/sdk/SetOptionsOperationTest.java | 2 +- src/test/java/org/stellar/sdk/SignerTest.java | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/stellar/sdk/SignedPayloadSigner.java b/src/main/java/org/stellar/sdk/SignedPayloadSigner.java index ea23dd173..a629f1544 100644 --- a/src/main/java/org/stellar/sdk/SignedPayloadSigner.java +++ b/src/main/java/org/stellar/sdk/SignedPayloadSigner.java @@ -12,39 +12,39 @@ * Data model for the signed payload signer */ public class SignedPayloadSigner { - private AccountID accountId; + private AccountID signerAccountId; private byte[] payload; /** * constructor * - * @param accountId - the xdr AccountID + * @param signerAccountId - the xdr AccountID * @param payload - the raw payload for a signed payload */ - public SignedPayloadSigner(AccountID accountId, byte[] payload) { - this.accountId = checkNotNull(accountId); + public SignedPayloadSigner(AccountID signerAccountId, byte[] payload) { + this.signerAccountId = checkNotNull(signerAccountId); this.payload = checkNotNull(payload); } /** * constructor * - * @param ed25519PublicKey raw bytes of a ED25519 public key + * @param signerED25519PublicKey raw bytes of a ED25519 public key for the signer account * @param payload the raw payload for a signed payload */ - public SignedPayloadSigner(byte[] ed25519PublicKey, byte[] payload ) { + public SignedPayloadSigner(byte[] signerED25519PublicKey, byte[] payload ) { this(new AccountID( new PublicKey.Builder() .discriminant(PublicKeyType.PUBLIC_KEY_TYPE_ED25519) - .ed25519(new Uint256(ed25519PublicKey)).build()), payload); + .ed25519(new Uint256(signerED25519PublicKey)).build()), payload); } /** * get the account that represents the signed payload signer * @return stellar account */ - public AccountID getAccountId() { - return accountId; + public AccountID getSignerAccountId() { + return signerAccountId; } /** diff --git a/src/main/java/org/stellar/sdk/Signer.java b/src/main/java/org/stellar/sdk/Signer.java index 50b1501e7..3966730bb 100644 --- a/src/main/java/org/stellar/sdk/Signer.java +++ b/src/main/java/org/stellar/sdk/Signer.java @@ -82,13 +82,13 @@ public static SignerKey preAuthTx(byte[] hash) { * @return org.stellar.sdk.xdr.SignerKey */ public static SignerKey signedPayload(SignedPayloadSigner signedPayloadSigner) { - checkNotNull(signedPayloadSigner.getAccountId(), "accountId cannot be null"); + checkNotNull(signedPayloadSigner.getSignerAccountId(), "accountId cannot be null"); checkArgument(signedPayloadSigner.getPayload().length <= SIGNED_PAYLOAD_MAX_PAYLOAD_LENGTH ); SignerKey signerKey = new SignerKey(); SignerKey.SignerKeyEd25519SignedPayload payloadSigner = new SignerKey.SignerKeyEd25519SignedPayload(); payloadSigner.setPayload(signedPayloadSigner.getPayload()); - payloadSigner.setEd25519(signedPayloadSigner.getAccountId().getAccountID().getEd25519()); + payloadSigner.setEd25519(signedPayloadSigner.getSignerAccountId().getAccountID().getEd25519()); signerKey.setDiscriminant(SignerKeyType.SIGNER_KEY_TYPE_ED25519_SIGNED_PAYLOAD); signerKey.setEd25519SignedPayload(payloadSigner); diff --git a/src/main/java/org/stellar/sdk/StrKey.java b/src/main/java/org/stellar/sdk/StrKey.java index 298909f4d..688556385 100644 --- a/src/main/java/org/stellar/sdk/StrKey.java +++ b/src/main/java/org/stellar/sdk/StrKey.java @@ -69,13 +69,13 @@ public static String encodeSignedPayload(SignedPayloadSigner signedPayloadSigner if (signedPayloadSigner.getPayload().length > SIGNED_PAYLOAD_MAX_PAYLOAD_LENGTH) { throw new FormatException("invalid payload length, must be less than " + SIGNED_PAYLOAD_MAX_PAYLOAD_LENGTH); } - if (!signedPayloadSigner.getAccountId().getAccountID().getDiscriminant().equals(PublicKeyType.PUBLIC_KEY_TYPE_ED25519)) { + if (!signedPayloadSigner.getSignerAccountId().getAccountID().getDiscriminant().equals(PublicKeyType.PUBLIC_KEY_TYPE_ED25519)) { throw new FormatException("invalid payload signer, only ED25519 public key accounts are supported currently"); } try { SignerKey.SignerKeyEd25519SignedPayload xdrPayloadSigner = new SignerKey.SignerKeyEd25519SignedPayload(); xdrPayloadSigner.setPayload(signedPayloadSigner.getPayload()); - xdrPayloadSigner.setEd25519(signedPayloadSigner.getAccountId().getAccountID().getEd25519()); + xdrPayloadSigner.setEd25519(signedPayloadSigner.getSignerAccountId().getAccountID().getEd25519()); ByteArrayOutputStream record = new ByteArrayOutputStream(); xdrPayloadSigner.encode(new XdrDataOutputStream(record)); diff --git a/src/test/java/org/stellar/sdk/SetOptionsOperationTest.java b/src/test/java/org/stellar/sdk/SetOptionsOperationTest.java index 23c072316..13d0a20b7 100644 --- a/src/test/java/org/stellar/sdk/SetOptionsOperationTest.java +++ b/src/test/java/org/stellar/sdk/SetOptionsOperationTest.java @@ -29,7 +29,7 @@ public void testPaylodSignerKey() { // verify round trip between xdr and pojo assertEquals(source.getAccountId(), parsedOperation.getSourceAccount()); - assertEquals(signedPayloadSigner.getAccountId().getAccountID().getEd25519(), parsedOperation.getSigner().getEd25519SignedPayload().getEd25519()); + assertEquals(signedPayloadSigner.getSignerAccountId().getAccountID().getEd25519(), parsedOperation.getSigner().getEd25519SignedPayload().getEd25519()); assertArrayEquals(signedPayloadSigner.getPayload(), parsedOperation.getSigner().getEd25519SignedPayload().getPayload()); // verify serialized xdr emitted with signed payload diff --git a/src/test/java/org/stellar/sdk/SignerTest.java b/src/test/java/org/stellar/sdk/SignerTest.java index e0d755091..0fca163dd 100644 --- a/src/test/java/org/stellar/sdk/SignerTest.java +++ b/src/test/java/org/stellar/sdk/SignerTest.java @@ -19,7 +19,7 @@ public void itCreatesSignedPayloadSigner() { SignerKey signerKey = Signer.signedPayload(signedPayloadSigner); assertArrayEquals(signerKey.getEd25519SignedPayload().getPayload(), payload); - assertEquals(signerKey.getEd25519SignedPayload().getEd25519(),signedPayloadSigner.getAccountId().getAccountID().getEd25519()); + assertEquals(signerKey.getEd25519SignedPayload().getEd25519(),signedPayloadSigner.getSignerAccountId().getAccountID().getEd25519()); } @Test From 49b477d5c24682dbe3dfa52fed0f9882a3c38d36 Mon Sep 17 00:00:00 2001 From: Shawn Reuland Date: Wed, 23 Mar 2022 11:03:04 -0700 Subject: [PATCH 6/7] #410: regenerated all xdr from latest .x source on p19 branch --- .../sdk/xdr/AccountEntryExtensionV2.java | 4 +- .../sdk/xdr/AccountEntryExtensionV3.java | 4 +- src/main/java/org/stellar/sdk/xdr/Asset.java | 4 +- .../org/stellar/sdk/xdr/ClaimPredicate.java | 4 +- .../stellar/sdk/xdr/ClaimableBalanceID.java | 4 +- .../java/org/stellar/sdk/xdr/Duration.java | 4 +- .../org/stellar/sdk/xdr/ExtensionPoint.java | 4 +- .../org/stellar/sdk/xdr/HashIDPreimage.java | 4 +- .../org/stellar/sdk/xdr/LedgerBounds.java | 4 +- .../sdk/xdr/LedgerHeaderExtensionV1.java | 4 +- .../java/org/stellar/sdk/xdr/MessageType.java | 6 +- .../org/stellar/sdk/xdr/Preconditions.java | 4 +- .../org/stellar/sdk/xdr/PreconditionsV2.java | 4 +- .../java/org/stellar/sdk/xdr/SendMore.java | 67 +++++++++++++++++++ .../java/org/stellar/sdk/xdr/SignerKey.java | 4 +- .../org/stellar/sdk/xdr/StellarMessage.java | 26 ++++++- .../org/stellar/sdk/xdr/StellarValue.java | 4 +- .../java/org/stellar/sdk/xdr/Transaction.java | 4 +- .../org/stellar/sdk/xdr/TrustLineEntry.java | 4 +- xdr/Stellar-overlay.x | 11 ++- 20 files changed, 138 insertions(+), 36 deletions(-) create mode 100644 src/main/java/org/stellar/sdk/xdr/SendMore.java diff --git a/src/main/java/org/stellar/sdk/xdr/AccountEntryExtensionV2.java b/src/main/java/org/stellar/sdk/xdr/AccountEntryExtensionV2.java index 1911d96f5..54ae3dc9f 100644 --- a/src/main/java/org/stellar/sdk/xdr/AccountEntryExtensionV2.java +++ b/src/main/java/org/stellar/sdk/xdr/AccountEntryExtensionV2.java @@ -4,9 +4,9 @@ package org.stellar.sdk.xdr; -import com.google.common.base.Objects; - import java.io.IOException; + +import com.google.common.base.Objects; import java.util.Arrays; // === xdr source ============================================================ diff --git a/src/main/java/org/stellar/sdk/xdr/AccountEntryExtensionV3.java b/src/main/java/org/stellar/sdk/xdr/AccountEntryExtensionV3.java index a63b1dee5..44a0890d0 100644 --- a/src/main/java/org/stellar/sdk/xdr/AccountEntryExtensionV3.java +++ b/src/main/java/org/stellar/sdk/xdr/AccountEntryExtensionV3.java @@ -4,10 +4,10 @@ package org.stellar.sdk.xdr; -import com.google.common.base.Objects; - import java.io.IOException; +import com.google.common.base.Objects; + // === xdr source ============================================================ // struct AccountEntryExtensionV3 diff --git a/src/main/java/org/stellar/sdk/xdr/Asset.java b/src/main/java/org/stellar/sdk/xdr/Asset.java index 0e9ccc672..542c98471 100644 --- a/src/main/java/org/stellar/sdk/xdr/Asset.java +++ b/src/main/java/org/stellar/sdk/xdr/Asset.java @@ -4,10 +4,10 @@ package org.stellar.sdk.xdr; -import com.google.common.base.Objects; - import java.io.IOException; +import com.google.common.base.Objects; + // === xdr source ============================================================ // union Asset switch (AssetType type) diff --git a/src/main/java/org/stellar/sdk/xdr/ClaimPredicate.java b/src/main/java/org/stellar/sdk/xdr/ClaimPredicate.java index 404b6282d..a200c875a 100644 --- a/src/main/java/org/stellar/sdk/xdr/ClaimPredicate.java +++ b/src/main/java/org/stellar/sdk/xdr/ClaimPredicate.java @@ -4,9 +4,9 @@ package org.stellar.sdk.xdr; -import com.google.common.base.Objects; - import java.io.IOException; + +import com.google.common.base.Objects; import java.util.Arrays; // === xdr source ============================================================ diff --git a/src/main/java/org/stellar/sdk/xdr/ClaimableBalanceID.java b/src/main/java/org/stellar/sdk/xdr/ClaimableBalanceID.java index c75a39d1e..b3e261ef2 100644 --- a/src/main/java/org/stellar/sdk/xdr/ClaimableBalanceID.java +++ b/src/main/java/org/stellar/sdk/xdr/ClaimableBalanceID.java @@ -4,10 +4,10 @@ package org.stellar.sdk.xdr; -import com.google.common.base.Objects; - import java.io.IOException; +import com.google.common.base.Objects; + // === xdr source ============================================================ // union ClaimableBalanceID switch (ClaimableBalanceIDType type) diff --git a/src/main/java/org/stellar/sdk/xdr/Duration.java b/src/main/java/org/stellar/sdk/xdr/Duration.java index 56507997c..9a467a8c9 100644 --- a/src/main/java/org/stellar/sdk/xdr/Duration.java +++ b/src/main/java/org/stellar/sdk/xdr/Duration.java @@ -4,10 +4,10 @@ package org.stellar.sdk.xdr; -import com.google.common.base.Objects; - import java.io.IOException; +import com.google.common.base.Objects; + // === xdr source ============================================================ // typedef int64 Duration; diff --git a/src/main/java/org/stellar/sdk/xdr/ExtensionPoint.java b/src/main/java/org/stellar/sdk/xdr/ExtensionPoint.java index fb785dc66..fb017c313 100644 --- a/src/main/java/org/stellar/sdk/xdr/ExtensionPoint.java +++ b/src/main/java/org/stellar/sdk/xdr/ExtensionPoint.java @@ -4,10 +4,10 @@ package org.stellar.sdk.xdr; -import com.google.common.base.Objects; - import java.io.IOException; +import com.google.common.base.Objects; + // === xdr source ============================================================ // union ExtensionPoint switch (int v) { diff --git a/src/main/java/org/stellar/sdk/xdr/HashIDPreimage.java b/src/main/java/org/stellar/sdk/xdr/HashIDPreimage.java index 559d9a584..bb659ebe4 100644 --- a/src/main/java/org/stellar/sdk/xdr/HashIDPreimage.java +++ b/src/main/java/org/stellar/sdk/xdr/HashIDPreimage.java @@ -4,10 +4,10 @@ package org.stellar.sdk.xdr; -import com.google.common.base.Objects; - import java.io.IOException; +import com.google.common.base.Objects; + // === xdr source ============================================================ // union HashIDPreimage switch (EnvelopeType type) diff --git a/src/main/java/org/stellar/sdk/xdr/LedgerBounds.java b/src/main/java/org/stellar/sdk/xdr/LedgerBounds.java index c55bb91ad..3a71b51eb 100644 --- a/src/main/java/org/stellar/sdk/xdr/LedgerBounds.java +++ b/src/main/java/org/stellar/sdk/xdr/LedgerBounds.java @@ -4,10 +4,10 @@ package org.stellar.sdk.xdr; -import com.google.common.base.Objects; - import java.io.IOException; +import com.google.common.base.Objects; + // === xdr source ============================================================ // struct LedgerBounds diff --git a/src/main/java/org/stellar/sdk/xdr/LedgerHeaderExtensionV1.java b/src/main/java/org/stellar/sdk/xdr/LedgerHeaderExtensionV1.java index 6be2aaa41..33cd29320 100644 --- a/src/main/java/org/stellar/sdk/xdr/LedgerHeaderExtensionV1.java +++ b/src/main/java/org/stellar/sdk/xdr/LedgerHeaderExtensionV1.java @@ -4,10 +4,10 @@ package org.stellar.sdk.xdr; -import com.google.common.base.Objects; - import java.io.IOException; +import com.google.common.base.Objects; + // === xdr source ============================================================ // struct LedgerHeaderExtensionV1 diff --git a/src/main/java/org/stellar/sdk/xdr/MessageType.java b/src/main/java/org/stellar/sdk/xdr/MessageType.java index c0278ebed..dfd269193 100644 --- a/src/main/java/org/stellar/sdk/xdr/MessageType.java +++ b/src/main/java/org/stellar/sdk/xdr/MessageType.java @@ -33,7 +33,9 @@ // HELLO = 13, // // SURVEY_REQUEST = 14, -// SURVEY_RESPONSE = 15 +// SURVEY_RESPONSE = 15, +// +// SEND_MORE = 16 // }; // =========================================================================== @@ -53,6 +55,7 @@ public enum MessageType implements XdrElement { HELLO(13), SURVEY_REQUEST(14), SURVEY_RESPONSE(15), + SEND_MORE(16), ; private int mValue; @@ -82,6 +85,7 @@ public static MessageType decode(XdrDataInputStream stream) throws IOException { case 13: return HELLO; case 14: return SURVEY_REQUEST; case 15: return SURVEY_RESPONSE; + case 16: return SEND_MORE; default: throw new RuntimeException("Unknown enum value: " + value); } diff --git a/src/main/java/org/stellar/sdk/xdr/Preconditions.java b/src/main/java/org/stellar/sdk/xdr/Preconditions.java index 7eb39c140..88e91a80e 100644 --- a/src/main/java/org/stellar/sdk/xdr/Preconditions.java +++ b/src/main/java/org/stellar/sdk/xdr/Preconditions.java @@ -4,10 +4,10 @@ package org.stellar.sdk.xdr; -import com.google.common.base.Objects; - import java.io.IOException; +import com.google.common.base.Objects; + // === xdr source ============================================================ // union Preconditions switch (PreconditionType type) { diff --git a/src/main/java/org/stellar/sdk/xdr/PreconditionsV2.java b/src/main/java/org/stellar/sdk/xdr/PreconditionsV2.java index dc098c1d4..d68b48064 100644 --- a/src/main/java/org/stellar/sdk/xdr/PreconditionsV2.java +++ b/src/main/java/org/stellar/sdk/xdr/PreconditionsV2.java @@ -4,9 +4,9 @@ package org.stellar.sdk.xdr; -import com.google.common.base.Objects; - import java.io.IOException; + +import com.google.common.base.Objects; import java.util.Arrays; // === xdr source ============================================================ diff --git a/src/main/java/org/stellar/sdk/xdr/SendMore.java b/src/main/java/org/stellar/sdk/xdr/SendMore.java new file mode 100644 index 000000000..72b2cc9e7 --- /dev/null +++ b/src/main/java/org/stellar/sdk/xdr/SendMore.java @@ -0,0 +1,67 @@ +// Automatically generated by xdrgen +// DO NOT EDIT or your changes may be overwritten + +package org.stellar.sdk.xdr; + + +import java.io.IOException; + +import com.google.common.base.Objects; + +// === xdr source ============================================================ + +// struct SendMore +// { +// uint32 numMessages; +// }; + +// =========================================================================== +public class SendMore implements XdrElement { + public SendMore () {} + private Uint32 numMessages; + public Uint32 getNumMessages() { + return this.numMessages; + } + public void setNumMessages(Uint32 value) { + this.numMessages = value; + } + public static void encode(XdrDataOutputStream stream, SendMore encodedSendMore) throws IOException{ + Uint32.encode(stream, encodedSendMore.numMessages); + } + public void encode(XdrDataOutputStream stream) throws IOException { + encode(stream, this); + } + public static SendMore decode(XdrDataInputStream stream) throws IOException { + SendMore decodedSendMore = new SendMore(); + decodedSendMore.numMessages = Uint32.decode(stream); + return decodedSendMore; + } + @Override + public int hashCode() { + return Objects.hashCode(this.numMessages); + } + @Override + public boolean equals(Object object) { + if (!(object instanceof SendMore)) { + return false; + } + + SendMore other = (SendMore) object; + return Objects.equal(this.numMessages, other.numMessages); + } + + public static final class Builder { + private Uint32 numMessages; + + public Builder numMessages(Uint32 numMessages) { + this.numMessages = numMessages; + return this; + } + + public SendMore build() { + SendMore val = new SendMore(); + val.setNumMessages(numMessages); + return val; + } + } +} diff --git a/src/main/java/org/stellar/sdk/xdr/SignerKey.java b/src/main/java/org/stellar/sdk/xdr/SignerKey.java index 303c661ae..a6aea4d82 100644 --- a/src/main/java/org/stellar/sdk/xdr/SignerKey.java +++ b/src/main/java/org/stellar/sdk/xdr/SignerKey.java @@ -4,9 +4,9 @@ package org.stellar.sdk.xdr; -import com.google.common.base.Objects; - import java.io.IOException; + +import com.google.common.base.Objects; import java.util.Arrays; // === xdr source ============================================================ diff --git a/src/main/java/org/stellar/sdk/xdr/StellarMessage.java b/src/main/java/org/stellar/sdk/xdr/StellarMessage.java index 0048adb27..8ac2536ca 100644 --- a/src/main/java/org/stellar/sdk/xdr/StellarMessage.java +++ b/src/main/java/org/stellar/sdk/xdr/StellarMessage.java @@ -49,6 +49,8 @@ // SCPEnvelope envelope; // case GET_SCP_STATE: // uint32 getSCPLedgerSeq; // ledger seq requested ; if 0, requests the latest +// case SEND_MORE: +// SendMore sendMoreMessage; // }; // =========================================================================== @@ -159,6 +161,13 @@ public Uint32 getGetSCPLedgerSeq() { public void setGetSCPLedgerSeq(Uint32 value) { this.getSCPLedgerSeq = value; } + private SendMore sendMoreMessage; + public SendMore getSendMoreMessage() { + return this.sendMoreMessage; + } + public void setSendMoreMessage(SendMore value) { + this.sendMoreMessage = value; + } public static final class Builder { private MessageType discriminant; @@ -176,6 +185,7 @@ public static final class Builder { private SCPQuorumSet qSet; private SCPEnvelope envelope; private Uint32 getSCPLedgerSeq; + private SendMore sendMoreMessage; public Builder discriminant(MessageType discriminant) { this.discriminant = discriminant; @@ -252,6 +262,11 @@ public Builder getSCPLedgerSeq(Uint32 getSCPLedgerSeq) { return this; } + public Builder sendMoreMessage(SendMore sendMoreMessage) { + this.sendMoreMessage = sendMoreMessage; + return this; + } + public StellarMessage build() { StellarMessage val = new StellarMessage(); val.setDiscriminant(discriminant); @@ -269,6 +284,7 @@ public StellarMessage build() { val.setQSet(qSet); val.setEnvelope(envelope); val.setGetSCPLedgerSeq(getSCPLedgerSeq); + val.setSendMoreMessage(sendMoreMessage); return val; } } @@ -326,6 +342,9 @@ public static void encode(XdrDataOutputStream stream, StellarMessage encodedStel case GET_SCP_STATE: Uint32.encode(stream, encodedStellarMessage.getSCPLedgerSeq); break; + case SEND_MORE: + SendMore.encode(stream, encodedStellarMessage.sendMoreMessage); + break; } } public void encode(XdrDataOutputStream stream) throws IOException { @@ -384,12 +403,15 @@ public static StellarMessage decode(XdrDataInputStream stream) throws IOExceptio case GET_SCP_STATE: decodedStellarMessage.getSCPLedgerSeq = Uint32.decode(stream); break; + case SEND_MORE: + decodedStellarMessage.sendMoreMessage = SendMore.decode(stream); + break; } return decodedStellarMessage; } @Override public int hashCode() { - return Objects.hashCode(this.error, this.hello, this.auth, this.dontHave, Arrays.hashCode(this.peers), this.txSetHash, this.txSet, this.transaction, this.signedSurveyRequestMessage, this.signedSurveyResponseMessage, this.qSetHash, this.qSet, this.envelope, this.getSCPLedgerSeq, this.type); + return Objects.hashCode(this.error, this.hello, this.auth, this.dontHave, Arrays.hashCode(this.peers), this.txSetHash, this.txSet, this.transaction, this.signedSurveyRequestMessage, this.signedSurveyResponseMessage, this.qSetHash, this.qSet, this.envelope, this.getSCPLedgerSeq, this.sendMoreMessage, this.type); } @Override public boolean equals(Object object) { @@ -398,6 +420,6 @@ public boolean equals(Object object) { } StellarMessage other = (StellarMessage) object; - return Objects.equal(this.error, other.error) && Objects.equal(this.hello, other.hello) && Objects.equal(this.auth, other.auth) && Objects.equal(this.dontHave, other.dontHave) && Arrays.equals(this.peers, other.peers) && Objects.equal(this.txSetHash, other.txSetHash) && Objects.equal(this.txSet, other.txSet) && Objects.equal(this.transaction, other.transaction) && Objects.equal(this.signedSurveyRequestMessage, other.signedSurveyRequestMessage) && Objects.equal(this.signedSurveyResponseMessage, other.signedSurveyResponseMessage) && Objects.equal(this.qSetHash, other.qSetHash) && Objects.equal(this.qSet, other.qSet) && Objects.equal(this.envelope, other.envelope) && Objects.equal(this.getSCPLedgerSeq, other.getSCPLedgerSeq) && Objects.equal(this.type, other.type); + return Objects.equal(this.error, other.error) && Objects.equal(this.hello, other.hello) && Objects.equal(this.auth, other.auth) && Objects.equal(this.dontHave, other.dontHave) && Arrays.equals(this.peers, other.peers) && Objects.equal(this.txSetHash, other.txSetHash) && Objects.equal(this.txSet, other.txSet) && Objects.equal(this.transaction, other.transaction) && Objects.equal(this.signedSurveyRequestMessage, other.signedSurveyRequestMessage) && Objects.equal(this.signedSurveyResponseMessage, other.signedSurveyResponseMessage) && Objects.equal(this.qSetHash, other.qSetHash) && Objects.equal(this.qSet, other.qSet) && Objects.equal(this.envelope, other.envelope) && Objects.equal(this.getSCPLedgerSeq, other.getSCPLedgerSeq) && Objects.equal(this.sendMoreMessage, other.sendMoreMessage) && Objects.equal(this.type, other.type); } } diff --git a/src/main/java/org/stellar/sdk/xdr/StellarValue.java b/src/main/java/org/stellar/sdk/xdr/StellarValue.java index c841d5903..7fd7f1640 100644 --- a/src/main/java/org/stellar/sdk/xdr/StellarValue.java +++ b/src/main/java/org/stellar/sdk/xdr/StellarValue.java @@ -4,9 +4,9 @@ package org.stellar.sdk.xdr; -import com.google.common.base.Objects; - import java.io.IOException; + +import com.google.common.base.Objects; import java.util.Arrays; // === xdr source ============================================================ diff --git a/src/main/java/org/stellar/sdk/xdr/Transaction.java b/src/main/java/org/stellar/sdk/xdr/Transaction.java index 728be1b57..37b9a7994 100644 --- a/src/main/java/org/stellar/sdk/xdr/Transaction.java +++ b/src/main/java/org/stellar/sdk/xdr/Transaction.java @@ -4,9 +4,9 @@ package org.stellar.sdk.xdr; -import com.google.common.base.Objects; - import java.io.IOException; + +import com.google.common.base.Objects; import java.util.Arrays; // === xdr source ============================================================ diff --git a/src/main/java/org/stellar/sdk/xdr/TrustLineEntry.java b/src/main/java/org/stellar/sdk/xdr/TrustLineEntry.java index 1a0417c29..c22caec9a 100644 --- a/src/main/java/org/stellar/sdk/xdr/TrustLineEntry.java +++ b/src/main/java/org/stellar/sdk/xdr/TrustLineEntry.java @@ -4,10 +4,10 @@ package org.stellar.sdk.xdr; -import com.google.common.base.Objects; - import java.io.IOException; +import com.google.common.base.Objects; + // === xdr source ============================================================ // struct TrustLineEntry diff --git a/xdr/Stellar-overlay.x b/xdr/Stellar-overlay.x index a4ab6b077..9e3a083d3 100644 --- a/xdr/Stellar-overlay.x +++ b/xdr/Stellar-overlay.x @@ -22,6 +22,11 @@ struct Error string msg<100>; }; +struct SendMore +{ + uint32 numMessages; +}; + struct AuthCert { Curve25519Public pubkey; @@ -93,7 +98,9 @@ enum MessageType HELLO = 13, SURVEY_REQUEST = 14, - SURVEY_RESPONSE = 15 + SURVEY_RESPONSE = 15, + + SEND_MORE = 16 }; struct DontHave @@ -214,6 +221,8 @@ case SCP_MESSAGE: SCPEnvelope envelope; case GET_SCP_STATE: uint32 getSCPLedgerSeq; // ledger seq requested ; if 0, requests the latest +case SEND_MORE: + SendMore sendMoreMessage; }; union AuthenticatedMessage switch (uint32 v) From c61a5d531371cdc78bb98acc0cb4755e14bcc3ed Mon Sep 17 00:00:00 2001 From: Shawn Reuland Date: Thu, 24 Mar 2022 14:37:52 -0700 Subject: [PATCH 7/7] #410: consolidate validation of signed payload aspects into SignedPayloadSigner, pr feedback --- .../org/stellar/sdk/SignedPayloadSigner.java | 12 +++++++- src/main/java/org/stellar/sdk/Signer.java | 4 --- src/main/java/org/stellar/sdk/StrKey.java | 8 ------ .../stellar/sdk/SignedPayloadSignerTest.java | 28 +++++++++++++++++++ src/test/java/org/stellar/sdk/SignerTest.java | 14 ---------- src/test/java/org/stellar/sdk/StrKeyTest.java | 10 ------- 6 files changed, 39 insertions(+), 37 deletions(-) diff --git a/src/main/java/org/stellar/sdk/SignedPayloadSigner.java b/src/main/java/org/stellar/sdk/SignedPayloadSigner.java index a629f1544..b5fcc4035 100644 --- a/src/main/java/org/stellar/sdk/SignedPayloadSigner.java +++ b/src/main/java/org/stellar/sdk/SignedPayloadSigner.java @@ -7,11 +7,12 @@ import static com.google.common.base.Preconditions.checkNotNull; - /** * Data model for the signed payload signer */ public class SignedPayloadSigner { + public static final int SIGNED_PAYLOAD_MAX_PAYLOAD_LENGTH = 64; + private AccountID signerAccountId; private byte[] payload; @@ -22,6 +23,15 @@ public class SignedPayloadSigner { * @param payload - the raw payload for a signed payload */ public SignedPayloadSigner(AccountID signerAccountId, byte[] payload) { + checkNotNull(payload, "payload cannot be null"); + checkNotNull(signerAccountId, "accountId cannot be null"); + if (payload.length > SIGNED_PAYLOAD_MAX_PAYLOAD_LENGTH) { + throw new IllegalArgumentException("invalid payload length, must be less than " + SIGNED_PAYLOAD_MAX_PAYLOAD_LENGTH); + } + if (signerAccountId.getAccountID().getDiscriminant() == null || + !signerAccountId.getAccountID().getDiscriminant().equals(PublicKeyType.PUBLIC_KEY_TYPE_ED25519)) { + throw new IllegalArgumentException("invalid payload signer, only ED25519 public key accounts are supported currently"); + } this.signerAccountId = checkNotNull(signerAccountId); this.payload = checkNotNull(payload); } diff --git a/src/main/java/org/stellar/sdk/Signer.java b/src/main/java/org/stellar/sdk/Signer.java index 3966730bb..b5fd69b21 100644 --- a/src/main/java/org/stellar/sdk/Signer.java +++ b/src/main/java/org/stellar/sdk/Signer.java @@ -11,8 +11,6 @@ * Signer is a helper class that creates {@link org.stellar.sdk.xdr.SignerKey} objects. */ public class Signer { - public static final int SIGNED_PAYLOAD_MAX_PAYLOAD_LENGTH = 64; - /** * Create ed25519PublicKey {@link org.stellar.sdk.xdr.SignerKey} from * a {@link org.stellar.sdk.KeyPair} @@ -82,8 +80,6 @@ public static SignerKey preAuthTx(byte[] hash) { * @return org.stellar.sdk.xdr.SignerKey */ public static SignerKey signedPayload(SignedPayloadSigner signedPayloadSigner) { - checkNotNull(signedPayloadSigner.getSignerAccountId(), "accountId cannot be null"); - checkArgument(signedPayloadSigner.getPayload().length <= SIGNED_PAYLOAD_MAX_PAYLOAD_LENGTH ); SignerKey signerKey = new SignerKey(); SignerKey.SignerKeyEd25519SignedPayload payloadSigner = new SignerKey.SignerKeyEd25519SignedPayload(); diff --git a/src/main/java/org/stellar/sdk/StrKey.java b/src/main/java/org/stellar/sdk/StrKey.java index 688556385..0342cac2e 100644 --- a/src/main/java/org/stellar/sdk/StrKey.java +++ b/src/main/java/org/stellar/sdk/StrKey.java @@ -22,8 +22,6 @@ import java.io.OutputStream; import java.util.Arrays; -import static org.stellar.sdk.Signer.SIGNED_PAYLOAD_MAX_PAYLOAD_LENGTH; - class StrKey { public static final int ACCOUNT_ID_ADDRESS_LENGTH = 56; @@ -66,12 +64,6 @@ public static String encodeStellarAccountId(AccountID accountID) { } public static String encodeSignedPayload(SignedPayloadSigner signedPayloadSigner) { - if (signedPayloadSigner.getPayload().length > SIGNED_PAYLOAD_MAX_PAYLOAD_LENGTH) { - throw new FormatException("invalid payload length, must be less than " + SIGNED_PAYLOAD_MAX_PAYLOAD_LENGTH); - } - if (!signedPayloadSigner.getSignerAccountId().getAccountID().getDiscriminant().equals(PublicKeyType.PUBLIC_KEY_TYPE_ED25519)) { - throw new FormatException("invalid payload signer, only ED25519 public key accounts are supported currently"); - } try { SignerKey.SignerKeyEd25519SignedPayload xdrPayloadSigner = new SignerKey.SignerKeyEd25519SignedPayload(); xdrPayloadSigner.setPayload(signedPayloadSigner.getPayload()); diff --git a/src/test/java/org/stellar/sdk/SignedPayloadSignerTest.java b/src/test/java/org/stellar/sdk/SignedPayloadSignerTest.java index 9869b3298..ddb539e67 100644 --- a/src/test/java/org/stellar/sdk/SignedPayloadSignerTest.java +++ b/src/test/java/org/stellar/sdk/SignedPayloadSignerTest.java @@ -1,7 +1,13 @@ package org.stellar.sdk; +import com.google.common.io.BaseEncoding; import org.junit.Test; import org.stellar.sdk.xdr.AccountID; +import org.stellar.sdk.xdr.PublicKey; +import org.stellar.sdk.xdr.PublicKeyType; +import org.stellar.sdk.xdr.Uint256; + +import javax.net.ssl.ExtendedSSLSession; import static org.junit.Assert.fail; @@ -15,4 +21,26 @@ public void itFailsWhenAccoutIDIsNull() { fail("should not create when accountid is null"); } catch (NullPointerException ignored){} } + + @Test + public void itFailsWhenPayloadLengthTooBig() { + String accountStrKey = "GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ"; + byte[] payload = BaseEncoding.base16().decode("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f200102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2001".toUpperCase()); + try { + new SignedPayloadSigner(StrKey.decodeStellarAccountId(accountStrKey), payload); + fail("should not create a payload signer if payload > max length"); + } catch (IllegalArgumentException ignored) {} + + } + + @Test + public void itFailsWhenSignerNotED25519() { + try { + new SignedPayloadSigner(new AccountID( + new PublicKey.Builder() + .ed25519(new Uint256(new byte[]{})).build()), new byte[]{}); + fail("should not create a payload signer if signer wasn't ed25519 type"); + } catch (IllegalArgumentException ignored) {} + + } } diff --git a/src/test/java/org/stellar/sdk/SignerTest.java b/src/test/java/org/stellar/sdk/SignerTest.java index 0fca163dd..d537db128 100644 --- a/src/test/java/org/stellar/sdk/SignerTest.java +++ b/src/test/java/org/stellar/sdk/SignerTest.java @@ -6,7 +6,6 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; public class SignerTest { @@ -21,17 +20,4 @@ public void itCreatesSignedPayloadSigner() { assertArrayEquals(signerKey.getEd25519SignedPayload().getPayload(), payload); assertEquals(signerKey.getEd25519SignedPayload().getEd25519(),signedPayloadSigner.getSignerAccountId().getAccountID().getEd25519()); } - - @Test - public void itFailsWhenInvalidParameters() { - String accountStrKey = "GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ"; - byte[] payload = BaseEncoding.base16().decode("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f200102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2001".toUpperCase()); - SignedPayloadSigner signedPayloadSigner = new SignedPayloadSigner(StrKey.decodeStellarAccountId(accountStrKey), payload); - try { - SignerKey signerKey = Signer.signedPayload(signedPayloadSigner); - fail("should not create a payload signer if payload > max length"); - } catch (IllegalArgumentException ignored) {} - - } - } diff --git a/src/test/java/org/stellar/sdk/StrKeyTest.java b/src/test/java/org/stellar/sdk/StrKeyTest.java index c6a43e352..8c937a2a2 100644 --- a/src/test/java/org/stellar/sdk/StrKeyTest.java +++ b/src/test/java/org/stellar/sdk/StrKeyTest.java @@ -149,16 +149,6 @@ public void testValidSignedPayloadEncode() { assertEquals(encoded, "PA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAOQCAQDAQCQMBYIBEFAWDANBYHRAEISCMKBKFQXDAMRUGY4DUAAAAFGBU"); } - @Test - public void testInvalidSignedPayloadEncode() { - byte[] payload = BaseEncoding.base16().decode("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f200102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2001".toUpperCase()); - SignedPayloadSigner signedPayloadSigner = new SignedPayloadSigner(StrKey.decodeStellarAccountId("GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ"), payload); - try { - StrKey.encodeSignedPayload(signedPayloadSigner); - fail("should not encode signed payloads > 64"); - } catch (FormatException ignored){} - } - @Test public void testRoundTripSignedPayloadVersionByte() { byte[] data = rawBytes(