diff --git a/app/src/main/java/org/ethereum/ethereum_android/EthereumManager.java b/app/src/main/java/org/ethereum/ethereum_android/EthereumManager.java index 49dcb635..9905630a 100644 --- a/app/src/main/java/org/ethereum/ethereum_android/EthereumManager.java +++ b/app/src/main/java/org/ethereum/ethereum_android/EthereumManager.java @@ -8,12 +8,16 @@ import org.ethereum.core.AccountState; import org.ethereum.facade.Ethereum; import org.ethereum.facade.Repository; import org.ethereum.listener.EthereumListenerAdapter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.Set; public class EthereumManager { + private static final Logger logger = LoggerFactory.getLogger("manager"); + public static Ethereum ethereum = null; public static AccountsDataAdapter adapter = null; @@ -31,6 +35,7 @@ public class EthereumManager { ethereum.connect(SystemProperties.CONFIG.activePeerIP(), SystemProperties.CONFIG.activePeerPort(), SystemProperties.CONFIG.activePeerNodeid()); + //ethereum.getBlockchain(); } public void loadAccounts() { @@ -59,6 +64,7 @@ public class EthereumManager { @Override public void trace(final String output) { + logger.info(output); log += output; log += "\n\n"; } diff --git a/app/src/main/java/org/ethereum/ethereum_android/MainActivity.java b/app/src/main/java/org/ethereum/ethereum_android/MainActivity.java index 6bab770f..3a8f2b72 100644 --- a/app/src/main/java/org/ethereum/ethereum_android/MainActivity.java +++ b/app/src/main/java/org/ethereum/ethereum_android/MainActivity.java @@ -66,7 +66,7 @@ public class MainActivity extends ActionBarActivity implements OnClickListener, text1 = (TextView) findViewById(R.id.text1); text1.setMovementMethod(new ScrollingMovementMethod()); - StrictMode.enableDefaults(); + //StrictMode.enableDefaults(); new PostTask().execute(ethereum); @@ -87,6 +87,7 @@ public class MainActivity extends ActionBarActivity implements OnClickListener, } }); } + text1.append("XXXXENDXXXX"); quit = 1; } catch (InterruptedException e) { } @@ -176,18 +177,21 @@ public class MainActivity extends ActionBarActivity implements OnClickListener, Log.v(TAG, "222"); ethereumManager.connect(); Log.v(TAG, "333"); + //ethereumManager.startPeerDiscovery(); while(true) { + /* try { - Thread.sleep(100); + Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } + */ if (quit == 1) { return "All Done!"; } + //publishProgress(1111); } - } @Override diff --git a/ethereumj-core/build.gradle b/ethereumj-core/build.gradle index ad40f28b..0e4e1841 100644 --- a/ethereumj-core/build.gradle +++ b/ethereumj-core/build.gradle @@ -83,7 +83,7 @@ dependencies { compile 'com.google.dagger:dagger:2.0' //compile 'com.android.support:appcompat-v7:+' compile fileTree(include: ['*.jar'], dir: 'libs') - provided 'org.glassfish:javax.annotation:10.0-b28' + provided 'javax.annotation:javax.annotation-api:1.2' compile 'com.j256.ormlite:ormlite-core:4.48' compile('com.j256.ormlite:ormlite-android:4.48') { exclude group: 'commons-logging', module: 'commons-logging' @@ -128,7 +128,7 @@ dependencies { compile 'com.yuvalshavit:antlr-denter:1.1' //compile 'org.javassist:javassist:3.15.0-GA' - compile 'org.slf4j:slf4j-android:1.6.1-RC1' + compile 'org.slf4j:slf4j-android:1.7.12' //compile "org.slf4j:slf4j-api:${slf4jVersion}" //compile "log4j:log4j:${log4jVersion}" diff --git a/ethereumj-core/src/main/java/org/ethereum/cli/CLIInterface.java b/ethereumj-core/src/main/java/org/ethereum/cli/CLIInterface.java index ab22cee0..fbd78b7e 100644 --- a/ethereumj-core/src/main/java/org/ethereum/cli/CLIInterface.java +++ b/ethereumj-core/src/main/java/org/ethereum/cli/CLIInterface.java @@ -2,9 +2,10 @@ package org.ethereum.cli; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - //import org.springframework.stereotype.Component; +import java.net.URI; + import static org.ethereum.config.SystemProperties.CONFIG; /** @@ -46,12 +47,14 @@ public class CLIInterface { // override the connect host:port directory if (args[i].equals("-connect") && i + 1 < args.length) { String connectStr = args[i + 1]; - logger.info("Connect host:port set to [{}]", connectStr); - String[] params = connectStr.split(":"); - String host = params[0]; - String port = params[1]; - CONFIG.setActivePeerIP(host); - CONFIG.setActivePeerPort(Integer.valueOf(port)); + logger.info("Connect URI set to [{}]", connectStr); + URI uri = new URI(connectStr); + if (!uri.getScheme().equals("enode")) + throw new RuntimeException("expecting URL in the format enode://PUBKEY@HOST:PORT"); + + CONFIG.setActivePeerIP(uri.getHost()); + CONFIG.setActivePeerPort(uri.getPort()); + CONFIG.setActivePeerNodeid(uri.getUserInfo()); } // override the listen port directory diff --git a/ethereumj-core/src/main/java/org/ethereum/config/SystemProperties.java b/ethereumj-core/src/main/java/org/ethereum/config/SystemProperties.java index 9dcc30ff..a502eacd 100644 --- a/ethereumj-core/src/main/java/org/ethereum/config/SystemProperties.java +++ b/ethereumj-core/src/main/java/org/ethereum/config/SystemProperties.java @@ -42,6 +42,7 @@ public class SystemProperties { private final static String DEFAULT_HELLO_PHRASE = "Dev"; private final static Boolean DEFAULT_VM_TRACE = false; private final static String DEFAULT_VM_TRACE_DIR = "dmp"; + private final static Boolean DEFAULT_VM_TRACE_COMPRESSED = false; private final static int DEFAULT_PEER_LISTEN_PORT = 30303; private final static String DEFAULT_KEY_VALUE_DATA_SOURCE = "leveldb"; private final static boolean DEFAULT_REDIS_ENABLED = true; @@ -246,6 +247,10 @@ public class SystemProperties { return boolProperty("vm.structured.trace", DEFAULT_VM_TRACE); } + public boolean vmTraceCompressed() { + return boolProperty("vm.structured.compressed", DEFAULT_VM_TRACE_COMPRESSED); + } + private boolean boolProperty(String key, Boolean defaultValue) { return Boolean.parseBoolean(prop.getProperty(key, String.valueOf(defaultValue))); } 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 3e572911..44ee7276 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java @@ -24,7 +24,7 @@ import org.spongycastle.util.encoders.Hex; //import org.springframework.util.FileSystemUtils; import org.apache.commons.io.FileUtils; -//import javax.annotation.Resource; +import javax.annotation.Resource; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; @@ -34,6 +34,7 @@ import java.math.BigDecimal; import java.util.*; import javax.inject.Inject; +import javax.inject.Qualifier; import static org.ethereum.config.Constants.*; import static org.ethereum.config.SystemProperties.CONFIG; @@ -81,8 +82,8 @@ public class BlockchainImpl implements Blockchain { // to avoid using minGasPrice=0 from Genesis for the wallet private static final long INITIAL_MIN_GAS_PRICE = 10 * SZABO.longValue(); -// @Resource -// @Qualifier("pendingTransactions") + @Resource + //@Qualifier("pendingTransactions") private Set pendingTransactions = new HashSet<>(); private Repository repository; @@ -110,12 +111,11 @@ public class BlockchainImpl implements Blockchain { private List altChains = new ArrayList<>(); private List garbage = new ArrayList<>(); + long exitOn = Long.MAX_VALUE; - public BlockchainImpl(final Set pendingTransactions) { - this.pendingTransactions = Collections.synchronizedSet(pendingTransactions); + public BlockchainImpl() { } - //todo: autowire over constructor @Inject public BlockchainImpl(BlockStore blockStore, Repository repository, @@ -129,6 +129,7 @@ public class BlockchainImpl implements Blockchain { this.channelManager = channelManager; this.blockQueue = new BlockQueue(this); this.programInvokeFactory = new ProgramInvokeFactoryImpl(); + this.programInvokeFactory.setBlockchain(this); } @Override @@ -249,6 +250,11 @@ public class BlockchainImpl implements Blockchain { @Override public void add(Block block) { + if (exitOn < block.getNumber()) { + System.out.print("Exiting after block.number: " + getBestBlock().getNumber()); + System.exit(-1); + } + if(!isValid(block)){ logger.warn("Invalid block with number: {}", block.getNumber()); return; @@ -293,6 +299,7 @@ public class BlockchainImpl implements Blockchain { track.commit(); repository.flush(); // saving to the disc + storeBlock(block, receipts); // Remove all wallet transactions as they already approved by the net wallet.removeTransactions(block.getTransactionsList()); @@ -466,7 +473,7 @@ public class BlockchainImpl implements Blockchain { wallet.processBlock(block); } } - storeBlock(block, receipts); + return receipts; } @@ -498,9 +505,10 @@ public class BlockchainImpl implements Blockchain { receipt.setCumulativeGas(totalGasUsed); receipt.setPostTxState(repository.getRoot()); receipt.setTransaction(tx); + receipt.setLogInfoList(executor.getVMLogs()); - //stateLogger.info("block: [{}] executed tx: [{}] \n state: [{}]", block.getNumber(), i, - // Hex.toHexString(repository.getRoot())); + stateLogger.info("block: [{}] executed tx: [{}] \n state: [{}]", block.getNumber(), i, + Hex.toHexString(repository.getRoot())); stateLogger.info("[{}] ", receipt.toString()); @@ -528,7 +536,7 @@ public class BlockchainImpl implements Blockchain { long totalTime = System.nanoTime() - saveTime; adminInfo.addBlockExecTime(totalTime); - //logger.info("block: num: [{}] hash: [{}], executed after: [{}]nano", block.getNumber(), block.getShortHash(), totalTime); + logger.info("block: num: [{}] hash: [{}], executed after: [{}]nano", block.getNumber(), block.getShortHash(), totalTime); return receipts; } @@ -648,11 +656,11 @@ public class BlockchainImpl implements Blockchain { if (!CONFIG.recordBlocks()) return; - if (bestBlock.isGenesis()) { + if (block.getNumber() == 1) { //FileSystemUtils.deleteRecursively(new File(CONFIG.dumpDir())); - try{ + try { FileUtils.forceDelete(new File(CONFIG.dumpDir())); - }catch(IOException e){ + } catch (IOException e) { e.printStackTrace(); } } @@ -729,5 +737,8 @@ public class BlockchainImpl implements Blockchain { track.commit(); } + public void setExitOn(long exitOn) { + this.exitOn = exitOn; + } -} +} \ No newline at end of file diff --git a/ethereumj-core/src/main/java/org/ethereum/core/TransactionExecutor.java b/ethereumj-core/src/main/java/org/ethereum/core/TransactionExecutor.java index 992c8740..329e607a 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/TransactionExecutor.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/TransactionExecutor.java @@ -1,24 +1,23 @@ package org.ethereum.core; -//import jdk.jfr.events.ThrowablesEvent; import org.ethereum.db.BlockStore; import org.ethereum.facade.Repository; import org.ethereum.listener.EthereumListener; import org.ethereum.listener.EthereumListenerAdapter; import org.ethereum.vm.*; -import org.ethereum.vmtrace.ProgramTrace; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spongycastle.util.encoders.Hex; import java.math.BigInteger; -import java.nio.ByteBuffer; import java.util.List; -import static java.nio.ByteBuffer.wrap; import static org.ethereum.config.SystemProperties.CONFIG; import static org.ethereum.util.BIUtil.*; import static org.ethereum.util.ByteUtil.EMPTY_BYTE_ARRAY; +import static org.ethereum.util.ByteUtil.toHexString; +import static org.ethereum.vm.VMUtils.saveProgramTraceFile; +import static org.ethereum.vm.VMUtils.zipAndEncode; /** * @author Roman Mandeleil @@ -51,6 +50,7 @@ public class TransactionExecutor { long m_endGas = 0; long basicTxCost = 0; + List logs = null; public TransactionExecutor(Transaction tx, byte[] coinbase, Repository track, BlockStore blockStore, ProgramInvokeFactory programInvokeFactory, Block currentBlock) { @@ -79,15 +79,15 @@ public class TransactionExecutor { * will be ready to run the transaction at the end * set readyToExecute = true */ - public void init(){ + public void init() { long txGasLimit = toBI(tx.getGasLimit()).longValue(); boolean cumulativeGasReached = (gasUsedInTheBlock + txGasLimit > currentBlock.getGasLimit()); - if (cumulativeGasReached){ + if (cumulativeGasReached) { if (logger.isWarnEnabled()) - logger.warn("Too much gas used in this block: Require: {} Got: {}", currentBlock.getGasLimit() - toBI(tx.getGasLimit()).longValue(), toBI(tx.getGasLimit()).longValue() ); + logger.warn("Too much gas used in this block: Require: {} Got: {}", currentBlock.getGasLimit() - toBI(tx.getGasLimit()).longValue(), toBI(tx.getGasLimit()).longValue()); // TODO: save reason for failure return; @@ -97,7 +97,7 @@ public class TransactionExecutor { tx.nonZeroDataBytes() * GasCost.TX_NO_ZERO_DATA + tx.zeroDataBytes() * GasCost.TX_ZERO_DATA); boolean basicCostCovered = (txGasLimit >= basicTxCost); - if (!basicCostCovered){ + if (!basicCostCovered) { if (logger.isWarnEnabled()) logger.warn("Too much gas used in this block: Require: {} Got: {}", txGasLimit, basicTxCost); @@ -111,7 +111,7 @@ public class TransactionExecutor { BigInteger txNonce = toBI(tx.getNonce()); boolean validNonce = (txNonce.compareTo(reqNonce) == 0); - if (!validNonce){ + if (!validNonce) { if (logger.isWarnEnabled()) logger.warn("Invalid nonce: required: {} , tx.nonce: {}", reqNonce, txNonce); @@ -126,7 +126,7 @@ public class TransactionExecutor { BigInteger senderBalance = track.getBalance(tx.getSender()); boolean canAfford = isCovers(senderBalance, totalCost); - if (!canAfford){ + if (!canAfford) { if (logger.isWarnEnabled()) logger.warn("Not enough cash: Require: {}, Sender cash: {}", totalCost, senderBalance); @@ -138,7 +138,7 @@ public class TransactionExecutor { readyToExecute = true; } - public void execute2(){ + public void execute2() { if (!readyToExecute) return; @@ -148,8 +148,8 @@ public class TransactionExecutor { BigInteger txGasCost = toBI(tx.getGasPrice()).multiply(toBI(txGasLimit)); track.addBalance(tx.getSender(), txGasCost.negate()); - //if (logger.isInfoEnabled()) - // logger.info("Paying: txGasCost: [{}], gasPrice: [{}], gasLimit: [{}]", txGasCost, toBI(tx.getGasPrice()), txGasLimit); + if (logger.isInfoEnabled()) + logger.info("Paying: txGasCost: [{}], gasPrice: [{}], gasLimit: [{}]", txGasCost, toBI(tx.getGasPrice()), txGasLimit); if (tx.isContractCreation()) create(); @@ -163,7 +163,7 @@ public class TransactionExecutor { byte[] targetAddress = tx.getReceiveAddress(); byte[] code = track.getCode(targetAddress); - if (code.length > 0){ + if (code.length > 0) { ProgramInvoke programInvoke = programInvokeFactory.createProgramInvoke(tx, currentBlock, cacheTrack, blockStore); @@ -182,7 +182,7 @@ public class TransactionExecutor { private void create() { byte[] newContractAddress = tx.getContractAddress(); - if (tx.getData() != null && !(tx.getData().length == 0)){ + if (tx.getData() != null && !(tx.getData().length == 0)) { ProgramInvoke programInvoke = programInvokeFactory.createProgramInvoke(tx, currentBlock, cacheTrack, blockStore); @@ -202,7 +202,7 @@ public class TransactionExecutor { } - public void go(){ + public void go() { if (!readyToExecute) return; // TODO: transaction call for pre-compiled contracts @@ -213,12 +213,12 @@ public class TransactionExecutor { vm.play(program); result = program.getResult(); - m_endGas = toBI(tx.getGasLimit()).subtract( toBI(result.getGasUsed()) ).longValue(); + m_endGas = toBI(tx.getGasLimit()).subtract(toBI(result.getGasUsed())).longValue(); - if (tx.isContractCreation()){ + if (tx.isContractCreation()) { byte[] initCode = EMPTY_BYTE_ARRAY; - if (result.getHReturn().length * GasCost.CREATE_DATA <= m_endGas){ + if (result.getHReturn().length * GasCost.CREATE_DATA <= m_endGas) { BigInteger returnDataGasValue = BigInteger.valueOf(result.getHReturn().length * GasCost.CREATE_DATA); m_endGas -= returnDataGasValue.longValue(); @@ -236,11 +236,27 @@ public class TransactionExecutor { // https://github.com/ethereum/cpp-ethereum/blob/develop/libethereum/Executive.cpp#L241 cacheTrack.rollback(); m_endGas = 0; + } finally { + if (CONFIG.vmTrace()) { + String trace = (program == null) ? "{}" : program.getProgramTrace() + .result(result.getHReturn()) + .error(result.getException()) + .toString(); + + + if (CONFIG.vmTraceCompressed()) { + trace = zipAndEncode(trace); + } + + String txHash = toHexString(tx.getHash()); + saveProgramTraceFile(txHash, trace); + listener.onVMTraceCreated(txHash, trace); + } } } - public void finalization(){ + public void finalization() { if (!readyToExecute) return; cacheTrack.commit(); @@ -256,7 +272,7 @@ public class TransactionExecutor { long gasLimit = toBI(tx.getGasLimit()).longValue(); if (result != null) - m_endGas += Math.min(result.getFutureRefund(), result.getGasUsed() / 2); + m_endGas += Math.min(result.getFutureRefund(), result.getGasUsed() / 2); BigInteger endGasBI = toBI(m_endGas); BigInteger gasPrice = toBI(tx.getGasPrice()); @@ -281,9 +297,15 @@ public class TransactionExecutor { // Keep execution logs todo: that yet //*cpp* if (m_ext) // m_logs = m_ext->sub.logs; + + if (result.getLogInfoList() != null){ + + } } +/* + @Deprecated public void execute() { @@ -337,18 +359,17 @@ public class TransactionExecutor { // THE SIMPLE VALUE/BALANCE CHANGE if (!(isContractCreation || code != EMPTY_BYTE_ARRAY)) // if code invoke transfer will be done latter - // for rollback purposes + // for rollback purposes if (isCovers(track.getBalance(senderAddress), txValue)) { transfer(track, senderAddress, receiverAddress, txValue); - /*if (stateLogger.isDebugEnabled()) + if (stateLogger.isDebugEnabled()) stateLogger.debug("Update value balance \n " + "sender={}, receiver={}, value={}", Hex.toHexString(senderAddress), Hex.toHexString(receiverAddress), new BigInteger(tx.getValue())); -*/ } @@ -394,13 +415,12 @@ public class TransactionExecutor { transfer(trackTx, senderAddress, receiverAddress, txValue); -/* if (stateLogger.isDebugEnabled()) + if (stateLogger.isDebugEnabled()) stateLogger.debug("Update value balance \n " + "sender={}, receiver={}, value={}", Hex.toHexString(senderAddress), Hex.toHexString(receiverAddress), new BigInteger(tx.getValue())); -*/ } logger.info("Start tracking VM run"); @@ -422,8 +442,6 @@ public class TransactionExecutor { if (CONFIG.playVM()) vm.play(program); - program.saveProgramTraceToFile(txHash); - result = program.getResult(); gasUsed = applyProgramResult(result, gasDebit, gasPrice, trackTx, senderAddress, receiverAddress, coinbase, isContractCreation); @@ -440,14 +458,19 @@ public class TransactionExecutor { return; } finally { if (CONFIG.vmTrace()) { - String traceAsJson = "{}"; - if (program != null) { - ProgramTrace trace = program.getProgramTrace(); - trace.setResult(wrap(result.getHReturn())); - trace.setError(result.getException()); - traceAsJson = trace.asJsonString(); + String trace = (program == null) ? "{}" : program.getProgramTrace() + .result(result.getHReturn()) + .error(result.getException()) + .toString(); + + + if (CONFIG.vmTraceCompressed()) { + trace = zipAndEncode(trace); } - listener.onVMTraceCreated(txHash, traceAsJson); + + saveProgramTraceFile(txHash, trace); + + listener.onVMTraceCreated(txHash, trace); } } trackTx.commit(); @@ -475,10 +498,11 @@ public class TransactionExecutor { transfer(track, tx.getSender(), currentBlock.getCoinbase(), feesEarned); } + */ /** * After any contract code finish the run the certain result should take place, * according to the given circumstances. - */ + *//* private long applyProgramResult(ProgramResult result, BigInteger gasDebit, BigInteger gasPrice, Repository repository, byte[] senderAddress, byte[] contractAddress, byte[] coinbase, boolean initResults) { @@ -499,13 +523,12 @@ public class TransactionExecutor { GasCost.SUICIDE_REFUND * (result.getDeleteAccounts() == null ? 0 : result.getDeleteAccounts().size())); if (isPositive(refund)) { - /*if (stateLogger.isDebugEnabled()) + if (stateLogger.isDebugEnabled()) stateLogger .debug("After contract execution the sender address refunded with gas leftover, " + "\n sender={} \n contract={} \n gas_refund= {}", Hex.toHexString(senderAddress), Hex.toHexString(contractAddress), refund); -*/ // gas refund transfer(repository, coinbase, senderAddress, refund); } @@ -519,13 +542,13 @@ public class TransactionExecutor { BigInteger futureRefundBI = toBI(futureRefund); BigInteger futureRefundVal = futureRefundBI.multiply(gasPrice); - /* if (stateLogger.isDebugEnabled()) + if (stateLogger.isDebugEnabled()) stateLogger .debug("After contract execution the sender address refunded with storage save refunds, " + "\n sender={} \n contract={} \n gas_refund= {}", Hex.toHexString(senderAddress), Hex.toHexString(contractAddress), futureRefundVal); -*/ + transfer(repository, coinbase, senderAddress, futureRefundVal); } @@ -567,17 +590,19 @@ public class TransactionExecutor { return gasUsed; } +*/ public TransactionReceipt getReceipt() { return receipt; } + public List getVMLogs() { return logs; } public ProgramResult getResult() { return result; } - public long getGasUsed(){ + public long getGasUsed() { return toBI(tx.getGasLimit()).longValue() - m_endGas; } diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Wallet.java b/ethereumj-core/src/main/java/org/ethereum/core/Wallet.java index 3581cc67..28843760 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/Wallet.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/Wallet.java @@ -4,7 +4,6 @@ import org.ethereum.crypto.ECKey; import org.ethereum.db.ByteArrayWrapper; import org.ethereum.facade.Repository; import org.ethereum.manager.WorldManager; -import org.ethereum.net.server.Channel; import org.ethereum.net.submit.WalletTransaction; import org.slf4j.Logger; @@ -77,12 +76,12 @@ public class Wallet { private Map transactionMap = new HashMap<>(); - @Inject Provider accountProvider; @Inject - public Wallet(Repository repository) { + public Wallet(Repository repository, Provider accountProvider) { this.repository = repository; + this.accountProvider = accountProvider; } diff --git a/ethereumj-core/src/main/java/org/ethereum/datasource/LevelDbDataSource.java b/ethereumj-core/src/main/java/org/ethereum/datasource/LevelDbDataSource.java index 88fb224b..663898ca 100644 --- a/ethereumj-core/src/main/java/org/ethereum/datasource/LevelDbDataSource.java +++ b/ethereumj-core/src/main/java/org/ethereum/datasource/LevelDbDataSource.java @@ -17,7 +17,6 @@ import java.io.IOException; import java.util.HashSet; import java.util.Map; import java.util.Set; -import org.iq80.leveldb.impl.Iq80DBFactory; import static org.iq80.leveldb.impl.Iq80DBFactory.factory; import android.content.Context; @@ -71,8 +70,7 @@ public class LevelDbDataSource implements KeyValueDataSource { logger.debug("Initializing new or existing database: '{}'", fileLocation.getAbsolutePath()); db = factory.open(fileLocation, options); - } catch (Exception ioe) { - logger.debug("x"); + } catch (IOException ioe) { logger.error(ioe.getMessage(), ioe); throw new RuntimeException("Can't initialize database"); } diff --git a/ethereumj-core/src/main/java/org/ethereum/datasource/redis/RedisConnectionImpl.java b/ethereumj-core/src/main/java/org/ethereum/datasource/redis/RedisConnectionImpl.java index ad0ffebe..41e0ac88 100644 --- a/ethereumj-core/src/main/java/org/ethereum/datasource/redis/RedisConnectionImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/datasource/redis/RedisConnectionImpl.java @@ -12,14 +12,13 @@ import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; import redis.clients.jedis.Protocol; +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; import java.net.URI; import java.util.Map; import java.util.Set; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; - -//import static org.springframework.util.StringUtils.hasLength; +//import static org.springframework.util.StringUtils.isEmpty; //@Component public class RedisConnectionImpl implements RedisConnection { diff --git a/ethereumj-core/src/main/java/org/ethereum/db/BlockStore.java b/ethereumj-core/src/main/java/org/ethereum/db/BlockStore.java index 0318f919..e7570716 100644 --- a/ethereumj-core/src/main/java/org/ethereum/db/BlockStore.java +++ b/ethereumj-core/src/main/java/org/ethereum/db/BlockStore.java @@ -3,7 +3,6 @@ package org.ethereum.db; import org.ethereum.core.Block; import org.ethereum.core.TransactionReceipt; -//import org.springframework.transaction.annotation.Transactional; import java.math.BigInteger; @@ -40,4 +39,4 @@ public interface BlockStore { void reset(); TransactionReceipt getTransactionReceiptByHash(byte[] hash); -} +} \ No newline at end of file diff --git a/ethereumj-core/src/main/java/org/ethereum/db/BlockStoreImpl.java b/ethereumj-core/src/main/java/org/ethereum/db/BlockStoreImpl.java index 40f4133a..7e19d5a9 100644 --- a/ethereumj-core/src/main/java/org/ethereum/db/BlockStoreImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/db/BlockStoreImpl.java @@ -4,13 +4,13 @@ import org.ethereum.core.Block; import org.ethereum.core.TransactionReceipt; import org.ethereum.util.ByteUtil; -import org.hibernate.SessionFactory; +//import org.hibernate.SessionFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Propagation; -import org.springframework.transaction.annotation.Transactional; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.context.ApplicationContext; +//import org.springframework.stereotype.Repository; +//import org.springframework.transaction.annotation.Propagation; +//import org.springframework.transaction.annotation.Transactional; import java.math.BigInteger; @@ -21,6 +21,7 @@ import java.util.List; * @author Roman Mandeleil * @since 12.11.2014 */ +/* public class BlockStoreImpl implements BlockStore { private SessionFactory sessionFactory; @@ -192,3 +193,4 @@ public class BlockStoreImpl implements BlockStore { } } +*/ \ No newline at end of file diff --git a/ethereumj-core/src/main/java/org/ethereum/db/InMemoryBlockStore.java b/ethereumj-core/src/main/java/org/ethereum/db/InMemoryBlockStore.java index d603ebcd..e9914b38 100644 --- a/ethereumj-core/src/main/java/org/ethereum/db/InMemoryBlockStore.java +++ b/ethereumj-core/src/main/java/org/ethereum/db/InMemoryBlockStore.java @@ -115,4 +115,3 @@ public class InMemoryBlockStore implements BlockStore { return null; } } - diff --git a/ethereumj-core/src/main/java/org/ethereum/db/RepositoryDummy.java b/ethereumj-core/src/main/java/org/ethereum/db/RepositoryDummy.java index 0d47c99d..4e546a44 100644 --- a/ethereumj-core/src/main/java/org/ethereum/db/RepositoryDummy.java +++ b/ethereumj-core/src/main/java/org/ethereum/db/RepositoryDummy.java @@ -74,14 +74,13 @@ public class RepositoryDummy extends RepositoryImpl { accountState.setStateRoot(contractDetails.getStorageHash()); accountState.setCodeHash(sha3(contractDetails.getCode())); worldState.put(hash, accountState); - /* if (logger.isDebugEnabled()) { + if (logger.isDebugEnabled()) { logger.debug("update: [{}],nonce: [{}] balance: [{}] \n [{}]", Hex.toHexString(hash.getData()), accountState.getNonce(), accountState.getBalance(), contractDetails.getStorage()); } - */ } 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 10963f38..c7324ac1 100644 --- a/ethereumj-core/src/main/java/org/ethereum/db/RepositoryImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/db/RepositoryImpl.java @@ -139,14 +139,14 @@ public class RepositoryImpl implements Repository { accountState.setStateRoot(contractDetails.getStorageHash()); accountState.setCodeHash(sha3(contractDetails.getCode())); worldState.update(hash.getData(), accountState.getEncoded()); - /*if (logger.isDebugEnabled()) { + if (logger.isDebugEnabled()) { logger.debug("update: [{}],nonce: [{}] balance: [{}] \n [{}]", Hex.toHexString(hash.getData()), accountState.getNonce(), accountState.getBalance(), contractDetails.getStorage()); } -*/ + } } 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 e7645a19..5aa8a4fc 100644 --- a/ethereumj-core/src/main/java/org/ethereum/db/RepositoryTrack.java +++ b/ethereumj-core/src/main/java/org/ethereum/db/RepositoryTrack.java @@ -123,8 +123,8 @@ public class RepositoryTrack implements Repository { BigInteger saveNonce = accountState.getNonce(); accountState.incrementNonce(); - //logger.trace("increase nonce addr: [{}], from: [{}], to: [{}]", Hex.toHexString(addr), - // saveNonce, accountState.getNonce()); + logger.trace("increase nonce addr: [{}], from: [{}], to: [{}]", Hex.toHexString(addr), + saveNonce, accountState.getNonce()); return accountState.getNonce(); } @@ -138,8 +138,8 @@ public class RepositoryTrack implements Repository { BigInteger saveNonce = accountState.getNonce(); accountState.setNonce(bigInteger); - //logger.trace("increase nonce addr: [{}], from: [{}], to: [{}]", Hex.toHexString(addr), - // saveNonce, accountState.getNonce()); + logger.trace("increase nonce addr: [{}], from: [{}], to: [{}]", Hex.toHexString(addr), + saveNonce, accountState.getNonce()); return accountState.getNonce(); @@ -168,8 +168,8 @@ public class RepositoryTrack implements Repository { BigInteger newBalance = accountState.addToBalance(value); - //logger.trace("adding to balance addr: [{}], balance: [{}], delta: [{}]", Hex.toHexString(addr), - // newBalance, value); + logger.trace("adding to balance addr: [{}], balance: [{}], delta: [{}]", Hex.toHexString(addr), + newBalance, value); return newBalance; } @@ -190,8 +190,8 @@ public class RepositoryTrack implements Repository { @Override public void addStorageRow(byte[] addr, DataWord key, DataWord value) { - //logger.trace("add storage row, addr: [{}], key: [{}] val: [{}]", Hex.toHexString(addr), - // key.toString(), value.toString()); + logger.trace("add storage row, addr: [{}], key: [{}] val: [{}]", Hex.toHexString(addr), + key.toString(), value.toString()); getContractDetails(addr).put(key, value); } diff --git a/ethereumj-core/src/main/java/org/ethereum/db/RepositoryVMTestDummy.java b/ethereumj-core/src/main/java/org/ethereum/db/RepositoryVMTestDummy.java index d2170a1d..7deccab3 100644 --- a/ethereumj-core/src/main/java/org/ethereum/db/RepositoryVMTestDummy.java +++ b/ethereumj-core/src/main/java/org/ethereum/db/RepositoryVMTestDummy.java @@ -71,13 +71,13 @@ public class RepositoryVMTestDummy extends RepositoryImpl{ accountState.setStateRoot(contractDetails.getStorageHash()); accountState.setCodeHash(sha3(contractDetails.getCode())); worldState.put(hash, accountState); - /*if (logger.isDebugEnabled()) { + if (logger.isDebugEnabled()) { logger.debug("update: [{}],nonce: [{}] balance: [{}] \n [{}]", Hex.toHexString(hash.getData()), accountState.getNonce(), accountState.getBalance(), contractDetails.getStorage()); - }*/ + } } diff --git a/ethereumj-core/src/main/java/org/ethereum/di/components/BlockchainComponent.java b/ethereumj-core/src/main/java/org/ethereum/di/components/BlockchainComponent.java deleted file mode 100644 index ae61f8d9..00000000 --- a/ethereumj-core/src/main/java/org/ethereum/di/components/BlockchainComponent.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.ethereum.di.components; - -import org.ethereum.di.modules.BlockchainModule; -import org.ethereum.di.modules.EthereumModule; - -import javax.inject.Singleton; - -import dagger.Component; - -@Singleton -@Component(modules = BlockchainModule.class) -public interface BlockchainComponent { -} \ No newline at end of file diff --git a/ethereumj-core/src/main/java/org/ethereum/di/modules/EthereumModule.java b/ethereumj-core/src/main/java/org/ethereum/di/modules/EthereumModule.java index c3e6a5d8..a66d5d3b 100644 --- a/ethereumj-core/src/main/java/org/ethereum/di/modules/EthereumModule.java +++ b/ethereumj-core/src/main/java/org/ethereum/di/modules/EthereumModule.java @@ -23,12 +23,15 @@ import org.ethereum.net.MessageQueue; import org.ethereum.net.client.PeerClient; import org.ethereum.net.eth.EthHandler; import org.ethereum.net.p2p.P2pHandler; +import org.ethereum.net.peerdiscovery.DiscoveryChannel; import org.ethereum.net.peerdiscovery.PeerDiscovery; +import org.ethereum.net.peerdiscovery.WorkerThread; import org.ethereum.net.server.ChannelManager; import org.ethereum.net.server.EthereumChannelInitializer; import org.ethereum.net.shh.ShhHandler; import org.ethereum.net.wire.MessageCodec; import org.ethereum.vm.ProgramInvokeFactory; +import org.ethereum.vm.ProgramInvokeFactoryImpl; import javax.inject.Provider; import javax.inject.Singleton; @@ -48,8 +51,8 @@ public class EthereumModule { @Provides @Singleton Ethereum provideEthereum(WorldManager worldManager, AdminInfo adminInfo, ChannelManager channelManager, - BlockLoader blockLoader, Provider peerClientProvider) { - return new EthereumImpl(worldManager, adminInfo, channelManager, blockLoader, peerClientProvider); + BlockLoader blockLoader, Provider peerClientProvider, EthereumListener listener) { + return new EthereumImpl(worldManager, adminInfo, channelManager, blockLoader, peerClientProvider, listener); } @Provides @@ -103,34 +106,40 @@ public class EthereumModule { @Provides @Singleton - ChannelManager provideChannelManager() { - return new ChannelManager(); + ChannelManager provideChannelManager(EthereumListener listener) { + return new ChannelManager(listener); } @Provides @Singleton - BlockLoader provideBlockLoader() { - return new BlockLoader(); + BlockLoader provideBlockLoader(Blockchain blockchain) { + return new BlockLoader(blockchain); } @Provides - EthHandler provideEthHandler() { - return new EthHandler(); + @Singleton + ProgramInvokeFactory provideProgramInvokeFactory() { + return new ProgramInvokeFactoryImpl(); } @Provides - ShhHandler provideShhHandler() { - return new ShhHandler(); + EthHandler provideEthHandler(Blockchain blockchain, EthereumListener listener, Wallet wallet) { + return new EthHandler(blockchain, listener, wallet); } @Provides - P2pHandler provideP2pHandler() { - return new P2pHandler(); + ShhHandler provideShhHandler(EthereumListener listener) { + return new ShhHandler(listener); } @Provides - MessageCodec provideMessageCodec() { - return new MessageCodec(); + P2pHandler provideP2pHandler(PeerDiscovery peerDiscovery, EthereumListener listener) { + return new P2pHandler(peerDiscovery, listener); + } + + @Provides + MessageCodec provideMessageCodec(EthereumListener listener) { + return new MessageCodec(listener); } @Provides @@ -140,8 +149,13 @@ public class EthereumModule { } @Provides - MessageQueue provideMessageQueue() { - return new MessageQueue(); + MessageQueue provideMessageQueue(EthereumListener listener) { + return new MessageQueue(listener); + } + + @Provides + WorkerThread provideWorkerThread(Provider discoveryChannelProvider) { + return new WorkerThread(discoveryChannelProvider); } @Provides @@ -151,11 +165,11 @@ public class EthereumModule { } - +/* @Provides String provideRemoteId() { return "bf01b54b6bc7faa203286dfb8359ce11d7b1fe822968fb4991f508d6f5a36ab7d9ae8af9b0d61c0467fb08567e0fb71cfb9925a370b69f9ede97927db473d1f5"; } - +*/ } diff --git a/ethereumj-core/src/main/java/org/ethereum/facade/Blockchain.java b/ethereumj-core/src/main/java/org/ethereum/facade/Blockchain.java index 9cfef0d6..90cc4793 100644 --- a/ethereumj-core/src/main/java/org/ethereum/facade/Blockchain.java +++ b/ethereumj-core/src/main/java/org/ethereum/facade/Blockchain.java @@ -56,5 +56,5 @@ public interface Blockchain { public void addPendingTransactions(Set transactions); public void clearPendingTransactions(List receivedTransactions); - + public void setExitOn(long exitOn); } diff --git a/ethereumj-core/src/main/java/org/ethereum/facade/CommonConfig.java b/ethereumj-core/src/main/java/org/ethereum/facade/CommonConfig.java index 9cf345de..32f68ad0 100644 --- a/ethereumj-core/src/main/java/org/ethereum/facade/CommonConfig.java +++ b/ethereumj-core/src/main/java/org/ethereum/facade/CommonConfig.java @@ -1,6 +1,12 @@ package org.ethereum.facade; import org.ethereum.config.SystemProperties; +import org.ethereum.core.Transaction; +import org.ethereum.datasource.KeyValueDataSource; +import org.ethereum.datasource.LevelDbDataSource; +import org.ethereum.datasource.redis.RedisConnection; +import org.ethereum.db.RepositoryImpl; +//import org.hibernate.SessionFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; //import org.springframework.beans.factory.annotation.Autowired; @@ -13,7 +19,13 @@ import org.slf4j.LoggerFactory; //import org.springframework.orm.hibernate4.LocalSessionFactoryBuilder; //import org.springframework.transaction.annotation.EnableTransactionManagement; +import java.sql.SQLException; +import java.util.Collections; +import java.util.HashSet; import java.util.Properties; +import java.util.Set; + +import static org.ethereum.config.SystemProperties.CONFIG; //@Configuration //@EnableTransactionManagement @@ -63,7 +75,7 @@ public class CommonConfig { } @Bean - public SessionFactory sessionFactory() throws SQLException { + public SessionFactory sessionFactory() { LocalSessionFactoryBuilder builder = new LocalSessionFactoryBuilder(dataSource()); builder.scanPackages("org.ethereum.db") @@ -90,11 +102,8 @@ public class CommonConfig { /* @Bean - public DataSourceTransactionManager transactionManager() { - DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(); - dataSourceTransactionManager.setDataSource(dataSource()); - - return dataSourceTransactionManager; + public HibernateTransactionManager txManager() { + return new HibernateTransactionManager(sessionFactory()); } */ /* @@ -118,6 +127,7 @@ public class CommonConfig { ds.setUsername("sa"); + return ds; } */ diff --git a/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java b/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java index acb82e57..cdf83590 100644 --- a/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java +++ b/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java @@ -135,4 +135,6 @@ public interface Ethereum { public Set getPendingTransactions(); public BlockLoader getBlockLoader(); + + public void exitOn(long number); } diff --git a/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java b/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java index b3858822..8b8b69b1 100644 --- a/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java @@ -19,7 +19,7 @@ import org.slf4j.LoggerFactory; //import org.springframework.context.ApplicationContext; //import org.springframework.stereotype.Component; -//import javax.annotation.PostConstruct; +import javax.annotation.PostConstruct; import java.math.BigInteger; import java.net.InetAddress; import java.util.HashSet; @@ -27,8 +27,6 @@ import java.util.Set; import java.util.concurrent.Executors; import java.util.concurrent.Future; -//import org.robospring.RoboSpring; -import javax.annotation.PostConstruct; import javax.inject.Inject; import javax.inject.Provider; @@ -43,7 +41,6 @@ public class EthereumImpl implements Ethereum { private static final Logger logger = LoggerFactory.getLogger("facade"); - @Inject EthereumListener listener; WorldManager worldManager; @@ -57,12 +54,12 @@ public class EthereumImpl implements Ethereum { BlockLoader blockLoader; - //@Inject Provider peerClientProvider; @Inject public EthereumImpl(WorldManager worldManager, AdminInfo adminInfo, - ChannelManager channelManager, BlockLoader blockLoader, Provider peerClientProvider) { + ChannelManager channelManager, BlockLoader blockLoader, + Provider peerClientProvider, EthereumListener listener) { System.out.println(); logger.info("EthereumImpl constructor"); this.worldManager = worldManager; @@ -70,9 +67,12 @@ public class EthereumImpl implements Ethereum { this.channelManager = channelManager; this.blockLoader = blockLoader; this.peerClientProvider = peerClientProvider; + this.listener = listener; + + this.init(); } - @PostConstruct + //@PostConstruct public void init() { worldManager.loadBlockchain(); if (CONFIG.listenPort() > 0) { @@ -265,4 +265,9 @@ public class EthereumImpl implements Ethereum { public BlockLoader getBlockLoader(){ return blockLoader; } -} + + @Override + public void exitOn(long number) { + worldManager.getBlockchain().setExitOn(number); + } +} \ No newline at end of file diff --git a/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/JSONReader.java b/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/JSONReader.java index 0a725ac8..b88a9968 100644 --- a/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/JSONReader.java +++ b/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/JSONReader.java @@ -23,9 +23,13 @@ import java.util.List; //import org.apache.commons.codec.binary.Base64; import android.util.Base64; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class JSONReader { + private static Logger logger = LoggerFactory.getLogger("TCK-Test"); + public static String loadJSON(String filename) { String json = ""; if (!SystemProperties.CONFIG.vmTestLoadLocal()) @@ -71,7 +75,7 @@ public class JSONReader { conn.connect(); InputStream in = conn.getInputStream(); rd = new BufferedReader(new InputStreamReader(in)); - System.out.println("Loading remote file: " + urlToRead); + logger.info("Loading remote file: " + urlToRead); while ((line = rd.readLine()) != null) { result += line; } @@ -134,4 +138,4 @@ public class JSONReader { return fileNames; } -} \ No newline at end of file +} diff --git a/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/TestProgramInvokeFactory.java b/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/TestProgramInvokeFactory.java index 3a7fc211..84f0f2b9 100644 --- a/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/TestProgramInvokeFactory.java +++ b/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/TestProgramInvokeFactory.java @@ -3,6 +3,7 @@ package org.ethereum.jsontestsuite; import org.ethereum.core.Block; import org.ethereum.core.Transaction; import org.ethereum.db.BlockStore; +import org.ethereum.facade.Blockchain; import org.ethereum.facade.Repository; import org.ethereum.util.ByteUtil; import org.ethereum.vm.DataWord; @@ -21,6 +22,8 @@ public class TestProgramInvokeFactory implements ProgramInvokeFactory { private final Env env; + private Blockchain blockchain; + public TestProgramInvokeFactory(Env env) { this.env = env; } @@ -93,4 +96,6 @@ public class TestProgramInvokeFactory implements ProgramInvokeFactory { timestamp, number, difficulty, gaslimit, repository, blockStore); } + public void setBlockchain(Blockchain blockchain) { this.blockchain = blockchain; } + } 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 e2460921..6b34737d 100644 --- a/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/TestRunner.java +++ b/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/TestRunner.java @@ -1,5 +1,6 @@ package org.ethereum.jsontestsuite; +import org.ethereum.core.Account; import org.ethereum.core.Block; import org.ethereum.core.BlockchainImpl; import org.ethereum.core.TransactionReceipt; @@ -12,8 +13,6 @@ import org.ethereum.jsontestsuite.model.BlockTck; import org.ethereum.listener.CompositeEthereumListener; import org.ethereum.listener.EthereumListener; import org.ethereum.manager.AdminInfo; -import org.ethereum.manager.WorldManager; -import org.ethereum.net.BlockQueue; import org.ethereum.net.server.ChannelManager; import org.ethereum.util.ByteUtil; import org.ethereum.vm.*; @@ -26,6 +25,7 @@ import java.math.BigInteger; import java.util.*; import javax.inject.Inject; +import javax.inject.Provider; import static org.ethereum.jsontestsuite.Utils.parseData; import static org.ethereum.util.ByteUtil.EMPTY_BYTE_ARRAY; @@ -41,17 +41,12 @@ public class TestRunner { private boolean setNewStateRoot; private String bestStateRoot; - @Inject - public WorldManager worldManager; - - @Inject public ChannelManager channelManager; @Inject - public ProgramInvokeFactory programInvokeFactory; - - @Inject - public BlockQueue blockqueue; + public TestRunner(ChannelManager channelManager) { + this.channelManager = channelManager; + } public List runTestSuite(TestSuite testSuite) { @@ -62,7 +57,7 @@ public class TestRunner { TestCase testCase = testIterator.next(); - TestRunner runner = new TestRunner(); + TestRunner runner = new TestRunner(channelManager); List result = runner.runTestCase(testCase); resultCollector.addAll(result); } @@ -76,20 +71,28 @@ public class TestRunner { /* 1 */ // Create genesis + init pre state Block genesis = BlockBuilder.build(testCase.getGenesisBlockHeader(), null, null); - Repository repository = RepositoryBuilder.build(testCase.getPre()); + final Repository repository = RepositoryBuilder.build(testCase.getPre()); BlockStore blockStore = new InMemoryBlockStore(); blockStore.saveBlock(genesis, new ArrayList()); - Wallet wallet = new Wallet(repository); + Provider accountProvider = new Provider() { + @Override + public Account get() { + return new Account(repository); + } + }; + Wallet wallet = new Wallet(repository, accountProvider); AdminInfo adminInfo = new AdminInfo(); EthereumListener listener = new CompositeEthereumListener(); + ProgramInvokeFactoryImpl programInvokeFactory = new ProgramInvokeFactoryImpl(); BlockchainImpl blockchain = new BlockchainImpl(blockStore, repository, wallet, adminInfo, listener, channelManager); blockchain.setBestBlock(genesis); blockchain.setTotalDifficulty(BigInteger.ZERO); blockchain.setProgramInvokeFactory(programInvokeFactory); + programInvokeFactory.setBlockchain(blockchain); // todo: validate root of the genesis *!!!* @@ -212,7 +215,8 @@ public class TestRunner { vmDidThrowAnEception = true; e = ex; } - program.saveProgramTraceToFile(testCase.getName()); + String content = program.getProgramTrace().asJsonString(true); + //program.saveProgramTraceToFile(testCase.getName(), content); if (testCase.getPost().size() == 0) { if (vmDidThrowAnEception != true) { @@ -233,7 +237,8 @@ public class TestRunner { this.trace = program.getProgramTrace(); - System.out.println("--------- POST --------"); + logger.info("--------- POST --------"); + /* 5. Assert Post values */ for (ByteArrayWrapper key : testCase.getPost().keySet()) { @@ -559,4 +564,4 @@ public class TestRunner { public ProgramTrace getTrace() { return trace; } -} +} \ No newline at end of file diff --git a/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/runners/StateTestRunner.java b/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/runners/StateTestRunner.java index 90bf8141..23acfd53 100644 --- a/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/runners/StateTestRunner.java +++ b/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/runners/StateTestRunner.java @@ -21,7 +21,6 @@ import org.slf4j.LoggerFactory; import org.spongycastle.util.encoders.Hex; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; public class StateTestRunner { @@ -37,7 +36,7 @@ public class StateTestRunner { Transaction transaction = TransactionBuilder.build(stateTestCase2.getTransaction()); logger.info("transaction: {}", transaction.toString()); - BlockchainImpl blockchain = new BlockchainImpl(new HashSet()); + BlockchainImpl blockchain = new BlockchainImpl(); blockchain.setRepository(repository); Env env = EnvBuilder.build(stateTestCase2.getEnv()); @@ -92,4 +91,4 @@ public class StateTestRunner { logger.info("\n\n"); return results; } -} \ No newline at end of file +} diff --git a/ethereumj-core/src/main/java/org/ethereum/manager/AdminInfo.java b/ethereumj-core/src/main/java/org/ethereum/manager/AdminInfo.java index ee182d2e..e5d5ccaa 100644 --- a/ethereumj-core/src/main/java/org/ethereum/manager/AdminInfo.java +++ b/ethereumj-core/src/main/java/org/ethereum/manager/AdminInfo.java @@ -15,12 +15,15 @@ import java.util.List; public class AdminInfo { - private long startupTimeStamp; + private long startupTimeStamp = System.currentTimeMillis();; private boolean consensus = true; private List blockExecTime = new LinkedList<>(); + public AdminInfo() { + this.init(); + } - @PostConstruct + //@PostConstruct public void init() { startupTimeStamp = System.currentTimeMillis(); } diff --git a/ethereumj-core/src/main/java/org/ethereum/manager/BlockLoader.java b/ethereumj-core/src/main/java/org/ethereum/manager/BlockLoader.java index 806d94b6..e8c088bf 100644 --- a/ethereumj-core/src/main/java/org/ethereum/manager/BlockLoader.java +++ b/ethereumj-core/src/main/java/org/ethereum/manager/BlockLoader.java @@ -3,19 +3,16 @@ package org.ethereum.manager; import org.ethereum.core.Block; import org.ethereum.facade.Blockchain; -import org.ethereum.net.BlockQueue; import org.spongycastle.util.encoders.Hex; //import org.springframework.beans.factory.annotation.Autowired; //import org.springframework.stereotype.Component; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; -import java.net.URISyntaxException; -import java.net.URL; import java.nio.charset.StandardCharsets; -//import java.nio.file.Files; -import org.apache.commons.io.FileUtils; import java.util.List; +import java.util.Scanner; import javax.inject.Inject; @@ -23,28 +20,40 @@ import static org.ethereum.config.SystemProperties.CONFIG; //@Component public class BlockLoader { - - @Inject + Blockchain blockchain; - + + Scanner scanner = null; + + @Inject + public BlockLoader(Blockchain blockchain) { + this.blockchain = blockchain; + } public void loadBlocks(){ String fileSrc = CONFIG.blocksLoader(); try { - File blocksFile = new File(fileSrc); + + FileInputStream inputStream = null; + inputStream = new FileInputStream(fileSrc); + scanner = new Scanner(inputStream, "UTF-8"); + System.out.println("Loading blocks: " + fileSrc); - //List blocksList = Files.readAllLines(blocksFile.toPath(), StandardCharsets.UTF_8); - List blocksList = FileUtils.readLines(blocksFile, StandardCharsets.UTF_8); - for (String blockRLP : blocksList){ + while (scanner.hasNextLine()) { - byte[] blockRLPBytes = Hex.decode( blockRLP ); + byte[] blockRLPBytes = Hex.decode( scanner.nextLine()); Block block = new Block(blockRLPBytes); + long t1 = System.nanoTime(); if (block.getNumber() > blockchain.getBestBlock().getNumber()){ - System.out.println("Importing block #" + block.getNumber()); blockchain.tryToConnect(block); + long t1_ = System.nanoTime(); + String result = String.format("Imported block #%d took: [%02.2f msec]", + block.getNumber(), ((float)(t1_ - t1) / 1_000_000)); + + System.out.println(result); } else System.out.println("Skipping block #" + block.getNumber()); @@ -53,7 +62,7 @@ public class BlockLoader { } catch (IOException e) { e.printStackTrace(); } - - } -} + + +} \ No newline at end of file diff --git a/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java b/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java index f1677e12..db8a58db 100644 --- a/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java @@ -28,9 +28,6 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -//import javax.annotation.PostConstruct; -//import javax.annotation.PreDestroy; - import static org.ethereum.config.SystemProperties.CONFIG; import javax.annotation.PostConstruct; @@ -78,9 +75,11 @@ public class WorldManager { this.blockStore = blockStore; this.channelManager = channelManager; this.listener = listener; + + this.init(); } - @PostConstruct + //@PostConstruct public void init() { byte[] cowAddr = HashUtil.sha3("cow".getBytes()); wallet.importKey(cowAddr); @@ -174,10 +173,10 @@ public class WorldManager { BigInteger totalDifficulty = blockStore.getTotalDifficulty(); blockchain.setTotalDifficulty(totalDifficulty); - //logger.info("*** Loaded up to block [{}] totalDifficulty [{}] with stateRoot [{}]", - // blockchain.getBestBlock().getNumber(), - // blockchain.getTotalDifficulty().toString(), - // Hex.toHexString(blockchain.getBestBlock().getStateRoot())); + logger.info("*** Loaded up to block [{}] totalDifficulty [{}] with stateRoot [{}]", + blockchain.getBestBlock().getNumber(), + blockchain.getTotalDifficulty().toString(), + Hex.toHexString(blockchain.getBestBlock().getStateRoot())); } if (CONFIG.rootHashStart() != null) { diff --git a/ethereumj-core/src/main/java/org/ethereum/net/MessageQueue.java b/ethereumj-core/src/main/java/org/ethereum/net/MessageQueue.java index df1ac63e..5feb53e0 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/MessageQueue.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/MessageQueue.java @@ -47,12 +47,12 @@ public class MessageQueue { private Queue messageQueue = new ConcurrentLinkedQueue<>(); private ChannelHandlerContext ctx = null; private final Timer timer = new Timer("MessageQueue"); - - @Inject + EthereumListener listener; boolean hasPing = false; - public MessageQueue() { + public MessageQueue(EthereumListener listener) { + this.listener = listener; } public void activate(ChannelHandlerContext ctx) { 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 69a936b4..610eaf76 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 @@ -75,19 +75,20 @@ public class EthHandler extends SimpleChannelInboundHandler { private Timer getBlocksTimer = new Timer("GetBlocksTimer"); private Timer getTxTimer = new Timer("GetTransactionsTimer"); - @Inject Blockchain blockchain; - @Inject EthereumListener listener; - @Inject Wallet wallet; private List sentHashes; private Block lastBlock = Genesis.getInstance(); - public EthHandler() { + @Inject + public EthHandler(Blockchain blockchain, EthereumListener listener, Wallet wallet) { + this.blockchain = blockchain; + this.listener = listener; + this.wallet = wallet; this.peerDiscoveryMode = false; } @@ -212,7 +213,7 @@ public class EthHandler extends SimpleChannelInboundHandler { // msgQueue.sendMessage(new DisconnectMessage(ReasonCode.INCOMPATIBLE_NETWORK)); ctx.pipeline().remove(this); // Peer is not compatible for the 'eth' sub-protocol } else if (msg.getNetworkId() != NETWORK_ID) - msgQueue.sendMessage(new DisconnectMessage(ReasonCode.INCOMPATIBLE_NETWORK)); + msgQueue.sendMessage(new DisconnectMessage(ReasonCode.NULL_IDENTITY)); else { BlockQueue chainQueue = blockchain.getQueue(); BigInteger peerTotalDifficulty = new BigInteger(1, msg.getTotalDifficulty()); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/eth/GetBlocksMessage.java b/ethereumj-core/src/main/java/org/ethereum/net/eth/GetBlocksMessage.java index c65b69c0..faff8a2d 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/eth/GetBlocksMessage.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/eth/GetBlocksMessage.java @@ -35,7 +35,7 @@ public class GetBlocksMessage extends EthMessage { RLPList paramsList = (RLPList) RLP.decode2(encoded).get(0); blockHashes = new ArrayList<>(); - for (int i = 1; i < paramsList.size(); ++i) { + for (int i = 0; i < paramsList.size(); ++i) { blockHashes.add(paramsList.get(i).getRLPData()); } parsed = true; diff --git a/ethereumj-core/src/main/java/org/ethereum/net/message/ReasonCode.java b/ethereumj-core/src/main/java/org/ethereum/net/message/ReasonCode.java index 86d6b3c5..c6a4901a 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/message/ReasonCode.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/message/ReasonCode.java @@ -37,7 +37,7 @@ public enum ReasonCode { /** * [0x05] Already have a running connection with this peer */ - ALREADY_CONNECTED(0x05), + DUPLICATE_PEER(0x05), /** * [0x06] Version of the p2p protocol is not the same as ours @@ -45,15 +45,23 @@ public enum ReasonCode { INCOMPATIBLE_PROTOCOL(0x06), /** - * [0x07] Peer identifies itself with the wrong networkId + * [0x07] */ - INCOMPATIBLE_NETWORK(0x07), + NULL_IDENTITY(0x07), /** * [0x08] Peer quit voluntarily */ PEER_QUITING(0x08), + UNEXPECTED_IDENTITY(0x09), + + LOCAL_IDENTITY(0x0A), + + PING_TIMEOUT(0x0B), + + USER_REASON(0x10), + /** * [0xFF] Reason not specified */ diff --git a/ethereumj-core/src/main/java/org/ethereum/net/p2p/DisconnectMessage.java b/ethereumj-core/src/main/java/org/ethereum/net/p2p/DisconnectMessage.java index b3e047e8..cb1ceb6f 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/p2p/DisconnectMessage.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/p2p/DisconnectMessage.java @@ -38,9 +38,8 @@ public class DisconnectMessage extends P2pMessage { } private void encode() { - byte[] encodedCommand = RLP.encodeByte(DISCONNECT.asByte()); byte[] encodedReason = RLP.encodeByte(this.reason.asByte()); - this.encoded = RLP.encodeList(encodedCommand, encodedReason); + this.encoded = RLP.encodeList(encodedReason); } @Override diff --git a/ethereumj-core/src/main/java/org/ethereum/net/p2p/HelloMessage.java b/ethereumj-core/src/main/java/org/ethereum/net/p2p/HelloMessage.java index 91907862..86724750 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/p2p/HelloMessage.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/p2p/HelloMessage.java @@ -8,6 +8,8 @@ import org.ethereum.util.RLPList; import com.google.common.base.Joiner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.spongycastle.util.encoders.Hex; import java.util.ArrayList; @@ -27,6 +29,9 @@ public class HelloMessage extends P2pMessage { * The implemented version of the P2P protocol. */ private byte p2pVersion; + + private final static Logger logger = LoggerFactory.getLogger("net"); + /** * The underlying client. A user-readable string. */ @@ -57,13 +62,12 @@ public class HelloMessage extends P2pMessage { this.listenPort = listenPort; this.peerId = peerId; this.parsed = true; + logger.info("Hello Message"); } private void parse() { + logger.info("Hello message parse"); RLPList paramsList = (RLPList) RLP.decode2(encoded).get(0); - // TODO: find out if it can be 0x00. Do we need to check for this? - // The message does not distinguish between 0 and null, - // so we check command code for null. byte[] p2pVersionBytes = paramsList.get(0).getRLPData(); this.p2pVersion = p2pVersionBytes != null ? p2pVersionBytes[0] : 0; diff --git a/ethereumj-core/src/main/java/org/ethereum/net/p2p/P2pHandler.java b/ethereumj-core/src/main/java/org/ethereum/net/p2p/P2pHandler.java index 855dcbc5..81b406ce 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/p2p/P2pHandler.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/p2p/P2pHandler.java @@ -64,7 +64,7 @@ import static org.ethereum.net.message.StaticMessages.*; //@Scope("prototype") public class P2pHandler extends SimpleChannelInboundHandler { - public final static byte VERSION = 3; + public final static byte VERSION = 4; private final static Logger logger = LoggerFactory.getLogger("net"); @@ -77,16 +77,17 @@ public class P2pHandler extends SimpleChannelInboundHandler { private HelloMessage handshakeHelloMessage = null; private Set lastPeersSent; - - @Inject + EthereumListener listener; - - @Inject + PeerDiscovery peerDiscovery; + private Channel channel; - public P2pHandler() { - + @Inject + public P2pHandler(PeerDiscovery peerDiscovery, EthereumListener listener) { + this.peerDiscovery = peerDiscovery; + this.listener = listener; this.peerDiscoveryMode = false; } diff --git a/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/DiscoveryChannel.java b/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/DiscoveryChannel.java index 98790dd9..c7bafa93 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/DiscoveryChannel.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/DiscoveryChannel.java @@ -43,10 +43,8 @@ public class DiscoveryChannel { private boolean peerDiscoveryMode = false; - @Inject EthereumListener listener; - @Inject Provider messageCodecProvider; MessageQueue messageQueue; @@ -59,11 +57,14 @@ public class DiscoveryChannel { @Inject public DiscoveryChannel(MessageQueue messageQueue, P2pHandler p2pHandler - , EthHandler ethHandler, ShhHandler shhHandler) { + , EthHandler ethHandler, ShhHandler shhHandler, + EthereumListener listener, Provider messageCodecProvider) { this.messageQueue = messageQueue; this.p2pHandler = p2pHandler; this.ethHandler = ethHandler; this.shhHandler = shhHandler; + this.listener = listener; + this.messageCodecProvider = messageCodecProvider; } public void connect(String host, int port) { @@ -90,7 +91,7 @@ public class DiscoveryChannel { shhHandler.setMsgQueue(messageQueue); - final MessageCodec decoder = messageCodecProvider.get();//ctx.getBean(MessageCodec.class); + final MessageCodec decoder = messageCodecProvider.get(); b.handler( @@ -143,4 +144,4 @@ public class DiscoveryChannel { public StatusMessage getStatusHandshake() { return ethHandler.getHandshakeStatusMessage(); } -} \ No newline at end of file +} diff --git a/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/PeerDiscovery.java b/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/PeerDiscovery.java index 44cd01bd..02ac43f5 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/PeerDiscovery.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/PeerDiscovery.java @@ -49,11 +49,15 @@ public class PeerDiscovery { private ThreadPoolExecutor executorPool; private RejectedExecutionHandler rejectionHandler; - private final AtomicBoolean started = new AtomicBoolean(false); - - @Inject + @Inject Provider workerThreadProvider; + @Inject + public PeerDiscovery() { + } + + private final AtomicBoolean started = new AtomicBoolean(false); + public void start() { // RejectedExecutionHandler implementation @@ -76,7 +80,7 @@ public class PeerDiscovery { addPeers(peerDataList); for (PeerInfo peerData : this.peers) { - WorkerThread workerThread = workerThreadProvider.get();//ctx.getBean(WorkerThread.class); + WorkerThread workerThread = workerThreadProvider.get(); workerThread.init(peerData, executorPool); executorPool.execute(workerThread); } @@ -126,7 +130,7 @@ public class PeerDiscovery { private void startWorker(PeerInfo peerInfo) { logger.debug("Add new peer for discovery: {}", peerInfo); - WorkerThread workerThread = workerThreadProvider.get();//ctx.getBean(WorkerThread.class); + WorkerThread workerThread = workerThreadProvider.get(); workerThread.init(peerInfo, executorPool); executorPool.execute(workerThread); } diff --git a/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/WorkerThread.java b/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/WorkerThread.java index 398245a2..d98b7c74 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/WorkerThread.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/peerdiscovery/WorkerThread.java @@ -1,6 +1,5 @@ package org.ethereum.net.peerdiscovery; -import org.ethereum.net.server.Channel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,10 +26,11 @@ public class WorkerThread implements Runnable { private PeerInfo peerInfo; private ThreadPoolExecutor poolExecutor; - @Inject Provider discoveryChannelProvider; - public WorkerThread() { + @Inject + public WorkerThread(Provider discoveryChannelProvider) { + this.discoveryChannelProvider = discoveryChannelProvider; } public void init(PeerInfo peer, ThreadPoolExecutor poolExecutor) { @@ -90,4 +90,4 @@ public class WorkerThread implements Runnable { public String toString() { return "Worker for: " + this.peerInfo.toString(); } -} \ No newline at end of file +} 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 99bb1868..daf9d00d 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 @@ -160,4 +160,4 @@ public class Channel { public void setInetSocketAddress(InetSocketAddress inetSocketAddress) { this.inetSocketAddress = inetSocketAddress; } -} \ No newline at end of file +} diff --git a/ethereumj-core/src/main/java/org/ethereum/net/server/ChannelManager.java b/ethereumj-core/src/main/java/org/ethereum/net/server/ChannelManager.java index f14a1ec4..572062a8 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/server/ChannelManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/server/ChannelManager.java @@ -24,8 +24,6 @@ import java.util.TimerTask; import javax.annotation.PostConstruct; import javax.inject.Inject; -//import javax.annotation.PostConstruct; - /** * @author Roman Mandeleil * @since 11.11.2014 @@ -39,15 +37,18 @@ public class ChannelManager { List channels = Collections.synchronizedList(new ArrayList()); Map blockCache = new HashMap<>(); - - @Inject + EthereumListener listener; - public ChannelManager() { + @Inject + public ChannelManager(EthereumListener listener) { + this.listener = listener; + + this.init(); } - @PostConstruct + //@PostConstruct public void init() { scheduleChannelCollector(); } @@ -145,4 +146,4 @@ public class ChannelManager { public List getChannels() { return channels; } -} \ No newline at end of file +} 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 4725f56c..64ea18f2 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 @@ -35,15 +35,15 @@ public class EthereumChannelInitializer extends ChannelInitializer channelProvider; @Inject - public EthereumChannelInitializer(Blockchain blockchain, ChannelManager channelManager, String remoteId) { + public EthereumChannelInitializer(Blockchain blockchain, ChannelManager channelManager, Provider channelProvider) { logger.info("Channel initializer instantiated"); this.blockchain = blockchain; this.channelManager = channelManager; - this.remoteId = remoteId; + this.channelProvider = channelProvider; + this.remoteId = ""; } @Override @@ -76,4 +76,4 @@ public class EthereumChannelInitializer extends ChannelInitializer { private final static Logger logger = LoggerFactory.getLogger("net"); - @Inject + public EthereumListener listener; - public ShhHandler() { + @Inject + public ShhHandler(EthereumListener listener) { + this.listener = listener; } public ShhHandler(MessageQueue msgQueue) { diff --git a/ethereumj-core/src/main/java/org/ethereum/net/wire/MessageCodec.java b/ethereumj-core/src/main/java/org/ethereum/net/wire/MessageCodec.java index b9cd663f..ca467e7e 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/wire/MessageCodec.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/wire/MessageCodec.java @@ -63,9 +63,14 @@ public class MessageCodec extends ByteToMessageCodec { } } - @Inject EthereumListener listener; + @Inject + public MessageCodec(EthereumListener listener) { + super(); + this.listener = listener; + } + @Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { if (!isHandshakeDone) @@ -87,7 +92,7 @@ public class MessageCodec extends ByteToMessageCodec { byte[] payload = ByteStreams.toByteArray(frame.getStream()); if (loggerWire.isDebugEnabled()) - loggerWire.debug("Encoded: [{}]", Hex.toHexString(payload)); + loggerWire.debug("Recv: Encoded: [{}]", Hex.toHexString(payload)); Message msg = MessageFactory.createMessage((byte) frame.getType(), payload); @@ -111,7 +116,7 @@ public class MessageCodec extends ByteToMessageCodec { byte[] encoded = msg.getEncoded(); if (loggerWire.isDebugEnabled()) - loggerWire.debug("Encoded: [{}]", Hex.toHexString(encoded)); + loggerWire.debug("Send: Encoded: [{}]", Hex.toHexString(encoded)); /* HERE WE ACTUALLY USING THE SECRET ENCODING */ byte code = getCode(msg.getCommand()); diff --git a/ethereumj-core/src/main/java/org/ethereum/util/AdvancedDeviceUtils.java b/ethereumj-core/src/main/java/org/ethereum/util/AdvancedDeviceUtils.java index 9fcbb94d..f75f92f6 100644 --- a/ethereumj-core/src/main/java/org/ethereum/util/AdvancedDeviceUtils.java +++ b/ethereumj-core/src/main/java/org/ethereum/util/AdvancedDeviceUtils.java @@ -19,4 +19,4 @@ public class AdvancedDeviceUtils { //PropertyConfigurator.configure(configFile); } } -} \ No newline at end of file +} diff --git a/ethereumj-core/src/main/java/org/ethereum/util/Utils.java b/ethereumj-core/src/main/java/org/ethereum/util/Utils.java index 5499a99a..cf4ca023 100644 --- a/ethereumj-core/src/main/java/org/ethereum/util/Utils.java +++ b/ethereumj-core/src/main/java/org/ethereum/util/Utils.java @@ -134,4 +134,4 @@ public class Utils { return sb.append(" ").append(firstHash).append("...").append(lastHash).toString(); } -} \ No newline at end of file +} diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/Program.java b/ethereumj-core/src/main/java/org/ethereum/vm/Program.java index 7fbe8c96..c9fab5b0 100644 --- a/ethereumj-core/src/main/java/org/ethereum/vm/Program.java +++ b/ethereumj-core/src/main/java/org/ethereum/vm/Program.java @@ -6,26 +6,22 @@ import org.ethereum.facade.Repository; import org.ethereum.util.ByteUtil; import org.ethereum.vm.MessageCall.MsgType; import org.ethereum.vm.PrecompiledContracts.PrecompiledContract; -import org.ethereum.vmtrace.Op; import org.ethereum.vmtrace.ProgramTrace; +import org.ethereum.vmtrace.ProgramTraceListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spongycastle.util.encoders.Hex; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; +import java.io.*; import java.math.BigInteger; -import java.nio.ByteBuffer; import java.util.*; import static java.lang.String.format; +import static java.lang.System.getProperty; import static org.ethereum.config.SystemProperties.CONFIG; import static org.ethereum.util.BIUtil.*; import static org.ethereum.util.ByteUtil.EMPTY_BYTE_ARRAY; //import static org.springframework.util.StringUtils.isEmpty; -//import static org.springframework.util.StringUtils.hasLength; /** * @author Roman Mandeleil @@ -51,9 +47,10 @@ public class Program { private int invokeHash; private ProgramListener listener; + private ProgramTraceListener traceListener = new ProgramTraceListener(); - Stack stack = new Stack<>(); - MemoryBuffer memory = new MemoryBuffer(); + Stack stack = new Stack(); + Memory memory = new Memory(); DataWord programAddress; ProgramResult result = new ProgramResult(); @@ -70,18 +67,28 @@ public class Program { ProgramInvoke invokeData; public Program(byte[] ops, ProgramInvoke invokeData) { + setupTraceListener(this.memory); + setupTraceListener(this.stack); - if (ops == null) ops = EMPTY_BYTE_ARRAY; - this.ops = ops; + this.ops = (ops == null) ? EMPTY_BYTE_ARRAY : ops; if (invokeData != null) { - this.invokeData = invokeData; this.programAddress = invokeData.getOwnerAddress(); + this.invokeData = invokeData; this.invokeHash = invokeData.hashCode(); - this.result.setRepository(invokeData.getRepository()); + + Repository repository = invokeData.getRepository(); + this.result.setRepository(setupTraceListener(new Storage(this.programAddress, repository))); + this.programTrace.initStorage(repository.getContractDetails(this.programAddress.getLast20Bytes())); + precompile(); } } + + private T setupTraceListener(T traceListenerAware) { + traceListenerAware.setTraceListener(traceListener); + return traceListenerAware; + } public byte getOp(int pc) { if (ops.length <= pc) @@ -136,7 +143,7 @@ public class Program { stack.push(stackWord); } - public Stack getStack() { + public Stack getStack() { return this.stack; } @@ -193,7 +200,7 @@ public class Program { * * @param stackSize int * @throws StackTooSmallException If the stack is - * smaller than stackSize + * smaller than stackSize */ public void stackRequire(int stackSize) { if (stack.size() < stackSize) { @@ -202,53 +209,53 @@ public class Program { } public void stackMax(int argsReqs, int returnReqs) { - if ( (stack.size() - argsReqs + returnReqs) > MAX_STACKSIZE) { + if ((stack.size() - argsReqs + returnReqs) > MAX_STACKSIZE) { throw new StackTooLargeException("Expected: overflow 1024 elements stack limit"); } } public int getMemSize() { - return memory.getSize(); + return memory.size(); } public void memorySave(DataWord addrB, DataWord value) { - memory.memorySave(addrB.intValue(), value.getData()); + memory.write(addrB.intValue(), value.getData()); } public void memorySave(int addr, byte[] value) { - memory.memorySave(addr, value); + memory.write(addr, value); } public void memoryExpand(DataWord outDataOffs, DataWord outDataSize) { if (outDataSize.isZero()) - return ; + return; - memory.memoryExpand(outDataOffs.intValue(), outDataSize.intValue()); + memory.extend(outDataOffs.intValue(), outDataSize.intValue()); } /** * Allocates a piece of memory and stores value at given offset address * - * @param addr is the offset address + * @param addr is the offset address * @param allocSize size of memory needed to write - * @param value the data to write to memory + * @param value the data to write to memory */ public void memorySave(int addr, int allocSize, byte[] value) { - memory.memorySave(addr, allocSize, value); + memory.extendAndWrite(addr, allocSize, value); } public DataWord memoryLoad(DataWord addr) { - return memory.memoryLoad(addr.intValue()); + return memory.readWord(addr.intValue()); } public DataWord memoryLoad(int address) { - return memory.memoryLoad(address); + return memory.readWord(address); } public byte[] memoryChunk(int offset, int size) { - return memory.memoryChunk(offset, size); + return memory.read(offset, size); } /** @@ -256,10 +263,10 @@ public class Program { * a specified size, calculated from a given offset * * @param offset the memory address offset - * @param size the number of bytes to allocate + * @param size the number of bytes to allocate */ public void allocateMemory(int offset, int size) { - memory.memoryExpand(offset, size); + memory.extend(offset, size); } @@ -278,6 +285,7 @@ public class Program { result.addDeleteAccount(this.getOwnerAddress()); } + @SuppressWarnings("ThrowableResultOfMethodCallIgnored") public void createContract(DataWord value, DataWord memStart, DataWord memSize) { if (invokeData.getCallDeep() == MAX_DEPTH) { @@ -326,7 +334,7 @@ public class Program { //In case of hashing collisions, check for any balance before createAccount() BigInteger oldBalance = result.getRepository().getBalance(newAddress); track.createAccount(newAddress); - track.addBalance(newAddress,oldBalance); + track.addBalance(newAddress, oldBalance); // [4] TRANSFER THE BALANCE track.addBalance(senderAddress, endowment.negate()); @@ -341,7 +349,7 @@ public class Program { this, new DataWord(newAddress), DataWord.ZERO, gasLimit, newBalance, null, track, this.invokeData.getBlockStore(), invokeData.byTestingSuite()); - ProgramResult result = null; + ProgramResult result = new ProgramResult(); if (programCode.length != 0) { VM vm = new VM(); @@ -352,8 +360,7 @@ public class Program { this.result.addLogInfos(result.getLogInfoList()); } - if (result != null && - result.getException() != null) { + if (result.getException() != null) { logger.debug("contract run halted by Exception: contract: [{}], exception: [{}]", Hex.toHexString(newAddress), result.getException()); @@ -365,8 +372,8 @@ public class Program { } if (programCode.length == 0) { - result = new ProgramResult(); - result.setHReturn(new byte[] {}); + result = new ProgramResult(); + result.setHReturn(new byte[]{}); } // 4. CREATE THE CONTRACT OUT OF RETURN @@ -402,7 +409,6 @@ public class Program { /** * That method is for internal code invocations - * * - Normal calls invoke a specified contract which updates itself * - Stateless calls invoke code from another contract, within the context of the caller * @@ -425,10 +431,10 @@ public class Program { // FETCH THE CODE byte[] programCode = this.result.getRepository().getCode(codeAddress); -/* if (logger.isInfoEnabled()) + if (logger.isInfoEnabled()) logger.info(msg.getType().name() + " for existing contract: address: [{}], outDataOffs: [{}], outDataSize: [{}] ", Hex.toHexString(contextAddress), msg.getOutDataOffs().longValue(), msg.getOutDataSize().longValue()); -*/ + Repository trackRepository = result.getRepository().startTracking(); // 2.1 PERFORM THE VALUE (endowment) PART @@ -440,7 +446,7 @@ public class Program { return; } - trackRepository .addBalance(senderAddress, endowment.negate()); + trackRepository.addBalance(senderAddress, endowment.negate()); BigInteger contextBalance = BigInteger.ZERO; if (!invokeData.byTestingSuite()) { @@ -512,12 +518,12 @@ public class Program { refundGas.toString()); } } else { - this.refundGas(msg.getGas().longValue(), "remaining gas from the internal call"); + this.refundGas(msg.getGas().longValue(), "remaining gas from the internal call"); } } public void spendGas(long gasValue, String cause) { - //gasLogger.info("[{}] Spent for cause: [{}], gas: [{}]", invokeHash, cause, gasValue); + gasLogger.info("[{}] Spent for cause: [{}], gas: [{}]", invokeHash, cause, gasValue); long afterSpend = invokeData.getGas().longValue() - gasValue - result.getGasUsed(); if (afterSpend < 0) { @@ -531,7 +537,7 @@ public class Program { } public void refundGas(long gasValue, String cause) { - //gasLogger.info("[{}] Refund for cause: [{}], gas: [{}]", invokeHash, cause, gasValue); + gasLogger.info("[{}] Refund for cause: [{}], gas: [{}]", invokeHash, cause, gasValue); result.refundGas(gasValue); } @@ -666,7 +672,7 @@ public class Program { } public String memoryToString() { - return memory.memoryToString(); + return memory.toString(); } public void fullTrace() { @@ -696,15 +702,15 @@ public class Program { StringBuilder memoryData = new StringBuilder(); StringBuilder oneLine = new StringBuilder(); - if (memory.getSize() > 32) + if (memory.size() > 32) memoryData.append("... Memory Folded.... ") .append("(") - .append(memory.getSize()) + .append(memory.size()) .append(") bytes"); else - for (int i = 0; i < memory.getSize(); ++i) { + for (int i = 0; i < memory.size(); ++i) { - byte value = memory.getByte(i); + byte value = memory.readByte(i); oneLine.append(ByteUtil.oneByteToHexString(value)).append(" "); if ((i + 1) % 16 == 0) { @@ -712,7 +718,7 @@ public class Program { Integer.toString(i, 16)).replace(" ", "0"); memoryData.append("").append(tmp).append(" "); memoryData.append(oneLine); - if (i < memory.getSize()) memoryData.append("\n"); + if (i < memory.size()) memoryData.append("\n"); oneLine.setLength(0); } } @@ -737,11 +743,11 @@ public class Program { logger.trace(" -- STACK -- {}", stackData); logger.trace(" -- MEMORY -- {}", memoryData); logger.trace(" -- STORAGE -- {}\n", storageData); - /*logger.trace("\n Spent Gas: [{}]/[{}]\n Left Gas: [{}]\n", + logger.trace("\n Spent Gas: [{}]/[{}]\n Left Gas: [{}]\n", result.getGasUsed(), invokeData.getGas().longValue(), getGas().longValue()); -*/ + StringBuilder globalOutput = new StringBuilder("\n"); if (stackData.length() > 0) stackData.append("\n"); @@ -770,50 +776,8 @@ public class Program { } public void saveOpTrace() { - - if (pc >= ops.length) return; - - Op op = new Op(); - op.setPc(pc); - op.setDeep(invokeData.getCallDeep()); - op.setOp(ops[pc]); - op.saveGas(getGas()); - - ContractDetails contractDetails = this.result.getRepository(). - getContractDetails(this.programAddress.getLast20Bytes()); - op.saveStorageMap(contractDetails.getStorage()); - op.saveMemory(memory.memoryChunk(0, memory.getSize())); - op.saveStack(stack); - - programTrace.addOp(op); - } - - public void saveProgramTraceToFile(String fileName) { - - if (!CONFIG.vmTrace() || CONFIG.vmTraceDir().isEmpty()) return; - - String dir = CONFIG.databaseDir() + "/" + CONFIG.vmTraceDir() + "/"; - - File dumpFile = new File(System.getProperty("user.dir") + "/" + dir + fileName + ".json"); - FileWriter fw = null; - BufferedWriter bw = null; - - try { - dumpFile.getParentFile().mkdirs(); - dumpFile.createNewFile(); - - fw = new FileWriter(dumpFile.getAbsoluteFile()); - bw = new BufferedWriter(fw); - bw.write(programTrace.asJsonString()); - } catch (IOException e) { - logger.error(e.getMessage(), e); - } finally { - try { - if (bw != null) bw.close(); - if (fw != null) fw.close(); - } catch (IOException e) { - e.printStackTrace(); - } + if (this.pc < ops.length) { + programTrace.addOp(ops[pc], pc, invokeData.getCallDeep(), getGas(), traceListener.resetActions()); } } @@ -836,7 +800,7 @@ public class Program { } - public static String stringify(byte[] code, int index, String result){ + public static String stringify(byte[] code, int index, String result) { if (code == null || code.length == 0) return result; @@ -851,11 +815,39 @@ public class Program { if (op == null) throw new IllegalOperationException("Invalid operation: " + Hex.toHexString(code, index, 1)); - switch(op) { - case PUSH1: case PUSH2: case PUSH3: case PUSH4: case PUSH5: case PUSH6: case PUSH7: case PUSH8: - case PUSH9: case PUSH10: case PUSH11: case PUSH12: case PUSH13: case PUSH14: case PUSH15: case PUSH16: - case PUSH17: case PUSH18: case PUSH19: case PUSH20: case PUSH21: case PUSH22: case PUSH23: case PUSH24: - case PUSH25: case PUSH26: case PUSH27: case PUSH28: case PUSH29: case PUSH30: case PUSH31: case PUSH32: + switch (op) { + case PUSH1: + case PUSH2: + case PUSH3: + case PUSH4: + case PUSH5: + case PUSH6: + case PUSH7: + case PUSH8: + case PUSH9: + case PUSH10: + case PUSH11: + case PUSH12: + case PUSH13: + case PUSH14: + case PUSH15: + case PUSH16: + case PUSH17: + case PUSH18: + case PUSH19: + case PUSH20: + case PUSH21: + case PUSH22: + case PUSH23: + case PUSH24: + case PUSH25: + case PUSH26: + case PUSH27: + case PUSH28: + case PUSH29: + case PUSH30: + case PUSH31: + case PUSH32: result += ' ' + op.name() + ' '; int nPush = op.val() - OpCode.PUSH1.val() + 1; @@ -972,9 +964,11 @@ public class Program { public static OutOfGasException notEnoughOpGas(OpCode op, long opGas, long programGas) { return new OutOfGasException("Not enough gas for '%s' operation executing: opGas[%d], programGas[%d];", op, opGas, programGas); } + public static OutOfGasException notEnoughOpGas(OpCode op, DataWord opGas, DataWord programGas) { return notEnoughOpGas(op, opGas.longValue(), programGas.longValue()); } + public static OutOfGasException notEnoughOpGas(OpCode op, BigInteger opGas, BigInteger programGas) { return notEnoughOpGas(op, opGas.longValue(), programGas.longValue()); } @@ -1012,14 +1006,14 @@ public class Program { * used mostly for testing reasons */ public byte[] getMemory() { - return memory.memoryChunk(0, memory.getSize()); + return memory.read(0, memory.size()); } /** * used mostly for testing reasons */ public void initMem(byte[] data) { - this.memory.memorySave(0, data); + this.memory.write(0, data); } diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/ProgramInvokeFactory.java b/ethereumj-core/src/main/java/org/ethereum/vm/ProgramInvokeFactory.java index 5a7614c5..46aba9e0 100644 --- a/ethereumj-core/src/main/java/org/ethereum/vm/ProgramInvokeFactory.java +++ b/ethereumj-core/src/main/java/org/ethereum/vm/ProgramInvokeFactory.java @@ -3,6 +3,7 @@ package org.ethereum.vm; import org.ethereum.core.Block; import org.ethereum.core.Transaction; import org.ethereum.db.BlockStore; +import org.ethereum.facade.Blockchain; import org.ethereum.facade.Repository; import java.math.BigInteger; @@ -21,5 +22,6 @@ public interface ProgramInvokeFactory { BigInteger balanceInt, byte[] dataIn, Repository repository, BlockStore blockStore, boolean byTestingSuite); + public void setBlockchain(Blockchain blockchain); } diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/ProgramInvokeFactoryImpl.java b/ethereumj-core/src/main/java/org/ethereum/vm/ProgramInvokeFactoryImpl.java index e7f5abd1..48ef7622 100644 --- a/ethereumj-core/src/main/java/org/ethereum/vm/ProgramInvokeFactoryImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/vm/ProgramInvokeFactoryImpl.java @@ -28,10 +28,12 @@ public class ProgramInvokeFactoryImpl implements ProgramInvokeFactory { private static final Logger logger = LoggerFactory.getLogger("VM"); - //@Autowired @Inject - public Blockchain blockchain; + Blockchain blockchain; + @Inject + public ProgramInvokeFactoryImpl() { + } // Invocation by the wire tx @Override @@ -87,7 +89,7 @@ public class ProgramInvokeFactoryImpl implements ProgramInvokeFactory { /*** GASLIMIT op ***/ long gaslimit = block.getGasLimit(); -/* + if (logger.isInfoEnabled()) { logger.info("Top level call: \n" + "address={}\n" + @@ -120,7 +122,7 @@ public class ProgramInvokeFactoryImpl implements ProgramInvokeFactory { Hex.toHexString(difficulty), gaslimit); } -*/ + return new ProgramInvokeImpl(address, origin, caller, balance, gasPrice, gas, callValue, data, lastHash, coinbase, timestamp, number, difficulty, gaslimit, repository, blockStore); @@ -151,7 +153,7 @@ public class ProgramInvokeFactoryImpl implements ProgramInvokeFactory { DataWord number = program.getNumber(); DataWord difficulty = program.getDifficulty(); DataWord gasLimit = program.getGaslimit(); -/* + if (logger.isInfoEnabled()) { logger.info("Internal call: \n" + "address={}\n" + @@ -183,7 +185,7 @@ public class ProgramInvokeFactoryImpl implements ProgramInvokeFactory { Hex.toHexString(difficulty.getNoLeadZeroesData()), gasLimit.bigIntValue()); } -*/ + return new ProgramInvokeImpl(address, origin, caller, balance, gasPrice, gas, callValue, data, lastHash, coinbase, timestamp, number, difficulty, gasLimit, repository, program.invokeData.getCallDeep() + 1, blockStore, byTestingSuite); @@ -192,4 +194,4 @@ public class ProgramInvokeFactoryImpl implements ProgramInvokeFactory { public void setBlockchain(Blockchain blockchain) { this.blockchain = blockchain; } -} \ No newline at end of file +} diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/VM.java b/ethereumj-core/src/main/java/org/ethereum/vm/VM.java index 14b520c4..e095fe89 100644 --- a/ethereumj-core/src/main/java/org/ethereum/vm/VM.java +++ b/ethereumj-core/src/main/java/org/ethereum/vm/VM.java @@ -10,7 +10,6 @@ import java.math.BigInteger; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Stack; import static org.ethereum.config.SystemProperties.CONFIG; import static org.ethereum.crypto.HashUtil.sha3; @@ -86,7 +85,7 @@ public class VM { long oldMemSize = program.getMemSize(); BigInteger newMemSize = BigInteger.ZERO; long copySize = 0; - Stack stack = program.getStack(); + Stack stack = program.getStack(); String hint = ""; long callGas = 0, memWords = 0; // parameters for logging @@ -829,11 +828,8 @@ public class VM { case SWAP13: case SWAP14: case SWAP15: case SWAP16:{ int n = op.val() - OpCode.SWAP1.val() + 2; - DataWord word_1 = stack.peek(); - stack.set(stack.size() - 1, stack.get(stack.size() - n)); - stack.set(stack.size() - n, word_1); + stack.swap(stack.size() - 1, stack.size() - n); program.step(); - } break; case LOG0: @@ -1037,13 +1033,13 @@ public class VM { DataWord value = program.stackPop(); DataWord inOffset = program.stackPop(); DataWord inSize = program.stackPop(); -/* + if (logger.isInfoEnabled()) logger.info(logString, program.getPC(), String.format("%-12s", op.name()), program.getGas().value(), program.invokeData.getCallDeep(), hint); -*/ + program.createContract(value, inOffset, inSize); program.step(); @@ -1069,12 +1065,10 @@ public class VM { + " gas: " + gas.shortHex() + " inOff: " + inDataOffs.shortHex() + " inSize: " + inDataSize.shortHex(); -/* logger.info(logString, program.getPC(), String.format("%-12s", op.name()), program.getGas().value(), program.invokeData.getCallDeep(), hint); -*/ } program.memoryExpand(outDataOffs, outDataSize); @@ -1126,13 +1120,13 @@ public class VM { } program.setPreviouslyExecutedOp(op.val()); -/* + if (logger.isInfoEnabled() && !op.equals(CALL) && !op.equals(CREATE)) logger.info(logString, stepBefore, String.format("%-12s", op.name()), program.getGas().longValue(), program.invokeData.getCallDeep(), hint); -*/ + vmCounter++; } catch (RuntimeException e) { logger.warn("VM halted: [{}]", e.toString()); @@ -1218,7 +1212,7 @@ public class VM { String opString = Hex.toHexString(new byte[]{op.val()}); String gasString = Hex.toHexString(program.getGas().getNoLeadZeroesData()); - //dumpLogger.trace("{} {} {} {}", addressString, pcString, opString, gasString); + dumpLogger.trace("{} {} {} {}", addressString, pcString, opString, gasString); } else if (CONFIG.dumpStyle().equals("pretty")) { dumpLogger.trace(" STACK"); for (DataWord item : program.getStack()) { @@ -1244,9 +1238,9 @@ public class VM { int level = program.invokeData.getCallDeep(); String contract = Hex.toHexString(program.getOwnerAddress().getLast20Bytes()); String internalSteps = String.format("%4s", Integer.toHexString(program.getPC())).replace(' ', '0').toUpperCase(); - //dumpLogger.trace("{} | {} | #{} | {} : {} | {} | -{} | {}x32", - // level, contract, vmCounter, internalSteps, op, - // gasBefore, gasCost, memWords); + dumpLogger.trace("{} | {} | #{} | {} : {} | {} | -{} | {}x32", + level, contract, vmCounter, internalSteps, op, + gasBefore, gasCost, memWords); } } } diff --git a/ethereumj-core/src/main/java/org/ethereum/vmtrace/Op.java b/ethereumj-core/src/main/java/org/ethereum/vmtrace/Op.java index c9fcf77a..62eda8dc 100644 --- a/ethereumj-core/src/main/java/org/ethereum/vmtrace/Op.java +++ b/ethereumj-core/src/main/java/org/ethereum/vmtrace/Op.java @@ -1,89 +1,54 @@ package org.ethereum.vmtrace; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import org.ethereum.vm.DataWord; -import org.spongycastle.util.encoders.Hex; +import org.ethereum.vm.OpCode; -import java.nio.ByteBuffer; -import java.util.*; +import java.math.BigInteger; -import static org.ethereum.vmtrace.Serializers.*; - -/** - * Data to for one program step to save. - * - * { - * 'op': 'CODECOPY' - * 'storage': {}, - * 'gas': '99376', - * 'deep': 0, - * 'pc': '9', - * 'memory': '', - * 'stack': ['15', '15', '14', '0'], - * } - * - * @author Roman Mandeleil - * @since 28.10.2014 - */ public class Op { - @JsonSerialize(using = OpCodeSerializer.class) - private byte op; + private OpCode code; private int deep; private int pc; - @JsonSerialize(using = DataWordSerializer.class) - private DataWord gas; - @JsonSerialize(using = ByteArraySerializer.class) - private byte[] memory; - private List stack; - private Map storage; + private BigInteger gas; + private OpActions actions; - public void setOp(byte op) { - this.op = op; + public OpCode getCode() { + return code; + } + + public void setCode(OpCode code) { + this.code = code; + } + + public int getDeep() { + return deep; } public void setDeep(int deep) { this.deep = deep; } + public int getPc() { + return pc; + } + public void setPc(int pc) { this.pc = pc; } - public void saveGas(DataWord gas) { + public BigInteger getGas() { + return gas; + } + + public void setGas(BigInteger gas) { this.gas = gas; } - public void saveStorageMap(Map storage) { - - this.storage = new HashMap<>(); - List keys = new ArrayList<>(storage.keySet()); - Collections.sort(keys); - for (DataWord key : keys) { - DataWord value = storage.get(key); - this.storage.put(Hex.toHexString(key.getData()), - Hex.toHexString(value.getData())); - } + public OpActions getActions() { + return actions; } - public void saveMemory(byte[] memory) { - this.memory = memory; - } - - public void saveStack(Stack stack) { - - this.stack = new ArrayList<>(); - - for (DataWord element : stack) { - this.stack.add(0, Hex.toHexString(element.getData())); - } - } - - public String toString() { - return asJsonString(); - } - - private String asJsonString() { - return serializeFieldsOnly(this, false); + public void setActions(OpActions actions) { + this.actions = actions; } } diff --git a/ethereumj-core/src/main/java/org/ethereum/vmtrace/ProgramTrace.java b/ethereumj-core/src/main/java/org/ethereum/vmtrace/ProgramTrace.java index 2c5a2dd4..6ec55ccf 100644 --- a/ethereumj-core/src/main/java/org/ethereum/vmtrace/ProgramTrace.java +++ b/ethereumj-core/src/main/java/org/ethereum/vmtrace/ProgramTrace.java @@ -1,55 +1,101 @@ package org.ethereum.vmtrace; -import com.fasterxml.jackson.annotation.JsonIgnore; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.spongycastle.util.encoders.Hex; +import org.ethereum.db.ContractDetails; +import org.ethereum.vm.DataWord; +import org.ethereum.vm.OpCode; -import java.nio.ByteBuffer; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import static java.lang.String.format; +import static org.ethereum.util.ByteUtil.toHexString; import static org.ethereum.vmtrace.Serializers.serializeFieldsOnly; -/** - * @author Roman Mandeleil - * @since 28.10.2014 - */ public class ProgramTrace { - private static final Logger LOGGER = LoggerFactory.getLogger("vmtrace"); - @JsonIgnore - private byte[] txHash; private List ops = new ArrayList<>(); private String result; private String error; + private Map initStorage = new HashMap<>(); - public void setTxHash(byte[] txHash) { - this.txHash = txHash; + public List getOps() { + return ops; } - public void setResult(ByteBuffer result) { - this.result = Hex.toHexString(result.array()); + public void setOps(List ops) { + this.ops = ops; } - public void setError(Exception error) { - this.error = (error == null) ? "" : format("%s: %s", error.getClass(), error.getMessage()); + public String getResult() { + return result; } - public void addOp(Op op) { + public void setResult(String result) { + this.result = result; + } + + public String getError() { + return error; + } + + public void setError(String error) { + this.error = error; + } + + public Map getInitStorage() { + return initStorage; + } + + public void setInitStorage(Map initStorage) { + this.initStorage = initStorage; + } + + public ProgramTrace initStorage(ContractDetails details) { + initStorage = new HashMap<>(); + for (Map.Entry entry : details.getStorage().entrySet()) { + initStorage.put(entry.getKey().toString(), entry.getValue().toString()); + } + return this; + } + + public ProgramTrace result(byte[] result) { + setResult(toHexString(result)); + return this; + } + + public ProgramTrace error(Exception error) { + setError(error == null ? "" : format("%s: %s", error.getClass(), error.getMessage())); + return this; + } + + public Op addOp(byte code, int pc, int deep, DataWord gas, OpActions actions) { + Op op = new Op(); + op.setActions(actions); + op.setCode(OpCode.code(code)); + op.setDeep(deep); + op.setGas(gas.value()); + op.setPc(pc); + ops.add(op); + + return op; } /** * Used for merging sub calls execution. */ public void merge(ProgramTrace programTrace) { - this.ops.addAll(programTrace.ops); } - public String asJsonString() { - return serializeFieldsOnly(this, true); + public String asJsonString(boolean formatted) { + return serializeFieldsOnly(this, formatted); + } + + @Override + public String toString() { + return asJsonString(true); } } diff --git a/ethereumj-core/src/main/java/org/ethereum/vmtrace/Serializers.java b/ethereumj-core/src/main/java/org/ethereum/vmtrace/Serializers.java index b7c06d74..5e1000e9 100644 --- a/ethereumj-core/src/main/java/org/ethereum/vmtrace/Serializers.java +++ b/ethereumj-core/src/main/java/org/ethereum/vmtrace/Serializers.java @@ -15,7 +15,7 @@ import org.spongycastle.util.encoders.Hex; import java.io.IOException; -final class Serializers { +public final class Serializers { private static final Logger LOGGER = LoggerFactory.getLogger("vmtrace"); @@ -48,7 +48,7 @@ final class Serializers { try { ObjectMapper mapper = createMapper(pretty); mapper.setVisibilityChecker(fieldsOnlyVisibilityChecker(mapper)); - + return mapper.writeValueAsString(value); } catch (Exception e) { LOGGER.error("JSON serialization error: ", e); diff --git a/ethereumj-core/src/main/java/org/ethereum/wallet/EtherSaleWallet.java b/ethereumj-core/src/main/java/org/ethereum/wallet/EtherSaleWallet.java index 885eb1e9..641fba07 100644 --- a/ethereumj-core/src/main/java/org/ethereum/wallet/EtherSaleWallet.java +++ b/ethereumj-core/src/main/java/org/ethereum/wallet/EtherSaleWallet.java @@ -68,4 +68,4 @@ public class EtherSaleWallet { } return data; } -} \ No newline at end of file +} diff --git a/ethereumj-core/src/main/resources/system.properties b/ethereumj-core/src/main/resources/system.properties index 67897053..15f25f7b 100644 --- a/ethereumj-core/src/main/resources/system.properties +++ b/ethereumj-core/src/main/resources/system.properties @@ -2,20 +2,50 @@ # the search of the online peers # values: [ip:port, ip:port, ip:port ...] peer.discovery.ip.list = poc-7.ethdev.com:30303,\ - 185.43.109.23:30303 + 185.43.109.23:30303 -# Peer Server Zero (poc-7.ethdev.com) -peer.active.ip = 139.162.13.89 +# my local box +#peer.active.ip = 192.168.1.146 +#peer.active.port = 30103 +#peer.active.nodeid = d348964fbb47d0cb9d206b926d416b2be8c1c0c68679f07d7611ef04ee797857d0ec8e7490cc3cc64094de9e7659be42baaf1fd24ca822c1bffc58ca9cf479dd + +# my poc-9-test peer-1 +peer.active.ip = 162.243.46.9 peer.active.port = 30303 -peer.active.nodeid = bf01b54b6bc7faa203286dfb8359ce11d7b1fe822968fb4991f508d6f5a36ab7d9ae8af9b0d61c0467fb08567e0fb71cfb9925a370b69f9ede97927db473d1f5 +peer.active.nodeid = e437a4836b77ad9d9ffe73ee782ef2614e6d8370fcf62191a6e488276e23717147073a7ce0b444d485fff5a0c34c4577251a7a990cf80d8542e21b95aa8c5e6c + + +# heiko peer +#peer.active.ip = 188.106.121.253 +#peer.active.port = 30303 +#peer.active.nodeid = 53f162c2e005aa04a763710c18e18a0042f4c46e2197162989161383c10d4e7b3cdcaeebf3c7f5336416a2c0a9787fb59365fde9313276b88703c8ada2f4e8d2 + +# victor peer +#peer.active.ip = 77.96.249.59 +#peer.active.port = 30300 +#peer.active.nodeid = 4e94cab3e9a85a22b59f69a2ad1f10ff1eaff5f8d94a0025df18c936a687b6ac99b3fb655677e8b9d08087319bca69ad2ab0b80a9d0ab47296bdc54c8cb09853 + + +#peer.active.ip = 139.162.13.89 +#peer.active.port = 30303 +#peer.active.nodeid = bf01b54b6bc7faa203286dfb8359ce11d7b1fe822968fb4991f508d6f5a36ab7d9ae8af9b0d61c0467fb08567e0fb71cfb9925a370b69f9ede97927db473d1f5 + +#peer.active.ip = 192.168.122.90 +#peer.active.port = 30303 +#peer.active.nodeid = 68cb34d6e806cd3f4e240f6eb2c5e1e8e4d2ebec2b7cf508a15c9847fc769a717da1f69f918548958fcfbe7e8cc77f1cd97f000ef39d0c28c618985e519806b4 + +# peer.active.ip = 52.4.40.229 +# peer.active.port = 30303 +# peer.active.nodeid = 65ce3a270c1f8409c072a889ab9a429b59d05774233e1508255f0cfafa719f6bb955503481b7e91774551fb36e41fb97f28bc647055fa988c1948b3651650cc5 + # Peer for server to listen for incoming # connections -peer.listen.port = 10101 +peer.listen.port = 30303 #peer.listen.port = 40304 # specify if the mechanism @@ -58,7 +88,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 @@ -95,7 +125,7 @@ dump.clean.on.restart = true # convenient form. vm.structured.trace = true vm.structured.dir = vmtrace - +vm.structured.compressed = true # make changes to tracing options # starting from certain block @@ -114,14 +144,14 @@ play.vm = true # we specify number of block we want # to get, recomendec value [1..1000] # Default: unlimited -max.hashes.ask = 1000 +max.hashes.ask = 10000 # maximum blocks to ask, # when downloading the chain # sequenteally sending GET_BLOCKS msg # we specify number of blocks we want # to get, recomendec value [1..120] -max.blocks.ask = 120 +max.blocks.ask = 500 # the network layer will ask for @@ -133,7 +163,7 @@ max.blocks.ask = 120 max.blocks.queued = 3000 # project version auto copied during build phase -project.version = 0.8.0 +project.version = 0.9.0 # hello phrase will be included in # the hello message of the peer @@ -159,4 +189,12 @@ keyvalue.datasource = leveldb # Redis cloud enabled flag. # Allows using RedisConnection for creating cloud based data structures. -redis.enabled=false \ No newline at end of file +redis.enabled=false + +record.blocks=false + +# Load the blocks +# from a rlp lines +# file and not for +# the net +blocks.loader=