merged develop branch
This commit is contained in:
parent
ccb8f4cdd1
commit
43905b99a2
|
@ -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";
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 {
|
|||
|
||||
}
|
||||
}
|
||||
*/
|
|
@ -115,4 +115,3 @@ public class InMemoryBlockStore implements BlockStore {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
}
|
|
@ -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";
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
}
|
||||
|
|
|
@ -56,5 +56,5 @@ public interface Blockchain {
|
|||
public void addPendingTransactions(Set<Transaction> transactions);
|
||||
public void clearPendingTransactions(List<Transaction> receivedTransactions);
|
||||
|
||||
|
||||
public void setExitOn(long exitOn);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -135,4 +135,6 @@ public interface Ethereum {
|
|||
public Set<Transaction> getPendingTransactions();
|
||||
|
||||
public BlockLoader getBlockLoader();
|
||||
|
||||
public void exitOn(long number);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
||||
}
|
||||
|
|
|
@ -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()) {
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -35,7 +35,6 @@ public class PeerServer {
|
|||
|
||||
public ChannelManager channelManager;
|
||||
|
||||
// TODO: this was removed ???
|
||||
public EthereumChannelInitializer ethereumChannelInitializer;
|
||||
|
||||
EthereumListener listener;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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=
|
||||
|
|
Loading…
Reference in New Issue