merged develop branch

This commit is contained in:
Adrian Tiberius 2015-05-26 15:23:26 +02:00
parent ccb8f4cdd1
commit 43905b99a2
57 changed files with 635 additions and 478 deletions

View File

@ -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";
}

View File

@ -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

View File

@ -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}"

View File

@ -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

View File

@ -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)));
}

View File

@ -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,7 +82,7 @@ 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
@Resource
//@Qualifier("pendingTransactions")
private Set<Transaction> pendingTransactions = new HashSet<>();
@ -110,12 +111,11 @@ public class BlockchainImpl implements Blockchain {
private List<Chain> altChains = new ArrayList<>();
private List<Block> garbage = new ArrayList<>();
long exitOn = Long.MAX_VALUE;
public BlockchainImpl(final Set<Transaction> 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,7 +656,7 @@ public class BlockchainImpl implements Blockchain {
if (!CONFIG.recordBlocks()) return;
if (bestBlock.isGenesis()) {
if (block.getNumber() == 1) {
//FileSystemUtils.deleteRecursively(new File(CONFIG.dumpDir()));
try {
FileUtils.forceDelete(new File(CONFIG.dumpDir()));
@ -729,5 +737,8 @@ public class BlockchainImpl implements Blockchain {
track.commit();
}
public void setExitOn(long exitOn) {
this.exitOn = exitOn;
}
}

View File

@ -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<LogInfo> logs = null;
public TransactionExecutor(Transaction tx, byte[] coinbase, Repository track, BlockStore blockStore,
ProgramInvokeFactory programInvokeFactory, Block currentBlock) {
@ -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();
@ -236,6 +236,22 @@ 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);
}
}
}
@ -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() {
@ -342,13 +364,12 @@ public class TransactionExecutor {
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,11 +590,13 @@ public class TransactionExecutor {
return gasUsed;
}
*/
public TransactionReceipt getReceipt() {
return receipt;
}
public List<LogInfo> getVMLogs() { return logs; }
public ProgramResult getResult() {
return result;

View File

@ -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<ByteArrayWrapper, Transaction> transactionMap = new HashMap<>();
@Inject
Provider<Account> accountProvider;
@Inject
public Wallet(Repository repository) {
public Wallet(Repository repository, Provider<Account> accountProvider) {
this.repository = repository;
this.accountProvider = accountProvider;
}

View File

@ -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");
}

View File

@ -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 {

View File

@ -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;

View File

@ -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 {
}
}
*/

View File

@ -115,4 +115,3 @@ public class InMemoryBlockStore implements BlockStore {
return null;
}
}

View File

@ -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());
}
*/
}

View File

@ -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());
}
*/
}
}

View File

@ -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);
}

View File

@ -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());
}*/
}
}

View File

@ -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 {
}

View File

@ -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<PeerClient> peerClientProvider) {
return new EthereumImpl(worldManager, adminInfo, channelManager, blockLoader, peerClientProvider);
BlockLoader blockLoader, Provider<PeerClient> 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<DiscoveryChannel> discoveryChannelProvider) {
return new WorkerThread(discoveryChannelProvider);
}
@Provides
@ -151,11 +165,11 @@ public class EthereumModule {
}
/*
@Provides
String provideRemoteId() {
return "bf01b54b6bc7faa203286dfb8359ce11d7b1fe822968fb4991f508d6f5a36ab7d9ae8af9b0d61c0467fb08567e0fb71cfb9925a370b69f9ede97927db473d1f5";
}
*/
}

View File

@ -56,5 +56,5 @@ public interface Blockchain {
public void addPendingTransactions(Set<Transaction> transactions);
public void clearPendingTransactions(List<Transaction> receivedTransactions);
public void setExitOn(long exitOn);
}

View File

@ -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;
}
*/

View File

@ -135,4 +135,6 @@ public interface Ethereum {
public Set<Transaction> getPendingTransactions();
public BlockLoader getBlockLoader();
public void exitOn(long number);
}

View File

@ -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<PeerClient> peerClientProvider;
@Inject
public EthereumImpl(WorldManager worldManager, AdminInfo adminInfo,
ChannelManager channelManager, BlockLoader blockLoader, Provider<PeerClient> peerClientProvider) {
ChannelManager channelManager, BlockLoader blockLoader,
Provider<PeerClient> 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);
}
}

View File

@ -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;
}

View File

@ -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; }
}

View File

@ -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<String> runTestSuite(TestSuite testSuite) {
@ -62,7 +57,7 @@ public class TestRunner {
TestCase testCase = testIterator.next();
TestRunner runner = new TestRunner();
TestRunner runner = new TestRunner(channelManager);
List<String> 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<TransactionReceipt>());
Wallet wallet = new Wallet(repository);
Provider<Account> accountProvider = new Provider<Account>() {
@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()) {

View File

@ -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<Transaction>());
BlockchainImpl blockchain = new BlockchainImpl();
blockchain.setRepository(repository);
Env env = EnvBuilder.build(stateTestCase2.getEnv());

View File

@ -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<Long> blockExecTime = new LinkedList<>();
public AdminInfo() {
this.init();
}
@PostConstruct
//@PostConstruct
public void init() {
startupTimeStamp = System.currentTimeMillis();
}

View File

@ -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;
@ -24,27 +21,39 @@ 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<String> blocksList = Files.readAllLines(blocksFile.toPath(), StandardCharsets.UTF_8);
List<String> 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();
}
}
}
}

View File

@ -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) {

View File

@ -48,11 +48,11 @@ public class MessageQueue {
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) {

View File

@ -75,19 +75,20 @@ public class EthHandler extends SimpleChannelInboundHandler<EthMessage> {
private Timer getBlocksTimer = new Timer("GetBlocksTimer");
private Timer getTxTimer = new Timer("GetTransactionsTimer");
@Inject
Blockchain blockchain;
@Inject
EthereumListener listener;
@Inject
Wallet wallet;
private List<ByteArrayWrapper> 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<EthMessage> {
// 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());

View File

@ -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;

View File

@ -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
*/

View File

@ -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

View File

@ -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;

View File

@ -64,7 +64,7 @@ import static org.ethereum.net.message.StaticMessages.*;
//@Scope("prototype")
public class P2pHandler extends SimpleChannelInboundHandler<P2pMessage> {
public final static byte VERSION = 3;
public final static byte VERSION = 4;
private final static Logger logger = LoggerFactory.getLogger("net");
@ -78,15 +78,16 @@ public class P2pHandler extends SimpleChannelInboundHandler<P2pMessage> {
private HelloMessage handshakeHelloMessage = null;
private Set<PeerInfo> 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;
}

View File

@ -43,10 +43,8 @@ public class DiscoveryChannel {
private boolean peerDiscoveryMode = false;
@Inject
EthereumListener listener;
@Inject
Provider<MessageCodec> 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<MessageCodec> 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(

View File

@ -49,11 +49,15 @@ public class PeerDiscovery {
private ThreadPoolExecutor executorPool;
private RejectedExecutionHandler rejectionHandler;
private final AtomicBoolean started = new AtomicBoolean(false);
@Inject
Provider<WorkerThread> 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);
}

View File

@ -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<DiscoveryChannel> discoveryChannelProvider;
public WorkerThread() {
@Inject
public WorkerThread(Provider<DiscoveryChannel> discoveryChannelProvider) {
this.discoveryChannelProvider = discoveryChannelProvider;
}
public void init(PeerInfo peer, ThreadPoolExecutor poolExecutor) {

View File

@ -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
@ -40,14 +38,17 @@ public class ChannelManager {
Map<ByteArrayWrapper, Block> blockCache = new HashMap<>();
@Inject
EthereumListener listener;
public ChannelManager() {
@Inject
public ChannelManager(EthereumListener listener) {
this.listener = listener;
this.init();
}
@PostConstruct
//@PostConstruct
public void init() {
scheduleChannelCollector();
}

View File

@ -35,15 +35,15 @@ public class EthereumChannelInitializer extends ChannelInitializer<NioSocketChan
String remoteId;
@Inject
Provider<Channel> channelProvider;
@Inject
public EthereumChannelInitializer(Blockchain blockchain, ChannelManager channelManager, String remoteId) {
public EthereumChannelInitializer(Blockchain blockchain, ChannelManager channelManager, Provider<Channel> channelProvider) {
logger.info("Channel initializer instantiated");
this.blockchain = blockchain;
this.channelManager = channelManager;
this.remoteId = remoteId;
this.channelProvider = channelProvider;
this.remoteId = "";
}
@Override

View File

@ -35,7 +35,6 @@ public class PeerServer {
public ChannelManager channelManager;
// TODO: this was removed ???
public EthereumChannelInitializer ethereumChannelInitializer;
EthereumListener listener;

View File

@ -32,10 +32,12 @@ public class ShhHandler extends SimpleChannelInboundHandler<ShhMessage> {
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) {

View File

@ -63,9 +63,14 @@ public class MessageCodec extends ByteToMessageCodec<Message> {
}
}
@Inject
EthereumListener listener;
@Inject
public MessageCodec(EthereumListener listener) {
super();
this.listener = listener;
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
if (!isHandshakeDone)
@ -87,7 +92,7 @@ public class MessageCodec extends ByteToMessageCodec<Message> {
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<Message> {
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());

View File

@ -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<DataWord> stack = new Stack<>();
MemoryBuffer memory = new MemoryBuffer();
Stack stack = new Stack();
Memory memory = new Memory();
DataWord programAddress;
ProgramResult result = new ProgramResult();
@ -70,19 +67,29 @@ 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 extends ProgramTraceListenerAware> T setupTraceListener(T traceListenerAware) {
traceListenerAware.setTraceListener(traceListener);
return traceListenerAware;
}
public byte getOp(int pc) {
if (ops.length <= pc)
return 0;
@ -136,7 +143,7 @@ public class Program {
stack.push(stackWord);
}
public Stack<DataWord> getStack() {
public Stack getStack() {
return this.stack;
}
@ -208,15 +215,15 @@ public class Program {
}
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) {
@ -224,7 +231,7 @@ public class Program {
if (outDataSize.isZero())
return;
memory.memoryExpand(outDataOffs.intValue(), outDataSize.intValue());
memory.extend(outDataOffs.intValue(), outDataSize.intValue());
}
/**
@ -235,20 +242,20 @@ public class Program {
* @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);
}
/**
@ -259,7 +266,7 @@ public class Program {
* @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) {
@ -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());
@ -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
@ -517,7 +523,7 @@ public class Program {
}
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());
}
}
@ -852,10 +816,38 @@ public class Program {
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:
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);
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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<DataWord> 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);
}
}
}

View File

@ -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<String> stack;
private Map<String, String> 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<DataWord, DataWord> storage) {
this.storage = new HashMap<>();
List<DataWord> 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<DataWord> 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;
}
}

View File

@ -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<Op> ops = new ArrayList<>();
private String result;
private String error;
private Map<String, String> initStorage = new HashMap<>();
public void setTxHash(byte[] txHash) {
this.txHash = txHash;
public List<Op> getOps() {
return ops;
}
public void setResult(ByteBuffer result) {
this.result = Hex.toHexString(result.array());
public void setOps(List<Op> 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<String, String> getInitStorage() {
return initStorage;
}
public void setInitStorage(Map<String, String> initStorage) {
this.initStorage = initStorage;
}
public ProgramTrace initStorage(ContractDetails details) {
initStorage = new HashMap<>();
for (Map.Entry<DataWord, DataWord> 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);
}
}

View File

@ -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");

View File

@ -6,16 +6,46 @@ peer.discovery.ip.list = poc-7.ethdev.com: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
@ -160,3 +190,11 @@ keyvalue.datasource = leveldb
# Redis cloud enabled flag.
# Allows using RedisConnection for creating cloud based data structures.
redis.enabled=false
record.blocks=false
# Load the blocks
# from a rlp lines
# file and not for
# the net
blocks.loader=