diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Bloom.java b/ethereumj-core/src/main/java/org/ethereum/core/Bloom.java index 300fa1ba..669d7c2c 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/Bloom.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/Bloom.java @@ -1,7 +1,10 @@ package org.ethereum.core; +import org.ethereum.util.ByteUtil; import org.spongycastle.util.encoders.Hex; +import java.nio.ByteBuffer; + /** * www.etherj.com * @@ -19,55 +22,31 @@ public class Bloom { public Bloom(byte[] data){ } - public static Bloom create(byte[] toBloom){ - - int mov1 = (toBloom[0] & 1) * 256 + (toBloom[1] & 255); - int mov2 = (toBloom[2] & 1) * 256 + (toBloom[3] & 255); - int mov3 = (toBloom[4] & 1) * 256 + (toBloom[5] & 255); + public static Bloom create(byte[] toBloom) { + int mov1 = ((255 & toBloom[0 + 1]) + 256 * ((255 & toBloom[0]) & 1)); + int mov2 = ((255 & toBloom[2 + 1]) + 256 * ((255 & toBloom[2]) & 1)); + int mov3 = ((255 & toBloom[4 + 1]) + 256 * ((255 & toBloom[4]) & 1)); byte[] data = new byte[64]; Bloom bloom = new Bloom(data); - bloom.setBit(mov1, 1); - bloom.setBit(mov2, 1); - bloom.setBit(mov3, 1); + ByteUtil.setBit(data, mov1, 1); + ByteUtil.setBit(data, mov2, 1); + ByteUtil.setBit(data, mov3, 1); return bloom; } public void or(Bloom bloom){ - for (int i = 0; i < data.length; ++i){ data[i] |= bloom.data[i]; } } - public void setBit(int pos, int val) { - - if (data.length * 8 < pos ) - throw new Error("outside bloom limit, pos: " + pos); - - int posByte = (pos - 1) / 8; - int posBit = (pos - 1) % 8; - byte oldByte = data[posByte]; - oldByte = (byte) (((0xFF7F >> (( posBit + 1)) & oldByte) & 0x00FF)); - byte newByte = (byte) ((val << ( 8 - ( posBit + 1))) | oldByte); - data[posByte] = newByte; + public byte[] getData() { + return data; } - public int getBit(int pos) { - - if (data.length - 1 < pos ) - throw new Error("outside bloom limit, pos: " + pos); - - int posByte = pos / 8; - int posBit = pos % 8; - byte valByte = data[posByte]; - int valInt = valByte >> (8 - (posBit + 1)) & 0x0001; - return valInt; - } - - @Override public String toString() { return Hex.toHexString(data); diff --git a/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/Logs.java b/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/Logs.java index 73a9255e..35270ec0 100644 --- a/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/Logs.java +++ b/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/Logs.java @@ -44,7 +44,7 @@ public class Logs { * @param k * @return */ - public LogInfo getLogBySHA3Key(byte[] k) { + public LogInfo getLogBloom(byte[] k) { if(logs.containsKey(k)) return logs.get(k); return null; diff --git a/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/TestRunner.java b/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/TestRunner.java index 8e2e4180..e82f6867 100644 --- a/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/TestRunner.java +++ b/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/TestRunner.java @@ -232,20 +232,20 @@ public class TestRunner { while(itr.hasNext()) { byte[] expectedLogKey = itr.next(); System.out.println("Expected key " + Hex.toHexString(expectedLogKey)); - LogInfo expectedLogInfo = logs.getLogBySHA3Key(expectedLogKey); + LogInfo expectedLogInfo = logs.getLogBloom(expectedLogKey); boolean found = false; for(LogInfo resultLogInfo:logResult) { - byte[] rlpHash = HashUtil.sha3(resultLogInfo.getEncoded()); - System.out.println("returned key " + Hex.toHexString(rlpHash)); - if(Arrays.equals(expectedLogKey, rlpHash)) { + byte[] resultKey = resultLogInfo.getBloom().getData(); + System.out.println("returned key " + Hex.toHexString(resultKey)); + if(Arrays.equals(expectedLogKey, resultKey)) { found = true; } } if(!found) { String output = - String.format("Expected log [ %s ] was not found", expectedLogInfo.toString()); + String.format("Expected log [ %s ]", expectedLogInfo.toString()); logger.info(output); results.add(output); } diff --git a/ethereumj-core/src/main/java/org/ethereum/util/ByteUtil.java b/ethereumj-core/src/main/java/org/ethereum/util/ByteUtil.java index 71f83d06..6f1c16e5 100644 --- a/ethereumj-core/src/main/java/org/ethereum/util/ByteUtil.java +++ b/ethereumj-core/src/main/java/org/ethereum/util/ByteUtil.java @@ -305,4 +305,34 @@ public class ByteUtil { 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 = (pos) / 8; + int posBit = (pos) % 8; + byte setter = (byte)(1 << (7 - 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 = pos / 8; + int posBit = pos % 8; + byte dataByte = data[posByte]; + return Math.min(1, (dataByte & (1 << (7 - posBit)))); + } } \ No newline at end of file diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/LogInfo.java b/ethereumj-core/src/main/java/org/ethereum/vm/LogInfo.java index fb94f2a5..71a7bae0 100644 --- a/ethereumj-core/src/main/java/org/ethereum/vm/LogInfo.java +++ b/ethereumj-core/src/main/java/org/ethereum/vm/LogInfo.java @@ -1,9 +1,12 @@ package org.ethereum.vm; import org.ethereum.core.BlockHeader; +import org.ethereum.core.Bloom; +import org.ethereum.crypto.HashUtil; import org.ethereum.util.RLP; import org.spongycastle.util.encoders.Hex; +import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -62,6 +65,15 @@ public class LogInfo { return RLP.encodeList(addressEncoded, RLP.encodeList(topicsEncoded), dataEncoded); } + public Bloom getBloom() { + Bloom ret = Bloom.create(HashUtil.sha3(address)); + for(byte[] topic:topics) { + ret.or(Bloom.create(HashUtil.sha3(topic))); + } + + return ret; + } + @Override public String toString() { diff --git a/ethereumj-core/src/test/java/test/ethereum/util/ByteUtilTest.java b/ethereumj-core/src/test/java/test/ethereum/util/ByteUtilTest.java index 3e37282f..c3fefeec 100644 --- a/ethereumj-core/src/test/java/test/ethereum/util/ByteUtilTest.java +++ b/ethereumj-core/src/test/java/test/ethereum/util/ByteUtilTest.java @@ -4,6 +4,8 @@ import static org.junit.Assert.*; import java.math.BigInteger; import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; import org.ethereum.util.ByteUtil; import org.ethereum.util.FastByteComparisons; @@ -237,6 +239,78 @@ public class ByteUtilTest { assertEquals(0, result); } + @Test + public void setBitTest() { + /* + Set on + */ + byte[] data = ByteBuffer.allocate(4).putInt(0).array(); + int posBit = 24; + int expected = 128; + int result = -1; + byte[] ret = ByteUtil.setBit(data, posBit, 1); + result = ByteUtil.byteArrayToInt(ret); + assertTrue(expected == result); + posBit = 25; + expected = 192; + ret = ByteUtil.setBit(data, posBit, 1); + result = ByteUtil.byteArrayToInt(ret); + assertTrue(expected == result); + posBit = 2; + expected = 536871104; + ret = ByteUtil.setBit(data, posBit, 1); + result = ByteUtil.byteArrayToInt(ret); + assertTrue(expected == result); + + /* + Set off + */ + posBit = 24; + expected = 536870976; + ret = ByteUtil.setBit(data, posBit, 0); + result = ByteUtil.byteArrayToInt(ret); + assertTrue(expected == result); + + posBit = 25; + expected = 536870912; + ret = ByteUtil.setBit(data, posBit, 0); + result = ByteUtil.byteArrayToInt(ret); + assertTrue(expected == result); + + posBit = 2; + expected = 0; + ret = ByteUtil.setBit(data, posBit, 0); + result = ByteUtil.byteArrayToInt(ret); + assertTrue(expected == result); + } + + @Test + public void getBitTest() { + byte[] data = ByteBuffer.allocate(4).putInt(0).array(); + ByteUtil.setBit(data, 24, 1); + ByteUtil.setBit(data, 25, 1); + ByteUtil.setBit(data, 2, 1); + + List found = new ArrayList(); + for(int i=0; i < (data.length * 8); i++) { + int res = ByteUtil.getBit(data, i); + if(res == 1) + if(i != 24 && i != 25 && i != 2) + assertTrue(false); + else + found.add(i); + else { + if(i == 24 || i == 25 || i == 2) + assertTrue(false); + } + } + + if(found.size() != 3) + assertTrue(false); + assertTrue(found.get(0) == 2); + assertTrue(found.get(1) == 24); + assertTrue(found.get(2) == 25); + } }