You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuweni.apache.org by to...@apache.org on 2021/05/29 07:05:55 UTC
[incubator-tuweni] branch main updated: UInt compat fixes
This is an automated email from the ASF dual-hosted git repository.
toulmean pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-tuweni.git
The following commit(s) were added to refs/heads/main by this push:
new 09091de UInt compat fixes
new 7990069 Merge pull request #250 from atoulme/uint_fixes
09091de is described below
commit 09091deb4c5d1e39f351c2b155a67767ec77024d
Author: Antoine Toulme <an...@lunar-ocean.com>
AuthorDate: Fri May 28 23:02:59 2021 -0700
UInt compat fixes
---
.../org/apache/tuweni/evm/impl/berlin/OpCodes.kt | 4 +-
.../tuweni/units/bigints/BaseUInt256Value.java | 6 +
.../org/apache/tuweni/units/bigints/UInt256.java | 6 +-
.../apache/tuweni/units/bigints/UInt256Value.java | 145 +++++++++++++++++++--
.../apache/tuweni/units/bigints/UInt32Value.java | 9 ++
.../apache/tuweni/units/bigints/UInt384Value.java | 9 ++
.../apache/tuweni/units/bigints/UInt64Value.java | 9 ++
.../apache/tuweni/units/bigints/UInt256Test.java | 5 +
.../apache/tuweni/units/bigints/UInt32Test.java | 4 +
.../apache/tuweni/units/bigints/UInt384Test.java | 5 +
.../apache/tuweni/units/bigints/UInt64Test.java | 5 +
.../org/apache/tuweni/units/ethereum/WeiTest.java | 20 +++
12 files changed, 210 insertions(+), 17 deletions(-)
diff --git a/evm/src/main/kotlin/org/apache/tuweni/evm/impl/berlin/OpCodes.kt b/evm/src/main/kotlin/org/apache/tuweni/evm/impl/berlin/OpCodes.kt
index eb0de1d..fa54494 100644
--- a/evm/src/main/kotlin/org/apache/tuweni/evm/impl/berlin/OpCodes.kt
+++ b/evm/src/main/kotlin/org/apache/tuweni/evm/impl/berlin/OpCodes.kt
@@ -102,7 +102,7 @@ val slt = Opcode { gasManager, _, stack, _, _, _, _ ->
if (null == item || null == item2) {
Result(EVMExecutionStatusCode.STACK_UNDERFLOW)
} else {
- if (item.toBigInteger() < item2.toBigInteger()) {
+ if (item.toSignedBigInteger() < item2.toSignedBigInteger()) {
stack.push(UInt256.ONE)
} else {
stack.push(UInt256.ZERO)
@@ -134,7 +134,7 @@ val sgt = Opcode { gasManager, _, stack, _, _, _, _ ->
if (null == item || null == item2) {
Result(EVMExecutionStatusCode.STACK_UNDERFLOW)
} else {
- if (item.toBigInteger() > item2.toBigInteger()) {
+ if (item.toSignedBigInteger() > item2.toSignedBigInteger()) {
stack.push(UInt256.ONE)
} else {
stack.push(UInt256.ZERO)
diff --git a/units/src/main/java/org/apache/tuweni/units/bigints/BaseUInt256Value.java b/units/src/main/java/org/apache/tuweni/units/bigints/BaseUInt256Value.java
index a6329cb..4bef9ac 100644
--- a/units/src/main/java/org/apache/tuweni/units/bigints/BaseUInt256Value.java
+++ b/units/src/main/java/org/apache/tuweni/units/bigints/BaseUInt256Value.java
@@ -19,6 +19,7 @@ import org.apache.tuweni.bytes.Bytes32;
import org.apache.tuweni.bytes.MutableBytes32;
import java.math.BigInteger;
+import java.nio.ByteOrder;
import java.util.function.Function;
/**
@@ -381,4 +382,9 @@ public abstract class BaseUInt256Value<T extends UInt256Value<T>> implements UIn
public MutableBytes32 mutableCopy() {
return MutableBytes32.wrap(value.toArrayUnsafe());
}
+
+ @Override
+ public long toLong(ByteOrder order) {
+ return value.toLong(order);
+ }
}
diff --git a/units/src/main/java/org/apache/tuweni/units/bigints/UInt256.java b/units/src/main/java/org/apache/tuweni/units/bigints/UInt256.java
index 94173b3..3bb2f4a 100644
--- a/units/src/main/java/org/apache/tuweni/units/bigints/UInt256.java
+++ b/units/src/main/java/org/apache/tuweni/units/bigints/UInt256.java
@@ -451,7 +451,7 @@ public final class UInt256 implements UInt256Value<UInt256> {
if (divisor.isZero()) {
return UInt256.ZERO;
} else {
- BigInteger result = this.toBigInteger().divide(divisor.toBigInteger());
+ BigInteger result = this.toSignedBigInteger().divide(divisor.toSignedBigInteger());
Bytes resultBytes = Bytes.wrap(result.toByteArray());
if (resultBytes.size() > 32) {
resultBytes = resultBytes.slice(resultBytes.size() - 32, 32);
@@ -532,8 +532,8 @@ public final class UInt256 implements UInt256Value<UInt256> {
return UInt256.ZERO;
}
- BigInteger bi = this.toBigInteger();
- BigInteger result = bi.abs().mod(modulus.toBigInteger().abs());
+ BigInteger bi = this.toSignedBigInteger();
+ BigInteger result = bi.abs().mod(modulus.toSignedBigInteger().abs());
if (bi.signum() < 0) {
result = result.negate();
diff --git a/units/src/main/java/org/apache/tuweni/units/bigints/UInt256Value.java b/units/src/main/java/org/apache/tuweni/units/bigints/UInt256Value.java
index 7c1cc35..63d0a70 100644
--- a/units/src/main/java/org/apache/tuweni/units/bigints/UInt256Value.java
+++ b/units/src/main/java/org/apache/tuweni/units/bigints/UInt256Value.java
@@ -13,9 +13,14 @@
package org.apache.tuweni.units.bigints;
+import static java.nio.ByteOrder.BIG_ENDIAN;
+
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
+import java.math.BigInteger;
+import java.nio.ByteOrder;
+
/**
* Represents a 256-bit (32 bytes) unsigned integer value.
@@ -336,13 +341,33 @@ public interface UInt256Value<T extends UInt256Value<T>> extends Bytes32 {
* @return True if this value fits a java {@code int} (i.e. is less or equal to {@code Integer.MAX_VALUE}).
*/
default boolean fitsInt() {
- // Ints are 4 bytes, so anything but the 4 last bytes must be zeroes
- for (int i = 0; i < Bytes32.SIZE - 4; i++) {
- if (get(i) != 0)
- return false;
+ return fitsInt(ByteOrder.BIG_ENDIAN);
+ }
+
+ /**
+ * Returns true if the value can fit in an int according to the byte order.
+ *
+ * @param order the byte order, little or big endian
+ * @return True if this value fits a java {@code int} (i.e. is less or equal to {@code Integer.MAX_VALUE}).
+ */
+ default boolean fitsInt(ByteOrder order) {
+ if (order == ByteOrder.BIG_ENDIAN) {
+ // Ints are 4 bytes, so anything but the 4 last bytes must be zeroes
+ for (int i = 0; i < Bytes32.SIZE - 4; i++) {
+ if (get(i) != 0)
+ return false;
+ }
+ // Lastly, the left-most byte of the int must not start with a 1.
+ return get(Bytes32.SIZE - 4) >= 0;
+ } else {
+ // Ints are 4 bytes, so only the 4 first bytes must not be zeroes
+ for (int i = 4; i < Bytes32.SIZE - 4; i++) {
+ if (get(i) != 0)
+ return false;
+ }
+ // Lastly, the right-most byte of the int must not start with a 1.
+ return get(3) >= 0;
}
- // Lastly, the left-most byte of the int must not start with a 1.
- return get(Bytes32.SIZE - 4) >= 0;
}
/**
@@ -358,19 +383,63 @@ public interface UInt256Value<T extends UInt256Value<T>> extends Bytes32 {
return getInt(Bytes32.SIZE - 4);
}
+ @Override
+ default int toInt(ByteOrder order) {
+ if (!fitsInt(order)) {
+ throw new ArithmeticException("Value does not fit a 4 byte int");
+ }
+ if (order == ByteOrder.BIG_ENDIAN) {
+ return getInt(Bytes32.SIZE - 4, order);
+ } else {
+ return getInt(0, order);
+ }
+ }
+
+ @Override
+ default long toLong(ByteOrder order) {
+ if (!fitsLong(order)) {
+ throw new ArithmeticException("Value does not fit a 8 byte long");
+ }
+ if (order == ByteOrder.BIG_ENDIAN) {
+ return getLong(Bytes32.SIZE - 8, order);
+ } else {
+ return getLong(0, order);
+ }
+ }
+
/**
* Returns true if the value can fit in a long.
*
* @return True if this value fits a java {@code long} (i.e. is less or equal to {@code Long.MAX_VALUE}).
*/
default boolean fitsLong() {
- // Longs are 8 bytes, so anything but the 8 last bytes must be zeroes
- for (int i = 0; i < Bytes32.SIZE - 8; i++) {
- if (get(i) != 0)
- return false;
+ return fitsLong(ByteOrder.BIG_ENDIAN);
+ }
+
+ /**
+ * Returns true if the value can fit in a long.
+ *
+ * @param order byte order, little or big endian
+ * @return True if this value fits a java {@code long} (i.e. is less or equal to {@code Long.MAX_VALUE}).
+ */
+ default boolean fitsLong(ByteOrder order) {
+ if (order == ByteOrder.BIG_ENDIAN) {
+ // Longs are 8 bytes, so anything but the 8 last bytes must be zeroes
+ for (int i = 0; i < Bytes32.SIZE - 8; i++) {
+ if (get(i) != 0)
+ return false;
+ }
+ // Lastly, the left-most byte of the long must not start with a 1.
+ return get(Bytes32.SIZE - 8) >= 0;
+ } else {
+ // Longs are 8 bytes, so only the 8 first bytes may not be zeroes
+ for (int i = 8; i < Bytes32.SIZE; i++) {
+ if (get(i) != 0)
+ return false;
+ }
+ // Lastly, the left-most byte of the long must not start with a 1.
+ return get(7) >= 0;
}
- // Lastly, the left-most byte of the long must not start with a 1.
- return get(Bytes32.SIZE - 8) >= 0;
}
/**
@@ -433,4 +502,56 @@ public interface UInt256Value<T extends UInt256Value<T>> extends Bytes32 {
default boolean lessOrEqualThan(UInt256Value<T> other) {
return compareTo(other) <= 0;
}
+
+ /**
+ * Returns the decimal representation of this value as a String.
+ *
+ * @return the decimal representation of this value as a String.
+ */
+ default String toDecimalString() {
+ return toBigInteger().toString(10);
+ }
+
+ /**
+ * The BigInteger corresponding to interpreting these bytes as a two's-complement signed integer.
+ *
+ * @return A {@link BigInteger} corresponding to interpreting these bytes as a two's-complement signed integer.
+ */
+ default BigInteger toSignedBigInteger() {
+ return toSignedBigInteger(BIG_ENDIAN);
+ }
+
+ /**
+ * The BigInteger corresponding to interpreting these bytes as a two's-complement signed integer.
+ *
+ * @param order The byte-order for decoding the integer.
+ * @return A {@link BigInteger} corresponding to interpreting these bytes as a two's-complement signed integer.
+ */
+ default BigInteger toSignedBigInteger(ByteOrder order) {
+ if (size() == 0) {
+ return BigInteger.ZERO;
+ }
+ return new BigInteger((order == BIG_ENDIAN) ? toArrayUnsafe() : reverse().toArrayUnsafe());
+ }
+
+ /**
+ * The BigInteger corresponding to interpreting these bytes as an unsigned integer.
+ *
+ * @return A positive (or zero) {@link BigInteger} corresponding to interpreting these bytes as an unsigned integer.
+ */
+ @Override
+ default BigInteger toBigInteger() {
+ return toUnsignedBigInteger();
+ }
+
+ /**
+ * The BigInteger corresponding to interpreting these bytes as an unsigned integer.
+ *
+ * @param order The byte-order for decoding the integer.
+ * @return A positive (or zero) {@link BigInteger} corresponding to interpreting these bytes as an unsigned integer.
+ */
+ @Override
+ default BigInteger toBigInteger(ByteOrder order) {
+ return toUnsignedBigInteger(order);
+ }
}
diff --git a/units/src/main/java/org/apache/tuweni/units/bigints/UInt32Value.java b/units/src/main/java/org/apache/tuweni/units/bigints/UInt32Value.java
index 72cdca8..c45b2a9 100644
--- a/units/src/main/java/org/apache/tuweni/units/bigints/UInt32Value.java
+++ b/units/src/main/java/org/apache/tuweni/units/bigints/UInt32Value.java
@@ -390,4 +390,13 @@ public interface UInt32Value<T extends UInt32Value<T>> extends Comparable<T> {
default int bitLength() {
return toBytes().bitLength();
}
+
+ /**
+ * Returns the decimal representation of this value as a String.
+ *
+ * @return the decimal representation of this value as a String.
+ */
+ default String toDecimalString() {
+ return toBigInteger().toString(10);
+ }
}
diff --git a/units/src/main/java/org/apache/tuweni/units/bigints/UInt384Value.java b/units/src/main/java/org/apache/tuweni/units/bigints/UInt384Value.java
index 1dd3829..62859b6 100644
--- a/units/src/main/java/org/apache/tuweni/units/bigints/UInt384Value.java
+++ b/units/src/main/java/org/apache/tuweni/units/bigints/UInt384Value.java
@@ -409,4 +409,13 @@ public interface UInt384Value<T extends UInt384Value<T>> extends Comparable<T> {
default int bitLength() {
return toBytes().bitLength();
}
+
+ /**
+ * Returns the decimal representation of this value as a String.
+ *
+ * @return the decimal representation of this value as a String.
+ */
+ default String toDecimalString() {
+ return toBigInteger().toString(10);
+ }
}
diff --git a/units/src/main/java/org/apache/tuweni/units/bigints/UInt64Value.java b/units/src/main/java/org/apache/tuweni/units/bigints/UInt64Value.java
index e396056..6def37a 100644
--- a/units/src/main/java/org/apache/tuweni/units/bigints/UInt64Value.java
+++ b/units/src/main/java/org/apache/tuweni/units/bigints/UInt64Value.java
@@ -403,4 +403,13 @@ public interface UInt64Value<T extends UInt64Value<T>> extends Comparable<T> {
default int bitLength() {
return toBytes().bitLength();
}
+
+ /**
+ * Returns the decimal representation of this value as a String.
+ *
+ * @return the decimal representation of this value as a String.
+ */
+ default String toDecimalString() {
+ return toBigInteger().toString(10);
+ }
}
diff --git a/units/src/test/java/org/apache/tuweni/units/bigints/UInt256Test.java b/units/src/test/java/org/apache/tuweni/units/bigints/UInt256Test.java
index 010ed5d..76b1490 100644
--- a/units/src/test/java/org/apache/tuweni/units/bigints/UInt256Test.java
+++ b/units/src/test/java/org/apache/tuweni/units/bigints/UInt256Test.java
@@ -1168,4 +1168,9 @@ class UInt256Test {
String msg = String.format("Expected %s but got %s", expected.toHexString(), actual.toHexString());
assertEquals(expected, actual, msg);
}
+
+ @Test
+ void testToDecimalString() {
+ assertEquals("3456", UInt256.valueOf(3456).toDecimalString());
+ }
}
diff --git a/units/src/test/java/org/apache/tuweni/units/bigints/UInt32Test.java b/units/src/test/java/org/apache/tuweni/units/bigints/UInt32Test.java
index c9a82bd..6fb4ace 100644
--- a/units/src/test/java/org/apache/tuweni/units/bigints/UInt32Test.java
+++ b/units/src/test/java/org/apache/tuweni/units/bigints/UInt32Test.java
@@ -863,4 +863,8 @@ class UInt32Test {
assertEquals(4294967295L, UInt32.MAX_VALUE.toLong());
}
+ @Test
+ void testToDecimalString() {
+ assertEquals("3456", UInt32.valueOf(3456).toDecimalString());
+ }
}
diff --git a/units/src/test/java/org/apache/tuweni/units/bigints/UInt384Test.java b/units/src/test/java/org/apache/tuweni/units/bigints/UInt384Test.java
index a8f4d22..8e3957b 100644
--- a/units/src/test/java/org/apache/tuweni/units/bigints/UInt384Test.java
+++ b/units/src/test/java/org/apache/tuweni/units/bigints/UInt384Test.java
@@ -1096,4 +1096,9 @@ class UInt384Test {
String msg = String.format("Expected %s but got %s", expected.toHexString(), actual.toHexString());
assertEquals(expected, actual, msg);
}
+
+ @Test
+ void testToDecimalString() {
+ assertEquals("3456", UInt384.valueOf(3456).toDecimalString());
+ }
}
diff --git a/units/src/test/java/org/apache/tuweni/units/bigints/UInt64Test.java b/units/src/test/java/org/apache/tuweni/units/bigints/UInt64Test.java
index 8d64fb3..bbfc7e3 100644
--- a/units/src/test/java/org/apache/tuweni/units/bigints/UInt64Test.java
+++ b/units/src/test/java/org/apache/tuweni/units/bigints/UInt64Test.java
@@ -848,4 +848,9 @@ class UInt64Test {
String msg = String.format("Expected %s but got %s", expected.toHexString(), actual.toHexString());
assertEquals(expected, actual, msg);
}
+
+ @Test
+ void testToDecimalString() {
+ assertEquals("3456", UInt64.valueOf(3456).toDecimalString());
+ }
}
diff --git a/units/src/test/java/org/apache/tuweni/units/ethereum/WeiTest.java b/units/src/test/java/org/apache/tuweni/units/ethereum/WeiTest.java
index e056867..f9113d9 100644
--- a/units/src/test/java/org/apache/tuweni/units/ethereum/WeiTest.java
+++ b/units/src/test/java/org/apache/tuweni/units/ethereum/WeiTest.java
@@ -16,6 +16,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotSame;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.apache.tuweni.units.bigints.UInt256;
import java.math.BigInteger;
import java.util.ArrayList;
@@ -65,4 +68,21 @@ class WeiTest {
void testFromEth() {
assertEquals(Wei.valueOf((long) Math.pow(10, 18)), Wei.fromEth(1));
}
+
+ @Test
+ void testToInt() {
+ assertTrue(Wei.valueOf(100L).fitsInt());
+ assertEquals(100, Wei.valueOf(100L).toInt());
+ }
+
+ @Test
+ void testToLong() {
+ assertTrue(Wei.valueOf(100L).fitsLong());
+ assertEquals(100L, Wei.valueOf(100L).toLong());
+ }
+
+ @Test
+ void toBigIntegerIsPositive() {
+ assertEquals(1, Wei.valueOf(UInt256.MAX_VALUE).toBigInteger().signum());
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@tuweni.apache.org
For additional commands, e-mail: commits-help@tuweni.apache.org