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

fix: revert for droppable tx receipt failed #65

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from
Draft
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
5 changes: 3 additions & 2 deletions core/chain_makers.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"fmt"
"math/big"

"github.com/holiman/uint256"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/misc"
Expand All @@ -33,7 +35,6 @@ import (
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/triedb"
"github.com/holiman/uint256"
)

// BlockGen creates blocks for testing.
Expand Down Expand Up @@ -120,7 +121,7 @@ func (b *BlockGen) addTx(bc *BlockChain, vmConfig vm.Config, tx *types.Transacti
b.SetCoinbase(common.Address{})
}
b.statedb.SetTxContext(tx.Hash(), len(b.txs))
receipt, err := ApplyTransaction(b.cm.config, bc, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed, vmConfig, NewReceiptBloomGenerator())
receipt, err := ApplyTransaction(b.cm.config, bc, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed, vmConfig, false, NewReceiptBloomGenerator())
if err != nil {
panic(err)
}
Expand Down
12 changes: 8 additions & 4 deletions core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
}
statedb.SetTxContext(tx.Hash(), i)

receipt, err := applyTransaction(msg, p.config, gp, statedb, blockNumber, blockHash, tx, usedGas, vmenv, bloomProcessors)
receipt, err := applyTransaction(msg, p.config, gp, statedb, blockNumber, blockHash, tx, usedGas, vmenv, false, bloomProcessors)
if err != nil {
bloomProcessors.Close()
return statedb, nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
Expand Down Expand Up @@ -155,7 +155,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
return statedb, receipts, allLogs, *usedGas, nil
}

func applyTransaction(msg *Message, config *params.ChainConfig, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM, receiptProcessors ...ReceiptProcessor) (*types.Receipt, error) {
func applyTransaction(msg *Message, config *params.ChainConfig, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM, droppable bool, receiptProcessors ...ReceiptProcessor) (*types.Receipt, error) {
// Create a new context to be used in the EVM environment.
txContext := NewEVMTxContext(msg)
evm.Reset(txContext, statedb)
Expand All @@ -166,6 +166,10 @@ func applyTransaction(msg *Message, config *params.ChainConfig, gp *GasPool, sta
return nil, err
}

if result.Failed() && droppable {
return nil, errors.New("droppable transaction receipt failed")
}

// Update the state with pending changes.
var root []byte
if config.IsByzantium(blockNumber) {
Expand Down Expand Up @@ -211,7 +215,7 @@ func applyTransaction(msg *Message, config *params.ChainConfig, gp *GasPool, sta
// 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, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config, receiptProcessors ...ReceiptProcessor) (*types.Receipt, error) {
func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config, droppable bool, receiptProcessors ...ReceiptProcessor) (*types.Receipt, error) {
msg, err := TransactionToMessage(tx, types.MakeSigner(config, header.Number, header.Time), header.BaseFee)
if err != nil {
return nil, err
Expand All @@ -225,7 +229,7 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
vm.EVMInterpreterPool.Put(ite)
vm.EvmPool.Put(vmenv)
}()
return applyTransaction(msg, config, gp, statedb, header.Number, header.Hash(), tx, usedGas, vmenv, receiptProcessors...)
return applyTransaction(msg, config, gp, statedb, header.Number, header.Hash(), tx, usedGas, vmenv, droppable, receiptProcessors...)
}

// ProcessBeaconBlockRoot applies the EIP-4788 system call to the beacon block root
Expand Down
2 changes: 1 addition & 1 deletion miner/bid_simulator.go
Original file line number Diff line number Diff line change
Expand Up @@ -846,7 +846,7 @@ func (r *BidRuntime) commitTransaction(chain *core.BlockChain, chainConfig *para
}

receipt, err := core.ApplyTransaction(chainConfig, chain, &env.coinbase, env.gasPool, env.state, env.header, tx,
&env.header.GasUsed, *chain.GetVMConfig(), core.NewReceiptBloomGenerator())
&env.header.GasUsed, *chain.GetVMConfig(), false, core.NewReceiptBloomGenerator())
if err != nil {
return err
} else if unRevertible && receipt.Status == types.ReceiptStatusFailed {
Expand Down
2 changes: 1 addition & 1 deletion miner/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,7 @@ func (w *worker) applyTransaction(env *environment, tx *types.Transaction, recei
gp = env.gasPool.Gas()
)

receipt, err := core.ApplyTransaction(w.chainConfig, w.chain, &env.coinbase, env.gasPool, env.state, env.header, tx, &env.header.GasUsed, *w.chain.GetVMConfig(), receiptProcessors...)
receipt, err := core.ApplyTransaction(w.chainConfig, w.chain, &env.coinbase, env.gasPool, env.state, env.header, tx, &env.header.GasUsed, *w.chain.GetVMConfig(), false, receiptProcessors...)
if err != nil {
env.state.RevertToSnapshot(snap)
env.gasPool.SetGas(gp)
Expand Down
14 changes: 9 additions & 5 deletions miner/worker_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -431,12 +431,15 @@ func (w *worker) simulateBundle(
snap := state.Snapshot()
gp := gasPool.Gas()

droppable := containsHash(bundle.DroppingTxHashes, tx.Hash())
revertible := containsHash(bundle.RevertingTxHashes, tx.Hash())

receipt, err := core.ApplyTransaction(w.chainConfig, w.chain, &w.coinbase, gasPool, state, env.header, tx,
&tempGasUsed, *w.chain.GetVMConfig())
&tempGasUsed, *w.chain.GetVMConfig(), droppable)
if err != nil {
log.Warn("fail to simulate bundle", "hash", bundle.Hash().String(), "err", err)

if containsHash(bundle.DroppingTxHashes, tx.Hash()) {
if droppable {
log.Warn("drop tx in bundle", "hash", tx.Hash().String())
state.RevertToSnapshot(snap)
gasPool.SetGas(gp)
Expand All @@ -458,12 +461,13 @@ func (w *worker) simulateBundle(
return nil, err
}

if receipt.Status == types.ReceiptStatusFailed && !containsHash(bundle.RevertingTxHashes, receipt.TxHash) {
if receipt.Status == types.ReceiptStatusFailed && !revertible {
// for unRevertible tx but itself can be dropped, we drop it and revert the state and gas pool
if containsHash(bundle.DroppingTxHashes, receipt.TxHash) {
if droppable {
log.Warn("drop tx in bundle", "hash", receipt.TxHash.String())
// NOTE: here should not revert state, when no err returned by ApplyTransaction, state.clearJournalAndRefund()
// must had been called to avoid reverting across transactions, so we can directly remove the tx from bundle
state.RevertToSnapshot(snap)
gasPool.SetGas(gp)
bundle.Txs = bundle.Txs.Remove(i)
txsLen = len(bundle.Txs)
Expand Down Expand Up @@ -559,7 +563,7 @@ func (w *worker) simulateGaslessBundle(env *environment, bundle *types.Bundle) (
)

receipt, err := core.ApplyTransaction(w.chainConfig, w.chain, &w.coinbase, env.gasPool, env.state, env.header, tx,
&env.header.GasUsed, *w.chain.GetVMConfig())
&env.header.GasUsed, *w.chain.GetVMConfig(), false)
if err != nil {
env.state.RevertToSnapshot(snap)
env.gasPool.SetGas(gp)
Expand Down
Loading