diff --git a/Java/pom.xml b/Java/pom.xml
index cfd45fb..29ff99e 100644
--- a/Java/pom.xml
+++ b/Java/pom.xml
@@ -4,7 +4,7 @@
4.0.0
org.ciyam
AT
- 1.3.2
+ 1.3.3
jar
true
diff --git a/Java/src/main/java/org/ciyam/at/API.java b/Java/src/main/java/org/ciyam/at/API.java
index ef34497..4b94c35 100644
--- a/Java/src/main/java/org/ciyam/at/API.java
+++ b/Java/src/main/java/org/ciyam/at/API.java
@@ -152,44 +152,98 @@ public abstract class API {
/* Convenience methods to allow subclasses to access package-scoped a1-a4, b1-b4 variables */
- public void zeroA(MachineState state) {
+ protected long getA1(MachineState state) {
+ return state.a1;
+ }
+
+ protected long getA2(MachineState state) {
+ return state.a2;
+ }
+
+ protected long getA3(MachineState state) {
+ return state.a3;
+ }
+
+ protected long getA4(MachineState state) {
+ return state.a4;
+ }
+
+ protected byte[] getA(MachineState state) {
+ ByteBuffer byteBuffer = ByteBuffer.allocate(4 * 8);
+
+ byteBuffer.putLong(state.a1);
+ byteBuffer.putLong(state.a2);
+ byteBuffer.putLong(state.a3);
+ byteBuffer.putLong(state.a4);
+
+ return byteBuffer.array();
+ }
+
+ protected long getB1(MachineState state) {
+ return state.b1;
+ }
+
+ protected long getB2(MachineState state) {
+ return state.b2;
+ }
+
+ protected long getB3(MachineState state) {
+ return state.b3;
+ }
+
+ protected long getB4(MachineState state) {
+ return state.b4;
+ }
+
+ protected byte[] getB(MachineState state) {
+ ByteBuffer byteBuffer = ByteBuffer.allocate(4 * 8);
+
+ byteBuffer.putLong(state.b1);
+ byteBuffer.putLong(state.b2);
+ byteBuffer.putLong(state.b3);
+ byteBuffer.putLong(state.b4);
+
+ return byteBuffer.array();
+ }
+
+ protected void zeroA(MachineState state) {
state.a1 = 0L;
state.a2 = 0L;
state.a3 = 0L;
state.a4 = 0L;
}
- public void zeroB(MachineState state) {
+ protected void zeroB(MachineState state) {
state.b1 = 0L;
state.b2 = 0L;
state.b3 = 0L;
state.b4 = 0L;
}
- public void setAToMaxValue(MachineState state) {
+ protected void setAToMaxValue(MachineState state) {
state.a1 = 0xffffffffffffffffL;
state.a2 = 0xffffffffffffffffL;
state.a3 = 0xffffffffffffffffL;
state.a4 = 0xffffffffffffffffL;
}
- public void setA1(MachineState state, long value) {
+ protected void setA1(MachineState state, long value) {
state.a1 = value;
}
- public void setA2(MachineState state, long value) {
+ protected void setA2(MachineState state, long value) {
state.a2 = value;
}
- public void setA3(MachineState state, long value) {
+ protected void setA3(MachineState state, long value) {
state.a3 = value;
}
- public void setA4(MachineState state, long value) {
+ protected void setA4(MachineState state, long value) {
state.a4 = value;
}
- public void setA(MachineState state, byte[] bytes) {
+ protected void setA(MachineState state, byte[] bytes) {
ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
state.a1 = byteBuffer.getLong();
@@ -198,23 +252,23 @@ public abstract class API {
state.a4 = byteBuffer.getLong();
}
- public void setB1(MachineState state, long value) {
+ protected void setB1(MachineState state, long value) {
state.b1 = value;
}
- public void setB2(MachineState state, long value) {
+ protected void setB2(MachineState state, long value) {
state.b2 = value;
}
- public void setB3(MachineState state, long value) {
+ protected void setB3(MachineState state, long value) {
state.b3 = value;
}
- public void setB4(MachineState state, long value) {
+ protected void setB4(MachineState state, long value) {
state.b4 = value;
}
- public void setB(MachineState state, byte[] bytes) {
+ protected void setB(MachineState state, byte[] bytes) {
ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
state.b1 = byteBuffer.getLong();
diff --git a/Java/src/main/java/org/ciyam/at/MachineState.java b/Java/src/main/java/org/ciyam/at/MachineState.java
index 3f12540..cc68eb6 100644
--- a/Java/src/main/java/org/ciyam/at/MachineState.java
+++ b/Java/src/main/java/org/ciyam/at/MachineState.java
@@ -329,60 +329,6 @@ public class MachineState {
this.hadFatalError = hadFatalError;
}
- public long getA1() {
- return this.a1;
- }
-
- public long getA2() {
- return this.a2;
- }
-
- public long getA3() {
- return this.a3;
- }
-
- public long getA4() {
- return this.a4;
- }
-
- public byte[] getA() {
- ByteBuffer byteBuffer = ByteBuffer.allocate(4 * 8);
-
- byteBuffer.putLong(this.a1);
- byteBuffer.putLong(this.a2);
- byteBuffer.putLong(this.a3);
- byteBuffer.putLong(this.a4);
-
- return byteBuffer.array();
- }
-
- public long getB1() {
- return this.b1;
- }
-
- public long getB2() {
- return this.b2;
- }
-
- public long getB3() {
- return this.b3;
- }
-
- public long getB4() {
- return this.b4;
- }
-
- public byte[] getB() {
- ByteBuffer byteBuffer = ByteBuffer.allocate(4 * 8);
-
- byteBuffer.putLong(this.b1);
- byteBuffer.putLong(this.b2);
- byteBuffer.putLong(this.b3);
- byteBuffer.putLong(this.b4);
-
- return byteBuffer.array();
- }
-
public int getCurrentBlockHeight() {
return this.currentBlockHeight;
}
diff --git a/Java/src/main/java/org/ciyam/at/OpCodeParam.java b/Java/src/main/java/org/ciyam/at/OpCodeParam.java
index 88acc99..ea15bf4 100644
--- a/Java/src/main/java/org/ciyam/at/OpCodeParam.java
+++ b/Java/src/main/java/org/ciyam/at/OpCodeParam.java
@@ -2,7 +2,7 @@ package org.ciyam.at;
import java.nio.ByteBuffer;
-public enum OpCodeParam {
+enum OpCodeParam {
VALUE {
@Override
diff --git a/Java/src/main/java/org/ciyam/at/Timestamp.java b/Java/src/main/java/org/ciyam/at/Timestamp.java
index aaec030..64cb407 100644
--- a/Java/src/main/java/org/ciyam/at/Timestamp.java
+++ b/Java/src/main/java/org/ciyam/at/Timestamp.java
@@ -100,10 +100,7 @@ public class Timestamp {
* @return CIYAM-AT "timestamp" as long
*/
public static long toLong(int blockHeight, int transactionSequence) {
- long longValue = ((long) blockHeight) << 32;
- // NOP: longValue |= ((long) NATIVE_BLOCKCHAIN_ID) << 24;
- longValue |= transactionSequence;
- return longValue;
+ return toLong(blockHeight, NATIVE_BLOCKCHAIN_ID, transactionSequence);
}
}
diff --git a/Java/src/main/java/org/ciyam/at/TwoValueComparator.java b/Java/src/main/java/org/ciyam/at/TwoValueComparator.java
index 00c6430..d4c6909 100644
--- a/Java/src/main/java/org/ciyam/at/TwoValueComparator.java
+++ b/Java/src/main/java/org/ciyam/at/TwoValueComparator.java
@@ -1,6 +1,7 @@
package org.ciyam.at;
-public interface TwoValueComparator {
+@FunctionalInterface
+interface TwoValueComparator {
public boolean compare(long a, long b);
diff --git a/Java/src/main/java/org/ciyam/at/TwoValueOperator.java b/Java/src/main/java/org/ciyam/at/TwoValueOperator.java
index 4cc6a55..9753502 100644
--- a/Java/src/main/java/org/ciyam/at/TwoValueOperator.java
+++ b/Java/src/main/java/org/ciyam/at/TwoValueOperator.java
@@ -1,6 +1,7 @@
package org.ciyam.at;
-public interface TwoValueOperator {
+@FunctionalInterface
+interface TwoValueOperator {
public long apply(long a, long b);
diff --git a/Java/src/main/java/org/ciyam/at/Utils.java b/Java/src/main/java/org/ciyam/at/Utils.java
index 6b965e4..4c98281 100644
--- a/Java/src/main/java/org/ciyam/at/Utils.java
+++ b/Java/src/main/java/org/ciyam/at/Utils.java
@@ -3,7 +3,7 @@ package org.ciyam.at;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
-public class Utils {
+interface Utils {
/**
* Returns immediate function code enum from code bytes at current position.
@@ -11,11 +11,11 @@ public class Utils {
* Initial position is codeByteBuffer.position() but on return is incremented by 2.
*
* @param codeByteBuffer
- * @return FunctionCode enum
- * @throws CodeSegmentException
- * @throws InvalidAddressException
+ * @return FunctionCode
+ * @throws CodeSegmentException if we ran out of bytes trying to fetch raw function code value
+ * @throws IllegalFunctionCodeException if we can't convert raw function code to FunctionCode object
*/
- public static FunctionCode getFunctionCode(ByteBuffer codeByteBuffer) throws CodeSegmentException, IllegalFunctionCodeException {
+ static FunctionCode getFunctionCode(ByteBuffer codeByteBuffer) throws CodeSegmentException, IllegalFunctionCodeException {
try {
int rawFunctionCode = codeByteBuffer.getShort();
@@ -38,11 +38,11 @@ public class Utils {
* Note: address is not scaled by Constants.VALUE_SIZE unlike other methods in this class.
*
* @param codeByteBuffer
- * @return int address into code bytes
- * @throws CodeSegmentException
- * @throws InvalidAddressException
+ * @return int address into code segment
+ * @throws CodeSegmentException if we ran out of bytes trying to fetch code address
+ * @throws InvalidAddressException if fetched address points outside of code segment
*/
- public static int getCodeAddress(ByteBuffer codeByteBuffer) throws CodeSegmentException, InvalidAddressException {
+ static int getCodeAddress(ByteBuffer codeByteBuffer) throws CodeSegmentException, InvalidAddressException {
try {
int address = codeByteBuffer.getInt();
@@ -63,11 +63,11 @@ public class Utils {
* Note: address is returned scaled by Constants.VALUE_SIZE.
*
* @param codeByteBuffer
- * @return int address into data bytes
- * @throws CodeSegmentException
- * @throws InvalidAddressException
+ * @return int address into data segment
+ * @throws CodeSegmentException if we ran out of bytes trying to fetch data address
+ * @throws InvalidAddressException if fetched address points outside of data segment
*/
- public static int getDataAddress(ByteBuffer codeByteBuffer, ByteBuffer dataByteBuffer) throws CodeSegmentException, InvalidAddressException {
+ static int getDataAddress(ByteBuffer codeByteBuffer, ByteBuffer dataByteBuffer) throws CodeSegmentException, InvalidAddressException {
try {
int address = codeByteBuffer.getInt() * MachineState.VALUE_SIZE;
@@ -89,17 +89,17 @@ public class Utils {
*
* @param codeByteBuffer
* @return byte offset
- * @throws CodeSegmentException
- * @throws InvalidAddressException
+ * @throws CodeSegmentException if we ran out of bytes trying to fetch offset
+ * @throws InvalidAddressException if position + offset is outside of code segment
*/
- public static byte getCodeOffset(ByteBuffer codeByteBuffer) throws CodeSegmentException, InvalidAddressException {
+ static byte getCodeOffset(ByteBuffer codeByteBuffer) throws CodeSegmentException, InvalidAddressException {
try {
final byte offset = codeByteBuffer.get();
final int target = codeByteBuffer.position() + offset;
- if (target < 0 || target >= codeByteBuffer.limit() - 1)
- throw new InvalidAddressException(String.format("Code target PC+%02x=[%04x] out of bounds: 0x0000 to 0x%04x",
- codeByteBuffer.position() - 1, offset, target, codeByteBuffer.limit() - 1 -1));
+ if (target < 0 || target >= codeByteBuffer.limit())
+ throw new InvalidAddressException(String.format("Code target PC(%04x) + %02x = %04x out of bounds: 0x0000 to 0x%04x",
+ codeByteBuffer.position() - 1, offset, target, codeByteBuffer.limit() - 1));
return offset;
} catch (BufferUnderflowException e) {
@@ -114,10 +114,9 @@ public class Utils {
*
* @param codeByteBuffer
* @return long value
- * @throws CodeSegmentException
- * @throws InvalidAddressException
+ * @throws CodeSegmentException if we ran out of bytes trying to fetch value
*/
- public static long getCodeValue(ByteBuffer codeByteBuffer) throws CodeSegmentException, InvalidAddressException {
+ static long getCodeValue(ByteBuffer codeByteBuffer) throws CodeSegmentException {
try {
return codeByteBuffer.getLong();
} catch (BufferUnderflowException e) {
diff --git a/Java/src/test/java/org/ciyam/at/BlockchainFunctionCodeTests.java b/Java/src/test/java/org/ciyam/at/BlockchainFunctionCodeTests.java
index 95ef767..feff13f 100644
--- a/Java/src/test/java/org/ciyam/at/BlockchainFunctionCodeTests.java
+++ b/Java/src/test/java/org/ciyam/at/BlockchainFunctionCodeTests.java
@@ -101,7 +101,7 @@ public class BlockchainFunctionCodeTests extends ExecutableTest {
byte[] expectedBlockHash = api.blockchain.get(previousBlockHeight - 1).blockHash;
- byte[] aBytes = state.getA();
+ byte[] aBytes = api.getA(state);
assertTrue("Block hash mismatch", Arrays.equals(expectedBlockHash, aBytes));
assertTrue(state.getIsFinished());
diff --git a/Java/src/test/java/org/ciyam/at/test/TestAPI.java b/Java/src/test/java/org/ciyam/at/test/TestAPI.java
index 4ed75e5..d500eef 100644
--- a/Java/src/test/java/org/ciyam/at/test/TestAPI.java
+++ b/Java/src/test/java/org/ciyam/at/test/TestAPI.java
@@ -304,7 +304,7 @@ public class TestAPI extends API {
}
public TestTransaction getTransactionFromA(MachineState state) {
- byte[] aBytes = state.getA();
+ byte[] aBytes = this.getA(state);
String txHashString = stringifyHash(aBytes);
return transactions.get(txHashString);
}
@@ -346,7 +346,7 @@ public class TestAPI extends API {
System.out.println("generateRandomUsingTransactionInA: second call - returning random");
// HASH(A and new block hash)
- return (state.getA1() ^ 9L) << 3 ^ (state.getA2() ^ 9L) << 12 ^ (state.getA3() ^ 9L) << 5 ^ (state.getA4() ^ 9L);
+ return (this.getA1(state) ^ 9L) << 3 ^ (this.getA2(state) ^ 9L) << 12 ^ (this.getA3(state) ^ 9L) << 5 ^ (this.getA4(state) ^ 9L);
}
}
@@ -385,7 +385,7 @@ public class TestAPI extends API {
@Override
public void payAmountToB(long amount, MachineState state) {
- byte[] bBytes = state.getB();
+ byte[] bBytes = this.getB(state);
String address = decodeAddress(bBytes);
TestAccount recipient = accounts.get(address);
@@ -402,14 +402,14 @@ public class TestAPI extends API {
@Override
public void messageAToB(MachineState state) {
- byte[] bBytes = state.getB();
+ byte[] bBytes = this.getB(state);
String address = decodeAddress(bBytes);
TestAccount recipient = accounts.get(address);
if (recipient == null)
throw new IllegalStateException("Refusing to send message to unknown account: " + address);
- recipient.messages.add(state.getA());
+ recipient.messages.add(this.getA(state));
}
@Override