From 254c51704a013e69990d95a534c2c25c2163e498 Mon Sep 17 00:00:00 2001 From: romanman Date: Thu, 4 Dec 2014 14:35:18 +0100 Subject: [PATCH] adapting for poc-7 final (eth:47) : + Repository refactoring --- .../org/ethereum/core/BlockchainImpl.java | 13 +- .../java/org/ethereum/db/ContractDetails.java | 2 +- .../java/org/ethereum/db/RepositoryImpl.java | 80 +- .../java/org/ethereum/db/RepositoryTrack.java | 38 +- .../java/org/ethereum/facade/Repository.java | 2 + .../ethereum/jsontestsuite/TestRunner.java | 4 +- .../java/org/ethereum/net/eth/EthHandler.java | 2 +- .../java/org/ethereum/net/server/Channel.java | 18 + .../server/EthereumChannelInitializer.java | 10 +- .../java/test/ethereum/core/BlockTest.java | 4 +- .../java/test/ethereum/db/RepositoryTest.java | 47 +- .../test/resources/blockload/scenario2.dmp | 4 - .../test/resources/blockload/scenario3.dmp | 1369 ----------------- .../test/resources/blockload/scenario4.dmp | 2 - 14 files changed, 116 insertions(+), 1479 deletions(-) delete mode 100644 ethereumj-core/src/test/resources/blockload/scenario2.dmp delete mode 100644 ethereumj-core/src/test/resources/blockload/scenario3.dmp delete mode 100644 ethereumj-core/src/test/resources/blockload/scenario4.dmp diff --git a/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java b/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java index a540f549..9357cd25 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java @@ -130,8 +130,9 @@ public class BlockchainImpl implements Blockchain { recordBlock(block); if (logger.isDebugEnabled()) - logger.debug("Try connect block: {}", - Hex.toHexString(block.getEncoded())); + logger.debug("Try connect block hash: {}, number: {}", + Hex.toHexString(block.getHash()).substring(0, 6), + block.getNumber()); if (blockStore.getBlockByHash(block.getHash()) != null){ // retry of well known block @@ -212,6 +213,9 @@ public class BlockchainImpl implements Blockchain { track.commit(); repository.flush(); // saving to the disc + stateLogger.info("applied reward for block: [{}] \n state: [{}]", + block.getNumber(), + Hex.toHexString(repository.getRoot())); // Remove all wallet transactions as they already approved by the net worldManager.getWallet().removeTransactions(block.getTransactionsList()); @@ -329,7 +333,7 @@ public class BlockchainImpl implements Blockchain { track.commit(); receipt.setPostTxState(repository.getRoot()); - stateLogger.info("executed block: [{}] tx: [{}] \n state: [{}]", block.getNumber(), i, + stateLogger.info("block: [{}] executed tx: [{}] \n state: [{}]", block.getNumber(), i, Hex.toHexString(repository.getRoot())); if(block.getNumber() >= CONFIG.traceStartBlock()) @@ -579,8 +583,7 @@ public class BlockchainImpl implements Blockchain { BigInteger gasPrice, Repository repository, byte[] senderAddress, byte[] contractAddress, byte[] coinbase, boolean initResults) { - if (result.getException() != null - && result.getException() instanceof Program.OutOfGasException) { + if (result.getException() != null) { stateLogger.debug("contract run halted by OutOfGas: contract={}", Hex.toHexString(contractAddress)); throw result.getException(); diff --git a/ethereumj-core/src/main/java/org/ethereum/db/ContractDetails.java b/ethereumj-core/src/main/java/org/ethereum/db/ContractDetails.java index 87e984f4..75476a1f 100644 --- a/ethereumj-core/src/main/java/org/ethereum/db/ContractDetails.java +++ b/ethereumj-core/src/main/java/org/ethereum/db/ContractDetails.java @@ -24,7 +24,7 @@ public class ContractDetails { private byte[] code = ByteUtil.EMPTY_BYTE_ARRAY; - private boolean dirty = true; + private boolean dirty = false; private boolean deleted = false; private Trie storageTrie = new TrieImpl(null); diff --git a/ethereumj-core/src/main/java/org/ethereum/db/RepositoryImpl.java b/ethereumj-core/src/main/java/org/ethereum/db/RepositoryImpl.java index a90ac10e..083d4df5 100644 --- a/ethereumj-core/src/main/java/org/ethereum/db/RepositoryImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/db/RepositoryImpl.java @@ -28,6 +28,7 @@ import java.util.List; import static org.ethereum.config.SystemProperties.CONFIG; import static org.ethereum.crypto.SHA3Helper.*; +import static org.ethereum.util.ByteUtil.wrap; /** * www.etherj.com @@ -88,40 +89,39 @@ public class RepositoryImpl implements Repository { public void updateBatch(HashMap stateCache, HashMap detailsCache) { - for (ByteArrayWrapper hash : detailsCache.keySet()) { - - ContractDetails contractDetails = detailsCache.get(hash); - - if (contractDetails.isDeleted()) - detailsDB.delete(hash.getData()); - else{ - if (contractDetails.isDirty()) - detailsDB.put(hash.getData(), contractDetails.getEncoded()); - } - - if (contractDetails.isDirty() || contractDetails.isDeleted()){ - - AccountState accountState = stateCache.get(hash); - accountState.setStateRoot(contractDetails.getStorageHash()); - accountState.setCodeHash(sha3(contractDetails.getCode())); - } - - contractDetails.setDeleted(false); - contractDetails.setDirty(false); - } - - for (ByteArrayWrapper hash : detailsCache.keySet()) { + for (ByteArrayWrapper hash : stateCache.keySet()) { AccountState accountState = stateCache.get(hash); + ContractDetails contractDetails = detailsCache.get(hash); - if (accountState.isDeleted()) + if (accountState.isDeleted()){ worldState.delete(hash.getData()); - else{ - if (accountState.isDirty()){ + detailsDB.delete(hash.getData()); + + logger.debug("delete: [{}]", + Hex.toHexString(hash.getData())); + + } else{ + + if (contractDetails.isDirty()){ + detailsDB.put(hash.getData(), contractDetails.getEncoded()); + accountState.setStateRoot(contractDetails.getStorageHash()); + accountState.setCodeHash(sha3(contractDetails.getCode())); + worldState.update(hash.getData(), accountState.getEncoded()); + if (logger.isDebugEnabled()){ + logger.debug("update: [{}],nonce: [{}] balance: [{}] \n [{}]", + Hex.toHexString(hash.getData()), + accountState.getNonce(), + accountState.getBalance(), + contractDetails.getStorage()); + } + + } + + if (!contractDetails.isDirty() && accountState.isDirty()){ worldState.update(hash.getData(), accountState.getEncoded()); if (logger.isDebugEnabled()){ - logger.debug("update: [{}],nonce: [{}] balance: [{}]", Hex.toHexString(hash.getData()), accountState.getNonce(), @@ -131,8 +131,8 @@ public class RepositoryImpl implements Repository { } } - accountState.setDeleted(false); - accountState.setDirty(false); + detailsCache.remove(hash.getData()); + stateCache.remove(hash.getData()); } } @@ -404,6 +404,28 @@ public class RepositoryImpl implements Repository { return accountState; } + @Override + public void loadAccount(byte[] addr, + HashMap cacheAccounts, + HashMap cacheDetails) { + + AccountState account = getAccountState(addr); + ContractDetails details = getContractDetails(addr); + + if (account == null) + account = new AccountState(); + else + account = account.clone(); + + if (details == null) + details = new ContractDetails(); + else + details = details.clone(); + + cacheAccounts.put(wrap(addr), account); + cacheDetails.put(wrap(addr), details); + } + @Override public byte[] getRoot() { return worldState.getRootHash(); diff --git a/ethereumj-core/src/main/java/org/ethereum/db/RepositoryTrack.java b/ethereumj-core/src/main/java/org/ethereum/db/RepositoryTrack.java index 6ce645a7..a392b1e0 100644 --- a/ethereumj-core/src/main/java/org/ethereum/db/RepositoryTrack.java +++ b/ethereumj-core/src/main/java/org/ethereum/db/RepositoryTrack.java @@ -56,30 +56,40 @@ public class RepositoryTrack implements Repository { AccountState accountState = cacheAccounts.get(wrap(addr)); if (accountState == null){ - accountState = repository.getAccountState(addr); - - if (accountState == null){ - - accountState = createAccount(addr); - } else { - - accountState = accountState.clone(); - cacheAccounts.put(wrap(addr), accountState); - - ContractDetails contractDetails = repository.getContractDetails(addr); - cacheDetails.put(wrap(addr), contractDetails.clone()); - } + repository.loadAccount(addr, cacheAccounts, cacheDetails); + accountState = cacheAccounts.get(wrap(addr)); } return accountState; } @Override public ContractDetails getContractDetails(byte[] addr) { - getAccountState(addr); + ContractDetails contractDetails = cacheDetails.get(wrap(addr)); + + if (contractDetails == null){ + repository.loadAccount(addr, cacheAccounts, cacheDetails); + contractDetails = cacheDetails.get(wrap(addr)); + } + return contractDetails; } + @Override + public void loadAccount(byte[] addr, HashMap cacheAccounts, + HashMap cacheDetails){ + + AccountState accountState = this.cacheAccounts.get(wrap(addr)); + ContractDetails contractDetails = this.cacheDetails.get(wrap(addr)); + + if (accountState == null){ + repository.loadAccount(addr, cacheAccounts, cacheDetails); + } else { + cacheAccounts.put(wrap(addr), accountState.clone()); + cacheDetails.put(wrap(addr), contractDetails.clone()); + } + } + @Override public void delete(byte[] addr) { diff --git a/ethereumj-core/src/main/java/org/ethereum/facade/Repository.java b/ethereumj-core/src/main/java/org/ethereum/facade/Repository.java index 2a43a471..00c17805 100644 --- a/ethereumj-core/src/main/java/org/ethereum/facade/Repository.java +++ b/ethereumj-core/src/main/java/org/ethereum/facade/Repository.java @@ -190,4 +190,6 @@ public interface Repository { public byte[] getRoot(); + void loadAccount(byte[] addr, HashMap cacheAccounts, + HashMap cacheDetails); } diff --git a/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/TestRunner.java b/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/TestRunner.java index 2a66aa44..16cdfe35 100644 --- a/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/TestRunner.java +++ b/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/TestRunner.java @@ -49,7 +49,9 @@ public class TestRunner { Repository repository = new RepositoryImpl(); try { - System.out.println("\nRunning test case: " + testCase.getName()); + System.out.println("\n***"); + System.out.println(" Running test case: [" + testCase.getName() + "]") ; + System.out.println("***\n"); List results = new ArrayList<>(); System.out.println("--------- PRE ---------"); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/eth/EthHandler.java b/ethereumj-core/src/main/java/org/ethereum/net/eth/EthHandler.java index dbd8c8d5..5e17c726 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/eth/EthHandler.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/eth/EthHandler.java @@ -42,7 +42,7 @@ import static org.ethereum.net.message.StaticMessages.GET_TRANSACTIONS_MESSAGE; @Scope("prototype") public class EthHandler extends SimpleChannelInboundHandler { - public final static byte VERSION = 46; + public final static byte VERSION = 47; public final static byte NETWORK_ID = 0x0; private final static Logger logger = LoggerFactory.getLogger("net"); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/server/Channel.java b/ethereumj-core/src/main/java/org/ethereum/net/server/Channel.java index 3eefc757..75449561 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/server/Channel.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/server/Channel.java @@ -6,6 +6,8 @@ import org.ethereum.net.MessageQueue; import org.ethereum.net.eth.EthHandler; import org.ethereum.net.p2p.P2pHandler; import org.ethereum.net.shh.ShhHandler; +import org.ethereum.net.wire.MessageDecoder; +import org.ethereum.net.wire.MessageEncoder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -35,6 +37,14 @@ public class Channel { @Autowired ShhHandler shhHandler; + @Autowired + MessageDecoder messageDecoder; + + @Autowired + MessageEncoder messageEncoder; + + + public Channel() { } @@ -57,6 +67,14 @@ public class Channel { return shhHandler; } + public MessageDecoder getMessageDecoder() { + return messageDecoder; + } + + public MessageEncoder getMessageEncoder() { + return messageEncoder; + } + public void sendTransaction(Transaction tx){ ethHandler.sendTransaction(tx); } diff --git a/ethereumj-core/src/main/java/org/ethereum/net/server/EthereumChannelInitializer.java b/ethereumj-core/src/main/java/org/ethereum/net/server/EthereumChannelInitializer.java index 69c6161f..4035b5ac 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/server/EthereumChannelInitializer.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/server/EthereumChannelInitializer.java @@ -46,12 +46,6 @@ public class EthereumChannelInitializer extends ChannelInitializer