mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 23:26:44 +00:00
refactor: eliminate double re-execution in AsyncChecker (#1036)
This commit is contained in:
parent
6cdcff6275
commit
7f79c7f21f
2 changed files with 5 additions and 32 deletions
|
|
@ -24,7 +24,7 @@ import (
|
||||||
const (
|
const (
|
||||||
VersionMajor = 5 // Major version component of the current release
|
VersionMajor = 5 // Major version component of the current release
|
||||||
VersionMinor = 7 // Minor version component of the current release
|
VersionMinor = 7 // Minor version component of the current release
|
||||||
VersionPatch = 13 // Patch version component of the current release
|
VersionPatch = 14 // Patch version component of the current release
|
||||||
VersionMeta = "mainnet" // Version metadata to append to the version string
|
VersionMeta = "mainnet" // Version metadata to append to the version string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -173,8 +173,6 @@ func (c *AsyncChecker) checkerTask(block *types.Block, ccc *Checker, forkCtx con
|
||||||
}
|
}
|
||||||
|
|
||||||
header := block.Header()
|
header := block.Header()
|
||||||
header.GasUsed = 0
|
|
||||||
gasPool := new(core.GasPool).AddGas(header.GasLimit)
|
|
||||||
ccc.Reset()
|
ccc.Reset()
|
||||||
|
|
||||||
accRc := new(types.RowConsumption)
|
accRc := new(types.RowConsumption)
|
||||||
|
|
@ -184,7 +182,7 @@ func (c *AsyncChecker) checkerTask(block *types.Block, ccc *Checker, forkCtx con
|
||||||
}
|
}
|
||||||
|
|
||||||
var curRc *types.RowConsumption
|
var curRc *types.RowConsumption
|
||||||
curRc, err = c.checkTxAndApply(parent, header, statedb, gasPool, tx, ccc)
|
curRc, err = c.checkTx(parent, header, statedb, tx, ccc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = &ErrorWithTxnIdx{
|
err = &ErrorWithTxnIdx{
|
||||||
TxIdx: uint(txIdx),
|
TxIdx: uint(txIdx),
|
||||||
|
|
@ -208,39 +206,14 @@ func (c *AsyncChecker) checkerTask(block *types.Block, ccc *Checker, forkCtx con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *AsyncChecker) checkTxAndApply(parent *types.Block, header *types.Header, state *state.StateDB, gasPool *core.GasPool, tx *types.Transaction, ccc *Checker) (*types.RowConsumption, error) {
|
func (c *AsyncChecker) checkTx(parent *types.Block, header *types.Header, state *state.StateDB, tx *types.Transaction, ccc *Checker) (*types.RowConsumption, error) {
|
||||||
// don't commit the state during tracing for circuit capacity checker, otherwise we cannot revert.
|
|
||||||
// and even if we don't commit the state, the `refund` value will still be correct, as explained in `CommitTransaction`
|
|
||||||
commitStateAfterApply := false
|
|
||||||
snap := state.Snapshot()
|
|
||||||
|
|
||||||
// 1. we have to check circuit capacity before `core.ApplyTransaction`,
|
|
||||||
// because if the tx can be successfully executed but circuit capacity overflows, it will be inconvenient to revert.
|
|
||||||
// 2. even if we don't commit to the state during the tracing (which means `clearJournalAndRefund` is not called during the tracing),
|
|
||||||
// the `refund` value will still be correct, because:
|
|
||||||
// 2.1 when starting handling the first tx, `state.refund` is 0 by default,
|
|
||||||
// 2.2 after tracing, the state is either committed in `core.ApplyTransaction`, or reverted, so the `state.refund` can be cleared,
|
|
||||||
// 2.3 when starting handling the following txs, `state.refund` comes as 0
|
|
||||||
trace, err := tracing.NewTracerWrapper().CreateTraceEnvAndGetBlockTrace(c.bc.Config(), c.bc, c.bc.Engine(), c.bc.Database(),
|
trace, err := tracing.NewTracerWrapper().CreateTraceEnvAndGetBlockTrace(c.bc.Config(), c.bc, c.bc.Engine(), c.bc.Database(),
|
||||||
state, parent, types.NewBlockWithHeader(header).WithBody([]*types.Transaction{tx}, nil), commitStateAfterApply)
|
state, parent, types.NewBlockWithHeader(header).WithBody([]*types.Transaction{tx}, nil), true)
|
||||||
// `w.current.traceEnv.State` & `w.current.state` share a same pointer to the state, so only need to revert `w.current.state`
|
|
||||||
// revert to snapshot for calling `core.ApplyMessage` again, (both `traceEnv.GetBlockTrace` & `core.ApplyTransaction` will call `core.ApplyMessage`)
|
|
||||||
state.RevertToSnapshot(snap)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
rc, err := ccc.ApplyTransaction(trace)
|
return ccc.ApplyTransaction(trace)
|
||||||
if err != nil {
|
|
||||||
return rc, err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = core.ApplyTransaction(c.bc.Config(), c.bc, nil /* coinbase will default to chainConfig.Scroll.FeeVaultAddress */, gasPool,
|
|
||||||
state, header, tx, &header.GasUsed, *c.bc.GetVMConfig())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return rc, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ScheduleError forces a block to error on a given transaction index
|
// ScheduleError forces a block to error on a given transaction index
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue