set and get bit util + tests

This commit is contained in:
alon muroch 2014-12-03 10:38:12 +01:00
parent f9baa5c78a
commit 5754f8bd2c
6 changed files with 134 additions and 39 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -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))));
}
}

View File

@ -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() {

View File

@ -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<Integer> found = new ArrayList<Integer>();
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);
}
}