Skip to content

Commit 7705d13

Browse files
jwasingermask-pps1na
authored
eth/tracers: fix standardTraceBlockToFile (#31763)
Fixes methods debug_standardTraceBlockToFile and debug_standardTraceBadBlockToFile which were outputting empty files. --------- Co-authored-by: maskpp <[email protected]> Co-authored-by: Sina Mahmoodi <[email protected]>
1 parent b135da2 commit 7705d13

File tree

2 files changed

+150
-30
lines changed

2 files changed

+150
-30
lines changed

eth/tracers/api.go

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,7 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block
778778
// Note: This copies the config, to not screw up the main config
779779
chainConfig, canon = overrideConfig(chainConfig, config.Overrides)
780780
}
781+
781782
evm := vm.NewEVM(vmctx, statedb, chainConfig, vm.Config{})
782783
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
783784
core.ProcessBeaconBlockRoot(*beaconRoot, evm)
@@ -787,42 +788,45 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block
787788
}
788789
for i, tx := range block.Transactions() {
789790
// Prepare the transaction for un-traced execution
790-
var (
791-
msg, _ = core.TransactionToMessage(tx, signer, block.BaseFee())
792-
vmConf vm.Config
793-
dump *os.File
794-
writer *bufio.Writer
795-
err error
796-
)
797-
// If the transaction needs tracing, swap out the configs
798-
if tx.Hash() == txHash || txHash == (common.Hash{}) {
799-
// Generate a unique temporary file to dump it into
800-
prefix := fmt.Sprintf("block_%#x-%d-%#x-", block.Hash().Bytes()[:4], i, tx.Hash().Bytes()[:4])
801-
if !canon {
802-
prefix = fmt.Sprintf("%valt-", prefix)
803-
}
804-
dump, err = os.CreateTemp(os.TempDir(), prefix)
791+
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
792+
if txHash != (common.Hash{}) && tx.Hash() != txHash {
793+
// Process the tx to update state, but don't trace it.
794+
_, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(msg.GasLimit))
805795
if err != nil {
806-
return nil, err
807-
}
808-
dumps = append(dumps, dump.Name())
809-
810-
// Swap out the noop logger to the standard tracer
811-
writer = bufio.NewWriter(dump)
812-
vmConf = vm.Config{
813-
Tracer: logger.NewJSONLogger(&logConfig, writer),
814-
EnablePreimageRecording: true,
796+
return dumps, err
815797
}
798+
// Finalize the state so any modifications are written to the trie
799+
// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
800+
statedb.Finalise(evm.ChainConfig().IsEIP158(block.Number()))
801+
continue
816802
}
803+
// The transaction should be traced.
804+
// Generate a unique temporary file to dump it into.
805+
prefix := fmt.Sprintf("block_%#x-%d-%#x-", block.Hash().Bytes()[:4], i, tx.Hash().Bytes()[:4])
806+
if !canon {
807+
prefix = fmt.Sprintf("%valt-", prefix)
808+
}
809+
var dump *os.File
810+
dump, err := os.CreateTemp(os.TempDir(), prefix)
811+
if err != nil {
812+
return nil, err
813+
}
814+
dumps = append(dumps, dump.Name())
815+
// Set up the tracer and EVM for the transaction.
816+
var (
817+
writer = bufio.NewWriter(dump)
818+
tracer = logger.NewJSONLogger(&logConfig, writer)
819+
evm = vm.NewEVM(vmctx, statedb, chainConfig, vm.Config{
820+
Tracer: tracer,
821+
NoBaseFee: true,
822+
})
823+
)
817824
// Execute the transaction and flush any traces to disk
818825
statedb.SetTxContext(tx.Hash(), i)
819-
if vmConf.Tracer.OnTxStart != nil {
820-
vmConf.Tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
821-
}
822-
vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(msg.GasLimit))
823-
if vmConf.Tracer.OnTxEnd != nil {
824-
vmConf.Tracer.OnTxEnd(&types.Receipt{GasUsed: vmRet.UsedGas}, err)
826+
if tracer.OnTxStart != nil {
827+
tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
825828
}
829+
_, err = core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(msg.GasLimit))
826830
if writer != nil {
827831
writer.Flush()
828832
}

