diff --git a/core/tx_pool.go b/core/tx_pool.go
index 0b0241aa67c454d3ff05b4fa9b6afeb91e8c9430..13c13ae3ecec37e44fdf6c4fc05b7c464e0a7593 100644
--- a/core/tx_pool.go
+++ b/core/tx_pool.go
@@ -26,6 +26,7 @@ import (
 
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/common/prque"
+	"github.com/ethereum/go-ethereum/consensus/misc"
 	"github.com/ethereum/go-ethereum/core/state"
 	"github.com/ethereum/go-ethereum/core/types"
 	"github.com/ethereum/go-ethereum/event"
@@ -496,13 +497,30 @@ func (pool *TxPool) Content() (map[common.Address]types.Transactions, map[common
 // Pending retrieves all currently processable transactions, grouped by origin
 // account and sorted by nonce. The returned transaction set is a copy and can be
 // freely modified by calling code.
-func (pool *TxPool) Pending() (map[common.Address]types.Transactions, error) {
+//
+// The enforceTips parameter can be used to do an extra filtering on the pending
+// transactions and only return those whose **effective** tip is large enough in
+// the next pending execution environment.
+func (pool *TxPool) Pending(enforceTips bool) (map[common.Address]types.Transactions, error) {
 	pool.mu.Lock()
 	defer pool.mu.Unlock()
 
 	pending := make(map[common.Address]types.Transactions)
 	for addr, list := range pool.pending {
-		pending[addr] = list.Flatten()
+		txs := list.Flatten()
+
+		// If the miner requests tip enforcement, cap the lists now
+		if enforceTips && !pool.locals.contains(addr) {
+			for i, tx := range txs {
+				if tx.EffectiveTipIntCmp(pool.gasPrice, pool.priced.urgent.baseFee) < 0 {
+					txs = txs[:i]
+					break
+				}
+			}
+		}
+		if len(txs) > 0 {
+			pending[addr] = txs
+		}
 	}
 	return pending, nil
 }
@@ -562,7 +580,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error {
 	if tx.Tip().BitLen() > 256 {
 		return ErrTipVeryHigh
 	}
-	// Ensure feeCap is less than or equal to tip.
+	// Ensure feeCap is greater than or equal to tip.
 	if tx.FeeCapIntCmp(tx.Tip()) < 0 {
 		return ErrTipAboveFeeCap
 	}
@@ -1114,8 +1132,9 @@ func (pool *TxPool) runReorg(done chan struct{}, reset *txpoolResetRequest, dirt
 	// because of another transaction (e.g. higher gas price).
 	if reset != nil {
 		pool.demoteUnexecutables()
-		if reset.newHead != nil {
-			pool.priced.SetBaseFee(reset.newHead.BaseFee)
+		if reset.newHead != nil && pool.chainconfig.IsLondon(new(big.Int).Add(reset.newHead.Number, big.NewInt(1))) {
+			pendingBaseFee := misc.CalcBaseFee(pool.chainconfig, reset.newHead)
+			pool.priced.SetBaseFee(pendingBaseFee)
 		}
 	}
 	// Ensure pool.queue and pool.pending sizes stay within the configured limits.
diff --git a/core/tx_pool_test.go b/core/tx_pool_test.go
index b23d40cd4289b736e7bc2dbb5617ab932a809be9..34877f42e0cfb783a044bf49611a10fbc25a37fd 100644
--- a/core/tx_pool_test.go
+++ b/core/tx_pool_test.go
@@ -252,7 +252,7 @@ func TestStateChangeDuringTransactionPoolReset(t *testing.T) {
 	trigger = true
 	<-pool.requestReset(nil, nil)
 
-	_, err := pool.Pending()
+	_, err := pool.Pending(false)
 	if err != nil {
 		t.Fatalf("Could not fetch pending transactions: %v", err)
 	}
diff --git a/core/types/transaction.go b/core/types/transaction.go
index 2b0435bc6395f6609fa45bd953ce4c67730d7f14..03c9c287519dc60f7844e3b09929d710d2ff6721 100644
--- a/core/types/transaction.go
+++ b/core/types/transaction.go
@@ -356,6 +356,14 @@ func (tx *Transaction) EffectiveTipCmp(other *Transaction, baseFee *big.Int) int
 	return tx.EffectiveTipValue(baseFee).Cmp(other.EffectiveTipValue(baseFee))
 }
 
+// EffectiveTipIntCmp compares the effective tip of a transaction to the given tip.
+func (tx *Transaction) EffectiveTipIntCmp(other *big.Int, baseFee *big.Int) int {
+	if baseFee == nil {
+		return tx.TipIntCmp(other)
+	}
+	return tx.EffectiveTipValue(baseFee).Cmp(other)
+}
+
 // Hash returns the transaction hash.
 func (tx *Transaction) Hash() common.Hash {
 	if hash := tx.hash.Load(); hash != nil {
diff --git a/eth/api_backend.go b/eth/api_backend.go
index 7a2e649cf07afbac022b0d7bff84055f236170be..e6810f2a9bedd9f1981a7904d2862ddc77007a33 100644
--- a/eth/api_backend.go
+++ b/eth/api_backend.go
@@ -231,7 +231,7 @@ func (b *EthAPIBackend) SendTx(ctx context.Context, signedTx *types.Transaction)
 }
 
 func (b *EthAPIBackend) GetPoolTransactions() (types.Transactions, error) {
-	pending, err := b.eth.txPool.Pending()
+	pending, err := b.eth.txPool.Pending(false)
 	if err != nil {
 		return nil, err
 	}
diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go
index 1e487d7781380caec8a9c8a134d9206d011e5ed4..bf717ed2800c74db1fe7d4c99592f0ff82a70b76 100644
--- a/eth/catalyst/api.go
+++ b/eth/catalyst/api.go
@@ -127,7 +127,7 @@ func (api *consensusAPI) AssembleBlock(params assembleBlockParams) (*executableD
 		time.Sleep(wait)
 	}
 
-	pending, err := pool.Pending()
+	pending, err := pool.Pending(true)
 	if err != nil {
 		return nil, err
 	}
diff --git a/eth/handler.go b/eth/handler.go
index cd165380446cdde787e268dd43a3799a3e162669..aff4871afa42683033f300bcf19eaef374645e4e 100644
--- a/eth/handler.go
+++ b/eth/handler.go
@@ -66,7 +66,7 @@ type txPool interface {
 
 	// Pending should return pending transactions.
 	// The slice should be modifiable by the caller.
-	Pending() (map[common.Address]types.Transactions, error)
+	Pending(enforceTips bool) (map[common.Address]types.Transactions, error)
 
 	// SubscribeNewTxsEvent should return an event subscription of
 	// NewTxsEvent and send events to the given channel.
diff --git a/eth/handler_test.go b/eth/handler_test.go
index a90ef5c348aa4af2efaa00cc91dedfd3f8d52858..090bd9239c2e227f0e7564b2b6cf0197ff530870 100644
--- a/eth/handler_test.go
+++ b/eth/handler_test.go
@@ -91,7 +91,7 @@ func (p *testTxPool) AddRemotes(txs []*types.Transaction) []error {
 }
 
 // Pending returns all the transactions known to the pool
-func (p *testTxPool) Pending() (map[common.Address]types.Transactions, error) {
+func (p *testTxPool) Pending(enforceTips bool) (map[common.Address]types.Transactions, error) {
 	p.lock.RLock()
 	defer p.lock.RUnlock()
 
diff --git a/eth/sync.go b/eth/sync.go
index 4520ec68794c7ed27de0ad10015c1dfe22d82a39..ab114b59f3e1fa21a1f8a29b0d90fd67c12f1652 100644
--- a/eth/sync.go
+++ b/eth/sync.go
@@ -54,7 +54,7 @@ func (h *handler) syncTransactions(p *eth.Peer) {
 	//
 	// TODO(karalabe): Figure out if we could get away with random order somehow
 	var txs types.Transactions
-	pending, _ := h.txpool.Pending()
+	pending, _ := h.txpool.Pending(false)
 	for _, batch := range pending {
 		txs = append(txs, batch...)
 	}
diff --git a/miner/worker.go b/miner/worker.go
index f9aae0fdc9baad64ebbdbff93131af22c255b80c..0b08b73364922b1acca544fa413610ef41a296d9 100644
--- a/miner/worker.go
+++ b/miner/worker.go
@@ -963,7 +963,7 @@ func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64)
 	}
 
 	// Fill the block with all available pending transactions.
-	pending, err := w.eth.TxPool().Pending()
+	pending, err := w.eth.TxPool().Pending(true)
 	if err != nil {
 		log.Error("Failed to fetch pending transactions", "err", err)
 		return