VM trace extending with 'result' and 'error' fields.

This commit is contained in:
eugene-shevchenko 2015-04-09 11:48:57 +03:00
parent e2f6eef1c9
commit a0ad521fa1
5 changed files with 52 additions and 8 deletions

View File

@ -13,6 +13,7 @@ import org.ethereum.vm.ProgramInvokeFactory;
import org.ethereum.vm.ProgramResult;
import org.ethereum.vm.VM;
import org.ethereum.vmtrace.ProgramTrace;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -200,9 +201,10 @@ public class TransactionExecutor {
if (isContractCreation || code != EMPTY_BYTE_ARRAY) {
// START TRACKING FOR REVERT CHANGES OPTION
Program program = null;
Repository trackTx = track.startTracking();
trackTx.addBalance(receiverAddress, BigInteger.ZERO); // the contract created for anycase but SUICIDE call
logger.info("Start tracking VM run");
try {
@ -217,12 +219,11 @@ public class TransactionExecutor {
programInvokeFactory.createProgramInvoke(tx, currentBlock, trackTx, blockStore);
VM vm = new VM();
Program program = new Program(code, programInvoke);
program = new Program(code, programInvoke);
if (CONFIG.playVM())
vm.play(program);
listener.onVMTraceCreated(txHash, program.getProgramTrace().getJsonString());
program.saveProgramTraceToFile(txHash);
result = program.getResult();
@ -238,6 +239,15 @@ public class TransactionExecutor {
receipt.setCumulativeGas(tx.getGasLimit());
this.receipt = receipt;
return;
} finally {
String traceAsJson = "{}";
if (program != null) {
ProgramTrace trace = program.getProgramTrace();
trace.setResult(result.getHReturn());
trace.setError(result.getException());
traceAsJson = trace.getJsonString();
}
listener.onVMTraceCreated(txHash, traceAsJson);
}
trackTx.commit();
} else {

View File

@ -84,9 +84,9 @@ public class CompositeEthereumListener implements EthereumListener {
}
@Override
public void onVMTraceCreated(String transactionHash, String traceAsJson) {
public void onVMTraceCreated(String transactionHash, String trace) {
for (EthereumListener listener : listeners) {
listener.onVMTraceCreated(transactionHash, traceAsJson);
listener.onVMTraceCreated(transactionHash, trace);
}
}

View File

@ -6,6 +6,7 @@ import org.ethereum.core.TransactionReceipt;
import org.ethereum.net.message.Message;
import org.ethereum.net.p2p.HelloMessage;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Set;
@ -35,5 +36,5 @@ public interface EthereumListener {
void onHandShakePeer(HelloMessage helloMessage);
void onVMTraceCreated(String transactionHash, String traceAsJson);
void onVMTraceCreated(String transactionHash, String trace);
}

View File

@ -60,7 +60,7 @@ public class EthereumListenerAdapter implements EthereumListener {
}
@Override
public void onVMTraceCreated(String transactionHash, String traceAsJson) {
public void onVMTraceCreated(String transactionHash, String trace) {
}
}

View File

@ -1,9 +1,22 @@
package org.ethereum.vmtrace;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spongycastle.util.encoders.Hex;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import static java.lang.String.format;
/**
* @author Roman Mandeleil
@ -11,13 +24,26 @@ import java.util.List;
*/
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;
public void setTxHash(byte[] txHash) {
this.txHash = txHash;
}
public void setResult(ByteBuffer result) {
this.result = Hex.toHexString(result.array());
}
public void setError(Exception error) {
this.error = (error == null) ? "" : format("%s: %s", error.getClass(), error.getMessage());;
}
public void addOp(Op op) {
ops.add(op);
}
@ -31,6 +57,13 @@ public class ProgramTrace {
}
public String getJsonString() {
return JSONArray.toJSONString(ops);
try {
return new ObjectMapper()
.enable(SerializationFeature.INDENT_OUTPUT)
.writeValueAsString(this);
} catch (JsonProcessingException e) {
LOGGER.error("JSON serialization error: ", e);
return "{}";
}
}
}