diff --git a/pom.xml b/pom.xml
index d072f024..14ef3c38 100644
--- a/pom.xml
+++ b/pom.xml
@@ -54,6 +54,7 @@
commons-io
commons-io
2.6
+ test
junit
diff --git a/src/main/java/dev/jlibra/KeyUtils.java b/src/main/java/dev/jlibra/KeyUtils.java
index f448be68..313c5dd8 100644
--- a/src/main/java/dev/jlibra/KeyUtils.java
+++ b/src/main/java/dev/jlibra/KeyUtils.java
@@ -13,9 +13,13 @@
public class KeyUtils {
- public static String toLibraAddress(byte[] publicKeyBytes) {
+ public static String toHexStringLibraAddress(byte[] publicKeyBytes) {
+ return new String(Hex.encode(toByteArrayLibraAddress(publicKeyBytes)));
+ }
+
+ public static byte[] toByteArrayLibraAddress(byte[] publicKeyBytes) {
SHA3.DigestSHA3 digestSHA3 = new SHA3.Digest256();
- return new String(Hex.encode(digestSHA3.digest(stripPublicKeyPrefix(publicKeyBytes))));
+ return digestSHA3.digest(stripPublicKeyPrefix(publicKeyBytes));
}
public static byte[] stripPublicKeyPrefix(byte[] pubKeyBytes) {
diff --git a/src/main/java/dev/jlibra/admissioncontrol/AdmissionControl.java b/src/main/java/dev/jlibra/admissioncontrol/AdmissionControl.java
new file mode 100644
index 00000000..a45ebbca
--- /dev/null
+++ b/src/main/java/dev/jlibra/admissioncontrol/AdmissionControl.java
@@ -0,0 +1,149 @@
+package dev.jlibra.admissioncontrol;
+
+import static java.util.stream.Collectors.toList;
+
+import java.io.IOException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.google.protobuf.ByteString;
+
+import admission_control.AdmissionControlGrpc;
+import admission_control.AdmissionControlGrpc.AdmissionControlBlockingStub;
+import admission_control.AdmissionControlOuterClass.SubmitTransactionRequest;
+import admission_control.AdmissionControlOuterClass.SubmitTransactionResponse;
+import dev.jlibra.AccountState;
+import dev.jlibra.KeyUtils;
+import dev.jlibra.LibraHelper;
+import dev.jlibra.admissioncontrol.query.GetAccountState;
+import dev.jlibra.admissioncontrol.query.UpdateToLatestLedgerResult;
+import dev.jlibra.admissioncontrol.transaction.SubmitTransactionResult;
+import dev.jlibra.admissioncontrol.transaction.Transaction;
+import dev.jlibra.admissioncontrol.transaction.TransactionArgument.Type;
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import types.GetWithProof.GetAccountStateRequest;
+import types.GetWithProof.RequestItem;
+import types.GetWithProof.UpdateToLatestLedgerRequest;
+import types.GetWithProof.UpdateToLatestLedgerResponse;
+import types.Transaction.Program;
+import types.Transaction.RawTransaction;
+import types.Transaction.SignedTransaction;
+import types.Transaction.TransactionArgument;
+import types.Transaction.TransactionArgument.ArgType;
+
+public class AdmissionControl {
+
+ private String host;
+
+ private int port;
+
+ public AdmissionControl(String host, int port) {
+ this.host = host;
+ this.port = port;
+ }
+
+ private static Map jlibraArgumentTypeToGrpcArgumentType;
+
+ static {
+ jlibraArgumentTypeToGrpcArgumentType = new HashMap<>();
+ jlibraArgumentTypeToGrpcArgumentType.put(Type.ADDRESS, ArgType.ADDRESS);
+ jlibraArgumentTypeToGrpcArgumentType.put(Type.U64, ArgType.U64);
+ }
+
+ public SubmitTransactionResult submitTransaction(PublicKey publicKey, PrivateKey privateKey,
+ Transaction transaction) {
+
+ ManagedChannel channel = ManagedChannelBuilder.forAddress(host, port)
+ .usePlaintext()
+ .build();
+
+ AdmissionControlBlockingStub stub = AdmissionControlGrpc.newBlockingStub(channel);
+
+ List transactionArguments = transaction.getProgram().getArguments().stream()
+ .map(txArgument -> TransactionArgument.newBuilder()
+ .setType(jlibraArgumentTypeToGrpcArgumentType.get(txArgument.type()))
+ .setData(ByteString.copyFrom(txArgument.toByteArray()))
+ .build())
+ .collect(toList());
+
+ Program program = Program.newBuilder()
+ .addAllArguments(transactionArguments)
+ .setCode(readCodeFromStream(transaction))
+ .addAllModules(new ArrayList())
+ .build();
+
+ RawTransaction rawTransaction = RawTransaction.newBuilder()
+ .setProgram(program)
+ .setExpirationTime(transaction.getExpirationTime())
+ .setGasUnitPrice(transaction.getGasUnitPrice())
+ .setMaxGasAmount(transaction.getMaxGasAmount())
+ .setSenderAccount(ByteString.copyFrom(KeyUtils.toByteArrayLibraAddress(publicKey.getEncoded())))
+ .setSequenceNumber(transaction.getSequenceNumber())
+ .build();
+
+ SignedTransaction signedTransaction = SignedTransaction.newBuilder()
+ .setRawTxnBytes(rawTransaction.toByteString())
+ .setSenderPublicKey(ByteString.copyFrom(KeyUtils.stripPublicKeyPrefix(publicKey.getEncoded())))
+ .setSenderSignature(ByteString.copyFrom(LibraHelper.signTransaction(rawTransaction, privateKey)))
+ .build();
+
+ SubmitTransactionRequest submitTransactionRequest = SubmitTransactionRequest.newBuilder()
+ .setSignedTxn(signedTransaction)
+ .build();
+
+ SubmitTransactionResponse response = stub.submitTransaction(submitTransactionRequest);
+
+ channel.shutdown();
+
+ return new SubmitTransactionResult(response.getAcStatus(), response.getMempoolStatus(), response.getVmStatus());
+ }
+
+ private ByteString readCodeFromStream(Transaction transaction) {
+ try {
+ return ByteString.readFrom(transaction.getProgram().getCode());
+ } catch (IOException e) {
+ throw new RuntimeException("Could not read move code from input stream", e);
+ }
+ }
+
+ public UpdateToLatestLedgerResult updateToLatestLedger(List arguments) {
+ ManagedChannel channel = ManagedChannelBuilder.forAddress(host, port)
+ .usePlaintext()
+ .build();
+
+ AdmissionControlBlockingStub stub = AdmissionControlGrpc.newBlockingStub(channel);
+
+ List requestItems = arguments.stream().map(argument -> {
+ GetAccountStateRequest getAccountStateRequest = GetAccountStateRequest.newBuilder()
+ .setAddress(ByteString.copyFrom(argument.getAddress()))
+ .build();
+
+ RequestItem requestItem = RequestItem.newBuilder()
+ .setGetAccountStateRequest(getAccountStateRequest)
+ .build();
+ return requestItem;
+ }).collect(toList());
+
+ UpdateToLatestLedgerResponse response = stub.updateToLatestLedger(UpdateToLatestLedgerRequest.newBuilder()
+ .addAllRequestedItems(requestItems)
+ .build());
+
+ List accountStates = new ArrayList<>();
+
+ response.getResponseItemsList().forEach(responseItem -> {
+ accountStates.addAll(LibraHelper.readAccountStates(responseItem.getGetAccountStateResponse()
+ .getAccountStateWithProof()));
+ });
+
+ UpdateToLatestLedgerResult result = UpdateToLatestLedgerResult.create()
+ .withAccountStates(accountStates);
+
+ return result;
+ }
+
+}
diff --git a/src/main/java/dev/jlibra/admissioncontrol/query/GetAccountState.java b/src/main/java/dev/jlibra/admissioncontrol/query/GetAccountState.java
new file mode 100644
index 00000000..f8c1f4dc
--- /dev/null
+++ b/src/main/java/dev/jlibra/admissioncontrol/query/GetAccountState.java
@@ -0,0 +1,13 @@
+package dev.jlibra.admissioncontrol.query;
+
+public class GetAccountState {
+ private byte[] address;
+
+ public GetAccountState(byte[] address) {
+ this.address = address;
+ }
+
+ public byte[] getAddress() {
+ return address;
+ }
+}
diff --git a/src/main/java/dev/jlibra/admissioncontrol/query/UpdateToLatestLedgerResult.java b/src/main/java/dev/jlibra/admissioncontrol/query/UpdateToLatestLedgerResult.java
new file mode 100644
index 00000000..6b6a1d55
--- /dev/null
+++ b/src/main/java/dev/jlibra/admissioncontrol/query/UpdateToLatestLedgerResult.java
@@ -0,0 +1,27 @@
+package dev.jlibra.admissioncontrol.query;
+
+import java.util.List;
+
+import dev.jlibra.AccountState;
+
+public class UpdateToLatestLedgerResult {
+
+ private List accountStates;
+
+ private UpdateToLatestLedgerResult() {
+ }
+
+ public static UpdateToLatestLedgerResult create() {
+ return new UpdateToLatestLedgerResult();
+ }
+
+ public UpdateToLatestLedgerResult withAccountStates(List accountStates) {
+ this.accountStates = accountStates;
+ return this;
+ }
+
+ public List getAccountStates() {
+ return accountStates;
+ }
+
+}
diff --git a/src/main/java/dev/jlibra/admissioncontrol/transaction/AddressArgument.java b/src/main/java/dev/jlibra/admissioncontrol/transaction/AddressArgument.java
new file mode 100644
index 00000000..ec970da0
--- /dev/null
+++ b/src/main/java/dev/jlibra/admissioncontrol/transaction/AddressArgument.java
@@ -0,0 +1,21 @@
+package dev.jlibra.admissioncontrol.transaction;
+
+public class AddressArgument implements TransactionArgument {
+
+ private byte[] address;
+
+ public AddressArgument(byte[] address) {
+ this.address = address;
+ }
+
+ @Override
+ public byte[] toByteArray() {
+ return address;
+ }
+
+ @Override
+ public Type type() {
+ return Type.ADDRESS;
+ }
+
+}
diff --git a/src/main/java/dev/jlibra/admissioncontrol/transaction/Program.java b/src/main/java/dev/jlibra/admissioncontrol/transaction/Program.java
new file mode 100644
index 00000000..45a58d77
--- /dev/null
+++ b/src/main/java/dev/jlibra/admissioncontrol/transaction/Program.java
@@ -0,0 +1,25 @@
+package dev.jlibra.admissioncontrol.transaction;
+
+import java.io.InputStream;
+import java.util.List;
+
+public class Program {
+
+ private InputStream code;
+
+ private List arguments;
+
+ public Program(InputStream code, List arguments) {
+ this.code = code;
+ this.arguments = arguments;
+ }
+
+ public InputStream getCode() {
+ return code;
+ }
+
+ public List getArguments() {
+ return arguments;
+ }
+
+}
diff --git a/src/main/java/dev/jlibra/admissioncontrol/transaction/SubmitTransactionResult.java b/src/main/java/dev/jlibra/admissioncontrol/transaction/SubmitTransactionResult.java
new file mode 100644
index 00000000..90bddc1f
--- /dev/null
+++ b/src/main/java/dev/jlibra/admissioncontrol/transaction/SubmitTransactionResult.java
@@ -0,0 +1,38 @@
+package dev.jlibra.admissioncontrol.transaction;
+
+import admission_control.AdmissionControlOuterClass.AdmissionControlStatus;
+import mempool.MempoolStatus;
+import types.VmErrors.VMStatus;
+
+public class SubmitTransactionResult {
+
+ // TODO: Create own enum types instead of putting grpc enums directly here
+ // Could also add the description texts for clearer errors
+
+ private AdmissionControlStatus admissionControlStatus;
+
+ private MempoolStatus.MempoolAddTransactionStatus mempoolStatus;
+
+ private VMStatus vmStatus;
+
+ public SubmitTransactionResult(AdmissionControlStatus admissionControlStatus,
+ MempoolStatus.MempoolAddTransactionStatus mempoolStatus,
+ VMStatus vmStatus) {
+ this.admissionControlStatus = admissionControlStatus;
+ this.mempoolStatus = mempoolStatus;
+ this.vmStatus = vmStatus;
+ }
+
+ public AdmissionControlStatus getAdmissionControlStatus() {
+ return admissionControlStatus;
+ }
+
+ public MempoolStatus.MempoolAddTransactionStatus getMempoolStatus() {
+ return mempoolStatus;
+ }
+
+ public VMStatus getVmStatus() {
+ return vmStatus;
+ }
+
+}
diff --git a/src/main/java/dev/jlibra/admissioncontrol/transaction/Transaction.java b/src/main/java/dev/jlibra/admissioncontrol/transaction/Transaction.java
new file mode 100644
index 00000000..ba9ba2fd
--- /dev/null
+++ b/src/main/java/dev/jlibra/admissioncontrol/transaction/Transaction.java
@@ -0,0 +1,67 @@
+package dev.jlibra.admissioncontrol.transaction;
+
+public class Transaction {
+
+ private long sequenceNumber;
+
+ private Program program;
+
+ private long expirationTime;
+
+ private long gasUnitPrice;
+
+ private long maxGasAmount;
+
+ private Transaction() {
+ }
+
+ public static Transaction create() {
+ return new Transaction();
+ }
+
+ public Transaction withProgram(Program program) {
+ this.program = program;
+ return this;
+ }
+
+ public Transaction withSequenceNumber(long sequenceNumber) {
+ this.sequenceNumber = sequenceNumber;
+ return this;
+ }
+
+ public Transaction withExpirationTime(long expirationTime) {
+ this.expirationTime = expirationTime;
+ return this;
+ }
+
+ public Transaction withGasUnitPrice(long gasUnitPrice) {
+ this.gasUnitPrice = gasUnitPrice;
+ return this;
+ }
+
+ public Transaction withMaxGasAmount(long maxGasAmount) {
+ this.maxGasAmount = maxGasAmount;
+ return this;
+ }
+
+ public long getSequenceNumber() {
+ return sequenceNumber;
+ }
+
+ public Program getProgram() {
+ return program;
+ }
+
+ public long getExpirationTime() {
+ return expirationTime;
+ }
+
+ public long getGasUnitPrice() {
+ return gasUnitPrice;
+ }
+
+ public long getMaxGasAmount() {
+ return maxGasAmount;
+ }
+
+}
diff --git a/src/main/java/dev/jlibra/admissioncontrol/transaction/TransactionArgument.java b/src/main/java/dev/jlibra/admissioncontrol/transaction/TransactionArgument.java
new file mode 100644
index 00000000..3c9e0e25
--- /dev/null
+++ b/src/main/java/dev/jlibra/admissioncontrol/transaction/TransactionArgument.java
@@ -0,0 +1,13 @@
+package dev.jlibra.admissioncontrol.transaction;
+
+public interface TransactionArgument {
+
+ public enum Type {
+ U64, ADDRESS
+ }
+
+ byte[] toByteArray();
+
+ Type type();
+
+}
diff --git a/src/main/java/dev/jlibra/admissioncontrol/transaction/U64Argument.java b/src/main/java/dev/jlibra/admissioncontrol/transaction/U64Argument.java
new file mode 100644
index 00000000..d348b360
--- /dev/null
+++ b/src/main/java/dev/jlibra/admissioncontrol/transaction/U64Argument.java
@@ -0,0 +1,26 @@
+package dev.jlibra.admissioncontrol.transaction;
+
+import static java.nio.ByteOrder.LITTLE_ENDIAN;
+
+import java.nio.ByteBuffer;
+
+public class U64Argument implements TransactionArgument {
+
+ private long value;
+
+ public U64Argument(long value) {
+ this.value = value;
+ }
+
+ @Override
+ public byte[] toByteArray() {
+ return ByteBuffer.allocate(Long.BYTES).order(LITTLE_ENDIAN).putLong(value)
+ .order(LITTLE_ENDIAN).array();
+ }
+
+ @Override
+ public Type type() {
+ return Type.U64;
+ }
+
+}
diff --git a/src/main/java/dev/jlibra/example/GetAccountStateExample.java b/src/main/java/dev/jlibra/example/GetAccountStateExample.java
index 9ea4bf78..77d2cec3 100644
--- a/src/main/java/dev/jlibra/example/GetAccountStateExample.java
+++ b/src/main/java/dev/jlibra/example/GetAccountStateExample.java
@@ -1,57 +1,27 @@
package dev.jlibra.example;
+import static java.util.Arrays.asList;
+
import java.io.IOException;
import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
import org.bouncycastle.util.encoders.Hex;
-import com.google.protobuf.ByteString;
-
-import admission_control.AdmissionControlGrpc;
-import admission_control.AdmissionControlGrpc.AdmissionControlBlockingStub;
-import dev.jlibra.AccountState;
-import dev.jlibra.LibraHelper;
-import io.grpc.ManagedChannel;
-import io.grpc.ManagedChannelBuilder;
-import types.GetWithProof.GetAccountStateRequest;
-import types.GetWithProof.RequestItem;
-import types.GetWithProof.UpdateToLatestLedgerRequest;
-import types.GetWithProof.UpdateToLatestLedgerResponse;
+import dev.jlibra.admissioncontrol.AdmissionControl;
+import dev.jlibra.admissioncontrol.query.GetAccountState;
+import dev.jlibra.admissioncontrol.query.UpdateToLatestLedgerResult;
public class GetAccountStateExample {
public static void main(String[] args) throws IOException {
String address = "045d3e63dba85f759d66f9bed4a0e4c262d17f9713f25e846fdae63891837a98";
- ManagedChannel channel = ManagedChannelBuilder.forAddress("ac.testnet.libra.org", 8000)
- .usePlaintext()
- .build();
-
- AdmissionControlBlockingStub stub = AdmissionControlGrpc.newBlockingStub(channel);
-
- GetAccountStateRequest getAccountStateRequest = GetAccountStateRequest.newBuilder()
- .setAddress(ByteString.copyFrom(Hex.decode(address)))
- .build();
+ AdmissionControl admissionControl = new AdmissionControl("ac.testnet.libra.org", 8000);
- RequestItem requestItem = RequestItem.newBuilder()
- .setGetAccountStateRequest(getAccountStateRequest)
- .build();
-
- UpdateToLatestLedgerResponse response = stub.updateToLatestLedger(UpdateToLatestLedgerRequest.newBuilder()
- .addAllRequestedItems(Arrays.asList(requestItem))
- .build());
-
- List accountStates = new ArrayList<>();
-
- response.getResponseItemsList().forEach(responseItem -> {
- accountStates.addAll(LibraHelper.readAccountStates(responseItem.getGetAccountStateResponse()
- .getAccountStateWithProof()));
- });
+ UpdateToLatestLedgerResult result = admissionControl
+ .updateToLatestLedger(asList(new GetAccountState(Hex.decode(address))));
- accountStates.forEach(accountState -> {
+ result.getAccountStates().forEach(accountState -> {
System.out.println("Address:" + new String(Hex.encode(accountState.getAddress())));
System.out.println("Received events: " + accountState.getReceivedEvents());
System.out.println("Sent events: " + accountState.getSentEvents());
diff --git a/src/main/java/dev/jlibra/example/TransferExample.java b/src/main/java/dev/jlibra/example/TransferExample.java
index 156d39b4..08733643 100644
--- a/src/main/java/dev/jlibra/example/TransferExample.java
+++ b/src/main/java/dev/jlibra/example/TransferExample.java
@@ -1,31 +1,22 @@
package dev.jlibra.example;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
+import static dev.jlibra.KeyUtils.toHexStringLibraAddress;
+import static java.util.Arrays.asList;
+
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
-import java.util.ArrayList;
-import java.util.Arrays;
import org.bouncycastle.util.encoders.Hex;
-import com.google.protobuf.ByteString;
-
-import admission_control.AdmissionControlGrpc;
-import admission_control.AdmissionControlGrpc.AdmissionControlBlockingStub;
-import admission_control.AdmissionControlOuterClass.SubmitTransactionRequest;
-import admission_control.AdmissionControlOuterClass.SubmitTransactionResponse;
import dev.jlibra.KeyUtils;
-import dev.jlibra.LibraHelper;
+import dev.jlibra.admissioncontrol.AdmissionControl;
+import dev.jlibra.admissioncontrol.transaction.AddressArgument;
+import dev.jlibra.admissioncontrol.transaction.Program;
+import dev.jlibra.admissioncontrol.transaction.SubmitTransactionResult;
+import dev.jlibra.admissioncontrol.transaction.Transaction;
+import dev.jlibra.admissioncontrol.transaction.U64Argument;
import dev.jlibra.move.Move;
-import io.grpc.ManagedChannel;
-import io.grpc.ManagedChannelBuilder;
-import types.Transaction.Program;
-import types.Transaction.RawTransaction;
-import types.Transaction.SignedTransaction;
-import types.Transaction.TransactionArgument;
-import types.Transaction.TransactionArgument.ArgType;
public class TransferExample {
@@ -36,63 +27,36 @@ public static void main(String[] args) throws Exception {
"3051020101300506032b6570042204207422e9df27029f7b83c37035622f93cd0e9b3a2a705d0745d573252756fd8c888121008e23fbceaa5b7a038c8994ca8258c8815e6e9007e3de86598cd46357e5e60024");
PublicKey publicKey = KeyUtils.publicKeyFromHexString(
"302a300506032b65700321008e23fbceaa5b7a038c8994ca8258c8815e6e9007e3de86598cd46357e5e60024");
- String fromAddress = "6674633c78e2e00c69fd6e027aa6d1db2abc2a6c80d78a3e129eaf33dd49ce1c";
String toAddress = "045d3e63dba85f759d66f9bed4a0e4c262d17f9713f25e846fdae63891837a98";
- long amount = 7;
-
- ManagedChannel channel = ManagedChannelBuilder.forAddress("ac.testnet.libra.org", 8000)
- .usePlaintext()
- .build();
-
- AdmissionControlBlockingStub stub = AdmissionControlGrpc.newBlockingStub(channel);
-
- TransactionArgument arg = TransactionArgument.newBuilder()
- .setType(ArgType.ADDRESS)
- .setData(ByteString.copyFrom(Hex.decode(toAddress)))
- .build();
-
- TransactionArgument arg2 = TransactionArgument.newBuilder()
- .setType(ArgType.U64)
- .setData(ByteString
- .copyFrom(
- ByteBuffer.allocate(Long.BYTES).order(ByteOrder.LITTLE_ENDIAN).putLong(amount * 1000000)
- .order(ByteOrder.LITTLE_ENDIAN).array()))
- .build();
-
- Program program = Program.newBuilder()
- .addAllArguments(Arrays.asList(arg, arg2))
- .setCode(ByteString.copyFrom(Move.peerToPeerTransfer()))
- .addAllModules(new ArrayList())
- .build();
-
- RawTransaction rawTransaction = RawTransaction.newBuilder()
- .setProgram(program)
- .setExpirationTime(600)
- .setGasUnitPrice(1)
- .setMaxGasAmount(6000)
- .setSenderAccount(ByteString.copyFrom(Hex.decode(fromAddress)))
- .setSequenceNumber(0)
- .build();
-
- SignedTransaction signedTransaction = SignedTransaction.newBuilder()
- .setRawTxnBytes(rawTransaction.toByteString())
- .setSenderPublicKey(ByteString.copyFrom(KeyUtils.stripPublicKeyPrefix(publicKey.getEncoded())))
- .setSenderSignature(ByteString.copyFrom(LibraHelper.signTransaction(rawTransaction, privateKey)))
- .build();
-
- SubmitTransactionRequest submitTransactionRequest = SubmitTransactionRequest.newBuilder()
- .setSignedTxn(signedTransaction)
- .build();
-
- SubmitTransactionResponse response = stub.submitTransaction(submitTransactionRequest);
+ long amount = 8;
+ int sequenceNumber = 5;
- Thread.sleep(2000); // add sleep to prevent premature closing of channel
+ System.out.println(
+ String.format("Sending from %s to %s", toHexStringLibraAddress(publicKey.getEncoded()), toAddress));
+
+ AdmissionControl admissionControl = new AdmissionControl("ac.testnet.libra.org", 8000);
- System.out.println("response: " + response);
+ // Arguments for the peer to peer transaction
+ U64Argument amountArgument = new U64Argument(amount * 1000000);
+ AddressArgument addressArgument = new AddressArgument(Hex.decode(toAddress));
- channel.shutdown();
+ Transaction transaction = Transaction.create()
+ .withSequenceNumber(sequenceNumber)
+ .withMaxGasAmount(6000)
+ .withGasUnitPrice(1)
+ .withExpirationTime(10000)
+ .withProgram(
+ new Program(Move.peerToPeerTransfer(), asList(addressArgument, amountArgument)));
+ SubmitTransactionResult result = admissionControl.submitTransaction(publicKey, privateKey,
+ transaction);
+
+ System.out.println("Admission control status: " + result.getAdmissionControlStatus());
+ System.out.println("Mempool status: " + result.getMempoolStatus());
+ System.out.println("VM status: " + result.getVmStatus());
+
+ Thread.sleep(2000); // add sleep to prevent premature closing of channel
}
}
diff --git a/src/main/java/dev/jlibra/move/Move.java b/src/main/java/dev/jlibra/move/Move.java
index b6f02b66..fcddf705 100644
--- a/src/main/java/dev/jlibra/move/Move.java
+++ b/src/main/java/dev/jlibra/move/Move.java
@@ -1,15 +1,11 @@
package dev.jlibra.move;
-import org.apache.commons.io.IOUtils;
+import java.io.InputStream;
public class Move {
- public static byte[] peerToPeerTransfer() {
- try {
- return IOUtils.toByteArray(Move.class.getResourceAsStream("/move/peer_to_peer_transfer.bin"));
- } catch (Exception e) {
- throw new RuntimeException("Reading the transfer script file failed", e);
- }
+ public static InputStream peerToPeerTransfer() {
+ return Move.class.getResourceAsStream("/move/peer_to_peer_transfer.bin");
}
}
diff --git a/src/test/java/dev/jlibra/KeyUtilsTest.java b/src/test/java/dev/jlibra/KeyUtilsTest.java
index d1aab6ed..25c73b5b 100644
--- a/src/test/java/dev/jlibra/KeyUtilsTest.java
+++ b/src/test/java/dev/jlibra/KeyUtilsTest.java
@@ -31,7 +31,7 @@ public void testToLibraAddress() throws Exception {
PublicKey publicKey = getKeyFactory().generatePublic(new X509EncodedKeySpec(Hex
.decode(PUBLIC_KEY_HEX)));
- assertThat(KeyUtils.toLibraAddress(publicKey.getEncoded()),
+ assertThat(KeyUtils.toHexStringLibraAddress(publicKey.getEncoded()),
is("eb99fc3808a8e439c58f87935cbe6774e4cc83459b463ea0813b34ef96f0ba87"));
}
diff --git a/src/test/java/dev/jlibra/move/MoveTest.java b/src/test/java/dev/jlibra/move/MoveTest.java
index 269edb21..5ba785d1 100644
--- a/src/test/java/dev/jlibra/move/MoveTest.java
+++ b/src/test/java/dev/jlibra/move/MoveTest.java
@@ -10,7 +10,7 @@ public class MoveTest {
@Test
public void testPeerToPeerTransfer() throws Exception {
- assertThat(Move.peerToPeerTransfer(),
+ assertThat(toByteArray(Move.peerToPeerTransfer()),
equalTo(toByteArray(MoveTest.this.getClass().getResourceAsStream("/move/peer_to_peer_transfer.bin"))));
}