Avoid putting conflicting state into the db
This commit is contained in:
parent
202be8f553
commit
d932294c0c
|
@ -13,7 +13,6 @@ import org.spongycastle.util.encoders.Hex;
|
|||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.ethereum.config.SystemProperties.CONFIG;
|
||||
|
@ -86,14 +85,13 @@ public class Blockchain {
|
|||
return new Block(chainDb.get(ByteUtil.longToBytes(blockNr)));
|
||||
}
|
||||
|
||||
public void applyBlock(Block block) {
|
||||
public void add(Block block) {
|
||||
|
||||
if (block == null)
|
||||
return;
|
||||
|
||||
|
||||
// if it is the first block to add
|
||||
// check that the parent is the genesis
|
||||
// make sure the parent is genesis
|
||||
if (index.isEmpty()
|
||||
&& !Arrays.equals(Genesis.getInstance().getHash(),
|
||||
block.getParentHash())) {
|
||||
|
@ -105,38 +103,24 @@ public class Blockchain {
|
|||
String blockParentHash = Hex.toHexString(block.getParentHash());
|
||||
if (!hashLast.equals(blockParentHash)) return;
|
||||
}
|
||||
|
||||
this.addBlock(block);
|
||||
|
||||
if (block.getNumber() >= CONFIG.traceStartBlock() && CONFIG.traceStartBlock() != -1) {
|
||||
AdvancedDeviceUtils.adjustDetailedTracing(block.getNumber());
|
||||
}
|
||||
|
||||
/* Debug check to see if the state is still as expected */
|
||||
if(logger.isWarnEnabled()) {
|
||||
String blockStateRootHash = Hex.toHexString(block.getStateRoot());
|
||||
String worldStateRootHash = Hex.toHexString(WorldManager.getInstance().getRepository().getWorldState().getRootHash());
|
||||
if(!blockStateRootHash.equals(worldStateRootHash)){
|
||||
logger.warn("WARNING: STATE CONFLICT! block: {} worldstate {} mismatch", block.getNumber(), worldStateRootHash);
|
||||
// Last fail on WARNING: STATE CONFLICT! block: 1157 worldstate b1d9a978451ef04c1639011d9516473d51c608dbd25906c89be791707008d2de mismatch
|
||||
// System.exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
this.processBlock(block);
|
||||
|
||||
// Remove all wallet transactions as they already approved by the net
|
||||
for (Transaction tx : block.getTransactionsList()) {
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("pending cleanup: tx.hash: [{}]", Hex.toHexString( tx.getHash()));
|
||||
WorldManager.getInstance().removeWalletTransaction(tx);
|
||||
}
|
||||
logger.info("*** Block chain size: [ {} ]", this.getSize());
|
||||
|
||||
|
||||
EthereumListener listener = WorldManager.getInstance().getListener();
|
||||
if (listener != null)
|
||||
listener.trace(String.format("Block chain size: [ %d ]", this.getSize()));
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
if (lastBlock.getNumber() >= 30) {
|
||||
System.out.println("** checkpoint **");
|
||||
|
@ -148,28 +132,42 @@ public class Blockchain {
|
|||
*/
|
||||
}
|
||||
|
||||
public void addBlock(Block block) {
|
||||
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);
|
||||
WorldManager.getInstance().applyBlock(block);
|
||||
WorldManager.getInstance().applyBlock(block);
|
||||
WorldManager.getInstance().getWallet().processBlock(block);
|
||||
}
|
||||
|
||||
this.chainDb.put(ByteUtil.longToBytes(block.getNumber()), block.getEncoded());
|
||||
this.index.put(block.getNumber(), block.getHash());
|
||||
|
||||
WorldManager.getInstance().getWallet().processBlock(block);
|
||||
this.setLastBlock(block);
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("block added {}", block.toFlatString());
|
||||
this.storeBlock(block);
|
||||
} else {
|
||||
logger.warn("Invalid block with nr: {}", block.getNumber());
|
||||
}
|
||||
}
|
||||
|
||||
private void storeBlock(Block block) {
|
||||
/* Debug check to see if the state is still as expected */
|
||||
if(logger.isWarnEnabled()) {
|
||||
String blockStateRootHash = Hex.toHexString(block.getStateRoot());
|
||||
String worldStateRootHash = Hex.toHexString(WorldManager.getInstance().getRepository().getWorldState().getRootHash());
|
||||
if(!blockStateRootHash.equals(worldStateRootHash)){
|
||||
logger.error("ERROR: STATE CONFLICT! block: {} worldstate {} mismatch", block.getNumber(), worldStateRootHash);
|
||||
// Last conflict on block 1157 -> worldstate b1d9a978451ef04c1639011d9516473d51c608dbd25906c89be791707008d2de
|
||||
System.exit(-1); // Don't add block
|
||||
}
|
||||
}
|
||||
|
||||
this.chainDb.put(ByteUtil.longToBytes(block.getNumber()), block.getEncoded());
|
||||
this.index.put(block.getNumber(), block.getHash());
|
||||
this.setLastBlock(block);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("block added {}", block.toFlatString());
|
||||
logger.info("*** Block chain size: [ {} ]", this.getSize());
|
||||
}
|
||||
|
||||
public long getGasPrice() {
|
||||
// In case of the genesis block we don't want to rely on the min gas price
|
||||
return lastBlock.isGenesis() ? lastBlock.getMinGasPrice() : INITIAL_MIN_GAS_PRICE;
|
||||
|
@ -188,7 +186,7 @@ public class Blockchain {
|
|||
if (!iterator.hasNext()) {
|
||||
logger.info("DB is empty - adding Genesis");
|
||||
this.lastBlock = Genesis.getInstance();
|
||||
this.addBlock(lastBlock);
|
||||
this.storeBlock(lastBlock);
|
||||
logger.debug("Block #{} -> {}", Genesis.NUMBER, lastBlock.toFlatString());
|
||||
} else {
|
||||
logger.debug("Displaying blocks stored in DB sorted on blocknumber");
|
||||
|
|
|
@ -308,6 +308,10 @@ public class WorldManager {
|
|||
|
||||
public void applyBlock(Block block) {
|
||||
|
||||
if(block.getNumber() == 1157) {
|
||||
logger.debug("Block 1157");
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for (Transaction tx : block.getTransactionsList()) {
|
||||
logger.info("apply block: [ {} ] tx: [ {} ] ", block.getNumber(), i);
|
||||
|
|
|
@ -40,10 +40,10 @@ public class BlockQueue {
|
|||
|
||||
Block block = blockQueue.poll();
|
||||
|
||||
WorldManager.getInstance().getBlockChain().applyBlock(block);
|
||||
WorldManager.getInstance().getBlockChain().add(block);
|
||||
}
|
||||
|
||||
public void addBlocks(List<Block> blockList){
|
||||
public void addBlocks(List<Block> blockList) {
|
||||
|
||||
Block lastReceivedBlock = blockList.get(blockList.size() - 1);
|
||||
if (lastReceivedBlock.getNumber() != getLast().getNumber() + 1) return;
|
||||
|
@ -61,7 +61,7 @@ public class BlockQueue {
|
|||
logger.trace("Blocks waiting to be proceed in the queue: [ {} ]", blockQueue.size());
|
||||
}
|
||||
|
||||
public Block getLast(){
|
||||
public Block getLast() {
|
||||
|
||||
if (blockQueue.isEmpty())
|
||||
return WorldManager.getInstance().getBlockChain().getLastBlock();
|
||||
|
@ -69,7 +69,7 @@ public class BlockQueue {
|
|||
return lastBlock;
|
||||
}
|
||||
|
||||
private class BlockByIndexComparator implements Comparator<Block>{
|
||||
private class BlockByIndexComparator implements Comparator<Block> {
|
||||
|
||||
@Override
|
||||
public int compare(Block o1, Block o2) {
|
||||
|
@ -83,7 +83,7 @@ public class BlockQueue {
|
|||
}
|
||||
}
|
||||
|
||||
public int size(){
|
||||
public int size() {
|
||||
return blockQueue.size();
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ import org.spongycastle.util.encoders.Hex;
|
|||
* @author: Nick Savers
|
||||
* Created on: 20/05/2014 10:44
|
||||
*/
|
||||
public class Trie implements TrieFacade{
|
||||
public class Trie implements TrieFacade {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger("trie");
|
||||
|
||||
|
|
|
@ -9,8 +9,12 @@ server.acceptConnections = false
|
|||
#peer.discovery.port = 30303
|
||||
|
||||
# Peer Server One: peer discovery
|
||||
peer.discovery.ip = 54.204.10.41
|
||||
|
||||
# Asimov
|
||||
peer.discovery.ip = 185.43.109.23
|
||||
peer.discovery.port = 30303
|
||||
|
||||
# RomanJ
|
||||
#peer.discovery.ip = 54.211.14.10
|
||||
#peer.discovery.port = 30303
|
||||
|
||||
|
@ -30,7 +34,7 @@ peer.discovery.port = 30303
|
|||
#peer.active.port = 30303
|
||||
|
||||
# PoC-5 testnet
|
||||
peer.active.ip = 54.204.10.41
|
||||
peer.active.ip = 185.43.109.23
|
||||
peer.active.port = 30303
|
||||
|
||||
#peer.active.ip = 54.72.69.180
|
||||
|
@ -80,7 +84,7 @@ samples.dir = samples
|
|||
# the existing database will be
|
||||
# destroyed and all the data will be
|
||||
# downloaded from peers again
|
||||
database.reset = true
|
||||
database.reset = false
|
||||
|
||||
# place to save physical storage files
|
||||
database.dir = database
|
||||
|
@ -104,14 +108,14 @@ dump.clean.on.restart = true
|
|||
# make changes to tracing options
|
||||
# starting from certain block
|
||||
# -1 don't make any tracing changes
|
||||
trace.startblock = 1150
|
||||
trace.startblock = 1155
|
||||
|
||||
# invoke vm program on
|
||||
# message received,
|
||||
# if the vm is not invoked
|
||||
# the balance transfer
|
||||
# occurs anyway [true/false]
|
||||
play.vm = false
|
||||
play.vm = true
|
||||
|
||||
# maximum blocks to ask,
|
||||
# when downloading the chain
|
||||
|
|
|
@ -115,7 +115,7 @@ public class BlockTest {
|
|||
assertEquals(new BigInteger(1, Genesis.DIFFICULTY), difficulty);
|
||||
|
||||
// Storing genesis because the parent needs to be in the DB for calculation.
|
||||
WorldManager.getInstance().getBlockChain().addBlock(genesis);
|
||||
WorldManager.getInstance().getBlockChain().add(genesis);
|
||||
|
||||
Block block1 = new Block(Hex.decode(block_1));
|
||||
BigInteger calcDifficulty = new BigInteger(1, block1.calcDifficulty());
|
||||
|
@ -137,7 +137,7 @@ public class BlockTest {
|
|||
assertEquals(Genesis.GAS_LIMIT, gasLimit);
|
||||
|
||||
// Storing genesis because the parent needs to be in the DB for calculation.
|
||||
WorldManager.getInstance().getBlockChain().addBlock(genesis);
|
||||
WorldManager.getInstance().getBlockChain().add(genesis);
|
||||
|
||||
// Test with block
|
||||
Block block1 = new Block(Hex.decode(block_1));
|
||||
|
|
Loading…
Reference in New Issue