Skip to content

Commit

Permalink
feat: Set network when building a transaction
Browse files Browse the repository at this point in the history
  • Loading branch information
overcat committed May 7, 2019
1 parent 321f5f1 commit dcbcc97
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 13 deletions.
16 changes: 15 additions & 1 deletion src/main/java/org/stellar/sdk/Network.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public String getNetworkPassphrase() {
* Returns network id (SHA-256 hashed <code>networkPassphrase</code>).
*/
public byte[] getNetworkId() {
return Util.hash(current.getNetworkPassphrase().getBytes(Charset.forName("UTF-8")));
return Util.hash(this.getNetworkPassphrase().getBytes(Charset.forName("UTF-8")));
}

/**
Expand Down Expand Up @@ -68,4 +68,18 @@ public static void usePublicNetwork() {
public static void useTestNetwork() {
Network.use(new Network(TESTNET));
}

/**
* Creates a new Network object to represent test network
*/
public static Network testNetwork() {
return new Network(TESTNET);
}

/**
* Creates a new Network object to represent public network
*/
public static Network publicNetwork() {
return new Network(PUBLIC);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
*/
public class NoNetworkSelectedException extends RuntimeException {
public NoNetworkSelectedException() {
super("No network selected. Use `Network.use`, `Network.usePublicNetwork` or `Network.useTestNetwork` helper methods to select network.");
super("No network selected. Use `Network.use`, `Network.usePublicNetwork` or `Network.useTestNetwork` helper methods to select network, you can also use a constructor that includes network options.");
}
}
76 changes: 65 additions & 11 deletions src/main/java/org/stellar/sdk/Transaction.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class Transaction {
private final Operation[] mOperations;
private final Memo mMemo;
private final TimeBounds mTimeBounds;
private Network mNetwork;
private List<DecoratedSignature> mSignatures;

Transaction(KeyPair sourceAccount, int fee, long sequenceNumber, Operation[] operations, Memo memo, TimeBounds timeBounds) {
Expand All @@ -39,7 +40,13 @@ public class Transaction {
mTimeBounds = timeBounds;
}

/**
Transaction(KeyPair sourceAccount, int fee, long sequenceNumber, Operation[] operations, Memo memo, TimeBounds timeBounds, Network network) {
this(sourceAccount, fee, sequenceNumber, operations, memo, timeBounds);

mNetwork = checkNotNull(network, "network cannot be null");
}

/**
* Adds a new signature ed25519PublicKey to this transaction.
* @param signer {@link KeyPair} object representing a signer
*/
Expand Down Expand Up @@ -81,14 +88,22 @@ public byte[] hash() {
* Returns signature base.
*/
public byte[] signatureBase() {
if (Network.current() == null) {
throw new NoNetworkSelectedException();
Network network = null;
if (Network.current() != null) {
network = Network.current();
}
// Networks configured through the constructor have a higher priority.
if (mNetwork != null) {
network = mNetwork;
}
if (network == null) {
throw new NoNetworkSelectedException();
}

try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
// Hashed NetworkID
outputStream.write(Network.current().getNetworkId());
outputStream.write(network.getNetworkId());
// Envelope Type - 4 bytes
outputStream.write(ByteBuffer.allocate(4).putInt(EnvelopeType.ENVELOPE_TYPE_TX.getValue()).array());
// Transaction XDR bytes
Expand Down Expand Up @@ -118,7 +133,6 @@ public List<DecoratedSignature> getSignatures() {
public Memo getMemo() {
return mMemo;
}

/**
* @return TimeBounds, or null (representing no time restrictions)
*/
Expand Down Expand Up @@ -182,11 +196,27 @@ public org.stellar.sdk.xdr.Transaction toXdr() {
* @throws IOException
*/
public static Transaction fromEnvelopeXdr(String envelope) throws IOException {
return fromEnvelopeXdr(envelope, null);
}

/**
* Creates a <code>Transaction</code> instance from previously build <code>TransactionEnvelope</code>
* @param envelope Base-64 encoded <code>TransactionEnvelope</code>
* @return
* @throws IOException
*/
public static Transaction fromEnvelopeXdr(String envelope, Network network) throws IOException {
BaseEncoding base64Encoding = BaseEncoding.base64();
byte[] bytes = base64Encoding.decode(envelope);

TransactionEnvelope transactionEnvelope = TransactionEnvelope.decode(new XdrDataInputStream(new ByteArrayInputStream(bytes)));
return fromEnvelopeXdr(transactionEnvelope);
Transaction transaction;
if (network == null) {
transaction = fromEnvelopeXdr(transactionEnvelope);
} else {
transaction = fromEnvelopeXdr(transactionEnvelope, network);
}
return transaction;
}

/**
Expand All @@ -195,6 +225,15 @@ public static Transaction fromEnvelopeXdr(String envelope) throws IOException {
* @return
*/
public static Transaction fromEnvelopeXdr(TransactionEnvelope envelope) {
return fromEnvelopeXdr(envelope, null);
}

/**
* Creates a <code>Transaction</code> instance from previously build <code>TransactionEnvelope</code>
* @param envelope
* @return
*/
public static Transaction fromEnvelopeXdr(TransactionEnvelope envelope, Network network) {
org.stellar.sdk.xdr.Transaction tx = envelope.getTx();
int mFee = tx.getFee().getUint32();
KeyPair mSourceAccount = KeyPair.fromXdrPublicKey(tx.getSourceAccount().getAccountID());
Expand All @@ -206,11 +245,15 @@ public static Transaction fromEnvelopeXdr(TransactionEnvelope envelope) {
for (int i = 0; i < tx.getOperations().length; i++) {
mOperations[i] = Operation.fromXdr(tx.getOperations()[i]);
}

Transaction transaction = new Transaction(mSourceAccount, mFee, mSequenceNumber, mOperations, mMemo, mTimeBounds);
Transaction transaction;
if (network == null) {
transaction = new Transaction(mSourceAccount, mFee, mSequenceNumber, mOperations, mMemo, mTimeBounds);
} else {
transaction = new Transaction(mSourceAccount, mFee, mSequenceNumber, mOperations, mMemo, mTimeBounds, network);
}

for (DecoratedSignature signature : envelope.getSignatures()) {
transaction.mSignatures.add(signature);
transaction.mSignatures.add(signature);
}

return transaction;
Expand Down Expand Up @@ -259,6 +302,7 @@ public static class Builder {
private boolean timeoutSet;
private static Integer defaultOperationFee;
private Integer operationFee;
private Network mNetwork;

public static final long TIMEOUT_INFINITE = 0;

Expand Down Expand Up @@ -313,7 +357,7 @@ public Builder addMemo(Memo memo) {
mMemo = memo;
return this;
}

/**
* Adds a <a href="https://www.stellar.org/developers/learn/concepts/transactions.html" target="_blank">time-bounds</a> to this transaction.
* @param timeBounds
Expand Down Expand Up @@ -376,6 +420,11 @@ public Builder setOperationFee(int operationFee) {
return this;
}

public Builder setNetwork(Network network) {
this.mNetwork = network;
return this;
}

/**
* Builds a transaction. It will increment sequence number of the source account.
*/
Expand All @@ -392,7 +441,12 @@ public Transaction build() {

Operation[] operations = new Operation[mOperations.size()];
operations = mOperations.toArray(operations);
Transaction transaction = new Transaction(mSourceAccount.getKeypair(), operations.length * operationFee, mSourceAccount.getIncrementedSequenceNumber(), operations, mMemo, mTimeBounds);
Transaction transaction;
if (mNetwork == null) {
transaction = new Transaction(mSourceAccount.getKeypair(), operations.length * operationFee, mSourceAccount.getIncrementedSequenceNumber(), operations, mMemo, mTimeBounds);
} else {
transaction = new Transaction(mSourceAccount.getKeypair(), operations.length * operationFee, mSourceAccount.getIncrementedSequenceNumber(), operations, mMemo, mTimeBounds, mNetwork);
}
// Increment sequence number when there were no exceptions when creating a transaction
mSourceAccount.incrementSequenceNumber();
return transaction;
Expand Down

0 comments on commit dcbcc97

Please sign in to comment.