Convert all files to unix line endings
This commit is contained in:
parent
9f9d864036
commit
c7cb5231fe
|
@ -1,66 +1,66 @@
|
|||
package org.ethereum.jsontestsuite;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
|
||||
import org.ethereum.config.SystemProperties;
|
||||
|
||||
public class JSONReader {
|
||||
|
||||
public static String loadJSON(String filename) {
|
||||
String json = "";
|
||||
if(!SystemProperties.CONFIG.vmTestLoadLocal())
|
||||
json = getFromUrl("https://raw.githubusercontent.com/ethereum/tests/develop/" + filename);
|
||||
return json == "" ? json = getFromLocal(filename) : json;
|
||||
}
|
||||
|
||||
public static String getFromLocal(String filename) {
|
||||
System.out.println("Loading local file: " + filename);
|
||||
try {
|
||||
if(System.getProperty("ETHEREUM_TEST_PATH") == null) {
|
||||
System.out.println("ETHEREUM_TEST_PATH is not passed as a VM argument, please make sure you pass it with the correct path");
|
||||
return "";
|
||||
}
|
||||
System.out.println("From: " + System.getProperty("ETHEREUM_TEST_PATH"));
|
||||
File vmTestFile = new File(System.getProperty("ETHEREUM_TEST_PATH") + filename);
|
||||
return new String(Files.readAllBytes(vmTestFile.toPath()));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static String getFromUrl(String urlToRead) {
|
||||
URL url;
|
||||
HttpURLConnection conn;
|
||||
BufferedReader rd;
|
||||
String line;
|
||||
String result = "";
|
||||
try {
|
||||
url = new URL(urlToRead);
|
||||
conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setRequestMethod("GET");
|
||||
conn.setDoOutput(true);
|
||||
conn.connect();
|
||||
InputStream in = conn.getInputStream();
|
||||
rd = new BufferedReader(new InputStreamReader(in));
|
||||
System.out.println("Loading remote file: " + urlToRead);
|
||||
while ((line = rd.readLine()) != null) {
|
||||
result += line;
|
||||
}
|
||||
rd.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
package org.ethereum.jsontestsuite;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
|
||||
import org.ethereum.config.SystemProperties;
|
||||
|
||||
public class JSONReader {
|
||||
|
||||
public static String loadJSON(String filename) {
|
||||
String json = "";
|
||||
if(!SystemProperties.CONFIG.vmTestLoadLocal())
|
||||
json = getFromUrl("https://raw.githubusercontent.com/ethereum/tests/develop/" + filename);
|
||||
return json == "" ? json = getFromLocal(filename) : json;
|
||||
}
|
||||
|
||||
public static String getFromLocal(String filename) {
|
||||
System.out.println("Loading local file: " + filename);
|
||||
try {
|
||||
if(System.getProperty("ETHEREUM_TEST_PATH") == null) {
|
||||
System.out.println("ETHEREUM_TEST_PATH is not passed as a VM argument, please make sure you pass it with the correct path");
|
||||
return "";
|
||||
}
|
||||
System.out.println("From: " + System.getProperty("ETHEREUM_TEST_PATH"));
|
||||
File vmTestFile = new File(System.getProperty("ETHEREUM_TEST_PATH") + filename);
|
||||
return new String(Files.readAllBytes(vmTestFile.toPath()));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static String getFromUrl(String urlToRead) {
|
||||
URL url;
|
||||
HttpURLConnection conn;
|
||||
BufferedReader rd;
|
||||
String line;
|
||||
String result = "";
|
||||
try {
|
||||
url = new URL(urlToRead);
|
||||
conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setRequestMethod("GET");
|
||||
conn.setDoOutput(true);
|
||||
conn.connect();
|
||||
InputStream in = conn.getInputStream();
|
||||
rd = new BufferedReader(new InputStreamReader(in));
|
||||
System.out.println("Loading remote file: " + urlToRead);
|
||||
while ((line = rd.readLine()) != null) {
|
||||
result += line;
|
||||
}
|
||||
rd.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -1,48 +1,48 @@
|
|||
package org.ethereum.net.client;
|
||||
|
||||
/**
|
||||
* The protocols and versions of those protocols that this peer support
|
||||
*/
|
||||
public class Capability implements Comparable<Capability> {
|
||||
|
||||
public final static String P2P = "p2p";
|
||||
public final static String ETH = "eth";
|
||||
public final static String SHH = "shh";
|
||||
|
||||
private String name;
|
||||
private byte version;
|
||||
|
||||
public Capability(String name, byte version) {
|
||||
this.name = name;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public byte getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof Capability)) return false;
|
||||
|
||||
Capability other = (Capability)obj;
|
||||
if (this.name == null)
|
||||
return other.name == null;
|
||||
else
|
||||
return this.name.equals(other.name) && this.version == other.version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Capability o) {
|
||||
return this.name.compareTo(o.name);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return name + ":" + version;
|
||||
}
|
||||
package org.ethereum.net.client;
|
||||
|
||||
/**
|
||||
* The protocols and versions of those protocols that this peer support
|
||||
*/
|
||||
public class Capability implements Comparable<Capability> {
|
||||
|
||||
public final static String P2P = "p2p";
|
||||
public final static String ETH = "eth";
|
||||
public final static String SHH = "shh";
|
||||
|
||||
private String name;
|
||||
private byte version;
|
||||
|
||||
public Capability(String name, byte version) {
|
||||
this.name = name;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public byte getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof Capability)) return false;
|
||||
|
||||
Capability other = (Capability)obj;
|
||||
if (this.name == null)
|
||||
return other.name == null;
|
||||
else
|
||||
return this.name.equals(other.name) && this.version == other.version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Capability o) {
|
||||
return this.name.compareTo(o.name);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return name + ":" + version;
|
||||
}
|
||||
}
|
|
@ -1,80 +1,80 @@
|
|||
package org.ethereum.net.message;
|
||||
|
||||
import org.ethereum.net.eth.*;
|
||||
import org.ethereum.net.p2p.*;
|
||||
import org.ethereum.net.shh.ShhMessageCodes;
|
||||
import org.ethereum.util.RLP;
|
||||
|
||||
/**
|
||||
* Factory to create protocol message objects based on the RLP encoded data
|
||||
*/
|
||||
public class MessageFactory {
|
||||
|
||||
public static Message createMessage(byte[] encoded) {
|
||||
byte code = RLP.getCommandCode(encoded);
|
||||
|
||||
if (P2pMessageCodes.inRange(code)){
|
||||
|
||||
P2pMessageCodes receivedCommand = P2pMessageCodes.fromByte(code);
|
||||
switch (receivedCommand) {
|
||||
case HELLO:
|
||||
return new HelloMessage(encoded);
|
||||
case DISCONNECT:
|
||||
return new DisconnectMessage(encoded);
|
||||
case PING:
|
||||
return StaticMessages.PING_MESSAGE;
|
||||
case PONG:
|
||||
return StaticMessages.PONG_MESSAGE;
|
||||
case GET_PEERS:
|
||||
return StaticMessages.GET_PEERS_MESSAGE;
|
||||
case PEERS:
|
||||
return new PeersMessage(encoded);
|
||||
}
|
||||
}
|
||||
|
||||
if (EthMessageCodes.inRange(code)) {
|
||||
|
||||
EthMessageCodes receivedCommand = EthMessageCodes.fromByte(code);
|
||||
switch (receivedCommand) {
|
||||
case STATUS:
|
||||
return new StatusMessage(encoded);
|
||||
case GET_TRANSACTIONS:
|
||||
return StaticMessages.GET_TRANSACTIONS_MESSAGE;
|
||||
case TRANSACTIONS:
|
||||
return new TransactionsMessage(encoded);
|
||||
case GET_BLOCK_HASHES:
|
||||
return new GetBlockHashesMessage(encoded);
|
||||
case BLOCK_HASHES:
|
||||
return new BlockHashesMessage(encoded);
|
||||
case GET_BLOCKS:
|
||||
return new GetBlocksMessage(encoded);
|
||||
case BLOCKS:
|
||||
return new BlocksMessage(encoded);
|
||||
case NEW_BLOCK:
|
||||
return new NewBlockMessage(encoded);
|
||||
case PACKET_COUNT:
|
||||
return new PacketCountMessage(encoded);
|
||||
}
|
||||
}
|
||||
|
||||
if (ShhMessageCodes.inRange(code)) {
|
||||
|
||||
ShhMessageCodes receivedCommand = ShhMessageCodes.fromByte(code);
|
||||
switch (receivedCommand) {
|
||||
case STATUS:
|
||||
break;
|
||||
case MESSAGE:
|
||||
break;
|
||||
case ADD_FILTER:
|
||||
break;
|
||||
case REMOVE_FILTER:
|
||||
break;
|
||||
case PACKET_COUNT:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("No such message");
|
||||
}
|
||||
|
||||
}
|
||||
package org.ethereum.net.message;
|
||||
|
||||
import org.ethereum.net.eth.*;
|
||||
import org.ethereum.net.p2p.*;
|
||||
import org.ethereum.net.shh.ShhMessageCodes;
|
||||
import org.ethereum.util.RLP;
|
||||
|
||||
/**
|
||||
* Factory to create protocol message objects based on the RLP encoded data
|
||||
*/
|
||||
public class MessageFactory {
|
||||
|
||||
public static Message createMessage(byte[] encoded) {
|
||||
byte code = RLP.getCommandCode(encoded);
|
||||
|
||||
if (P2pMessageCodes.inRange(code)){
|
||||
|
||||
P2pMessageCodes receivedCommand = P2pMessageCodes.fromByte(code);
|
||||
switch (receivedCommand) {
|
||||
case HELLO:
|
||||
return new HelloMessage(encoded);
|
||||
case DISCONNECT:
|
||||
return new DisconnectMessage(encoded);
|
||||
case PING:
|
||||
return StaticMessages.PING_MESSAGE;
|
||||
case PONG:
|
||||
return StaticMessages.PONG_MESSAGE;
|
||||
case GET_PEERS:
|
||||
return StaticMessages.GET_PEERS_MESSAGE;
|
||||
case PEERS:
|
||||
return new PeersMessage(encoded);
|
||||
}
|
||||
}
|
||||
|
||||
if (EthMessageCodes.inRange(code)) {
|
||||
|
||||
EthMessageCodes receivedCommand = EthMessageCodes.fromByte(code);
|
||||
switch (receivedCommand) {
|
||||
case STATUS:
|
||||
return new StatusMessage(encoded);
|
||||
case GET_TRANSACTIONS:
|
||||
return StaticMessages.GET_TRANSACTIONS_MESSAGE;
|
||||
case TRANSACTIONS:
|
||||
return new TransactionsMessage(encoded);
|
||||
case GET_BLOCK_HASHES:
|
||||
return new GetBlockHashesMessage(encoded);
|
||||
case BLOCK_HASHES:
|
||||
return new BlockHashesMessage(encoded);
|
||||
case GET_BLOCKS:
|
||||
return new GetBlocksMessage(encoded);
|
||||
case BLOCKS:
|
||||
return new BlocksMessage(encoded);
|
||||
case NEW_BLOCK:
|
||||
return new NewBlockMessage(encoded);
|
||||
case PACKET_COUNT:
|
||||
return new PacketCountMessage(encoded);
|
||||
}
|
||||
}
|
||||
|
||||
if (ShhMessageCodes.inRange(code)) {
|
||||
|
||||
ShhMessageCodes receivedCommand = ShhMessageCodes.fromByte(code);
|
||||
switch (receivedCommand) {
|
||||
case STATUS:
|
||||
break;
|
||||
case MESSAGE:
|
||||
break;
|
||||
case ADD_FILTER:
|
||||
break;
|
||||
case REMOVE_FILTER:
|
||||
break;
|
||||
case PACKET_COUNT:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("No such message");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,354 +1,354 @@
|
|||
package org.ethereum.util;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.ethereum.db.ByteArrayWrapper;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
public class ByteUtil {
|
||||
|
||||
public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
|
||||
public static final byte[] ZERO_BYTE_ARRAY = new byte[]{0};
|
||||
|
||||
/**
|
||||
* Creates a copy of bytes and appends b to the end of it
|
||||
*/
|
||||
public static byte[] appendByte(byte[] bytes, byte b) {
|
||||
byte[] result = Arrays.copyOf(bytes, bytes.length + 1);
|
||||
result[result.length - 1] = b;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* The regular {@link java.math.BigInteger#toByteArray()} method isn't quite what we often need:
|
||||
* it appends a leading zero to indicate that the number is positive and may need padding.
|
||||
*
|
||||
* @param b the integer to format into a byte array
|
||||
* @param numBytes the desired size of the resulting byte array
|
||||
* @return numBytes byte long array.
|
||||
*/
|
||||
public static byte[] bigIntegerToBytes(BigInteger b, int numBytes) {
|
||||
if (b == null)
|
||||
return null;
|
||||
byte[] bytes = new byte[numBytes];
|
||||
byte[] biBytes = b.toByteArray();
|
||||
int start = (biBytes.length == numBytes + 1) ? 1 : 0;
|
||||
int length = Math.min(biBytes.length, numBytes);
|
||||
System.arraycopy(biBytes, start, bytes, numBytes - length, length);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Omitting sign indication byte.
|
||||
* <br><br>
|
||||
* Instead of {@link org.spongycastle.util.BigIntegers#asUnsignedByteArray(BigInteger)}
|
||||
* <br>we use this custom method to avoid an empty array in case of BigInteger.ZERO
|
||||
*
|
||||
* @param value - any big integer number. A <code>null</code>-value will return <code>null</code>
|
||||
* @return A byte array without a leading zero byte if present in the signed encoding.
|
||||
* BigInteger.ZERO will return an array with length 1 and byte-value 0.
|
||||
*/
|
||||
public static byte[] bigIntegerToBytes(BigInteger value) {
|
||||
if (value == null)
|
||||
return null;
|
||||
|
||||
byte[] data = value.toByteArray();
|
||||
|
||||
if (data.length != 1 && data[0] == 0) {
|
||||
byte[] tmp = new byte[data.length - 1];
|
||||
System.arraycopy(data, 1, tmp, 0, tmp.length);
|
||||
data = tmp;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amount of nibbles that match each other from 0 ...
|
||||
* amount will never be larger than smallest input
|
||||
*
|
||||
* @param a - first input
|
||||
* @param b - second input
|
||||
* @return Number of bytes that match
|
||||
*/
|
||||
public static int matchingNibbleLength(byte[] a, byte[] b) {
|
||||
int i = 0;
|
||||
int length = a.length < b.length ? a.length : b.length;
|
||||
while (i < length) {
|
||||
if (a[i] != b[i])
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a long value into a byte array.
|
||||
*
|
||||
* @param val - long value to convert
|
||||
* @return <code>byte[]</code> of length 8, representing the long value
|
||||
*/
|
||||
public static byte[] longToBytes(long val) {
|
||||
return ByteBuffer.allocate(8).putLong(val).array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a byte-array into a hex String.<br>
|
||||
* Works similar to {@link Hex#toHexString}
|
||||
* but allows for <code>null</code>
|
||||
*
|
||||
* @param data - byte-array to convert to a hex-string
|
||||
* @return hex representation of the data.<br>
|
||||
* Returns an empty String if the input is <code>null</code>
|
||||
*
|
||||
* @see Hex#toHexString
|
||||
*/
|
||||
public static String toHexString(byte[] data) {
|
||||
return data == null ? "" : Hex.toHexString(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate packet length
|
||||
* @param msg byte[]
|
||||
* @return byte-array with 4 elements
|
||||
*/
|
||||
public static byte[] calcPacketLength(byte[] msg) {
|
||||
int msgLen = msg.length;
|
||||
byte[] len = {
|
||||
(byte)((msgLen >> 24) & 0xFF),
|
||||
(byte)((msgLen >> 16) & 0xFF),
|
||||
(byte)((msgLen >> 8) & 0xFF),
|
||||
(byte)((msgLen ) & 0xFF)};
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast hex encoded value from byte[] to int
|
||||
*
|
||||
* Limited to Integer.MAX_VALUE: 2^32-1 (4 bytes)
|
||||
*
|
||||
* @param b array contains the values
|
||||
* @return unsigned positive int value.
|
||||
*/
|
||||
public static int byteArrayToInt(byte[] b) {
|
||||
if (b == null || b.length == 0)
|
||||
return 0;
|
||||
return new BigInteger(1, b).intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast hex encoded value from byte[] to int
|
||||
*
|
||||
* Limited to Integer.MAX_VALUE: 2^32-1 (4 bytes)
|
||||
*
|
||||
* @param b array contains the values
|
||||
* @return unsigned positive long value.
|
||||
*/
|
||||
public static long byteArrayToLong(byte[] b) {
|
||||
if (b == null || b.length == 0)
|
||||
return 0;
|
||||
return new BigInteger(1, b).longValue();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Turn nibbles to a pretty looking output string
|
||||
*
|
||||
* Example. [ 1, 2, 3, 4, 5 ] becomes '\x11\x23\x45'
|
||||
*
|
||||
* @param nibbles - getting byte of data [ 04 ] and turning
|
||||
* it to a '\x04' representation
|
||||
* @return pretty string of nibbles
|
||||
*/
|
||||
public static String nibblesToPrettyString(byte[] nibbles){
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
for (byte nibble : nibbles) {
|
||||
String nibleString = oneByteToHexString(nibble);
|
||||
buffer.append("\\x" + nibleString);
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public static String oneByteToHexString(byte value) {
|
||||
String retVal = Integer.toString(value & 0xFF, 16);
|
||||
if (retVal.length() == 1) retVal = "0" + retVal;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the number of bytes need
|
||||
* to encode the number
|
||||
*
|
||||
* @param val - number
|
||||
* @return number of min bytes used to encode the number
|
||||
*/
|
||||
public static int numBytes(String val) {
|
||||
|
||||
BigInteger bInt = new BigInteger(val);
|
||||
int bytes = 0;
|
||||
|
||||
while(!bInt.equals(BigInteger.ZERO)) {
|
||||
bInt = bInt.shiftRight(8);
|
||||
++bytes;
|
||||
}
|
||||
if (bytes == 0) ++bytes;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param arg - not more that 32 bits
|
||||
* @return - bytes of the value pad with complete to 32 zeroes
|
||||
*/
|
||||
public static byte[] encodeValFor32Bits(Object arg) {
|
||||
|
||||
byte[] data;
|
||||
|
||||
// check if the string is numeric
|
||||
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]+"))
|
||||
data = new BigInteger(arg.toString().trim().substring(2), 16).toByteArray();
|
||||
else
|
||||
data = arg.toString().trim().getBytes();
|
||||
|
||||
|
||||
if (data.length > 32)
|
||||
throw new RuntimeException("values can't be more than 32 byte");
|
||||
|
||||
byte[] val = new byte[32];
|
||||
|
||||
int j = 0;
|
||||
for (int i = data.length; i > 0; --i) {
|
||||
val[31 - j] = data[i - 1];
|
||||
++j;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* encode the values and concatenate together
|
||||
* @param args Object
|
||||
* @return byte[]
|
||||
*/
|
||||
public static byte[] encodeDataList(Object... args) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
for (Object arg : args) {
|
||||
byte[] val = encodeValFor32Bits(arg);
|
||||
try {
|
||||
baos.write(val);
|
||||
} catch (IOException e) {
|
||||
throw new Error("Happen something that should never happen ", e);
|
||||
}
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
public static int firstNonZeroByte(byte[] data){
|
||||
int firstNonZero = -1;
|
||||
int i = 0;
|
||||
for (; i < data.length; ++i) {
|
||||
if (data[i] != 0) {
|
||||
firstNonZero = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return firstNonZero;
|
||||
}
|
||||
|
||||
public static byte[] stripLeadingZeroes(byte[] data) {
|
||||
|
||||
if (data == null)
|
||||
return null;
|
||||
|
||||
int firstNonZero = firstNonZeroByte(data);
|
||||
int i = 0;
|
||||
for (; i < data.length; ++i) {
|
||||
if (data[i] != 0) {
|
||||
firstNonZero = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* increment byte array as a number until max is reached
|
||||
*
|
||||
* @param bytes byte[]
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean increment(byte[] bytes) {
|
||||
final int startIndex = 0;
|
||||
int i;
|
||||
for (i = bytes.length-1; i >= startIndex; i--) {
|
||||
bytes[i]++;
|
||||
if (bytes[i] != 0)
|
||||
break;
|
||||
}
|
||||
// we return false when all bytes are 0 again
|
||||
return (i >= startIndex || bytes[startIndex] != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function to copy a byte array into a new byte array with given size.
|
||||
* If the src length is smaller than the given size, the result will be left-padded
|
||||
* with zeros.
|
||||
*
|
||||
* @param value - a BigInteger with a maximum value of 2^256-1
|
||||
* @return Byte array of given size with a copy of the <code>src</code>
|
||||
*/
|
||||
public static byte[] copyToArray(BigInteger value) {
|
||||
byte[] src = ByteUtil.bigIntegerToBytes(value);
|
||||
byte[] dest = ByteBuffer.allocate(32).array();
|
||||
System.arraycopy(src, 0, dest, dest.length - src.length, src.length);
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
public static ByteArrayWrapper wrap(byte[] data){
|
||||
return new ByteArrayWrapper(data);
|
||||
}
|
||||
|
||||
public static byte[] setBit(byte[] data, int pos, int val) {
|
||||
|
||||
if ( (data.length * 8) - 1 < pos )
|
||||
throw new Error("outside byte array limit, pos: " + pos);
|
||||
|
||||
int posByte = data.length - 1 - (pos) / 8;
|
||||
int posBit = (pos) % 8;
|
||||
byte setter = (byte)(1 << (posBit));
|
||||
byte toBeSet = data[posByte];
|
||||
byte result;
|
||||
if(val == 1)
|
||||
result = (byte)(toBeSet | setter);
|
||||
else
|
||||
result = (byte)(toBeSet & ~setter);
|
||||
|
||||
data[posByte] = result;
|
||||
return data;
|
||||
}
|
||||
|
||||
public static int getBit(byte[] data, int pos) {
|
||||
|
||||
if ((data.length * 8) - 1 < pos )
|
||||
throw new Error("outside byte array limit, pos: " + pos);
|
||||
|
||||
int posByte = data.length - 1 - pos / 8;
|
||||
int posBit = pos % 8;
|
||||
byte dataByte = data[posByte];
|
||||
return Math.min(1, (dataByte & (1 << (posBit))));
|
||||
}
|
||||
package org.ethereum.util;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.ethereum.db.ByteArrayWrapper;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
public class ByteUtil {
|
||||
|
||||
public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
|
||||
public static final byte[] ZERO_BYTE_ARRAY = new byte[]{0};
|
||||
|
||||
/**
|
||||
* Creates a copy of bytes and appends b to the end of it
|
||||
*/
|
||||
public static byte[] appendByte(byte[] bytes, byte b) {
|
||||
byte[] result = Arrays.copyOf(bytes, bytes.length + 1);
|
||||
result[result.length - 1] = b;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* The regular {@link java.math.BigInteger#toByteArray()} method isn't quite what we often need:
|
||||
* it appends a leading zero to indicate that the number is positive and may need padding.
|
||||
*
|
||||
* @param b the integer to format into a byte array
|
||||
* @param numBytes the desired size of the resulting byte array
|
||||
* @return numBytes byte long array.
|
||||
*/
|
||||
public static byte[] bigIntegerToBytes(BigInteger b, int numBytes) {
|
||||
if (b == null)
|
||||
return null;
|
||||
byte[] bytes = new byte[numBytes];
|
||||
byte[] biBytes = b.toByteArray();
|
||||
int start = (biBytes.length == numBytes + 1) ? 1 : 0;
|
||||
int length = Math.min(biBytes.length, numBytes);
|
||||
System.arraycopy(biBytes, start, bytes, numBytes - length, length);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Omitting sign indication byte.
|
||||
* <br><br>
|
||||
* Instead of {@link org.spongycastle.util.BigIntegers#asUnsignedByteArray(BigInteger)}
|
||||
* <br>we use this custom method to avoid an empty array in case of BigInteger.ZERO
|
||||
*
|
||||
* @param value - any big integer number. A <code>null</code>-value will return <code>null</code>
|
||||
* @return A byte array without a leading zero byte if present in the signed encoding.
|
||||
* BigInteger.ZERO will return an array with length 1 and byte-value 0.
|
||||
*/
|
||||
public static byte[] bigIntegerToBytes(BigInteger value) {
|
||||
if (value == null)
|
||||
return null;
|
||||
|
||||
byte[] data = value.toByteArray();
|
||||
|
||||
if (data.length != 1 && data[0] == 0) {
|
||||
byte[] tmp = new byte[data.length - 1];
|
||||
System.arraycopy(data, 1, tmp, 0, tmp.length);
|
||||
data = tmp;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amount of nibbles that match each other from 0 ...
|
||||
* amount will never be larger than smallest input
|
||||
*
|
||||
* @param a - first input
|
||||
* @param b - second input
|
||||
* @return Number of bytes that match
|
||||
*/
|
||||
public static int matchingNibbleLength(byte[] a, byte[] b) {
|
||||
int i = 0;
|
||||
int length = a.length < b.length ? a.length : b.length;
|
||||
while (i < length) {
|
||||
if (a[i] != b[i])
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a long value into a byte array.
|
||||
*
|
||||
* @param val - long value to convert
|
||||
* @return <code>byte[]</code> of length 8, representing the long value
|
||||
*/
|
||||
public static byte[] longToBytes(long val) {
|
||||
return ByteBuffer.allocate(8).putLong(val).array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a byte-array into a hex String.<br>
|
||||
* Works similar to {@link Hex#toHexString}
|
||||
* but allows for <code>null</code>
|
||||
*
|
||||
* @param data - byte-array to convert to a hex-string
|
||||
* @return hex representation of the data.<br>
|
||||
* Returns an empty String if the input is <code>null</code>
|
||||
*
|
||||
* @see Hex#toHexString
|
||||
*/
|
||||
public static String toHexString(byte[] data) {
|
||||
return data == null ? "" : Hex.toHexString(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate packet length
|
||||
* @param msg byte[]
|
||||
* @return byte-array with 4 elements
|
||||
*/
|
||||
public static byte[] calcPacketLength(byte[] msg) {
|
||||
int msgLen = msg.length;
|
||||
byte[] len = {
|
||||
(byte)((msgLen >> 24) & 0xFF),
|
||||
(byte)((msgLen >> 16) & 0xFF),
|
||||
(byte)((msgLen >> 8) & 0xFF),
|
||||
(byte)((msgLen ) & 0xFF)};
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast hex encoded value from byte[] to int
|
||||
*
|
||||
* Limited to Integer.MAX_VALUE: 2^32-1 (4 bytes)
|
||||
*
|
||||
* @param b array contains the values
|
||||
* @return unsigned positive int value.
|
||||
*/
|
||||
public static int byteArrayToInt(byte[] b) {
|
||||
if (b == null || b.length == 0)
|
||||
return 0;
|
||||
return new BigInteger(1, b).intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast hex encoded value from byte[] to int
|
||||
*
|
||||
* Limited to Integer.MAX_VALUE: 2^32-1 (4 bytes)
|
||||
*
|
||||
* @param b array contains the values
|
||||
* @return unsigned positive long value.
|
||||
*/
|
||||
public static long byteArrayToLong(byte[] b) {
|
||||
if (b == null || b.length == 0)
|
||||
return 0;
|
||||
return new BigInteger(1, b).longValue();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Turn nibbles to a pretty looking output string
|
||||
*
|
||||
* Example. [ 1, 2, 3, 4, 5 ] becomes '\x11\x23\x45'
|
||||
*
|
||||
* @param nibbles - getting byte of data [ 04 ] and turning
|
||||
* it to a '\x04' representation
|
||||
* @return pretty string of nibbles
|
||||
*/
|
||||
public static String nibblesToPrettyString(byte[] nibbles){
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
for (byte nibble : nibbles) {
|
||||
String nibleString = oneByteToHexString(nibble);
|
||||
buffer.append("\\x" + nibleString);
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public static String oneByteToHexString(byte value) {
|
||||
String retVal = Integer.toString(value & 0xFF, 16);
|
||||
if (retVal.length() == 1) retVal = "0" + retVal;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the number of bytes need
|
||||
* to encode the number
|
||||
*
|
||||
* @param val - number
|
||||
* @return number of min bytes used to encode the number
|
||||
*/
|
||||
public static int numBytes(String val) {
|
||||
|
||||
BigInteger bInt = new BigInteger(val);
|
||||
int bytes = 0;
|
||||
|
||||
while(!bInt.equals(BigInteger.ZERO)) {
|
||||
bInt = bInt.shiftRight(8);
|
||||
++bytes;
|
||||
}
|
||||
if (bytes == 0) ++bytes;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param arg - not more that 32 bits
|
||||
* @return - bytes of the value pad with complete to 32 zeroes
|
||||
*/
|
||||
public static byte[] encodeValFor32Bits(Object arg) {
|
||||
|
||||
byte[] data;
|
||||
|
||||
// check if the string is numeric
|
||||
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]+"))
|
||||
data = new BigInteger(arg.toString().trim().substring(2), 16).toByteArray();
|
||||
else
|
||||
data = arg.toString().trim().getBytes();
|
||||
|
||||
|
||||
if (data.length > 32)
|
||||
throw new RuntimeException("values can't be more than 32 byte");
|
||||
|
||||
byte[] val = new byte[32];
|
||||
|
||||
int j = 0;
|
||||
for (int i = data.length; i > 0; --i) {
|
||||
val[31 - j] = data[i - 1];
|
||||
++j;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* encode the values and concatenate together
|
||||
* @param args Object
|
||||
* @return byte[]
|
||||
*/
|
||||
public static byte[] encodeDataList(Object... args) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
for (Object arg : args) {
|
||||
byte[] val = encodeValFor32Bits(arg);
|
||||
try {
|
||||
baos.write(val);
|
||||
} catch (IOException e) {
|
||||
throw new Error("Happen something that should never happen ", e);
|
||||
}
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
public static int firstNonZeroByte(byte[] data){
|
||||
int firstNonZero = -1;
|
||||
int i = 0;
|
||||
for (; i < data.length; ++i) {
|
||||
if (data[i] != 0) {
|
||||
firstNonZero = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return firstNonZero;
|
||||
}
|
||||
|
||||
public static byte[] stripLeadingZeroes(byte[] data) {
|
||||
|
||||
if (data == null)
|
||||
return null;
|
||||
|
||||
int firstNonZero = firstNonZeroByte(data);
|
||||
int i = 0;
|
||||
for (; i < data.length; ++i) {
|
||||
if (data[i] != 0) {
|
||||
firstNonZero = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* increment byte array as a number until max is reached
|
||||
*
|
||||
* @param bytes byte[]
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean increment(byte[] bytes) {
|
||||
final int startIndex = 0;
|
||||
int i;
|
||||
for (i = bytes.length-1; i >= startIndex; i--) {
|
||||
bytes[i]++;
|
||||
if (bytes[i] != 0)
|
||||
break;
|
||||
}
|
||||
// we return false when all bytes are 0 again
|
||||
return (i >= startIndex || bytes[startIndex] != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function to copy a byte array into a new byte array with given size.
|
||||
* If the src length is smaller than the given size, the result will be left-padded
|
||||
* with zeros.
|
||||
*
|
||||
* @param value - a BigInteger with a maximum value of 2^256-1
|
||||
* @return Byte array of given size with a copy of the <code>src</code>
|
||||
*/
|
||||
public static byte[] copyToArray(BigInteger value) {
|
||||
byte[] src = ByteUtil.bigIntegerToBytes(value);
|
||||
byte[] dest = ByteBuffer.allocate(32).array();
|
||||
System.arraycopy(src, 0, dest, dest.length - src.length, src.length);
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
public static ByteArrayWrapper wrap(byte[] data){
|
||||
return new ByteArrayWrapper(data);
|
||||
}
|
||||
|
||||
public static byte[] setBit(byte[] data, int pos, int val) {
|
||||
|
||||
if ( (data.length * 8) - 1 < pos )
|
||||
throw new Error("outside byte array limit, pos: " + pos);
|
||||
|
||||
int posByte = data.length - 1 - (pos) / 8;
|
||||
int posBit = (pos) % 8;
|
||||
byte setter = (byte)(1 << (posBit));
|
||||
byte toBeSet = data[posByte];
|
||||
byte result;
|
||||
if(val == 1)
|
||||
result = (byte)(toBeSet | setter);
|
||||
else
|
||||
result = (byte)(toBeSet & ~setter);
|
||||
|
||||
data[posByte] = result;
|
||||
return data;
|
||||
}
|
||||
|
||||
public static int getBit(byte[] data, int pos) {
|
||||
|
||||
if ((data.length * 8) - 1 < pos )
|
||||
throw new Error("outside byte array limit, pos: " + pos);
|
||||
|
||||
int posByte = data.length - 1 - pos / 8;
|
||||
int posBit = pos % 8;
|
||||
byte dataByte = data[posByte];
|
||||
return Math.min(1, (dataByte & (1 << (posBit))));
|
||||
}
|
||||
}
|
|
@ -1,25 +1,25 @@
|
|||
package org.ethereum.util;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Simple LRU map used for reusing lookup values.
|
||||
*/
|
||||
public class LRUMap<K,V> extends ConcurrentHashMap<K,V> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
protected final int maxEntries;
|
||||
|
||||
public LRUMap(int initialEntries, int maxEntries) {
|
||||
super(initialEntries, 0.8f, 3);
|
||||
this.maxEntries = maxEntries;
|
||||
}
|
||||
|
||||
/* todo: temporary removed during concurrent impl
|
||||
@Override
|
||||
protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
|
||||
return size() > maxEntries;
|
||||
}
|
||||
*/
|
||||
package org.ethereum.util;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Simple LRU map used for reusing lookup values.
|
||||
*/
|
||||
public class LRUMap<K,V> extends ConcurrentHashMap<K,V> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
protected final int maxEntries;
|
||||
|
||||
public LRUMap(int initialEntries, int maxEntries) {
|
||||
super(initialEntries, 0.8f, 3);
|
||||
this.maxEntries = maxEntries;
|
||||
}
|
||||
|
||||
/* todo: temporary removed during concurrent impl
|
||||
@Override
|
||||
protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
|
||||
return size() > maxEntries;
|
||||
}
|
||||
*/
|
||||
}
|
|
@ -1,82 +1,82 @@
|
|||
package org.ethereum.vm;
|
||||
|
||||
/**
|
||||
* A wrapper for a message call from a contract to another account.
|
||||
* This can either be a normal CALL, STATELESS call or POST call.
|
||||
*/
|
||||
public class MessageCall {
|
||||
|
||||
public enum MsgType {
|
||||
CALL,
|
||||
STATELESS,
|
||||
POST;
|
||||
}
|
||||
|
||||
/** Type of internal call. Either CALL, STATELESS or POST */
|
||||
private MsgType type;
|
||||
|
||||
/** gas to pay for the call, remaining gas will be refunded to the caller */
|
||||
private DataWord gas;
|
||||
/** address of account which code to call */
|
||||
private DataWord codeAddress;
|
||||
/** the value that can be transfer along with the code execution */
|
||||
private DataWord endowment;
|
||||
/** start of memory to be input data to the call */
|
||||
private DataWord inDataOffs;
|
||||
/** size of memory to be input data to the call */
|
||||
private DataWord inDataSize;
|
||||
/** start of memory to be output of the call */
|
||||
private DataWord outDataOffs;
|
||||
/** size of memory to be output data to the call */
|
||||
private DataWord outDataSize;
|
||||
|
||||
public MessageCall(MsgType type, DataWord gas, DataWord codeAddress,
|
||||
DataWord endowment, DataWord inDataOffs, DataWord inDataSize) {
|
||||
this.type = type;
|
||||
this.gas = gas;
|
||||
this.codeAddress = codeAddress;
|
||||
this.endowment = endowment;
|
||||
this.inDataOffs = inDataOffs;
|
||||
this.inDataSize = inDataSize;
|
||||
}
|
||||
|
||||
public MessageCall(MsgType type, DataWord gas, DataWord codeAddress,
|
||||
DataWord endowment, DataWord inDataOffs, DataWord inDataSize,
|
||||
DataWord outDataOffs, DataWord outDataSize) {
|
||||
this(type, gas, codeAddress, endowment, inDataOffs, inDataSize);
|
||||
this.outDataOffs = outDataOffs;
|
||||
this.outDataSize = outDataSize;
|
||||
}
|
||||
|
||||
public MsgType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public DataWord getGas() {
|
||||
return gas;
|
||||
}
|
||||
|
||||
public DataWord getCodeAddress() {
|
||||
return codeAddress;
|
||||
}
|
||||
|
||||
public DataWord getEndowment() {
|
||||
return endowment;
|
||||
}
|
||||
|
||||
public DataWord getInDataOffs() {
|
||||
return inDataOffs;
|
||||
}
|
||||
|
||||
public DataWord getInDataSize() {
|
||||
return inDataSize;
|
||||
}
|
||||
|
||||
public DataWord getOutDataOffs() {
|
||||
return outDataOffs;
|
||||
}
|
||||
|
||||
public DataWord getOutDataSize() {
|
||||
return outDataSize;
|
||||
}
|
||||
}
|
||||
package org.ethereum.vm;
|
||||
|
||||
/**
|
||||
* A wrapper for a message call from a contract to another account.
|
||||
* This can either be a normal CALL, STATELESS call or POST call.
|
||||
*/
|
||||
public class MessageCall {
|
||||
|
||||
public enum MsgType {
|
||||
CALL,
|
||||
STATELESS,
|
||||
POST;
|
||||
}
|
||||
|
||||
/** Type of internal call. Either CALL, STATELESS or POST */
|
||||
private MsgType type;
|
||||
|
||||
/** gas to pay for the call, remaining gas will be refunded to the caller */
|
||||
private DataWord gas;
|
||||
/** address of account which code to call */
|
||||
private DataWord codeAddress;
|
||||
/** the value that can be transfer along with the code execution */
|
||||
private DataWord endowment;
|
||||
/** start of memory to be input data to the call */
|
||||
private DataWord inDataOffs;
|
||||
/** size of memory to be input data to the call */
|
||||
private DataWord inDataSize;
|
||||
/** start of memory to be output of the call */
|
||||
private DataWord outDataOffs;
|
||||
/** size of memory to be output data to the call */
|
||||
private DataWord outDataSize;
|
||||
|
||||
public MessageCall(MsgType type, DataWord gas, DataWord codeAddress,
|
||||
DataWord endowment, DataWord inDataOffs, DataWord inDataSize) {
|
||||
this.type = type;
|
||||
this.gas = gas;
|
||||
this.codeAddress = codeAddress;
|
||||
this.endowment = endowment;
|
||||
this.inDataOffs = inDataOffs;
|
||||
this.inDataSize = inDataSize;
|
||||
}
|
||||
|
||||
public MessageCall(MsgType type, DataWord gas, DataWord codeAddress,
|
||||
DataWord endowment, DataWord inDataOffs, DataWord inDataSize,
|
||||
DataWord outDataOffs, DataWord outDataSize) {
|
||||
this(type, gas, codeAddress, endowment, inDataOffs, inDataSize);
|
||||
this.outDataOffs = outDataOffs;
|
||||
this.outDataSize = outDataSize;
|
||||
}
|
||||
|
||||
public MsgType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public DataWord getGas() {
|
||||
return gas;
|
||||
}
|
||||
|
||||
public DataWord getCodeAddress() {
|
||||
return codeAddress;
|
||||
}
|
||||
|
||||
public DataWord getEndowment() {
|
||||
return endowment;
|
||||
}
|
||||
|
||||
public DataWord getInDataOffs() {
|
||||
return inDataOffs;
|
||||
}
|
||||
|
||||
public DataWord getInDataSize() {
|
||||
return inDataSize;
|
||||
}
|
||||
|
||||
public DataWord getOutDataOffs() {
|
||||
return outDataOffs;
|
||||
}
|
||||
|
||||
public DataWord getOutDataSize() {
|
||||
return outDataSize;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue