Use sha3 cache for extra performance

This commit is contained in:
nicksavers 2014-08-02 00:52:22 +02:00
parent f4bab10327
commit d2ea940992
4 changed files with 82 additions and 71 deletions

View File

@ -1,6 +1,7 @@
package org.ethereum.core;
import org.ethereum.crypto.HashUtil;
import static org.ethereum.util.ByteUtil.EMPTY_BYTE_ARRAY;
import static org.ethereum.crypto.HashUtil.EMPTY_DATA_HASH;
import org.ethereum.util.RLP;
import org.ethereum.util.RLPList;
@ -28,7 +29,7 @@ public class AccountState {
* I define a convenient equivalence TRIE (σ[a] s ) σ[a] s .
* It shall be understood that σ[a] s is not a physical member
* of the account and does not contribute to its later serialisation */
private byte[] stateRoot = new byte[0];
private byte[] stateRoot = EMPTY_BYTE_ARRAY;
/* The hash of the EVM code of this contractthis is the code
* that gets executed should this address receive a message call;
@ -36,7 +37,7 @@ public class AccountState {
* after construction. All such code fragments are contained in
* the state database under their corresponding hashes for later
* retrieval */
private byte[] codeHash = HashUtil.sha3(new byte[0]);
private byte[] codeHash = EMPTY_DATA_HASH;
public AccountState() {
this(BigInteger.ZERO, BigInteger.ZERO);

View File

@ -5,7 +5,10 @@ import static java.util.Arrays.copyOfRange;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import org.ethereum.db.ByteArrayWrapper;
import org.ethereum.util.ByteUtil;
import org.ethereum.util.RLP;
import org.ethereum.util.Utils;
@ -13,7 +16,8 @@ import org.spongycastle.util.encoders.Hex;
public class HashUtil {
public static byte[] EMPTY_DATA_HASH = HashUtil.sha3(new byte[0]);
public static Map<ByteArrayWrapper, byte[]> hashes = new HashMap<>();
public static final byte[] EMPTY_DATA_HASH = HashUtil.sha3(new byte[0]);
private static final MessageDigest sha256digest;
@ -30,13 +34,14 @@ public class HashUtil {
}
public static byte[] sha3(byte[] input) {
return SHA3Helper.sha3(input);
ByteArrayWrapper byteArray = new ByteArrayWrapper(input);
if(hashes.keySet().contains(byteArray))
return hashes.get(byteArray);
byte[] result = SHA3Helper.sha3(input);
hashes.put(byteArray, result);
return result;
}
public static String sha3String(String input) {
return SHA3Helper.sha3String(input);
}
/**
* Calculates RIGTMOST160(SHA3(input)). This is used in address calculations.
*/

View File

@ -7,72 +7,74 @@ import org.spongycastle.util.encoders.Hex;
public class SHA3Helper {
public static String sha3String(String message) {
return sha3String(message, new SHA3Digest(256), true);
}
private static int DEFAULT_SIZE = 256;
public static String sha3String(byte[] message) {
return sha3String(message, new SHA3Digest(256), true);
}
public static String sha3String(String message) {
return sha3String(message, new SHA3Digest(DEFAULT_SIZE), true);
}
public static byte[] sha3(String message) {
return sha3(Hex.decode(message), new SHA3Digest(256), true);
}
public static byte[] sha3(byte[] message) {
return sha3(message, new SHA3Digest(256), true);
}
protected static String sha3String(String message, Size bitSize) {
SHA3Digest digest = new SHA3Digest(bitSize.bits);
return sha3String(message, digest, true);
}
protected static String sha3String(byte[] message, Size bitSize) {
SHA3Digest digest = new SHA3Digest(bitSize.bits);
return sha3String(message, digest, true);
}
protected static String sha3String(String message, Size bitSize, boolean bouncyencoder) {
SHA3Digest digest = new SHA3Digest(bitSize.bits);
return sha3String(message, digest, bouncyencoder);
}
protected static String sha3string(byte[] message, Size bitSize, boolean bouncyencoder) {
SHA3Digest digest = new SHA3Digest(bitSize.bits);
return sha3String(message, digest, bouncyencoder);
}
private static String sha3String(String message, SHA3Digest digest, boolean bouncyencoder) {
if (message != null) {
return sha3String(Hex.decode(message), digest, bouncyencoder);
}
throw new NullPointerException("Can't hash a NULL value");
}
public static String sha3String(byte[] message) {
return sha3String(message, new SHA3Digest(DEFAULT_SIZE), true);
}
private static String sha3String(byte[] message, SHA3Digest digest, boolean bouncyencoder) {
byte[] hash = doSha3(message, digest, bouncyencoder);
if (bouncyencoder) {
return Hex.toHexString(hash);
} else {
BigInteger bigInt = new BigInteger(1, hash);
return bigInt.toString(16);
}
}
private static byte[] sha3(byte[] message, SHA3Digest digest, boolean bouncyencoder) {
return doSha3(message, digest, bouncyencoder);
}
private static byte[] doSha3(byte[] message, SHA3Digest digest, boolean bouncyencoder) {
byte[] hash = new byte[digest.getDigestSize()];
public static byte[] sha3(String message) {
return sha3(Hex.decode(message), new SHA3Digest(DEFAULT_SIZE), true);
}
if (message.length != 0) {
digest.update(message, 0, message.length);
}
digest.doFinal(hash, 0);
return hash;
}
public static byte[] sha3(byte[] message) {
return sha3(message, new SHA3Digest(DEFAULT_SIZE), true);
}
protected static String sha3String(String message, Size bitSize) {
SHA3Digest digest = new SHA3Digest(bitSize.bits);
return sha3String(message, digest, true);
}
protected static String sha3String(byte[] message, Size bitSize) {
SHA3Digest digest = new SHA3Digest(bitSize.bits);
return sha3String(message, digest, true);
}
protected static String sha3String(String message, Size bitSize, boolean bouncyencoder) {
SHA3Digest digest = new SHA3Digest(bitSize.bits);
return sha3String(message, digest, bouncyencoder);
}
protected static String sha3string(byte[] message, Size bitSize, boolean bouncyencoder) {
SHA3Digest digest = new SHA3Digest(bitSize.bits);
return sha3String(message, digest, bouncyencoder);
}
private static String sha3String(String message, SHA3Digest digest, boolean bouncyencoder) {
if (message != null) {
return sha3String(Hex.decode(message), digest, bouncyencoder);
}
throw new NullPointerException("Can't hash a NULL value");
}
private static String sha3String(byte[] message, SHA3Digest digest, boolean bouncyencoder) {
byte[] hash = doSha3(message, digest, bouncyencoder);
if (bouncyencoder) {
return Hex.toHexString(hash);
} else {
BigInteger bigInt = new BigInteger(1, hash);
return bigInt.toString(16);
}
}
private static byte[] sha3(byte[] message, SHA3Digest digest, boolean bouncyencoder) {
return doSha3(message, digest, bouncyencoder);
}
private static byte[] doSha3(byte[] message, SHA3Digest digest, boolean bouncyencoder) {
byte[] hash = new byte[digest.getDigestSize()];
if (message.length != 0) {
digest.update(message, 0, message.length);
}
digest.doFinal(hash, 0);
return hash;
}
public enum Size {
@ -91,4 +93,5 @@ public class SHA3Helper {
return this.bits;
}
}
}

View File

@ -10,6 +10,8 @@ import org.spongycastle.util.encoders.Hex;
public class ByteUtil {
public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
/**
* Creates a copy of bytes and appends b to the end of it
*/