diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go
index f13038c63ce16d75a7919b29befbd14f3e8d6e94..10e4d98a3cfd79e8b11a74aca3e546dcadfa4fe7 100644
--- a/cmd/evm/internal/t8ntool/execution.go
+++ b/cmd/evm/internal/t8ntool/execution.go
@@ -108,7 +108,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
 	}
 	var (
 		db          = kv.NewMemDatabase()
-		ibs         = MakePreState(context.Background(), db, pre.Pre)
+		ibs         = MakePreState(chainConfig.Rules(0), db, pre.Pre)
 		signer      = types.MakeSigner(chainConfig, pre.Env.Number)
 		gaspool     = new(core.GasPool)
 		blockHash   = common.Hash{0x13, 0x37}
@@ -233,7 +233,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
 		ibs.AddBalance(pre.Env.Coinbase, minerReward)
 	}
 
-	err := ibs.FinalizeTx(context.Background(), state.NewDbStateWriter(db, 1))
+	err := ibs.FinalizeTx(chainConfig.Rules(1), state.NewDbStateWriter(db, 1))
 	if err != nil {
 		return nil, nil, err
 	}
@@ -258,7 +258,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
 	return db.RwKV(), execRs, nil
 }
 
-func MakePreState(ctx context.Context, db ethdb.Database, accounts core.GenesisAlloc) *state.IntraBlockState {
+func MakePreState(chainRules params.Rules, db ethdb.Database, accounts core.GenesisAlloc) *state.IntraBlockState {
 	var blockNr uint64 = 0
 	r, _ := state.NewDbStateReader(db), state.NewDbStateWriter(db, blockNr)
 	statedb := state.New(r)
@@ -278,10 +278,10 @@ func MakePreState(ctx context.Context, db ethdb.Database, accounts core.GenesisA
 		}
 	}
 	// Commit and re-open to start with a clean state.
-	if err := statedb.FinalizeTx(ctx, state.NewDbStateWriter(db, blockNr+1)); err != nil {
+	if err := statedb.FinalizeTx(chainRules, state.NewDbStateWriter(db, blockNr+1)); err != nil {
 		panic(err)
 	}
-	if err := statedb.CommitBlock(ctx, state.NewDbStateWriter(db, blockNr+1)); err != nil {
+	if err := statedb.CommitBlock(chainRules, state.NewDbStateWriter(db, blockNr+1)); err != nil {
 		panic(err)
 	}
 	return statedb
diff --git a/cmd/evm/runner.go b/cmd/evm/runner.go
index 02a760e5210545d3bd3ed6d9c394458f15d7fbdd..b4de1651d6faa13d715a26637b08cd3453f4ef07 100644
--- a/cmd/evm/runner.go
+++ b/cmd/evm/runner.go
@@ -273,11 +273,11 @@ func runCmd(ctx *cli.Context) error {
 	output, leftOverGas, stats, err := timedExec(bench, execFunc)
 
 	if ctx.GlobalBool(DumpFlag.Name) {
-		ctx := context.Background()
+		var rules params.Rules
 		if chainConfig != nil {
-			ctx = chainConfig.WithEIPsFlags(context.Background(), runtimeConfig.BlockNumber.Uint64())
+			rules = chainConfig.Rules(runtimeConfig.BlockNumber.Uint64())
 		}
-		if err = statedb.CommitBlock(ctx, state.NewNoopWriter()); err != nil {
+		if err = statedb.CommitBlock(rules, state.NewNoopWriter()); err != nil {
 			fmt.Println("Could not commit state: ", err)
 			os.Exit(1)
 		}
diff --git a/cmd/evm/staterunner.go b/cmd/evm/staterunner.go
index ea0866e6c14b5bc3358690cf069085c2adf52650..92ced4a2717bb773f1d9f72acc3a9f1c49953019 100644
--- a/cmd/evm/staterunner.go
+++ b/cmd/evm/staterunner.go
@@ -29,6 +29,7 @@ import (
 	"github.com/ledgerwatch/erigon/core/vm"
 	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/log"
+	"github.com/ledgerwatch/erigon/params"
 	"github.com/ledgerwatch/erigon/tests"
 	"github.com/ledgerwatch/erigon/turbo/trie"
 	"github.com/urfave/cli"
@@ -114,7 +115,7 @@ func stateTestCmd(ctx *cli.Context) error {
 			var root common.Hash
 			var calcRootErr error
 
-			statedb, err := test.Run(context.Background(), tx, st, cfg)
+			statedb, err := test.Run(params.Rules{}, tx, st, cfg)
 			// print state root for evmlab tracing
 			root, calcRootErr = trie.CalcRoot("", tx)
 			if err == nil && calcRootErr != nil {
diff --git a/cmd/hack/hack.go b/cmd/hack/hack.go
index 2f0b8335a869fd03cbc77a88a0601ff7740f3e1c..d6ed0018828a33940f89dd4369c6724cb9ab71a3 100644
--- a/cmd/hack/hack.go
+++ b/cmd/hack/hack.go
@@ -2313,6 +2313,7 @@ func runBlock(ibs *state.IntraBlockState, txnWriter state.StateWriter, blockWrit
 	if chainConfig.DAOForkSupport && chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(block.Number()) == 0 {
 		misc.ApplyDAOHardFork(ibs)
 	}
+	rules := chainConfig.Rules(block.NumberU64())
 	for i, tx := range block.Transactions() {
 		ibs.Prepare(tx.Hash(), block.Hash(), i)
 		receipt, _, err := core.ApplyTransaction(chainConfig, getHeader, engine, nil, gp, ibs, txnWriter, header, tx, usedGas, vmConfig, checkTEVM)
@@ -2329,8 +2330,7 @@ func runBlock(ibs *state.IntraBlockState, txnWriter state.StateWriter, blockWrit
 			return nil, fmt.Errorf("finalize of block %d failed: %v", block.NumberU64(), err)
 		}
 
-		ctx := chainConfig.WithEIPsFlags(context.Background(), header.Number.Uint64())
-		if err := ibs.CommitBlock(ctx, blockWriter); err != nil {
+		if err := ibs.CommitBlock(rules, blockWriter); err != nil {
 			return nil, fmt.Errorf("committing block %d failed: %v", block.NumberU64(), err)
 		}
 	}
diff --git a/cmd/pics/state.go b/cmd/pics/state.go
index 504cccfb52a8b6d470ab1e0a95c4cd14f63ef2df..9e4a83bbedd9d2b0d6fdcf0fac5193d33ae26200 100644
--- a/cmd/pics/state.go
+++ b/cmd/pics/state.go
@@ -307,7 +307,7 @@ func initialState1() error {
 			err error
 		)
 
-		ctx := gspec.Config.WithEIPsFlags(context.Background(), block.Number().Uint64())
+		ctx := context.Background()
 		switch i {
 		case 0:
 			tx, err = types.SignTx(types.NewTransaction(0, theAddr, uint256.NewInt(1000000000000000), 21000, new(uint256.Int), nil), *signer, key)
diff --git a/cmd/rpcdaemon/commands/eth_block.go b/cmd/rpcdaemon/commands/eth_block.go
index f8f0fd036e98d7e2d7794e82b71500c17f3795bf..58c1671453241fb535baa3044d7b29f4ac293105 100644
--- a/cmd/rpcdaemon/commands/eth_block.go
+++ b/cmd/rpcdaemon/commands/eth_block.go
@@ -96,7 +96,6 @@ func (api *APIImpl) CallBundle(ctx context.Context, txHashes []common.Hash, stat
 		timeoutMilliSeconds = *timeoutMilliSecondsPtr
 	}
 	timeout := time.Millisecond * time.Duration(timeoutMilliSeconds)
-
 	// Setup context so it may be cancelled the call has completed
 	// or, in case of unmetered gas, setup a context with a timeout.
 	var cancel context.CancelFunc
diff --git a/cmd/rpcdaemon/commands/trace_adhoc.go b/cmd/rpcdaemon/commands/trace_adhoc.go
index 6e9f9e15b9660ece1fb5cb2e21a467d5c1e2c473..71dc7e375069d13fdc676d5bc03875427587b8f9 100644
--- a/cmd/rpcdaemon/commands/trace_adhoc.go
+++ b/cmd/rpcdaemon/commands/trace_adhoc.go
@@ -532,7 +532,7 @@ func (api *TraceAPIImpl) ReplayTransaction(ctx context.Context, txHash common.Ha
 		sdMap := make(map[common.Address]*StateDiffAccount)
 		traceResult.StateDiff = sdMap
 		sd := &StateDiff{sdMap: sdMap}
-		if err = ibs.FinalizeTx(ctx, sd); err != nil {
+		if err = ibs.FinalizeTx(chainConfig.Rules(blockNumber), sd); err != nil {
 			return nil, err
 		}
 	}
@@ -786,7 +786,7 @@ func (api *TraceAPIImpl) Call(ctx context.Context, args TraceCallParam, traceTyp
 		sdMap := make(map[common.Address]*StateDiffAccount)
 		traceResult.StateDiff = sdMap
 		sd := &StateDiff{sdMap: sdMap}
-		if err = ibs.FinalizeTx(ctx, sd); err != nil {
+		if err = ibs.FinalizeTx(evm.ChainRules, sd); err != nil {
 			return nil, err
 		}
 		// Create initial IntraBlockState, we will compare it with ibs (IntraBlockState after the transaction)
@@ -901,6 +901,9 @@ func (api *TraceAPIImpl) doCallMany(ctx context.Context, dbtx ethdb.Tx, callPara
 	results := []*TraceCallResult{}
 
 	for txIndex, args := range callParams {
+		if err := common.Stopped(ctx.Done()); err != nil {
+			return nil, err
+		}
 		traceResult := &TraceCallResult{Trace: []*ParityTrace{}}
 		var traceTypeTrace, traceTypeStateDiff, traceTypeVmTrace bool
 		for _, traceType := range args.traceTypes {
@@ -959,18 +962,18 @@ func (api *TraceAPIImpl) doCallMany(ctx context.Context, dbtx ethdb.Tx, callPara
 			sdMap := make(map[common.Address]*StateDiffAccount)
 			traceResult.StateDiff = sdMap
 			sd := &StateDiff{sdMap: sdMap}
-			if err = ibs.FinalizeTx(ctx, sd); err != nil {
+			if err = ibs.FinalizeTx(evm.ChainRules, sd); err != nil {
 				return nil, err
 			}
 			sd.CompareStates(initialIbs, ibs)
-			if err = ibs.CommitBlock(ctx, cachedWriter); err != nil {
+			if err = ibs.CommitBlock(evm.ChainRules, cachedWriter); err != nil {
 				return nil, err
 			}
 		} else {
-			if err = ibs.FinalizeTx(ctx, noop); err != nil {
+			if err = ibs.FinalizeTx(evm.ChainRules, noop); err != nil {
 				return nil, err
 			}
-			if err = ibs.CommitBlock(ctx, cachedWriter); err != nil {
+			if err = ibs.CommitBlock(evm.ChainRules, cachedWriter); err != nil {
 				return nil, err
 			}
 		}
diff --git a/cmd/rpcdaemon/rpcdaemontest/test_util.go b/cmd/rpcdaemon/rpcdaemontest/test_util.go
index 7ee937f5b7c08248e0f9935fc6edc15c2c6b46ed..03de80a6cea2f136eabde789e6d5dec79d547c7a 100644
--- a/cmd/rpcdaemon/rpcdaemontest/test_util.go
+++ b/cmd/rpcdaemon/rpcdaemontest/test_util.go
@@ -74,7 +74,7 @@ func CreateTestKV(t *testing.T) ethdb.RwKV {
 			err error
 		)
 
-		ctx := gspec.Config.WithEIPsFlags(context.Background(), block.Number().Uint64())
+		ctx := context.Background()
 		switch i {
 		case 0:
 			txn, err = types.SignTx(types.NewTransaction(0, theAddr, uint256.NewInt(1000000000000000), 21000, new(uint256.Int), nil), *signer, key)
diff --git a/cmd/state/commands/opcode_tracer.go b/cmd/state/commands/opcode_tracer.go
index 6c121ad435d8ed0803c82aa11caacd4ac0ce5cfe..a471e06fbc522a66e7fa854a4343631cfb318203 100644
--- a/cmd/state/commands/opcode_tracer.go
+++ b/cmd/state/commands/opcode_tracer.go
@@ -674,6 +674,7 @@ func runBlock(ibs *state.IntraBlockState, txnWriter state.StateWriter, blockWrit
 	if chainConfig.DAOForkSupport && chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(block.Number()) == 0 {
 		misc.ApplyDAOHardFork(ibs)
 	}
+	rules := chainConfig.Rules(block.NumberU64())
 	for i, tx := range block.Transactions() {
 		ibs.Prepare(tx.Hash(), block.Hash(), i)
 		receipt, _, err := core.ApplyTransaction(chainConfig, getHeader, engine, nil, gp, ibs, txnWriter, header, tx, usedGas, vmConfig, checkTEVM)
@@ -689,8 +690,7 @@ func runBlock(ibs *state.IntraBlockState, txnWriter state.StateWriter, blockWrit
 			return nil, fmt.Errorf("finalize of block %d failed: %v", block.NumberU64(), err)
 		}
 
-		ctx := chainConfig.WithEIPsFlags(context.Background(), header.Number.Uint64())
-		if err := ibs.CommitBlock(ctx, blockWriter); err != nil {
+		if err := ibs.CommitBlock(rules, blockWriter); err != nil {
 			return nil, fmt.Errorf("committing block %d failed: %v", block.NumberU64(), err)
 		}
 	}
diff --git a/core/blockchain.go b/core/blockchain.go
index 47b8fba13caee44761783b8a290877ef912b21d7..363c4174c04df2f5997fec90faa08b56054f4db0 100644
--- a/core/blockchain.go
+++ b/core/blockchain.go
@@ -18,7 +18,6 @@
 package core
 
 import (
-	"context"
 	"encoding/json"
 	"fmt"
 	"os"
@@ -206,8 +205,7 @@ func FinalizeBlockExecution(engine consensus.Engine, header *types.Header, txs t
 		return CallContract(contract, data, *cc, ibs, header, engine)
 	})
 
-	ctx := cc.WithEIPsFlags(context.Background(), header.Number.Uint64())
-	if err := ibs.CommitBlock(ctx, stateWriter); err != nil {
+	if err := ibs.CommitBlock(cc.Rules(header.Number.Uint64()), stateWriter); err != nil {
 		return fmt.Errorf("committing block %d failed: %v", header.Number.Uint64(), err)
 	}
 	if err := stateWriter.WriteChangeSets(); err != nil {
diff --git a/core/chain_makers.go b/core/chain_makers.go
index 7f10c0b33c96ea35103a2d804014347209583ed7..64ae4ae39651716a8e5d9803a09e6563a31cf889 100644
--- a/core/chain_makers.go
+++ b/core/chain_makers.go
@@ -279,9 +279,8 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
 			if _, err := b.engine.FinalizeAndAssemble(config, b.header, ibs, b.txs, b.uncles, b.receipts, nil); err != nil {
 				return nil, nil, fmt.Errorf("call to FinaliseAndAssemble: %w", err)
 			}
-			ctx := config.WithEIPsFlags(context.Background(), b.header.Number.Uint64())
 			// Write state changes to db
-			if err := ibs.CommitBlock(ctx, plainStateWriter); err != nil {
+			if err := ibs.CommitBlock(config.Rules(b.header.Number.Uint64()), plainStateWriter); err != nil {
 				return nil, nil, fmt.Errorf("call to CommitBlock to plainStateWriter: %w", err)
 			}
 
diff --git a/core/genesis.go b/core/genesis.go
index cab47eb6ed3f451c87220bb66e3aae4ae0d99abd..2fa5aad5023cdbc43894395dc9dac3456eb7c79f 100644
--- a/core/genesis.go
+++ b/core/genesis.go
@@ -350,7 +350,7 @@ func (g *Genesis) ToBlock() (*types.Block, *state.IntraBlockState, error) {
 				statedb.SetIncarnation(addr, 1)
 			}
 		}
-		if err := statedb.FinalizeTx(context.Background(), w); err != nil {
+		if err := statedb.FinalizeTx(params.Rules{}, w); err != nil {
 			panic(err)
 		}
 		root, err = trie.CalcRoot("genesis", tx)
@@ -426,7 +426,7 @@ func (g *Genesis) WriteGenesisState(tx ethdb.RwTx, history bool) (*types.Block,
 
 	blockWriter := state.NewPlainStateWriter(tx, tx, 0)
 
-	if err := statedb.CommitBlock(context.Background(), blockWriter); err != nil {
+	if err := statedb.CommitBlock(params.Rules{}, blockWriter); err != nil {
 		return nil, statedb, fmt.Errorf("cannot write state: %v", err)
 	}
 	if err := blockWriter.WriteChangeSets(); err != nil {
diff --git a/core/state/database_test.go b/core/state/database_test.go
index 47c2f1bb23d697fa6675612d6428b046306a8e31..913eb7c33c6d6cb82a3a4bbd5c624f0768296e3c 100644
--- a/core/state/database_test.go
+++ b/core/state/database_test.go
@@ -824,28 +824,27 @@ func TestReproduceCrash(t *testing.T) {
 	db := kv.NewTestDB(t)
 	tsw := state.NewPlainStateWriter(db, nil, 0)
 	intraBlockState := state.New(state.NewPlainStateReader(db))
-	ctx := context.Background()
 	// Start the 1st transaction
 	intraBlockState.CreateAccount(contract, true)
-	if err := intraBlockState.FinalizeTx(ctx, tsw); err != nil {
+	if err := intraBlockState.FinalizeTx(params.Rules{}, tsw); err != nil {
 		t.Errorf("error finalising 1st tx: %v", err)
 	}
 	// Start the 2nd transaction
 	intraBlockState.SetState(contract, &storageKey1, *value1)
-	if err := intraBlockState.FinalizeTx(ctx, tsw); err != nil {
+	if err := intraBlockState.FinalizeTx(params.Rules{}, tsw); err != nil {
 		t.Errorf("error finalising 1st tx: %v", err)
 	}
 	// Start the 3rd transaction
 	intraBlockState.AddBalance(contract, uint256.NewInt(1000000000))
 	intraBlockState.SetState(contract, &storageKey2, *value2)
-	if err := intraBlockState.FinalizeTx(ctx, tsw); err != nil {
+	if err := intraBlockState.FinalizeTx(params.Rules{}, tsw); err != nil {
 		t.Errorf("error finalising 1st tx: %v", err)
 	}
 	// Start the 4th transaction - clearing both storage cells
 	intraBlockState.SubBalance(contract, uint256.NewInt(1000000000))
 	intraBlockState.SetState(contract, &storageKey1, *value0)
 	intraBlockState.SetState(contract, &storageKey2, *value0)
-	if err := intraBlockState.FinalizeTx(ctx, tsw); err != nil {
+	if err := intraBlockState.FinalizeTx(params.Rules{}, tsw); err != nil {
 		t.Errorf("error finalising 1st tx: %v", err)
 	}
 }
@@ -1202,7 +1201,6 @@ func TestChangeAccountCodeBetweenBlocks(t *testing.T) {
 	db := kv.NewTestDB(t)
 	r, tsw := state.NewPlainStateReader(db), state.NewPlainStateWriter(db, nil, 0)
 	intraBlockState := state.New(r)
-	ctx := context.Background()
 	// Start the 1st transaction
 	intraBlockState.CreateAccount(contract, true)
 
@@ -1210,10 +1208,10 @@ func TestChangeAccountCodeBetweenBlocks(t *testing.T) {
 
 	intraBlockState.SetCode(contract, oldCode)
 	intraBlockState.AddBalance(contract, uint256.NewInt(1000000000))
-	if err := intraBlockState.FinalizeTx(ctx, tsw); err != nil {
+	if err := intraBlockState.FinalizeTx(params.Rules{}, tsw); err != nil {
 		t.Errorf("error finalising 1st tx: %w", err)
 	}
-	err := db.RwKV().View(ctx, func(tx ethdb.Tx) error {
+	err := db.RwKV().View(context.Background(), func(tx ethdb.Tx) error {
 		_, err := trie.CalcRoot("test", tx)
 		return err
 	})
@@ -1226,7 +1224,7 @@ func TestChangeAccountCodeBetweenBlocks(t *testing.T) {
 	newCode := []byte{0x04, 0x04, 0x04, 0x04}
 	intraBlockState.SetCode(contract, newCode)
 
-	if err := intraBlockState.FinalizeTx(ctx, tsw); err != nil {
+	if err := intraBlockState.FinalizeTx(params.Rules{}, tsw); err != nil {
 		t.Errorf("error finalising 1st tx: %v", err)
 	}
 
@@ -1244,7 +1242,6 @@ func TestCacheCodeSizeSeparately(t *testing.T) {
 	db := kv.NewTestDB(t)
 	r, w := state.NewPlainStateReader(db), state.NewPlainStateWriter(db, nil, 0)
 	intraBlockState := state.New(r)
-	ctx := context.Background()
 	// Start the 1st transaction
 	intraBlockState.CreateAccount(contract, true)
 
@@ -1252,10 +1249,10 @@ func TestCacheCodeSizeSeparately(t *testing.T) {
 
 	intraBlockState.SetCode(contract, code)
 	intraBlockState.AddBalance(contract, uint256.NewInt(1000000000))
-	if err := intraBlockState.FinalizeTx(ctx, w); err != nil {
+	if err := intraBlockState.FinalizeTx(params.Rules{}, w); err != nil {
 		t.Errorf("error finalising 1st tx: %v", err)
 	}
-	if err := intraBlockState.CommitBlock(ctx, w); err != nil {
+	if err := intraBlockState.CommitBlock(params.Rules{}, w); err != nil {
 		t.Errorf("error committing block: %v", err)
 	}
 
@@ -1286,10 +1283,10 @@ func TestCacheCodeSizeInTrie(t *testing.T) {
 
 	intraBlockState.SetCode(contract, code)
 	intraBlockState.AddBalance(contract, uint256.NewInt(1000000000))
-	if err := intraBlockState.FinalizeTx(ctx, w); err != nil {
+	if err := intraBlockState.FinalizeTx(params.Rules{}, w); err != nil {
 		t.Errorf("error finalising 1st tx: %v", err)
 	}
-	if err := intraBlockState.CommitBlock(ctx, w); err != nil {
+	if err := intraBlockState.CommitBlock(params.Rules{}, w); err != nil {
 		t.Errorf("error committing block: %v", err)
 	}
 
diff --git a/core/state/intra_block_state.go b/core/state/intra_block_state.go
index f3acdcaf712f7c1ee783902ad5381a85f991259b..8e56fe0cd1ec11122070b53845acb0feac3ca183 100644
--- a/core/state/intra_block_state.go
+++ b/core/state/intra_block_state.go
@@ -18,7 +18,6 @@
 package state
 
 import (
-	"context"
 	"fmt"
 	"sort"
 
@@ -734,8 +733,7 @@ func updateAccount(EIP158Enabled bool, stateWriter StateWriter, addr common.Addr
 }
 
 // FinalizeTx should be called after every transaction.
-func (sdb *IntraBlockState) FinalizeTx(ctx context.Context, stateWriter StateWriter) error {
-	EIP158Enabled := params.GetForkFlag(ctx, params.IsEIP158Enabled)
+func (sdb *IntraBlockState) FinalizeTx(chainRules params.Rules, stateWriter StateWriter) error {
 	for addr := range sdb.journal.dirties {
 		stateObject, exist := sdb.stateObjects[addr]
 		if !exist {
@@ -748,7 +746,7 @@ func (sdb *IntraBlockState) FinalizeTx(ctx context.Context, stateWriter StateWri
 			continue
 		}
 
-		if err := updateAccount(EIP158Enabled, stateWriter, addr, stateObject, true); err != nil {
+		if err := updateAccount(chainRules.IsEIP158, stateWriter, addr, stateObject, true); err != nil {
 			return err
 		}
 
@@ -761,14 +759,13 @@ func (sdb *IntraBlockState) FinalizeTx(ctx context.Context, stateWriter StateWri
 
 // CommitBlock finalizes the state by removing the self destructed objects
 // and clears the journal as well as the refunds.
-func (sdb *IntraBlockState) CommitBlock(ctx context.Context, stateWriter StateWriter) error {
-	EIP158Enabled := params.GetForkFlag(ctx, params.IsEIP158Enabled)
+func (sdb *IntraBlockState) CommitBlock(chainRules params.Rules, stateWriter StateWriter) error {
 	for addr := range sdb.journal.dirties {
 		sdb.stateObjectsDirty[addr] = struct{}{}
 	}
 	for addr, stateObject := range sdb.stateObjects {
 		_, isDirty := sdb.stateObjectsDirty[addr]
-		if err := updateAccount(EIP158Enabled, stateWriter, addr, stateObject, isDirty); err != nil {
+		if err := updateAccount(chainRules.IsEIP158, stateWriter, addr, stateObject, isDirty); err != nil {
 			return err
 		}
 	}
diff --git a/core/state/intra_block_state_test.go b/core/state/intra_block_state_test.go
index cf2e5a8fa256f410eb676741e426f8bb411bb58e..0d3b859d370e5116b78efa061fbc80d8fbe33dcc 100644
--- a/core/state/intra_block_state_test.go
+++ b/core/state/intra_block_state_test.go
@@ -18,7 +18,6 @@ package state
 
 import (
 	"bytes"
-	"context"
 	"encoding/binary"
 	"fmt"
 	"math"
@@ -31,6 +30,7 @@ import (
 
 	"github.com/holiman/uint256"
 	"github.com/ledgerwatch/erigon/ethdb/kv"
+	"github.com/ledgerwatch/erigon/params"
 	"gopkg.in/check.v1"
 
 	"github.com/ledgerwatch/erigon/common"
@@ -321,12 +321,12 @@ func (test *snapshotTest) checkEqual(state, checkstate *IntraBlockState) error {
 func (s *StateSuite) TestTouchDelete(c *check.C) {
 	s.state.GetOrNewStateObject(common.Address{})
 
-	err := s.state.FinalizeTx(context.Background(), s.w)
+	err := s.state.FinalizeTx(params.Rules{}, s.w)
 	if err != nil {
 		c.Fatal("error while finalize", err)
 	}
 
-	err = s.state.CommitBlock(context.Background(), s.w)
+	err = s.state.CommitBlock(params.Rules{}, s.w)
 	if err != nil {
 		c.Fatal("error while commit", err)
 	}
diff --git a/core/state/state_test.go b/core/state/state_test.go
index a9543a938731f3375c4798add78679ae21d29c54..7a7df83f68d7f612e4f38d03c4579b2b99b75ea2 100644
--- a/core/state/state_test.go
+++ b/core/state/state_test.go
@@ -23,6 +23,7 @@ import (
 
 	"github.com/holiman/uint256"
 	"github.com/ledgerwatch/erigon/ethdb/kv"
+	"github.com/ledgerwatch/erigon/params"
 	checker "gopkg.in/check.v1"
 
 	"github.com/ledgerwatch/erigon/common"
@@ -53,16 +54,15 @@ func (s *StateSuite) TestDump(c *checker.C) {
 	obj3.SetBalance(uint256.NewInt(44))
 
 	// write some of them to the trie
-	ctx := context.TODO()
 	err := s.w.UpdateAccountData(obj1.address, &obj1.data, new(accounts.Account))
 	c.Check(err, checker.IsNil)
 	err = s.w.UpdateAccountData(obj2.address, &obj2.data, new(accounts.Account))
 	c.Check(err, checker.IsNil)
 
-	err = s.state.FinalizeTx(ctx, s.w)
+	err = s.state.FinalizeTx(params.Rules{}, s.w)
 	c.Check(err, checker.IsNil)
 
-	err = s.state.CommitBlock(ctx, s.w)
+	err = s.state.CommitBlock(params.Rules{}, s.w)
 	c.Check(err, checker.IsNil)
 
 	// check that dump contains the state objects that are in trie
@@ -118,11 +118,10 @@ func (s *StateSuite) TestNull(c *checker.C) {
 
 	s.state.SetState(address, &common.Hash{}, value)
 
-	ctx := context.TODO()
-	err := s.state.FinalizeTx(ctx, s.w)
+	err := s.state.FinalizeTx(params.Rules{}, s.w)
 	c.Check(err, checker.IsNil)
 
-	err = s.state.CommitBlock(ctx, s.w)
+	err = s.state.CommitBlock(params.Rules{}, s.w)
 	c.Check(err, checker.IsNil)
 
 	s.state.GetCommittedState(address, &common.Hash{}, &value)
@@ -171,7 +170,6 @@ func (s *StateSuite) TestSnapshotEmpty(c *checker.C) {
 func TestSnapshot2(t *testing.T) {
 
 	db := kv.NewMemDatabase()
-	ctx := context.TODO()
 	w := NewDbStateWriter(db, 0)
 	state := New(NewDbStateReader(db))
 
@@ -194,13 +192,13 @@ func TestSnapshot2(t *testing.T) {
 	so0.deleted = false
 	state.setStateObject(so0)
 
-	err := state.FinalizeTx(ctx, w)
+	err := state.FinalizeTx(params.Rules{}, w)
 	if err != nil {
 		t.Fatal("error while finalizing transaction", err)
 	}
 	w = NewDbStateWriter(db, 1)
 
-	err = state.CommitBlock(ctx, w)
+	err = state.CommitBlock(params.Rules{}, w)
 	if err != nil {
 		t.Fatal("error while committing state", err)
 	}
@@ -300,7 +298,6 @@ func TestDump(t *testing.T) {
 	obj3.SetBalance(uint256.NewInt(44))
 
 	// write some of them to the trie
-	ctx := context.TODO()
 	err := w.UpdateAccountData(obj1.address, &obj1.data, new(accounts.Account))
 	if err != nil {
 		t.Fatal(err)
@@ -310,13 +307,13 @@ func TestDump(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	err = state.FinalizeTx(ctx, w)
+	err = state.FinalizeTx(params.Rules{}, w)
 	if err != nil {
 		t.Fatal(err)
 	}
 
 	blockWriter := NewPlainStateWriter(tx, tx, 1)
-	err = state.CommitBlock(ctx, blockWriter)
+	err = state.CommitBlock(params.Rules{}, blockWriter)
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/core/state_processor.go b/core/state_processor.go
index 7f868ef454a21322136a9be8f1946831584cbe09..e9ad615960dc311cf3d968ecda7495cc8e265d12 100644
--- a/core/state_processor.go
+++ b/core/state_processor.go
@@ -17,7 +17,6 @@
 package core
 
 import (
-	"context"
 	"fmt"
 
 	"github.com/ledgerwatch/erigon/common"
@@ -91,14 +90,10 @@ func applyTransaction(config *params.ChainConfig, gp *GasPool, statedb *state.In
 		return nil, nil, err
 	}
 
-	ctx := config.WithEIPsFlags(context.Background(), header.Number.Uint64())
 	txContext := NewEVMTxContext(msg)
 	if cfg.TraceJumpDest {
 		txContext.TxHash = tx.Hash()
 	}
-	// Add addresses to access list if applicable
-	// about the transaction and calling mechanisms.
-	cfg.SkipAnalysis = SkipAnalysis(config, header.Number.Uint64())
 
 	// Update the evm with the new transaction context.
 	evm.Reset(txContext, statedb)
@@ -108,7 +103,7 @@ func applyTransaction(config *params.ChainConfig, gp *GasPool, statedb *state.In
 		return nil, nil, err
 	}
 	// Update the state with pending changes
-	if err = statedb.FinalizeTx(ctx, stateWriter); err != nil {
+	if err = statedb.FinalizeTx(evm.ChainRules, stateWriter); err != nil {
 		return nil, nil, err
 	}
 
@@ -148,6 +143,9 @@ func ApplyTransaction(config *params.ChainConfig, getHeader func(hash common.Has
 	// Create a new context to be used in the EVM environment
 	blockContext := NewEVMBlockContext(header, getHeader, engine, author, checkTEVM)
 	vmenv := vm.NewEVM(blockContext, vm.TxContext{}, ibs, config, cfg)
+	// Add addresses to access list if applicable
+	// about the transaction and calling mechanisms.
+	cfg.SkipAnalysis = SkipAnalysis(config, header.Number.Uint64())
 
 	return applyTransaction(config, gp, ibs, stateWriter, header, tx, usedGas, vmenv, cfg)
 }
diff --git a/core/state_transition.go b/core/state_transition.go
index 60f8599d7cafd91b3392f6906e8fb7ecf8efd702..4491f7a1547aff2bd380b4ebafb247493d05ded0 100644
--- a/core/state_transition.go
+++ b/core/state_transition.go
@@ -230,7 +230,7 @@ func (st *StateTransition) preCheck(gasBailout bool) error {
 		}
 	}
 	// Make sure the transaction feeCap is greater than the block's baseFee.
-	if st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber) {
+	if st.evm.ChainRules.IsLondon {
 		if l := st.feeCap.BitLen(); l > 256 {
 			return fmt.Errorf("%w: address %v, feeCap bit length: %d", ErrFeeCapVeryHigh,
 				st.msg.From().Hex(), l)
@@ -282,9 +282,9 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*Executi
 	}
 	msg := st.msg
 	sender := vm.AccountRef(msg.From())
-	homestead := st.evm.ChainConfig().IsHomestead(st.evm.Context.BlockNumber)
-	istanbul := st.evm.ChainConfig().IsIstanbul(st.evm.Context.BlockNumber)
-	london := st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber)
+	homestead := st.evm.ChainRules.IsHomestead
+	istanbul := st.evm.ChainRules.IsIstanbul
+	london := st.evm.ChainRules.IsLondon
 	contractCreation := msg.To() == nil
 
 	// Check clauses 4-5, subtract intrinsic gas if everything is correct
@@ -307,7 +307,7 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*Executi
 		}
 	}
 	// Set up the initial access list.
-	if st.evm.ChainConfig().IsBerlin(st.evm.Context.BlockNumber) {
+	if st.evm.ChainRules.IsBerlin {
 		st.state.PrepareAccessList(msg.From(), msg.To(), st.evm.ActivePrecompiles(), msg.AccessList())
 	}
 
@@ -336,7 +336,7 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*Executi
 		}
 	}
 	effectiveTip := st.gasPrice
-	if st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber) {
+	if st.evm.ChainRules.IsLondon {
 		effectiveTip = cmath.Min256(st.tip, new(uint256.Int).Sub(st.feeCap, st.evm.Context.BaseFee))
 	}
 	st.state.AddBalance(st.evm.Context.Coinbase, new(uint256.Int).Mul(new(uint256.Int).SetUint64(st.gasUsed()), effectiveTip))
diff --git a/core/tx_pool_test.go b/core/tx_pool_test.go
index fba3c9911f6483fe5601363c4e496dc543796595..b28ab0c4768901d0a362ad4be67a43b77224ce58 100644
--- a/core/tx_pool_test.go
+++ b/core/tx_pool_test.go
@@ -17,7 +17,6 @@
 package core
 
 import (
-	"context"
 	"crypto/ecdsa"
 	"fmt"
 	"io/ioutil"
@@ -190,8 +189,7 @@ func TestStateChangeDuringTransactionPoolReset(t *testing.T) {
 	// setup pool with 2 transaction in it
 	// Using AddBalance instead of SetBalance to make it dirty
 	ibs.AddBalance(address, new(uint256.Int).SetUint64(params.Ether))
-	ctx := context.Background()
-	if err := ibs.CommitBlock(ctx, stateWriter); err != nil {
+	if err := ibs.CommitBlock(params.Rules{}, stateWriter); err != nil {
 		t.Fatal(err)
 	}
 	tx0 := transaction(0, 100000, key)
@@ -355,8 +353,7 @@ func TestTransactionChainFork(t *testing.T) {
 		stateWriter := state.NewPlainStateWriter(pool.chaindb, nil, 1)
 		ibs := state.New(state.NewPlainStateReader(pool.chaindb))
 		ibs.AddBalance(addr, uint256.NewInt(100000000000000))
-		ctx := context.Background()
-		if err := ibs.CommitBlock(ctx, stateWriter); err != nil {
+		if err := ibs.CommitBlock(params.Rules{}, stateWriter); err != nil {
 			t.Fatal(err)
 		}
 		pool.ResetHead(1000000000, 1)
@@ -384,8 +381,7 @@ func TestTransactionDoubleNonce(t *testing.T) {
 		stateWriter := state.NewPlainStateWriter(pool.chaindb, nil, 1)
 		ibs := state.New(state.NewPlainStateReader(pool.chaindb))
 		ibs.AddBalance(addr, uint256.NewInt(100000000000000))
-		ctx := context.Background()
-		if err := ibs.CommitBlock(ctx, stateWriter); err != nil {
+		if err := ibs.CommitBlock(params.Rules{}, stateWriter); err != nil {
 			t.Fatal(err)
 		}
 		pool.ResetHead(1000000000, 1)
@@ -1739,7 +1735,7 @@ func testTransactionJournaling(t *testing.T, nolocals bool) {
 	ibs := state.New(state.NewPlainStateReader(db))
 	ibs.AddBalance(crypto.PubkeyToAddress(local.PublicKey), uint256.NewInt(1000000000))
 	ibs.AddBalance(crypto.PubkeyToAddress(remote.PublicKey), uint256.NewInt(1000000000))
-	if err := ibs.CommitBlock(context.Background(), stateWriter); err != nil {
+	if err := ibs.CommitBlock(params.Rules{}, stateWriter); err != nil {
 		t.Fatal(err)
 	}
 
@@ -1773,7 +1769,7 @@ func testTransactionJournaling(t *testing.T, nolocals bool) {
 	stateWriter = state.NewPlainStateWriter(db, nil, 1)
 	ibs = state.New(state.NewPlainStateReader(db))
 	ibs.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1)
-	if err := ibs.CommitBlock(context.Background(), stateWriter); err != nil {
+	if err := ibs.CommitBlock(params.Rules{}, stateWriter); err != nil {
 		t.Fatal(err)
 	}
 
@@ -1802,7 +1798,7 @@ func testTransactionJournaling(t *testing.T, nolocals bool) {
 	stateWriter = state.NewPlainStateWriter(db, nil, 1)
 	ibs = state.New(state.NewPlainStateReader(db))
 	ibs.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 2)
-	if err := ibs.CommitBlock(context.Background(), stateWriter); err != nil {
+	if err := ibs.CommitBlock(params.Rules{}, stateWriter); err != nil {
 		t.Fatal(err)
 	}
 	pool.ResetHead(1000000000, 1)
@@ -1814,7 +1810,7 @@ func testTransactionJournaling(t *testing.T, nolocals bool) {
 	stateWriter = state.NewPlainStateWriter(db, nil, 1)
 	ibs = state.New(state.NewPlainStateReader(db))
 	ibs.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1)
-	if err := ibs.CommitBlock(context.Background(), stateWriter); err != nil {
+	if err := ibs.CommitBlock(params.Rules{}, stateWriter); err != nil {
 		t.Fatal(err)
 	}
 
diff --git a/core/vm/eips.go b/core/vm/eips.go
index 97c26705e6980c623697b40b704dcd335a029e7b..b428a3a823c9d58506270d6d0e120007da80c69a 100644
--- a/core/vm/eips.go
+++ b/core/vm/eips.go
@@ -99,7 +99,7 @@ func enable1344(jt *JumpTable) {
 
 // opChainID implements CHAINID opcode
 func opChainID(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
-	chainId, _ := uint256.FromBig(interpreter.evm.chainConfig.ChainID)
+	chainId, _ := uint256.FromBig(interpreter.evm.ChainRules.ChainID)
 	callContext.stack.Push(chainId)
 	return nil, nil
 }
diff --git a/core/vm/evm.go b/core/vm/evm.go
index 7b9bdaad28d4d42d23987eda803f0ed2d4c32aea..bded07148ab9f2cbb9583d5e95e6cdd746d97532 100644
--- a/core/vm/evm.go
+++ b/core/vm/evm.go
@@ -48,11 +48,11 @@ type (
 // configuration
 func (evm *EVM) ActivePrecompiles() []common.Address {
 	switch {
-	case evm.chainRules.IsBerlin:
+	case evm.ChainRules.IsBerlin:
 		return PrecompiledAddressesBerlin
-	case evm.chainRules.IsIstanbul:
+	case evm.ChainRules.IsIstanbul:
 		return PrecompiledAddressesIstanbul
-	case evm.chainRules.IsByzantium:
+	case evm.ChainRules.IsByzantium:
 		return PrecompiledAddressesByzantium
 	default:
 		return PrecompiledAddressesHomestead
@@ -62,11 +62,11 @@ func (evm *EVM) ActivePrecompiles() []common.Address {
 func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) {
 	var precompiles map[common.Address]PrecompiledContract
 	switch {
-	case evm.chainRules.IsBerlin:
+	case evm.ChainRules.IsBerlin:
 		precompiles = PrecompiledContractsBerlin
-	case evm.chainRules.IsIstanbul:
+	case evm.ChainRules.IsIstanbul:
 		precompiles = PrecompiledContractsIstanbul
-	case evm.chainRules.IsByzantium:
+	case evm.ChainRules.IsByzantium:
 		precompiles = PrecompiledContractsByzantium
 	default:
 		precompiles = PrecompiledContractsHomestead
@@ -147,7 +147,7 @@ type EVM struct {
 	// chainConfig contains information about the current chain
 	chainConfig *params.ChainConfig
 	// chain rules contains the chain rules for the current epoch
-	chainRules params.Rules
+	ChainRules params.Rules
 	// virtual machine configuration options used to initialise the
 	// evm.
 	vmConfig Config
@@ -173,7 +173,7 @@ func NewEVM(blockCtx BlockContext, txCtx TxContext, state IntraBlockState, chain
 		IntraBlockState: state,
 		vmConfig:        vmConfig,
 		chainConfig:     chainConfig,
-		chainRules:      chainConfig.Rules(blockCtx.BlockNumber),
+		ChainRules:      chainConfig.Rules(blockCtx.BlockNumber),
 	}
 
 	evm.interpreters = []Interpreter{
@@ -240,7 +240,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
 		snapshot = evm.IntraBlockState.Snapshot()
 	)
 	if !evm.IntraBlockState.Exist(addr) {
-		if !isPrecompile && evm.chainRules.IsEIP158 && value.Sign() == 0 {
+		if !isPrecompile && evm.ChainRules.IsEIP158 && value.Sign() == 0 {
 			return nil, gas, nil
 		}
 		evm.IntraBlockState.CreateAccount(addr, false)
@@ -497,7 +497,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
 	evm.IntraBlockState.SetNonce(caller.Address(), nonce+1)
 	// We add this to the access list _before_ taking a snapshot. Even if the creation fails,
 	// the access-list change should not be rolled back
-	if evm.chainRules.IsBerlin {
+	if evm.ChainRules.IsBerlin {
 		evm.IntraBlockState.AddAddressToAccessList(address)
 	}
 	// Ensure there's no existing contract already at the designated address
@@ -509,7 +509,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
 	// Create a new account on the state
 	snapshot := evm.IntraBlockState.Snapshot()
 	evm.IntraBlockState.CreateAccount(address, true)
-	if evm.chainRules.IsEIP158 {
+	if evm.ChainRules.IsEIP158 {
 		evm.IntraBlockState.SetNonce(address, 1)
 	}
 	evm.Context.Transfer(evm.IntraBlockState, caller.Address(), address, value, false /* bailout */)
@@ -526,11 +526,11 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
 	ret, err = run(evm, contract, nil, false)
 
 	// check whether the max code size has been exceeded
-	maxCodeSizeExceeded := evm.chainRules.IsEIP158 && len(ret) > params.MaxCodeSize
+	maxCodeSizeExceeded := evm.ChainRules.IsEIP158 && len(ret) > params.MaxCodeSize
 
 	// Reject code starting with 0xEF if EIP-3541 is enabled.
 	if err == nil && !maxCodeSizeExceeded {
-		if evm.chainRules.IsLondon && len(ret) >= 1 && ret[0] == 0xEF {
+		if evm.ChainRules.IsLondon && len(ret) >= 1 && ret[0] == 0xEF {
 			err = ErrInvalidCode
 		}
 	}
@@ -550,7 +550,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
 	// When an error was returned by the EVM or when setting the creation code
 	// above we revert to the snapshot and consume any gas remaining. Additionally
 	// when we're in homestead this also counts for code storage gas errors.
-	if maxCodeSizeExceeded || (err != nil && (evm.chainRules.IsHomestead || err != ErrCodeStoreOutOfGas)) {
+	if maxCodeSizeExceeded || (err != nil && (evm.ChainRules.IsHomestead || err != ErrCodeStoreOutOfGas)) {
 		evm.IntraBlockState.RevertToSnapshot(snapshot)
 		if err != ErrExecutionReverted {
 			contract.UseGas(contract.Gas)
diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go
index cd96ced3b251a6efb2f4c76cc832b002588de425..efd5fa7c2986c3c0821f682bc3467981c5a7cc68 100644
--- a/core/vm/gas_table.go
+++ b/core/vm/gas_table.go
@@ -104,7 +104,7 @@ func gasSStore(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory, me
 	// The legacy gas metering only takes into consideration the current state
 	// Legacy rules should be applied if we are in Petersburg (removal of EIP-1283)
 	// OR Constantinople is not active
-	if evm.chainRules.IsPetersburg || !evm.chainRules.IsConstantinople {
+	if evm.ChainRules.IsPetersburg || !evm.ChainRules.IsConstantinople {
 		// This checks for 3 scenario's and calculates gas accordingly:
 		//
 		// 1. From a zero-value address to a non-zero value         (NEW VALUE)
@@ -336,7 +336,7 @@ func gasCall(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memo
 		transfersValue = !stack.Back(2).IsZero()
 		address        = common.Address(stack.Back(1).Bytes20())
 	)
-	if evm.chainRules.IsEIP158 {
+	if evm.ChainRules.IsEIP158 {
 		if transfersValue && evm.IntraBlockState.Empty(address) {
 			gas += params.CallNewAccountGas
 		}
@@ -355,7 +355,7 @@ func gasCall(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memo
 		return 0, ErrGasUintOverflow
 	}
 
-	evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, gas, stack.Back(0))
+	evm.callGasTemp, err = callGas(evm.ChainRules.IsEIP150, contract.Gas, gas, stack.Back(0))
 	if err != nil {
 		return 0, err
 	}
@@ -380,7 +380,7 @@ func gasCallCode(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory,
 	if gas, overflow = math.SafeAdd(gas, memoryGas); overflow {
 		return 0, ErrGasUintOverflow
 	}
-	evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, gas, stack.Back(0))
+	evm.callGasTemp, err = callGas(evm.ChainRules.IsEIP150, contract.Gas, gas, stack.Back(0))
 	if err != nil {
 		return 0, err
 	}
@@ -395,7 +395,7 @@ func gasDelegateCall(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memo
 	if err != nil {
 		return 0, err
 	}
-	evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, gas, stack.Back(0))
+	evm.callGasTemp, err = callGas(evm.ChainRules.IsEIP150, contract.Gas, gas, stack.Back(0))
 	if err != nil {
 		return 0, err
 	}
@@ -411,7 +411,7 @@ func gasStaticCall(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory
 	if err != nil {
 		return 0, err
 	}
-	evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, gas, stack.Back(0))
+	evm.callGasTemp, err = callGas(evm.ChainRules.IsEIP150, contract.Gas, gas, stack.Back(0))
 	if err != nil {
 		return 0, err
 	}
@@ -425,11 +425,11 @@ func gasStaticCall(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory
 func gasSelfdestruct(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) {
 	var gas uint64
 	// EIP150 homestead gas reprice fork:
-	if evm.chainRules.IsEIP150 {
+	if evm.ChainRules.IsEIP150 {
 		gas = params.SelfdestructGasEIP150
 		var address = common.Address(stack.Back(0).Bytes20())
 
-		if evm.chainRules.IsEIP158 {
+		if evm.ChainRules.IsEIP158 {
 			// if empty and transfers value
 			if evm.IntraBlockState.Empty(address) && evm.IntraBlockState.GetBalance(contract.Address()).Sign() != 0 {
 				gas += params.CreateBySelfdestructGas
diff --git a/core/vm/gas_table_test.go b/core/vm/gas_table_test.go
index 585df1ae71fcbc47ccae030eacf3608d427a1a87..022741d36bb8402728f082c353f3cf8f763465c4 100644
--- a/core/vm/gas_table_test.go
+++ b/core/vm/gas_table_test.go
@@ -17,7 +17,6 @@
 package vm
 
 import (
-	"context"
 	"errors"
 	"math"
 	"strconv"
@@ -95,7 +94,7 @@ func TestEIP2200(t *testing.T) {
 			s.SetCode(address, hexutil.MustDecode(tt.input))
 			s.SetState(address, &common.Hash{}, *uint256.NewInt(uint64(tt.original)))
 
-			_ = s.CommitBlock(context.Background(), state.NewPlainStateWriter(tx, tx, 0))
+			_ = s.CommitBlock(params.AllEthashProtocolChanges.Rules(0), state.NewPlainStateWriter(tx, tx, 0))
 			vmctx := BlockContext{
 				CanTransfer: func(IntraBlockState, common.Address, *uint256.Int) bool { return true },
 				Transfer:    func(IntraBlockState, common.Address, common.Address, *uint256.Int, bool) {},
diff --git a/core/vm/instructions.go b/core/vm/instructions.go
index 2dc492f70a105fb1030e58453aa09a140eac5a44..2768b774978ea50461a3f01fafe16c25368d71f3 100644
--- a/core/vm/instructions.go
+++ b/core/vm/instructions.go
@@ -620,7 +620,7 @@ func opCreate(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]
 		input  = callContext.memory.GetCopy(offset.Uint64(), size.Uint64())
 		gas    = callContext.contract.Gas
 	)
-	if interpreter.evm.chainRules.IsEIP150 {
+	if interpreter.evm.ChainRules.IsEIP150 {
 		gas -= gas / 64
 	}
 	// reuse size int for stackvalue
@@ -634,7 +634,7 @@ func opCreate(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]
 	// homestead we must check for CodeStoreOutOfGasError (homestead only
 	// rule) and treat as an error, if the ruleset is frontier we must
 	// ignore this error and pretend the operation was successful.
-	if interpreter.evm.chainRules.IsHomestead && suberr == ErrCodeStoreOutOfGas {
+	if interpreter.evm.ChainRules.IsHomestead && suberr == ErrCodeStoreOutOfGas {
 		stackvalue.Clear()
 	} else if suberr != nil && suberr != ErrCodeStoreOutOfGas {
 		stackvalue.Clear()
diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go
index 3d49f721a103fd1282b3d5e9bcefc4bad15ae2e6..7a3ccc35f66143bf47011c50d2e2d72fe53f8875 100644
--- a/core/vm/interpreter.go
+++ b/core/vm/interpreter.go
@@ -85,21 +85,21 @@ type EVMInterpreter struct {
 func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter {
 	var jt *JumpTable
 	switch {
-	case evm.chainRules.IsLondon:
+	case evm.ChainRules.IsLondon:
 		jt = &londonInstructionSet
-	case evm.chainRules.IsBerlin:
+	case evm.ChainRules.IsBerlin:
 		jt = &berlinInstructionSet
-	case evm.chainRules.IsIstanbul:
+	case evm.ChainRules.IsIstanbul:
 		jt = &istanbulInstructionSet
-	case evm.chainRules.IsConstantinople:
+	case evm.ChainRules.IsConstantinople:
 		jt = &constantinopleInstructionSet
-	case evm.chainRules.IsByzantium:
+	case evm.ChainRules.IsByzantium:
 		jt = &byzantiumInstructionSet
-	case evm.chainRules.IsEIP158:
+	case evm.ChainRules.IsEIP158:
 		jt = &spuriousDragonInstructionSet
-	case evm.chainRules.IsEIP150:
+	case evm.ChainRules.IsEIP150:
 		jt = &tangerineWhistleInstructionSet
-	case evm.chainRules.IsHomestead:
+	case evm.ChainRules.IsHomestead:
 		jt = &homesteadInstructionSet
 	default:
 		jt = &frontierInstructionSet
@@ -217,7 +217,7 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
 			return nil, &ErrStackOverflow{stackLen: sLen, limit: operation.maxStack}
 		}
 		// If the operation is valid, enforce and write restrictions
-		if in.readOnly && in.evm.chainRules.IsByzantium {
+		if in.readOnly && in.evm.ChainRules.IsByzantium {
 			// If the interpreter is operating in readonly mode, make sure no
 			// state-modifying operation is performed. The 3rd stack item
 			// for a call operation is the value. Transferring value from one
diff --git a/eth/tracers/tracer.go b/eth/tracers/tracer.go
index e1f9952086dbd341a34ab0c469b0fce0f9c7fff7..64fea02981b1527b1afeb5123b7f52e5b29d0482 100644
--- a/eth/tracers/tracer.go
+++ b/eth/tracers/tracer.go
@@ -558,8 +558,8 @@ func (jst *Tracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost
 		if !jst.inited {
 			jst.ctx["block"] = env.Context.BlockNumber
 			// Compute intrinsic gas
-			isHomestead := env.ChainConfig().IsHomestead(env.Context.BlockNumber)
-			isIstanbul := env.ChainConfig().IsIstanbul(env.Context.BlockNumber)
+			isHomestead := env.ChainRules.IsHomestead
+			isIstanbul := env.ChainRules.IsIstanbul
 			var input []byte
 			if data, ok := jst.ctx["input"].([]byte); ok {
 				input = data
diff --git a/eth/tracers/tracers_test.go b/eth/tracers/tracers_test.go
index af89b561ca495329c4e0afb40c1745fce10ed327..60db77bc436d507d80a56d26d85fc170e009ff03 100644
--- a/eth/tracers/tracers_test.go
+++ b/eth/tracers/tracers_test.go
@@ -18,7 +18,6 @@ package tracers
 
 import (
 	"bytes"
-	"context"
 	"crypto/ecdsa"
 	"crypto/rand"
 	"encoding/json"
@@ -146,7 +145,6 @@ func TestPrestateTracerCreate2(t *testing.T) {
 	    gas (assuming no mem expansion): 32006
 	    result: 0x60f3f640a8508fC6a86d45DF051962668E1e8AC7
 	*/
-	ctx := context.TODO()
 	origin, _ := signer.Sender(tx)
 	txContext := vm.TxContext{
 		Origin:   origin,
@@ -176,7 +174,7 @@ func TestPrestateTracerCreate2(t *testing.T) {
 		Code:    []byte{},
 		Balance: big.NewInt(500000000000000),
 	}
-	statedb, _ := tests.MakePreState(ctx, kv.NewTestDB(t), alloc, context.BlockNumber)
+	statedb, _ := tests.MakePreState(params.Rules{}, kv.NewTestDB(t), alloc, context.BlockNumber)
 
 	// Create the tracer, the EVM environment and run it
 	tracer, err := New("prestateTracer", txContext)
@@ -210,8 +208,6 @@ func TestPrestateTracerCreate2(t *testing.T) {
 // Iterates over all the input-output datasets in the tracer test harness and
 // runs the JavaScript tracers against them.
 func TestCallTracer(t *testing.T) {
-	ctx := context.TODO()
-
 	files, filesErr := ioutil.ReadDir("testdata")
 	if filesErr != nil {
 		t.Fatalf("failed to retrieve tracer test suite: %v", filesErr)
@@ -254,7 +250,7 @@ func TestCallTracer(t *testing.T) {
 				GasLimit:    uint64(test.Context.GasLimit),
 				CheckTEVM:   func(common.Hash) (bool, error) { return false, nil },
 			}
-			statedb, _ := tests.MakePreState(ctx, kv.NewTestDB(t), test.Genesis.Alloc, uint64(test.Context.Number))
+			statedb, _ := tests.MakePreState(params.Rules{}, kv.NewTestDB(t), test.Genesis.Alloc, uint64(test.Context.Number))
 
 			// Create the tracer, the EVM environment and run it
 			tracer, err := New("callTracer", txContext)
diff --git a/migrations/receipt_repair.go b/migrations/receipt_repair.go
index 5c8ef4246cc647720e0baa80b4e4b70907115a28..e37b46083ffe38bd2b459f292849155b078b4ffa 100644
--- a/migrations/receipt_repair.go
+++ b/migrations/receipt_repair.go
@@ -2,7 +2,6 @@ package migrations
 
 import (
 	"bytes"
-	"context"
 	"encoding/binary"
 	"fmt"
 	"time"
@@ -155,8 +154,7 @@ func runBlock(ibs *state.IntraBlockState, txnWriter state.StateWriter, blockWrit
 			return nil, fmt.Errorf("finalize of block %d failed: %v", block.NumberU64(), err)
 		}
 
-		ctx := chainConfig.WithEIPsFlags(context.Background(), header.Number.Uint64())
-		if err := ibs.CommitBlock(ctx, blockWriter); err != nil {
+		if err := ibs.CommitBlock(chainConfig.Rules(header.Number.Uint64()), blockWriter); err != nil {
 			return nil, fmt.Errorf("committing block %d failed: %v", block.NumberU64(), err)
 		}
 	}
diff --git a/tests/state_test.go b/tests/state_test.go
index f787ab98357cd3282e355e5e53f982eb1798cc0b..9a3cf1576833f31c9e8b4e4612d086f27b56e063 100644
--- a/tests/state_test.go
+++ b/tests/state_test.go
@@ -82,14 +82,13 @@ func TestState(t *testing.T) {
 						if !ok {
 							return UnsupportedForkError{subtest.Fork}
 						}
-						ctx := config.WithEIPsFlags(context.Background(), 1)
-
+						rules := config.Rules(1)
 						tx, err := db.BeginRw(context.Background())
 						if err != nil {
 							t.Fatal(err)
 						}
 						defer tx.Rollback()
-						_, err = test.Run(ctx, tx, subtest, vmconfig)
+						_, err = test.Run(rules, tx, subtest, vmconfig)
 						tx.Rollback()
 						return st.checkFailure(t, err)
 					})
diff --git a/tests/state_test_util.go b/tests/state_test_util.go
index f1660e3ded508c56826f309a4e4abf3ac1c03484..79f8c095d354636f07c9dbb82fe18b56049f134a 100644
--- a/tests/state_test_util.go
+++ b/tests/state_test_util.go
@@ -17,7 +17,6 @@
 package tests
 
 import (
-	"context"
 	"encoding/hex"
 	"encoding/json"
 	"fmt"
@@ -160,8 +159,8 @@ func (t *StateTest) Subtests() []StateSubtest {
 }
 
 // Run executes a specific subtest and verifies the post-state and logs
-func (t *StateTest) Run(ctx context.Context, tx ethdb.RwTx, subtest StateSubtest, vmconfig vm.Config) (*state.IntraBlockState, error) {
-	state, root, err := t.RunNoVerify(ctx, tx, subtest, vmconfig)
+func (t *StateTest) Run(rules params.Rules, tx ethdb.RwTx, subtest StateSubtest, vmconfig vm.Config) (*state.IntraBlockState, error) {
+	state, root, err := t.RunNoVerify(rules, tx, subtest, vmconfig)
 	if err != nil {
 		return state, err
 	}
@@ -178,7 +177,7 @@ func (t *StateTest) Run(ctx context.Context, tx ethdb.RwTx, subtest StateSubtest
 }
 
 // RunNoVerify runs a specific subtest and returns the statedb and post-state root
-func (t *StateTest) RunNoVerify(ctx context.Context, kvtx ethdb.RwTx, subtest StateSubtest, vmconfig vm.Config) (*state.IntraBlockState, common.Hash, error) {
+func (t *StateTest) RunNoVerify(rules params.Rules, kvtx ethdb.RwTx, subtest StateSubtest, vmconfig vm.Config) (*state.IntraBlockState, common.Hash, error) {
 	tx := kv.WrapIntoTxDB(kvtx)
 	config, eips, err := GetChainConfig(subtest.Fork)
 	if err != nil {
@@ -192,9 +191,8 @@ func (t *StateTest) RunNoVerify(ctx context.Context, kvtx ethdb.RwTx, subtest St
 
 	readBlockNr := block.Number().Uint64()
 	writeBlockNr := readBlockNr + 1
-	ctx = config.WithEIPsFlags(ctx, writeBlockNr)
 
-	_, err = MakePreState(context.Background(), tx, t.json.Pre, readBlockNr)
+	_, err = MakePreState(params.Rules{}, tx, t.json.Pre, readBlockNr)
 	if err != nil {
 		return nil, common.Hash{}, UnsupportedForkError{subtest.Fork}
 	}
@@ -242,10 +240,10 @@ func (t *StateTest) RunNoVerify(ctx context.Context, kvtx ethdb.RwTx, subtest St
 	// - there are only 'bad' transactions, which aren't executed. In those cases,
 	//   the coinbase gets no txfee, so isn't created, and thus needs to be touched
 	statedb.AddBalance(block.Coinbase(), new(uint256.Int))
-	if err = statedb.FinalizeTx(ctx, w); err != nil {
+	if err = statedb.FinalizeTx(evm.ChainRules, w); err != nil {
 		return nil, common.Hash{}, err
 	}
-	if err = statedb.CommitBlock(ctx, w); err != nil {
+	if err = statedb.CommitBlock(evm.ChainRules, w); err != nil {
 		return nil, common.Hash{}, err
 	}
 	// Generate hashed state
@@ -300,7 +298,7 @@ func (t *StateTest) gasLimit(subtest StateSubtest) uint64 {
 	return t.json.Tx.GasLimit[t.json.Post[subtest.Fork][subtest.Index].Indexes.Gas]
 }
 
-func MakePreState(ctx context.Context, db ethdb.Database, accounts core.GenesisAlloc, blockNr uint64) (*state.IntraBlockState, error) {
+func MakePreState(rules params.Rules, db ethdb.Database, accounts core.GenesisAlloc, blockNr uint64) (*state.IntraBlockState, error) {
 	r := state.NewPlainStateReader(db)
 	statedb := state.New(r)
 	for addr, a := range accounts {
@@ -319,10 +317,10 @@ func MakePreState(ctx context.Context, db ethdb.Database, accounts core.GenesisA
 		}
 	}
 	// Commit and re-open to start with a clean state.
-	if err := statedb.FinalizeTx(ctx, state.NewPlainStateWriter(db, nil, blockNr+1)); err != nil {
+	if err := statedb.FinalizeTx(rules, state.NewPlainStateWriter(db, nil, blockNr+1)); err != nil {
 		return nil, err
 	}
-	if err := statedb.CommitBlock(ctx, state.NewPlainStateWriter(db, nil, blockNr+1)); err != nil {
+	if err := statedb.CommitBlock(rules, state.NewPlainStateWriter(db, nil, blockNr+1)); err != nil {
 		return nil, err
 	}
 	return statedb, nil
diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go
index 94ca206b08c426fbbb825ae6f6aaf210127547a5..4b192c21d6ffaf4ff233eda9893f4574352bffef 100644
--- a/tests/vm_test_util.go
+++ b/tests/vm_test_util.go
@@ -18,7 +18,6 @@ package tests
 
 import (
 	"bytes"
-	"context"
 	"encoding/json"
 	"fmt"
 	"math/big"
@@ -83,8 +82,7 @@ type vmExecMarshaling struct {
 }
 
 func (t *VMTest) Run(tx ethdb.RwTx, vmconfig vm.Config, blockNr uint64) error {
-	ctx := params.MainnetChainConfig.WithEIPsFlags(context.Background(), blockNr)
-	state, err := MakePreState(ctx, kv.WrapIntoTxDB(tx), t.json.Pre, blockNr)
+	state, err := MakePreState(params.MainnetChainConfig.Rules(blockNr), kv.WrapIntoTxDB(tx), t.json.Pre, blockNr)
 	if err != nil {
 		return fmt.Errorf("error in MakePreState: %v", err)
 	}
diff --git a/turbo/transactions/tracing.go b/turbo/transactions/tracing.go
index de13b22c4d69922929c23b0bee6a112fb57debe4..4024ca15d7c4288634763bf33cbddcf7a93dbe51 100644
--- a/turbo/transactions/tracing.go
+++ b/turbo/transactions/tracing.go
@@ -50,7 +50,6 @@ func ComputeTxEnv(ctx context.Context, block *types.Block, cfg *params.ChainConf
 
 	BlockContext := core.NewEVMBlockContext(block.Header(), getHeader, engine, nil, checkTEVM)
 	vmenv := vm.NewEVM(BlockContext, vm.TxContext{}, statedb, cfg, vm.Config{})
-	ctx = vmenv.ChainConfig().WithEIPsFlags(ctx, block.NumberU64())
 	for idx, tx := range block.Transactions() {
 		select {
 		default:
@@ -72,7 +71,7 @@ func ComputeTxEnv(ctx context.Context, block *types.Block, cfg *params.ChainConf
 		}
 		// Ensure any modifications are committed to the state
 		// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
-		_ = statedb.FinalizeTx(ctx, state.NewNoopWriter())
+		_ = statedb.FinalizeTx(vmenv.ChainRules, state.NewNoopWriter())
 	}
 	return nil, vm.BlockContext{}, vm.TxContext{}, nil, nil, fmt.Errorf("transaction index %d out of range for block %x", txIndex, blockHash)
 }