VM trace extending with 'result' and 'error' fields.
This commit is contained in:
parent
e2f6eef1c9
commit
a0ad521fa1
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ public class EthereumListenerAdapter implements EthereumListener {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onVMTraceCreated(String transactionHash, String traceAsJson) {
|
||||
public void onVMTraceCreated(String transactionHash, String trace) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 "{}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue