VMComplexTest introduced
This commit is contained in:
parent
82dd0f9761
commit
f7a264b0a8
|
@ -1,6 +1,5 @@
|
|||
package org.ethereum.gui;
|
||||
|
||||
import com.sun.javafx.binding.StringFormatter;
|
||||
import org.ethereum.core.Account;
|
||||
import org.ethereum.core.AccountState;
|
||||
import org.ethereum.core.ContractDetails;
|
||||
|
@ -19,13 +18,10 @@ import org.spongycastle.util.encoders.Hex;
|
|||
import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.border.EtchedBorder;
|
||||
import javax.swing.border.TitledBorder;
|
||||
import javax.swing.plaf.ComboBoxUI;
|
||||
import javax.swing.plaf.basic.BasicComboBoxUI;
|
||||
import javax.swing.plaf.basic.BasicComboPopup;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import javax.swing.table.TableModel;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.math.BigInteger;
|
||||
|
|
|
@ -39,10 +39,10 @@ public class ToolBar extends JFrame {
|
|||
public ToolBar() throws HeadlessException {
|
||||
|
||||
introLogger.info("");
|
||||
introLogger.info("<> EthereumJ [v0.5.1] by RomanJ");
|
||||
introLogger.info("<> Code by Roman Mandeleil, (c) 2014.");
|
||||
introLogger.info("<> Contribution: Nick Savers ");
|
||||
introLogger.info("<> Based on a design by Vitalik Buterin.");
|
||||
introLogger.info("|Ξ| EthereumJ [v0.5.1] by RomanJ");
|
||||
introLogger.info("|Ξ| Code by Roman Mandeleil, (c) 2014.");
|
||||
introLogger.info("|Ξ| Contribution: Nick Savers ");
|
||||
introLogger.info("|Ξ| Based on a design by Vitalik Buterin.");
|
||||
introLogger.info("");
|
||||
introLogger.info("java.version: " + System.getProperty("java.version"));
|
||||
introLogger.info("java.home: " + System.getProperty("java.home"));
|
||||
|
|
|
@ -76,7 +76,7 @@ public class WorldManager {
|
|||
|
||||
public void applyTransaction(Transaction tx) {
|
||||
|
||||
// TODO: refactor the wallet transactions to the world manager
|
||||
// TODO: refactor the wallet pending transactions to the world manager
|
||||
if (blockChain != null)
|
||||
blockChain.addWalletTransaction(tx);
|
||||
|
||||
|
|
|
@ -66,7 +66,8 @@ public class PeerData {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Peer: [ip=" + getInetAddress().getHostAddress() + ", port=" + getPort() + ", peerId=" + Hex.toHexString(getPeerId()) + "]";
|
||||
return "Peer: [ip=" + getInetAddress().getHostAddress() + ", port=" + getPort() +
|
||||
", peerId=" + (getPeerId() == null ? "": Hex.toHexString(getPeerId())) + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.util.*;
|
|||
public class Program {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger("VM");
|
||||
private Logger gasLogger = null;
|
||||
ProgramListener listener;
|
||||
|
||||
Stack<DataWord> stack = new Stack<DataWord>();
|
||||
|
@ -38,6 +39,8 @@ public class Program {
|
|||
|
||||
public Program(byte[] ops, ProgramInvoke invokeData) {
|
||||
|
||||
gasLogger = LoggerFactory.getLogger("gas - " + invokeData.hashCode());
|
||||
|
||||
result.setStateDb(invokeData.getStateDb());
|
||||
result.setChainDb(invokeData.getChainDb());
|
||||
result.setDetailDB(invokeData.getDetaildDB());
|
||||
|
@ -47,8 +50,14 @@ public class Program {
|
|||
this.invokeData = invokeData;
|
||||
this.ops = ops;
|
||||
|
||||
spendGas(GasCost.TRANSACTION);
|
||||
spendGas(GasCost.TXDATA * invokeData.getDataSize().intValue());
|
||||
// In case the program invoked by wire got
|
||||
// transaction, this will be the gas cost,
|
||||
// otherwise the call done by other contract
|
||||
// charged by CALL op
|
||||
if (invokeData.byTransaction()){
|
||||
spendGas(GasCost.TRANSACTION, "TRANSACTION");
|
||||
spendGas(GasCost.TXDATA * invokeData.getDataSize().intValue(), "DATA");
|
||||
}
|
||||
|
||||
if (invokeData.getStorage() != null){
|
||||
storage = invokeData.getStorage();
|
||||
|
@ -220,13 +229,13 @@ public class Program {
|
|||
* That method implement internal calls
|
||||
* and code invocations
|
||||
*
|
||||
* @param gas
|
||||
* @param toAddressDW
|
||||
* @param endowmentValue
|
||||
* @param inDataOffs
|
||||
* @param inDataSize
|
||||
* @param outDataOffs
|
||||
* @param outDataSize
|
||||
* @param gas - gas to pay for the call, remain gas will be refunded to the caller
|
||||
* @param toAddressDW - address to call
|
||||
* @param endowmentValue - the value that can be transfer along with the code execution
|
||||
* @param inDataOffs - start of memory to be input data to the call
|
||||
* @param inDataSize - size of memory to be input data to the call
|
||||
* @param outDataOffs - start of memory to be output of the call
|
||||
* @param outDataSize - size of memory to be output data to the call
|
||||
*/
|
||||
public void callToAddress(DataWord gas, DataWord toAddressDW, DataWord endowmentValue,
|
||||
DataWord inDataOffs, DataWord inDataSize,DataWord outDataOffs, DataWord outDataSize){
|
||||
|
@ -252,11 +261,6 @@ public class Program {
|
|||
receiverState = new AccountState(accountData);
|
||||
}
|
||||
|
||||
// todo: endowment rollbacked move it from here
|
||||
receiverState.addToBalance(endowmentValue.value());
|
||||
result.getStateDb().update(toAddress, receiverState.getEncoded());
|
||||
// todo: endowment rollbacked move it from here
|
||||
|
||||
byte[] programCode = result.getChainDb().get(receiverState.getCodeHash());
|
||||
if (programCode != null && programCode.length != 0){
|
||||
|
||||
|
@ -285,7 +289,6 @@ public class Program {
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
// 2.2 UPDATE THE NONCE
|
||||
// (THIS STAGE IS NOT REVERTED BY ANY EXCEPTION)
|
||||
senderState.incrementNonce();
|
||||
|
@ -298,14 +301,17 @@ public class Program {
|
|||
chainDB.startTrack();
|
||||
stateDB.startTrack();
|
||||
|
||||
// todo: update the balance/value simple transfer
|
||||
// todo: check if the endowment can really be done
|
||||
receiverState.addToBalance(endowmentValue.value());
|
||||
stateDB.update(toAddress, receiverState.getEncoded());
|
||||
|
||||
Map<DataWord, DataWord> storage = null;
|
||||
if (details != null)
|
||||
storage = details.getStorage();
|
||||
|
||||
ProgramInvoke programInvoke =
|
||||
ProgramInvokeFactory.createProgramInvoke(this, toAddressDW, storage, endowmentValue, gas,receiverState.getBalance(),
|
||||
ProgramInvokeFactory.createProgramInvoke(this, toAddressDW, storage,
|
||||
endowmentValue, gas, receiverState.getBalance(),
|
||||
data.array(),
|
||||
detailDB, chainDB, stateDB);
|
||||
|
||||
|
@ -326,7 +332,8 @@ public class Program {
|
|||
}
|
||||
|
||||
// todo: apply results: result.gethReturn()
|
||||
// todo: refund for remain gas
|
||||
// todo: if there is out specified place hReturn on the out
|
||||
|
||||
|
||||
detailDB.commitTrack();
|
||||
chainDB.commitTrack();
|
||||
|
@ -334,7 +341,7 @@ public class Program {
|
|||
stackPush(new DataWord(1));
|
||||
|
||||
// the gas spent in any internal outcome
|
||||
spendGas(result.getGasUsed());
|
||||
spendGas(result.getGasUsed(), " 'Total for CALL run' ");
|
||||
logger.info("The usage of the gas in external call updated", result.getGasUsed());
|
||||
|
||||
// update the storage , it could
|
||||
|
@ -348,7 +355,9 @@ public class Program {
|
|||
}
|
||||
|
||||
|
||||
public void spendGas(int gasValue){
|
||||
public void spendGas(int gasValue, String cause){
|
||||
|
||||
gasLogger.info("Spent: for cause={} gas={}", cause, gasValue);
|
||||
|
||||
long afterSpend = invokeData.getGas().longValue() - gasValue - result.getGasUsed();
|
||||
if (afterSpend < 0)
|
||||
|
|
|
@ -38,5 +38,7 @@ public interface ProgramInvoke {
|
|||
public TrackDatabase getChainDb();
|
||||
public TrackTrie getStateDb();
|
||||
|
||||
public boolean byTransaction();
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import org.ethereum.db.TrackDatabase;
|
|||
import org.ethereum.trie.TrackTrie;
|
||||
import org.ethereum.util.ByteUtil;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
|
@ -38,6 +39,7 @@ public class ProgramInvokeImpl implements ProgramInvoke {
|
|||
TrackDatabase detaildDB;
|
||||
TrackDatabase chainDb;
|
||||
TrackTrie stateDb;
|
||||
private boolean byTransaction = true;
|
||||
|
||||
public ProgramInvokeImpl(DataWord address, DataWord origin, DataWord caller, DataWord balance,
|
||||
DataWord gasPrice, DataWord gas, DataWord callValue, byte[] msgData,
|
||||
|
@ -68,6 +70,7 @@ public class ProgramInvokeImpl implements ProgramInvoke {
|
|||
this.detaildDB = detaildDB;
|
||||
this.chainDb = chainDb;
|
||||
this.stateDb = stateDB;
|
||||
this.byTransaction = false;
|
||||
|
||||
}
|
||||
|
||||
|
@ -234,4 +237,63 @@ public class ProgramInvokeImpl implements ProgramInvoke {
|
|||
public TrackTrie getStateDb() {
|
||||
return stateDb;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean byTransaction() {
|
||||
return byTransaction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
ProgramInvokeImpl that = (ProgramInvokeImpl) o;
|
||||
|
||||
if (byTransaction != that.byTransaction) return false;
|
||||
if (address != null ? !address.equals(that.address) : that.address != null) return false;
|
||||
if (balance != null ? !balance.equals(that.balance) : that.balance != null) return false;
|
||||
if (callValue != null ? !callValue.equals(that.callValue) : that.callValue != null) return false;
|
||||
if (caller != null ? !caller.equals(that.caller) : that.caller != null) return false;
|
||||
if (chainDb != null ? !chainDb.equals(that.chainDb) : that.chainDb != null) return false;
|
||||
if (coinbase != null ? !coinbase.equals(that.coinbase) : that.coinbase != null) return false;
|
||||
if (detaildDB != null ? !detaildDB.equals(that.detaildDB) : that.detaildDB != null) return false;
|
||||
if (difficulty != null ? !difficulty.equals(that.difficulty) : that.difficulty != null) return false;
|
||||
if (gas != null ? !gas.equals(that.gas) : that.gas != null) return false;
|
||||
if (gasPrice != null ? !gasPrice.equals(that.gasPrice) : that.gasPrice != null) return false;
|
||||
if (gaslimit != null ? !gaslimit.equals(that.gaslimit) : that.gaslimit != null) return false;
|
||||
if (!Arrays.equals(msgData, that.msgData)) return false;
|
||||
if (number != null ? !number.equals(that.number) : that.number != null) return false;
|
||||
if (origin != null ? !origin.equals(that.origin) : that.origin != null) return false;
|
||||
if (prevHash != null ? !prevHash.equals(that.prevHash) : that.prevHash != null) return false;
|
||||
if (stateDb != null ? !stateDb.equals(that.stateDb) : that.stateDb != null) return false;
|
||||
if (storage != null ? !storage.equals(that.storage) : that.storage != null) return false;
|
||||
if (timestamp != null ? !timestamp.equals(that.timestamp) : that.timestamp != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = address != null ? address.hashCode() : 0;
|
||||
result = 31 * result + (origin != null ? origin.hashCode() : 0);
|
||||
result = 31 * result + (caller != null ? caller.hashCode() : 0);
|
||||
result = 31 * result + (balance != null ? balance.hashCode() : 0);
|
||||
result = 31 * result + (gas != null ? gas.hashCode() : 0);
|
||||
result = 31 * result + (gasPrice != null ? gasPrice.hashCode() : 0);
|
||||
result = 31 * result + (callValue != null ? callValue.hashCode() : 0);
|
||||
result = 31 * result + (msgData != null ? Arrays.hashCode(msgData) : 0);
|
||||
result = 31 * result + (prevHash != null ? prevHash.hashCode() : 0);
|
||||
result = 31 * result + (coinbase != null ? coinbase.hashCode() : 0);
|
||||
result = 31 * result + (timestamp != null ? timestamp.hashCode() : 0);
|
||||
result = 31 * result + (number != null ? number.hashCode() : 0);
|
||||
result = 31 * result + (difficulty != null ? difficulty.hashCode() : 0);
|
||||
result = 31 * result + (gaslimit != null ? gaslimit.hashCode() : 0);
|
||||
result = 31 * result + (storage != null ? storage.hashCode() : 0);
|
||||
result = 31 * result + (detaildDB != null ? detaildDB.hashCode() : 0);
|
||||
result = 31 * result + (chainDb != null ? chainDb.hashCode() : 0);
|
||||
result = 31 * result + (stateDb != null ? stateDb.hashCode() : 0);
|
||||
result = 31 * result + (byTransaction ? 1 : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,24 +65,24 @@ public class VM {
|
|||
|
||||
switch (OpCode.code(op)) {
|
||||
case SHA3:
|
||||
program.spendGas(GasCost.SHA3);
|
||||
program.spendGas(GasCost.SHA3, OpCode.code(op).name());
|
||||
break;
|
||||
case SLOAD:
|
||||
program.spendGas(GasCost.SLOAD);
|
||||
program.spendGas(GasCost.SLOAD, OpCode.code(op).name());
|
||||
break;
|
||||
case SSTORE:
|
||||
break;
|
||||
case BALANCE:
|
||||
program.spendGas(GasCost.BALANCE);
|
||||
program.spendGas(GasCost.BALANCE, OpCode.code(op).name());
|
||||
break;
|
||||
case CREATE:
|
||||
program.spendGas(GasCost.CREATE);
|
||||
program.spendGas(GasCost.CREATE, OpCode.code(op).name());
|
||||
break;
|
||||
case CALL:
|
||||
program.spendGas(GasCost.CALL);
|
||||
program.spendGas(GasCost.CALL, OpCode.code(op).name());
|
||||
break;
|
||||
default:
|
||||
program.spendGas(GasCost.STEP);
|
||||
program.spendGas(GasCost.STEP, OpCode.code(op).name());
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -458,11 +458,11 @@ public class VM {
|
|||
DataWord oldValue = program.storageLoad(addr);
|
||||
program.storageSave(addr, value);
|
||||
if (oldValue == null && !value.isZero()){
|
||||
program.spendGas(GasCost.SSTORE * 2);
|
||||
program.spendGas(GasCost.SSTORE * 2, OpCode.code(op).name());
|
||||
} else if (oldValue != null && value.isZero()){
|
||||
program.spendGas(GasCost.SSTORE * 0);
|
||||
program.spendGas(GasCost.SSTORE * 0, OpCode.code(op).name());
|
||||
} else
|
||||
program.spendGas(GasCost.SSTORE);
|
||||
program.spendGas(GasCost.SSTORE, OpCode.code(op).name());
|
||||
program.step();
|
||||
} break;
|
||||
case JUMP:{
|
||||
|
@ -554,7 +554,10 @@ public class VM {
|
|||
|
||||
// memory gas calc
|
||||
int newMemSize = program.getMemSize();
|
||||
program.spendGas(GasCost.MEMORY * (newMemSize - oldMemSize) /32);
|
||||
int memoryUsage = (newMemSize - oldMemSize) /32;
|
||||
|
||||
if (memoryUsage > 0)
|
||||
program.spendGas(GasCost.MEMORY * memoryUsage, OpCode.code(op).name());
|
||||
|
||||
program.fullTrace();
|
||||
} catch (RuntimeException e) {
|
||||
|
|
|
@ -5,9 +5,10 @@ server.acceptConnections = false
|
|||
# one default access point to start
|
||||
# discover the network e.g. ip: [54.201.28.117] port: [30303]
|
||||
# Peer Server Zero: peer discovery
|
||||
peer.discovery.ip = 54.201.28.117
|
||||
peer.discovery.ip = 54.72.69.180
|
||||
peer.discovery.port = 30303
|
||||
|
||||
|
||||
# Peer Server One: peer discovery
|
||||
#peer.discovery.ip = 54.204.10.41
|
||||
#peer.discovery.port = 30303
|
||||
|
@ -16,8 +17,8 @@ peer.discovery.port = 30303
|
|||
# that is the peer through
|
||||
# we get the chain: [54.201.28.117] port: [30303]
|
||||
# ZeroGox
|
||||
peer.active.ip = 54.204.10.41
|
||||
peer.active.port = 30303
|
||||
#peer.active.ip = 54.204.10.41
|
||||
#peer.active.port = 30303
|
||||
|
||||
# Some dude in Canada
|
||||
#peer.active.ip = 131.104.247.135
|
||||
|
@ -29,8 +30,12 @@ peer.active.port = 30303
|
|||
|
||||
|
||||
# RomanJ general
|
||||
#peer.active.ip = 54.211.14.10
|
||||
#peer.active.port = 50505
|
||||
peer.active.ip = 54.211.14.10
|
||||
peer.active.port = 30303
|
||||
|
||||
#poc5.testnet.ethereum.org
|
||||
#peer.active.ip = 54.72.69.180
|
||||
#peer.active.port = 30303
|
||||
|
||||
#peer.active.ip = 151.64.223.120
|
||||
#peer.active.port = 30304
|
||||
|
@ -48,7 +53,7 @@ peer.discovery = true
|
|||
# number of workers that
|
||||
# tastes the peers for being
|
||||
# online [1..10]
|
||||
peer.discovery.workers = 5
|
||||
peer.discovery.workers = 15
|
||||
|
||||
# connection timeout for trying to
|
||||
# connect to a peer [seconds]
|
||||
|
@ -59,13 +64,13 @@ peer.discovery.timeout = 2
|
|||
# transaction got approved when
|
||||
# include into a transactions msg
|
||||
# retrieved from the peer [seconds]
|
||||
transaction.approve.timeout = 360
|
||||
transaction.approve.timeout = 15
|
||||
|
||||
# the parameter specifies how much
|
||||
# time the active peer will wait
|
||||
# for a message to come before kill
|
||||
# the channel
|
||||
active.peer.channel.timeout = 360
|
||||
active.peer.channel.timeout = 15
|
||||
|
||||
# default directory where we keep
|
||||
# basic Serpent samples relative
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
package org.ethereum.vm;
|
||||
|
||||
import org.ethereum.core.ContractDetails;
|
||||
import org.ethereum.crypto.ECKey;
|
||||
import org.ethereum.crypto.HashUtil;
|
||||
import org.ethereum.db.TrackDatabase;
|
||||
import org.ethereum.manager.WorldManager;
|
||||
import org.ethereum.trie.TrackTrie;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
|
@ -18,6 +20,13 @@ public class ProgramInvokeMockImpl implements ProgramInvoke {
|
|||
|
||||
byte[] msgData;
|
||||
|
||||
TrackTrie stateDB = null;
|
||||
TrackDatabase chainDb = null;
|
||||
TrackDatabase detaildDB = null;
|
||||
|
||||
ContractDetails details = null;
|
||||
|
||||
|
||||
|
||||
public ProgramInvokeMockImpl(byte[] msgDataRaw){
|
||||
this.msgData = msgDataRaw;
|
||||
|
@ -29,9 +38,7 @@ public class ProgramInvokeMockImpl implements ProgramInvoke {
|
|||
/* ADDRESS op */
|
||||
public DataWord getOwnerAddress(){
|
||||
|
||||
byte[] cowPrivKey = HashUtil.sha3("cow".getBytes());
|
||||
byte[] addr = ECKey.fromPrivate(cowPrivKey).getAddress();
|
||||
|
||||
byte[] addr = Hex.decode("77045e71a7a2c50903d88e564cd72fab11e82051");
|
||||
return new DataWord(addr);
|
||||
}
|
||||
|
||||
|
@ -69,7 +76,7 @@ public class ProgramInvokeMockImpl implements ProgramInvoke {
|
|||
|
||||
/* GAS op */
|
||||
public DataWord getGas() {
|
||||
byte[] minGasPrice = Hex.decode("03E8");
|
||||
byte[] minGasPrice = Hex.decode("0F4240");
|
||||
return new DataWord(minGasPrice);
|
||||
}
|
||||
|
||||
|
@ -159,27 +166,50 @@ public class ProgramInvokeMockImpl implements ProgramInvoke {
|
|||
|
||||
@Override
|
||||
public DataWord getGaslimit() {
|
||||
long gasLimit = 968269;
|
||||
long gasLimit = 1000000;
|
||||
return new DataWord(gasLimit);
|
||||
}
|
||||
|
||||
|
||||
public void setStateDB(TrackTrie stateDB) {
|
||||
this.stateDB = stateDB;
|
||||
}
|
||||
|
||||
public void setChainDb(TrackDatabase chainDb) {
|
||||
this.chainDb = chainDb;
|
||||
}
|
||||
|
||||
public void setDetaildDB(TrackDatabase detaildDB) {
|
||||
this.detaildDB = detaildDB;
|
||||
}
|
||||
|
||||
public void setDetails(ContractDetails details) {
|
||||
this.details = details;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<DataWord, DataWord> getStorage() {
|
||||
return null;
|
||||
if (details == null) return null;
|
||||
return details.getStorage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrackDatabase getDetaildDB() {
|
||||
return null;
|
||||
return detaildDB;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrackDatabase getChainDb() {
|
||||
return null;
|
||||
return chainDb;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrackTrie getStateDb() {
|
||||
return null;
|
||||
return stateDB;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean byTransaction() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
package org.ethereum.vm;
|
||||
|
||||
import org.ethereum.core.AccountState;
|
||||
import org.ethereum.core.ContractDetails;
|
||||
import org.ethereum.crypto.HashUtil;
|
||||
import org.ethereum.db.TrackDatabase;
|
||||
import org.ethereum.manager.WorldManager;
|
||||
import org.ethereum.trie.TrackTrie;
|
||||
import org.junit.Test;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
*
|
||||
* @author: Roman Mandeleil
|
||||
* Created on: 16/06/2014 10:37
|
||||
*/
|
||||
|
||||
public class VMComplexTest {
|
||||
|
||||
|
||||
@Test // contract call recursive
|
||||
public void test1(){
|
||||
|
||||
/**
|
||||
* #The code will run
|
||||
* ------------------
|
||||
|
||||
a = contract.storage[999]
|
||||
if a > 0:
|
||||
contract.storage[999] = a - 1
|
||||
|
||||
# call to contract: 77045e71a7a2c50903d88e564cd72fab11e82051
|
||||
send((tx.gas / 10 * 8), 0x77045e71a7a2c50903d88e564cd72fab11e82051, 0)
|
||||
else:
|
||||
stop
|
||||
*/
|
||||
|
||||
DataWord key1 = new DataWord(999);
|
||||
DataWord value1 = new DataWord(3);
|
||||
|
||||
HashMap<DataWord, DataWord> storage = new HashMap<>();
|
||||
storage.put(key1, value1);
|
||||
|
||||
ContractDetails contractDetails = new ContractDetails(storage);
|
||||
|
||||
|
||||
// Set contract into Database
|
||||
String callerAddr = "cd2a3d9f938e13cd947ec05abc7fe734df8dd826";
|
||||
String contractAddr = "77045e71a7a2c50903d88e564cd72fab11e82051";
|
||||
String code = "6103e75660005460006000530b0f630000004b596001600053036103e757600060006000600060007377045e71a7a2c50903d88e564cd72fab11e820516008600a5c0402f1630000004c5800";
|
||||
|
||||
byte[] contractAddrB = Hex.decode(contractAddr);
|
||||
byte[] callerAddrB = Hex.decode(callerAddr);
|
||||
byte[] codeB = Hex.decode(code);
|
||||
|
||||
byte[] codeKey = HashUtil.sha3(codeB);
|
||||
AccountState accountState = new AccountState();
|
||||
accountState.setCodeHash(codeKey);
|
||||
|
||||
AccountState callerAcountState = new AccountState();
|
||||
callerAcountState.addToBalance(new BigInteger("100000000000000000000"));
|
||||
|
||||
WorldManager.instance.worldState.update(callerAddrB, callerAcountState.getEncoded());
|
||||
WorldManager.instance.worldState.update(contractAddrB, accountState.getEncoded());
|
||||
WorldManager.instance.chainDB.put(codeKey, codeB);
|
||||
WorldManager.instance.detaildDB.put(contractAddrB, contractDetails.getEncoded());
|
||||
|
||||
TrackTrie stateDB = new TrackTrie(WorldManager.instance.worldState);
|
||||
TrackDatabase chainDb = new TrackDatabase(WorldManager.instance.chainDB);
|
||||
TrackDatabase detaildDB = new TrackDatabase(WorldManager.instance.detaildDB);
|
||||
|
||||
ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl();
|
||||
pi.setDetaildDB(detaildDB);
|
||||
pi.setChainDb(chainDb);
|
||||
pi.setStateDB(stateDB);
|
||||
pi.setDetails(contractDetails);
|
||||
|
||||
// Play the program
|
||||
VM vm = new VM();
|
||||
Program program = new Program(codeB, pi);
|
||||
|
||||
try {
|
||||
while(!program.isStopped())
|
||||
vm.step(program);
|
||||
} catch (RuntimeException e) {
|
||||
program.setRuntimeFailure(e);
|
||||
}
|
||||
|
||||
|
||||
System.out.println("============ Results ============");
|
||||
AccountState as =
|
||||
new AccountState(WorldManager.instance.worldState.get(
|
||||
Hex.decode( contractAddr) ));
|
||||
|
||||
System.out.println("*** Used gas: " + program.result.getGasUsed());
|
||||
System.out.println("*** Contract Balance: " + as.getBalance());
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -2544,7 +2544,7 @@ public class VMTest {
|
|||
Program program =
|
||||
new Program(Hex.decode("30"),
|
||||
createProgramInvoke_1());
|
||||
String s_expected_1 = "000000000000000000000000CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826";
|
||||
String s_expected_1 = "00000000000000000000000077045E71A7A2C50903D88E564CD72FAB11E82051";
|
||||
|
||||
vm.step(program);
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
# Root logger option
|
||||
log4j.rootLogger=DEBUG, stdout
|
||||
|
||||
# Direct log messages to stdout
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.Target=System.out
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern= %d{HH:mm:ss} [%c{1}] %m%n
|
||||
|
||||
# filter noisy classes
|
||||
log4j.logger.org.ethereum.net = FATAL
|
||||
log4j.logger.peerdiscovery = FATAL
|
||||
log4j.logger.java.nio = FATAL
|
||||
log4j.logger.io.netty = FATAL
|
||||
log4j.logger.org.ethereum.core = FATAL
|
||||
log4j.logger.wire = FATAL
|
||||
log4j.logger.VM = FATAL
|
||||
log4j.logger.main = FATAL
|
||||
log4j.logger.state = FATAL
|
||||
log4j.logger.blockchain = FATAL
|
||||
log4j.logger.ui = FATAL
|
||||
log4j.logger.gas = DEBUG
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
# if the system will work as a server also
|
||||
# accept for incoming connections [true/false]
|
||||
server.acceptConnections = false
|
||||
|
||||
# one default access point to start
|
||||
# discover the network e.g. ip: [54.201.28.117] port: [30303]
|
||||
# Peer Server Zero: peer discovery
|
||||
peer.discovery.ip = 54.201.28.117
|
||||
peer.discovery.port = 30303
|
||||
|
||||
# Peer Server One: peer discovery
|
||||
#peer.discovery.ip = 54.204.10.41
|
||||
#peer.discovery.port = 30303
|
||||
|
||||
# active peer ip and port
|
||||
# that is the peer through
|
||||
# we get the chain: [54.201.28.117] port: [30303]
|
||||
# ZeroGox
|
||||
#peer.active.ip = 54.204.10.41
|
||||
#peer.active.port = 30303
|
||||
|
||||
# Some dude in Canada
|
||||
#peer.active.ip = 131.104.247.135
|
||||
#peer.active.port = 30303
|
||||
|
||||
# Nick
|
||||
#peer.active.ip = 82.217.72.169
|
||||
#peer.active.port = 30303
|
||||
|
||||
|
||||
# RomanJ general
|
||||
peer.active.ip = 54.211.14.10
|
||||
peer.active.port = 50505
|
||||
|
||||
#poc5.testnet.ethereum.org
|
||||
#peer.active.ip = 54.72.69.180
|
||||
#peer.active.port = 30303
|
||||
|
||||
#peer.active.ip = 151.64.223.120
|
||||
#peer.active.port = 30304
|
||||
|
||||
# specify if the mechanism
|
||||
# to discover more and more
|
||||
# peers and check the already
|
||||
# discovered peers is on
|
||||
# if peer discovery is off
|
||||
# the peer window will show
|
||||
# only what retrieved by active
|
||||
# peer [true/false]
|
||||
peer.discovery = true
|
||||
|
||||
# number of workers that
|
||||
# tastes the peers for being
|
||||
# online [1..10]
|
||||
peer.discovery.workers = 15
|
||||
|
||||
# connection timeout for trying to
|
||||
# connect to a peer [seconds]
|
||||
peer.discovery.timeout = 2
|
||||
|
||||
# the time we wait to the network
|
||||
# to approve the transaction, the
|
||||
# transaction got approved when
|
||||
# include into a transactions msg
|
||||
# retrieved from the peer [seconds]
|
||||
transaction.approve.timeout = 15
|
||||
|
||||
# the parameter specifies how much
|
||||
# time the active peer will wait
|
||||
# for a message to come before kill
|
||||
# the channel
|
||||
active.peer.channel.timeout = 15
|
||||
|
||||
# default directory where we keep
|
||||
# basic Serpent samples relative
|
||||
# to home.dir
|
||||
samples.dir = samples
|
||||
|
||||
# everytime the application starts
|
||||
# the existing database will be
|
||||
# destroyed and all the data will be
|
||||
# downloaded from peers again
|
||||
database.reset = true
|
||||
|
||||
|
||||
# this string is computed
|
||||
# to be eventually the address
|
||||
# that get the miner reward
|
||||
coinbase.secret = "monkey"
|
Loading…
Reference in New Issue