Latest merges from develop branch.

This commit is contained in:
Adrian Tiberius 2015-05-27 22:09:04 +02:00
parent 80bdbf0f66
commit 8fe358c2f6
12 changed files with 50 additions and 250 deletions

View File

@ -7,7 +7,7 @@ import org.ethereum.core.AccountState;
import org.ethereum.core.Block; import org.ethereum.core.Block;
import org.ethereum.core.Transaction; import org.ethereum.core.Transaction;
import org.ethereum.core.TransactionReceipt; import org.ethereum.core.TransactionReceipt;
import org.ethereum.db.ContractDetails; import org.ethereum.db.ContractDetailsImpl;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@ -134,21 +134,21 @@ public final class Serializers {
} }
} }
private static class ContractDetailsSerializer extends BaseRedisSerializer<ContractDetails> { private static class ContractDetailsSerializer extends BaseRedisSerializer<ContractDetailsImpl> {
@Override @Override
public boolean supports(Class<?> aClass) { public boolean supports(Class<?> aClass) {
return ContractDetails.class.isAssignableFrom(aClass); return ContractDetailsImpl.class.isAssignableFrom(aClass);
} }
@Override @Override
public byte[] serialize(ContractDetails contractDetails) { public byte[] serialize(ContractDetailsImpl contractDetails) {
return (contractDetails == null) ? EMPTY_ARRAY : contractDetails.getEncoded(); return (contractDetails == null) ? EMPTY_ARRAY : contractDetails.getEncoded();
} }
@Override @Override
public ContractDetails deserialize(byte[] bytes) { public ContractDetailsImpl deserialize(byte[] bytes) {
return isEmpty(bytes) ? null : new ContractDetails(bytes); return isEmpty(bytes) ? null : new ContractDetailsImpl(bytes);
} }
} }

View File

@ -1,235 +1,41 @@
package org.ethereum.db; package org.ethereum.db;
import org.ethereum.trie.SecureTrie; import org.ethereum.db.ContractDetailsImpl;
import org.ethereum.trie.Trie;
import org.ethereum.trie.TrieImpl;
import org.ethereum.util.ByteUtil;
import org.ethereum.util.RLP;
import org.ethereum.util.RLPElement;
import org.ethereum.util.RLPItem;
import org.ethereum.util.RLPList;
import org.ethereum.vm.DataWord; import org.ethereum.vm.DataWord;
import org.spongycastle.util.encoders.Hex;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
/** public interface ContractDetails {
* @author Roman Mandeleil void put(DataWord key, DataWord value);
* @since 24.06.2014
*/
public class ContractDetails {
private byte[] rlpEncoded; DataWord get(DataWord key);
private List<DataWord> storageKeys = new ArrayList<>(); byte[] getCode();
private List<DataWord> storageValues = new ArrayList<>();
private byte[] code = ByteUtil.EMPTY_BYTE_ARRAY; void setCode(byte[] code);
private boolean dirty = false; byte[] getStorageHash();
private boolean deleted = false;
private Trie storageTrie = new SecureTrie(null); void decode(byte[] rlpCode);
public ContractDetails() { void setDirty(boolean dirty);
}
public ContractDetails(byte[] rlpCode) { void setDeleted(boolean deleted);
decode(rlpCode);
}
public ContractDetails(Map<DataWord, DataWord> storage, byte[] code) { boolean isDirty();
}
public void put(DataWord key, DataWord value) { boolean isDeleted();
if (value.equals(DataWord.ZERO)) { byte[] getEncoded();
storageTrie.delete(key.getData()); Map<DataWord, DataWord> getStorage();
int index = storageKeys.indexOf(key);
if (index != -1) {
storageKeys.remove(index);
storageValues.remove(index);
}
} else {
storageTrie.update(key.getData(), RLP.encodeElement(value.getNoLeadZeroesData())); void setStorage(List<DataWord> storageKeys, List<DataWord> storageValues);
int index = storageKeys.indexOf(key);
if (index != -1) {
storageKeys.remove(index);
storageValues.remove(index);
}
storageKeys.add(key);
storageValues.add(value);
}
this.setDirty(true); void setStorage(Map<DataWord, DataWord> storage);
this.rlpEncoded = null;
}
public DataWord get(DataWord key) { ContractDetails clone();
if (storageKeys.size() == 0)
return null;
int foundIndex = storageKeys.indexOf(key);
if (foundIndex != -1) {
DataWord value = storageValues.get(foundIndex);
return value.clone();
} else
return null;
}
public byte[] getCode() {
return code;
}
public void setCode(byte[] code) {
this.code = code;
this.setDirty(true);
this.rlpEncoded = null;
}
public byte[] getStorageHash() {
storageTrie = new SecureTrie(null);
// calc the trie for root hash
for (int i = 0; i < storageKeys.size(); ++i) {
storageTrie.update(storageKeys.get(i).getData(), RLP
.encodeElement(storageValues.get(i).getNoLeadZeroesData()));
}
return storageTrie.getRootHash();
}
public void decode(byte[] rlpCode) {
RLPList data = RLP.decode2(rlpCode);
RLPList rlpList = (RLPList) data.get(0);
RLPList keys = (RLPList) rlpList.get(0);
RLPList values = (RLPList) rlpList.get(1);
RLPElement code = rlpList.get(2);
if (keys.size() > 0) {
storageKeys = new ArrayList<>();
storageValues = new ArrayList<>();
}
for (Object key : keys) {
RLPItem rlpItem = (RLPItem) key;
storageKeys.add(new DataWord(rlpItem.getRLPData()));
}
for (Object value : values) {
RLPItem rlpItem = (RLPItem) value;
storageValues.add(new DataWord(rlpItem.getRLPData()));
}
for (int i = 0; i < keys.size(); ++i) {
DataWord key = storageKeys.get(i);
DataWord value = storageValues.get(i);
storageTrie.update(key.getData(), RLP.encodeElement(value.getNoLeadZeroesData()));
}
this.code = (code.getRLPData() == null) ? ByteUtil.EMPTY_BYTE_ARRAY : code.getRLPData();
this.rlpEncoded = rlpCode;
}
public void setDirty(boolean dirty) {
this.dirty = dirty;
}
public void setDeleted(boolean deleted) {
this.deleted = deleted;
}
public boolean isDirty() {
return dirty;
}
public boolean isDeleted() {
return deleted;
}
public byte[] getEncoded() {
if (rlpEncoded == null) {
int size = storageKeys == null ? 0 : storageKeys.size();
byte[][] keys = new byte[size][];
byte[][] values = new byte[size][];
for (int i = 0; i < size; ++i) {
DataWord key = storageKeys.get(i);
keys[i] = RLP.encodeElement(key.getData());
}
for (int i = 0; i < size; ++i) {
DataWord value = storageValues.get(i);
values[i] = RLP.encodeElement(value.getNoLeadZeroesData());
}
byte[] rlpKeysList = RLP.encodeList(keys);
byte[] rlpValuesList = RLP.encodeList(values);
byte[] rlpCode = RLP.encodeElement(code);
this.rlpEncoded = RLP.encodeList(rlpKeysList, rlpValuesList, rlpCode);
}
return rlpEncoded;
}
public Map<DataWord, DataWord> getStorage() {
Map<DataWord, DataWord> storage = new HashMap<>();
for (int i = 0; storageKeys != null && i < storageKeys.size(); ++i) {
storage.put(storageKeys.get(i), storageValues.get(i));
}
return Collections.unmodifiableMap(storage);
}
public void setStorage(List<DataWord> storageKeys, List<DataWord> storageValues) {
this.storageKeys = storageKeys;
this.storageValues = storageValues;
}
public void setStorage(Map<DataWord, DataWord> storage) {
List<DataWord> keys = new ArrayList<>();
keys.addAll(storage.keySet());
List<DataWord> values = new ArrayList<>();
for (DataWord key : keys) {
DataWord value = storage.get(key);
values.add(value);
}
this.storageKeys = keys;
this.storageValues = values;
}
public ContractDetails clone() {
ContractDetails contractDetails = new ContractDetails();
contractDetails.setCode(this.getCode());
contractDetails.setStorage(new ArrayList<>(this.storageKeys),
new ArrayList<>(this.storageValues));
return contractDetails;
}
public String toString() {
String ret = " Code: " + Hex.toHexString(code) + "\n";
ret += " Storage: " + getStorage().toString();
return ret;
}
String toString();
} }

View File

@ -264,7 +264,7 @@ public class RepositoryDummy extends RepositoryImpl {
AccountState accountState = new AccountState(); AccountState accountState = new AccountState();
worldState.put(wrap(addr), accountState); worldState.put(wrap(addr), accountState);
ContractDetails contractDetails = new ContractDetails(); ContractDetails contractDetails = new ContractDetailsImpl();
detailsDB.put(wrap(addr), contractDetails); detailsDB.put(wrap(addr), contractDetails);
return accountState; return accountState;
@ -293,7 +293,7 @@ public class RepositoryDummy extends RepositoryImpl {
account = account.clone(); account = account.clone();
if (details == null) if (details == null)
details = new ContractDetails(); details = new ContractDetailsImpl();
else else
details = details.clone(); details = details.clone();

View File

@ -118,6 +118,8 @@ public class RepositoryImpl implements Repository {
public void updateBatch(HashMap<ByteArrayWrapper, AccountState> stateCache, public void updateBatch(HashMap<ByteArrayWrapper, AccountState> stateCache,
HashMap<ByteArrayWrapper, ContractDetails> detailsCache) { HashMap<ByteArrayWrapper, ContractDetails> detailsCache) {
logger.info("updatingBatch: detailsCache.size: {}", detailsCache.size());
for (ByteArrayWrapper hash : stateCache.keySet()) { for (ByteArrayWrapper hash : stateCache.keySet()) {
AccountState accountState = stateCache.get(hash); AccountState accountState = stateCache.get(hash);
@ -150,6 +152,9 @@ public class RepositoryImpl implements Repository {
} }
} }
logger.info("updated: detailsCache.size: {}", detailsCache.size());
stateCache.clear(); stateCache.clear();
detailsCache.clear(); detailsCache.clear();
} }
@ -418,7 +423,7 @@ public class RepositoryImpl implements Repository {
byte[] detailsData = detailsDB.get(addr); byte[] detailsData = detailsDB.get(addr);
if (detailsData != null) if (detailsData != null)
result = new ContractDetails(detailsData); result = new ContractDetailsImpl(detailsData);
return result; return result;
} }
@ -441,7 +446,7 @@ public class RepositoryImpl implements Repository {
AccountState accountState = new AccountState(); AccountState accountState = new AccountState();
worldState.update(addr, accountState.getEncoded()); worldState.update(addr, accountState.getEncoded());
ContractDetails contractDetails = new ContractDetails(); ContractDetails contractDetails = new ContractDetailsImpl();
detailsDB.put(addr, contractDetails.getEncoded()); detailsDB.put(addr, contractDetails.getEncoded());
return accountState; return accountState;
@ -466,9 +471,9 @@ public class RepositoryImpl implements Repository {
account = account.clone(); account = account.clone();
if (details == null) if (details == null)
details = new ContractDetails(); details = new ContractDetailsCacheImpl();
else else
details = details.clone(); details = new ContractDetailsCacheImpl(details.getEncoded());
cacheAccounts.put(wrap(addr), account); cacheAccounts.put(wrap(addr), account);
cacheDetails.put(wrap(addr), details); cacheDetails.put(wrap(addr), details);

View File

@ -47,7 +47,7 @@ public class RepositoryTrack implements Repository {
AccountState accountState = new AccountState(); AccountState accountState = new AccountState();
cacheAccounts.put(wrap(addr), accountState); cacheAccounts.put(wrap(addr), accountState);
ContractDetails contractDetails = new ContractDetails(); ContractDetails contractDetails = new ContractDetailsCacheImpl();
cacheDetails.put(wrap(addr), contractDetails); cacheDetails.put(wrap(addr), contractDetails);
return accountState; return accountState;

View File

@ -266,7 +266,7 @@ public class RepositoryVMTestDummy extends RepositoryImpl{
AccountState accountState = new AccountState(); AccountState accountState = new AccountState();
worldState.put(wrap(addr), accountState); worldState.put(wrap(addr), accountState);
ContractDetails contractDetails = new ContractDetails(); ContractDetails contractDetails = new ContractDetailsImpl();
detailsDB.put(wrap(addr), contractDetails); detailsDB.put(wrap(addr), contractDetails);
return accountState; return accountState;
@ -295,7 +295,7 @@ public class RepositoryVMTestDummy extends RepositoryImpl{
account = account.clone(); account = account.clone();
if (details == null) if (details == null)
details = new ContractDetails(); details = new ContractDetailsImpl();
else else
details = details.clone(); details = details.clone();

View File

@ -1,6 +1,6 @@
package org.ethereum.jsontestsuite; package org.ethereum.jsontestsuite;
import org.ethereum.db.ContractDetails; import org.ethereum.db.ContractDetailsImpl;
import org.ethereum.util.ByteUtil; import org.ethereum.util.ByteUtil;
import org.ethereum.vm.DataWord; import org.ethereum.vm.DataWord;
@ -93,7 +93,7 @@ public class AccountState {
return storage; return storage;
} }
public List<String> compareToReal(org.ethereum.core.AccountState state, ContractDetails details) { public List<String> compareToReal(org.ethereum.core.AccountState state, ContractDetailsImpl details) {
List<String> results = new ArrayList<>(); List<String> results = new ArrayList<>();

View File

@ -1,7 +1,7 @@
package org.ethereum.jsontestsuite.builder; package org.ethereum.jsontestsuite.builder;
import org.ethereum.core.AccountState; import org.ethereum.core.AccountState;
import org.ethereum.db.ContractDetails; import org.ethereum.db.ContractDetailsImpl;
import org.ethereum.jsontestsuite.model.AccountTck; import org.ethereum.jsontestsuite.model.AccountTck;
import org.ethereum.vm.DataWord; import org.ethereum.vm.DataWord;
@ -16,7 +16,7 @@ public class AccountBuilder {
public static StateWrap build(AccountTck account) { public static StateWrap build(AccountTck account) {
ContractDetails details = new ContractDetails(); ContractDetailsImpl details = new ContractDetailsImpl();
details.setCode(parseData(account.getCode())); details.setCode(parseData(account.getCode()));
details.setStorage(convertStorage(account.getStorage())); details.setStorage(convertStorage(account.getStorage()));
@ -50,9 +50,9 @@ public class AccountBuilder {
public static class StateWrap { public static class StateWrap {
AccountState accountState; AccountState accountState;
ContractDetails contractDetails; ContractDetailsImpl contractDetails;
public StateWrap(AccountState accountState, ContractDetails contractDetails) { public StateWrap(AccountState accountState, ContractDetailsImpl contractDetails) {
this.accountState = accountState; this.accountState = accountState;
this.contractDetails = contractDetails; this.contractDetails = contractDetails;
} }
@ -61,7 +61,7 @@ public class AccountBuilder {
return accountState; return accountState;
} }
public ContractDetails getContractDetails() { public ContractDetailsImpl getContractDetails() {
return contractDetails; return contractDetails;
} }
} }

View File

@ -2,10 +2,8 @@ package org.ethereum.jsontestsuite.builder;
import org.ethereum.core.AccountState; import org.ethereum.core.AccountState;
import org.ethereum.datasource.HashMapDB; import org.ethereum.datasource.HashMapDB;
import org.ethereum.datasource.KeyValueDataSource;
import org.ethereum.db.ByteArrayWrapper; import org.ethereum.db.ByteArrayWrapper;
import org.ethereum.db.ContractDetails; import org.ethereum.db.ContractDetails;
import org.ethereum.db.RepositoryDummy;
import org.ethereum.db.RepositoryImpl; import org.ethereum.db.RepositoryImpl;
import org.ethereum.facade.Repository; import org.ethereum.facade.Repository;
import org.ethereum.jsontestsuite.model.AccountTck; import org.ethereum.jsontestsuite.model.AccountTck;

View File

@ -1,12 +1,5 @@
package org.ethereum.jsontestsuite.model; package org.ethereum.jsontestsuite.model;
import org.ethereum.db.ContractDetails;
import org.ethereum.util.ByteUtil;
import org.ethereum.vm.DataWord;
import org.json.simple.JSONObject;
import org.spongycastle.util.encoders.Hex;
import java.math.BigInteger;
import java.util.*; import java.util.*;
/** /**

View File

@ -1,10 +1,8 @@
package org.ethereum.jsontestsuite.validators; package org.ethereum.jsontestsuite.validators;
import com.google.common.collect.Sets;
import org.ethereum.core.AccountState; import org.ethereum.core.AccountState;
import org.ethereum.db.ContractDetails; import org.ethereum.db.ContractDetails;
import org.ethereum.facade.Repository; import org.ethereum.facade.Repository;
import org.ethereum.util.ByteUtil;
import org.spongycastle.util.encoders.Hex; import org.spongycastle.util.encoders.Hex;
import java.util.ArrayList; import java.util.ArrayList;