Latest merges from develop branch.
This commit is contained in:
parent
80bdbf0f66
commit
8fe358c2f6
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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<>();
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue