Merge remote-tracking branch 'origin/master'
Conflicts: src/main/java/org/ethereum/util/ByteUtil.java
This commit is contained in:
commit
f94862bc95
|
@ -150,13 +150,6 @@ mvn clean package -Dmaven.test.skip=true
|
|||
<version>1.1.1</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>16.0.1</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -1,56 +1,48 @@
|
|||
package org.ethereum.db;
|
||||
|
||||
import com.google.common.primitives.UnsignedBytes;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.ethereum.util.FastByteComparisons;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
*
|
||||
* @author: Roman Mandeleil
|
||||
* Created on: 11/06/2014 15:02
|
||||
* @author: Roman Mandeleil Created on: 11/06/2014 15:02
|
||||
*/
|
||||
|
||||
public class ByteArrayWrapper implements Comparable{
|
||||
public class ByteArrayWrapper implements Comparable<ByteArrayWrapper> {
|
||||
|
||||
private final byte[] data;
|
||||
|
||||
public ByteArrayWrapper(byte[] data)
|
||||
{
|
||||
if (data == null)
|
||||
{
|
||||
public ByteArrayWrapper(byte[] data) {
|
||||
if (data == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other)
|
||||
{
|
||||
if (!(other instanceof ByteArrayWrapper))
|
||||
{
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof ByteArrayWrapper)) {
|
||||
return false;
|
||||
}
|
||||
return Arrays.equals(data, ((ByteArrayWrapper)other).data);
|
||||
byte[] otherData = ((ByteArrayWrapper) other).getData();
|
||||
return FastByteComparisons.compareTo(
|
||||
data, 0, data.length,
|
||||
otherData, 0, otherData.length) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ByteArrayWrapper o) {
|
||||
return FastByteComparisons.compareTo(
|
||||
data, 0, data.length,
|
||||
o.getData(), 0, o.getData().length);
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Object second) {
|
||||
|
||||
Comparator<byte[]> comparator = UnsignedBytes.lexicographicalComparator();
|
||||
|
||||
return comparator.compare(this.data, ((ByteArrayWrapper)second).getData());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,11 +2,9 @@ package org.ethereum.json;
|
|||
|
||||
import org.ethereum.vm.DataWord;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.JSONValue;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
|
@ -18,14 +16,12 @@ import java.util.*;
|
|||
|
||||
public class JSONHelper {
|
||||
|
||||
|
||||
|
||||
public static String dumpLine(byte[] address, byte[] nonce, byte[] balance, byte[] stateRoot,
|
||||
byte[] codeHash, byte[] code, Map<DataWord, DataWord> storageMap){
|
||||
|
||||
// {address: x, nonce: n1, balance: b1, stateRoot: s1, codeHash: c1, code: c2, sotrage: [key: k1, value: v1, key:k2, value: v2 ] }
|
||||
|
||||
ArrayList<DataWord> storageKeys = new ArrayList(storageMap.keySet());
|
||||
List<DataWord> storageKeys = new ArrayList<DataWord>(storageMap.keySet());
|
||||
Collections.sort((List)storageKeys);
|
||||
|
||||
Map outMap = new LinkedHashMap();
|
||||
|
|
|
@ -111,7 +111,7 @@ public class ClientPeer {
|
|||
|
||||
ByteBuf buffer = channel.alloc().buffer(payload.length + 8);
|
||||
buffer.writeBytes(StaticMessages.MAGIC_PACKET);
|
||||
buffer.writeBytes(ByteUtil.calcPacketSize(payload));
|
||||
buffer.writeBytes(ByteUtil.calcPacketLength(payload));
|
||||
buffer.writeBytes(payload);
|
||||
|
||||
logger.info("Send msg: [ " +
|
||||
|
|
|
@ -361,7 +361,7 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
|
|||
|
||||
ByteBuf buffer = ctx.alloc().buffer(chainMessage.getPayload().length + 8);
|
||||
buffer.writeBytes(StaticMessages.MAGIC_PACKET);
|
||||
buffer.writeBytes(ByteUtil.calcPacketSize(chainMessage.getPayload()));
|
||||
buffer.writeBytes(ByteUtil.calcPacketLength(chainMessage.getPayload()));
|
||||
buffer.writeBytes(chainMessage.getPayload());
|
||||
|
||||
ctx.writeAndFlush(buffer);
|
||||
|
|
|
@ -6,12 +6,9 @@ package org.ethereum.trie;
|
|||
* @author: Roman Mandeleil
|
||||
* Created on: 11/06/2014 19:44
|
||||
*/
|
||||
|
||||
public interface TrieFacade {
|
||||
|
||||
public void update(byte[] key, byte[] value);
|
||||
public byte[] get(byte[] key);
|
||||
public void delete(byte[] key);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -47,19 +47,6 @@ public class ByteUtil {
|
|||
else return Hex.toHexString(data);
|
||||
}
|
||||
|
||||
// The packet size should be 4 byte long
|
||||
public static byte[] calcPacketSize(byte[] packet){
|
||||
|
||||
byte[] size = new byte[4];
|
||||
|
||||
size[0] = (byte)(packet.length >> 24 & 0xFF);
|
||||
size[1] = (byte)(packet.length >> 16 & 0xFF);
|
||||
size[2] = (byte)(packet.length >> 8 & 0xFF);
|
||||
size[3] = (byte)(packet.length >> 0 & 0xFF);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate packet length
|
||||
* @param msg
|
||||
|
@ -118,17 +105,13 @@ public class ByteUtil {
|
|||
byte[] data;
|
||||
|
||||
// check if the string is numeric
|
||||
if (arg.toString().trim().matches("-?\\d+(\\.\\d+)?")) {
|
||||
if (arg.toString().trim().matches("-?\\d+(\\.\\d+)?"))
|
||||
data = new BigInteger(arg.toString().trim()).toByteArray();
|
||||
|
||||
// check if it's hex number
|
||||
} else if (arg.toString().trim().matches("0[xX][0-9a-fA-F]+")){
|
||||
else if (arg.toString().trim().matches("0[xX][0-9a-fA-F]+"))
|
||||
data = new BigInteger(arg.toString().trim().substring(2), 16).toByteArray();
|
||||
|
||||
} else {
|
||||
else
|
||||
data = arg.toString().trim().getBytes();
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (data.length > 32)
|
||||
|
@ -160,30 +143,23 @@ public class ByteUtil {
|
|||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
public static byte[] stripLeadingZeroes(byte[] data) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static byte[] stripLeadingZeroes(byte[] data){
|
||||
|
||||
if (data == null) return null;
|
||||
if (data == null)
|
||||
return null;
|
||||
|
||||
int firstNonZero = 0;
|
||||
int i = 0;
|
||||
for (i = 0; i < data.length; ++i)
|
||||
if (data[i] != 0){
|
||||
for (i = 0; i < data.length; ++i) {
|
||||
if (data[i] != 0) {
|
||||
firstNonZero = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == data.length) return new byte[1];
|
||||
if (firstNonZero == 0) return data;
|
||||
}
|
||||
if (i == data.length)
|
||||
return new byte[1];
|
||||
if (firstNonZero == 0)
|
||||
return data;
|
||||
|
||||
byte[] result = new byte[data.length - firstNonZero];
|
||||
System.arraycopy(data, firstNonZero, result, 0, data.length - firstNonZero);
|
||||
|
|
|
@ -3,7 +3,6 @@ package org.ethereum.core;
|
|||
import java.math.BigInteger;
|
||||
|
||||
import org.ethereum.manager.WorldManager;
|
||||
import org.ethereum.net.message.StaticMessages;
|
||||
import org.ethereum.util.ByteUtil;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import org.ethereum.core.Block;
|
||||
|
|
|
@ -3,13 +3,7 @@ package org.ethereum.core;
|
|||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.ethereum.util.ByteUtil;
|
||||
import org.ethereum.util.FastByteComparisons;
|
||||
import org.junit.Test;
|
||||
import org.spongycastle.util.BigIntegers;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
public class MinerTest {
|
||||
|
@ -68,40 +62,4 @@ public class MinerTest {
|
|||
newBlock.setStateRoot(Hex.decode("50188ab86bdf164ac90eb2835a04a8930aae5393c3a2ef1166fb95028f9456b8"));
|
||||
return newBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* This test shows the difference between iterating over,
|
||||
* and comparing byte[] vs BigInteger value.
|
||||
*
|
||||
* Results indicate that the former has ~15x better performance.
|
||||
* Therefore this is used in the Miner.mine() method.
|
||||
*/
|
||||
@Test
|
||||
public void testIncrementPerformance() {
|
||||
boolean testEnabled = false;
|
||||
|
||||
if(testEnabled) {
|
||||
byte[] counter1 = new byte[4];
|
||||
byte[] max = ByteBuffer.allocate(4).putInt(Integer.MAX_VALUE).array();
|
||||
long start1 = System.currentTimeMillis();
|
||||
while(ByteUtil.increment(counter1)) {
|
||||
if(FastByteComparisons.compareTo(counter1, 0, 4, max, 0, 4) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
System.out.println(System.currentTimeMillis() - start1 + "ms to reach: " + Hex.toHexString(counter1));
|
||||
|
||||
BigInteger counter2 = BigInteger.ZERO;
|
||||
long start2 = System.currentTimeMillis();
|
||||
while(true) {
|
||||
if(counter2.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) == 0) {
|
||||
break;
|
||||
}
|
||||
counter2 = counter2.add(BigInteger.ONE);
|
||||
|
||||
}
|
||||
System.out.println(System.currentTimeMillis() - start2 + "ms to reach: " + Hex.toHexString(BigIntegers.asUnsignedByteArray(4, counter2)));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
package org.ethereum.db;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.ethereum.util.FastByteComparisons;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
import com.google.common.primitives.UnsignedBytes;
|
||||
|
||||
public class ByteArrayWrapperTest {
|
||||
|
||||
static ByteArrayWrapper wrapper1;
|
||||
static ByteArrayWrapper wrapper2;
|
||||
static ByteArrayWrapper wrapper3;
|
||||
static ByteArrayWrapper wrapper4;
|
||||
|
||||
@BeforeClass
|
||||
public static void loadByteArrays() {
|
||||
|
||||
String block = "f9072df8d3a077ef4fdaf389dca53236bcf7f72698e154eab2828f86fbc4fc6c"
|
||||
+ "d9225d285c89a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0"
|
||||
+ "a142fd40d493479476f5eabe4b342ee56b8ceba6ab2a770c3e2198e7a0faa0ca"
|
||||
+ "43105f667dceb168eb4e0cdc98ef28a9da5c381edef70d843207601719a06785"
|
||||
+ "f3860460b2aa29122698e83a5151b270e82532c1663e89e3df8c5445b8ca833f"
|
||||
+ "f000018609184e72a000830f3e6f8227d2845387c58f80a00000000000000000"
|
||||
+ "0000000000000000000000000000000094148d7738f78c04f90654f8c6f8a080"
|
||||
+ "8609184e72a00082271094000000000000000000000000000000000000000080"
|
||||
+ "b83a33604557602a5160106000396000f200604556330e0f602a59366000530a"
|
||||
+ "0f602a596020600053013560005335576040600053016000546009581ca033a6"
|
||||
+ "bfa5eb2f4b63f1b98bed9a987d096d32e56deecb050367c84955508f5365a015"
|
||||
+ "034e7574ec073f0c448aac1d9f844387610dfef5342834b6825fbc35df5913a0"
|
||||
+ "ee258e73d41ada73d8d6071ba7d236fbbe24fcfb9627fbd4310e24ffd87b961a"
|
||||
+ "8203e9f90194f9016d018609184e72a000822710940000000000000000000000"
|
||||
+ "00000000000000000080b901067f4e616d655265670000000000000000000000"
|
||||
+ "00000000000000000000000000003057307f4e616d6552656700000000000000"
|
||||
+ "000000000000000000000000000000000000577f436f6e666967000000000000"
|
||||
+ "000000000000000000000000000000000000000073ccdeac59d35627b7de0933"
|
||||
+ "2e819d5159e7bb72505773ccdeac59d35627b7de09332e819d5159e7bb72507f"
|
||||
+ "436f6e6669670000000000000000000000000000000000000000000000000000"
|
||||
+ "57336045576041516100c56000396000f20036602259604556330e0f600f5933"
|
||||
+ "ff33560f601e5960003356576000335700604158600035560f602b590033560f"
|
||||
+ "603659600033565733600035576000353357001ca0f3c527e484ea5546189979"
|
||||
+ "c767b69aa9f1ad5a6f4b6077d4bccf5142723a67c9a069a4a29a2a315102fcd0"
|
||||
+ "822d39ad696a6d7988c993bb2b911cc2a78bb8902d91a01ebe4782ea3ed224cc"
|
||||
+ "bb777f5de9ee7b5bbb282ac08f7fa0ef95d3d1c1c6d1a1820ef7f8ccf8a60286"
|
||||
+ "09184e72a00082271094ccdeac59d35627b7de09332e819d5159e7bb725080b8"
|
||||
+ "4000000000000000000000000000000000000000000000000000000000000000"
|
||||
+ "000000000000000000000000002d0aceee7e5ab874e22ccf8d1a649f59106d74"
|
||||
+ "e81ba095ad45bf574c080e4d72da2cfd3dbe06cc814c1c662b5f74561f13e1e7"
|
||||
+ "5058f2a057745a3db5482bccb5db462922b074f4b79244c4b1fa811ed094d728"
|
||||
+ "e7b6da92a08599ea5d6cb6b9ad3311f0d82a3337125e05f4a82b9b0556cb3776"
|
||||
+ "a6e1a02f8782132df8abf885038609184e72a000822710942d0aceee7e5ab874"
|
||||
+ "e22ccf8d1a649f59106d74e880a0476176000000000000000000000000000000"
|
||||
+ "00000000000000000000000000001ca09b5fdabd54ebc284249d2d2df6d43875"
|
||||
+ "cb86c52bd2bac196d4f064c8ade054f2a07b33f5c8b277a408ec38d2457441d2"
|
||||
+ "af32e55681c8ecb28eef3d2a152e8db5a9a0227a67fceb1bf4ddd31a7047e24b"
|
||||
+ "e93c947ab3b539471555bb3509ed6e393c8e82178df90277f90250048609184e"
|
||||
+ "72a0008246dd94000000000000000000000000000000000000000080b901e961"
|
||||
+ "010033577f476176436f696e0000000000000000000000000000000000000000"
|
||||
+ "000000000060005460006000600760006000732d0aceee7e5ab874e22ccf8d1a"
|
||||
+ "649f59106d74e860645c03f150436000576000600157620f424060025761017d"
|
||||
+ "5161006c6000396000f2006020360e0f61013f59602060006000374360205460"
|
||||
+ "0056600054602056602054437f6e000000000000000000000000000000000000"
|
||||
+ "00000000000000000000000000560e0f0f61008059437f6e0000000000000000"
|
||||
+ "0000000000000000000000000000000000000000000000576000602054610400"
|
||||
+ "60005304600053036000547f6400000000000000000000000000000000000000"
|
||||
+ "0000000000000000000000005660016000030460406000200a0f61013e596001"
|
||||
+ "60205301602054600a6020530b0f6100f45961040060005304600053017f6400"
|
||||
+ "0000000000000000000000000000000000000000000000000000000000005760"
|
||||
+ "20537f6900000000000000000000000000000000000000000000000000000000"
|
||||
+ "000000576000537f640000000000000000000000000000000000000000000000"
|
||||
+ "000000000000000057006040360e0f0f61014a59003356604054600035566060"
|
||||
+ "546020356080546080536040530a0f6101695900608053604053033357608053"
|
||||
+ "60605301600035571ba0190fc7ab634dc497fe1656fde523a4c26926d51a93db"
|
||||
+ "2ba37af8e83c3741225da066ae0ec1217b0ca698a5369d4881e1c4cbde56af99"
|
||||
+ "31ebf9281580a23b659c08a051f947cb2315d0259f55848c630caa10cd91d6e4"
|
||||
+ "4ff8bad7758c65b25e2191308227d2c0";
|
||||
|
||||
byte[] test1 = Hex.decode(block);
|
||||
byte[] test2 = Hex.decode(block);
|
||||
byte[] test3 = Hex.decode("4ff8bad7758c65b25e2191308227d2c0");
|
||||
byte[] test4 = Hex.decode("");
|
||||
|
||||
wrapper1 = new ByteArrayWrapper(test1);
|
||||
wrapper2 = new ByteArrayWrapper(test2);
|
||||
wrapper3 = new ByteArrayWrapper(test3);
|
||||
wrapper4 = new ByteArrayWrapper(test4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEqualsObject() {
|
||||
assertTrue(wrapper1.equals(wrapper2));
|
||||
assertFalse(wrapper1.equals(wrapper3));
|
||||
assertFalse(wrapper1.equals(wrapper4));
|
||||
assertFalse(wrapper1.equals(null));
|
||||
assertFalse(wrapper2.equals(wrapper3));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompareTo() {
|
||||
assertTrue(wrapper1.compareTo(wrapper2) == 0);
|
||||
assertTrue(wrapper1.compareTo(wrapper3) > 1);
|
||||
assertTrue(wrapper1.compareTo(wrapper4) > 1);
|
||||
assertTrue(wrapper2.compareTo(wrapper3) > 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEqualsPerformance() {
|
||||
boolean testEnabled = false;
|
||||
|
||||
if(testEnabled) {
|
||||
final int ITERATIONS = 10000000;
|
||||
long start1 = System.currentTimeMillis();
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
Comparator<byte[]> comparator = UnsignedBytes
|
||||
.lexicographicalComparator();
|
||||
|
||||
comparator.compare(wrapper1.getData(),
|
||||
wrapper2.getData());
|
||||
}
|
||||
System.out.println(System.currentTimeMillis() - start1 + "ms");
|
||||
|
||||
long start2 = System.currentTimeMillis();
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
Arrays.equals(wrapper1.getData(), wrapper2.getData());
|
||||
}
|
||||
System.out.println(System.currentTimeMillis() - start2 + "ms");
|
||||
|
||||
long start3 = System.currentTimeMillis();
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
FastByteComparisons.compareTo(wrapper1.getData(), 0, wrapper1.getData().length, wrapper2.getData(), 0, wrapper1.getData().length);
|
||||
}
|
||||
System.out.println(System.currentTimeMillis() - start3 + "ms");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -436,7 +436,7 @@ public class MessagesTest {
|
|||
|
||||
assertEquals(expected, Hex.toHexString(getChainMessage.getPayload()).toUpperCase());
|
||||
|
||||
byte[] size = ByteUtil.calcPacketSize( getChainMessage.getPayload());
|
||||
byte[] size = ByteUtil.calcPacketLength( getChainMessage.getPayload());
|
||||
|
||||
assertEquals("00000067", Hex.toHexString(size));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
package org.ethereum.util;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.spongycastle.util.BigIntegers;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
public class ByteUtilTest {
|
||||
|
||||
@Test
|
||||
public void testAppendByte() {
|
||||
byte[] bytes = "tes".getBytes();
|
||||
byte b = 0x74;
|
||||
assertArrayEquals("test".getBytes(), ByteUtil.appendByte(bytes, b));
|
||||
}
|
||||
|
||||
// @Test
|
||||
// public void testBigIntegerToBytes() {
|
||||
// fail("Not yet implemented");
|
||||
// }
|
||||
|
||||
@Test
|
||||
public void testToHexString() {
|
||||
assertEquals("null", ByteUtil.toHexString(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCalcPacketLength() {
|
||||
byte[] test = new byte[] { 0x0f, 0x10, 0x43 };
|
||||
byte[] expected = new byte[] { 0x00, 0x00, 0x00, 0x03 };
|
||||
assertArrayEquals(expected, ByteUtil.calcPacketLength(test));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testByteArrayToInt() {
|
||||
assertEquals(0, ByteUtil.byteArrayToInt(null));
|
||||
assertEquals(0, ByteUtil.byteArrayToInt(new byte[0]));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNumBytes() {
|
||||
String test1 = "0";
|
||||
String test2 = "1";
|
||||
String test3 = "1000000000"; //3B9ACA00
|
||||
int expected1 = 1;
|
||||
int expected2 = 1;
|
||||
int expected3 = 4;
|
||||
assertEquals(expected1, ByteUtil.numBytes(test1));
|
||||
assertEquals(expected2, ByteUtil.numBytes(test2));
|
||||
assertEquals(expected3, ByteUtil.numBytes(test3));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStripLeadingZeroes() {
|
||||
byte[] test1 = new byte[] { 0x00, 0x01 };
|
||||
byte[] test2 = new byte[] { 0x00, 0x00, 0x01 };
|
||||
byte[] expected = new byte[] { 0x01 };
|
||||
assertArrayEquals(expected, ByteUtil.stripLeadingZeroes(test1));
|
||||
assertArrayEquals(expected, ByteUtil.stripLeadingZeroes(test2));
|
||||
}
|
||||
|
||||
/**
|
||||
* This test shows the difference between iterating over,
|
||||
* and comparing byte[] vs BigInteger value.
|
||||
*
|
||||
* Results indicate that the former has ~15x better performance.
|
||||
* Therefore this is used in the Miner.mine() method.
|
||||
*/
|
||||
@Test
|
||||
public void testIncrementPerformance() {
|
||||
boolean testEnabled = false;
|
||||
|
||||
if(testEnabled) {
|
||||
byte[] counter1 = new byte[4];
|
||||
byte[] max = ByteBuffer.allocate(4).putInt(Integer.MAX_VALUE).array();
|
||||
long start1 = System.currentTimeMillis();
|
||||
while(ByteUtil.increment(counter1)) {
|
||||
if(FastByteComparisons.compareTo(counter1, 0, 4, max, 0, 4) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
System.out.println(System.currentTimeMillis() - start1 + "ms to reach: " + Hex.toHexString(counter1));
|
||||
|
||||
BigInteger counter2 = BigInteger.ZERO;
|
||||
long start2 = System.currentTimeMillis();
|
||||
while(true) {
|
||||
if(counter2.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) == 0) {
|
||||
break;
|
||||
}
|
||||
counter2 = counter2.add(BigInteger.ONE);
|
||||
}
|
||||
System.out.println(System.currentTimeMillis() - start2 + "ms to reach: " + Hex.toHexString(BigIntegers.asUnsignedByteArray(4, counter2)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue