Merged latest develop changes.
This commit is contained in:
parent
805234deb7
commit
74eca228dc
|
@ -89,6 +89,11 @@ public class LevelDbDataSource implements KeyValueDataSource {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] get(byte[] key) {
|
public byte[] get(byte[] key) {
|
||||||
return db.get(key);
|
return db.get(key);
|
||||||
|
|
|
@ -46,6 +46,11 @@ public class MapDBDataSource implements KeyValueDataSource {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] get(byte[] key) {
|
public byte[] get(byte[] key) {
|
||||||
return map.get(wrap(key));
|
return map.get(wrap(key));
|
||||||
|
|
|
@ -129,7 +129,7 @@ dependencies {
|
||||||
compile "com.h2database:h2:1.4.187"
|
compile "com.h2database:h2:1.4.187"
|
||||||
|
|
||||||
// compile "org.mapdb:mapdb:1.0.7"
|
// compile "org.mapdb:mapdb:1.0.7"
|
||||||
compile "org.mapdb:mapdb:2.0-alpha3"
|
compile "org.mapdb:mapdb:2.0-beta1"
|
||||||
|
|
||||||
compile "org.slf4j:slf4j-log4j12:${slf4jVersion}"
|
compile "org.slf4j:slf4j-log4j12:${slf4jVersion}"
|
||||||
compile "log4j:apache-log4j-extras:${log4jVersion}"
|
compile "log4j:apache-log4j-extras:${log4jVersion}"
|
||||||
|
|
|
@ -295,6 +295,12 @@ public class BlockchainImpl implements Blockchain {
|
||||||
track.commit();
|
track.commit();
|
||||||
storeBlock(block, receipts);
|
storeBlock(block, receipts);
|
||||||
|
|
||||||
|
if (block.getNumber() == 650_000){
|
||||||
|
repository.flush();
|
||||||
|
blockStore.flush();
|
||||||
|
System.exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
if (needFlush(block)) {
|
if (needFlush(block)) {
|
||||||
repository.flush();
|
repository.flush();
|
||||||
blockStore.flush();
|
blockStore.flush();
|
||||||
|
@ -322,13 +328,16 @@ public class BlockchainImpl implements Blockchain {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean needFlush(Block block) {
|
private boolean needFlush(Block block) {
|
||||||
|
|
||||||
|
boolean possibleFlush = CONFIG.flushBlocksIgnoreConsensus() || adminInfo.isConsensus();
|
||||||
|
if (!possibleFlush)return false;
|
||||||
|
|
||||||
if (CONFIG.flushBlocksRepoSize() > 0 && repository.getClass().isAssignableFrom(RepositoryImpl.class)) {
|
if (CONFIG.flushBlocksRepoSize() > 0 && repository.getClass().isAssignableFrom(RepositoryImpl.class)) {
|
||||||
return ((RepositoryImpl) repository).getAllocatedMemorySize() > CONFIG.flushBlocksRepoSize();
|
return ((RepositoryImpl) repository).getAllocatedMemorySize() > CONFIG.flushBlocksRepoSize();
|
||||||
} else {
|
} else {
|
||||||
boolean isBatchReached = block.getNumber() % CONFIG.flushBlocksBatchSize() == 0;
|
boolean isBatchReached = block.getNumber() % CONFIG.flushBlocksBatchSize() == 0;
|
||||||
boolean isConsensus = CONFIG.flushBlocksIgnoreConsensus() || adminInfo.isConsensus();
|
|
||||||
|
|
||||||
return isConsensus && isBatchReached;
|
return isBatchReached;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import org.ethereum.util.ByteUtil;
|
||||||
import org.ethereum.util.RLP;
|
import org.ethereum.util.RLP;
|
||||||
import org.ethereum.util.RLPList;
|
import org.ethereum.util.RLPList;
|
||||||
|
|
||||||
|
import org.ethereum.vm.GasCost;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -108,6 +109,22 @@ public class Transaction {
|
||||||
this.signature = signature;
|
this.signature = signature;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long transactionCost(){
|
||||||
|
|
||||||
|
if (!parsed) rlpParse();
|
||||||
|
|
||||||
|
long nonZeroes = nonZeroDataBytes();
|
||||||
|
long zeroVals = getDataSize() - nonZeroes;
|
||||||
|
|
||||||
|
return GasCost.TRANSACTION + zeroVals * GasCost.TX_ZERO_DATA + nonZeroes * GasCost.TX_NO_ZERO_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getDataSize(){
|
||||||
|
if (data == null)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return data.length;
|
||||||
|
}
|
||||||
|
|
||||||
public void rlpParse() {
|
public void rlpParse() {
|
||||||
|
|
||||||
|
|
|
@ -237,6 +237,10 @@ public class TransactionExecutor {
|
||||||
if (vm == null) return;
|
if (vm == null) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
// Charge basic cost of the transaction
|
||||||
|
program.spendGas(tx.transactionCost(), "TRANSACTION COST");
|
||||||
|
|
||||||
if (CONFIG.playVM())
|
if (CONFIG.playVM())
|
||||||
vm.play(program);
|
vm.play(program);
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,43 @@
|
||||||
package org.ethereum.datasource;
|
package org.ethereum.datasource;
|
||||||
|
|
||||||
import java.util.Map;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
|
import static org.slf4j.LoggerFactory.getLogger;
|
||||||
|
|
||||||
public class DataSourcePool {
|
public class DataSourcePool {
|
||||||
|
|
||||||
private static Map<String, KeyValueDataSource> pool = new ConcurrentHashMap<>();
|
private static Logger logger = getLogger("db");
|
||||||
|
private static ConcurrentMap<String, DataSource> pool = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
public static KeyValueDataSource levelDbByName(String name) {
|
public static KeyValueDataSource levelDbByName(String name) {
|
||||||
KeyValueDataSource dataSource = pool.get(name);
|
return (KeyValueDataSource) getDataSourceFromPool(name, new LevelDbDataSource(name));
|
||||||
if (dataSource == null) {
|
}
|
||||||
dataSource = new LevelDbDataSource(name);
|
|
||||||
dataSource.init();
|
private static DataSource getDataSourceFromPool(String name, DataSource dataSource) {
|
||||||
|
DataSource result = pool.putIfAbsent(name, dataSource);
|
||||||
pool.put(name, dataSource);
|
if (result == null) {
|
||||||
|
synchronized (dataSource) {
|
||||||
|
dataSource.init();
|
||||||
|
result = dataSource;
|
||||||
|
}
|
||||||
|
logger.info("Data source '{}' created and added to pool.", dataSource.getName());
|
||||||
|
} else {
|
||||||
|
logger.info("Data source '{}' returned from pool.", dataSource.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
return dataSource;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void closeDataSource(String name){
|
||||||
|
DataSource dataSource = pool.remove(name);
|
||||||
|
if (dataSource != null){
|
||||||
|
synchronized (dataSource) {
|
||||||
|
dataSource.close();
|
||||||
|
logger.info("Data source '{}' closed and removed from pool.", dataSource.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,11 @@ public class HashMapDB implements KeyValueDataSource {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "in-memory";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<byte[]> keys() {
|
public Set<byte[]> keys() {
|
||||||
Set<byte[]> keys = new HashSet<>();
|
Set<byte[]> keys = new HashSet<>();
|
||||||
|
@ -69,6 +74,6 @@ public class HashMapDB implements KeyValueDataSource {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
|
this.storage.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -7,11 +7,7 @@ import java.util.Set;
|
||||||
* @author Roman Mandeleil
|
* @author Roman Mandeleil
|
||||||
* @since 18.01.2015
|
* @since 18.01.2015
|
||||||
*/
|
*/
|
||||||
public interface KeyValueDataSource {
|
public interface KeyValueDataSource extends DataSource {
|
||||||
|
|
||||||
void init();
|
|
||||||
|
|
||||||
void setName(String name);
|
|
||||||
|
|
||||||
byte[] get(byte[] key);
|
byte[] get(byte[] key);
|
||||||
|
|
||||||
|
@ -22,6 +18,4 @@ public interface KeyValueDataSource {
|
||||||
Set<byte[]> keys();
|
Set<byte[]> keys();
|
||||||
|
|
||||||
void updateBatch(Map<byte[], byte[]> rows);
|
void updateBatch(Map<byte[], byte[]> rows);
|
||||||
|
|
||||||
void close();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,10 +51,6 @@ public class LevelDbDataSource implements KeyValueDataSource {
|
||||||
File dbLocation = fileLocation.getParentFile();
|
File dbLocation = fileLocation.getParentFile();
|
||||||
if (!dbLocation.exists()) dbLocation.mkdirs();
|
if (!dbLocation.exists()) dbLocation.mkdirs();
|
||||||
|
|
||||||
if (CONFIG.databaseReset()) {
|
|
||||||
destroyDB(fileLocation);
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.debug("Initializing new or existing database: '{}'", name);
|
logger.debug("Initializing new or existing database: '{}'", name);
|
||||||
db = factory.open(fileLocation, options);
|
db = factory.open(fileLocation, options);
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
|
@ -79,6 +75,11 @@ public class LevelDbDataSource implements KeyValueDataSource {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] get(byte[] key) {
|
public byte[] get(byte[] key) {
|
||||||
return db.get(key);
|
return db.get(key);
|
||||||
|
|
|
@ -42,6 +42,11 @@ public class MapDBDataSource implements KeyValueDataSource {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] get(byte[] key) {
|
public byte[] get(byte[] key) {
|
||||||
return map.get(key);
|
return map.get(key);
|
||||||
|
|
|
@ -53,6 +53,11 @@ public class RedisDataSource extends RedisMap<byte[], byte[]> implements KeyValu
|
||||||
super.setName(name);
|
super.setName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return new String(getNameBytes());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] get(byte[] key) {
|
public byte[] get(byte[] key) {
|
||||||
return super.get(key);
|
return super.get(key);
|
||||||
|
|
|
@ -33,7 +33,7 @@ public class RedisMap<K, V> extends RedisStorage<V> implements Map<K, V> {
|
||||||
return pooledWithResult(new Function<Jedis, Integer>() {
|
return pooledWithResult(new Function<Jedis, Integer>() {
|
||||||
@Override
|
@Override
|
||||||
public Integer apply(Jedis jedis) {
|
public Integer apply(Jedis jedis) {
|
||||||
return jedis.hlen(getName()).intValue();
|
return jedis.hlen(getNameBytes()).intValue();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ public class RedisMap<K, V> extends RedisStorage<V> implements Map<K, V> {
|
||||||
return pooledWithResult(new Function<Jedis, Boolean>() {
|
return pooledWithResult(new Function<Jedis, Boolean>() {
|
||||||
@Override
|
@Override
|
||||||
public Boolean apply(Jedis jedis) {
|
public Boolean apply(Jedis jedis) {
|
||||||
return jedis.hexists(getName(), serializeKey((K) key));
|
return jedis.hexists(getNameBytes(), serializeKey((K) key));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ public class RedisMap<K, V> extends RedisStorage<V> implements Map<K, V> {
|
||||||
return pooledWithResult(new Function<Jedis, V>() {
|
return pooledWithResult(new Function<Jedis, V>() {
|
||||||
@Override
|
@Override
|
||||||
public V apply(Jedis jedis) {
|
public V apply(Jedis jedis) {
|
||||||
byte[] value = jedis.hget(getName(), serializeKey((K) key));
|
byte[] value = jedis.hget(getNameBytes(), serializeKey((K) key));
|
||||||
return deserialize(value);
|
return deserialize(value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -75,8 +75,8 @@ public class RedisMap<K, V> extends RedisStorage<V> implements Map<K, V> {
|
||||||
@Override
|
@Override
|
||||||
public V apply(Jedis jedis) {
|
public V apply(Jedis jedis) {
|
||||||
byte[] serializedKey = serializeKey(key);
|
byte[] serializedKey = serializeKey(key);
|
||||||
byte[] oldValue = jedis.hget(getName(), serializedKey);
|
byte[] oldValue = jedis.hget(getNameBytes(), serializedKey);
|
||||||
jedis.hset(getName(), serializedKey, serialize(value));
|
jedis.hset(getNameBytes(), serializedKey, serialize(value));
|
||||||
return deserialize(oldValue);
|
return deserialize(oldValue);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -88,8 +88,8 @@ public class RedisMap<K, V> extends RedisStorage<V> implements Map<K, V> {
|
||||||
@Override
|
@Override
|
||||||
public V apply(Jedis jedis) {
|
public V apply(Jedis jedis) {
|
||||||
byte[] serializedKey = serializeKey((K) key);
|
byte[] serializedKey = serializeKey((K) key);
|
||||||
byte[] oldValue = jedis.hget(getName(), serializedKey);
|
byte[] oldValue = jedis.hget(getNameBytes(), serializedKey);
|
||||||
jedis.hdel(getName(), serializedKey);
|
jedis.hdel(getNameBytes(), serializedKey);
|
||||||
return deserialize(oldValue);
|
return deserialize(oldValue);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -104,7 +104,7 @@ public class RedisMap<K, V> extends RedisStorage<V> implements Map<K, V> {
|
||||||
for (Entry<? extends K, ? extends V> entry : m.entrySet()) {
|
for (Entry<? extends K, ? extends V> entry : m.entrySet()) {
|
||||||
map.put(serializeKey(entry.getKey()), serialize(entry.getValue()));
|
map.put(serializeKey(entry.getKey()), serialize(entry.getValue()));
|
||||||
}
|
}
|
||||||
jedis.hmset(getName(), map);
|
jedis.hmset(getNameBytes(), map);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ public class RedisMap<K, V> extends RedisStorage<V> implements Map<K, V> {
|
||||||
pooled(new Consumer<Jedis>() {
|
pooled(new Consumer<Jedis>() {
|
||||||
@Override
|
@Override
|
||||||
public void accept(Jedis jedis) {
|
public void accept(Jedis jedis) {
|
||||||
jedis.del(getName());
|
jedis.del(getNameBytes());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -125,7 +125,7 @@ public class RedisMap<K, V> extends RedisStorage<V> implements Map<K, V> {
|
||||||
@Override
|
@Override
|
||||||
public Set<K> apply(Jedis jedis) {
|
public Set<K> apply(Jedis jedis) {
|
||||||
Set<K> result = new HashSet<K>();
|
Set<K> result = new HashSet<K>();
|
||||||
collect(jedis.hkeys(getName()), new Transformer<byte[], K>() {
|
collect(jedis.hkeys(getNameBytes()), new Transformer<byte[], K>() {
|
||||||
@Override
|
@Override
|
||||||
public K transform(byte[] input) {
|
public K transform(byte[] input) {
|
||||||
return deserializeKey(input);
|
return deserializeKey(input);
|
||||||
|
@ -141,7 +141,7 @@ public class RedisMap<K, V> extends RedisStorage<V> implements Map<K, V> {
|
||||||
return pooledWithResult(new Function<Jedis, Collection<V>>() {
|
return pooledWithResult(new Function<Jedis, Collection<V>>() {
|
||||||
@Override
|
@Override
|
||||||
public Collection<V> apply(Jedis jedis) {
|
public Collection<V> apply(Jedis jedis) {
|
||||||
return deserialize(jedis.hvals(getName()));
|
return deserialize(jedis.hvals(getNameBytes()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ public class RedisMap<K, V> extends RedisStorage<V> implements Map<K, V> {
|
||||||
@Override
|
@Override
|
||||||
public Set<Entry<K, V>> apply(Jedis jedis) {
|
public Set<Entry<K, V>> apply(Jedis jedis) {
|
||||||
Set<Entry<K, V>> result = new HashSet<Entry<K, V>>();
|
Set<Entry<K, V>> result = new HashSet<Entry<K, V>>();
|
||||||
collect(jedis.hgetAll(getName()).entrySet(), new Transformer<Entry<byte[], byte[]>, Entry<K, V>>() {
|
collect(jedis.hgetAll(getNameBytes()).entrySet(), new Transformer<Entry<byte[], byte[]>, Entry<K, V>>() {
|
||||||
@Override
|
@Override
|
||||||
public Entry<K, V> transform(Entry<byte[], byte[]> input) {
|
public Entry<K, V> transform(Entry<byte[], byte[]> input) {
|
||||||
K key = deserializeKey(input.getKey());
|
K key = deserializeKey(input.getKey());
|
||||||
|
|
|
@ -23,7 +23,7 @@ public class RedisSet<T> extends RedisStorage<T> implements Set<T> {
|
||||||
return pooledWithResult(new Function<Jedis, Integer>() {
|
return pooledWithResult(new Function<Jedis, Integer>() {
|
||||||
@Override
|
@Override
|
||||||
public Integer apply(Jedis jedis) {
|
public Integer apply(Jedis jedis) {
|
||||||
return jedis.scard(getName()).intValue();
|
return jedis.scard(getNameBytes()).intValue();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ public class RedisSet<T> extends RedisStorage<T> implements Set<T> {
|
||||||
return pooledWithResult(new Function<Jedis, Boolean>() {
|
return pooledWithResult(new Function<Jedis, Boolean>() {
|
||||||
@Override
|
@Override
|
||||||
public Boolean apply(Jedis jedis) {
|
public Boolean apply(Jedis jedis) {
|
||||||
return jedis.sismember(getName(), serialize((T) o));
|
return jedis.sismember(getNameBytes(), serialize((T) o));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ public class RedisSet<T> extends RedisStorage<T> implements Set<T> {
|
||||||
Set<byte[]> members = pooledWithResult(new Function<Jedis, Set<byte[]>>() {
|
Set<byte[]> members = pooledWithResult(new Function<Jedis, Set<byte[]>>() {
|
||||||
@Override
|
@Override
|
||||||
public Set<byte[]> apply(Jedis jedis) {
|
public Set<byte[]> apply(Jedis jedis) {
|
||||||
return jedis.smembers(getName());
|
return jedis.smembers(getNameBytes());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return deserialize(members);
|
return deserialize(members);
|
||||||
|
@ -88,7 +88,7 @@ public class RedisSet<T> extends RedisStorage<T> implements Set<T> {
|
||||||
return pooledWithResult(new Function<Jedis, Boolean>() {
|
return pooledWithResult(new Function<Jedis, Boolean>() {
|
||||||
@Override
|
@Override
|
||||||
public Boolean apply(Jedis jedis) {
|
public Boolean apply(Jedis jedis) {
|
||||||
return jedis.sadd(getName(), serialize(c)) == c.size();
|
return jedis.sadd(getNameBytes(), serialize(c)) == c.size();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ public class RedisSet<T> extends RedisStorage<T> implements Set<T> {
|
||||||
byte[] tempName = temporaryName();
|
byte[] tempName = temporaryName();
|
||||||
try {
|
try {
|
||||||
jedis.sadd(tempName, serialize(c));
|
jedis.sadd(tempName, serialize(c));
|
||||||
return jedis.scard(getName()) != jedis.sinterstore(getName(), getName(), tempName);
|
return jedis.scard(getNameBytes()) != jedis.sinterstore(getNameBytes(), getNameBytes(), tempName);
|
||||||
} finally {
|
} finally {
|
||||||
jedis.del(tempName);
|
jedis.del(tempName);
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ public class RedisSet<T> extends RedisStorage<T> implements Set<T> {
|
||||||
return CollectionUtils.isEmpty(c) || pooledWithResult(new Function<Jedis, Boolean>() {
|
return CollectionUtils.isEmpty(c) || pooledWithResult(new Function<Jedis, Boolean>() {
|
||||||
@Override
|
@Override
|
||||||
public Boolean apply(Jedis jedis) {
|
public Boolean apply(Jedis jedis) {
|
||||||
return jedis.srem(getName(), serialize(c)) == c.size();
|
return jedis.srem(getNameBytes(), serialize(c)) == c.size();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -124,7 +124,7 @@ public class RedisSet<T> extends RedisStorage<T> implements Set<T> {
|
||||||
pooled(new Consumer<Jedis>() {
|
pooled(new Consumer<Jedis>() {
|
||||||
@Override
|
@Override
|
||||||
public void accept(Jedis jedis) {
|
public void accept(Jedis jedis) {
|
||||||
jedis.del(getName());
|
jedis.del(getNameBytes());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ public abstract class RedisStorage<T> {
|
||||||
this.serializer = serializer;
|
this.serializer = serializer;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected byte[] getName() {
|
protected byte[] getNameBytes() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ public abstract class RedisStorage<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected byte[] formatName(String suffix) {
|
protected byte[] formatName(String suffix) {
|
||||||
return Bytes.concat(getName(), suffix.getBytes());
|
return Bytes.concat(getNameBytes(), suffix.getBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected byte[] temporaryName() {
|
protected byte[] temporaryName() {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package org.ethereum.db;
|
package org.ethereum.db;
|
||||||
|
|
||||||
import org.ethereum.config.SystemProperties;
|
import org.ethereum.config.SystemProperties;
|
||||||
|
import org.ethereum.datasource.DataSourcePool;
|
||||||
import org.ethereum.datasource.KeyValueDataSource;
|
import org.ethereum.datasource.KeyValueDataSource;
|
||||||
import org.ethereum.trie.SecureTrie;
|
import org.ethereum.trie.SecureTrie;
|
||||||
import org.ethereum.util.RLP;
|
import org.ethereum.util.RLP;
|
||||||
|
@ -52,13 +53,13 @@ public class ContractDetailsImpl implements ContractDetails {
|
||||||
keys.add(wrap(key));
|
keys.add(wrap(key));
|
||||||
keysSize += key.length;
|
keysSize += key.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeKey(byte[] key) {
|
private void removeKey(byte[] key) {
|
||||||
if (keys.remove(wrap(key))) {
|
if (keys.remove(wrap(key))) {
|
||||||
keysSize -= key.length;
|
keysSize -= key.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void put(DataWord key, DataWord value) {
|
public void put(DataWord key, DataWord value) {
|
||||||
if (value.equals(DataWord.ZERO)) {
|
if (value.equals(DataWord.ZERO)) {
|
||||||
|
@ -71,7 +72,7 @@ public class ContractDetailsImpl implements ContractDetails {
|
||||||
|
|
||||||
this.setDirty(true);
|
this.setDirty(true);
|
||||||
this.rlpEncoded = null;
|
this.rlpEncoded = null;
|
||||||
|
|
||||||
externalStorage = (keys.size() > SystemProperties.CONFIG.detailsInMemoryStorageLimit()) || externalStorage;
|
externalStorage = (keys.size() > SystemProperties.CONFIG.detailsInMemoryStorageLimit()) || externalStorage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +124,7 @@ public class ContractDetailsImpl implements ContractDetails {
|
||||||
for (RLPElement key : keys) {
|
for (RLPElement key : keys) {
|
||||||
addKey(key.getRLPData());
|
addKey(key.getRLPData());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (externalStorage) {
|
if (externalStorage) {
|
||||||
storageTrie.setRoot(storageRoot.getRLPData());
|
storageTrie.setRoot(storageRoot.getRLPData());
|
||||||
storageTrie.getCache().setDB(getExternalStorageDataSource());
|
storageTrie.getCache().setDB(getExternalStorageDataSource());
|
||||||
|
@ -215,6 +216,8 @@ public class ContractDetailsImpl implements ContractDetails {
|
||||||
if (externalStorage) {
|
if (externalStorage) {
|
||||||
storageTrie.getCache().setDB(getExternalStorageDataSource());
|
storageTrie.getCache().setDB(getExternalStorageDataSource());
|
||||||
storageTrie.sync();
|
storageTrie.sync();
|
||||||
|
|
||||||
|
DataSourcePool.closeDataSource("details-storage/" + toHexString(address));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,14 +253,14 @@ public class ContractDetailsImpl implements ContractDetails {
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getAllocatedMemorySize() {
|
public int getAllocatedMemorySize() {
|
||||||
int result = rlpEncoded == null ? 0 : rlpEncoded.length;
|
int result = rlpEncoded == null ? 0 : rlpEncoded.length;
|
||||||
result += address.length;
|
result += address.length;
|
||||||
result += code.length;
|
result += code.length;
|
||||||
result += storageTrie.getCache().getAllocatedMemorySize();
|
result += storageTrie.getCache().getAllocatedMemorySize();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,7 +135,7 @@ public class RepositoryImpl implements Repository {
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (!contractDetails.isDirty()) continue;
|
if (!contractDetails.isDirty()) continue;
|
||||||
|
|
||||||
ContractDetailsCacheImpl contractDetailsCache = (ContractDetailsCacheImpl)contractDetails;
|
ContractDetailsCacheImpl contractDetailsCache = (ContractDetailsCacheImpl)contractDetails;
|
||||||
if (contractDetailsCache.origContract == null){
|
if (contractDetailsCache.origContract == null){
|
||||||
contractDetailsCache.origContract = new ContractDetailsImpl();
|
contractDetailsCache.origContract = new ContractDetailsImpl();
|
||||||
|
@ -170,12 +170,26 @@ public class RepositoryImpl implements Repository {
|
||||||
detailsCache.clear();
|
detailsCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flushNoReconnect(){
|
||||||
|
|
||||||
|
gLogger.info("flushing to disk");
|
||||||
|
|
||||||
|
dds.flush();
|
||||||
|
worldState.sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void flush() {
|
public void flush() {
|
||||||
gLogger.info("flushing to disk");
|
gLogger.info("flushing to disk");
|
||||||
|
|
||||||
dds.flush();
|
dds.flush();
|
||||||
worldState.sync();
|
worldState.sync();
|
||||||
|
|
||||||
|
byte[] root = worldState.getRootHash();
|
||||||
|
reset();
|
||||||
|
worldState.setRoot(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getAllocatedMemorySize() {
|
public int getAllocatedMemorySize() {
|
||||||
|
|
|
@ -244,6 +244,10 @@ public class RepositoryTrack implements Repository {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flushNoReconnect() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void commit() {
|
public void commit() {
|
||||||
|
|
|
@ -24,6 +24,8 @@ public class CommonConfig {
|
||||||
|
|
||||||
private RedisConnection redisConnection;
|
private RedisConnection redisConnection;
|
||||||
|
|
||||||
|
private MapDBFactory mapDBFactory;
|
||||||
|
|
||||||
Repository repository() {
|
Repository repository() {
|
||||||
return new RepositoryImpl(keyValueDataSource(), keyValueDataSource());
|
return new RepositoryImpl(keyValueDataSource(), keyValueDataSource());
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,11 @@ import org.ethereum.di.components.DaggerEthereumComponent;
|
||||||
import org.ethereum.net.eth.EthHandler;
|
import org.ethereum.net.eth.EthHandler;
|
||||||
import org.ethereum.net.shh.ShhHandler;
|
import org.ethereum.net.shh.ShhHandler;
|
||||||
|
|
||||||
|
import org.ethereum.util.FileUtil;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import static org.ethereum.config.SystemProperties.CONFIG;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Roman Mandeleil
|
* @author Roman Mandeleil
|
||||||
|
@ -22,6 +24,16 @@ public class EthereumFactory {
|
||||||
|
|
||||||
public static Ethereum createEthereum() {
|
public static Ethereum createEthereum() {
|
||||||
|
|
||||||
|
if (CONFIG.databaseReset()){
|
||||||
|
FileUtil.recursiveDelete(CONFIG.databaseDir());
|
||||||
|
logger.info("Database reset done");
|
||||||
|
}
|
||||||
|
|
||||||
|
return createEthereum(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Ethereum createEthereum(Class clazz) {
|
||||||
|
|
||||||
logger.info("capability eth version: [{}]", EthHandler.VERSION);
|
logger.info("capability eth version: [{}]", EthHandler.VERSION);
|
||||||
logger.info("capability shh version: [{}]", ShhHandler.VERSION);
|
logger.info("capability shh version: [{}]", ShhHandler.VERSION);
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@ import org.hibernate.SessionFactory;
|
||||||
*/
|
*/
|
||||||
public class RemoteConfig {
|
public class RemoteConfig {
|
||||||
|
|
||||||
|
//@Autowired
|
||||||
|
CommonConfig commonConfig;
|
||||||
|
|
||||||
public BlockStore blockStore(SessionFactory sessionFactory){
|
public BlockStore blockStore(SessionFactory sessionFactory){
|
||||||
|
|
||||||
|
|
|
@ -151,6 +151,7 @@ public interface Repository {
|
||||||
public Repository startTracking();
|
public Repository startTracking();
|
||||||
|
|
||||||
public void flush();
|
public void flush();
|
||||||
|
public void flushNoReconnect();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -71,7 +71,8 @@ public class TestProgramInvokeFactory implements ProgramInvokeFactory {
|
||||||
/*** CALLDATALOAD op ***/
|
/*** CALLDATALOAD op ***/
|
||||||
/*** CALLDATACOPY op ***/
|
/*** CALLDATACOPY op ***/
|
||||||
/*** CALLDATASIZE op ***/
|
/*** CALLDATASIZE op ***/
|
||||||
byte[] data = tx.getData() == null ? ByteUtil.EMPTY_BYTE_ARRAY : tx.getData();
|
byte[] data = tx.isContractCreation() ? ByteUtil.EMPTY_BYTE_ARRAY :( tx.getData() == null ? ByteUtil.EMPTY_BYTE_ARRAY : tx.getData() );
|
||||||
|
// byte[] data = tx.getData() == null ? ByteUtil.EMPTY_BYTE_ARRAY : tx.getData() ;
|
||||||
|
|
||||||
/*** PREVHASH op ***/
|
/*** PREVHASH op ***/
|
||||||
byte[] lastHash = env.getPreviousHash();
|
byte[] lastHash = env.getPreviousHash();
|
||||||
|
|
|
@ -21,6 +21,8 @@ public class Utils {
|
||||||
data = data.substring(2);
|
data = data.substring(2);
|
||||||
if (data.equals("")) return EMPTY_BYTE_ARRAY;
|
if (data.equals("")) return EMPTY_BYTE_ARRAY;
|
||||||
|
|
||||||
|
if (data.length() % 2 == 1) data = "0" + data;
|
||||||
|
|
||||||
return Hex.decode(data);
|
return Hex.decode(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ public class RepositoryBuilder {
|
||||||
|
|
||||||
RepositoryImpl repositoryDummy = new RepositoryImpl(new HashMapDB(), new HashMapDB());
|
RepositoryImpl repositoryDummy = new RepositoryImpl(new HashMapDB(), new HashMapDB());
|
||||||
repositoryDummy.updateBatch(stateBatch, detailsBatch);
|
repositoryDummy.updateBatch(stateBatch, detailsBatch);
|
||||||
repositoryDummy.flush();
|
repositoryDummy.flushNoReconnect();
|
||||||
|
|
||||||
return repositoryDummy;
|
return repositoryDummy;
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ public class StateTestRunner {
|
||||||
}
|
}
|
||||||
|
|
||||||
track.commit();
|
track.commit();
|
||||||
repository.flush();
|
repository.flushNoReconnect();
|
||||||
|
|
||||||
List<LogInfo> origLogs = executor.getResult().getLogInfoList();
|
List<LogInfo> origLogs = executor.getResult().getLogInfoList();
|
||||||
List<LogInfo> postLogs = LogBuilder.build(stateTestCase2.getLogs());
|
List<LogInfo> postLogs = LogBuilder.build(stateTestCase2.getLogs());
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
package org.ethereum.net.p2p;
|
package org.ethereum.net.p2p;
|
||||||
|
|
||||||
|
import com.google.common.base.Joiner;
|
||||||
import org.ethereum.net.client.Capability;
|
import org.ethereum.net.client.Capability;
|
||||||
import org.ethereum.util.ByteUtil;
|
import org.ethereum.util.ByteUtil;
|
||||||
import org.ethereum.util.RLP;
|
import org.ethereum.util.RLP;
|
||||||
import org.ethereum.util.RLPElement;
|
import org.ethereum.util.RLPElement;
|
||||||
import org.ethereum.util.RLPList;
|
import org.ethereum.util.RLPList;
|
||||||
|
|
||||||
import com.google.common.base.Joiner;
|
|
||||||
|
|
||||||
import org.spongycastle.util.encoders.Hex;
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -64,33 +62,28 @@ public class HelloMessage extends P2pMessage {
|
||||||
byte[] p2pVersionBytes = paramsList.get(0).getRLPData();
|
byte[] p2pVersionBytes = paramsList.get(0).getRLPData();
|
||||||
this.p2pVersion = p2pVersionBytes != null ? p2pVersionBytes[0] : 0;
|
this.p2pVersion = p2pVersionBytes != null ? p2pVersionBytes[0] : 0;
|
||||||
|
|
||||||
try {
|
byte[] clientIdBytes = paramsList.get(1).getRLPData();
|
||||||
byte[] clientIdBytes = paramsList.get(1).getRLPData();
|
this.clientId = new String(clientIdBytes != null ? clientIdBytes : EMPTY_BYTE_ARRAY);
|
||||||
this.clientId = new String(clientIdBytes != null ? clientIdBytes : EMPTY_BYTE_ARRAY);
|
|
||||||
|
|
||||||
RLPList capabilityList = (RLPList) paramsList.get(2);
|
RLPList capabilityList = (RLPList) paramsList.get(2);
|
||||||
this.capabilities = new ArrayList<>();
|
this.capabilities = new ArrayList<>();
|
||||||
for (Object aCapabilityList : capabilityList) {
|
for (Object aCapabilityList : capabilityList) {
|
||||||
|
|
||||||
RLPElement capId = ((RLPList) aCapabilityList).get(0);
|
RLPElement capId = ((RLPList) aCapabilityList).get(0);
|
||||||
RLPElement capVersion = ((RLPList) aCapabilityList).get(1);
|
RLPElement capVersion = ((RLPList) aCapabilityList).get(1);
|
||||||
|
|
||||||
String name = new String(capId.getRLPData());
|
String name = new String(capId.getRLPData());
|
||||||
byte version = capVersion.getRLPData() == null ? 0 : capVersion.getRLPData()[0];
|
byte version = capVersion.getRLPData() == null ? 0 : capVersion.getRLPData()[0];
|
||||||
|
|
||||||
Capability cap = new Capability(name, version);
|
Capability cap = new Capability(name, version);
|
||||||
this.capabilities.add(cap);
|
this.capabilities.add(cap);
|
||||||
}
|
|
||||||
|
|
||||||
byte[] peerPortBytes = paramsList.get(3).getRLPData();
|
|
||||||
this.listenPort = ByteUtil.byteArrayToInt(peerPortBytes);
|
|
||||||
|
|
||||||
byte[] peerIdBytes = paramsList.get(4).getRLPData();
|
|
||||||
this.peerId = Hex.toHexString(peerIdBytes);
|
|
||||||
}
|
|
||||||
catch ( Exception e ) {
|
|
||||||
System.out.println(e.getMessage());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
byte[] peerPortBytes = paramsList.get(3).getRLPData();
|
||||||
|
this.listenPort = ByteUtil.byteArrayToInt(peerPortBytes);
|
||||||
|
|
||||||
|
byte[] peerIdBytes = paramsList.get(4).getRLPData();
|
||||||
|
this.peerId = Hex.toHexString(peerIdBytes);
|
||||||
this.parsed = true;
|
this.parsed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +95,7 @@ public class HelloMessage extends P2pMessage {
|
||||||
Capability capability = this.capabilities.get(i);
|
Capability capability = this.capabilities.get(i);
|
||||||
capabilities[i] = RLP.encodeList(
|
capabilities[i] = RLP.encodeList(
|
||||||
RLP.encodeElement(capability.getName().getBytes()),
|
RLP.encodeElement(capability.getName().getBytes()),
|
||||||
RLP.encodeElement(new byte[]{capability.getVersion()}));
|
RLP.encodeInt(capability.getVersion()));
|
||||||
}
|
}
|
||||||
byte[] capabilityList = RLP.encodeList(capabilities);
|
byte[] capabilityList = RLP.encodeList(capabilities);
|
||||||
byte[] peerPort = RLP.encodeInt(this.listenPort);
|
byte[] peerPort = RLP.encodeInt(this.listenPort);
|
||||||
|
|
|
@ -759,7 +759,7 @@ public class RLP {
|
||||||
if (isNullOrZeroArray(srcData))
|
if (isNullOrZeroArray(srcData))
|
||||||
return new byte[]{(byte) OFFSET_SHORT_ITEM};
|
return new byte[]{(byte) OFFSET_SHORT_ITEM};
|
||||||
else if (isSingleZero(srcData))
|
else if (isSingleZero(srcData))
|
||||||
return new byte[]{00};
|
return srcData;
|
||||||
else if (srcData.length == 1 && (srcData[0] & 0xFF) < 0x80) {
|
else if (srcData.length == 1 && (srcData[0] & 0xFF) < 0x80) {
|
||||||
return srcData;
|
return srcData;
|
||||||
} else if (srcData.length < SIZE_THRESHOLD) {
|
} else if (srcData.length < SIZE_THRESHOLD) {
|
||||||
|
|
|
@ -488,7 +488,7 @@ public class Program {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result != null &&
|
if (result != null &&
|
||||||
result.getException() != null) {
|
result.getException() != null) {
|
||||||
gasLogger.debug("contract run halted by Exception: contract: [{}], exception: [{}]",
|
gasLogger.debug("contract run halted by Exception: contract: [{}], exception: [{}]",
|
||||||
Hex.toHexString(contextAddress),
|
Hex.toHexString(contextAddress),
|
||||||
result.getException());
|
result.getException());
|
||||||
|
|
|
@ -29,8 +29,6 @@ public interface ProgramInvoke {
|
||||||
|
|
||||||
public byte[] getDataCopy(DataWord offsetData, DataWord lengthData);
|
public byte[] getDataCopy(DataWord offsetData, DataWord lengthData);
|
||||||
|
|
||||||
public int countNonZeroData();
|
|
||||||
|
|
||||||
public DataWord getPrevHash();
|
public DataWord getPrevHash();
|
||||||
|
|
||||||
public DataWord getCoinbase();
|
public DataWord getCoinbase();
|
||||||
|
|
|
@ -66,7 +66,7 @@ public class ProgramInvokeFactoryImpl implements ProgramInvokeFactory {
|
||||||
/*** CALLDATALOAD op ***/
|
/*** CALLDATALOAD op ***/
|
||||||
/*** CALLDATACOPY op ***/
|
/*** CALLDATACOPY op ***/
|
||||||
/*** CALLDATASIZE op ***/
|
/*** CALLDATASIZE op ***/
|
||||||
byte[] data = tx.getData() == null ? ByteUtil.EMPTY_BYTE_ARRAY : tx.getData();
|
byte[] data = tx.isContractCreation() ? ByteUtil.EMPTY_BYTE_ARRAY :( tx.getData() == null ? ByteUtil.EMPTY_BYTE_ARRAY : tx.getData() );
|
||||||
|
|
||||||
/*** PREVHASH op ***/
|
/*** PREVHASH op ***/
|
||||||
byte[] lastHash = lastBlock.getHash();
|
byte[] lastHash = lastBlock.getHash();
|
||||||
|
|
|
@ -194,17 +194,6 @@ public class ProgramInvokeImpl implements ProgramInvoke {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int countNonZeroData() {
|
|
||||||
|
|
||||||
int counter = 0;
|
|
||||||
for (byte aMsgData : msgData) {
|
|
||||||
|
|
||||||
if (aMsgData != 0) ++counter;
|
|
||||||
}
|
|
||||||
return counter;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* PREVHASH op */
|
/* PREVHASH op */
|
||||||
public DataWord getPrevHash() {
|
public DataWord getPrevHash() {
|
||||||
return prevHash;
|
return prevHash;
|
||||||
|
|
|
@ -157,18 +157,6 @@ public class ProgramInvokeMockImpl implements ProgramInvoke {
|
||||||
return new DataWord(prevHash);
|
return new DataWord(prevHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int countNonZeroData() {
|
|
||||||
|
|
||||||
int counter = 0;
|
|
||||||
for (byte aMsgData : msgData) {
|
|
||||||
|
|
||||||
if (aMsgData != 0) ++counter;
|
|
||||||
}
|
|
||||||
return counter;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DataWord getCoinbase() {
|
public DataWord getCoinbase() {
|
||||||
byte[] coinBase = Hex.decode("E559DE5527492BCB42EC68D07DF0742A98EC3F1E");
|
byte[] coinBase = Hex.decode("E559DE5527492BCB42EC68D07DF0742A98EC3F1E");
|
||||||
|
|
|
@ -119,6 +119,12 @@ public class Storage implements Repository, ProgramTraceListenerAware {
|
||||||
repository.flush();
|
repository.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flushNoReconnect() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void commit() {
|
public void commit() {
|
||||||
repository.commit();
|
repository.commit();
|
||||||
|
|
|
@ -182,11 +182,11 @@ public class VM {
|
||||||
|
|
||||||
//check to see if account does not exist and is not a precompiled contract
|
//check to see if account does not exist and is not a precompiled contract
|
||||||
if (op != CALLCODE && !program.result.getRepository().isExist(callAddressWord.getLast20Bytes()))
|
if (op != CALLCODE && !program.result.getRepository().isExist(callAddressWord.getLast20Bytes()))
|
||||||
gasCost += GasCost.NEW_ACCT_CALL;
|
gasCost += GasCost.NEW_ACCT_CALL;
|
||||||
|
|
||||||
//TODO #POC9 Make sure this is converted to BigInteger (256num support)
|
//TODO #POC9 Make sure this is converted to BigInteger (256num support)
|
||||||
if (!stack.get(stack.size() - 3).isZero() )
|
if (!stack.get(stack.size() - 3).isZero() )
|
||||||
gasCost += GasCost.VT_CALL;
|
gasCost += GasCost.VT_CALL;
|
||||||
|
|
||||||
BigInteger in = memNeeded(stack.get(stack.size() - 4), stack.get(stack.size() - 5)); // in offset+size
|
BigInteger in = memNeeded(stack.get(stack.size() - 4), stack.get(stack.size() - 5)); // in offset+size
|
||||||
BigInteger out = memNeeded(stack.get(stack.size() - 6), stack.get(stack.size() - 7)); // out offset+size
|
BigInteger out = memNeeded(stack.get(stack.size() - 6), stack.get(stack.size() - 7)); // out offset+size
|
||||||
|
@ -240,7 +240,7 @@ public class VM {
|
||||||
long memWordsOld = (oldMemSize / 32);
|
long memWordsOld = (oldMemSize / 32);
|
||||||
//TODO #POC9 c_quadCoeffDiv = 512, this should be a constant, not magic number
|
//TODO #POC9 c_quadCoeffDiv = 512, this should be a constant, not magic number
|
||||||
long memGas = ( GasCost.MEMORY * memWords + memWords * memWords / 512)
|
long memGas = ( GasCost.MEMORY * memWords + memWords * memWords / 512)
|
||||||
- (GasCost.MEMORY * memWordsOld + memWordsOld * memWordsOld / 512);
|
- (GasCost.MEMORY * memWordsOld + memWordsOld * memWordsOld / 512);
|
||||||
program.spendGas(memGas, op.name() + " (memory usage)");
|
program.spendGas(memGas, op.name() + " (memory usage)");
|
||||||
gasCost += memGas;
|
gasCost += memGas;
|
||||||
}
|
}
|
||||||
|
@ -1144,19 +1144,6 @@ public class VM {
|
||||||
|
|
||||||
public void play(Program program) {
|
public void play(Program program) {
|
||||||
try {
|
try {
|
||||||
// In case the program invoked by wire got
|
|
||||||
// transaction, this will be the gas cost,
|
|
||||||
// otherwise the call done by other contract
|
|
||||||
// charged by CALL op
|
|
||||||
if (program.invokeData.byTransaction()) {
|
|
||||||
program.spendGas(GasCost.TRANSACTION, "TRANSACTION");
|
|
||||||
int dataSize = program.invokeData.getDataSize().intValue();
|
|
||||||
int nonZeroesVals = program.invokeData.countNonZeroData();
|
|
||||||
int zeroVals = dataSize - nonZeroesVals;
|
|
||||||
|
|
||||||
program.spendGas(GasCost.TX_NO_ZERO_DATA * nonZeroesVals, "DATA");
|
|
||||||
program.spendGas(GasCost.TX_ZERO_DATA * zeroVals, "DATA");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (program.invokeData.byTestingSuite()) return;
|
if (program.invokeData.byTestingSuite()) return;
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,18 @@
|
||||||
package org.ethereum;
|
package org.ethereum;
|
||||||
|
|
||||||
|
import org.ethereum.db.IndexedBlockStore;
|
||||||
import org.ethereum.vm.DataWord;
|
import org.ethereum.vm.DataWord;
|
||||||
|
import org.mapdb.DB;
|
||||||
|
import org.mapdb.DBMaker;
|
||||||
|
import org.mapdb.Serializer;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
|
import static org.ethereum.db.IndexedBlockStore.BLOCK_INFO_SERIALIZER;
|
||||||
|
|
||||||
public final class TestUtils {
|
public final class TestUtils {
|
||||||
|
|
||||||
private TestUtils() {
|
private TestUtils() {
|
||||||
|
@ -22,4 +31,30 @@ public final class TestUtils {
|
||||||
public static byte[] randomAddress() {
|
public static byte[] randomAddress() {
|
||||||
return randomBytes(20);
|
return randomBytes(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Map<Long, List<IndexedBlockStore.BlockInfo>> createIndexMap(DB db){
|
||||||
|
|
||||||
|
Map<Long, List<IndexedBlockStore.BlockInfo>> index = db.hashMapCreate("index")
|
||||||
|
.keySerializer(Serializer.LONG)
|
||||||
|
.valueSerializer(BLOCK_INFO_SERIALIZER)
|
||||||
|
.makeOrGet();
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DB createMapDB(String testDBDir){
|
||||||
|
|
||||||
|
String blocksIndexFile = testDBDir + "/blocks/index";
|
||||||
|
File dbFile = new File(blocksIndexFile);
|
||||||
|
if (!dbFile.getParentFile().exists()) dbFile.getParentFile().mkdirs();
|
||||||
|
|
||||||
|
DB db = DBMaker.fileDB(dbFile)
|
||||||
|
.transactionDisable()
|
||||||
|
.closeOnJvmShutdown()
|
||||||
|
.make();
|
||||||
|
|
||||||
|
|
||||||
|
return db;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,19 +19,22 @@ import static org.ethereum.jsontestsuite.JSONReader.getFileNamesForTreeSha;
|
||||||
public class GitHubStateTest {
|
public class GitHubStateTest {
|
||||||
|
|
||||||
//SHACOMMIT of tested commit, ethereum/tests.git
|
//SHACOMMIT of tested commit, ethereum/tests.git
|
||||||
public String shacommit = "baf4b8479c0b524560137d27e61d7e573dc4ab17";
|
public String shacommit = "cfae68e67aa922e08428c274d1ddbbc2741a975b";
|
||||||
|
|
||||||
|
|
||||||
@Ignore
|
@Ignore
|
||||||
@Test // this method is mostly for hands-on convenient testing
|
@Test // this method is mostly for hands-on convenient testing
|
||||||
public void stSingleTest() throws ParseException, IOException {
|
public void stSingleTest() throws ParseException, IOException {
|
||||||
|
|
||||||
String json = JSONReader.loadJSONFromCommit("StateTests/stPreCompiledContracts.json", shacommit);
|
// String shacommit = "cfae68e67aa922e08428c274d1ddbbc2741a975b";
|
||||||
GitHubJSONTestSuite.runStateTest(json, "CallEcrecover0_BonusGas");
|
|
||||||
|
String json = JSONReader.loadJSONFromCommit("StateTests/stCallCreateCallCodeTest.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runStateTest(json, "CallRecursiveBombPreCall");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void stExample() throws ParseException, IOException {
|
public void stExample() throws ParseException, IOException {
|
||||||
|
|
||||||
Set<String> excluded = new HashSet<>();
|
Set<String> excluded = new HashSet<>();
|
||||||
String json = JSONReader.loadJSONFromCommit("StateTests/stExample.json", shacommit);
|
String json = JSONReader.loadJSONFromCommit("StateTests/stExample.json", shacommit);
|
||||||
GitHubJSONTestSuite.runStateTest(json, excluded);
|
GitHubJSONTestSuite.runStateTest(json, excluded);
|
||||||
|
@ -39,6 +42,7 @@ public class GitHubStateTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void stCallCreateCallCodeTest() throws ParseException, IOException {
|
public void stCallCreateCallCodeTest() throws ParseException, IOException {
|
||||||
|
|
||||||
Set<String> excluded = new HashSet<>();
|
Set<String> excluded = new HashSet<>();
|
||||||
excluded.add("createJS_ExampleContract"); //FIXME Bug on CPP testrunner, storage/SSTORE
|
excluded.add("createJS_ExampleContract"); //FIXME Bug on CPP testrunner, storage/SSTORE
|
||||||
excluded.add("Callcode1024OOG");
|
excluded.add("Callcode1024OOG");
|
||||||
|
@ -46,7 +50,7 @@ public class GitHubStateTest {
|
||||||
excluded.add("callcodeWithHighValue");
|
excluded.add("callcodeWithHighValue");
|
||||||
excluded.add("callWithHighValue");
|
excluded.add("callWithHighValue");
|
||||||
excluded.add("Call1024PreCalls");
|
excluded.add("Call1024PreCalls");
|
||||||
excluded.add("CallRecursiveBombPreCall");
|
excluded.add("CallRecursiveBombPreCall"); // FIXME gas not BI limit
|
||||||
String json = JSONReader.loadJSONFromCommit("StateTests/stCallCreateCallCodeTest.json", shacommit);
|
String json = JSONReader.loadJSONFromCommit("StateTests/stCallCreateCallCodeTest.json", shacommit);
|
||||||
GitHubJSONTestSuite.runStateTest(json, excluded);
|
GitHubJSONTestSuite.runStateTest(json, excluded);
|
||||||
}
|
}
|
||||||
|
@ -67,7 +71,7 @@ public class GitHubStateTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void stPreCompiledContracts() throws ParseException, IOException {
|
public void stPreCompiledContracts() throws ParseException, IOException {
|
||||||
|
String shacommit = "baf4b8479c0b524560137d27e61d7e573dc4ab17";
|
||||||
Set<String> excluded = new HashSet<>();
|
Set<String> excluded = new HashSet<>();
|
||||||
String json = JSONReader.loadJSONFromCommit("StateTests/stPreCompiledContracts.json", shacommit);
|
String json = JSONReader.loadJSONFromCommit("StateTests/stPreCompiledContracts.json", shacommit);
|
||||||
GitHubJSONTestSuite.runStateTest(json, excluded);
|
GitHubJSONTestSuite.runStateTest(json, excluded);
|
||||||
|
@ -100,7 +104,6 @@ public class GitHubStateTest {
|
||||||
GitHubJSONTestSuite.runStateTest(json, excluded);
|
GitHubJSONTestSuite.runStateTest(json, excluded);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore
|
|
||||||
@Test
|
@Test
|
||||||
public void stSolidityTest() throws ParseException, IOException {
|
public void stSolidityTest() throws ParseException, IOException {
|
||||||
Set<String> excluded = new HashSet<>();
|
Set<String> excluded = new HashSet<>();
|
||||||
|
@ -126,11 +129,9 @@ public class GitHubStateTest {
|
||||||
@Test
|
@Test
|
||||||
public void stSpecialTest() throws ParseException, IOException {
|
public void stSpecialTest() throws ParseException, IOException {
|
||||||
Set<String> excluded = new HashSet<>();
|
Set<String> excluded = new HashSet<>();
|
||||||
excluded.add("txfrom0_deja"); // (!!!) FIXME fix them as soon as possible
|
|
||||||
excluded.add("JUMPDEST_AttackwithJump"); // (!!!) FIXME fix them as soon as possible
|
excluded.add("JUMPDEST_AttackwithJump"); // (!!!) FIXME fix them as soon as possible
|
||||||
excluded.add("JUMPDEST_Attack"); // (!!!) FIXME fix them as soon as possible
|
excluded.add("JUMPDEST_Attack"); // (!!!) FIXME fix them as soon as possible
|
||||||
|
|
||||||
|
|
||||||
String json = JSONReader.loadJSONFromCommit("StateTests/stSpecialTest.json", shacommit);
|
String json = JSONReader.loadJSONFromCommit("StateTests/stSpecialTest.json", shacommit);
|
||||||
GitHubJSONTestSuite.runStateTest(json, excluded);
|
GitHubJSONTestSuite.runStateTest(json, excluded);
|
||||||
}
|
}
|
||||||
|
@ -141,7 +142,6 @@ public class GitHubStateTest {
|
||||||
GitHubJSONTestSuite.runStateTest(json);
|
GitHubJSONTestSuite.runStateTest(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
//@Ignore
|
|
||||||
@Test
|
@Test
|
||||||
public void stSystemOperationsTest() throws IOException {
|
public void stSystemOperationsTest() throws IOException {
|
||||||
|
|
||||||
|
@ -155,6 +155,7 @@ public class GitHubStateTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void stTransactionTest() throws ParseException, IOException {
|
public void stTransactionTest() throws ParseException, IOException {
|
||||||
|
|
||||||
Set<String> excluded = new HashSet<>();
|
Set<String> excluded = new HashSet<>();
|
||||||
excluded.add("OverflowGasRequire"); //FIXME wont work until we use gaslimit as long
|
excluded.add("OverflowGasRequire"); //FIXME wont work until we use gaslimit as long
|
||||||
excluded.add("EmptyTransaction2"); // Buggy testcase
|
excluded.add("EmptyTransaction2"); // Buggy testcase
|
||||||
|
|
|
@ -5,6 +5,8 @@ import org.ethereum.crypto.HashUtil;
|
||||||
import com.cedarsoftware.util.DeepEquals;
|
import com.cedarsoftware.util.DeepEquals;
|
||||||
|
|
||||||
import org.ethereum.db.ByteArrayWrapper;
|
import org.ethereum.db.ByteArrayWrapper;
|
||||||
|
import org.ethereum.net.client.Capability;
|
||||||
|
import org.ethereum.net.p2p.HelloMessage;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -1052,4 +1054,40 @@ public class RLPTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test // capabilities: (eth:60, bzz:0, shh:2)
|
||||||
|
public void testEncodeHelloMessageCap0(){
|
||||||
|
|
||||||
|
List<Capability> capabilities = new ArrayList<>();
|
||||||
|
capabilities.add(new Capability("eth", (byte) 0x60));
|
||||||
|
capabilities.add(new Capability("shh", (byte) 0x02));
|
||||||
|
capabilities.add(new Capability("bzz", (byte) 0x00));
|
||||||
|
|
||||||
|
HelloMessage helloMessage = new HelloMessage((byte)4,
|
||||||
|
"Geth/v0.9.29-4182e20e/windows/go1.4.2",
|
||||||
|
capabilities , 30303,
|
||||||
|
"a52205ce10b39be86507e28f6c3dc08ab4c3e8250e062ec47c6b7fa13cf4a4312d68d6c340315ef953ada7e19d69123a1b902ea84ec00aa5386e5d550e6c550e");
|
||||||
|
|
||||||
|
byte[] rlp = helloMessage.getEncoded();
|
||||||
|
|
||||||
|
HelloMessage helloMessage_ = new HelloMessage(rlp);
|
||||||
|
|
||||||
|
String eth = helloMessage_.getCapabilities().get(0).getName();
|
||||||
|
byte eth_60 = helloMessage_.getCapabilities().get(0).getVersion();
|
||||||
|
|
||||||
|
assertEquals("eth", eth);
|
||||||
|
assertEquals(0x60, eth_60);
|
||||||
|
|
||||||
|
String shh = helloMessage_.getCapabilities().get(1).getName();
|
||||||
|
byte shh_02 = helloMessage_.getCapabilities().get(1).getVersion();
|
||||||
|
|
||||||
|
assertEquals("shh", shh);
|
||||||
|
assertEquals(0x02, shh_02);
|
||||||
|
|
||||||
|
String bzz = helloMessage_.getCapabilities().get(2).getName();
|
||||||
|
byte bzz_00 = helloMessage_.getCapabilities().get(2).getVersion();
|
||||||
|
|
||||||
|
assertEquals("bzz", bzz);
|
||||||
|
assertEquals(0x00, bzz_00);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue