mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 14:46:42 +00:00
internal/ethapi: fix tx.from in eth_simulateV1
This commit is contained in:
parent
8e3b94da1e
commit
ae0e825d11
1 changed files with 28 additions and 9 deletions
|
|
@ -79,11 +79,25 @@ type simBlockResult struct {
|
||||||
chainConfig *params.ChainConfig
|
chainConfig *params.ChainConfig
|
||||||
Block *types.Block
|
Block *types.Block
|
||||||
Calls []simCallResult
|
Calls []simCallResult
|
||||||
|
// senders is a map of transaction hashes to their senders.
|
||||||
|
senders map[common.Hash]common.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *simBlockResult) MarshalJSON() ([]byte, error) {
|
func (r *simBlockResult) MarshalJSON() ([]byte, error) {
|
||||||
blockData := RPCMarshalBlock(r.Block, true, r.fullTx, r.chainConfig)
|
blockData := RPCMarshalBlock(r.Block, true, r.fullTx, r.chainConfig)
|
||||||
blockData["calls"] = r.Calls
|
blockData["calls"] = r.Calls
|
||||||
|
// Set tx sender if user requested full tx objects.
|
||||||
|
if r.fullTx {
|
||||||
|
if raw, ok := blockData["transactions"].([]any); ok {
|
||||||
|
for _, tx := range raw {
|
||||||
|
if tx, ok := tx.(*RPCTransaction); ok {
|
||||||
|
tx.From = r.senders[tx.Hash]
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("simulated transaction result has invalid type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return json.Marshal(blockData)
|
return json.Marshal(blockData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -141,18 +155,18 @@ func (sim *simulator) execute(ctx context.Context, blocks []simBlock) ([]*simBlo
|
||||||
parent = sim.base
|
parent = sim.base
|
||||||
)
|
)
|
||||||
for bi, block := range blocks {
|
for bi, block := range blocks {
|
||||||
result, callResults, err := sim.processBlock(ctx, &block, headers[bi], parent, headers[:bi], timeout)
|
result, callResults, senders, err := sim.processBlock(ctx, &block, headers[bi], parent, headers[:bi], timeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
headers[bi] = result.Header()
|
headers[bi] = result.Header()
|
||||||
results[bi] = &simBlockResult{fullTx: sim.fullTx, chainConfig: sim.chainConfig, Block: result, Calls: callResults}
|
results[bi] = &simBlockResult{fullTx: sim.fullTx, chainConfig: sim.chainConfig, Block: result, Calls: callResults, senders: senders}
|
||||||
parent = result.Header()
|
parent = result.Header()
|
||||||
}
|
}
|
||||||
return results, nil
|
return results, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, parent *types.Header, headers []*types.Header, timeout time.Duration) (*types.Block, []simCallResult, error) {
|
func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, parent *types.Header, headers []*types.Header, timeout time.Duration) (*types.Block, []simCallResult, map[common.Hash]common.Address, error) {
|
||||||
// Set header fields that depend only on parent block.
|
// Set header fields that depend only on parent block.
|
||||||
// Parent hash is needed for evm.GetHashFn to work.
|
// Parent hash is needed for evm.GetHashFn to work.
|
||||||
header.ParentHash = parent.Hash()
|
header.ParentHash = parent.Hash()
|
||||||
|
|
@ -182,7 +196,7 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header,
|
||||||
precompiles := sim.activePrecompiles(sim.base)
|
precompiles := sim.activePrecompiles(sim.base)
|
||||||
// State overrides are applied prior to execution of a block
|
// State overrides are applied prior to execution of a block
|
||||||
if err := block.StateOverrides.Apply(sim.state, precompiles); err != nil {
|
if err := block.StateOverrides.Apply(sim.state, precompiles); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
gasUsed, blobGasUsed uint64
|
gasUsed, blobGasUsed uint64
|
||||||
|
|
@ -195,6 +209,10 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header,
|
||||||
NoBaseFee: !sim.validate,
|
NoBaseFee: !sim.validate,
|
||||||
Tracer: tracer.Hooks(),
|
Tracer: tracer.Hooks(),
|
||||||
}
|
}
|
||||||
|
// senders is a map of transaction hashes to their senders.
|
||||||
|
// Transaction objects contain only the signature, and we lose track
|
||||||
|
// of the sender when translating the arguments into a transaction object.
|
||||||
|
senders = make(map[common.Hash]common.Address)
|
||||||
)
|
)
|
||||||
tracingStateDB := vm.StateDB(sim.state)
|
tracingStateDB := vm.StateDB(sim.state)
|
||||||
if hooks := tracer.Hooks(); hooks != nil {
|
if hooks := tracer.Hooks(); hooks != nil {
|
||||||
|
|
@ -212,16 +230,17 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header,
|
||||||
var allLogs []*types.Log
|
var allLogs []*types.Log
|
||||||
for i, call := range block.Calls {
|
for i, call := range block.Calls {
|
||||||
if err := ctx.Err(); err != nil {
|
if err := ctx.Err(); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
if err := sim.sanitizeCall(&call, sim.state, header, blockContext, &gasUsed); err != nil {
|
if err := sim.sanitizeCall(&call, sim.state, header, blockContext, &gasUsed); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
tx = call.ToTransaction(types.DynamicFeeTxType)
|
tx = call.ToTransaction(types.DynamicFeeTxType)
|
||||||
txHash = tx.Hash()
|
txHash = tx.Hash()
|
||||||
)
|
)
|
||||||
txes[i] = tx
|
txes[i] = tx
|
||||||
|
senders[txHash] = call.from()
|
||||||
tracer.reset(txHash, uint(i))
|
tracer.reset(txHash, uint(i))
|
||||||
sim.state.SetTxContext(txHash, i)
|
sim.state.SetTxContext(txHash, i)
|
||||||
// EoA check is always skipped, even in validation mode.
|
// EoA check is always skipped, even in validation mode.
|
||||||
|
|
@ -229,7 +248,7 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header,
|
||||||
result, err := applyMessageWithEVM(ctx, evm, msg, timeout, sim.gp)
|
result, err := applyMessageWithEVM(ctx, evm, msg, timeout, sim.gp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
txErr := txValidationError(err)
|
txErr := txValidationError(err)
|
||||||
return nil, nil, txErr
|
return nil, nil, nil, txErr
|
||||||
}
|
}
|
||||||
// Update the state with pending changes.
|
// Update the state with pending changes.
|
||||||
var root []byte
|
var root []byte
|
||||||
|
|
@ -264,7 +283,7 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header,
|
||||||
requests = [][]byte{}
|
requests = [][]byte{}
|
||||||
// EIP-6110
|
// EIP-6110
|
||||||
if err := core.ParseDepositLogs(&requests, allLogs, sim.chainConfig); err != nil {
|
if err := core.ParseDepositLogs(&requests, allLogs, sim.chainConfig); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
// EIP-7002
|
// EIP-7002
|
||||||
core.ProcessWithdrawalQueue(&requests, evm)
|
core.ProcessWithdrawalQueue(&requests, evm)
|
||||||
|
|
@ -286,7 +305,7 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header,
|
||||||
}
|
}
|
||||||
b := types.NewBlock(header, &types.Body{Transactions: txes, Withdrawals: withdrawals}, receipts, trie.NewStackTrie(nil))
|
b := types.NewBlock(header, &types.Body{Transactions: txes, Withdrawals: withdrawals}, receipts, trie.NewStackTrie(nil))
|
||||||
repairLogs(callResults, b.Hash())
|
repairLogs(callResults, b.Hash())
|
||||||
return b, callResults, nil
|
return b, callResults, senders, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// repairLogs updates the block hash in the logs present in the result of
|
// repairLogs updates the block hash in the logs present in the result of
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue