mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 06:06:44 +00:00
fix: enable worker but skip CCC on follower nodes (#474)
* fix: enable worker but skip CCC on follower nodes * fix worker snapshot * fix worker snapshot
This commit is contained in:
parent
e8d9d60cf0
commit
d4597e369e
2 changed files with 47 additions and 44 deletions
|
|
@ -873,46 +873,53 @@ func (w *worker) updateSnapshot() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *worker) commitTransaction(tx *types.Transaction, coinbase common.Address) ([]*types.Log, error) {
|
func (w *worker) commitTransaction(tx *types.Transaction, coinbase common.Address) ([]*types.Log, error) {
|
||||||
|
var accRows *types.RowConsumption
|
||||||
|
|
||||||
|
// do not do CCC checks on follower nodes
|
||||||
|
if w.isRunning() {
|
||||||
|
snap := w.current.state.Snapshot()
|
||||||
|
|
||||||
|
log.Trace(
|
||||||
|
"Worker apply ccc for tx",
|
||||||
|
"id", w.circuitCapacityChecker.ID,
|
||||||
|
"txhash", tx.Hash(),
|
||||||
|
)
|
||||||
|
|
||||||
|
// 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
|
||||||
|
traces, err := w.current.traceEnv.GetBlockTrace(
|
||||||
|
types.NewBlockWithHeader(w.current.header).WithBody([]*types.Transaction{tx}, nil),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
// `w.current.traceEnv.State` & `w.current.state` share a same pointer to the state, so only need to revert `w.current.state`
|
||||||
|
w.current.state.RevertToSnapshot(snap)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
accRows, err = w.circuitCapacityChecker.ApplyTransaction(traces)
|
||||||
|
if err != nil {
|
||||||
|
// `w.current.traceEnv.State` & `w.current.state` share a same pointer to the state, so only need to revert `w.current.state`
|
||||||
|
w.current.state.RevertToSnapshot(snap)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
log.Trace(
|
||||||
|
"Worker apply ccc for tx result",
|
||||||
|
"id", w.circuitCapacityChecker.ID,
|
||||||
|
"txhash", tx.Hash(),
|
||||||
|
"accRows", accRows,
|
||||||
|
)
|
||||||
|
|
||||||
|
// revert to snapshot for calling `core.ApplyMessage` again, (both `traceEnv.GetBlockTrace` & `core.ApplyTransaction` will call `core.ApplyMessage`)
|
||||||
|
w.current.state.RevertToSnapshot(snap)
|
||||||
|
}
|
||||||
|
|
||||||
|
// create new snapshot for `core.ApplyTransaction`
|
||||||
snap := w.current.state.Snapshot()
|
snap := w.current.state.Snapshot()
|
||||||
|
|
||||||
log.Trace(
|
|
||||||
"Worker apply ccc for tx",
|
|
||||||
"id", w.circuitCapacityChecker.ID,
|
|
||||||
"txhash", tx.Hash(),
|
|
||||||
)
|
|
||||||
|
|
||||||
// 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
|
|
||||||
traces, err := w.current.traceEnv.GetBlockTrace(
|
|
||||||
types.NewBlockWithHeader(w.current.header).WithBody([]*types.Transaction{tx}, nil),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
// `w.current.traceEnv.State` & `w.current.state` share a same pointer to the state, so only need to revert `w.current.state`
|
|
||||||
w.current.state.RevertToSnapshot(snap)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
accRows, err := w.circuitCapacityChecker.ApplyTransaction(traces)
|
|
||||||
if err != nil {
|
|
||||||
// `w.current.traceEnv.State` & `w.current.state` share a same pointer to the state, so only need to revert `w.current.state`
|
|
||||||
w.current.state.RevertToSnapshot(snap)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
log.Trace(
|
|
||||||
"Worker apply ccc for tx result",
|
|
||||||
"id", w.circuitCapacityChecker.ID,
|
|
||||||
"txhash", tx.Hash(),
|
|
||||||
"accRows", accRows,
|
|
||||||
)
|
|
||||||
|
|
||||||
// revert to snapshot for calling `core.ApplyMessage` again, (both `traceEnv.GetBlockTrace` & `core.ApplyTransaction` will call `core.ApplyMessage`)
|
|
||||||
w.current.state.RevertToSnapshot(snap)
|
|
||||||
// create new snapshot for `core.ApplyTransaction`
|
|
||||||
snap = w.current.state.Snapshot()
|
|
||||||
receipt, err := core.ApplyTransaction(w.chainConfig, w.chain, &coinbase, w.current.gasPool, w.current.state, w.current.header, tx, &w.current.header.GasUsed, *w.chain.GetVMConfig())
|
receipt, err := core.ApplyTransaction(w.chainConfig, w.chain, &coinbase, w.current.gasPool, w.current.state, w.current.header, tx, &w.current.header.GasUsed, *w.chain.GetVMConfig())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.current.state.RevertToSnapshot(snap)
|
w.current.state.RevertToSnapshot(snap)
|
||||||
|
|
@ -1159,10 +1166,6 @@ func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64)
|
||||||
w.mu.RLock()
|
w.mu.RLock()
|
||||||
defer w.mu.RUnlock()
|
defer w.mu.RUnlock()
|
||||||
|
|
||||||
if !w.isRunning() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
tstart := time.Now()
|
tstart := time.Now()
|
||||||
parent := w.chain.CurrentBlock()
|
parent := w.chain.CurrentBlock()
|
||||||
w.circuitCapacityChecker.Reset()
|
w.circuitCapacityChecker.Reset()
|
||||||
|
|
@ -1334,7 +1337,7 @@ func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64)
|
||||||
func (w *worker) commit(uncles []*types.Header, interval func(), update bool, start time.Time) error {
|
func (w *worker) commit(uncles []*types.Header, interval func(), update bool, start time.Time) error {
|
||||||
// set w.current.accRows for empty-but-not-genesis block
|
// set w.current.accRows for empty-but-not-genesis block
|
||||||
if (w.current.header.Number.Uint64() != 0) &&
|
if (w.current.header.Number.Uint64() != 0) &&
|
||||||
(w.current.accRows == nil || len(*w.current.accRows) == 0) {
|
(w.current.accRows == nil || len(*w.current.accRows) == 0) && w.isRunning() {
|
||||||
log.Trace(
|
log.Trace(
|
||||||
"Worker apply ccc for empty block",
|
"Worker apply ccc for empty block",
|
||||||
"id", w.circuitCapacityChecker.ID,
|
"id", w.circuitCapacityChecker.ID,
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ import (
|
||||||
const (
|
const (
|
||||||
VersionMajor = 4 // Major version component of the current release
|
VersionMajor = 4 // Major version component of the current release
|
||||||
VersionMinor = 3 // Minor version component of the current release
|
VersionMinor = 3 // Minor version component of the current release
|
||||||
VersionPatch = 42 // Patch version component of the current release
|
VersionPatch = 43 // Patch version component of the current release
|
||||||
VersionMeta = "sepolia" // Version metadata to append to the version string
|
VersionMeta = "sepolia" // Version metadata to append to the version string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue