Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix: Only call CalcOrder once in worker and check if parent is prime terminus #1992

Merged
merged 1 commit into from
Aug 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -1255,17 +1255,22 @@ func (p *StateProcessor) Apply(batch ethdb.Batch, block *types.WorkObject) ([]*t
// and uses the input parameters for its environment. It returns the receipt
// for the transaction, gas used and an error if the transaction failed,
// indicating the block was invalid.
func ApplyTransaction(config *params.ChainConfig, parent *types.WorkObject, bc ChainContext, author *common.Address, gp *types.GasPool, statedb *state.StateDB, header *types.WorkObject, tx *types.Transaction, usedGas *uint64, cfg vm.Config, etxRLimit, etxPLimit *int, logger *log.Logger) (*types.Receipt, *big.Int, error) {
func ApplyTransaction(config *params.ChainConfig, parent *types.WorkObject, parentOrder int, bc ChainContext, author *common.Address, gp *types.GasPool, statedb *state.StateDB, header *types.WorkObject, tx *types.Transaction, usedGas *uint64, cfg vm.Config, etxRLimit, etxPLimit *int, logger *log.Logger) (*types.Receipt, *big.Int, error) {
nodeCtx := config.Location.Context()
msg, err := tx.AsMessage(types.MakeSigner(config, header.Number(nodeCtx)), header.BaseFee())
if err != nil {
return nil, nil, err
}
if tx.Type() == types.ExternalTxType && tx.ETXSender().Location().Equal(*tx.To().Location()) { // Qi->Quai Conversion
msg.SetLock(new(big.Int).Add(header.Number(nodeCtx), big.NewInt(params.ConversionLockPeriod)))
primeTerminus := bc.GetHeaderByHash(header.PrimeTerminus())
if primeTerminus == nil {
return nil, nil, fmt.Errorf("could not find prime terminus header %032x", header.PrimeTerminus())
var primeTerminus *types.WorkObject
if parentOrder == common.PRIME_CTX {
primeTerminus = parent
} else {
primeTerminus = bc.GetHeaderByHash(header.PrimeTerminus())
if primeTerminus == nil {
return nil, nil, fmt.Errorf("could not find prime terminus header %032x", header.PrimeTerminus())
}
}
// Convert Qi to Quai
msg.SetValue(misc.QiToQuai(primeTerminus.WorkObjectHeader(), tx.Value()))
Expand Down
83 changes: 20 additions & 63 deletions core/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,15 @@ const (
type environment struct {
signer types.Signer

state *state.StateDB // apply state changes here
ancestors mapset.Set // ancestor set (used for checking uncle parent validity)
family mapset.Set // family set (used for checking uncle invalidity)
tcount int // tx count in cycle
gasPool *types.GasPool // available gas used to pack transactions
coinbase common.Address
etxRLimit int // Remaining number of cross-region ETXs that can be included
etxPLimit int // Remaining number of cross-prime ETXs that can be included

state *state.StateDB // apply state changes here
ancestors mapset.Set // ancestor set (used for checking uncle parent validity)
family mapset.Set // family set (used for checking uncle invalidity)
tcount int // tx count in cycle
gasPool *types.GasPool // available gas used to pack transactions
coinbase common.Address
etxRLimit int // Remaining number of cross-region ETXs that can be included
etxPLimit int // Remaining number of cross-prime ETXs that can be included
parentOrder *int
wo *types.WorkObject
txs []*types.Transaction
etxs []*types.Transaction
Expand All @@ -84,46 +84,6 @@ type environment struct {
uncles map[common.Hash]*types.WorkObjectHeader
}

// copy creates a deep copy of environment.
func (env *environment) copy(processingState bool, nodeCtx int) *environment {
if nodeCtx == common.ZONE_CTX && processingState {
cpy := &environment{
signer: env.signer,
state: env.state.Copy(),
ancestors: env.ancestors.Clone(),
family: env.family.Clone(),
tcount: env.tcount,
coinbase: env.coinbase,
etxRLimit: env.etxRLimit,
etxPLimit: env.etxPLimit,
wo: types.CopyWorkObject(env.wo),
receipts: copyReceipts(env.receipts),
utxoFees: new(big.Int).Set(env.utxoFees),
quaiFees: new(big.Int).Set(env.quaiFees),
}
if env.gasPool != nil {
gasPool := *env.gasPool
cpy.gasPool = &gasPool
}
// The content of txs and uncles are immutable, unnecessary
// to do the expensive deep copy for them.
cpy.txs = make([]*types.Transaction, len(env.txs))
copy(cpy.txs, env.txs)
cpy.etxs = make([]*types.Transaction, len(env.etxs))
copy(cpy.etxs, env.etxs)

env.uncleMu.Lock()
cpy.uncles = make(map[common.Hash]*types.WorkObjectHeader)
for hash, uncle := range env.uncles {
cpy.uncles[hash] = uncle
}
env.uncleMu.Unlock()
return cpy
} else {
return &environment{wo: types.CopyWorkObject(env.wo)}
}
}

// unclelist returns the contained uncles as the list format.
func (env *environment) unclelist() []*types.WorkObjectHeader {
env.uncleMu.RLock()
Expand Down Expand Up @@ -594,13 +554,11 @@ func (w *worker) GeneratePendingHeader(block *types.WorkObject, fill bool) (*typ
}).Info("Filled and sorted pending transactions")
}

// If the current block is a prime block, its a prime terminus
_, order, err := w.CalcOrder(block)
if err != nil {
return nil, err
if work.parentOrder == nil {
return nil, fmt.Errorf("parent order not set")
}
var primeTerminus *types.WorkObject
if order == common.PRIME_CTX {
if *work.parentOrder == common.PRIME_CTX {
primeTerminus = block
} else {
// convert the Quai reward into Qi and add it to the utxoFees
Expand Down Expand Up @@ -815,12 +773,11 @@ func (w *worker) commitTransaction(env *environment, parent *types.WorkObject, t
if tx.ETXSender().Location().Equal(*tx.To().Location()) { // Quai->Qi conversion
txGas := tx.Gas()
lock := new(big.Int).Add(env.wo.Number(w.hc.NodeCtx()), big.NewInt(params.ConversionLockPeriod))
_, parentOrder, err := w.CalcOrder(parent)
if err != nil {
return nil, false, err
if env.parentOrder == nil {
return nil, false, errors.New("parent order not set")
}
var primeTerminus *types.WorkObject
if parentOrder == common.PRIME_CTX {
if *env.parentOrder == common.PRIME_CTX {
primeTerminus = parent
} else {
primeTerminus = w.hc.GetPrimeTerminus(env.wo)
Expand Down Expand Up @@ -881,7 +838,7 @@ func (w *worker) commitTransaction(env *environment, parent *types.WorkObject, t
snap := env.state.Snapshot()
// retrieve the gas used int and pass in the reference to the ApplyTransaction
gasUsed := env.wo.GasUsed()
receipt, quaiFees, err := ApplyTransaction(w.chainConfig, parent, w.hc, &env.coinbase, env.gasPool, env.state, env.wo, tx, &gasUsed, *w.hc.bc.processor.GetVMConfig(), &env.etxRLimit, &env.etxPLimit, w.logger)
receipt, quaiFees, err := ApplyTransaction(w.chainConfig, parent, *env.parentOrder, w.hc, &env.coinbase, env.gasPool, env.state, env.wo, tx, &gasUsed, *w.hc.bc.processor.GetVMConfig(), &env.etxRLimit, &env.etxPLimit, w.logger)
if err != nil {
w.logger.WithFields(log.Fields{
"err": err,
Expand Down Expand Up @@ -1307,6 +1264,7 @@ func (w *worker) prepareWork(genParams *generateParams, wo *types.WorkObject) (*
w.logger.WithField("err", err).Error("Failed to create sealing context")
return nil, err
}
env.parentOrder = &order
// Accumulate the uncles for the sealing work.
commitUncles := func(wos *lru.Cache[common.Hash, types.WorkObjectHeader]) {
var uncles []*types.WorkObjectHeader
Expand Down Expand Up @@ -1672,12 +1630,11 @@ func (w *worker) processQiTx(tx *types.Transaction, env *environment, parent *ty
return err
}

_, parentOrder, err := w.CalcOrder(parent)
if err != nil {
return err
if env.parentOrder == nil {
return errors.New("parent order not set")
}
var primeTerminus *types.WorkObject
if parentOrder == common.PRIME_CTX {
if *env.parentOrder == common.PRIME_CTX {
primeTerminus = parent
} else {
primeTerminus = w.hc.GetPrimeTerminus(env.wo)
Expand Down
Loading