package tracetest import ( "encoding/json" "reflect" "strings" "unicode" // Force-load native and js packages, to trigger registration _ "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, "") }