mirror of
https://github.com/status-im/ethereumj-personal.git
synced 2025-01-11 12:24:13 +00:00
Android adjustments
+ property to omit all transactions , for blockchain rip only + connections dead kill the timers - fix +onPeerDisconnect in EthereumListener +LRUMap wasn't thread safe, todo: implement eviction policy + NPE in Trie edge cases
This commit is contained in:
parent
d63cc83976
commit
c7dd99e358
@ -32,6 +32,7 @@ public class SystemProperties {
|
||||
private static String DEFAULT_DATABASE_DIR = System.getProperty("user.dir");
|
||||
private static Boolean DEFAULT_DUMP_CLEAN_ON_RESTART = true;
|
||||
private static Boolean DEFAULT_PLAY_VM = true;
|
||||
private static Boolean DEFAULT_BLOCKCHAIN_ONLY = false;
|
||||
private static int DEFAULT_TRACE_STARTBLOCK = -1;
|
||||
private static byte DEFAULT_MAX_BLOCKS_ASK = 10;
|
||||
private static int DEFAULT_MAX_BLOCKS_QUEUED = 300;
|
||||
@ -175,6 +176,12 @@ public class SystemProperties {
|
||||
return Boolean.parseBoolean(prop.getProperty("play.vm"));
|
||||
}
|
||||
|
||||
public Boolean blockChainOnly() {
|
||||
if(prop.isEmpty()) return DEFAULT_BLOCKCHAIN_ONLY;
|
||||
return Boolean.parseBoolean(prop.getProperty("blockchain.only"));
|
||||
}
|
||||
|
||||
|
||||
public Byte maxBlocksAsk() {
|
||||
if(prop.isEmpty()) return DEFAULT_MAX_BLOCKS_ASK;
|
||||
return Byte.parseByte(prop.getProperty("max.blocks.ask"));
|
||||
|
@ -166,13 +166,22 @@ public class Blockchain {
|
||||
public void processBlock(Block block) {
|
||||
if(block.isValid()) {
|
||||
if (!block.isGenesis()) {
|
||||
for (Transaction tx : block.getTransactionsList())
|
||||
// TODO: refactor the wallet pending transactions to the world manager
|
||||
WorldManager.getInstance().addWalletTransaction(tx);
|
||||
this.applyBlock(block);
|
||||
WorldManager.getInstance().getWallet().processBlock(block);
|
||||
|
||||
if (!CONFIG.blockChainOnly()) {
|
||||
|
||||
for (Transaction tx : block.getTransactionsList())
|
||||
// TODO: refactor the wallet pending transactions to the world manager
|
||||
WorldManager.getInstance().addWalletTransaction(tx);
|
||||
|
||||
this.applyBlock(block);
|
||||
|
||||
WorldManager.getInstance().getWallet().processBlock(block);
|
||||
|
||||
repository.dumpState(block.getNumber(), 0,
|
||||
null);
|
||||
}
|
||||
}
|
||||
this.storeBlock(block);
|
||||
this.storeBlock(block);
|
||||
} else {
|
||||
logger.warn("Invalid block with nr: {}", block.getNumber());
|
||||
}
|
||||
@ -196,12 +205,10 @@ public class Blockchain {
|
||||
for (Block uncle : block.getUncleList()) {
|
||||
repository.addBalance(uncle.getCoinbase(), Block.UNCLE_REWARD);
|
||||
}
|
||||
|
||||
repository.dumpState(block.getNumber(), 0,
|
||||
null);
|
||||
}
|
||||
|
||||
public void storeBlock(Block block) {
|
||||
public void storeBlock(Block block) {
|
||||
|
||||
/* Debug check to see if the state is still as expected */
|
||||
if(logger.isWarnEnabled()) {
|
||||
String blockStateRootHash = Hex.toHexString(block.getStateRoot());
|
||||
|
@ -15,6 +15,7 @@ import org.iq80.leveldb.DBIterator;
|
||||
import org.iq80.leveldb.Options;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
/**
|
||||
* Generic interface for Ethereum database
|
||||
@ -26,7 +27,7 @@ import org.slf4j.LoggerFactory;
|
||||
*/
|
||||
public class DatabaseImpl implements Database {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(DatabaseImpl.class);
|
||||
private static Logger logger = LoggerFactory.getLogger("db");
|
||||
private DB db;
|
||||
private String name;
|
||||
|
||||
@ -51,6 +52,23 @@ public class DatabaseImpl implements Database {
|
||||
// logger.debug("Showing database stats");
|
||||
// String stats = DATABASE.getProperty("leveldb.stats");
|
||||
// logger.debug(stats);
|
||||
|
||||
if (logger.isTraceEnabled()){
|
||||
|
||||
logger.trace("dump for: {}", fileLocation.toString());
|
||||
DBIterator iter = db.iterator();
|
||||
|
||||
while(iter.hasNext()){
|
||||
byte[] key = iter.peekNext().getKey();
|
||||
byte[] value = iter.peekNext().getValue();
|
||||
|
||||
logger.trace("key={}, value={}", Hex.toHexString(key), Hex.toHexString(value));
|
||||
iter.next();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
} catch (IOException ioe) {
|
||||
logger.error(ioe.getMessage(), ioe);
|
||||
throw new RuntimeException("Can't initialize database");
|
||||
|
@ -187,7 +187,7 @@ public class Repository {
|
||||
|
||||
byte[] accountStateRLP = accountStateDB.get(addr);
|
||||
|
||||
if (accountStateRLP.length == 0)
|
||||
if (accountStateRLP == null || accountStateRLP.length == 0)
|
||||
return null;
|
||||
|
||||
AccountState state = new AccountState(accountStateRLP);
|
||||
|
@ -16,5 +16,6 @@ public interface EthereumListener {
|
||||
public void onBlock(Block block);
|
||||
public void onRecvMessage(Message message);
|
||||
public void onSendMessage(Message message);
|
||||
public void onPeerDisconnect(String host, long port);
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,39 @@
|
||||
package org.ethereum.listener;
|
||||
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.net.message.Message;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
*
|
||||
* @author: Roman Mandeleil
|
||||
* Created on: 08/08/2014 15:22
|
||||
*/
|
||||
|
||||
public class EthereumListenerAdapter implements EthereumListener {
|
||||
|
||||
@Override
|
||||
public void trace(String output) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlock(Block block) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecvMessage(Message message) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSendMessage(Message message) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPeerDisconnect(String host, long port) {
|
||||
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@ import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import io.netty.handler.timeout.ReadTimeoutHandler;
|
||||
|
||||
import org.ethereum.core.Transaction;
|
||||
import org.ethereum.listener.EthereumListener;
|
||||
import org.ethereum.manager.WorldManager;
|
||||
import org.ethereum.net.EthereumMessageSizeEstimator;
|
||||
import org.ethereum.net.PeerListener;
|
||||
@ -16,6 +17,7 @@ import org.slf4j.LoggerFactory;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.ethereum.config.SystemProperties.CONFIG;
|
||||
@ -76,10 +78,28 @@ public class ClientPeer {
|
||||
// Wait until the connection is closed.
|
||||
f.channel().closeFuture().sync();
|
||||
|
||||
|
||||
} catch (InterruptedException ie) {
|
||||
logger.error("-- ClientPeer: catch (InterruptedException ie) --", ie);
|
||||
} finally {
|
||||
workerGroup.shutdownGracefully();
|
||||
|
||||
handler.killTimers();
|
||||
|
||||
List<PeerData> peers = WorldManager.getInstance().getPeers();
|
||||
|
||||
for (PeerData peer : peers){
|
||||
if (host.equals(peer.getInetAddress().getHostAddress()) &&
|
||||
port == peer.getPort()){
|
||||
peer.setOnline(false);
|
||||
}
|
||||
}
|
||||
|
||||
EthereumListener listener = WorldManager.getInstance().getListener();
|
||||
if (listener != null){
|
||||
listener.onPeerDisconnect(host, port);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -378,4 +378,12 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
|
||||
new GetChainMessage( SystemProperties.CONFIG.maxBlocksAsk(), hash);
|
||||
sendMsg(chainMessage);
|
||||
}
|
||||
|
||||
public void killTimers(){
|
||||
chainAskTimer.cancel();
|
||||
chainAskTimer.purge();
|
||||
|
||||
timer.cancel();
|
||||
timer.purge();
|
||||
}
|
||||
}
|
@ -135,7 +135,8 @@ public class Trie implements TrieFacade {
|
||||
}
|
||||
byte[] k = binToNibbles(key);
|
||||
Value c = new Value( this.get(this.root, k) );
|
||||
return c.asBytes();
|
||||
|
||||
return (c == null)? null : c.asBytes();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -172,6 +173,7 @@ public class Trie implements TrieFacade {
|
||||
}
|
||||
|
||||
Value currentNode = this.getNode(node);
|
||||
if (currentNode == null) return null;
|
||||
|
||||
if (currentNode.length() == PAIR_SIZE) {
|
||||
// Decode the key
|
||||
|
@ -2,23 +2,27 @@ package org.ethereum.util;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentSkipListMap;
|
||||
|
||||
/**
|
||||
* Simple LRU map used for reusing lookup values.
|
||||
*/
|
||||
public class LRUMap<K,V> extends LinkedHashMap<K,V> {
|
||||
public class LRUMap<K,V> extends ConcurrentHashMap<K,V> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
protected final int maxEntries;
|
||||
|
||||
public LRUMap(int initialEntries, int maxEntries) {
|
||||
super(initialEntries, 0.8f, true);
|
||||
super(initialEntries, 0.8f, 3);
|
||||
this.maxEntries = maxEntries;
|
||||
}
|
||||
|
||||
/* todo: temporary removed during concurrent impl
|
||||
@Override
|
||||
protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
|
||||
return size() > maxEntries;
|
||||
}
|
||||
*/
|
||||
}
|
@ -14,12 +14,15 @@ public class Value {
|
||||
private Object value;
|
||||
|
||||
public static Value fromRlpEncoded(byte[] data) {
|
||||
if (data.length != 0) {
|
||||
if (data != null && data.length != 0) {
|
||||
return new Value(RLP.decode(data, 0).getDecoded());
|
||||
} return null;
|
||||
}
|
||||
|
||||
public Value(Object obj) {
|
||||
|
||||
if (obj == null) return;
|
||||
|
||||
if (obj instanceof Value) {
|
||||
this.value = ((Value) obj).asObj();
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user