2022-10-05 19:05:43 -05:00
|
|
|
package tracetest
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"reflect"
|
|
|
|
"strings"
|
|
|
|
"unicode"
|
|
|
|
|
2022-10-11 02:37:00 -05:00
|
|
|
// Force-load native and js packages, to trigger registration
|
2022-10-05 19:05:43 -05:00
|
|
|
_ "github.com/ethereum/go-ethereum/eth/tracers/js"
|
|
|
|
_ "github.com/ethereum/go-ethereum/eth/tracers/native"
|
|
|
|
)
|
|
|
|
|
|
|
|
// To generate a new callTracer test, copy paste the makeTest method below into
|
|
|
|
// a Geth console and call it with a transaction hash you which to export.
|
|
|
|
|
|
|
|
/*
|
|
|
|
// makeTest generates a callTracer test by running a prestate reassembled and a
|
|
|
|
// call trace run, assembling all the gathered information into a test case.
|
|
|
|
var makeTest = function(tx, rewind) {
|
|
|
|
// Generate the genesis block from the block, transaction and prestate data
|
|
|
|
var block = eth.getBlock(eth.getTransaction(tx).blockHash);
|
|
|
|
var genesis = eth.getBlock(block.parentHash);
|
|
|
|
|
|
|
|
delete genesis.gasUsed;
|
|
|
|
delete genesis.logsBloom;
|
|
|
|
delete genesis.parentHash;
|
|
|
|
delete genesis.receiptsRoot;
|
|
|
|
delete genesis.sha3Uncles;
|
|
|
|
delete genesis.size;
|
|
|
|
delete genesis.transactions;
|
|
|
|
delete genesis.transactionsRoot;
|
|
|
|
delete genesis.uncles;
|
|
|
|
|
|
|
|
genesis.gasLimit = genesis.gasLimit.toString();
|
|
|
|
genesis.number = genesis.number.toString();
|
|
|
|
genesis.timestamp = genesis.timestamp.toString();
|
|
|
|
|
|
|
|
genesis.alloc = debug.traceTransaction(tx, {tracer: "prestateTracer", rewind: rewind});
|
|
|
|
for (var key in genesis.alloc) {
|
|
|
|
var nonce = genesis.alloc[key].nonce;
|
|
|
|
if (nonce) {
|
|
|
|
genesis.alloc[key].nonce = nonce.toString();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
genesis.config = admin.nodeInfo.protocols.eth.config;
|
|
|
|
|
|
|
|
// Generate the call trace and produce the test input
|
|
|
|
var result = debug.traceTransaction(tx, {tracer: "callTracer", rewind: rewind});
|
|
|
|
delete result.time;
|
|
|
|
|
|
|
|
console.log(JSON.stringify({
|
|
|
|
genesis: genesis,
|
|
|
|
context: {
|
|
|
|
number: block.number.toString(),
|
|
|
|
difficulty: block.difficulty,
|
|
|
|
timestamp: block.timestamp.toString(),
|
|
|
|
gasLimit: block.gasLimit.toString(),
|
|
|
|
miner: block.miner,
|
|
|
|
},
|
|
|
|
input: eth.getRawTransaction(tx),
|
|
|
|
result: result,
|
|
|
|
}, null, 2));
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
// jsonEqual is similar to reflect.DeepEqual, but does a 'bounce' via json prior to
|
|
|
|
// comparison
|
|
|
|
func jsonEqual(xi, yi, xt, yt interface{}) bool {
|
|
|
|
if xj, err := json.Marshal(xi); err == nil {
|
|
|
|
json.Unmarshal(xj, xt)
|
|
|
|
} else {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if yj, err := json.Marshal(yi); err == nil {
|
|
|
|
json.Unmarshal(yj, yt)
|
|
|
|
} else {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return reflect.DeepEqual(xt, yt)
|
|
|
|
}
|
|
|
|
|
|
|
|
// camel converts a snake cased input string into a camel cased output.
|
|
|
|
func camel(str string) string {
|
|
|
|
pieces := strings.Split(str, "_")
|
|
|
|
for i := 1; i < len(pieces); i++ {
|
|
|
|
pieces[i] = string(unicode.ToUpper(rune(pieces[i][0]))) + pieces[i][1:]
|
|
|
|
}
|
|
|
|
return strings.Join(pieces, "")
|
|
|
|
}
|