VM integration go on:

+ ProgramInvoke addapted to work with env vars (no Block data yet)
+ ProgramPlayDialog, can play real code generated from the editor
+ Successfully got the production chain even that CALL doesn't work yet.
This commit is contained in:
romanman 2014-06-09 01:47:27 +01:00
parent c6dd4f31f9
commit 30459202c1
8 changed files with 127 additions and 75 deletions

View File

@ -97,7 +97,17 @@ class ContractSubmitDialog extends JDialog implements MessageAwareDialog {
@Override
public void mouseClicked(MouseEvent e) {
ProgramPlayDialog.createAndShowGUI();
Transaction tx = null;
try {
tx = createTransaction();
} catch (Exception e1) {
dialog.alertStatusMsg("Failed to sign the transaction");
return;
}
contractAddrInput.setText(Hex.toHexString(tx.getContractAddress()));
ProgramPlayDialog.createAndShowGUI(tx);
}}
);
@ -248,9 +258,32 @@ class ContractSubmitDialog extends JDialog implements MessageAwareDialog {
this.statusMsg.setText(text);
}
public void submitContract(){
Transaction tx = null;
try {
tx = createTransaction();
} catch (Exception e1) {
dialog.alertStatusMsg("Failed to sign the transaction");
return;
}
contractAddrInput.setText(Hex.toHexString(tx.getContractAddress()));
ClientPeer peer = MainData.instance.getActivePeer();
if (peer == null) {
dialog.alertStatusMsg("Not connected to any peer");
return;
}
// SwingWorker
DialogWorker worker = new DialogWorker(tx, this);
worker.execute();
}
private Transaction createTransaction(){
Account account = ((AccountWrapper)creatorAddressCombo.getSelectedItem()).getAccount();
byte[] senderPrivKey = account.getEcKey().getPrivKeyBytes();
@ -266,27 +299,9 @@ class ContractSubmitDialog extends JDialog implements MessageAwareDialog {
Transaction tx = new Transaction(nonce, gasPrice, gasValue,
zeroAddress, endowment, initByteCode);
try {
tx.sign(senderPrivKey);
} catch (Exception e1) {
dialog.alertStatusMsg("Failed to sign the transaction");
return;
}
contractAddrInput.setText(Hex.toHexString(tx.getContractAddress()));
ClientPeer peer = MainData.instance.getActivePeer();
if (peer == null) {
dialog.alertStatusMsg("Not connected to any peer");
return;
}
// SwingWorker
DialogWorker worker = new DialogWorker(tx, this);
worker.execute();
tx.sign(senderPrivKey);
return tx;
}
public static void main(String args[]) {

View File

@ -1,6 +1,8 @@
package org.ethereum.gui;
import org.ethereum.core.Transaction;
import org.ethereum.vm.Program;
import org.ethereum.vm.ProgramInvokeFactory;
import org.ethereum.vm.ProgramInvokeImpl;
import org.ethereum.vm.VM;
import org.spongycastle.util.encoders.Hex;
@ -27,20 +29,25 @@ public class ProgramPlayDialog extends JPanel implements ActionListener,
public JTextArea console;
public JSlider stepSlider;
public ProgramPlayDialog() {
private Transaction tx;
public ProgramPlayDialog(Transaction tx) {
this.tx = tx;
outputList = new ArrayList<String>();
VM vm = new VM();
// Program program = new Program(Hex.decode("630000000060445960CC60DD611234600054615566602054630000000060445960CC60DD611234600054615566602054630000000060445960CC60DD611234600054615566602054"));
// Program program = new Program(Hex.decode("60016023576000605f556014600054601e60205463abcddcba6040545b51602001600a5254516040016014525451606001601e5254516080016028525460a052546016604860003960166000f26000603f556103e75660005460005360200235602054"), null);
String code = "60016000546006601160003960066000f261778e600054";
// String code = "60016000546006601160003960066000f261778e600054";
// String code = "620f424073cd2a3d9f938e13cd947ec05abc7fe734df8dd826576086602660003960866000f26001602036040e0f630000002159600060200235600054600053565b525b54602052f263000000765833602054602053566040546000602002356060546001602002356080546080536040530a0f0f630000006c59608053604053036020535760805360605356016060535760015b525b54602052f263000000765860005b525b54602052f2";
byte[] codeBytes =
Hex.decode(code);
Program program = new Program(codeBytes ,
new ProgramInvokeImpl(codeBytes));
// byte[] codeBytes =
// Hex.decode(code);
Program program = new Program(tx.getData() ,
ProgramInvokeFactory.createProgramInvoke(tx));
program.addListener(this);
program.fullTrace();
@ -121,9 +128,9 @@ public class ProgramPlayDialog extends JPanel implements ActionListener,
* this method should be invoked from the
* event-dispatching thread.
*/
public static void createAndShowGUI() {
public static void createAndShowGUI(Transaction tx) {
ProgramPlayDialog ppd = new ProgramPlayDialog();
ProgramPlayDialog ppd = new ProgramPlayDialog(tx);
//Create and set up the window.
JFrame frame = new JFrame("Program Draft Play");
@ -159,11 +166,14 @@ public class ProgramPlayDialog extends JPanel implements ActionListener,
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
/* todo: make dummy tx for dialog single invokation
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
*/
}
}

View File

@ -6,9 +6,7 @@ import org.ethereum.core.Transaction;
import org.ethereum.crypto.HashUtil;
import org.ethereum.db.Database;
import org.ethereum.trie.Trie;
import org.ethereum.vm.Program;
import org.ethereum.vm.ProgramResult;
import org.ethereum.vm.VM;
import org.ethereum.vm.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spongycastle.util.encoders.Hex;
@ -107,23 +105,34 @@ public class WorldManager {
byte[] initCode = tx.getData();
ProgramInvoke programInvoke =
ProgramInvokeFactory.createProgramInvoke(tx);
VM vm = new VM();
Program program = new Program(initCode, null);
Program program = new Program(initCode, programInvoke);
vm.play(program);
ProgramResult result = program.getResult();
byte[] bodyCode = result.gethReturn().array();
byte[] bodyCode = null;
if (result.gethReturn() != null){
result.gethReturn().array();
}
// TODO: what if the body code is null , still submit ?
// TODO: (!!!!!) ALL THE CHECKS FOR THE PROGRAM RESULT
byte[] key = HashUtil.sha3(bodyCode);
chainDB.put(key, bodyCode);
if (bodyCode != null){
byte[] key = HashUtil.sha3(bodyCode);
chainDB.put(key, bodyCode);
if (stateLogger.isInfoEnabled())
stateLogger.info("saving code of the contract to the db: sha3(code)={} code={}",
Hex.toHexString(key),
Hex.toHexString(bodyCode));
}
if (stateLogger.isInfoEnabled())
stateLogger.info("saving code of the contract to the db: sha3(code)={} code={}",
Hex.toHexString(key),
Hex.toHexString(bodyCode));
} else {
// TODO: 2. check if the address is a contract, if it is perform contract call
}

View File

@ -32,8 +32,14 @@ public class DataWord {
}
public DataWord(byte[] data) {
if (data == null || data.length > 32)
throw new RuntimeException("bad push data: " + data);
if (data == null){
this.data = new byte[]{};
return;
}
if (data.length > 32)
throw new RuntimeException("Data word can't exit 32 bytes: " + data);
System.arraycopy(data, 0, this.data, 32 - data.length, data.length);
}

View File

@ -12,6 +12,14 @@ import org.spongycastle.util.encoders.Hex;
public class ProgramInvokeImpl implements ProgramInvoke {
DataWord address;
DataWord origin;
DataWord caller;
DataWord balance;
DataWord gas;
DataWord gasPrice;
DataWord callValue;
byte[] msgData;
@ -19,56 +27,50 @@ public class ProgramInvokeImpl implements ProgramInvoke {
this.msgData = msgDataRaw;
}
public ProgramInvokeImpl() {
public ProgramInvokeImpl(byte[] address, byte[] origin, byte[] caller, byte[] balance,
byte[] gasPrice, byte[] gas, byte[] callValue, byte[] msgData) {
this.address = new DataWord(address);
this.origin = new DataWord(origin);
this.caller = new DataWord(caller);
this.balance = new DataWord(balance);
this.gasPrice = new DataWord(gasPrice);
this.gas = new DataWord(gas);
this.callValue = new DataWord(callValue);
this.msgData = msgData;
}
/* ADDRESS op */
public DataWord getOwnerAddress(){
byte[] cowPrivKey = HashUtil.sha3("cow".getBytes());
byte[] addr = ECKey.fromPrivate(cowPrivKey).getAddress();
return new DataWord(addr);
return address;
}
/* BALANCE op */
public DataWord getBalance(){
byte[] balance = Hex.decode("0DE0B6B3A7640000");
return new DataWord(balance);
return balance;
}
/* ORIGIN op */
public DataWord getOriginAddress(){
byte[] cowPrivKey = HashUtil.sha3("horse".getBytes());
byte[] addr = ECKey.fromPrivate(cowPrivKey).getAddress();
return new DataWord(addr);
return origin;
}
/* CALLER op */
public DataWord getCallerAddress(){
byte[] cowPrivKey = HashUtil.sha3("monkey".getBytes());
byte[] addr = ECKey.fromPrivate(cowPrivKey).getAddress();
return new DataWord(addr);
return caller;
}
/* GASPRICE op */
public DataWord getMinGasPrice(){
byte[] minGasPrice = Hex.decode("09184e72a000");
return new DataWord(minGasPrice);
return gasPrice;
}
/* CALLVALUE op */
public DataWord getCallValue(){
byte[] balance = Hex.decode("0DE0B6B3A7640000");
return new DataWord(balance);
return callValue;
}

View File

@ -371,6 +371,9 @@ public class VM {
program.step();
} break;
case GASPRICE:
program.step();
break;
/**
@ -378,16 +381,22 @@ public class VM {
*/
case PREVHASH:
program.step();
break;
case COINBASE:
program.step();
break;
case TIMESTAMP:
program.step();
break;
case NUMBER:
program.step();
break;
case DIFFICULTY:
program.step();
break;
case GASLIMIT:
program.step();
break;
case POP:{
program.stackPop();
@ -477,6 +486,7 @@ public class VM {
program.step();
} break;
case GAS:
program.step();
break;
case PUSH1: case PUSH2: case PUSH3: case PUSH4: case PUSH5: case PUSH6: case PUSH7: case PUSH8:

View File

@ -13,8 +13,8 @@ log4j.logger.org.ethereum.net.peerdiscovery = WARN
log4j.logger.java.nio = WARN
log4j.logger.io.netty = FATAL
log4j.logger.org.ethereum.core = FATAL
log4j.logger.wire = FATAL
log4j.logger.wire = INFO
log4j.logger.VM = DEBUG
log4j.logger.main = FATAL
log4j.logger.state = FATAL
log4j.logger.blockchain = FATAL
log4j.logger.main = DEBUG
log4j.logger.state = DEBUG
log4j.logger.blockchain = INFO

View File

@ -16,8 +16,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 +29,8 @@ peer.discovery.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 = 50505
#peer.active.ip = 151.64.223.120
#peer.active.port = 30304