eth/tracers/api_test.go

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"errors"
2424
"fmt"
2525
"math/big"
26+
"os"
2627
"reflect"
2728
"slices"
2829
"sync/atomic"
@@ -1218,3 +1219,118 @@ func TestTraceBlockWithBasefee(t *testing.T) {
12181219
}
12191220
}
12201221
}
1222+
1223+
func TestStandardTraceBlockToFile(t *testing.T) {
1224+
var (
1225+
// A sender who makes transactions, has some funds
1226+
key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
1227+
address = crypto.PubkeyToAddress(key.PublicKey)
1228+
funds = big.NewInt(1000000000000000)
1229+
1230+
// first contract the sender transacts with
1231+
aa = common.HexToAddress("0x7217d81b76bdd8707601e959454e3d776aee5f43")
1232+
aaCode = []byte{byte(vm.PUSH1), 0x00, byte(vm.POP)}
1233+
1234+
// second contract the sender transacts with
1235+
bb = common.HexToAddress("0x7217d81b76bdd8707601e959454e3d776aee5f44")
1236+
bbCode = []byte{byte(vm.PUSH2), 0x00, 0x01, byte(vm.POP)}
1237+
)
1238+
1239+
genesis := &core.Genesis{
1240+
Config: params.TestChainConfig,
1241+
Alloc: types.GenesisAlloc{
1242+
address: {Balance: funds},
1243+
aa: {
1244+
Code: aaCode,
1245+
Nonce: 1,
1246+
Balance: big.NewInt(0),
1247+
},
1248+
bb: {
1249+
Code: bbCode,
1250+
Nonce: 1,
1251+
Balance: big.NewInt(0),
1252+
},
1253+
},
1254+
}
1255+
txHashs := make([]common.Hash, 0, 2)
1256+
backend := newTestBackend(t, 1, genesis, func(i int, b *core.BlockGen) {
1257+
b.SetCoinbase(common.Address{1})
1258+
// first tx to aa
1259+
tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{
1260+
Nonce: 0,
1261+
To: &aa,
1262+
Value: big.NewInt(0),
1263+
Gas: 50000,
1264+
GasPrice: b.BaseFee(),
1265+
Data: nil,
1266+
}), types.HomesteadSigner{}, key)
1267+
b.AddTx(tx)
1268+
txHashs = append(txHashs, tx.Hash())
1269+
// second tx to bb
1270+
tx, _ = types.SignTx(types.NewTx(&types.LegacyTx{
1271+
Nonce: 1,
1272+
To: &bb,
1273+
Value: big.NewInt(1),
1274+
Gas: 100000,
1275+
GasPrice: b.BaseFee(),
1276+
Data: nil,
1277+
}), types.HomesteadSigner{}, key)
1278+
b.AddTx(tx)
1279+
txHashs = append(txHashs, tx.Hash())
1280+
})
1281+
defer backend.chain.Stop()
1282+
1283+
var testSuite = []struct {
1284+
blockNumber rpc.BlockNumber
1285+
config *StdTraceConfig
1286+
want []string
1287+
}{
1288+
{
1289+
// test that all traces in the block were outputted if no trace config is specified
1290+
blockNumber: rpc.LatestBlockNumber,
1291+
config: nil,
1292+
want: []string{
1293+
`{"pc":0,"op":96,"gas":"0x7148","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"}
1294+
{"pc":2,"op":80,"gas":"0x7145","gasCost":"0x2","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"POP"}
1295+
{"pc":3,"op":0,"gas":"0x7143","gasCost":"0x0","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"STOP"}
1296+
{"output":"","gasUsed":"0x5"}
1297+
`,
1298+
`{"pc":0,"op":97,"gas":"0x13498","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH2"}
1299+
{"pc":3,"op":80,"gas":"0x13495","gasCost":"0x2","memSize":0,"stack":["0x1"],"depth":1,"refund":0,"opName":"POP"}
1300+
{"pc":4,"op":0,"gas":"0x13493","gasCost":"0x0","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"STOP"}
1301+
{"output":"","gasUsed":"0x5"}
1302+
`,
1303+
},
1304+
},
1305+
{
1306+
// test that only a specific tx is traced if specified
1307+
blockNumber: rpc.LatestBlockNumber,
1308+
config: &StdTraceConfig{TxHash: txHashs[1]},
1309+
want: []string{
1310+
`{"pc":0,"op":97,"gas":"0x13498","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH2"}
1311+
{"pc":3,"op":80,"gas":"0x13495","gasCost":"0x2","memSize":0,"stack":["0x1"],"depth":1,"refund":0,"opName":"POP"}
1312+
{"pc":4,"op":0,"gas":"0x13493","gasCost":"0x0","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"STOP"}
1313+
{"output":"","gasUsed":"0x5"}
1314+
`,
1315+
},
1316+
},
1317+
}
1318+
1319+
api := NewAPI(backend)
1320+
for i, tc := range testSuite {
1321+
block, _ := api.blockByNumber(context.Background(), tc.blockNumber)
1322+
txTraces, err := api.StandardTraceBlockToFile(context.Background(), block.Hash(), tc.config)
1323+
if err != nil {
1324+
t.Fatalf("test index %d received error %v", i, err)
1325+
}
1326+
for j, traceFileName := range txTraces {
1327+
traceReceived, err := os.ReadFile(traceFileName)
1328+
if err != nil {
1329+
t.Fatalf("could not read trace file: %v", err)
1330+
}
1331+
if tc.want[j] != string(traceReceived) {
1332+
t.Fatalf("unexpected trace result. expected\n'%s'\n\nreceived\n'%s'\n", tc.want[j], string(traceReceived))
1333+
}
1334+
}
1335+
}
1336+
}

0 commit comments

Comments
 (0)