From 5ee4ef77f206939cff67496f4de77a39de6f5f32 Mon Sep 17 00:00:00 2001 From: "Nelson R. Perez" Date: Mon, 6 Mar 2017 17:04:20 -0500 Subject: [PATCH] Added limit_order_create_operation and implemented its toBytes and toJsonObject serialization, and a test class --- .../de/bitsharesmunich/graphenej/Main.java | 4 +- .../de/bitsharesmunich/graphenej/Test.java | 2 +- .../graphenej/BaseOperation.java | 3 + .../graphenej/TransactionBuilder.java | 26 ------ .../operations/LimitOrderCreateOperation.java | 86 +++++++++++++++++++ .../operations/TransferOperation.java | 2 - .../LimitOrderCreateOperationTest.java | 56 ++++++++++++ 7 files changed, 148 insertions(+), 31 deletions(-) delete mode 100644 graphenej/src/main/java/de/bitsharesmunich/graphenej/TransactionBuilder.java create mode 100644 graphenej/src/main/java/de/bitsharesmunich/graphenej/operations/LimitOrderCreateOperation.java create mode 100644 graphenej/src/test/java/de/bitsharesmunich/graphenej/operations/LimitOrderCreateOperationTest.java diff --git a/app/src/main/java/de/bitsharesmunich/graphenej/Main.java b/app/src/main/java/de/bitsharesmunich/graphenej/Main.java index 75b710f..8fcabf3 100644 --- a/app/src/main/java/de/bitsharesmunich/graphenej/Main.java +++ b/app/src/main/java/de/bitsharesmunich/graphenej/Main.java @@ -50,7 +50,7 @@ public class Main { // e.printStackTrace(); // } // test.testCustomSerializer(); -// test.testUserAccountSerialization(); + test.testUserAccountSerialization(); // test.testTransactionSerialization(); // test.testLoginSerialization(); // test.testNetworkBroadcastSerialization(); @@ -76,7 +76,7 @@ public class Main { // test.testAccountUpdateOperationBroadcast(); // test.testCreateBinFile(); // test.testImportBinFile(); - test.testExportBinFile(); +// test.testExportBinFile(); // test.testLzmaCompression(); // test.testLzmaDecompression(); // test.testSimpleDecompression(); diff --git a/app/src/main/java/de/bitsharesmunich/graphenej/Test.java b/app/src/main/java/de/bitsharesmunich/graphenej/Test.java index 68ffad5..42306e2 100644 --- a/app/src/main/java/de/bitsharesmunich/graphenej/Test.java +++ b/app/src/main/java/de/bitsharesmunich/graphenej/Test.java @@ -221,7 +221,7 @@ public class Test { } public void testUserAccountSerialization() { - UserAccount account = new UserAccount("1.2.138632"); + UserAccount account = new UserAccount("1.2.143563"); System.out.println(Util.bytesToHex(account.toBytes())); } diff --git a/graphenej/src/main/java/de/bitsharesmunich/graphenej/BaseOperation.java b/graphenej/src/main/java/de/bitsharesmunich/graphenej/BaseOperation.java index caf1721..36bdf10 100644 --- a/graphenej/src/main/java/de/bitsharesmunich/graphenej/BaseOperation.java +++ b/graphenej/src/main/java/de/bitsharesmunich/graphenej/BaseOperation.java @@ -8,6 +8,9 @@ import de.bitsharesmunich.graphenej.interfaces.JsonSerializable; */ public abstract class BaseOperation implements ByteSerializable, JsonSerializable { + public static final String KEY_FEE = "fee"; + public static final String KEY_EXTENSIONS = "extensions"; + protected OperationType type; protected Extensions extensions; diff --git a/graphenej/src/main/java/de/bitsharesmunich/graphenej/TransactionBuilder.java b/graphenej/src/main/java/de/bitsharesmunich/graphenej/TransactionBuilder.java deleted file mode 100644 index fecf99e..0000000 --- a/graphenej/src/main/java/de/bitsharesmunich/graphenej/TransactionBuilder.java +++ /dev/null @@ -1,26 +0,0 @@ -package de.bitsharesmunich.graphenej; - -import de.bitsharesmunich.graphenej.errors.MalformedTransactionException; -import org.bitcoinj.core.ECKey; - - -/** - * Created by nelson on 11/14/16. - */ -public abstract class TransactionBuilder { - protected ECKey privateKey; - protected BlockData blockData; - - public TransactionBuilder(){} - - public TransactionBuilder(ECKey privKey){ - this.privateKey = privKey; - } - - public TransactionBuilder setBlockData(BlockData blockData){ - this.blockData = blockData; - return this; - } - - public abstract Transaction build() throws MalformedTransactionException; -} diff --git a/graphenej/src/main/java/de/bitsharesmunich/graphenej/operations/LimitOrderCreateOperation.java b/graphenej/src/main/java/de/bitsharesmunich/graphenej/operations/LimitOrderCreateOperation.java new file mode 100644 index 0000000..a522542 --- /dev/null +++ b/graphenej/src/main/java/de/bitsharesmunich/graphenej/operations/LimitOrderCreateOperation.java @@ -0,0 +1,86 @@ +package de.bitsharesmunich.graphenej.operations; + +import com.google.common.primitives.Bytes; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import de.bitsharesmunich.graphenej.*; + +import java.nio.ByteBuffer; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * Operation used to denote the creation of a limit order on the blockchain. + */ +public class LimitOrderCreateOperation extends BaseOperation { + // Number of bytes used for the expiration field. + private final int EXPIRATION_BYTE_LENGTH = 4; + + // Constants used in the JSON representation + public static final String KEY_SELLER = "seller"; + public static final String KEY_AMOUNT_TO_SELL = "amount_to_sell"; + public static final String KEY_MIN_TO_RECEIVE = "min_to_receive"; + public static final String KEY_EXPIRATION = "expiration"; + public static final String KEY_FILL_OR_KILL = "fill_or_kill"; + + // Inner fields of a limit order + private AssetAmount fee; + private UserAccount seller; + private AssetAmount toSell; + private AssetAmount minToReceive; + private int expiration; + private boolean fillOrKill; + + public LimitOrderCreateOperation(UserAccount seller, AssetAmount toSell, AssetAmount minToReceive, int expiration, boolean fillOrKill){ + super(OperationType.LIMIT_ORDER_CREATE_OPERATION); + this.seller = seller; + this.toSell = toSell; + this.minToReceive = minToReceive; + this.expiration = expiration; + this.fillOrKill = fillOrKill; + } + + @Override + public String toJsonString() { + return null; + } + + @Override + public JsonElement toJsonObject() { + JsonArray array = new JsonArray(); + array.add(this.getId()); + JsonObject jsonObject = new JsonObject(); + if(fee != null) + jsonObject.add(KEY_FEE, fee.toJsonObject()); + jsonObject.addProperty(KEY_SELLER, seller.toJsonString()); + jsonObject.add(KEY_AMOUNT_TO_SELL, toSell.toJsonObject()); + jsonObject.add(KEY_MIN_TO_RECEIVE, minToReceive.toJsonObject()); + + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(Util.TIME_DATE_FORMAT); + jsonObject.addProperty(KEY_EXPIRATION, simpleDateFormat.format(new Date(expiration))); + jsonObject.add(KEY_EXTENSIONS, new JsonArray()); + array.add(jsonObject); + return array; + } + + @Override + public void setFee(AssetAmount assetAmount) { + this.fee = assetAmount; + } + + @Override + public byte[] toBytes() { + byte[] feeBytes = this.fee.toBytes(); + byte[] sellerBytes = this.seller.toBytes(); + byte[] amountBytes = this.toSell.toBytes(); + byte[] minAmountBytes = this.minToReceive.toBytes(); + + ByteBuffer buffer = ByteBuffer.allocate(EXPIRATION_BYTE_LENGTH); + buffer.putInt(this.expiration); + byte[] expirationBytes = Util.revertBytes(buffer.array()); + + byte[] fillOrKill = this.fillOrKill ? new byte[]{ 0x1 } : new byte[]{ 0x0 }; + return Bytes.concat(feeBytes, sellerBytes, amountBytes, minAmountBytes, expirationBytes, fillOrKill); + } +} diff --git a/graphenej/src/main/java/de/bitsharesmunich/graphenej/operations/TransferOperation.java b/graphenej/src/main/java/de/bitsharesmunich/graphenej/operations/TransferOperation.java index 73ddbc9..882c584 100644 --- a/graphenej/src/main/java/de/bitsharesmunich/graphenej/operations/TransferOperation.java +++ b/graphenej/src/main/java/de/bitsharesmunich/graphenej/operations/TransferOperation.java @@ -14,9 +14,7 @@ import java.lang.reflect.Type; * Class used to encapsulate the TransferOperation operation related functionalities. */ public class TransferOperation extends BaseOperation { - public static final String KEY_FEE = "fee"; public static final String KEY_AMOUNT = "amount"; - public static final String KEY_EXTENSIONS = "extensions"; public static final String KEY_FROM = "from"; public static final String KEY_TO = "to"; public static final String KEY_MEMO = "memo"; diff --git a/graphenej/src/test/java/de/bitsharesmunich/graphenej/operations/LimitOrderCreateOperationTest.java b/graphenej/src/test/java/de/bitsharesmunich/graphenej/operations/LimitOrderCreateOperationTest.java new file mode 100644 index 0000000..52fc9cb --- /dev/null +++ b/graphenej/src/test/java/de/bitsharesmunich/graphenej/operations/LimitOrderCreateOperationTest.java @@ -0,0 +1,56 @@ +package de.bitsharesmunich.graphenej.operations; + +import com.google.common.primitives.UnsignedLong; +import de.bitsharesmunich.graphenej.Asset; +import de.bitsharesmunich.graphenej.AssetAmount; +import de.bitsharesmunich.graphenej.UserAccount; +import de.bitsharesmunich.graphenej.Util; +import org.hamcrest.core.IsEqual; +import org.hamcrest.core.IsNot; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Created by nelson on 3/6/17. + */ +public class LimitOrderCreateOperationTest { + private final int AMOUNT_TO_SELL = 25000000; + private final int MIN_TO_RECEIVE = 1; + private final Asset CORE_ASSET = new Asset("1.3.0"); + private final Asset BIT_USD = new Asset("1.3.121"); + private final int DEFAULT_EXPIRATION = 1488831620; // 2017-03-06T20:20:20 + + private UserAccount seller; + private AssetAmount amountToSell; + private AssetAmount minToReceive; + private int expiration; + private boolean fillOrKill; + + @Before + public void setup(){ + seller = new UserAccount("1.2.143563"); + amountToSell = new AssetAmount(UnsignedLong.valueOf(AMOUNT_TO_SELL), CORE_ASSET); + minToReceive = new AssetAmount(UnsignedLong.valueOf(MIN_TO_RECEIVE), BIT_USD); + expiration = DEFAULT_EXPIRATION; + } + + @Test + public void toBytes() throws Exception { + // Testing serialization of operation with fillOrKill parameter == true + LimitOrderCreateOperation operation = new LimitOrderCreateOperation(seller, amountToSell, minToReceive, expiration, true); + operation.setFee(new AssetAmount(UnsignedLong.valueOf(2), CORE_ASSET)); + byte[] serialized = operation.toBytes(); + Assert.assertArrayEquals("Correct serialization", serialized, Util.hexToBytes("020000000000000000cbe10840787d01000000000001000000000000007984c4bd5801")); + Assert.assertThat("Incorrect serialization", serialized, IsNot.not(IsEqual.equalTo("020000000000000000cbe10840787d01000000000001000000000000007984c4bd5800"))); + + // Testing serialization of operation with fillOrKill parameter == false + operation = new LimitOrderCreateOperation(seller, amountToSell, minToReceive, expiration, false); + operation.setFee(new AssetAmount(UnsignedLong.valueOf(2), CORE_ASSET)); + serialized = operation.toBytes(); + Assert.assertArrayEquals("Correct serialization", serialized, Util.hexToBytes("020000000000000000cbe10840787d01000000000001000000000000007984c4bd5800")); + Assert.assertThat("Incorrect serialization", serialized, IsNot.not(IsEqual.equalTo("020000000000000000cbe10840787d01000000000001000000000000007984c4bd5801"))); + } +} \ No newline at end of file