Skip to content
This repository was archived by the owner on Oct 25, 2024. It is now read-only.

Commit 4d1b163

Browse files
authored
Use snapshots for blocklist revert (#5)
1 parent 7379542 commit 4d1b163

5 files changed

Lines changed: 48 additions & 37 deletions

File tree

core/chain_makers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ func (b *BlockGen) AddTxWithChain(bc *BlockChain, tx *types.Transaction) {
103103
b.SetCoinbase(common.Address{})
104104
}
105105
b.statedb.Prepare(tx.Hash(), len(b.txs))
106-
receipt, err := ApplyTransaction(b.config, bc, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed, vm.Config{})
106+
receipt, err := ApplyTransaction(b.config, bc, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed, vm.Config{}, nil)
107107
if err != nil {
108108
panic(err)
109109
}

core/state_processor.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
7979
return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
8080
}
8181
statedb.Prepare(tx.Hash(), i)
82-
receipt, err := applyTransaction(msg, p.config, nil, gp, statedb, blockNumber, blockHash, tx, usedGas, vmenv)
82+
receipt, err := applyTransaction(msg, p.config, nil, gp, statedb, blockNumber, blockHash, tx, usedGas, vmenv, nil)
8383
if err != nil {
8484
return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
8585
}
@@ -92,16 +92,24 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
9292
return receipts, allLogs, *usedGas, nil
9393
}
9494

95-
func applyTransaction(msg types.Message, config *params.ChainConfig, author *common.Address, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (*types.Receipt, error) {
95+
func applyTransaction(msg types.Message, config *params.ChainConfig, author *common.Address, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM, preFinalizeHook func() error) (*types.Receipt, error) {
9696
// Create a new context to be used in the EVM environment.
9797
txContext := NewEVMTxContext(msg)
9898
evm.Reset(txContext, statedb)
9999

100+
snapshot := statedb.Snapshot()
100101
// Apply the transaction to the current state (included in the env).
101102
result, err := ApplyMessage(evm, msg, gp)
102103
if err != nil {
103104
return nil, err
104105
}
106+
if preFinalizeHook != nil {
107+
err = preFinalizeHook()
108+
if err != nil {
109+
statedb.RevertToSnapshot(snapshot)
110+
return nil, err
111+
}
112+
}
105113

106114
// Update the state with pending changes.
107115
var root []byte
@@ -186,15 +194,15 @@ func applyTransactionWithResult(msg types.Message, config *params.ChainConfig, b
186194
// and uses the input parameters for its environment. It returns the receipt
187195
// for the transaction, gas used and an error if the transaction failed,
188196
// indicating the block was invalid.
189-
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) (*types.Receipt, error) {
197+
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, preFinalizeHook func() error) (*types.Receipt, error) {
190198
msg, err := tx.AsMessage(types.MakeSigner(config, header.Number), header.BaseFee)
191199
if err != nil {
192200
return nil, err
193201
}
194202
// Create a new context to be used in the EVM environment
195203
blockContext := NewEVMBlockContext(header, bc, author)
196204
vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, config, cfg)
197-
return applyTransaction(msg, config, author, gp, statedb, header.Number, header.Hash(), tx, usedGas, vmenv)
205+
return applyTransaction(msg, config, author, gp, statedb, header.Number, header.Hash(), tx, usedGas, vmenv, preFinalizeHook)
198206
}
199207

200208
func ApplyTransactionWithResult(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, *ExecutionResult, error) {

miner/algo_common.go

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ func applyTransactionWithBlacklist(signer types.Signer, config *params.ChainConf
8888
// short circuit if blacklist is empty
8989
if len(blacklist) == 0 {
9090
snap := statedb.Snapshot()
91-
receipt, err := core.ApplyTransaction(config, bc, author, gp, statedb, header, tx, usedGas, cfg)
91+
receipt, err := core.ApplyTransaction(config, bc, author, gp, statedb, header, tx, usedGas, cfg, nil)
9292
if err != nil {
9393
statedb.RevertToSnapshot(snap)
9494
}
@@ -114,29 +114,28 @@ func applyTransactionWithBlacklist(signer types.Signer, config *params.ChainConf
114114
cfg.Tracer = touchTracer
115115
cfg.Debug = true
116116

117+
hook := func() error {
118+
for _, address := range touchTracer.TouchedAddresses() {
119+
if _, in := blacklist[address]; in {
120+
return errors.New("blacklist violation, tx trace")
121+
}
122+
}
123+
return nil
124+
}
125+
117126
usedGasTmp := *usedGas
118127
gasPoolTmp := new(core.GasPool).AddGas(gp.Gas())
119-
stateCopy := statedb.Copy()
120-
snap := stateCopy.Snapshot()
128+
snap := statedb.Snapshot()
121129

122-
stateCopy.Prepare(tx.Hash(), statedb.TxIndex())
123-
receipt, err := core.ApplyTransaction(config, bc, author, gasPoolTmp, stateCopy, header, tx, &usedGasTmp, cfg)
130+
receipt, err := core.ApplyTransaction(config, bc, author, gasPoolTmp, statedb, header, tx, &usedGasTmp, cfg, hook)
124131
if err != nil {
125-
stateCopy.RevertToSnapshot(snap)
126-
*usedGas = usedGasTmp
127-
*gp = *gasPoolTmp
128-
return receipt, stateCopy, err
129-
}
130-
131-
for _, address := range touchTracer.TouchedAddresses() {
132-
if _, in := blacklist[address]; in {
133-
return nil, statedb, errors.New("blacklist violation, tx trace")
134-
}
132+
statedb.RevertToSnapshot(snap)
133+
return receipt, statedb, err
135134
}
136135

137136
*usedGas = usedGasTmp
138137
*gp = *gasPoolTmp
139-
return receipt, stateCopy, nil
138+
return receipt, statedb, err
140139
}
141140

142141
// commit tx to envDiff

miner/algo_common_test.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func simulateBundle(env *environment, bundle types.MevBundle, chData chainData,
7171
coinbaseBalanceBefore := stateDB.GetBalance(env.coinbase)
7272

7373
var tempGasUsed uint64
74-
receipt, err := core.ApplyTransaction(chData.chainConfig, chData.chain, &env.coinbase, gasPool, stateDB, env.header, tx, &tempGasUsed, *chData.chain.GetVMConfig())
74+
receipt, err := core.ApplyTransaction(chData.chainConfig, chData.chain, &env.coinbase, gasPool, stateDB, env.header, tx, &tempGasUsed, *chData.chain.GetVMConfig(), nil)
7575
if err != nil {
7676
return types.SimulatedBundle{}, err
7777
}
@@ -439,6 +439,8 @@ func TestBlacklist(t *testing.T) {
439439
env := newEnvironment(chData, statedb, signers.addresses[0], GasLimit, big.NewInt(1))
440440
envDiff := newEnvironmentDiff(env)
441441

442+
beforeRoot := statedb.IntermediateRoot(true)
443+
442444
blacklist := map[common.Address]struct{}{
443445
signers.addresses[3]: {},
444446
}
@@ -494,6 +496,11 @@ func TestBlacklist(t *testing.T) {
494496
if len(envDiff.newReceipts) != 0 {
495497
t.Fatal("newReceipts changed")
496498
}
499+
500+
afterRoot := statedb.IntermediateRoot(true)
501+
if beforeRoot != afterRoot {
502+
t.Fatal("statedb root changed")
503+
}
497504
}
498505

499506
func TestGetSealingWorkAlgos(t *testing.T) {

miner/worker.go

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -919,12 +919,7 @@ func (w *worker) updateSnapshot(env *environment) {
919919
func (w *worker) commitTransaction(env *environment, tx *types.Transaction) ([]*types.Log, error) {
920920
gasPool := *env.gasPool
921921
envGasUsed := env.header.GasUsed
922-
var stateDB *state.StateDB
923-
if len(w.blockList) != 0 {
924-
stateDB = env.state.Copy()
925-
} else {
926-
stateDB = env.state
927-
}
922+
stateDB := env.state
928923

929924
// It's important to copy then .Prepare() - don't reorder.
930925
stateDB.Prepare(tx.Hash(), env.tcount)
@@ -937,25 +932,27 @@ func (w *worker) commitTransaction(env *environment, tx *types.Transaction) ([]*
937932
}
938933

939934
var tracer *logger.AccountTouchTracer
935+
var hook func() error
940936
config := *w.chain.GetVMConfig()
941937
if len(w.blockList) != 0 {
942938
tracer = logger.NewAccountTouchTracer()
943939
config.Tracer = tracer
944940
config.Debug = true
941+
hook = func() error {
942+
for _, address := range tracer.TouchedAddresses() {
943+
if _, in := w.blockList[address]; in {
944+
return errBlocklistViolation
945+
}
946+
}
947+
return nil
948+
}
945949
}
946950

947-
receipt, err := core.ApplyTransaction(w.chainConfig, w.chain, &env.coinbase, &gasPool, stateDB, env.header, tx, &envGasUsed, config)
951+
receipt, err := core.ApplyTransaction(w.chainConfig, w.chain, &env.coinbase, &gasPool, stateDB, env.header, tx, &envGasUsed, config, hook)
948952
if err != nil {
949953
stateDB.RevertToSnapshot(snapshot)
950954
return nil, err
951955
}
952-
if len(w.blockList) != 0 {
953-
for _, address := range tracer.TouchedAddresses() {
954-
if _, in := w.blockList[address]; in {
955-
return nil, errBlocklistViolation
956-
}
957-
}
958-
}
959956

960957
*env.gasPool = gasPool
961958
env.header.GasUsed = envGasUsed
@@ -1769,7 +1766,7 @@ func (w *worker) computeBundleGas(env *environment, bundle types.MevBundle, stat
17691766
config.Tracer = tracer
17701767
config.Debug = true
17711768
}
1772-
receipt, err := core.ApplyTransaction(w.chainConfig, w.chain, &env.coinbase, gasPool, state, env.header, tx, &tempGasUsed, config)
1769+
receipt, err := core.ApplyTransaction(w.chainConfig, w.chain, &env.coinbase, gasPool, state, env.header, tx, &tempGasUsed, config, nil)
17731770
if err != nil {
17741771
return simulatedBundle{}, err
17751772
}

0 commit comments

Comments
 (0)